jukebox-media-server 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/client/assets/{Watch-kJkUCvFd.js → Watch-DE2orFm6.js} +32 -32
- package/dist/client/assets/index-CLZKF1oG.css +1 -0
- package/dist/client/assets/index-hOWDqZr2.js +58 -0
- package/dist/client/index.html +2 -2
- package/dist/client/sw.js +1 -1
- package/dist/server/index.js +1944 -379
- package/drizzle/0005_settings_table.sql +5 -0
- package/drizzle/0006_watch_progress_cascade.sql +20 -0
- package/drizzle/0007_scan_jobs.sql +10 -0
- package/drizzle/0008_search_fts.sql +154 -0
- package/drizzle/0009_subtitles.sql +10 -0
- package/drizzle/0010_metadata_rename.sql +49 -0
- package/drizzle/meta/0005_snapshot.json +911 -0
- package/drizzle/meta/0006_snapshot.json +911 -0
- package/drizzle/meta/0007_snapshot.json +980 -0
- package/drizzle/meta/0008_snapshot.json +980 -0
- package/drizzle/meta/0009_snapshot.json +1059 -0
- package/drizzle/meta/0010_snapshot.json +1059 -0
- package/drizzle/meta/_journal.json +43 -1
- package/package.json +2 -1
- package/dist/client/assets/index-1v1BzSVv.js +0 -56
- package/dist/client/assets/index-FPcl2l8F.css +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
2
|
+
CREATE TABLE `__new_watch_progress` (
|
|
3
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
4
|
+
`profile_id` integer NOT NULL,
|
|
5
|
+
`movie_id` integer,
|
|
6
|
+
`episode_id` integer,
|
|
7
|
+
`current_time` integer NOT NULL,
|
|
8
|
+
`duration` integer,
|
|
9
|
+
`updated_at` integer NOT NULL,
|
|
10
|
+
FOREIGN KEY (`profile_id`) REFERENCES `profiles`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
11
|
+
FOREIGN KEY (`movie_id`) REFERENCES `movies`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
12
|
+
FOREIGN KEY (`episode_id`) REFERENCES `episodes`(`id`) ON UPDATE no action ON DELETE cascade
|
|
13
|
+
);
|
|
14
|
+
--> statement-breakpoint
|
|
15
|
+
INSERT INTO `__new_watch_progress`("id", "profile_id", "movie_id", "episode_id", "current_time", "duration", "updated_at") SELECT "id", "profile_id", "movie_id", "episode_id", "current_time", "duration", "updated_at" FROM `watch_progress`;--> statement-breakpoint
|
|
16
|
+
DROP TABLE `watch_progress`;--> statement-breakpoint
|
|
17
|
+
ALTER TABLE `__new_watch_progress` RENAME TO `watch_progress`;--> statement-breakpoint
|
|
18
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
19
|
+
CREATE UNIQUE INDEX `watch_progress_profile_movie_idx` ON `watch_progress` (`profile_id`,`movie_id`);--> statement-breakpoint
|
|
20
|
+
CREATE UNIQUE INDEX `watch_progress_profile_episode_idx` ON `watch_progress` (`profile_id`,`episode_id`);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
CREATE TABLE `scan_jobs` (
|
|
2
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
3
|
+
`started_at` integer NOT NULL,
|
|
4
|
+
`ended_at` integer,
|
|
5
|
+
`status` text NOT NULL,
|
|
6
|
+
`added` integer DEFAULT 0 NOT NULL,
|
|
7
|
+
`updated` integer DEFAULT 0 NOT NULL,
|
|
8
|
+
`total` integer DEFAULT 0 NOT NULL,
|
|
9
|
+
`error_message` text
|
|
10
|
+
);
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
-- Full-text search across movies, shows, and episodes via SQLite FTS5.
|
|
2
|
+
--
|
|
3
|
+
-- We use external-content virtual tables (content='<source>',
|
|
4
|
+
-- content_rowid='rowid') so the FTS tables don't duplicate the underlying
|
|
5
|
+
-- title/overview text. Triggers keep the FTS shadow tables in sync with the
|
|
6
|
+
-- real source tables on every INSERT, UPDATE, and DELETE.
|
|
7
|
+
--
|
|
8
|
+
-- Episodes also need to match against the parent show title, which FTS5 can't
|
|
9
|
+
-- JOIN on. Triggers on `episodes` resolve `shows.title` at write time and
|
|
10
|
+
-- store it in the episodes_fts virtual table as a third column.
|
|
11
|
+
|
|
12
|
+
CREATE VIRTUAL TABLE `movies_fts` USING fts5(
|
|
13
|
+
title,
|
|
14
|
+
overview,
|
|
15
|
+
genres,
|
|
16
|
+
content='movies',
|
|
17
|
+
content_rowid='rowid'
|
|
18
|
+
);
|
|
19
|
+
--> statement-breakpoint
|
|
20
|
+
|
|
21
|
+
CREATE VIRTUAL TABLE `shows_fts` USING fts5(
|
|
22
|
+
title,
|
|
23
|
+
overview,
|
|
24
|
+
genres,
|
|
25
|
+
content='shows',
|
|
26
|
+
content_rowid='rowid'
|
|
27
|
+
);
|
|
28
|
+
--> statement-breakpoint
|
|
29
|
+
|
|
30
|
+
CREATE VIRTUAL TABLE `episodes_fts` USING fts5(
|
|
31
|
+
title,
|
|
32
|
+
overview,
|
|
33
|
+
show_title,
|
|
34
|
+
content='episodes',
|
|
35
|
+
content_rowid='rowid'
|
|
36
|
+
);
|
|
37
|
+
--> statement-breakpoint
|
|
38
|
+
|
|
39
|
+
CREATE TRIGGER `movies_fts_insert` AFTER INSERT ON `movies` BEGIN
|
|
40
|
+
INSERT INTO `movies_fts`(rowid, title, overview, genres)
|
|
41
|
+
VALUES (NEW.rowid, NEW.title, NEW.overview, NEW.genres);
|
|
42
|
+
END;
|
|
43
|
+
--> statement-breakpoint
|
|
44
|
+
|
|
45
|
+
CREATE TRIGGER `movies_fts_delete` AFTER DELETE ON `movies` BEGIN
|
|
46
|
+
INSERT INTO `movies_fts`(`movies_fts`, rowid, title, overview, genres)
|
|
47
|
+
VALUES ('delete', OLD.rowid, OLD.title, OLD.overview, OLD.genres);
|
|
48
|
+
END;
|
|
49
|
+
--> statement-breakpoint
|
|
50
|
+
|
|
51
|
+
CREATE TRIGGER `movies_fts_update` AFTER UPDATE ON `movies` BEGIN
|
|
52
|
+
INSERT INTO `movies_fts`(`movies_fts`, rowid, title, overview, genres)
|
|
53
|
+
VALUES ('delete', OLD.rowid, OLD.title, OLD.overview, OLD.genres);
|
|
54
|
+
INSERT INTO `movies_fts`(rowid, title, overview, genres)
|
|
55
|
+
VALUES (NEW.rowid, NEW.title, NEW.overview, NEW.genres);
|
|
56
|
+
END;
|
|
57
|
+
--> statement-breakpoint
|
|
58
|
+
|
|
59
|
+
CREATE TRIGGER `shows_fts_insert` AFTER INSERT ON `shows` BEGIN
|
|
60
|
+
INSERT INTO `shows_fts`(rowid, title, overview, genres)
|
|
61
|
+
VALUES (NEW.rowid, NEW.title, NEW.overview, NEW.genres);
|
|
62
|
+
END;
|
|
63
|
+
--> statement-breakpoint
|
|
64
|
+
|
|
65
|
+
CREATE TRIGGER `shows_fts_delete` AFTER DELETE ON `shows` BEGIN
|
|
66
|
+
INSERT INTO `shows_fts`(`shows_fts`, rowid, title, overview, genres)
|
|
67
|
+
VALUES ('delete', OLD.rowid, OLD.title, OLD.overview, OLD.genres);
|
|
68
|
+
END;
|
|
69
|
+
--> statement-breakpoint
|
|
70
|
+
|
|
71
|
+
CREATE TRIGGER `shows_fts_update` AFTER UPDATE ON `shows` BEGIN
|
|
72
|
+
INSERT INTO `shows_fts`(`shows_fts`, rowid, title, overview, genres)
|
|
73
|
+
VALUES ('delete', OLD.rowid, OLD.title, OLD.overview, OLD.genres);
|
|
74
|
+
INSERT INTO `shows_fts`(rowid, title, overview, genres)
|
|
75
|
+
VALUES (NEW.rowid, NEW.title, NEW.overview, NEW.genres);
|
|
76
|
+
END;
|
|
77
|
+
--> statement-breakpoint
|
|
78
|
+
|
|
79
|
+
CREATE TRIGGER `episodes_fts_insert` AFTER INSERT ON `episodes` BEGIN
|
|
80
|
+
INSERT INTO `episodes_fts`(rowid, title, overview, show_title)
|
|
81
|
+
VALUES (
|
|
82
|
+
NEW.rowid,
|
|
83
|
+
NEW.title,
|
|
84
|
+
NEW.overview,
|
|
85
|
+
(SELECT `title` FROM `shows` WHERE `id` = NEW.show_id)
|
|
86
|
+
);
|
|
87
|
+
END;
|
|
88
|
+
--> statement-breakpoint
|
|
89
|
+
|
|
90
|
+
CREATE TRIGGER `episodes_fts_delete` AFTER DELETE ON `episodes` BEGIN
|
|
91
|
+
INSERT INTO `episodes_fts`(`episodes_fts`, rowid, title, overview, show_title)
|
|
92
|
+
VALUES (
|
|
93
|
+
'delete',
|
|
94
|
+
OLD.rowid,
|
|
95
|
+
OLD.title,
|
|
96
|
+
OLD.overview,
|
|
97
|
+
(SELECT `title` FROM `shows` WHERE `id` = OLD.show_id)
|
|
98
|
+
);
|
|
99
|
+
END;
|
|
100
|
+
--> statement-breakpoint
|
|
101
|
+
|
|
102
|
+
CREATE TRIGGER `episodes_fts_update` AFTER UPDATE ON `episodes` BEGIN
|
|
103
|
+
INSERT INTO `episodes_fts`(`episodes_fts`, rowid, title, overview, show_title)
|
|
104
|
+
VALUES (
|
|
105
|
+
'delete',
|
|
106
|
+
OLD.rowid,
|
|
107
|
+
OLD.title,
|
|
108
|
+
OLD.overview,
|
|
109
|
+
(SELECT `title` FROM `shows` WHERE `id` = OLD.show_id)
|
|
110
|
+
);
|
|
111
|
+
INSERT INTO `episodes_fts`(rowid, title, overview, show_title)
|
|
112
|
+
VALUES (
|
|
113
|
+
NEW.rowid,
|
|
114
|
+
NEW.title,
|
|
115
|
+
NEW.overview,
|
|
116
|
+
(SELECT `title` FROM `shows` WHERE `id` = NEW.show_id)
|
|
117
|
+
);
|
|
118
|
+
END;
|
|
119
|
+
--> statement-breakpoint
|
|
120
|
+
|
|
121
|
+
-- When a show's title changes, refresh the show_title column on every
|
|
122
|
+
-- matching episode_fts row. We can't use 'rebuild' here because
|
|
123
|
+
-- episodes_fts is external-content backed by `episodes`, which doesn't
|
|
124
|
+
-- know about the show title — so we issue a manual delete/insert per
|
|
125
|
+
-- affected episode rowid.
|
|
126
|
+
CREATE TRIGGER `episodes_fts_show_title_update` AFTER UPDATE OF `title` ON `shows` BEGIN
|
|
127
|
+
INSERT INTO `episodes_fts`(`episodes_fts`, rowid, title, overview, show_title)
|
|
128
|
+
SELECT 'delete', `episodes`.rowid, `episodes`.`title`, `episodes`.`overview`, OLD.`title`
|
|
129
|
+
FROM `episodes`
|
|
130
|
+
WHERE `episodes`.`show_id` = NEW.`id`;
|
|
131
|
+
INSERT INTO `episodes_fts`(rowid, title, overview, show_title)
|
|
132
|
+
SELECT `episodes`.rowid, `episodes`.`title`, `episodes`.`overview`, NEW.`title`
|
|
133
|
+
FROM `episodes`
|
|
134
|
+
WHERE `episodes`.`show_id` = NEW.`id`;
|
|
135
|
+
END;
|
|
136
|
+
--> statement-breakpoint
|
|
137
|
+
|
|
138
|
+
-- One-time backfill for any rows that already exist before this migration ran.
|
|
139
|
+
INSERT INTO `movies_fts`(rowid, title, overview, genres)
|
|
140
|
+
SELECT rowid, title, overview, genres FROM `movies`;
|
|
141
|
+
--> statement-breakpoint
|
|
142
|
+
|
|
143
|
+
INSERT INTO `shows_fts`(rowid, title, overview, genres)
|
|
144
|
+
SELECT rowid, title, overview, genres FROM `shows`;
|
|
145
|
+
--> statement-breakpoint
|
|
146
|
+
|
|
147
|
+
INSERT INTO `episodes_fts`(rowid, title, overview, show_title)
|
|
148
|
+
SELECT
|
|
149
|
+
`episodes`.rowid,
|
|
150
|
+
`episodes`.`title`,
|
|
151
|
+
`episodes`.`overview`,
|
|
152
|
+
`shows`.`title`
|
|
153
|
+
FROM `episodes`
|
|
154
|
+
LEFT JOIN `shows` ON `shows`.`id` = `episodes`.`show_id`;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
CREATE TABLE `subtitles` (
|
|
2
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
3
|
+
`movie_id` integer,
|
|
4
|
+
`episode_id` integer,
|
|
5
|
+
`file_path` text NOT NULL,
|
|
6
|
+
`language` text NOT NULL,
|
|
7
|
+
`format` text NOT NULL,
|
|
8
|
+
FOREIGN KEY (`movie_id`) REFERENCES `movies`(`id`) ON UPDATE no action ON DELETE cascade,
|
|
9
|
+
FOREIGN KEY (`episode_id`) REFERENCES `episodes`(`id`) ON UPDATE no action ON DELETE cascade
|
|
10
|
+
);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
-- Migration: rename TMDB-specific columns to neutral "external_id" +
|
|
2
|
+
-- "poster_url"/"backdrop_url"/"still_url" so the project can talk to any
|
|
3
|
+
-- metadata API. Also drop the tmdbApiKey setting row since we no longer
|
|
4
|
+
-- store a key.
|
|
5
|
+
--
|
|
6
|
+
-- The stored poster/backdrop/still values used to be relative TMDB paths
|
|
7
|
+
-- (e.g. "/abc.jpg") and the frontend prefixed image.tmdb.org. The new API
|
|
8
|
+
-- returns absolute URLs, so we null out the old values — a re-scan will
|
|
9
|
+
-- repopulate them with fully-qualified URLs.
|
|
10
|
+
--
|
|
11
|
+
-- SQLite 3.35+ supports RENAME COLUMN and DROP COLUMN, which better-sqlite3
|
|
12
|
+
-- ships with, so we can do this in-place without table recreation.
|
|
13
|
+
|
|
14
|
+
-- movies ---------------------------------------------------------------
|
|
15
|
+
ALTER TABLE `movies` ADD COLUMN `external_id` text;--> statement-breakpoint
|
|
16
|
+
UPDATE `movies` SET `external_id` = CAST(`tmdb_id` AS TEXT) WHERE `tmdb_id` IS NOT NULL;--> statement-breakpoint
|
|
17
|
+
ALTER TABLE `movies` DROP COLUMN `tmdb_id`;--> statement-breakpoint
|
|
18
|
+
|
|
19
|
+
ALTER TABLE `movies` RENAME COLUMN `poster_path` TO `poster_url`;--> statement-breakpoint
|
|
20
|
+
ALTER TABLE `movies` RENAME COLUMN `backdrop_path` TO `backdrop_url`;--> statement-breakpoint
|
|
21
|
+
|
|
22
|
+
UPDATE `movies` SET `poster_url` = NULL WHERE `poster_url` IS NOT NULL;--> statement-breakpoint
|
|
23
|
+
UPDATE `movies` SET `backdrop_url` = NULL WHERE `backdrop_url` IS NOT NULL;--> statement-breakpoint
|
|
24
|
+
|
|
25
|
+
-- shows ----------------------------------------------------------------
|
|
26
|
+
ALTER TABLE `shows` ADD COLUMN `external_id` text;--> statement-breakpoint
|
|
27
|
+
UPDATE `shows` SET `external_id` = CAST(`tmdb_id` AS TEXT) WHERE `tmdb_id` IS NOT NULL;--> statement-breakpoint
|
|
28
|
+
ALTER TABLE `shows` DROP COLUMN `tmdb_id`;--> statement-breakpoint
|
|
29
|
+
|
|
30
|
+
ALTER TABLE `shows` RENAME COLUMN `poster_path` TO `poster_url`;--> statement-breakpoint
|
|
31
|
+
ALTER TABLE `shows` RENAME COLUMN `backdrop_path` TO `backdrop_url`;--> statement-breakpoint
|
|
32
|
+
|
|
33
|
+
UPDATE `shows` SET `poster_url` = NULL WHERE `poster_url` IS NOT NULL;--> statement-breakpoint
|
|
34
|
+
UPDATE `shows` SET `backdrop_url` = NULL WHERE `backdrop_url` IS NOT NULL;--> statement-breakpoint
|
|
35
|
+
|
|
36
|
+
-- seasons --------------------------------------------------------------
|
|
37
|
+
ALTER TABLE `seasons` RENAME COLUMN `poster_path` TO `poster_url`;--> statement-breakpoint
|
|
38
|
+
UPDATE `seasons` SET `poster_url` = NULL WHERE `poster_url` IS NOT NULL;--> statement-breakpoint
|
|
39
|
+
|
|
40
|
+
-- episodes -------------------------------------------------------------
|
|
41
|
+
-- episodes.tmdb_id was never populated (always null), so no copy needed.
|
|
42
|
+
ALTER TABLE `episodes` ADD COLUMN `external_id` text;--> statement-breakpoint
|
|
43
|
+
ALTER TABLE `episodes` DROP COLUMN `tmdb_id`;--> statement-breakpoint
|
|
44
|
+
|
|
45
|
+
ALTER TABLE `episodes` RENAME COLUMN `still_path` TO `still_url`;--> statement-breakpoint
|
|
46
|
+
UPDATE `episodes` SET `still_url` = NULL WHERE `still_url` IS NOT NULL;--> statement-breakpoint
|
|
47
|
+
|
|
48
|
+
-- settings: drop the unused TMDB API key row ---------------------------
|
|
49
|
+
DELETE FROM `settings` WHERE `key` = 'tmdbApiKey';
|