mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 10:15:31 +00:00
Migrate archiveFile graphql files to model
This commit is contained in:
parent
ba7989db9c
commit
ace904f357
7 changed files with 71 additions and 106 deletions
|
|
@ -1,81 +0,0 @@
|
|||
import { Int } from "grats";
|
||||
import ArchiveFileModel from "../../../data/ArchiveFileModel";
|
||||
import SkinModel from "../../../data/SkinModel";
|
||||
import { ISkin } from "./CommonSkinResolver";
|
||||
import SkinResolver from "./SkinResolver";
|
||||
|
||||
/**
|
||||
* A file found within a Winamp Skin's .wsz archive
|
||||
* @gqlType ArchiveFile
|
||||
*/
|
||||
export default class ArchiveFileResolver {
|
||||
_model: ArchiveFileModel;
|
||||
constructor(model: ArchiveFileModel) {
|
||||
this._model = model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filename of the file within the archive
|
||||
* @gqlField
|
||||
*/
|
||||
filename(): string {
|
||||
return this._model.getFileName();
|
||||
}
|
||||
/**
|
||||
* A URL to download the file. **Note:** This is powered by a little
|
||||
* serverless Cloudflare function which tries to exctact the file on the fly.
|
||||
* It may not work for all files.
|
||||
* @gqlField
|
||||
*/
|
||||
url(): string {
|
||||
return this._model.getUrl();
|
||||
}
|
||||
/**
|
||||
* The md5 hash of the file within the archive
|
||||
* @gqlField
|
||||
*/
|
||||
file_md5(): string {
|
||||
return this._model.getFileMd5();
|
||||
}
|
||||
/**
|
||||
* The uncompressed size of the file in bytes.
|
||||
*
|
||||
* **Note:** Will be `null` for directories
|
||||
* @gqlField
|
||||
*/
|
||||
size(): Promise<Int | null> {
|
||||
return this._model.getFileSize();
|
||||
}
|
||||
/**
|
||||
* The content of the file, if it's a text file
|
||||
* @gqlField
|
||||
*/
|
||||
text_content(): Promise<string | null> {
|
||||
return this._model.getTextContent();
|
||||
}
|
||||
/**
|
||||
* Is the file a directory?
|
||||
* @gqlField
|
||||
*/
|
||||
is_directory(): boolean {
|
||||
return this._model.getIsDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* The skin in which this file was found
|
||||
* @gqlField
|
||||
*/
|
||||
async skin(_: never, { ctx }): Promise<ISkin | null> {
|
||||
const model = await SkinModel.fromMd5Assert(ctx, this._model.getMd5());
|
||||
return SkinResolver.fromModel(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* The date on the file inside the archive. Given in simplified extended ISO
|
||||
* format (ISO 8601).
|
||||
* @gqlField
|
||||
*/
|
||||
date(): string {
|
||||
return this._model.getFileDate().toISOString();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,9 @@ import { NodeResolver, toId } from "./NodeResolver";
|
|||
import ReviewResolver from "./ReviewResolver";
|
||||
import path from "path";
|
||||
import { ID, Int } from "grats";
|
||||
import ArchiveFileResolver from "./ArchiveFileResolver";
|
||||
import InternetArchiveItemResolver from "./InternetArchiveItemResolver";
|
||||
import TweetModel from "../../../data/TweetModel";
|
||||
import ArchiveFileModel from "../../../data/ArchiveFileModel";
|
||||
|
||||
/**
|
||||
* A classic Winamp skin
|
||||
|
|
@ -70,7 +70,7 @@ export default class ClassicSkinResolver
|
|||
/**
|
||||
* List of files contained within the skin's .wsz archive
|
||||
* @gqlField */
|
||||
archive_files(): Promise<Array<ArchiveFileResolver | null>> {
|
||||
archive_files(): Promise<Array<ArchiveFileModel | null>> {
|
||||
return super.archive_files();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { ID } from "grats";
|
||||
import SkinModel from "../../../data/SkinModel";
|
||||
import ArchiveFileResolver from "./ArchiveFileResolver";
|
||||
import InternetArchiveItemResolver from "./InternetArchiveItemResolver";
|
||||
import ReviewResolver from "./ReviewResolver";
|
||||
import TweetModel from "../../../data/TweetModel";
|
||||
import ArchiveFileModel from "../../../data/ArchiveFileModel";
|
||||
|
||||
/**
|
||||
* A Winamp skin. Could be modern or classic.
|
||||
|
|
@ -63,7 +63,7 @@ export interface ISkin {
|
|||
* List of files contained within the skin's .wsz archive
|
||||
* @gqlField
|
||||
*/
|
||||
archive_files(): Promise<Array<ArchiveFileResolver | null>>;
|
||||
archive_files(): Promise<Array<ArchiveFileModel | null>>;
|
||||
|
||||
/**
|
||||
* The skin's "item" at archive.org
|
||||
|
|
@ -127,9 +127,8 @@ export default abstract class CommonSkinResolver {
|
|||
async tweets(): Promise<Array<TweetModel | null>> {
|
||||
return this._model.getTweets();
|
||||
}
|
||||
async archive_files(): Promise<Array<ArchiveFileResolver | null>> {
|
||||
const files = await this._model.getArchiveFiles();
|
||||
return files.map((file) => new ArchiveFileResolver(file));
|
||||
async archive_files(): Promise<Array<ArchiveFileModel | null>> {
|
||||
return this._model.getArchiveFiles();
|
||||
}
|
||||
async internet_archive_item(): Promise<InternetArchiveItemResolver | null> {
|
||||
const item = await this._model.getIaItem();
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import path from "path";
|
|||
import { ID } from "grats";
|
||||
import ReviewResolver from "./ReviewResolver";
|
||||
import InternetArchiveItemResolver from "./InternetArchiveItemResolver";
|
||||
import ArchiveFileResolver from "./ArchiveFileResolver";
|
||||
import { XMLParser } from "fast-xml-parser";
|
||||
import TweetModel from "../../../data/TweetModel";
|
||||
import ArchiveFileModel from "../../../data/ArchiveFileModel";
|
||||
|
||||
/**
|
||||
* A "modern" Winamp skin. These skins use the `.wal` file extension and are free-form.
|
||||
|
|
@ -78,7 +78,7 @@ export default class ModernSkinResolver
|
|||
/**
|
||||
* List of files contained within the skin's .wsz archive
|
||||
* @gqlField */
|
||||
async archive_files(): Promise<Array<ArchiveFileResolver | null>> {
|
||||
async archive_files(): Promise<Array<ArchiveFileModel | null>> {
|
||||
return super.archive_files();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import algoliasearch from "algoliasearch";
|
|||
import MutationResolver from "./MutationResolver";
|
||||
import { knex } from "../../../db";
|
||||
import ArchiveFileModel from "../../../data/ArchiveFileModel";
|
||||
import ArchiveFileResolver from "./ArchiveFileResolver";
|
||||
import DatabaseStatisticsResolver from "./DatabaseStatisticsResolver";
|
||||
import { fromId, NodeResolver } from "./NodeResolver";
|
||||
import ModernSkinsConnection from "../ModernSkinsConnection";
|
||||
|
|
@ -104,12 +103,8 @@ class RootResolver extends MutationResolver {
|
|||
async fetch_archive_file_by_md5(
|
||||
{ md5 }: { md5: string },
|
||||
{ ctx }
|
||||
): Promise<ArchiveFileResolver | null> {
|
||||
const archiveFile = await ArchiveFileModel.fromFileMd5(ctx, md5);
|
||||
if (archiveFile == null) {
|
||||
return null;
|
||||
}
|
||||
return new ArchiveFileResolver(archiveFile);
|
||||
): Promise<ArchiveFileModel | null> {
|
||||
return ArchiveFileModel.fromFileMd5(ctx, md5);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,29 +13,29 @@ type ArchiveFile {
|
|||
The date on the file inside the archive. Given in simplified extended ISO
|
||||
format (ISO 8601).
|
||||
"""
|
||||
date: String
|
||||
date: String @methodName(name: "getIsoDate")
|
||||
"""The md5 hash of the file within the archive"""
|
||||
file_md5: String
|
||||
file_md5: String @methodName(name: "getFileMd5")
|
||||
"""Filename of the file within the archive"""
|
||||
filename: String
|
||||
filename: String @methodName(name: "getFileName")
|
||||
"""Is the file a directory?"""
|
||||
is_directory: Boolean
|
||||
is_directory: Boolean @methodName(name: "getIsDirectory")
|
||||
"""
|
||||
The uncompressed size of the file in bytes.
|
||||
|
||||
**Note:** Will be `null` for directories
|
||||
"""
|
||||
size: Int
|
||||
size: Int @methodName(name: "getFileSize")
|
||||
"""The skin in which this file was found"""
|
||||
skin: Skin
|
||||
"""The content of the file, if it's a text file"""
|
||||
text_content: String
|
||||
text_content: String @methodName(name: "getTextContent")
|
||||
"""
|
||||
A URL to download the file. **Note:** This is powered by a little
|
||||
serverless Cloudflare function which tries to exctact the file on the fly.
|
||||
It may not work for all files.
|
||||
"""
|
||||
url: String
|
||||
url: String @methodName(name: "getUrl")
|
||||
}
|
||||
|
||||
"""A classic Winamp skin"""
|
||||
|
|
|
|||
|
|
@ -4,11 +4,18 @@ import DataLoader from "dataloader";
|
|||
import { knex } from "../db";
|
||||
import SkinModel from "./SkinModel";
|
||||
import FileInfoModel from "./FileInfoModel";
|
||||
import { ISkin } from "../api/graphql/resolvers/CommonSkinResolver";
|
||||
import SkinResolver from "../api/graphql/resolvers/SkinResolver";
|
||||
import { Int } from "grats";
|
||||
|
||||
export type ArchiveFileDebugData = {
|
||||
row: ArchiveFileRow;
|
||||
};
|
||||
|
||||
/**
|
||||
* A file found within a Winamp Skin's .wsz archive
|
||||
* @gqlType ArchiveFile
|
||||
*/
|
||||
export default class ArchiveFileModel {
|
||||
constructor(readonly ctx: UserContext, readonly row: ArchiveFileRow) {}
|
||||
|
||||
|
|
@ -38,10 +45,18 @@ export default class ArchiveFileModel {
|
|||
return this.row.skin_md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* The md5 hash of the file within the archive
|
||||
* @gqlField file_md5
|
||||
*/
|
||||
getFileMd5(): string {
|
||||
return this.row.file_md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filename of the file within the archive
|
||||
* @gqlField filename
|
||||
*/
|
||||
getFileName(): string {
|
||||
return this.row.file_name;
|
||||
}
|
||||
|
|
@ -50,8 +65,22 @@ export default class ArchiveFileModel {
|
|||
return new Date(this.row.file_date);
|
||||
}
|
||||
|
||||
// Null if directory
|
||||
async getFileSize(): Promise<number | null> {
|
||||
/**
|
||||
* The date on the file inside the archive. Given in simplified extended ISO
|
||||
* format (ISO 8601).
|
||||
* @gqlField date
|
||||
*/
|
||||
getIsoDate(): string {
|
||||
return this.getFileDate().toISOString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The uncompressed size of the file in bytes.
|
||||
*
|
||||
* **Note:** Will be `null` for directories
|
||||
* @gqlField size
|
||||
*/
|
||||
async getFileSize(): Promise<Int | null> {
|
||||
const info = await this._getFileInfo();
|
||||
if (info == null) {
|
||||
return null;
|
||||
|
|
@ -59,6 +88,10 @@ export default class ArchiveFileModel {
|
|||
return info.getFileSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* The content of the file, if it's a text file
|
||||
* @gqlField text_content
|
||||
*/
|
||||
async getTextContent(): Promise<string | null> {
|
||||
const info = await this._getFileInfo();
|
||||
if (info == null) {
|
||||
|
|
@ -67,10 +100,20 @@ export default class ArchiveFileModel {
|
|||
return info.getTextContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the file a directory?
|
||||
* @gqlField is_directory
|
||||
*/
|
||||
getIsDirectory(): boolean {
|
||||
return Boolean(this.row.is_directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* A URL to download the file. **Note:** This is powered by a little
|
||||
* serverless Cloudflare function which tries to exctact the file on the fly.
|
||||
* It may not work for all files.
|
||||
* @gqlField url
|
||||
*/
|
||||
getUrl(): string {
|
||||
const filename = encodeURIComponent(this.getFileName());
|
||||
return `https://zip-worker.jordan1320.workers.dev/zip/${this.getMd5()}/${filename}`;
|
||||
|
|
@ -80,6 +123,15 @@ export default class ArchiveFileModel {
|
|||
return SkinModel.fromMd5Assert(this.ctx, this.getMd5());
|
||||
}
|
||||
|
||||
/**
|
||||
* The skin in which this file was found
|
||||
* @gqlField skin
|
||||
*/
|
||||
async skin(): Promise<ISkin | null> {
|
||||
const model = await SkinModel.fromMd5Assert(this.ctx, this.getMd5());
|
||||
return SkinResolver.fromModel(model);
|
||||
}
|
||||
|
||||
// Let's try to keep this as an implementation detail
|
||||
async _getFileInfo(): Promise<FileInfoModel | null> {
|
||||
return FileInfoModel.fromFileMd5(this.ctx, this.getFileMd5());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue