Add filter web UI
This commit is contained in:
parent
0ebaca4a83
commit
c90f2d48e2
|
@ -19,8 +19,10 @@ defmodule Frenzy.Feed do
|
|||
field :last_updated, :utc_datetime
|
||||
field :site_url, :string
|
||||
field :title, :string
|
||||
field :filter_enabled, :boolean
|
||||
|
||||
has_many :items, Frenzy.Item, on_delete: :delete_all
|
||||
has_one :filter, Frenzy.Filter, on_delete: :delete_all
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
@ -28,7 +30,8 @@ defmodule Frenzy.Feed do
|
|||
@doc false
|
||||
def changeset(feed, attrs) do
|
||||
feed
|
||||
|> cast(attrs, [:title, :feed_url, :site_url, :last_updated])
|
||||
|> cast(attrs, [:title, :feed_url, :site_url, :last_updated, :filter_enabled])
|
||||
|> cast_assoc(:filter, required: true)
|
||||
|> validate_required([:feed_url])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
defmodule Frenzy.Filter do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
schema "filters" do
|
||||
field :mode, :string
|
||||
field :score, :integer
|
||||
|
||||
belongs_to :feed, Frenzy.Feed
|
||||
has_many :rules, Frenzy.Rule, on_delete: :delete_all
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(filter, attrs) do
|
||||
filter
|
||||
|> cast(attrs, [:mode, :score])
|
||||
|> cast_assoc(:rules)
|
||||
|> validate_required([:mode, :score])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
defmodule Frenzy.Rule do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
schema "rules" do
|
||||
field :mode, :string
|
||||
field :property, :string
|
||||
field :param, :string
|
||||
field :weight, :integer
|
||||
|
||||
belongs_to :filter, Frenzy.Filter
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(rule, attrs) do
|
||||
rule
|
||||
|> cast(attrs, [:mode, :property, :param, :weight])
|
||||
|> validate_required([:mode, :property, :param, :weight])
|
||||
end
|
||||
end
|
|
@ -81,6 +81,7 @@ defmodule Frenzy.UpdateFeeds do
|
|||
feed = Repo.preload(feed, :items)
|
||||
|
||||
Enum.map(rss.items, fn entry ->
|
||||
# todo: use Repo.exists for this
|
||||
if !Enum.any?(feed.items, fn item -> item.guid == entry.id end) do
|
||||
create_item(feed, entry)
|
||||
end
|
||||
|
@ -100,7 +101,7 @@ defmodule Frenzy.UpdateFeeds do
|
|||
|
||||
{:err, reason} ->
|
||||
Logger.warn("Unable to fetch article for #{url}: #{reason}")
|
||||
entry.content || entry.summary
|
||||
entry.description
|
||||
end
|
||||
|
||||
changeset =
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
defmodule FrenzyWeb.FeedController do
|
||||
use FrenzyWeb, :controller
|
||||
alias Frenzy.{Repo, Feed, Item}
|
||||
alias Frenzy.{Repo, Feed, Filter, Item}
|
||||
alias FrenzyWeb.Router.Helpers, as: Routes
|
||||
alias FrenzyWeb.Endpoint
|
||||
import Ecto.Query
|
||||
|
@ -10,8 +10,9 @@ defmodule FrenzyWeb.FeedController do
|
|||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
feed = Repo.get(Feed, id)
|
||||
feed = Repo.get(Feed, id) |> Repo.preload(:filter)
|
||||
items = Repo.all(from Item, where: [feed_id: ^id], order_by: [desc: :date])
|
||||
|
||||
render(conn, "show.html", %{
|
||||
feed: feed,
|
||||
items: items
|
||||
|
@ -20,15 +21,41 @@ defmodule FrenzyWeb.FeedController do
|
|||
|
||||
def new(conn, _params) do
|
||||
changeset = Feed.changeset(%Feed{}, %{})
|
||||
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def create(conn, %{"feed" => feed}) do
|
||||
changeset = Feed.changeset(%Feed{}, feed)
|
||||
changeset =
|
||||
Feed.changeset(
|
||||
%Feed{
|
||||
filter: %Filter{
|
||||
mode: "accept",
|
||||
score: 0,
|
||||
rules: []
|
||||
}
|
||||
},
|
||||
feed
|
||||
)
|
||||
|
||||
{:ok, feed} = Repo.insert(changeset)
|
||||
redirect(conn, to: Routes.feed_path(Endpoint, :index))
|
||||
end
|
||||
|
||||
def enable_filter(conn, %{"id" => id}) do
|
||||
feed = Repo.get(Feed, id) |> Repo.preload(:filter)
|
||||
changeset = Feed.changeset(feed, %{filter_enabled: true})
|
||||
Repo.update(changeset)
|
||||
redirect(conn, to: Routes.feed_path(Endpoint, :show, id))
|
||||
end
|
||||
|
||||
def disable_filter(conn, %{"id" => id}) do
|
||||
feed = Repo.get(Feed, id)
|
||||
changeset = Feed.changeset(feed, %{filter_enabled: false})
|
||||
Repo.update(changeset)
|
||||
redirect(conn, to: Routes.feed_path(Endpoint, :show, id))
|
||||
end
|
||||
|
||||
def delete(conn, %{"id" => id}) do
|
||||
feed = Repo.get(Feed, id)
|
||||
{:ok, _} = Repo.delete(feed)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
defmodule FrenzyWeb.FilterController do
|
||||
use FrenzyWeb, :controller
|
||||
alias Frenzy.{Repo, Feed, Filter, Rule}
|
||||
alias FrenzyWeb.Router.Helpers, as: Routes
|
||||
alias FrenzyWeb.Endpoint
|
||||
import Ecto.Query
|
||||
|
||||
def edit(conn, %{"id" => id}) do
|
||||
filter = Repo.get(Filter, id) |> Repo.preload(:rules)
|
||||
changeset = Filter.changeset(filter, %{})
|
||||
render(conn, "edit.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def update(conn, %{"id" => id, "filter" => filter_params}) do
|
||||
filter = Repo.get(Filter, id) |> Repo.preload(:rules)
|
||||
changeset = Filter.changeset(filter, filter_params)
|
||||
Repo.update(changeset)
|
||||
redirect(conn, to: Routes.filter_path(Endpoint, :edit, id))
|
||||
end
|
||||
|
||||
def add_rule(conn, %{"id" => id}) do
|
||||
filter = Repo.get(Filter, id)
|
||||
|
||||
changeset =
|
||||
Ecto.build_assoc(filter, :rules, %{
|
||||
property: "title",
|
||||
mode: "contains_string",
|
||||
param: "",
|
||||
weight: 5
|
||||
})
|
||||
|
||||
Repo.insert(changeset)
|
||||
|
||||
redirect(conn, to: Routes.filter_path(Endpoint, :edit, id))
|
||||
end
|
||||
end
|
|
@ -12,7 +12,6 @@ defmodule FrenzyWeb.Router do
|
|||
|
||||
pipeline :api do
|
||||
plug :accepts, ["json"]
|
||||
|
||||
end
|
||||
|
||||
scope "/", FrenzyWeb do
|
||||
|
@ -23,6 +22,11 @@ defmodule FrenzyWeb.Router do
|
|||
get "/", FeedController, :index
|
||||
resources "/feeds", FeedController, except: [:edit, :update]
|
||||
post "/feeds/:id/refresh", FeedController, :refresh
|
||||
post "/feeds/:id/enable_filter", FeedController, :enable_filter
|
||||
post "/feeds/:id/disable_filter", FeedController, :disable_filter
|
||||
|
||||
resources "/filters", FilterController, only: [:edit, :update]
|
||||
post "/filters/:id/add_rule", FilterController, :add_rule
|
||||
|
||||
resources "/items", ItemController, only: [:show]
|
||||
post "/items/:id/read", ItemController, :read
|
||||
|
|
|
@ -2,10 +2,26 @@
|
|||
<%= submit "Refresh Feed" %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<%= if @feed.filter_enabled do %>
|
||||
<%= form_tag Routes.feed_path(@conn, :disable_filter, @feed.id), method: :post do %>
|
||||
<%= submit "Disable Filter" %>
|
||||
<% end %>
|
||||
|
||||
<%= form_tag Routes.filter_path(@conn, :edit, @feed.filter.id), method: :get do %>
|
||||
<%= submit "Edit Filter" %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= form_tag Routes.feed_path(@conn, :enable_filter, @feed.id), method: :post do %>
|
||||
<%= submit "Enable Filter" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= form_tag Routes.feed_path(@conn, :delete, @feed.id), method: :delete do %>
|
||||
<%= submit "Delete Feed" %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<table>
|
||||
<%= for item <- @items do %>
|
||||
<tr <%= if item.read do %>class="item-read"<% end %>>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<h2>Filter</h2>
|
||||
<%= form_for @changeset, Routes.filter_path(@conn, :update, @changeset.data.id), fn form -> %>
|
||||
<div class="form-group">
|
||||
<label for="mode">Mode</label>
|
||||
<%= select form, :mode, [{"Accept", :accept}, {"Reject", :reject}] %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="score">Score</label>
|
||||
<%= number_input form, :score %>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Mode</th>
|
||||
<th>Param</th>
|
||||
<th>Weight</th>
|
||||
</tr>
|
||||
<%= inputs_for form, :rules, fn p -> %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= select p, :property, [{"URL", :url}, {"Title", :title}, {"Author", :author}, {"Content", :content}] %>
|
||||
</td>
|
||||
<td>
|
||||
<%= select p, :mode, [{"contains", :contains_string}, {"matches regex", :matches_regex}] %>
|
||||
</td>
|
||||
<td>
|
||||
<%= text_input p, :param %>
|
||||
</td>
|
||||
<td>
|
||||
<%= number_input p, :weight %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<div class="form-group">
|
||||
<%= submit "Update Filter" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= form_tag Routes.filter_path(@conn, :add_rule, @changeset.data.id), method: :post do %>
|
||||
<%= submit "Add Rule" %>
|
||||
<% end %>
|
|
@ -0,0 +1,3 @@
|
|||
defmodule FrenzyWeb.FilterView do
|
||||
use FrenzyWeb, :view
|
||||
end
|
|
@ -10,6 +10,5 @@ defmodule Frenzy.Repo.Migrations.CreateFeeds do
|
|||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
defmodule Frenzy.Repo.Migrations.CreateRules do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:filters) do
|
||||
add :mode, :string
|
||||
add :score, :integer
|
||||
add :rules, :map
|
||||
add :feed_id, references(:feeds)
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
# create index(:rules, [:filter])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
defmodule Frenzy.Repo.Migrations.FeedsAddFilter do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table(:feeds) do
|
||||
add :filter_enabled, :boolean
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
defmodule Frenzy.Repo.Migrations.CreateRules do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:rules) do
|
||||
add :mode, :string
|
||||
add :property, :string
|
||||
add :param, :string
|
||||
add :weight, :integer
|
||||
add :filter_id, references(:filters)
|
||||
|
||||
timestamps()
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue