From 0bafc3722a121900a6edc0aa4449dec6227d9a97 Mon Sep 17 00:00:00 2001 From: Daniel Nitsikopoulos Date: Sun, 11 Feb 2024 14:40:46 +1100 Subject: [PATCH] Add blogroll --- app/actions/blogroll/index.rb | 15 +++++++++++++ app/actions/blogroll/list.rb | 15 +++++++++++++ app/actions/blogroll/opml.rb | 16 +++++++++++++ app/queries/blogroll/index.rb | 30 +++++++++++++++++++++++++ app/templates/blogroll/index.html.slim | 11 +++++++++ app/templates/blogroll/list.html.slim | 13 +++++++++++ app/templates/blogroll/opml.xml.builder | 16 +++++++++++++ app/templates/more/index.html.slim | 8 ++++--- app/views/blogroll/index.rb | 9 ++++++++ app/views/blogroll/list.rb | 25 +++++++++++++++++++++ app/views/blogroll/opml.rb | 25 +++++++++++++++++++++ config/routes.rb | 4 ++++ config/settings.rb | 4 ++++ 13 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 app/actions/blogroll/index.rb create mode 100644 app/actions/blogroll/list.rb create mode 100644 app/actions/blogroll/opml.rb create mode 100644 app/queries/blogroll/index.rb create mode 100644 app/templates/blogroll/index.html.slim create mode 100644 app/templates/blogroll/list.html.slim create mode 100644 app/templates/blogroll/opml.xml.builder create mode 100644 app/views/blogroll/index.rb create mode 100644 app/views/blogroll/list.rb create mode 100644 app/views/blogroll/opml.rb diff --git a/app/actions/blogroll/index.rb b/app/actions/blogroll/index.rb new file mode 100644 index 0000000..f18ae0d --- /dev/null +++ b/app/actions/blogroll/index.rb @@ -0,0 +1,15 @@ +require "time_math" + +module Adamantium + module Actions + module Blogroll + class Index < Action + include Deps["views.blogroll.index"] + + def handle(req, res) + res.render index + end + end + end + end +end diff --git a/app/actions/blogroll/list.rb b/app/actions/blogroll/list.rb new file mode 100644 index 0000000..6c7803a --- /dev/null +++ b/app/actions/blogroll/list.rb @@ -0,0 +1,15 @@ +require "time_math" + +module Adamantium + module Actions + module Blogroll + class List < Action + include Deps["views.blogroll.list"] + + def handle(req, res) + res.body = cache(key: "blogroll", content_proc: -> { list.call.to_str }, expiry: TimeMath.min.advance(Time.now, +60)) + end + end + end + end +end diff --git a/app/actions/blogroll/opml.rb b/app/actions/blogroll/opml.rb new file mode 100644 index 0000000..4b50ee4 --- /dev/null +++ b/app/actions/blogroll/opml.rb @@ -0,0 +1,16 @@ +require "time_math" + +module Adamantium + module Actions + module Blogroll + class Opml < Action + include Deps["views.blogroll.opml"] + + def handle(req, res) + res.content_type = "text/xml; charset=utf-8" + res.render opml, format: :xml + end + end + end + end +end diff --git a/app/queries/blogroll/index.rb b/app/queries/blogroll/index.rb new file mode 100644 index 0000000..15e3ca4 --- /dev/null +++ b/app/queries/blogroll/index.rb @@ -0,0 +1,30 @@ +require "httparty" + +module Adamantium + module Queries + module Blogroll + class Index + include Deps["settings"] + + def call + resp = HTTParty.get("https://#{settings.rss_url}/api/greader.php/reader/api/0/subscription/list?output=json", { + headers: { + "Authorization" => "GoogleLogin auth=#{auth_token}" + } + }) + + resp.body + end + + private + + def auth_token + auth_url = "https://#{settings.rss_url}/api/greader.php/accounts/ClientLogin?Email=#{settings.rss_username}&Passwd=#{settings.rss_password}" + resp = HTTParty.get(auth_url) + auth = resp.match(/SID=(.*)/) + auth[1].strip + end + end + end + end +end diff --git a/app/templates/blogroll/index.html.slim b/app/templates/blogroll/index.html.slim new file mode 100644 index 0000000..0dd821f --- /dev/null +++ b/app/templates/blogroll/index.html.slim @@ -0,0 +1,11 @@ +- context.content_for(:title, "Blogroll | ") +div class="mb-4 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" + h1 Blogroll + +div class="h-feed mb-12 max-w-prose mx-auto prose dark:prose-invert" + p Here's the list of all the sites & blogs I enjoy reading, taken directly from my RSS aggregator! + p + a href="/blogroll/opml" Get the OPML + div class="grow" hx-get="/blogroll/list" hx-trigger="load" + + diff --git a/app/templates/blogroll/list.html.slim b/app/templates/blogroll/list.html.slim new file mode 100644 index 0000000..3fbba74 --- /dev/null +++ b/app/templates/blogroll/list.html.slim @@ -0,0 +1,13 @@ +- blogroll.each do |blog| + div class="flex mb-4" + img loading="lazy" class="w-8 h-8 rounded mx-0 my-0 mr-4" src=blog[:icon] + div + div + = "#{blog[:title]} — (" + a href=blog[:url] RSS + = " | " + a href=blog[:html_url] Website + = ")" + div + small Categories: + small = " #{blog[:categories].join(",")}" \ No newline at end of file diff --git a/app/templates/blogroll/opml.xml.builder b/app/templates/blogroll/opml.xml.builder new file mode 100644 index 0000000..c6d0a9f --- /dev/null +++ b/app/templates/blogroll/opml.xml.builder @@ -0,0 +1,16 @@ +# xml.instruct! "xml-stylesheet", {href: "/assets/style.xslt", type: "text/xsl"} +xml.opml("xmlns:frss" => "https://freshrss.org/opml", version: "2.0") do + xml.head do |head| + head.title "Daniel Nitsikopoulos's RSS subscriptions" + head.link "https://dnitza.com/blogroll/opml" + head.lastBuildDate Time.now.rfc2822 + head.pubDate Time.now.rfc2822 + head.ttl 1800 + end + + xml.body do + blogroll.each do |blog| + xml.outline(text: blog[:title], type: "rss", xmlUrl: blog[:url], htmlUrl: blog[:html_url]) + end + end +end diff --git a/app/templates/more/index.html.slim b/app/templates/more/index.html.slim index e191a74..1b3b4f0 100644 --- a/app/templates/more/index.html.slim +++ b/app/templates/more/index.html.slim @@ -13,12 +13,14 @@ div class="mb-12 max-w-prose mx-auto text-gray-800 dark:text-gray-200" h2 class="text-xl" Explore everything else div class="grid grid-cols-2 gap-2 mb-6" + a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/blogroll" 🪵 Blogroll + a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/bookshelf" 📚️ Bookshelf + a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/collections" 📦 Collections a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/colophon" 🧱 Colophon a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/hikes" 🥾 Hikes a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/movies" 🍿 Movies - a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/trips" 🛫 Trips a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/podcasts" 🎙️ Podcasts - a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/bookshelf" 📚️ Bookshelf - a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/collections" 📦 Collections + a class="block p-1 border border-blue-200 bg-blue-200 text-blue-900 hover:bg-blue-300 text-center rounded-lg" href="/trips" 🛫 Trips + / a class="block p-1 border border-blue-200 bg-blue-300 text-blue-900 hover:bg-blue-200 text-center rounded-lg" href="/art" 🎨 Art things diff --git a/app/views/blogroll/index.rb b/app/views/blogroll/index.rb new file mode 100644 index 0000000..8592fef --- /dev/null +++ b/app/views/blogroll/index.rb @@ -0,0 +1,9 @@ +module Adamantium + module Views + module Blogroll + class Index < Adamantium::View + + end + end + end +end diff --git a/app/views/blogroll/list.rb b/app/views/blogroll/list.rb new file mode 100644 index 0000000..960f2f7 --- /dev/null +++ b/app/views/blogroll/list.rb @@ -0,0 +1,25 @@ +module Adamantium + module Views + module Blogroll + class List < Adamantium::View + include Deps[blogroll_list: "queries.blogroll.index"] + + expose :blogroll do |blogroll_result| + JSON.parse(blogroll_result)["subscriptions"].map do |feed| + { + title: feed["title"], + url: feed["url"], + html_url: feed["htmlUrl"], + icon: feed["iconUrl"], + categories: feed["categories"].map {|cat| cat["label"]} + } + end + end + + private_expose :blogroll_result do + blogroll_list.call + end + end + end + end +end diff --git a/app/views/blogroll/opml.rb b/app/views/blogroll/opml.rb new file mode 100644 index 0000000..eff8849 --- /dev/null +++ b/app/views/blogroll/opml.rb @@ -0,0 +1,25 @@ +module Adamantium + module Views + module Blogroll + class Opml < Adamantium::View + include Deps[blogroll_list: "queries.blogroll.index"] + + expose :blogroll do |blogroll_result| + JSON.parse(blogroll_result)["subscriptions"].map do |feed| + { + title: feed["title"], + url: feed["url"], + html_url: feed["htmlUrl"], + icon: feed["iconUrl"], + categories: feed["categories"].map {|cat| cat["label"]} + } + end + end + + private_expose :blogroll_result do + blogroll_list.call + end + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index ece24ec..6ac93bf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -39,6 +39,10 @@ module Adamantium get "/movies", to: "movies.index" + get "/blogroll", to: "blogroll.index" + get "/blogroll/list", to: "blogroll.list" + get "/blogroll/opml", to: "blogroll.opml" + get "/recently_played", to: "recently_played.index" get "/:slug", to: "pages.show" diff --git a/config/settings.rb b/config/settings.rb index f347223..251b106 100644 --- a/config/settings.rb +++ b/config/settings.rb @@ -30,6 +30,10 @@ module Adamantium setting :pingback_url, default: nil setting :webmention_token, default: nil + setting :rss_url, default: nil + setting :rss_username, default: nil + setting :rss_password, default: nil + setting :lastfm_api_key, default: nil setting :lastfm_secret, default: nil