feat(route): add Link3 (#16524)

* Add Route: Link3

add Link3 Route: events, profile

* Update event.ts and profile.ts

1. Avoid using the same name for routes and namespaces
2. Add parameter description to profile.ts
This commit is contained in:
hinus
2024-08-25 13:36:49 +08:00
committed by GitHub
parent 0888a2c259
commit 0fc620951e
3 changed files with 235 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
import { Route } from '@/types';
import { parseDate } from '@/utils/parse-date';
import ofetch from '@/utils/ofetch';
export const route: Route = {
path: '/events',
name: 'Link3 Events',
url: 'link3.to',
maintainers: ['cxheng315'],
example: '/link3/events',
categories: ['other'],
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['link3.to/events'],
target: '/events',
},
],
handler,
};
async function handler() {
const url = 'https://api.cyberconnect.dev/profile/';
const response = await ofetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: {
variables: {
order: 'START_TIME_ASC',
},
query: `
query getTrendingEvents($first: Int, $after: String, $order: TrendingEventsRequest_EventOrder, $filter: TrendingEventsRequest_EventFilter) {
trendingEvents(first: $first, after: $after, order: $order, filter: $filter) {
list {
id
info
title
posterUrl
startTimestamp
endTimestamp
organizer {
lightInfo {
displayName
profilePicture
profileHandle
}
}
}
}
}
`,
},
});
const items = response.data.trendingEvents.list.map((event) => ({
title: event.title,
link: `https://link3.to/e/${event.id}`,
description: event.info ?? '',
author: event.organizer.lightInfo.displayName,
guid: event.id,
pubDate: parseDate(event.startTimestamp * 1000),
itunes_item_image: event.posterUrl,
itunes_duration: event.endTimestamp - event.startTimestamp,
}));
return {
title: 'Link3 Events',
link: 'https://link3.to/events',
description: 'Link3 is a Web3 native social platform built on CyberConnect protocol.',
image: 'https://link3.to/logo.svg',
logo: 'https://link3.to/logo.svg',
author: 'Link3',
item: items,
};
}
+6
View File
@@ -0,0 +1,6 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: 'Link3',
url: 'link3.to',
};
+143
View File
@@ -0,0 +1,143 @@
import { Route } from '@/types';
import { parseDate } from '@/utils/parse-date';
import ofetch from '@/utils/ofetch';
export const route: Route = {
path: '/profile/:handle',
name: 'Link3 Profile',
url: 'link3.to',
maintainers: ['cxheng315'],
example: '/link3/profile/synfutures_defi',
parameters: { handle: 'Profile handle' },
categories: ['other'],
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
radar: [
{
source: ['link3.to/:handle'],
target: '/:handle',
},
],
handler,
};
async function handler(ctx) {
const url = 'https://api.cyberconnect.dev/profile/';
const handle = ctx.req.param('handle');
const response = await ofetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: {
variables: {
handle,
},
query: `
query getProfile($id: ID, $handle: String) {
profile(id: $id, handle: $handle) {
status
data {
handle
... on OrgProfile {
displayName
bio
profilePicture
backgroundPicture
__typename
}
... on PerProfile {
bio
personalDisplayName: displayName {
displayName
}
personalProfilePicture: profilePicture {
picture
}
personalBackgroundPicture: backgroundPicture {
picture
}
__typename
}
blocks {
... on Block {
... on EventBlock {
__typename
events {
id
title
info
posterUrl
startTimestamp
endTimestamp
}
}
}
}
}
}
}
`,
},
});
const status = response.data.profile.status;
if (status !== 'SUCCESS') {
return {
title: 'Error',
description: 'Profile not found',
items: [
{
title: 'Error',
description: 'Profile not found',
link: `https://link3.to/${handle}`,
},
],
};
}
const profile = response.data.profile.data;
const items = profile.blocks
.filter((block) => block.__typename === 'EventBlock')
.flatMap((block) => block.events)
.map((event) => ({
title: event.title,
link: `https://link3.to/e/${event.id}`,
description: event.info ?? '',
author: profile.handle,
guid: event.id,
pubDate: event.startTimestamp ? parseDate(event.startTimestamp * 1000) : null,
itunes_item_image: event.posterUrl,
itunes_duration: event.endTimestamp - event.startTimestamp,
}));
return {
title: profile.displayName ?? profile.personalDisplayName.displayName,
link: `https://link3.to/${profile.handle}`,
description: profile.bio,
logo: profile.profilePicture ?? profile.personalProfilePicture.picture,
image: profile.profilePicture ?? profile.personalProfilePicture.picture,
author: profile.handle,
item:
items && items.length > 0
? items
: [
{
title: 'No events',
description: 'No events',
link: `https://link3.to/${handle}`,
},
],
};
}