Browse Source

scrape bookmark source for title on creation

pull/26/head
Inhji Y. 1 year ago
parent
commit
0d6938f9d2
  1. 91
      apps/bookmarks/lib/bookmarks.ex
  2. 10
      apps/bookmarks/lib/bookmarks/worker.ex
  3. 1
      apps/bookmarks/mix.exs
  4. 17
      apps/bookmarks/test/bookmarks_test.exs
  5. 2
      apps/scraper/lib/scraper.ex
  6. 5
      apps/tomie_web/lib/tomie_web/controllers/bookmark_controller.ex
  7. 1
      apps/tomie_web/mix.exs
  8. 3
      mix.lock

91
apps/bookmarks/lib/bookmarks.ex

@ -8,11 +8,6 @@ defmodule Bookmarks do
@doc """
Creates a bookmark from the given attributes.
## Examples
create_bookmark(%{source: "https://inhji.de"})
iex> {:ok, %Bookmarks.Bookmark{}}
"""
def create_bookmark(attrs \\ %{}) do
%Bookmark{}
@ -21,57 +16,24 @@ defmodule Bookmarks do
end
@doc """
Updates a bookmark's tags
## Examples
update_tags(["foo", "bar"], 1)
iex> {:ok, %Bookmarks.Bookmark{}}
"""
def update_tags(tags, bookmark_id) when is_list(tags) do
bookmark = Bookmarks.get_bookmark!(bookmark_id)
tags
|> Tags.update_tags_for_entity(bookmark)
end
@doc """
Updates a bookmarks tags
## Examples
update_tags("foo, bar", 1)
iex> {:ok, %Bookmarks.Bookmark{}}
Updates a bookmarks with the given attributes
"""
def update_tags(tags, bookmark_id) when is_binary(tags) do
bookmark = Bookmarks.get_bookmark!(bookmark_id)
tags
|> Tags.from_string()
|> Tags.update_tags_for_entity(bookmark)
def update_bookmark(bookmark, attrs) do
bookmark
|> Bookmark.changeset(attrs)
|> Db.Repo.update()
end
@doc """
Gets a bookmark by its id
## Examples
get_bookmark(1)
iex> {:ok, %Bookmarks.Bookmark{}}
"""
def get_bookmark!(id), do: Db.Repo.get!(Bookmark, id) |> Db.Repo.preload([:tags])
def get_bookmark!(id),
do:
Db.Repo.get!(Bookmark, id)
|> Db.Repo.preload([:tags])
@doc """
Lists bookmarks ordered by insertion date
## Examples
list_bookmarks()
iex> [%Bookmarks.Bookmark{}]
"""
def list_bookmarks do
Db.Repo.all(
@ -84,16 +46,8 @@ defmodule Bookmarks do
@doc """
Registers a visit of the bookmarks url by updating `views` and `viewed_at`
## Examples
visit_bookmark(1)
iex> {:ok, %Bookmarks.Bookmark{}}
"""
def visit_bookmark(id) do
bookmark = get_bookmark!(id)
def visit_bookmark(bookmark) do
bookmark
|> Bookmark.changeset(%{
views: bookmark.views + 1,
@ -101,4 +55,29 @@ defmodule Bookmarks do
})
|> Db.Repo.update()
end
@doc """
Updates a bookmark's tags
Bookmark is reloaded to ensure it's tags are loaded
"""
def update_tags(tags, bookmark) when is_list(tags) do
bookmark = Bookmarks.get_bookmark!(bookmark.id)
tags
|> Tags.update_tags_for_entity(bookmark)
end
@doc """
Updates a bookmarks tags.
Bookmark is reloaded to ensure it's tags are loaded
"""
def update_tags(tags, bookmark) when is_binary(tags) do
bookmark = Bookmarks.get_bookmark!(bookmark.id)
tags
|> Tags.from_string()
|> Tags.update_tags_for_entity(bookmark)
end
end

10
apps/bookmarks/lib/bookmarks/worker.ex

@ -0,0 +1,10 @@
defmodule Bookmarks.Worker do
use Que.Worker
def perform(%Bookmarks.Bookmark{source: source} = bookmark) do
{:ok, html} = Scraper.get_html(source)
title = Scraper.get_title!(html)
Bookmarks.update_bookmark(bookmark, %{title: title})
end
end

1
apps/bookmarks/mix.exs

@ -25,6 +25,7 @@ defmodule Bookmarks.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:que, "~> 0.10.1"},
{:ecto_sql, "~> 3.1"},
{:db, in_umbrella: true},
{:tags, in_umbrella: true},

17
apps/bookmarks/test/bookmarks_test.exs

@ -3,6 +3,7 @@ defmodule BookmarksTest do
doctest Bookmarks
@source "https://inhji.de"
@title "some title"
@post_type "bookmark"
setup tags do
@ -22,6 +23,13 @@ defmodule BookmarksTest do
assert bookmark.type == @post_type
end
test "update_bookmark/2 updates a bookmarks with the given attributes" do
{:ok, bookmark} = Bookmarks.create_bookmark(%{source: @source})
{:ok, updated_bookmark} = Bookmarks.update_bookmark(bookmark, %{title: @title})
assert bookmark.title != updated_bookmark.title
assert updated_bookmark.title == @title
end
test "get_bookmark/1 returns a bookmark by its id" do
{:ok, bookmark} = Bookmarks.create_bookmark(%{source: @source})
new_bookmark = Bookmarks.get_bookmark!(bookmark.id)
@ -39,7 +47,7 @@ defmodule BookmarksTest do
test "visit_bookmark/1 increments visits and updates visited_at" do
{:ok, bookmark} = Bookmarks.create_bookmark(%{source: @source})
{:ok, viewed_bookmark} = Bookmarks.visit_bookmark(bookmark.id)
{:ok, viewed_bookmark} = Bookmarks.visit_bookmark(bookmark)
assert viewed_bookmark.views == bookmark.views + 1
assert viewed_bookmark.viewed_at != bookmark.viewed_at
@ -47,13 +55,14 @@ defmodule BookmarksTest do
test "update_tags updates the tags for a given entity" do
{:ok, bookmark} = Bookmarks.create_bookmark(%{source: @source})
{:ok, updated_bookmark} = Bookmarks.update_tags(["foo"], bookmark.id)
{:ok, updated_bookmark} = Bookmarks.update_tags(["foo"], bookmark)
assert Enum.count(updated_bookmark.tags) == 1
{:ok, updated_bookmark} = Bookmarks.update_tags(["foo", "bar"], bookmark.id)
{:ok, updated_bookmark} = Bookmarks.update_tags(["foo", "bar"], bookmark)
assert Enum.count(updated_bookmark.tags) == 2
{:ok, updated_bookmark} = Bookmarks.update_tags(["foo"], bookmark.id)
{:ok, updated_bookmark} = Bookmarks.update_tags(["foo"], bookmark)
assert Enum.count(updated_bookmark.tags) == 1
end
end

2
apps/scraper/lib/scraper.ex

@ -24,7 +24,7 @@ defmodule Scraper do
end
end
def get_title(html) do
def get_title!(html) do
{:ok, document} = Floki.parse_document(html)
document

5
apps/tomie_web/lib/tomie_web/controllers/bookmark_controller.ex

@ -18,6 +18,8 @@ defmodule TomieWeb.BookmarkController do
def create(conn, %{"bookmark" => bookmark_params}) do
case Bookmarks.create_bookmark(bookmark_params) do
{:ok, bookmark} ->
Que.add(Bookmarks.Worker, bookmark)
conn
|> put_flash(:info, @bookmark_created)
|> redirect(to: Routes.bookmark_path(conn, :show, bookmark))
@ -33,7 +35,8 @@ defmodule TomieWeb.BookmarkController do
end
def visit(conn, %{"id" => id}) do
{:ok, bookmark} = Bookmarks.visit_bookmark(id)
bookmark = Bookmarks.get_bookmark!(id)
{:ok, _visited_bookmark} = Bookmarks.visit_bookmark(bookmark)
conn
|> redirect(external: bookmark.source)

1
apps/tomie_web/mix.exs

@ -46,6 +46,7 @@ defmodule TomieWeb.MixProject do
{:jason, "~> 1.0"},
{:plug_cowboy, "~> 2.0"},
{:pow, "~> 1.0.19"},
{:que, "~> 0.10.1"},
{:tomie, in_umbrella: true},
{:bookmarks, in_umbrella: true},
{:db, in_umbrella: true, only: :test}

3
mix.lock

@ -8,6 +8,7 @@
"ecto": {:hex, :ecto, "3.4.0", "a7a83ab8359bf816ce729e5e65981ce25b9fc5adfc89c2ea3980f4fed0bfd7c1", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "5eed18252f5b5bbadec56a24112b531343507dbe046273133176b12190ce19cc"},
"ecto_autoslug_field": {:hex, :ecto_autoslug_field, "2.0.1", "2177c1c253f6dd3efd4b56d1cb76104d0a6ef044c6b9a7a0ad6d32665c4111e5", [:mix], [{:ecto, ">= 2.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:slugger, ">= 0.2.0", [hex: :slugger, repo: "hexpm", optional: false]}], "hexpm", "a3cc73211f2e75b89a03332183812ebe1ac08be2e25a1df5aa3d1422f92c45c3"},
"ecto_sql": {:hex, :ecto_sql, "3.4.1", "3c9136ba138f9b74d31286c73c61232a92bd19385f7c5607bdeb3a4587ef91f5", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.0", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9b4be0bffe7b0bdf5393defcae52712f248e70cc2bc0e8ab6ddb03be66371516"},
"ex_utils": {:hex, :ex_utils, "0.1.7", "2c133e0bcdc49a858cf8dacf893308ebc05bc5fba501dc3d2935e65365ec0bf3", [:mix], [], "hexpm", "66d4fe75285948f2d1e69c2a5ddd651c398c813574f8d36a9eef11dc20356ef6"},
"fast_html": {:hex, :fast_html, "1.0.3", "2cc0d4b68496266a1530e0c852cafeaede0bd10cfdee26fda50dc696c203162f", [:make, :mix], [], "hexpm", "ab3d782b639d3c4655fbaec0f9d032c91f8cab8dd791ac7469c2381bc7c32f85"},
"file_system": {:hex, :file_system, "0.2.8", "f632bd287927a1eed2b718f22af727c5aeaccc9a98d8c2bd7bff709e851dc986", [:mix], [], "hexpm", "97a3b6f8d63ef53bd0113070102db2ce05352ecf0d25390eb8d747c2bde98bca"},
"floki": {:hex, :floki, "0.26.0", "4df88977e2e357c6720e1b650f613444bfb48c5acfc6a0c646ab007d08ad13bf", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e7b66ce7feef5518a9cd9fc7b52dd62a64028bd9cb6d6ad282a0f0fc90a4ae52"},
@ -17,6 +18,7 @@
"httpoison": {:hex, :httpoison, "1.6.2", "ace7c8d3a361cebccbed19c283c349b3d26991eff73a1eaaa8abae2e3c8089b6", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "aa2c74bd271af34239a3948779612f87df2422c2fdcfdbcec28d9c105f0773fe"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"},
"jason": {:hex, :jason, "1.2.0", "10043418c42d2493d0ee212d3fddd25d7ffe484380afad769a0a38795938e448", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "116747dbe057794c3a3e4e143b7c8390b29f634e16c78a7f59ba75bfa6852e7f"},
"memento": {:hex, :memento, "0.3.1", "b2909390820550d8b90b68ec96f9e15ff8a45a28b6f97fa4a62ef50e87c2f9d9", [:mix], [], "hexpm", "ff8fc66255d21dcd539c5d77a0b5458715bf3efec91b389dd06017bbb4e2e916"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
@ -31,6 +33,7 @@
"plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"},
"postgrex": {:hex, :postgrex, "0.15.3", "5806baa8a19a68c4d07c7a624ccdb9b57e89cbc573f1b98099e3741214746ae4", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "4737ce62a31747b4c63c12b20c62307e51bb4fcd730ca0c32c280991e0606c90"},
"pow": {:hex, :pow, "1.0.19", "e6295de629338661afdc52b3420f1fa37c191d246aef5d844161843fed6fe88b", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.3.0 or ~> 1.4.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, ">= 2.0.0 and <= 3.0.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:plug, ">= 1.5.0 and < 2.0.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "da77fab98e038b39c5360a77dc98e606cdd1446dabdd65a88991e8b23f67a356"},
"que": {:hex, :que, "0.10.1", "788ed0ec92ed69bdf9cfb29bf41a94ca6355b8d44959bd0669cf706e557ac891", [:mix], [{:ex_utils, "~> 0.1.6", [hex: :ex_utils, repo: "hexpm", optional: false]}, {:memento, "~> 0.3.0", [hex: :memento, repo: "hexpm", optional: false]}], "hexpm", "a737b365253e75dbd24b2d51acc1d851049e87baae08cd0c94e2bc5cd65088d5"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
"slugger": {:hex, :slugger, "0.3.0", "efc667ab99eee19a48913ccf3d038b1fb9f165fa4fbf093be898b8099e61b6ed", [:mix], [], "hexpm", "20d0ded0e712605d1eae6c5b4889581c3460d92623a930ddda91e0e609b5afba"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"},

Loading…
Cancel
Save