A set of simple IndieWeb Jamstack publishing syndication tools
Go to file
Wouter Groeneveld 7bdd377b43 remove publishedFromNow, its static so useless! 2021-03-25 20:57:49 +01:00
.github/workflows Create main.yml 2021-03-05 11:28:01 +01:00
.yarn/releases disable yarn cache uploads; 1.0.3: howlongtobeat 2021-03-05 14:08:10 +01:00
src remove publishedFromNow, its static so useless! 2021-03-25 20:57:49 +01:00
test remove publishedFromNow, its static so useless! 2021-03-25 20:57:49 +01:00
.gitignore disable yarn cache uploads; 1.0.3: howlongtobeat 2021-03-05 14:08:10 +01:00
.pnp.js implement image enclosure parsing 2021-03-14 21:21:47 +01:00
.yarnrc.yml move masto-feed-parser out of brainbaking repo, first jest tests 2021-03-04 19:01:25 +01:00
README.md add the option ignoreReplies 2021-03-20 13:11:22 +01:00
jam-my-stack.sublime-project move masto-feed-parser out of brainbaking repo, first jest tests 2021-03-04 19:01:25 +01:00
jest.config.js use moment.js insted of parsing dates yourself... 2021-03-05 16:55:32 +01:00
package-lock.json move masto-feed-parser out of brainbaking repo, first jest tests 2021-03-04 19:01:25 +01:00
package.json add the option ignoreReplies - now for real 2021-03-20 13:18:24 +01:00
yarn.lock implement image enclosure parsing 2021-03-14 21:21:47 +01:00

README.md

jam-my-stack 🥞

A set of simple IndieWeb Jamstack publishing syndication tools

Published at https://www.npmjs.com/package/jam-my-stack

npm version

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:

  1. yarn add jam-my-stack
  2. const { mastodon, goodreads, lunr } = 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 docs
  • titleCount: 50. Will add "..." and trim if title length bigger.
  • titlePrefix: "". Will add before title (e.g. "Note: ")
  • ignoreReplies: false. If true, will not process in-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: &lt;a href=&quot;https://brainbaking.com/post/2021/03/getting-rid-of-tracking-using-lineageos/&quot; rel=&quot;ugc&quot;&gt;https://brainbaking.com/post/2021/03/getting-rid-of-tracking-using-lineageos/&lt;/a&gt; Very impressed so far! Also rely on my own CalDAV server to replace GCalendar. Any others here running &lt;a class=&quot;hashtag&quot; data-tag=&quot;lineageos&quot; href=&quot;https://chat.brainbaking.com/tag/lineageos&quot; rel=&quot;tag ugc&quot;&gt;#lineageos&lt;/a&gt; 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"
context: ""
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 (see render-enclosures.ejs) ejs template, that is appended to the Markdown file if any are found. Styling is up to you...

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

3.1 buildIndex

An async function that reads all .md files of certain locations (pass as an array []), generating a Lunr.js .json index object. Serialize it yourself wherever you'd like it to go.

Usage example:

    const index = await lunr.buildIndex([
        `${__dirname}/content/post`,
        `${__dirname}/content/notes`])
    await fsp.writeFile(`${__dirname}/static/js/brainbaking-post.json`, JSON.stringify(index), 'utf-8')

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).

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(`${__dirname}/content/articles`)

It will print out games and metadata it found. Uses the cool howlongtobeat npm package to do its dirty work.

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/serve-my-jams

5.1 getWebmentions

Calls the get webmention endpoint, sorts by date, adds metadata such as relative date (x days ago, property publishedFromNow), and returns data. Could be written in a data folder for Hugo to parse, for example.

Parameters: just one, the domain.

5.1 send

Calls the set webmention endpoint using a PUT. Based on the RSS feed located at /index.xml, see the serve-my-jams README.

Parameters: just two:

  1. domain (see 5.1)
  2. configfile location where an ISO-formatted datetime property is kept.