Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Le glorious refactoring of FavoritesService in DuckieTV
/**
* Refactored: 52 lines
*/
addFavorite: function(data, watched) {
watched = watched || [];
console.log("FavoritesService.addFavorite!", data, watched);
return service.getById(data.tvdb_id).then(function(serie) {
if (!serie) {
serie = new Serie();
} else if (serie.name.toLowerCase() != data.title.toLowerCase()) { // remove update checks for series that have their name changed (will be re-added with new name)
EventSchedulerService.clear(serie.name + ' update check');
}
fillSerie(serie, data);
return serie.Persist().then(function(e) {
// schedule updates for ended series only every 2 weeks. Saves useless updates otherwise update every 2 days.
EventSchedulerService.createInterval(serie.name + ' update check', serie.status.toLowerCase() == 'ended' ? 60 * 24 * 14 : 60 * 24 * 2, 'favoritesservice:checkforupdates', {
ID: serie.getID(),
TVDB_ID: serie.TVDB_ID
});
addToFavoritesList(serie); // cache serie in favoritesservice.favorites
$rootScope.$broadcast('background:load', serie.fanart);
return service.updateEpisodes(serie, data.seasons, watched).then(function(result) { // add serie completely done, broadcast sync and update event.
console.log("Adding serie completely done, broadcasting storage sync event.");
$rootScope.$broadcast('episodes:updated', service.favorites);
$rootScope.$broadcast('storage:update');
return result;
});
});
});
},
updateEpisodes: function(serie, seasons, watched) {
watched = watched || [];
return serie.getSeasonsByNumber().then(function(seasonCache) { // fetch the seasons and cache them by number.
return serie.getEpisodesMap().then(function(cache) { // then fetch the episodes already existing mapped by tvdb_id as cache object
cleanOldSeries(seasons, serie.getID()); // clean up episodes from the database that were saved but are no longer in the latest update
return $q.all(seasons.map(function(season) {
var SE = (season.season in seasonCache) ? seasonCache[season.season] : new Season();
for (var s in season) { // update the season's properties
SE[s] = season[s];
}
SE.seasonnumber = season.season;
SE.ID_Serie = serie.getID();
return SE.Persist().then(function(r) {
return $q.all(SE.episodes.map(function(episode, idx) { // update the season's episodes
var e = (!(episode.tvdb_id in cache)) ? new Episode() : cache[episode.tvdb_id];
fillEpisode(e, episode, season, watched);
e.ID_Serie = serie.getID();
e.ID_Season = SE.getID();
return e.Persist();
}));
});
}));
});
});
},
/**
* Original: 147 lines
*/
addFavorite: function(data, watched) {
watched = watched || [];
console.log("FavoritesService.addFavorite!", data, watched);
var d = $q.defer();
service.getById(data.tvdb_id).then(function(serie) {
if (!serie) {
serie = new Serie();
}
if (serie.getID() !== false && serie.name.toLowerCase() != data.title.toLowerCase()) {
console.log("Serie name has changed versus database name, removing it's updatecheck.");
EventSchedulerService.clear(serie.name + ' update check');
}
fillSerie(serie, data);
serie.Persist().then(function(e) {
var updateInterval = serie.status.toLowerCase() == 'ended' ? 60 * 24 * 14 : 60 * 24 * 2; // schedule updates for ended series only every 2 weeks. Saves useless updates.
EventSchedulerService.createInterval(serie.name + ' update check', updateInterval, 'favoritesservice:checkforupdates', {
ID: serie.getID(),
TVDB_ID: serie.TVDB_ID
});
if (service.favorites.filter(function(el) {
return el.TVDB_ID == serie.TVDB_ID;
}).length == 0) {
service.favorites.push(serie);
} else {
service.favorites.map(function(el, index) {
if (el.TVDB_ID == serie.TVDB_ID) {
service.favorites[index] = serie;
}
});
}
$rootScope.$broadcast('background:load', serie.fanart);
service.updateEpisodes(serie, data.seasons, watched).then(function(result) {
$rootScope.$broadcast('episodes:updated', service.favorites);
console.log("Adding serie completely done, broadcasting storage sync event.");
$rootScope.$broadcast('storage:update');
d.resolve(serie);
}, function(err) {
console.log("Error updating episodes!");
d.reject(err);
}, function(notify) {
console.log('Service update episodes progress notification event for ', serie, notify);
});
});
});
return d.promise;
},
updateEpisodes: function(serie, seasons, watched) {
watched = watched || [];
var seasonCache = {};
var p = $q.defer();
var totalEpisodes = 0;
var updatedEpisodes = 0;
seasons.map(function(s) { // keep track of the total number of episodes for all seasons, so that we know when all promises have finished.
totalEpisodes += s.episodes.length;
});
serie.getSeasons().then(function(sea) { // fetch the seasons and cache them by number.
sea.map(function(el) {
seasonCache[el.seasonnumber] = el;
});
}).then(function() {
serie.getEpisodes().then(function(data) { // then fetch the episodes and put them in a big cache object
var cache = {};
data.map(function(episode) {
cache[episode.TVDB_ID] = episode;
});
data = null;
var pq = [];
cleanOldSeries(seasons, serie.getID());
seasons.map(function(season) {
var SE = (season.season in seasonCache) ? seasonCache[season.season] : new Season();
for (var s in season) { // update the season's properties
if (s == 'episodes') continue;
SE.set(s, season[s]);
}
SE.set('seasonnumber', season.season);
SE.set('ID_Serie', serie.getID());
SE.episodes = season.episodes;
SE.Persist().then(function(r) {
SE.episodes.map(function(episode, idx) { // update the season's episodes
var e = (!(episode.tvdb_id in cache)) ? new Episode() : cache[episode.tvdb_id];
fillEpisode(e, episode);
e.seasonnumber = season.season;
e.ID_Serie = serie.getID();
e.ID_Season = SE.getID();
// if there's an entry for the episode in watchedEpisodes, this is a backup restore
var watchedEpisodes = watched.filter(function(el) {
return el.TVDB_ID == e.TVDB_ID;
});
if (watchedEpisodes.length > 0) {
e.set('watched', '1');
e.set('watchedAt', watchedEpisodes[0].watchedAt);
}
// save the changes and free some memory, or do it immediately if there's no promise to wait for
if (Object.keys(e.changedValues).length > 0) { // if the dbObject is dirty, we wait for the persist to resolve
e.Persist().then(function(res) {
updatedEpisodes++;
if (updatedEpisodes == totalEpisodes) { // when all episodes are done, resolve the promise.
if (service.favoriteIDs.indexOf(serie.TVDB_ID) == -1) {
service.favoriteIDs.push(serie.TVDB_ID);
}
p.resolve();
}
cache[episode.tvdb_id] = null;
e = null;
episode = null;
}, function(err) {
console.error("PERSIST ERROR!", err);
});
} else { // nothing has changed here, update the counter and continue or resolve.
updatedEpisodes++;
e = null;
cache[episode.tvdb_id] = null;
episode = null;
if (updatedEpisodes == totalEpisodes) { // when all episodes are done, resolve the promise.
if (service.favoriteIDs.indexOf(serie.TVDB_ID) == -1) {
service.favoriteIDs.push(serie.TVDB_ID);
}
p.resolve();
}
}
});
SE.episodes = null;
SE = null;
seasonCache[season.season] = null;
season = null;
});
});
});
});
return p.promise;
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.