diff --git a/lib/something_erlang/awful_api/awful_api.ex b/lib/something_erlang/awful_api/awful_api.ex index a11d903..070675e 100644 --- a/lib/something_erlang/awful_api/awful_api.ex +++ b/lib/something_erlang/awful_api/awful_api.ex @@ -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 diff --git a/lib/something_erlang/awful_api/bookmarks.ex b/lib/something_erlang/awful_api/bookmarks.ex index d0097bd..b318378 100644 --- a/lib/something_erlang/awful_api/bookmarks.ex +++ b/lib/something_erlang/awful_api/bookmarks.ex @@ -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 diff --git a/lib/something_erlang/awful_api/thread.ex b/lib/something_erlang/awful_api/thread.ex index 6be1818..93ff4d1 100644 --- a/lib/something_erlang/awful_api/thread.ex +++ b/lib/something_erlang/awful_api/thread.ex @@ -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 + diff --git a/lib/something_erlang/grover.ex b/lib/something_erlang/grover.ex index 8a907a6..5ad8cd4 100644 --- a/lib/something_erlang/grover.ex +++ b/lib/something_erlang/grover.ex @@ -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 diff --git a/lib/something_erlang_web/live/bookmarks_live.ex b/lib/something_erlang_web/live/bookmarks_live.ex new file mode 100644 index 0000000..a962c33 --- /dev/null +++ b/lib/something_erlang_web/live/bookmarks_live.ex @@ -0,0 +1,42 @@ +defmodule SomethingErlangWeb.BookmarksLive do + use SomethingErlangWeb, :live_view + + alias SomethingErlang.Grover + + def render(assigns) do + ~H""" +
+ <.bookmark + :for={thread <- @bookmarks} + id={thread.id} + title={thread.title.thread_title} + post_count={thread.replies} + /> +
+ """ + end + + defp bookmark(assigns) do + assigns = assign(assigns, :pages, trunc(assigns.post_count / 40)) + + ~H""" +
+ <.link href={~p"/thread/#{@id}"}><%= @title %> + <.link href={~p"/thread/#{@id}?page=#{@pages}"}><%= @pages %> +
+ """ + 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 diff --git a/lib/something_erlang_web/router.ex b/lib/something_erlang_web/router.ex index 712109c..aede270 100644 --- a/lib/something_erlang_web/router.ex +++ b/lib/something_erlang_web/router.ex @@ -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 diff --git a/mix.lock b/mix.lock index 294e5a8..e91bf26 100644 --- a/mix.lock +++ b/mix.lock @@ -12,7 +12,7 @@ "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, "floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"}, "gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"}, - "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]}, + "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]}, "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "meeseeks": {:hex, :meeseeks, "0.17.0", "8a41ceccd2365476c2b779292e7649fb25f0a9735030905941f1244d2095c8a6", [:mix], [{:meeseeks_html5ever, "~> 0.14.3", [hex: :meeseeks_html5ever, repo: "hexpm", optional: false]}], "hexpm", "13efaf321a1517dea046cb48ff9baa9dc0604d9afd82c57501bc01dc45a5e309"},