From 49a26ae896678dc2bddc9002f8fa1e99eb19c56c Mon Sep 17 00:00:00 2001 From: notofoe <43095406+notofoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 00:37:54 +0800 Subject: [PATCH 1/7] fix: mastodon reblog media --- lib/routes/mastodon/utils.js | 41 +++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/lib/routes/mastodon/utils.js b/lib/routes/mastodon/utils.js index 9fb46ddc5..1c81e6da7 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -2,36 +2,39 @@ const ProcessFeed = (data) => data.map((item) => { const content = item.content ? item.content - .replace(/|<\/span.*?>/gm, '') - .replace(/<(?:.|\n)*?>/gm, '\n') - .split('\n') - .filter((s) => s !== '')[0] + .replace(/|<\/span.*?>/gm, '') + .replace(/<(?:.|\n)*?>/gm, '\n') + .split('\n') + .filter((s) => s !== '')[0] : ''; - const media = item.media_attachments - .map((item) => { - switch (item.type) { - case 'gifv': - return `
`; - case 'video': - return `
`; - case 'image': - return `
`; - default: - return ''; - } - }) - .join(''); + const mediaParse = (media_attachments) => + media_attachments + .map((item) => { + switch (item.type) { + case 'gifv': + return `
`; + case 'video': + return `
`; + case 'image': + return `
`; + default: + return ''; + } + }) + .join(''); - let author, link, titleAuthor; + let author, link, titleAuthor, media; if (item.reblog !== null) { author = `${item.reblog.account.display_name} (@${item.reblog.account.acct})`; link = item.reblog.url; titleAuthor = `Re @${item.reblog.account.username}`; + media = mediaParse(item.reblog.media_attachments); } else { author = `${item.account.display_name} (@${item.account.acct})`; link = item.url; titleAuthor = `@${item.account.username}`; + media = mediaParse(item.media_attachments); } const titleText = item.sentitive === true ? `(CW) ${item.spoiler_text}` : content; From 771df7bd4c042d39042e86fd189e3b63e3d5b8e2 Mon Sep 17 00:00:00 2001 From: notofoe <43095406+notofoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 01:04:33 +0800 Subject: [PATCH 2/7] fix: mastodon rm html filter --- lib/routes/mastodon/utils.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/routes/mastodon/utils.js b/lib/routes/mastodon/utils.js index 1c81e6da7..1578c5137 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -1,12 +1,6 @@ const ProcessFeed = (data) => data.map((item) => { - const content = item.content - ? item.content - .replace(/|<\/span.*?>/gm, '') - .replace(/<(?:.|\n)*?>/gm, '\n') - .split('\n') - .filter((s) => s !== '')[0] - : ''; + const content = item.content ? item.content.replace(/|<\/span.*?>/gm, '') : ''; const mediaParse = (media_attachments) => media_attachments From 7677205172b44f6f361f59ecb8781017c56b60e8 Mon Sep 17 00:00:00 2001 From: notofoe <43095406+notofoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 17:06:14 +0800 Subject: [PATCH 3/7] refactor: mastodon extract & rename function --- lib/routes/mastodon/account_id.js | 28 ++--------- lib/routes/mastodon/acct.js | 77 ++--------------------------- lib/routes/mastodon/timeline.js | 2 +- lib/routes/mastodon/utils.js | 82 ++++++++++++++++++++++++++++++- 4 files changed, 88 insertions(+), 101 deletions(-) diff --git a/lib/routes/mastodon/account_id.js b/lib/routes/mastodon/account_id.js index 32d1bbaa5..84f9a5ff2 100644 --- a/lib/routes/mastodon/account_id.js +++ b/lib/routes/mastodon/account_id.js @@ -1,39 +1,17 @@ -const got = require('@/utils/got'); const utils = require('./utils'); module.exports = async (ctx) => { const site = ctx.params.site; const account_id = ctx.params.account_id; - const only_media = ctx.params.only_media ? true : false; + const only_media = ctx.params.only_media ? 'true' : 'false'; - const statuses_url = `http://${site}/api/v1/accounts/${account_id}/statuses`; - const statuses_response = await got({ - method: 'get', - url: statuses_url, - }); - let data = statuses_response.data; - - let account_data; - if (data.length !== 0 && data[0].account !== null) { - account_data = data[0].account; - } else { - const account_url = `http://${site}/api/v1/accounts/${account_id}`; - const account_response = await got({ - method: 'get', - url: account_url, - }); - account_data = account_response.data; - } - - if (only_media === true) { - data = data.filter((item) => item.media_attachments.length !== 0); - } + const { account_data, data } = await utils.getAccountStatuses(site, account_id, only_media); ctx.state.data = { title: `${account_data.display_name} (@${account_data.acct})`, link: `${account_data.url}`, description: `${account_data.note}`, - item: utils.ProcessFeed(data), + item: utils.parseStatuses(data), allowEmpty: true, }; }; diff --git a/lib/routes/mastodon/acct.js b/lib/routes/mastodon/acct.js index 7290e3eb6..92384c500 100644 --- a/lib/routes/mastodon/acct.js +++ b/lib/routes/mastodon/acct.js @@ -1,87 +1,18 @@ -const got = require('@/utils/got'); const utils = require('./utils'); -const config = require('@/config').value; -const mastodonConfig = config.mastodon; module.exports = async (ctx) => { - const getAccountIdByAcct = async (acct) => { - if (!(mastodonConfig.apiHost && mastodonConfig.accessToken && mastodonConfig.acctDomain)) { - throw 'this route require api configuration, please check documentation'; - } - - const site = mastodonConfig.apiHost; - - const search_url = `http://${site}/api/v2/search`; - const cacheUid = `mastodon_acct_id/${site}/${acct}`; - - return await ctx.cache.tryGet(cacheUid, async () => { - const search_response = await got({ - method: 'get', - url: search_url, - headers: { - Authorization: `Bearer ${mastodonConfig.accessToken}`, - }, - searchParams: { - q: acct, - type: 'accounts', - }, - }); - const [acctUser, acctHost] = acct.split('@').filter((e) => e); - let acctOnServer; - - if (acctHost) { - if (acctHost === mastodonConfig.acctDomain) { - acctOnServer = acctUser; - } else { - acctOnServer = acctUser + '@' + acctHost; - } - } else { - acctOnServer = acctUser; - } - - const accountData = search_response.data.accounts.filter((item) => item.acct === acctOnServer); - - if (accountData.length === 0) { - throw `acct ${acct} not found`; - } - return accountData[0].id; - }); - }; - const acct = ctx.params.acct; - const only_media = ctx.params.only_media ? true : false; + const only_media = ctx.params.only_media ? 'true' : 'false'; - const site = mastodonConfig.apiHost; - const account_id = await getAccountIdByAcct(acct); + const { site, account_id } = await utils.getAccountIdByAcct(acct, ctx); - const statuses_url = `http://${site}/api/v1/accounts/${account_id}/statuses`; - const statuses_response = await got({ - method: 'get', - url: statuses_url, - }); - let data = statuses_response.data; - - let account_data; - if (data.length !== 0 && data[0].account !== null) { - account_data = data[0].account; - } else { - const account_url = `http://${site}/api/v1/accounts/${account_id}`; - const account_response = await got({ - method: 'get', - url: account_url, - }); - account_data = account_response.data; - } - - if (only_media === true) { - data = data.filter((item) => item.media_attachments.length !== 0); - } + const { account_data, data } = await utils.getAccountStatuses(site, account_id, only_media); ctx.state.data = { title: `${account_data.display_name} (@${account_data.acct})`, link: `${account_data.url}`, description: `${account_data.note}`, - item: utils.ProcessFeed(data), + item: utils.parseStatuses(data), allowEmpty: true, }; }; diff --git a/lib/routes/mastodon/timeline.js b/lib/routes/mastodon/timeline.js index 75c42c799..f22fbae15 100644 --- a/lib/routes/mastodon/timeline.js +++ b/lib/routes/mastodon/timeline.js @@ -13,6 +13,6 @@ module.exports = async (ctx) => { ctx.state.data = { title: `Local Public${ctx.params.only_media ? ' Media' : ''} Timeline on ${site}`, link: `http://${site}`, - item: utils.ProcessFeed(list), + item: utils.parseStatuses(list), }; }; diff --git a/lib/routes/mastodon/utils.js b/lib/routes/mastodon/utils.js index 1578c5137..475d9f49d 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -1,4 +1,6 @@ -const ProcessFeed = (data) => +const got = require('@/utils/got'); + +const parseStatuses = (data) => data.map((item) => { const content = item.content ? item.content.replace(/|<\/span.*?>/gm, '') : ''; @@ -42,6 +44,82 @@ const ProcessFeed = (data) => }; }); +async function getAccountStatuses(site, account_id, only_media) { + const statuses_url = `http://${site}/api/v1/accounts/${account_id}/statuses?only_media=${only_media}`; + const statuses_response = await got({ + method: 'get', + url: statuses_url, + }); + let data = statuses_response.data; + + let account_data; + if (data.length !== 0 && data[0].account !== null) { + account_data = data[0].account; + } else { + const account_url = `http://${site}/api/v1/accounts/${account_id}`; + const account_response = await got({ + method: 'get', + url: account_url, + }); + account_data = account_response.data; + } + + if (only_media === true) { + data = data.filter((item) => item.media_attachments.length !== 0); + } + return { account_data, data }; +} + +async function getAccountIdByAcct(acct, ctx) { + const config = require('@/config').value; + const mastodonConfig = config.mastodon; + + if (!(mastodonConfig.apiHost && mastodonConfig.accessToken && mastodonConfig.acctDomain)) { + throw 'this route require api configuration, please check documentation'; + } + + const site = mastodonConfig.apiHost; + + const search_url = `http://${site}/api/v2/search`; + const cacheUid = `mastodon_acct_id/${site}/${acct}`; + + const account_id = await ctx.cache.tryGet(cacheUid, async () => { + const search_response = await got({ + method: 'get', + url: search_url, + headers: { + Authorization: `Bearer ${mastodonConfig.accessToken}`, + }, + searchParams: { + q: acct, + type: 'accounts', + }, + }); + const [acctUser, acctHost] = acct.split('@').filter((e) => e); + let acctOnServer; + + if (acctHost) { + if (acctHost === mastodonConfig.acctDomain) { + acctOnServer = acctUser; + } else { + acctOnServer = acctUser + '@' + acctHost; + } + } else { + acctOnServer = acctUser; + } + + const accountData = search_response.data.accounts.filter((item) => item.acct === acctOnServer); + + if (accountData.length === 0) { + throw `acct ${acct} not found`; + } + return accountData[0].id; + }); + return { site, account_id }; +} + module.exports = { - ProcessFeed: ProcessFeed, + parseStatuses: parseStatuses, + getAccountStatuses: getAccountStatuses, + getAccountIdByAcct: getAccountIdByAcct, }; From ffef6e1dde57573a23dfab614d27ab656eee104e Mon Sep 17 00:00:00 2001 From: notofoe <43095406+notofoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 17:12:13 +0800 Subject: [PATCH 4/7] feat: mastodon remove html tags for title --- lib/routes/mastodon/utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/routes/mastodon/utils.js b/lib/routes/mastodon/utils.js index 475d9f49d..9f45fee57 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -3,6 +3,7 @@ const got = require('@/utils/got'); const parseStatuses = (data) => data.map((item) => { const content = item.content ? item.content.replace(/|<\/span.*?>/gm, '') : ''; + const contentRemovedHtml = content.replace(/<(?:.|\n)*?>/gm, '\n'); const mediaParse = (media_attachments) => media_attachments @@ -32,7 +33,7 @@ const parseStatuses = (data) => titleAuthor = `@${item.account.username}`; media = mediaParse(item.media_attachments); } - const titleText = item.sentitive === true ? `(CW) ${item.spoiler_text}` : content; + const titleText = item.sentitive === true ? `(CW) ${item.spoiler_text}` : contentRemovedHtml; return { title: `${titleAuthor}: "${titleText}"`, From 9f26f0521fb40501756a78912939349f7d19000b Mon Sep 17 00:00:00 2001 From: notofoe <43095406+notofoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 17:26:24 +0800 Subject: [PATCH 5/7] fix: mastodon rm filtering of toots with media --- lib/routes/mastodon/utils.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/routes/mastodon/utils.js b/lib/routes/mastodon/utils.js index 9f45fee57..9315f5a84 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -51,7 +51,7 @@ async function getAccountStatuses(site, account_id, only_media) { method: 'get', url: statuses_url, }); - let data = statuses_response.data; + const data = statuses_response.data; let account_data; if (data.length !== 0 && data[0].account !== null) { @@ -65,9 +65,6 @@ async function getAccountStatuses(site, account_id, only_media) { account_data = account_response.data; } - if (only_media === true) { - data = data.filter((item) => item.media_attachments.length !== 0); - } return { account_data, data }; } From db213a433d85eefe5615395e93b81c225383d9b4 Mon Sep 17 00:00:00 2001 From: notofoe <43095406+notofoe@users.noreply.github.com> Date: Sun, 9 Aug 2020 00:45:17 +0800 Subject: [PATCH 6/7] feat: include spoiler_text in content --- lib/routes/mastodon/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/routes/mastodon/utils.js b/lib/routes/mastodon/utils.js index 9315f5a84..9e78c5233 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -38,7 +38,7 @@ const parseStatuses = (data) => return { title: `${titleAuthor}: "${titleText}"`, author: author, - description: content + media, + description: item.spoiler_text + '

' + content + media, pubDate: new Date(item.created_at).toUTCString(), link: link, guid: item.uri, From fea9429ab089f8896f1aa35e0663f61740934bb3 Mon Sep 17 00:00:00 2001 From: notofoe <43095406+notofoe@users.noreply.github.com> Date: Sun, 9 Aug 2020 00:55:24 +0800 Subject: [PATCH 7/7] feat: trivial format --- lib/routes/mastodon/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/routes/mastodon/utils.js b/lib/routes/mastodon/utils.js index 9e78c5233..b07bfecfd 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -38,7 +38,7 @@ const parseStatuses = (data) => return { title: `${titleAuthor}: "${titleText}"`, author: author, - description: item.spoiler_text + '

' + content + media, + description: item.spoiler_text + '
' + content + media, pubDate: new Date(item.created_at).toUTCString(), link: link, guid: item.uri,