@@ -73,7 +73,7 @@
TorrentLibrary.js
/**
* The variable where we store all kind of media files found in paths
- * @typedef {Map.<string, {(TPN_Extended[]| Map.<string,TPN_Extended[]> )}>} StoreVar
+ * @typedef {Map.<string, {( Set<TPN_Extended>| Map.<string,Set<TPN_Extended>> )}>} StoreVar
* @example
* // An example of the variable after the scan method
* [
@@ -107,16 +107,31 @@
TorrentLibrary.js
/**
* module for exploring directories
+ * @external FileHound
* @see {@link https://nspragg.github.io/filehound/}
*/
-import FileHound from 'filehound';
+import FileHound from 'filehound';
/**
- * module fs from node
- * @see {@link https://nodejs.org/api/fs.html}
+ * Access method from module fs (node)
+ * @external access
+ * @see {@link https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback}
*/
import {access} from 'fs';
+/**
+ * uniq method from Lodash
+ * @external uniq
+ * @see {@link https://lodash.com/docs/4.17.4#uniq}
+ */
+import {uniq} from 'lodash';
+/**
+ * difference method from lodash
+ * @external difference
+ * @see {@link https://lodash.com/docs/4.17.4#difference}
+ */
+import {difference} from 'lodash';
+
/**
* A promise object provided by the bluebird promise library.
* @external Promise
@@ -126,10 +141,25 @@
TorrentLibrary.js
/**
* List of video file extensions
+ * @external videosExtension
* @see {@link https://github.com/sindresorhus/video-extensions}
*/
import videosExtension from 'video-extensions';
+/**
+ * Parser for media files name
+ * @external nameParser
+ * @see {@link https://github.com/jy95/torrent-name-parser}
+ */
+import nameParser from 'torrent-name-parser'
+
+/**
+ * Constants for fs access
+ */
+import {
+ constants as FsConstants
+} from 'fs'
+
import {
EventEmitter
} from 'events';
@@ -146,13 +176,17 @@
TorrentLibrary.js
* @since 0.0.0
* @return {string}
*/
- static get MOVIES_TYPE() { return "MOVIES" }
+ static get MOVIES_TYPE() {
+ return "MOVIES"
+ }
/**
* constant for tv series category
* @return {string}
*/
- static get TV_SERIES_TYPE() { return "TV_SERIES"}
+ static get TV_SERIES_TYPE() {
+ return "TV_SERIES"
+ }
/**
* Create a TorrentLibrary
@@ -179,9 +213,92 @@
TorrentLibrary.js
* @member {StoreVar}
*/
this.stores = new Map([
- [ TorrentLibrary.MOVIES_TYPE , [] ],
- [ TorrentLibrary.TV_SERIES_TYPE, new Map()]
- ])
+ [TorrentLibrary.MOVIES_TYPE, new Set()],
+ [TorrentLibrary.TV_SERIES_TYPE, new Map()]
+ ]);
+ /**
+ * Mapping filepath => category
+ * @type {Map}
+ * @example
+ * { "D:\somePath\Captain Russia The Summer Soldier (2014) 1080p BrRip x264.MKV" => TorrentLibrary.MOVIES_TYPE }
+ */
+ this.categoryForFile = new Map();
+ /**
+ * Private method for adding new files
+ * @private
+ * @param files {string[]} An array of filePath
+ */
+ this.addNewFiles = function (files) {
+
+ // find the new files to be added
+ let alreadyFoundFiles = [...this.categoryForFile.keys()];
+ let newFiles = difference(files, alreadyFoundFiles);
+
+ // temp var for new files before adding them to stores var
+ let moviesSet = new Set();
+ let tvSeriesSet = new Set();
+
+ // get previous result of stores var
+ let newMovies = this.stores.get(TorrentLibrary.MOVIES_TYPE);
+ let newTvSeries = this.stores.get(TorrentLibrary.TV_SERIES_TYPE);
+
+ // process each file
+ for (let file of newFiles) {
+ // get data from nameParser lib
+ let jsonFile = nameParser(file);
+ // extend this object in order to be used by this library
+ Object.assign(jsonFile, {"filePath": file});
+ // find out which type of this file
+ // if it has not undefined properties (season and episode) => TV_SERIES , otherwise MOVIE
+ let fileCategory = ( checkProperties(jsonFile, ["season", "episode"]) )
+ ? TorrentLibrary.TV_SERIES_TYPE : TorrentLibrary.MOVIES_TYPE;
+ // add it in found files
+ this.categoryForFile.set(file, fileCategory);
+ // also in temp var
+ (fileCategory === TorrentLibrary.TV_SERIES_TYPE) ? tvSeriesSet.add(jsonFile) : moviesSet.add(jsonFile);
+ }
+
+ // add the movies into newMovies
+ newMovies = new Set([...newMovies, ...moviesSet]);
+
+ // add the tv series into newTvSeries
+ // First step : find all the series not in newTvSeries and add them to newTvSeries
+ difference(
+ uniq(
+ [...tvSeriesSet].map(function (tvSeries) {
+ return tvSeries.title;
+ })
+ ),
+ ...newTvSeries.keys()
+ ).forEach(function (tvSeriesToInsert) {
+ newTvSeries.set(tvSeriesToInsert, new Set());
+ });
+
+ // Second step : add the new files into the correct tvSeries Set
+ uniq(
+ [...tvSeriesSet].map(function (tvSeries) {
+ return tvSeries.title;
+ })
+ ).forEach(function (tvSerie) {
+
+ // get the current set for this tvSerie
+ let currentTvSerie = newTvSeries.get(tvSerie);
+
+ // find all the episodes in the new one for this serie
+ let episodes = [...tvSeriesSet].filter(function (episode) {
+ return episode.title === tvSerie;
+ });
+
+ // add them and updates newTvSeries
+ newTvSeries.set(tvSerie, new Set([...currentTvSerie,...episodes]));
+
+ });
+
+ // updates the stores var
+ this.stores.set(TorrentLibrary.MOVIES_TYPE, newMovies);
+ this.stores.set(TorrentLibrary.TV_SERIES_TYPE, newTvSeries);
+
+ }
}
/**
@@ -193,7 +310,7 @@
TorrentLibrary.js
* TorrentLibrary.listVideosExtension()
* @static
*/
- static listVideosExtension(){
+ static listVideosExtension() {
return videosExtension;
}
@@ -205,26 +322,25 @@
TorrentLibrary.js
* // return resolved Promise "All paths were added!"
* TorrentLibraryInstance.addNewPath("C:\Users\jy95\Desktop\New folder");
* @return {external:Promise} On success the promise will be resolved with "All paths were added!"<br>
- * On error the promise will be rejected with an "Missing parameter" if the argument is missing<br>
- * or "Cannot find/read a path" if one of the provided paths doesn't exist or is not readable<br>
+ * On error the promise will be rejected with an Error object "Missing parameter" if the argument is missing<br>
+ * or an Error object from fs <br>
*/
- addNewPath(...paths){
+ addNewPath(...paths) {
// the user should provide us at lest a path
if (paths.length === 0)
return missingParam();
let that = this;
- return new PromiseLib(function (resolve,reject) {
+ return new PromiseLib(function (resolve, reject) {
- return new PromiseLib.map(paths, function (path) {
- // https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback
- // check if directory exists and is readable
- return access(path, fs.constants.F_OK | fs.constants.R_OK);
+ PromiseLib.map(paths, function (path) {
+ return access(path, FsConstants.F_OK | FsConstants.R_OK);
}).then(function () {
- that.paths = [...that.paths, ...paths];
+ // keep only unique paths
+ that.paths = uniq([...that.paths, ...paths]);
resolve("All paths were added!");
}).catch(e => {
- reject("Cannot find/read a path");
+ reject(e);
})
});
@@ -236,7 +352,7 @@
TorrentLibrary.js
* @since 0.0.0
* @returns {boolean}
*/
- hasPathsProvidedByUser(){
+ hasPathsProvidedByUser() {
return this.paths.length === 0;
}
@@ -244,26 +360,42 @@
TorrentLibrary.js
* @todo Write the documentation.
* @todo Implement this function.
*/
- scan(){
- /*
- const files = FileHound.create()
- .paths( (this.paths.length === 0) ? this.defaultPath : this.paths)
+ scan() {
+
+ const foundFiles = FileHound.create()
+ .paths((this.paths.length === 0) ? this.defaultPath : this.paths)
.ext(videosExtension)
.find();
- */
- return null;
+ let that = this;
+ return new PromiseLib(function (resolve, reject) {
+ foundFiles
+ .then(function (files) {
+ that.addNewFiles(files);
+ resolve("Scanning completed");
+ })
+ .catch(function (err) {
+ reject(err);
+ });
+ });
}
}
// rejected promise when someone doesn't provide
function missingParam() {
- return new PromiseLib(function (resolve,reject) {
- reject("Missing parameter");
+ return new PromiseLib(function (resolve, reject) {
+ reject(new Error("Missing parameter"));
});
}
+// check if an object has these properties and they are not undefined
+function checkProperties(obj, properties) {
+ return properties.every(function (x) {
+ return x in obj && obj[x];
+ })
+}
+
export default TorrentLibrary;
@@ -276,7 +408,7 @@
TorrentLibrary.js
- Generated by JSDoc 3.5.4 on Sat Aug 26 2017 02:36:48 GMT+0200 (Romance Daylight Time) using the Minami theme.
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
diff --git a/docs/external-FileHound.html b/docs/external-FileHound.html
new file mode 100644
index 0000000..ec35014
--- /dev/null
+++ b/docs/external-FileHound.html
@@ -0,0 +1,148 @@
+
+
+
+
+
+
FileHound - Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
+
+
+
+
+
FileHound
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
module for exploring directories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+ See:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/external-Promise.html b/docs/external-Promise.html
index 1174d52..9f556fa 100644
--- a/docs/external-Promise.html
+++ b/docs/external-Promise.html
@@ -24,7 +24,7 @@
- Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E Promise Globals
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
@@ -87,7 +87,7 @@
Source:
@@ -139,7 +139,7 @@
- Generated by JSDoc 3.5.4 on Sat Aug 26 2017 02:36:48 GMT+0200 (Romance Daylight Time) using the Minami theme.
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
diff --git a/docs/external-access.html b/docs/external-access.html
new file mode 100644
index 0000000..4cd3115
--- /dev/null
+++ b/docs/external-access.html
@@ -0,0 +1,148 @@
+
+
+
+
+
+ access - Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
+
+
+
+
+
access
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Access method from module fs (node)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+ See:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/external-difference.html b/docs/external-difference.html
new file mode 100644
index 0000000..20c0ab9
--- /dev/null
+++ b/docs/external-difference.html
@@ -0,0 +1,148 @@
+
+
+
+
+
+ difference - Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
+
+
+
+
+
difference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
difference method from lodash
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+ See:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/external-nameParser.html b/docs/external-nameParser.html
new file mode 100644
index 0000000..b26559a
--- /dev/null
+++ b/docs/external-nameParser.html
@@ -0,0 +1,148 @@
+
+
+
+
+
+ nameParser - Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
+
+
+
+
+
nameParser
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Parser for media files name
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+ See:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/external-uniq.html b/docs/external-uniq.html
new file mode 100644
index 0000000..7b102c5
--- /dev/null
+++ b/docs/external-uniq.html
@@ -0,0 +1,148 @@
+
+
+
+
+
+ uniq - Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
+
+
+
+
+
uniq
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
uniq method from Lodash
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+ See:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/external-videosExtension.html b/docs/external-videosExtension.html
new file mode 100644
index 0000000..d492dd4
--- /dev/null
+++ b/docs/external-videosExtension.html
@@ -0,0 +1,148 @@
+
+
+
+
+
+ videosExtension - Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
+
+
+
+
+
videosExtension
+
+
+
+
+
+
+
+
+
+
+
+
+ videosExtension
+
+
+
+
+
+
+
+
+
+
List of video file extensions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source:
+
+
+
+
+
+
+ See:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/global.html b/docs/global.html
index 61e8cc3..7afcf9c 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -24,7 +24,7 @@
- Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E Promise Globals
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
@@ -175,7 +175,7 @@
Type:
-Map.<string, {(Array.<TPN_Extended >|Map.<string, Array.<TPN_Extended >>)}>
+Map.<string, {(Set.<TPN_Extended >|Map.<string, Set.<TPN_Extended >>)}>
@@ -975,7 +975,7 @@ Type:
- Generated by JSDoc 3.5.4 on Sat Aug 26 2017 02:36:48 GMT+0200 (Romance Daylight Time) using the Minami theme.
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
diff --git a/docs/index.html b/docs/index.html
index 28ece0a..51b6d65 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -24,7 +24,7 @@
- Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E Promise Globals
+ Home Classes C TorrentLibrary F listVideosExtension F addNewPath F hasPathsProvidedByUser F scan Externals E access E difference E FileHound E nameParser E Promise E uniq E videosExtension Globals
@@ -57,7 +57,7 @@
- Generated by JSDoc 3.5.4 on Sat Aug 26 2017 02:36:48 GMT+0200 (Romance Daylight Time) using the Minami theme.
+ Generated by JSDoc 3.5.4 on Sat Aug 26 2017 19:02:13 GMT+0200 (Romance Daylight Time) using the Minami theme.
diff --git a/package-lock.json b/package-lock.json
index eb8a793..fd63b23 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4122,6 +4122,9 @@
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
"dev": true
},
+ "torrent-name-parser": {
+ "version": "git+https://github.com/jy95/torrent-name-parser.git#5f03a3e2a79276d3fd3368eb7161fa99bc33483a"
+ },
"tough-cookie": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
diff --git a/package.json b/package.json
index f9ccb91..5c9fbc3 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,8 @@
"dependencies": {
"bluebird": "^3.5.0",
"filehound": "^1.16.2",
+ "lodash": "^4.17.4",
+ "torrent-name-parser": "git+https://github.com/jy95/torrent-name-parser.git",
"video-extensions": "^1.1.0"
}
}
diff --git a/src/TorrentLibrary.js b/src/TorrentLibrary.js
index beaffca..ea36669 100644
--- a/src/TorrentLibrary.js
+++ b/src/TorrentLibrary.js
@@ -32,7 +32,7 @@
/**
* The variable where we store all kind of media files found in paths
- * @typedef {Map.
)}>} StoreVar
+ * @typedef {Map.| Map.> )}>} StoreVar
* @example
* // An example of the variable after the scan method
* [
@@ -66,16 +66,31 @@
/**
* module for exploring directories
+ * @external FileHound
* @see {@link https://nspragg.github.io/filehound/}
*/
-import FileHound from 'filehound';
+import FileHound from 'filehound';
/**
- * module fs from node
- * @see {@link https://nodejs.org/api/fs.html}
+ * Access method from module fs (node)
+ * @external access
+ * @see {@link https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback}
*/
import {access} from 'fs';
+/**
+ * uniq method from Lodash
+ * @external uniq
+ * @see {@link https://lodash.com/docs/4.17.4#uniq}
+ */
+import {uniq} from 'lodash';
+/**
+ * difference method from lodash
+ * @external difference
+ * @see {@link https://lodash.com/docs/4.17.4#difference}
+ */
+import {difference} from 'lodash';
+
/**
* A promise object provided by the bluebird promise library.
* @external Promise
@@ -85,10 +100,25 @@ import PromiseLib from 'bluebird'
/**
* List of video file extensions
+ * @external videosExtension
* @see {@link https://github.com/sindresorhus/video-extensions}
*/
import videosExtension from 'video-extensions';
+/**
+ * Parser for media files name
+ * @external nameParser
+ * @see {@link https://github.com/jy95/torrent-name-parser}
+ */
+import nameParser from 'torrent-name-parser'
+
+/**
+ * Constants for fs access
+ */
+import {
+ constants as FsConstants
+} from 'fs'
+
import {
EventEmitter
} from 'events';
@@ -105,13 +135,17 @@ class TorrentLibrary extends EventEmitter {
* @since 0.0.0
* @return {string}
*/
- static get MOVIES_TYPE() { return "MOVIES" }
+ static get MOVIES_TYPE() {
+ return "MOVIES"
+ }
/**
* constant for tv series category
* @return {string}
*/
- static get TV_SERIES_TYPE() { return "TV_SERIES"}
+ static get TV_SERIES_TYPE() {
+ return "TV_SERIES"
+ }
/**
* Create a TorrentLibrary
@@ -138,9 +172,92 @@ class TorrentLibrary extends EventEmitter {
* @member {StoreVar}
*/
this.stores = new Map([
- [ TorrentLibrary.MOVIES_TYPE , [] ],
- [ TorrentLibrary.TV_SERIES_TYPE, new Map()]
- ])
+ [TorrentLibrary.MOVIES_TYPE, new Set()],
+ [TorrentLibrary.TV_SERIES_TYPE, new Map()]
+ ]);
+ /**
+ * Mapping filepath => category
+ * @type {Map}
+ * @example
+ * { "D:\somePath\Captain Russia The Summer Soldier (2014) 1080p BrRip x264.MKV" => TorrentLibrary.MOVIES_TYPE }
+ */
+ this.categoryForFile = new Map();
+ /**
+ * Private method for adding new files
+ * @private
+ * @param files {string[]} An array of filePath
+ */
+ this.addNewFiles = function (files) {
+
+ // find the new files to be added
+ let alreadyFoundFiles = [...this.categoryForFile.keys()];
+ let newFiles = difference(files, alreadyFoundFiles);
+
+ // temp var for new files before adding them to stores var
+ let moviesSet = new Set();
+ let tvSeriesSet = new Set();
+
+ // get previous result of stores var
+ let newMovies = this.stores.get(TorrentLibrary.MOVIES_TYPE);
+ let newTvSeries = this.stores.get(TorrentLibrary.TV_SERIES_TYPE);
+
+ // process each file
+ for (let file of newFiles) {
+ // get data from nameParser lib
+ let jsonFile = nameParser(file);
+ // extend this object in order to be used by this library
+ Object.assign(jsonFile, {"filePath": file});
+ // find out which type of this file
+ // if it has not undefined properties (season and episode) => TV_SERIES , otherwise MOVIE
+ let fileCategory = ( checkProperties(jsonFile, ["season", "episode"]) )
+ ? TorrentLibrary.TV_SERIES_TYPE : TorrentLibrary.MOVIES_TYPE;
+ // add it in found files
+ this.categoryForFile.set(file, fileCategory);
+ // also in temp var
+ (fileCategory === TorrentLibrary.TV_SERIES_TYPE) ? tvSeriesSet.add(jsonFile) : moviesSet.add(jsonFile);
+ }
+
+ // add the movies into newMovies
+ newMovies = new Set([...newMovies, ...moviesSet]);
+
+ // add the tv series into newTvSeries
+ // First step : find all the series not in newTvSeries and add them to newTvSeries
+ difference(
+ uniq(
+ [...tvSeriesSet].map(function (tvSeries) {
+ return tvSeries.title;
+ })
+ ),
+ ...newTvSeries.keys()
+ ).forEach(function (tvSeriesToInsert) {
+ newTvSeries.set(tvSeriesToInsert, new Set());
+ });
+
+ // Second step : add the new files into the correct tvSeries Set
+ uniq(
+ [...tvSeriesSet].map(function (tvSeries) {
+ return tvSeries.title;
+ })
+ ).forEach(function (tvSerie) {
+
+ // get the current set for this tvSerie
+ let currentTvSerie = newTvSeries.get(tvSerie);
+
+ // find all the episodes in the new one for this serie
+ let episodes = [...tvSeriesSet].filter(function (episode) {
+ return episode.title === tvSerie;
+ });
+
+ // add them and updates newTvSeries
+ newTvSeries.set(tvSerie, new Set([...currentTvSerie,...episodes]));
+
+ });
+
+ // updates the stores var
+ this.stores.set(TorrentLibrary.MOVIES_TYPE, newMovies);
+ this.stores.set(TorrentLibrary.TV_SERIES_TYPE, newTvSeries);
+
+ }
}
/**
@@ -152,7 +269,7 @@ class TorrentLibrary extends EventEmitter {
* TorrentLibrary.listVideosExtension()
* @static
*/
- static listVideosExtension(){
+ static listVideosExtension() {
return videosExtension;
}
@@ -164,26 +281,25 @@ class TorrentLibrary extends EventEmitter {
* // return resolved Promise "All paths were added!"
* TorrentLibraryInstance.addNewPath("C:\Users\jy95\Desktop\New folder");
* @return {external:Promise} On success the promise will be resolved with "All paths were added!"
- * On error the promise will be rejected with an "Missing parameter" if the argument is missing
- * or "Cannot find/read a path" if one of the provided paths doesn't exist or is not readable
+ * On error the promise will be rejected with an Error object "Missing parameter" if the argument is missing
+ * or an Error object from fs
*/
- addNewPath(...paths){
+ addNewPath(...paths) {
// the user should provide us at lest a path
if (paths.length === 0)
return missingParam();
let that = this;
- return new PromiseLib(function (resolve,reject) {
+ return new PromiseLib(function (resolve, reject) {
- return new PromiseLib.map(paths, function (path) {
- // https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback
- // check if directory exists and is readable
- return access(path, fs.constants.F_OK | fs.constants.R_OK);
+ PromiseLib.map(paths, function (path) {
+ return access(path, FsConstants.F_OK | FsConstants.R_OK);
}).then(function () {
- that.paths = [...that.paths, ...paths];
+ // keep only unique paths
+ that.paths = uniq([...that.paths, ...paths]);
resolve("All paths were added!");
}).catch(e => {
- reject("Cannot find/read a path");
+ reject(e);
})
});
@@ -195,7 +311,7 @@ class TorrentLibrary extends EventEmitter {
* @since 0.0.0
* @returns {boolean}
*/
- hasPathsProvidedByUser(){
+ hasPathsProvidedByUser() {
return this.paths.length === 0;
}
@@ -203,23 +319,40 @@ class TorrentLibrary extends EventEmitter {
* @todo Write the documentation.
* @todo Implement this function.
*/
- scan(){
- /*
- const files = FileHound.create()
- .paths( (this.paths.length === 0) ? this.defaultPath : this.paths)
+ scan() {
+
+ const foundFiles = FileHound.create()
+ .paths((this.paths.length === 0) ? this.defaultPath : this.paths)
.ext(videosExtension)
.find();
- */
- return null;
+ let that = this;
+
+ return new PromiseLib(function (resolve, reject) {
+ foundFiles
+ .then(function (files) {
+ that.addNewFiles(files);
+ resolve("Scanning completed");
+ })
+ .catch(function (err) {
+ reject(err);
+ });
+ });
}
}
// rejected promise when someone doesn't provide
function missingParam() {
- return new PromiseLib(function (resolve,reject) {
- reject("Missing parameter");
+ return new PromiseLib(function (resolve, reject) {
+ reject(new Error("Missing parameter"));
});
}
+// check if an object has these properties and they are not undefined
+function checkProperties(obj, properties) {
+ return properties.every(function (x) {
+ return x in obj && obj[x];
+ })
+}
+
export default TorrentLibrary;
\ No newline at end of file
diff --git a/test/APITests.js b/test/APITests.js
index e3297c9..4de98a8 100644
--- a/test/APITests.js
+++ b/test/APITests.js
@@ -1,14 +1,53 @@
import TorrentLibrary from "../lib/TorrentLibrary";
import videosExtension from 'video-extensions';
import assert from "assert";
+import path from "path";
+import fs from "fs";
+
+// just a cross plateform way to remove folder recursively
+function deleteFolderRecursive(path) {
+ if (fs.existsSync(path)) {
+ fs.readdirSync(path).forEach(function (file, index) {
+ var curPath = path + "/" + file;
+ if (fs.lstatSync(curPath).isDirectory()) { // recurse
+ deleteFolderRecursive(curPath);
+ } else { // delete file
+ fs.unlinkSync(curPath);
+ }
+ });
+ fs.rmdirSync(path);
+ }
+}
-describe("TorrentLibrary tests",function () {
+describe("TorrentLibrary tests", function () {
let libInstance;
+ let folders = [path.join(__dirname, "folder1"), path.join(__dirname, "folder2")];
+ let files = [
+ path.join(__dirname, "folder1", "The.Blacklist.S04E21.FRENCH.WEBRip.XviD.avi"),
+ path.join(__dirname, "folder2", "The.Blacklist.S04E14.FRENCH.WEBRip.XviD.avi"),
+ path.join(__dirname, "folder1", "Bad.Ass.2012.LiMiTED.TRUEFRENCH.DVDRiP.XviD-www.zone-telechargement.ws.avi")
+ ];
// initialization
before(function () {
libInstance = new TorrentLibrary();
+
+ // removes previously folders for test and recreate them
+ folders.forEach(function (folder) {
+ deleteFolderRecursive(folder);
+ fs.mkdir(folder, (err) => {
+ if (err) throw err;
+ });
+ });
+
+ // create the files for scan methods
+ files.forEach(function (file) {
+ fs.writeFile(file, "", (err) => {
+ if (err) throw err;
+ });
+ });
+
});
describe("Static methods", function () {
@@ -16,7 +55,7 @@ describe("TorrentLibrary tests",function () {
context("listVideosExtension()", function () {
it("should provide the same list of videos extensions", function () {
- assert.deepEqual(JSON.stringify(videosExtension), JSON.stringify(TorrentLibrary.listVideosExtension()), "Not the same JSON" );
+ assert.deepEqual(JSON.stringify(videosExtension), JSON.stringify(TorrentLibrary.listVideosExtension()), "Not the same JSON");
});
});
@@ -24,34 +63,64 @@ describe("TorrentLibrary tests",function () {
context("Constants", function () {
it("MOVIES_TYPE", function () {
- assert.equal(TorrentLibrary.MOVIES_TYPE, "MOVIES", "Someone changed this constant value !");
+ assert.equal(TorrentLibrary.MOVIES_TYPE, "MOVIES", "Someone changed this constant value !");
});
it("TV_SERIES_TYPE", function () {
- assert.equal(TorrentLibrary.TV_SERIES_TYPE, "TV_SERIES", "Someone changed this constant value !");
+ assert.equal(TorrentLibrary.TV_SERIES_TYPE, "TV_SERIES", "Someone changed this constant value !");
});
});
});
- describe("Instance Methods - To be implemented", function () {
+ describe("Instance Methods", function () {
- /*
context("addNewPath()", function () {
- it("missing parameter",function (done) {
- return libInstance.addNewPath()
- .then( () => {
+ it("missing parameter", function (done) {
+ libInstance.addNewPath()
+ .then(() => {
done(new Error("Missing parameter"));
})
- .catch( (err) => {
+ .catch(() => {
done();
})
- })
+ });
+ it("inexistent Path", function (done) {
+ libInstance.addNewPath(path.join(__dirname, "wrongPath"))
+ .then(() => {
+ done(new Error("This path should not exist or be readable"));
+ })
+ .catch(() => {
+ done();
+ })
+ });
+
+ /*
+ it("existent paths", function (done) {
+ libInstance.addNewPath(folders)
+ .then(() => {
+ done()
+ }).catch((err) => {
+ done(err);
+ })
+ });
+ */
});
- */
+
+ context("scan()", function () {
+ this.timeout(10000);
+
+ it("Must work without error", function (done) {
+ libInstance.scan().then(function () {
+ done();
+ }).catch((err) => {
+ done(err);
+ });
+ });
+ })
});