feat: Post and comment search
This commit is contained in:
parent
852f69f690
commit
e24f6d61d7
8 changed files with 144 additions and 5 deletions
|
@ -41,4 +41,26 @@ defmodule BdfrBrowser.Comment do
|
||||||
group_by: [c.id, p.id, s.name]
|
group_by: [c.id, p.id, s.name]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def search(str) do
|
||||||
|
search_str = "%#{str}%"
|
||||||
|
|
||||||
|
from(c in __MODULE__,
|
||||||
|
join: p in assoc(c, :post),
|
||||||
|
join: s in assoc(p, :subreddit),
|
||||||
|
select: %{
|
||||||
|
author: c.author,
|
||||||
|
body: c.body,
|
||||||
|
children: [],
|
||||||
|
posted_at: c.posted_at,
|
||||||
|
subreddit: s.name,
|
||||||
|
post_id: p.id,
|
||||||
|
post_title: p.title,
|
||||||
|
post_date: fragment("to_char(?, 'YYYY-MM')", p.posted_at)
|
||||||
|
},
|
||||||
|
where: ilike(c.body, ^search_str),
|
||||||
|
order_by: [desc: c.posted_at],
|
||||||
|
group_by: [c.id, p.id, s.name]
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -106,6 +106,32 @@ defmodule BdfrBrowser.HTTP.Plug do
|
||||||
|> send_resp(200, content)
|
|> send_resp(200, content)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
get "/search" do
|
||||||
|
conn = Plug.Conn.fetch_query_params(conn)
|
||||||
|
params = conn.query_params
|
||||||
|
|
||||||
|
{tpl, tpl_args} =
|
||||||
|
if not is_nil(params["comment"]) and String.length(params["comment"]) > 0 do
|
||||||
|
search = params["comment"]
|
||||||
|
|
||||||
|
{"search_comments", [search: search, comments: search |> Comment.search() |> Repo.all()]}
|
||||||
|
else
|
||||||
|
search = params["post"]
|
||||||
|
|
||||||
|
{"search_posts",
|
||||||
|
[
|
||||||
|
search: search,
|
||||||
|
posts: search |> Post.search() |> Repo.all()
|
||||||
|
]}
|
||||||
|
end
|
||||||
|
|
||||||
|
content = render_template(tpl, tpl_args)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_resp_header("content-type", "text/html; charset=utf-8")
|
||||||
|
|> send_resp(200, content)
|
||||||
|
end
|
||||||
|
|
||||||
get "/static/*path" do
|
get "/static/*path" do
|
||||||
file_path = Application.app_dir(:bdfr_browser, Path.join("priv/static", path))
|
file_path = Application.app_dir(:bdfr_browser, Path.join("priv/static", path))
|
||||||
|
|
||||||
|
|
|
@ -78,4 +78,25 @@ defmodule BdfrBrowser.Post do
|
||||||
group_by: [p.id, s.name]
|
group_by: [p.id, s.name]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def search(str) do
|
||||||
|
search_str = "%#{str}%"
|
||||||
|
|
||||||
|
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,
|
||||||
|
date: fragment("to_char(?, 'YYYY-MM')", p.posted_at)
|
||||||
|
},
|
||||||
|
where: ilike(p.title, ^search_str) or ilike(p.selftext, ^search_str),
|
||||||
|
order_by: [desc: p.posted_at],
|
||||||
|
group_by: [p.id, s.name]
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,33 @@
|
||||||
<h2>Archived Subreddits</h2>
|
<h1>BDFR Browser</h1>
|
||||||
|
|
||||||
<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">
|
||||||
<a class="btn btn-outline-primary btn-lg" href="/chats" role="button">Chats</a>
|
<a class="btn btn-outline-primary btn-lg" href="/chats" role="button">Chats</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<form method="get" action="/search" class="row justify-content-center">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<input type="text" class="form-control" placeholder="Post" name="post" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<input type="text" class="form-control" placeholder="Comment" name="comment" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-2 text-center">
|
||||||
|
<button type="submit" class="btn btn-primary">Search</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<h2>Archived Subreddits</h2>
|
||||||
|
|
||||||
|
<div class="row text-center">
|
||||||
|
<div class="d-grid gap-2 col-12 mx-auto">
|
||||||
<%= for subreddit <- subreddits, not String.starts_with?(subreddit, "u_") do %>
|
<%= for subreddit <- subreddits, not String.starts_with?(subreddit, "u_") do %>
|
||||||
<a class="btn btn-outline-secondary btn-lg" href="/r/<%= subreddit %>" role="button"><%= subreddit %></a>
|
<a class="btn btn-outline-secondary btn-lg" href="/r/<%= subreddit %>" role="button"><%= subreddit %></a>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -23,3 +47,5 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
22
priv/templates/http/search_comments.eex
Normal file
22
priv/templates/http/search_comments.eex
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<h2>Search: <%= search %></h2>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="d-grid gap-2 col-12 mx-auto">
|
||||||
|
<%= for comment <- comments do %>
|
||||||
|
<div class="card" style="margin-bottom: 4px;">
|
||||||
|
<div class="card-body">
|
||||||
|
<blockquote class="blockquote mb-0" style="font-size: 1rem;">
|
||||||
|
<%= BdfrBrowser.RenderUtils.comment(comment.body) %>
|
||||||
|
|
||||||
|
<footer class="blockquote-footer">
|
||||||
|
<a href="/user/<%= comment.author %>"><%= comment.author %></a>,
|
||||||
|
<a href="/r/<%= comment.subreddit %>/<%= comment.post_date %>/<%= comment.post_id %>"><%= comment.post_title %></a>,
|
||||||
|
<a href="/r/<%= comment.subreddit %>/<%= comment.post_date %>/"><%= comment.subreddit %></a>,
|
||||||
|
<small><%= DateTime.to_iso8601(comment.posted_at) %></small>
|
||||||
|
</footer>
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
20
priv/templates/http/search_posts.eex
Normal file
20
priv/templates/http/search_posts.eex
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<h2>Search: <%= search %></h2>
|
||||||
|
|
||||||
|
<div class="row text-center">
|
||||||
|
<div class="d-grid gap-2 col-12 mx-auto">
|
||||||
|
<%= for post <- posts do %>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title"><a href="/r/<%= post.subreddit %>/<%= post.date %>/<%= post.id %>"><%= post.title %></a></h5>
|
||||||
|
<h6 class="card-subtitle mb-2 text-body-secondary">
|
||||||
|
<small>
|
||||||
|
<a href="/r/<%= post.subreddit %>/<%= post.date %>/"><%= post.subreddit %></a> -
|
||||||
|
<%= post.num_comments %> comment(s) -
|
||||||
|
<%= Calendar.strftime(post.posted_at, "%Y-%m-%d") %>
|
||||||
|
</small>
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -7,7 +7,7 @@
|
||||||
<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/<%= 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">
|
||||||
<%= post.num_comments %> comment(s) - <%= DateTime.to_iso8601(post.posted_at) %>
|
<small><%= post.num_comments %> comment(s) - <%= DateTime.to_iso8601(post.posted_at) %></small>
|
||||||
</h6>
|
</h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,9 +29,11 @@
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title"><a href="/r/<%= post.subreddit %>/<%= post.date %>/<%= post.id %>"><%= post.title %></a></h5>
|
<h5 class="card-title"><a href="/r/<%= post.subreddit %>/<%= post.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">
|
||||||
<a href="/r/<%= post.subreddit %>/<%= post.date %>/"><%= post.subreddit %></a> -
|
<small>
|
||||||
<%= post.num_comments %> comment(s) -
|
<a href="/r/<%= post.subreddit %>/<%= post.date %>/"><%= post.subreddit %></a> -
|
||||||
<%= Calendar.strftime(post.posted_at, "%Y-%m-%d") %>
|
<%= post.num_comments %> comment(s) -
|
||||||
|
<%= Calendar.strftime(post.posted_at, "%Y-%m-%d") %>
|
||||||
|
</small>
|
||||||
</h6>
|
</h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in a new issue