public List<Contract_MissingFile> GetMyListFilesForRemoval(int userID) { List<Contract_MissingFile> contracts = new List<Contract_MissingFile>(); /*Contract_MissingFile missingFile2 = new Contract_MissingFile(); missingFile2.AnimeID = 1; missingFile2.AnimeTitle = "Gundam Age"; missingFile2.EpisodeID = 2; missingFile2.EpisodeNumber = 7; missingFile2.FileID = 8; missingFile2.AnimeSeries = null; contracts.Add(missingFile2); Thread.Sleep(5000); return contracts;*/ AniDB_FileRepository repAniFile = new AniDB_FileRepository(); CrossRef_File_EpisodeRepository repFileEp = new CrossRef_File_EpisodeRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_EpisodeRepository repEpisodes = new AniDB_EpisodeRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); Dictionary<int, AniDB_Anime> animeCache = new Dictionary<int, AniDB_Anime>(); Dictionary<int, AnimeSeries> animeSeriesCache = new Dictionary<int, AnimeSeries>(); try { AniDBHTTPCommand_GetMyList cmd = new AniDBHTTPCommand_GetMyList(); cmd.Init(ServerSettings.AniDB_Username, ServerSettings.AniDB_Password); enHelperActivityType ev = cmd.Process(); if (ev == enHelperActivityType.GotMyListHTTP) { foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems) { // let's check if the file on AniDB actually exists in the user's local collection string hash = string.Empty; AniDB_File anifile = repAniFile.GetByFileID(myitem.FileID); if (anifile != null) hash = anifile.Hash; else { // look for manually linked files List<CrossRef_File_Episode> xrefs = repFileEp.GetByEpisodeID(myitem.EpisodeID); foreach (CrossRef_File_Episode xref in xrefs) { if (xref.CrossRefSource != (int)CrossRefSource.AniDB) { hash = xref.Hash; break; } } } bool fileMissing = false; if (string.IsNullOrEmpty(hash)) fileMissing = true; else { // now check if the file actually exists on disk VideoLocal vid = repVids.GetByHash(hash); if (vid != null && !File.Exists(vid.FullServerPath)) fileMissing = true; } if (fileMissing) { // this means we can't find the file AniDB_Anime anime = null; if (animeCache.ContainsKey(myitem.AnimeID)) anime = animeCache[myitem.AnimeID]; else { anime = repAnime.GetByAnimeID(myitem.AnimeID); animeCache[myitem.AnimeID] = anime; } AnimeSeries ser = null; if (animeSeriesCache.ContainsKey(myitem.AnimeID)) ser = animeSeriesCache[myitem.AnimeID]; else { ser = repSeries.GetByAnimeID(myitem.AnimeID); animeSeriesCache[myitem.AnimeID] = ser; } Contract_MissingFile missingFile = new Contract_MissingFile(); missingFile.AnimeID = myitem.AnimeID; missingFile.AnimeTitle = "Data Missing"; if (anime != null) missingFile.AnimeTitle = anime.MainTitle; missingFile.EpisodeID = myitem.EpisodeID; AniDB_Episode ep = repEpisodes.GetByEpisodeID(myitem.EpisodeID); missingFile.EpisodeNumber = -1; missingFile.EpisodeType = 1; if (ep != null) { missingFile.EpisodeNumber = ep.EpisodeNumber; missingFile.EpisodeType = ep.EpisodeType; } missingFile.FileID = myitem.FileID; if (ser == null) missingFile.AnimeSeries = null; else missingFile.AnimeSeries = ser.ToContract(ser.GetUserRecord(userID)); contracts.Add(missingFile); } } } if (contracts.Count > 0) { List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("AnimeTitle", false, SortType.eString)); sortCriteria.Add(new SortPropOrFieldAndDirection("EpisodeID", false, SortType.eInteger)); contracts = Sorting.MultiSort<Contract_MissingFile>(contracts, sortCriteria); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return contracts; }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_SyncMyList"); try { // we will always assume that an anime was downloaded via http first ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AniDB_FileRepository repAniFile = new AniDB_FileRepository(); VideoLocalRepository repVidLocals = new VideoLocalRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBMyListSync); if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.AniDBMyListSync; sched.UpdateDetails = ""; } else { int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_MyList_UpdateFrequency); // if we have run this in the last 24 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) { if (!ForceRefresh) return; } } AniDBHTTPCommand_GetMyList cmd = new AniDBHTTPCommand_GetMyList(); cmd.Init(ServerSettings.AniDB_Username, ServerSettings.AniDB_Password); enHelperActivityType ev = cmd.Process(); if (ev == enHelperActivityType.GotMyListHTTP && cmd.MyListItems.Count > 1) { int totalItems = 0; int watchedItems = 0; int modifiedItems = 0; double pct = 0; // 2. find files locally for the user, which are not recorded on anidb // and then add them to anidb Dictionary<int, Raw_AniDB_MyListFile> onlineFiles = new Dictionary<int, Raw_AniDB_MyListFile>(); foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems) onlineFiles[myitem.FileID] = myitem; Dictionary<string, AniDB_File> dictAniFiles = new Dictionary<string, AniDB_File>(); List<AniDB_File> allAniFiles = repAniFile.GetAll(); foreach (AniDB_File anifile in allAniFiles) dictAniFiles[anifile.Hash] = anifile; int missingFiles = 0; foreach (VideoLocal vid in repVidLocals.GetAll()) { if (!dictAniFiles.ContainsKey(vid.Hash)) continue; int fileID = dictAniFiles[vid.Hash].FileID; if (!onlineFiles.ContainsKey(fileID)) { // means we have found a file in our local collection, which is not recorded online CommandRequest_AddFileToMyList cmdAddFile = new CommandRequest_AddFileToMyList(vid.Hash); cmdAddFile.Save(); missingFiles++; } } logger.Info(string.Format("MYLIST Missing Files: {0} Added to queue for inclusion", missingFiles)); JMMUserRepository repUsers = new JMMUserRepository(); List<JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); VideoLocal_UserRepository repVidUsers = new VideoLocal_UserRepository(); CrossRef_File_EpisodeRepository repFileEp = new CrossRef_File_EpisodeRepository(); // 1 . sync mylist items foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems) { // ignore files mark as deleted by the user if (myitem.State == (int)AniDBFileStatus.Deleted) continue; totalItems++; if (myitem.IsWatched) watchedItems++; //calculate percentage pct = (double)totalItems / (double)cmd.MyListItems.Count * (double)100; string spct = pct.ToString("#0.0"); string hash = string.Empty; AniDB_File anifile = repAniFile.GetByFileID(myitem.FileID); if (anifile != null) hash = anifile.Hash; else { // look for manually linked files List<CrossRef_File_Episode> xrefs = repFileEp.GetByEpisodeID(myitem.EpisodeID); foreach (CrossRef_File_Episode xref in xrefs) { if (xref.CrossRefSource != (int)CrossRefSource.AniDB) { hash = xref.Hash; break; } } } if (!string.IsNullOrEmpty(hash)) { // find the video associated with this record VideoLocal vl = repVidLocals.GetByHash(hash); if (vl == null) continue; foreach (JMMUser juser in aniDBUsers) { bool localStatus = false; int? jmmUserID = null; // doesn't matter which anidb user we use jmmUserID = juser.JMMUserID; VideoLocal_User userRecord = vl.GetUserRecord(juser.JMMUserID); if (userRecord != null) localStatus = true; string action = ""; if (localStatus != myitem.IsWatched) { if (localStatus == true) { // local = watched, anidb = unwatched if (ServerSettings.AniDB_MyList_ReadUnwatched) { modifiedItems++; if (jmmUserID.HasValue) vl.ToggleWatchedStatus(myitem.IsWatched, false, myitem.WatchedDate, false, false, jmmUserID.Value, false, true); action = "Used AniDB Status"; } } else { // means local is un-watched, and anidb is watched if (ServerSettings.AniDB_MyList_ReadWatched) { modifiedItems++; if (jmmUserID.HasValue) vl.ToggleWatchedStatus(true, false, myitem.WatchedDate, false, false, jmmUserID.Value, false, true); action = "Updated Local record to Watched"; } } string msg = string.Format("MYLISTDIFF:: File {0} - Local Status = {1}, AniDB Status = {2} --- {3}", vl.FullServerPath, localStatus, myitem.IsWatched, action); logger.Info(msg); } } //string msg = string.Format("MYLIST:: File {0} - Local Status = {1}, AniDB Status = {2} --- {3}", // vl.FullServerPath, localStatus, myitem.IsWatched, action); //logger.Info(msg); } } // now update all stats Importer.UpdateAllStats(); logger.Info("Process MyList: {0} Items, {1} Watched, {2} Modified", totalItems, watchedItems, modifiedItems); sched.LastUpdate = DateTime.Now; repSched.Save(sched); } } catch (Exception ex) { logger.Error("Error processing CommandRequest_SyncMyList: {0} ", ex.ToString()); return; } }