From 2365b574d1b668e8b6ad450c5e3438f69c5e7ad2 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Mon, 27 Apr 2020 23:13:22 +0200
Subject: [PATCH] Cleanup metadata loader

---
 src/api/imdb_api.js        |  4 +-
 src/directory_walker.js    |  5 +-
 src/metadata_loader.js     | 36 +++++++++++++--
 src/old_metadata_loader.js | 94 --------------------------------------
 src/util/encode-path.js    |  7 +++
 src/util/video-mime.js     |  4 +-
 6 files changed, 47 insertions(+), 103 deletions(-)
 delete mode 100644 src/old_metadata_loader.js
 create mode 100644 src/util/encode-path.js

diff --git a/src/api/imdb_api.js b/src/api/imdb_api.js
index 85a026e..12313c7 100644
--- a/src/api/imdb_api.js
+++ b/src/api/imdb_api.js
@@ -30,11 +30,11 @@ class ImdbApi {
     }
 
     search(type, title, year) {
-        return this.queryJson(ImdbApi.querySearch, {
+        return this.query(ImdbApi.querySearch, {
             1: type,
             2: title, 3: title,
             4: year
-        });
+        }).then(row => row.tconst);
     }
 
     static querySearch = `
diff --git a/src/directory_walker.js b/src/directory_walker.js
index f96daa2..59a4071 100644
--- a/src/directory_walker.js
+++ b/src/directory_walker.js
@@ -1,5 +1,6 @@
 import path from 'path';
 import {promises as fsPromises} from 'fs';
+import encodePath from "./util/encode-path";
 
 class FileManager {
     basePath;
@@ -94,7 +95,7 @@ class FileManager {
 
         const media = await Promise.all(mediaFiles.map(fileName => this.videoMimeParser.parseMediaInfo(path.join(base, fileName)).then(metadata => {
             return {
-                src: encodeURI(path.relative(this.basePath, path.join(base, fileName))),
+                src: encodePath(path.relative(this.basePath, path.join(base, fileName))),
                 ...metadata
             }
         })));
@@ -107,7 +108,7 @@ class FileManager {
                     region: region,
                     specifier: specifier,
                     format: format,
-                    src: encodeURI(path.relative(this.basePath, path.join(base, "subtitles", name)))
+                    src: encodePath(path.relative(this.basePath, path.join(base, "subtitles", name)))
                 }
             }),
             media: media
diff --git a/src/metadata_loader.js b/src/metadata_loader.js
index 1151072..3357826 100644
--- a/src/metadata_loader.js
+++ b/src/metadata_loader.js
@@ -2,6 +2,7 @@ import ranking_confidence from './util/statistics';
 import uuid from 'uuid';
 import path from "path";
 import downloadFile from "./util/download-file";
+import encodePath from "./util/encode-path";
 
 class MetadataLoader {
     imdb;
@@ -130,22 +131,51 @@ class MetadataLoader {
         } : null;
     }
 
+    async identifyShow(title, year) {
+        /*
+        FIXME: Implement this properly, previous implementation for clarity below
+
+        const imdbId = await this.imdb.search("tvSeries", title, year);
+
+        const tvdbResults = await this.tvdb.getSeriesByImdbId(imdbId).catch((e) => console.error(e));
+        const tvdbResult = tvdbResults[0];
+
+        if (!tvdbResult) return null;
+
+        const tmdbResults = await this.tmdb.request(`find/${imdbId}`, {
+            "external_source": "imdb_id",
+        }).catch((e) => console.error(e));
+
+        const tmdbResult = tmdbResults.tv_results.sort((a, b) => {
+            return b.popularity - a.popularity;
+        })[0];
+
+        if (!tmdbResult) return null;
+
+        return {
+            imdb: imdbId,
+            tvdb: tvdbResult.id,
+            tmdb: tmdbResult.id,
+        };
+         */
+    }
+
     async processImages(basePath, filePath, images) {
         const imageData = !images ? [] : [
             !images.logo ? null : !images.logo.url ? null : {
                 type: "logo",
                 url: images.logo.url,
-                src: encodeURI(path.relative(basePath, path.join(filePath, "metadata", `logo${path.extname(images.logo.url)}`)))
+                src: encodePath(path.relative(basePath, path.join(filePath, "metadata", `logo${path.extname(images.logo.url)}`)))
             },
             !images.poster ? null : !images.poster.file_path ? null : {
                 type: "poster",
                 url: this.tmdb.getImageUrl(images.poster.file_path),
-                src: encodeURI(path.relative(basePath, path.join(filePath, "metadata", `poster${path.extname(images.poster.file_path)}`)))
+                src: encodePath(path.relative(basePath, path.join(filePath, "metadata", `poster${path.extname(images.poster.file_path)}`)))
             },
             !images.backdrop ? null : !images.backdrop.file_path ? null : {
                 type: "backdrop",
                 url: this.tmdb.getImageUrl(images.backdrop.file_path),
-                src: encodeURI(path.relative(basePath, path.join(filePath, "metadata", `backdrop${path.extname(images.backdrop.file_path)}`)))
+                src: encodePath(path.relative(basePath, path.join(filePath, "metadata", `backdrop${path.extname(images.backdrop.file_path)}`)))
             }
         ].filter(el => el !== null);
 
diff --git a/src/old_metadata_loader.js b/src/old_metadata_loader.js
deleted file mode 100644
index 5dd6f7d..0000000
--- a/src/old_metadata_loader.js
+++ /dev/null
@@ -1,94 +0,0 @@
-// FIXME: Implement all this over to the metadata loader, and clean it up meanwhile
-
-async function identifyMovie(api, imdb, tvdb, title, year) {
-    const results = await api.request(`search/movie`, {
-        query: title,
-        primary_release_year: year
-    }).catch((e) => console.error(e));
-
-    const result = results.results.sort((a, b) => {
-        return b.popularity - a.popularity;
-    })[0];
-
-    return result ? {
-        tmdb: result.id
-    } : null;
-}
-
-async function identifyShow(tmdbApi, imdbApi, tvdbApi, title, showYear) {
-    const imdbId = await utils.promisify(imdbApi, "get", idQuery, {1: "tvSeries", 2: title, 3: title, 4: showYear})
-        .then((data) => data.tconst);
-
-    const tvdbResults = await tvdbApi.getSeriesByImdbId(imdbId).catch((e) => console.error(e));
-    const tvdbResult = tvdbResults[0];
-
-    if (!tvdbResult) return null;
-
-    const tmdbResults = await tmdbApi.request(`find/${imdbId}`, {
-        "external_source": "imdb_id",
-    }).catch((e) => console.error(e));
-
-    const tmdbResult = tmdbResults.tv_results.sort((a, b) => {
-        return b.popularity - a.popularity;
-    })[0];
-
-    if (!tmdbResult) return null;
-
-    return {
-        imdb: imdbId,
-        tvdb: tvdbResult.id,
-        tmdb: tmdbResult.id,
-    };
-}
-
-function downloadImage(url, filePath) {
-    return new Promise(((resolve, reject) => {
-        const file = fs.createWriteStream(filePath);
-        https.get(url, function (response) {
-            response.pipe(file);
-            file.on('finish', function () {
-                file.close(() => {
-                    resolve();
-                });
-            });
-        }).on('error', function (err) {
-            fs.unlink(filePath);
-            reject(err);
-        });
-    }));
-}
-
-async function processFile(isShow, tmdbApi, fanartApi, imdb, tvdbApi, uuid, filePath) {
-    const {name, year} = /^(?<name>.+) \((?<year>\d+)\)$/.exec(path.basename(filePath)).groups;
-
-    const identifyFunction = isShow ? identifyShow : identifyMovie;
-    const ids = await identifyFunction(tmdbApi, imdb, tvdbApi, name, year);
-    if (ids === null) {
-        console.error(`No item in TMDB found for "${name}" from year "${year}" at path "${filePath}"`);
-        return
-    }
-
-    function processImage(type, imageUrl) {
-        const ending = path.extname(imageUrl);
-        return downloadImage(imageUrl, path.join(filePath, `metadata/${type}${ending}`));
-    }
-
-    data.data.subtitles = processSubtitles(filePath);
-    data.data.hasLogo = !!hdMovieLogo;
-    data.data.src = path.join("/api/", isShow ? "Shows" : "Movies", encodeURIComponent(path.basename(filePath)));
-
-    // Write metadata
-    await utils.promisify(fs, "writeFile", path.join(filePath, "metadata.json"), JSON.stringify(data.data));
-
-    // Creating metadata folder
-    if (!fs.existsSync(path.join(filePath, 'metadata'))) {
-        await fs.promises.mkdir(path.join(filePath, 'metadata'));
-    }
-
-    // Writing images
-    await Promise.all([
-        poster ? processImage("poster", tmdbApi.getImageUrl(poster.file_path)) : null,
-        backdrop ? processImage("backdrop", tmdbApi.getImageUrl(backdrop.file_path)) : null,
-        hdMovieLogo ? processImage("logo", hdMovieLogo.url) : null,
-    ].filter(el => el));
-}
\ No newline at end of file
diff --git a/src/util/encode-path.js b/src/util/encode-path.js
new file mode 100644
index 0000000..69c3025
--- /dev/null
+++ b/src/util/encode-path.js
@@ -0,0 +1,7 @@
+import path from 'path';
+
+function encodePath(filePath) {
+    return path.join(...filePath.split(path.sep).map(encodeURIComponent))
+}
+
+export default encodePath;
\ No newline at end of file
diff --git a/src/util/video-mime.js b/src/util/video-mime.js
index 7a42433..32c0d9f 100644
--- a/src/util/video-mime.js
+++ b/src/util/video-mime.js
@@ -1,4 +1,4 @@
-import fs, {promises as fsPromises} from 'fs';
+import {promises as fsPromises} from 'fs';
 import path from 'path';
 import xml2json from 'xml2json';
 import {exec} from 'child_process';
@@ -16,7 +16,7 @@ class VideoMimeParser {
     async parseMediaInfoDash(filePath) {
         const info = xml2json.toJson(await fsPromises.readFile(filePath), {object: true});
         return {
-            container: "application/xml+dash",
+            container: "application/dash+xml",
             tracks: info.MPD.Period.AdaptationSet.map((track, i) => {
                 return {
                     id: i,
-- 
GitLab