]>
Commit | Line | Data |
---|---|---|
89326417 RBR |
1 | const { exec } = require('child_process'); |
2 | const { resolve, join} = require('path'); | |
3 | const { rm, writeFile } = require('fs/promises'); | |
2390d230 | 4 | const { promisify } = require('util'); |
89326417 RBR |
5 | |
6 | const internals = { | |
7 | exec: promisify(exec), | |
2390d230 | 8 | |
fdb5251c RBR |
9 | apiUrl: process.env.API_URL, |
10 | apiToken: process.env.API_TOKEN, | |
2390d230 RBR |
11 | blogUrl: process.env.BLOG_URL, |
12 | archiveUrl: process.env.ARCHIVE_URL, | |
9d9552d1 RBR |
13 | blogPublicUrl: process.env.BLOG_PUBLIC_URL, |
14 | archivePublicUrl: process.env.ARCHIVE_PUBLIC_URL, | |
278296c2 | 15 | tootToken: process.env.TOOT_TOKEN, |
9d9552d1 | 16 | mastodonDomain: process.env.MASTODON_DOMAIN, |
2390d230 | 17 | |
89326417 RBR |
18 | date: (new Date()).toISOString().split('T')[0], |
19 | ||
f0b2faff | 20 | generateGemtext(title, text) { |
89326417 | 21 | |
f0b2faff RBR |
22 | return `# ${title}\n\n${text}`; |
23 | }, | |
89326417 | 24 | |
f0b2faff RBR |
25 | getText(posts) { |
26 | ||
278296c2 | 27 | return posts.map((post) => { |
f0b2faff | 28 | |
fdb5251c | 29 | return `=> ${post.url} ${post.title}\n${post.notes}`; |
89326417 | 30 | }).join('\n\n'); |
f0b2faff RBR |
31 | }, |
32 | ||
33 | getTitle(posts) { | |
89326417 | 34 | |
f0b2faff | 35 | if (posts.length === 1) { |
fdb5251c | 36 | return `Link: ${posts[0].title}`; |
f0b2faff RBR |
37 | } |
38 | return `${posts.length} links for ${internals.date}`; | |
39 | }, | |
40 | ||
41 | slugify(text) { | |
42 | ||
43 | return text.toLowerCase().replace(/[^a-z0-9 ]/g, '').replace(/ +/g, '-') | |
278296c2 RBR |
44 | }, |
45 | ||
46 | async toot(title) { | |
47 | ||
48 | const body = new FormData(); | |
49 | body.set( | |
50 | 'status', | |
9d9552d1 | 51 | `New post: ${title}\n\nAvailable on:\n\nāļø the gemini archive ${internals.archivePublicUrl}\n\n or, the ephemeral blog š: ${internals.blogPublicUrl}` |
278296c2 | 52 | ); |
9d9552d1 | 53 | return fetch(`https://${internals.mastodonDomain}/api/v1/statuses`, { |
fdb5251c | 54 | method: 'POST', |
278296c2 RBR |
55 | headers: { |
56 | Authorization: `Bearer ${internals.tootToken}`, | |
57 | }, | |
58 | body | |
59 | }); | |
fdb5251c RBR |
60 | }, |
61 | ||
62 | async getBookmarks() { | |
63 | ||
64 | const url = join(internals.apiUrl, 'bookmarks') + '?q=%23linkblog'; | |
65 | const response = await fetch(url, { | |
66 | headers: { | |
67 | 'Content-Type': 'application/json', | |
68 | Authorization: `Token ${internals.apiToken}` | |
69 | } | |
70 | }); | |
71 | const data = await response.json(); | |
72 | ||
73 | return data.results; | |
74 | }, | |
278296c2 | 75 | |
fdb5251c RBR |
76 | async updateBookmark(bookmark) { |
77 | ||
78 | console.log(bookmark.tag_names); | |
79 | console.log(bookmark.tag_names.map((tag) => tag === 'linkblog' ? 'linkblog-posted' : tag)); | |
80 | ||
81 | const url = join(internals.apiUrl, 'bookmarks', `${bookmark.id}`) | |
82 | const response = await fetch(url, { | |
83 | method: 'PATCH', | |
84 | body: JSON.stringify( | |
85 | { | |
86 | tag_names: bookmark.tag_names.map((tag) => tag === 'linkblog' ? 'linkblog-posted' : tag) | |
87 | } | |
88 | ), | |
89 | headers: { | |
90 | 'Content-Type': 'application/json', | |
91 | Authorization: `Token ${internals.apiToken}` | |
92 | } | |
93 | }); | |
94 | ||
95 | const data = await response.text(); | |
96 | console.log(url); | |
97 | console.log(data); | |
98 | } | |
89326417 RBR |
99 | }; |
100 | ||
101 | ||
102 | async function run() { | |
fdb5251c | 103 | const bookmarks = await internals.getBookmarks(); |
89326417 | 104 | |
fdb5251c | 105 | if (bookmarks.length === 0) { |
89326417 RBR |
106 | console.error('No links to post'); |
107 | return; | |
108 | } | |
109 | ||
fdb5251c RBR |
110 | const title = internals.getTitle(bookmarks); |
111 | const text = internals.getText(bookmarks); | |
f0b2faff RBR |
112 | const gemtext = internals.generateGemtext(title, text); |
113 | const filename = internals.slugify(title); | |
114 | ||
115 | const gemfile = resolve(join(__dirname, `${filename}.gmi`)); | |
89326417 | 116 | await writeFile(gemfile, gemtext); |
70dc59db RBR |
117 | await internals.exec(`blog add ${gemfile}`); |
118 | await internals.exec(`blog publish ${internals.blogUrl}`); | |
119 | await internals.exec(`blog publish-archive ${internals.archiveUrl}`); | |
89326417 RBR |
120 | await rm(gemfile); |
121 | ||
fdb5251c RBR |
122 | for (const bookmark of bookmarks) { |
123 | await internals.updateBookmark(bookmark); | |
89326417 | 124 | } |
278296c2 RBR |
125 | |
126 | if (internals.tootToken) { | |
127 | await internals.toot(title); | |
128 | } | |
89326417 RBR |
129 | } |
130 | ||
131 | run() | |
132 | .then(() => process.exit(0)) | |
133 | .catch((err) => { | |
134 | console.error(err); | |
135 | process.exit(1); | |
136 | }) |