From b224b627e3e772468a546d3ceac4b7fa3ea5fdb7 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sat, 1 Oct 2022 14:21:46 -0700 Subject: [PATCH] Search filter exploration --- packages/skin-database/Search filter ideas | 22 +++++ .../graphql/resolvers/ClassicSkinResolver.ts | 3 + .../skin-database/api/graphql/schema.graphql | 5 ++ .../skin-database/data/ArchiveFileModel.ts | 1 - packages/skin-database/data/SkinModel.ts | 81 +++++++++++++++++++ 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 packages/skin-database/Search filter ideas diff --git a/packages/skin-database/Search filter ideas b/packages/skin-database/Search filter ideas new file mode 100644 index 00000000..02af5a01 --- /dev/null +++ b/packages/skin-database/Search filter ideas @@ -0,0 +1,22 @@ +// Built in windows +filter:equalizer // includes eqmain.bmp +filter:playlist // includes pledit.bmp +filter:browser // includes mb.bmp +filter:general // Includes gen.bmp and genex.bmp (you need both right?) +filter:library // Alias of filter:general (Should there be other aliases of general?) +filter:video // Includes video.bmp + + +// Cursors +filter:cur // Includes at least one .cur file +filter:ani // Includes at least one .ani file (we could try to get fancy here and try to check for .ani files named .cur) + +// Other attributes +filter:transparency // Includes region.txt (we could get fancy and ensure it has actual points) + +// Plugins +filter:milkdrop // Alias of filter:general +filter:mikro // Includes mikro.bmp (Should this also require winampmb.txt? Or maybe either?) +filter:vidamp // Incldues vidamp.bmp +filter:avs // Includes avs.bmp + diff --git a/packages/skin-database/api/graphql/resolvers/ClassicSkinResolver.ts b/packages/skin-database/api/graphql/resolvers/ClassicSkinResolver.ts index 21b9f0bd..37dab4be 100644 --- a/packages/skin-database/api/graphql/resolvers/ClassicSkinResolver.ts +++ b/packages/skin-database/api/graphql/resolvers/ClassicSkinResolver.ts @@ -28,6 +28,9 @@ export default class ClassicSkinResolver average_color() { return this._model.getAverageColor(); } + has_media_library(): Promise { + return this._model.hasMediaLibrary(); + } async reviews() { const reviews = await this._model.getReviews(); return reviews.map((row) => new ReviewResolver(row)); diff --git a/packages/skin-database/api/graphql/schema.graphql b/packages/skin-database/api/graphql/schema.graphql index 324a1482..f97665f4 100644 --- a/packages/skin-database/api/graphql/schema.graphql +++ b/packages/skin-database/api/graphql/schema.graphql @@ -206,6 +206,11 @@ type ClassicSkin implements Skin & Node { """ archive_files: [ArchiveFile] + """ + Does the skin include sprite sheets for the media library? + """ + has_media_library: Boolean + """ The skin's "item" at archive.org """ diff --git a/packages/skin-database/data/ArchiveFileModel.ts b/packages/skin-database/data/ArchiveFileModel.ts index 66d303a7..c891d9a5 100644 --- a/packages/skin-database/data/ArchiveFileModel.ts +++ b/packages/skin-database/data/ArchiveFileModel.ts @@ -64,7 +64,6 @@ export default class ArchiveFileModel { if (info == null) { return null; } - console.log("info", info); return info.getTextContent(); } diff --git a/packages/skin-database/data/SkinModel.ts b/packages/skin-database/data/SkinModel.ts index a8d9fb9d..b416edcf 100644 --- a/packages/skin-database/data/SkinModel.ts +++ b/packages/skin-database/data/SkinModel.ts @@ -267,6 +267,87 @@ export default class SkinModel { return withUrlAsTempFile(this.getSkinUrl(), filename, cb); } + async _hasSpriteSheet(base: string): Promise { + const ext = "(bmp)|(png)"; + return this._hasFile(base, ext); + } + + async _hasFile(base: string, ext: string): Promise { + // TODO: Pre-compile regexp + const matcher = new RegExp(`^(.*[/\\\\])?${base}.(${ext})$`, "i"); + const archiveFiles = await this.getArchiveFiles(); + return archiveFiles.some((file) => { + return matcher.test(file.getFileName()); + }); + } + + /** + * + * @returns + */ + async hasMediaLibrary(): Promise { + return this.hasGeneral(); + } + + async hasMiniBrowser(): Promise { + return this._hasSpriteSheet("MB"); + } + + async hasAVS(): Promise { + return this._hasSpriteSheet("AVS"); + } + + async hasVideo(): Promise { + return this._hasSpriteSheet("VIDEO"); + } + + // Has built-in support for the MikroAMP plugin. + async hasMikro(): Promise { + // Could also check for `WINAMPMB.TXT`. + return this._hasSpriteSheet("MIKRO"); + } + + // Has built-in support of the Amarok plugin. + async hasAmarok(): Promise { + return this._hasSpriteSheet("AMAROK"); + } + + // Has built-in support of the vidamp + async hasVidamp(): Promise { + return this._hasSpriteSheet("VIDAMP"); + } + + // Includes custom cursors + async hasCur(): Promise { + const matcher = new RegExp(`^.(cur)$`, "i"); + const archiveFiles = await this.getArchiveFiles(); + return archiveFiles.some((file) => { + return matcher.test(file.getFileName()); + }); + } + + // Has transparency + async hasTransparency(): Promise { + return this._hasFile("region", "txt"); + } + + async hasAni(): Promise { + // Note: This should be expanded to check for animated cursors that use the + // .cur extension (but are actually .ani under the hood). + const matcher = new RegExp(`^.(ani)$`, "i"); + const archiveFiles = await this.getArchiveFiles(); + return archiveFiles.some((file) => { + return matcher.test(file.getFileName()); + }); + } + + async hasGeneral(): Promise { + return ( + (await this._hasSpriteSheet("GEN")) && + (await this._hasSpriteSheet("GENEX")) + ); + } + async withScreenshotTempFile( cb: (file: string) => Promise ): Promise {