feat: Simulated multireddits
All checks were successful
Build / build (push) Successful in 2m42s

This commit is contained in:
Daniel Kempkens 2023-10-02 12:59:52 +02:00
parent 0a7c16fe48
commit 38df258ce5
Signed by: daniel
SSH key fingerprint: SHA256:Ks/MyhQYcPRQiwMKLAKquWCdCPe3JXlb1WttgnAoSeM
8 changed files with 154 additions and 16 deletions

View file

@ -8,11 +8,18 @@ defmodule BdfrBrowser.HTTP.Plug do
get "/" do get "/" do
config_file = Application.fetch_env!(:bdfr_browser, :config_file) config_file = Application.fetch_env!(:bdfr_browser, :config_file)
archived_subreddits = Enum.sort(config_file["archived_subreddits"]) archived_subreddits = Enum.sort_by(config_file["archived_subreddits"], &String.downcase/1)
archived_users = Enum.sort(config_file["archived_users"]) archived_users = Enum.sort_by(config_file["archived_users"], &String.downcase/1)
saved_searches = Enum.sort(config_file["saved_searches"]) simulated_multireddits = Enum.sort_by(config_file["simulated_multireddits"], fn {t, _} -> String.downcase(t) end)
saved_searches = Enum.sort_by(config_file["saved_searches"], &String.downcase/1)
tpl_args = [
subreddits: archived_subreddits,
users: archived_users,
multireddits: simulated_multireddits,
searches: saved_searches
]
tpl_args = [subreddits: archived_subreddits, users: archived_users, searches: saved_searches]
content = render_template("index", tpl_args) content = render_template("index", tpl_args)
conn conn
@ -21,7 +28,10 @@ defmodule BdfrBrowser.HTTP.Plug do
end end
get "/all/subreddits" do get "/all/subreddits" do
tpl_args = [subreddits: Subreddit.names() |> Repo.all()] config_file = Application.fetch_env!(:bdfr_browser, :config_file)
archived_subreddits = MapSet.new(config_file["archived_subreddits"])
tpl_args = [subreddits: Subreddit.names() |> Repo.all(), archived_subreddits: archived_subreddits]
content = render_template("all_subreddits", tpl_args) content = render_template("all_subreddits", tpl_args)
conn conn
@ -78,6 +88,39 @@ defmodule BdfrBrowser.HTTP.Plug do
|> send_resp(200, content) |> send_resp(200, content)
end end
get "/m/:subreddits" do
subreddit_names = String.split(subreddits, "+")
subreddit_records = Subreddit.multiple_names(subreddit_names) |> Repo.all()
tpl_args = [
subreddit: subreddit_names,
dates: subreddit_records |> Post.date_listing() |> Repo.all()
]
content = render_template("subreddit", tpl_args)
conn
|> put_resp_header("content-type", "text/html; charset=utf-8")
|> send_resp(200, content)
end
get "/m/:subreddits/:date" do
subreddit_names = String.split(subreddits, "+")
subreddit_records = Subreddit.multiple_names(subreddit_names) |> Repo.all()
tpl_args = [
subreddit: subreddit_names,
date: date,
posts: subreddit_records |> Post.during_month(date) |> Repo.all()
]
content = render_template("subreddit_posts", tpl_args)
conn
|> put_resp_header("content-type", "text/html; charset=utf-8")
|> send_resp(200, content)
end
get "/chats" do get "/chats" do
tpl_args = [chats: Chat.listing() |> Repo.all()] tpl_args = [chats: Chat.listing() |> Repo.all()]
content = render_template("chats", tpl_args) content = render_template("chats", tpl_args)

View file

@ -21,6 +21,17 @@ defmodule BdfrBrowser.Post do
has_many :comments, Comment has_many :comments, Comment
end end
def date_listing(subreddits) when is_list(subreddits) do
subreddit_ids = for s <- subreddits, do: s.id
from(p in __MODULE__,
select: fragment("to_char(?, 'YYYY-MM')", p.posted_at),
where: p.subreddit_id in ^subreddit_ids,
distinct: true,
order_by: [desc: fragment("to_char(?, 'YYYY-MM')", p.posted_at)]
)
end
def date_listing(subreddit) do def date_listing(subreddit) do
from(p in __MODULE__, from(p in __MODULE__,
select: fragment("to_char(?, 'YYYY-MM')", p.posted_at), select: fragment("to_char(?, 'YYYY-MM')", p.posted_at),
@ -35,15 +46,45 @@ defmodule BdfrBrowser.Post do
during_range(subreddit, Date.beginning_of_month(d), Date.end_of_month(d)) during_range(subreddit, Date.beginning_of_month(d), Date.end_of_month(d))
end end
def during_range(subreddits, start_date, end_date) when is_list(subreddits) do
subreddit_ids = for s <- subreddits, do: s.id
from(p in __MODULE__,
left_join: c in assoc(p, :comments),
join: s in assoc(p, :subreddit),
select: %{
id: p.id,
title: p.title,
author: p.author,
posted_at: p.posted_at,
num_comments: count(c.id),
subreddit: s.name
},
where:
p.subreddit_id in ^subreddit_ids and type(p.posted_at, :date) >= ^start_date and
type(p.posted_at, :date) <= ^end_date,
order_by: [desc: p.posted_at],
group_by: [p.id, s.name]
)
end
def during_range(subreddit, start_date, end_date) do def during_range(subreddit, start_date, end_date) do
from(p in __MODULE__, from(p in __MODULE__,
left_join: c in assoc(p, :comments), left_join: c in assoc(p, :comments),
select: %{id: p.id, title: p.title, author: p.author, posted_at: p.posted_at, num_comments: count(c.id)}, join: s in assoc(p, :subreddit),
select: %{
id: p.id,
title: p.title,
author: p.author,
posted_at: p.posted_at,
num_comments: count(c.id),
subreddit: s.name
},
where: where:
p.subreddit_id == ^subreddit.id and type(p.posted_at, :date) >= ^start_date and p.subreddit_id == ^subreddit.id and type(p.posted_at, :date) >= ^start_date and
type(p.posted_at, :date) <= ^end_date, type(p.posted_at, :date) <= ^end_date,
order_by: [desc: p.posted_at], order_by: [desc: p.posted_at],
group_by: p.id group_by: [p.id, s.name]
) )
end end

View file

@ -6,9 +6,13 @@ defmodule BdfrBrowser.Subreddit do
alias BdfrBrowser.Post alias BdfrBrowser.Post
schema "subreddits" do schema "subreddits" do
field(:name, :string) field :name, :string
has_many(:posts, Post) has_many :posts, Post
end
def multiple_names(names) do
from(s in __MODULE__, where: s.name in ^names)
end end
def names do def names do

View file

@ -10,7 +10,10 @@
<div class="row text-center"> <div class="row text-center">
<div class="d-grid gap-2 col-12 mx-auto"> <div class="d-grid gap-2 col-12 mx-auto">
<%= for subreddit <- subreddits do %> <%= for subreddit <- subreddits do %>
<a class="btn btn-outline-secondary btn-lg" href="/r/<%= subreddit %>" role="button"><%= subreddit %></a> <a class="btn btn-outline-<%= if MapSet.member?(archived_subreddits, subreddit), do: "info", else: "secondary" %> btn-lg"
href="/r/<%= subreddit %>" role="button">
<%= subreddit %>
</a>
<% end %> <% end %>
</div> </div>
</div> </div>

View file

@ -45,6 +45,18 @@
<br> <br>
<h2>Simulated Multireddits</h2>
<div class="row text-center">
<div class="d-grid gap-2 col-12 mx-auto">
<%= for {title, subreddits} <- multireddits do %>
<a class="btn btn-outline-secondary btn-lg" href="/m/<%= Enum.join(subreddits, "+") %>" role="button"><%= title %></a>
<% end %>
</div>
</div>
<br>
<h2>Saved Searches</h2> <h2>Saved Searches</h2>
<div class="row text-center"> <div class="row text-center">

View file

@ -1,16 +1,32 @@
<nav style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb"> <nav style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Overview</a></li> <li class="breadcrumb-item"><a href="/">Overview</a></li>
<li class="breadcrumb-item active" aria-current="page"><%= subreddit %></li> <li class="breadcrumb-item active" aria-current="page">
<%= if is_list(subreddit) do %>
<%= Enum.join(subreddit, ", ") %>
<% else %>
<%= subreddit %>
<% end %>
</li>
</ol> </ol>
</nav> </nav>
<h2><%= subreddit %></h2> <h2>
<%= if is_list(subreddit) do %>
<%= Enum.join(subreddit, ", ") %>
<% else %>
<%= subreddit %>
<% end %>
</h2>
<div class="row text-center"> <div class="row text-center">
<div class="d-grid gap-2 col-12 mx-auto"> <div class="d-grid gap-2 col-12 mx-auto">
<%= for date <- dates do %> <%= for date <- dates do %>
<a class="btn btn-outline-secondary btn-lg" href="/r/<%= subreddit %>/<%= date %>" role="button"><%= date %></a> <%= if is_list(subreddit) do %>
<a class="btn btn-outline-secondary btn-lg" href="/m/<%= Enum.join(subreddit, "+") %>/<%= date %>" role="button"><%= date %></a>
<% else %>
<a class="btn btn-outline-secondary btn-lg" href="/r/<%= subreddit %>/<%= date %>" role="button"><%= date %></a>
<% end %>
<% end %> <% end %>
</div> </div>
</div> </div>

View file

@ -1,19 +1,31 @@
<nav style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb"> <nav style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Overview</a></li> <li class="breadcrumb-item"><a href="/">Overview</a></li>
<li class="breadcrumb-item"><a href="/r/<%= subreddit %>"><%= subreddit %></a></li> <li class="breadcrumb-item">
<%= if is_list(subreddit) do %>
<a href="/m/<%= Enum.join(subreddit, "+") %>"><%= Enum.join(subreddit, ", ") %></a>
<% else %>
<a href="/r/<%= subreddit %>"><%= subreddit %></a>
<% end %>
</li>
<li class="breadcrumb-item active" aria-current="page"><%= date %></li> <li class="breadcrumb-item active" aria-current="page"><%= date %></li>
</ol> </ol>
</nav> </nav>
<h2><%= subreddit %></h2> <h2>
<%= if is_list(subreddit) do %>
<%= Enum.join(subreddit, ", ") %>
<% else %>
<%= subreddit %>
<% end %>
</h2>
<div class="row text-center"> <div class="row text-center">
<div class="d-grid gap-2 col-12 mx-auto"> <div class="d-grid gap-2 col-12 mx-auto">
<%= for post <- posts do %> <%= for post <- posts do %>
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title"><a href="/r/<%= subreddit %>/<%= date %>/<%= post.id %>"><%= post.title %></a></h5> <h5 class="card-title"><a href="/r/<%= post.subreddit %>/<%= date %>/<%= post.id %>"><%= post.title %></a></h5>
<h6 class="card-subtitle mb-2 text-body-secondary"> <h6 class="card-subtitle mb-2 text-body-secondary">
<small><%= post.num_comments %> comment(s) - <%= DateTime.to_iso8601(post.posted_at) %></small> <small><%= post.num_comments %> comment(s) - <%= DateTime.to_iso8601(post.posted_at) %></small>
</h6> </h6>

View file

@ -1,3 +1,10 @@
<nav style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Overview</a></li>
<li class="breadcrumb-item active" aria-current="page">User</li>
</ol>
</nav>
<h2><%= name %></h2> <h2><%= name %></h2>
<ul class="nav nav-pills" id="userTab" role="tablist"> <ul class="nav nav-pills" id="userTab" role="tablist">