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 9fb46ddc5..b07bfecfd 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -1,50 +1,123 @@ -const ProcessFeed = (data) => +const got = require('@/utils/got'); + +const parseStatuses = (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 contentRemovedHtml = content.replace(/<(?:.|\n)*?>/gm, '\n'); - 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; + const titleText = item.sentitive === true ? `(CW) ${item.spoiler_text}` : contentRemovedHtml; 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, }; }); +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, + }); + const 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; + } + + 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, };