import { ApolloError, UserInputError } from 'apollo-server'; import { Channels, Videos } from '../../../database'; import { PlatformId } from '../../../database/types/members'; import { memcache } from '../../modules'; import { ChannelId } from '../../modules/types/youtube'; import { cutChannelIds, cutGroupString, getCacheKey, parseOrganization } from './consts'; const CACHE_TTL = +(process.env.TTL_LONG ?? 900); interface Query { organizations: string[]; exclude_organizations: string[]; channel_id: ChannelId[]; exclude_channel_id: ChannelId[]; platforms: PlatformId[]; } export async function data(_, query: Query) { try { const { organizations = [], exclude_organizations = [], channel_id = [], exclude_channel_id = [], platforms = [] } = query; if (organizations.length && exclude_organizations.length) { return new UserInputError('Setting both organizations and exclude_organizations is redundant. Only choose one.'); } if (channel_id.length && exclude_channel_id.length) { return new UserInputError('Setting both channel_id and exclude_channel_id is redundant. Only choose one.'); } const EXCLUDE_ORG = !organizations.length; const EXCLUDE_IDS = !channel_id.length; const ORGANIZATIONS = parseOrganization(EXCLUDE_ORG ? exclude_organizations : organizations); const CHANNEL_IDS = EXCLUDE_IDS ? exclude_channel_id : channel_id; const CACHE_KEY = getCacheKey(`CHNLS:${+EXCLUDE_ORG}${cutGroupString(ORGANIZATIONS)}${cutChannelIds(CHANNEL_IDS)}${platforms}`, false); const cached = await memcache.get(CACHE_KEY); if (cached) return cached; const QUERY = { ...ORGANIZATIONS[0] && { organization: { ...EXCLUDE_ORG ? { $not: { $regex: ORGANIZATIONS, $options: 'i' } } : { $regex: ORGANIZATIONS, $options: 'i' } } }, ...channel_id[0] && { channel_id: { [EXCLUDE_IDS ? '$nin' : '$in']: CHANNEL_IDS } }, ...platforms[0] && { platform_id: { $in: platforms } } }; const getChannelList = Channels.find(QUERY).lean().exec(); const getVideoCount = Videos.countDocuments(QUERY).lean().exec(); const [channelList, videoCount] = await Promise.all([getChannelList, getVideoCount]); const groupList = channelList .map(value => value.organization) .filter((value, index, array) => array.indexOf(value) === index); const channelCount = channelList.length; const result = { organizations: groupList, channels: channelCount, videos: videoCount }; memcache.set(CACHE_KEY, result, CACHE_TTL); return result; } catch(err) { throw new ApolloError(err); } }