From 7f3ff1792564a69be4582691035aa726023070b3 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 20 Jul 2019 19:08:56 -0400 Subject: [PATCH] Start pipeline UI --- lib/frenzy_web/controllers/feed_controller.ex | 10 +- .../controllers/pipeline_controller.ex | 114 ++++++++++++++++++ lib/frenzy_web/router.ex | 10 +- lib/frenzy_web/templates/feed/edit.html.eex | 50 ++++---- .../templates/pipeline/edit.html.eex | 9 ++ .../templates/pipeline/new.html.eex | 27 +++++ lib/frenzy_web/views/pipeline_view.ex | 3 + 7 files changed, 195 insertions(+), 28 deletions(-) create mode 100644 lib/frenzy_web/controllers/pipeline_controller.ex create mode 100644 lib/frenzy_web/templates/pipeline/edit.html.eex create mode 100644 lib/frenzy_web/templates/pipeline/new.html.eex create mode 100644 lib/frenzy_web/views/pipeline_view.ex diff --git a/lib/frenzy_web/controllers/feed_controller.ex b/lib/frenzy_web/controllers/feed_controller.ex index 70528c2..7cb0e57 100644 --- a/lib/frenzy_web/controllers/feed_controller.ex +++ b/lib/frenzy_web/controllers/feed_controller.ex @@ -53,9 +53,13 @@ defmodule FrenzyWeb.FeedController do end def edit(conn, _params) do - feed = conn.assigns[:feed] |> Repo.preload(:filter) - changeset = Feed.changeset(feed, %{}) - render(conn, "edit.html", changeset: changeset) + feed = conn.assigns[:feed] |> Repo.preload([:filter, :pipeline_stages]) + stages = Enum.sort_by(feed.pipeline_stages, fn stage -> stage.index end) + + render(conn, "edit.html", %{ + feed: feed, + stages: stages + }) end def update(conn, %{"feed" => feed_params}) do diff --git a/lib/frenzy_web/controllers/pipeline_controller.ex b/lib/frenzy_web/controllers/pipeline_controller.ex new file mode 100644 index 0000000..ac94343 --- /dev/null +++ b/lib/frenzy_web/controllers/pipeline_controller.ex @@ -0,0 +1,114 @@ +defmodule FrenzyWeb.PipelineController do + use FrenzyWeb, :controller + alias Frenzy.{Repo, Feed, PipelineStage} + alias FrenzyWeb.Router.Helpers, as: Routes + alias FrenzyWeb.Endpoint + import Ecto.Query + + plug :user_owns_feed + plug :user_owns_stage + + defp user_owns_feed(%Plug.Conn{path_params: %{"feed_id" => feed_id}} = conn, _opts) do + user = conn.assigns[:user] + + feed = Repo.get(Feed, feed_id) |> Repo.preload(:pipeline_stages) + + if Enum.any?(user.groups, fn g -> g.id == feed.group_id end) do + conn + |> assign(:feed, feed) + else + conn + |> put_flash(:error, "You do not have permission to access that resource.") + |> redirect(to: Routes.group_path(Endpoint, :index)) + |> halt() + end + end + + defp user_owns_feed(conn, _opts), do: conn + + defp user_owns_stage(%Plug.Conn{path_params: %{"stage_id" => stage_id}} = conn, _opts) do + feed = conn.assigns[:feed] + + stage = Repo.get(PipelineStage, stage_id) + + if stage.feed_id == feed.id do + conn + |> assign(:stage, stage) + else + conn + |> put_flash(:error, "You do not have permission to access that resource.") + |> redirect(to: Routes.group_path(Endpoint, :index)) + |> halt() + end + end + + defp user_owns_stage(conn, _opts), do: conn + + def edit(conn, %{"stage_id" => stage_id}) do + feed = conn.assigns[:feed] + stage = conn.assigns[:stage] + {:ok, options_json} = Jason.encode(stage.options, pretty: true) + + render(conn, "edit.html", %{ + feed: feed, + stage: stage, + options: options_json + }) + end + + def update(conn, %{"options" => options_json}) do + feed = conn.assigns[:feed] + stage = conn.assigns[:stage] + {:ok, options} = Jason.decode(options_json) + changeset = PipelineStage.changeset(stage, %{options: options}) + {:ok, _stage} = Repo.update(changeset) + + conn + |> put_flash(:info, "Pipeline Stage updated") + |> redirect(to: Routes.feed_path(Endpoint, :edit, feed.id)) + end + + def new(conn, _params) do + changeset = PipelineStage.changeset(%PipelineStage{}, %{}) + + render(conn, "new.html", %{ + feed: conn.assigns[:feed], + changeset: changeset + }) + end + + def create(conn, %{ + "pipeline_stage" => %{ + "index" => index, + "module_name" => module_name, + "options" => options_json + } + }) do + feed = conn.assigns[:feed] + {index, _} = Integer.parse(index) + {:ok, options} = Jason.decode(options_json) + + changeset = + Ecto.build_assoc(feed, :pipeline_stages, %{ + index: index, + module_name: module_name, + options: options + }) + + {:ok, _stage} = Repo.insert(changeset) + + conn + |> put_flash(:info, "Pipeline Stage created") + |> redirect(to: Routes.feed_path(Endpoint, :edit, feed.id)) + end + + def delete(conn, _params) do + feed = conn.assigns[:feed] + stage = conn.assigns[:stage] + {:ok, _stage} = Repo.delete(stage) + + conn + |> put_flash(:info, "Pipeline Stage deleted") + |> redirect(to: Routes.feed_path(Endpoint, :edit, feed.id)) + end +end diff --git a/lib/frenzy_web/router.ex b/lib/frenzy_web/router.ex index 4f7e673..7b40175 100644 --- a/lib/frenzy_web/router.ex +++ b/lib/frenzy_web/router.ex @@ -49,8 +49,14 @@ defmodule FrenzyWeb.Router do resources "/feeds", FeedController, except: [:index, :new] post "/feeds/:id/refresh", FeedController, :refresh - #post "/feeds/:id/enable_filter", FeedController, :enable_filter - #post "/feeds/:id/disable_filter", FeedController, :disable_filter + + # resources "/pipelines", PipelineController, only: [:edit, :update, :new, :create] + + get "/feeds/:feed_id/pipelines/:stage_id/edit", PipelineController, :edit + post "/feeds/:feed_id/pipelines/:stage_id/update", PipelineController, :update + delete "/feeds/:feed_id/pipelines/:stage_id/delete", PipelineController, :delete + get "/feeds/:feed_id/pipelines/new", PipelineController, :new + post "/feeds/:feed_id/pipelines/create", PipelineController, :create resources "/filters", FilterController, only: [:edit, :update] post "/filters/:id/add_rule", FilterController, :add_rule diff --git a/lib/frenzy_web/templates/feed/edit.html.eex b/lib/frenzy_web/templates/feed/edit.html.eex index 6acb57a..a42aabc 100644 --- a/lib/frenzy_web/templates/feed/edit.html.eex +++ b/lib/frenzy_web/templates/feed/edit.html.eex @@ -1,25 +1,29 @@ -

Feed

-<%= form_tag Routes.filter_path(@conn, :edit, @changeset.data.filter.id), method: :get, class: "d-inline" do %> - <%= submit "Edit Filter", class: "btn btn-secondary" %> -<% end %> +

Feed Pipeline

-<%= form_for @changeset, Routes.feed_path(@conn, :update, @changeset.data.id), fn form -> %> -
- -
- <%= checkbox form, :filter_enabled %> -
-
-
- -
- <%= checkbox form, :scrape_remote_content %> -
-
+ + + + + + + + + <%= for stage <- @stages do %> + + + + + <% end %> + +
Module
+ <%= stage.module_name %> + + + Edit + + <%= form_for @conn, Routes.pipeline_path(@conn, :delete, @feed.id, stage.id), [method: :delete, style: "display: inline-block;"], fn f -> %> + <%= submit "Delete", class: "btn btn-danger btn-sm" %> + <% end %> +
-
-
- <%= submit "Update Feed", class: "btn btn-primary" %> -
-
-<% end %> +Add Stage diff --git a/lib/frenzy_web/templates/pipeline/edit.html.eex b/lib/frenzy_web/templates/pipeline/edit.html.eex new file mode 100644 index 0000000..65ee0c8 --- /dev/null +++ b/lib/frenzy_web/templates/pipeline/edit.html.eex @@ -0,0 +1,9 @@ +

Pipeline Stage

+

Feed: <%= @feed.title %>

+

Module: <%= @stage.module_name %>

+ +<%= form_for @conn, Routes.pipeline_path(@conn, :update, @feed.id, @stage.id), fn f -> %> + <%= textarea f, :options, value: @options, class: "form-control", rows: 15, style: "font-family: monospace;" %> + <%= submit "Update", class: "btn btn-primary mt-2" %> +<% end %> + diff --git a/lib/frenzy_web/templates/pipeline/new.html.eex b/lib/frenzy_web/templates/pipeline/new.html.eex new file mode 100644 index 0000000..3bb7941 --- /dev/null +++ b/lib/frenzy_web/templates/pipeline/new.html.eex @@ -0,0 +1,27 @@ +

Feed Pipeline

+ +<%= form_for @changeset, Routes.pipeline_path(@conn, :create, @feed.id), fn f -> %> +
+ +
+ <%= text_input f, :module_name, placeholder: "Frenzy.Pipeline.FilterStage", class: "form-control" %> +
+
+
+ +
+ <%= number_input f, :index, value: "#{@feed.pipeline_stages |> Enum.count()}", class: "form-control" %> +
+
+
+ +
+ <%= textarea f, :options, value: "{}", class: "form-control", rows: 15, style: "font-family: monospace;" %> +
+
+
+
+ <%= submit "Create Stage", class: "btn btn-primary" %> +
+
+<% end %> diff --git a/lib/frenzy_web/views/pipeline_view.ex b/lib/frenzy_web/views/pipeline_view.ex new file mode 100644 index 0000000..0b41d33 --- /dev/null +++ b/lib/frenzy_web/views/pipeline_view.ex @@ -0,0 +1,3 @@ +defmodule FrenzyWeb.PipelineView do + use FrenzyWeb, :view +end