🏡 index : github.com/captn3m0/youtube-cue.git

author Nemo <commits@captnemo.in> 2021-07-29 11:28:30.0 +05:30:00
committer GitHub <noreply@github.com> 2021-07-29 11:28:30.0 +05:30:00
commit
2eadb53b8f5c47eb2591d241fedc244a30ea000e [patch]
tree
81464efa5537a2aca726f9f0561dad9650309cc1
parent
e0f05fe646f1601b36a8f18d053158e73b562ccc
parent
44e68fc14003f2f0fb1dbe8501da3618d81b923d
download
2eadb53b8f5c47eb2591d241fedc244a30ea000e.tar.gz

Add prettier as linter



Diff

 index.js                     | 54 +++++++++++++++++++++++++++++++++++++++---------------
 package-lock.json            | 25 +++++++++++++++++++++++++
 package.json                 |  6 ++++--
 src/cue.js                   | 13 ++++++++-----
 src/parser.js                | 29 +++++++++++++++--------------
 test/parser_test.js          | 32 +++++++++++++++++++++-----------
 .github/workflows/action.yml | 15 ++++++++-------
 7 files changed, 103 insertions(+), 71 deletions(-)

diff --git a/index.js b/index.js
index 441756e..0aa84b2 100755
--- a/index.js
+++ a/index.js
@@ -1,16 +1,16 @@
#!/usr/bin/env node
import ytdl from 'ytdl-core';
import getArtistTitle from 'get-artist-title'
import {parse} from './src/parser.js'
import {generate} from './src/cue.js'
import minimist from 'minimist'
import exit from 'process'
import ytdl from "ytdl-core";
import getArtistTitle from "get-artist-title";
import { parse } from "./src/parser.js";
import { generate } from "./src/cue.js";
import minimist from "minimist";
import exit from "process";

let argv = minimist(process.argv.slice(2), {
  string: 'audio-file'
  string: "audio-file",
});

if (argv._.length <1 || argv.help ){
if (argv._.length < 1 || argv.help) {
  console.log(`Usage
    $ youtube-cue [--audio-file audio.m4a] <youtube_url> [output_file]

@@ -36,32 +36,38 @@
    $ youtube-cue --audio-file audio.m4a "https://www.youtube.com/watch?v=THzUassmQwE"
      "T A Y L O R  S W I F T – Folklore [Full album].cue" saved
    $ youtube-cue "https://youtu.be/THzUassmQwE" folklore.cue
      folklore.cue saved`)
      folklore.cue saved`);
} else {
  let url = argv._[0]
  let url = argv._[0];

  ytdl.getInfo(url).then(info=>{
    let audioFile = argv['audio-file']? argv['audio-file'] : `${info.videoDetails.title}.m4a`
  ytdl.getInfo(url).then((info) => {
    let audioFile = argv["audio-file"]
      ? argv["audio-file"]
      : `${info.videoDetails.title}.m4a`;

    let output_file = argv._[1]? argv._[1] : `${info.videoDetails.title}.cue`
    let output_file = argv._[1] ? argv._[1] : `${info.videoDetails.title}.cue`;

    let forceTimestamps = argv['timestamps']? argv['timestamps'] : false;
    let forceTimestamps = argv["timestamps"] ? argv["timestamps"] : false;

    let forceDurations = argv['durations']? argv['durations'] : false;
    let forceDurations = argv["durations"] ? argv["durations"] : false;

    if (forceTimestamps && forceDurations) {
      console.error("You can't pass both --timestamps and durations");
      exit(1)
      exit(1);
    }

    let res = getArtistTitle(info.videoDetails.title,{
    let res = getArtistTitle(info.videoDetails.title, {
      defaultArtist: "Unknown Artist",
      defaultTitle: info.videoDetails.title
      defaultTitle: info.videoDetails.title,
    });
    let [artist, album] = res
    artist = (info.videoDetails.media ? info.videoDetails.media.artist : artist)
    let tracks = parse(info.videoDetails.description, {artist, forceTimestamps, forceDurations})
    generate({tracks, artist, audioFile, album}, output_file)
    console.log(`"${output_file}" saved`)
  })
    let [artist, album] = res;
    artist = info.videoDetails.media ? info.videoDetails.media.artist : artist;
    let tracks = parse(info.videoDetails.description, {
      artist,
      forceTimestamps,
      forceDurations,
    });
    generate({ tracks, artist, audioFile, album }, output_file);
    console.log(`"${output_file}" saved`);
  });
}
diff --git a/package-lock.json b/package-lock.json
index dfb8d2c..0c9c467 100644
--- a/package-lock.json
+++ a/package-lock.json
@@ -1,11 +1,11 @@
{
  "name": "youtube-cue",
  "version": "1.0.5",
  "version": "1.0.6",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "version": "1.0.5",
      "version": "1.0.6",
      "license": "MIT",
      "dependencies": {
        "console-log-level": "^1.4.1",
@@ -17,7 +17,8 @@
        "youtube-cue": "index.js"
      },

      "devDependencies": {
        "mocha": "^9.0.0"
        "mocha": "^9.0.0",
        "prettier": "^2.3.2"
      }

    },

    "node_modules/@ungap/promise-all-settled": {
@@ -794,6 +795,18 @@
      },

      "funding": {
        "url": "https://github.com/sponsors/jonschlinkert"
      }

    },

    "node_modules/prettier": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
      "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
      "dev": true,
      "bin": {
        "prettier": "bin-prettier.js"
      },

      "engines": {
        "node": ">=10.13.0"
      }

    },

    "node_modules/randombytes": {
@@ -1714,6 +1727,12 @@
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
      "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
      "dev": true
    },

    "prettier": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
      "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
      "dev": true
    },

    "randombytes": {
diff --git a/package.json b/package.json
index c72b0f2..ca15e29 100644
--- a/package.json
+++ a/package.json
@@ -1,16 +1,18 @@
{
  "name": "youtube-cue",
  "version": "1.0.6",
  "description": "Generates Cue sheet from Youtube URL",
  "main": "index.js",
  "scripts": {
    "test": "mocha"
    "test": "mocha",
    "lint": "prettier --check *.js src/*.js test/*.js"
  },

  "bin": "index.js",
  "author": "Nemo <npm@captnemo.in>",
  "license": "MIT",
  "devDependencies": {
    "mocha": "^9.0.0"
    "mocha": "^9.0.0",
    "prettier": "^2.3.2"
  },

  "dependencies": {
    "console-log-level": "^1.4.1",
diff --git a/src/cue.js b/src/cue.js
index 718cae1..df1a630 100644
--- a/src/cue.js
+++ a/src/cue.js
@@ -1,21 +1,24 @@
import fs from 'fs';
import fs from "fs";

// https://en.wikipedia.org/wiki/Cue_sheet_(computing)
export function generate(data, outputFile) {
  try {
    fs.truncateSync(outputFile)
    fs.truncateSync(outputFile);
  } catch {}
  fs.appendFileSync(outputFile, `REM Generated using youtube-cue\n`);
  fs.appendFileSync(outputFile, `PERFORMER "${data.artist}"\n`);
  fs.appendFileSync(outputFile, `TITLE "${data.album}"\n`);
  fs.appendFileSync(outputFile, `FILE "${data.audioFile}" M4A\n`);
  for(var i in data.tracks) {
  for (var i in data.tracks) {
    let song = data.tracks[i];
    let minutes = (song.start.hh * 60) + (song.start.mm)
    let minutes = song.start.hh * 60 + song.start.mm;
    fs.appendFileSync(outputFile, `  TRACK ${song.track} AUDIO\n`);
    fs.appendFileSync(outputFile, `    TITLE "${song.title}"\n`);
    fs.appendFileSync(outputFile, `    PERFORMER "${song.artist}"\n`);
    // Cue File is always MINUTES:SECONDS:FRAME, where FRAME is 00
    fs.appendFileSync(outputFile, `    INDEX 01 ${minutes}:${song.start.ss}:00\n`);
    fs.appendFileSync(
      outputFile,
      `    INDEX 01 ${minutes}:${song.start.ss}:00\n`
    );
  }
}
diff --git a/src/parser.js b/src/parser.js
index 5e4b701..ad966d3 100644
--- a/src/parser.js
+++ a/src/parser.js
@@ -20,7 +20,8 @@
 *
 * It is suggested to check their lengths and pick one to parse as the Track Title
 */
const TS_REGEX = /^((?<trackl>\d{1,3})\.)? *(?<text_1>.*?) *[\(\[]?(?<start_ts>((?<start_hh>\d{1,2}):)?(?<start_mm>\d{1,2}):(?<start_ss>\d{1,2})) *-? *[\)\]]?(?<end_ts>(?<end_hh>\d{1,2}:)?(?<end_mm>\d{1,2}):(?<end_ss>\d{1,2}))? *((?<trackr>\d{1,3})\.)? *(?<text_2>.*?)$/;
const TS_REGEX =
  /^((?<trackl>\d{1,3})\.)? *(?<text_1>.*?) *[\(\[]?(?<start_ts>((?<start_hh>\d{1,2}):)?(?<start_mm>\d{1,2}):(?<start_ss>\d{1,2})) *-? *[\)\]]?(?<end_ts>(?<end_hh>\d{1,2}:)?(?<end_mm>\d{1,2}):(?<end_ss>\d{1,2}))? *((?<trackr>\d{1,3})\.)? *(?<text_2>.*?)$/;
import getArtistTitle from "get-artist-title";
var _options = {};

@@ -30,12 +31,12 @@
}

// Only picks out lines which have a timestamp in them
var filterTimestamp = function(line) {
var filterTimestamp = function (line) {
  return TS_REGEX.test(line);
};

// Parse each line as per the regex
var firstPass = function(line) {
var firstPass = function (line) {
  let matches = line.match(TS_REGEX);
  let track = matches.groups["trackl"]
    ? +matches.groups["trackl"]
@@ -71,7 +72,7 @@
};

// Add a calc attribute with total seconds
var calcTimestamp = function(obj) {
var calcTimestamp = function (obj) {
  if (obj.end) {
    obj.end.calc = convertTime(obj.end.hh, obj.end.mm, obj.end.ss);
  }
@@ -80,7 +81,7 @@
};

// Pick the longer "text" from left or right side.
var parseTitle = function(obj) {
var parseTitle = function (obj) {
  obj.title =
    obj._.left_text.length > obj._.right_text.length
      ? obj._.left_text
@@ -89,7 +90,7 @@
};

// Parse the text as the title/artist
var parseArtist = function(obj) {
var parseArtist = function (obj) {
  let [artist, title] = getArtistTitle(obj.title, {
    defaultArtist: _options.artist,
    defaultTitle: obj.title,
@@ -100,7 +101,7 @@
};

// If track numbers are not present, add them accordingly
var addTrack = function(obj, index) {
var addTrack = function (obj, index) {
  if (obj.track == null) {
    obj.track = index + 1;
  }
@@ -108,7 +109,7 @@
};

// Add "end" timestamps as next start timestamps
var addEnd = function(obj, index, arr) {
var addEnd = function (obj, index, arr) {
  if (!obj.end) {
    if (arr.length != index + 1) {
      let next = arr[index + 1];
@@ -119,7 +120,7 @@
  return obj;
};

var timeToObject = function(obj) {
var timeToObject = function (obj) {
  let d = new Date(obj.calc * 1000).toISOString();
  obj.hh = +d.substr(11, 2);
  obj.mm = +d.substr(14, 2);
@@ -131,7 +132,7 @@
// Instead of timestamps, some tracklists use durations
// If durations are provided, use them to re-calculate
// the starting and ending timestamps
var fixDurations = function(list) {
var fixDurations = function (list) {
  for (let i in list) {
    if (i == 0) {
      // Set the first one to start of track.
@@ -167,7 +168,7 @@
  if (!options.forceTimestamps) {
    // If our timestamps are not in increasing order
    // Assume that we've been given a duration list instead
    if (result[0].start.calc!=0) {
    if (result[0].start.calc != 0) {
      result.forEach((current, index, list) => {
        if (index > 0) {
          let previous = list[index - 1];
@@ -183,9 +184,5 @@
    }
  }

  return result
    .map(parseTitle)
    .map(parseArtist)
    .map(addTrack)
    .map(addEnd);
  return result.map(parseTitle).map(parseArtist).map(addTrack).map(addEnd);
}
diff --git a/test/parser_test.js b/test/parser_test.js
index bb3e592..3085c67 100644
--- a/test/parser_test.js
+++ a/test/parser_test.js
@@ -24,21 +24,21 @@

const TEXT_WITH_ARTIST = "12:23 Rolling Stones - Hello World";

describe("Parser", function() {
describe("Parser", function () {
  var big_result;
  before(function() {
  before(function () {
    big_result = parse(TEXT);
  });
  it("should find all timestamps", function() {
  it("should find all timestamps", function () {
    assert.equal(big_result.length, 15);
  });

  it("should find artist names", function() {
  it("should find artist names", function () {
    let result = parse(TEXT_WITH_ARTIST);
    assert.equal(result[0].artist, "Rolling Stones");
  });

  it("should find track numbers", function() {
  it("should find track numbers", function () {
    assert.equal(big_result[3].track, 1);
    assert.equal(big_result[4].track, 2);
    assert.equal(big_result[5].track, 3);
@@ -51,7 +51,7 @@
    assert.equal(big_result[12].track, 10);
  });

  it("should ensure ending timestamps for all", function() {
  it("should ensure ending timestamps for all", function () {
    assert.deepEqual(big_result[13].end, {
      calc: 3023,
      hh: 0,
@@ -63,8 +63,9 @@
    assert.deepEqual(big_result[14].end, null);
  });

  it("should parse timestamps with square brackets", function() {
    let result = parse(`[00:00:00] 1. Steve Kroeger x Skye Holland - Through The Dark
  it("should parse timestamps with square brackets", function () {
    let result =
      parse(`[00:00:00] 1. Steve Kroeger x Skye Holland - Through The Dark
      [00:02:53] 2. Gabri Ponte x Jerome - Lonely `);
    assert.deepEqual(result[0], {
      artist: "Steve Kroeger x Skye Holland",
@@ -79,7 +80,7 @@
    });
  });

  it("should parse durations when given", function() {
  it("should parse durations when given", function () {
    let result = parse(`1. Artist - Title 6:19
2. Another Artist - Another Title 6:59
3. Yet Another Artist - Yet another title 5:12`);
@@ -113,7 +114,7 @@
    });
  });

  it("should parse as timestamps if first timestamp is 00:00", function() {
  it("should parse as timestamps if first timestamp is 00:00", function () {
    let result = parse(`1. Artist - Title 00:00
2. Another Artist - Another Title 01:00
3. Yet Another Artist - Yet another title 02:00`);
@@ -140,11 +141,14 @@
      track: 3,
      end: null,
      start: { ts: "00:02:00", hh: 0, mm: 2, ss: 0, calc: 120 },
      _: { left_text: "Yet Another Artist - Yet another title", right_text: "" },
      _: {
        left_text: "Yet Another Artist - Yet another title",
        right_text: "",
      },
    });
  });

  it("should parse durations as timestamps when forced", function() {
  it("should parse durations as timestamps when forced", function () {
    let result = parse(
      `1. Artist - Title 5:00
2. Another Artist - Another Title 4:20`,
@@ -166,7 +170,7 @@
    });
  });

  it("should parse timestamps as durations when forced", function() {
  it("should parse timestamps as durations when forced", function () {
    let result = parse(
      `1. Artist - Title 1:00
2. Another Artist - Another Title 1:15`,
@@ -214,7 +218,7 @@
    });
  });

  it("should parse taylor swift", function() {
  it("should parse taylor swift", function () {
    let result = parse(`0:00 the 1
    3:29 cardigan
    9:30 the last great american dynasty
diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml
index 0a3c917..a3c340e 100644
--- a/.github/workflows/action.yml
+++ a/.github/workflows/action.yml
@@ -1,16 +1,17 @@
on: push
name: Main Workflow
jobs:
  tests:
    strategy:
      matrix:
        node: ['16', '14', '12']
        node: ["16", "14", "12"]
    name: Run NPM Stuff
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - uses: actions/setup-node@v2
      with:
        node-version: ${{matrix.node}}
    - run: npm install
    - run: npm test
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v2
        with:
          node-version: ${{matrix.node}}
      - run: npm install
      - run: npm run lint
      - run: npm run test