Use GQL for rss feed generation

This commit is contained in:
Jorge Vargas 2024-08-27 22:06:40 -06:00
parent f22cc01005
commit a5a5f4ee2a
6 changed files with 67 additions and 60 deletions

View file

@ -1,7 +1,7 @@
// import mutations from './mutations' // import mutations from './mutations'
import queries from './queries' 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 export default resolvers

View file

@ -1,29 +1,35 @@
import Sequelize from 'sequelize' //@ts-ignore
const { Op, literal } = Sequelize import { Op, literal } from 'sequelize'
import type { Resolvers } from '@/graphql/__generated__/types.generated' import type { Resolvers } from '@/graphql/__generated__/types.generated'
const fuzzySearch = (words: string[]) => `^${words.map(w => `(?=.*\b${w}\b)`)}.+/i` const fuzzySearch = (words: string[]) => `^${words.map(w => `(?=.*\b${w}\b)`)}.+/i`
const resolvers: Resolvers = { const resolvers: Resolvers = {
Query: { Query: {
searchAlbum: (parent, args, { db }) => { searchAlbum: (_, args, { db }) => {
const { title, categories, limit = 10, offset = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] } = args 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({ return db.models.album.findAndCountAll({
limit, offset, limit, offset,
where: { where: {
[Op.or]: [ ...fuzzyCondition,
{ title: { [Op.regexp]: fuzzySearch(titleWords) } },
{ subTitle: { [Op.regexp]: fuzzySearch(titleWords) } }
],
status: { [Op.in]: status } 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])] 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 }) => { /* 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}%` } } }] const include = [{ model: db.models.artist, where: { name: { [Op.like]: `%${name}%` } } }]

View file

@ -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 { const resolvers: Resolvers = {
checkHeaderColor, // Upload: GraphQLUpload,
solveRating,
checkPlaceholder
} from '@/server/utils/resolvers'
import { getUser } from '@/next/utils/getSession'
const resolvers = {
Upload: GraphQLUpload,
Album: { Album: {
// @ts-ignore
artists: (parent, args, context, info) => parent.getArtists(), 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) => classifications: (parent, args, context, info) =>
parent.getClassifications(), parent.getClassifications(),
platforms: (parent, args, context, info) => platforms: (parent, args, context, info) =>
@ -50,10 +44,10 @@ const resolvers = {
favorites: (album, _, { db }) => album.countUsers(), favorites: (album, _, { db }) => album.countUsers(),
placeholder: (album, _, { db }) => checkPlaceholder(album, 'album'), placeholder: (album, _, { db }) => checkPlaceholder(album, 'album'),
headerColor: (album, _, { db }) => checkHeaderColor(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), username: (parent) => (parent.anon ? null : parent.username),
album: (comment, _, { db }) => comment.getAlbum() album: (comment, _, { db }) => comment.getAlbum()
}, },
@ -148,7 +142,7 @@ const resolvers = {
Disc: { Disc: {
album: (parent) => parent.getAlbum(), album: (parent) => parent.getAlbum(),
tracks: (parent) => parent.body.split(',') tracks: (parent) => parent.body.split(',')
} } */
} }
export default resolvers export default resolvers

View file

@ -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

View file

@ -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

View file

@ -1,39 +1,46 @@
import rss, { type RSSFeedItem } from '@astrojs/rss'; import rss, { type RSSFeedItem } from '@astrojs/rss';
import type { APIContext } from 'astro'; 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) { export async function GET(context: APIContext) {
const date = new Date() const client = await getApolloClient()
date.setDate(date.getDate() - 8) const { data } = await client.query({ query: addedQuery, variables: { limit: 15 } })
const isoDate = date.toISOString() if (!data.added?.rows) throw new Error()
const limitDate = `${isoDate.split('T')[0]}T00:00:00Z` const { rows } = data.added
const commonArgs = { include: [db.models.artist], order: [['createdAt', 'DESC']] }
let albums = await db.models.album.findAll({ where: { createdAt: { [Op.gte]: limitDate } }, ...commonArgs }) const items: RSSFeedItem[] = rows.map((album) => ({
if (albums.length < 15) albums = await db.models.album.findAll({ limit: 15, ...commonArgs }) guid: `album/${album?.id}`,
title: album?.title,
const items: RSSFeedItem[] = albums.map((album: any) => { pubDate: new Date(album?.createdAt || ''),
const { dataValues } = album description: album?.subTitle || album?.artists.map(a => a?.name).join(' - '),
const item: RSSFeedItem = { link: `https://www.sittingonclouds.net/album/${album?.id}`,
title: dataValues.title, customData: `<media:content
pubDate: dataValues.createdAt,
description: dataValues.subTitle || dataValues.artists.map((a: { name: string }) => a.name).join(' - '),
link: `https://www.sittingonclouds.net/album/${dataValues.id}`,
customData: `<media:content
type="image/png" type="image/png"
width="100" width="100"
height="100" height="100"
medium="image" medium="image"
url="https://cdn.sittingonclouds.net/album/${dataValues.id}.png" /> url="https://cdn.sittingonclouds.net/album/${album?.id}.png" />
`, `,
} }))
return item
})
return rss({ return rss({
xmlns: { xmlns: {