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.
@@ -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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atris",
3
- "version": "3.48.1",
3
+ "version": "3.49.0",
4
4
  "description": "you say what you want in plain words. atris builds it, checks it, and shows you proof.",
5
5
  "main": "bin/atris.js",
6
6
  "bin": {