diff --git a/apps/api/bruno/rocksky/feed/Get Now Playings.bru b/apps/api/bruno/rocksky/feed/Get Now Playings.bru deleted file mode 100644 index 392d0271..00000000 --- a/apps/api/bruno/rocksky/feed/Get Now Playings.bru +++ /dev/null @@ -1,11 +0,0 @@ -meta { - name: Get Now Playings - type: http - seq: 1 -} - -get { - url: {{url}}/xrpc/app.rocksky.feed.getNowPlayings - body: none - auth: inherit -} diff --git a/apps/api/lexicons/feed/defs.json b/apps/api/lexicons/feed/defs.json index 322310da..46834cf3 100644 --- a/apps/api/lexicons/feed/defs.json +++ b/apps/api/lexicons/feed/defs.json @@ -32,75 +32,6 @@ } } }, - "nowPlayingView": { - "type": "object", - "properties": { - "album": { - "type": "string" - }, - "albumArt": { - "type": "string", - "format": "uri" - }, - "albumArtist": { - "type": "string" - }, - "albumUri": { - "type": "string", - "format": "at-uri" - }, - "artist": { - "type": "string" - }, - "artistUri": { - "type": "string", - "format": "at-uri" - }, - "avatar": { - "type": "string", - "format": "uri" - }, - "createdAt": { - "type": "string" - }, - "did": { - "type": "string", - "format": "at-identifier" - }, - "handle": { - "type": "string" - }, - "id": { - "type": "string" - }, - "title": { - "type": "string" - }, - "trackId": { - "type": "string" - }, - "trackUri": { - "type": "string", - "format": "at-uri" - }, - "uri": { - "type": "string", - "format": "at-uri" - } - } - }, - "nowPlayingsView": { - "type": "object", - "properties": { - "nowPlayings": { - "type": "array", - "items": { - "type": "ref", - "ref": "app.rocksky.feed.defs#nowPlayingView" - } - } - } - }, "storyView": { "type": "object", "properties": { diff --git a/apps/api/lexicons/feed/getNowPlayings.json b/apps/api/lexicons/feed/getNowPlayings.json deleted file mode 100644 index 4aa9aa9c..00000000 --- a/apps/api/lexicons/feed/getNowPlayings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "lexicon": 1, - "id": "app.rocksky.feed.getNowPlayings", - "defs": { - "main": { - "type": "query", - "description": "Get all currently playing tracks by users", - "parameters": { - "type": "params", - "properties": { - "size": { - "type": "integer", - "description": "The maximum number of now playing tracks to return.", - "minimum": 1 - } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "ref", - "ref": "app.rocksky.feed.defs#nowPlayingsView" - } - } - } - } -} diff --git a/apps/api/pkl/defs/feed/defs.pkl b/apps/api/pkl/defs/feed/defs.pkl index ac3eed88..4c9d2a2d 100644 --- a/apps/api/pkl/defs/feed/defs.pkl +++ b/apps/api/pkl/defs/feed/defs.pkl @@ -34,75 +34,6 @@ defs = new Mapping { } } } - ["nowPlayingView"] = new ObjectType { - type = "object" - properties { - ["album"] = new StringType { - type = "string" - } - ["albumArt"] = new StringType { - type = "string" - format = "uri" - } - ["albumArtist"] = new StringType { - type = "string" - } - ["albumUri"] = new StringType { - type = "string" - format = "at-uri" - } - ["artist"] = new StringType { - type = "string" - } - ["artistUri"] = new StringType { - type = "string" - format = "at-uri" - } - ["avatar"] = new StringType { - type = "string" - format = "uri" - } - ["createdAt"] = new StringType { - type = "string" - } - ["did"] = new StringType { - type = "string" - format = "at-identifier" - } - ["handle"] = new StringType { - type = "string" - } - ["id"] = new StringType { - type = "string" - } - ["title"] = new StringType { - type = "string" - } - ["trackId"] = new StringType { - type = "string" - } - ["trackUri"] = new StringType { - type = "string" - format = "at-uri" - } - ["uri"] = new StringType { - type = "string" - format = "at-uri" - } - } - } - ["nowPlayingsView"] = new ObjectType { - type = "object" - properties { - ["nowPlayings"] = new Array { - type = "array" - items = new Ref { - type = "ref" - ref = "app.rocksky.feed.defs#nowPlayingView" - } - } - } - } ["storyView"] = new ObjectType { type = "object" properties { diff --git a/apps/api/pkl/defs/feed/getNowPlayings.pkl b/apps/api/pkl/defs/feed/getNowPlayings.pkl deleted file mode 100644 index c7464bbd..00000000 --- a/apps/api/pkl/defs/feed/getNowPlayings.pkl +++ /dev/null @@ -1,27 +0,0 @@ -amends "../../schema/lexicon.pkl" - -lexicon = 1 -id = "app.rocksky.feed.getNowPlayings" -defs = new Mapping { - ["main"] { - type = "query" - description = "Get all currently playing tracks by users" - parameters { - type = "params" - properties { - ["size"] = new IntegerType { - type = "integer" - description = "The maximum number of now playing tracks to return." - minimum = 1 - } - } - } - output { - encoding = "application/json" - schema = new Ref { - type = "ref" - ref = "app.rocksky.feed.defs#nowPlayingsView" - } - } - } -} \ No newline at end of file diff --git a/apps/api/src/lexicon/index.ts b/apps/api/src/lexicon/index.ts index 20596593..5fc3fbd6 100644 --- a/apps/api/src/lexicon/index.ts +++ b/apps/api/src/lexicon/index.ts @@ -47,7 +47,6 @@ import type * as AppRockskyFeedGetFeed from "./types/app/rocksky/feed/getFeed"; import type * as AppRockskyFeedGetFeedGenerator from "./types/app/rocksky/feed/getFeedGenerator"; import type * as AppRockskyFeedGetFeedGenerators from "./types/app/rocksky/feed/getFeedGenerators"; import type * as AppRockskyFeedGetFeedSkeleton from "./types/app/rocksky/feed/getFeedSkeleton"; -import type * as AppRockskyFeedGetNowPlayings from "./types/app/rocksky/feed/getNowPlayings"; import type * as AppRockskyFeedGetStories from "./types/app/rocksky/feed/getStories"; import type * as AppRockskyFeedSearch from "./types/app/rocksky/feed/search"; import type * as AppRockskyGoogledriveDownloadFile from "./types/app/rocksky/googledrive/downloadFile"; @@ -698,17 +697,6 @@ export class AppRockskyFeedNS { return this._server.xrpc.method(nsid, cfg); } - getNowPlayings( - cfg: ConfigOf< - AV, - AppRockskyFeedGetNowPlayings.Handler>, - AppRockskyFeedGetNowPlayings.HandlerReqCtx> - >, - ) { - const nsid = "app.rocksky.feed.getNowPlayings"; // @ts-ignore - return this._server.xrpc.method(nsid, cfg); - } - getStories( cfg: ConfigOf< AV, diff --git a/apps/api/src/lexicon/lexicons.ts b/apps/api/src/lexicon/lexicons.ts index df63023f..c81b6c93 100644 --- a/apps/api/src/lexicon/lexicons.ts +++ b/apps/api/src/lexicon/lexicons.ts @@ -2548,75 +2548,6 @@ export const schemaDict = { }, }, }, - nowPlayingView: { - type: "object", - properties: { - album: { - type: "string", - }, - albumArt: { - type: "string", - format: "uri", - }, - albumArtist: { - type: "string", - }, - albumUri: { - type: "string", - format: "at-uri", - }, - artist: { - type: "string", - }, - artistUri: { - type: "string", - format: "at-uri", - }, - avatar: { - type: "string", - format: "uri", - }, - createdAt: { - type: "string", - }, - did: { - type: "string", - format: "at-identifier", - }, - handle: { - type: "string", - }, - id: { - type: "string", - }, - title: { - type: "string", - }, - trackId: { - type: "string", - }, - trackUri: { - type: "string", - format: "at-uri", - }, - uri: { - type: "string", - format: "at-uri", - }, - }, - }, - nowPlayingsView: { - type: "object", - properties: { - nowPlayings: { - type: "array", - items: { - type: "ref", - ref: "lex:app.rocksky.feed.defs#nowPlayingView", - }, - }, - }, - }, storyView: { type: "object", properties: { @@ -2990,34 +2921,6 @@ export const schemaDict = { }, }, }, - AppRockskyFeedGetNowPlayings: { - lexicon: 1, - id: "app.rocksky.feed.getNowPlayings", - defs: { - main: { - type: "query", - description: "Get all currently playing tracks by users", - parameters: { - type: "params", - properties: { - size: { - type: "integer", - description: - "The maximum number of now playing tracks to return.", - minimum: 1, - }, - }, - }, - output: { - encoding: "application/json", - schema: { - type: "ref", - ref: "lex:app.rocksky.feed.defs#nowPlayingsView", - }, - }, - }, - }, - }, AppRockskyFeedGetStories: { lexicon: 1, id: "app.rocksky.feed.getStories", @@ -6282,7 +6185,6 @@ export const ids = { AppRockskyFeedGetFeedGenerator: "app.rocksky.feed.getFeedGenerator", AppRockskyFeedGetFeedGenerators: "app.rocksky.feed.getFeedGenerators", AppRockskyFeedGetFeedSkeleton: "app.rocksky.feed.getFeedSkeleton", - AppRockskyFeedGetNowPlayings: "app.rocksky.feed.getNowPlayings", AppRockskyFeedGetStories: "app.rocksky.feed.getStories", AppRockskyFeedSearch: "app.rocksky.feed.search", AppRockskyGoogledriveDefs: "app.rocksky.googledrive.defs", diff --git a/apps/api/src/lexicon/types/app/rocksky/feed/defs.ts b/apps/api/src/lexicon/types/app/rocksky/feed/defs.ts index 6867ec93..30387f15 100644 --- a/apps/api/src/lexicon/types/app/rocksky/feed/defs.ts +++ b/apps/api/src/lexicon/types/app/rocksky/feed/defs.ts @@ -40,54 +40,6 @@ export function validateSearchResultsView(v: unknown): ValidationResult { return lexicons.validate("app.rocksky.feed.defs#searchResultsView", v); } -export interface NowPlayingView { - album?: string; - albumArt?: string; - albumArtist?: string; - albumUri?: string; - artist?: string; - artistUri?: string; - avatar?: string; - createdAt?: string; - did?: string; - handle?: string; - id?: string; - title?: string; - trackId?: string; - trackUri?: string; - uri?: string; - [k: string]: unknown; -} - -export function isNowPlayingView(v: unknown): v is NowPlayingView { - return ( - isObj(v) && - hasProp(v, "$type") && - v.$type === "app.rocksky.feed.defs#nowPlayingView" - ); -} - -export function validateNowPlayingView(v: unknown): ValidationResult { - return lexicons.validate("app.rocksky.feed.defs#nowPlayingView", v); -} - -export interface NowPlayingsView { - nowPlayings?: NowPlayingView[]; - [k: string]: unknown; -} - -export function isNowPlayingsView(v: unknown): v is NowPlayingsView { - return ( - isObj(v) && - hasProp(v, "$type") && - v.$type === "app.rocksky.feed.defs#nowPlayingsView" - ); -} - -export function validateNowPlayingsView(v: unknown): ValidationResult { - return lexicons.validate("app.rocksky.feed.defs#nowPlayingsView", v); -} - export interface StoryView { album?: string; albumArt?: string; diff --git a/apps/api/src/lexicon/types/app/rocksky/feed/getNowPlayings.ts b/apps/api/src/lexicon/types/app/rocksky/feed/getNowPlayings.ts deleted file mode 100644 index dd108561..00000000 --- a/apps/api/src/lexicon/types/app/rocksky/feed/getNowPlayings.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * GENERATED CODE - DO NOT MODIFY - */ -import type express from "express"; -import { ValidationResult, BlobRef } from "@atproto/lexicon"; -import { lexicons } from "../../../../lexicons"; -import { isObj, hasProp } from "../../../../util"; -import { CID } from "multiformats/cid"; -import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; -import type * as AppRockskyFeedDefs from "./defs"; - -export interface QueryParams { - /** The maximum number of now playing tracks to return. */ - size?: number; -} - -export type InputSchema = undefined; -export type OutputSchema = AppRockskyFeedDefs.NowPlayingsView; -export type HandlerInput = undefined; - -export interface HandlerSuccess { - encoding: "application/json"; - body: OutputSchema; - headers?: { [key: string]: string }; -} - -export interface HandlerError { - status: number; - message?: string; -} - -export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; -export type HandlerReqCtx = { - auth: HA; - params: QueryParams; - input: HandlerInput; - req: express.Request; - res: express.Response; - resetRouteRateLimits: () => Promise; -}; -export type Handler = ( - ctx: HandlerReqCtx, -) => Promise | HandlerOutput; diff --git a/apps/api/src/xrpc/app/rocksky/feed/getNowPlayings.ts b/apps/api/src/xrpc/app/rocksky/feed/getNowPlayings.ts deleted file mode 100644 index 6632e158..00000000 --- a/apps/api/src/xrpc/app/rocksky/feed/getNowPlayings.ts +++ /dev/null @@ -1,138 +0,0 @@ -import type { Context } from "context"; -import { consola } from "consola"; -import { desc, eq, sql } from "drizzle-orm"; -import { Cache, Duration, Effect, pipe } from "effect"; -import type { Server } from "lexicon"; -import type { NowPlayingView } from "lexicon/types/app/rocksky/feed/defs"; -import type { QueryParams } from "lexicon/types/app/rocksky/feed/getNowPlayings"; -import albums from "schema/albums"; -import artists from "schema/artists"; -import scrobbles from "schema/scrobbles"; -import tracks from "schema/tracks"; -import users from "schema/users"; - -export default function (server: Server, ctx: Context) { - const nowPlayingCache = Cache.make({ - capacity: 100, - timeToLive: Duration.seconds(30), - lookup: (params: QueryParams) => - pipe( - { params, ctx }, - retrieve, - Effect.map((data) => ({ data })), - Effect.flatMap(presentation), - Effect.retry({ times: 3 }), - Effect.timeout("120 seconds"), - ), - }); - - const getNowPlayings = (params) => - pipe( - nowPlayingCache, - Effect.flatMap((cache) => cache.get(params)), - Effect.catchAll((err) => { - consola.error(err); - return Effect.succeed({}); - }), - ); - server.app.rocksky.feed.getNowPlayings({ - handler: async ({ params }) => { - const result = await Effect.runPromise(getNowPlayings(params)); - return { - encoding: "application/json", - body: result, - }; - }, - }); -} - -const retrieve = ({ - params, - ctx, -}: { - params: QueryParams; - ctx: Context; -}): Effect.Effect => { - return Effect.tryPromise({ - try: () => - ctx.db - .select({ - xataId: scrobbles.id, - trackId: tracks.id, - title: tracks.title, - artist: tracks.artist, - albumArtist: tracks.albumArtist, - album: tracks.album, - albumArt: tracks.albumArt, - handle: users.handle, - did: users.did, - avatar: users.avatar, - uri: scrobbles.uri, - trackUri: tracks.uri, - artistUri: artists.uri, - albumUri: albums.uri, - timestamp: scrobbles.timestamp, - }) - .from(scrobbles) - .leftJoin(artists, eq(scrobbles.artistId, artists.id)) - .leftJoin(albums, eq(scrobbles.albumId, albums.id)) - .leftJoin(tracks, eq(scrobbles.trackId, tracks.id)) - .leftJoin(users, eq(scrobbles.userId, users.id)) - .where( - sql`scrobbles.xata_id IN ( - SELECT DISTINCT ON (inner_s.user_id) inner_s.xata_id - FROM scrobbles inner_s - ORDER BY inner_s.user_id, inner_s.timestamp DESC, inner_s.xata_id DESC - )`, - ) - .orderBy(desc(scrobbles.timestamp)) - .limit(params.size || 20) - .execute(), - catch: (error) => - new Error(`Failed to retrieve now playing songs: ${error}`), - }); -}; - -const presentation = ({ - data, -}: { - data: NowPlayingRecord[]; -}): Effect.Effect<{ nowPlayings: NowPlayingView[] }, never> => { - return Effect.sync(() => ({ - nowPlayings: data.map((record) => ({ - album: record.album, - albumArt: record.albumArt, - albumArtist: record.albumArtist, - albumUri: record.albumUri, - artist: record.artist, - artistUri: record.artistUri, - avatar: record.avatar, - createdAt: record.timestamp.toISOString(), - did: record.did, - handle: record.handle, - id: record.trackId, - title: record.title, - trackId: record.trackId, - trackUri: record.trackUri, - uri: record.uri, - })), - })); -}; - -type NowPlayingRecord = { - xataId: string; - trackId: string; - title: string; - artist: string; - albumArtist: string; - album: string; - albumArt: string; - handle: string; - did: string; - avatar: string; - uri: string; - trackUri: string; - artistUri: string; - albumUri: string; - timestamp: Date; -}; diff --git a/apps/api/src/xrpc/app/rocksky/feed/getStories.ts b/apps/api/src/xrpc/app/rocksky/feed/getStories.ts index f9517409..4ebefecb 100644 --- a/apps/api/src/xrpc/app/rocksky/feed/getStories.ts +++ b/apps/api/src/xrpc/app/rocksky/feed/getStories.ts @@ -26,7 +26,7 @@ export default function (server: Server, ctx: Context) { ), }); - const getNowPlayings = (params) => + const getStories = (params: QueryParams) => pipe( storiesCache, Effect.flatMap((cache) => cache.get(params)), @@ -37,7 +37,7 @@ export default function (server: Server, ctx: Context) { ); server.app.rocksky.feed.getStories({ handler: async ({ params }) => { - const result = await Effect.runPromise(getNowPlayings(params)); + const result = await Effect.runPromise(getStories(params)); return { encoding: "application/json", body: result, diff --git a/apps/api/src/xrpc/index.ts b/apps/api/src/xrpc/index.ts index 72d565b3..79fff020 100644 --- a/apps/api/src/xrpc/index.ts +++ b/apps/api/src/xrpc/index.ts @@ -24,7 +24,6 @@ import downloadFileFromDropbox from "./app/rocksky/dropbox/downloadFile"; import getFilesFromDropbox from "./app/rocksky/dropbox/getFiles"; import getMetadataFromDropbox from "./app/rocksky/dropbox/getMetadata"; import getTemporaryLinkFromDropbox from "./app/rocksky/dropbox/getTemporaryLink"; -import getNowPlayings from "./app/rocksky/feed/getNowPlayings"; import search from "./app/rocksky/feed/search"; import downloadFileFromGoogleDrive from "./app/rocksky/googledrive/downloadFile"; import getFileFromGoogleDrive from "./app/rocksky/googledrive/getFile"; @@ -113,7 +112,6 @@ export default function (server: Server, ctx: Context) { getFilesFromDropbox(server, ctx); getMetadataFromDropbox(server, ctx); getTemporaryLinkFromDropbox(server, ctx); - getNowPlayings(server, ctx); search(server, ctx); downloadFileFromGoogleDrive(server, ctx); getFilesFromGoogleDrive(server, ctx);