Auto update youtube-dl
authorChocobozzz <me@florianbigard.com>
Thu, 2 Aug 2018 14:02:51 +0000 (16:02 +0200)
committerChocobozzz <me@florianbigard.com>
Mon, 6 Aug 2018 09:19:16 +0000 (11:19 +0200)
server.ts
server/initializers/constants.ts
server/lib/schedulers/youtube-dl-update-scheduler.ts [new file with mode: 0644]

index 0e6f787a68a11ca788c9ae9bdd82b17d322235df..9aaa64dbf2d3f067ddaadadf48e5f2d073125fdb 100644 (file)
--- a/server.ts
+++ b/server.ts
@@ -89,6 +89,7 @@ import { Redis } from './server/lib/redis'
 import { BadActorFollowScheduler } from './server/lib/schedulers/bad-actor-follow-scheduler'
 import { RemoveOldJobsScheduler } from './server/lib/schedulers/remove-old-jobs-scheduler'
 import { UpdateVideosScheduler } from './server/lib/schedulers/update-videos-scheduler'
+import { YoutubeDlUpdateScheduler } from './server/lib/schedulers/youtube-dl-update-scheduler'
 
 // ----------- Command line -----------
 
@@ -186,6 +187,7 @@ async function startApplication () {
   BadActorFollowScheduler.Instance.enable()
   RemoveOldJobsScheduler.Instance.enable()
   UpdateVideosScheduler.Instance.enable()
+  YoutubeDlUpdateScheduler.Instance.enable()
 
   // Redis initialization
   Redis.Instance.init()
index fdd772d849acce2f6a8b7da32f3fd01fd8df4431..cc363d4f2699a0497e9ddd7f289c64010f2a8dac 100644 (file)
@@ -108,7 +108,8 @@ const JOB_COMPLETED_LIFETIME = 60000 * 60 * 24 * 2 // 2 days
 let SCHEDULER_INTERVALS_MS = {
   badActorFollow: 60000 * 60, // 1 hour
   removeOldJobs: 60000 * 60, // 1 hour
-  updateVideos: 60000 // 1 minute
+  updateVideos: 60000, // 1 minute
+  youtubeDLUpdate: 60000 * 60 * 24 // 1 day
 }
 
 // ---------------------------------------------------------------------------
diff --git a/server/lib/schedulers/youtube-dl-update-scheduler.ts b/server/lib/schedulers/youtube-dl-update-scheduler.ts
new file mode 100644 (file)
index 0000000..b736f17
--- /dev/null
@@ -0,0 +1,72 @@
+// Thanks: https://github.com/przemyslawpluta/node-youtube-dl/blob/master/lib/downloader.js
+// Use rewrote it to avoid sync calls
+
+import { AbstractScheduler } from './abstract-scheduler'
+import { SCHEDULER_INTERVALS_MS } from '../../initializers'
+import { logger } from '../../helpers/logger'
+import * as request from 'request'
+import { createWriteStream, writeFile } from 'fs'
+import { join } from 'path'
+import { root } from '../../helpers/core-utils'
+
+export class YoutubeDlUpdateScheduler extends AbstractScheduler {
+
+  private static instance: AbstractScheduler
+
+  protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.youtubeDLUpdate
+
+  private constructor () {
+    super()
+  }
+
+  async execute () {
+    const binDirectory = join(root(), 'node_modules', 'youtube-dl', 'bin')
+    const bin = join(binDirectory, 'youtube-dl')
+    const detailsPath = join(binDirectory, 'details')
+    const url = 'https://yt-dl.org/downloads/latest/youtube-dl'
+
+    request.get(url, { followRedirect: false }, (err, res) => {
+      if (err) {
+        logger.error('Cannot update youtube-dl.', { err })
+        return
+      }
+
+      if (res.statusCode !== 302) {
+        logger.error('youtube-dl update error: did not get redirect for the latest version link. Status %d', res.statusCode)
+        return
+      }
+
+      const url = res.headers.location
+      const downloadFile = request.get(url)
+      const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(url)[1]
+
+      downloadFile.on('response', res => {
+        if (res.statusCode !== 200) {
+          logger.error('Cannot update youtube-dl: new version response is not 200, it\'s %d.', res.statusCode)
+          return
+        }
+
+        downloadFile.pipe(createWriteStream(bin, { mode: 493 }))
+      })
+
+      downloadFile.on('error', err => logger.error('youtube-dl update error.', { err }))
+
+      downloadFile.on('end', () => {
+        const details = JSON.stringify({ version: newVersion, path: bin, exec: 'youtube-dl' })
+        writeFile(detailsPath, details, { encoding: 'utf8' }, err => {
+          if (err) {
+            logger.error('youtube-dl update error: cannot write details.', { err })
+            return
+          }
+
+          logger.info('youtube-dl updated to version %s.', newVersion)
+        })
+      })
+
+    })
+  }
+
+  static get Instance () {
+    return this.instance || (this.instance = new this())
+  }
+}