GUI-STUDIO commited on
Commit
a7fdbc8
·
1 Parent(s): 5eb55cc

Refactor scraper paths; add websockets & showtime

Browse files

Rename scraper modules to _generic/_post-processing and update imports across services. Add WebSocket support to app-ffmpeg (new lib/ws and /ws route) and hook into showtime V2. Improve bucket logging and upload flow; refactor find_seed_file into db/bucket/local runners, document seed files after upload, and trigger post-upload recording. Also change proxy lookup env from 'serverless' to 'edgeone' and update related scrape-worker imports.

src/index.ts CHANGED
@@ -10,6 +10,7 @@ import { TestRouter } from "./sub-router/test";
10
  import { NS_runtime } from "../../../../packages/lib/env.runtime";
11
  import { NS_workers_proxy } from "../../../../packages/lib/proxy-server/workers-proxy";
12
  import { start_mongo_db } from "../../../../packages/db/mongo-db/init";
 
13
 
14
  await NS_runtime.set_env_var_db();
15
 
@@ -105,6 +106,31 @@ const app = new Elysia()
105
  return res;
106
  })
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  .listen({
109
  port: PORT || 7860,
110
  ...(NS_runtime.IS_PROD && { hostname: "0.0.0.0" }),
 
10
  import { NS_runtime } from "../../../../packages/lib/env.runtime";
11
  import { NS_workers_proxy } from "../../../../packages/lib/proxy-server/workers-proxy";
12
  import { start_mongo_db } from "../../../../packages/db/mongo-db/init";
13
+ import { NS_websockets } from "./lib/ws";
14
 
15
  await NS_runtime.set_env_var_db();
16
 
 
106
  return res;
107
  })
108
 
109
+ .ws("/ws", {
110
+ open(socket: any) {
111
+ const socket_id = socket.id;
112
+ const remote_address = socket.remoteAddress;
113
+
114
+ NS_websockets.ws_clients.set(socket_id, socket);
115
+
116
+ if (!NS_runtime.IS_PROD) {
117
+ console.log("WS CONNECTED:", remote_address, socket_id);
118
+ }
119
+
120
+ socket.send(JSON.stringify({ type: "CONNECTED", ws_id: socket_id }));
121
+ },
122
+ close(socket: any) {
123
+ const socket_id = socket.id;
124
+ const remote_address = socket.remoteAddress;
125
+
126
+ NS_websockets.ws_clients.delete(socket_id);
127
+
128
+ if (!NS_runtime.IS_PROD) {
129
+ console.log("WS CLOSED:", remote_address, socket_id);
130
+ }
131
+ }
132
+ })
133
+
134
  .listen({
135
  port: PORT || 7860,
136
  ...(NS_runtime.IS_PROD && { hostname: "0.0.0.0" }),
src/lib/bucket.ts CHANGED
@@ -270,7 +270,7 @@ async function upload_to_bucket(arg0: {
270
  created_at: Date.now()
271
  });
272
 
273
- console.log("\n", "🧲 UPLOADING TO BUCKET", "\n");
274
 
275
  if (!skip?.probe) {
276
  const [E_, R_] = await NS_promise.F_catch_promise({
@@ -285,7 +285,7 @@ async function upload_to_bucket(arg0: {
285
 
286
  if (E_ || !R_) {
287
  upload_jobs.delete(job_id);
288
- console.log("\n", "❌ UPLOAD BUCKET: FFPROBE FAILED", "\n");
289
  return;
290
  }
291
  }
@@ -308,16 +308,11 @@ async function upload_to_bucket(arg0: {
308
  upload_jobs.delete(job_id);
309
 
310
  if (E__) {
311
- console.log("\n", "❌ UPLOAD BUCKET FAILED", E__, "\n");
312
  return { success: false };
313
  }
314
 
315
- console.log("\n", "🔥 UPLOAD BUCKET DONE", "\n");
316
-
317
- if (REQ0) {
318
- REQ0.searchParams.set("ops", "just_check");
319
- fetch(REQ0.toString());
320
- }
321
 
322
  return { success: true };
323
  }
 
270
  created_at: Date.now()
271
  });
272
 
273
+ console.log("\n", `🧲 UPLOADING TO BUCKET: ${job_id}`, "\n");
274
 
275
  if (!skip?.probe) {
276
  const [E_, R_] = await NS_promise.F_catch_promise({
 
285
 
286
  if (E_ || !R_) {
287
  upload_jobs.delete(job_id);
288
+ console.log("\n", `❌ UPLOAD BUCKET: FFPROBE FAILED: ${job_id}`, "\n");
289
  return;
290
  }
291
  }
 
308
  upload_jobs.delete(job_id);
309
 
310
  if (E__) {
311
+ console.log("\n", `❌ UPLOAD BUCKET FAILED: ${job_id}`, E__, "\n");
312
  return { success: false };
313
  }
314
 
315
+ console.log("\n", `🔥 UPLOAD BUCKET DONE: ${job_id}`, "\n");
 
 
 
 
 
316
 
317
  return { success: true };
318
  }
src/lib/ws.ts ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import { ServerWebSocket } from "elysia/ws/bun";
2
+
3
+ const ws_clients = new Map<string, ServerWebSocket>();
4
+
5
+ export const NS_websockets = {
6
+ ws_clients,
7
+ };
src/sub-router/showtime/helper.ts CHANGED
@@ -61,12 +61,14 @@ async function find_seed_file(arg0: {
61
  picture_quality = picture_quality.trim();
62
  }
63
 
64
- // check database first
65
- const db_ = await (async () => {
 
 
 
 
66
  const [_, db_file_info] = await NS_promise.F_catch_promise({
67
  promise: (async () => {
68
- if (skip?.db === true) return;
69
-
70
  const _ =
71
  await NS_mongo_db_record_factory.NS_record_factory_s3_bucket.findRecordsByFingerprint(
72
  { job_id, sbe_id },
@@ -87,7 +89,7 @@ async function find_seed_file(arg0: {
87
 
88
  if (!in_db) return;
89
 
90
- const stream_link = db_file_info!.url;
91
 
92
  const _u = new URL(stream_link);
93
  _u.searchParams.set("download", "true");
@@ -107,18 +109,22 @@ async function find_seed_file(arg0: {
107
  in_db,
108
  data
109
  };
110
- })();
 
 
111
 
112
  if (db_?.data) {
113
  return db_.data;
114
  }
115
 
116
  // check bucket
117
- const bucket_ = await (async () => {
 
 
 
 
118
  const [__, bucket_file_info] = await NS_promise.F_catch_promise({
119
  promise: (async () => {
120
- if (skip?.bucket === true) return;
121
-
122
  return NS_bucket.get_latest_hf_bucket_file_by_name({
123
  folder_path: cache_folder,
124
  human_filename: file_id,
@@ -135,7 +141,20 @@ async function find_seed_file(arg0: {
135
 
136
  const stream_link = bucket_file_info!.url;
137
 
138
- if (!db_?.in_db && skip?.db !== true && document === true) {
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  document_seed_file({
140
  job_id,
141
  sbe_id,
@@ -152,15 +171,19 @@ async function find_seed_file(arg0: {
152
  stream_link,
153
  size: bucket_file_info?.size
154
  };
155
- })();
 
 
156
 
157
  if (bucket_) {
158
  return bucket_;
159
  }
160
 
161
  // check local
162
- const local_ = await (async () => {
163
- if (skip?.local === true) return;
 
 
164
 
165
  const file =
166
  output_destination?.file_with_path &&
@@ -296,17 +319,15 @@ async function find_seed_file(arg0: {
296
  if (local_file) {
297
  return local_file;
298
  }
299
- })();
 
 
300
 
301
  if (local_) {
302
  return local_;
303
  }
304
  }
305
 
306
- async function find_seed_local_file(arg0: {}) {
307
- const {} = arg0;
308
- }
309
-
310
  async function document_seed_file(arg0: {
311
  job_id: string;
312
  sbe_id: string;
@@ -328,10 +349,12 @@ async function document_seed_file(arg0: {
328
  qLevel
329
  } = arg0;
330
 
 
 
331
  const [E_, R_] = await NS_promise.F_catch_promise({
332
  promise:
333
  NS_mongo_db_record_factory.NS_record_factory_s3_bucket.upsertRecord(
334
- { job_id, sbe_id, file_id },
335
  {
336
  provider: "hugging face",
337
  job_id,
 
61
  picture_quality = picture_quality.trim();
62
  }
63
 
64
+ // check database
65
+ async function db_check_runner(arg0: { skip_db?: boolean }) {
66
+ const { skip_db } = arg0;
67
+
68
+ if (skip_db === true) return;
69
+
70
  const [_, db_file_info] = await NS_promise.F_catch_promise({
71
  promise: (async () => {
 
 
72
  const _ =
73
  await NS_mongo_db_record_factory.NS_record_factory_s3_bucket.findRecordsByFingerprint(
74
  { job_id, sbe_id },
 
89
 
90
  if (!in_db) return;
91
 
92
+ const stream_link = db_file_info?.url;
93
 
94
  const _u = new URL(stream_link);
95
  _u.searchParams.set("download", "true");
 
109
  in_db,
110
  data
111
  };
112
+ }
113
+
114
+ const db_ = await db_check_runner({ skip_db: skip?.db });
115
 
116
  if (db_?.data) {
117
  return db_.data;
118
  }
119
 
120
  // check bucket
121
+ async function bucket_check_runner(arg0: { skip_bucket?: boolean }) {
122
+ const { skip_bucket } = arg0;
123
+
124
+ if (skip_bucket === true) return;
125
+
126
  const [__, bucket_file_info] = await NS_promise.F_catch_promise({
127
  promise: (async () => {
 
 
128
  return NS_bucket.get_latest_hf_bucket_file_by_name({
129
  folder_path: cache_folder,
130
  human_filename: file_id,
 
141
 
142
  const stream_link = bucket_file_info!.url;
143
 
144
+ const document_metadata = await (async () => {
145
+ if (document !== true || db_?.in_db) return;
146
+
147
+ if (skip?.db === true) {
148
+ // const db_ = await db_check_runner({});
149
+ // if (db_?.in_db) {
150
+ // return
151
+ // }
152
+ }
153
+
154
+ return true;
155
+ })();
156
+
157
+ if (document_metadata) {
158
  document_seed_file({
159
  job_id,
160
  sbe_id,
 
171
  stream_link,
172
  size: bucket_file_info?.size
173
  };
174
+ }
175
+
176
+ const bucket_ = await bucket_check_runner({ skip_bucket: skip?.bucket });
177
 
178
  if (bucket_) {
179
  return bucket_;
180
  }
181
 
182
  // check local
183
+ async function locals_check_runner(arg0: { skip_local?: boolean }) {
184
+ const { skip_local } = arg0;
185
+
186
+ if (skip_local === true) return;
187
 
188
  const file =
189
  output_destination?.file_with_path &&
 
319
  if (local_file) {
320
  return local_file;
321
  }
322
+ }
323
+
324
+ const local_ = await locals_check_runner({ skip_local: skip?.local });
325
 
326
  if (local_) {
327
  return local_;
328
  }
329
  }
330
 
 
 
 
 
331
  async function document_seed_file(arg0: {
332
  job_id: string;
333
  sbe_id: string;
 
349
  qLevel
350
  } = arg0;
351
 
352
+ console.log("\n", `📊 DOCUMENTING: ${job_id}`, "\n");
353
+
354
  const [E_, R_] = await NS_promise.F_catch_promise({
355
  promise:
356
  NS_mongo_db_record_factory.NS_record_factory_s3_bucket.upsertRecord(
357
+ { job_id, sbe_id },
358
  {
359
  provider: "hugging face",
360
  job_id,
src/sub-router/showtime/v2.ts CHANGED
@@ -15,6 +15,7 @@ import { spawn } from "node:child_process";
15
  import { NS_showtime_v2_helper } from "./helper";
16
  import { T_playback } from "../ffmpeg/validator-v2";
17
  import { NS_runtime } from "../../../../../../packages/lib/env.runtime";
 
18
 
19
  const APP_ENV = () => NS_runtime.ENV_VAR_DB?.APP_ENV || process?.env?.APP_ENV;
20
 
@@ -35,6 +36,10 @@ type T_TranscodeJob = {
35
  error?: string;
36
  logs?: string[];
37
  log_errors?: string[];
 
 
 
 
38
  created_at: number;
39
  };
40
 
@@ -252,8 +257,16 @@ const sub_router = new Elysia({ prefix: "/showtimeV2" }).get(
252
  }
253
  }
254
 
255
- // check/serve seeded file
256
- const seed_file = await (async () => {
 
 
 
 
 
 
 
 
257
  if (!is_download_mode) return;
258
 
259
  const [E_, R_] = await NS_promise.F_catch_promise({
@@ -271,19 +284,12 @@ const sub_router = new Elysia({ prefix: "/showtimeV2" }).get(
271
  job_id,
272
  S3Dir,
273
  cleanup_corruption: true,
274
- document: true,
275
- ideal_runtime: playback.ideal_runtime
 
276
  })
277
  });
278
 
279
- if (typeof R_ === "string") {
280
- if (!NS_misc.isValidUrlFormat(R_)) {
281
- return;
282
- }
283
-
284
- // create a function to proxima the seed link
285
- }
286
-
287
  if (R_ && "stream_link" in R_ && R_.stream_link) {
288
  if (!NS_misc.isValidUrlFormat(R_.stream_link)) {
289
  return;
@@ -291,20 +297,48 @@ const sub_router = new Elysia({ prefix: "/showtimeV2" }).get(
291
  }
292
 
293
  return R_;
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  })();
295
 
296
  if (seed_file) {
297
- if (ops === "just_check") {
298
- const file_size_bytes = parseFloat(`${seed_file?.size}`);
299
 
300
- const percent = 100;
301
- const percentage = typeof percent === "number" ? `${percent} %` : "";
302
- const transcoded_size = file_size_bytes
303
- ? NS_ffmpeg.F_format_size(file_size_bytes)
304
- : current_job?.transcoded_size;
305
- const progress_endpoint =
306
- current_job?.progress_endpoint || progress_update_endpoint;
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  return {
309
  passed: true,
310
  ready: true,
@@ -313,7 +347,6 @@ const sub_router = new Elysia({ prefix: "/showtimeV2" }).get(
313
  output_destination,
314
  flags: current_job?.flags,
315
  logs: current_job?.logs,
316
- ...(typeof seed_file === "string" ? { stream_link: seed_file } : {}),
317
  ...(seed_file && "stream_link" in seed_file && seed_file.stream_link
318
  ? { stream_link: seed_file.stream_link }
319
  : {}),
@@ -322,12 +355,8 @@ const sub_router = new Elysia({ prefix: "/showtimeV2" }).get(
322
  }
323
 
324
  // handle direct file or url redirect
325
- if (
326
- seed_file &&
327
- (typeof seed_file === "string" ||
328
- ("stream_link" in seed_file && seed_file.stream_link))
329
- ) {
330
- const stream_link = new URL(seed_file.stream_link || seed_file);
331
  stream_link.searchParams.set("download", "true");
332
 
333
  const [E_, R_] = await NS_promise.F_catch_promise({
@@ -473,10 +502,6 @@ const sub_router = new Elysia({ prefix: "/showtimeV2" }).get(
473
  }
474
  }
475
 
476
- let node_proc = spawn(NS_ffmpeg.ffmpeg_path, flags, {
477
- signal: controller.signal
478
- });
479
-
480
  const passthrough = (() => {
481
  if (delivery_mode !== "stream") {
482
  return;
@@ -486,6 +511,10 @@ const sub_router = new Elysia({ prefix: "/showtimeV2" }).get(
486
  return new PassThrough();
487
  })();
488
 
 
 
 
 
489
  let progress_data: Record<string, any> | undefined = undefined;
490
  let seek_size_bytes = 0;
491
 
@@ -648,11 +677,30 @@ const sub_router = new Elysia({ prefix: "/showtimeV2" }).get(
648
  file_with_path &&
649
  APP_ENV() !== "dev"
650
  ) {
 
 
651
  NS_bucket.upload_to_bucket({
652
  job_id,
653
  bucket_path: `${cache_folder}/${file_id}`,
654
  file_with_path,
655
  REQ0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  });
657
  }
658
  }
 
15
  import { NS_showtime_v2_helper } from "./helper";
16
  import { T_playback } from "../ffmpeg/validator-v2";
17
  import { NS_runtime } from "../../../../../../packages/lib/env.runtime";
18
+ import { NS_websockets } from "../../lib/ws";
19
 
20
  const APP_ENV = () => NS_runtime.ENV_VAR_DB?.APP_ENV || process?.env?.APP_ENV;
21
 
 
36
  error?: string;
37
  logs?: string[];
38
  log_errors?: string[];
39
+ db_metadata?: {
40
+ stream_link: string;
41
+ size: number | undefined;
42
+ };
43
  created_at: number;
44
  };
45
 
 
257
  }
258
  }
259
 
260
+ async function wide_search_runner(arg0: {
261
+ skip?: {
262
+ local?: boolean;
263
+ db?: boolean;
264
+ bucket?: boolean;
265
+ };
266
+ document: boolean;
267
+ }) {
268
+ const { skip, document } = arg0;
269
+
270
  if (!is_download_mode) return;
271
 
272
  const [E_, R_] = await NS_promise.F_catch_promise({
 
284
  job_id,
285
  S3Dir,
286
  cleanup_corruption: true,
287
+ document,
288
+ ideal_runtime: playback.ideal_runtime,
289
+ skip
290
  })
291
  });
292
 
 
 
 
 
 
 
 
 
293
  if (R_ && "stream_link" in R_ && R_.stream_link) {
294
  if (!NS_misc.isValidUrlFormat(R_.stream_link)) {
295
  return;
 
297
  }
298
 
299
  return R_;
300
+ }
301
+
302
+ // check/serve seeded file
303
+ const seed_file = await (async () => {
304
+ const _ = current_job?.db_metadata?.stream_link;
305
+
306
+ if (_) {
307
+ return current_job.db_metadata;
308
+ }
309
+
310
+ const __ = await wide_search_runner({ document: true });
311
+
312
+ return __;
313
  })();
314
 
315
  if (seed_file) {
316
+ const file_size_bytes = parseFloat(`${seed_file?.size}`);
 
317
 
318
+ const percent = 100;
319
+ const percentage = typeof percent === "number" ? `${percent} %` : "";
320
+ const transcoded_size = file_size_bytes
321
+ ? NS_ffmpeg.F_format_size(file_size_bytes)
322
+ : current_job?.transcoded_size;
323
+ const progress_endpoint =
324
+ current_job?.progress_endpoint || progress_update_endpoint;
325
 
326
+ if (!current_job?.db_metadata?.stream_link) {
327
+ record_task_info({
328
+ job_id,
329
+ file_with_path: file_with_path || "",
330
+ status: "done",
331
+ info: {
332
+ percent,
333
+ transcoded_size,
334
+ ...("stream_link" in seed_file && seed_file.stream_link
335
+ ? { db_metadata: seed_file }
336
+ : {})
337
+ }
338
+ });
339
+ }
340
+
341
+ if (ops === "just_check") {
342
  return {
343
  passed: true,
344
  ready: true,
 
347
  output_destination,
348
  flags: current_job?.flags,
349
  logs: current_job?.logs,
 
350
  ...(seed_file && "stream_link" in seed_file && seed_file.stream_link
351
  ? { stream_link: seed_file.stream_link }
352
  : {}),
 
355
  }
356
 
357
  // handle direct file or url redirect
358
+ if (seed_file && "stream_link" in seed_file && seed_file.stream_link) {
359
+ const stream_link = new URL(seed_file.stream_link);
 
 
 
 
360
  stream_link.searchParams.set("download", "true");
361
 
362
  const [E_, R_] = await NS_promise.F_catch_promise({
 
502
  }
503
  }
504
 
 
 
 
 
505
  const passthrough = (() => {
506
  if (delivery_mode !== "stream") {
507
  return;
 
511
  return new PassThrough();
512
  })();
513
 
514
+ let node_proc = spawn(NS_ffmpeg.ffmpeg_path, flags, {
515
+ signal: controller.signal
516
+ });
517
+
518
  let progress_data: Record<string, any> | undefined = undefined;
519
  let seek_size_bytes = 0;
520
 
 
677
  file_with_path &&
678
  APP_ENV() !== "dev"
679
  ) {
680
+ transcode_jobs.delete(job_id);
681
+
682
  NS_bucket.upload_to_bucket({
683
  job_id,
684
  bucket_path: `${cache_folder}/${file_id}`,
685
  file_with_path,
686
  REQ0
687
+ }).then((cc) => {
688
+ if (!cc?.success) {
689
+ return;
690
+ }
691
+
692
+ // document file
693
+ wide_search_runner({
694
+ document: true,
695
+ skip: {
696
+ local: true,
697
+ db: true
698
+ }
699
+ }).then((ccc) => {
700
+ if (!ccc) {
701
+ return;
702
+ }
703
+ });
704
  });
705
  }
706
  }