Add fetcher functions

This commit is contained in:
Yarmo Mackenbach 2021-03-25 14:31:29 +01:00
parent 1db8683886
commit 358b4bbf8f
No known key found for this signature in database
GPG key ID: 37367F4AF4087AD1
6 changed files with 269 additions and 0 deletions

34
src/fetcher/dns.js Normal file
View file

@ -0,0 +1,34 @@
/*
Copyright 2021 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const dns = require('dns')
module.exports = async (hostname) => {
return new Promise((resolve, reject) => {
dns.resolveTxt(hostname, (err, records) => {
if (err) {
reject(err)
return
}
resolve({
hostname: hostname,
records: {
txt: records,
},
})
})
})
}

20
src/fetcher/index.js Normal file
View file

@ -0,0 +1,20 @@
/*
Copyright 2021 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
exports.dns = require('./dns')
exports.irc = require('./irc')
exports.matrix = require('./matrix')
exports.twitter = require('./twitter')
exports.xmpp = require('./xmpp')

47
src/fetcher/irc.js Normal file
View file

@ -0,0 +1,47 @@
/*
Copyright 2021 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const irc = require('irc-upd')
module.exports = async (serverHostname, nickQuery, nickLogin) => {
return new Promise((resolve, reject) => {
try {
const client = new irc.Client(serverHostname, nickLogin, {
port: 6697,
secure: true,
channels: [],
})
const reKey = /[a-zA-Z0-9\-\_]+\s+:\s(openpgp4fpr\:.*)/
const reEnd = /End\sof\s.*\staxonomy./
let keys = []
client.addListener('registered', (message) => {
client.send(`PRIVMSG NickServ :TAXONOMY ${nickQuery}`)
})
client.addListener('notice', (nick, to, text, message) => {
if (reKey.test(text)) {
const match = text.match(reKey)
keys.push(match[1])
}
if (reEnd.test(text)) {
client.disconnect()
resolve(keys)
}
})
} catch (error) {
reject(error)
}
})
}

34
src/fetcher/matrix.js Normal file
View file

@ -0,0 +1,34 @@
/*
Copyright 2021 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const bent = require('bent')
const bentReq = bent('GET')
module.exports = async (roomId, eventId, opts) => {
const url = `https://${opts.instance}/_matrix/client/r0/rooms/${roomId}/event/${eventId}?access_token=${opts.accessToken}`
return bentReq(url, null, {
Accept: 'application/json',
})
.then(async (data) => {
return await data.json()
})
.then((data) => {
return data
})
.catch((error) => {
return error
})
}

37
src/fetcher/twitter.js Normal file
View file

@ -0,0 +1,37 @@
/*
Copyright 2021 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const bent = require('bent')
const bentReq = bent('GET')
module.exports = async (tweetId, bearerToken) => {
return bentReq(
`https://api.twitter.com/1.1/statuses/show.json?id=${tweetId}&tweet_mode=extended`,
null,
{
Accept: 'application/json',
Authorization: `Bearer ${bearerToken}`,
}
)
.then(async (data) => {
return await data.json()
})
.then((data) => {
return data.full_text
})
.catch((error) => {
return error
})
}

97
src/fetcher/xmpp.js Normal file
View file

@ -0,0 +1,97 @@
/*
Copyright 2021 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const jsdom = require('jsdom')
const { client, xml } = require('@xmpp/client')
const debug = require('@xmpp/debug')
let xmpp = null,
iqCaller = null
const xmppStart = async (service, username, password) => {
return new Promise((resolve, reject) => {
const xmpp = client({
service: service,
username: username,
password: password,
})
if (process.env.NODE_ENV !== 'production') {
debug(xmpp, true)
}
const { iqCaller } = xmpp
xmpp.start()
xmpp.on('online', (address) => {
console.log('online', address.toString())
resolve({ xmpp: xmpp, iqCaller: iqCaller })
})
xmpp.on('error', (error) => {
reject(error)
})
})
}
module.exports = async (id, data, opts) => {
return new Promise(async (resolve, reject) => {
if (!xmpp) {
const xmppStartRes = await xmppStart(
opts.service,
opts.username,
opts.password
)
xmpp = xmppStartRes.xmpp
iqCaller = xmppStartRes.iqCaller
}
const response = await iqCaller.request(
xml(
'iq',
{ type: 'get', to: id },
xml('vCard', 'vcard-temp')
),
30 * 1000
)
const vcardRow = response.getChild('vCard', 'vcard-temp').toString()
const dom = new jsdom.JSDOM(vcardRow)
try {
let vcard
switch (data.toLowerCase()) {
case 'desc':
case 'note':
vcard = dom.window.document.querySelector('note text')
if (!vcard) {
vcard = dom.window.document.querySelector('DESC')
}
if (vcard) {
vcard = vcard.textContent
} else {
throw new Error('No DESC or NOTE field found in vCard')
}
break
default:
vcard = dom.window.document.querySelector(data)
.textContent
break
}
xmpp.stop()
resolve(vcard)
} catch (error) {
reject(error)
}
})
}