chore(*.sql): use sql-formatter for sql formatting

This commit is contained in:
Cory Dransfeldt 2025-06-14 17:10:41 -07:00
parent cf1ee4c97f
commit 1d7f13d1f5
No known key found for this signature in database
63 changed files with 4432 additions and 2358 deletions

View file

@ -1 +1,2 @@
npx lint-staged npx lint-staged
npm run format:sql

87
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "coryd.dev", "name": "coryd.dev",
"version": "10.2.4", "version": "10.3.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "coryd.dev", "name": "coryd.dev",
"version": "10.2.4", "version": "10.3.4",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"minisearch": "^7.1.2", "minisearch": "^7.1.2",
@ -34,6 +34,7 @@
"postcss-import-ext-glob": "^2.1.1", "postcss-import-ext-glob": "^2.1.1",
"prettier": "3.5.3", "prettier": "3.5.3",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"sql-formatter": "15.6.4",
"terser": "^5.42.0", "terser": "^5.42.0",
"truncate-html": "^1.2.2" "truncate-html": "^1.2.2"
}, },
@ -1422,6 +1423,13 @@
"node": ">=4" "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": { "node_modules/dom-serializer": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "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": "^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": { "node_modules/no-case": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@ -3930,6 +3968,27 @@
], ],
"license": "MIT" "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": { "node_modules/range-parser": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -4034,6 +4093,16 @@
"url": "https://github.com/sponsors/sindresorhus" "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": { "node_modules/reusify": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
@ -4321,6 +4390,20 @@
"dev": true, "dev": true,
"license": "BSD-3-Clause" "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": { "node_modules/ssri": {
"version": "11.0.0", "version": "11.0.0",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz", "resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz",

View file

@ -1,6 +1,6 @@
{ {
"name": "coryd.dev", "name": "coryd.dev",
"version": "10.2.4", "version": "10.3.4",
"description": "The source for my personal site. Built using 11ty (and other tools).", "description": "The source for my personal site. Built using 11ty (and other tools).",
"type": "module", "type": "module",
"engines": { "engines": {
@ -13,7 +13,8 @@
"php": "export $(grep -v '^#' .env | xargs) && php -d error_reporting=E_ALL^E_DEPRECATED -S localhost:8080 -t dist", "php": "export $(grep -v '^#' .env | xargs) && php -d error_reporting=E_ALL^E_DEPRECATED -S localhost:8080 -t dist",
"build": "eleventy", "build": "eleventy",
"clean": "rimraf dist .cache", "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", "update": "composer update && npm upgrade && npm --prefix cli upgrade && ncu && ncu --cwd cli",
"setup": "sh ./scripts/setup.sh", "setup": "sh ./scripts/setup.sh",
"setup:deploy": "sh ./scripts/setup.sh --deploy", "setup:deploy": "sh ./scripts/setup.sh --deploy",
@ -60,6 +61,7 @@
"postcss-import-ext-glob": "^2.1.1", "postcss-import-ext-glob": "^2.1.1",
"prettier": "3.5.3", "prettier": "3.5.3",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"sql-formatter": "15.6.4",
"terser": "^5.42.0", "terser": "^5.42.0",
"truncate-html": "^1.2.2" "truncate-html": "^1.2.2"
} }

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION get_feed_data(feed_key TEXT) CREATE OR REPLACE FUNCTION get_feed_data (feed_key TEXT) RETURNS JSON AS $$
RETURNS JSON AS $$
DECLARE DECLARE
result JSON; result JSON;
sql_query TEXT; sql_query TEXT;

View file

@ -2,8 +2,7 @@ CREATE OR REPLACE FUNCTION get_tagged_content(
tag_query TEXT, tag_query TEXT,
page_size INTEGER DEFAULT 20, page_size INTEGER DEFAULT 20,
page_offset INTEGER DEFAULT 0 page_offset INTEGER DEFAULT 0
) ) RETURNS TABLE (
RETURNS TABLE (
tag TEXT, tag TEXT,
title TEXT, title TEXT,
url TEXT, url TEXT,

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION get_top_tag_groups() CREATE OR REPLACE FUNCTION get_top_tag_groups () RETURNS JSON AS $$
RETURNS JSON AS $$
BEGIN BEGIN
RETURN json_build_object( RETURN json_build_object(
'tags', ( 'tags', (

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION normalize_country_field(countryField TEXT) CREATE OR REPLACE FUNCTION normalize_country_field (countryField TEXT) RETURNS TEXT AS $$
RETURNS TEXT AS $$
DECLARE DECLARE
delimiters TEXT[] := ARRAY[',', '/', '&', 'and']; delimiters TEXT[] := ARRAY[',', '/', '&', 'and'];
countries TEXT[]; countries TEXT[];

View file

@ -1,7 +1,11 @@
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[]) CREATE FUNCTION search_optimized_index (
RETURNS TABLE( search_query text,
page_size integer,
page_offset integer,
sections text[]
) RETURNS TABLE (
result_id integer, result_id integer,
url text, url text,
title text, title text,
@ -14,8 +18,7 @@ CREATE FUNCTION search_optimized_index(search_query text, page_size integer, pag
total_plays text, total_plays text,
rank real, rank real,
total_count bigint total_count bigint
) ) AS $$
AS $$
BEGIN BEGIN
RETURN QUERY RETURN QUERY
SELECT SELECT
@ -42,5 +45,4 @@ BEGIN
rank DESC rank DESC
LIMIT page_size OFFSET page_offset; LIMIT page_size OFFSET page_offset;
END; END;
$$ $$ LANGUAGE plpgsql;
LANGUAGE plpgsql;

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION slugify(input TEXT) CREATE OR REPLACE FUNCTION slugify (input TEXT) RETURNS TEXT AS $$
RETURNS TEXT AS $$
BEGIN BEGIN
RETURN lower(regexp_replace(unaccent(regexp_replace(input, '[^\w\s-]', '', 'g')), '\s+', '-', 'g')); RETURN lower(regexp_replace(unaccent(regexp_replace(input, '[^\w\s-]', '', 'g')), '\s+', '-', 'g'));
END; END;

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION update_album_key(old_album_key TEXT, new_album_key TEXT) CREATE OR REPLACE FUNCTION update_album_key (old_album_key TEXT, new_album_key TEXT) RETURNS void AS $$
RETURNS void AS $$
BEGIN BEGIN
UPDATE listens UPDATE listens
SET album_key = new_album_key SET album_key = new_album_key

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION update_artist_name(old_artist_name TEXT, new_artist_name TEXT) CREATE OR REPLACE FUNCTION update_artist_name (old_artist_name TEXT, new_artist_name TEXT) RETURNS void AS $$
RETURNS void AS $$
BEGIN BEGIN
UPDATE listens UPDATE listens
SET artist_name = new_artist_name SET artist_name = new_artist_name

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION update_days_read() CREATE OR REPLACE FUNCTION update_days_read () RETURNS TRIGGER AS $$
RETURNS TRIGGER AS $$
DECLARE DECLARE
pacific_today DATE; pacific_today DATE;
last_read DATE; last_read DATE;

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION update_listen_totals() CREATE OR REPLACE FUNCTION update_listen_totals () RETURNS void AS $$
RETURNS void AS $$
BEGIN BEGIN
WITH artist_plays AS ( WITH artist_plays AS (
SELECT artist_name, COUNT(*)::integer AS total_plays SELECT artist_name, COUNT(*)::integer AS total_plays

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION update_scheduled_episode_status() CREATE OR REPLACE FUNCTION update_scheduled_episode_status () RETURNS TRIGGER AS $$
RETURNS TRIGGER AS $$
BEGIN BEGIN
UPDATE scheduled_episodes UPDATE scheduled_episodes
SET status = 'aired' SET status = 'aired'

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION update_scheduled_on_watch() CREATE OR REPLACE FUNCTION update_scheduled_on_watch () RETURNS TRIGGER AS $$
RETURNS TRIGGER AS $$
BEGIN BEGIN
UPDATE scheduled_episodes UPDATE scheduled_episodes
SET status = 'watched' SET status = 'watched'

View file

@ -1,6 +1,8 @@
SELECT cron.schedule( SELECT
cron.schedule (
'0 0 * * *', '0 0 * * *',
$$ UPDATE scheduled_episodes $$ UPDATE scheduled_episodes
SET status = 'aired' SET status = 'aired'
WHERE air_date < CURRENT_DATE WHERE air_date < CURRENT_DATE
AND status = 'upcoming' $$); AND status = 'upcoming' $$
);

View file

@ -5,7 +5,15 @@ SELECT
FROM FROM
optimized_listens l optimized_listens l
WHERE 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.artist_name IS NOT NULL
AND l.album_name IS NOT NULL AND l.album_name IS NOT NULL
GROUP BY GROUP BY
@ -13,4 +21,5 @@ GROUP BY
l.album_name l.album_name
ORDER BY ORDER BY
COUNT(l.id) DESC COUNT(l.id) DESC
LIMIT 10; LIMIT
10;

View file

@ -4,10 +4,19 @@ SELECT
FROM FROM
optimized_listens l optimized_listens l
WHERE 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.artist_name IS NOT NULL
GROUP BY GROUP BY
l.artist_name l.artist_name
ORDER BY ORDER BY
COUNT(l.id) DESC COUNT(l.id) DESC
LIMIT 10; LIMIT
10;

View file

@ -1,17 +1,30 @@
BEGIN BEGIN
UPDATE artists UPDATE artists
SET total_plays = total_plays - 1 SET
WHERE name_string = OLD.artist_name; total_plays = total_plays - 1
WHERE
name_string = OLD.artist_name;
UPDATE albums UPDATE albums
SET total_plays = total_plays - 1 SET
WHERE name = OLD.album_name total_plays = total_plays - 1
WHERE
name = OLD.album_name
AND artist_name = OLD.artist_name; AND artist_name = OLD.artist_name;
UPDATE genres UPDATE genres
SET total_plays = total_plays - 1 SET
WHERE id = ( total_plays = total_plays - 1
SELECT genres WHERE
FROM artists id = (
WHERE name_string = OLD.artist_name SELECT
genres
FROM
artists
WHERE
name_string = OLD.artist_name
); );
RETURN OLD; RETURN OLD;
END; END;

View file

@ -1,4 +1,3 @@
CREATE TRIGGER mark_scheduled_as_watched CREATE TRIGGER mark_scheduled_as_watched
AFTER INSERT ON episodes AFTER INSERT ON episodes FOR EACH ROW
FOR EACH ROW
EXECUTE FUNCTION update_scheduled_on_watch (); EXECUTE FUNCTION update_scheduled_on_watch ();

View file

@ -1,5 +1,10 @@
CREATE TRIGGER trigger_update_days_read CREATE TRIGGER trigger_update_days_read
AFTER UPDATE OF progress ON books AFTER
FOR EACH ROW UPDATE OF progress ON books FOR EACH ROW WHEN (
WHEN (OLD.progress IS DISTINCT FROM NEW.progress AND (NEW.read_status = 'started' OR NEW.read_status = 'finished')) OLD.progress IS DISTINCT FROM NEW.progress
AND (
NEW.read_status = 'started'
OR NEW.read_status = 'finished'
)
)
EXECUTE FUNCTION update_days_read (); EXECUTE FUNCTION update_days_read ();

View file

@ -1,5 +1,4 @@
CREATE OR REPLACE FUNCTION update_scheduled_episode_status() CREATE OR REPLACE FUNCTION update_scheduled_episode_status () RETURNS TRIGGER AS $$
RETURNS TRIGGER AS $$
BEGIN BEGIN
IF NEW.air_date < CURRENT_DATE AND NEW.status = 'upcoming' THEN IF NEW.air_date < CURRENT_DATE AND NEW.status = 'upcoming' THEN
NEW.status := 'aired'; NEW.status := 'aired';

View file

@ -1,17 +1,30 @@
BEGIN BEGIN
UPDATE artists UPDATE artists
SET total_plays = total_plays + 1 SET
WHERE name_string = NEW.artist_name; total_plays = total_plays + 1
WHERE
name_string = NEW.artist_name;
UPDATE albums UPDATE albums
SET total_plays = total_plays + 1 SET
WHERE key = NEW.album_key total_plays = total_plays + 1
WHERE
key = NEW.album_key
AND artist_name = NEW.artist_name; AND artist_name = NEW.artist_name;
UPDATE genres UPDATE genres
SET total_plays = total_plays + 1 SET
WHERE id = ( total_plays = total_plays + 1
SELECT genres WHERE
FROM artists id = (
WHERE name_string = NEW.artist_name SELECT
genres
FROM
artists
WHERE
name_string = NEW.artist_name
); );
RETURN NEW; RETURN NEW;
END; END;

View file

@ -6,6 +6,9 @@ SELECT
json_feed, json_feed,
newsletter, newsletter,
mastodon mastodon
FROM authors FROM
WHERE blogroll = true authors
ORDER BY LOWER(unaccent(name)) ASC; WHERE
blogroll = true
ORDER BY
LOWER(unaccent (name)) ASC;

View file

@ -7,24 +7,45 @@ SELECT
l.link, l.link,
a.mastodon, a.mastodon,
a.name, 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, 'link' AS type,
( (
SELECT array_agg(t.name) SELECT
FROM links_tags lt array_agg(t.name)
FROM
links_tags lt
LEFT JOIN tags t ON lt.tags_id = t.id LEFT JOIN tags t ON lt.tags_id = t.id
WHERE lt.links_id = l.id WHERE
lt.links_id = l.id
) AS tags, ) AS tags,
json_build_object( json_build_object(
'title', CONCAT(l.title, ' via ', a.name), 'title',
'url', l.link, CONCAT(l.title, ' via ', a.name),
'description', l.description, 'url',
'date', l.date l.link,
'description',
l.description,
'date',
l.date
) AS feed ) AS feed
FROM FROM
links l links l
JOIN authors a ON l.author = a.id JOIN authors a ON l.author = a.id
GROUP BY 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 ORDER BY
l.date DESC; l.date DESC;

View file

@ -8,183 +8,367 @@ SELECT
p.featured, p.featured,
p.slug AS url, p.slug AS url,
CASE CASE
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN WHEN df.filename_disk IS NOT NULL
CONCAT(globals.cdn_url, '/', df.filename_disk) AND df.filename_disk != ''
AND df.filename_disk != '/' THEN CONCAT(globals.cdn_url, '/', df.filename_disk)
ELSE NULL ELSE NULL
END AS image, END AS image,
p.image_alt, 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 SELECT
json_agg(
CASE
WHEN pb.collection = 'youtube_player' THEN json_build_object('type', pb.collection, 'url', yp.url) 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 = '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 = '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 = 'npm_banner' THEN json_build_object(
WHEN pb.collection = 'rss_banner' THEN json_build_object('type', pb.collection, 'url', rb.url, 'text', rb.text) 'type',
WHEN pb.collection = 'calendar_banner' THEN json_build_object('type', pb.collection, 'url', cb.url, 'text', cb.text) pb.collection,
WHEN pb.collection = 'hero' THEN json_build_object('type', pb.collection, 'image', CONCAT('/', df_hero.filename_disk), 'alt_text', h.alt_text) '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) WHEN pb.collection = 'markdown' THEN json_build_object('type', pb.collection, 'text', md.text)
ELSE json_build_object('type', pb.collection) ELSE json_build_object('type', pb.collection)
END) END
FROM posts_blocks pb )
LEFT JOIN youtube_player yp ON pb.collection = 'youtube_player' AND yp.id = pb.item::integer FROM
LEFT JOIN forgejo_banner fb ON pb.collection = 'forgejo_banner' AND fb.id = pb.item::integer posts_blocks pb
LEFT JOIN github_banner gb ON pb.collection = 'github_banner' AND gb.id = pb.item::integer LEFT JOIN youtube_player yp ON pb.collection = 'youtube_player'
LEFT JOIN npm_banner nb ON pb.collection = 'npm_banner' AND nb.id = pb.item::integer AND yp.id = pb.item::integer
LEFT JOIN rss_banner rb ON pb.collection = 'rss_banner' AND rb.id = pb.item::integer LEFT JOIN forgejo_banner fb ON pb.collection = 'forgejo_banner'
LEFT JOIN calendar_banner cb ON pb.collection = 'calendar_banner' AND cb.id = pb.item::integer AND fb.id = pb.item::integer
LEFT JOIN hero h ON pb.collection = 'hero' AND h.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 directus_files df_hero ON h.image = df_hero.id
LEFT JOIN markdown md ON pb.collection = 'markdown' AND md.id = pb.item::integer LEFT JOIN markdown md ON pb.collection = 'markdown'
WHERE pb.posts_id = p.id AND md.id = pb.item::integer
WHERE
pb.posts_id = p.id
) AS blocks, ) AS blocks,
( (
SELECT array_agg(t.name) SELECT
FROM posts_tags pt array_agg(t.name)
FROM
posts_tags pt
LEFT JOIN tags t ON pt.tags_id = t.id LEFT JOIN tags t ON pt.tags_id = t.id
WHERE pt.posts_id = p.id WHERE
pt.posts_id = p.id
) AS tags, ) AS tags,
( (
SELECT json_agg(json_build_object('name', g.name, 'url', g.slug) ORDER BY g.name ASC) SELECT
FROM posts_genres gp 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 LEFT JOIN genres g ON gp.genres_id = g.id
WHERE gp.posts_id = p.id WHERE
gp.posts_id = p.id
) AS genres, ) AS genres,
( (
SELECT json_agg(json_build_object( SELECT
'name', a.name_string, json_agg(
'url', a.slug, json_build_object(
'country', a.country, 'name',
'total_plays', a.total_plays, a.name_string,
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), 'url',
'grid', json_build_object( a.slug,
'title', a.name_string, 'country',
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), a.country,
'alt', CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name_string), 'total_plays',
'subtext', CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays'), a.total_plays,
'url', a.slug '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
), ),
'type', 'music' 'subtext',
) ORDER BY a.total_plays DESC) CONCAT(
FROM posts_artists pa 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 artists a ON pa.artists_id = a.id
LEFT JOIN directus_files df_artist ON a.art = df_artist.id LEFT JOIN directus_files df_artist ON a.art = df_artist.id
WHERE pa.posts_id = p.id WHERE
AND a.total_plays IS NOT NULL AND a.total_plays > 0 pa.posts_id = p.id
AND a.total_plays IS NOT NULL
AND a.total_plays > 0
) AS artists, ) AS artists,
( (
SELECT json_agg(json_build_object( SELECT
'title', b.title, json_agg(
'author', b.author, json_build_object(
'url', b.slug, 'title',
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), b.title,
'grid', json_build_object( 'author',
'title', NULL, b.author,
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), 'url',
'alt', CONCAT('Cover for ', b.title, ' by ', b.author), b.slug,
'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating ELSE NULL END, 'image',
'url', b.slug 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' 'type',
) ORDER BY b.title ASC) 'books'
FROM posts_books pbk )
ORDER BY
b.title ASC
)
FROM
posts_books pbk
LEFT JOIN books b ON pbk.books_id = b.id LEFT JOIN books b ON pbk.books_id = b.id
LEFT JOIN directus_files df_book ON b.art = df_book.id LEFT JOIN directus_files df_book ON b.art = df_book.id
WHERE pbk.posts_id = p.id WHERE
pbk.posts_id = p.id
AND LOWER(b.read_status) = 'finished' AND LOWER(b.read_status) = 'finished'
) AS books, ) AS books,
( (
SELECT json_agg(json_build_object( SELECT
'title', m.title, json_agg(
'year', m.year, json_build_object(
'url', m.slug, 'title',
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), m.title,
'grid', json_build_object( 'year',
'title', NULL, m.year,
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), 'url',
'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), m.slug,
'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, 'image',
'url', m.slug 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' 'type',
) ORDER BY m.year ASC) 'movies'
FROM posts_movies pm )
ORDER BY
m.year ASC
)
FROM
posts_movies pm
LEFT JOIN movies m ON pm.movies_id = m.id LEFT JOIN movies m ON pm.movies_id = m.id
LEFT JOIN directus_files df_movie ON m.art = df_movie.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 WHERE
pm.posts_id = p.id
AND m.last_watched IS NOT NULL
) AS movies, ) AS movies,
( (
SELECT json_agg(json_build_object( SELECT
'title', s.title, json_agg(
'year', s.year, json_build_object(
'url', s.slug, 'title',
'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), s.title,
'grid', json_build_object( 'year',
'title', NULL, s.year,
'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), 'url',
'alt', CONCAT('Artwork for ', s.title), s.slug,
'subtext', CASE '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 ( WHEN (
SELECT MAX(e1.last_watched_at) SELECT
FROM episodes e1 MAX(e1.last_watched_at)
WHERE e1.show = s.id FROM
) >= NOW() - INTERVAL '90 days' THEN episodes e1
( WHERE
SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) e1.show = s.id
FROM episodes e2 ) >= NOW() - INTERVAL '90 days' THEN (
WHERE e2.show = s.id SELECT
ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC CONCAT('S', e2.season_number, 'E', e2.episode_number)
LIMIT 1 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 ELSE s.year::text
END, END,
'url', s.slug 'url',
s.slug
), ),
'type', 'tv' 'type',
) ORDER BY s.year ASC) 'tv'
FROM posts_shows ps )
ORDER BY
s.year ASC
)
FROM
posts_shows ps
LEFT JOIN shows s ON ps.shows_id = s.id LEFT JOIN shows s ON ps.shows_id = s.id
LEFT JOIN directus_files df_show ON s.art = df_show.id LEFT JOIN directus_files df_show ON s.art = df_show.id
WHERE ps.posts_id = p.id WHERE
ps.posts_id = p.id
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT
FROM episodes e 1
WHERE e.show = s.id FROM
episodes e
WHERE
e.show = s.id
AND e.last_watched_at IS NOT NULL AND e.last_watched_at IS NOT NULL
) )
) AS shows, ) AS shows,
json_build_object( json_build_object(
'title', p.title, 'title',
'url', p.slug, p.title,
'description', p.description, 'url',
'content', p.content, p.slug,
'date', p.date, 'description',
'image', CASE p.description,
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CONCAT(globals.cdn_url, '/', df.filename_disk) '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 ELSE NULL
END END
) AS feed, ) AS feed,
json_build_object( json_build_object(
'title', p.title, 'title',
'description', LEFT( p.title,
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace(p.description, E'[*_`~#>-]', '', 'g'), regexp_replace(p.description, E'[*_`~#>-]', '', 'g'),
E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' E'\\[(.*?)\\]\\((.*?)\\)',
E'\\1',
'g'
), ),
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
'',
'g'
), ),
250 250
), ),
'open_graph_image', CASE 'open_graph_image',
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CASE
CONCAT('/', df.filename_disk) 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' ELSE globals.metadata ->> 'open_graph_image'
END, END,
'url', CONCAT(globals.url, p.slug), 'url',
'type', 'article' CONCAT(globals.url, p.slug),
'type',
'article'
) AS metadata ) AS metadata
FROM posts p FROM
posts p
LEFT JOIN directus_files df ON p.image = df.id LEFT JOIN directus_files df ON p.image = df.id
CROSS JOIN optimized_globals globals 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'; GROUP BY
p.id,
df.filename_disk,
globals.cdn_url,
globals.site_name,
globals.url,
globals.metadata ->> 'open_graph_image';

View file

@ -1,65 +1,117 @@
CREATE OR REPLACE VIEW optimized_all_activity AS CREATE OR REPLACE VIEW optimized_all_activity AS
WITH feed_data AS ( WITH
SELECT json_build_object( feed_data AS (
'title', p.title, SELECT
'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
json_build_object( json_build_object(
'title', CONCAT(b.title, ' by ', b.author, 'title',
CASE WHEN b.rating IS NOT NULL THEN CONCAT(' (', b.rating, ')') ELSE '' END 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 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, 'url',
'description', COALESCE(b.review, b.description), b.url,
'date', b.date_finished, 'description',
'type', 'books', COALESCE(b.review, b.description),
'label', 'Book', 'date',
'image', b.image, b.date_finished,
'rating', b.rating 'type',
'books',
'label',
'Book',
'image',
b.image,
'rating',
b.rating
) )
ELSE NULL ELSE NULL
END AS feed END AS feed
FROM optimized_books b FROM
optimized_books b
UNION ALL UNION ALL
SELECT CASE SELECT
WHEN m.last_watched IS NOT NULL THEN CASE
json_build_object( WHEN m.last_watched IS NOT NULL THEN json_build_object(
'title', CONCAT(m.title, 'title',
CASE WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')') ELSE '' END CONCAT(
m.title,
CASE
WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')')
ELSE ''
END
), ),
'url', m.url, 'url',
'description', COALESCE(m.review, m.description), m.url,
'date', m.last_watched, 'description',
'type', 'movies', COALESCE(m.review, m.description),
'label', 'Movie', 'date',
'image', m.image, m.last_watched,
'rating', m.rating 'type',
'movies',
'label',
'Movie',
'image',
m.image,
'rating',
m.rating
) )
ELSE NULL ELSE NULL
END AS feed END AS feed
FROM optimized_movies m FROM
optimized_movies m
) )
SELECT feed SELECT
FROM feed_data feed
WHERE feed IS NOT NULL FROM
ORDER BY (feed->>'date')::timestamp DESC feed_data
LIMIT 20; WHERE
feed IS NOT NULL
ORDER BY
(feed ->> 'date')::timestamp DESC
LIMIT
20;

View file

@ -1,12 +1,12 @@
CREATE OR REPLACE VIEW optimized_headers AS CREATE OR REPLACE VIEW optimized_headers AS
SELECT SELECT
p.path AS resource_path, 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 FROM
paths p paths p
JOIN JOIN paths_header_rules phr ON p.id = phr.paths_id
paths_header_rules phr ON p.id = phr.paths_id JOIN header_rules hr ON phr.header_rules_id = hr.id
JOIN
header_rules hr ON phr.header_rules_id = hr.id
GROUP BY GROUP BY
p.path; p.path;

View file

@ -1,70 +1,151 @@
CREATE OR REPLACE VIEW optimized_oembed AS CREATE OR REPLACE VIEW optimized_oembed AS
WITH oembed_data AS ( WITH
oembed_data AS (
SELECT SELECT
'post' AS type, 'post' AS type,
p.url::TEXT AS url, p.url::TEXT AS url,
p.title AS title, p.title AS title,
p.description AS description, p.description AS description,
COALESCE(NULLIF(p.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, 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 p.date AS content_date
FROM optimized_posts p FROM
optimized_posts p
UNION ALL UNION ALL
SELECT SELECT
'page' AS type, 'page' AS type,
pa.permalink::TEXT AS url, pa.permalink::TEXT AS url,
pa.title AS title, pa.title AS title,
pa.description AS description, pa.description AS description,
COALESCE(NULLIF(pa.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, 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 NULL::timestamptz AS content_date
FROM optimized_pages pa FROM
optimized_pages pa
UNION ALL UNION ALL
SELECT SELECT
'book' AS type, 'book' AS type,
b.url::TEXT AS url, b.url::TEXT AS url,
b.title AS title, b.title AS title,
b.description AS description, b.description AS description,
COALESCE(NULLIF(b.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, 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 b.date_finished AS content_date
FROM optimized_books b FROM
optimized_books b
UNION ALL UNION ALL
SELECT SELECT
'artist' AS type, 'artist' AS type,
ar.url::TEXT AS url, ar.url::TEXT AS url,
ar.name AS title, ar.name AS title,
ar.description AS description, ar.description AS description,
COALESCE(NULLIF(ar.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, 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 CURRENT_TIMESTAMP AS content_date
FROM optimized_artists ar FROM
optimized_artists ar
UNION ALL UNION ALL
SELECT SELECT
'genre' AS type, 'genre' AS type,
g.url::TEXT AS url, g.url::TEXT AS url,
g.name AS title, g.name AS title,
g.description AS description, g.description AS description,
COALESCE(NULLIF(g.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, 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 CURRENT_TIMESTAMP AS content_date
FROM optimized_genres g FROM
optimized_genres g
UNION ALL UNION ALL
SELECT SELECT
'show' AS type, 'show' AS type,
s.url::TEXT AS url, s.url::TEXT AS url,
s.title AS title, s.title AS title,
s.description AS description, s.description AS description,
COALESCE(NULLIF(s.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, 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 s.last_watched_at AS content_date
FROM optimized_shows s FROM
optimized_shows s
UNION ALL UNION ALL
SELECT SELECT
'movie' AS type, 'movie' AS type,
m.url::TEXT AS url, m.url::TEXT AS url,
m.title AS title, m.title AS title,
m.description AS description, m.description AS description,
COALESCE(NULLIF(m.metadata->>'open_graph_image', ''), (SELECT metadata->>'open_graph_image' FROM optimized_globals LIMIT 1)) AS image_url, 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 m.last_watched AS content_date
FROM optimized_movies m FROM
optimized_movies m
) )
SELECT SELECT
ROW_NUMBER() OVER (ORDER BY url) AS id, ROW_NUMBER() OVER (
ORDER BY
url
) AS id,
* *
FROM FROM
oembed_data; oembed_data;

View file

@ -1,5 +1,6 @@
CREATE OR REPLACE VIEW optimized_recent_activity AS CREATE OR REPLACE VIEW optimized_recent_activity AS
WITH activity_data AS ( WITH
activity_data AS (
SELECT SELECT
NULL::bigint AS id, NULL::bigint AS id,
p.date AS content_date, p.date AS content_date,
@ -18,10 +19,9 @@ WITH activity_data AS (
NULL AS notes, NULL AS notes,
'article' AS type, 'article' AS type,
'Post' AS label 'Post' AS label
FROM optimized_posts p FROM
optimized_posts p
UNION ALL UNION ALL
SELECT SELECT
NULL::bigint AS id, NULL::bigint AS id,
l.date AS content_date, l.date AS content_date,
@ -40,15 +40,18 @@ WITH activity_data AS (
NULL AS notes, NULL AS notes,
'link' AS type, 'link' AS type,
'Link' AS label 'Link' AS label
FROM optimized_links l FROM
optimized_links l
UNION ALL UNION ALL
SELECT SELECT
NULL::bigint AS id, NULL::bigint AS id,
b.date_finished AS content_date, b.date_finished AS content_date,
CONCAT(b.title, CONCAT(
CASE WHEN b.rating IS NOT NULL THEN CONCAT(' (', b.rating, ')') ELSE '' END b.title,
CASE
WHEN b.rating IS NOT NULL THEN CONCAT(' (', b.rating, ')')
ELSE ''
END
) AS title, ) AS title,
b.description, b.description,
b.url AS url, b.url AS url,
@ -64,16 +67,20 @@ WITH activity_data AS (
NULL AS notes, NULL AS notes,
'books' AS type, 'books' AS type,
'Book' AS label 'Book' AS label
FROM optimized_books b FROM
WHERE LOWER(b.status) = 'finished' optimized_books b
WHERE
LOWER(b.status) = 'finished'
UNION ALL UNION ALL
SELECT SELECT
NULL::bigint AS id, NULL::bigint AS id,
m.last_watched AS content_date, m.last_watched AS content_date,
CONCAT(m.title, CONCAT(
CASE WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')') ELSE '' END m.title,
CASE
WHEN m.rating IS NOT NULL THEN CONCAT(' (', m.rating, ')')
ELSE ''
END
) AS title, ) AS title,
m.description, m.description,
m.url AS url, m.url AS url,
@ -89,15 +96,19 @@ WITH activity_data AS (
NULL AS notes, NULL AS notes,
'movies' AS type, 'movies' AS type,
'Movie' AS label 'Movie' AS label
FROM optimized_movies m FROM
WHERE m.last_watched IS NOT NULL optimized_movies m
WHERE
m.last_watched IS NOT NULL
UNION ALL UNION ALL
SELECT SELECT
c.id, c.id,
c.date AS content_date, c.date AS content_date,
CONCAT(c.artist->>'name', ' at ', c.venue->>'name_short') AS title, CONCAT(
c.artist ->> 'name',
' at ',
c.venue ->> 'name_short'
) AS title,
c.concert_notes AS description, c.concert_notes AS description,
NULL AS url, NULL AS url,
NULL AS featured, NULL AS featured,
@ -112,13 +123,25 @@ WITH activity_data AS (
c.concert_notes AS notes, c.concert_notes AS notes,
'concerts' AS type, 'concerts' AS type,
'Concert' AS label 'Concert' AS label
FROM optimized_concerts c FROM
optimized_concerts c
) )
SELECT json_agg(recent_activity_data ORDER BY recent_activity_data.content_date DESC) AS feed SELECT
FROM ( json_agg(
SELECT * recent_activity_data
FROM activity_data ORDER BY
WHERE content_date IS NOT NULL recent_activity_data.content_date DESC
ORDER BY content_date DESC ) AS feed
LIMIT 20 FROM
(
SELECT
*
FROM
activity_data
WHERE
content_date IS NOT NULL
ORDER BY
content_date DESC
LIMIT
20
) AS recent_activity_data; ) AS recent_activity_data;

View file

@ -1,12 +1,14 @@
CREATE OR REPLACE VIEW optimized_robots AS CREATE OR REPLACE VIEW optimized_robots AS
SELECT SELECT
r.path, 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 FROM
robots AS r robots AS r
JOIN JOIN robots_user_agents AS rua ON r.id = rua.robots_id
robots_user_agents AS rua ON r.id = rua.robots_id JOIN user_agents AS ua ON rua.user_agents_id = ua.id
JOIN
user_agents AS ua ON rua.user_agents_id = ua.id
GROUP BY GROUP BY
r.path; r.path;

View file

@ -1,5 +1,6 @@
CREATE OR REPLACE VIEW optimized_search_index AS CREATE OR REPLACE VIEW optimized_search_index AS
WITH search_data AS ( WITH
search_data AS (
SELECT SELECT
p.title, p.title,
p.url::TEXT AS url, p.url::TEXT AS url,
@ -29,10 +30,9 @@ WITH search_data AS (
optimized_links l optimized_links l
UNION ALL UNION ALL
SELECT SELECT
CASE WHEN b.rating IS NOT NULL THEN CASE
CONCAT(b.title, ' (', b.rating, ')') WHEN b.rating IS NOT NULL THEN CONCAT(b.title, ' (', b.rating, ')')
ELSE ELSE b.title
b.title
END AS title, END AS title,
b.url::TEXT AS url, b.url::TEXT AS url,
b.description AS description, b.description AS description,
@ -53,7 +53,11 @@ WITH search_data AS (
ar.url::TEXT AS url, ar.url::TEXT AS url,
ar.description AS description, ar.description AS description,
ARRAY[ar.genre_name] AS tags, ARRAY[ar.genre_name] AS tags,
CONCAT(COALESCE(ar.emoji, ar.genre_emoji, '🎧'), ' ', ar.genre_name) AS genre_name, CONCAT(
COALESCE(ar.emoji, ar.genre_emoji, '🎧'),
' ',
ar.genre_name
) AS genre_name,
ar.genre_slug AS genre_url, ar.genre_slug AS genre_url,
TO_CHAR(ar.total_plays::NUMERIC, 'FM999,999,999,999') AS total_plays, TO_CHAR(ar.total_plays::NUMERIC, 'FM999,999,999,999') AS total_plays,
NULL AS content_date, NULL AS content_date,
@ -112,7 +116,10 @@ WITH search_data AS (
m.last_watched IS NOT NULL m.last_watched IS NOT NULL
) )
SELECT SELECT
ROW_NUMBER() OVER (ORDER BY url) AS id, ROW_NUMBER() OVER (
ORDER BY
url
) AS id,
* *
FROM FROM
search_data; search_data;

View file

@ -1,5 +1,6 @@
CREATE OR REPLACE VIEW optimized_sitemap AS CREATE OR REPLACE VIEW optimized_sitemap AS
WITH sitemap_data AS ( WITH
sitemap_data AS (
SELECT SELECT
p.url::TEXT AS url p.url::TEXT AS url
FROM FROM
@ -40,9 +41,13 @@ WITH sitemap_data AS (
FROM FROM
static_slugs ss static_slugs ss
UNION ALL UNION ALL
SELECT CONCAT('/tags/', LOWER(REPLACE(tag, ' ', '-'))) AS url SELECT
FROM optimized_all_tags CONCAT('/tags/', LOWER(REPLACE(tag, ' ', '-'))) AS url
WHERE tag IS NOT NULL AND TRIM(tag) <> '' FROM
optimized_all_tags
WHERE
tag IS NOT NULL
AND TRIM(tag) <> ''
) )
SELECT SELECT
url url

View file

@ -1,28 +1,38 @@
CREATE OR REPLACE VIEW optimized_stats AS CREATE OR REPLACE VIEW optimized_stats AS
WITH artist_stats AS ( WITH
artist_stats AS (
SELECT SELECT
TO_CHAR(COUNT(DISTINCT artist_name), 'FM999,999,999') AS artist_count TO_CHAR(COUNT(DISTINCT artist_name), 'FM999,999,999') AS artist_count
FROM optimized_listens FROM
WHERE artist_name IS NOT NULL optimized_listens
WHERE
artist_name IS NOT NULL
), ),
track_stats AS ( track_stats AS (
SELECT SELECT
TO_CHAR(COUNT(*), 'FM999,999,999') AS listen_count TO_CHAR(COUNT(*), 'FM999,999,999') AS listen_count
FROM optimized_listens FROM
optimized_listens
), ),
concert_stats AS ( concert_stats AS (
SELECT SELECT
TO_CHAR(COUNT(*), 'FM999,999,999') AS concert_count TO_CHAR(COUNT(*), 'FM999,999,999') AS concert_count
FROM concerts FROM
concerts
), ),
venue_stats AS ( venue_stats AS (
SELECT SELECT
TO_CHAR(COUNT(DISTINCT venue), 'FM999,999,999') AS venue_count TO_CHAR(COUNT(DISTINCT venue), 'FM999,999,999') AS venue_count
FROM concerts FROM
concerts
), ),
yearly_data AS ( yearly_data AS (
SELECT SELECT
EXTRACT(YEAR FROM e.last_watched_at) AS year, EXTRACT(
YEAR
FROM
e.last_watched_at
) AS year,
0 AS artist_count, 0 AS artist_count,
0 AS listen_count, 0 AS listen_count,
0 AS genre_count, 0 AS genre_count,
@ -34,12 +44,27 @@ yearly_data AS (
0 AS movie_count, 0 AS movie_count,
0 AS concert_count, 0 AS concert_count,
0 AS venue_count 0 AS venue_count
FROM episodes e FROM
GROUP BY EXTRACT(YEAR FROM e.last_watched_at) episodes e
HAVING EXTRACT(YEAR FROM e.last_watched_at) >= 2023 GROUP BY
EXTRACT(
YEAR
FROM
e.last_watched_at
)
HAVING
EXTRACT(
YEAR
FROM
e.last_watched_at
) >= 2023
UNION ALL UNION ALL
SELECT SELECT
EXTRACT(YEAR FROM p.date) AS year, EXTRACT(
YEAR
FROM
p.date
) AS year,
0 AS artist_count, 0 AS artist_count,
0 AS listen_count, 0 AS listen_count,
0 AS genre_count, 0 AS genre_count,
@ -51,12 +76,27 @@ yearly_data AS (
0 AS movie_count, 0 AS movie_count,
0 AS concert_count, 0 AS concert_count,
0 AS venue_count 0 AS venue_count
FROM optimized_posts p FROM
GROUP BY EXTRACT(YEAR FROM p.date) optimized_posts p
HAVING EXTRACT(YEAR FROM p.date) >= 2023 GROUP BY
EXTRACT(
YEAR
FROM
p.date
)
HAVING
EXTRACT(
YEAR
FROM
p.date
) >= 2023
UNION ALL UNION ALL
SELECT SELECT
EXTRACT(YEAR FROM o.date) AS year, EXTRACT(
YEAR
FROM
o.date
) AS year,
0 AS artist_count, 0 AS artist_count,
0 AS listen_count, 0 AS listen_count,
0 AS genre_count, 0 AS genre_count,
@ -68,12 +108,27 @@ yearly_data AS (
0 AS movie_count, 0 AS movie_count,
0 AS concert_count, 0 AS concert_count,
0 AS venue_count 0 AS venue_count
FROM optimized_links o FROM
GROUP BY EXTRACT(YEAR FROM o.date) optimized_links o
HAVING EXTRACT(YEAR FROM o.date) >= 2023 GROUP BY
EXTRACT(
YEAR
FROM
o.date
)
HAVING
EXTRACT(
YEAR
FROM
o.date
) >= 2023
UNION ALL UNION ALL
SELECT SELECT
EXTRACT(YEAR FROM b.date_finished) AS year, EXTRACT(
YEAR
FROM
b.date_finished
) AS year,
0 AS artist_count, 0 AS artist_count,
0 AS listen_count, 0 AS listen_count,
0 AS genre_count, 0 AS genre_count,
@ -85,13 +140,29 @@ yearly_data AS (
0 AS movie_count, 0 AS movie_count,
0 AS concert_count, 0 AS concert_count,
0 AS venue_count 0 AS venue_count
FROM optimized_books b FROM
WHERE LOWER(b.status) = 'finished' optimized_books b
GROUP BY EXTRACT(YEAR FROM b.date_finished) WHERE
HAVING EXTRACT(YEAR FROM b.date_finished) >= 2023 LOWER(b.status) = 'finished'
GROUP BY
EXTRACT(
YEAR
FROM
b.date_finished
)
HAVING
EXTRACT(
YEAR
FROM
b.date_finished
) >= 2023
UNION ALL UNION ALL
SELECT SELECT
EXTRACT(YEAR FROM m.last_watched) AS year, EXTRACT(
YEAR
FROM
m.last_watched
) AS year,
0 AS artist_count, 0 AS artist_count,
0 AS listen_count, 0 AS listen_count,
0 AS genre_count, 0 AS genre_count,
@ -103,12 +174,27 @@ yearly_data AS (
COUNT(*) AS movie_count, COUNT(*) AS movie_count,
0 AS concert_count, 0 AS concert_count,
0 AS venue_count 0 AS venue_count
FROM optimized_movies m FROM
GROUP BY EXTRACT(YEAR FROM m.last_watched) optimized_movies m
HAVING EXTRACT(YEAR FROM m.last_watched) >= 2023 GROUP BY
EXTRACT(
YEAR
FROM
m.last_watched
)
HAVING
EXTRACT(
YEAR
FROM
m.last_watched
) >= 2023
UNION ALL UNION ALL
SELECT SELECT
EXTRACT(YEAR FROM TO_TIMESTAMP(l.listened_at)) AS year, EXTRACT(
YEAR
FROM
TO_TIMESTAMP(l.listened_at)
) AS year,
COUNT(DISTINCT l.artist_name) AS artist_count, COUNT(DISTINCT l.artist_name) AS artist_count,
COUNT(l.id) AS listen_count, COUNT(l.id) AS listen_count,
COUNT(DISTINCT l.genre_name) AS genre_count, COUNT(DISTINCT l.genre_name) AS genre_count,
@ -120,12 +206,27 @@ yearly_data AS (
0 AS movie_count, 0 AS movie_count,
0 AS concert_count, 0 AS concert_count,
0 AS venue_count 0 AS venue_count
FROM optimized_listens l FROM
GROUP BY EXTRACT(YEAR FROM TO_TIMESTAMP(l.listened_at)) optimized_listens l
HAVING EXTRACT(YEAR FROM TO_TIMESTAMP(l.listened_at)) >= 2023 GROUP BY
EXTRACT(
YEAR
FROM
TO_TIMESTAMP(l.listened_at)
)
HAVING
EXTRACT(
YEAR
FROM
TO_TIMESTAMP(l.listened_at)
) >= 2023
UNION ALL UNION ALL
SELECT SELECT
EXTRACT(YEAR FROM c.date) AS year, EXTRACT(
YEAR
FROM
c.date
) AS year,
0 AS artist_count, 0 AS artist_count,
0 AS listen_count, 0 AS listen_count,
0 AS genre_count, 0 AS genre_count,
@ -137,9 +238,20 @@ yearly_data AS (
0 AS movie_count, 0 AS movie_count,
COUNT(*) AS concert_count, COUNT(*) AS concert_count,
COUNT(DISTINCT c.venue) AS venue_count COUNT(DISTINCT c.venue) AS venue_count
FROM concerts c FROM
GROUP BY EXTRACT(YEAR FROM c.date) concerts c
HAVING EXTRACT(YEAR FROM c.date) >= 2023 GROUP BY
EXTRACT(
YEAR
FROM
c.date
)
HAVING
EXTRACT(
YEAR
FROM
c.date
) >= 2023
), ),
aggregated_yearly_stats AS ( aggregated_yearly_stats AS (
SELECT SELECT
@ -155,36 +267,146 @@ aggregated_yearly_stats AS (
SUM(movie_count) AS movie_count, SUM(movie_count) AS movie_count,
SUM(concert_count) AS concert_count, SUM(concert_count) AS concert_count,
SUM(venue_count) AS venue_count SUM(venue_count) AS venue_count
FROM yearly_data FROM
GROUP BY year yearly_data
ORDER BY year DESC GROUP BY
year
ORDER BY
year DESC
) )
SELECT SELECT
(SELECT artist_count FROM artist_stats) AS artist_count, (
(SELECT listen_count FROM track_stats) AS listen_count, SELECT
(SELECT concert_count FROM concert_stats) AS concert_count, artist_count
(SELECT venue_count FROM venue_stats) AS venue_count, FROM
(SELECT TO_CHAR(COUNT(DISTINCT e.show), 'FM999,999,999') FROM episodes e) AS show_count, artist_stats
(SELECT TO_CHAR(COUNT(*), 'FM999,999,999') FROM episodes e) AS episode_count, ) AS artist_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
(SELECT TO_CHAR(COUNT(*), 'FM999,999,999') FROM optimized_books WHERE LOWER(status) = 'finished') AS book_count, listen_count
(SELECT TO_CHAR(COUNT(*), 'FM999,999,999') FROM optimized_movies WHERE last_watched IS NOT NULL) AS movie_count, FROM
(SELECT TO_CHAR(COUNT(DISTINCT genre_name), 'FM999,999,999') FROM optimized_listens WHERE genre_name IS NOT NULL) AS genre_count, 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_AGG(
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
'year', ys.year, 'year',
'artist_count', CASE WHEN ys.artist_count > 0 THEN TO_CHAR(ys.artist_count, 'FM999,999,999') ELSE NULL END, ys.year,
'listen_count', CASE WHEN ys.listen_count > 0 THEN TO_CHAR(ys.listen_count, 'FM999,999,999') ELSE NULL END, 'artist_count',
'genre_count', CASE WHEN ys.genre_count > 0 THEN TO_CHAR(ys.genre_count, 'FM999,999,999') ELSE NULL END, CASE
'show_count', CASE WHEN ys.show_count > 0 THEN TO_CHAR(ys.show_count, 'FM999,999,999') ELSE NULL END, WHEN ys.artist_count > 0 THEN TO_CHAR(ys.artist_count, 'FM999,999,999')
'episode_count', CASE WHEN ys.episode_count > 0 THEN TO_CHAR(ys.episode_count, 'FM999,999,999') ELSE NULL END, ELSE NULL
'post_count', CASE WHEN ys.post_count > 0 THEN TO_CHAR(ys.post_count, 'FM999,999,999') ELSE NULL END, END,
'link_count', CASE WHEN ys.link_count > 0 THEN TO_CHAR(ys.link_count, 'FM999,999,999') ELSE NULL END, 'listen_count',
'book_count', CASE WHEN ys.book_count > 0 THEN TO_CHAR(ys.book_count, 'FM999,999,999') ELSE NULL END, CASE
'movie_count', CASE WHEN ys.movie_count > 0 THEN TO_CHAR(ys.movie_count, 'FM999,999,999') ELSE NULL END, WHEN ys.listen_count > 0 THEN TO_CHAR(ys.listen_count, 'FM999,999,999')
'concert_count', CASE WHEN ys.concert_count > 0 THEN TO_CHAR(ys.concert_count, 'FM999,999,999') ELSE NULL END, ELSE NULL
'venue_count', CASE WHEN ys.venue_count > 0 THEN TO_CHAR(ys.venue_count, 'FM999,999,999') ELSE NULL END 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 ) AS yearly_breakdown
FROM aggregated_yearly_stats ys; FROM
aggregated_yearly_stats ys;

View file

@ -1,93 +1,153 @@
CREATE OR REPLACE VIEW optimized_syndication AS CREATE OR REPLACE VIEW optimized_syndication AS
WITH syndication_data AS ( WITH
syndication_data AS (
SELECT SELECT
p.date AS content_date, p.date AS content_date,
json_build_object( json_build_object(
'title', CONCAT('📝 ', p.title, ' ', ( 'title',
SELECT array_to_string( CONCAT(
'📝 ',
p.title,
' ',
(
SELECT
array_to_string(
array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))), array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))),
' ' ' '
) )
FROM unnest(p.tags) AS t(name), FROM
unnest(p.tags) AS t (name),
regexp_split_to_table(t.name, '\s*&\s*') AS tag_part regexp_split_to_table(t.name, '\s*&\s*') AS tag_part
)), )
'description', p.description, ),
'url', p.url, 'description',
'image', p.image, p.description,
'date', p.date 'url',
p.url,
'image',
p.image,
'date',
p.date
) AS feed ) AS feed
FROM optimized_posts p FROM
optimized_posts p
UNION ALL UNION ALL
SELECT SELECT
l.date AS content_date, l.date AS content_date,
json_build_object( json_build_object(
'title', CONCAT('🔗 ', l.title, CASE '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) 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) ELSE CONCAT(' via ', l.name)
END, ' ', ( END,
SELECT array_to_string( ' ',
(
SELECT
array_to_string(
array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))), array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))),
' ' ' '
) )
FROM unnest(l.tags) AS t(name), FROM
unnest(l.tags) AS t (name),
regexp_split_to_table(t.name, '\s*&\s*') AS tag_part regexp_split_to_table(t.name, '\s*&\s*') AS tag_part
)), )
'description', l.description, ),
'url', l.link, 'description',
'date', l.date l.description,
'url',
l.link,
'date',
l.date
) AS feed ) AS feed
FROM optimized_links l FROM
optimized_links l
UNION ALL UNION ALL
SELECT SELECT
b.date_finished AS content_date, b.date_finished AS content_date,
CASE CASE
WHEN LOWER(b.status) = 'finished' THEN WHEN LOWER(b.status) = 'finished' THEN json_build_object(
json_build_object( 'title',
'title', CONCAT('📖 ', b.title, CASE CONCAT(
WHEN b.rating IS NOT NULL THEN ' (' || b.rating || ')' ELSE '' END, ' ', ( '📖 ',
SELECT array_to_string( 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), ' ', ''))), array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))),
' ' ' '
) )
FROM unnest(b.tags) AS t(name), FROM
unnest(b.tags) AS t (name),
regexp_split_to_table(t.name, '\s*&\s*') AS tag_part regexp_split_to_table(t.name, '\s*&\s*') AS tag_part
) )
), ),
'description', b.description, 'description',
'url', b.url, b.description,
'image', b.image, 'url',
'date', b.date_finished b.url,
'image',
b.image,
'date',
b.date_finished
) )
ELSE NULL ELSE NULL
END AS feed END AS feed
FROM optimized_books b FROM
optimized_books b
UNION ALL UNION ALL
SELECT SELECT
m.last_watched AS content_date, m.last_watched AS content_date,
CASE CASE
WHEN m.last_watched IS NOT NULL THEN WHEN m.last_watched IS NOT NULL THEN json_build_object(
json_build_object( 'title',
'title', CONCAT('🎥 ', m.title, CASE CONCAT(
WHEN m.rating IS NOT NULL THEN ' (' || m.rating || ')' ELSE '' END, ' ', ( '🎥 ',
SELECT array_to_string( 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), ' ', ''))), array_agg('#' || initcap(replace(trim(tag_part), ' ', ''))),
' ' ' '
) )
FROM unnest(m.tags) AS t(name), FROM
unnest(m.tags) AS t (name),
regexp_split_to_table(t.name, '\s*&\s*') AS tag_part regexp_split_to_table(t.name, '\s*&\s*') AS tag_part
) )
), ),
'description', m.description, 'description',
'url', m.url, m.description,
'image', m.image, 'url',
'date', m.last_watched m.url,
'image',
m.image,
'date',
m.last_watched
) )
ELSE NULL ELSE NULL
END AS feed END AS feed
FROM optimized_movies m FROM
optimized_movies m
) )
SELECT feed SELECT
FROM syndication_data feed
WHERE feed IS NOT NULL FROM
ORDER BY content_date DESC syndication_data
LIMIT 3; WHERE
feed IS NOT NULL
ORDER BY
content_date DESC
LIMIT
3;

View file

@ -10,7 +10,8 @@ SELECT
p.tags::TEXT[], p.tags::TEXT[],
'article'::TEXT AS type, 'article'::TEXT AS type,
'Post'::TEXT AS label 'Post'::TEXT AS label
FROM optimized_posts p FROM
optimized_posts p
UNION ALL UNION ALL
SELECT SELECT
unnest(l.tags) AS tag, unnest(l.tags) AS tag,
@ -23,7 +24,8 @@ SELECT
l.tags::TEXT[], l.tags::TEXT[],
'link'::TEXT AS type, 'link'::TEXT AS type,
'Link'::TEXT AS label 'Link'::TEXT AS label
FROM optimized_links l FROM
optimized_links l
UNION ALL UNION ALL
SELECT SELECT
unnest(b.tags) AS tag, unnest(b.tags) AS tag,
@ -36,8 +38,10 @@ SELECT
b.tags::TEXT[], b.tags::TEXT[],
'books'::TEXT AS type, 'books'::TEXT AS type,
'Book'::TEXT AS label 'Book'::TEXT AS label
FROM optimized_books b FROM
WHERE LOWER(b.status) = 'finished' optimized_books b
WHERE
LOWER(b.status) = 'finished'
UNION ALL UNION ALL
SELECT SELECT
unnest(m.tags) AS tag, unnest(m.tags) AS tag,
@ -50,8 +54,10 @@ SELECT
m.tags::TEXT[], m.tags::TEXT[],
'movies'::TEXT AS type, 'movies'::TEXT AS type,
'Movie'::TEXT AS label 'Movie'::TEXT AS label
FROM optimized_movies m FROM
WHERE m.last_watched IS NOT NULL optimized_movies m
WHERE
m.last_watched IS NOT NULL
UNION ALL UNION ALL
SELECT SELECT
unnest(s.tags) AS tag, unnest(s.tags) AS tag,
@ -64,5 +70,7 @@ SELECT
s.tags::TEXT[], s.tags::TEXT[],
'tv'::TEXT AS type, 'tv'::TEXT AS type,
'Show'::TEXT AS label 'Show'::TEXT AS label
FROM optimized_shows s FROM
WHERE s.last_watched_at IS NOT NULL; optimized_shows s
WHERE
s.last_watched_at IS NOT NULL;

View file

@ -2,6 +2,9 @@ CREATE OR REPLACE VIEW optimized_all_tags AS
SELECT SELECT
tag, tag,
COUNT(*) AS uses COUNT(*) AS uses
FROM optimized_tagged_content FROM
GROUP BY tag optimized_tagged_content
ORDER BY tag ASC; GROUP BY
tag
ORDER BY
tag ASC;

View file

@ -1,6 +1,8 @@
CREATE OR REPLACE VIEW optimized_globals AS CREATE OR REPLACE VIEW optimized_globals AS
SELECT * SELECT
FROM ( *
FROM
(
SELECT SELECT
g.site_name, g.site_name,
g.site_description, g.site_description,
@ -21,20 +23,26 @@ FROM (
CONCAT(g.cdn_url, '/', df2.filename_disk) AS avatar_transparent, CONCAT(g.cdn_url, '/', df2.filename_disk) AS avatar_transparent,
CONCAT(g.cdn_url, '/', df3.filename_disk) AS avatar_header, CONCAT(g.cdn_url, '/', df3.filename_disk) AS avatar_header,
json_build_object( json_build_object(
'open_graph_image', CASE 'open_graph_image',
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CASE
CONCAT('/', df.filename_disk) WHEN df.filename_disk IS NOT NULL
AND df.filename_disk != ''
AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk)
ELSE NULL ELSE NULL
END, END,
'open_graph_image_transparent', CASE 'open_graph_image_transparent',
WHEN df2.filename_disk IS NOT NULL AND df2.filename_disk != '' AND df2.filename_disk != '/' THEN CASE
CONCAT('/', df2.filename_disk) WHEN df2.filename_disk IS NOT NULL
AND df2.filename_disk != ''
AND df2.filename_disk != '/' THEN CONCAT('/', df2.filename_disk)
ELSE NULL ELSE NULL
END END
) AS metadata ) AS metadata
FROM globals g FROM
globals g
LEFT JOIN directus_files df ON g.avatar = df.id 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 df2 ON g.avatar_transparent = df2.id
LEFT JOIN directus_files df3 ON g.avatar_header = df3.id LEFT JOIN directus_files df3 ON g.avatar_header = df3.id
LIMIT 1 LIMIT
1
) sub; ) sub;

View file

@ -5,47 +5,80 @@ SELECT
p.permalink, p.permalink,
p.description, p.description,
json_build_object( json_build_object(
'title', CONCAT(p.title, '', globals.site_name), 'title',
'description', LEFT( CONCAT(p.title, '', globals.site_name),
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace(p.description, E'[*_`~#>-]', '', 'g'), regexp_replace(p.description, E'[*_`~#>-]', '', 'g'),
E'\\[(.*?)\\]\\((.*?)\\)', '\\1', 'g' E'\\[(.*?)\\]\\((.*?)\\)',
'\\1',
'g'
), ),
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
'',
'g'
), ),
250 250
), ),
'open_graph_image', CASE 'open_graph_image',
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CASE
CONCAT('/', df.filename_disk) 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' ELSE globals.metadata ->> 'open_graph_image'
END, END,
'url', CONCAT(globals.url, p.permalink), 'url',
'type', 'page' CONCAT(globals.url, p.permalink),
'type',
'page'
) AS metadata, ) AS metadata,
( (
SELECT SELECT
json_agg( json_agg(
CASE WHEN pb.collection = 'youtube_player' THEN CASE
json_build_object('type', pb.collection, 'url', yp.url) WHEN pb.collection = 'youtube_player' THEN json_build_object('type', pb.collection, 'url', yp.url)
WHEN pb.collection = 'forgejo_banner' THEN WHEN pb.collection = 'forgejo_banner' THEN json_build_object('type', pb.collection, 'url', fb.url)
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 = 'github_banner' THEN WHEN pb.collection = 'npm_banner' THEN json_build_object(
json_build_object('type', pb.collection, 'url', gb.url) 'type',
WHEN pb.collection = 'npm_banner' THEN pb.collection,
json_build_object('type', pb.collection, 'url', nb.url, 'command', nb.command) 'url',
WHEN pb.collection = 'rss_banner' THEN nb.url,
json_build_object('type', pb.collection, 'url', rb.url, 'text', rb.text) 'command',
WHEN pb.collection = 'calendar_banner' THEN nb.command
json_build_object('type', pb.collection, 'url', cb.url, 'text', cb.text) )
WHEN pb.collection = 'hero' THEN WHEN pb.collection = 'rss_banner' THEN json_build_object(
json_build_object('type', pb.collection, 'image', CONCAT('/', df_hero.filename_disk), 'alt', h.alt_text) 'type',
WHEN pb.collection = 'markdown' THEN pb.collection,
json_build_object('type', pb.collection, 'text', md.text) 'url',
ELSE rb.url,
json_build_object('type', pb.collection) 'text',
END ORDER BY pb.sort) 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 FROM
pages_blocks pb pages_blocks pb
LEFT JOIN youtube_player yp ON pb.collection = 'youtube_player' LEFT JOIN youtube_player yp ON pb.collection = 'youtube_player'
@ -66,7 +99,8 @@ SELECT
LEFT JOIN markdown md ON pb.collection = 'markdown' LEFT JOIN markdown md ON pb.collection = 'markdown'
AND md.id = pb.item::integer AND md.id = pb.item::integer
WHERE WHERE
pb.pages_id = p.id) AS blocks pb.pages_id = p.id
) AS blocks
FROM FROM
pages p pages p
LEFT JOIN directus_files df ON p.open_graph_image = df.id LEFT JOIN directus_files df ON p.open_graph_image = df.id

View file

@ -1,7 +1,11 @@
CREATE OR REPLACE VIEW optimized_books AS CREATE OR REPLACE VIEW optimized_books AS
SELECT SELECT
b.date_finished, b.date_finished,
EXTRACT(YEAR FROM b.date_finished) AS year, EXTRACT(
YEAR
FROM
b.date_finished
) AS year,
b.author, b.author,
b.description, b.description,
b.title, b.title,
@ -14,184 +18,341 @@ SELECT
b.favorite, b.favorite,
b.tattoo, b.tattoo,
( (
SELECT array_agg(t.name) SELECT
FROM books_tags bt array_agg(t.name)
FROM
books_tags bt
LEFT JOIN tags t ON bt.tags_id = t.id LEFT JOIN tags t ON bt.tags_id = t.id
WHERE bt.books_id = b.id WHERE
bt.books_id = b.id
) AS tags, ) AS tags,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'name', a.name_string, 'name',
'url', a.slug, a.name_string,
'country', a.country, 'url',
'total_plays', a.total_plays, a.slug,
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), 'country',
'grid', json_build_object( a.country,
'title', a.name_string, 'total_plays',
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), a.total_plays,
'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, 'image',
'subtext', CASE WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays') ELSE NULL END, CONCAT(globals.cdn_url, '/', df_artist.filename_disk),
'url', a.slug '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' 'type',
'music'
) )
ORDER BY a.total_plays DESC ORDER BY
a.total_plays DESC
) )
FROM books_artists ba FROM
books_artists ba
LEFT JOIN artists a ON ba.artists_id = a.id LEFT JOIN artists a ON ba.artists_id = a.id
LEFT JOIN directus_files df_artist ON a.art = df_artist.id LEFT JOIN directus_files df_artist ON a.art = df_artist.id
WHERE ba.books_id = b.id WHERE
ba.books_id = b.id
) AS artists, ) AS artists,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', m.title, 'title',
'year', m.year, m.title,
'url', m.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), m.year,
'grid', json_build_object( 'url',
'title', NULL, m.slug,
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), 'image',
'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), CONCAT(globals.cdn_url, '/', df_movie.filename_disk),
'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, 'grid',
'url', m.slug 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' 'type',
'movies'
) )
ORDER BY m.year ASC ORDER BY
m.year ASC
) )
FROM movies_books mb FROM
movies_books mb
LEFT JOIN movies m ON mb.movies_id = m.id LEFT JOIN movies m ON mb.movies_id = m.id
LEFT JOIN directus_files df_movie ON m.art = df_movie.id LEFT JOIN directus_files df_movie ON m.art = df_movie.id
WHERE mb.books_id = b.id WHERE
mb.books_id = b.id
AND m.last_watched IS NOT NULL AND m.last_watched IS NOT NULL
) AS movies, ) AS movies,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object('name', g.name, 'url', g.slug) json_build_object('name', g.name, 'url', g.slug)
ORDER BY g.name ASC ORDER BY
g.name ASC
) )
FROM genres_books gb FROM
genres_books gb
LEFT JOIN genres g ON gb.genres_id = g.id LEFT JOIN genres g ON gb.genres_id = g.id
WHERE gb.books_id = b.id WHERE
gb.books_id = b.id
) AS genres, ) AS genres,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', s.title, 'title',
'year', s.year, s.title,
'url', s.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), s.year,
'grid', json_build_object( 'url',
'title', NULL, s.slug,
'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), 'image',
'alt', CONCAT('Artwork for ', s.title), CONCAT(globals.cdn_url, '/', df_show.filename_disk),
'subtext', CASE 'grid',
json_build_object(
'title',
NULL,
'image',
CONCAT(globals.cdn_url, '/', df_show.filename_disk),
'alt',
CONCAT('Artwork for ', s.title),
'subtext',
CASE
WHEN ( WHEN (
SELECT MAX(e1.last_watched_at) SELECT
FROM episodes e1 MAX(e1.last_watched_at)
WHERE e1.show = s.id FROM
episodes e1
WHERE
e1.show = s.id
) >= NOW() - INTERVAL '90 days' THEN ( ) >= NOW() - INTERVAL '90 days' THEN (
SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) SELECT
FROM episodes e2 CONCAT('S', e2.season_number, 'E', e2.episode_number)
WHERE e2.show = s.id FROM
ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC episodes e2
LIMIT 1 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 ELSE s.year::text
END, END,
'url', s.slug 'url',
s.slug
), ),
'type', 'tv' 'type',
'tv'
) )
ORDER BY s.year ASC ORDER BY
s.year ASC
) )
FROM shows_books sb FROM
shows_books sb
LEFT JOIN shows s ON sb.shows_id = s.id LEFT JOIN shows s ON sb.shows_id = s.id
LEFT JOIN directus_files df_show ON s.art = df_show.id LEFT JOIN directus_files df_show ON s.art = df_show.id
WHERE sb.books_id = b.id WHERE
sb.books_id = b.id
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT
FROM episodes e 1
WHERE e.show = s.id FROM
episodes e
WHERE
e.show = s.id
AND e.last_watched_at IS NOT NULL AND e.last_watched_at IS NOT NULL
) )
) AS shows, ) AS shows,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object('title', p.title, 'date', p.date, 'url', p.slug) json_build_object('title', p.title, 'date', p.date, 'url', p.slug)
ORDER BY p.date DESC ORDER BY
p.date DESC
) )
FROM posts_books pb FROM
posts_books pb
LEFT JOIN posts p ON pb.posts_id = p.id LEFT JOIN posts p ON pb.posts_id = p.id
WHERE pb.books_id = b.id WHERE
pb.books_id = b.id
) AS posts, ) AS posts,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', rb.title, 'title',
'author', rb.author, rb.title,
'url', rb.slug, 'author',
'image', CONCAT(globals.cdn_url, '/', df_rb.filename_disk), rb.author,
'grid', json_build_object( 'url',
'title', NULL, rb.slug,
'image', CONCAT(globals.cdn_url, '/', df_rb.filename_disk), 'image',
'alt', CONCAT('Cover for ', rb.title, ' by ', rb.author), CONCAT(globals.cdn_url, '/', df_rb.filename_disk),
'subtext', CASE WHEN rb.star_rating IS NOT NULL THEN rb.star_rating ELSE NULL END, 'grid',
'url', rb.slug 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' 'type',
'books'
) )
ORDER BY rb.title ASC ORDER BY
rb.title ASC
) )
FROM related_books rbk FROM
related_books rbk
LEFT JOIN books rb ON rbk.related_books_id = rb.id LEFT JOIN books rb ON rbk.related_books_id = rb.id
LEFT JOIN directus_files df_rb ON rb.art = df_rb.id LEFT JOIN directus_files df_rb ON rb.art = df_rb.id
WHERE rbk.books_id = b.id WHERE
rbk.books_id = b.id
AND LOWER(b.read_status) = 'finished' AND LOWER(b.read_status) = 'finished'
) AS related_books, ) AS related_books,
json_build_object( json_build_object(
'title', NULL, 'title',
'image', CONCAT(globals.cdn_url, '/', df.filename_disk), NULL,
'url', b.slug, 'image',
'alt', CONCAT('Book cover from ', b.title, ' by ', b.author), CONCAT(globals.cdn_url, '/', df.filename_disk),
'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating::text ELSE NULL END, 'url',
'type', 'books' 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, ) AS grid,
CASE CASE
WHEN LOWER(b.read_status) = 'finished' AND b.star_rating IS NOT NULL THEN WHEN LOWER(b.read_status) = 'finished'
json_build_object( AND b.star_rating IS NOT NULL THEN json_build_object(
'title', CONCAT(b.title, ' by ', b.author, ' (', b.star_rating, ')'), 'title',
'url', b.slug, CONCAT(
'date', b.date_finished, b.title,
'description', COALESCE(b.review, b.description), ' by ',
'image', CONCAT(globals.cdn_url, '/', df.filename_disk), b.author,
'rating', b.star_rating ' (',
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 ELSE NULL
END AS feed, 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( json_build_object(
'title', CONCAT('Book • ', b.title, ' by ', b.author, '', globals.site_name), 'title',
'description', LEFT( CONCAT(
'Book • ',
b.title,
' by ',
b.author,
'',
globals.site_name
),
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace(b.description, E'[*_`~#>-]', '', 'g'), regexp_replace(b.description, E'[*_`~#>-]', '', 'g'),
E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' E'\\[(.*?)\\]\\((.*?)\\)',
E'\\1',
'g'
), ),
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
'',
'g'
), ),
250 250
), ),
'open_graph_image', CASE 'open_graph_image',
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) CASE
WHEN df.filename_disk IS NOT NULL
AND df.filename_disk != ''
AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk)
ELSE NULL ELSE NULL
END, END,
'url', CONCAT(globals.url, b.slug), 'url',
'type', 'book' CONCAT(globals.url, b.slug),
'type',
'book'
) AS metadata ) AS metadata
FROM books b FROM
books b
LEFT JOIN directus_files df ON b.art = df.id LEFT JOIN directus_files df ON b.art = df.id
CROSS JOIN optimized_globals globals CROSS JOIN optimized_globals globals
GROUP BY b.id, df.filename_disk, globals.cdn_url, globals.site_name, globals.url; GROUP BY
b.id,
df.filename_disk,
globals.cdn_url,
globals.site_name,
globals.url;

View file

@ -15,192 +15,322 @@ SELECT
CONCAT(globals.cdn_url, '/', df.filename_disk) AS image, CONCAT(globals.cdn_url, '/', df.filename_disk) AS image,
CONCAT(globals.cdn_url, '/', df2.filename_disk) AS backdrop, CONCAT(globals.cdn_url, '/', df2.filename_disk) AS backdrop,
json_build_object( json_build_object(
'title', m.title, 'title',
'url', m.slug, m.title,
'image', CONCAT(globals.cdn_url, '/', df.filename_disk), 'url',
'backdrop', CONCAT(globals.cdn_url, '/', df2.filename_disk), m.slug,
'alt', CONCAT('Poster from ', m.title), 'image',
'subtext', CASE 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 WHEN m.last_watched >= NOW() - INTERVAL '90 days' THEN m.star_rating::text
ELSE m.year::text ELSE m.year::text
END, END,
'type', 'movies' 'type',
'movies'
) AS grid, ) AS grid,
( (
SELECT array_agg(t.name) SELECT
FROM movies_tags mt array_agg(t.name)
FROM
movies_tags mt
LEFT JOIN tags t ON mt.tags_id = t.id LEFT JOIN tags t ON mt.tags_id = t.id
WHERE mt.movies_id = m.id WHERE
mt.movies_id = m.id
) AS tags, ) AS tags,
( (
SELECT json_agg(json_build_object('name', g.name, 'url', g.slug) SELECT
ORDER BY g.name ASC) json_agg(
FROM genres_movies gm 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 LEFT JOIN genres g ON gm.genres_id = g.id
WHERE gm.movies_id = m.id WHERE
gm.movies_id = m.id
) AS genres, ) AS genres,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'name', a.name_string, 'name',
'url', a.slug, a.name_string,
'country', a.country, 'url',
'total_plays', a.total_plays, a.slug,
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), 'country',
'grid', json_build_object( a.country,
'title', a.name_string, 'total_plays',
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), a.total_plays,
'alt', CASE 'image',
WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name_string) 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) ELSE CONCAT('Artwork of ', a.name_string)
END, END,
'subtext', CASE 'subtext',
WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays') CASE
WHEN a.total_plays > 0 THEN CONCAT(
to_char(a.total_plays, 'FM999,999,999,999'),
' plays'
)
ELSE NULL ELSE NULL
END, END,
'url', a.slug 'url',
a.slug
), ),
'type', 'music' 'type',
'music'
) )
ORDER BY a.total_plays DESC ORDER BY
a.total_plays DESC
) )
FROM movies_artists ma FROM
movies_artists ma
LEFT JOIN artists a ON ma.artists_id = a.id LEFT JOIN artists a ON ma.artists_id = a.id
LEFT JOIN directus_files df_artist ON a.art = df_artist.id LEFT JOIN directus_files df_artist ON a.art = df_artist.id
WHERE ma.movies_id = m.id WHERE
ma.movies_id = m.id
) AS artists, ) AS artists,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', b.title, 'title',
'author', b.author, b.title,
'url', b.slug, 'author',
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), b.author,
'grid', json_build_object( 'url',
'title', b.title, b.slug,
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), 'image',
'alt', CONCAT('Cover for ', b.title, ' by ', b.author), CONCAT(globals.cdn_url, '/', df_book.filename_disk),
'subtext', b.author, 'grid',
'url', b.slug 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' 'type',
'books'
) )
ORDER BY b.title ORDER BY
b.title
) )
FROM movies_books mb FROM
movies_books mb
LEFT JOIN books b ON mb.books_id = b.id LEFT JOIN books b ON mb.books_id = b.id
LEFT JOIN directus_files df_book ON b.art = df_book.id LEFT JOIN directus_files df_book ON b.art = df_book.id
WHERE mb.movies_id = m.id WHERE
mb.movies_id = m.id
AND LOWER(b.read_status) = 'finished' AND LOWER(b.read_status) = 'finished'
) AS books, ) AS books,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', s.title, 'title',
'year', s.year, s.title,
'url', s.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), s.year,
'grid', json_build_object( 'url',
'title', NULL, s.slug,
'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), 'image',
'alt', CONCAT('Artwork for ', s.title), CONCAT(globals.cdn_url, '/', df_show.filename_disk),
'subtext', CASE 'grid',
json_build_object(
'title',
NULL,
'image',
CONCAT(globals.cdn_url, '/', df_show.filename_disk),
'alt',
CONCAT('Artwork for ', s.title),
'subtext',
CASE
WHEN ( WHEN (
SELECT MAX(e1.last_watched_at) SELECT
FROM episodes e1 MAX(e1.last_watched_at)
WHERE e1.show = s.id FROM
episodes e1
WHERE
e1.show = s.id
) >= NOW() - INTERVAL '90 days' THEN ( ) >= NOW() - INTERVAL '90 days' THEN (
SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) SELECT
FROM episodes e2 CONCAT('S', e2.season_number, 'E', e2.episode_number)
WHERE e2.show = s.id FROM
ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC episodes e2
LIMIT 1 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 ELSE s.year::text
END, END,
'url', s.slug 'url',
s.slug
), ),
'type', 'tv' 'type',
'tv'
) )
ORDER BY s.year ASC ORDER BY
s.year ASC
) )
FROM shows_movies sm FROM
shows_movies sm
LEFT JOIN shows s ON sm.shows_id = s.id LEFT JOIN shows s ON sm.shows_id = s.id
LEFT JOIN directus_files df_show ON s.art = df_show.id LEFT JOIN directus_files df_show ON s.art = df_show.id
WHERE sm.movies_id = m.id WHERE
sm.movies_id = m.id
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT
FROM episodes e 1
WHERE e.show = s.id FROM
episodes e
WHERE
e.show = s.id
AND e.last_watched_at IS NOT NULL AND e.last_watched_at IS NOT NULL
) )
) AS shows, ) AS shows,
( (
SELECT json_agg(json_build_object('title', p.title, 'date', p.date, 'url', p.slug) SELECT
ORDER BY p.date DESC) json_agg(
FROM posts_movies pm 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 LEFT JOIN posts p ON pm.posts_id = p.id
WHERE pm.movies_id = m.id WHERE
pm.movies_id = m.id
) AS posts, ) AS posts,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', rm.title, 'title',
'year', rm.year, rm.title,
'url', rm.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), rm.year,
'grid', json_build_object( 'url',
'title', rm.title, rm.slug,
'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), 'image',
'alt', CONCAT('Poster for ', rm.title), CONCAT(globals.cdn_url, '/', df_related.filename_disk),
'subtext', CASE WHEN rm.last_watched IS NOT NULL THEN rm.star_rating::text ELSE rm.year::text END, 'grid',
'url', rm.slug 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' 'type',
'movies'
) )
ORDER BY rm.year ASC ORDER BY
rm.year ASC
) )
FROM related_movies r FROM
related_movies r
LEFT JOIN movies rm ON r.related_movies_id = rm.id LEFT JOIN movies rm ON r.related_movies_id = rm.id
LEFT JOIN directus_files df_related ON rm.art = df_related.id LEFT JOIN directus_files df_related ON rm.art = df_related.id
WHERE r.movies_id = m.id WHERE
r.movies_id = m.id
AND rm.last_watched IS NOT NULL AND rm.last_watched IS NOT NULL
) AS related_movies, ) AS related_movies,
CASE CASE
WHEN m.star_rating IS NOT NULL AND m.last_watched IS NOT NULL THEN WHEN m.star_rating IS NOT NULL
json_build_object( AND m.last_watched IS NOT NULL THEN json_build_object(
'title', CONCAT(m.title, ' (', m.star_rating, ')'), 'title',
'url', m.slug, CONCAT(m.title, ' (', m.star_rating, ')'),
'date', m.last_watched, 'url',
'description', COALESCE(m.review, m.description), m.slug,
'image', CONCAT(globals.cdn_url, '/', df.filename_disk), 'date',
'rating', m.star_rating m.last_watched,
'description',
COALESCE(m.review, m.description),
'image',
CONCAT(globals.cdn_url, '/', df.filename_disk),
'rating',
m.star_rating
) )
ELSE NULL ELSE NULL
END AS feed, END AS feed,
json_build_object( json_build_object(
'title', CONCAT('Movie • ', m.title, '', globals.site_name), 'title',
'description', LEFT( CONCAT('Movie • ', m.title, '', globals.site_name),
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace(m.description, E'[*_`~#>-]', '', 'g'), regexp_replace(m.description, E'[*_`~#>-]', '', 'g'),
E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' E'\\[(.*?)\\]\\((.*?)\\)',
E'\\1',
'g'
), ),
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
'',
'g'
), ),
250 250
), ),
'open_graph_image', CASE 'open_graph_image',
WHEN df2.filename_disk IS NOT NULL AND df2.filename_disk != '' AND df2.filename_disk != '/' THEN CASE
CONCAT('/', df2.filename_disk) WHEN df2.filename_disk IS NOT NULL
AND df2.filename_disk != ''
AND df2.filename_disk != '/' THEN CONCAT('/', df2.filename_disk)
ELSE NULL ELSE NULL
END, END,
'url', CONCAT(globals.url, m.slug), 'url',
'type', 'movie' CONCAT(globals.url, m.slug),
'type',
'movie'
) AS metadata ) AS metadata
FROM movies m FROM
movies m
LEFT JOIN directus_files df ON m.art = df.id LEFT JOIN directus_files df ON m.art = df.id
LEFT JOIN directus_files df2 ON m.backdrop = df2.id LEFT JOIN directus_files df2 ON m.backdrop = df2.id
CROSS JOIN optimized_globals globals CROSS JOIN optimized_globals globals
GROUP BY m.id, df.filename_disk, df2.filename_disk, globals.cdn_url, globals.site_name, globals.url GROUP BY
ORDER BY m.last_watched DESC; m.id,
df.filename_disk,
df2.filename_disk,
globals.cdn_url,
globals.site_name,
globals.url
ORDER BY
m.last_watched DESC;

View file

@ -5,14 +5,34 @@ SELECT
COALESCE(a.release_link, ar.slug) AS url, COALESCE(a.release_link, ar.slug) AS url,
a.total_plays, a.total_plays,
CONCAT('/', df.filename_disk) AS image, 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( json_build_object(
'title', a.name, 'name',
'image', CONCAT(globals.cdn_url, '/', df.filename_disk), ar.name_string,
'url', COALESCE(a.release_link, ar.slug), 'url',
'alt', CONCAT(a.name, ' by ', ar.name_string), ar.slug,
'subtext', CONCAT(ar.name_string, '', TO_CHAR(a.release_date, 'Mon FMDD, YYYY')) '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 ) AS grid
FROM FROM
albums a albums a

View file

@ -8,23 +8,44 @@ SELECT
ar.slug AS artist_url, ar.slug AS artist_url,
CONCAT(globals.cdn_url, '/', df_album.filename_disk) AS image, CONCAT(globals.cdn_url, '/', df_album.filename_disk) AS image,
json_build_object( json_build_object(
'title', al.name, 'title',
'image', CONCAT(globals.cdn_url, '/', df_album.filename_disk), al.name,
'url', ar.slug, 'image',
'alt', CONCAT('Cover for ', al.name, ' by ', ar.name_string), CONCAT(globals.cdn_url, '/', df_album.filename_disk),
'subtext', CONCAT(to_char(al.total_plays, 'FM999,999,999,999'), ' plays') '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, ) AS grid,
json_build_object( json_build_object(
'title', al.name, 'title',
'artist', ar.name_string, al.name,
'plays', to_char(al.total_plays, 'FM999,999,999,999'), 'artist',
'image', CONCAT(globals.cdn_url, '/', df_album.filename_disk), ar.name_string,
'url', ar.slug, 'plays',
'year', al.release_year, to_char(al.total_plays, 'FM999,999,999,999'),
'alt', CONCAT('Cover for ', al.name, ' by ', ar.name_string) '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 ) AS table
FROM albums al FROM
albums al
LEFT JOIN artists ar ON al.artist = ar.id LEFT JOIN artists ar ON al.artist = ar.id
LEFT JOIN directus_files df_album ON al.art = df_album.id LEFT JOIN directus_files df_album ON al.art = df_album.id
CROSS JOIN optimized_globals globals CROSS JOIN optimized_globals globals
GROUP BY al.id, ar.name_string, ar.slug, df_album.filename_disk, globals.cdn_url; GROUP BY
al.id,
ar.name_string,
ar.slug,
df_album.filename_disk,
globals.cdn_url;

View file

@ -16,196 +16,383 @@ SELECT
ar.tattoo, ar.tattoo,
CONCAT(globals.cdn_url, '/', df.filename_disk) AS image, CONCAT(globals.cdn_url, '/', df.filename_disk) AS image,
json_build_object( json_build_object(
'title', ar.name_string, 'title',
'image', CONCAT(globals.cdn_url, '/', df.filename_disk), ar.name_string,
'url', ar.slug, 'image',
'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, CONCAT(globals.cdn_url, '/', df.filename_disk),
'subtext', CASE WHEN ar.total_plays > 0 THEN CONCAT(to_char(ar.total_plays, 'FM999,999,999,999'), ' plays') ELSE NULL END '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, ) AS grid,
json_build_object( json_build_object(
'title', ar.name_string, 'title',
'genre', g.name, ar.name_string,
'genre_url', g.slug, 'genre',
'emoji', COALESCE(ar.emoji, g.emoji), g.name,
'plays', to_char(ar.total_plays, 'FM999,999,999,999'), 'genre_url',
'image', CONCAT(globals.cdn_url, '/', df.filename_disk), g.slug,
'url', ar.slug, 'emoji',
'alt', CONCAT(to_char(ar.total_plays, 'FM999,999,999,999'), ' plays of ', ar.name_string) 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, ) AS table,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'name', a.name, 'name',
'release_year', a.release_year, a.name,
'total_plays', to_char(a.total_plays, 'FM999,999,999,999'), 'release_year',
'art', df_album.filename_disk, a.release_year,
'grid', json_build_object( 'total_plays',
'title', a.name, to_char(a.total_plays, 'FM999,999,999,999'),
'image', CONCAT(globals.cdn_url, '/', df_album.filename_disk), 'art',
'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, df_album.filename_disk,
'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 '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' 'type',
'albums'
) )
ORDER BY a.release_year ORDER BY
a.release_year
) )
FROM albums a FROM
albums a
LEFT JOIN directus_files df_album ON a.art = df_album.id LEFT JOIN directus_files df_album ON a.art = df_album.id
WHERE a.artist = ar.id WHERE
a.artist = ar.id
) AS albums, ) AS albums,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'id', c.id, 'id',
'date', c.date, c.id,
'venue_name', v.name, 'date',
'venue_name_short', trim(split_part(v.name, ',', 1)), c.date,
'venue_latitude', v.latitude, 'venue_name',
'venue_longitude', v.longitude, v.name,
'notes', c.notes '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 FROM
concerts c
LEFT JOIN venues v ON c.venue = v.id LEFT JOIN venues v ON c.venue = v.id
WHERE c.artist = ar.id WHERE
c.artist = ar.id
) AS concerts, ) AS concerts,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', b.title, 'title',
'author', b.author, b.title,
'url', b.slug, 'author',
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), b.author,
'grid', json_build_object( 'url',
'title', NULL, b.slug,
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), 'image',
'alt', CONCAT('Cover for ', b.title, ' by ', b.author), CONCAT(globals.cdn_url, '/', df_book.filename_disk),
'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating ELSE NULL END, 'grid',
'url', b.slug 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' 'type',
'books'
) )
ORDER BY b.title ASC ORDER BY
b.title ASC
) )
FROM books_artists ba FROM
books_artists ba
LEFT JOIN books b ON ba.books_id = b.id LEFT JOIN books b ON ba.books_id = b.id
LEFT JOIN directus_files df_book ON b.art = df_book.id LEFT JOIN directus_files df_book ON b.art = df_book.id
WHERE ba.artists_id = ar.id WHERE
ba.artists_id = ar.id
AND LOWER(b.read_status) = 'finished' AND LOWER(b.read_status) = 'finished'
) AS books, ) AS books,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', m.title, 'title',
'year', m.year, m.title,
'url', m.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), m.year,
'grid', json_build_object( 'url',
'title', NULL, m.slug,
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), 'image',
'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), CONCAT(globals.cdn_url, '/', df_movie.filename_disk),
'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, 'grid',
'url', m.slug 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' 'type',
'movies'
) )
ORDER BY m.year ASC ORDER BY
m.year ASC
) )
FROM movies_artists ma FROM
movies_artists ma
LEFT JOIN movies m ON ma.movies_id = m.id LEFT JOIN movies m ON ma.movies_id = m.id
LEFT JOIN directus_files df_movie ON m.art = df_movie.id LEFT JOIN directus_files df_movie ON m.art = df_movie.id
WHERE ma.artists_id = ar.id WHERE
ma.artists_id = ar.id
AND m.last_watched IS NOT NULL AND m.last_watched IS NOT NULL
) AS movies, ) AS movies,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', s.title, 'title',
'year', s.year, s.title,
'url', s.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), s.year,
'grid', json_build_object( 'url',
'title', NULL, s.slug,
'image', CONCAT(globals.cdn_url, '/', df_show.filename_disk), 'image',
'alt', CONCAT('Artwork for ', s.title), CONCAT(globals.cdn_url, '/', df_show.filename_disk),
'subtext', CASE 'grid',
json_build_object(
'title',
NULL,
'image',
CONCAT(globals.cdn_url, '/', df_show.filename_disk),
'alt',
CONCAT('Artwork for ', s.title),
'subtext',
CASE
WHEN ( WHEN (
SELECT MAX(e1.last_watched_at) SELECT
FROM episodes e1 MAX(e1.last_watched_at)
WHERE e1.show = s.id FROM
) >= NOW() - INTERVAL '90 days' THEN episodes e1
( WHERE
SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) e1.show = s.id
FROM episodes e2 ) >= NOW() - INTERVAL '90 days' THEN (
WHERE e2.show = s.id SELECT
ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC CONCAT('S', e2.season_number, 'E', e2.episode_number)
LIMIT 1 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 ELSE s.year::text
END, END,
'url', s.slug 'url',
s.slug
), ),
'type', 'tv' 'type',
'tv'
) )
ORDER BY s.year ASC ORDER BY
s.year ASC
) )
FROM shows_artists sa FROM
shows_artists sa
LEFT JOIN shows s ON sa.shows_id = s.id LEFT JOIN shows s ON sa.shows_id = s.id
LEFT JOIN directus_files df_show ON s.art = df_show.id LEFT JOIN directus_files df_show ON s.art = df_show.id
WHERE sa.artists_id = ar.id WHERE
sa.artists_id = ar.id
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT
FROM episodes e 1
WHERE e.show = s.id FROM
episodes e
WHERE
e.show = s.id
AND e.last_watched_at IS NOT NULL AND e.last_watched_at IS NOT NULL
) )
) AS shows, ) AS shows,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'name', related_ar.name_string, 'name',
'url', related_ar.slug, related_ar.name_string,
'country', related_ar.country, 'url',
'total_plays', to_char(related_ar.total_plays, 'FM999,999,999,999'), related_ar.slug,
'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), 'country',
'grid', json_build_object( related_ar.country,
'title', related_ar.name_string, 'total_plays',
'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), to_char(related_ar.total_plays, 'FM999,999,999,999'),
'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, 'image',
'subtext', CASE WHEN related_ar.total_plays > 0 THEN CONCAT(to_char(related_ar.total_plays, 'FM999,999,999,999'), ' plays') ELSE NULL END, CONCAT(globals.cdn_url, '/', df_related.filename_disk),
'url', related_ar.slug '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' 'type',
'music'
) )
ORDER BY related_ar.total_plays DESC ORDER BY
related_ar.total_plays DESC
) )
FROM related_artists ra FROM
related_artists ra
LEFT JOIN artists related_ar ON ra.related_artists_id = related_ar.id 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 LEFT JOIN directus_files df_related ON related_ar.art = df_related.id
WHERE ra.artists_id = ar.id WHERE
ra.artists_id = ar.id
) AS related_artists, ) AS related_artists,
json_build_object( json_build_object(
'title', CONCAT('Artist • ', ar.name_string, '', globals.site_name), 'title',
'description', LEFT( CONCAT(
'Artist • ',
ar.name_string,
'',
globals.site_name
),
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace(ar.description, E'[*_`~#>-]', '', 'g'), regexp_replace(ar.description, E'[*_`~#>-]', '', 'g'),
E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' E'\\[(.*?)\\]\\((.*?)\\)',
E'\\1',
'g'
), ),
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
'',
'g'
), ),
250 250
), ),
'open_graph_image', CASE 'open_graph_image',
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk) CASE
WHEN df.filename_disk IS NOT NULL
AND df.filename_disk != ''
AND df.filename_disk != '/' THEN CONCAT('/', df.filename_disk)
ELSE NULL ELSE NULL
END, END,
'url', CONCAT(globals.url, ar.slug), 'url',
'type', 'artist' CONCAT(globals.url, ar.slug),
'type',
'artist'
) AS metadata ) AS metadata
FROM artists ar FROM
artists ar
LEFT JOIN directus_files df ON ar.art = df.id LEFT JOIN directus_files df ON ar.art = df.id
LEFT JOIN genres g ON ar.genres = g.id LEFT JOIN genres g ON ar.genres = g.id
CROSS JOIN optimized_globals globals 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; GROUP BY
ar.id,
df.filename_disk,
g.name,
g.slug,
g.emoji,
globals.cdn_url,
globals.site_name,
globals.url;

View file

@ -2,12 +2,22 @@ CREATE OR REPLACE VIEW optimized_concerts AS
SELECT SELECT
c.id, c.id,
c.date, c.date,
CASE WHEN c.artist IS NOT NULL THEN CASE
json_build_object('name', a.name_string, 'url', a.slug) WHEN c.artist IS NOT NULL THEN json_build_object('name', a.name_string, 'url', a.slug)
ELSE ELSE json_build_object('name', c.artist_name_string, 'url', NULL)
json_build_object('name', c.artist_name_string, 'url', NULL)
END AS artist, 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 c.notes AS concert_notes
FROM FROM
concerts c concerts c

View file

@ -8,131 +8,216 @@ SELECT
g.wiki_link, g.wiki_link,
g.slug AS url, g.slug AS url,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'name', a.name_string, 'name',
'url', a.slug, a.name_string,
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), 'url',
'total_plays', to_char(a.total_plays, 'FM999,999,999,999'), a.slug,
'grid', json_build_object( 'image',
'title', a.name_string, CONCAT(globals.cdn_url, '/', df_artist.filename_disk),
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), 'total_plays',
'alt', CASE to_char(a.total_plays, 'FM999,999,999,999'),
WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays of ', a.name_string) '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) ELSE CONCAT('Artwork of ', a.name_string)
END, END,
'subtext', CASE 'subtext',
WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays') CASE
WHEN a.total_plays > 0 THEN CONCAT(
to_char(a.total_plays, 'FM999,999,999,999'),
' plays'
)
ELSE NULL ELSE NULL
END, END,
'url', a.slug 'url',
a.slug
), ),
'type', 'music' 'type',
'music'
) )
ORDER BY a.total_plays DESC ORDER BY
a.total_plays DESC
) )
FROM artists a FROM
artists a
LEFT JOIN directus_files df_artist ON a.art = df_artist.id LEFT JOIN directus_files df_artist ON a.art = df_artist.id
WHERE a.genres = g.id WHERE
a.genres = g.id
) AS artists, ) AS artists,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', b.title, 'title',
'author', b.author, b.title,
'url', b.slug, 'author',
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), b.author,
'grid', json_build_object( 'url',
'title', NULL, b.slug,
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), 'image',
'alt', CONCAT('Cover for ', b.title, ' by ', b.author), CONCAT(globals.cdn_url, '/', df_book.filename_disk),
'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating ELSE NULL END, 'grid',
'url', b.slug 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' 'type',
'books'
) )
ORDER BY b.title ASC ORDER BY
b.title ASC
) )
FROM books b FROM
books b
JOIN genres_books gb ON gb.books_id = b.id JOIN genres_books gb ON gb.books_id = b.id
LEFT JOIN directus_files df_book ON b.art = df_book.id LEFT JOIN directus_files df_book ON b.art = df_book.id
WHERE gb.genres_id = g.id WHERE
gb.genres_id = g.id
AND LOWER(b.read_status) = 'finished' AND LOWER(b.read_status) = 'finished'
) AS books, ) AS books,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', m.title, 'title',
'year', m.year, m.title,
'url', m.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), m.year,
'grid', json_build_object( 'url',
'title', NULL, m.slug,
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), 'image',
'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), CONCAT(globals.cdn_url, '/', df_movie.filename_disk),
'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, 'grid',
'url', m.slug 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' 'type',
'movies'
) )
ORDER BY m.year ASC ORDER BY
m.year ASC
) )
FROM movies m FROM
movies m
JOIN genres_movies gm ON gm.movies_id = m.id JOIN genres_movies gm ON gm.movies_id = m.id
LEFT JOIN directus_files df_movie ON m.art = df_movie.id LEFT JOIN directus_files df_movie ON m.art = df_movie.id
WHERE gm.genres_id = g.id WHERE
gm.genres_id = g.id
AND m.last_watched IS NOT NULL AND m.last_watched IS NOT NULL
) AS movies, ) AS movies,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', p.title, 'title',
'date', p.date, p.title,
'url', p.slug, 'date',
'grid', json_build_object( p.date,
'title', p.title, 'url',
'image', CONCAT(globals.cdn_url, '/', df_post.filename_disk), p.slug,
'alt', p.title, 'grid',
'subtext', TO_CHAR(p.date, 'FMMonth DD, YYYY'), json_build_object(
'url', p.slug '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' 'type',
'posts'
) )
ORDER BY p.date DESC ORDER BY
p.date DESC
) )
FROM posts_genres pg FROM
posts_genres pg
LEFT JOIN posts p ON pg.posts_id = p.id LEFT JOIN posts p ON pg.posts_id = p.id
LEFT JOIN directus_files df_post ON p.image = df_post.id LEFT JOIN directus_files df_post ON p.image = df_post.id
WHERE pg.genres_id = g.id WHERE
pg.genres_id = g.id
) AS posts, ) AS posts,
json_build_object( json_build_object(
'title', CONCAT('Genre • ', g.name, '', globals.site_name), 'title',
'description', LEFT( CONCAT('Genre • ', g.name, '', globals.site_name),
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(g.description, E'[*_`~#>-]', '', 'g'),
g.description, E'\\[(.*?)\\]\\((.*?)\\)',
E'[*_`~#>-]', '', 'g' E'\\1',
'g'
), ),
E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
), '',
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' 'g'
), ),
250 250
), ),
'open_graph_image', ( 'open_graph_image',
SELECT CONCAT('/', df_artist.filename_disk) (
FROM artists a SELECT
CONCAT('/', df_artist.filename_disk)
FROM
artists a
LEFT JOIN directus_files df_artist ON a.art = df_artist.id LEFT JOIN directus_files df_artist ON a.art = df_artist.id
WHERE a.genres = g.id WHERE
a.genres = g.id
AND df_artist.filename_disk IS NOT NULL AND df_artist.filename_disk IS NOT NULL
AND df_artist.filename_disk != '' AND df_artist.filename_disk != ''
ORDER BY a.total_plays DESC ORDER BY
LIMIT 1 a.total_plays DESC
LIMIT
1
), ),
'url', CONCAT(globals.url, g.slug), 'url',
'type', 'genre' CONCAT(globals.url, g.slug),
'type',
'genre'
) AS metadata ) AS metadata
FROM genres g FROM
genres g
CROSS JOIN optimized_globals globals CROSS JOIN optimized_globals globals
ORDER BY g.id ASC; ORDER BY
g.id ASC;

View file

@ -9,11 +9,9 @@ SELECT
NULL::FLOAT AS progress_ticks NULL::FLOAT AS progress_ticks
FROM FROM
listens l listens l
JOIN JOIN artists a ON l.artist_name = a.name_string
artists a LEFT JOIN genres g ON a.genres = g.id
ON l.artist_name = a.name_string ORDER BY
LEFT JOIN l.listened_at DESC
genres g LIMIT
ON a.genres = g.id 1;
ORDER BY l.listened_at DESC
LIMIT 1;

View file

@ -1,9 +1,15 @@
CREATE OR REPLACE VIEW optimized_listens AS CREATE OR REPLACE VIEW optimized_listens AS
SELECT DISTINCT ON (l.id, l.listened_at, l.track_name, l.artist_name, l.album_name) SELECT DISTINCT
ON (
l.id, l.id,
l.listened_at, l.listened_at,
l.track_name, l.track_name,
l.artist_name, l.artist_name,
l.album_name
) l.id,
l.listened_at,
l.track_name,
l.artist_name,
l.album_name, l.album_name,
l.album_key, l.album_key,
CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS artist_art, CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS artist_art,

View file

@ -6,16 +6,23 @@ SELECT
ol.album_art, ol.album_art,
ol.artist_url, ol.artist_url,
json_build_object( json_build_object(
'title', ol.album_name, 'title',
'image', ol.album_art, ol.album_name,
'url', ol.artist_url, 'image',
'alt', CONCAT(ol.album_name, ' by ', ol.artist_name), ol.album_art,
'subtext', ol.artist_name 'url',
ol.artist_url,
'alt',
CONCAT(ol.album_name, ' by ', ol.artist_name),
'subtext',
ol.artist_name
) AS grid, ) AS grid,
json_build_object( json_build_object(
'open_graph_image', 'open_graph_image',
CASE 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 ELSE NULL
END END
) AS metadata ) AS metadata

View file

@ -6,16 +6,23 @@ SELECT
ol.artist_url, ol.artist_url,
ARRAY_AGG(DISTINCT ol.genre_name) AS genres, ARRAY_AGG(DISTINCT ol.genre_name) AS genres,
json_build_object( json_build_object(
'title', ol.artist_name, 'title',
'image', ol.artist_art, ol.artist_name,
'url', ol.artist_url, 'image',
'alt', CONCAT(COUNT(*), ' plays of ', ol.artist_name), ol.artist_art,
'subtext', CONCAT(COUNT(*), ' plays') 'url',
ol.artist_url,
'alt',
CONCAT(COUNT(*), ' plays of ', ol.artist_name),
'subtext',
CONCAT(COUNT(*), ' plays')
) AS grid, ) AS grid,
json_build_object( json_build_object(
'open_graph_image', 'open_graph_image',
CASE 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 ELSE NULL
END END
) AS metadata ) AS metadata

View file

@ -3,7 +3,12 @@ SELECT
ol.genre_name, ol.genre_name,
ol.genre_url, ol.genre_url,
COUNT(*) AS plays, 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 FROM
optimized_listens ol optimized_listens ol
WHERE WHERE
@ -13,4 +18,3 @@ GROUP BY
ol.genre_url ol.genre_url
ORDER BY ORDER BY
plays DESC; plays DESC;

View file

@ -1,5 +1,6 @@
CREATE OR REPLACE VIEW month_tracks AS CREATE OR REPLACE VIEW month_tracks AS
WITH track_stats AS ( WITH
track_stats AS (
SELECT SELECT
ol.track_name, ol.track_name,
ol.artist_name, ol.artist_name,
@ -28,10 +29,24 @@ SELECT
last_listened, last_listened,
album_art, album_art,
artist_url, 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 FROM
track_stats track_stats
ORDER BY ORDER BY
plays DESC, plays DESC,
last_listened DESC; last_listened DESC;

View file

@ -13,11 +13,23 @@ SELECT
ol.album_art, ol.album_art,
ol.artist_url, ol.artist_url,
ol.genre_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 FROM
optimized_listens ol optimized_listens ol
WHERE WHERE
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days' TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days'
ORDER BY ORDER BY
TO_TIMESTAMP(ol.listened_at) DESC; TO_TIMESTAMP(ol.listened_at) DESC;

View file

@ -6,16 +6,23 @@ SELECT
ol.album_art, ol.album_art,
ol.artist_url, ol.artist_url,
json_build_object( json_build_object(
'title', ol.album_name, 'title',
'image', ol.album_art, ol.album_name,
'url', ol.artist_url, 'image',
'alt', CONCAT(ol.album_name, ' by ', ol.artist_name), ol.album_art,
'subtext', ol.artist_name 'url',
ol.artist_url,
'alt',
CONCAT(ol.album_name, ' by ', ol.artist_name),
'subtext',
ol.artist_name
) AS grid, ) AS grid,
json_build_object( json_build_object(
'open_graph_image', 'open_graph_image',
CASE 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 ELSE NULL
END END
) AS metadata ) AS metadata

View file

@ -6,16 +6,23 @@ SELECT
ol.artist_url, ol.artist_url,
ARRAY_AGG(DISTINCT ol.genre_name) AS genres, ARRAY_AGG(DISTINCT ol.genre_name) AS genres,
json_build_object( json_build_object(
'title', ol.artist_name, 'title',
'image', ol.artist_art, ol.artist_name,
'url', ol.artist_url, 'image',
'alt', CONCAT(COUNT(*), ' plays of ', ol.artist_name), ol.artist_art,
'subtext', CONCAT(COUNT(*), ' plays') 'url',
ol.artist_url,
'alt',
CONCAT(COUNT(*), ' plays of ', ol.artist_name),
'subtext',
CONCAT(COUNT(*), ' plays')
) AS grid, ) AS grid,
json_build_object( json_build_object(
'open_graph_image', 'open_graph_image',
CASE 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 ELSE NULL
END END
) AS metadata ) AS metadata

View file

@ -3,7 +3,12 @@ SELECT
ol.genre_name, ol.genre_name,
ol.genre_url, ol.genre_url,
COUNT(*) AS plays, 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 FROM
optimized_listens ol optimized_listens ol
WHERE WHERE
@ -13,4 +18,3 @@ GROUP BY
ol.genre_url ol.genre_url
ORDER BY ORDER BY
plays DESC; plays DESC;

View file

@ -1,34 +1,111 @@
CREATE OR REPLACE VIEW optimized_week_music AS CREATE OR REPLACE VIEW optimized_week_music AS
SELECT json_build_object( SELECT
'week_artists', ( json_build_object(
SELECT json_agg(a ORDER BY a.plays DESC) 'week_artists',
FROM ( (
SELECT * FROM week_artists ORDER BY plays DESC LIMIT 8 SELECT
json_agg(
a
ORDER BY
a.plays DESC
)
FROM
(
SELECT
*
FROM
week_artists
ORDER BY
plays DESC
LIMIT
8
) a ) a
), ),
'week_albums', ( 'week_albums',
SELECT json_agg(al ORDER BY al.plays DESC) (
FROM ( SELECT
SELECT * FROM week_albums ORDER BY plays DESC LIMIT 8 json_agg(
al
ORDER BY
al.plays DESC
)
FROM
(
SELECT
*
FROM
week_albums
ORDER BY
plays DESC
LIMIT
8
) al ) al
), ),
'week_genres', ( 'week_genres',
SELECT json_agg(g ORDER BY g.plays DESC) (
FROM ( SELECT
SELECT * FROM week_genres ORDER BY plays DESC LIMIT 5 json_agg(
g
ORDER BY
g.plays DESC
)
FROM
(
SELECT
*
FROM
week_genres
ORDER BY
plays DESC
LIMIT
5
) g ) g
), ),
'recent_tracks', ( 'recent_tracks',
SELECT json_agg(r ORDER BY r.listened_at DESC) (
FROM ( SELECT
SELECT * FROM recent_tracks ORDER BY listened_at DESC LIMIT 10 json_agg(
r
ORDER BY
r.listened_at DESC
)
FROM
(
SELECT
*
FROM
recent_tracks
ORDER BY
listened_at DESC
LIMIT
10
) r ) r
), ),
'week_summary', ( 'week_summary',
SELECT json_build_object( (
'total_tracks', (SELECT COUNT(*) FROM week_tracks), SELECT
'total_artists', (SELECT COUNT(*) FROM week_artists), json_build_object(
'total_albums', (SELECT COUNT(*) FROM week_albums) '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;

View file

@ -1,5 +1,6 @@
CREATE OR REPLACE VIEW week_tracks AS CREATE OR REPLACE VIEW week_tracks AS
WITH track_stats AS ( WITH
track_stats AS (
SELECT SELECT
ol.track_name, ol.track_name,
ol.artist_name, ol.artist_name,
@ -9,7 +10,11 @@ WITH track_stats AS (
ol.album_art, ol.album_art,
ol.artist_url, ol.artist_url,
MAX(COUNT(*)) OVER () AS most_played, MAX(COUNT(*)) OVER () AS most_played,
RANK() OVER (ORDER BY COUNT(*) DESC, MAX(ol.listened_at) DESC) AS rank RANK() OVER (
ORDER BY
COUNT(*) DESC,
MAX(ol.listened_at) DESC
) AS rank
FROM FROM
optimized_listens ol optimized_listens ol
WHERE WHERE
@ -30,14 +35,22 @@ SELECT
album_art, album_art,
artist_url, artist_url,
json_build_object( json_build_object(
'title', track_name, 'title',
'artist', artist_name, track_name,
'url', artist_url, 'artist',
'plays', plays, artist_name,
'alt', CONCAT(track_name, ' by ', artist_name), 'url',
'subtext', CONCAT(album_name, ' (', plays, ' plays)'), artist_url,
'percentage', ROUND((plays::decimal / most_played) * 100, 2), 'plays',
'rank', rank 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 ) AS chart
FROM FROM
track_stats track_stats

View file

@ -1,19 +1,28 @@
CREATE OR REPLACE VIEW optimized_recent_media AS CREATE OR REPLACE VIEW optimized_recent_media AS
WITH ordered_artists AS ( WITH
ordered_artists AS (
SELECT SELECT
wa.artist_name, wa.artist_name,
wa.artist_art, wa.artist_art,
wa.artist_url, wa.artist_url,
wa.plays, wa.plays,
json_build_object( json_build_object(
'title', wa.artist_name, 'title',
'image', wa.artist_art, wa.artist_name,
'url', wa.artist_url, 'image',
'alt', CONCAT(wa.plays, ' plays of ', wa.artist_name), wa.artist_art,
'subtext', CONCAT(wa.plays, ' plays') 'url',
wa.artist_url,
'alt',
CONCAT(wa.plays, ' plays of ', wa.artist_name),
'subtext',
CONCAT(wa.plays, ' plays')
) AS grid ) AS grid
FROM week_artists wa FROM
ORDER BY wa.plays DESC, wa.artist_name ASC week_artists wa
ORDER BY
wa.plays DESC,
wa.artist_name ASC
), ),
ordered_albums AS ( ordered_albums AS (
SELECT SELECT
@ -23,17 +32,35 @@ ordered_albums AS (
wa.artist_url, wa.artist_url,
wa.plays, wa.plays,
json_build_object( json_build_object(
'title', wa.album_name, 'title',
'image', wa.album_art, wa.album_name,
'url', wa.artist_url, 'image',
'alt', CONCAT(wa.album_name, ' by ', wa.artist_name, ' (', wa.plays, ' plays)'), wa.album_art,
'subtext', wa.artist_name 'url',
wa.artist_url,
'alt',
CONCAT(
wa.album_name,
' by ',
wa.artist_name,
' (',
wa.plays,
' plays)'
),
'subtext',
wa.artist_name
) AS grid ) AS grid
FROM week_albums wa FROM
ORDER BY wa.plays DESC, wa.album_name ASC week_albums wa
ORDER BY
wa.plays DESC,
wa.album_name ASC
), ),
recent_music AS ( recent_music AS (
SELECT * FROM ( SELECT
*
FROM
(
( (
SELECT SELECT
artist_name AS title, artist_name AS title,
@ -42,8 +69,10 @@ recent_music AS (
'music' AS type, 'music' AS type,
1 AS rank, 1 AS rank,
grid grid
FROM ordered_artists FROM
LIMIT 1 ordered_artists
LIMIT
1
) )
UNION ALL UNION ALL
( (
@ -54,8 +83,10 @@ recent_music AS (
'music' AS type, 'music' AS type,
2 AS rank, 2 AS rank,
grid grid
FROM ordered_albums FROM
LIMIT 1 ordered_albums
LIMIT
1
) )
UNION ALL UNION ALL
( (
@ -66,8 +97,12 @@ recent_music AS (
'music' AS type, 'music' AS type,
3 AS rank, 3 AS rank,
grid grid
FROM ordered_artists FROM
OFFSET 1 LIMIT 1 ordered_artists
OFFSET
1
LIMIT
1
) )
UNION ALL UNION ALL
( (
@ -78,13 +113,20 @@ recent_music AS (
'music' AS type, 'music' AS type,
4 AS rank, 4 AS rank,
grid grid
FROM ordered_albums FROM
OFFSET 1 LIMIT 1 ordered_albums
OFFSET
1
LIMIT
1
) )
) AS recent_music_subquery ) AS recent_music_subquery
), ),
recent_watched_read AS ( recent_watched_read AS (
SELECT * FROM ( SELECT
*
FROM
(
( (
SELECT SELECT
om.title, om.title,
@ -93,21 +135,31 @@ recent_watched_read AS (
'tv' AS type, 'tv' AS type,
1 AS rank, 1 AS rank,
json_build_object( json_build_object(
'title', NULL, 'title',
'url', om.url, NULL,
'image', om.image, 'url',
'backdrop', om.backdrop, om.url,
'alt', CONCAT('Poster from ', om.title, ' (', om.year, ')'), 'image',
'subtext', CASE WHEN om.rating IS NOT NULL THEN om.image,
om.rating::text 'backdrop',
ELSE om.backdrop,
om.year::text '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 END
) AS grid ) AS grid
FROM optimized_movies om FROM
WHERE om.last_watched IS NOT NULL optimized_movies om
ORDER BY om.last_watched DESC, om.title ASC WHERE
LIMIT 1 om.last_watched IS NOT NULL
ORDER BY
om.last_watched DESC,
om.title ASC
LIMIT
1
) )
UNION ALL UNION ALL
( (
@ -118,22 +170,39 @@ recent_watched_read AS (
'tv' AS type, 'tv' AS type,
2 AS rank, 2 AS rank,
json_build_object( json_build_object(
'title', NULL, 'title',
'image', os.image, NULL,
'url', os.url, 'image',
'alt', CONCAT('Poster from ', os.title), os.image,
'subtext', ( 'url',
SELECT CONCAT('S', e.season_number, 'E', e.episode_number) os.url,
FROM episodes e 'alt',
WHERE e.show = os.id CONCAT('Poster from ', os.title),
ORDER BY e.last_watched_at DESC, e.season_number DESC, e.episode_number DESC 'subtext',
LIMIT 1 (
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 ) AS grid
FROM optimized_shows os FROM
WHERE os.last_watched_at IS NOT NULL optimized_shows os
ORDER BY os.last_watched_at DESC, os.title ASC WHERE
LIMIT 1 os.last_watched_at IS NOT NULL
ORDER BY
os.last_watched_at DESC,
os.title ASC
LIMIT
1
) )
UNION ALL UNION ALL
( (
@ -144,20 +213,29 @@ recent_watched_read AS (
'books' AS type, 'books' AS type,
3 AS rank, 3 AS rank,
json_build_object( json_build_object(
'title', NULL, 'title',
'image', ob.image, NULL,
'url', ob.url, 'image',
'alt', CONCAT('Book cover from ', ob.title, ' by ', ob.author), ob.image,
'subtext', CASE WHEN ob.rating IS NOT NULL THEN 'url',
ob.rating ob.url,
ELSE 'alt',
NULL CONCAT('Book cover from ', ob.title, ' by ', ob.author),
'subtext',
CASE
WHEN ob.rating IS NOT NULL THEN ob.rating
ELSE NULL
END END
) AS grid ) AS grid
FROM optimized_books ob FROM
WHERE ob.status = 'finished' optimized_books ob
ORDER BY ob.date_finished DESC, ob.title ASC WHERE
LIMIT 1 ob.status = 'finished'
ORDER BY
ob.date_finished DESC,
ob.title ASC
LIMIT
1
) )
UNION ALL UNION ALL
( (
@ -168,21 +246,33 @@ recent_watched_read AS (
'tv' AS type, 'tv' AS type,
4 AS rank, 4 AS rank,
json_build_object( json_build_object(
'title', NULL, 'title',
'url', om.url, NULL,
'image', om.image, 'url',
'backdrop', om.backdrop, om.url,
'alt', CONCAT('Poster from ', om.title, ' (', om.year, ')'), 'image',
'subtext', CASE WHEN om.rating IS NOT NULL THEN om.image,
om.rating::text 'backdrop',
ELSE om.backdrop,
om.year::text '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 END
) AS grid ) AS grid
FROM optimized_movies om FROM
WHERE om.last_watched IS NOT NULL optimized_movies om
ORDER BY om.last_watched DESC, om.title ASC WHERE
OFFSET 1 LIMIT 1 om.last_watched IS NOT NULL
ORDER BY
om.last_watched DESC,
om.title ASC
OFFSET
1
LIMIT
1
) )
UNION ALL UNION ALL
( (
@ -193,22 +283,41 @@ recent_watched_read AS (
'tv' AS type, 'tv' AS type,
5 AS rank, 5 AS rank,
json_build_object( json_build_object(
'title', NULL, 'title',
'image', os.image, NULL,
'url', os.url, 'image',
'alt', CONCAT('Poster from ', os.title), os.image,
'subtext', ( 'url',
SELECT CONCAT('S', e.season_number, 'E', e.episode_number) os.url,
FROM episodes e 'alt',
WHERE e.show = os.id CONCAT('Poster from ', os.title),
ORDER BY e.last_watched_at DESC, e.season_number DESC, e.episode_number DESC 'subtext',
LIMIT 1 (
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 ) AS grid
FROM optimized_shows os FROM
WHERE os.last_watched_at IS NOT NULL optimized_shows os
ORDER BY os.last_watched_at DESC, os.title ASC WHERE
OFFSET 1 LIMIT 1 os.last_watched_at IS NOT NULL
ORDER BY
os.last_watched_at DESC,
os.title ASC
OFFSET
1
LIMIT
1
) )
UNION ALL UNION ALL
( (
@ -219,30 +328,56 @@ recent_watched_read AS (
'books' AS type, 'books' AS type,
6 AS rank, 6 AS rank,
json_build_object( json_build_object(
'title', NULL, 'title',
'image', ob.image, NULL,
'url', ob.url, 'image',
'alt', CONCAT('Book cover from ', ob.title, ' by ', ob.author), ob.image,
'subtext', CASE WHEN ob.rating IS NOT NULL THEN 'url',
ob.rating ob.url,
ELSE 'alt',
NULL CONCAT('Book cover from ', ob.title, ' by ', ob.author),
'subtext',
CASE
WHEN ob.rating IS NOT NULL THEN ob.rating
ELSE NULL
END END
) AS grid ) AS grid
FROM optimized_books ob FROM
WHERE ob.status = 'finished' optimized_books ob
ORDER BY ob.date_finished DESC, ob.title ASC WHERE
OFFSET 1 LIMIT 1 ob.status = 'finished'
ORDER BY
ob.date_finished DESC,
ob.title ASC
OFFSET
1
LIMIT
1
) )
) AS recent_watched_read_subquery ) AS recent_watched_read_subquery
) )
SELECT json_build_object( SELECT
'recentMusic', ( json_build_object(
SELECT json_agg(m.* ORDER BY m.rank) 'recentMusic',
FROM recent_music m (
SELECT
json_agg(
m.*
ORDER BY
m.rank
)
FROM
recent_music m
), ),
'recentWatchedRead', ( 'recentWatchedRead',
SELECT json_agg(w.* ORDER BY w.rank) (
FROM recent_watched_read w SELECT
json_agg(
w.*
ORDER BY
w.rank
)
FROM
recent_watched_read w
) )
) AS recent_activity; ) AS recent_activity;

View file

@ -1,10 +1,14 @@
CREATE OR REPLACE VIEW optimized_last_watched_episodes AS CREATE OR REPLACE VIEW optimized_last_watched_episodes AS
SELECT DISTINCT ON (e.show) SELECT DISTINCT
e.show AS show_id, ON (e.show) e.show AS show_id,
e.season_number, e.season_number,
e.episode_number, e.episode_number,
e.last_watched_at, e.last_watched_at,
CONCAT('S', e.season_number, 'E', e.episode_number) AS last_watched_episode CONCAT('S', e.season_number, 'E', e.episode_number) AS last_watched_episode
FROM episodes e FROM
WHERE e.last_watched_at IS NOT NULL episodes e
ORDER BY e.show, e.last_watched_at DESC; WHERE
e.last_watched_at IS NOT NULL
ORDER BY
e.show,
e.last_watched_at DESC;

View file

@ -6,21 +6,38 @@ SELECT
se.status, se.status,
se.air_date, se.air_date,
( (
SELECT CONCAT('S', se2.season_number, 'E', se2.episode_number) SELECT
FROM scheduled_episodes se2 CONCAT('S', se2.season_number, 'E', se2.episode_number)
WHERE se2.show_id = se.show_id FROM
scheduled_episodes se2
WHERE
se2.show_id = se.show_id
AND se2.status IN ('upcoming', 'aired') AND se2.status IN ('upcoming', 'aired')
ORDER BY se2.air_date ASC ORDER BY
LIMIT 1 se2.air_date ASC
LIMIT
1
) AS next_scheduled_episode, ) AS next_scheduled_episode,
( (
SELECT se2.air_date SELECT
FROM scheduled_episodes se2 se2.air_date
WHERE se2.show_id = se.show_id FROM
scheduled_episodes se2
WHERE
se2.show_id = se.show_id
AND se2.status IN ('upcoming', 'aired') AND se2.status IN ('upcoming', 'aired')
ORDER BY se2.air_date ASC ORDER BY
LIMIT 1 se2.air_date ASC
LIMIT
1
) AS next_air_date ) AS next_air_date
FROM scheduled_episodes se FROM
WHERE se.status IN ('upcoming', 'aired') scheduled_episodes se
GROUP BY se.show_id, se.season_number, se.episode_number, se.status, se.air_date; WHERE
se.status IN ('upcoming', 'aired')
GROUP BY
se.show_id,
se.season_number,
se.episode_number,
se.status,
se.air_date;

View file

@ -1,7 +1,12 @@
CREATE OR REPLACE VIEW optimized_scheduled_shows AS CREATE OR REPLACE VIEW optimized_scheduled_shows AS
SELECT json_build_object( SELECT
'watching', ( json_build_object(
SELECT json_agg(watching) FROM ( 'watching',
(
SELECT
json_agg(watching)
FROM
(
SELECT SELECT
s.id, s.id,
s.tmdb_id, s.tmdb_id,
@ -12,121 +17,217 @@ SELECT json_build_object(
CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image, CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image,
CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop, CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop,
json_build_object( json_build_object(
'title', s.title, 'title',
'image', CONCAT(globals.cdn_url, '/', df_art.filename_disk), s.title,
'backdrop', CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), 'image',
'url', s.slug, CONCAT(globals.cdn_url, '/', df_art.filename_disk),
'alt', CONCAT('Poster from ', s.title), 'backdrop',
'subtext', COALESCE( CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk),
(SELECT CONCAT( 'url',
'S', se.season_number, 'E', se.episode_number, '', s.slug,
'alt',
CONCAT('Poster from ', s.title),
'subtext',
COALESCE(
(
SELECT
CONCAT(
'S',
se.season_number,
'E',
se.episode_number,
'',
CASE CASE
WHEN EXTRACT(YEAR FROM se.air_date) < EXTRACT(YEAR FROM CURRENT_DATE) WHEN EXTRACT(
THEN TO_CHAR(se.air_date, 'FMMM/FMDD/YY') 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') ELSE TO_CHAR(se.air_date, 'FMMM/FMDD')
END END
) )
FROM scheduled_episodes se FROM
WHERE se.show_id = s.id scheduled_episodes se
WHERE
se.show_id = s.id
AND se.status IN ('upcoming', 'aired') AND se.status IN ('upcoming', 'aired')
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 FROM episodes e SELECT
WHERE e.show = s.id 1
FROM
episodes e
WHERE
e.show = s.id
AND e.season_number = se.season_number AND e.season_number = se.season_number
AND e.episode_number = se.episode_number AND e.episode_number = se.episode_number
) )
ORDER BY se.season_number ASC, se.episode_number ASC ORDER BY
LIMIT 1), se.season_number ASC,
(SELECT CONCAT( se.episode_number ASC
'S', e.season_number, 'E', e.episode_number, '', LIMIT
1
),
(
SELECT
CONCAT(
'S',
e.season_number,
'E',
e.episode_number,
'',
CASE CASE
WHEN EXTRACT(YEAR FROM e.last_watched_at) < EXTRACT(YEAR FROM CURRENT_DATE) WHEN EXTRACT(
THEN TO_CHAR(e.last_watched_at, 'FMMM/FMDD/YY') 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') ELSE TO_CHAR(e.last_watched_at, 'FMMM/FMDD')
END END
) )
FROM episodes e FROM
WHERE e.show = s.id episodes e
ORDER BY e.last_watched_at DESC, e.season_number DESC, e.episode_number DESC WHERE
LIMIT 1), e.show = s.id
ORDER BY
e.last_watched_at DESC,
e.season_number DESC,
e.episode_number DESC
LIMIT
1
),
s.year::text s.year::text
) )
) AS grid, ) AS grid,
json_build_object( json_build_object(
'title', CONCAT('Show • ', s.title, '', globals.site_name), 'title',
'description', LEFT( CONCAT('Show • ', s.title, '', globals.site_name),
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace(s.description, E'[*_`~#>-]', '', 'g'), regexp_replace(s.description, E'[*_`~#>-]', '', 'g'),
E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' E'\\[(.*?)\\]\\((.*?)\\)',
E'\\1',
'g'
), ),
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
'',
'g'
), ),
250 250
), ),
'open_graph_image', CASE 'open_graph_image',
WHEN df_backdrop.filename_disk IS NOT NULL AND df_backdrop.filename_disk != '' AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) 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 ELSE NULL
END, END,
'url', CONCAT(globals.url, s.slug), 'url',
'type', 'scheduled_show' CONCAT(globals.url, s.slug),
'type',
'scheduled_show'
) AS metadata, ) AS metadata,
CASE CASE
WHEN ( WHEN (
SELECT se.air_date SELECT
FROM scheduled_episodes se se.air_date
WHERE se.show_id = s.id FROM
scheduled_episodes se
WHERE
se.show_id = s.id
AND se.status IN ('upcoming', 'aired') AND se.status IN ('upcoming', 'aired')
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 FROM episodes e SELECT
WHERE e.show = s.id 1
FROM
episodes e
WHERE
e.show = s.id
AND e.season_number = se.season_number AND e.season_number = se.season_number
AND e.episode_number = se.episode_number AND e.episode_number = se.episode_number
) )
ORDER BY se.season_number ASC, se.episode_number ASC ORDER BY
LIMIT 1 se.season_number ASC,
) >= NOW() se.episode_number ASC
THEN ( LIMIT
SELECT se.air_date::timestamp 1
FROM scheduled_episodes se ) >= NOW() THEN (
WHERE se.show_id = s.id SELECT
se.air_date::timestamp
FROM
scheduled_episodes se
WHERE
se.show_id = s.id
AND se.status IN ('upcoming', 'aired') AND se.status IN ('upcoming', 'aired')
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 FROM episodes e SELECT
WHERE e.show = s.id 1
FROM
episodes e
WHERE
e.show = s.id
AND e.season_number = se.season_number AND e.season_number = se.season_number
AND e.episode_number = se.episode_number AND e.episode_number = se.episode_number
) )
ORDER BY se.season_number ASC, se.episode_number ASC ORDER BY
LIMIT 1 se.season_number ASC,
se.episode_number ASC
LIMIT
1
) )
ELSE ( ELSE (
SELECT MIN(e.last_watched_at)::timestamp SELECT
FROM episodes e MIN(e.last_watched_at)::timestamp
WHERE e.show = s.id FROM
episodes e
WHERE
e.show = s.id
) )
END AS sort_date END AS sort_date
FROM shows s FROM
shows s
LEFT JOIN directus_files df_art ON s.art = df_art.id LEFT JOIN directus_files df_art ON s.art = df_art.id
LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id
CROSS JOIN optimized_globals globals CROSS JOIN optimized_globals globals
WHERE s.ongoing = true WHERE
s.ongoing = true
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT
FROM scheduled_episodes se 1
WHERE se.show_id = s.id FROM
scheduled_episodes se
WHERE
se.show_id = s.id
AND se.status IN ('upcoming', 'aired') AND se.status IN ('upcoming', 'aired')
) )
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT
FROM episodes e 1
WHERE e.show = s.id FROM
episodes e
WHERE
e.show = s.id
) )
ORDER BY sort_date ASC NULLS LAST, s.title ASC NULLS LAST ORDER BY
sort_date ASC NULLS LAST,
s.title ASC NULLS LAST
) watching ) watching
), ),
'unstarted', ( 'unstarted',
SELECT json_agg(unstarted) FROM ( (
SELECT
json_agg(unstarted)
FROM
(
SELECT SELECT
s.id, s.id,
s.tmdb_id, s.tmdb_id,
@ -137,69 +238,115 @@ SELECT json_build_object(
CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image, CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image,
CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop, CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop,
json_build_object( json_build_object(
'title', s.title, 'title',
'image', CONCAT(globals.cdn_url, '/', df_art.filename_disk), s.title,
'backdrop', CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), 'image',
'url', s.slug, CONCAT(globals.cdn_url, '/', df_art.filename_disk),
'alt', CONCAT('Poster from ', s.title), 'backdrop',
'subtext', COALESCE( CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk),
'url',
s.slug,
'alt',
CONCAT('Poster from ', s.title),
'subtext',
COALESCE(
( (
SELECT CONCAT( SELECT
'S', se.season_number, 'E', se.episode_number, '', CONCAT(
'S',
se.season_number,
'E',
se.episode_number,
'',
CASE CASE
WHEN EXTRACT(YEAR FROM se.air_date) < EXTRACT(YEAR FROM CURRENT_DATE) WHEN EXTRACT(
THEN TO_CHAR(se.air_date, 'FMMM/FMDD/YY') 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') ELSE TO_CHAR(se.air_date, 'FMMM/FMDD')
END END
) )
FROM scheduled_episodes se FROM
WHERE se.show_id = s.id scheduled_episodes se
WHERE
se.show_id = s.id
AND se.status IN ('upcoming', 'aired') AND se.status IN ('upcoming', 'aired')
ORDER BY se.season_number ASC, se.episode_number ASC ORDER BY
LIMIT 1 se.season_number ASC,
se.episode_number ASC
LIMIT
1
), ),
s.year::text s.year::text
) )
) AS grid, ) AS grid,
json_build_object( json_build_object(
'title', CONCAT('Show • ', s.title, '', globals.site_name), 'title',
'description', LEFT( CONCAT('Show • ', s.title, '', globals.site_name),
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace(s.description, E'[*_`~#>-]', '', 'g'), regexp_replace(s.description, E'[*_`~#>-]', '', 'g'),
E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' E'\\[(.*?)\\]\\((.*?)\\)',
E'\\1',
'g'
), ),
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
'',
'g'
), ),
250 250
), ),
'open_graph_image', CASE 'open_graph_image',
WHEN df_backdrop.filename_disk IS NOT NULL AND df_backdrop.filename_disk != '' AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) 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 ELSE NULL
END, END,
'url', CONCAT(globals.url, s.slug), 'url',
'type', 'scheduled_show' CONCAT(globals.url, s.slug),
'type',
'scheduled_show'
) AS metadata ) AS metadata
FROM shows s FROM
shows s
LEFT JOIN directus_files df_art ON s.art = df_art.id LEFT JOIN directus_files df_art ON s.art = df_art.id
LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id
CROSS JOIN optimized_globals globals CROSS JOIN optimized_globals globals
WHERE s.ongoing = true WHERE
s.ongoing = true
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT
FROM scheduled_episodes se 1
WHERE se.show_id = s.id FROM
scheduled_episodes se
WHERE
se.show_id = s.id
AND se.status IN ('upcoming', 'aired') AND se.status IN ('upcoming', 'aired')
) )
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 SELECT
FROM episodes e 1
WHERE e.show = s.id FROM
episodes e
WHERE
e.show = s.id
) )
ORDER BY ( ORDER BY
SELECT MIN(se.air_date) (
FROM scheduled_episodes se SELECT
WHERE se.show_id = s.id MIN(se.air_date)
FROM
scheduled_episodes se
WHERE
se.show_id = s.id
AND se.status IN ('upcoming', 'aired') AND se.status IN ('upcoming', 'aired')
) ASC NULLS LAST ) ASC NULLS LAST
) unstarted ) unstarted

View file

@ -13,194 +13,355 @@ SELECT
CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image, CONCAT(globals.cdn_url, '/', df_art.filename_disk) AS image,
CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop, CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk) AS backdrop,
json_build_object( json_build_object(
'title', NULL, 'title',
'image', CONCAT(globals.cdn_url, '/', df_art.filename_disk), NULL,
'backdrop', CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), 'image',
'url', s.slug, CONCAT(globals.cdn_url, '/', df_art.filename_disk),
'alt', CONCAT('Artwork for ', s.title), 'backdrop',
'subtext', CASE CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk),
'url',
s.slug,
'alt',
CONCAT('Artwork for ', s.title),
'subtext',
CASE
WHEN ( WHEN (
SELECT MAX(e1.last_watched_at) SELECT
FROM episodes e1 MAX(e1.last_watched_at)
WHERE e1.show = s.id FROM
) >= NOW() - INTERVAL '90 days' THEN episodes e1
(SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) WHERE
FROM episodes e2 e1.show = s.id
WHERE e2.show = s.id ) >= NOW() - INTERVAL '90 days' THEN (
ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC SELECT
LIMIT 1) 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 ELSE s.year::text
END, END,
'type', 'tv' 'type',
'tv'
) AS grid, ) AS grid,
json_build_object( json_build_object(
'title', s.title, 'title',
'year', s.year, s.title,
'url', s.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_art.filename_disk), s.year,
'backdrop', CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk), 'url',
'formatted_episode', COALESCE(( s.slug,
SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) 'image',
FROM episodes e2 CONCAT(globals.cdn_url, '/', df_art.filename_disk),
WHERE e2.show = s.id 'backdrop',
ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC CONCAT(globals.cdn_url, '/', df_backdrop.filename_disk),
LIMIT 1 'formatted_episode',
), NULL), COALESCE(
'last_watched_at', ( (
SELECT MAX(e3.last_watched_at) SELECT
FROM episodes e3 CONCAT('S', e2.season_number, 'E', e2.episode_number)
WHERE e3.show = s.id 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, ) AS episode,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', m.title, 'title',
'year', m.year, m.title,
'url', m.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), m.year,
'grid', json_build_object( 'url',
'title', NULL, m.slug,
'image', CONCAT(globals.cdn_url, '/', df_movie.filename_disk), 'image',
'alt', CONCAT('Poster for ', m.title, ' (', m.year, ')'), CONCAT(globals.cdn_url, '/', df_movie.filename_disk),
'subtext', CASE WHEN m.star_rating IS NOT NULL THEN m.star_rating::text ELSE m.year::text END, 'grid',
'url', m.slug 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' 'type',
'movies'
) )
ORDER BY m.year ASC ORDER BY
m.year ASC
) )
FROM shows_movies sm FROM
shows_movies sm
LEFT JOIN movies m ON sm.movies_id = m.id LEFT JOIN movies m ON sm.movies_id = m.id
LEFT JOIN directus_files df_movie ON m.art = df_movie.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 WHERE
sm.shows_id = s.id
AND m.last_watched IS NOT NULL
) AS movies, ) AS movies,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', b.title, 'title',
'author', b.author, b.title,
'url', b.slug, 'author',
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), b.author,
'grid', json_build_object( 'url',
'title', NULL, b.slug,
'image', CONCAT(globals.cdn_url, '/', df_book.filename_disk), 'image',
'alt', CONCAT('Cover for ', b.title, ' by ', b.author), CONCAT(globals.cdn_url, '/', df_book.filename_disk),
'subtext', CASE WHEN b.star_rating IS NOT NULL THEN b.star_rating ELSE NULL END, 'grid',
'url', b.slug 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' 'type',
'books'
) )
ORDER BY b.title ORDER BY
b.title
) )
FROM shows_books sb FROM
shows_books sb
LEFT JOIN books b ON sb.books_id = b.id LEFT JOIN books b ON sb.books_id = b.id
LEFT JOIN directus_files df_book ON b.art = df_book.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' WHERE
sb.shows_id = s.id
AND LOWER(b.read_status) = 'finished'
) AS books, ) AS books,
( (
SELECT json_agg(json_build_object('title', p.title, 'date', p.date, 'url', p.slug) ORDER BY p.date DESC) SELECT
FROM posts_shows ps 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 LEFT JOIN posts p ON ps.posts_id = p.id
WHERE ps.shows_id = s.id WHERE
ps.shows_id = s.id
) AS posts, ) AS posts,
( (
SELECT array_agg(t.name) SELECT
FROM shows_tags st array_agg(t.name)
FROM
shows_tags st
LEFT JOIN tags t ON st.tags_id = t.id LEFT JOIN tags t ON st.tags_id = t.id
WHERE st.shows_id = s.id WHERE
st.shows_id = s.id
) AS tags, ) AS tags,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'title', rs.title, 'title',
'year', rs.year, rs.title,
'url', rs.slug, 'year',
'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), rs.year,
'grid', json_build_object( 'url',
'title', NULL, rs.slug,
'image', CONCAT(globals.cdn_url, '/', df_related.filename_disk), 'image',
'alt', CONCAT('Artwork for ', rs.title), CONCAT(globals.cdn_url, '/', df_related.filename_disk),
'subtext', CASE 'grid',
json_build_object(
'title',
NULL,
'image',
CONCAT(globals.cdn_url, '/', df_related.filename_disk),
'alt',
CONCAT('Artwork for ', rs.title),
'subtext',
CASE
WHEN ( WHEN (
SELECT MAX(e1.last_watched_at) SELECT
FROM episodes e1 MAX(e1.last_watched_at)
WHERE e1.show = rs.id FROM
) >= NOW() - INTERVAL '90 days' THEN episodes e1
( WHERE
SELECT CONCAT('S', e2.season_number, 'E', e2.episode_number) e1.show = rs.id
FROM episodes e2 ) >= NOW() - INTERVAL '90 days' THEN (
WHERE e2.show = rs.id SELECT
ORDER BY e2.last_watched_at DESC, e2.season_number DESC, e2.episode_number DESC CONCAT('S', e2.season_number, 'E', e2.episode_number)
LIMIT 1 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 ELSE rs.year::text
END, END,
'url', rs.slug 'url',
rs.slug
), ),
'type', 'tv' 'type',
'tv'
) )
ORDER BY rs.year ASC ORDER BY
rs.year ASC
) )
FROM related_shows sr FROM
related_shows sr
LEFT JOIN shows rs ON sr.related_shows_id = rs.id LEFT JOIN shows rs ON sr.related_shows_id = rs.id
LEFT JOIN directus_files df_related ON rs.art = df_related.id LEFT JOIN directus_files df_related ON rs.art = df_related.id
WHERE sr.shows_id = s.id WHERE
sr.shows_id = s.id
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT
FROM episodes e 1
WHERE e.show = rs.id FROM
episodes e
WHERE
e.show = rs.id
AND e.last_watched_at IS NOT NULL AND e.last_watched_at IS NOT NULL
) )
) AS related_shows, ) AS related_shows,
( (
SELECT json_agg( SELECT
json_agg(
json_build_object( json_build_object(
'name', a.name_string, 'name',
'url', a.slug, a.name_string,
'country', a.country, 'url',
'total_plays', a.total_plays, a.slug,
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), 'country',
'grid', json_build_object( a.country,
'title', a.name_string, 'total_plays',
'image', CONCAT(globals.cdn_url, '/', df_artist.filename_disk), a.total_plays,
'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, 'image',
'subtext', CASE WHEN a.total_plays > 0 THEN CONCAT(to_char(a.total_plays, 'FM999,999,999,999'), ' plays') ELSE NULL END, CONCAT(globals.cdn_url, '/', df_artist.filename_disk),
'url', a.slug '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' 'type',
'music'
) )
ORDER BY a.total_plays DESC ORDER BY
a.total_plays DESC
) )
FROM shows_artists sa FROM
shows_artists sa
LEFT JOIN artists a ON sa.artists_id = a.id LEFT JOIN artists a ON sa.artists_id = a.id
LEFT JOIN directus_files df_artist ON a.art = df_artist.id LEFT JOIN directus_files df_artist ON a.art = df_artist.id
WHERE sa.shows_id = s.id WHERE
sa.shows_id = s.id
) AS artists, ) AS artists,
MAX(e.last_watched_at) AS last_watched_at, MAX(e.last_watched_at) AS last_watched_at,
json_build_object( json_build_object(
'title', CONCAT('Show • ', s.title, '', globals.site_name), 'title',
'description', LEFT( CONCAT('Show • ', s.title, '', globals.site_name),
'description',
LEFT(
regexp_replace( regexp_replace(
regexp_replace( regexp_replace(
regexp_replace(s.description, E'[*_`~#>-]', '', 'g'), regexp_replace(s.description, E'[*_`~#>-]', '', 'g'),
E'\\[(.*?)\\]\\((.*?)\\)', E'\\1', 'g' E'\\[(.*?)\\]\\((.*?)\\)',
E'\\1',
'g'
), ),
E'!\\[(.*?)\\]\\((.*?)\\)', '', 'g' E'!\\[(.*?)\\]\\((.*?)\\)',
'',
'g'
), ),
250 250
), ),
'open_graph_image', CASE 'open_graph_image',
WHEN df_backdrop.filename_disk IS NOT NULL AND df_backdrop.filename_disk != '' AND df_backdrop.filename_disk != '/' THEN CONCAT('/', df_backdrop.filename_disk) 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 ELSE NULL
END, END,
'url', CONCAT(globals.url, s.slug), 'url',
'type', 'show' CONCAT(globals.url, s.slug),
'type',
'show'
) AS metadata ) AS metadata
FROM shows s FROM
shows s
LEFT JOIN episodes e ON s.id = e.show 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_art ON s.art = df_art.id
LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id LEFT JOIN directus_files df_backdrop ON s.backdrop = df_backdrop.id
CROSS JOIN optimized_globals globals 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 GROUP BY
ORDER BY MAX(e.last_watched_at) DESC; 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;