atris 3.48.1 → 3.49.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/commands/youtube.js +71 -0
- package/package.json +1 -1
package/commands/youtube.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { apiRequestJson } = require('../utils/api');
|
|
2
2
|
const { ensureValidCredentials } = require('../utils/auth');
|
|
3
3
|
const { spawnSync } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
4
5
|
const path = require('path');
|
|
5
6
|
const https = require('https');
|
|
6
7
|
|
|
@@ -444,6 +445,67 @@ function formatYoutubeResult(data) {
|
|
|
444
445
|
return lines.join('\n');
|
|
445
446
|
}
|
|
446
447
|
|
|
448
|
+
function videoIdFromUrl(url) {
|
|
449
|
+
const text = String(url || '');
|
|
450
|
+
const watch = text.match(/[?&]v=([^&]+)/);
|
|
451
|
+
if (watch) return watch[1];
|
|
452
|
+
const short = text.match(/youtu\.be\/([^?&/]+)/);
|
|
453
|
+
return short ? short[1] : null;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function dateStamp(now) {
|
|
457
|
+
if (typeof now === 'string' && /^\d{4}-\d{2}-\d{2}/.test(now)) {
|
|
458
|
+
return now.slice(0, 10);
|
|
459
|
+
}
|
|
460
|
+
const value = now instanceof Date ? now : new Date(now || Date.now());
|
|
461
|
+
if (Number.isNaN(value.getTime())) return new Date().toISOString().slice(0, 10);
|
|
462
|
+
return value.toISOString().slice(0, 10);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function firstHeading(notes) {
|
|
466
|
+
const match = String(notes || '').replace(/\r\n/g, '\n').match(/^#{1,6}\s+(.+)$/m);
|
|
467
|
+
return match ? match[1].trim() : '';
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function fileBriefFromNotes({ cwd, url, workDir, now } = {}) {
|
|
471
|
+
try {
|
|
472
|
+
const id = videoIdFromUrl(url);
|
|
473
|
+
if (!id) return;
|
|
474
|
+
const notesPath = path.join(workDir, `yt_${id}.md`);
|
|
475
|
+
if (!fs.existsSync(notesPath)) return;
|
|
476
|
+
const notes = fs.readFileSync(notesPath, 'utf8');
|
|
477
|
+
const wikiDir = path.join(cwd, 'atris', 'wiki');
|
|
478
|
+
if (!fs.existsSync(wikiDir)) return;
|
|
479
|
+
|
|
480
|
+
const heading = firstHeading(notes);
|
|
481
|
+
const date = dateStamp(now);
|
|
482
|
+
const header = [
|
|
483
|
+
heading.toLowerCase(),
|
|
484
|
+
'',
|
|
485
|
+
`date: ${date}`,
|
|
486
|
+
`source: ${url}`,
|
|
487
|
+
'rail: atris youtube notes, quotes repaired against the transcript',
|
|
488
|
+
].join('\n');
|
|
489
|
+
const briefsDir = path.join(wikiDir, 'briefs');
|
|
490
|
+
fs.mkdirSync(briefsDir, { recursive: true });
|
|
491
|
+
const relBrief = `atris/wiki/briefs/youtube-${id}.md`;
|
|
492
|
+
fs.writeFileSync(path.join(cwd, relBrief), `${header}\n${notes}`);
|
|
493
|
+
|
|
494
|
+
const year = date.slice(0, 4);
|
|
495
|
+
const journalPath = path.join(cwd, 'atris', 'logs', year, `${date}.md`);
|
|
496
|
+
fs.mkdirSync(path.dirname(journalPath), { recursive: true });
|
|
497
|
+
let existing = '';
|
|
498
|
+
if (fs.existsSync(journalPath)) existing = fs.readFileSync(journalPath, 'utf8');
|
|
499
|
+
const prefix = existing && !existing.endsWith('\n') ? '\n' : '';
|
|
500
|
+
const line = `- [claimable] watched: ${heading} -> ${relBrief}`;
|
|
501
|
+
fs.writeFileSync(journalPath, `${existing}${prefix}${line}\n`);
|
|
502
|
+
|
|
503
|
+
console.log(`brief filed: ${relBrief}`);
|
|
504
|
+
} catch {
|
|
505
|
+
// notes filing must never break the youtube command
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
447
509
|
function runYoutubeNotes(args = [], deps = {}) {
|
|
448
510
|
const output = deps.output || ((line = '') => console.error(line));
|
|
449
511
|
const url = args[0];
|
|
@@ -459,6 +521,14 @@ function runYoutubeNotes(args = [], deps = {}) {
|
|
|
459
521
|
const childArgs = engine ? [url, engine] : [url];
|
|
460
522
|
const result = spawn(script, childArgs, { stdio: 'inherit' });
|
|
461
523
|
if (result.status == null) return 1;
|
|
524
|
+
if (result.status === 0) {
|
|
525
|
+
fileBriefFromNotes({
|
|
526
|
+
cwd: deps.cwd || process.cwd(),
|
|
527
|
+
url,
|
|
528
|
+
workDir: deps.workDir || path.join(process.env.TMPDIR || '/tmp', 'ytnotes'),
|
|
529
|
+
now: deps.now || new Date(),
|
|
530
|
+
});
|
|
531
|
+
}
|
|
462
532
|
return result.status;
|
|
463
533
|
}
|
|
464
534
|
|
|
@@ -488,5 +558,6 @@ module.exports = {
|
|
|
488
558
|
processYoutube,
|
|
489
559
|
shouldRetryWithLocalTranscript,
|
|
490
560
|
formatYoutubeResult,
|
|
561
|
+
fileBriefFromNotes,
|
|
491
562
|
youtubeCommand,
|
|
492
563
|
};
|