From a5a5f4ee2adac440c1c492d54c6729ff2c44d7b5 Mon Sep 17 00:00:00 2001 From: Jorge Vargas Date: Tue, 27 Aug 2024 22:06:40 -0600 Subject: [PATCH] Use GQL for rss feed generation --- src/graphql/resolvers/index.ts | 4 +- src/graphql/resolvers/queries/search.ts | 28 ++++++---- .../resolvers/types/{album.js => album.ts} | 24 +++----- src/graphql/resolvers/types/index.js | 8 --- src/graphql/resolvers/types/index.ts | 8 +++ src/pages/rss.xml.ts | 55 +++++++++++-------- 6 files changed, 67 insertions(+), 60 deletions(-) rename src/graphql/resolvers/types/{album.js => album.ts} (91%) delete mode 100644 src/graphql/resolvers/types/index.js create mode 100644 src/graphql/resolvers/types/index.ts diff --git a/src/graphql/resolvers/index.ts b/src/graphql/resolvers/index.ts index 7a27753..4606712 100644 --- a/src/graphql/resolvers/index.ts +++ b/src/graphql/resolvers/index.ts @@ -1,7 +1,7 @@ // import mutations from './mutations' import queries from './queries' -// import types from './types' +import types from './types' -const resolvers = { /*...mutations,*/ ...queries /*...types*/ } +const resolvers = { /*...mutations,*/ ...queries, ...types } export default resolvers diff --git a/src/graphql/resolvers/queries/search.ts b/src/graphql/resolvers/queries/search.ts index 2eccb6e..31fae50 100644 --- a/src/graphql/resolvers/queries/search.ts +++ b/src/graphql/resolvers/queries/search.ts @@ -1,29 +1,35 @@ -import Sequelize from 'sequelize' -const { Op, literal } = Sequelize +//@ts-ignore +import { Op, literal } from 'sequelize' import type { Resolvers } from '@/graphql/__generated__/types.generated' + + const fuzzySearch = (words: string[]) => `^${words.map(w => `(?=.*\b${w}\b)`)}.+/i` const resolvers: Resolvers = { Query: { - searchAlbum: (parent, args, { db }) => { + searchAlbum: (_, args, { db }) => { const { title, categories, limit = 10, offset = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] } = args - const titleWords = title?.split(' ') || [] + const fuzzyCondition = title ? { + [Op.or]: [ + { title: { [Op.regexp]: fuzzySearch(title.split(' ')) } }, + { subTitle: { [Op.regexp]: fuzzySearch(title.split(' ')) } } + ] + } : {} + + const include = [] + if (categories) include.push({ model: db.models.category, where: { name: { [Op.in]: categories } } }) return db.models.album.findAndCountAll({ limit, offset, where: { - [Op.or]: [ - { title: { [Op.regexp]: fuzzySearch(titleWords) } }, - { subTitle: { [Op.regexp]: fuzzySearch(titleWords) } } - ], + ...fuzzyCondition, status: { [Op.in]: status } }, - include: categories ? [{ model: db.models.category, where: { name: { [Op.in]: categories } } }] : [], + include, order: [literal('`album`.`status` = \'coming\' DESC'), ...order.map(o => [o, mode])] }) - - }, + } /* searchAlbumByArtist: async (parent, { name, categories, limit, page = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] }, { db }) => { const include = [{ model: db.models.artist, where: { name: { [Op.like]: `%${name}%` } } }] diff --git a/src/graphql/resolvers/types/album.js b/src/graphql/resolvers/types/album.ts similarity index 91% rename from src/graphql/resolvers/types/album.js rename to src/graphql/resolvers/types/album.ts index 9010e4d..f15f478 100644 --- a/src/graphql/resolvers/types/album.js +++ b/src/graphql/resolvers/types/album.ts @@ -1,18 +1,12 @@ -import { GraphQLUpload } from 'graphql-upload-minimal' +// import { GraphQLUpload } from 'graphql-upload-minimal' +import type { Resolvers } from "@/graphql/__generated__/types.generated" -import { - checkHeaderColor, - solveRating, - checkPlaceholder -} from '@/server/utils/resolvers' - -import { getUser } from '@/next/utils/getSession' - -const resolvers = { - Upload: GraphQLUpload, +const resolvers: Resolvers = { + // Upload: GraphQLUpload, Album: { + // @ts-ignore artists: (parent, args, context, info) => parent.getArtists(), - categories: (parent, args, context, info) => parent.getCategories(), + /* categories: (parent, args, context, info) => parent.getCategories(), classifications: (parent, args, context, info) => parent.getClassifications(), platforms: (parent, args, context, info) => @@ -50,10 +44,10 @@ const resolvers = { favorites: (album, _, { db }) => album.countUsers(), placeholder: (album, _, { db }) => checkPlaceholder(album, 'album'), headerColor: (album, _, { db }) => checkHeaderColor(album, 'album'), - avgRating: async (album, _, { db }) => solveRating(album) + avgRating: async (album, _, { db }) => solveRating(album) */ }, - Comment: { + /* Comment: { username: (parent) => (parent.anon ? null : parent.username), album: (comment, _, { db }) => comment.getAlbum() }, @@ -148,7 +142,7 @@ const resolvers = { Disc: { album: (parent) => parent.getAlbum(), tracks: (parent) => parent.body.split(',') - } + } */ } export default resolvers diff --git a/src/graphql/resolvers/types/index.js b/src/graphql/resolvers/types/index.js deleted file mode 100644 index 943346f..0000000 --- a/src/graphql/resolvers/types/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import merge from 'lodash/merge' - -import album from './album' -import user from './user' - -const types = merge(album, user) - -export default types diff --git a/src/graphql/resolvers/types/index.ts b/src/graphql/resolvers/types/index.ts new file mode 100644 index 0000000..bcb0922 --- /dev/null +++ b/src/graphql/resolvers/types/index.ts @@ -0,0 +1,8 @@ +// import merge from 'lodash/merge' + +import album from './album' +// import user from './user' + +const types = /*(merge(*/album/*, user)*/ + +export default types diff --git a/src/pages/rss.xml.ts b/src/pages/rss.xml.ts index b14a39c..e485a04 100644 --- a/src/pages/rss.xml.ts +++ b/src/pages/rss.xml.ts @@ -1,39 +1,46 @@ import rss, { type RSSFeedItem } from '@astrojs/rss'; import type { APIContext } from 'astro'; -// @ts-ignore -import { Op } from 'sequelize' -import db from '@/sequelize'; +import { getApolloClient } from '@/graphql/apolloClient.mjs'; +import { gql } from '@/graphql/__generated__/client'; + +const addedQuery = gql(` + query LastAdded ($limit: Int) { + added: searchAlbum(limit: $limit, status: ["show"]) { + rows { + id + createdAt + title + subTitle + artists { + name + } + } + } + } +`) export async function GET(context: APIContext) { - const date = new Date() - date.setDate(date.getDate() - 8) + const client = await getApolloClient() + const { data } = await client.query({ query: addedQuery, variables: { limit: 15 } }) - const isoDate = date.toISOString() - const limitDate = `${isoDate.split('T')[0]}T00:00:00Z` - const commonArgs = { include: [db.models.artist], order: [['createdAt', 'DESC']] } + if (!data.added?.rows) throw new Error() + const { rows } = data.added - let albums = await db.models.album.findAll({ where: { createdAt: { [Op.gte]: limitDate } }, ...commonArgs }) - if (albums.length < 15) albums = await db.models.album.findAll({ limit: 15, ...commonArgs }) - - const items: RSSFeedItem[] = albums.map((album: any) => { - const { dataValues } = album - const item: RSSFeedItem = { - title: dataValues.title, - pubDate: dataValues.createdAt, - description: dataValues.subTitle || dataValues.artists.map((a: { name: string }) => a.name).join(' - '), - link: `https://www.sittingonclouds.net/album/${dataValues.id}`, - customData: ` ({ + guid: `album/${album?.id}`, + title: album?.title, + pubDate: new Date(album?.createdAt || ''), + description: album?.subTitle || album?.artists.map(a => a?.name).join(' - '), + link: `https://www.sittingonclouds.net/album/${album?.id}`, + customData: ` + url="https://cdn.sittingonclouds.net/album/${album?.id}.png" /> `, - } - - return item - }) + })) return rss({ xmlns: {