diff options
| author | Acid Chicken (硫酸鶏) <root@acid-chicken.com> | 2018-12-21 11:54:39 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-21 11:54:39 +0900 |
| commit | 1395cf89cee2916cf5e2a1af52357707222b6afd (patch) | |
| tree | 556a7d3b384541bf27d8347f09661eb443046aac /src/server/web | |
| parent | Fix comment (diff) | |
| download | misskey-1395cf89cee2916cf5e2a1af52357707222b6afd.tar.gz misskey-1395cf89cee2916cf5e2a1af52357707222b6afd.tar.bz2 misskey-1395cf89cee2916cf5e2a1af52357707222b6afd.zip | |
Feed (#3698)
* wip
* Implement feed
* Update feed.ts
* Update index.ts
* Update feed.ts
Diffstat (limited to 'src/server/web')
| -rw-r--r-- | src/server/web/feed.ts | 54 | ||||
| -rw-r--r-- | src/server/web/index.ts | 47 |
2 files changed, 101 insertions, 0 deletions
diff --git a/src/server/web/feed.ts b/src/server/web/feed.ts new file mode 100644 index 0000000000..09ac10c576 --- /dev/null +++ b/src/server/web/feed.ts @@ -0,0 +1,54 @@ +import { Feed } from 'feed'; +import config from '../../config'; +import Note from '../../models/note'; +import { IUser } from '../../models/user'; +import { getOriginalUrl } from '../../misc/get-drive-file-url'; + +export default async function(user: IUser) { + const author: Author = { + link: `${config.url}/@${user.username}`, + name: user.name || user.username + }; + + const notes = await Note.find({ + userId: user._id, + renoteId: null, + $or: [ + { visibility: 'public' }, + { visibility: 'home' } + ] + }, { + sort: { createdAt: -1 }, + limit: 20 + }); + + const feed = new Feed({ + id: author.link, + title: `${author.name} (@${user.username}@${config.host})`, + updated: notes[0].createdAt, + generator: 'Misskey', + description: `${user.notesCount} Notes, ${user.followingCount} Following, ${user.followersCount} Followers${user.description ? ` · ${user.description}` : ''}`, + link: author.link, + image: user.avatarUrl, + feedLinks: { + json: `${author.link}.json`, + atom: `${author.link}.atom`, + }, + author + } as FeedOptions); + + for (const note of notes) { + const file = note._files && note._files.find(file => file.contentType.startsWith('image/')); + + feed.addItem({ + title: `New note by ${author.name}`, + link: `${config.url}/notes/${note._id}`, + date: note.createdAt, + description: note.cw, + content: note.text, + image: file && getOriginalUrl(file) + }); + } + + return feed; +} diff --git a/src/server/web/index.ts b/src/server/web/index.ts index 5a5029c7fb..f2a40c01f7 100644 --- a/src/server/web/index.ts +++ b/src/server/web/index.ts @@ -10,6 +10,7 @@ import * as favicon from 'koa-favicon'; import * as views from 'koa-views'; import docs from './docs'; +import packFeed from './feed'; import User from '../../models/user'; import parseAcct from '../../misc/acct/parse'; import config from '../../config'; @@ -82,6 +83,52 @@ router.use('/docs', docs.routes()); // URL preview endpoint router.get('/url', require('./url-preview')); +const getFeed = async (acct: string) => { + const { username, host } = parseAcct(acct); + const user = await User.findOne({ + usernameLower: username.toLowerCase(), + host + }); + + return user && await packFeed(user); +}; + +// Atom +router.get('/@:user.atom', async ctx => { + const feed = await getFeed(ctx.params.user); + + if (feed) { + ctx.set('Content-Type', 'application/atom+xml; charset=utf-8'); + ctx.body = feed.atom1(); + } else { + ctx.status = 404; + } +}); + +// RSS +router.get('/@:user.rss', async ctx => { + const feed = await getFeed(ctx.params.user); + + if (feed) { + ctx.set('Content-Type', 'application/rss+xml; charset=utf-8'); + ctx.body = feed.rss2(); + } else { + ctx.status = 404; + } +}); + +// JSON +router.get('/@:user.json', async ctx => { + const feed = await getFeed(ctx.params.user); + + if (feed) { + ctx.set('Content-Type', 'application/json; charset=utf-8'); + ctx.body = feed.json1(); + } else { + ctx.status = 404; + } +}); + //#region for crawlers // User router.get('/@:user', async (ctx, next) => { |