mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 10:15:31 +00:00
566 lines
18 KiB
GraphQL
566 lines
18 KiB
GraphQL
# Schema generated by Grats (https://grats.capt.dev)
|
|
# Do not manually edit. Regenerate by running `npx grats`.
|
|
|
|
"""
|
|
Indicates that a position is semantically non null: it is only null if there is a matching error in the `errors` array.
|
|
In all other cases, the position is non-null.
|
|
|
|
Tools doing code generation may use this information to generate the position as non-null if field errors are handled out of band:
|
|
|
|
```graphql
|
|
type User {
|
|
# email is semantically non-null and can be generated as non-null by error-handling clients.
|
|
email: String @semanticNonNull
|
|
}
|
|
```
|
|
|
|
The `levels` argument indicates what levels are semantically non null in case of lists:
|
|
|
|
```graphql
|
|
type User {
|
|
# friends is semantically non null
|
|
friends: [User] @semanticNonNull # same as @semanticNonNull(levels: [0])
|
|
|
|
# every friends[k] is semantically non null
|
|
friends: [User] @semanticNonNull(levels: [1])
|
|
|
|
# friends as well as every friends[k] is semantically non null
|
|
friends: [User] @semanticNonNull(levels: [0, 1])
|
|
}
|
|
```
|
|
|
|
`levels` are zero indexed.
|
|
Passing a negative level or a level greater than the list dimension is an error.
|
|
"""
|
|
directive @semanticNonNull(levels: [Int] = [0]) on FIELD_DEFINITION
|
|
|
|
"""The judgement made about a skin by a moderator"""
|
|
enum Rating {
|
|
APPROVED
|
|
NSFW
|
|
REJECTED
|
|
}
|
|
|
|
"""
|
|
The current status of a pending upload.
|
|
|
|
**Note:** Expect more values here as we try to be more transparent about
|
|
the status of a pending uploads.
|
|
"""
|
|
enum SkinUploadStatus {
|
|
ARCHIVED
|
|
DELAYED
|
|
ERRORED
|
|
UPLOAD_REPORTED
|
|
URL_REQUESTED
|
|
}
|
|
|
|
enum SkinsFilterOption {
|
|
APPROVED
|
|
NSFW
|
|
REJECTED
|
|
TWEETED
|
|
}
|
|
|
|
enum SkinsSortOption {
|
|
MUSEUM
|
|
}
|
|
|
|
enum TweetsSortOption {
|
|
LIKES
|
|
RETWEETS
|
|
}
|
|
|
|
"""
|
|
A globally unique object. The `id` here is intended only for use within
|
|
GraphQL.
|
|
https://graphql.org/learn/global-object-identification/
|
|
"""
|
|
interface Node {
|
|
id: ID!
|
|
}
|
|
|
|
"""A Winamp skin. Could be modern or classic."""
|
|
interface Skin {
|
|
"""List of files contained within the skin's .wsz archive"""
|
|
archive_files: [ArchiveFile] @semanticNonNull
|
|
"""String representation (rgb usually) of the skin's average color"""
|
|
average_color: String
|
|
"""URL to download the skin"""
|
|
download_url: String @semanticNonNull
|
|
"""
|
|
Filename of skin when uploaded to the Museum. Note: In some cases a skin
|
|
has been uploaded under multiple names. Here we just pick one.
|
|
"""
|
|
filename(
|
|
"""
|
|
If true, the museum ID will be appended to the filename to ensure filenames are globally unique.
|
|
"""
|
|
include_museum_id: Boolean! = false
|
|
"""
|
|
If true, the the correct file extension (.wsz or .wal) will be .
|
|
Otherwise, the original user-uploaded file extension will be used.
|
|
"""
|
|
normalize_extension: Boolean! = false
|
|
): String @semanticNonNull
|
|
"""GraphQL ID of the skin"""
|
|
id: ID!
|
|
"""The skin's "item" at archive.org"""
|
|
internet_archive_item: InternetArchiveItem
|
|
"""MD5 hash of the skin's file"""
|
|
md5: String @semanticNonNull
|
|
"""URL of the skin on the Winamp Skin Museum"""
|
|
museum_url: String
|
|
"""
|
|
Has the skin been flagged as "not safe for work"?"
|
|
"""
|
|
nsfw: Boolean
|
|
"""Text of the readme file extracted from the skin"""
|
|
readme_text: String
|
|
"""
|
|
Times that the skin has been reviewed either on the Museum's Tinder-style
|
|
review page, or via the Discord bot.
|
|
"""
|
|
reviews: [Review] @semanticNonNull
|
|
"""URL of a screenshot of the skin"""
|
|
screenshot_url: String
|
|
"""Has the skin been tweeted?"""
|
|
tweeted: Boolean @semanticNonNull
|
|
"""List of"""
|
|
tweets: [Tweet] @semanticNonNull
|
|
"""URL of webamp.org with the skin loaded"""
|
|
webamp_url: String
|
|
}
|
|
|
|
"""Input object used for a user to request an UploadUrl"""
|
|
input UploadUrlRequest {
|
|
filename: String!
|
|
md5: String!
|
|
}
|
|
|
|
"""A file found within a Winamp Skin's .wsz archive"""
|
|
type ArchiveFile {
|
|
"""
|
|
The date on the file inside the archive. Given in simplified extended ISO
|
|
format (ISO 8601).
|
|
"""
|
|
date: String @semanticNonNull
|
|
"""The md5 hash of the file within the archive"""
|
|
file_md5: String @semanticNonNull
|
|
"""Filename of the file within the archive"""
|
|
filename: String @semanticNonNull
|
|
"""Is the file a directory?"""
|
|
is_directory: Boolean @semanticNonNull
|
|
"""
|
|
The uncompressed size of the file in bytes.
|
|
|
|
**Note:** Will be `null` for directories
|
|
"""
|
|
size: Int
|
|
"""The skin in which this file was found"""
|
|
skin: Skin
|
|
"""The content of the file, if it's a text file"""
|
|
text_content: String
|
|
"""
|
|
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
|
|
}
|
|
|
|
"""Connection for bulk download skin metadata"""
|
|
type BulkDownloadConnection {
|
|
"""Estimated total size in bytes (approximation for progress indication)"""
|
|
estimatedSizeBytes: String @semanticNonNull
|
|
"""List of skin metadata for bulk download"""
|
|
nodes: [Skin!] @semanticNonNull
|
|
"""Total number of skins available for download"""
|
|
totalCount: Int @semanticNonNull
|
|
}
|
|
|
|
"""A classic Winamp skin"""
|
|
type ClassicSkin implements Node & Skin {
|
|
"""List of files contained within the skin's .wsz archive"""
|
|
archive_files: [ArchiveFile] @semanticNonNull
|
|
"""String representation (rgb usually) of the skin's average color"""
|
|
average_color: String
|
|
"""URL to download the skin"""
|
|
download_url: String @semanticNonNull
|
|
"""
|
|
Filename of skin when uploaded to the Museum. Note: In some cases a skin
|
|
has been uploaded under multiple names. Here we just pick one.
|
|
"""
|
|
filename(
|
|
"""
|
|
If true, the museum ID will be appended to the filename to ensure filenames are globally unique.
|
|
"""
|
|
include_museum_id: Boolean! = false
|
|
"""
|
|
If true, the the correct file extension (.wsz or .wal) will be .
|
|
Otherwise, the original user-uploaded file extension will be used.
|
|
"""
|
|
normalize_extension: Boolean! = false
|
|
): String @semanticNonNull
|
|
"""Does the skin include sprite sheets for the media library?"""
|
|
has_media_library: Boolean @semanticNonNull
|
|
"""GraphQL ID of the skin"""
|
|
id: ID!
|
|
"""The skin's "item" at archive.org"""
|
|
internet_archive_item: InternetArchiveItem
|
|
"""
|
|
The date on which this skin was last updated in the Algolia search index.
|
|
Given in simplified extended ISO format (ISO 8601).
|
|
"""
|
|
last_algolia_index_update_date: String
|
|
"""MD5 hash of the skin's file"""
|
|
md5: String @semanticNonNull
|
|
"""URL of the skin on the Winamp Skin Museum"""
|
|
museum_url: String
|
|
"""
|
|
Has the skin been flagged as "not safe for work"?"
|
|
"""
|
|
nsfw: Boolean
|
|
"""Text of the readme file extracted from the skin"""
|
|
readme_text: String
|
|
"""
|
|
Times that the skin has been reviewed either on the Museum's Tinder-style
|
|
review page, or via the Discord bot.
|
|
"""
|
|
reviews: [Review] @semanticNonNull
|
|
"""URL of a screenshot of the skin"""
|
|
screenshot_url: String
|
|
"""The number of transparent pixels rendered by the skin."""
|
|
transparent_pixels: Int @semanticNonNull
|
|
"""Has the skin been tweeted?"""
|
|
tweeted: Boolean @semanticNonNull
|
|
"""List of"""
|
|
tweets: [Tweet] @semanticNonNull
|
|
"""URL of webamp.org with the skin loaded"""
|
|
webamp_url: String
|
|
}
|
|
|
|
"""Statistics about the contents of the Museum's database."""
|
|
type DatabaseStatistics {
|
|
"""
|
|
The number of skins that have been approved for tweeting. This includes both
|
|
tweeted and untweeted skins.
|
|
|
|
**Note:** Skins can be both approved and rejected by different users.
|
|
"""
|
|
approved_skins_count: Int @semanticNonNull
|
|
"""
|
|
The number of skins that have been marked as NSFW.
|
|
|
|
**Note:** Skins can be approved and rejected by different users.
|
|
**Note:** Generally skins that have been marked NSFW are also marked as rejected.
|
|
"""
|
|
nsfw_skins_count: Int @semanticNonNull
|
|
"""
|
|
The number of skins that have been rejected for tweeting.
|
|
|
|
**Note:** Skins can be both approved and rejected by different users.
|
|
**Note:** Generally skins that have been marked NSFW are also marked as rejected.
|
|
"""
|
|
rejected_skins_count: Int @semanticNonNull
|
|
"""
|
|
The number of skins that have been approved for tweeting, but not yet tweeted.
|
|
"""
|
|
tweetable_skins_count: Int @semanticNonNull
|
|
"""The number of skins in the Museum that have been tweeted by"""
|
|
tweeted_skins_count: Int @semanticNonNull
|
|
"""The total number of classic skins in the Museum's database"""
|
|
unique_classic_skins_count: Int @semanticNonNull
|
|
"""The number of skins that have never been reviewed."""
|
|
unreviewed_skins_count: Int @semanticNonNull
|
|
"""Skins uploads that have errored during processing."""
|
|
uploads_in_error_state_count: Int @semanticNonNull
|
|
"""
|
|
Skins uplaods awaiting processing. This can happen when there are a large
|
|
number of skin uplaods at the same time, or when the skin uploading processing
|
|
pipeline gets stuck.
|
|
"""
|
|
uploads_pending_processing_count: Int @semanticNonNull
|
|
"""
|
|
Number of skins that have been uploaded to the Museum via the web interface.
|
|
"""
|
|
web_uploads_count: Int @semanticNonNull
|
|
}
|
|
|
|
type InternetArchiveItem {
|
|
"""The Internet Archive's unique identifier for this item"""
|
|
identifier: String @semanticNonNull
|
|
"""
|
|
The date and time that we last scraped this item's metadata.
|
|
**Note:** This field is temporary and will be removed in the future.
|
|
The date format is just what we get from the database, and it's ambiguous.
|
|
"""
|
|
last_metadata_scrape_date_UNSTABLE: String
|
|
"""URL to get the Internet Archive's metadata for this item in JSON form."""
|
|
metadata_url: String @semanticNonNull
|
|
"""
|
|
Our cached version of the metadata available at \`metadata_url\` (above)
|
|
"""
|
|
raw_metadata_json: String
|
|
"""The skin that this item contains"""
|
|
skin: Skin
|
|
"""The URL where this item can be viewed on the Internet Archive"""
|
|
url: String @semanticNonNull
|
|
}
|
|
|
|
"""
|
|
A "modern" Winamp skin. These skins use the `.wal` file extension and are free-form.
|
|
|
|
Most functionality in the Winamp Skin Museum is centered around "classic" skins,
|
|
which are currently called just `Skin` in this schema.
|
|
"""
|
|
type ModernSkin implements Node & Skin {
|
|
"""List of files contained within the skin's .wsz archive"""
|
|
archive_files: [ArchiveFile] @semanticNonNull
|
|
"""String representation (rgb usually) of the skin's average color"""
|
|
average_color: String
|
|
"""URL to download the skin"""
|
|
download_url: String @semanticNonNull
|
|
"""
|
|
Filename of skin when uploaded to the Museum. Note: In some cases a skin
|
|
has been uploaded under multiple names. Here we just pick one.
|
|
"""
|
|
filename(
|
|
"""
|
|
If true, the museum ID will be appended to the filename to ensure filenames are globally unique.
|
|
"""
|
|
include_museum_id: Boolean! = false
|
|
"""
|
|
If true, the the correct file extension (.wsz or .wal) will be .
|
|
Otherwise, the original user-uploaded file extension will be used.
|
|
"""
|
|
normalize_extension: Boolean! = false
|
|
): String @semanticNonNull
|
|
"""GraphQL ID of the skin"""
|
|
id: ID!
|
|
"""The skin's "item" at archive.org"""
|
|
internet_archive_item: InternetArchiveItem
|
|
"""MD5 hash of the skin's file"""
|
|
md5: String @semanticNonNull
|
|
"""URL of the skin on the Winamp Skin Museum"""
|
|
museum_url: String
|
|
"""
|
|
Has the skin been flagged as "not safe for work"?"
|
|
"""
|
|
nsfw: Boolean
|
|
"""Text of the readme file extracted from the skin"""
|
|
readme_text: String
|
|
"""
|
|
Times that the skin has been reviewed either on the Museum's Tinder-style
|
|
review page, or via the Discord bot.
|
|
"""
|
|
reviews: [Review] @semanticNonNull
|
|
"""URL of a screenshot of the skin"""
|
|
screenshot_url: String
|
|
"""Has the skin been tweeted?"""
|
|
tweeted: Boolean @semanticNonNull
|
|
"""List of"""
|
|
tweets: [Tweet] @semanticNonNull
|
|
"""URL of webamp.org with the skin loaded"""
|
|
webamp_url: String
|
|
}
|
|
|
|
"""A collection of "modern" Winamp skins"""
|
|
type ModernSkinsConnection {
|
|
"""The total number of skins matching the filter"""
|
|
count: Int @semanticNonNull
|
|
"""The list of skins"""
|
|
nodes: [ModernSkin] @semanticNonNull
|
|
}
|
|
|
|
type Mutation {
|
|
"""
|
|
Approve skin for tweeting
|
|
|
|
**Note:** Requires being logged in
|
|
"""
|
|
approve_skin(md5: String!): Boolean @semanticNonNull
|
|
"""
|
|
Mark a skin as NSFW
|
|
|
|
**Note:** Requires being logged in
|
|
"""
|
|
mark_skin_nsfw(md5: String!): Boolean @semanticNonNull
|
|
"""
|
|
Reject skin for tweeting
|
|
|
|
**Note:** Requires being logged in
|
|
"""
|
|
reject_skin(md5: String!): Boolean @semanticNonNull
|
|
"""
|
|
Request that an admin check if this skin is NSFW.
|
|
Unlike other review mutation endpoints, this one does not require being logged
|
|
in.
|
|
"""
|
|
request_nsfw_review_for_skin(md5: String!): Boolean @semanticNonNull
|
|
"""
|
|
Send a message to the admin of the site. Currently this appears in Discord.
|
|
"""
|
|
send_feedback(email: String, message: String!, url: String): Boolean @semanticNonNull
|
|
"""Mutations for the upload flow"""
|
|
upload: UploadMutations @semanticNonNull
|
|
}
|
|
|
|
type Query {
|
|
"""Get metadata for bulk downloading all skins in the museum"""
|
|
bulkDownload(first: Int! = 1000, offset: Int! = 0): BulkDownloadConnection @semanticNonNull
|
|
"""
|
|
Fetch archive file by it's MD5 hash
|
|
|
|
Get information about a file found within a skin's wsz/wal/zip archive.
|
|
"""
|
|
fetch_archive_file_by_md5(md5: String!): ArchiveFile
|
|
"""
|
|
Get an archive.org item by its identifier. You can find this in the URL:
|
|
|
|
https://archive.org/details/<identifier>/
|
|
"""
|
|
fetch_internet_archive_item_by_identifier(identifier: String!): InternetArchiveItem
|
|
"""Get a skin by its MD5 hash"""
|
|
fetch_skin_by_md5(md5: String!): Skin
|
|
"""Get a tweet by its URL"""
|
|
fetch_tweet_by_url(url: String!): Tweet
|
|
"""The currently authenticated user, if any."""
|
|
me: User
|
|
"""All modern skins in the database"""
|
|
modern_skins(first: Int! = 10, offset: Int! = 0): ModernSkinsConnection @semanticNonNull
|
|
"""
|
|
Get a globally unique object by its ID.
|
|
|
|
https://graphql.org/learn/global-object-identification/
|
|
"""
|
|
node(id: ID!): Node
|
|
"""
|
|
Search the database using SQLite's FTS (full text search) index.
|
|
|
|
Useful for locating a particular skin.
|
|
"""
|
|
search_classic_skins(first: Int! = 10, offset: Int! = 0, query: String!): [ClassicSkin] @semanticNonNull
|
|
"""
|
|
Search the database using the Algolia search index used by the Museum.
|
|
|
|
Useful for locating a particular skin.
|
|
"""
|
|
search_skins(first: Int! = 10, offset: Int! = 0, query: String!): [Skin] @semanticNonNull
|
|
"""A random skin that needs to be reviewed"""
|
|
skin_to_review: Skin
|
|
"""
|
|
All classic skins in the database
|
|
|
|
**Note:** We don't currently support combining sorting and filtering.
|
|
"""
|
|
skins(filter: SkinsFilterOption, first: Int! = 10, offset: Int! = 0, sort: SkinsSortOption): SkinsConnection @semanticNonNull
|
|
"""A namespace for statistics about the database"""
|
|
statistics: DatabaseStatistics @semanticNonNull
|
|
"""Tweets tweeted by"""
|
|
tweets(first: Int! = 10, offset: Int! = 0, sort: TweetsSortOption): TweetsConnection @semanticNonNull
|
|
"""Get the status of a batch of uploads by ids"""
|
|
upload_statuses(ids: [String!]!): [SkinUpload] @semanticNonNull
|
|
"""Get the status of a batch of uploads by md5s"""
|
|
upload_statuses_by_md5(md5s: [String!]!): [SkinUpload] @deprecated(reason: "Prefer `upload_statuses` instead, were we operate on ids.") @semanticNonNull
|
|
}
|
|
|
|
"""
|
|
A review of a skin. Done either on the Museum's Tinder-style
|
|
reivew page, or via the Discord bot.
|
|
"""
|
|
type Review {
|
|
"""The rating that the user gave the skin"""
|
|
rating: Rating @semanticNonNull
|
|
"""
|
|
The user who made the review (if known). **Note:** In the early days we didn't
|
|
track this, so many will be null.
|
|
"""
|
|
reviewer: String @semanticNonNull
|
|
"""The skin that was reviewed"""
|
|
skin: Skin
|
|
}
|
|
|
|
"""Information about an attempt to upload a skin to the Museum."""
|
|
type SkinUpload {
|
|
id: String @semanticNonNull
|
|
"""
|
|
Skin that was uploaded. **Note:** This is null if the skin has not yet been
|
|
fully processed. (status == ARCHIVED)
|
|
"""
|
|
skin: Skin
|
|
status: SkinUploadStatus @semanticNonNull
|
|
"""Md5 hash given when requesting the upload URL."""
|
|
upload_md5: String @semanticNonNull
|
|
}
|
|
|
|
"""A collection of classic Winamp skins"""
|
|
type SkinsConnection {
|
|
"""The total number of skins matching the filter"""
|
|
count: Int @semanticNonNull
|
|
"""The list of skins"""
|
|
nodes: [Skin] @semanticNonNull
|
|
}
|
|
|
|
"""A tweet made by"""
|
|
type Tweet {
|
|
"""
|
|
Number of likes the tweet has received. Updated nightly. (Note: Recent likes on older tweets may not be reflected here)
|
|
"""
|
|
likes: Int @semanticNonNull
|
|
"""
|
|
Number of retweets the tweet has received. Updated nightly. (Note: Recent retweets on older tweets may not be reflected here)
|
|
"""
|
|
retweets: Int @semanticNonNull
|
|
"""The skin featured in this Tweet"""
|
|
skin: Skin
|
|
"""
|
|
URL of the tweet. **Note:** Early on in the bot's life we just recorded
|
|
_which_ skins were tweeted, not any info about the actual tweet. This means we
|
|
don't always know the URL of the tweet.
|
|
"""
|
|
url: String
|
|
}
|
|
|
|
"""A collection of tweets made by the"""
|
|
type TweetsConnection {
|
|
"""The total number of tweets"""
|
|
count: Int @semanticNonNull
|
|
"""The list of tweets"""
|
|
nodes: [Tweet] @semanticNonNull
|
|
}
|
|
|
|
"""
|
|
Mutations for the upload flow
|
|
|
|
1. The user finds the md5 hash of their local files.
|
|
2. (`get_upload_urls`) The user requests upload URLs for each of their files.
|
|
3. The server returns upload URLs for each of their files which are not already in the collection.
|
|
4. The user uploads each of their files to the URLs returned in step 3.
|
|
5. (`report_skin_uploaded`) The user notifies the server that they're done uploading.
|
|
6. (TODO) The user polls for the status of their uploads.
|
|
"""
|
|
type UploadMutations {
|
|
"""
|
|
Get a (possibly incomplete) list of UploadUrls for each of the files. If an
|
|
UploadUrl is not returned for a given hash, it means the file is already in
|
|
the collection.
|
|
"""
|
|
get_upload_urls(files: [UploadUrlRequest!]!): [UploadUrl] @semanticNonNull
|
|
"""Notify the server that the user is done uploading."""
|
|
report_skin_uploaded(id: String!, md5: String!): Boolean @semanticNonNull
|
|
}
|
|
|
|
"""
|
|
A URL that the client can use to upload a skin to S3, and then notify the server
|
|
when they're done.
|
|
"""
|
|
type UploadUrl {
|
|
id: String @semanticNonNull
|
|
md5: String @semanticNonNull
|
|
url: String @semanticNonNull
|
|
}
|
|
|
|
type User {
|
|
username: String
|
|
}
|