meeseeks bookmarks; also bookmarks

This commit is contained in:
Rüdiger Diedrich
2024-08-12 15:46:13 +02:00
parent 2ab3f7ba7f
commit fede012e44
6 changed files with 114 additions and 50 deletions

View File

@ -19,7 +19,8 @@ defmodule SomethingErlang.AwfulApi do
|> Thread.compile()
end
def bookmarks(user) do
Bookmarks.compile(1, user)
def bookmarks(page, user) do
Client.bookmarks_doc(page, user)
|> Bookmarks.compile()
end
end

View File

@ -1,59 +1,80 @@
defmodule SomethingErlang.AwfulApi.Bookmarks do
import Meeseeks.CSS
require Logger
alias SomethingErlang.AwfulApi.Client
def compile(html) do
for thread <- Meeseeks.all(html, css("tr.thread")) do
thread_id =
Meeseeks.attr(thread, "id")
|> String.split("thread")
|> List.last()
|> String.to_integer()
def compile(page, user) do
doc = Client.bookmarks_doc(page, user)
html = Floki.parse_document!(doc)
for thread <- Floki.find(html, "tr.thread") do
parse(thread)
|> Map.put(:id, thread_id)
end
end
def parse(thread) do
%{
title: Floki.find(thread, "td.title") |> inner_html() |> Floki.raw_html(),
icon: Floki.find(thread, "td.icon") |> inner_html() |> Floki.raw_html(),
author: Floki.find(thread, "td.author") |> inner_html() |> Floki.text(),
replies: Floki.find(thread, "td.replies") |> inner_html() |> Floki.text(),
views: Floki.find(thread, "td.views") |> inner_html() |> Floki.text(),
rating: Floki.find(thread, "td.rating") |> inner_html() |> Floki.raw_html(),
lastpost: Floki.find(thread, "td.lastpost") |> inner_html() |> Floki.raw_html()
}
for {"td", [{"class", class} | _attrs], children} <- Floki.find(thread, "td"),
String.starts_with?(class, "star") == false,
for col <- Meeseeks.all(thread, css("td:not(.star)")),
class = Meeseeks.attr(col, "class") |> String.split() |> List.first(),
into: %{} do
case class do
<<"title", _rest::binary>> ->
{:title, children |> Floki.raw_html()}
<<"icon", _rest::binary>> ->
{:icon, children |> Floki.raw_html()}
<<"author", _rest::binary>> ->
{:author, children |> Floki.text()}
<<"replies", _rest::binary>> ->
{:replies, children |> Floki.text() |> String.to_integer()}
<<"views", _rest::binary>> ->
{:views, children |> Floki.text() |> String.to_integer()}
<<"rating", _rest::binary>> ->
{:rating, children |> Floki.raw_html()}
<<"lastpost", _rest::binary>> ->
{:lastpost, children |> Floki.raw_html()}
end
{String.to_atom(class), thread_data(class, col)}
end
end
defp inner_html(node) do
node
|> List.first()
|> Floki.children()
defp thread_data("icon", td) do
img = Meeseeks.one(td, css("img"))
%{
icon: Meeseeks.attr(img, "src"),
title: Meeseeks.attr(img, "alt")
}
end
defp thread_data("title", td) do
last_seen = Meeseeks.one(td, css(".lastseen .count"))
info = Meeseeks.one(td, css(".info"))
%{
new_posts: Meeseeks.text(last_seen) |> String.to_integer(),
thread_title: Meeseeks.text(Meeseeks.one(info, css(".thread_title")))
}
end
defp thread_data("author", td) do
Meeseeks.text(td)
end
defp thread_data("replies", td) do
Meeseeks.text(td)
|> String.to_integer()
end
defp thread_data("views", td) do
Meeseeks.text(td)
|> String.to_integer()
end
defp thread_data("rating", td) do
img = Meeseeks.one(td, css("img"))
%{
icon: Meeseeks.attr(img, "src"),
title: Meeseeks.attr(img, "title")
}
end
defp thread_data("lastpost", td) do
date = Meeseeks.one(td, css(".date"))
author = Meeseeks.one(td, css(".author"))
%{
date: Meeseeks.text(date),
author: Meeseeks.text(author)
}
end
defp thread_data(class, _td), do: Logger.error("#{inspect(class)} not found")
end

View File

@ -12,7 +12,6 @@ defmodule SomethingErlang.AwfulApi.Thread do
thread =
Meeseeks.one(html, css("#thread"))
thread_id =
Meeseeks.attr(thread, "class")
|> String.split(":")
@ -74,7 +73,6 @@ defmodule SomethingErlang.AwfulApi.Thread do
date
|> String.split(~r{[\s,:]}, trim: true)
|> Enum.drop(2)
|> dbg()
month =
1 +

View File

@ -55,8 +55,8 @@ defmodule SomethingErlang.Grover do
end
@impl true
def handle_call({:show_bookmarks, _page_number}, _from, state) do
bookmarks = AwfulApi.bookmarks(state.user)
def handle_call({:show_bookmarks, page_number}, _from, state) do
bookmarks = AwfulApi.bookmarks(page_number, state.user)
{:reply, bookmarks, state}
end

View File

@ -0,0 +1,42 @@
defmodule SomethingErlangWeb.BookmarksLive do
use SomethingErlangWeb, :live_view
alias SomethingErlang.Grover
def render(assigns) do
~H"""
<div :if={@bookmarks}>
<.bookmark
:for={thread <- @bookmarks}
id={thread.id}
title={thread.title.thread_title}
post_count={thread.replies}
/>
</div>
"""
end
defp bookmark(assigns) do
assigns = assign(assigns, :pages, trunc(assigns.post_count / 40))
~H"""
<div>
<.link href={~p"/thread/#{@id}"}><%= @title %></.link>
<.link href={~p"/thread/#{@id}?page=#{@pages}"}><%= @pages %></.link>
</div>
"""
end
def mount(_params, session, socket) do
user =
socket.assigns.current_user
|> Map.put(:bbpassword, session["bbpassword"])
Grover.mount(user)
{:ok,
socket
|> assign(:page_title, "Bookmarks")
|> assign(:bookmarks, Grover.get_bookmarks!(1) |> dbg())}
end
end

View File

@ -28,6 +28,8 @@ defmodule SomethingErlangWeb.Router do
on_mount: [{SomethingErlangWeb.UserAuth, :ensure_authenticated}] do
live("/thread", ThreadLive)
live("/thread/:id", ThreadLive)
live("/bookmarks", BookmarksLive)
live("/bookmarks/:id", BookmarksLive)
end
end