+
Skip to content

Improvements #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 25, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 79 additions & 80 deletions src/MediaScan.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Imports
import FileHound from 'filehound';
import {basename, normalize} from 'path';
import {uniq, difference, partition, cloneDeep} from 'lodash';
import {uniq, difference, partition, cloneDeep, reduce, concat, has, forIn, map, chain, filter, some, includes} from 'lodash';
import PromiseLib from 'bluebird';

const videosExtension = require('video-extensions');
Expand Down Expand Up @@ -65,16 +65,8 @@ module.exports = class MediaScan extends EventEmitter {
const alreadyFoundFiles = [...this.categoryForFile.keys()];
const newFiles = difference(files, alreadyFoundFiles);

// temp var for new files before adding them to stores var
const moviesSet = new Set();
const tvSeriesSet = new Set();

// get previous result of stores var
let newMovies = this.allMovies;
const newTvSeries = this.allTvSeries;

// process each file
for (const file of newFiles) {
let scanningResult = reduce(newFiles, (result, file) => {
// get data from nameParser lib
// what we need is only the basename, not the full path
const jsonFile = this.parser(basename(file));
Expand All @@ -85,48 +77,37 @@ module.exports = class MediaScan extends EventEmitter {
const fileCategory = this.whichCategory(jsonFile);
// add it in found files
this.categoryForFile.set(file, fileCategory);
// also in temp var
// workaround : const string enum aren't compiled correctly with Babel
if (fileCategory !== MediaScan.TV_SERIES_TYPE) {
moviesSet.add(jsonFile);
} else {
tvSeriesSet.add(jsonFile);
}
// store the result for next usage
result[fileCategory] = concat((has(result, fileCategory)) ? result[fileCategory] : [], jsonFile);
return result;
}, {});

// add the found movies
if (scanningResult[MediaScan.MOVIES_TYPE] !== undefined) {
this.stores.set(MediaScan.MOVIES_TYPE,
new Set([...this.allMovies, ...scanningResult[MediaScan.MOVIES_TYPE]]));
}

// 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(tvSeries => tvSeries.title)),
...newTvSeries.keys(),
).forEach((tvSeriesToInsert) => {
newTvSeries.set(tvSeriesToInsert, new Set());
});

// Second step : add the new files into the correct tvSeries Set
uniq([...tvSeriesSet].map(tvSeries => tvSeries.title))
.forEach((tvSerie) => {
// get the current set for this tvSerie
const currentTvSerie: Set<mediaScan.TPN_Extended> = newTvSeries.get(tvSerie);

// find all the episodes in the new one for this serie
const episodes = [...tvSeriesSet]
.filter(episode => episode.title === tvSerie);

// add them and updates newTvSeries
// add the found tv-series
if (scanningResult[MediaScan.TV_SERIES_TYPE] !== undefined) {
// mapping for faster result(s)
let newSeries = reduce(scanningResult[MediaScan.TV_SERIES_TYPE], (result, tvSeries) => {
result[tvSeries.title] = concat((has(result, tvSeries.title)) ? result[tvSeries.title] : [], tvSeries);
return result;
}, {});
// fastest way to update things
let newTvSeries = this.allTvSeries;
forIn(newSeries, (seriesArray, seriesName) => {
let resultSet = (newTvSeries.has(seriesName)) ? newTvSeries.get(seriesName) : new Set();
newTvSeries.set(
tvSerie,
new Set([...currentTvSerie, ...episodes]),
);
seriesName,
new Set([...resultSet, ...seriesArray]),
)
});
// update the stores var
this.stores.set(MediaScan.TV_SERIES_TYPE, newTvSeries);
}

// updates the stores var
// workaround : const string enum aren't compiled correctly with Babel
this.stores.set(MediaScan.MOVIES_TYPE, newMovies);
this.stores.set(MediaScan.TV_SERIES_TYPE, newTvSeries);
resolve();
} catch (err) {
reject(err);
Expand Down Expand Up @@ -198,45 +179,63 @@ module.exports = class MediaScan extends EventEmitter {
removeOldFiles(...files: string[]): Promise<any> {
return new PromiseLib((resolve, reject) => {
try {
// get the data to handle this case
// in the first group, we got all the tv series files and in the second, the movies
// workaround : const string enum aren't compiled correctly with Babel
const processData = partition(files, file =>
this.categoryForFile.get(file) === MediaScan.TV_SERIES_TYPE);
// for movies, just an easy removal
// workaround : const string enum aren't compiled correctly with Babel
this.stores.set(
MediaScan.MOVIES_TYPE,
new Set([...this.allMovies]
.filter(movie => !(processData[1].includes(movie.filePath)))),
// get the data to handle the two cases
const processData = partition(
filter(
map(
files,
(file) => {
return {filePath: file, category: this.categoryForFile.get(file)};
}
), (resultObject) => resultObject.category !== undefined
), file => file.category === MediaScan.TV_SERIES_TYPE
);

// for the tv-series, a bit more complicated
// first step : find the unique tv series of these files
const tvSeriesShows = uniq(processData[0]
.map(file => this.parser(basename(file)).title));
// second step : foreach each series in tvSeriesShows
const newTvSeriesMap = this.allTvSeries;

for (const series of tvSeriesShows) {
// get the set for this serie
const filteredSet = new Set([...newTvSeriesMap.get(series)]
.filter(episode =>
!(processData[0].includes(episode.filePath))));
// if the filtered set is empty => no more episodes for this series
if (filteredSet.size === 0) {
newTvSeriesMap.delete(series);
} else newTvSeriesMap.set(series, filteredSet);
// for movies, just an easy removal
if (processData[1].length > 0){
this.stores.set(
MediaScan.MOVIES_TYPE,
new Set(
filter(...this.allMovies, (movie) => !some(map(processData[1], 'filePath'), movie.filePath))
)
);
}

// save the updated map
// workaround : const string enum aren't compiled correctly with Babel
this.stores.set(MediaScan.TV_SERIES_TYPE, newTvSeriesMap);
// for series , a bit more complex
if (processData[0].length > 0){

// Get the series and their files that will be deleted
const seriesShows = reduce(processData[0], (result, file) => {
const seriesName = this.parser(basename(file.filePath)).title;
result[seriesName] = concat((has(result, seriesName)) ? result[seriesName] : [], file.filePath);
return result;
}, {});

let newTvSeries = this.allTvSeries;
// check if needed to store new Value
let shouldUpdate = false;
forIn(seriesShows, (seriesArray, seriesName) => {
let previousSet = (newTvSeries.has(seriesName)) ? newTvSeries.get(seriesName) : new Set();
let filteredSet: Set<mediaScan.TPN_Extended> = new Set(
filter([...previousSet], (episode) => !includes(seriesArray, episode.filePath))
);
// should I update later ?
if (previousSet.size !== filteredSet.size)
shouldUpdate = true;
// if the filtered set is empty => no more episodes for this series
if (filteredSet.size === 0) {
newTvSeries.delete(seriesName);
} else newTvSeries.set(seriesName, filteredSet);
});
// save the updated map
if (shouldUpdate)
this.stores.set(MediaScan.TV_SERIES_TYPE, newTvSeries);
}

// remove the mapping
files.forEach((file) => {
// remove the mapping of each deleted file(s)
for (const file of files) {
this.categoryForFile.delete(file);
});
}
this.emit('removeOldFiles', {files});
resolve({
message: 'The files have been deleted from the library',
Expand Down
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载