@serifpersia/dango 3.6.7 → 3.6.9

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.
Files changed (156) hide show
  1. package/README.md +1 -1
  2. package/client/dist/assets/{AnimeCard-C3P9zWi9.js → AnimeCard-DKDJK8Mp.js} +1 -1
  3. package/client/dist/assets/{AnimeInfo-Et6687Tl.js → AnimeInfo-CTcvfjva.js} +1 -1
  4. package/client/dist/assets/{AnimeInfoPage-DX4eNnlH.js → AnimeInfoPage-B_UiacIN.js} +2 -2
  5. package/client/dist/assets/{Asmr-CCdEWrFi.js → Asmr-DMSN2vxl.js} +2 -2
  6. package/client/dist/assets/{AsmrResetProgressModal-DgEWBJOw.js → AsmrResetProgressModal-CRwfOatX.js} +1 -1
  7. package/client/dist/assets/{AvSyncCalibrator-CQ2fjf2E.js → AvSyncCalibrator-CRJsi-vz.js} +1 -1
  8. package/client/dist/assets/{Home-DUkUTTTy.js → Home-pwmK9_Eh.js} +1 -1
  9. package/client/dist/assets/{Insights-QCh4xW12.js → Insights-m7kFzg2A.js} +1 -1
  10. package/client/dist/assets/{LibraryListPage-BoTxRqHz.js → LibraryListPage-C1wpPvu6.js} +1 -1
  11. package/client/dist/assets/ListeningList-OzfEI1Ga.js +1 -0
  12. package/client/dist/assets/{Manga-HydR-L7o.js → Manga-ChRCExhK.js} +1 -1
  13. package/client/dist/assets/{MangaInfoPage-CBakEI9a.js → MangaInfoPage-DSHJPo2A.js} +1 -1
  14. package/client/dist/assets/{MangaReadPage-DwAR3iPy.js → MangaReadPage-CzOVY1wA.js} +1 -1
  15. package/client/dist/assets/{MangaResetProgressModal-DGzl8vsO.js → MangaResetProgressModal-CJfzdUBb.js} +1 -1
  16. package/client/dist/assets/{Mature-Pi0TxKuF.js → Mature-CifQMfhs.js} +1 -1
  17. package/client/dist/assets/{MediaCard--cuFxOCS.js → MediaCard-CM10yB9V.js} +1 -1
  18. package/client/dist/assets/{OptionListMenu-B3D39dGS.js → OptionListMenu-6Kovbsqw.js} +1 -1
  19. package/client/dist/assets/{Player-CsH4x_I_.js → Player-CK0hT-u4.js} +2 -2
  20. package/client/dist/assets/{PlayerSettings-DGxBsi3F.js → PlayerSettings-Bb66uqT9.js} +1 -1
  21. package/client/dist/assets/{QueueOptionsButton-Djq4Cpex.js → QueueOptionsButton-C_nTj8_q.js} +1 -1
  22. package/client/dist/assets/{QueueRail-DOrYgNVX.js → QueueRail-DUK7URAE.js} +1 -1
  23. package/client/dist/assets/{ReadingList-DwYoBrNk.js → ReadingList-Ck9LJThU.js} +1 -1
  24. package/client/dist/assets/{ResetProgressModal-CMF86mX6.js → ResetProgressModal-BUphIv0k.js} +1 -1
  25. package/client/dist/assets/{Search-DFkhuk-x.js → Search-zJyP15h6.js} +1 -1
  26. package/client/dist/assets/{Settings-DBB2r0VQ.js → Settings-BYdoSEUh.js} +1 -1
  27. package/client/dist/assets/{SkeletonGrid-DJelJgAv.js → SkeletonGrid-CqgbOhjX.js} +1 -1
  28. package/client/dist/assets/{Trackers-DGYXFhYZ.js → Trackers-BVjyv6CM.js} +1 -1
  29. package/client/dist/assets/{Tv-C5MDGD2Z.js → Tv-L13ylswR.js} +1 -1
  30. package/client/dist/assets/{TvInfo-DrKuK13u.js → TvInfo-Cvcm5U2D.js} +1 -1
  31. package/client/dist/assets/{TvPopup-DtHilRDT.js → TvPopup-DhxfKvYm.js} +1 -1
  32. package/client/dist/assets/{TvSearch-CzNxdu_w.js → TvSearch-P8bFE6_X.js} +1 -1
  33. package/client/dist/assets/{TvWatchlist-D7p4br6S.js → TvWatchlist-D5gVPjtb.js} +1 -1
  34. package/client/dist/assets/{Watchlist-DrOzswl2.js → Watchlist-Cjq8l3rU.js} +1 -1
  35. package/client/dist/assets/{hls-BGCX7mJy.js → hls-BkzuANAg.js} +1 -1
  36. package/client/dist/assets/{index-CnfZwsds.js → index-CLVgzKLk.js} +19 -19
  37. package/client/dist/assets/{useAnimeInfoData-DYXWBPF-.js → useAnimeInfoData-DZJZu-so.js} +1 -1
  38. package/client/dist/assets/{useAsmr-BbhQ59bk.js → useAsmr-CvrMGHuo.js} +1 -1
  39. package/client/dist/assets/useAsmrPopup-Bimy8Ouw.js +1 -0
  40. package/client/dist/assets/{useMangaLibrary-DuesWQaE.js → useMangaLibrary--MiN11uR.js} +1 -1
  41. package/client/dist/assets/{useMangaPopup-D57OVGUr.js → useMangaPopup-CR5XhKKS.js} +1 -1
  42. package/client/dist/assets/{useProviders-mpQb_dix.js → useProviders-DqdT4fA5.js} +1 -1
  43. package/client/dist/assets/{useTv-DGflCsSI.js → useTv-BL0HMDyP.js} +1 -1
  44. package/client/dist/assets/{useTvLibrary-BqeSmyc4.js → useTvLibrary-D4U4iqN8.js} +1 -1
  45. package/client/dist/index.html +1 -1
  46. package/package.json +3 -5
  47. package/server/dist/config.js +1 -174
  48. package/server/dist/server.js +1068 -289
  49. package/server/dist/shipped-defaults.js +1 -6
  50. package/server/package.json +4 -5
  51. package/client/dist/assets/Asmr.module-CdWlioTY.js +0 -1
  52. package/client/dist/assets/ListeningList-DguKjI_t.js +0 -1
  53. package/client/dist/assets/Music-BGH_0voi.css +0 -1
  54. package/client/dist/assets/Music-CQpyXTLH.js +0 -1
  55. package/client/dist/assets/Radio-CCHNFN7R.css +0 -1
  56. package/client/dist/assets/Radio-DF6g6odd.js +0 -1
  57. package/client/dist/assets/Radio.module-DGSZLpKM.js +0 -1
  58. package/client/dist/assets/useAsmrPopup-SymV1J-b.js +0 -1
  59. package/server/dist/app-auth.js +0 -157
  60. package/server/dist/app-hono.js +0 -598
  61. package/server/dist/db/drizzle.js +0 -16
  62. package/server/dist/db/schema-anime.js +0 -61
  63. package/server/dist/db/schema-asmr.js +0 -13
  64. package/server/dist/db/schema-manga.js +0 -31
  65. package/server/dist/db/schema-tv.js +0 -18
  66. package/server/dist/db.js +0 -217
  67. package/server/dist/discord-gateway.js +0 -385
  68. package/server/dist/discord-rpc.js +0 -413
  69. package/server/dist/github-sync.js +0 -508
  70. package/server/dist/google.js +0 -741
  71. package/server/dist/hono/asmr.js +0 -10
  72. package/server/dist/hono/auth.js +0 -49
  73. package/server/dist/hono/music.js +0 -209
  74. package/server/dist/hono/proxy.js +0 -827
  75. package/server/dist/hono/tv.js +0 -200
  76. package/server/dist/hono/watchlist.js +0 -341
  77. package/server/dist/lib/anilist.js +0 -1583
  78. package/server/dist/lib/anischedule.js +0 -191
  79. package/server/dist/lib/insights.js +0 -185
  80. package/server/dist/lib/ipc.js +0 -23
  81. package/server/dist/lib/kitsu.js +0 -517
  82. package/server/dist/lib/mal-import.js +0 -291
  83. package/server/dist/lib/mal.js +0 -957
  84. package/server/dist/lib/migration.js +0 -310
  85. package/server/dist/lib/offline-db.js +0 -395
  86. package/server/dist/lib/potoken.js +0 -135
  87. package/server/dist/lib/recommendations.service.js +0 -216
  88. package/server/dist/lib/temp-ids.js +0 -3
  89. package/server/dist/lib/tmdb.js +0 -72
  90. package/server/dist/lib/tracker/anilist-tracker.js +0 -308
  91. package/server/dist/lib/tracker/manga-sync.service.js +0 -773
  92. package/server/dist/lib/tracker/sync-state.js +0 -21
  93. package/server/dist/lib/tracker/sync.service.js +0 -476
  94. package/server/dist/lib/translate.js +0 -79
  95. package/server/dist/lib/ump.js +0 -106
  96. package/server/dist/lib/ytmusic.js +0 -162
  97. package/server/dist/logger.js +0 -16
  98. package/server/dist/providers/manga/manga.types.js +0 -1
  99. package/server/dist/providers/provider.interface.js +0 -1
  100. package/server/dist/providers/remote-loader.js +0 -614
  101. package/server/dist/providers/remote-types.js +0 -159
  102. package/server/dist/providers/title-matching.js +0 -226
  103. package/server/dist/providers/tv.types.js +0 -1
  104. package/server/dist/rclone.js +0 -120
  105. package/server/dist/repositories/asmr.repository.js +0 -77
  106. package/server/dist/repositories/insights.repository.js +0 -106
  107. package/server/dist/repositories/library.repository.js +0 -94
  108. package/server/dist/repositories/mal-cache.repository.js +0 -52
  109. package/server/dist/repositories/manga.repository.js +0 -95
  110. package/server/dist/repositories/notifications.repository.js +0 -60
  111. package/server/dist/repositories/queue.repository.js +0 -72
  112. package/server/dist/repositories/settings.repository.js +0 -30
  113. package/server/dist/repositories/shows-meta.repository.js +0 -58
  114. package/server/dist/repositories/temp-show-ids.repository.js +0 -63
  115. package/server/dist/repositories/tv.repository.js +0 -93
  116. package/server/dist/repositories/watched-episodes.repository.js +0 -82
  117. package/server/dist/repositories/watchlist.repository.js +0 -60
  118. package/server/dist/scripts/backfill-episode-duration.js +0 -42
  119. package/server/dist/sync-payload.js +0 -91
  120. package/server/dist/sync.js +0 -657
  121. package/server/dist/trpc/context.js +0 -7
  122. package/server/dist/trpc/errors.js +0 -15
  123. package/server/dist/trpc/index.js +0 -18
  124. package/server/dist/trpc/router.js +0 -49
  125. package/server/dist/trpc/routers/asmr-library.js +0 -112
  126. package/server/dist/trpc/routers/asmr-progress.js +0 -121
  127. package/server/dist/trpc/routers/asmr.js +0 -87
  128. package/server/dist/trpc/routers/auth.js +0 -194
  129. package/server/dist/trpc/routers/continue-watching.js +0 -81
  130. package/server/dist/trpc/routers/data.js +0 -1026
  131. package/server/dist/trpc/routers/discord.js +0 -285
  132. package/server/dist/trpc/routers/discovery.js +0 -11
  133. package/server/dist/trpc/routers/insights.js +0 -14
  134. package/server/dist/trpc/routers/manga-library.js +0 -263
  135. package/server/dist/trpc/routers/manga-progress.js +0 -169
  136. package/server/dist/trpc/routers/manga.js +0 -201
  137. package/server/dist/trpc/routers/music.js +0 -655
  138. package/server/dist/trpc/routers/notifications.js +0 -80
  139. package/server/dist/trpc/routers/progress.js +0 -109
  140. package/server/dist/trpc/routers/queue.js +0 -93
  141. package/server/dist/trpc/routers/radio.js +0 -145
  142. package/server/dist/trpc/routers/settings.js +0 -96
  143. package/server/dist/trpc/routers/tracker.js +0 -213
  144. package/server/dist/trpc/routers/tv-library.js +0 -135
  145. package/server/dist/trpc/routers/tv-progress.js +0 -159
  146. package/server/dist/trpc/routers/tv.js +0 -551
  147. package/server/dist/trpc/routers/watchlist.js +0 -550
  148. package/server/dist/trpc/validation.js +0 -258
  149. package/server/dist/utils/cache.utils.js +0 -25
  150. package/server/dist/utils/cookie.utils.js +0 -13
  151. package/server/dist/utils/db-utils.js +0 -17
  152. package/server/dist/utils/env.utils.js +0 -77
  153. package/server/dist/utils/http.utils.js +0 -82
  154. package/server/dist/utils/request-context.js +0 -2
  155. package/server/dist/utils/security.utils.js +0 -76
  156. /package/client/dist/assets/{Asmr-D1KuQwQy.css → useAsmrPopup-D1KuQwQy.css} +0 -0
@@ -1,291 +0,0 @@
1
- import { XMLParser } from 'fast-xml-parser';
2
- import { searchAnilistByTitle, isAnilistRateLimited, getShowMetaById } from './anilist.js';
3
- import { kitsuSearchAnime } from './kitsu.js';
4
- import { offlineDb } from './offline-db.js';
5
- import { SettingsRepository } from '../repositories/settings.repository.js';
6
- import { ShowsMetaRepository } from '../repositories/shows-meta.repository.js';
7
- import { performWriteTransactionAsync } from '../sync.js';
8
- import logger from '../logger.js';
9
- let activeImportStatus = {
10
- running: false,
11
- current: 0,
12
- total: 0,
13
- phase: 'done',
14
- source: null,
15
- };
16
- let activeImportCancelled = false;
17
- export function getMalImportStatus() {
18
- return activeImportStatus;
19
- }
20
- export function requestMalImportCancel() {
21
- if (!activeImportStatus.running) {
22
- return { success: true, message: 'No import running' };
23
- }
24
- activeImportCancelled = true;
25
- return { success: true, message: 'Import cancellation requested' };
26
- }
27
- export function prepareMalImport(fileBuffer, flags) {
28
- if (activeImportStatus.running) {
29
- return { ok: false, status: 409, body: { error: 'An import is already in progress' } };
30
- }
31
- if (!fileBuffer)
32
- return { ok: false, status: 400, body: { error: 'No file' } };
33
- const { erase, useOfflineDb, skipFallback } = flags;
34
- const offlineEnabled = useOfflineDb !== 'false' && useOfflineDb !== false && useOfflineDb !== '0';
35
- const shouldSkipFallback = skipFallback === 'true' || skipFallback === true || skipFallback === '1';
36
- let result;
37
- try {
38
- result = malXmlParser.parse(fileBuffer.toString());
39
- }
40
- catch {
41
- return { ok: false, status: 400, body: { error: 'Invalid XML' } };
42
- }
43
- const animeList = result?.myanimelist?.anime || [];
44
- if (animeList.length === 0) {
45
- return { ok: false, status: 400, body: { error: 'No anime found in XML' } };
46
- }
47
- activeImportCancelled = false;
48
- activeImportStatus = {
49
- running: true,
50
- current: 0,
51
- total: animeList.length,
52
- phase: 'offline',
53
- source: 'offline',
54
- };
55
- return { ok: true, import: { animeList, erase, offlineEnabled, shouldSkipFallback } };
56
- }
57
- export async function executeMalImport(db, prepared, sendEvent) {
58
- const { animeList, erase, offlineEnabled, shouldSkipFallback } = prepared;
59
- const total = animeList.length;
60
- let skippedCount = 0;
61
- const offlineShows = [];
62
- const offlineMeta = [];
63
- const fallbackQueue = [];
64
- for (const item of animeList) {
65
- const malTitle = xmlText(item.series_title);
66
- const status = mapMalStatus(xmlText(item.my_status));
67
- let matched = false;
68
- if (offlineEnabled) {
69
- const malId = parseInt(xmlText(item.series_animedb_id), 10);
70
- if (malId && !Number.isNaN(malId)) {
71
- const entry = offlineDb.getByMalId(malId);
72
- if (entry) {
73
- matched = true;
74
- const showId = String(entry.anilistId);
75
- const title = entry.title || malTitle;
76
- offlineShows.push({ id: showId, name: title, thumbnail: entry.thumbnail, status });
77
- if (entry.thumbnail || entry.type || entry.genres) {
78
- offlineMeta.push({
79
- id: showId,
80
- thumbnail: entry.thumbnail,
81
- type: entry.type,
82
- genres: entry.genres,
83
- });
84
- }
85
- activeImportStatus = {
86
- running: true,
87
- current: offlineShows.length,
88
- total,
89
- phase: 'offline',
90
- source: 'offline',
91
- title: malTitle,
92
- matchedTitle: title,
93
- status,
94
- found: true,
95
- imported: offlineShows.length,
96
- };
97
- sendEvent('progress', {
98
- current: offlineShows.length,
99
- total,
100
- title: malTitle,
101
- matchedTitle: title,
102
- status,
103
- source: 'offline',
104
- found: true,
105
- });
106
- }
107
- }
108
- }
109
- if (!matched)
110
- fallbackQueue.push(item);
111
- }
112
- if (offlineShows.length > 0 || erase) {
113
- try {
114
- await performWriteTransactionAsync(db, async (tx) => {
115
- if (erase)
116
- await SettingsRepository.clearWatchlist(tx);
117
- await SettingsRepository.upsertWatchlistBatch(tx, offlineShows);
118
- for (const meta of offlineMeta) {
119
- if (meta.thumbnail || meta.type || meta.genres) {
120
- await ShowsMetaRepository.upsert(tx, {
121
- id: meta.id,
122
- thumbnail: meta.thumbnail,
123
- type: meta.type,
124
- genres: meta.genres,
125
- });
126
- }
127
- }
128
- });
129
- }
130
- catch (dbErr) {
131
- logger.error({ err: dbErr }, 'Failed to commit offline import matches');
132
- }
133
- }
134
- let fallbackImported = 0;
135
- if (shouldSkipFallback || activeImportCancelled) {
136
- skippedCount += fallbackQueue.length;
137
- }
138
- else if (fallbackQueue.length > 0) {
139
- activeImportStatus = { ...activeImportStatus, phase: 'fallback', source: null };
140
- const BATCH_SIZE = 5;
141
- for (let i = 0; i < fallbackQueue.length; i += BATCH_SIZE) {
142
- if (activeImportCancelled) {
143
- skippedCount += fallbackQueue.length - i;
144
- break;
145
- }
146
- const batch = fallbackQueue.slice(i, i + BATCH_SIZE);
147
- const batchResults = await Promise.allSettled(batch.map((item) => searchByTitleForMal(xmlText(item.series_title))));
148
- const batchShows = [];
149
- const batchMeta = [];
150
- const metaPromises = [];
151
- batchResults.forEach((r, idx) => {
152
- const malTitle = xmlText(batch[idx].series_title);
153
- const status = mapMalStatus(xmlText(batch[idx].my_status));
154
- const current = offlineShows.length + fallbackImported + idx + 1;
155
- if (r.status === 'fulfilled' && r.value) {
156
- const show = r.value;
157
- const title = show.title?.english || show.title?.romaji || malTitle;
158
- batchShows.push({ id: String(show.id), name: title, status });
159
- activeImportStatus = {
160
- running: true,
161
- current,
162
- total,
163
- phase: 'fallback',
164
- source: show.source,
165
- title: malTitle,
166
- matchedTitle: title,
167
- status,
168
- found: true,
169
- imported: offlineShows.length + fallbackImported + 1,
170
- };
171
- sendEvent('progress', {
172
- current,
173
- total,
174
- title: malTitle,
175
- matchedTitle: title,
176
- status,
177
- source: show.source,
178
- found: true,
179
- });
180
- metaPromises.push(getShowMetaById(String(show.id))
181
- .then((meta) => {
182
- if (meta) {
183
- batchMeta.push({
184
- id: String(show.id),
185
- thumbnail: meta.thumbnail || undefined,
186
- type: meta.type || undefined,
187
- });
188
- }
189
- })
190
- .catch(() => { }));
191
- }
192
- else {
193
- skippedCount++;
194
- activeImportStatus = {
195
- running: true,
196
- current,
197
- total,
198
- phase: 'fallback',
199
- source: null,
200
- title: malTitle,
201
- matchedTitle: null,
202
- status,
203
- found: false,
204
- imported: offlineShows.length + fallbackImported,
205
- };
206
- sendEvent('progress', {
207
- current,
208
- total,
209
- title: malTitle,
210
- matchedTitle: null,
211
- status,
212
- source: null,
213
- found: false,
214
- });
215
- }
216
- });
217
- await Promise.allSettled(metaPromises);
218
- if (batchShows.length > 0) {
219
- try {
220
- await performWriteTransactionAsync(db, async (tx) => {
221
- await SettingsRepository.upsertWatchlistBatch(tx, batchShows);
222
- for (const meta of batchMeta) {
223
- if (meta.thumbnail) {
224
- await ShowsMetaRepository.upsert(tx, {
225
- id: meta.id,
226
- thumbnail: meta.thumbnail,
227
- type: meta.type,
228
- });
229
- }
230
- }
231
- });
232
- fallbackImported += batchShows.length;
233
- }
234
- catch (dbErr) {
235
- logger.error({ err: dbErr }, 'Failed to commit fallback import batch');
236
- skippedCount += batchShows.length;
237
- }
238
- }
239
- }
240
- }
241
- const imported = offlineShows.length + fallbackImported;
242
- activeImportStatus = {
243
- running: false,
244
- current: total,
245
- total,
246
- phase: 'done',
247
- source: null,
248
- imported,
249
- skipped: skippedCount,
250
- };
251
- sendEvent('complete', { imported, skipped: skippedCount });
252
- }
253
- function xmlText(value) {
254
- if (Array.isArray(value))
255
- return String(value[0] ?? '');
256
- return String(value ?? '');
257
- }
258
- function mapMalStatus(malStatus) {
259
- switch (malStatus) {
260
- case 'Plan to Watch':
261
- return 'Planned';
262
- case 'On Hold':
263
- return 'On-Hold';
264
- default:
265
- return malStatus;
266
- }
267
- }
268
- const malXmlParser = new XMLParser({
269
- isArray: (name) => name === 'anime',
270
- parseTagValue: false,
271
- trimValues: true,
272
- });
273
- async function searchByTitleForMal(title) {
274
- const result = await searchAnilistByTitle(title);
275
- if (result)
276
- return { ...result, source: 'anilist' };
277
- if (isAnilistRateLimited()) {
278
- logger.debug({ title }, 'AniList rate limited, trying Kitsu fallback for MAL import');
279
- const fb = await kitsuSearchAnime({ query: title, page: 1, perPage: 5 });
280
- if (fb.length > 0) {
281
- const lowerTitle = title.toLowerCase();
282
- const exactMatch = fb.find((m) => m.title?.romaji?.toLowerCase() === lowerTitle ||
283
- m.title?.english?.toLowerCase() === lowerTitle);
284
- const best = exactMatch || fb[0];
285
- if (best.id > 0) {
286
- return { id: best.id, title: best.title ?? {}, source: 'kitsu' };
287
- }
288
- }
289
- }
290
- return null;
291
- }