Add blogroll
This commit is contained in:
15
app/actions/blogroll/index.rb
Normal file
15
app/actions/blogroll/index.rb
Normal file
@@ -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
|
15
app/actions/blogroll/list.rb
Normal file
15
app/actions/blogroll/list.rb
Normal file
@@ -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
|
16
app/actions/blogroll/opml.rb
Normal file
16
app/actions/blogroll/opml.rb
Normal file
@@ -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
|
30
app/queries/blogroll/index.rb
Normal file
30
app/queries/blogroll/index.rb
Normal file
@@ -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
|
11
app/templates/blogroll/index.html.slim
Normal file
11
app/templates/blogroll/index.html.slim
Normal file
@@ -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"
|
||||
|
||||
|
13
app/templates/blogroll/list.html.slim
Normal file
13
app/templates/blogroll/list.html.slim
Normal file
@@ -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(",")}"
|
16
app/templates/blogroll/opml.xml.builder
Normal file
16
app/templates/blogroll/opml.xml.builder
Normal file
@@ -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
|
@@ -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
|
||||
|
||||
|
9
app/views/blogroll/index.rb
Normal file
9
app/views/blogroll/index.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
module Adamantium
|
||||
module Views
|
||||
module Blogroll
|
||||
class Index < Adamantium::View
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
25
app/views/blogroll/list.rb
Normal file
25
app/views/blogroll/list.rb
Normal file
@@ -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
|
25
app/views/blogroll/opml.rb
Normal file
25
app/views/blogroll/opml.rb
Normal file
@@ -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
|
Reference in New Issue
Block a user