feat(route/tumblr): Add Tumblr tagged route (#20576)
* tumblr.com: Code to access tagged/ endpoint * tumblr.com: Change processPost for tagged endpoint * Tumblr.com: "Tagged" response is a list of posts * tumblr.com: removed unnecessary link * tumblr.com: fixing api key auth as per https://www.tumblr.com/docs/en/api/v2#authentication * tumblr.com: user query params properly * tumblr.com: compliance with Script Standard * tumblr.com: ensuring `api_key` works for posts.ts * tumblr: don't mess up the types this time * tumblr/tagged/:tag Feed Description + Link * /tumblr Can now parse blog answers * /tumblr "answer" is the correct type * /tumblr: Better format for blog answers * /tumblr: fixed misplaced </p> tag * lib/routes/tumblr/tagged.ts: Removed unnecessary template literals Co-authored-by: Tony <TonyRL@users.noreply.github.com> * /tumblr/tagged: Only one category * /tumblr: Fixed how the asker's url is handled * Ran ESLint --------- Co-authored-by: Tony <TonyRL@users.noreply.github.com>
This commit is contained in:
parent
27cd651d58
commit
8fcbaac983
|
|
@ -38,7 +38,7 @@ export const route: Route = {
|
|||
supportScihub: false,
|
||||
},
|
||||
name: 'Posts',
|
||||
maintainers: ['Rakambda'],
|
||||
maintainers: ['Rakambda', 'PolarisStarnor'],
|
||||
description: `::: tip
|
||||
Tumblr provides official RSS feeds for non "dashboard only" blogs, for instance [https://biketouring-nearby.tumblr.com](https://biketouring-nearby.tumblr.com/rss).
|
||||
:::`,
|
||||
|
|
@ -55,7 +55,7 @@ async function handler(ctx: Context): Promise<Data> {
|
|||
|
||||
const response = await got.get(`https://api.tumblr.com/v2/blog/${blogIdentifier}/posts`, {
|
||||
searchParams: {
|
||||
...utils.generateAuthParams(),
|
||||
api_key: utils.generateAuthParams(),
|
||||
limit,
|
||||
},
|
||||
headers: await utils.generateAuthHeaders(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
import type { Context } from 'hono';
|
||||
|
||||
import { config } from '@/config';
|
||||
import ConfigNotFoundError from '@/errors/types/config-not-found';
|
||||
import type { Data, Route } from '@/types';
|
||||
import got from '@/utils/got';
|
||||
import { fallback, queryToInteger } from '@/utils/readable-social';
|
||||
|
||||
import utils from './utils';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/tagged/:tag',
|
||||
categories: ['social-media'],
|
||||
example: '/tumblr/tagged/nature',
|
||||
parameters: {
|
||||
tag: 'Tag name (see `https://www.tumblr.com/docs/en/api/v2#tagged--get-posts-with-tag`)',
|
||||
},
|
||||
radar: [],
|
||||
features: {
|
||||
requireConfig: [
|
||||
{
|
||||
name: 'TUMBLR_CLIENT_ID',
|
||||
description: 'Please see above for details.',
|
||||
},
|
||||
{
|
||||
name: 'TUMBLR_CLIENT_SECRET',
|
||||
description: 'Please see above for details.',
|
||||
},
|
||||
{
|
||||
name: 'TUMBLR_REFRESH_TOKEN',
|
||||
description: 'Please see above for details.',
|
||||
},
|
||||
],
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
},
|
||||
name: 'Tagged Posts',
|
||||
maintainers: ['PolarisStarnor'],
|
||||
handler,
|
||||
};
|
||||
|
||||
async function handler(ctx: Context): Promise<Data> {
|
||||
if (!config.tumblr || !config.tumblr.clientId) {
|
||||
throw new ConfigNotFoundError('Tumblr RSS is disabled due to the lack of <a href="https://docs.rsshub.app/deploy/config#route-specific-configurations">relevant config</a>');
|
||||
}
|
||||
|
||||
const tag = ctx.req.param('tag');
|
||||
const limit = fallback(undefined, queryToInteger(ctx.req.query('limit')), 20);
|
||||
|
||||
const response = await got.get('https://api.tumblr.com/v2/tagged', {
|
||||
searchParams: {
|
||||
tag,
|
||||
api_key: utils.generateAuthParams(),
|
||||
limit,
|
||||
},
|
||||
headers: await utils.generateAuthHeaders(),
|
||||
});
|
||||
|
||||
const posts = response.data.response.map((post: any) => utils.processPost(post));
|
||||
|
||||
return {
|
||||
title: `Tumblr - ${tag}`,
|
||||
description: `Tumblr posts tagged #${tag}`,
|
||||
link: `https://tumblr.com/tagged/${tag}`,
|
||||
item: posts,
|
||||
allowEmpty: true,
|
||||
};
|
||||
}
|
||||
|
|
@ -31,9 +31,7 @@ const generateAuthHeaders: () => Promise<{ Authorization?: string }> = async ()
|
|||
};
|
||||
};
|
||||
|
||||
const generateAuthParams: () => { apiKey?: string } = () => ({
|
||||
apiKey: config.tumblr.clientId,
|
||||
});
|
||||
const generateAuthParams: () => string = () => config.tumblr.clientId!;
|
||||
|
||||
const processPost: (post: any) => DataItem = (post) => {
|
||||
let description = '';
|
||||
|
|
@ -42,6 +40,13 @@ const processPost: (post: any) => DataItem = (post) => {
|
|||
case 'text':
|
||||
description = post.body;
|
||||
break;
|
||||
case 'answer':
|
||||
description += post.asking_url === null ? `<p>${post.asking_name} asks:</p>` : `<p><a href="${post.asking_url}">${post.asking_name}</a> asks:</p>`;
|
||||
description += post.question;
|
||||
description += '<hr>';
|
||||
description += `<p><a href="${post.blog.url}">${post.blog_name}</a> answers:</p>`;
|
||||
description += post.answer;
|
||||
break;
|
||||
case 'photo':
|
||||
for (const photo of post.photos ?? []) {
|
||||
description += `<img src="${photo.original_size.url}"/><br/>`;
|
||||
|
|
@ -58,6 +63,7 @@ const processPost: (post: any) => DataItem = (post) => {
|
|||
}
|
||||
|
||||
return {
|
||||
author: post.blog_name,
|
||||
id: post.id_string,
|
||||
title: post.summary ?? `New post from ${post.blog_name}`,
|
||||
link: post.post_url,
|
||||
|
|
|
|||
Loading…
Reference in New Issue