|
9 months ago | |
---|---|---|
.github/workflows | 2 years ago | |
.yarn/releases | 2 years ago | |
src | 9 months ago | |
test | 9 months ago | |
.gitignore | 1 year ago | |
.yarnrc.yml | 1 year ago | |
README.md | 9 months ago | |
jam-my-stack.sublime-project | 2 years ago | |
jest.config.js | 2 years ago | |
package-lock.json | 2 years ago | |
package.json | 9 months ago | |
yarn.lock | 9 months ago |
README.md
jam-my-stack 🥞
A set of simple IndieWeb Jamstack publishing syndication tools
Published at https://www.npmjs.com/package/jam-my-stack
These simple scripts enrich your Jamstack-site by adding/manipulating/whatever (meta)data, such as extra posts, indexing, and so forth. A primary example of these tools in action is my own site https://brainbaking.com - inspect how it's used at https://github.com/wgroeneveld/brainbaking
Are you looking for a way to receive webmentions? See https://github.com/wgroeneveld/serve-my-jams !
The tools
Usage:
yarn add jam-my-stack
const { mastodon, goodreads } = require('jam-my-stack')
1. Mastodon
1.1 parseFeed
An async function that parses your Fediverse-compatible feed (Mastodon/Pleroma/...) and converts entries to .md
Markdown files for your Jamstack to enjoy.
Usage example:
await mastodon.parseFeed({
notesdir: `${__dirname}/content/notes`,
url: "https://chat.brainbaking.com/users/wouter/feed",
utcOffset: 60,
titleCount: 50,
titlePrefix: "Note: "
})
Options and their default values:
utcOffset
:60
(= GMT+1, that's where I am!) (in minutes, see day.js docstitleCount
:50
. Will add "..." and trim if title length bigger.titlePrefix
:""
. Will add before title (e.g. "Note: ")ignoreReplies
:false
. If true, will not processin-reply-to
items.
Note that this does not delete the notes dir with every call. It simply checks if there isn't already a file with the same name (based on the publication date), and adds one if not.
Example feed entry:
<entry>
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
<id>https://chat.brainbaking.com/objects/77a3ecfb-47e1-4d7a-a24a-8b779d80a8ac</id>
<title>I pulled the Google plug and installed LineageOS: https://brainbaking.com/post/2021/03/getting-ri...</title>
<content type="html">I pulled the Google plug and installed LineageOS: <a href="https://brainbaking.com/post/2021/03/getting-rid-of-tracking-using-lineageos/" rel="ugc">https://brainbaking.com/post/2021/03/getting-rid-of-tracking-using-lineageos/</a> Very impressed so far! Also rely on my own CalDAV server to replace GCalendar. Any others here running <a class="hashtag" data-tag="lineageos" href="https://chat.brainbaking.com/tag/lineageos" rel="tag ugc">#lineageos</a> for privacy reasons?</content>
<published>2021-03-01T19:03:35.273023Z</published>
<updated>2021-03-01T19:03:35.273023Z</updated>
<ostatus:conversation ref="https://chat.brainbaking.com/contexts/ff9aa62e-3357-41ad-951d-15f6ad506424">
https://chat.brainbaking.com/contexts/ff9aa62e-3357-41ad-951d-15f6ad506424
</ostatus:conversation>
<link href="https://chat.brainbaking.com/contexts/ff9aa62e-3357-41ad-951d-15f6ad506424" rel="ostatus:conversation"/>
<summary></summary>
<link type="application/atom+xml" href='https://chat.brainbaking.com/objects/77a3ecfb-47e1-4d7a-a24a-8b779d80a8ac' rel="self"/>
<link type="text/html" href='https://chat.brainbaking.com/objects/77a3ecfb-47e1-4d7a-a24a-8b779d80a8ac' rel="alternate"/>
<category term="lineageos"></category>
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://chat.brainbaking.com/users/wouter"/>
</entry>
This generates the file 01h20m03s35.md
(it assumes UTC times in the feed and adjusts according to specified utcOffset
, such as GMT+1 in this example), with contents:
---
source: "https://chat.brainbaking.com/objects/77a3ecfb-47e1-4d7a-a24a-8b779d80a8ac"
title: "I pulled the Google plug and installed LineageOS: https://brainbaking.com/post/2021/03/getting-ri..."
date: "2021-03-01T19:03:35"
---
I pulled the Google plug and installed LineageOS: <a href="https://brainbaking.com/post/2021/03/getting-rid-of-tracking-using-lineageos/" rel="ugc">https://brainbaking.com/post/2021/03/getting-rid-of-tracking-using-lineageos/</a> Very impressed so far! Also rely on my own CalDAV server to replace GCalendar. Any others here running <a class="hashtag" data-tag="lineageos" href="https://chat.brainbaking.com/tag/lineageos" rel="tag ugc">#lineageos</a> for privacy reasons?
See implementation for more details and features.
Also parsers:
<link rel="enclosure"/>
image types (seerender-enclosures.ejs
) ejs template, that is appended to the Markdown file if any are found. Styling is up to you...... @https://blah.com/blie hi there
- this is a in-reply-to toot which addscontext
frontmatter, so your html renderer can use the correct IndieWeb classes. This should also enable webmention sending since you mention the URL. If you "at" a valid Mastodon user, it will automatically do this.
2. Goodreads
2.1 createWidget
An async function that reads and modifies Goodreads JS widget embed code, converting low-res book covers to hi-res ones if possible. This omits possible Goodread cookies and cross-domain mishaps.
Usage example:
const widget = await goodreads.createWidget("https://www.goodreads.com/review/grid_widget/5451893.Wouter's%20bookshelf:%20read?cover_size=medium&hide_link=&hide_title=&num_books=12&order=d&shelf=read&sort=date_added&widget_id=1496758344")
await fsp.writeFile(`${__dirname}/static/js/goodreads.js`, widget, 'utf-8')
3. Lunr
As of version 1.0.30
, Lunr functionality was removed in favor of https://pagefind.app/
With Pagefind, there's no need to integrate it into jam-my-stack, greatly simplifying things and reducing the index file size.
4. Howlongtobeat
4.1 howlong
Adds https://howlongtobeat.com/ game length (MainGame
) and an ID to your front matter (keys howlongtobeat_id
and howlongtobeat_hrs
), provided you first added a property called game_name
. (This gets substituted).
It also downloads a thumbnail of the cover image if you provided the dir as an option. The downloaded thumbnail is automatically optimized for the web using mogrify
(this will emit a warning if you do not have ImageMagick installed locally).
So, Frontmatter like this:
---
title: Diablo 3 my Review
game_name: Diablo 3
---
Gets subsituted by something like this:
---
title: Diablo 3 my Review
howlongtobeat_id: 62129
howlongtobeat_hrs: 20.5
---
In your Hugo template, add a link to https://howlongtobeat.com/game?id={howlongtobeat_id}
and you're all set!
Usage example:
await howlong({
postDir: `${__dirname}/content/articles`,
downloadDir: `${__dirname}/static/img/howlongtobeat_thumbs`)
It will print out games and metadata it found.
Working example: https://jefklakscodex.com/articles/reviews/diablo-3/ (on the left side). Check out the Hugo template to use the properties at https://github.com/wgroeneveld/jefklakscodex .
5. Webmentions
In cooperation with https://github.com/wgroeneveld/go-jamming
5.1 getWebmentions
Calls the get webmention endpoint, sorts by date, adds metadata such as relative date (relativeTarget
, property), and returns data. Could be written in a data
folder for Hugo to parse, for example.
Parameters: first domain
, second the config for the endpoint and token. Usage example:
await getWebmentions("brainbaking.com", {
endpoint: 'https://jam.brainbaking.com',
token: 'lol'
})
5.1 send
Calls the set webmention endpoint using a PUT
. Based on the RSS feed, see the go-jamming README.
Same as getWebmentions
.
6. YouTube
Thanks to ideas from rubenerd.com and his video.sh script. This downloads a thumbnail using youtube-dl
, smacks a play button on it using convert
, and stores that in the specified folder. Use in conjunction with a Hugo shortcode to get rid of YouTube's iframes!
This method will fail if you do not have ImageMagick installed locally.
Usage example:
await download({
postDir: 'somewhere/posts',
downloadDir: 'static/youtube-thumbs',
overlayImg: 'playbtn.png'
})
It scans all .md
files in the posts dir for {{< youtube xxx >}}
shortcodes.