Add bookmark admin

This commit is contained in:
2023-05-07 11:31:15 +10:00
parent fa146fbfb3
commit 3fddc1757e
17 changed files with 186 additions and 2 deletions

View File

@@ -29,6 +29,8 @@ gem "gpx"
gem "gnuplot"
gem "matrix"
gem "ruby-readability", :require => "readability"
gem "down"
gem "httparty"
gem "redcarpet"
gem "reverse_markdown"

View File

@@ -76,6 +76,8 @@ GEM
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
down (5.4.0)
addressable (~> 2.8)
dry-auto_inject (1.0.1)
dry-core (~> 1.0)
zeitwerk (~> 2.6)
@@ -165,6 +167,7 @@ GEM
guard (~> 2.14)
guard-compat (~> 1.2)
puma (>= 4.0, < 7)
guess_html_encoding (0.0.11)
hanami (2.0.3)
bundler (>= 1.16, < 3)
dry-configurable (~> 1.0, < 2)
@@ -375,6 +378,9 @@ GEM
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
ruby-progressbar (1.13.0)
ruby-readability (0.7.0)
guess_html_encoding (>= 0.0.4)
nokogiri (>= 1.6.0)
ruby2_keywords (0.0.5)
sanitize (6.0.1)
crass (~> 1.0.2)
@@ -433,6 +439,7 @@ DEPENDENCIES
capistrano3-puma!
database_cleaner-sequel
dotenv
down
dry-matcher
dry-monads
dry-types
@@ -463,6 +470,7 @@ DEPENDENCIES
rom-factory
rom-sql
ruby-filemagic!
ruby-readability
sanitize
scraperd!
slim

View File

@@ -1,13 +1,20 @@
div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200"
h1 = bookmark.name
div class="mb-12 prose max-w-prose mx-auto text-gray-800 dark:text-gray-200"
div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" x-data="{ open: false }"
a class="text-blue-600 no-underline hover:underline" href=bookmark.url
p class="text-xl"
= bookmark.url
== bookmark.content
- unless bookmark.cached_content.nil?
button @click="open = ! open" Toggle cached version
span x-show="open"
div class="rounded bg-blue-50 px-4 py-2"
== bookmark.cached_content
div class="prose max-w-prose mx-auto text-gray-800 dark:text-gray-200 grid grid-cols-5 gap-2" hx-get="/bookmarks/metadata/#{bookmark.id}" hx-trigger="load"
div class="mb-8 max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600"

View File

@@ -28,6 +28,7 @@ html
script src="/assets/index.js"
script src="https://unpkg.com/htmx.org@1.8.4" integrity="sha384-wg5Y/JwF7VxGk4zLsJEcAojRtlVp1FKKdGy1qN+OMtdq72WRvX/EdRdqg/LOhYeV" crossorigin="anonymous"
script src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.0/dist/cdn.min.js" defer="true"
script src="https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js"
link href="https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css" rel="stylesheet"

View File

@@ -4,11 +4,12 @@ require "hanami"
module Adamantium
class App < Hanami::App
config.actions.content_security_policy[:script_src] += " https://gist.github.com"
config.actions.content_security_policy[:script_src] += " 'unsafe-eval' https://gist.github.com"
config.actions.content_security_policy[:script_src] += " *.dnitza.com"
config.actions.content_security_policy[:script_src] += " https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js"
config.actions.content_security_policy[:media_src] += " https://dnitza.com"
config.actions.content_security_policy[:script_src] += " https://unpkg.com/htmx.org@1.8.4 https://unpkg.com/htmx.org@1.9.2"
config.actions.content_security_policy[:script_src] += " https://cdn.jsdelivr.net/npm/alpinejs@3.12.0/dist/cdn.min.js"
config.actions.content_security_policy[:connect_src] += " https://stats.dnitza.com/api/event https://*.mapbox.com"
config.actions.content_security_policy[:frame_src] += " https://embed.music.apple.com"
config.actions.content_security_policy[:style_src] += " https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css"

View File

@@ -65,6 +65,10 @@ module Adamantium
get "/tags/auto_tagging/new", to: "auto_tagging.new"
post "/tags/auto_tagging", to: "auto_tagging.create"
delete "/tags/auto_taggings/:id", to: "auto_tagging.delete"
get "/bookmarks", to: "bookmarks.index"
delete "/bookmarks/:id", to: "bookmarks.delete"
post "/bookmarks/cache/:id", to: "bookmarks.cache"
end
end
end

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
ROM::SQL.migration do
change do
alter_table(:posts) do
add_column :cached_content, :text
end
end
end

View File

@@ -0,0 +1,20 @@
module Admin
module Actions
module Bookmarks
class Cache < Action
include Deps["commands.bookmarks.cache"]
def handle(req, res)
bookmark_id = req.params[:id]
if cache.(bookmark_id: bookmark_id).success?
res.body = "Success"
else
res.body = "Failed"
end
end
end
end
end
end

View File

@@ -0,0 +1,17 @@
module Admin
module Actions
module Bookmarks
class Delete < Action
include Deps["repos.bookmark_repo", "repos.post_tag_repo"]
def handle(req, res)
bookmark_id = req.params[:id]
post_tag_repo.delete_by_post_id(post_id: bookmark_id)
bookmark_repo.delete(id: bookmark_id)
end
end
end
end
end

View File

@@ -0,0 +1,14 @@
module Admin
module Actions
module Bookmarks
class Index < Action
include Deps["views.bookmarks.index"]
def handle(req, res)
res.render index
end
end
end
end
end

View File

@@ -0,0 +1,25 @@
require "readability"
require "down"
module Admin
module Commands
module Bookmarks
class Cache
include Dry::Monads[:result]
include Deps["repos.bookmark_repo"]
def call(bookmark_id: )
bookmark = bookmark_repo.fetch(id: bookmark_id)
bookmark.url
tempfile = Down.download(bookmark.url)
content = Readability::Document.new(tempfile.read, tags: %w[div p h1 h2 h3 h4 h5 h6]).content
bookmark_repo.update(id: bookmark_id, cached_content: content)
Success()
end
end
end
end
end

View File

@@ -0,0 +1,23 @@
module Admin
module Repos
class BookmarkRepo < Adamantium::Repo[:posts]
def list
posts
.where(post_type: "bookmark")
.to_a
end
def fetch(id:)
posts.where(id: id).one
end
def delete(id:)
posts.where(id: id).delete
end
def update(id:, cached_content:)
posts.where(id: id).update(cached_content: cached_content)
end
end
end
end

View File

@@ -5,6 +5,10 @@ module Admin
def delete(tag_id:)
post_tags.where(tag_id: tag_id).delete
end
def delete_by_post_id(post_id:)
post_tags.where(post_id: post_id).delete
end
end
end
end

View File

@@ -0,0 +1,31 @@
div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200"
h1 Admin // Bookmarks
div class="max-w-prose mx-auto"
table class="prose dark:prose-invert table-auto prose-a:text-blue-600 prose-a:no-underline"
thead
th Details
th Date
th Actions
tbody
- bookmarks.each do |bookmark|
tr id="bookmark-#{bookmark.id}"
td
div
= bookmark.name
a class="no-underline" href=bookmark.url
small class="text-gray-400 dark:text-gray-600" = bookmark.url
div
- if bookmark.cached_content
a href="/bookmark/#{bookmark.slug}" View cached version
- else
button hx-post="/admin/bookmarks/cache/#{bookmark.id}" No cached content, cache now?
td
= bookmark.published_at&.strftime("%d %b %Y")
td
button hx-delete="/admin/bookmarks/#{bookmark.id}" hx-target="#bookmark-#{bookmark.id}" delete
div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600"

View File

@@ -7,6 +7,8 @@ div class="max-w-prose mx-auto prose dark:prose-invert"
a href="/admin/tags" Tags
li
a href="/admin/tags/auto_tagging" Auto tagging
li
a href="/admin/bookmarks" Bookmarks
div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600"

View File

@@ -47,6 +47,8 @@ html
a class="p-1 rounded text-gray-400 hover:bg-red-100 hover:text-red-400 dark:hover:bg-red-200 #{link_active?('about') ? 'text-red-600 dark:text-red-400' : ''}" href="/admin/tags" Tags
span class="text-gray-400 dark:text-gray-600"
= "/"
a class="p-1 rounded text-gray-400 hover:bg-red-100 hover:text-red-400 dark:hover:bg-red-200 #{link_active?('about') ? 'text-red-600 dark:text-red-400' : ''}" href="/admin/bookmarks" Bookmarks
== yield
div class="px-4 max-w-screen-md mx-auto pb-10"
p class="float-left text-gray-200 dark:text-gray-600" © 2023 Daniel Nitsikopoulos. All rights reserved.

View File

@@ -0,0 +1,14 @@
module Admin
module Views
module Bookmarks
class Index < Admin::View
include Deps["repos.bookmark_repo"]
expose :bookmarks do
bookmark_repo.list
end
end
end
end
end