From 1d7f13d1f52a3af7353895b604d016b2b74de241 Mon Sep 17 00:00:00 2001 From: Cory Dransfeldt Date: Sat, 14 Jun 2025 17:10:41 -0700 Subject: [PATCH] chore(*.sql): use sql-formatter for sql formatting --- .husky/pre-commit | 1 + package-lock.json | 87 ++- package.json | 6 +- queries/functions/get_feed_data.sql | 3 +- queries/functions/get_tagged_content.sql | 5 +- queries/functions/get_top_tags.sql | 3 +- queries/functions/parse_country_field.sql | 3 +- queries/functions/search.sql | 40 +- queries/functions/slugify.sql | 3 +- queries/functions/update_album_key.sql | 3 +- queries/functions/update_artist_key.sql | 3 +- queries/functions/update_days_read.sql | 3 +- queries/functions/update_listen_totals.sql | 3 +- .../update_scheduled_episode_status.sql | 3 +- .../functions/update_scheduled_on_watch.sql | 3 +- queries/jobs/update_scheduled_episodes.sql | 10 +- queries/selects/top_albums.sql | 13 +- queries/selects/top_artists.sql | 13 +- queries/triggers/decrement_total_plays.sql | 41 +- .../triggers/mark_scheduled_as_watched.sql | 5 +- queries/triggers/update_days_read.sql | 13 +- queries/triggers/update_scheduled_status.sql | 3 +- queries/triggers/update_total_plays.sql | 41 +- queries/views/content/blogroll.sql | 9 +- queries/views/content/links.sql | 41 +- queries/views/content/posts.sql | 474 +++++++++---- queries/views/feeds/all_activity.sql | 176 +++-- queries/views/feeds/headers.sql | 10 +- queries/views/feeds/oembed.sql | 219 ++++-- queries/views/feeds/recent_activity.sql | 269 ++++---- queries/views/feeds/robots.sql | 12 +- queries/views/feeds/search.sql | 233 +++---- queries/views/feeds/sitemap.sql | 95 +-- queries/views/feeds/stats.sql | 590 +++++++++++------ queries/views/feeds/syndication.sql | 226 ++++--- queries/views/feeds/tagged_content.sql | 24 +- queries/views/feeds/tags.sql | 9 +- queries/views/globals/index.sql | 86 +-- queries/views/globals/pages.sql | 134 ++-- queries/views/media/books.sql | 451 +++++++++---- queries/views/media/movies.sql | 426 +++++++----- queries/views/media/music/album_releases.sql | 34 +- queries/views/media/music/albums.sql | 55 +- queries/views/media/music/artists.sql | 497 +++++++++----- queries/views/media/music/concerts.sql | 20 +- queries/views/media/music/genres.sql | 293 +++++--- queries/views/media/music/latest_listen.sql | 14 +- queries/views/media/music/listens.sql | 10 +- queries/views/media/music/month/albums.sql | 19 +- queries/views/media/music/month/artists.sql | 19 +- queries/views/media/music/month/genres.sql | 8 +- queries/views/media/music/month/tracks.sql | 61 +- queries/views/media/music/recent_tracks.sql | 16 +- queries/views/media/music/week/albums.sql | 19 +- queries/views/media/music/week/artists.sql | 19 +- queries/views/media/music/week/genres.sql | 8 +- queries/views/media/music/week/summary.sql | 141 +++- queries/views/media/music/week/tracks.sql | 73 +- queries/views/media/recent_media.sql | 625 +++++++++++------- .../media/shows/last_watched_episodes.sql | 14 +- .../views/media/shows/scheduled_episodes.sql | 43 +- queries/views/media/shows/scheduled_shows.sql | 545 +++++++++------ queries/views/media/shows/shows.sql | 465 ++++++++----- 63 files changed, 4432 insertions(+), 2358 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 2312dc5..eaad2a0 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1,2 @@ npx lint-staged +npm run format:sql diff --git a/package-lock.json b/package-lock.json index 3171ba3..a49adcc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "coryd.dev", - "version": "10.2.4", + "version": "10.3.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coryd.dev", - "version": "10.2.4", + "version": "10.3.4", "license": "MIT", "dependencies": { "minisearch": "^7.1.2", @@ -34,6 +34,7 @@ "postcss-import-ext-glob": "^2.1.1", "prettier": "3.5.3", "rimraf": "^6.0.1", + "sql-formatter": "15.6.4", "terser": "^5.42.0", "truncate-html": "^1.2.2" }, @@ -1422,6 +1423,13 @@ "node": ">=4" } }, + "node_modules/discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", + "dev": true, + "license": "MIT" + }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -2858,6 +2866,36 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/nearley": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", + "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6" + }, + "bin": { + "nearley-railroad": "bin/nearley-railroad.js", + "nearley-test": "bin/nearley-test.js", + "nearley-unparse": "bin/nearley-unparse.js", + "nearleyc": "bin/nearleyc.js" + }, + "funding": { + "type": "individual", + "url": "https://nearley.js.org/#give-to-nearley" + } + }, + "node_modules/nearley/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -3930,6 +3968,27 @@ ], "license": "MIT" }, + "node_modules/railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -4034,6 +4093,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -4321,6 +4390,20 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/sql-formatter": { + "version": "15.6.4", + "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.6.4.tgz", + "integrity": "sha512-osSvFAtUu/SqT4ywdPTraCHR/VzMjeG+cXFEGwJJtm2SoA/uewU6Sm2HYyqo6W7VTGSWUWx7WT8KkE3HJq51cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "nearley": "^2.20.1" + }, + "bin": { + "sql-formatter": "bin/sql-formatter-cli.cjs" + } + }, "node_modules/ssri": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz", diff --git a/package.json b/package.json index 182c9f4..9151146 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coryd.dev", - "version": "10.2.4", + "version": "10.3.4", "description": "The source for my personal site. Built using 11ty (and other tools).", "type": "module", "engines": { @@ -13,7 +13,8 @@ "php": "export $(grep -v '^#' .env | xargs) && php -d error_reporting=E_ALL^E_DEPRECATED -S localhost:8080 -t dist", "build": "eleventy", "clean": "rimraf dist .cache", - "format": "npx prettier --write '**/*.{js,ts,json,css,md}' && composer format:php", + "format": "npx prettier --write '**/*.{js,ts,json,css,md}' && composer format:php && npm run format:sql", + "format:sql": "find queries -name '*.sql' -print0 | xargs -0 -n 1 sql-formatter --language postgresql --fix", "update": "composer update && npm upgrade && npm --prefix cli upgrade && ncu && ncu --cwd cli", "setup": "sh ./scripts/setup.sh", "setup:deploy": "sh ./scripts/setup.sh --deploy", @@ -60,6 +61,7 @@ "postcss-import-ext-glob": "^2.1.1", "prettier": "3.5.3", "rimraf": "^6.0.1", + "sql-formatter": "15.6.4", "terser": "^5.42.0", "truncate-html": "^1.2.2" } diff --git a/queries/functions/get_feed_data.sql b/queries/functions/get_feed_data.sql index 9a144bd..6144d10 100644 --- a/queries/functions/get_feed_data.sql +++ b/queries/functions/get_feed_data.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION get_feed_data(feed_key TEXT) -RETURNS JSON AS $$ +CREATE OR REPLACE FUNCTION get_feed_data (feed_key TEXT) RETURNS JSON AS $$ DECLARE result JSON; sql_query TEXT; diff --git a/queries/functions/get_tagged_content.sql b/queries/functions/get_tagged_content.sql index 1484168..23c124a 100644 --- a/queries/functions/get_tagged_content.sql +++ b/queries/functions/get_tagged_content.sql @@ -1,9 +1,8 @@ -CREATE OR REPLACE FUNCTION get_tagged_content( +CREATE OR REPLACE FUNCTION get_tagged_content ( tag_query TEXT, page_size INTEGER DEFAULT 20, page_offset INTEGER DEFAULT 0 -) -RETURNS TABLE ( +) RETURNS TABLE ( tag TEXT, title TEXT, url TEXT, diff --git a/queries/functions/get_top_tags.sql b/queries/functions/get_top_tags.sql index 2e91066..a4edb37 100644 --- a/queries/functions/get_top_tags.sql +++ b/queries/functions/get_top_tags.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION get_top_tag_groups() -RETURNS JSON AS $$ +CREATE OR REPLACE FUNCTION get_top_tag_groups () RETURNS JSON AS $$ BEGIN RETURN json_build_object( 'tags', ( diff --git a/queries/functions/parse_country_field.sql b/queries/functions/parse_country_field.sql index b2d9269..d0a89ec 100644 --- a/queries/functions/parse_country_field.sql +++ b/queries/functions/parse_country_field.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION normalize_country_field(countryField TEXT) -RETURNS TEXT AS $$ +CREATE OR REPLACE FUNCTION normalize_country_field (countryField TEXT) RETURNS TEXT AS $$ DECLARE delimiters TEXT[] := ARRAY[',', '/', '&', 'and']; countries TEXT[]; diff --git a/queries/functions/search.sql b/queries/functions/search.sql index 0e07833..3285b7b 100644 --- a/queries/functions/search.sql +++ b/queries/functions/search.sql @@ -1,21 +1,24 @@ -DROP FUNCTION IF EXISTS search_optimized_index(text, integer, integer, text[]); +DROP FUNCTION IF EXISTS search_optimized_index (text, integer, integer, text[]); -CREATE FUNCTION search_optimized_index(search_query text, page_size integer, page_offset integer, sections text[]) - RETURNS TABLE( - result_id integer, - url text, - title text, - description text, - tags text[], - genre_name text, - genre_url text, - section text, - type text, - total_plays text, - rank real, - total_count bigint - ) - AS $$ +CREATE FUNCTION search_optimized_index ( + search_query text, + page_size integer, + page_offset integer, + sections text[] +) RETURNS TABLE ( + result_id integer, + url text, + title text, + description text, + tags text[], + genre_name text, + genre_url text, + section text, + type text, + total_plays text, + rank real, + total_count bigint +) AS $$ BEGIN RETURN QUERY SELECT @@ -42,5 +45,4 @@ BEGIN rank DESC LIMIT page_size OFFSET page_offset; END; -$$ -LANGUAGE plpgsql; +$$ LANGUAGE plpgsql; diff --git a/queries/functions/slugify.sql b/queries/functions/slugify.sql index edf4836..8f61d90 100644 --- a/queries/functions/slugify.sql +++ b/queries/functions/slugify.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION slugify(input TEXT) -RETURNS TEXT AS $$ +CREATE OR REPLACE FUNCTION slugify (input TEXT) RETURNS TEXT AS $$ BEGIN RETURN lower(regexp_replace(unaccent(regexp_replace(input, '[^\w\s-]', '', 'g')), '\s+', '-', 'g')); END; diff --git a/queries/functions/update_album_key.sql b/queries/functions/update_album_key.sql index 5da8434..dce55ba 100644 --- a/queries/functions/update_album_key.sql +++ b/queries/functions/update_album_key.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION update_album_key(old_album_key TEXT, new_album_key TEXT) -RETURNS void AS $$ +CREATE OR REPLACE FUNCTION update_album_key (old_album_key TEXT, new_album_key TEXT) RETURNS void AS $$ BEGIN UPDATE listens SET album_key = new_album_key diff --git a/queries/functions/update_artist_key.sql b/queries/functions/update_artist_key.sql index cc386f2..e2bd4d0 100644 --- a/queries/functions/update_artist_key.sql +++ b/queries/functions/update_artist_key.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION update_artist_name(old_artist_name TEXT, new_artist_name TEXT) -RETURNS void AS $$ +CREATE OR REPLACE FUNCTION update_artist_name (old_artist_name TEXT, new_artist_name TEXT) RETURNS void AS $$ BEGIN UPDATE listens SET artist_name = new_artist_name diff --git a/queries/functions/update_days_read.sql b/queries/functions/update_days_read.sql index 125d2b1..c86a159 100644 --- a/queries/functions/update_days_read.sql +++ b/queries/functions/update_days_read.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION update_days_read() -RETURNS TRIGGER AS $$ +CREATE OR REPLACE FUNCTION update_days_read () RETURNS TRIGGER AS $$ DECLARE pacific_today DATE; last_read DATE; diff --git a/queries/functions/update_listen_totals.sql b/queries/functions/update_listen_totals.sql index 827ba33..8b1b877 100644 --- a/queries/functions/update_listen_totals.sql +++ b/queries/functions/update_listen_totals.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION update_listen_totals() -RETURNS void AS $$ +CREATE OR REPLACE FUNCTION update_listen_totals () RETURNS void AS $$ BEGIN WITH artist_plays AS ( SELECT artist_name, COUNT(*)::integer AS total_plays diff --git a/queries/functions/update_scheduled_episode_status.sql b/queries/functions/update_scheduled_episode_status.sql index 066a454..c71fae7 100644 --- a/queries/functions/update_scheduled_episode_status.sql +++ b/queries/functions/update_scheduled_episode_status.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION update_scheduled_episode_status() -RETURNS TRIGGER AS $$ +CREATE OR REPLACE FUNCTION update_scheduled_episode_status () RETURNS TRIGGER AS $$ BEGIN UPDATE scheduled_episodes SET status = 'aired' diff --git a/queries/functions/update_scheduled_on_watch.sql b/queries/functions/update_scheduled_on_watch.sql index 913ac8c..a08d109 100644 --- a/queries/functions/update_scheduled_on_watch.sql +++ b/queries/functions/update_scheduled_on_watch.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION update_scheduled_on_watch() -RETURNS TRIGGER AS $$ +CREATE OR REPLACE FUNCTION update_scheduled_on_watch () RETURNS TRIGGER AS $$ BEGIN UPDATE scheduled_episodes SET status = 'watched' diff --git a/queries/jobs/update_scheduled_episodes.sql b/queries/jobs/update_scheduled_episodes.sql index bca8c8d..86ee668 100644 --- a/queries/jobs/update_scheduled_episodes.sql +++ b/queries/jobs/update_scheduled_episodes.sql @@ -1,6 +1,8 @@ -SELECT cron.schedule( - '0 0 * * *', - $$ UPDATE scheduled_episodes +SELECT + cron.schedule ( + '0 0 * * *', + $$ UPDATE scheduled_episodes SET status = 'aired' WHERE air_date < CURRENT_DATE - AND status = 'upcoming' $$); + AND status = 'upcoming' $$ + ); diff --git a/queries/selects/top_albums.sql b/queries/selects/top_albums.sql index ad85c4c..6d9681c 100644 --- a/queries/selects/top_albums.sql +++ b/queries/selects/top_albums.sql @@ -5,7 +5,15 @@ SELECT FROM optimized_listens l WHERE - EXTRACT(YEAR FROM TO_TIMESTAMP(l.listened_at)) = EXTRACT(YEAR FROM CURRENT_DATE) + EXTRACT( + YEAR + FROM + TO_TIMESTAMP(l.listened_at) + ) = EXTRACT( + YEAR + FROM + CURRENT_DATE + ) AND l.artist_name IS NOT NULL AND l.album_name IS NOT NULL GROUP BY @@ -13,4 +21,5 @@ GROUP BY l.album_name ORDER BY COUNT(l.id) DESC -LIMIT 10; +LIMIT + 10; diff --git a/queries/selects/top_artists.sql b/queries/selects/top_artists.sql index 1e0b5ee..e8923e5 100644 --- a/queries/selects/top_artists.sql +++ b/queries/selects/top_artists.sql @@ -4,10 +4,19 @@ SELECT FROM optimized_listens l WHERE - EXTRACT(YEAR FROM TO_TIMESTAMP(l.listened_at)) = EXTRACT(YEAR FROM CURRENT_DATE) + EXTRACT( + YEAR + FROM + TO_TIMESTAMP(l.listened_at) + ) = EXTRACT( + YEAR + FROM + CURRENT_DATE + ) AND l.artist_name IS NOT NULL GROUP BY l.artist_name ORDER BY COUNT(l.id) DESC -LIMIT 10; +LIMIT + 10; diff --git a/queries/triggers/decrement_total_plays.sql b/queries/triggers/decrement_total_plays.sql index 5dc3eb6..b3bcd4c 100644 --- a/queries/triggers/decrement_total_plays.sql +++ b/queries/triggers/decrement_total_plays.sql @@ -1,17 +1,30 @@ BEGIN - UPDATE artists - SET total_plays = total_plays - 1 - WHERE name_string = OLD.artist_name; - UPDATE albums - SET total_plays = total_plays - 1 - WHERE name = OLD.album_name - AND artist_name = OLD.artist_name; - UPDATE genres - SET total_plays = total_plays - 1 - WHERE id = ( - SELECT genres - FROM artists - WHERE name_string = OLD.artist_name +UPDATE artists +SET + total_plays = total_plays - 1 +WHERE + name_string = OLD.artist_name; + +UPDATE albums +SET + total_plays = total_plays - 1 +WHERE + name = OLD.album_name + AND artist_name = OLD.artist_name; + +UPDATE genres +SET + total_plays = total_plays - 1 +WHERE + id = ( + SELECT + genres + FROM + artists + WHERE + name_string = OLD.artist_name ); - RETURN OLD; + +RETURN OLD; + END; diff --git a/queries/triggers/mark_scheduled_as_watched.sql b/queries/triggers/mark_scheduled_as_watched.sql index 90a5741..a7579ad 100644 --- a/queries/triggers/mark_scheduled_as_watched.sql +++ b/queries/triggers/mark_scheduled_as_watched.sql @@ -1,4 +1,3 @@ CREATE TRIGGER mark_scheduled_as_watched -AFTER INSERT ON episodes -FOR EACH ROW -EXECUTE FUNCTION update_scheduled_on_watch(); +AFTER INSERT ON episodes FOR EACH ROW +EXECUTE FUNCTION update_scheduled_on_watch (); diff --git a/queries/triggers/update_days_read.sql b/queries/triggers/update_days_read.sql index 2f8b019..d25a987 100644 --- a/queries/triggers/update_days_read.sql +++ b/queries/triggers/update_days_read.sql @@ -1,5 +1,10 @@ CREATE TRIGGER trigger_update_days_read -AFTER UPDATE OF progress ON books -FOR EACH ROW -WHEN (OLD.progress IS DISTINCT FROM NEW.progress AND (NEW.read_status = 'started' OR NEW.read_status = 'finished')) -EXECUTE FUNCTION update_days_read(); +AFTER +UPDATE OF progress ON books FOR EACH ROW WHEN ( + OLD.progress IS DISTINCT FROM NEW.progress + AND ( + NEW.read_status = 'started' + OR NEW.read_status = 'finished' + ) +) +EXECUTE FUNCTION update_days_read (); diff --git a/queries/triggers/update_scheduled_status.sql b/queries/triggers/update_scheduled_status.sql index 228a928..cccb7a4 100644 --- a/queries/triggers/update_scheduled_status.sql +++ b/queries/triggers/update_scheduled_status.sql @@ -1,5 +1,4 @@ -CREATE OR REPLACE FUNCTION update_scheduled_episode_status() -RETURNS TRIGGER AS $$ +CREATE OR REPLACE FUNCTION update_scheduled_episode_status () RETURNS TRIGGER AS $$ BEGIN IF NEW.air_date < CURRENT_DATE AND NEW.status = 'upcoming' THEN NEW.status := 'aired'; diff --git a/queries/triggers/update_total_plays.sql b/queries/triggers/update_total_plays.sql index a533664..992b862 100644 --- a/queries/triggers/update_total_plays.sql +++ b/queries/triggers/update_total_plays.sql @@ -1,17 +1,30 @@ BEGIN - UPDATE artists - SET total_plays = total_plays + 1 - WHERE name_string = NEW.artist_name; - UPDATE albums - SET total_plays = total_plays + 1 - WHERE key = NEW.album_key - AND artist_name = NEW.artist_name; - UPDATE genres - SET total_plays = total_plays + 1 - WHERE id = ( - SELECT genres - FROM artists - WHERE name_string = NEW.artist_name +UPDATE artists +SET + total_plays = total_plays + 1 +WHERE + name_string = NEW.artist_name; + +UPDATE albums +SET + total_plays = total_plays + 1 +WHERE + key = NEW.album_key + AND artist_name = NEW.artist_name; + +UPDATE genres +SET + total_plays = total_plays + 1 +WHERE + id = ( + SELECT + genres + FROM + artists + WHERE + name_string = NEW.artist_name ); - RETURN NEW; + +RETURN NEW; + END; diff --git a/queries/views/content/blogroll.sql b/queries/views/content/blogroll.sql index be185d4..67429c7 100644 --- a/queries/views/content/blogroll.sql +++ b/queries/views/content/blogroll.sql @@ -6,6 +6,9 @@ SELECT json_feed, newsletter, mastodon -FROM authors -WHERE blogroll = true -ORDER BY LOWER(unaccent(name)) ASC; +FROM + authors +WHERE + blogroll = true +ORDER BY + LOWER(unaccent (name)) ASC; diff --git a/queries/views/content/links.sql b/queries/views/content/links.sql index 5156f6c..c24200a 100644 --- a/queries/views/content/links.sql +++ b/queries/views/content/links.sql @@ -7,24 +7,45 @@ SELECT l.link, a.mastodon, a.name, - json_build_object('name', a.name, 'url', a.url, 'mastodon', a.mastodon) AS author, + json_build_object( + 'name', + a.name, + 'url', + a.url, + 'mastodon', + a.mastodon + ) AS author, 'link' AS type, ( - SELECT array_agg(t.name) - FROM links_tags lt - LEFT JOIN tags t ON lt.tags_id = t.id - WHERE lt.links_id = l.id + SELECT + array_agg(t.name) + FROM + links_tags lt + LEFT JOIN tags t ON lt.tags_id = t.id + WHERE + lt.links_id = l.id ) AS tags, json_build_object( - 'title', CONCAT(l.title, ' via ', a.name), - 'url', l.link, - 'description', l.description, - 'date', l.date + 'title', + CONCAT(l.title, ' via ', a.name), + 'url', + l.link, + 'description', + l.description, + 'date', + l.date ) AS feed FROM links l JOIN authors a ON l.author = a.id GROUP BY - l.id, l.title, l.date, l.description, l.link, a.mastodon, a.name, a.url + l.id, + l.title, + l.date, + l.description, + l.link, + a.mastodon, + a.name, + a.url ORDER BY l.date DESC; diff --git a/queries/views/content/posts.sql b/queries/views/content/posts.sql index 5c8e051..dd973e3 100644 --- a/queries/views/content/posts.sql +++ b/queries/views/content/posts.sql @@ -8,183 +8,367 @@ SELECT p.featured, p.slug AS url, CASE - WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN - CONCAT(globals.cdn_url, '/', df.filename_disk) + WHEN df.filename_disk IS NOT NULL + AND df.filename_disk != '' + AND df.filename_disk != '/' THEN CONCAT(globals.cdn_url, '/', df.filename_disk) ELSE NULL END AS image, p.image_alt, - CASE WHEN EXTRACT(YEAR FROM AGE(CURRENT_DATE, p.date)) > 3 THEN TRUE ELSE FALSE END AS old_post, + CASE + WHEN EXTRACT( + YEAR + FROM + AGE (CURRENT_DATE, p.date) + ) > 3 THEN TRUE + ELSE FALSE + END AS old_post, ( - SELECT json_agg(CASE - WHEN pb.collection = 'youtube_player' THEN json_build_object('type', pb.collection, 'url', yp.url) - WHEN pb.collection = 'forgejo_banner' THEN json_build_object('type', pb.collection, 'url', fb.url) - WHEN pb.collection = 'github_banner' THEN json_build_object('type', pb.collection, 'url', gb.url) - WHEN pb.collection = 'npm_banner' THEN json_build_object('type', pb.collection, 'url', nb.url, 'command', nb.command) - WHEN pb.collection = 'rss_banner' THEN json_build_object('type', pb.collection, 'url', rb.url, 'text', rb.text) - WHEN pb.collection = 'calendar_banner' THEN json_build_object('type', pb.collection, 'url', cb.url, 'text', cb.text) - WHEN pb.collection = 'hero' THEN json_build_object('type', pb.collection, 'image', CONCAT('/', df_hero.filename_disk), 'alt_text', h.alt_text) - WHEN pb.collection = 'markdown' THEN json_build_object('type', pb.collection, 'text', md.text) - ELSE json_build_object('type', pb.collection) - END) - FROM posts_blocks pb - LEFT JOIN youtube_player yp ON pb.collection = 'youtube_player' AND yp.id = pb.item::integer - LEFT JOIN forgejo_banner fb ON pb.collection = 'forgejo_banner' AND fb.id = pb.item::integer - LEFT JOIN github_banner gb ON pb.collection = 'github_banner' AND gb.id = pb.item::integer - LEFT JOIN npm_banner nb ON pb.collection = 'npm_banner' AND nb.id = pb.item::integer - LEFT JOIN rss_banner rb ON pb.collection = 'rss_banner' AND rb.id = pb.item::integer - LEFT JOIN calendar_banner cb ON pb.collection = 'calendar_banner' AND cb.id = pb.item::integer - LEFT JOIN hero h ON pb.collection = 'hero' AND h.id = pb.item::integer - LEFT JOIN directus_files df_hero ON h.image = df_hero.id - LEFT JOIN markdown md ON pb.collection = 'markdown' AND md.id = pb.item::integer - WHERE pb.posts_id = p.id + SELECT + json_agg( + CASE + WHEN pb.collection = 'youtube_player' THEN json_build_object('type', pb.collection, 'url', yp.url) + WHEN pb.collection = 'forgejo_banner' THEN json_build_object('type', pb.collection, 'url', fb.url) + WHEN pb.collection = 'github_banner' THEN json_build_object('type', pb.collection, 'url', gb.url) + WHEN pb.collection = 'npm_banner' THEN json_build_object( + 'type', + pb.collection, + 'url', + nb.url, + 'command', + nb.command + ) + WHEN pb.collection = 'rss_banner' THEN json_build_object( + 'type', + pb.collection, + 'url', + rb.url, + 'text', + rb.text + ) + WHEN pb.collection = 'calendar_banner' THEN json_build_object( + 'type', + pb.collection, + 'url', + cb.url, + 'text', + cb.text + ) + WHEN pb.collection = 'hero' THEN json_build_object( + 'type', + pb.collection, + 'image', + CONCAT('/', df_hero.filename_disk), + 'alt_text', + h.alt_text + ) + WHEN pb.collection = 'markdown' THEN json_build_object('type', pb.collection, 'text', md.text) + ELSE json_build_object('type', pb.collection) + END + ) + FROM + posts_blocks pb + LEFT JOIN youtube_player yp ON pb.collection = 'youtube_player' + AND yp.id = pb.item::integer + LEFT JOIN forgejo_banner fb ON pb.collection = 'forgejo_banner' + AND fb.id = pb.item::integer + LEFT JOIN github_banner gb ON pb.collection = 'github_banner' + AND gb.id = pb.item::integer + LEFT JOIN npm_banner nb ON pb.collection = 'npm_banner' + AND nb.id = pb.item::integer + LEFT JOIN rss_banner rb ON pb.collection = 'rss_banner' + AND rb.id = pb.item::integer + LEFT JOIN calendar_banner cb ON pb.collection = 'calendar_banner' + AND cb.id = pb.item::integer + LEFT JOIN hero h ON pb.collection = 'hero' + AND h.id = pb.item::integer + LEFT JOIN directus_files df_hero ON h.image = df_hero.id + LEFT JOIN markdown md ON pb.collection = 'markdown' + AND md.id = pb.item::integer + WHERE + pb.posts_id = p.id ) AS blocks, ( - SELECT array_agg(t.name) - FROM posts_tags pt - LEFT JOIN tags t ON pt.tags_id = t.id - WHERE pt.posts_id = p.id + SELECT + array_agg(t.name) + FROM + posts_tags pt + LEFT JOIN tags t ON pt.tags_id = t.id + WHERE + pt.posts_id = p.id ) AS tags, ( - SELECT json_agg(json_build_object('name', g.name, 'url', g.slug) ORDER BY g.name ASC) - FROM posts_genres gp - LEFT JOIN genres g ON gp.genres_id = g.id - WHERE gp.posts_id = p.id + SELECT + json_agg( + json_build_object('name', g.name, 'url', g.slug) + ORDER BY + g.name ASC + ) + FROM + posts_genres gp + LEFT JOIN genres g ON gp.genres_id = g.id + WHERE + gp.posts_id = p.id ) AS genres, ( - SELECT json_agg(json_build_object( - 'name', a.name_string, - 'url', a.slug, - 'country', a.country, - 'total_plays', a.total_plays, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'grid', json_build_object( - 'title', a.name_string, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'alt', CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name_string), - 'subtext', CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays'), - 'url', a.slug - ), - 'type', 'music' - ) ORDER BY a.total_plays DESC) - FROM posts_artists pa - LEFT JOIN artists a ON pa.artists_id = a.id - LEFT JOIN directus_files df_artist ON a.art = df_artist.id - WHERE pa.posts_id = p.id - AND a.total_plays IS NOT NULL AND a.total_plays > 0 + SELECT + json_agg( + json_build_object( + 'name', + a.name_string, + 'url', + a.slug, + 'country', + a.country, + 'total_plays', + a.total_plays, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'grid', + json_build_object( + 'title', + a.name_string, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'alt', + CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays of ', + a.name_string + ), + 'subtext', + CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays' + ), + 'url', + a.slug + ), + 'type', + 'music' + ) + ORDER BY + a.total_plays DESC + ) + FROM + posts_artists pa + LEFT JOIN artists a ON pa.artists_id = a.id + LEFT JOIN directus_files df_artist ON a.art = df_artist.id + WHERE + pa.posts_id = p.id + AND a.total_plays IS NOT NULL + AND a.total_plays > 0 ) AS artists, ( - SELECT json_agg(json_build_object( - 'title', b.title, - 'author', b.author, - 'url', b.slug, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'alt', CONCAT('Cover for ', b.title, ' by ', b.author), - 'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating ELSE NULL END, - 'url', b.slug - ), - 'type', 'books' - ) ORDER BY b.title ASC) - FROM posts_books pbk - LEFT JOIN books b ON pbk.books_id = b.id - LEFT JOIN directus_files df_book ON b.art = df_book.id - WHERE pbk.posts_id = p.id + SELECT + json_agg( + json_build_object( + 'title', + b.title, + 'author', + b.author, + 'url', + b.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'alt', + CONCAT('Cover for ', b.title, ' by ', b.author), + 'subtext', + CASE + WHEN b.star_rating IS NOT NULL THEN b.star_rating + ELSE NULL + END, + 'url', + b.slug + ), + 'type', + 'books' + ) + ORDER BY + b.title ASC + ) + FROM + posts_books pbk + LEFT JOIN books b ON pbk.books_id = b.id + LEFT JOIN directus_files df_book ON b.art = df_book.id + WHERE + pbk.posts_id = p.id AND LOWER(b.read_status) = 'finished' ) AS books, ( - SELECT json_agg(json_build_object( - 'title', m.title, - 'year', m.year, - 'url', m.slug, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), - 'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, - 'url', m.slug - ), - 'type', 'movies' - ) ORDER BY m.year ASC) - FROM posts_movies pm - LEFT JOIN movies m ON pm.movies_id = m.id - LEFT JOIN directus_files df_movie ON m.art = df_movie.id - WHERE pm.posts_id = p.id AND m.last_watched IS NOT NULL + SELECT + json_agg( + json_build_object( + 'title', + m.title, + 'year', + m.year, + 'url', + m.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'alt', + CONCAT('Poster for ', m.title, ' (', m.year, ')'), + 'subtext', + CASE + WHEN m.star_rating IS NOT NULL THEN m.star_rating::text + ELSE m.year::text + END, + 'url', + m.slug + ), + 'type', + 'movies' + ) + ORDER BY + m.year ASC + ) + FROM + posts_movies pm + LEFT JOIN movies m ON pm.movies_id = m.id + LEFT JOIN directus_files df_movie ON m.art = df_movie.id + WHERE + pm.posts_id = p.id + AND m.last_watched IS NOT NULL ) AS movies, ( - SELECT json_agg(json_build_object( - 'title', s.title, - 'year', s.year, - 'url', s.slug, - 'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), - 'alt', CONCAT('Artwork for ', s.title), - 'subtext', CASE - WHEN ( - SELECT MAX(e1.last_watched_at) - FROM episodes e1 - WHERE e1.show = s.id - ) >= NOW() - INTERVAL '90 days' THEN - ( - SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) - FROM episodes e2 - WHERE e2.show = s.id - ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC - LIMIT 1 - ) - ELSE s.year::text - END, - 'url', s.slug - ), - 'type', 'tv' - ) ORDER BY s.year ASC) - FROM posts_shows ps - LEFT JOIN shows s ON ps.shows_id = s.id - LEFT JOIN directus_files df_show ON s.art = df_show.id - WHERE ps.posts_id = p.id + SELECT + json_agg( + json_build_object( + 'title', + s.title, + 'year', + s.year, + 'url', + s.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_show.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_show.filename_disk), + 'alt', + CONCAT('Artwork for ', s.title), + 'subtext', + CASE + WHEN ( + SELECT + MAX(e1.last_watched_at) + FROM + episodes e1 + WHERE + e1.show = s.id + ) >= NOW() - INTERVAL '90 days' THEN ( + SELECT + CONCAT('S', e2.season_number, 'E', e2.episode_number) + FROM + episodes e2 + WHERE + e2.show = s.id + ORDER BY + e2.last_watched_at DESC, + e2.season_number DESC, + e2.episode_number DESC + LIMIT + 1 + ) + ELSE s.year::text + END, + 'url', + s.slug + ), + 'type', + 'tv' + ) + ORDER BY + s.year ASC + ) + FROM + posts_shows ps + LEFT JOIN shows s ON ps.shows_id = s.id + LEFT JOIN directus_files df_show ON s.art = df_show.id + WHERE + ps.posts_id = p.id AND EXISTS ( - SELECT 1 - FROM episodes e - WHERE e.show = s.id + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id AND e.last_watched_at IS NOT NULL ) ) AS shows, json_build_object( - 'title', p.title, - 'url', p.slug, - 'description', p.description, - 'content', p.content, - 'date', p.date, - 'image', CASE - WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CONCAT(globals.cdn_url, '/', df.filename_disk) + 'title', + p.title, + 'url', + p.slug, + 'description', + p.description, + 'content', + p.content, + 'date', + p.date, + 'image', + CASE + WHEN df.filename_disk IS NOT NULL + AND df.filename_disk != '' + AND df.filename_disk != '/' THEN CONCAT(globals.cdn_url, '/', df.filename_disk) ELSE NULL END ) AS feed, json_build_object( - 'title', p.title, - 'description', LEFT( + 'title', + p.title, + 'description', + LEFT( regexp_replace( regexp_replace( regexp_replace(p.description, E'[*_`~#>-]', '', 'g'), - E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' + E'\\[(.*?)\\]\\((.*?)\\)', + E'\\1', + 'g' ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' ), 250 ), - 'open_graph_image', CASE - WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN - CONCAT('/', df.filename_disk) - ELSE globals.metadata->>'open_graph_image' + 'open_graph_image', + CASE + WHEN df.filename_disk IS NOT NULL + AND df.filename_disk != '' + AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) + ELSE globals.metadata ->> 'open_graph_image' END, - 'url', CONCAT(globals.url, p.slug), - 'type', 'article' + 'url', + CONCAT(globals.url, p.slug), + 'type', + 'article' ) AS metadata -FROM posts p -LEFT JOIN directus_files df ON p.image = df.id -CROSS JOIN optimized_globals globals -GROUP BY p.id, df.filename_disk, globals.cdn_url, globals.site_name, globals.url, globals.metadata->>'open_graph_image'; +FROM + posts p + LEFT JOIN directus_files df ON p.image = df.id + CROSS JOIN optimized_globals globals +GROUP BY + p.id, + df.filename_disk, + globals.cdn_url, + globals.site_name, + globals.url, + globals.metadata ->> 'open_graph_image'; diff --git a/queries/views/feeds/all_activity.sql b/queries/views/feeds/all_activity.sql index a37ac8c..ad15d55 100644 --- a/queries/views/feeds/all_activity.sql +++ b/queries/views/feeds/all_activity.sql @@ -1,65 +1,117 @@ CREATE OR REPLACE VIEW optimized_all_activity AS -WITH feed_data AS ( - SELECT json_build_object( - 'title', p.title, - 'url', p.url, - 'description', p.content, - 'date', p.date, - 'type', 'article', - 'label', 'Post', - 'content', p.content - ) AS feed - FROM optimized_posts p - UNION ALL - SELECT json_build_object( - 'title', CONCAT(l.title, ' via ', l.author->>'name'), - 'url', l.link, - 'description', l.description, - 'date', l.date, - 'type', 'link', - 'label', 'Link', - 'author', l.author - ) AS feed - FROM optimized_links l - UNION ALL - SELECT CASE - WHEN LOWER(b.status) = 'finished' THEN +WITH + feed_data AS ( + SELECT json_build_object( - 'title', CONCAT(b.title, ' by ', b.author, - CASE WHEN b.rating IS NOT NULL THEN CONCAT(' (', b.rating, ')') ELSE '' END - ), - 'url', b.url, - 'description', COALESCE(b.review, b.description), - 'date', b.date_finished, - 'type', 'books', - 'label', 'Book', - 'image', b.image, - 'rating', b.rating - ) - ELSE NULL - END AS feed - FROM optimized_books b - UNION ALL - SELECT CASE - WHEN m.last_watched IS NOT NULL THEN + 'title', + p.title, + 'url', + p.url, + 'description', + p.content, + 'date', + p.date, + 'type', + 'article', + 'label', + 'Post', + 'content', + p.content + ) AS feed + FROM + optimized_posts p + UNION ALL + SELECT json_build_object( - 'title', CONCAT(m.title, - CASE WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')') ELSE '' END - ), - 'url', m.url, - 'description', COALESCE(m.review, m.description), - 'date', m.last_watched, - 'type', 'movies', - 'label', 'Movie', - 'image', m.image, - 'rating', m.rating - ) - ELSE NULL - END AS feed - FROM optimized_movies m -) -SELECT feed -FROM feed_data -WHERE feed IS NOT NULL -ORDER BY (feed->>'date')::timestamp DESC -LIMIT 20; + 'title', + CONCAT(l.title, ' via ', l.author ->> 'name'), + 'url', + l.link, + 'description', + l.description, + 'date', + l.date, + 'type', + 'link', + 'label', + 'Link', + 'author', + l.author + ) AS feed + FROM + optimized_links l + UNION ALL + SELECT + CASE + WHEN LOWER(b.status) = 'finished' THEN json_build_object( + 'title', + CONCAT( + b.title, + ' by ', + b.author, + CASE + WHEN b.rating IS NOT NULL THEN CONCAT(' (', b.rating, ')') + ELSE '' + END + ), + 'url', + b.url, + 'description', + COALESCE(b.review, b.description), + 'date', + b.date_finished, + 'type', + 'books', + 'label', + 'Book', + 'image', + b.image, + 'rating', + b.rating + ) + ELSE NULL + END AS feed + FROM + optimized_books b + UNION ALL + SELECT + CASE + WHEN m.last_watched IS NOT NULL THEN json_build_object( + 'title', + CONCAT( + m.title, + CASE + WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')') + ELSE '' + END + ), + 'url', + m.url, + 'description', + COALESCE(m.review, m.description), + 'date', + m.last_watched, + 'type', + 'movies', + 'label', + 'Movie', + 'image', + m.image, + 'rating', + m.rating + ) + ELSE NULL + END AS feed + FROM + optimized_movies m + ) +SELECT + feed +FROM + feed_data +WHERE + feed IS NOT NULL +ORDER BY + (feed ->> 'date')::timestamp DESC +LIMIT + 20; diff --git a/queries/views/feeds/headers.sql b/queries/views/feeds/headers.sql index 9d48bdf..f5aff82 100644 --- a/queries/views/feeds/headers.sql +++ b/queries/views/feeds/headers.sql @@ -1,12 +1,12 @@ CREATE OR REPLACE VIEW optimized_headers AS SELECT p.path AS resource_path, - json_agg(json_build_object('header_name', hr.name, 'header_value', hr.value)) AS headers + json_agg( + json_build_object('header_name', hr.name, 'header_value', hr.value) + ) AS headers FROM paths p -JOIN - paths_header_rules phr ON p.id = phr.paths_id -JOIN - header_rules hr ON phr.header_rules_id = hr.id + JOIN paths_header_rules phr ON p.id = phr.paths_id + JOIN header_rules hr ON phr.header_rules_id = hr.id GROUP BY p.path; diff --git a/queries/views/feeds/oembed.sql b/queries/views/feeds/oembed.sql index 23bc635..9799183 100644 --- a/queries/views/feeds/oembed.sql +++ b/queries/views/feeds/oembed.sql @@ -1,70 +1,151 @@ -CREATE OR REPLACE VIEW optimized_oembed AS -WITH oembed_data AS ( - SELECT - 'post' AS type, - p.url::TEXT AS url, - p.title AS title, - p.description AS description, - COALESCE(NULLIF(p.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, - p.date AS content_date - FROM optimized_posts p - UNION ALL - SELECT - 'page' AS type, - pa.permalink::TEXT AS url, - pa.title AS title, - pa.description AS description, - COALESCE(NULLIF(pa.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, - NULL::timestamptz AS content_date - FROM optimized_pages pa - UNION ALL - SELECT - 'book' AS type, - b.url::TEXT AS url, - b.title AS title, - b.description AS description, - COALESCE(NULLIF(b.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, - b.date_finished AS content_date - FROM optimized_books b - UNION ALL - SELECT - 'artist' AS type, - ar.url::TEXT AS url, - ar.name AS title, - ar.description AS description, - COALESCE(NULLIF(ar.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, - CURRENT_TIMESTAMP AS content_date - FROM optimized_artists ar - UNION ALL - SELECT - 'genre' AS type, - g.url::TEXT AS url, - g.name AS title, - g.description AS description, - COALESCE(NULLIF(g.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, - CURRENT_TIMESTAMP AS content_date - FROM optimized_genres g - UNION ALL - SELECT - 'show' AS type, - s.url::TEXT AS url, - s.title AS title, - s.description AS description, - COALESCE(NULLIF(s.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, - s.last_watched_at AS content_date - FROM optimized_shows s - UNION ALL - SELECT - 'movie' AS type, - m.url::TEXT AS url, - m.title AS title, - m.description AS description, - COALESCE(NULLIF(m.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, - m.last_watched AS content_date - FROM optimized_movies m -) -SELECT - ROW_NUMBER() OVER (ORDER BY url) AS id, - * -FROM +CREATE OR REPLACE VIEW optimized_oembed AS +WITH + oembed_data AS ( + SELECT + 'post' AS type, + p.url::TEXT AS url, + p.title AS title, + p.description AS description, + COALESCE( + NULLIF(p.metadata ->> 'open_graph_image', ''), + ( + SELECT + metadata ->> 'open_graph_image' + FROM + optimized_globals + LIMIT + 1 + ) + ) AS image_url, + p.date AS content_date + FROM + optimized_posts p + UNION ALL + SELECT + 'page' AS type, + pa.permalink::TEXT AS url, + pa.title AS title, + pa.description AS description, + COALESCE( + NULLIF(pa.metadata ->> 'open_graph_image', ''), + ( + SELECT + metadata ->> 'open_graph_image' + FROM + optimized_globals + LIMIT + 1 + ) + ) AS image_url, + NULL::timestamptz AS content_date + FROM + optimized_pages pa + UNION ALL + SELECT + 'book' AS type, + b.url::TEXT AS url, + b.title AS title, + b.description AS description, + COALESCE( + NULLIF(b.metadata ->> 'open_graph_image', ''), + ( + SELECT + metadata ->> 'open_graph_image' + FROM + optimized_globals + LIMIT + 1 + ) + ) AS image_url, + b.date_finished AS content_date + FROM + optimized_books b + UNION ALL + SELECT + 'artist' AS type, + ar.url::TEXT AS url, + ar.name AS title, + ar.description AS description, + COALESCE( + NULLIF(ar.metadata ->> 'open_graph_image', ''), + ( + SELECT + metadata ->> 'open_graph_image' + FROM + optimized_globals + LIMIT + 1 + ) + ) AS image_url, + CURRENT_TIMESTAMP AS content_date + FROM + optimized_artists ar + UNION ALL + SELECT + 'genre' AS type, + g.url::TEXT AS url, + g.name AS title, + g.description AS description, + COALESCE( + NULLIF(g.metadata ->> 'open_graph_image', ''), + ( + SELECT + metadata ->> 'open_graph_image' + FROM + optimized_globals + LIMIT + 1 + ) + ) AS image_url, + CURRENT_TIMESTAMP AS content_date + FROM + optimized_genres g + UNION ALL + SELECT + 'show' AS type, + s.url::TEXT AS url, + s.title AS title, + s.description AS description, + COALESCE( + NULLIF(s.metadata ->> 'open_graph_image', ''), + ( + SELECT + metadata ->> 'open_graph_image' + FROM + optimized_globals + LIMIT + 1 + ) + ) AS image_url, + s.last_watched_at AS content_date + FROM + optimized_shows s + UNION ALL + SELECT + 'movie' AS type, + m.url::TEXT AS url, + m.title AS title, + m.description AS description, + COALESCE( + NULLIF(m.metadata ->> 'open_graph_image', ''), + ( + SELECT + metadata ->> 'open_graph_image' + FROM + optimized_globals + LIMIT + 1 + ) + ) AS image_url, + m.last_watched AS content_date + FROM + optimized_movies m + ) +SELECT + ROW_NUMBER() OVER ( + ORDER BY + url + ) AS id, + * +FROM oembed_data; diff --git a/queries/views/feeds/recent_activity.sql b/queries/views/feeds/recent_activity.sql index 4475c61..201624b 100644 --- a/queries/views/feeds/recent_activity.sql +++ b/queries/views/feeds/recent_activity.sql @@ -1,124 +1,147 @@ CREATE OR REPLACE VIEW optimized_recent_activity AS -WITH activity_data AS ( - SELECT - NULL::bigint AS id, - p.date AS content_date, - p.title, - p.content AS description, - p.url AS url, - p.featured AS featured, - p.tags::TEXT[], - NULL AS author, - NULL AS image, - NULL AS rating, - NULL AS artist_url, - NULL AS venue_lat, - NULL AS venue_lon, - NULL AS venue_name, - NULL AS notes, - 'article' AS type, - 'Post' AS label - FROM optimized_posts p - - UNION ALL - - SELECT - NULL::bigint AS id, - l.date AS content_date, - l.title, - l.description, - l.link AS url, - NULL AS featured, - l.tags::TEXT[], - l.author, - NULL AS image, - NULL AS rating, - NULL AS artist_url, - NULL AS venue_lat, - NULL AS venue_lon, - NULL AS venue_name, - NULL AS notes, - 'link' AS type, - 'Link' AS label - FROM optimized_links l - - UNION ALL - - SELECT - NULL::bigint AS id, - b.date_finished AS content_date, - CONCAT(b.title, - CASE WHEN b.rating IS NOT NULL THEN CONCAT(' (', b.rating, ')') ELSE '' END - ) AS title, - b.description, - b.url AS url, - NULL AS featured, - b.tags::TEXT[], - NULL AS author, - b.image, - b.rating, - NULL AS artist_url, - NULL AS venue_lat, - NULL AS venue_lon, - NULL AS venue_name, - NULL AS notes, - 'books' AS type, - 'Book' AS label - FROM optimized_books b - WHERE LOWER(b.status) = 'finished' - - UNION ALL - - SELECT - NULL::bigint AS id, - m.last_watched AS content_date, - CONCAT(m.title, - CASE WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')') ELSE '' END - ) AS title, - m.description, - m.url AS url, - NULL AS featured, - m.tags::TEXT[], - NULL AS author, - m.image, - m.rating, - NULL AS artist_url, - NULL AS venue_lat, - NULL AS venue_lon, - NULL AS venue_name, - NULL AS notes, - 'movies' AS type, - 'Movie' AS label - FROM optimized_movies m - WHERE m.last_watched IS NOT NULL - - UNION ALL - - SELECT - c.id, - c.date AS content_date, - CONCAT(c.artist->>'name', ' at ', c.venue->>'name_short') AS title, - c.concert_notes AS description, - NULL AS url, - NULL AS featured, - NULL AS tags, - NULL AS author, - NULL AS image, - NULL AS rating, - c.artist->>'url' AS artist_url, - c.venue->>'latitude' AS venue_lat, - c.venue->>'longitude' AS venue_lon, - c.venue->>'name_short' AS venue_name, - c.concert_notes AS notes, - 'concerts' AS type, - 'Concert' AS label - FROM optimized_concerts c -) -SELECT json_agg(recent_activity_data ORDER BY recent_activity_data.content_date DESC) AS feed -FROM ( - SELECT * - FROM activity_data - WHERE content_date IS NOT NULL - ORDER BY content_date DESC - LIMIT 20 -) AS recent_activity_data; +WITH + activity_data AS ( + SELECT + NULL::bigint AS id, + p.date AS content_date, + p.title, + p.content AS description, + p.url AS url, + p.featured AS featured, + p.tags::TEXT[], + NULL AS author, + NULL AS image, + NULL AS rating, + NULL AS artist_url, + NULL AS venue_lat, + NULL AS venue_lon, + NULL AS venue_name, + NULL AS notes, + 'article' AS type, + 'Post' AS label + FROM + optimized_posts p + UNION ALL + SELECT + NULL::bigint AS id, + l.date AS content_date, + l.title, + l.description, + l.link AS url, + NULL AS featured, + l.tags::TEXT[], + l.author, + NULL AS image, + NULL AS rating, + NULL AS artist_url, + NULL AS venue_lat, + NULL AS venue_lon, + NULL AS venue_name, + NULL AS notes, + 'link' AS type, + 'Link' AS label + FROM + optimized_links l + UNION ALL + SELECT + NULL::bigint AS id, + b.date_finished AS content_date, + CONCAT( + b.title, + CASE + WHEN b.rating IS NOT NULL THEN CONCAT(' (', b.rating, ')') + ELSE '' + END + ) AS title, + b.description, + b.url AS url, + NULL AS featured, + b.tags::TEXT[], + NULL AS author, + b.image, + b.rating, + NULL AS artist_url, + NULL AS venue_lat, + NULL AS venue_lon, + NULL AS venue_name, + NULL AS notes, + 'books' AS type, + 'Book' AS label + FROM + optimized_books b + WHERE + LOWER(b.status) = 'finished' + UNION ALL + SELECT + NULL::bigint AS id, + m.last_watched AS content_date, + CONCAT( + m.title, + CASE + WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')') + ELSE '' + END + ) AS title, + m.description, + m.url AS url, + NULL AS featured, + m.tags::TEXT[], + NULL AS author, + m.image, + m.rating, + NULL AS artist_url, + NULL AS venue_lat, + NULL AS venue_lon, + NULL AS venue_name, + NULL AS notes, + 'movies' AS type, + 'Movie' AS label + FROM + optimized_movies m + WHERE + m.last_watched IS NOT NULL + UNION ALL + SELECT + c.id, + c.date AS content_date, + CONCAT( + c.artist ->> 'name', + ' at ', + c.venue ->> 'name_short' + ) AS title, + c.concert_notes AS description, + NULL AS url, + NULL AS featured, + NULL AS tags, + NULL AS author, + NULL AS image, + NULL AS rating, + c.artist ->> 'url' AS artist_url, + c.venue ->> 'latitude' AS venue_lat, + c.venue ->> 'longitude' AS venue_lon, + c.venue ->> 'name_short' AS venue_name, + c.concert_notes AS notes, + 'concerts' AS type, + 'Concert' AS label + FROM + optimized_concerts c + ) +SELECT + json_agg( + recent_activity_data + ORDER BY + recent_activity_data.content_date DESC + ) AS feed +FROM + ( + SELECT + * + FROM + activity_data + WHERE + content_date IS NOT NULL + ORDER BY + content_date DESC + LIMIT + 20 + ) AS recent_activity_data; diff --git a/queries/views/feeds/robots.sql b/queries/views/feeds/robots.sql index 985bad6..b18cf5b 100644 --- a/queries/views/feeds/robots.sql +++ b/queries/views/feeds/robots.sql @@ -1,12 +1,14 @@ CREATE OR REPLACE VIEW optimized_robots AS SELECT r.path, - array_agg(ua.user_agent ORDER BY ua.user_agent) AS user_agents + array_agg( + ua.user_agent + ORDER BY + ua.user_agent + ) AS user_agents FROM robots AS r -JOIN - robots_user_agents AS rua ON r.id = rua.robots_id -JOIN - user_agents AS ua ON rua.user_agents_id = ua.id + JOIN robots_user_agents AS rua ON r.id = rua.robots_id + JOIN user_agents AS ua ON rua.user_agents_id = ua.id GROUP BY r.path; diff --git a/queries/views/feeds/search.sql b/queries/views/feeds/search.sql index c3b3072..fc1eb07 100644 --- a/queries/views/feeds/search.sql +++ b/queries/views/feeds/search.sql @@ -1,118 +1,125 @@ CREATE OR REPLACE VIEW optimized_search_index AS -WITH search_data AS ( - SELECT - p.title, - p.url::TEXT AS url, - p.description AS description, - p.tags, - NULL AS genre_name, - NULL AS genre_url, - NULL::TEXT AS total_plays, - p.date AS content_date, - 'article' AS type, - 'post' AS section - FROM - optimized_posts p - UNION ALL - SELECT - CONCAT(l.title, ' via ', l.name) AS title, - l.link::TEXT AS url, - l.description AS description, - l.tags, - NULL AS genre_name, - NULL AS genre_url, - NULL::TEXT AS total_plays, - l.date AS content_date, - 'link' AS type, - 'link' AS section - FROM - optimized_links l - UNION ALL - SELECT - CASE WHEN b.rating IS NOT NULL THEN - CONCAT(b.title, ' (', b.rating, ')') - ELSE - b.title - END AS title, - b.url::TEXT AS url, - b.description AS description, - b.tags, - NULL AS genre_name, - NULL AS genre_url, - NULL::TEXT AS total_plays, - b.date_finished AS content_date, - 'books' AS type, - 'book' AS section - FROM - optimized_books b - WHERE - LOWER(b.status) = 'finished' - UNION ALL - SELECT - ar.name AS title, - ar.url::TEXT AS url, - ar.description AS description, - ARRAY[ar.genre_name] AS tags, - CONCAT(COALESCE(ar.emoji, ar.genre_emoji, '🎧'), ' ', ar.genre_name) AS genre_name, - ar.genre_slug AS genre_url, - TO_CHAR(ar.total_plays::NUMERIC, 'FM999,999,999,999') AS total_plays, - NULL AS content_date, - 'music' AS type, - 'artist' AS section - FROM - optimized_artists ar - UNION ALL - SELECT - g.name AS title, - g.url::TEXT AS url, - g.description AS description, - NULL AS tags, - g.name AS genre_name, - g.url AS genre_url, - g.total_plays AS total_plays, - NULL AS content_date, - 'music' AS type, - 'genre' AS section - FROM - optimized_genres g - UNION ALL - SELECT - CONCAT(s.title, ' (', s.year, ')') AS title, - s.url::TEXT AS url, - s.description AS description, - s.tags, - NULL AS genre_name, - NULL AS genre_url, - NULL::TEXT AS total_plays, - s.last_watched_at AS content_date, - 'tv' AS type, - 'show' AS section - FROM - optimized_shows s - WHERE - s.last_watched_at IS NOT NULL - UNION ALL - SELECT - CASE - WHEN m.rating IS NOT NULL THEN CONCAT(m.title, ' (', m.rating, ')') - ELSE CONCAT(m.title, ' (', m.year, ')') - END AS title, - m.url::TEXT AS url, - m.description AS description, - m.tags, - NULL AS genre_name, - NULL AS genre_url, - NULL::TEXT AS total_plays, - m.last_watched AS content_date, - 'movies' AS type, - 'movie' AS section - FROM - optimized_movies m - WHERE - m.last_watched IS NOT NULL -) +WITH + search_data AS ( + SELECT + p.title, + p.url::TEXT AS url, + p.description AS description, + p.tags, + NULL AS genre_name, + NULL AS genre_url, + NULL::TEXT AS total_plays, + p.date AS content_date, + 'article' AS type, + 'post' AS section + FROM + optimized_posts p + UNION ALL + SELECT + CONCAT(l.title, ' via ', l.name) AS title, + l.link::TEXT AS url, + l.description AS description, + l.tags, + NULL AS genre_name, + NULL AS genre_url, + NULL::TEXT AS total_plays, + l.date AS content_date, + 'link' AS type, + 'link' AS section + FROM + optimized_links l + UNION ALL + SELECT + CASE + WHEN b.rating IS NOT NULL THEN CONCAT(b.title, ' (', b.rating, ')') + ELSE b.title + END AS title, + b.url::TEXT AS url, + b.description AS description, + b.tags, + NULL AS genre_name, + NULL AS genre_url, + NULL::TEXT AS total_plays, + b.date_finished AS content_date, + 'books' AS type, + 'book' AS section + FROM + optimized_books b + WHERE + LOWER(b.status) = 'finished' + UNION ALL + SELECT + ar.name AS title, + ar.url::TEXT AS url, + ar.description AS description, + ARRAY[ar.genre_name] AS tags, + CONCAT( + COALESCE(ar.emoji, ar.genre_emoji, '🎧'), + ' ', + ar.genre_name + ) AS genre_name, + ar.genre_slug AS genre_url, + TO_CHAR(ar.total_plays::NUMERIC, 'FM999,999,999,999') AS total_plays, + NULL AS content_date, + 'music' AS type, + 'artist' AS section + FROM + optimized_artists ar + UNION ALL + SELECT + g.name AS title, + g.url::TEXT AS url, + g.description AS description, + NULL AS tags, + g.name AS genre_name, + g.url AS genre_url, + g.total_plays AS total_plays, + NULL AS content_date, + 'music' AS type, + 'genre' AS section + FROM + optimized_genres g + UNION ALL + SELECT + CONCAT(s.title, ' (', s.year, ')') AS title, + s.url::TEXT AS url, + s.description AS description, + s.tags, + NULL AS genre_name, + NULL AS genre_url, + NULL::TEXT AS total_plays, + s.last_watched_at AS content_date, + 'tv' AS type, + 'show' AS section + FROM + optimized_shows s + WHERE + s.last_watched_at IS NOT NULL + UNION ALL + SELECT + CASE + WHEN m.rating IS NOT NULL THEN CONCAT(m.title, ' (', m.rating, ')') + ELSE CONCAT(m.title, ' (', m.year, ')') + END AS title, + m.url::TEXT AS url, + m.description AS description, + m.tags, + NULL AS genre_name, + NULL AS genre_url, + NULL::TEXT AS total_plays, + m.last_watched AS content_date, + 'movies' AS type, + 'movie' AS section + FROM + optimized_movies m + WHERE + m.last_watched IS NOT NULL + ) SELECT - ROW_NUMBER() OVER (ORDER BY url) AS id, + ROW_NUMBER() OVER ( + ORDER BY + url + ) AS id, * FROM search_data; diff --git a/queries/views/feeds/sitemap.sql b/queries/views/feeds/sitemap.sql index 8b6c492..2c76f2d 100644 --- a/queries/views/feeds/sitemap.sql +++ b/queries/views/feeds/sitemap.sql @@ -1,49 +1,54 @@ CREATE OR REPLACE VIEW optimized_sitemap AS -WITH sitemap_data AS ( - SELECT - p.url::TEXT AS url - FROM - optimized_posts p - UNION ALL - SELECT - b.url::TEXT AS url - FROM - optimized_books b - UNION ALL - SELECT - m.url::TEXT AS url - FROM - optimized_movies m - UNION ALL - SELECT - ar.url::TEXT AS url - FROM - optimized_artists ar - UNION ALL - SELECT - g.url::TEXT AS url - FROM - optimized_genres g - UNION ALL - SELECT - s.url::TEXT AS url - FROM - optimized_shows s - UNION ALL - SELECT - pa.permalink::TEXT AS url - FROM - optimized_pages pa - UNION ALL - SELECT - ss.slug AS url - FROM - static_slugs ss - UNION ALL - SELECT CONCAT('/tags/', LOWER(REPLACE(tag, ' ', '-'))) AS url - FROM optimized_all_tags - WHERE tag IS NOT NULL AND TRIM(tag) <> '' -) +WITH + sitemap_data AS ( + SELECT + p.url::TEXT AS url + FROM + optimized_posts p + UNION ALL + SELECT + b.url::TEXT AS url + FROM + optimized_books b + UNION ALL + SELECT + m.url::TEXT AS url + FROM + optimized_movies m + UNION ALL + SELECT + ar.url::TEXT AS url + FROM + optimized_artists ar + UNION ALL + SELECT + g.url::TEXT AS url + FROM + optimized_genres g + UNION ALL + SELECT + s.url::TEXT AS url + FROM + optimized_shows s + UNION ALL + SELECT + pa.permalink::TEXT AS url + FROM + optimized_pages pa + UNION ALL + SELECT + ss.slug AS url + FROM + static_slugs ss + UNION ALL + SELECT + CONCAT('/tags/', LOWER(REPLACE(tag, ' ', '-'))) AS url + FROM + optimized_all_tags + WHERE + tag IS NOT NULL + AND TRIM(tag) <> '' + ) SELECT url FROM diff --git a/queries/views/feeds/stats.sql b/queries/views/feeds/stats.sql index a4665f5..2ecf398 100644 --- a/queries/views/feeds/stats.sql +++ b/queries/views/feeds/stats.sql @@ -1,190 +1,412 @@ CREATE OR REPLACE VIEW optimized_stats AS -WITH artist_stats AS ( - SELECT - TO_CHAR(COUNT(DISTINCT artist_name), 'FM999,999,999') AS artist_count - FROM optimized_listens - WHERE artist_name IS NOT NULL -), -track_stats AS ( - SELECT - TO_CHAR(COUNT(*), 'FM999,999,999') AS listen_count - FROM optimized_listens -), -concert_stats AS ( - SELECT - TO_CHAR(COUNT(*), 'FM999,999,999') AS concert_count - FROM concerts -), -venue_stats AS ( - SELECT - TO_CHAR(COUNT(DISTINCT venue), 'FM999,999,999') AS venue_count - FROM concerts -), -yearly_data AS ( - SELECT - EXTRACT(YEAR FROM e.last_watched_at) AS year, - 0 AS artist_count, - 0 AS listen_count, - 0 AS genre_count, - COUNT(DISTINCT e.show) AS show_count, - COUNT(*) AS episode_count, - 0 AS post_count, - 0 AS link_count, - 0 AS book_count, - 0 AS movie_count, - 0 AS concert_count, - 0 AS venue_count - FROM episodes e - GROUP BY EXTRACT(YEAR FROM e.last_watched_at) - HAVING EXTRACT(YEAR FROM e.last_watched_at) >= 2023 - UNION ALL - SELECT - EXTRACT(YEAR FROM p.date) AS year, - 0 AS artist_count, - 0 AS listen_count, - 0 AS genre_count, - 0 AS show_count, - 0 AS episode_count, - COUNT(*) AS post_count, - 0 AS link_count, - 0 AS book_count, - 0 AS movie_count, - 0 AS concert_count, - 0 AS venue_count - FROM optimized_posts p - GROUP BY EXTRACT(YEAR FROM p.date) - HAVING EXTRACT(YEAR FROM p.date) >= 2023 - UNION ALL - SELECT - EXTRACT(YEAR FROM o.date) AS year, - 0 AS artist_count, - 0 AS listen_count, - 0 AS genre_count, - 0 AS show_count, - 0 AS episode_count, - 0 AS post_count, - COUNT(*) AS link_count, - 0 AS book_count, - 0 AS movie_count, - 0 AS concert_count, - 0 AS venue_count - FROM optimized_links o - GROUP BY EXTRACT(YEAR FROM o.date) - HAVING EXTRACT(YEAR FROM o.date) >= 2023 - UNION ALL - SELECT - EXTRACT(YEAR FROM b.date_finished) AS year, - 0 AS artist_count, - 0 AS listen_count, - 0 AS genre_count, - 0 AS show_count, - 0 AS episode_count, - 0 AS post_count, - 0 AS link_count, - COUNT(*) AS book_count, - 0 AS movie_count, - 0 AS concert_count, - 0 AS venue_count - FROM optimized_books b - WHERE LOWER(b.status) = 'finished' - GROUP BY EXTRACT(YEAR FROM b.date_finished) - HAVING EXTRACT(YEAR FROM b.date_finished) >= 2023 - UNION ALL - SELECT - EXTRACT(YEAR FROM m.last_watched) AS year, - 0 AS artist_count, - 0 AS listen_count, - 0 AS genre_count, - 0 AS show_count, - 0 AS episode_count, - 0 AS post_count, - 0 AS link_count, - 0 AS book_count, - COUNT(*) AS movie_count, - 0 AS concert_count, - 0 AS venue_count - FROM optimized_movies m - GROUP BY EXTRACT(YEAR FROM m.last_watched) - HAVING EXTRACT(YEAR FROM m.last_watched) >= 2023 - UNION ALL - SELECT - EXTRACT(YEAR FROM TO_TIMESTAMP(l.listened_at)) AS year, - COUNT(DISTINCT l.artist_name) AS artist_count, - COUNT(l.id) AS listen_count, - COUNT(DISTINCT l.genre_name) AS genre_count, - 0 AS show_count, - 0 AS episode_count, - 0 AS post_count, - 0 AS link_count, - 0 AS book_count, - 0 AS movie_count, - 0 AS concert_count, - 0 AS venue_count - FROM optimized_listens l - GROUP BY EXTRACT(YEAR FROM TO_TIMESTAMP(l.listened_at)) - HAVING EXTRACT(YEAR FROM TO_TIMESTAMP(l.listened_at)) >= 2023 - UNION ALL - SELECT - EXTRACT(YEAR FROM c.date) AS year, - 0 AS artist_count, - 0 AS listen_count, - 0 AS genre_count, - 0 AS show_count, - 0 AS episode_count, - 0 AS post_count, - 0 AS link_count, - 0 AS book_count, - 0 AS movie_count, - COUNT(*) AS concert_count, - COUNT(DISTINCT c.venue) AS venue_count - FROM concerts c - GROUP BY EXTRACT(YEAR FROM c.date) - HAVING EXTRACT(YEAR FROM c.date) >= 2023 -), -aggregated_yearly_stats AS ( - SELECT - year, - SUM(artist_count) AS artist_count, - SUM(listen_count) AS listen_count, - SUM(genre_count) AS genre_count, - SUM(show_count) AS show_count, - SUM(episode_count) AS episode_count, - SUM(post_count) AS post_count, - SUM(link_count) AS link_count, - SUM(book_count) AS book_count, - SUM(movie_count) AS movie_count, - SUM(concert_count) AS concert_count, - SUM(venue_count) AS venue_count - FROM yearly_data - GROUP BY year - ORDER BY year DESC -) +WITH + artist_stats AS ( + SELECT + TO_CHAR(COUNT(DISTINCT artist_name), 'FM999,999,999') AS artist_count + FROM + optimized_listens + WHERE + artist_name IS NOT NULL + ), + track_stats AS ( + SELECT + TO_CHAR(COUNT(*), 'FM999,999,999') AS listen_count + FROM + optimized_listens + ), + concert_stats AS ( + SELECT + TO_CHAR(COUNT(*), 'FM999,999,999') AS concert_count + FROM + concerts + ), + venue_stats AS ( + SELECT + TO_CHAR(COUNT(DISTINCT venue), 'FM999,999,999') AS venue_count + FROM + concerts + ), + yearly_data AS ( + SELECT + EXTRACT( + YEAR + FROM + e.last_watched_at + ) AS year, + 0 AS artist_count, + 0 AS listen_count, + 0 AS genre_count, + COUNT(DISTINCT e.show) AS show_count, + COUNT(*) AS episode_count, + 0 AS post_count, + 0 AS link_count, + 0 AS book_count, + 0 AS movie_count, + 0 AS concert_count, + 0 AS venue_count + FROM + episodes e + GROUP BY + EXTRACT( + YEAR + FROM + e.last_watched_at + ) + HAVING + EXTRACT( + YEAR + FROM + e.last_watched_at + ) >= 2023 + UNION ALL + SELECT + EXTRACT( + YEAR + FROM + p.date + ) AS year, + 0 AS artist_count, + 0 AS listen_count, + 0 AS genre_count, + 0 AS show_count, + 0 AS episode_count, + COUNT(*) AS post_count, + 0 AS link_count, + 0 AS book_count, + 0 AS movie_count, + 0 AS concert_count, + 0 AS venue_count + FROM + optimized_posts p + GROUP BY + EXTRACT( + YEAR + FROM + p.date + ) + HAVING + EXTRACT( + YEAR + FROM + p.date + ) >= 2023 + UNION ALL + SELECT + EXTRACT( + YEAR + FROM + o.date + ) AS year, + 0 AS artist_count, + 0 AS listen_count, + 0 AS genre_count, + 0 AS show_count, + 0 AS episode_count, + 0 AS post_count, + COUNT(*) AS link_count, + 0 AS book_count, + 0 AS movie_count, + 0 AS concert_count, + 0 AS venue_count + FROM + optimized_links o + GROUP BY + EXTRACT( + YEAR + FROM + o.date + ) + HAVING + EXTRACT( + YEAR + FROM + o.date + ) >= 2023 + UNION ALL + SELECT + EXTRACT( + YEAR + FROM + b.date_finished + ) AS year, + 0 AS artist_count, + 0 AS listen_count, + 0 AS genre_count, + 0 AS show_count, + 0 AS episode_count, + 0 AS post_count, + 0 AS link_count, + COUNT(*) AS book_count, + 0 AS movie_count, + 0 AS concert_count, + 0 AS venue_count + FROM + optimized_books b + WHERE + LOWER(b.status) = 'finished' + GROUP BY + EXTRACT( + YEAR + FROM + b.date_finished + ) + HAVING + EXTRACT( + YEAR + FROM + b.date_finished + ) >= 2023 + UNION ALL + SELECT + EXTRACT( + YEAR + FROM + m.last_watched + ) AS year, + 0 AS artist_count, + 0 AS listen_count, + 0 AS genre_count, + 0 AS show_count, + 0 AS episode_count, + 0 AS post_count, + 0 AS link_count, + 0 AS book_count, + COUNT(*) AS movie_count, + 0 AS concert_count, + 0 AS venue_count + FROM + optimized_movies m + GROUP BY + EXTRACT( + YEAR + FROM + m.last_watched + ) + HAVING + EXTRACT( + YEAR + FROM + m.last_watched + ) >= 2023 + UNION ALL + SELECT + EXTRACT( + YEAR + FROM + TO_TIMESTAMP(l.listened_at) + ) AS year, + COUNT(DISTINCT l.artist_name) AS artist_count, + COUNT(l.id) AS listen_count, + COUNT(DISTINCT l.genre_name) AS genre_count, + 0 AS show_count, + 0 AS episode_count, + 0 AS post_count, + 0 AS link_count, + 0 AS book_count, + 0 AS movie_count, + 0 AS concert_count, + 0 AS venue_count + FROM + optimized_listens l + GROUP BY + EXTRACT( + YEAR + FROM + TO_TIMESTAMP(l.listened_at) + ) + HAVING + EXTRACT( + YEAR + FROM + TO_TIMESTAMP(l.listened_at) + ) >= 2023 + UNION ALL + SELECT + EXTRACT( + YEAR + FROM + c.date + ) AS year, + 0 AS artist_count, + 0 AS listen_count, + 0 AS genre_count, + 0 AS show_count, + 0 AS episode_count, + 0 AS post_count, + 0 AS link_count, + 0 AS book_count, + 0 AS movie_count, + COUNT(*) AS concert_count, + COUNT(DISTINCT c.venue) AS venue_count + FROM + concerts c + GROUP BY + EXTRACT( + YEAR + FROM + c.date + ) + HAVING + EXTRACT( + YEAR + FROM + c.date + ) >= 2023 + ), + aggregated_yearly_stats AS ( + SELECT + year, + SUM(artist_count) AS artist_count, + SUM(listen_count) AS listen_count, + SUM(genre_count) AS genre_count, + SUM(show_count) AS show_count, + SUM(episode_count) AS episode_count, + SUM(post_count) AS post_count, + SUM(link_count) AS link_count, + SUM(book_count) AS book_count, + SUM(movie_count) AS movie_count, + SUM(concert_count) AS concert_count, + SUM(venue_count) AS venue_count + FROM + yearly_data + GROUP BY + year + ORDER BY + year DESC + ) SELECT - (SELECT artist_count FROM artist_stats) AS artist_count, - (SELECT listen_count FROM track_stats) AS listen_count, - (SELECT concert_count FROM concert_stats) AS concert_count, - (SELECT venue_count FROM venue_stats) AS venue_count, - (SELECT TO_CHAR(COUNT(DISTINCT e.show), 'FM999,999,999') FROM episodes e) AS show_count, - (SELECT TO_CHAR(COUNT(*), 'FM999,999,999') FROM episodes e) AS episode_count, - (SELECT TO_CHAR(COUNT(*), 'FM999,999,999') FROM optimized_posts) AS post_count, - (SELECT TO_CHAR(COUNT(*), 'FM999,999,999') FROM optimized_links) AS link_count, - (SELECT TO_CHAR(COUNT(*), 'FM999,999,999') FROM optimized_books WHERE LOWER(status) = 'finished') AS book_count, - (SELECT TO_CHAR(COUNT(*), 'FM999,999,999') FROM optimized_movies WHERE last_watched IS NOT NULL) AS movie_count, - (SELECT TO_CHAR(COUNT(DISTINCT genre_name), 'FM999,999,999') FROM optimized_listens WHERE genre_name IS NOT NULL) AS genre_count, + ( + SELECT + artist_count + FROM + artist_stats + ) AS artist_count, + ( + SELECT + listen_count + FROM + track_stats + ) AS listen_count, + ( + SELECT + concert_count + FROM + concert_stats + ) AS concert_count, + ( + SELECT + venue_count + FROM + venue_stats + ) AS venue_count, + ( + SELECT + TO_CHAR(COUNT(DISTINCT e.show), 'FM999,999,999') + FROM + episodes e + ) AS show_count, + ( + SELECT + TO_CHAR(COUNT(*), 'FM999,999,999') + FROM + episodes e + ) AS episode_count, + ( + SELECT + TO_CHAR(COUNT(*), 'FM999,999,999') + FROM + optimized_posts + ) AS post_count, + ( + SELECT + TO_CHAR(COUNT(*), 'FM999,999,999') + FROM + optimized_links + ) AS link_count, + ( + SELECT + TO_CHAR(COUNT(*), 'FM999,999,999') + FROM + optimized_books + WHERE + LOWER(status) = 'finished' + ) AS book_count, + ( + SELECT + TO_CHAR(COUNT(*), 'FM999,999,999') + FROM + optimized_movies + WHERE + last_watched IS NOT NULL + ) AS movie_count, + ( + SELECT + TO_CHAR(COUNT(DISTINCT genre_name), 'FM999,999,999') + FROM + optimized_listens + WHERE + genre_name IS NOT NULL + ) AS genre_count, JSON_AGG( JSON_BUILD_OBJECT( - 'year', ys.year, - 'artist_count', CASE WHEN ys.artist_count > 0 THEN TO_CHAR(ys.artist_count, 'FM999,999,999') ELSE NULL END, - 'listen_count', CASE WHEN ys.listen_count > 0 THEN TO_CHAR(ys.listen_count, 'FM999,999,999') ELSE NULL END, - 'genre_count', CASE WHEN ys.genre_count > 0 THEN TO_CHAR(ys.genre_count, 'FM999,999,999') ELSE NULL END, - 'show_count', CASE WHEN ys.show_count > 0 THEN TO_CHAR(ys.show_count, 'FM999,999,999') ELSE NULL END, - 'episode_count', CASE WHEN ys.episode_count > 0 THEN TO_CHAR(ys.episode_count, 'FM999,999,999') ELSE NULL END, - 'post_count', CASE WHEN ys.post_count > 0 THEN TO_CHAR(ys.post_count, 'FM999,999,999') ELSE NULL END, - 'link_count', CASE WHEN ys.link_count > 0 THEN TO_CHAR(ys.link_count, 'FM999,999,999') ELSE NULL END, - 'book_count', CASE WHEN ys.book_count > 0 THEN TO_CHAR(ys.book_count, 'FM999,999,999') ELSE NULL END, - 'movie_count', CASE WHEN ys.movie_count > 0 THEN TO_CHAR(ys.movie_count, 'FM999,999,999') ELSE NULL END, - 'concert_count', CASE WHEN ys.concert_count > 0 THEN TO_CHAR(ys.concert_count, 'FM999,999,999') ELSE NULL END, - 'venue_count', CASE WHEN ys.venue_count > 0 THEN TO_CHAR(ys.venue_count, 'FM999,999,999') ELSE NULL END + 'year', + ys.year, + 'artist_count', + CASE + WHEN ys.artist_count > 0 THEN TO_CHAR(ys.artist_count, 'FM999,999,999') + ELSE NULL + END, + 'listen_count', + CASE + WHEN ys.listen_count > 0 THEN TO_CHAR(ys.listen_count, 'FM999,999,999') + ELSE NULL + END, + 'genre_count', + CASE + WHEN ys.genre_count > 0 THEN TO_CHAR(ys.genre_count, 'FM999,999,999') + ELSE NULL + END, + 'show_count', + CASE + WHEN ys.show_count > 0 THEN TO_CHAR(ys.show_count, 'FM999,999,999') + ELSE NULL + END, + 'episode_count', + CASE + WHEN ys.episode_count > 0 THEN TO_CHAR(ys.episode_count, 'FM999,999,999') + ELSE NULL + END, + 'post_count', + CASE + WHEN ys.post_count > 0 THEN TO_CHAR(ys.post_count, 'FM999,999,999') + ELSE NULL + END, + 'link_count', + CASE + WHEN ys.link_count > 0 THEN TO_CHAR(ys.link_count, 'FM999,999,999') + ELSE NULL + END, + 'book_count', + CASE + WHEN ys.book_count > 0 THEN TO_CHAR(ys.book_count, 'FM999,999,999') + ELSE NULL + END, + 'movie_count', + CASE + WHEN ys.movie_count > 0 THEN TO_CHAR(ys.movie_count, 'FM999,999,999') + ELSE NULL + END, + 'concert_count', + CASE + WHEN ys.concert_count > 0 THEN TO_CHAR(ys.concert_count, 'FM999,999,999') + ELSE NULL + END, + 'venue_count', + CASE + WHEN ys.venue_count > 0 THEN TO_CHAR(ys.venue_count, 'FM999,999,999') + ELSE NULL + END ) ) AS yearly_breakdown -FROM aggregated_yearly_stats ys; +FROM + aggregated_yearly_stats ys; diff --git a/queries/views/feeds/syndication.sql b/queries/views/feeds/syndication.sql index 6df115b..5e4fada 100644 --- a/queries/views/feeds/syndication.sql +++ b/queries/views/feeds/syndication.sql @@ -1,93 +1,153 @@ CREATE OR REPLACE VIEW optimized_syndication AS -WITH syndication_data AS ( - SELECT - p.date AS content_date, - json_build_object( - 'title', CONCAT('📝 ', p.title, ' ', ( - SELECT array_to_string( - array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))), - ' ' - ) - FROM unnest(p.tags) AS t(name), - regexp_split_to_table(t.name, '\s*&\s*') AS tag_part - )), - 'description', p.description, - 'url', p.url, - 'image', p.image, - 'date', p.date - ) AS feed - FROM optimized_posts p - UNION ALL - SELECT - l.date AS content_date, - json_build_object( - 'title', CONCAT('🔗 ', l.title, CASE - WHEN l.mastodon IS NOT NULL THEN ' via @' || split_part(l.mastodon, '@', 2) || '@' || split_part(split_part(l.mastodon, 'https://', 2), '/', 1) - ELSE CONCAT(' via ', l.name) - END, ' ', ( - SELECT array_to_string( - array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))), - ' ' - ) - FROM unnest(l.tags) AS t(name), - regexp_split_to_table(t.name, '\s*&\s*') AS tag_part - )), - 'description', l.description, - 'url', l.link, - 'date', l.date - ) AS feed - FROM optimized_links l - UNION ALL - SELECT - b.date_finished AS content_date, - CASE - WHEN LOWER(b.status) = 'finished' THEN - json_build_object( - 'title', CONCAT('📖 ', b.title, CASE - WHEN b.rating IS NOT NULL THEN ' (' || b.rating || ')' ELSE '' END, ' ', ( - SELECT array_to_string( +WITH + syndication_data AS ( + SELECT + p.date AS content_date, + json_build_object( + 'title', + CONCAT( + '📝 ', + p.title, + ' ', + ( + SELECT + array_to_string( array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))), ' ' ) - FROM unnest(b.tags) AS t(name), - regexp_split_to_table(t.name, '\s*&\s*') AS tag_part - ) - ), - 'description', b.description, - 'url', b.url, - 'image', b.image, - 'date', b.date_finished - ) - ELSE NULL - END AS feed - FROM optimized_books b - UNION ALL - SELECT - m.last_watched AS content_date, - CASE - WHEN m.last_watched IS NOT NULL THEN - json_build_object( - 'title', CONCAT('🎥 ', m.title, CASE - WHEN m.rating IS NOT NULL THEN ' (' || m.rating || ')' ELSE '' END, ' ', ( - SELECT array_to_string( + FROM + unnest(p.tags) AS t (name), + regexp_split_to_table(t.name, '\s*&\s*') AS tag_part + ) + ), + 'description', + p.description, + 'url', + p.url, + 'image', + p.image, + 'date', + p.date + ) AS feed + FROM + optimized_posts p + UNION ALL + SELECT + l.date AS content_date, + json_build_object( + 'title', + CONCAT( + '🔗 ', + l.title, + CASE + WHEN l.mastodon IS NOT NULL THEN ' via @' || split_part(l.mastodon, '@', 2) || '@' || split_part(split_part(l.mastodon, 'https://', 2), '/', 1) + ELSE CONCAT(' via ', l.name) + END, + ' ', + ( + SELECT + array_to_string( array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))), ' ' ) - FROM unnest(m.tags) AS t(name), - regexp_split_to_table(t.name, '\s*&\s*') AS tag_part + FROM + unnest(l.tags) AS t (name), + regexp_split_to_table(t.name, '\s*&\s*') AS tag_part + ) + ), + 'description', + l.description, + 'url', + l.link, + 'date', + l.date + ) AS feed + FROM + optimized_links l + UNION ALL + SELECT + b.date_finished AS content_date, + CASE + WHEN LOWER(b.status) = 'finished' THEN json_build_object( + 'title', + CONCAT( + '📖 ', + b.title, + CASE + WHEN b.rating IS NOT NULL THEN ' (' || b.rating || ')' + ELSE '' + END, + ' ', + ( + SELECT + array_to_string( + array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))), + ' ' + ) + FROM + unnest(b.tags) AS t (name), + regexp_split_to_table(t.name, '\s*&\s*') AS tag_part ) ), - 'description', m.description, - 'url', m.url, - 'image', m.image, - 'date', m.last_watched + 'description', + b.description, + 'url', + b.url, + 'image', + b.image, + 'date', + b.date_finished ) - ELSE NULL - END AS feed - FROM optimized_movies m -) -SELECT feed -FROM syndication_data -WHERE feed IS NOT NULL -ORDER BY content_date DESC -LIMIT 3; + ELSE NULL + END AS feed + FROM + optimized_books b + UNION ALL + SELECT + m.last_watched AS content_date, + CASE + WHEN m.last_watched IS NOT NULL THEN json_build_object( + 'title', + CONCAT( + '🎥 ', + m.title, + CASE + WHEN m.rating IS NOT NULL THEN ' (' || m.rating || ')' + ELSE '' + END, + ' ', + ( + SELECT + array_to_string( + array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))), + ' ' + ) + FROM + unnest(m.tags) AS t (name), + regexp_split_to_table(t.name, '\s*&\s*') AS tag_part + ) + ), + 'description', + m.description, + 'url', + m.url, + 'image', + m.image, + 'date', + m.last_watched + ) + ELSE NULL + END AS feed + FROM + optimized_movies m + ) +SELECT + feed +FROM + syndication_data +WHERE + feed IS NOT NULL +ORDER BY + content_date DESC +LIMIT + 3; diff --git a/queries/views/feeds/tagged_content.sql b/queries/views/feeds/tagged_content.sql index b4b1337..3392b44 100644 --- a/queries/views/feeds/tagged_content.sql +++ b/queries/views/feeds/tagged_content.sql @@ -10,7 +10,8 @@ SELECT p.tags::TEXT[], 'article'::TEXT AS type, 'Post'::TEXT AS label -FROM optimized_posts p +FROM + optimized_posts p UNION ALL SELECT unnest(l.tags) AS tag, @@ -23,7 +24,8 @@ SELECT l.tags::TEXT[], 'link'::TEXT AS type, 'Link'::TEXT AS label -FROM optimized_links l +FROM + optimized_links l UNION ALL SELECT unnest(b.tags) AS tag, @@ -36,8 +38,10 @@ SELECT b.tags::TEXT[], 'books'::TEXT AS type, 'Book'::TEXT AS label -FROM optimized_books b -WHERE LOWER(b.status) = 'finished' +FROM + optimized_books b +WHERE + LOWER(b.status) = 'finished' UNION ALL SELECT unnest(m.tags) AS tag, @@ -50,8 +54,10 @@ SELECT m.tags::TEXT[], 'movies'::TEXT AS type, 'Movie'::TEXT AS label -FROM optimized_movies m -WHERE m.last_watched IS NOT NULL +FROM + optimized_movies m +WHERE + m.last_watched IS NOT NULL UNION ALL SELECT unnest(s.tags) AS tag, @@ -64,5 +70,7 @@ SELECT s.tags::TEXT[], 'tv'::TEXT AS type, 'Show'::TEXT AS label -FROM optimized_shows s -WHERE s.last_watched_at IS NOT NULL; +FROM + optimized_shows s +WHERE + s.last_watched_at IS NOT NULL; diff --git a/queries/views/feeds/tags.sql b/queries/views/feeds/tags.sql index 3cf52bf..efecba9 100644 --- a/queries/views/feeds/tags.sql +++ b/queries/views/feeds/tags.sql @@ -2,6 +2,9 @@ CREATE OR REPLACE VIEW optimized_all_tags AS SELECT tag, COUNT(*) AS uses -FROM optimized_tagged_content -GROUP BY tag -ORDER BY tag ASC; +FROM + optimized_tagged_content +GROUP BY + tag +ORDER BY + tag ASC; diff --git a/queries/views/globals/index.sql b/queries/views/globals/index.sql index 23a96df..c42f836 100644 --- a/queries/views/globals/index.sql +++ b/queries/views/globals/index.sql @@ -1,40 +1,48 @@ CREATE OR REPLACE VIEW optimized_globals AS -SELECT * -FROM ( - SELECT - g.site_name, - g.site_description, - g.intro, - g.author, - g.email, - g.mastodon, - g.url, - g.cdn_url, - g.sitemap_uri, - g.theme_color, - g.site_type, - g.locale, - g.lang, - g.webfinger_username, - g.webfinger_hostname, - CONCAT(g.cdn_url, '/', df.filename_disk) AS avatar, - CONCAT(g.cdn_url, '/', df2.filename_disk) AS avatar_transparent, - CONCAT(g.cdn_url, '/', df3.filename_disk) AS avatar_header, - json_build_object( - 'open_graph_image', CASE - WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN - CONCAT('/', df.filename_disk) - ELSE NULL - END, - 'open_graph_image_transparent', CASE - WHEN df2.filename_disk IS NOT NULL AND df2.filename_disk != '' AND df2.filename_disk != '/' THEN - CONCAT('/', df2.filename_disk) - ELSE NULL - END - ) AS metadata - FROM globals g - LEFT JOIN directus_files df ON g.avatar = df.id - LEFT JOIN directus_files df2 ON g.avatar_transparent = df2.id - LEFT JOIN directus_files df3 ON g.avatar_header = df3.id - LIMIT 1 -) sub; +SELECT + * +FROM + ( + SELECT + g.site_name, + g.site_description, + g.intro, + g.author, + g.email, + g.mastodon, + g.url, + g.cdn_url, + g.sitemap_uri, + g.theme_color, + g.site_type, + g.locale, + g.lang, + g.webfinger_username, + g.webfinger_hostname, + CONCAT(g.cdn_url, '/', df.filename_disk) AS avatar, + CONCAT(g.cdn_url, '/', df2.filename_disk) AS avatar_transparent, + CONCAT(g.cdn_url, '/', df3.filename_disk) AS avatar_header, + json_build_object( + 'open_graph_image', + CASE + WHEN df.filename_disk IS NOT NULL + AND df.filename_disk != '' + AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) + ELSE NULL + END, + 'open_graph_image_transparent', + CASE + WHEN df2.filename_disk IS NOT NULL + AND df2.filename_disk != '' + AND df2.filename_disk != '/' THEN CONCAT('/', df2.filename_disk) + ELSE NULL + END + ) AS metadata + FROM + globals g + LEFT JOIN directus_files df ON g.avatar = df.id + LEFT JOIN directus_files df2 ON g.avatar_transparent = df2.id + LEFT JOIN directus_files df3 ON g.avatar_header = df3.id + LIMIT + 1 + ) sub; diff --git a/queries/views/globals/pages.sql b/queries/views/globals/pages.sql index 947f3ee..5eba630 100644 --- a/queries/views/globals/pages.sql +++ b/queries/views/globals/pages.sql @@ -5,68 +5,102 @@ SELECT p.permalink, p.description, json_build_object( - 'title', CONCAT(p.title, ' • ', globals.site_name), - 'description', LEFT( + 'title', + CONCAT(p.title, ' • ', globals.site_name), + 'description', + LEFT( regexp_replace( regexp_replace( regexp_replace(p.description, E'[*_`~#>-]', '', 'g'), - E'\\[(.*?)\\]\\((.*?)\\)', '\\1', 'g' + E'\\[(.*?)\\]\\((.*?)\\)', + '\\1', + 'g' ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' ), 250 ), - 'open_graph_image', CASE - WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN - CONCAT('/', df.filename_disk) - ELSE globals.metadata->>'open_graph_image' + 'open_graph_image', + CASE + WHEN df.filename_disk IS NOT NULL + AND df.filename_disk != '' + AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) + ELSE globals.metadata ->> 'open_graph_image' END, - 'url', CONCAT(globals.url, p.permalink), - 'type', 'page' + 'url', + CONCAT(globals.url, p.permalink), + 'type', + 'page' ) AS metadata, -( + ( SELECT json_agg( - CASE WHEN pb.collection = 'youtube_player' THEN - json_build_object('type', pb.collection, 'url', yp.url) - WHEN pb.collection = 'forgejo_banner' THEN - json_build_object('type', pb.collection, 'url', fb.url) - WHEN pb.collection = 'github_banner' THEN - json_build_object('type', pb.collection, 'url', gb.url) - WHEN pb.collection = 'npm_banner' THEN - json_build_object('type', pb.collection, 'url', nb.url, 'command', nb.command) - WHEN pb.collection = 'rss_banner' THEN - json_build_object('type', pb.collection, 'url', rb.url, 'text', rb.text) - WHEN pb.collection = 'calendar_banner' THEN - json_build_object('type', pb.collection, 'url', cb.url, 'text', cb.text) - WHEN pb.collection = 'hero' THEN - json_build_object('type', pb.collection, 'image', CONCAT('/', df_hero.filename_disk), 'alt', h.alt_text) - WHEN pb.collection = 'markdown' THEN - json_build_object('type', pb.collection, 'text', md.text) - ELSE - json_build_object('type', pb.collection) - END ORDER BY pb.sort) + CASE + WHEN pb.collection = 'youtube_player' THEN json_build_object('type', pb.collection, 'url', yp.url) + WHEN pb.collection = 'forgejo_banner' THEN json_build_object('type', pb.collection, 'url', fb.url) + WHEN pb.collection = 'github_banner' THEN json_build_object('type', pb.collection, 'url', gb.url) + WHEN pb.collection = 'npm_banner' THEN json_build_object( + 'type', + pb.collection, + 'url', + nb.url, + 'command', + nb.command + ) + WHEN pb.collection = 'rss_banner' THEN json_build_object( + 'type', + pb.collection, + 'url', + rb.url, + 'text', + rb.text + ) + WHEN pb.collection = 'calendar_banner' THEN json_build_object( + 'type', + pb.collection, + 'url', + cb.url, + 'text', + cb.text + ) + WHEN pb.collection = 'hero' THEN json_build_object( + 'type', + pb.collection, + 'image', + CONCAT('/', df_hero.filename_disk), + 'alt', + h.alt_text + ) + WHEN pb.collection = 'markdown' THEN json_build_object('type', pb.collection, 'text', md.text) + ELSE json_build_object('type', pb.collection) + END + ORDER BY + pb.sort + ) FROM pages_blocks pb - LEFT JOIN youtube_player yp ON pb.collection = 'youtube_player' - AND yp.id = pb.item::integer - LEFT JOIN forgejo_banner fb ON pb.collection = 'forgejo_banner' - AND fb.id = pb.item::integer - LEFT JOIN github_banner gb ON pb.collection = 'github_banner' - AND gb.id = pb.item::integer - LEFT JOIN npm_banner nb ON pb.collection = 'npm_banner' - AND nb.id = pb.item::integer - LEFT JOIN rss_banner rb ON pb.collection = 'rss_banner' - AND rb.id = pb.item::integer - LEFT JOIN calendar_banner cb ON pb.collection = 'calendar_banner' - AND cb.id = pb.item::integer - LEFT JOIN hero h ON pb.collection = 'hero' - AND h.id = pb.item::integer - LEFT JOIN directus_files df_hero ON h.image = df_hero.id - LEFT JOIN markdown md ON pb.collection = 'markdown' - AND md.id = pb.item::integer -WHERE - pb.pages_id = p.id) AS blocks + LEFT JOIN youtube_player yp ON pb.collection = 'youtube_player' + AND yp.id = pb.item::integer + LEFT JOIN forgejo_banner fb ON pb.collection = 'forgejo_banner' + AND fb.id = pb.item::integer + LEFT JOIN github_banner gb ON pb.collection = 'github_banner' + AND gb.id = pb.item::integer + LEFT JOIN npm_banner nb ON pb.collection = 'npm_banner' + AND nb.id = pb.item::integer + LEFT JOIN rss_banner rb ON pb.collection = 'rss_banner' + AND rb.id = pb.item::integer + LEFT JOIN calendar_banner cb ON pb.collection = 'calendar_banner' + AND cb.id = pb.item::integer + LEFT JOIN hero h ON pb.collection = 'hero' + AND h.id = pb.item::integer + LEFT JOIN directus_files df_hero ON h.image = df_hero.id + LEFT JOIN markdown md ON pb.collection = 'markdown' + AND md.id = pb.item::integer + WHERE + pb.pages_id = p.id + ) AS blocks FROM pages p LEFT JOIN directus_files df ON p.open_graph_image = df.id @@ -77,4 +111,4 @@ GROUP BY globals.cdn_url, globals.site_name, globals.url, - globals.metadata->>'open_graph_image'; + globals.metadata ->> 'open_graph_image'; diff --git a/queries/views/media/books.sql b/queries/views/media/books.sql index 5818b51..8704365 100644 --- a/queries/views/media/books.sql +++ b/queries/views/media/books.sql @@ -1,7 +1,11 @@ CREATE OR REPLACE VIEW optimized_books AS SELECT b.date_finished, - EXTRACT(YEAR FROM b.date_finished) AS year, + EXTRACT( + YEAR + FROM + b.date_finished + ) AS year, b.author, b.description, b.title, @@ -14,184 +18,341 @@ SELECT b.favorite, b.tattoo, ( - SELECT array_agg(t.name) - FROM books_tags bt - LEFT JOIN tags t ON bt.tags_id = t.id - WHERE bt.books_id = b.id + SELECT + array_agg(t.name) + FROM + books_tags bt + LEFT JOIN tags t ON bt.tags_id = t.id + WHERE + bt.books_id = b.id ) AS tags, ( - SELECT json_agg( - json_build_object( - 'name', a.name_string, - 'url', a.slug, - 'country', a.country, - 'total_plays', a.total_plays, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'grid', json_build_object( - 'title', a.name_string, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'alt', CASE WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name_string) ELSE CONCAT('Artwork of ', a.name_string) END, - 'subtext', CASE WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays') ELSE NULL END, - 'url', a.slug - ), - 'type', 'music' + SELECT + json_agg( + json_build_object( + 'name', + a.name_string, + 'url', + a.slug, + 'country', + a.country, + 'total_plays', + a.total_plays, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'grid', + json_build_object( + 'title', + a.name_string, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'alt', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays of ', + a.name_string + ) + ELSE CONCAT('Artwork of ', a.name_string) + END, + 'subtext', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays' + ) + ELSE NULL + END, + 'url', + a.slug + ), + 'type', + 'music' + ) + ORDER BY + a.total_plays DESC ) - ORDER BY a.total_plays DESC - ) - FROM books_artists ba - LEFT JOIN artists a ON ba.artists_id = a.id - LEFT JOIN directus_files df_artist ON a.art = df_artist.id - WHERE ba.books_id = b.id + FROM + books_artists ba + LEFT JOIN artists a ON ba.artists_id = a.id + LEFT JOIN directus_files df_artist ON a.art = df_artist.id + WHERE + ba.books_id = b.id ) AS artists, ( - SELECT json_agg( - json_build_object( - 'title', m.title, - 'year', m.year, - 'url', m.slug, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), - 'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, - 'url', m.slug - ), - 'type', 'movies' + SELECT + json_agg( + json_build_object( + 'title', + m.title, + 'year', + m.year, + 'url', + m.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'alt', + CONCAT('Poster for ', m.title, ' (', m.year, ')'), + 'subtext', + CASE + WHEN m.star_rating IS NOT NULL THEN m.star_rating::text + ELSE m.year::text + END, + 'url', + m.slug + ), + 'type', + 'movies' + ) + ORDER BY + m.year ASC ) - ORDER BY m.year ASC - ) - FROM movies_books mb - LEFT JOIN movies m ON mb.movies_id = m.id - LEFT JOIN directus_files df_movie ON m.art = df_movie.id - WHERE mb.books_id = b.id + FROM + movies_books mb + LEFT JOIN movies m ON mb.movies_id = m.id + LEFT JOIN directus_files df_movie ON m.art = df_movie.id + WHERE + mb.books_id = b.id AND m.last_watched IS NOT NULL ) AS movies, ( - SELECT json_agg( - json_build_object('name', g.name, 'url', g.slug) - ORDER BY g.name ASC - ) - FROM genres_books gb - LEFT JOIN genres g ON gb.genres_id = g.id - WHERE gb.books_id = b.id + SELECT + json_agg( + json_build_object('name', g.name, 'url', g.slug) + ORDER BY + g.name ASC + ) + FROM + genres_books gb + LEFT JOIN genres g ON gb.genres_id = g.id + WHERE + gb.books_id = b.id ) AS genres, ( - SELECT json_agg( - json_build_object( - 'title', s.title, - 'year', s.year, - 'url', s.slug, - 'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), - 'alt', CONCAT('Artwork for ', s.title), - 'subtext', CASE - WHEN ( - SELECT MAX(e1.last_watched_at) - FROM episodes e1 - WHERE e1.show = s.id - ) >= NOW() - INTERVAL '90 days' THEN ( - SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) - FROM episodes e2 - WHERE e2.show = s.id - ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC - LIMIT 1 - ) - ELSE s.year::text - END, - 'url', s.slug - ), - 'type', 'tv' + SELECT + json_agg( + json_build_object( + 'title', + s.title, + 'year', + s.year, + 'url', + s.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_show.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_show.filename_disk), + 'alt', + CONCAT('Artwork for ', s.title), + 'subtext', + CASE + WHEN ( + SELECT + MAX(e1.last_watched_at) + FROM + episodes e1 + WHERE + e1.show = s.id + ) >= NOW() - INTERVAL '90 days' THEN ( + SELECT + CONCAT('S', e2.season_number, 'E', e2.episode_number) + FROM + episodes e2 + WHERE + e2.show = s.id + ORDER BY + e2.last_watched_at DESC, + e2.season_number DESC, + e2.episode_number DESC + LIMIT + 1 + ) + ELSE s.year::text + END, + 'url', + s.slug + ), + 'type', + 'tv' + ) + ORDER BY + s.year ASC ) - ORDER BY s.year ASC - ) - FROM shows_books sb - LEFT JOIN shows s ON sb.shows_id = s.id - LEFT JOIN directus_files df_show ON s.art = df_show.id - WHERE sb.books_id = b.id + FROM + shows_books sb + LEFT JOIN shows s ON sb.shows_id = s.id + LEFT JOIN directus_files df_show ON s.art = df_show.id + WHERE + sb.books_id = b.id AND EXISTS ( - SELECT 1 - FROM episodes e - WHERE e.show = s.id + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id AND e.last_watched_at IS NOT NULL ) ) AS shows, ( - SELECT json_agg( - json_build_object('title', p.title, 'date', p.date, 'url', p.slug) - ORDER BY p.date DESC - ) - FROM posts_books pb - LEFT JOIN posts p ON pb.posts_id = p.id - WHERE pb.books_id = b.id + SELECT + json_agg( + json_build_object('title', p.title, 'date', p.date, 'url', p.slug) + ORDER BY + p.date DESC + ) + FROM + posts_books pb + LEFT JOIN posts p ON pb.posts_id = p.id + WHERE + pb.books_id = b.id ) AS posts, ( - SELECT json_agg( - json_build_object( - 'title', rb.title, - 'author', rb.author, - 'url', rb.slug, - 'image', CONCAT(globals.cdn_url, '/', df_rb.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_rb.filename_disk), - 'alt', CONCAT('Cover for ', rb.title, ' by ', rb.author), - 'subtext', CASE WHEN rb.star_rating IS NOT NULL THEN rb.star_rating ELSE NULL END, - 'url', rb.slug - ), - 'type', 'books' + SELECT + json_agg( + json_build_object( + 'title', + rb.title, + 'author', + rb.author, + 'url', + rb.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_rb.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_rb.filename_disk), + 'alt', + CONCAT('Cover for ', rb.title, ' by ', rb.author), + 'subtext', + CASE + WHEN rb.star_rating IS NOT NULL THEN rb.star_rating + ELSE NULL + END, + 'url', + rb.slug + ), + 'type', + 'books' + ) + ORDER BY + rb.title ASC ) - ORDER BY rb.title ASC - ) - FROM related_books rbk - LEFT JOIN books rb ON rbk.related_books_id = rb.id - LEFT JOIN directus_files df_rb ON rb.art = df_rb.id - WHERE rbk.books_id = b.id + FROM + related_books rbk + LEFT JOIN books rb ON rbk.related_books_id = rb.id + LEFT JOIN directus_files df_rb ON rb.art = df_rb.id + WHERE + rbk.books_id = b.id AND LOWER(b.read_status) = 'finished' ) AS related_books, json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df.filename_disk), - 'url', b.slug, - 'alt', CONCAT('Book cover from ', b.title, ' by ', b.author), - 'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating::text ELSE NULL END, - 'type', 'books' + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df.filename_disk), + 'url', + b.slug, + 'alt', + CONCAT('Book cover from ', b.title, ' by ', b.author), + 'subtext', + CASE + WHEN b.star_rating IS NOT NULL THEN b.star_rating::text + ELSE NULL + END, + 'type', + 'books' ) AS grid, CASE - WHEN LOWER(b.read_status) = 'finished' AND b.star_rating IS NOT NULL THEN - json_build_object( - 'title', CONCAT(b.title, ' by ', b.author, ' (', b.star_rating, ')'), - 'url', b.slug, - 'date', b.date_finished, - 'description', COALESCE(b.review, b.description), - 'image', CONCAT(globals.cdn_url, '/', df.filename_disk), - 'rating', b.star_rating - ) + WHEN LOWER(b.read_status) = 'finished' + AND b.star_rating IS NOT NULL THEN json_build_object( + 'title', + CONCAT( + b.title, + ' by ', + b.author, + ' (', + b.star_rating, + ')' + ), + 'url', + b.slug, + 'date', + b.date_finished, + 'description', + COALESCE(b.review, b.description), + 'image', + CONCAT(globals.cdn_url, '/', df.filename_disk), + 'rating', + b.star_rating + ) ELSE NULL END AS feed, - (SELECT TO_CHAR(days_read, 'FM999G999G999') FROM reading_streak LIMIT 1) AS days_read, + ( + SELECT + TO_CHAR(days_read, 'FM999G999G999') + FROM + reading_streak + LIMIT + 1 + ) AS days_read, json_build_object( - 'title', CONCAT('Book • ', b.title, ' by ', b.author, ' • ', globals.site_name), - 'description', LEFT( + 'title', + CONCAT( + 'Book • ', + b.title, + ' by ', + b.author, + ' • ', + globals.site_name + ), + 'description', + LEFT( regexp_replace( regexp_replace( - regexp_replace( b.description, E'[*_`~#>-]', '', 'g'), - E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' + regexp_replace(b.description, E'[*_`~#>-]', '', 'g'), + E'\\[(.*?)\\]\\((.*?)\\)', + E'\\1', + 'g' ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' ), 250 ), - 'open_graph_image', CASE - WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) + 'open_graph_image', + CASE + WHEN df.filename_disk IS NOT NULL + AND df.filename_disk != '' + AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) ELSE NULL END, - 'url', CONCAT(globals.url, b.slug), - 'type', 'book' + 'url', + CONCAT(globals.url, b.slug), + 'type', + 'book' ) AS metadata -FROM books b -LEFT JOIN directus_files df ON b.art = df.id -CROSS JOIN optimized_globals globals -GROUP BY b.id, df.filename_disk, globals.cdn_url, globals.site_name, globals.url; +FROM + books b + LEFT JOIN directus_files df ON b.art = df.id + CROSS JOIN optimized_globals globals +GROUP BY + b.id, + df.filename_disk, + globals.cdn_url, + globals.site_name, + globals.url; diff --git a/queries/views/media/movies.sql b/queries/views/media/movies.sql index 4abda69..24b9a35 100644 --- a/queries/views/media/movies.sql +++ b/queries/views/media/movies.sql @@ -15,192 +15,322 @@ SELECT CONCAT(globals.cdn_url, '/', df.filename_disk) AS image, CONCAT(globals.cdn_url, '/', df2.filename_disk) AS backdrop, json_build_object( - 'title', m.title, - 'url', m.slug, - 'image', CONCAT(globals.cdn_url, '/', df.filename_disk), - 'backdrop', CONCAT(globals.cdn_url, '/', df2.filename_disk), - 'alt', CONCAT('Poster from ', m.title), - 'subtext', CASE + 'title', + m.title, + 'url', + m.slug, + 'image', + CONCAT(globals.cdn_url, '/', df.filename_disk), + 'backdrop', + CONCAT(globals.cdn_url, '/', df2.filename_disk), + 'alt', + CONCAT('Poster from ', m.title), + 'subtext', + CASE WHEN m.last_watched >= NOW() - INTERVAL '90 days' THEN m.star_rating::text ELSE m.year::text END, - 'type', 'movies' + 'type', + 'movies' ) AS grid, ( - SELECT array_agg(t.name) - FROM movies_tags mt - LEFT JOIN tags t ON mt.tags_id = t.id - WHERE mt.movies_id = m.id + SELECT + array_agg(t.name) + FROM + movies_tags mt + LEFT JOIN tags t ON mt.tags_id = t.id + WHERE + mt.movies_id = m.id ) AS tags, ( - SELECT json_agg(json_build_object('name', g.name, 'url', g.slug) - ORDER BY g.name ASC) - FROM genres_movies gm - LEFT JOIN genres g ON gm.genres_id = g.id - WHERE gm.movies_id = m.id + SELECT + json_agg( + json_build_object('name', g.name, 'url', g.slug) + ORDER BY + g.name ASC + ) + FROM + genres_movies gm + LEFT JOIN genres g ON gm.genres_id = g.id + WHERE + gm.movies_id = m.id ) AS genres, ( - SELECT json_agg( - json_build_object( - 'name', a.name_string, - 'url', a.slug, - 'country', a.country, - 'total_plays', a.total_plays, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'grid', json_build_object( - 'title', a.name_string, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'alt', CASE - WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name_string) - ELSE CONCAT('Artwork of ', a.name_string) - END, - 'subtext', CASE - WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays') - ELSE NULL - END, - 'url', a.slug - ), - 'type', 'music' + SELECT + json_agg( + json_build_object( + 'name', + a.name_string, + 'url', + a.slug, + 'country', + a.country, + 'total_plays', + a.total_plays, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'grid', + json_build_object( + 'title', + a.name_string, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'alt', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays of ', + a.name_string + ) + ELSE CONCAT('Artwork of ', a.name_string) + END, + 'subtext', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays' + ) + ELSE NULL + END, + 'url', + a.slug + ), + 'type', + 'music' + ) + ORDER BY + a.total_plays DESC ) - ORDER BY a.total_plays DESC - ) - FROM movies_artists ma - LEFT JOIN artists a ON ma.artists_id = a.id - LEFT JOIN directus_files df_artist ON a.art = df_artist.id - WHERE ma.movies_id = m.id + FROM + movies_artists ma + LEFT JOIN artists a ON ma.artists_id = a.id + LEFT JOIN directus_files df_artist ON a.art = df_artist.id + WHERE + ma.movies_id = m.id ) AS artists, ( - SELECT json_agg( - json_build_object( - 'title', b.title, - 'author', b.author, - 'url', b.slug, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'grid', json_build_object( - 'title', b.title, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'alt', CONCAT('Cover for ', b.title, ' by ', b.author), - 'subtext', b.author, - 'url', b.slug - ), - 'type', 'books' + SELECT + json_agg( + json_build_object( + 'title', + b.title, + 'author', + b.author, + 'url', + b.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'grid', + json_build_object( + 'title', + b.title, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'alt', + CONCAT('Cover for ', b.title, ' by ', b.author), + 'subtext', + b.author, + 'url', + b.slug + ), + 'type', + 'books' + ) + ORDER BY + b.title ) - ORDER BY b.title - ) - FROM movies_books mb - LEFT JOIN books b ON mb.books_id = b.id - LEFT JOIN directus_files df_book ON b.art = df_book.id - WHERE mb.movies_id = m.id + FROM + movies_books mb + LEFT JOIN books b ON mb.books_id = b.id + LEFT JOIN directus_files df_book ON b.art = df_book.id + WHERE + mb.movies_id = m.id AND LOWER(b.read_status) = 'finished' ) AS books, ( - SELECT json_agg( - json_build_object( - 'title', s.title, - 'year', s.year, - 'url', s.slug, - 'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), - 'alt', CONCAT('Artwork for ', s.title), - 'subtext', CASE - WHEN ( - SELECT MAX(e1.last_watched_at) - FROM episodes e1 - WHERE e1.show = s.id - ) >= NOW() - INTERVAL '90 days' THEN ( - SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) - FROM episodes e2 - WHERE e2.show = s.id - ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC - LIMIT 1 - ) - ELSE s.year::text - END, - 'url', s.slug - ), - 'type', 'tv' + SELECT + json_agg( + json_build_object( + 'title', + s.title, + 'year', + s.year, + 'url', + s.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_show.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_show.filename_disk), + 'alt', + CONCAT('Artwork for ', s.title), + 'subtext', + CASE + WHEN ( + SELECT + MAX(e1.last_watched_at) + FROM + episodes e1 + WHERE + e1.show = s.id + ) >= NOW() - INTERVAL '90 days' THEN ( + SELECT + CONCAT('S', e2.season_number, 'E', e2.episode_number) + FROM + episodes e2 + WHERE + e2.show = s.id + ORDER BY + e2.last_watched_at DESC, + e2.season_number DESC, + e2.episode_number DESC + LIMIT + 1 + ) + ELSE s.year::text + END, + 'url', + s.slug + ), + 'type', + 'tv' + ) + ORDER BY + s.year ASC ) - ORDER BY s.year ASC - ) - FROM shows_movies sm - LEFT JOIN shows s ON sm.shows_id = s.id - LEFT JOIN directus_files df_show ON s.art = df_show.id - WHERE sm.movies_id = m.id + FROM + shows_movies sm + LEFT JOIN shows s ON sm.shows_id = s.id + LEFT JOIN directus_files df_show ON s.art = df_show.id + WHERE + sm.movies_id = m.id AND EXISTS ( - SELECT 1 - FROM episodes e - WHERE e.show = s.id + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id AND e.last_watched_at IS NOT NULL ) ) AS shows, ( - SELECT json_agg(json_build_object('title', p.title, 'date', p.date, 'url', p.slug) - ORDER BY p.date DESC) - FROM posts_movies pm - LEFT JOIN posts p ON pm.posts_id = p.id - WHERE pm.movies_id = m.id + SELECT + json_agg( + json_build_object('title', p.title, 'date', p.date, 'url', p.slug) + ORDER BY + p.date DESC + ) + FROM + posts_movies pm + LEFT JOIN posts p ON pm.posts_id = p.id + WHERE + pm.movies_id = m.id ) AS posts, ( - SELECT json_agg( - json_build_object( - 'title', rm.title, - 'year', rm.year, - 'url', rm.slug, - 'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), - 'grid', json_build_object( - 'title', rm.title, - 'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), - 'alt', CONCAT('Poster for ', rm.title), - 'subtext', CASE WHEN rm.last_watched IS NOT NULL THEN rm.star_rating::text ELSE rm.year::text END, - 'url', rm.slug - ), - 'type', 'movies' + SELECT + json_agg( + json_build_object( + 'title', + rm.title, + 'year', + rm.year, + 'url', + rm.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_related.filename_disk), + 'grid', + json_build_object( + 'title', + rm.title, + 'image', + CONCAT(globals.cdn_url, '/', df_related.filename_disk), + 'alt', + CONCAT('Poster for ', rm.title), + 'subtext', + CASE + WHEN rm.last_watched IS NOT NULL THEN rm.star_rating::text + ELSE rm.year::text + END, + 'url', + rm.slug + ), + 'type', + 'movies' + ) + ORDER BY + rm.year ASC ) - ORDER BY rm.year ASC - ) - FROM related_movies r - LEFT JOIN movies rm ON r.related_movies_id = rm.id - LEFT JOIN directus_files df_related ON rm.art = df_related.id - WHERE r.movies_id = m.id + FROM + related_movies r + LEFT JOIN movies rm ON r.related_movies_id = rm.id + LEFT JOIN directus_files df_related ON rm.art = df_related.id + WHERE + r.movies_id = m.id AND rm.last_watched IS NOT NULL ) AS related_movies, CASE - WHEN m.star_rating IS NOT NULL AND m.last_watched IS NOT NULL THEN - json_build_object( - 'title', CONCAT(m.title, ' (', m.star_rating, ')'), - 'url', m.slug, - 'date', m.last_watched, - 'description', COALESCE(m.review, m.description), - 'image', CONCAT(globals.cdn_url, '/', df.filename_disk), - 'rating', m.star_rating - ) + WHEN m.star_rating IS NOT NULL + AND m.last_watched IS NOT NULL THEN json_build_object( + 'title', + CONCAT(m.title, ' (', m.star_rating, ')'), + 'url', + m.slug, + 'date', + m.last_watched, + 'description', + COALESCE(m.review, m.description), + 'image', + CONCAT(globals.cdn_url, '/', df.filename_disk), + 'rating', + m.star_rating + ) ELSE NULL END AS feed, json_build_object( - 'title', CONCAT('Movie • ', m.title, ' • ', globals.site_name), - 'description', LEFT( + 'title', + CONCAT('Movie • ', m.title, ' • ', globals.site_name), + 'description', + LEFT( regexp_replace( regexp_replace( regexp_replace(m.description, E'[*_`~#>-]', '', 'g'), - E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' + E'\\[(.*?)\\]\\((.*?)\\)', + E'\\1', + 'g' ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' ), 250 ), - 'open_graph_image', CASE - WHEN df2.filename_disk IS NOT NULL AND df2.filename_disk != '' AND df2.filename_disk != '/' THEN - CONCAT('/', df2.filename_disk) + 'open_graph_image', + CASE + WHEN df2.filename_disk IS NOT NULL + AND df2.filename_disk != '' + AND df2.filename_disk != '/' THEN CONCAT('/', df2.filename_disk) ELSE NULL END, - 'url', CONCAT(globals.url, m.slug), - 'type', 'movie' + 'url', + CONCAT(globals.url, m.slug), + 'type', + 'movie' ) AS metadata -FROM movies m -LEFT JOIN directus_files df ON m.art = df.id -LEFT JOIN directus_files df2 ON m.backdrop = df2.id -CROSS JOIN optimized_globals globals -GROUP BY m.id, df.filename_disk, df2.filename_disk, globals.cdn_url, globals.site_name, globals.url -ORDER BY m.last_watched DESC; +FROM + movies m + LEFT JOIN directus_files df ON m.art = df.id + LEFT JOIN directus_files df2 ON m.backdrop = df2.id + CROSS JOIN optimized_globals globals +GROUP BY + m.id, + df.filename_disk, + df2.filename_disk, + globals.cdn_url, + globals.site_name, + globals.url +ORDER BY + m.last_watched DESC; diff --git a/queries/views/media/music/album_releases.sql b/queries/views/media/music/album_releases.sql index d57b5c9..62712ae 100644 --- a/queries/views/media/music/album_releases.sql +++ b/queries/views/media/music/album_releases.sql @@ -5,14 +5,34 @@ SELECT COALESCE(a.release_link, ar.slug) AS url, a.total_plays, CONCAT('/', df.filename_disk) AS image, - json_build_object('name', ar.name_string, 'url', ar.slug, 'description', ar.description) AS artist, - EXTRACT(EPOCH FROM a.release_date) AS release_timestamp, json_build_object( - 'title', a.name, - 'image', CONCAT(globals.cdn_url, '/', df.filename_disk), - 'url', COALESCE(a.release_link, ar.slug), - 'alt', CONCAT(a.name, ' by ', ar.name_string), - 'subtext', CONCAT(ar.name_string, ' • ', TO_CHAR(a.release_date, 'Mon FMDD, YYYY')) + 'name', + ar.name_string, + 'url', + ar.slug, + 'description', + ar.description + ) AS artist, + EXTRACT( + EPOCH + FROM + a.release_date + ) AS release_timestamp, + json_build_object( + 'title', + a.name, + 'image', + CONCAT(globals.cdn_url, '/', df.filename_disk), + 'url', + COALESCE(a.release_link, ar.slug), + 'alt', + CONCAT(a.name, ' by ', ar.name_string), + 'subtext', + CONCAT( + ar.name_string, + ' • ', + TO_CHAR(a.release_date, 'Mon FMDD, YYYY') + ) ) AS grid FROM albums a diff --git a/queries/views/media/music/albums.sql b/queries/views/media/music/albums.sql index 5458f68..b19bae8 100644 --- a/queries/views/media/music/albums.sql +++ b/queries/views/media/music/albums.sql @@ -8,23 +8,44 @@ SELECT ar.slug AS artist_url, CONCAT(globals.cdn_url, '/', df_album.filename_disk) AS image, json_build_object( - 'title', al.name, - 'image', CONCAT(globals.cdn_url, '/', df_album.filename_disk), - 'url', ar.slug, - 'alt', CONCAT('Cover for ', al.name, ' by ', ar.name_string), - 'subtext', CONCAT(to_char(al.total_plays, 'FM999,999,999,999'), ' plays') + 'title', + al.name, + 'image', + CONCAT(globals.cdn_url, '/', df_album.filename_disk), + 'url', + ar.slug, + 'alt', + CONCAT('Cover for ', al.name, ' by ', ar.name_string), + 'subtext', + CONCAT( + to_char(al.total_plays, 'FM999,999,999,999'), + ' plays' + ) ) AS grid, json_build_object( - 'title', al.name, - 'artist', ar.name_string, - 'plays', to_char(al.total_plays, 'FM999,999,999,999'), - 'image', CONCAT(globals.cdn_url, '/', df_album.filename_disk), - 'url', ar.slug, - 'year', al.release_year, - 'alt', CONCAT('Cover for ', al.name, ' by ', ar.name_string) + 'title', + al.name, + 'artist', + ar.name_string, + 'plays', + to_char(al.total_plays, 'FM999,999,999,999'), + 'image', + CONCAT(globals.cdn_url, '/', df_album.filename_disk), + 'url', + ar.slug, + 'year', + al.release_year, + 'alt', + CONCAT('Cover for ', al.name, ' by ', ar.name_string) ) AS table -FROM albums al -LEFT JOIN artists ar ON al.artist = ar.id -LEFT JOIN directus_files df_album ON al.art = df_album.id -CROSS JOIN optimized_globals globals -GROUP BY al.id, ar.name_string, ar.slug, df_album.filename_disk, globals.cdn_url; +FROM + albums al + LEFT JOIN artists ar ON al.artist = ar.id + LEFT JOIN directus_files df_album ON al.art = df_album.id + CROSS JOIN optimized_globals globals +GROUP BY + al.id, + ar.name_string, + ar.slug, + df_album.filename_disk, + globals.cdn_url; diff --git a/queries/views/media/music/artists.sql b/queries/views/media/music/artists.sql index 818711e..c1e7f7e 100644 --- a/queries/views/media/music/artists.sql +++ b/queries/views/media/music/artists.sql @@ -16,196 +16,383 @@ SELECT ar.tattoo, CONCAT(globals.cdn_url, '/', df.filename_disk) AS image, json_build_object( - 'title', ar.name_string, - 'image', CONCAT(globals.cdn_url, '/', df.filename_disk), - 'url', ar.slug, - 'alt', CASE WHEN ar.total_plays > 0 THEN CONCAT(to_char(ar.total_plays, 'FM999,999,999,999'), ' plays of ', ar.name_string) ELSE CONCAT('Artwork of ', ar.name_string) END, - 'subtext', CASE WHEN ar.total_plays > 0 THEN CONCAT(to_char(ar.total_plays, 'FM999,999,999,999'), ' plays') ELSE NULL END + 'title', + ar.name_string, + 'image', + CONCAT(globals.cdn_url, '/', df.filename_disk), + 'url', + ar.slug, + 'alt', + CASE + WHEN ar.total_plays > 0 THEN CONCAT( + to_char(ar.total_plays, 'FM999,999,999,999'), + ' plays of ', + ar.name_string + ) + ELSE CONCAT('Artwork of ', ar.name_string) + END, + 'subtext', + CASE + WHEN ar.total_plays > 0 THEN CONCAT( + to_char(ar.total_plays, 'FM999,999,999,999'), + ' plays' + ) + ELSE NULL + END ) AS grid, json_build_object( - 'title', ar.name_string, - 'genre', g.name, - 'genre_url', g.slug, - 'emoji', COALESCE(ar.emoji, g.emoji), - 'plays', to_char(ar.total_plays, 'FM999,999,999,999'), - 'image', CONCAT(globals.cdn_url, '/', df.filename_disk), - 'url', ar.slug, - 'alt', CONCAT(to_char(ar.total_plays, 'FM999,999,999,999'), ' plays of ', ar.name_string) + 'title', + ar.name_string, + 'genre', + g.name, + 'genre_url', + g.slug, + 'emoji', + COALESCE(ar.emoji, g.emoji), + 'plays', + to_char(ar.total_plays, 'FM999,999,999,999'), + 'image', + CONCAT(globals.cdn_url, '/', df.filename_disk), + 'url', + ar.slug, + 'alt', + CONCAT( + to_char(ar.total_plays, 'FM999,999,999,999'), + ' plays of ', + ar.name_string + ) ) AS table, ( - SELECT json_agg( - json_build_object( - 'name', a.name, - 'release_year', a.release_year, - 'total_plays', to_char(a.total_plays, 'FM999,999,999,999'), - 'art', df_album.filename_disk, - 'grid', json_build_object( - 'title', a.name, - 'image', CONCAT(globals.cdn_url, '/', df_album.filename_disk), - 'alt', CASE WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name) ELSE CONCAT('Artwork for ', a.name) END, - 'subtext', CASE WHEN a.total_plays > 0 THEN CONCAT(a.release_year, ' • ', to_char(a.total_plays, 'FM999,999,999,999'), ' plays') ELSE a.release_year::text END - ), - 'type', 'albums' + SELECT + json_agg( + json_build_object( + 'name', + a.name, + 'release_year', + a.release_year, + 'total_plays', + to_char(a.total_plays, 'FM999,999,999,999'), + 'art', + df_album.filename_disk, + 'grid', + json_build_object( + 'title', + a.name, + 'image', + CONCAT(globals.cdn_url, '/', df_album.filename_disk), + 'alt', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays of ', + a.name + ) + ELSE CONCAT('Artwork for ', a.name) + END, + 'subtext', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + a.release_year, + ' • ', + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays' + ) + ELSE a.release_year::text + END + ), + 'type', + 'albums' + ) + ORDER BY + a.release_year ) - ORDER BY a.release_year - ) - FROM albums a - LEFT JOIN directus_files df_album ON a.art = df_album.id - WHERE a.artist = ar.id + FROM + albums a + LEFT JOIN directus_files df_album ON a.art = df_album.id + WHERE + a.artist = ar.id ) AS albums, ( - SELECT json_agg( - json_build_object( - 'id', c.id, - 'date', c.date, - 'venue_name', v.name, - 'venue_name_short', trim(split_part(v.name, ',', 1)), - 'venue_latitude', v.latitude, - 'venue_longitude', v.longitude, - 'notes', c.notes + SELECT + json_agg( + json_build_object( + 'id', + c.id, + 'date', + c.date, + 'venue_name', + v.name, + 'venue_name_short', + trim(split_part(v.name, ',', 1)), + 'venue_latitude', + v.latitude, + 'venue_longitude', + v.longitude, + 'notes', + c.notes + ) + ORDER BY + c.date DESC ) - ORDER BY c.date DESC - ) - FROM concerts c - LEFT JOIN venues v ON c.venue = v.id - WHERE c.artist = ar.id + FROM + concerts c + LEFT JOIN venues v ON c.venue = v.id + WHERE + c.artist = ar.id ) AS concerts, ( - SELECT json_agg( - json_build_object( - 'title', b.title, - 'author', b.author, - 'url', b.slug, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'alt', CONCAT('Cover for ', b.title, ' by ', b.author), - 'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating ELSE NULL END, - 'url', b.slug - ), - 'type', 'books' + SELECT + json_agg( + json_build_object( + 'title', + b.title, + 'author', + b.author, + 'url', + b.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'alt', + CONCAT('Cover for ', b.title, ' by ', b.author), + 'subtext', + CASE + WHEN b.star_rating IS NOT NULL THEN b.star_rating + ELSE NULL + END, + 'url', + b.slug + ), + 'type', + 'books' + ) + ORDER BY + b.title ASC ) - ORDER BY b.title ASC - ) - FROM books_artists ba - LEFT JOIN books b ON ba.books_id = b.id - LEFT JOIN directus_files df_book ON b.art = df_book.id - WHERE ba.artists_id = ar.id + FROM + books_artists ba + LEFT JOIN books b ON ba.books_id = b.id + LEFT JOIN directus_files df_book ON b.art = df_book.id + WHERE + ba.artists_id = ar.id AND LOWER(b.read_status) = 'finished' ) AS books, ( - SELECT json_agg( - json_build_object( - 'title', m.title, - 'year', m.year, - 'url', m.slug, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), - 'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, - 'url', m.slug - ), - 'type', 'movies' + SELECT + json_agg( + json_build_object( + 'title', + m.title, + 'year', + m.year, + 'url', + m.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'alt', + CONCAT('Poster for ', m.title, ' (', m.year, ')'), + 'subtext', + CASE + WHEN m.star_rating IS NOT NULL THEN m.star_rating::text + ELSE m.year::text + END, + 'url', + m.slug + ), + 'type', + 'movies' + ) + ORDER BY + m.year ASC ) - ORDER BY m.year ASC - ) - FROM movies_artists ma - LEFT JOIN movies m ON ma.movies_id = m.id - LEFT JOIN directus_files df_movie ON m.art = df_movie.id - WHERE ma.artists_id = ar.id + FROM + movies_artists ma + LEFT JOIN movies m ON ma.movies_id = m.id + LEFT JOIN directus_files df_movie ON m.art = df_movie.id + WHERE + ma.artists_id = ar.id AND m.last_watched IS NOT NULL ) AS movies, ( - SELECT json_agg( - json_build_object( - 'title', s.title, - 'year', s.year, - 'url', s.slug, - 'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), - 'alt', CONCAT('Artwork for ', s.title), - 'subtext', CASE - WHEN ( - SELECT MAX(e1.last_watched_at) - FROM episodes e1 - WHERE e1.show = s.id - ) >= NOW() - INTERVAL '90 days' THEN - ( - SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) - FROM episodes e2 - WHERE e2.show = s.id - ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC - LIMIT 1 + SELECT + json_agg( + json_build_object( + 'title', + s.title, + 'year', + s.year, + 'url', + s.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_show.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_show.filename_disk), + 'alt', + CONCAT('Artwork for ', s.title), + 'subtext', + CASE + WHEN ( + SELECT + MAX(e1.last_watched_at) + FROM + episodes e1 + WHERE + e1.show = s.id + ) >= NOW() - INTERVAL '90 days' THEN ( + SELECT + CONCAT('S', e2.season_number, 'E', e2.episode_number) + FROM + episodes e2 + WHERE + e2.show = s.id + ORDER BY + e2.last_watched_at DESC, + e2.season_number DESC, + e2.episode_number DESC + LIMIT + 1 ) - ELSE s.year::text - END, - 'url', s.slug - ), - 'type', 'tv' + ELSE s.year::text + END, + 'url', + s.slug + ), + 'type', + 'tv' + ) + ORDER BY + s.year ASC ) - ORDER BY s.year ASC - ) - FROM shows_artists sa - LEFT JOIN shows s ON sa.shows_id = s.id - LEFT JOIN directus_files df_show ON s.art = df_show.id - WHERE sa.artists_id = ar.id + FROM + shows_artists sa + LEFT JOIN shows s ON sa.shows_id = s.id + LEFT JOIN directus_files df_show ON s.art = df_show.id + WHERE + sa.artists_id = ar.id AND EXISTS ( - SELECT 1 - FROM episodes e - WHERE e.show = s.id + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id AND e.last_watched_at IS NOT NULL ) ) AS shows, ( - SELECT json_agg( - json_build_object( - 'name', related_ar.name_string, - 'url', related_ar.slug, - 'country', related_ar.country, - 'total_plays', to_char(related_ar.total_plays, 'FM999,999,999,999'), - 'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), - 'grid', json_build_object( - 'title', related_ar.name_string, - 'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), - 'alt', CASE WHEN related_ar.total_plays > 0 THEN CONCAT(to_char(related_ar.total_plays, 'FM999,999,999,999'), ' plays of ', related_ar.name_string) ELSE CONCAT('Artwork of ', related_ar.name_string) END, - 'subtext', CASE WHEN related_ar.total_plays > 0 THEN CONCAT(to_char(related_ar.total_plays, 'FM999,999,999,999'), ' plays') ELSE NULL END, - 'url', related_ar.slug - ), - 'type', 'music' + SELECT + json_agg( + json_build_object( + 'name', + related_ar.name_string, + 'url', + related_ar.slug, + 'country', + related_ar.country, + 'total_plays', + to_char(related_ar.total_plays, 'FM999,999,999,999'), + 'image', + CONCAT(globals.cdn_url, '/', df_related.filename_disk), + 'grid', + json_build_object( + 'title', + related_ar.name_string, + 'image', + CONCAT(globals.cdn_url, '/', df_related.filename_disk), + 'alt', + CASE + WHEN related_ar.total_plays > 0 THEN CONCAT( + to_char(related_ar.total_plays, 'FM999,999,999,999'), + ' plays of ', + related_ar.name_string + ) + ELSE CONCAT('Artwork of ', related_ar.name_string) + END, + 'subtext', + CASE + WHEN related_ar.total_plays > 0 THEN CONCAT( + to_char(related_ar.total_plays, 'FM999,999,999,999'), + ' plays' + ) + ELSE NULL + END, + 'url', + related_ar.slug + ), + 'type', + 'music' + ) + ORDER BY + related_ar.total_plays DESC ) - ORDER BY related_ar.total_plays DESC - ) - FROM related_artists ra - LEFT JOIN artists related_ar ON ra.related_artists_id = related_ar.id - LEFT JOIN directus_files df_related ON related_ar.art = df_related.id - WHERE ra.artists_id = ar.id + FROM + related_artists ra + LEFT JOIN artists related_ar ON ra.related_artists_id = related_ar.id + LEFT JOIN directus_files df_related ON related_ar.art = df_related.id + WHERE + ra.artists_id = ar.id ) AS related_artists, json_build_object( - 'title', CONCAT('Artist • ', ar.name_string, ' • ', globals.site_name), - 'description', LEFT( + 'title', + CONCAT( + 'Artist • ', + ar.name_string, + ' • ', + globals.site_name + ), + 'description', + LEFT( regexp_replace( regexp_replace( regexp_replace(ar.description, E'[*_`~#>-]', '', 'g'), - E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' + E'\\[(.*?)\\]\\((.*?)\\)', + E'\\1', + 'g' ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' ), 250 ), - 'open_graph_image', CASE - WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) + 'open_graph_image', + CASE + WHEN df.filename_disk IS NOT NULL + AND df.filename_disk != '' + AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) ELSE NULL END, - 'url', CONCAT(globals.url, ar.slug), - 'type', 'artist' + 'url', + CONCAT(globals.url, ar.slug), + 'type', + 'artist' ) AS metadata -FROM artists ar -LEFT JOIN directus_files df ON ar.art = df.id -LEFT JOIN genres g ON ar.genres = g.id -CROSS JOIN optimized_globals globals -GROUP BY ar.id, df.filename_disk, g.name, g.slug, g.emoji, globals.cdn_url, globals.site_name, globals.url; +FROM + artists ar + LEFT JOIN directus_files df ON ar.art = df.id + LEFT JOIN genres g ON ar.genres = g.id + CROSS JOIN optimized_globals globals +GROUP BY + ar.id, + df.filename_disk, + g.name, + g.slug, + g.emoji, + globals.cdn_url, + globals.site_name, + globals.url; diff --git a/queries/views/media/music/concerts.sql b/queries/views/media/music/concerts.sql index c577821..0749651 100644 --- a/queries/views/media/music/concerts.sql +++ b/queries/views/media/music/concerts.sql @@ -2,12 +2,22 @@ CREATE OR REPLACE VIEW optimized_concerts AS SELECT c.id, c.date, - CASE WHEN c.artist IS NOT NULL THEN - json_build_object('name', a.name_string, 'url', a.slug) - ELSE - json_build_object('name', c.artist_name_string, 'url', NULL) + CASE + WHEN c.artist IS NOT NULL THEN json_build_object('name', a.name_string, 'url', a.slug) + ELSE json_build_object('name', c.artist_name_string, 'url', NULL) END AS artist, - json_build_object('name', v.name, 'name_short', trim(split_part(v.name, ',', 1)), 'latitude', v.latitude, 'longitude', v.longitude, 'notes', v.notes) AS venue, + json_build_object( + 'name', + v.name, + 'name_short', + trim(split_part(v.name, ',', 1)), + 'latitude', + v.latitude, + 'longitude', + v.longitude, + 'notes', + v.notes + ) AS venue, c.notes AS concert_notes FROM concerts c diff --git a/queries/views/media/music/genres.sql b/queries/views/media/music/genres.sql index d8f1073..831663f 100644 --- a/queries/views/media/music/genres.sql +++ b/queries/views/media/music/genres.sql @@ -8,131 +8,216 @@ SELECT g.wiki_link, g.slug AS url, ( - SELECT json_agg( - json_build_object( - 'name', a.name_string, - 'url', a.slug, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'total_plays', to_char(a.total_plays, 'FM999,999,999,999'), - 'grid', json_build_object( - 'title', a.name_string, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'alt', CASE - WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name_string) - ELSE CONCAT('Artwork of ', a.name_string) - END, - 'subtext', CASE - WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays') - ELSE NULL - END, - 'url', a.slug - ), - 'type', 'music' + SELECT + json_agg( + json_build_object( + 'name', + a.name_string, + 'url', + a.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'total_plays', + to_char(a.total_plays, 'FM999,999,999,999'), + 'grid', + json_build_object( + 'title', + a.name_string, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'alt', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays of ', + a.name_string + ) + ELSE CONCAT('Artwork of ', a.name_string) + END, + 'subtext', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays' + ) + ELSE NULL + END, + 'url', + a.slug + ), + 'type', + 'music' + ) + ORDER BY + a.total_plays DESC ) - ORDER BY a.total_plays DESC - ) - FROM artists a - LEFT JOIN directus_files df_artist ON a.art = df_artist.id - WHERE a.genres = g.id + FROM + artists a + LEFT JOIN directus_files df_artist ON a.art = df_artist.id + WHERE + a.genres = g.id ) AS artists, ( - SELECT json_agg( - json_build_object( - 'title', b.title, - 'author', b.author, - 'url', b.slug, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'alt', CONCAT('Cover for ', b.title, ' by ', b.author), - 'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating ELSE NULL END, - 'url', b.slug - ), - 'type', 'books' + SELECT + json_agg( + json_build_object( + 'title', + b.title, + 'author', + b.author, + 'url', + b.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'alt', + CONCAT('Cover for ', b.title, ' by ', b.author), + 'subtext', + CASE + WHEN b.star_rating IS NOT NULL THEN b.star_rating + ELSE NULL + END, + 'url', + b.slug + ), + 'type', + 'books' + ) + ORDER BY + b.title ASC ) - ORDER BY b.title ASC - ) - FROM books b - JOIN genres_books gb ON gb.books_id = b.id - LEFT JOIN directus_files df_book ON b.art = df_book.id - WHERE gb.genres_id = g.id + FROM + books b + JOIN genres_books gb ON gb.books_id = b.id + LEFT JOIN directus_files df_book ON b.art = df_book.id + WHERE + gb.genres_id = g.id AND LOWER(b.read_status) = 'finished' ) AS books, ( - SELECT json_agg( - json_build_object( - 'title', m.title, - 'year', m.year, - 'url', m.slug, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), - 'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, - 'url', m.slug - ), - 'type', 'movies' + SELECT + json_agg( + json_build_object( + 'title', + m.title, + 'year', + m.year, + 'url', + m.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'alt', + CONCAT('Poster for ', m.title, ' (', m.year, ')'), + 'subtext', + CASE + WHEN m.star_rating IS NOT NULL THEN m.star_rating::text + ELSE m.year::text + END, + 'url', + m.slug + ), + 'type', + 'movies' + ) + ORDER BY + m.year ASC ) - ORDER BY m.year ASC - ) - FROM movies m - JOIN genres_movies gm ON gm.movies_id = m.id - LEFT JOIN directus_files df_movie ON m.art = df_movie.id - WHERE gm.genres_id = g.id + FROM + movies m + JOIN genres_movies gm ON gm.movies_id = m.id + LEFT JOIN directus_files df_movie ON m.art = df_movie.id + WHERE + gm.genres_id = g.id AND m.last_watched IS NOT NULL ) AS movies, ( - SELECT json_agg( - json_build_object( - 'title', p.title, - 'date', p.date, - 'url', p.slug, - 'grid', json_build_object( - 'title', p.title, - 'image', CONCAT(globals.cdn_url, '/', df_post.filename_disk), - 'alt', p.title, - 'subtext', TO_CHAR(p.date, 'FMMonth DD, YYYY'), - 'url', p.slug - ), - 'type', 'posts' + SELECT + json_agg( + json_build_object( + 'title', + p.title, + 'date', + p.date, + 'url', + p.slug, + 'grid', + json_build_object( + 'title', + p.title, + 'image', + CONCAT(globals.cdn_url, '/', df_post.filename_disk), + 'alt', + p.title, + 'subtext', + TO_CHAR(p.date, 'FMMonth DD, YYYY'), + 'url', + p.slug + ), + 'type', + 'posts' + ) + ORDER BY + p.date DESC ) - ORDER BY p.date DESC - ) - FROM posts_genres pg - LEFT JOIN posts p ON pg.posts_id = p.id - LEFT JOIN directus_files df_post ON p.image = df_post.id - WHERE pg.genres_id = g.id + FROM + posts_genres pg + LEFT JOIN posts p ON pg.posts_id = p.id + LEFT JOIN directus_files df_post ON p.image = df_post.id + WHERE + pg.genres_id = g.id ) AS posts, json_build_object( - 'title', CONCAT('Genre • ', g.name, ' • ', globals.site_name), - 'description', LEFT( + 'title', + CONCAT('Genre • ', g.name, ' • ', globals.site_name), + 'description', + LEFT( regexp_replace( regexp_replace( - regexp_replace( - g.description, - E'[*_`~#>-]', '', 'g' - ), - E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' + regexp_replace(g.description, E'[*_`~#>-]', '', 'g'), + E'\\[(.*?)\\]\\((.*?)\\)', + E'\\1', + 'g' ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' ), 250 ), - 'open_graph_image', ( - SELECT CONCAT('/', df_artist.filename_disk) - FROM artists a - LEFT JOIN directus_files df_artist ON a.art = df_artist.id - WHERE a.genres = g.id + 'open_graph_image', + ( + SELECT + CONCAT('/', df_artist.filename_disk) + FROM + artists a + LEFT JOIN directus_files df_artist ON a.art = df_artist.id + WHERE + a.genres = g.id AND df_artist.filename_disk IS NOT NULL AND df_artist.filename_disk != '' - ORDER BY a.total_plays DESC - LIMIT 1 + ORDER BY + a.total_plays DESC + LIMIT + 1 ), - 'url', CONCAT(globals.url, g.slug), - 'type', 'genre' + 'url', + CONCAT(globals.url, g.slug), + 'type', + 'genre' ) AS metadata -FROM genres g -CROSS JOIN optimized_globals globals -ORDER BY g.id ASC; +FROM + genres g + CROSS JOIN optimized_globals globals +ORDER BY + g.id ASC; diff --git a/queries/views/media/music/latest_listen.sql b/queries/views/media/music/latest_listen.sql index 34766b4..8292b02 100644 --- a/queries/views/media/music/latest_listen.sql +++ b/queries/views/media/music/latest_listen.sql @@ -9,11 +9,9 @@ SELECT NULL::FLOAT AS progress_ticks FROM listens l -JOIN - artists a - ON l.artist_name = a.name_string -LEFT JOIN - genres g - ON a.genres = g.id -ORDER BY l.listened_at DESC -LIMIT 1; + JOIN artists a ON l.artist_name = a.name_string + LEFT JOIN genres g ON a.genres = g.id +ORDER BY + l.listened_at DESC +LIMIT + 1; diff --git a/queries/views/media/music/listens.sql b/queries/views/media/music/listens.sql index 3f81835..226d0d3 100644 --- a/queries/views/media/music/listens.sql +++ b/queries/views/media/music/listens.sql @@ -1,6 +1,12 @@ CREATE OR REPLACE VIEW optimized_listens AS -SELECT DISTINCT ON (l.id, l.listened_at, l.track_name, l.artist_name, l.album_name) - l.id, +SELECT DISTINCT + ON ( + l.id, + l.listened_at, + l.track_name, + l.artist_name, + l.album_name + ) l.id, l.listened_at, l.track_name, l.artist_name, diff --git a/queries/views/media/music/month/albums.sql b/queries/views/media/music/month/albums.sql index 39a453e..59e390b 100644 --- a/queries/views/media/music/month/albums.sql +++ b/queries/views/media/music/month/albums.sql @@ -6,16 +6,23 @@ SELECT ol.album_art, ol.artist_url, json_build_object( - 'title', ol.album_name, - 'image', ol.album_art, - 'url', ol.artist_url, - 'alt', CONCAT(ol.album_name, ' by ', ol.artist_name), - 'subtext', ol.artist_name + 'title', + ol.album_name, + 'image', + ol.album_art, + 'url', + ol.artist_url, + 'alt', + CONCAT(ol.album_name, ' by ', ol.artist_name), + 'subtext', + ol.artist_name ) AS grid, json_build_object( 'open_graph_image', CASE - WHEN ol.opengraph_image_album IS NOT NULL AND ol.opengraph_image_album != '' AND ol.opengraph_image_album != '/' THEN ol.opengraph_image_album + WHEN ol.opengraph_image_album IS NOT NULL + AND ol.opengraph_image_album != '' + AND ol.opengraph_image_album != '/' THEN ol.opengraph_image_album ELSE NULL END ) AS metadata diff --git a/queries/views/media/music/month/artists.sql b/queries/views/media/music/month/artists.sql index 77bfb7c..6370311 100644 --- a/queries/views/media/music/month/artists.sql +++ b/queries/views/media/music/month/artists.sql @@ -6,16 +6,23 @@ SELECT ol.artist_url, ARRAY_AGG(DISTINCT ol.genre_name) AS genres, json_build_object( - 'title', ol.artist_name, - 'image', ol.artist_art, - 'url', ol.artist_url, - 'alt', CONCAT(COUNT(*), ' plays of ', ol.artist_name), - 'subtext', CONCAT(COUNT(*), ' plays') + 'title', + ol.artist_name, + 'image', + ol.artist_art, + 'url', + ol.artist_url, + 'alt', + CONCAT(COUNT(*), ' plays of ', ol.artist_name), + 'subtext', + CONCAT(COUNT(*), ' plays') ) AS grid, json_build_object( 'open_graph_image', CASE - WHEN ol.opengraph_image_artist IS NOT NULL AND ol.opengraph_image_artist != '' AND ol.opengraph_image_artist != '/' THEN ol.opengraph_image_artist + WHEN ol.opengraph_image_artist IS NOT NULL + AND ol.opengraph_image_artist != '' + AND ol.opengraph_image_artist != '/' THEN ol.opengraph_image_artist ELSE NULL END ) AS metadata diff --git a/queries/views/media/music/month/genres.sql b/queries/views/media/music/month/genres.sql index e8089aa..ef5bf98 100644 --- a/queries/views/media/music/month/genres.sql +++ b/queries/views/media/music/month/genres.sql @@ -3,7 +3,12 @@ SELECT ol.genre_name, ol.genre_url, COUNT(*) AS plays, - json_build_object('alt', ol.genre_name, 'subtext', CONCAT(COUNT(*), ' plays')) AS grid + json_build_object( + 'alt', + ol.genre_name, + 'subtext', + CONCAT(COUNT(*), ' plays') + ) AS grid FROM optimized_listens ol WHERE @@ -13,4 +18,3 @@ GROUP BY ol.genre_url ORDER BY plays DESC; - diff --git a/queries/views/media/music/month/tracks.sql b/queries/views/media/music/month/tracks.sql index 9db3477..4b811d4 100644 --- a/queries/views/media/music/month/tracks.sql +++ b/queries/views/media/music/month/tracks.sql @@ -1,25 +1,26 @@ CREATE OR REPLACE VIEW month_tracks AS -WITH track_stats AS ( - SELECT - ol.track_name, - ol.artist_name, - ol.album_name, - COUNT(*) AS plays, - MAX(ol.listened_at) AS last_listened, - ol.album_art, - ol.artist_url, - MAX(COUNT(*)) OVER () AS most_played - FROM - optimized_listens ol - WHERE - TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '30 days' - GROUP BY - ol.track_name, - ol.artist_name, - ol.album_name, - ol.album_art, - ol.artist_url -) +WITH + track_stats AS ( + SELECT + ol.track_name, + ol.artist_name, + ol.album_name, + COUNT(*) AS plays, + MAX(ol.listened_at) AS last_listened, + ol.album_art, + ol.artist_url, + MAX(COUNT(*)) OVER () AS most_played + FROM + optimized_listens ol + WHERE + TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '30 days' + GROUP BY + ol.track_name, + ol.artist_name, + ol.album_name, + ol.album_art, + ol.artist_url + ) SELECT track_name, artist_name, @@ -28,10 +29,24 @@ SELECT last_listened, album_art, artist_url, - json_build_object('title', track_name, 'artist', artist_name, 'url', artist_url, 'plays', plays, 'alt', CONCAT(track_name, ' by ', artist_name), 'subtext', CONCAT(album_name, ' (', plays, ' plays)'), 'percentage', ROUND((plays::decimal / most_played) * 100, 2)) AS chart + json_build_object( + 'title', + track_name, + 'artist', + artist_name, + 'url', + artist_url, + 'plays', + plays, + 'alt', + CONCAT(track_name, ' by ', artist_name), + 'subtext', + CONCAT(album_name, ' (', plays, ' plays)'), + 'percentage', + ROUND((plays::decimal / most_played) * 100, 2) + ) AS chart FROM track_stats ORDER BY plays DESC, last_listened DESC; - diff --git a/queries/views/media/music/recent_tracks.sql b/queries/views/media/music/recent_tracks.sql index 59b0e59..2bbe7af 100644 --- a/queries/views/media/music/recent_tracks.sql +++ b/queries/views/media/music/recent_tracks.sql @@ -13,11 +13,23 @@ SELECT ol.album_art, ol.artist_url, ol.genre_url, - json_build_object('title', ol.track_name, 'subtext', ol.artist_name, 'alt', CONCAT(ol.track_name, ' by ', ol.artist_name), 'url', ol.artist_url, 'image', ol.album_art, 'played_at', ol.listened_at) AS chart + json_build_object( + 'title', + ol.track_name, + 'subtext', + ol.artist_name, + 'alt', + CONCAT(ol.track_name, ' by ', ol.artist_name), + 'url', + ol.artist_url, + 'image', + ol.album_art, + 'played_at', + ol.listened_at + ) AS chart FROM optimized_listens ol WHERE TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days' ORDER BY TO_TIMESTAMP(ol.listened_at) DESC; - diff --git a/queries/views/media/music/week/albums.sql b/queries/views/media/music/week/albums.sql index 07914b0..0009a57 100644 --- a/queries/views/media/music/week/albums.sql +++ b/queries/views/media/music/week/albums.sql @@ -6,16 +6,23 @@ SELECT ol.album_art, ol.artist_url, json_build_object( - 'title', ol.album_name, - 'image', ol.album_art, - 'url', ol.artist_url, - 'alt', CONCAT(ol.album_name, ' by ', ol.artist_name), - 'subtext', ol.artist_name + 'title', + ol.album_name, + 'image', + ol.album_art, + 'url', + ol.artist_url, + 'alt', + CONCAT(ol.album_name, ' by ', ol.artist_name), + 'subtext', + ol.artist_name ) AS grid, json_build_object( 'open_graph_image', CASE - WHEN ol.opengraph_image_album IS NOT NULL AND ol.opengraph_image_album != '' AND ol.opengraph_image_album != '/' THEN ol.opengraph_image_album + WHEN ol.opengraph_image_album IS NOT NULL + AND ol.opengraph_image_album != '' + AND ol.opengraph_image_album != '/' THEN ol.opengraph_image_album ELSE NULL END ) AS metadata diff --git a/queries/views/media/music/week/artists.sql b/queries/views/media/music/week/artists.sql index 9169f27..df8a906 100644 --- a/queries/views/media/music/week/artists.sql +++ b/queries/views/media/music/week/artists.sql @@ -6,16 +6,23 @@ SELECT ol.artist_url, ARRAY_AGG(DISTINCT ol.genre_name) AS genres, json_build_object( - 'title', ol.artist_name, - 'image', ol.artist_art, - 'url', ol.artist_url, - 'alt', CONCAT(COUNT(*), ' plays of ', ol.artist_name), - 'subtext', CONCAT(COUNT(*), ' plays') + 'title', + ol.artist_name, + 'image', + ol.artist_art, + 'url', + ol.artist_url, + 'alt', + CONCAT(COUNT(*), ' plays of ', ol.artist_name), + 'subtext', + CONCAT(COUNT(*), ' plays') ) AS grid, json_build_object( 'open_graph_image', CASE - WHEN ol.opengraph_image_artist IS NOT NULL AND ol.opengraph_image_artist != '' AND ol.opengraph_image_artist != '/' THEN ol.opengraph_image_artist + WHEN ol.opengraph_image_artist IS NOT NULL + AND ol.opengraph_image_artist != '' + AND ol.opengraph_image_artist != '/' THEN ol.opengraph_image_artist ELSE NULL END ) AS metadata diff --git a/queries/views/media/music/week/genres.sql b/queries/views/media/music/week/genres.sql index 28339ee..92f6415 100644 --- a/queries/views/media/music/week/genres.sql +++ b/queries/views/media/music/week/genres.sql @@ -3,7 +3,12 @@ SELECT ol.genre_name, ol.genre_url, COUNT(*) AS plays, - json_build_object('alt', ol.genre_name, 'subtext', CONCAT(COUNT(*), ' plays')) AS grid + json_build_object( + 'alt', + ol.genre_name, + 'subtext', + CONCAT(COUNT(*), ' plays') + ) AS grid FROM optimized_listens ol WHERE @@ -13,4 +18,3 @@ GROUP BY ol.genre_url ORDER BY plays DESC; - diff --git a/queries/views/media/music/week/summary.sql b/queries/views/media/music/week/summary.sql index 7cad661..af45c30 100644 --- a/queries/views/media/music/week/summary.sql +++ b/queries/views/media/music/week/summary.sql @@ -1,34 +1,111 @@ CREATE OR REPLACE VIEW optimized_week_music AS -SELECT json_build_object( - 'week_artists', ( - SELECT json_agg(a ORDER BY a.plays DESC) - FROM ( - SELECT * FROM week_artists ORDER BY plays DESC LIMIT 8 - ) a - ), - 'week_albums', ( - SELECT json_agg(al ORDER BY al.plays DESC) - FROM ( - SELECT * FROM week_albums ORDER BY plays DESC LIMIT 8 - ) al - ), - 'week_genres', ( - SELECT json_agg(g ORDER BY g.plays DESC) - FROM ( - SELECT * FROM week_genres ORDER BY plays DESC LIMIT 5 - ) g - ), - 'recent_tracks', ( - SELECT json_agg(r ORDER BY r.listened_at DESC) - FROM ( - SELECT * FROM recent_tracks ORDER BY listened_at DESC LIMIT 10 - ) r - ), - 'week_summary', ( - SELECT json_build_object( - 'total_tracks', (SELECT COUNT(*) FROM week_tracks), - 'total_artists', (SELECT COUNT(*) FROM week_artists), - 'total_albums', (SELECT COUNT(*) FROM week_albums) +SELECT + json_build_object( + 'week_artists', + ( + SELECT + json_agg( + a + ORDER BY + a.plays DESC + ) + FROM + ( + SELECT + * + FROM + week_artists + ORDER BY + plays DESC + LIMIT + 8 + ) a + ), + 'week_albums', + ( + SELECT + json_agg( + al + ORDER BY + al.plays DESC + ) + FROM + ( + SELECT + * + FROM + week_albums + ORDER BY + plays DESC + LIMIT + 8 + ) al + ), + 'week_genres', + ( + SELECT + json_agg( + g + ORDER BY + g.plays DESC + ) + FROM + ( + SELECT + * + FROM + week_genres + ORDER BY + plays DESC + LIMIT + 5 + ) g + ), + 'recent_tracks', + ( + SELECT + json_agg( + r + ORDER BY + r.listened_at DESC + ) + FROM + ( + SELECT + * + FROM + recent_tracks + ORDER BY + listened_at DESC + LIMIT + 10 + ) r + ), + 'week_summary', + ( + SELECT + json_build_object( + 'total_tracks', + ( + SELECT + COUNT(*) + FROM + week_tracks + ), + 'total_artists', + ( + SELECT + COUNT(*) + FROM + week_artists + ), + 'total_albums', + ( + SELECT + COUNT(*) + FROM + week_albums + ) + ) ) - ) -) AS week_music; + ) AS week_music; diff --git a/queries/views/media/music/week/tracks.sql b/queries/views/media/music/week/tracks.sql index 3359c70..e4d0ab0 100644 --- a/queries/views/media/music/week/tracks.sql +++ b/queries/views/media/music/week/tracks.sql @@ -1,26 +1,31 @@ CREATE OR REPLACE VIEW week_tracks AS -WITH track_stats AS ( - SELECT - ol.track_name, - ol.artist_name, - ol.album_name, - COUNT(*) AS plays, - MAX(ol.listened_at) AS last_listened, - ol.album_art, - ol.artist_url, - MAX(COUNT(*)) OVER () AS most_played, - RANK() OVER (ORDER BY COUNT(*) DESC, MAX(ol.listened_at) DESC) AS rank - FROM - optimized_listens ol - WHERE - TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days' - GROUP BY - ol.track_name, - ol.artist_name, - ol.album_name, - ol.album_art, - ol.artist_url -) +WITH + track_stats AS ( + SELECT + ol.track_name, + ol.artist_name, + ol.album_name, + COUNT(*) AS plays, + MAX(ol.listened_at) AS last_listened, + ol.album_art, + ol.artist_url, + MAX(COUNT(*)) OVER () AS most_played, + RANK() OVER ( + ORDER BY + COUNT(*) DESC, + MAX(ol.listened_at) DESC + ) AS rank + FROM + optimized_listens ol + WHERE + TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days' + GROUP BY + ol.track_name, + ol.artist_name, + ol.album_name, + ol.album_art, + ol.artist_url + ) SELECT track_name, artist_name, @@ -30,14 +35,22 @@ SELECT album_art, artist_url, json_build_object( - 'title', track_name, - 'artist', artist_name, - 'url', artist_url, - 'plays', plays, - 'alt', CONCAT(track_name, ' by ', artist_name), - 'subtext', CONCAT(album_name, ' (', plays, ' plays)'), - 'percentage', ROUND((plays::decimal / most_played) * 100, 2), - 'rank', rank + 'title', + track_name, + 'artist', + artist_name, + 'url', + artist_url, + 'plays', + plays, + 'alt', + CONCAT(track_name, ' by ', artist_name), + 'subtext', + CONCAT(album_name, ' (', plays, ' plays)'), + 'percentage', + ROUND((plays::decimal / most_played) * 100, 2), + 'rank', + rank ) AS chart FROM track_stats diff --git a/queries/views/media/recent_media.sql b/queries/views/media/recent_media.sql index 2aea76e..de06e65 100644 --- a/queries/views/media/recent_media.sql +++ b/queries/views/media/recent_media.sql @@ -1,248 +1,383 @@ CREATE OR REPLACE VIEW optimized_recent_media AS -WITH ordered_artists AS ( - SELECT - wa.artist_name, - wa.artist_art, - wa.artist_url, - wa.plays, - json_build_object( - 'title', wa.artist_name, - 'image', wa.artist_art, - 'url', wa.artist_url, - 'alt', CONCAT(wa.plays, ' plays of ', wa.artist_name), - 'subtext', CONCAT(wa.plays, ' plays') - ) AS grid - FROM week_artists wa - ORDER BY wa.plays DESC, wa.artist_name ASC -), -ordered_albums AS ( - SELECT - wa.album_name, - wa.album_art, - wa.artist_name, - wa.artist_url, - wa.plays, - json_build_object( - 'title', wa.album_name, - 'image', wa.album_art, - 'url', wa.artist_url, - 'alt', CONCAT(wa.album_name, ' by ', wa.artist_name, ' (', wa.plays, ' plays)'), - 'subtext', wa.artist_name - ) AS grid - FROM week_albums wa - ORDER BY wa.plays DESC, wa.album_name ASC -), -recent_music AS ( - SELECT * FROM ( - ( - SELECT - artist_name AS title, - artist_art AS image, - artist_url AS url, - 'music' AS type, - 1 AS rank, - grid - FROM ordered_artists - LIMIT 1 - ) - UNION ALL - ( - SELECT - album_name AS title, - album_art AS image, - artist_url AS url, - 'music' AS type, - 2 AS rank, - grid - FROM ordered_albums - LIMIT 1 - ) - UNION ALL - ( - SELECT - artist_name AS title, - artist_art AS image, - artist_url AS url, - 'music' AS type, - 3 AS rank, - grid - FROM ordered_artists - OFFSET 1 LIMIT 1 - ) - UNION ALL - ( - SELECT - album_name AS title, - album_art AS image, - artist_url AS url, - 'music' AS type, - 4 AS rank, - grid - FROM ordered_albums - OFFSET 1 LIMIT 1 - ) - ) AS recent_music_subquery -), -recent_watched_read AS ( - SELECT * FROM ( - ( - SELECT - om.title, - om.image, - om.url, - 'tv' AS type, - 1 AS rank, - json_build_object( - 'title', NULL, - 'url', om.url, - 'image', om.image, - 'backdrop', om.backdrop, - 'alt', CONCAT('Poster from ', om.title, ' (', om.year, ')'), - 'subtext', CASE WHEN om.rating IS NOT NULL THEN - om.rating::text - ELSE - om.year::text - END - ) AS grid - FROM optimized_movies om - WHERE om.last_watched IS NOT NULL - ORDER BY om.last_watched DESC, om.title ASC - LIMIT 1 - ) - UNION ALL - ( - SELECT - os.title, - os.image, - os.url, - 'tv' AS type, - 2 AS rank, - json_build_object( - 'title', NULL, - 'image', os.image, - 'url', os.url, - 'alt', CONCAT('Poster from ', os.title), - 'subtext', ( - SELECT CONCAT('S', e.season_number, 'E', e.episode_number) - FROM episodes e - WHERE e.show = os.id - ORDER BY e.last_watched_at DESC, e.season_number DESC, e.episode_number DESC - LIMIT 1 - ) - ) AS grid - FROM optimized_shows os - WHERE os.last_watched_at IS NOT NULL - ORDER BY os.last_watched_at DESC, os.title ASC - LIMIT 1 - ) - UNION ALL - ( - SELECT - ob.title, - ob.image, - ob.url, - 'books' AS type, - 3 AS rank, - json_build_object( - 'title', NULL, - 'image', ob.image, - 'url', ob.url, - 'alt', CONCAT('Book cover from ', ob.title, ' by ', ob.author), - 'subtext', CASE WHEN ob.rating IS NOT NULL THEN - ob.rating - ELSE - NULL - END - ) AS grid - FROM optimized_books ob - WHERE ob.status = 'finished' - ORDER BY ob.date_finished DESC, ob.title ASC - LIMIT 1 - ) - UNION ALL - ( - SELECT - om.title, - om.image, - om.url, - 'tv' AS type, - 4 AS rank, - json_build_object( - 'title', NULL, - 'url', om.url, - 'image', om.image, - 'backdrop', om.backdrop, - 'alt', CONCAT('Poster from ', om.title, ' (', om.year, ')'), - 'subtext', CASE WHEN om.rating IS NOT NULL THEN - om.rating::text - ELSE - om.year::text - END - ) AS grid - FROM optimized_movies om - WHERE om.last_watched IS NOT NULL - ORDER BY om.last_watched DESC, om.title ASC - OFFSET 1 LIMIT 1 - ) - UNION ALL - ( - SELECT - os.title, - os.image, - os.url, - 'tv' AS type, - 5 AS rank, - json_build_object( - 'title', NULL, - 'image', os.image, - 'url', os.url, - 'alt', CONCAT('Poster from ', os.title), - 'subtext', ( - SELECT CONCAT('S', e.season_number, 'E', e.episode_number) - FROM episodes e - WHERE e.show = os.id - ORDER BY e.last_watched_at DESC, e.season_number DESC, e.episode_number DESC - LIMIT 1 - ) - ) AS grid - FROM optimized_shows os - WHERE os.last_watched_at IS NOT NULL - ORDER BY os.last_watched_at DESC, os.title ASC - OFFSET 1 LIMIT 1 - ) - UNION ALL - ( - SELECT - ob.title, - ob.image, - ob.url, - 'books' AS type, - 6 AS rank, - json_build_object( - 'title', NULL, - 'image', ob.image, - 'url', ob.url, - 'alt', CONCAT('Book cover from ', ob.title, ' by ', ob.author), - 'subtext', CASE WHEN ob.rating IS NOT NULL THEN - ob.rating - ELSE - NULL - END - ) AS grid - FROM optimized_books ob - WHERE ob.status = 'finished' - ORDER BY ob.date_finished DESC, ob.title ASC - OFFSET 1 LIMIT 1 - ) - ) AS recent_watched_read_subquery -) -SELECT json_build_object( - 'recentMusic', ( - SELECT json_agg(m.* ORDER BY m.rank) - FROM recent_music m +WITH + ordered_artists AS ( + SELECT + wa.artist_name, + wa.artist_art, + wa.artist_url, + wa.plays, + json_build_object( + 'title', + wa.artist_name, + 'image', + wa.artist_art, + 'url', + wa.artist_url, + 'alt', + CONCAT(wa.plays, ' plays of ', wa.artist_name), + 'subtext', + CONCAT(wa.plays, ' plays') + ) AS grid + FROM + week_artists wa + ORDER BY + wa.plays DESC, + wa.artist_name ASC ), - 'recentWatchedRead', ( - SELECT json_agg(w.* ORDER BY w.rank) - FROM recent_watched_read w + ordered_albums AS ( + SELECT + wa.album_name, + wa.album_art, + wa.artist_name, + wa.artist_url, + wa.plays, + json_build_object( + 'title', + wa.album_name, + 'image', + wa.album_art, + 'url', + wa.artist_url, + 'alt', + CONCAT( + wa.album_name, + ' by ', + wa.artist_name, + ' (', + wa.plays, + ' plays)' + ), + 'subtext', + wa.artist_name + ) AS grid + FROM + week_albums wa + ORDER BY + wa.plays DESC, + wa.album_name ASC + ), + recent_music AS ( + SELECT + * + FROM + ( + ( + SELECT + artist_name AS title, + artist_art AS image, + artist_url AS url, + 'music' AS type, + 1 AS rank, + grid + FROM + ordered_artists + LIMIT + 1 + ) + UNION ALL + ( + SELECT + album_name AS title, + album_art AS image, + artist_url AS url, + 'music' AS type, + 2 AS rank, + grid + FROM + ordered_albums + LIMIT + 1 + ) + UNION ALL + ( + SELECT + artist_name AS title, + artist_art AS image, + artist_url AS url, + 'music' AS type, + 3 AS rank, + grid + FROM + ordered_artists + OFFSET + 1 + LIMIT + 1 + ) + UNION ALL + ( + SELECT + album_name AS title, + album_art AS image, + artist_url AS url, + 'music' AS type, + 4 AS rank, + grid + FROM + ordered_albums + OFFSET + 1 + LIMIT + 1 + ) + ) AS recent_music_subquery + ), + recent_watched_read AS ( + SELECT + * + FROM + ( + ( + SELECT + om.title, + om.image, + om.url, + 'tv' AS type, + 1 AS rank, + json_build_object( + 'title', + NULL, + 'url', + om.url, + 'image', + om.image, + 'backdrop', + om.backdrop, + 'alt', + CONCAT('Poster from ', om.title, ' (', om.year, ')'), + 'subtext', + CASE + WHEN om.rating IS NOT NULL THEN om.rating::text + ELSE om.year::text + END + ) AS grid + FROM + optimized_movies om + WHERE + om.last_watched IS NOT NULL + ORDER BY + om.last_watched DESC, + om.title ASC + LIMIT + 1 + ) + UNION ALL + ( + SELECT + os.title, + os.image, + os.url, + 'tv' AS type, + 2 AS rank, + json_build_object( + 'title', + NULL, + 'image', + os.image, + 'url', + os.url, + 'alt', + CONCAT('Poster from ', os.title), + 'subtext', + ( + SELECT + CONCAT('S', e.season_number, 'E', e.episode_number) + FROM + episodes e + WHERE + e.show = os.id + ORDER BY + e.last_watched_at DESC, + e.season_number DESC, + e.episode_number DESC + LIMIT + 1 + ) + ) AS grid + FROM + optimized_shows os + WHERE + os.last_watched_at IS NOT NULL + ORDER BY + os.last_watched_at DESC, + os.title ASC + LIMIT + 1 + ) + UNION ALL + ( + SELECT + ob.title, + ob.image, + ob.url, + 'books' AS type, + 3 AS rank, + json_build_object( + 'title', + NULL, + 'image', + ob.image, + 'url', + ob.url, + 'alt', + CONCAT('Book cover from ', ob.title, ' by ', ob.author), + 'subtext', + CASE + WHEN ob.rating IS NOT NULL THEN ob.rating + ELSE NULL + END + ) AS grid + FROM + optimized_books ob + WHERE + ob.status = 'finished' + ORDER BY + ob.date_finished DESC, + ob.title ASC + LIMIT + 1 + ) + UNION ALL + ( + SELECT + om.title, + om.image, + om.url, + 'tv' AS type, + 4 AS rank, + json_build_object( + 'title', + NULL, + 'url', + om.url, + 'image', + om.image, + 'backdrop', + om.backdrop, + 'alt', + CONCAT('Poster from ', om.title, ' (', om.year, ')'), + 'subtext', + CASE + WHEN om.rating IS NOT NULL THEN om.rating::text + ELSE om.year::text + END + ) AS grid + FROM + optimized_movies om + WHERE + om.last_watched IS NOT NULL + ORDER BY + om.last_watched DESC, + om.title ASC + OFFSET + 1 + LIMIT + 1 + ) + UNION ALL + ( + SELECT + os.title, + os.image, + os.url, + 'tv' AS type, + 5 AS rank, + json_build_object( + 'title', + NULL, + 'image', + os.image, + 'url', + os.url, + 'alt', + CONCAT('Poster from ', os.title), + 'subtext', + ( + SELECT + CONCAT('S', e.season_number, 'E', e.episode_number) + FROM + episodes e + WHERE + e.show = os.id + ORDER BY + e.last_watched_at DESC, + e.season_number DESC, + e.episode_number DESC + LIMIT + 1 + ) + ) AS grid + FROM + optimized_shows os + WHERE + os.last_watched_at IS NOT NULL + ORDER BY + os.last_watched_at DESC, + os.title ASC + OFFSET + 1 + LIMIT + 1 + ) + UNION ALL + ( + SELECT + ob.title, + ob.image, + ob.url, + 'books' AS type, + 6 AS rank, + json_build_object( + 'title', + NULL, + 'image', + ob.image, + 'url', + ob.url, + 'alt', + CONCAT('Book cover from ', ob.title, ' by ', ob.author), + 'subtext', + CASE + WHEN ob.rating IS NOT NULL THEN ob.rating + ELSE NULL + END + ) AS grid + FROM + optimized_books ob + WHERE + ob.status = 'finished' + ORDER BY + ob.date_finished DESC, + ob.title ASC + OFFSET + 1 + LIMIT + 1 + ) + ) AS recent_watched_read_subquery ) -) AS recent_activity; +SELECT + json_build_object( + 'recentMusic', + ( + SELECT + json_agg( + m.* + ORDER BY + m.rank + ) + FROM + recent_music m + ), + 'recentWatchedRead', + ( + SELECT + json_agg( + w.* + ORDER BY + w.rank + ) + FROM + recent_watched_read w + ) + ) AS recent_activity; diff --git a/queries/views/media/shows/last_watched_episodes.sql b/queries/views/media/shows/last_watched_episodes.sql index db0b91d..85ee0d9 100644 --- a/queries/views/media/shows/last_watched_episodes.sql +++ b/queries/views/media/shows/last_watched_episodes.sql @@ -1,10 +1,14 @@ CREATE OR REPLACE VIEW optimized_last_watched_episodes AS -SELECT DISTINCT ON (e.show) - e.show AS show_id, +SELECT DISTINCT + ON (e.show) e.show AS show_id, e.season_number, e.episode_number, e.last_watched_at, CONCAT('S', e.season_number, 'E', e.episode_number) AS last_watched_episode -FROM episodes e -WHERE e.last_watched_at IS NOT NULL -ORDER BY e.show, e.last_watched_at DESC; +FROM + episodes e +WHERE + e.last_watched_at IS NOT NULL +ORDER BY + e.show, + e.last_watched_at DESC; diff --git a/queries/views/media/shows/scheduled_episodes.sql b/queries/views/media/shows/scheduled_episodes.sql index c74f8ca..8fd5ac4 100644 --- a/queries/views/media/shows/scheduled_episodes.sql +++ b/queries/views/media/shows/scheduled_episodes.sql @@ -6,21 +6,38 @@ SELECT se.status, se.air_date, ( - SELECT CONCAT('S', se2.season_number, 'E', se2.episode_number) - FROM scheduled_episodes se2 - WHERE se2.show_id = se.show_id + SELECT + CONCAT('S', se2.season_number, 'E', se2.episode_number) + FROM + scheduled_episodes se2 + WHERE + se2.show_id = se.show_id AND se2.status IN ('upcoming', 'aired') - ORDER BY se2.air_date ASC - LIMIT 1 + ORDER BY + se2.air_date ASC + LIMIT + 1 ) AS next_scheduled_episode, ( - SELECT se2.air_date - FROM scheduled_episodes se2 - WHERE se2.show_id = se.show_id + SELECT + se2.air_date + FROM + scheduled_episodes se2 + WHERE + se2.show_id = se.show_id AND se2.status IN ('upcoming', 'aired') - ORDER BY se2.air_date ASC - LIMIT 1 + ORDER BY + se2.air_date ASC + LIMIT + 1 ) AS next_air_date -FROM scheduled_episodes se -WHERE se.status IN ('upcoming', 'aired') -GROUP BY se.show_id, se.season_number, se.episode_number, se.status, se.air_date; +FROM + scheduled_episodes se +WHERE + se.status IN ('upcoming', 'aired') +GROUP BY + se.show_id, + se.season_number, + se.episode_number, + se.status, + se.air_date; diff --git a/queries/views/media/shows/scheduled_shows.sql b/queries/views/media/shows/scheduled_shows.sql index 3bd751f..fa58de1 100644 --- a/queries/views/media/shows/scheduled_shows.sql +++ b/queries/views/media/shows/scheduled_shows.sql @@ -1,207 +1,354 @@ CREATE OR REPLACE VIEW optimized_scheduled_shows AS -SELECT json_build_object( - 'watching', ( - SELECT json_agg(watching) FROM ( +SELECT + json_build_object( + 'watching', + ( SELECT - s.id, - s.tmdb_id, - s.title, - s.year, - s.ongoing, - s.slug AS url, - CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image, - CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop, - json_build_object( - 'title', s.title, - 'image', CONCAT(globals.cdn_url, '/', df_art.filename_disk), - 'backdrop', CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), - 'url', s.slug, - 'alt', CONCAT('Poster from ', s.title), - 'subtext', COALESCE( - (SELECT CONCAT( - 'S', se.season_number, 'E', se.episode_number, ' • ', - CASE - WHEN EXTRACT(YEAR FROM se.air_date) < EXTRACT(YEAR FROM CURRENT_DATE) - THEN TO_CHAR(se.air_date, 'FMMM/FMDD/YY') - ELSE TO_CHAR(se.air_date, 'FMMM/FMDD') - END - ) - FROM scheduled_episodes se - WHERE se.show_id = s.id - AND se.status IN ('upcoming', 'aired') - AND NOT EXISTS ( - SELECT 1 FROM episodes e - WHERE e.show = s.id - AND e.season_number = se.season_number - AND e.episode_number = se.episode_number + json_agg(watching) + FROM + ( + SELECT + s.id, + s.tmdb_id, + s.title, + s.year, + s.ongoing, + s.slug AS url, + CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image, + CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop, + json_build_object( + 'title', + s.title, + 'image', + CONCAT(globals.cdn_url, '/', df_art.filename_disk), + 'backdrop', + CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), + 'url', + s.slug, + 'alt', + CONCAT('Poster from ', s.title), + 'subtext', + COALESCE( + ( + SELECT + CONCAT( + 'S', + se.season_number, + 'E', + se.episode_number, + ' • ', + CASE + WHEN EXTRACT( + YEAR + FROM + se.air_date + ) < EXTRACT( + YEAR + FROM + CURRENT_DATE + ) THEN TO_CHAR(se.air_date, 'FMMM/FMDD/YY') + ELSE TO_CHAR(se.air_date, 'FMMM/FMDD') + END + ) + FROM + scheduled_episodes se + WHERE + se.show_id = s.id + AND se.status IN ('upcoming', 'aired') + AND NOT EXISTS ( + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id + AND e.season_number = se.season_number + AND e.episode_number = se.episode_number + ) + ORDER BY + se.season_number ASC, + se.episode_number ASC + LIMIT + 1 + ), + ( + SELECT + CONCAT( + 'S', + e.season_number, + 'E', + e.episode_number, + ' • ', + CASE + WHEN EXTRACT( + YEAR + FROM + e.last_watched_at + ) < EXTRACT( + YEAR + FROM + CURRENT_DATE + ) THEN TO_CHAR(e.last_watched_at, 'FMMM/FMDD/YY') + ELSE TO_CHAR(e.last_watched_at, 'FMMM/FMDD') + END + ) + FROM + episodes e + WHERE + e.show = s.id + ORDER BY + e.last_watched_at DESC, + e.season_number DESC, + e.episode_number DESC + LIMIT + 1 + ), + s.year::text ) - ORDER BY se.season_number ASC, se.episode_number ASC - LIMIT 1), - (SELECT CONCAT( - 'S', e.season_number, 'E', e.episode_number, ' • ', - CASE - WHEN EXTRACT(YEAR FROM e.last_watched_at) < EXTRACT(YEAR FROM CURRENT_DATE) - THEN TO_CHAR(e.last_watched_at, 'FMMM/FMDD/YY') - ELSE TO_CHAR(e.last_watched_at, 'FMMM/FMDD') - END - ) - FROM episodes e - WHERE e.show = s.id - ORDER BY e.last_watched_at DESC, e.season_number DESC, e.episode_number DESC - LIMIT 1), - s.year::text - ) - ) AS grid, - json_build_object( - 'title', CONCAT('Show • ', s.title, ' • ', globals.site_name), - 'description', LEFT( - regexp_replace( - regexp_replace( - regexp_replace(s.description, E'[*_`~#>-]', '', 'g'), - E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' + ) AS grid, + json_build_object( + 'title', + CONCAT('Show • ', s.title, ' • ', globals.site_name), + 'description', + LEFT( + regexp_replace( + regexp_replace( + regexp_replace(s.description, E'[*_`~#>-]', '', 'g'), + E'\\[(.*?)\\]\\((.*?)\\)', + E'\\1', + 'g' + ), + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' + ), + 250 ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' - ), - 250 - ), - 'open_graph_image', CASE - WHEN df_backdrop.filename_disk IS NOT NULL AND df_backdrop.filename_disk != '' AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) - ELSE NULL - END, - 'url', CONCAT(globals.url, s.slug), - 'type', 'scheduled_show' - ) AS metadata, - CASE - WHEN ( - SELECT se.air_date - FROM scheduled_episodes se - WHERE se.show_id = s.id - AND se.status IN ('upcoming', 'aired') - AND NOT EXISTS ( - SELECT 1 FROM episodes e - WHERE e.show = s.id - AND e.season_number = se.season_number - AND e.episode_number = se.episode_number + 'open_graph_image', + CASE + WHEN df_backdrop.filename_disk IS NOT NULL + AND df_backdrop.filename_disk != '' + AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) + ELSE NULL + END, + 'url', + CONCAT(globals.url, s.slug), + 'type', + 'scheduled_show' + ) AS metadata, + CASE + WHEN ( + SELECT + se.air_date + FROM + scheduled_episodes se + WHERE + se.show_id = s.id + AND se.status IN ('upcoming', 'aired') + AND NOT EXISTS ( + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id + AND e.season_number = se.season_number + AND e.episode_number = se.episode_number + ) + ORDER BY + se.season_number ASC, + se.episode_number ASC + LIMIT + 1 + ) >= NOW() THEN ( + SELECT + se.air_date::timestamp + FROM + scheduled_episodes se + WHERE + se.show_id = s.id + AND se.status IN ('upcoming', 'aired') + AND NOT EXISTS ( + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id + AND e.season_number = se.season_number + AND e.episode_number = se.episode_number + ) + ORDER BY + se.season_number ASC, + se.episode_number ASC + LIMIT + 1 ) - ORDER BY se.season_number ASC, se.episode_number ASC - LIMIT 1 - ) >= NOW() - THEN ( - SELECT se.air_date::timestamp - FROM scheduled_episodes se - WHERE se.show_id = s.id - AND se.status IN ('upcoming', 'aired') - AND NOT EXISTS ( - SELECT 1 FROM episodes e - WHERE e.show = s.id - AND e.season_number = se.season_number - AND e.episode_number = se.episode_number + ELSE ( + SELECT + MIN(e.last_watched_at)::timestamp + FROM + episodes e + WHERE + e.show = s.id ) - ORDER BY se.season_number ASC, se.episode_number ASC - LIMIT 1 - ) - ELSE ( - SELECT MIN(e.last_watched_at)::timestamp - FROM episodes e - WHERE e.show = s.id - ) - END AS sort_date - FROM shows s - LEFT JOIN directus_files df_art ON s.art = df_art.id - LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id - CROSS JOIN optimized_globals globals - WHERE s.ongoing = true - AND EXISTS ( - SELECT 1 - FROM scheduled_episodes se - WHERE se.show_id = s.id - AND se.status IN ('upcoming', 'aired') - ) - AND EXISTS ( - SELECT 1 - FROM episodes e - WHERE e.show = s.id - ) - ORDER BY sort_date ASC NULLS LAST, s.title ASC NULLS LAST - ) watching - ), - 'unstarted', ( - SELECT json_agg(unstarted) FROM ( - SELECT - s.id, - s.tmdb_id, - s.title, - s.year, - s.ongoing, - s.slug AS url, - CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image, - CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop, - json_build_object( - 'title', s.title, - 'image', CONCAT(globals.cdn_url, '/', df_art.filename_disk), - 'backdrop', CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), - 'url', s.slug, - 'alt', CONCAT('Poster from ', s.title), - 'subtext', COALESCE( - ( - SELECT CONCAT( - 'S', se.season_number, 'E', se.episode_number, ' • ', - CASE - WHEN EXTRACT(YEAR FROM se.air_date) < EXTRACT(YEAR FROM CURRENT_DATE) - THEN TO_CHAR(se.air_date, 'FMMM/FMDD/YY') - ELSE TO_CHAR(se.air_date, 'FMMM/FMDD') - END - ) - FROM scheduled_episodes se - WHERE se.show_id = s.id + END AS sort_date + FROM + shows s + LEFT JOIN directus_files df_art ON s.art = df_art.id + LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id + CROSS JOIN optimized_globals globals + WHERE + s.ongoing = true + AND EXISTS ( + SELECT + 1 + FROM + scheduled_episodes se + WHERE + se.show_id = s.id AND se.status IN ('upcoming', 'aired') - ORDER BY se.season_number ASC, se.episode_number ASC - LIMIT 1 - ), - s.year::text - ) - ) AS grid, - json_build_object( - 'title', CONCAT('Show • ', s.title, ' • ', globals.site_name), - 'description', LEFT( - regexp_replace( - regexp_replace( - regexp_replace(s.description, E'[*_`~#>-]', '', 'g'), - E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' + ) + AND EXISTS ( + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id + ) + ORDER BY + sort_date ASC NULLS LAST, + s.title ASC NULLS LAST + ) watching + ), + 'unstarted', + ( + SELECT + json_agg(unstarted) + FROM + ( + SELECT + s.id, + s.tmdb_id, + s.title, + s.year, + s.ongoing, + s.slug AS url, + CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image, + CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop, + json_build_object( + 'title', + s.title, + 'image', + CONCAT(globals.cdn_url, '/', df_art.filename_disk), + 'backdrop', + CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), + 'url', + s.slug, + 'alt', + CONCAT('Poster from ', s.title), + 'subtext', + COALESCE( + ( + SELECT + CONCAT( + 'S', + se.season_number, + 'E', + se.episode_number, + ' • ', + CASE + WHEN EXTRACT( + YEAR + FROM + se.air_date + ) < EXTRACT( + YEAR + FROM + CURRENT_DATE + ) THEN TO_CHAR(se.air_date, 'FMMM/FMDD/YY') + ELSE TO_CHAR(se.air_date, 'FMMM/FMDD') + END + ) + FROM + scheduled_episodes se + WHERE + se.show_id = s.id + AND se.status IN ('upcoming', 'aired') + ORDER BY + se.season_number ASC, + se.episode_number ASC + LIMIT + 1 + ), + s.year::text + ) + ) AS grid, + json_build_object( + 'title', + CONCAT('Show • ', s.title, ' • ', globals.site_name), + 'description', + LEFT( + regexp_replace( + regexp_replace( + regexp_replace(s.description, E'[*_`~#>-]', '', 'g'), + E'\\[(.*?)\\]\\((.*?)\\)', + E'\\1', + 'g' + ), + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' + ), + 250 ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' - ), - 250 - ), - 'open_graph_image', CASE - WHEN df_backdrop.filename_disk IS NOT NULL AND df_backdrop.filename_disk != '' AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) - ELSE NULL - END, - 'url', CONCAT(globals.url, s.slug), - 'type', 'scheduled_show' - ) AS metadata - FROM shows s - LEFT JOIN directus_files df_art ON s.art = df_art.id - LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id - CROSS JOIN optimized_globals globals - WHERE s.ongoing = true - AND EXISTS ( - SELECT 1 - FROM scheduled_episodes se - WHERE se.show_id = s.id - AND se.status IN ('upcoming', 'aired') - ) - AND NOT EXISTS ( - SELECT 1 - FROM episodes e - WHERE e.show = s.id - ) - ORDER BY ( - SELECT MIN(se.air_date) - FROM scheduled_episodes se - WHERE se.show_id = s.id - AND se.status IN ('upcoming', 'aired') - ) ASC NULLS LAST - ) unstarted - ) -) AS scheduled_shows + 'open_graph_image', + CASE + WHEN df_backdrop.filename_disk IS NOT NULL + AND df_backdrop.filename_disk != '' + AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) + ELSE NULL + END, + 'url', + CONCAT(globals.url, s.slug), + 'type', + 'scheduled_show' + ) AS metadata + FROM + shows s + LEFT JOIN directus_files df_art ON s.art = df_art.id + LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id + CROSS JOIN optimized_globals globals + WHERE + s.ongoing = true + AND EXISTS ( + SELECT + 1 + FROM + scheduled_episodes se + WHERE + se.show_id = s.id + AND se.status IN ('upcoming', 'aired') + ) + AND NOT EXISTS ( + SELECT + 1 + FROM + episodes e + WHERE + e.show = s.id + ) + ORDER BY + ( + SELECT + MIN(se.air_date) + FROM + scheduled_episodes se + WHERE + se.show_id = s.id + AND se.status IN ('upcoming', 'aired') + ) ASC NULLS LAST + ) unstarted + ) + ) AS scheduled_shows diff --git a/queries/views/media/shows/shows.sql b/queries/views/media/shows/shows.sql index 1a04389..3413afa 100644 --- a/queries/views/media/shows/shows.sql +++ b/queries/views/media/shows/shows.sql @@ -13,194 +13,355 @@ SELECT CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image, CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop, json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_art.filename_disk), - 'backdrop', CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), - 'url', s.slug, - 'alt', CONCAT('Artwork for ', s.title), - 'subtext', CASE + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_art.filename_disk), + 'backdrop', + CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), + 'url', + s.slug, + 'alt', + CONCAT('Artwork for ', s.title), + 'subtext', + CASE WHEN ( - SELECT MAX(e1.last_watched_at) - FROM episodes e1 - WHERE e1.show = s.id - ) >= NOW() - INTERVAL '90 days' THEN - (SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) - FROM episodes e2 - WHERE e2.show = s.id - ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC - LIMIT 1) + SELECT + MAX(e1.last_watched_at) + FROM + episodes e1 + WHERE + e1.show = s.id + ) >= NOW() - INTERVAL '90 days' THEN ( + SELECT + CONCAT('S', e2.season_number, 'E', e2.episode_number) + FROM + episodes e2 + WHERE + e2.show = s.id + ORDER BY + e2.last_watched_at DESC, + e2.season_number DESC, + e2.episode_number DESC + LIMIT + 1 + ) ELSE s.year::text END, - 'type', 'tv' + 'type', + 'tv' ) AS grid, json_build_object( - 'title', s.title, - 'year', s.year, - 'url', s.slug, - 'image', CONCAT(globals.cdn_url, '/', df_art.filename_disk), - 'backdrop', CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), - 'formatted_episode', COALESCE(( - SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) - FROM episodes e2 - WHERE e2.show = s.id - ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC - LIMIT 1 - ), NULL), - 'last_watched_at', ( - SELECT MAX(e3.last_watched_at) - FROM episodes e3 - WHERE e3.show = s.id + 'title', + s.title, + 'year', + s.year, + 'url', + s.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_art.filename_disk), + 'backdrop', + CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), + 'formatted_episode', + COALESCE( + ( + SELECT + CONCAT('S', e2.season_number, 'E', e2.episode_number) + FROM + episodes e2 + WHERE + e2.show = s.id + ORDER BY + e2.last_watched_at DESC, + e2.season_number DESC, + e2.episode_number DESC + LIMIT + 1 + ), + NULL + ), + 'last_watched_at', + ( + SELECT + MAX(e3.last_watched_at) + FROM + episodes e3 + WHERE + e3.show = s.id ) ) AS episode, ( - SELECT json_agg( - json_build_object( - 'title', m.title, - 'year', m.year, - 'url', m.slug, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), - 'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), - 'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, - 'url', m.slug - ), - 'type', 'movies' + SELECT + json_agg( + json_build_object( + 'title', + m.title, + 'year', + m.year, + 'url', + m.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_movie.filename_disk), + 'alt', + CONCAT('Poster for ', m.title, ' (', m.year, ')'), + 'subtext', + CASE + WHEN m.star_rating IS NOT NULL THEN m.star_rating::text + ELSE m.year::text + END, + 'url', + m.slug + ), + 'type', + 'movies' + ) + ORDER BY + m.year ASC ) - ORDER BY m.year ASC - ) - FROM shows_movies sm - LEFT JOIN movies m ON sm.movies_id = m.id - LEFT JOIN directus_files df_movie ON m.art = df_movie.id - WHERE sm.shows_id = s.id AND m.last_watched IS NOT NULL + FROM + shows_movies sm + LEFT JOIN movies m ON sm.movies_id = m.id + LEFT JOIN directus_files df_movie ON m.art = df_movie.id + WHERE + sm.shows_id = s.id + AND m.last_watched IS NOT NULL ) AS movies, ( - SELECT json_agg( - json_build_object( - 'title', b.title, - 'author', b.author, - 'url', b.slug, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), - 'alt', CONCAT('Cover for ', b.title, ' by ', b.author), - 'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating ELSE NULL END, - 'url', b.slug - ), - 'type', 'books' + SELECT + json_agg( + json_build_object( + 'title', + b.title, + 'author', + b.author, + 'url', + b.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_book.filename_disk), + 'alt', + CONCAT('Cover for ', b.title, ' by ', b.author), + 'subtext', + CASE + WHEN b.star_rating IS NOT NULL THEN b.star_rating + ELSE NULL + END, + 'url', + b.slug + ), + 'type', + 'books' + ) + ORDER BY + b.title ) - ORDER BY b.title - ) - FROM shows_books sb - LEFT JOIN books b ON sb.books_id = b.id - LEFT JOIN directus_files df_book ON b.art = df_book.id - WHERE sb.shows_id = s.id AND LOWER(b.read_status) = 'finished' + FROM + shows_books sb + LEFT JOIN books b ON sb.books_id = b.id + LEFT JOIN directus_files df_book ON b.art = df_book.id + WHERE + sb.shows_id = s.id + AND LOWER(b.read_status) = 'finished' ) AS books, ( - SELECT json_agg(json_build_object('title', p.title, 'date', p.date, 'url', p.slug) ORDER BY p.date DESC) - FROM posts_shows ps - LEFT JOIN posts p ON ps.posts_id = p.id - WHERE ps.shows_id = s.id + SELECT + json_agg( + json_build_object('title', p.title, 'date', p.date, 'url', p.slug) + ORDER BY + p.date DESC + ) + FROM + posts_shows ps + LEFT JOIN posts p ON ps.posts_id = p.id + WHERE + ps.shows_id = s.id ) AS posts, ( - SELECT array_agg(t.name) - FROM shows_tags st - LEFT JOIN tags t ON st.tags_id = t.id - WHERE st.shows_id = s.id + SELECT + array_agg(t.name) + FROM + shows_tags st + LEFT JOIN tags t ON st.tags_id = t.id + WHERE + st.shows_id = s.id ) AS tags, ( - SELECT json_agg( - json_build_object( - 'title', rs.title, - 'year', rs.year, - 'url', rs.slug, - 'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), - 'grid', json_build_object( - 'title', NULL, - 'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), - 'alt', CONCAT('Artwork for ', rs.title), - 'subtext', CASE - WHEN ( - SELECT MAX(e1.last_watched_at) - FROM episodes e1 - WHERE e1.show = rs.id - ) >= NOW() - INTERVAL '90 days' THEN - ( - SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) - FROM episodes e2 - WHERE e2.show = rs.id - ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC - LIMIT 1 + SELECT + json_agg( + json_build_object( + 'title', + rs.title, + 'year', + rs.year, + 'url', + rs.slug, + 'image', + CONCAT(globals.cdn_url, '/', df_related.filename_disk), + 'grid', + json_build_object( + 'title', + NULL, + 'image', + CONCAT(globals.cdn_url, '/', df_related.filename_disk), + 'alt', + CONCAT('Artwork for ', rs.title), + 'subtext', + CASE + WHEN ( + SELECT + MAX(e1.last_watched_at) + FROM + episodes e1 + WHERE + e1.show = rs.id + ) >= NOW() - INTERVAL '90 days' THEN ( + SELECT + CONCAT('S', e2.season_number, 'E', e2.episode_number) + FROM + episodes e2 + WHERE + e2.show = rs.id + ORDER BY + e2.last_watched_at DESC, + e2.season_number DESC, + e2.episode_number DESC + LIMIT + 1 ) - ELSE rs.year::text - END, - 'url', rs.slug - ), - 'type', 'tv' + ELSE rs.year::text + END, + 'url', + rs.slug + ), + 'type', + 'tv' + ) + ORDER BY + rs.year ASC ) - ORDER BY rs.year ASC - ) - FROM related_shows sr - LEFT JOIN shows rs ON sr.related_shows_id = rs.id - LEFT JOIN directus_files df_related ON rs.art = df_related.id - WHERE sr.shows_id = s.id + FROM + related_shows sr + LEFT JOIN shows rs ON sr.related_shows_id = rs.id + LEFT JOIN directus_files df_related ON rs.art = df_related.id + WHERE + sr.shows_id = s.id AND EXISTS ( - SELECT 1 - FROM episodes e - WHERE e.show = rs.id + SELECT + 1 + FROM + episodes e + WHERE + e.show = rs.id AND e.last_watched_at IS NOT NULL ) ) AS related_shows, ( - SELECT json_agg( - json_build_object( - 'name', a.name_string, - 'url', a.slug, - 'country', a.country, - 'total_plays', a.total_plays, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'grid', json_build_object( - 'title', a.name_string, - 'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), - 'alt', CASE WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name_string) ELSE CONCAT('Artwork of ', a.name_string) END, - 'subtext', CASE WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays') ELSE NULL END, - 'url', a.slug - ), - 'type', 'music' + SELECT + json_agg( + json_build_object( + 'name', + a.name_string, + 'url', + a.slug, + 'country', + a.country, + 'total_plays', + a.total_plays, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'grid', + json_build_object( + 'title', + a.name_string, + 'image', + CONCAT(globals.cdn_url, '/', df_artist.filename_disk), + 'alt', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays of ', + a.name_string + ) + ELSE CONCAT('Artwork of ', a.name_string) + END, + 'subtext', + CASE + WHEN a.total_plays > 0 THEN CONCAT( + to_char(a.total_plays, 'FM999,999,999,999'), + ' plays' + ) + ELSE NULL + END, + 'url', + a.slug + ), + 'type', + 'music' + ) + ORDER BY + a.total_plays DESC ) - ORDER BY a.total_plays DESC - ) - FROM shows_artists sa - LEFT JOIN artists a ON sa.artists_id = a.id - LEFT JOIN directus_files df_artist ON a.art = df_artist.id - WHERE sa.shows_id = s.id + FROM + shows_artists sa + LEFT JOIN artists a ON sa.artists_id = a.id + LEFT JOIN directus_files df_artist ON a.art = df_artist.id + WHERE + sa.shows_id = s.id ) AS artists, MAX(e.last_watched_at) AS last_watched_at, json_build_object( - 'title', CONCAT('Show • ', s.title, ' • ', globals.site_name), - 'description', LEFT( + 'title', + CONCAT('Show • ', s.title, ' • ', globals.site_name), + 'description', + LEFT( regexp_replace( regexp_replace( regexp_replace(s.description, E'[*_`~#>-]', '', 'g'), - E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' + E'\\[(.*?)\\]\\((.*?)\\)', + E'\\1', + 'g' ), - E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' + E'!\\[(.*?)\\]\\((.*?)\\)', + '', + 'g' ), 250 ), - 'open_graph_image', CASE - WHEN df_backdrop.filename_disk IS NOT NULL AND df_backdrop.filename_disk != '' AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) + 'open_graph_image', + CASE + WHEN df_backdrop.filename_disk IS NOT NULL + AND df_backdrop.filename_disk != '' + AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) ELSE NULL END, - 'url', CONCAT(globals.url, s.slug), - 'type', 'show' + 'url', + CONCAT(globals.url, s.slug), + 'type', + 'show' ) AS metadata -FROM shows s -LEFT JOIN episodes e ON s.id = e.show -LEFT JOIN directus_files df_art ON s.art = df_art.id -LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id -CROSS JOIN optimized_globals globals -GROUP BY s.id, df_art.filename_disk, df_backdrop.filename_disk, globals.cdn_url, globals.site_name, globals.url -ORDER BY MAX(e.last_watched_at) DESC; +FROM + shows s + LEFT JOIN episodes e ON s.id = e.show + LEFT JOIN directus_files df_art ON s.art = df_art.id + LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id + CROSS JOIN optimized_globals globals +GROUP BY + s.id, + df_art.filename_disk, + df_backdrop.filename_disk, + globals.cdn_url, + globals.site_name, + globals.url +ORDER BY + MAX(e.last_watched_at) DESC;