Add feed endpoints; fix cc license logo styles; add humans.txt
This commit is contained in:
parent
e461635f3a
commit
e643bf6df0
@ -8,7 +8,7 @@
|
|||||||
"lib": "lib"
|
"lib": "lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@extollo/lib": "^0.9.28",
|
"@extollo/lib": "^0.9.31",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"feed": "^4.2.2",
|
"feed": "^4.2.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
|
@ -2,7 +2,7 @@ lockfileVersion: 5.3
|
|||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
'@extollo/cc': ^0.6.0
|
'@extollo/cc': ^0.6.0
|
||||||
'@extollo/lib': ^0.9.28
|
'@extollo/lib': ^0.9.31
|
||||||
copyfiles: ^2.4.1
|
copyfiles: ^2.4.1
|
||||||
feed: ^4.2.2
|
feed: ^4.2.2
|
||||||
rimraf: ^3.0.2
|
rimraf: ^3.0.2
|
||||||
@ -13,7 +13,7 @@ specifiers:
|
|||||||
zod: ^3.11.6
|
zod: ^3.11.6
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@extollo/lib': 0.9.28
|
'@extollo/lib': 0.9.31
|
||||||
copyfiles: 2.4.1
|
copyfiles: 2.4.1
|
||||||
feed: 4.2.2
|
feed: 4.2.2
|
||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
@ -112,8 +112,8 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@extollo/lib/0.9.28:
|
/@extollo/lib/0.9.31:
|
||||||
resolution: {integrity: sha512-lMI2FWOTKbRsqJrOAvZofzfz0DaNwWecYsDX98XkNbktaUjhaGc7xr1OVxscxUC/Edapyj/p02MLdsUoIsARxA==}
|
resolution: {integrity: sha512-sYtqWTL+hmkPZ44fwWdRsHK1081m98547r9snFm8i+ou13Npw3i4RBf8k+uFRUCayMM4PKVWqgo0bZJLvO4W1g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@atao60/fse-cli': 0.1.7
|
'@atao60/fse-cli': 0.1.7
|
||||||
'@extollo/ui': 0.1.0_@types+node@14.18.12
|
'@extollo/ui': 0.1.0_@types+node@14.18.12
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {Controller, view, Injectable, Collection} from '@extollo/lib'
|
import {Controller, view, Injectable, Collection, Inject, Routing, plaintext} from '@extollo/lib'
|
||||||
import {FeedPost} from '../../models/FeedPost.model'
|
import {FeedPost} from '../../models/FeedPost.model'
|
||||||
|
import * as RSSFeed from 'feed'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Feed Controller
|
* Feed Controller
|
||||||
@ -8,9 +9,72 @@ import {FeedPost} from '../../models/FeedPost.model'
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Feed extends Controller {
|
export class Feed extends Controller {
|
||||||
|
@Inject()
|
||||||
|
protected readonly routing!: Routing
|
||||||
|
|
||||||
public async feed(feedPosts: Collection<FeedPost>) {
|
public async feed(feedPosts: Collection<FeedPost>) {
|
||||||
return view('feed', {
|
return view('feed', {
|
||||||
feedPosts: feedPosts.toArray(),
|
feedPosts: feedPosts.toArray(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async rss(feedPosts: Collection<FeedPost>) {
|
||||||
|
const feed = this.getFeed(feedPosts)
|
||||||
|
return plaintext(feed.rss2()).contentType('application/rss+xml; charset=UTF-8')
|
||||||
|
}
|
||||||
|
|
||||||
|
public async atom(feedPosts: Collection<FeedPost>) {
|
||||||
|
const feed = this.getFeed(feedPosts)
|
||||||
|
return plaintext(feed.atom1()).contentType('application/atom+xml; charset=UTF-8')
|
||||||
|
}
|
||||||
|
|
||||||
|
public async json(feedPosts: Collection<FeedPost>) {
|
||||||
|
const feed = this.getFeed(feedPosts)
|
||||||
|
return plaintext(feed.json1()).contentType('application/feed+json; charset=UTF-8')
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getFeed(feedPosts: Collection<FeedPost>): RSSFeed.Feed {
|
||||||
|
const feed = new RSSFeed.Feed({
|
||||||
|
title: 'Garrett Mills',
|
||||||
|
description: 'A sporadic collection of my thoughts, blog posts, and project updates',
|
||||||
|
id: `${this.routing.getAppUrl()}#about`,
|
||||||
|
link: this.routing.getNamedPath('feed').toRemote,
|
||||||
|
language: 'en',
|
||||||
|
image: this.routing.getAssetPath('favicon', 'apple-touch-icon.png').toRemote,
|
||||||
|
favicon: this.routing.getAssetPath('favicon', 'favicon.ico').toRemote,
|
||||||
|
copyright: `Copyright (c) ${(new Date).getFullYear()} Garrett Mills. See website for licensing details.`,
|
||||||
|
updated: feedPosts.whereMax('postedAt').first()?.postedAt,
|
||||||
|
generator: '',
|
||||||
|
feedLinks: {
|
||||||
|
json: this.routing.getNamedPath('feed.json').toRemote,
|
||||||
|
atom: this.routing.getNamedPath('feed.atom').toRemote,
|
||||||
|
rss: this.routing.getNamedPath('feed.rss').toRemote,
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
name: 'Garrett Mills',
|
||||||
|
email: 'shout@garrettmills.dev',
|
||||||
|
link: 'https://garrettmills.dev/#about',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
feed.addCategory('Technology')
|
||||||
|
feed.addCategory('Software Development')
|
||||||
|
|
||||||
|
feedPosts.each(post => {
|
||||||
|
feed.addItem({
|
||||||
|
title: post.tag, // FIXME better title generation
|
||||||
|
date: post.postedAt,
|
||||||
|
id: `${this.routing.getNamedPath('feed')}#${post.feedPostId}`,
|
||||||
|
link: `${this.routing.getNamedPath('feed')}#${post.feedPostId}`,
|
||||||
|
content: post.body,
|
||||||
|
author: [{
|
||||||
|
name: 'Garrett Mills',
|
||||||
|
email: 'shout@garrettmills.dev',
|
||||||
|
link: 'https://garrettmills.dev/#about',
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return feed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Controller, view, Injectable, SecurityContext, Inject, Collection, Config, Routing, file, Application} from '@extollo/lib'
|
import {Controller, view, Injectable, SecurityContext, Inject, Collection, Config, Routing, file, Application, plaintext} from '@extollo/lib'
|
||||||
import {WorkItem} from '../../models/WorkItem.model'
|
import {WorkItem} from '../../models/WorkItem.model'
|
||||||
import {FeedPost} from '../../models/FeedPost.model'
|
import {FeedPost} from '../../models/FeedPost.model'
|
||||||
|
|
||||||
@ -82,4 +82,10 @@ export class Home extends Controller {
|
|||||||
.appPath('resources', 'assets', 'favicon', 'favicon.ico')
|
.appPath('resources', 'assets', 'favicon', 'favicon.ico')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
humans() {
|
||||||
|
return Application.getApplication()
|
||||||
|
.appPath('resources', 'assets', 'humans.txt')
|
||||||
|
.read()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ Route
|
|||||||
.calls<Home>(Home, home => home.welcome)
|
.calls<Home>(Home, home => home.welcome)
|
||||||
.alias('home')
|
.alias('home')
|
||||||
|
|
||||||
|
Route.get('/humans.txt')
|
||||||
|
.calls<Home>(Home, home => home.humans)
|
||||||
|
|
||||||
Route.get('/technical')
|
Route.get('/technical')
|
||||||
.calls<Home>(Home, home => home.technical)
|
.calls<Home>(Home, home => home.technical)
|
||||||
|
|
||||||
@ -25,11 +28,6 @@ Route
|
|||||||
.calls<Home>(Home, home => home.optOut)
|
.calls<Home>(Home, home => home.optOut)
|
||||||
.alias('opt-out')
|
.alias('opt-out')
|
||||||
|
|
||||||
Route.get('/feed')
|
|
||||||
.parameterMiddleware(LoadFeedPosts, {all: true})
|
|
||||||
.calls<Feed>(Feed, feed => feed.feed)
|
|
||||||
.alias('feed')
|
|
||||||
|
|
||||||
Route.get('/snippet/:slug')
|
Route.get('/snippet/:slug')
|
||||||
.parameterMiddleware(LoadSnippet)
|
.parameterMiddleware(LoadSnippet)
|
||||||
.calls<Snippets>(Snippets, snippets => snippets.viewSnippet)
|
.calls<Snippets>(Snippets, snippets => snippets.viewSnippet)
|
||||||
@ -39,6 +37,28 @@ Route
|
|||||||
|
|
||||||
Route.get('/favicon.ico')
|
Route.get('/favicon.ico')
|
||||||
.calls<Home>(Home, home => home.favicon)
|
.calls<Home>(Home, home => home.favicon)
|
||||||
|
|
||||||
|
Route.group('feed', () => {
|
||||||
|
Route.get('/')
|
||||||
|
.parameterMiddleware(LoadFeedPosts, {all: true})
|
||||||
|
.calls<Feed>(Feed, feed => feed.feed)
|
||||||
|
.alias('feed')
|
||||||
|
|
||||||
|
Route.get('/rss.xml')
|
||||||
|
.parameterMiddleware(LoadFeedPosts, {all: true})
|
||||||
|
.calls<Feed>(Feed, feed => feed.rss)
|
||||||
|
.alias('feed.rss')
|
||||||
|
|
||||||
|
Route.get('/atom.xml')
|
||||||
|
.parameterMiddleware(LoadFeedPosts, {all: true})
|
||||||
|
.calls<Feed>(Feed, feed => feed.atom)
|
||||||
|
.alias('feed.atom')
|
||||||
|
|
||||||
|
Route.get('/json.json')
|
||||||
|
.parameterMiddleware(LoadFeedPosts, {all: true})
|
||||||
|
.calls<Feed>(Feed, feed => feed.json)
|
||||||
|
.alias('feed.json')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.pre(SessionAuthMiddleware)
|
.pre(SessionAuthMiddleware)
|
||||||
.pre(PageView)
|
.pre(PageView)
|
||||||
|
16
src/app/resources/assets/humans.txt
Normal file
16
src/app/resources/assets/humans.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/* PEOPLE */
|
||||||
|
Garrett Mills - Developer/Speaker/Designer
|
||||||
|
E-Mail: shout@garrettmills.dev
|
||||||
|
Twitter: @glmdev
|
||||||
|
From: Lawrence, Kansas, USA (Rock Chalk!)
|
||||||
|
|
||||||
|
/* SITE */
|
||||||
|
Updated: 2022-04-05
|
||||||
|
Language: English
|
||||||
|
Doctype: HTML5
|
||||||
|
This site was built with Extollo, a free & libre application framework.
|
||||||
|
Learn more at: https://extollo.garrettmills.dev/
|
||||||
|
Copyright (C) 2022 Garrett Mills. All Rights Reserved.
|
||||||
|
|
||||||
|
/* OTHER */
|
||||||
|
Just a little something for the humans scraping the web... -GM
|
@ -10,6 +10,12 @@ block content
|
|||||||
.fira-p
|
.fira-p
|
||||||
p This page contains a smattering of technical information that I think some people might find interesting, but not enough people for it to be included on the main page.
|
p This page contains a smattering of technical information that I think some people might find interesting, but not enough people for it to be included on the main page.
|
||||||
|
|
||||||
|
h3 Source Code & Licensing
|
||||||
|
a(href='https://creativecommons.org/licenses/by-nc-sa/4.0/' target='_blank' style='margin-top: 15px')
|
||||||
|
img(src=asset('cc-by-nc-sa.png'))
|
||||||
|
p This website, its source code, and its contents are licensed under the terms of the Creative Commons BY-NC-SA 4.0 license. Learn more <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">here</a>.
|
||||||
|
p The source code for this site is available openly under the terms of the aforementioned license. You can view it <a href="https://code.garrettmills.dev/garrettmills/www" target="_blank">here</a>.
|
||||||
|
|
||||||
h3 Framework
|
h3 Framework
|
||||||
p This site is built with Extollo, my free & libre application framework. You can learn more about Extollo <a href="https://extollo.garrettmills.dev" target="_blank">here</a>.
|
p This site is built with Extollo, my free & libre application framework. You can learn more about Extollo <a href="https://extollo.garrettmills.dev" target="_blank">here</a>.
|
||||||
|
|
||||||
|
@ -15,9 +15,10 @@ head
|
|||||||
block style
|
block style
|
||||||
link(rel='stylesheet' href=asset('main.css'))
|
link(rel='stylesheet' href=asset('main.css'))
|
||||||
|
|
||||||
link(rel='author' href='humans.txt')
|
link(rel='author' href='/humans.txt')
|
||||||
link(rel="alternate" href="/feed/atom.xml" title="Garrett Mills - Posts & Updates" type="application/atom+xml")
|
link(rel="alternate" href="/feed/atom.xml" title="Garrett Mills - Posts & Updates" type="application/atom+xml")
|
||||||
link(rel="alternate" href="/feed/rss.xml" title="Garrett Mills - Posts & Updates" type="application/rss+xml")
|
link(rel="alternate" href="/feed/rss.xml" title="Garrett Mills - Posts & Updates" type="application/rss+xml")
|
||||||
|
link(rel="alternate" href="/feed/json.json" title="Garrett Mills - Posts & Updates" type="application/feed+json")
|
||||||
|
|
||||||
link(rel='apple-touch-icon' sizes='180x180' href=asset('favicon/apple-touch-icon.png'))
|
link(rel='apple-touch-icon' sizes='180x180' href=asset('favicon/apple-touch-icon.png'))
|
||||||
link(rel='manifest' href=asset('favicon/site.webmanifest'))
|
link(rel='manifest' href=asset('favicon/site.webmanifest'))
|
||||||
@ -34,8 +35,8 @@ body
|
|||||||
img(src=asset('ffox.png') width="75" style="margin-top: -1px")
|
img(src=asset('ffox.png') width="75" style="margin-top: -1px")
|
||||||
.by-line garrettmills
|
.by-line garrettmills
|
||||||
.copy#tagline(title="my, aren't you curious...") copyright © #{(new Date()).getFullYear()} garrett mills
|
.copy#tagline(title="my, aren't you curious...") copyright © #{(new Date()).getFullYear()} garrett mills
|
||||||
.copyright
|
.copyright(style='display: flex; justify-content: right')
|
||||||
a(href='https://creativecommons.org/licenses/by-nc-sa/4.0/' target='_blank')
|
a(style='display: flex; padding-top: 10px' href='https://creativecommons.org/licenses/by-nc-sa/4.0/' target='_blank')
|
||||||
img(src=asset('cc-by-nc-sa-small.png') title='This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License')
|
img(src=asset('cc-by-nc-sa-small.png') title='This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License')
|
||||||
if false
|
if false
|
||||||
div.auth-container
|
div.auth-container
|
||||||
|
Loading…
Reference in New Issue
Block a user