rough work of tooting and ac buddy done

This commit is contained in:
Wouter Groeneveld 2021-03-30 15:55:01 +02:00
parent 617d6ea556
commit e4c2aaf260
10 changed files with 645 additions and 412 deletions

2
.gitignore vendored
View File

@ -3,6 +3,8 @@
data/ac/*.png
src/config.js
.yarn/*
!.yarn/patches
!.yarn/plugins

44
.pnp.js generated
View File

@ -37,6 +37,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
[null, {
"packageLocation": "./",
"packageDependencies": [
["axios", "npm:0.21.1"],
["form-data", "npm:4.0.0"],
["got", "npm:11.8.2"],
["jest", "npm:26.6.3"],
["jsdom", "virtual:defa486869c88441047200a53b3aa18d79743b272095f3ee31b5b7b80b2c93d87f722added867470dcb94104504489a1a89040ea8fd89dffb9cfb1864d4bf54e#npm:16.5.2"],
@ -1340,6 +1342,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD",
}]
]],
["axios", [
["npm:0.21.1", {
"packageLocation": "./.yarn/cache/axios-npm-0.21.1-d192f6b3b3-864fb7b5d0.zip/node_modules/axios/",
"packageDependencies": [
["axios", "npm:0.21.1"],
["follow-redirects", "virtual:d192f6b3b31cd5d11a443145a3883a70c04cbd7c813c53085dbaf50263735f1162f10fdbddd53c24e162ec3bc37b90966413084323739b7cf942b8bfb4da8831#npm:1.13.3"]
],
"linkType": "HARD",
}]
]],
["babel-jest", [
["npm:26.6.3", {
"packageLocation": "./.yarn/cache/babel-jest-npm-26.6.3-5630fee2b8-89231d00e6.zip/node_modules/babel-jest/",
@ -2513,6 +2525,26 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD",
}]
]],
["follow-redirects", [
["npm:1.13.3", {
"packageLocation": "./.yarn/cache/follow-redirects-npm-1.13.3-bc35dfad3e-9ad74c3b66.zip/node_modules/follow-redirects/",
"packageDependencies": [
["follow-redirects", "npm:1.13.3"]
],
"linkType": "SOFT",
}],
["virtual:d192f6b3b31cd5d11a443145a3883a70c04cbd7c813c53085dbaf50263735f1162f10fdbddd53c24e162ec3bc37b90966413084323739b7cf942b8bfb4da8831#npm:1.13.3", {
"packageLocation": "./.yarn/$$virtual/follow-redirects-virtual-355f55dffb/0/cache/follow-redirects-npm-1.13.3-bc35dfad3e-9ad74c3b66.zip/node_modules/follow-redirects/",
"packageDependencies": [
["follow-redirects", "virtual:d192f6b3b31cd5d11a443145a3883a70c04cbd7c813c53085dbaf50263735f1162f10fdbddd53c24e162ec3bc37b90966413084323739b7cf942b8bfb4da8831#npm:1.13.3"],
["debug", null]
],
"packagePeers": [
"debug"
],
"linkType": "HARD",
}]
]],
["for-in", [
["npm:1.0.2", {
"packageLocation": "./.yarn/cache/for-in-npm-1.0.2-37e3d7aae5-e8d7280a65.zip/node_modules/for-in/",
@ -2541,6 +2573,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["mime-types", "npm:2.1.29"]
],
"linkType": "HARD",
}],
["npm:4.0.0", {
"packageLocation": "./.yarn/cache/form-data-npm-4.0.0-916facec2d-ecbe8f41bc.zip/node_modules/form-data/",
"packageDependencies": [
["form-data", "npm:4.0.0"],
["asynckit", "npm:0.4.0"],
["combined-stream", "npm:1.0.8"],
["mime-types", "npm:2.1.29"]
],
"linkType": "HARD",
}]
]],
["fragment-cache", [
@ -4707,6 +4749,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"packageLocation": "./",
"packageDependencies": [
["plerobuddies", "workspace:."],
["axios", "npm:0.21.1"],
["form-data", "npm:4.0.0"],
["got", "npm:11.8.2"],
["jest", "npm:26.6.3"],
["jsdom", "virtual:defa486869c88441047200a53b3aa18d79743b272095f3ee31b5b7b80b2c93d87f722added867470dcb94104504489a1a89040ea8fd89dffb9cfb1864d4bf54e#npm:16.5.2"],

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,8 @@
"jest": "^26.6.3"
},
"dependencies": {
"axios": "^0.21.1",
"form-data": "^4.0.0",
"got": "^11.8.2",
"jsdom": "^16.5.2",
"md5": "^2.3.0"

View File

@ -0,0 +1,34 @@
const { collect } = require('./collector')
const md5 = require('md5')
async function chat() {
/* format:
{
"href": "/wiki/Admiral",
"name": "Admiral",
"birthday": "January 27<sup>th</sup>\n",
"img": "https://static.wikia.nocookie.net/animalcrossing/images/5/52/NH-Admiral_poster.png/revision/latest?cb=20200522013249",
"quotes": [
"Only quitters give up."
]
}
*/
const animaldb = await collect()
const possibleToots = animaldb.animals.map(record => {
return record.quotes.map(quote => {
const birthday = record.birthday.replace(/\n/g, "")
return {
"toot": `${record.name}: "${quote}"\n\n${birthday} is my birthday.\nhttps://animalcrossing.fandom.com${record.href}`,
"attach": `data/ac/${md5(record.img)}.png`,
"attachDescription": `Screenshot of Animal Crossing villager ${record.name}`
}
})
}).flat()
return possibleToots[Math.floor(Math.random() * possibleToots.length)]
}
module.exports = {
chat
}

View File

@ -41,33 +41,37 @@ async function discoverQuotes(animal) {
return itm
.replace("</i>", "")
.replace(/<a href=.*>(.*)<\/a>/g, "$1")
.replace(/<sup>(.*)<\/sup>/g, "$1")
.replace("<span style=\"font-family:Copper Black; color:#9e6700; font-size:18px\"><b>“<\/b><\/span><i>", "")
})
}
async function collect() {
const shouldICollect = existsSync('data/ac/animals.json')
if(shouldICollect) {
console.log(' AC buddy: already collected, returning data. ')
const animals = await fsp.readFile('data/ac/animals.json')
return JSON.parse(animals)
}
console.log(' AC buddy: no data detected, fetching... ')
const animals = await discoverAnimals()
const shouldIDownloadQuotes = existsSync('data/ac/animals.json')
for await(animal of animals) {
const fileName = `data/ac/${md5(animal.img)}.png`
if(!existsSync(fileName)) {
await pipeline(got.stream(animal.img), createWriteStream(fileName))
console.log(`${animal.name} avatar downloaded.`)
console.log(` AC buddy: ${animal.name} avatar downloaded.`)
}
if(!shouldIDownloadQuotes) {
const quotes = await discoverQuotes(animal)
animal.quotes = quotes
console.log(`${animal.name} quotes downloaded (${quotes}).`)
}
const quotes = await discoverQuotes(animal)
animal.quotes = quotes
console.log(` AC buddy: ${animal.name} quotes downloaded (${quotes}).`)
}
if(!shouldIDownloadQuotes) {
await fsp.writeFile('data/ac/animals.json', JSON.stringify({ animals }, null, 2))
console.log('Okay, animals.json written!')
}
await fsp.writeFile('data/ac/animals.json', JSON.stringify({ animals }, null, 2))
console.log(' AC buddy: Okay, animals.json written!')
return animals
}
@ -75,4 +79,4 @@ async function collect() {
module.exports = {
collect
}
}

View File

@ -1,6 +1,22 @@
// the main juice
const acbuddy = require('./buddies/animalcrossing/collector')
const { buddies } = require('./config')
if(!buddies) throw "Did you seutp your config?"
const { toot } = require('./toot');
(async function() {
for await(buddy of buddies) {
const { chat } = require(`./buddies/${buddy}/buddy`)
// contains 'toot', and maybe 'attach' / 'attachDescription'
const message = await chat()
console.log(`buddy ${buddy} has this to say: ${JSON.stringify(message)}`)
await toot(message)
}
console.log('Done! for now... ')
})()
acbuddy.collect()

48
src/registerApp.js Normal file
View File

@ -0,0 +1,48 @@
const axios = require('axios')
const instance = 'https://chat.brainbaking.com'
const clientName = "plerobuddies"
// Fill these in after register() ed. calls
const clientId = ""
const clientSecret = ""
const approvalCode = ""
async function register() {
const raw = await axios.post(`${instance}/api/v1/apps`, {
client_name: clientName,
redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
scopes: "read write"
}
)
console.log(raw.data)
console.log(`${instance}/oauth/authorize?redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&client_id=${clientId}&scope=read%20write`)
}
async function fetchToken() {
const raw = await axios.post(`${instance}/oauth/token`, {
client_id: clientId,
client_secret: clientSecret,
redirect_uri: "urn:ietf:wg:oauth:2.0:oob",
scopes: "read write",
grant_type: "authorization_code",
code: approvalCode
}
)
console.log(raw.data)
console.log(raw.data.access_token)
}
(async function() {
try {
await fetchToken()
} catch(err) {
console.log(err.message)
console.log(err.response?.data)
}
})()

51
src/toot.js Normal file
View File

@ -0,0 +1,51 @@
const axios = require('axios')
const FormData = require('form-data')
const { createReadStream } = require('fs')
const { instance, oauthToken } = require('./config')
async function toot(data) {
// contains 'toot', and maybe 'attach' / 'attachDescription'
const media_ids = []
if(data.attach) {
const id = await uploadMedia(data.attach, data.attachDescription)
media_ids.push(id)
}
// https://docs.joinmastodon.org/methods/statuses/
const result = await axios.post(`${instance}/api/v1/statuses`, {
status: data.toot,
media_ids: media_ids,
}, {
headers: {
"Authorization": `Bearer ${oauthToken}`
}
})
console.log(` toot: status result: ${result.status}`)
}
async function uploadMedia(fileName, description) {
const formData = new FormData()
formData.append('file', createReadStream(fileName))
formData.append('description', description)
// https://docs.joinmastodon.org/methods/statuses/media/
const result = await axios.post(`${instance}/api/v1/media`, formData, {
headers: {
"Content-Type": `multipart/form-data; boundary=${formData.getBoundary()}`,
"Authorization": `Bearer ${oauthToken}`
}
});
if(result.status !== 200) {
throw "something went wrong with " + result.data
}
console.log(` toot: media result: ${result.status} - media id: ${result.data.id}`)
return result.data.id
}
module.exports = {
toot
}

View File

@ -1044,6 +1044,15 @@ __metadata:
languageName: node
linkType: hard
"axios@npm:^0.21.1":
version: 0.21.1
resolution: "axios@npm:0.21.1"
dependencies:
follow-redirects: ^1.10.0
checksum: 864fb7b5d077d236737f10adca53bf451a93f35a15271f56fba8da07265a02d26b7d881b935a6697dc6adb0549ea3e56d2eecb403edaa3bb78f6479901c10f69
languageName: node
linkType: hard
"babel-jest@npm:^26.6.3":
version: 26.6.3
resolution: "babel-jest@npm:26.6.3"
@ -1468,7 +1477,7 @@ __metadata:
languageName: node
linkType: hard
"combined-stream@npm:^1.0.6, combined-stream@npm:~1.0.6":
"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8, combined-stream@npm:~1.0.6":
version: 1.0.8
resolution: "combined-stream@npm:1.0.8"
dependencies:
@ -2044,6 +2053,16 @@ __metadata:
languageName: node
linkType: hard
"follow-redirects@npm:^1.10.0":
version: 1.13.3
resolution: "follow-redirects@npm:1.13.3"
peerDependenciesMeta:
debug:
optional: true
checksum: 9ad74c3b66ad5c32d8c009a2afb4e5c1b9e5dbe1f631419296c21f8e4f9976ed2c52f9a676c4acdd1d7f41a8f17a03dfaa3704993b25b5965eb11bc9dc9a8ef5
languageName: node
linkType: hard
"for-in@npm:^1.0.2":
version: 1.0.2
resolution: "for-in@npm:1.0.2"
@ -2058,6 +2077,17 @@ __metadata:
languageName: node
linkType: hard
"form-data@npm:^4.0.0":
version: 4.0.0
resolution: "form-data@npm:4.0.0"
dependencies:
asynckit: ^0.4.0
combined-stream: ^1.0.8
mime-types: ^2.1.12
checksum: ecbe8f41bcf5c415f38e39058b34598a9261bb74a3d54b633d0b5dd8b7cf9a30b0626cd06ae8e79874a2ca88c222041142a7893e5afdd35fdfc3272264d03d44
languageName: node
linkType: hard
"form-data@npm:~2.3.2":
version: 2.3.3
resolution: "form-data@npm:2.3.3"
@ -4004,6 +4034,8 @@ fsevents@^2.1.2:
version: 0.0.0-use.local
resolution: "plerobuddies@workspace:."
dependencies:
axios: ^0.21.1
form-data: ^4.0.0
got: ^11.8.2
jest: ^26.6.3
jsdom: ^16.5.2