From 5bb188a822499613dcfdd4bf54bca2092eba1e43 Mon Sep 17 00:00:00 2001
From: Geometrically <18202329+Geometrically@users.noreply.github.com>
Date: Thu, 29 Dec 2022 17:20:50 -0700
Subject: [PATCH] Project Colors (#512)
* Inital tests
* Finish project colors
* Run fmt + clippy + prepare
* Fix dp+rp fmting
---
.idea/sqldialects.xml | 6 -
Cargo.lock | 270 ++-
Cargo.toml | 3 +
migrations/20221227010515_project-colors.sql | 2 +
sqlx-data.json | 2088 +++++++++---------
src/database/models/project_item.rs | 22 +-
src/models/projects.rs | 4 +
src/routes/mod.rs | 7 +
src/routes/project_creation.rs | 23 +-
src/routes/projects.rs | 10 +-
src/search/indexing/local_import.rs | 3 +-
src/search/mod.rs | 2 +
src/util/ext.rs | 5 +-
src/util/img.rs | 19 +
src/util/mod.rs | 1 +
src/util/webhook.rs | 19 +-
16 files changed, 1422 insertions(+), 1062 deletions(-)
delete mode 100644 .idea/sqldialects.xml
create mode 100644 migrations/20221227010515_project-colors.sql
create mode 100644 src/util/img.rs
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
deleted file mode 100644
index 6df4889b0..000000000
--- a/.idea/sqldialects.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 77398bf0c..938439ade 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -432,7 +432,7 @@ dependencies = [
"cc",
"cfg-if",
"libc",
- "miniz_oxide",
+ "miniz_oxide 0.5.4",
"object",
"rustc-demangle",
]
@@ -464,6 +464,12 @@ dependencies = [
"serde",
]
+[[package]]
+name = "bit_field"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
+
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -515,6 +521,12 @@ version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+[[package]]
+name = "bytemuck"
+version = "1.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f"
+
[[package]]
name = "byteorder"
version = "1.4.3"
@@ -634,6 +646,21 @@ dependencies = [
"unicode-width",
]
+[[package]]
+name = "color-thief"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6460d760cf38ce67c9e0318f896538820acc54f2d0a3bfc5b2c557211066c98"
+dependencies = [
+ "rgb",
+]
+
+[[package]]
+name = "color_quant"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+
[[package]]
name = "concurrent-queue"
version = "1.2.4"
@@ -725,6 +752,30 @@ dependencies = [
"crossbeam-utils",
]
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "crossbeam-utils",
+ "memoffset",
+ "scopeguard",
+]
+
[[package]]
name = "crossbeam-queue"
version = "0.3.6"
@@ -744,6 +795,12 @@ dependencies = [
"cfg-if",
]
+[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
[[package]]
name = "crypto-common"
version = "0.1.6"
@@ -999,6 +1056,21 @@ version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
+[[package]]
+name = "exr"
+version = "1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded"
+dependencies = [
+ "bit_field",
+ "flume",
+ "half",
+ "lebe",
+ "miniz_oxide 0.6.2",
+ "smallvec",
+ "threadpool",
+]
+
[[package]]
name = "fastrand"
version = "1.8.0"
@@ -1015,7 +1087,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
dependencies = [
"crc32fast",
- "miniz_oxide",
+ "miniz_oxide 0.5.4",
+]
+
+[[package]]
+name = "flume"
+version = "0.10.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+ "nanorand",
+ "pin-project",
+ "spin 0.9.4",
]
[[package]]
@@ -1186,8 +1271,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
+ "js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "gif"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06"
+dependencies = [
+ "color_quant",
+ "weezl",
]
[[package]]
@@ -1215,6 +1312,15 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "half"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554"
+dependencies = [
+ "crunchy",
+]
+
[[package]]
name = "hashbrown"
version = "0.12.3"
@@ -1430,6 +1536,25 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
+[[package]]
+name = "image"
+version = "0.24.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+ "color_quant",
+ "exr",
+ "gif",
+ "jpeg-decoder",
+ "num-rational",
+ "num-traits",
+ "png",
+ "scoped_threadpool",
+ "tiff",
+]
+
[[package]]
name = "indexmap"
version = "1.9.1"
@@ -1525,6 +1650,15 @@ dependencies = [
"libc",
]
+[[package]]
+name = "jpeg-decoder"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
+dependencies = [
+ "rayon",
+]
+
[[package]]
name = "js-sys"
version = "0.3.60"
@@ -1549,6 +1683,7 @@ dependencies = [
"bytes",
"censor",
"chrono",
+ "color-thief",
"dashmap",
"dotenvy",
"env_logger",
@@ -1556,6 +1691,7 @@ dependencies = [
"futures-timer",
"hex",
"hmac 0.11.0",
+ "image",
"itertools 0.10.5",
"lazy_static",
"log",
@@ -1598,6 +1734,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+[[package]]
+name = "lebe"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
+
[[package]]
name = "lexical-core"
version = "0.7.6"
@@ -1764,6 +1906,15 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+[[package]]
+name = "memoffset"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
+dependencies = [
+ "autocfg",
+]
+
[[package]]
name = "mime"
version = "0.3.16"
@@ -1804,6 +1955,15 @@ dependencies = [
"adler",
]
+[[package]]
+name = "miniz_oxide"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
+dependencies = [
+ "adler",
+]
+
[[package]]
name = "mio"
version = "0.8.5"
@@ -1816,6 +1976,15 @@ dependencies = [
"windows-sys 0.42.0",
]
+[[package]]
+name = "nanorand"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
+dependencies = [
+ "getrandom",
+]
+
[[package]]
name = "native-tls"
version = "0.2.10"
@@ -1876,6 +2045,17 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "num-rational"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
[[package]]
name = "num-traits"
version = "0.2.15"
@@ -2119,6 +2299,18 @@ version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
+[[package]]
+name = "png"
+version = "0.17.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638"
+dependencies = [
+ "bitflags",
+ "crc32fast",
+ "flate2",
+ "miniz_oxide 0.6.2",
+]
+
[[package]]
name = "polling"
version = "2.4.0"
@@ -2220,6 +2412,28 @@ dependencies = [
"getrandom",
]
+[[package]]
+name = "rayon"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-utils",
+ "num_cpus",
+]
+
[[package]]
name = "redox_syscall"
version = "0.2.16"
@@ -2317,6 +2531,15 @@ dependencies = [
"winreg",
]
+[[package]]
+name = "rgb"
+version = "0.8.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3603b7d71ca82644f79b5a06d1220e9a58ede60bd32255f698cb1af8838b8db3"
+dependencies = [
+ "bytemuck",
+]
+
[[package]]
name = "ring"
version = "0.16.20"
@@ -2326,7 +2549,7 @@ dependencies = [
"cc",
"libc",
"once_cell",
- "spin",
+ "spin 0.5.2",
"untrusted",
"web-sys",
"winapi",
@@ -2455,6 +2678,12 @@ dependencies = [
"windows-sys 0.36.1",
]
+[[package]]
+name = "scoped_threadpool"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
+
[[package]]
name = "scopeguard"
version = "1.1.0"
@@ -2802,6 +3031,15 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+[[package]]
+name = "spin"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
+dependencies = [
+ "lock_api",
+]
+
[[package]]
name = "sqlformat"
version = "0.2.0"
@@ -2994,6 +3232,26 @@ dependencies = [
"syn",
]
+[[package]]
+name = "threadpool"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
+dependencies = [
+ "num_cpus",
+]
+
+[[package]]
+name = "tiff"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471"
+dependencies = [
+ "flate2",
+ "jpeg-decoder",
+ "weezl",
+]
+
[[package]]
name = "time"
version = "0.1.44"
@@ -3474,6 +3732,12 @@ dependencies = [
"webpki",
]
+[[package]]
+name = "weezl"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
+
[[package]]
name = "wepoll-ffi"
version = "0.1.2"
diff --git a/Cargo.toml b/Cargo.toml
index b4765bac8..1d20f4fb2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -69,3 +69,6 @@ rust_decimal = { version = "1.26", features = ["serde-with-float", "serde-with-s
sentry = "0.29.1"
sentry-actix = "0.29.1"
+
+image = "0.24.5"
+color-thief = "0.2.2"
diff --git a/migrations/20221227010515_project-colors.sql b/migrations/20221227010515_project-colors.sql
new file mode 100644
index 000000000..8928d6565
--- /dev/null
+++ b/migrations/20221227010515_project-colors.sql
@@ -0,0 +1,2 @@
+-- Add migration script here
+ALTER TABLE mods ADD COLUMN color integer NULL;
\ No newline at end of file
diff --git a/sqlx-data.json b/sqlx-data.json
index 16d319375..63266bdc1 100644
--- a/sqlx-data.json
+++ b/sqlx-data.json
@@ -102,6 +102,18 @@
},
"query": "\n UPDATE mods\n SET moderation_message_body = NULL\n WHERE (id = $1)\n "
},
+ "04e5ecb14c526000e9098efb65861f6125e6fcc88f39d6ad811ac8504d229de1": {
+ "describe": {
+ "columns": [],
+ "nullable": [],
+ "parameters": {
+ "Left": [
+ "Int8"
+ ]
+ }
+ },
+ "query": "\n UPDATE mods\n SET icon_url = NULL, color = NULL\n WHERE (id = $1)\n "
+ },
"05baeb26d9856218e5c6f8856a96788b2a7ac3536ff9412a50552cef1d561a1e": {
"describe": {
"columns": [],
@@ -1701,182 +1713,6 @@
},
"query": "\n SELECT f.version_id version_id\n FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n INNER JOIN versions v on f.version_id = v.id AND v.status != ANY($1)\n INNER JOIN mods m on v.mod_id = m.id\n WHERE h.algorithm = $3 AND h.hash = $2 AND m.status != ANY($4)\n "
},
- "3b898f215cf98cbe9204f93b04be659790d2278610da186304bbf056533d5c55": {
- "describe": {
- "columns": [
- {
- "name": "project_type",
- "ordinal": 0,
- "type_info": "Int4"
- },
- {
- "name": "title",
- "ordinal": 1,
- "type_info": "Varchar"
- },
- {
- "name": "description",
- "ordinal": 2,
- "type_info": "Varchar"
- },
- {
- "name": "downloads",
- "ordinal": 3,
- "type_info": "Int4"
- },
- {
- "name": "follows",
- "ordinal": 4,
- "type_info": "Int4"
- },
- {
- "name": "icon_url",
- "ordinal": 5,
- "type_info": "Varchar"
- },
- {
- "name": "body",
- "ordinal": 6,
- "type_info": "Varchar"
- },
- {
- "name": "published",
- "ordinal": 7,
- "type_info": "Timestamptz"
- },
- {
- "name": "updated",
- "ordinal": 8,
- "type_info": "Timestamptz"
- },
- {
- "name": "approved",
- "ordinal": 9,
- "type_info": "Timestamptz"
- },
- {
- "name": "status",
- "ordinal": 10,
- "type_info": "Varchar"
- },
- {
- "name": "requested_status",
- "ordinal": 11,
- "type_info": "Varchar"
- },
- {
- "name": "issues_url",
- "ordinal": 12,
- "type_info": "Varchar"
- },
- {
- "name": "source_url",
- "ordinal": 13,
- "type_info": "Varchar"
- },
- {
- "name": "wiki_url",
- "ordinal": 14,
- "type_info": "Varchar"
- },
- {
- "name": "discord_url",
- "ordinal": 15,
- "type_info": "Varchar"
- },
- {
- "name": "license_url",
- "ordinal": 16,
- "type_info": "Varchar"
- },
- {
- "name": "team_id",
- "ordinal": 17,
- "type_info": "Int8"
- },
- {
- "name": "client_side",
- "ordinal": 18,
- "type_info": "Int4"
- },
- {
- "name": "server_side",
- "ordinal": 19,
- "type_info": "Int4"
- },
- {
- "name": "license",
- "ordinal": 20,
- "type_info": "Varchar"
- },
- {
- "name": "slug",
- "ordinal": 21,
- "type_info": "Varchar"
- },
- {
- "name": "moderation_message",
- "ordinal": 22,
- "type_info": "Varchar"
- },
- {
- "name": "moderation_message_body",
- "ordinal": 23,
- "type_info": "Varchar"
- },
- {
- "name": "flame_anvil_project",
- "ordinal": 24,
- "type_info": "Int4"
- },
- {
- "name": "flame_anvil_user",
- "ordinal": 25,
- "type_info": "Int8"
- },
- {
- "name": "webhook_sent",
- "ordinal": 26,
- "type_info": "Bool"
- }
- ],
- "nullable": [
- false,
- false,
- false,
- false,
- false,
- true,
- false,
- false,
- false,
- true,
- false,
- true,
- true,
- true,
- true,
- true,
- true,
- false,
- false,
- false,
- false,
- true,
- true,
- true,
- true,
- true,
- false
- ],
- "parameters": {
- "Left": [
- "Int8"
- ]
- }
- },
- "query": "\n SELECT project_type, title, description, downloads, follows,\n icon_url, body, published,\n updated, approved, status, requested_status,\n issues_url, source_url, wiki_url, discord_url, license_url,\n team_id, client_side, server_side, license, slug,\n moderation_message, moderation_message_body, flame_anvil_project,\n flame_anvil_user, webhook_sent\n FROM mods\n WHERE id = $1\n "
- },
"3bdcbfa5abe43cc9b4f996f147277a7f6921cca00f82cad0ef5d85032c761a36": {
"describe": {
"columns": [],
@@ -2114,17 +1950,187 @@
},
"query": "\n SELECT EXISTS(SELECT 1 FROM hashes h\n WHERE h.algorithm = $2 AND h.hash = $1)\n "
},
- "436dbf448697436ec90c30f44b27c92ec626601e7a7a9edb4d11bd916741b60f": {
+ "42d0a51c5a2eec6860a904b7753c4907b1b03fb5f081f07149367222bcdc62fb": {
"describe": {
- "columns": [],
- "nullable": [],
+ "columns": [
+ {
+ "name": "project_type",
+ "ordinal": 0,
+ "type_info": "Int4"
+ },
+ {
+ "name": "title",
+ "ordinal": 1,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "description",
+ "ordinal": 2,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "downloads",
+ "ordinal": 3,
+ "type_info": "Int4"
+ },
+ {
+ "name": "follows",
+ "ordinal": 4,
+ "type_info": "Int4"
+ },
+ {
+ "name": "icon_url",
+ "ordinal": 5,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "body",
+ "ordinal": 6,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "published",
+ "ordinal": 7,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "updated",
+ "ordinal": 8,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "approved",
+ "ordinal": 9,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "status",
+ "ordinal": 10,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "requested_status",
+ "ordinal": 11,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "issues_url",
+ "ordinal": 12,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "source_url",
+ "ordinal": 13,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "wiki_url",
+ "ordinal": 14,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "discord_url",
+ "ordinal": 15,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "license_url",
+ "ordinal": 16,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "team_id",
+ "ordinal": 17,
+ "type_info": "Int8"
+ },
+ {
+ "name": "client_side",
+ "ordinal": 18,
+ "type_info": "Int4"
+ },
+ {
+ "name": "server_side",
+ "ordinal": 19,
+ "type_info": "Int4"
+ },
+ {
+ "name": "license",
+ "ordinal": 20,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "slug",
+ "ordinal": 21,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "moderation_message",
+ "ordinal": 22,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "moderation_message_body",
+ "ordinal": 23,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "flame_anvil_project",
+ "ordinal": 24,
+ "type_info": "Int4"
+ },
+ {
+ "name": "flame_anvil_user",
+ "ordinal": 25,
+ "type_info": "Int8"
+ },
+ {
+ "name": "webhook_sent",
+ "ordinal": 26,
+ "type_info": "Bool"
+ },
+ {
+ "name": "color",
+ "ordinal": 27,
+ "type_info": "Int4"
+ }
+ ],
+ "nullable": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ false,
+ false,
+ false,
+ true,
+ false,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false,
+ true
+ ],
"parameters": {
"Left": [
"Int8"
]
}
},
- "query": "\n UPDATE mods\n SET icon_url = NULL\n WHERE (id = $1)\n "
+ "query": "\n SELECT project_type, title, description, downloads, follows,\n icon_url, body, published,\n updated, approved, status, requested_status,\n issues_url, source_url, wiki_url, discord_url, license_url,\n team_id, client_side, server_side, license, slug,\n moderation_message, moderation_message_body, flame_anvil_project,\n flame_anvil_user, webhook_sent, color\n FROM mods\n WHERE id = $1\n "
},
"447350097928db863d47d756354cd52668f52f7156dd7f3673a826f7b9aca2fd": {
"describe": {
@@ -3151,6 +3157,20 @@
},
"query": "\n DELETE FROM versions WHERE id = $1\n "
},
+ "73d77f11f97a9073f601119c6eb450ea08ae1d2df1a27ba9af1efa972ed9a836": {
+ "describe": {
+ "columns": [],
+ "nullable": [],
+ "parameters": {
+ "Left": [
+ "Varchar",
+ "Int4",
+ "Int8"
+ ]
+ }
+ },
+ "query": "\n UPDATE mods\n SET icon_url = $1, color = $2\n WHERE (id = $3)\n "
+ },
"742f20f422361971c21b72c629c57a6c3870d8d6c41577496907290db5994f12": {
"describe": {
"columns": [],
@@ -3458,6 +3478,194 @@
},
"query": "\n SELECT id FROM mods\n WHERE status = $1\n ORDER BY updated ASC\n LIMIT $2;\n "
},
+ "7c3ab073109e0fd0a01a0c02a9a2b04050d76874520c59c574d10b071c5e88ab": {
+ "describe": {
+ "columns": [
+ {
+ "name": "id",
+ "ordinal": 0,
+ "type_info": "Int8"
+ },
+ {
+ "name": "project_type",
+ "ordinal": 1,
+ "type_info": "Int4"
+ },
+ {
+ "name": "title",
+ "ordinal": 2,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "description",
+ "ordinal": 3,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "downloads",
+ "ordinal": 4,
+ "type_info": "Int4"
+ },
+ {
+ "name": "follows",
+ "ordinal": 5,
+ "type_info": "Int4"
+ },
+ {
+ "name": "icon_url",
+ "ordinal": 6,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "body",
+ "ordinal": 7,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "published",
+ "ordinal": 8,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "updated",
+ "ordinal": 9,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "approved",
+ "ordinal": 10,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "status",
+ "ordinal": 11,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "requested_status",
+ "ordinal": 12,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "issues_url",
+ "ordinal": 13,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "source_url",
+ "ordinal": 14,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "wiki_url",
+ "ordinal": 15,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "discord_url",
+ "ordinal": 16,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "license_url",
+ "ordinal": 17,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "team_id",
+ "ordinal": 18,
+ "type_info": "Int8"
+ },
+ {
+ "name": "client_side",
+ "ordinal": 19,
+ "type_info": "Int4"
+ },
+ {
+ "name": "server_side",
+ "ordinal": 20,
+ "type_info": "Int4"
+ },
+ {
+ "name": "license",
+ "ordinal": 21,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "slug",
+ "ordinal": 22,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "moderation_message",
+ "ordinal": 23,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "moderation_message_body",
+ "ordinal": 24,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "flame_anvil_project",
+ "ordinal": 25,
+ "type_info": "Int4"
+ },
+ {
+ "name": "flame_anvil_user",
+ "ordinal": 26,
+ "type_info": "Int8"
+ },
+ {
+ "name": "webhook_sent",
+ "ordinal": 27,
+ "type_info": "Bool"
+ },
+ {
+ "name": "color",
+ "ordinal": 28,
+ "type_info": "Int4"
+ }
+ ],
+ "nullable": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ false,
+ false,
+ false,
+ true,
+ false,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false,
+ true
+ ],
+ "parameters": {
+ "Left": [
+ "Int8Array"
+ ]
+ }
+ },
+ "query": "\n SELECT id, project_type, title, description, downloads, follows,\n icon_url, body, published,\n updated, approved, status, requested_status,\n issues_url, source_url, wiki_url, discord_url, license_url,\n team_id, client_side, server_side, license, slug,\n moderation_message, moderation_message_body, flame_anvil_project,\n flame_anvil_user, webhook_sent, color\n FROM mods\n WHERE id = ANY($1)\n "
+ },
"7c61fee015231f0a97c25d24f2c6be24821e39e330ab82344ad3b985d0d2aaea": {
"describe": {
"columns": [
@@ -3827,179 +4035,6 @@
},
"query": "\n DELETE FROM loaders\n WHERE loader = $1\n "
},
- "8fd5d332e9cd2f760f956bf4936350f29df414552643bcfb352ca8a8a0b98439": {
- "describe": {
- "columns": [],
- "nullable": [],
- "parameters": {
- "Left": [
- "Varchar",
- "Int8"
- ]
- }
- },
- "query": "\n UPDATE mods\n SET icon_url = $1\n WHERE (id = $2)\n "
- },
- "9225b9e3b3262227b26d8da5aa1423495ca0f9052f992a11440d0333b177c702": {
- "describe": {
- "columns": [
- {
- "name": "id",
- "ordinal": 0,
- "type_info": "Int8"
- },
- {
- "name": "project_type",
- "ordinal": 1,
- "type_info": "Int4"
- },
- {
- "name": "title",
- "ordinal": 2,
- "type_info": "Varchar"
- },
- {
- "name": "description",
- "ordinal": 3,
- "type_info": "Varchar"
- },
- {
- "name": "downloads",
- "ordinal": 4,
- "type_info": "Int4"
- },
- {
- "name": "follows",
- "ordinal": 5,
- "type_info": "Int4"
- },
- {
- "name": "icon_url",
- "ordinal": 6,
- "type_info": "Varchar"
- },
- {
- "name": "published",
- "ordinal": 7,
- "type_info": "Timestamptz"
- },
- {
- "name": "approved",
- "ordinal": 8,
- "type_info": "Timestamptz"
- },
- {
- "name": "updated",
- "ordinal": 9,
- "type_info": "Timestamptz"
- },
- {
- "name": "team_id",
- "ordinal": 10,
- "type_info": "Int8"
- },
- {
- "name": "license",
- "ordinal": 11,
- "type_info": "Varchar"
- },
- {
- "name": "slug",
- "ordinal": 12,
- "type_info": "Varchar"
- },
- {
- "name": "status_name",
- "ordinal": 13,
- "type_info": "Varchar"
- },
- {
- "name": "client_side_type",
- "ordinal": 14,
- "type_info": "Varchar"
- },
- {
- "name": "server_side_type",
- "ordinal": 15,
- "type_info": "Varchar"
- },
- {
- "name": "project_type_name",
- "ordinal": 16,
- "type_info": "Varchar"
- },
- {
- "name": "username",
- "ordinal": 17,
- "type_info": "Varchar"
- },
- {
- "name": "categories",
- "ordinal": 18,
- "type_info": "VarcharArray"
- },
- {
- "name": "additional_categories",
- "ordinal": 19,
- "type_info": "VarcharArray"
- },
- {
- "name": "loaders",
- "ordinal": 20,
- "type_info": "VarcharArray"
- },
- {
- "name": "versions",
- "ordinal": 21,
- "type_info": "VarcharArray"
- },
- {
- "name": "gallery",
- "ordinal": 22,
- "type_info": "VarcharArray"
- },
- {
- "name": "featured_gallery",
- "ordinal": 23,
- "type_info": "VarcharArray"
- }
- ],
- "nullable": [
- false,
- false,
- false,
- false,
- false,
- false,
- true,
- false,
- true,
- false,
- false,
- false,
- true,
- false,
- false,
- false,
- false,
- false,
- null,
- null,
- null,
- null,
- null,
- null
- ],
- "parameters": {
- "Left": [
- "TextArray",
- "TextArray",
- "Text"
- ]
- }
- },
- "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.published published, m.approved approved, m.updated updated,\n m.team_id team_id, m.license license, m.slug slug, m.status status_name,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, u.username username,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n ARRAY_AGG(DISTINCT lo.loader) filter (where lo.loader is not null) loaders,\n ARRAY_AGG(DISTINCT gv.version) filter (where gv.version is not null) versions,\n ARRAY_AGG(DISTINCT mg.image_url) filter (where mg.image_url is not null and mg.featured is false) gallery,\n ARRAY_AGG(DISTINCT mg.image_url) filter (where mg.image_url is not null and mg.featured is true) featured_gallery\n FROM mods m\n LEFT OUTER JOIN mods_categories mc ON joining_mod_id = m.id\n LEFT OUTER JOIN categories c ON mc.joining_category_id = c.id\n LEFT OUTER JOIN versions v ON v.mod_id = m.id AND v.status != ANY($1)\n LEFT OUTER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id\n LEFT OUTER JOIN game_versions gv ON gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv ON lv.version_id = v.id\n LEFT OUTER JOIN loaders lo ON lo.id = lv.loader_id\n LEFT OUTER JOIN mods_gallery mg ON mg.mod_id = m.id\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.role = $3 AND tm.accepted = TRUE\n INNER JOIN users u ON tm.user_id = u.id\n WHERE m.status = ANY($2)\n GROUP BY m.id, cs.id, ss.id, pt.id, u.id;\n "
- },
"9348309884811e8b22f33786ae7c0f259f37f3c90e545f00761a641570107160": {
"describe": {
"columns": [
@@ -4187,237 +4222,6 @@
},
"query": "\n SELECT u.stripe_customer_id\n FROM users u\n WHERE u.id = $1\n "
},
- "9f6fda46555ce4466b69cabecfa5e167918e54b61257e9b0f5c4fdb7cdbdf4d9": {
- "describe": {
- "columns": [
- {
- "name": "id",
- "ordinal": 0,
- "type_info": "Int8"
- },
- {
- "name": "project_type",
- "ordinal": 1,
- "type_info": "Int4"
- },
- {
- "name": "title",
- "ordinal": 2,
- "type_info": "Varchar"
- },
- {
- "name": "description",
- "ordinal": 3,
- "type_info": "Varchar"
- },
- {
- "name": "downloads",
- "ordinal": 4,
- "type_info": "Int4"
- },
- {
- "name": "follows",
- "ordinal": 5,
- "type_info": "Int4"
- },
- {
- "name": "icon_url",
- "ordinal": 6,
- "type_info": "Varchar"
- },
- {
- "name": "body",
- "ordinal": 7,
- "type_info": "Varchar"
- },
- {
- "name": "published",
- "ordinal": 8,
- "type_info": "Timestamptz"
- },
- {
- "name": "updated",
- "ordinal": 9,
- "type_info": "Timestamptz"
- },
- {
- "name": "approved",
- "ordinal": 10,
- "type_info": "Timestamptz"
- },
- {
- "name": "status",
- "ordinal": 11,
- "type_info": "Varchar"
- },
- {
- "name": "requested_status",
- "ordinal": 12,
- "type_info": "Varchar"
- },
- {
- "name": "issues_url",
- "ordinal": 13,
- "type_info": "Varchar"
- },
- {
- "name": "source_url",
- "ordinal": 14,
- "type_info": "Varchar"
- },
- {
- "name": "wiki_url",
- "ordinal": 15,
- "type_info": "Varchar"
- },
- {
- "name": "discord_url",
- "ordinal": 16,
- "type_info": "Varchar"
- },
- {
- "name": "license_url",
- "ordinal": 17,
- "type_info": "Varchar"
- },
- {
- "name": "team_id",
- "ordinal": 18,
- "type_info": "Int8"
- },
- {
- "name": "client_side",
- "ordinal": 19,
- "type_info": "Int4"
- },
- {
- "name": "server_side",
- "ordinal": 20,
- "type_info": "Int4"
- },
- {
- "name": "license",
- "ordinal": 21,
- "type_info": "Varchar"
- },
- {
- "name": "slug",
- "ordinal": 22,
- "type_info": "Varchar"
- },
- {
- "name": "moderation_message",
- "ordinal": 23,
- "type_info": "Varchar"
- },
- {
- "name": "moderation_message_body",
- "ordinal": 24,
- "type_info": "Varchar"
- },
- {
- "name": "client_side_type",
- "ordinal": 25,
- "type_info": "Varchar"
- },
- {
- "name": "server_side_type",
- "ordinal": 26,
- "type_info": "Varchar"
- },
- {
- "name": "project_type_name",
- "ordinal": 27,
- "type_info": "Varchar"
- },
- {
- "name": "flame_anvil_project",
- "ordinal": 28,
- "type_info": "Int4"
- },
- {
- "name": "flame_anvil_user",
- "ordinal": 29,
- "type_info": "Int8"
- },
- {
- "name": "webhook_sent",
- "ordinal": 30,
- "type_info": "Bool"
- },
- {
- "name": "categories",
- "ordinal": 31,
- "type_info": "VarcharArray"
- },
- {
- "name": "additional_categories",
- "ordinal": 32,
- "type_info": "VarcharArray"
- },
- {
- "name": "versions",
- "ordinal": 33,
- "type_info": "Jsonb"
- },
- {
- "name": "gallery",
- "ordinal": 34,
- "type_info": "Jsonb"
- },
- {
- "name": "donations",
- "ordinal": 35,
- "type_info": "Jsonb"
- }
- ],
- "nullable": [
- false,
- false,
- false,
- false,
- false,
- false,
- true,
- false,
- false,
- false,
- true,
- false,
- true,
- true,
- true,
- true,
- true,
- true,
- false,
- false,
- false,
- false,
- true,
- true,
- true,
- false,
- false,
- false,
- true,
- true,
- false,
- null,
- null,
- null,
- null,
- null
- ],
- "parameters": {
- "Left": [
- "Int8",
- "TextArray"
- ]
- }
- },
- "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.published published,\n m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent webhook_sent,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n WHERE m.id = $1\n GROUP BY pt.id, cs.id, ss.id, m.id;\n "
- },
"a0148ff25855202e7bb220b6a2bc9220a95e309fb0dae41d9a05afa86e6b33af": {
"describe": {
"columns": [],
@@ -4659,6 +4463,243 @@
},
"query": "\n SELECT id FROM categories\n WHERE category = $1 AND project_type = $2\n "
},
+ "abdd57a514fc34bca239384c16c7a18f1faffcf1db9616ef0576fc2b1691a16e": {
+ "describe": {
+ "columns": [
+ {
+ "name": "id",
+ "ordinal": 0,
+ "type_info": "Int8"
+ },
+ {
+ "name": "project_type",
+ "ordinal": 1,
+ "type_info": "Int4"
+ },
+ {
+ "name": "title",
+ "ordinal": 2,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "description",
+ "ordinal": 3,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "downloads",
+ "ordinal": 4,
+ "type_info": "Int4"
+ },
+ {
+ "name": "follows",
+ "ordinal": 5,
+ "type_info": "Int4"
+ },
+ {
+ "name": "icon_url",
+ "ordinal": 6,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "body",
+ "ordinal": 7,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "published",
+ "ordinal": 8,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "updated",
+ "ordinal": 9,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "approved",
+ "ordinal": 10,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "status",
+ "ordinal": 11,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "requested_status",
+ "ordinal": 12,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "issues_url",
+ "ordinal": 13,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "source_url",
+ "ordinal": 14,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "wiki_url",
+ "ordinal": 15,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "discord_url",
+ "ordinal": 16,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "license_url",
+ "ordinal": 17,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "team_id",
+ "ordinal": 18,
+ "type_info": "Int8"
+ },
+ {
+ "name": "client_side",
+ "ordinal": 19,
+ "type_info": "Int4"
+ },
+ {
+ "name": "server_side",
+ "ordinal": 20,
+ "type_info": "Int4"
+ },
+ {
+ "name": "license",
+ "ordinal": 21,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "slug",
+ "ordinal": 22,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "moderation_message",
+ "ordinal": 23,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "moderation_message_body",
+ "ordinal": 24,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "client_side_type",
+ "ordinal": 25,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "server_side_type",
+ "ordinal": 26,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "project_type_name",
+ "ordinal": 27,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "flame_anvil_project",
+ "ordinal": 28,
+ "type_info": "Int4"
+ },
+ {
+ "name": "flame_anvil_user",
+ "ordinal": 29,
+ "type_info": "Int8"
+ },
+ {
+ "name": "webhook_sent",
+ "ordinal": 30,
+ "type_info": "Bool"
+ },
+ {
+ "name": "color",
+ "ordinal": 31,
+ "type_info": "Int4"
+ },
+ {
+ "name": "categories",
+ "ordinal": 32,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "additional_categories",
+ "ordinal": 33,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "versions",
+ "ordinal": 34,
+ "type_info": "Jsonb"
+ },
+ {
+ "name": "gallery",
+ "ordinal": 35,
+ "type_info": "Jsonb"
+ },
+ {
+ "name": "donations",
+ "ordinal": 36,
+ "type_info": "Jsonb"
+ }
+ ],
+ "nullable": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ false,
+ false,
+ false,
+ true,
+ false,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ true,
+ false,
+ false,
+ false,
+ true,
+ true,
+ false,
+ true,
+ null,
+ null,
+ null,
+ null,
+ null
+ ],
+ "parameters": {
+ "Left": [
+ "Int8Array",
+ "TextArray"
+ ]
+ }
+ },
+ "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.published published,\n m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent, m.color,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n WHERE m.id = ANY($1)\n GROUP BY pt.id, cs.id, ss.id, m.id;\n "
+ },
"ac2d17b7d7147b14f072c15ffa214c14f32f27ffa6a3c2b2a5f80f3ad49ca5e9": {
"describe": {
"columns": [
@@ -4932,188 +4973,6 @@
},
"query": "\n SELECT tm.id id, tm.role member_role, tm.permissions permissions, tm.accepted accepted, tm.payouts_split payouts_split, tm.ordering ordering,\n u.id user_id, u.github_id github_id, u.name user_name, u.email email,\n u.avatar_url avatar_url, u.username username, u.bio bio,\n u.created created, u.role user_role, u.badges badges, u.balance balance,\n u.payout_wallet payout_wallet, u.payout_wallet_type payout_wallet_type,\n u.payout_address payout_address, u.flame_anvil_key flame_anvil_key\n FROM team_members tm\n INNER JOIN users u ON u.id = tm.user_id\n WHERE tm.team_id = $1\n ORDER BY tm.ordering\n "
},
- "b660307d4e4027223c6b7297237ee57e5d82c40423707c1fb0f3b8b45737a353": {
- "describe": {
- "columns": [
- {
- "name": "id",
- "ordinal": 0,
- "type_info": "Int8"
- },
- {
- "name": "project_type",
- "ordinal": 1,
- "type_info": "Int4"
- },
- {
- "name": "title",
- "ordinal": 2,
- "type_info": "Varchar"
- },
- {
- "name": "description",
- "ordinal": 3,
- "type_info": "Varchar"
- },
- {
- "name": "downloads",
- "ordinal": 4,
- "type_info": "Int4"
- },
- {
- "name": "follows",
- "ordinal": 5,
- "type_info": "Int4"
- },
- {
- "name": "icon_url",
- "ordinal": 6,
- "type_info": "Varchar"
- },
- {
- "name": "body",
- "ordinal": 7,
- "type_info": "Varchar"
- },
- {
- "name": "published",
- "ordinal": 8,
- "type_info": "Timestamptz"
- },
- {
- "name": "updated",
- "ordinal": 9,
- "type_info": "Timestamptz"
- },
- {
- "name": "approved",
- "ordinal": 10,
- "type_info": "Timestamptz"
- },
- {
- "name": "status",
- "ordinal": 11,
- "type_info": "Varchar"
- },
- {
- "name": "requested_status",
- "ordinal": 12,
- "type_info": "Varchar"
- },
- {
- "name": "issues_url",
- "ordinal": 13,
- "type_info": "Varchar"
- },
- {
- "name": "source_url",
- "ordinal": 14,
- "type_info": "Varchar"
- },
- {
- "name": "wiki_url",
- "ordinal": 15,
- "type_info": "Varchar"
- },
- {
- "name": "discord_url",
- "ordinal": 16,
- "type_info": "Varchar"
- },
- {
- "name": "license_url",
- "ordinal": 17,
- "type_info": "Varchar"
- },
- {
- "name": "team_id",
- "ordinal": 18,
- "type_info": "Int8"
- },
- {
- "name": "client_side",
- "ordinal": 19,
- "type_info": "Int4"
- },
- {
- "name": "server_side",
- "ordinal": 20,
- "type_info": "Int4"
- },
- {
- "name": "license",
- "ordinal": 21,
- "type_info": "Varchar"
- },
- {
- "name": "slug",
- "ordinal": 22,
- "type_info": "Varchar"
- },
- {
- "name": "moderation_message",
- "ordinal": 23,
- "type_info": "Varchar"
- },
- {
- "name": "moderation_message_body",
- "ordinal": 24,
- "type_info": "Varchar"
- },
- {
- "name": "flame_anvil_project",
- "ordinal": 25,
- "type_info": "Int4"
- },
- {
- "name": "flame_anvil_user",
- "ordinal": 26,
- "type_info": "Int8"
- },
- {
- "name": "webhook_sent",
- "ordinal": 27,
- "type_info": "Bool"
- }
- ],
- "nullable": [
- false,
- false,
- false,
- false,
- false,
- false,
- true,
- false,
- false,
- false,
- true,
- false,
- true,
- true,
- true,
- true,
- true,
- true,
- false,
- false,
- false,
- false,
- true,
- true,
- true,
- true,
- true,
- false
- ],
- "parameters": {
- "Left": [
- "Int8Array"
- ]
- }
- },
- "query": "\n SELECT id, project_type, title, description, downloads, follows,\n icon_url, body, published,\n updated, approved, status, requested_status,\n issues_url, source_url, wiki_url, discord_url, license_url,\n team_id, client_side, server_side, license, slug,\n moderation_message, moderation_message_body, flame_anvil_project,\n flame_anvil_user, webhook_sent\n FROM mods\n WHERE id = ANY($1)\n "
- },
"b69a6f42965b3e7103fcbf46e39528466926789ff31e9ed2591bb175527ec169": {
"describe": {
"columns": [],
@@ -5395,6 +5254,204 @@
},
"query": "\n DELETE FROM game_versions_versions gvv\n WHERE gvv.joining_version_id = $1\n "
},
+ "bf3cc4f6b22db45df42fa8b1c5b26505ebdb312d14cf657891b9ec4dff8bc55c": {
+ "describe": {
+ "columns": [],
+ "nullable": [],
+ "parameters": {
+ "Left": [
+ "Int8",
+ "Int8",
+ "Varchar",
+ "Varchar",
+ "Varchar",
+ "Timestamptz",
+ "Int4",
+ "Varchar",
+ "Varchar",
+ "Varchar",
+ "Varchar",
+ "Varchar",
+ "Varchar",
+ "Varchar",
+ "Int4",
+ "Int4",
+ "Varchar",
+ "Varchar",
+ "Text",
+ "Int4",
+ "Int4"
+ ]
+ }
+ },
+ "query": "\n INSERT INTO mods (\n id, team_id, title, description, body,\n published, downloads, icon_url, issues_url,\n source_url, wiki_url, status, requested_status, discord_url,\n client_side, server_side, license_url, license,\n slug, project_type, color\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7, $8, $9,\n $10, $11, $12, $13, $14,\n $15, $16, $17, $18,\n LOWER($19), $20, $21\n )\n "
+ },
+ "bf4afeda41a54e09a80a4cc505d1fbb72124c442ebaca731a291f022524daf1a": {
+ "describe": {
+ "columns": [
+ {
+ "name": "id",
+ "ordinal": 0,
+ "type_info": "Int8"
+ },
+ {
+ "name": "project_type",
+ "ordinal": 1,
+ "type_info": "Int4"
+ },
+ {
+ "name": "title",
+ "ordinal": 2,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "description",
+ "ordinal": 3,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "downloads",
+ "ordinal": 4,
+ "type_info": "Int4"
+ },
+ {
+ "name": "follows",
+ "ordinal": 5,
+ "type_info": "Int4"
+ },
+ {
+ "name": "icon_url",
+ "ordinal": 6,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "published",
+ "ordinal": 7,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "approved",
+ "ordinal": 8,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "updated",
+ "ordinal": 9,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "team_id",
+ "ordinal": 10,
+ "type_info": "Int8"
+ },
+ {
+ "name": "license",
+ "ordinal": 11,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "slug",
+ "ordinal": 12,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "status_name",
+ "ordinal": 13,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "color",
+ "ordinal": 14,
+ "type_info": "Int4"
+ },
+ {
+ "name": "client_side_type",
+ "ordinal": 15,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "server_side_type",
+ "ordinal": 16,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "project_type_name",
+ "ordinal": 17,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "username",
+ "ordinal": 18,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "categories",
+ "ordinal": 19,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "additional_categories",
+ "ordinal": 20,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "loaders",
+ "ordinal": 21,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "versions",
+ "ordinal": 22,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "gallery",
+ "ordinal": 23,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "featured_gallery",
+ "ordinal": 24,
+ "type_info": "VarcharArray"
+ }
+ ],
+ "nullable": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ ],
+ "parameters": {
+ "Left": [
+ "TextArray",
+ "TextArray",
+ "Text"
+ ]
+ }
+ },
+ "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.published published, m.approved approved, m.updated updated,\n m.team_id team_id, m.license license, m.slug slug, m.status status_name, m.color color,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, u.username username,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n ARRAY_AGG(DISTINCT lo.loader) filter (where lo.loader is not null) loaders,\n ARRAY_AGG(DISTINCT gv.version) filter (where gv.version is not null) versions,\n ARRAY_AGG(DISTINCT mg.image_url) filter (where mg.image_url is not null and mg.featured is false) gallery,\n ARRAY_AGG(DISTINCT mg.image_url) filter (where mg.image_url is not null and mg.featured is true) featured_gallery\n FROM mods m\n LEFT OUTER JOIN mods_categories mc ON joining_mod_id = m.id\n LEFT OUTER JOIN categories c ON mc.joining_category_id = c.id\n LEFT OUTER JOIN versions v ON v.mod_id = m.id AND v.status != ANY($1)\n LEFT OUTER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id\n LEFT OUTER JOIN game_versions gv ON gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv ON lv.version_id = v.id\n LEFT OUTER JOIN loaders lo ON lo.id = lv.loader_id\n LEFT OUTER JOIN mods_gallery mg ON mg.mod_id = m.id\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.role = $3 AND tm.accepted = TRUE\n INNER JOIN users u ON tm.user_id = u.id\n WHERE m.status = ANY($2)\n GROUP BY m.id, cs.id, ss.id, pt.id, u.id;\n "
+ },
"bf7f721664f5e0ed41adc41b5483037256635f28ff6c4e5d3cbcec4387f9c8ef": {
"describe": {
"columns": [
@@ -5701,237 +5758,6 @@
},
"query": "\n UPDATE versions\n SET status = requested_status\n WHERE status = $1 AND date_published < CURRENT_DATE AND requested_status IS NOT NULL\n "
},
- "c9686c5c7dc5a9496fdf3c9b7b5a05c64abf77bb5d525a54c697c2c87a95fc57": {
- "describe": {
- "columns": [
- {
- "name": "id",
- "ordinal": 0,
- "type_info": "Int8"
- },
- {
- "name": "project_type",
- "ordinal": 1,
- "type_info": "Int4"
- },
- {
- "name": "title",
- "ordinal": 2,
- "type_info": "Varchar"
- },
- {
- "name": "description",
- "ordinal": 3,
- "type_info": "Varchar"
- },
- {
- "name": "downloads",
- "ordinal": 4,
- "type_info": "Int4"
- },
- {
- "name": "follows",
- "ordinal": 5,
- "type_info": "Int4"
- },
- {
- "name": "icon_url",
- "ordinal": 6,
- "type_info": "Varchar"
- },
- {
- "name": "body",
- "ordinal": 7,
- "type_info": "Varchar"
- },
- {
- "name": "published",
- "ordinal": 8,
- "type_info": "Timestamptz"
- },
- {
- "name": "updated",
- "ordinal": 9,
- "type_info": "Timestamptz"
- },
- {
- "name": "approved",
- "ordinal": 10,
- "type_info": "Timestamptz"
- },
- {
- "name": "status",
- "ordinal": 11,
- "type_info": "Varchar"
- },
- {
- "name": "requested_status",
- "ordinal": 12,
- "type_info": "Varchar"
- },
- {
- "name": "issues_url",
- "ordinal": 13,
- "type_info": "Varchar"
- },
- {
- "name": "source_url",
- "ordinal": 14,
- "type_info": "Varchar"
- },
- {
- "name": "wiki_url",
- "ordinal": 15,
- "type_info": "Varchar"
- },
- {
- "name": "discord_url",
- "ordinal": 16,
- "type_info": "Varchar"
- },
- {
- "name": "license_url",
- "ordinal": 17,
- "type_info": "Varchar"
- },
- {
- "name": "team_id",
- "ordinal": 18,
- "type_info": "Int8"
- },
- {
- "name": "client_side",
- "ordinal": 19,
- "type_info": "Int4"
- },
- {
- "name": "server_side",
- "ordinal": 20,
- "type_info": "Int4"
- },
- {
- "name": "license",
- "ordinal": 21,
- "type_info": "Varchar"
- },
- {
- "name": "slug",
- "ordinal": 22,
- "type_info": "Varchar"
- },
- {
- "name": "moderation_message",
- "ordinal": 23,
- "type_info": "Varchar"
- },
- {
- "name": "moderation_message_body",
- "ordinal": 24,
- "type_info": "Varchar"
- },
- {
- "name": "client_side_type",
- "ordinal": 25,
- "type_info": "Varchar"
- },
- {
- "name": "server_side_type",
- "ordinal": 26,
- "type_info": "Varchar"
- },
- {
- "name": "project_type_name",
- "ordinal": 27,
- "type_info": "Varchar"
- },
- {
- "name": "flame_anvil_project",
- "ordinal": 28,
- "type_info": "Int4"
- },
- {
- "name": "flame_anvil_user",
- "ordinal": 29,
- "type_info": "Int8"
- },
- {
- "name": "webhook_sent",
- "ordinal": 30,
- "type_info": "Bool"
- },
- {
- "name": "categories",
- "ordinal": 31,
- "type_info": "VarcharArray"
- },
- {
- "name": "additional_categories",
- "ordinal": 32,
- "type_info": "VarcharArray"
- },
- {
- "name": "versions",
- "ordinal": 33,
- "type_info": "Jsonb"
- },
- {
- "name": "gallery",
- "ordinal": 34,
- "type_info": "Jsonb"
- },
- {
- "name": "donations",
- "ordinal": 35,
- "type_info": "Jsonb"
- }
- ],
- "nullable": [
- false,
- false,
- false,
- false,
- false,
- false,
- true,
- false,
- false,
- false,
- true,
- false,
- true,
- true,
- true,
- true,
- true,
- true,
- false,
- false,
- false,
- false,
- true,
- true,
- true,
- false,
- false,
- false,
- true,
- true,
- false,
- null,
- null,
- null,
- null,
- null
- ],
- "parameters": {
- "Left": [
- "Int8Array",
- "TextArray"
- ]
- }
- },
- "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.published published,\n m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n WHERE m.id = ANY($1)\n GROUP BY pt.id, cs.id, ss.id, m.id;\n "
- },
"c9d63ed46799db7c30a7e917d97a5d4b2b78b0234cce49e136fa57526b38c1ca": {
"describe": {
"columns": [
@@ -6507,6 +6333,243 @@
},
"query": "\n SELECT id, user_id, role, permissions, accepted, payouts_split, ordering\n FROM team_members\n WHERE (team_id = $1 AND user_id = $2)\n "
},
+ "df35aee011aa176f5511729afd68b493ac70b997168cb502b5fd7e4224da27bb": {
+ "describe": {
+ "columns": [
+ {
+ "name": "id",
+ "ordinal": 0,
+ "type_info": "Int8"
+ },
+ {
+ "name": "project_type",
+ "ordinal": 1,
+ "type_info": "Int4"
+ },
+ {
+ "name": "title",
+ "ordinal": 2,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "description",
+ "ordinal": 3,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "downloads",
+ "ordinal": 4,
+ "type_info": "Int4"
+ },
+ {
+ "name": "follows",
+ "ordinal": 5,
+ "type_info": "Int4"
+ },
+ {
+ "name": "icon_url",
+ "ordinal": 6,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "body",
+ "ordinal": 7,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "published",
+ "ordinal": 8,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "updated",
+ "ordinal": 9,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "approved",
+ "ordinal": 10,
+ "type_info": "Timestamptz"
+ },
+ {
+ "name": "status",
+ "ordinal": 11,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "requested_status",
+ "ordinal": 12,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "issues_url",
+ "ordinal": 13,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "source_url",
+ "ordinal": 14,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "wiki_url",
+ "ordinal": 15,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "discord_url",
+ "ordinal": 16,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "license_url",
+ "ordinal": 17,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "team_id",
+ "ordinal": 18,
+ "type_info": "Int8"
+ },
+ {
+ "name": "client_side",
+ "ordinal": 19,
+ "type_info": "Int4"
+ },
+ {
+ "name": "server_side",
+ "ordinal": 20,
+ "type_info": "Int4"
+ },
+ {
+ "name": "license",
+ "ordinal": 21,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "slug",
+ "ordinal": 22,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "moderation_message",
+ "ordinal": 23,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "moderation_message_body",
+ "ordinal": 24,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "client_side_type",
+ "ordinal": 25,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "server_side_type",
+ "ordinal": 26,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "project_type_name",
+ "ordinal": 27,
+ "type_info": "Varchar"
+ },
+ {
+ "name": "flame_anvil_project",
+ "ordinal": 28,
+ "type_info": "Int4"
+ },
+ {
+ "name": "flame_anvil_user",
+ "ordinal": 29,
+ "type_info": "Int8"
+ },
+ {
+ "name": "webhook_sent",
+ "ordinal": 30,
+ "type_info": "Bool"
+ },
+ {
+ "name": "color",
+ "ordinal": 31,
+ "type_info": "Int4"
+ },
+ {
+ "name": "categories",
+ "ordinal": 32,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "additional_categories",
+ "ordinal": 33,
+ "type_info": "VarcharArray"
+ },
+ {
+ "name": "versions",
+ "ordinal": 34,
+ "type_info": "Jsonb"
+ },
+ {
+ "name": "gallery",
+ "ordinal": 35,
+ "type_info": "Jsonb"
+ },
+ {
+ "name": "donations",
+ "ordinal": 36,
+ "type_info": "Jsonb"
+ }
+ ],
+ "nullable": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ false,
+ false,
+ false,
+ true,
+ false,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ true,
+ false,
+ false,
+ false,
+ true,
+ true,
+ false,
+ true,
+ null,
+ null,
+ null,
+ null,
+ null
+ ],
+ "parameters": {
+ "Left": [
+ "Int8",
+ "TextArray"
+ ]
+ }
+ },
+ "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.published published,\n m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent webhook_sent, m.color,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n WHERE m.id = $1\n GROUP BY pt.id, cs.id, ss.id, m.id;\n "
+ },
"df871bd959ba97f105ac575f34d8d2a39cbc44a07e0339750a0e477e6fd582ed": {
"describe": {
"columns": [],
@@ -7128,37 +7191,6 @@
},
"query": "\n DELETE FROM dependencies WHERE mod_dependency_id = $1\n "
},
- "edd50de303f84695508a1067683ce881283bba5342aff36b7d03dc9638a6f9f3": {
- "describe": {
- "columns": [],
- "nullable": [],
- "parameters": {
- "Left": [
- "Int8",
- "Int8",
- "Varchar",
- "Varchar",
- "Varchar",
- "Timestamptz",
- "Int4",
- "Varchar",
- "Varchar",
- "Varchar",
- "Varchar",
- "Varchar",
- "Varchar",
- "Varchar",
- "Int4",
- "Int4",
- "Varchar",
- "Varchar",
- "Text",
- "Int4"
- ]
- }
- },
- "query": "\n INSERT INTO mods (\n id, team_id, title, description, body,\n published, downloads, icon_url, issues_url,\n source_url, wiki_url, status, requested_status, discord_url,\n client_side, server_side, license_url, license,\n slug, project_type\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7, $8, $9,\n $10, $11, $12, $13, $14,\n $15, $16, $17, $18,\n LOWER($19), $20\n )\n "
- },
"ef3d43d3424824eed67370f10cc0672581a95a169bf404022cbe3cac0415d99c": {
"describe": {
"columns": [
diff --git a/src/database/models/project_item.rs b/src/database/models/project_item.rs
index be147e55e..36c57ba2e 100644
--- a/src/database/models/project_item.rs
+++ b/src/database/models/project_item.rs
@@ -100,6 +100,7 @@ pub struct ProjectBuilder {
pub slug: Option,
pub donation_urls: Vec,
pub gallery_items: Vec,
+ pub color: Option,
}
impl ProjectBuilder {
@@ -137,6 +138,7 @@ impl ProjectBuilder {
flame_anvil_project: None,
flame_anvil_user: None,
webhook_sent: false,
+ color: self.color,
};
project_struct.insert(&mut *transaction).await?;
@@ -213,6 +215,7 @@ pub struct Project {
pub flame_anvil_project: Option,
pub flame_anvil_user: Option,
pub webhook_sent: bool,
+ pub color: Option,
}
impl Project {
@@ -227,14 +230,14 @@ impl Project {
published, downloads, icon_url, issues_url,
source_url, wiki_url, status, requested_status, discord_url,
client_side, server_side, license_url, license,
- slug, project_type
+ slug, project_type, color
)
VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8, $9,
$10, $11, $12, $13, $14,
$15, $16, $17, $18,
- LOWER($19), $20
+ LOWER($19), $20, $21
)
",
self.id as ProjectId,
@@ -256,7 +259,8 @@ impl Project {
self.license_url.as_ref(),
&self.license,
self.slug.as_ref(),
- self.project_type as ProjectTypeId
+ self.project_type as ProjectTypeId,
+ self.color.map(|x| x as i32)
)
.execute(&mut *transaction)
.await?;
@@ -279,7 +283,7 @@ impl Project {
issues_url, source_url, wiki_url, discord_url, license_url,
team_id, client_side, server_side, license, slug,
moderation_message, moderation_message_body, flame_anvil_project,
- flame_anvil_user, webhook_sent
+ flame_anvil_user, webhook_sent, color
FROM mods
WHERE id = $1
",
@@ -321,6 +325,7 @@ impl Project {
flame_anvil_project: row.flame_anvil_project,
flame_anvil_user: row.flame_anvil_user.map(UserId),
webhook_sent: row.webhook_sent,
+ color: row.color.map(|x| x as u32),
}))
} else {
Ok(None)
@@ -346,7 +351,7 @@ impl Project {
issues_url, source_url, wiki_url, discord_url, license_url,
team_id, client_side, server_side, license, slug,
moderation_message, moderation_message_body, flame_anvil_project,
- flame_anvil_user, webhook_sent
+ flame_anvil_user, webhook_sent, color
FROM mods
WHERE id = ANY($1)
",
@@ -388,6 +393,7 @@ impl Project {
flame_anvil_project: m.flame_anvil_project,
flame_anvil_user: m.flame_anvil_user.map(UserId),
webhook_sent: m.webhook_sent,
+ color: m.color.map(|x| x as u32),
}))
})
.try_collect::>()
@@ -666,7 +672,7 @@ impl Project {
m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,
m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,
m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,
- cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent webhook_sent,
+ cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent webhook_sent, m.color,
ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,
ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,
JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,
@@ -725,6 +731,7 @@ impl Project {
flame_anvil_project: m.flame_anvil_project,
flame_anvil_user: m.flame_anvil_user.map(UserId),
webhook_sent: m.webhook_sent,
+ color: m.color.map(|x| x as u32),
},
project_type: m.project_type_name,
categories: m.categories.unwrap_or_default(),
@@ -794,7 +801,7 @@ impl Project {
m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,
m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,
m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,
- cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent,
+ cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user, m.webhook_sent, m.color,
ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,
ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,
JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,
@@ -856,6 +863,7 @@ impl Project {
flame_anvil_project: m.flame_anvil_project,
flame_anvil_user: m.flame_anvil_user.map(UserId),
webhook_sent: m.webhook_sent,
+ color: m.color.map(|x| x as u32),
},
project_type: m.project_type_name,
categories: m.categories.unwrap_or_default(),
diff --git a/src/models/projects.rs b/src/models/projects.rs
index a37bd2468..7f4efbca2 100644
--- a/src/models/projects.rs
+++ b/src/models/projects.rs
@@ -97,6 +97,9 @@ pub struct Project {
pub flame_anvil_project: Option,
/// The user_id of the team member whose token
pub flame_anvil_user: Option,
+
+ /// The color of the project (picked from icon)
+ pub color: Option,
}
impl From for Project {
@@ -181,6 +184,7 @@ impl From for Project {
.collect(),
flame_anvil_project: m.flame_anvil_project,
flame_anvil_user: m.flame_anvil_user.map(|x| x.into()),
+ color: m.color,
}
}
}
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index f4d346c78..d9021358d 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -30,6 +30,7 @@ pub use self::index::index_get;
pub use self::not_found::not_found;
use crate::file_hosting::FileHostingError;
use actix_web::web;
+use image::ImageError;
pub fn v2_config(cfg: &mut web::ServiceConfig) {
cfg.service(
@@ -230,6 +231,8 @@ pub enum ApiError {
DiscordError(String),
#[error("Error while decoding Base62: {0}")]
Decoding(#[from] crate::models::ids::DecodingError),
+ #[error("Image Parsing Error: {0}")]
+ ImageError(#[from] ImageError),
}
impl actix_web::ResponseError for ApiError {
@@ -280,6 +283,9 @@ impl actix_web::ResponseError for ApiError {
actix_web::http::StatusCode::FAILED_DEPENDENCY
}
ApiError::Decoding(..) => actix_web::http::StatusCode::BAD_REQUEST,
+ ApiError::ImageError(..) => {
+ actix_web::http::StatusCode::BAD_REQUEST
+ }
}
}
@@ -304,6 +310,7 @@ impl actix_web::ResponseError for ApiError {
ApiError::Payments(..) => "payments_error",
ApiError::DiscordError(..) => "discord_error",
ApiError::Decoding(..) => "decoding_error",
+ ApiError::ImageError(..) => "invalid_image",
},
description: &self.to_string(),
},
diff --git a/src/routes/project_creation.rs b/src/routes/project_creation.rs
index 4ac247ced..bc5abf7e4 100644
--- a/src/routes/project_creation.rs
+++ b/src/routes/project_creation.rs
@@ -18,6 +18,7 @@ use actix_web::web::Data;
use actix_web::{post, HttpRequest, HttpResponse};
use chrono::Utc;
use futures::stream::StreamExt;
+use image::ImageError;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use sqlx::postgres::PgPool;
@@ -65,6 +66,8 @@ pub enum CreateError {
Unauthorized(#[from] AuthenticationError),
#[error("Authentication Error: {0}")]
CustomAuthenticationError(String),
+ #[error("Image Parsing Error: {0}")]
+ ImageError(#[from] ImageError),
}
impl actix_web::ResponseError for CreateError {
@@ -95,6 +98,7 @@ impl actix_web::ResponseError for CreateError {
CreateError::SlugCollision => StatusCode::BAD_REQUEST,
CreateError::ValidationError(..) => StatusCode::BAD_REQUEST,
CreateError::FileValidationError(..) => StatusCode::BAD_REQUEST,
+ CreateError::ImageError(..) => StatusCode::BAD_REQUEST,
}
}
@@ -120,6 +124,7 @@ impl actix_web::ResponseError for CreateError {
CreateError::SlugCollision => "invalid_input",
CreateError::ValidationError(..) => "invalid_input",
CreateError::FileValidationError(..) => "invalid_input",
+ CreateError::ImageError(..) => "invalid_image",
},
description: &self.to_string(),
})
@@ -468,7 +473,7 @@ pub async fn project_create_inner(
))
})?;
- let mut icon_url = None;
+ let mut icon_data = None;
while let Some(item) = payload.next().await {
let mut field: Field = item.map_err(CreateError::MultipartError)?;
@@ -482,13 +487,13 @@ pub async fn project_create_inner(
super::version_creation::get_name_ext(&content_disposition)?;
if name == "icon" {
- if icon_url.is_some() {
+ if icon_data.is_some() {
return Err(CreateError::InvalidInput(String::from(
"Projects can only have one icon",
)));
}
// Upload the icon to the cdn
- icon_url = Some(
+ icon_data = Some(
process_icon_upload(
uploaded_files,
project_id,
@@ -731,7 +736,7 @@ pub async fn project_create_inner(
title: project_create_data.title,
description: project_create_data.description,
body: project_create_data.body,
- icon_url,
+ icon_url: icon_data.clone().map(|x| x.0),
issues_url: project_create_data.issues_url,
source_url: project_create_data.source_url,
wiki_url: project_create_data.wiki_url,
@@ -759,6 +764,7 @@ pub async fn project_create_inner(
ordering: x.ordering,
})
.collect(),
+ color: icon_data.and_then(|x| x.1),
};
let now = Utc::now();
@@ -803,6 +809,7 @@ pub async fn project_create_inner(
gallery: gallery_urls,
flame_anvil_project: None,
flame_anvil_user: None,
+ color: project_builder.color,
};
let _project_id = project_builder.insert(&mut *transaction).await?;
@@ -911,9 +918,9 @@ async fn process_icon_upload(
project_id: ProjectId,
file_extension: &str,
file_host: &dyn FileHost,
- mut field: actix_multipart::Field,
+ mut field: Field,
cdn_url: &str,
-) -> Result {
+) -> Result<(String, Option), CreateError> {
if let Some(content_type) =
crate::util::ext::get_image_content_type(file_extension)
{
@@ -924,6 +931,8 @@ async fn process_icon_upload(
)
.await?;
+ let color = crate::util::img::get_color_from_img(&data)?;
+
let hash = sha1::Sha1::from(&data).hexdigest();
let upload_data = file_host
.upload_file(
@@ -938,7 +947,7 @@ async fn process_icon_upload(
file_name: upload_data.file_name.clone(),
});
- Ok(format!("{}/{}", cdn_url, upload_data.file_name))
+ Ok((format!("{}/{}", cdn_url, upload_data.file_name), color))
} else {
Err(CreateError::InvalidIconFormat(file_extension.to_string()))
}
diff --git a/src/routes/projects.rs b/src/routes/projects.rs
index cd21bab20..ed1ad6ec9 100644
--- a/src/routes/projects.rs
+++ b/src/routes/projects.rs
@@ -1288,6 +1288,9 @@ pub async fn project_icon_edit(
"Icons must be smaller than 256KiB",
)
.await?;
+
+ let color = crate::util::img::get_color_from_img(&bytes)?;
+
let hash = sha1::Sha1::from(&bytes).hexdigest();
let project_id: ProjectId = project_item.id.into();
let upload_data = file_host
@@ -1303,10 +1306,11 @@ pub async fn project_icon_edit(
sqlx::query!(
"
UPDATE mods
- SET icon_url = $1
- WHERE (id = $2)
+ SET icon_url = $1, color = $2
+ WHERE (id = $3)
",
format!("{}/{}", cdn_url, upload_data.file_name),
+ color.map(|x| x as i32),
project_item.id as database::models::ids::ProjectId,
)
.execute(&mut *transaction)
@@ -1379,7 +1383,7 @@ pub async fn delete_project_icon(
sqlx::query!(
"
UPDATE mods
- SET icon_url = NULL
+ SET icon_url = NULL, color = NULL
WHERE (id = $1)
",
project_item.id as database::models::ids::ProjectId,
diff --git a/src/search/indexing/local_import.rs b/src/search/indexing/local_import.rs
index 3b47db4ec..5a7e55d76 100644
--- a/src/search/indexing/local_import.rs
+++ b/src/search/indexing/local_import.rs
@@ -16,7 +16,7 @@ pub async fn index_local(
"
SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,
m.icon_url icon_url, m.published published, m.approved approved, m.updated updated,
- m.team_id team_id, m.license license, m.slug slug, m.status status_name,
+ m.team_id team_id, m.license license, m.slug slug, m.status status_name, m.color color,
cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, u.username username,
ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,
ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,
@@ -96,6 +96,7 @@ pub async fn index_local(
gallery,
display_categories,
open_source,
+ color: m.color.map(|x| x as u32),
}
}))
})
diff --git a/src/search/mod.rs b/src/search/mod.rs
index b78d7d499..d3d173dd4 100644
--- a/src/search/mod.rs
+++ b/src/search/mod.rs
@@ -98,6 +98,7 @@ pub struct UploadSearchProject {
/// Unix timestamp of the last major modification
pub modified_timestamp: i64,
pub open_source: bool,
+ pub color: Option,
}
#[derive(Serialize, Deserialize, Debug)]
@@ -132,6 +133,7 @@ pub struct ResultSearchProject {
pub client_side: String,
pub server_side: String,
pub gallery: Vec,
+ pub color: Option,
}
impl Document for UploadSearchProject {
diff --git a/src/util/ext.rs b/src/util/ext.rs
index a51a233ba..fec68eef8 100644
--- a/src/util/ext.rs
+++ b/src/util/ext.rs
@@ -2,12 +2,9 @@ pub fn get_image_content_type(extension: &str) -> Option<&'static str> {
match extension {
"bmp" => Some("image/bmp"),
"gif" => Some("image/gif"),
- "jpeg" | "jpg" | "jpe" => Some("image/jpeg"),
+ "jpeg" | "jpg" => Some("image/jpeg"),
"png" => Some("image/png"),
- "svg" | "svgz" => Some("image/svg+xml"),
"webp" => Some("image/webp"),
- "rgb" => Some("image/x-rgb"),
- "mp4" => Some("video/mp4"),
_ => None,
}
}
diff --git a/src/util/img.rs b/src/util/img.rs
new file mode 100644
index 000000000..1dd12f38d
--- /dev/null
+++ b/src/util/img.rs
@@ -0,0 +1,19 @@
+use color_thief::ColorFormat;
+use image::imageops::FilterType;
+use image::{EncodableLayout, ImageError};
+
+pub fn get_color_from_img(data: &[u8]) -> Result