mirror of
https://github.com/feeddeck/feeddeck.git
synced 2026-04-28 18:38:34 -05:00
This commit adds a new source type "pinterest", which can be used to follow the post of an user or a board on Pinterest. To use the new source type a user can select the "Pinterest" item in the add source modal. In the form a user can provide the username or board he wants to follow via FeedDeck. In the corresponding Supabase function we then convert the input provided by the user to an valid RSS feed url for Pinterest. This means that we have to add `/feed.rss` for users and `.rss` for boards to the Pinterest url. Then we generate the source and items as for the other sources and reuse the existing components to render the preview and details item. We had to adjust the rendering logic for these items, to ignore empty values, from which also other sources will benefit.
125 lines
4.2 KiB
TypeScript
125 lines
4.2 KiB
TypeScript
import { SupabaseClient } from '@supabase/supabase-js';
|
|
import { Redis } from 'redis';
|
|
|
|
import { IItem } from '../models/item.ts';
|
|
import { ISource } from '../models/source.ts';
|
|
import { getMediumFeed, isMediumUrl } from './medium.ts';
|
|
import { getPinterestFeed, isPinterestUrl } from './pinterest.ts';
|
|
import { getRSSFeed } from './rss.ts';
|
|
import { getPodcastFeed } from './podcast.ts';
|
|
import { getTumblrFeed, isTumblrUrl } from './tumblr.ts';
|
|
import { getStackoverflowFeed } from './stackoverflow.ts';
|
|
import { getGooglenewsFeed } from './googlenews.ts';
|
|
import { getYoutubeFeed, isYoutubeUrl } from './youtube.ts';
|
|
import { getRedditFeed, isRedditUrl } from './reddit.ts';
|
|
import { getGithubFeed } from './github.ts';
|
|
import { IProfile } from '../models/profile.ts';
|
|
import { getNitterFeed } from './nitter.ts';
|
|
import { getMastodonFeed } from './mastodon.ts';
|
|
// import { getXFeed } from './x.ts';
|
|
|
|
/**
|
|
* `getFeed` returns a feed which consist of a source and a list of items for
|
|
* the provided `source`. Based on the `type` of the provided source it will use
|
|
* the appropriate function to get the feed.
|
|
*/
|
|
export const getFeed = async (
|
|
supabaseClient: SupabaseClient,
|
|
redisClient: Redis | undefined,
|
|
profile: IProfile,
|
|
source: ISource,
|
|
): Promise<{ source: ISource; items: IItem[] }> => {
|
|
switch (source.type) {
|
|
case 'github':
|
|
return await getGithubFeed(supabaseClient, redisClient, profile, source);
|
|
case 'googlenews':
|
|
return await getGooglenewsFeed(
|
|
supabaseClient,
|
|
redisClient,
|
|
profile,
|
|
source,
|
|
);
|
|
case 'mastodon':
|
|
return await getMastodonFeed(
|
|
supabaseClient,
|
|
redisClient,
|
|
profile,
|
|
source,
|
|
);
|
|
case 'medium':
|
|
return await getMediumFeed(supabaseClient, redisClient, profile, source);
|
|
case 'nitter':
|
|
return await getNitterFeed(supabaseClient, redisClient, profile, source);
|
|
case 'pinterest':
|
|
return await getPinterestFeed(
|
|
supabaseClient,
|
|
redisClient,
|
|
profile,
|
|
source,
|
|
);
|
|
case 'podcast':
|
|
return await getPodcastFeed(supabaseClient, redisClient, profile, source);
|
|
case 'reddit':
|
|
return await getRedditFeed(supabaseClient, redisClient, profile, source);
|
|
case 'rss':
|
|
try {
|
|
if (source.options?.rss && isMediumUrl(source.options.rss)) {
|
|
return await getMediumFeed(supabaseClient, redisClient, profile, {
|
|
...source,
|
|
options: { medium: source.options.rss },
|
|
});
|
|
}
|
|
|
|
if (source.options?.rss && isPinterestUrl(source.options.rss)) {
|
|
return await getPinterestFeed(supabaseClient, redisClient, profile, {
|
|
...source,
|
|
options: { pinterest: source.options.rss },
|
|
});
|
|
}
|
|
|
|
if (source.options?.rss && isRedditUrl(source.options.rss)) {
|
|
return await getTumblrFeed(supabaseClient, redisClient, profile, {
|
|
...source,
|
|
options: { reddit: source.options.reddit },
|
|
});
|
|
}
|
|
|
|
if (source.options?.rss && isTumblrUrl(source.options.rss)) {
|
|
return await getTumblrFeed(supabaseClient, redisClient, profile, {
|
|
...source,
|
|
options: { tumblr: source.options.rss },
|
|
});
|
|
}
|
|
|
|
if (source.options?.rss && isYoutubeUrl(source.options.rss)) {
|
|
return await getYoutubeFeed(supabaseClient, redisClient, profile, {
|
|
...source,
|
|
options: { youtube: source.options.rss },
|
|
});
|
|
}
|
|
} catch (_) {
|
|
/**
|
|
* We ignore any errors at this point and try to use the general
|
|
* `getRSSFeed` function instead.
|
|
*/
|
|
}
|
|
|
|
return await getRSSFeed(supabaseClient, redisClient, profile, source);
|
|
case 'stackoverflow':
|
|
return await getStackoverflowFeed(
|
|
supabaseClient,
|
|
redisClient,
|
|
profile,
|
|
source,
|
|
);
|
|
case 'tumblr':
|
|
return await getTumblrFeed(supabaseClient, redisClient, profile, source);
|
|
// case "x":
|
|
// return await getXFeed(supabaseClient, redisClient, profile, source);
|
|
case 'youtube':
|
|
return await getYoutubeFeed(supabaseClient, redisClient, profile, source);
|
|
default:
|
|
throw new Error('Invalid source type');
|
|
}
|
|
};
|