Compare commits
4 Commits
ab105d71ae
...
5f3be52132
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 5f3be52132 | |
Shadowfacts | dffd653738 | |
Shadowfacts | 978ee86667 | |
Shadowfacts | 93aebeb600 |
|
@ -23,7 +23,7 @@ defmodule Frenzy.OPML.Importer do
|
||||||
outline_elements
|
outline_elements
|
||||||
|> Enum.flat_map(&get_feeds/1)
|
|> Enum.flat_map(&get_feeds/1)
|
||||||
|> Enum.reduce(%{}, fn {group, feed_url}, acc ->
|
|> Enum.reduce(%{}, fn {group, feed_url}, acc ->
|
||||||
Map.update(acc, group, [], fn feeds -> [feed_url | feeds] end)
|
Map.update(acc, group, [feed_url], fn feeds -> [feed_url | feeds] end)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ defmodule Frenzy.User do
|
||||||
has_many :approved_clients, Frenzy.ApprovedClient, on_delete: :delete_all
|
has_many :approved_clients, Frenzy.ApprovedClient, on_delete: :delete_all
|
||||||
|
|
||||||
has_many :groups, Frenzy.Group, on_delete: :delete_all
|
has_many :groups, Frenzy.Group, on_delete: :delete_all
|
||||||
|
has_many :feeds, through: [:groups, :feeds]
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,13 +7,11 @@ defmodule FrenzyWeb.Fervor.ItemsController do
|
||||||
plug :get_specific_item
|
plug :get_specific_item
|
||||||
|
|
||||||
def get_specific_item(%Plug.Conn{path_params: %{"id" => id}} = conn, _opts) do
|
def get_specific_item(%Plug.Conn{path_params: %{"id" => id}} = conn, _opts) do
|
||||||
user = conn.assigns[:user] |> Repo.preload(groups: [:feeds])
|
user = conn.assigns[:user] |> Repo.preload(:feeds)
|
||||||
|
|
||||||
feeds = Enum.flat_map(user.groups, fn g -> g.feeds end)
|
|
||||||
|
|
||||||
item = Repo.get(Item, id)
|
item = Repo.get(Item, id)
|
||||||
|
|
||||||
if Enum.any?(feeds, fn f -> f.id == item.feed_id end) do
|
if Enum.any?(user.feeds, fn f -> f.id == item.feed_id end) do
|
||||||
assign(conn, :item, item)
|
assign(conn, :item, item)
|
||||||
else
|
else
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -10,9 +10,7 @@ defmodule FrenzyWeb.ItemController do
|
||||||
|
|
||||||
item = Repo.get(Item, id)
|
item = Repo.get(Item, id)
|
||||||
|
|
||||||
feeds = Enum.flat_map(user.groups, fn g -> g.feeds end)
|
if Enum.any?(user.feeds, fn f -> f.id == item.feed_id end) do
|
||||||
|
|
||||||
if Enum.any?(feeds, fn f -> f.id == item.feed_id end) do
|
|
||||||
conn
|
conn
|
||||||
|> assign(:item, item)
|
|> assign(:item, item)
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,29 +1,20 @@
|
||||||
<div id="<%= @id %>">
|
<div id="<%= @id %>"><%= f = form_for @rule, "#", [phx_change: :update_rule, phx_target: "##{@parent_id}"] %>
|
||||||
<%= f = form_for @rule, "#", [phx_change: :update_rule, phx_target: "##{@parent_id}"] %>
|
|
||||||
<%= hidden_input f, :index, value: @index %>
|
<%= hidden_input f, :index, value: @index %>
|
||||||
<div class="form-group row mb-2">
|
<div class="row">
|
||||||
<label class="col-sm-2 col-form-label" for="<%= @id %>-property">Item Property</label>
|
<div class="col-3">
|
||||||
<div class="col-sm-10">
|
|
||||||
<%= select f, :property, @properties, id: "#{@id}-property", class: "custom-select" %>
|
<%= select f, :property, @properties, id: "#{@id}-property", class: "custom-select" %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-3">
|
||||||
<div class="form-group row mb-2">
|
|
||||||
<label class="col-sm-2 col-form-label" for="<%= @id %>-mode">Mode</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<%= select f, :mode, @modes, id: "#{@id}-mode", class: "custom-select" %>
|
<%= select f, :mode, @modes, id: "#{@id}-mode", class: "custom-select" %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col">
|
||||||
<div class="form-group row mb-2">
|
|
||||||
<label class="col-sm-2 col-form-label" for="<%= @id %>-param">Value</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<%= text_input f, :param, id: "#{@id}-param", placeholder: if(@rule["mode"] == "contains_string", do: "substring", else: "regex"), class: "form-control text-monospace" %>
|
<%= text_input f, :param, id: "#{@id}-param", placeholder: if(@rule["mode"] == "contains_string", do: "substring", else: "regex"), class: "form-control text-monospace" %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-0">
|
<div class="form-group row mb-0 mt-4">
|
||||||
<label class="col-sm-2 col-form-label" for="<%= @id %>-weight">Rule Weight</label>
|
<label class="col-sm-2 col-form-label" for="<%= @id %>-weight">Rule Weight</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<%= number_input f, :weight, id: "#{@id}-weight", class: "form-control" %>
|
<%= number_input f, :weight, id: "#{@id}-weight", class: "form-control" %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form></div>
|
||||||
</div>
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ defmodule FrenzyWeb.Plug.Authenticate do
|
||||||
|> halt()
|
|> halt()
|
||||||
|
|
||||||
user ->
|
user ->
|
||||||
user = Repo.preload(user, groups: [:feeds])
|
user = Repo.preload(user, [:groups, :feeds])
|
||||||
assign(conn, :user, user)
|
assign(conn, :user, user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
2
mix.lock
2
mix.lock
|
@ -18,7 +18,7 @@
|
||||||
"fiet": {:git, "https://github.com/shadowfacts/fiet.git", "bf117bc30a6355a189d05a562127cfaf9e0187ae", [branch: "master"]},
|
"fiet": {:git, "https://github.com/shadowfacts/fiet.git", "bf117bc30a6355a189d05a562127cfaf9e0187ae", [branch: "master"]},
|
||||||
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm", "0d50da6b04c58e101a3793b1600f9a03b86e3a8057b192ac1766013d35706fa6"},
|
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm", "0d50da6b04c58e101a3793b1600f9a03b86e3a8057b192ac1766013d35706fa6"},
|
||||||
"floki": {:hex, :floki, "0.23.0", "956ab6dba828c96e732454809fb0bd8d43ce0979b75f34de6322e73d4c917829", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e680b5ef0b61ce02faa7137db8d1714903a5552be4c89fb57293b8770e7f49c2"},
|
"floki": {:hex, :floki, "0.23.0", "956ab6dba828c96e732454809fb0bd8d43ce0979b75f34de6322e73d4c917829", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e680b5ef0b61ce02faa7137db8d1714903a5552be4c89fb57293b8770e7f49c2"},
|
||||||
"gemini": {:git, "https://git.shadowfacts.net/shadowfacts/gemini-ex.git", "b97479c58d278274568010387d9a18f8557d0ca7", [branch: "main"]},
|
"gemini": {:git, "https://git.shadowfacts.net/shadowfacts/gemini-ex.git", "322c233e18b2868c1fdc4ac14c3ededdd5c458f0", [branch: "main"]},
|
||||||
"gettext": {:hex, :gettext, "0.17.0", "abe21542c831887a2b16f4c94556db9c421ab301aee417b7c4fbde7fbdbe01ec", [:mix], [], "hexpm", "e0b8598e802676c81e66b061a2148c37c03886b24a3ca86a1f98ed40693b94b3"},
|
"gettext": {:hex, :gettext, "0.17.0", "abe21542c831887a2b16f4c94556db9c421ab301aee417b7c4fbde7fbdbe01ec", [:mix], [], "hexpm", "e0b8598e802676c81e66b061a2148c37c03886b24a3ca86a1f98ed40693b94b3"},
|
||||||
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
|
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
|
||||||
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm", "3e3d7156a272950373ce5a4018b1490bea26676f8d6a7d409f6fac8568b8cb9a"},
|
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm", "3e3d7156a272950373ce5a4018b1490bea26676f8d6a7d409f6fac8568b8cb9a"},
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
defmodule Frenzy.OPML.ExporterTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
alias Frenzy.OPML.Exporter
|
||||||
|
alias Frenzy.{Feed, Group}
|
||||||
|
doctest Exporter
|
||||||
|
|
||||||
|
test "export groups" do
|
||||||
|
res =
|
||||||
|
Exporter.export([
|
||||||
|
%Group{
|
||||||
|
title: "Group 1",
|
||||||
|
feeds: [
|
||||||
|
%Feed{
|
||||||
|
feed_url: "https://shadowfacts.net/feed.xml",
|
||||||
|
site_url: "https://shadowfacts.net/",
|
||||||
|
title: "Shadowfacts"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
%Group{
|
||||||
|
title: "Group 2",
|
||||||
|
feeds: [
|
||||||
|
%Feed{
|
||||||
|
feed_url: "some other url",
|
||||||
|
site_url: "my site",
|
||||||
|
title: "the title"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
assert res ==
|
||||||
|
"""
|
||||||
|
<opml version="1.0">
|
||||||
|
<head>
|
||||||
|
<title>Frenzy export</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<outline text="Group 1" title="Group 1">
|
||||||
|
<outline htmlUrl="https://shadowfacts.net/" text="Shadowfacts" title="Shadowfacts" type="rss" xmlUrl="https://shadowfacts.net/feed.xml"/>
|
||||||
|
</outline>
|
||||||
|
<outline text="Group 2" title="Group 2">
|
||||||
|
<outline htmlUrl="my site" text="the title" title="the title" type="rss" xmlUrl="some other url"/>
|
||||||
|
</outline>
|
||||||
|
</body>
|
||||||
|
</opml>
|
||||||
|
"""
|
||||||
|
|> String.trim()
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,30 @@
|
||||||
|
defmodule Frenzy.OPML.ImporterTests do
|
||||||
|
use ExUnit.Case
|
||||||
|
alias Frenzy.OPML.Importer
|
||||||
|
doctest Importer
|
||||||
|
|
||||||
|
@opml """
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- OPML generated by NetNewsWire -->
|
||||||
|
<opml version="1.1">
|
||||||
|
<head>
|
||||||
|
<title>Subscriptions-OnMyMac.opml</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<outline text="Julia Evans" title="Julia Evans" description="" type="rss" version="RSS" htmlUrl="" xmlUrl="https://jvns.ca/atom.xml"/>
|
||||||
|
<outline text="my folder" title="my folder">
|
||||||
|
<outline text="The Shape of Everything" title="The Shape of Everything" description="" type="rss" version="RSS" htmlUrl="https://shapeof.com/" xmlUrl="https://shapeof.com/feed.json"/>
|
||||||
|
</outline>
|
||||||
|
</body>
|
||||||
|
</opml>
|
||||||
|
"""
|
||||||
|
|
||||||
|
test "parse simple OPML" do
|
||||||
|
res = Importer.parse_opml(@opml)
|
||||||
|
|
||||||
|
assert res == %{
|
||||||
|
:default => ["https://jvns.ca/atom.xml"],
|
||||||
|
"my folder" => ["https://shapeof.com/feed.json"]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue