public override void ProcessCommand() { logger.Info("Processing CommandRequest_UpdateMyListFileStatus: {0}", Hash); try { VideoLocalRepository repVids = new VideoLocalRepository(); AnimeEpisodeRepository repEpisodes = new AnimeEpisodeRepository(); // NOTE - we might return more than one VideoLocal record here, if there are duplicates by hash VideoLocal vid = repVids.GetByHash(this.Hash); if (vid != null) { bool isManualLink = false; List<CrossRef_File_Episode> xrefs = vid.EpisodeCrossRefs; if (xrefs.Count > 0) isManualLink = xrefs[0].CrossRefSource != (int)CrossRefSource.AniDB; if (isManualLink) { JMMService.AnidbProcessor.UpdateMyListFileStatus(xrefs[0].AnimeID, xrefs[0].Episode.EpisodeNumber, this.Watched); logger.Info("Updating file list status (GENERIC): {0} - {1}", vid.ToString(), this.Watched); } else { if (WatchedDateAsSecs > 0) { DateTime? watchedDate = Utils.GetAniDBDateAsDate(WatchedDateAsSecs); JMMService.AnidbProcessor.UpdateMyListFileStatus(vid, this.Watched, watchedDate); } else JMMService.AnidbProcessor.UpdateMyListFileStatus(vid, this.Watched, null); logger.Info("Updating file list status: {0} - {1}", vid.ToString(), this.Watched); } if (UpdateSeriesStats) { // update watched stats List<AnimeEpisode> eps = repEpisodes.GetByHash(vid.ED2KHash); if (eps.Count > 0) { // all the eps should belong to the same anime eps[0].GetAnimeSeries().UpdateStats(true, false, true); //eps[0].AnimeSeries.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, false); } } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_UpdateMyListFileStatus: {0} - {1}", Hash, ex.ToString()); return; } }
public VideoLocal_User GetVideoLocalUserRecord(int userID) { VideoLocalRepository repVids = new VideoLocalRepository(); VideoLocal vid = repVids.GetByHash(Hash); if (vid != null) { VideoLocal_User vidUser = vid.GetUserRecord(userID); if (vidUser != null) return vidUser; } return null; }
public List<Contract_VideoLocal> SearchForFiles(int searchType, string searchCriteria, int userID) { try { List<Contract_VideoLocal> vids = new List<Contract_VideoLocal>(); FileSearchCriteria sType = (FileSearchCriteria)searchType; VideoLocalRepository repVids = new VideoLocalRepository(); switch (sType) { case FileSearchCriteria.Name: List<VideoLocal> results1 = repVids.GetByName(searchCriteria.Trim()); foreach (VideoLocal vid in results1) vids.Add(vid.ToContract(userID)); break; case FileSearchCriteria.ED2KHash: VideoLocal vidByHash = repVids.GetByHash(searchCriteria.Trim()); if (vidByHash != null) vids.Add(vidByHash.ToContract(userID)); break; case FileSearchCriteria.Size: break; case FileSearchCriteria.LastOneHundred: List<VideoLocal> results2 = repVids.GetMostRecentlyAdded(100); foreach (VideoLocal vid in results2) vids.Add(vid.ToContract(userID)); break; } return vids; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return new List<Contract_VideoLocal>(); }
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; }
private VideoLocal ProcessFile_LocalInfo() { // hash and read media info for file int nshareID = -1; string filePath = ""; ImportFolderRepository repNS = new ImportFolderRepository(); List<ImportFolder> shares = repNS.GetAll(); DataAccessHelper.GetShareAndPath(FileName, shares, ref nshareID, ref filePath); if (!File.Exists(FileName)) { logger.Error("File does not exist: {0}", FileName); return null; } int numAttempts = 0; // Wait 3 minutes seconds before giving up on trying to access the file while ((!CanAccessFile(FileName)) && (numAttempts < 180)) { numAttempts++; Thread.Sleep(1000); Console.WriteLine("Attempt # " + numAttempts.ToString()); } // if we failed to access the file, get ouuta here if (numAttempts == 180) { logger.Error("Could not access file: " + FileName); return null; } // check if we have already processed this file VideoLocal vlocal = null; VideoLocalRepository repVidLocal = new VideoLocalRepository(); FileNameHashRepository repFNHash = new FileNameHashRepository(); List<VideoLocal> vidLocals = repVidLocal.GetByFilePathAndShareID(filePath, nshareID); FileInfo fi = new FileInfo(FileName); if (vidLocals.Count > 0) { vlocal = vidLocals[0]; logger.Trace("VideoLocal record found in database: {0}", vlocal.VideoLocalID); if (ForceHash) { vlocal.FileSize = fi.Length; vlocal.DateTimeUpdated = DateTime.Now; } } else { logger.Trace("VideoLocal, creating new record"); vlocal = new VideoLocal(); vlocal.DateTimeUpdated = DateTime.Now; vlocal.DateTimeCreated = vlocal.DateTimeUpdated; vlocal.FilePath = filePath; vlocal.FileSize = fi.Length; vlocal.ImportFolderID = nshareID; vlocal.Hash = ""; vlocal.CRC32 = ""; vlocal.MD5 = ""; vlocal.SHA1 = ""; vlocal.IsIgnored = 0; vlocal.IsVariation = 0; } // check if we need to get a hash this file Hashes hashes = null; if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash) { // try getting the hash from the CrossRef if (!ForceHash) { CrossRef_File_EpisodeRepository repCrossRefs = new CrossRef_File_EpisodeRepository(); List<CrossRef_File_Episode> crossRefs = repCrossRefs.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize); if (crossRefs.Count == 1) { vlocal.Hash = crossRefs[0].Hash; vlocal.HashSource = (int)HashSource.DirectHash; } } // try getting the hash from the LOCAL cache if (!ForceHash && string.IsNullOrEmpty(vlocal.Hash)) { List<FileNameHash> fnhashes = repFNHash.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize); if (fnhashes != null && fnhashes.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes) { repFNHash.Delete(fnh.FileNameHashID); } } if (fnhashes != null && fnhashes.Count == 1) { logger.Trace("Got hash from LOCAL cache: {0} ({1})", FileName, fnhashes[0].Hash); vlocal.Hash = fnhashes[0].Hash; vlocal.HashSource = (int)HashSource.WebCacheFileName; } } // hash the file if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash) { DateTime start = DateTime.Now; logger.Trace("Calculating hashes for: {0}", FileName); // update the VideoLocal record with the Hash hashes = FileHashHelper.GetHashInfo(FileName, true, MainWindow.OnHashProgress, ServerSettings.Hash_CRC32, ServerSettings.Hash_MD5, ServerSettings.Hash_SHA1); TimeSpan ts = DateTime.Now - start; logger.Trace("Hashed file in {0} seconds --- {1} ({2})", ts.TotalSeconds.ToString("#0.0"), FileName, Utils.FormatByteSize(vlocal.FileSize)); vlocal.Hash = hashes.ed2k; vlocal.CRC32 = hashes.crc32; vlocal.MD5 = hashes.md5; vlocal.SHA1 = hashes.sha1; vlocal.HashSource = (int)HashSource.DirectHash; } // We should have a hash by now // before we save it, lets make sure there is not any other record with this hash (possible duplicate file) VideoLocal vidTemp = repVidLocal.GetByHash(vlocal.Hash); if (vidTemp != null) { // don't delete it, if it is actually the same record if (vidTemp.VideoLocalID != vlocal.VideoLocalID) { // delete the VideoLocal record logger.Warn("Deleting duplicate video file record"); logger.Warn("---------------------------------------------"); logger.Warn("Keeping record for: {0}", vlocal.FullServerPath); logger.Warn("Deleting record for: {0}", vidTemp.FullServerPath); logger.Warn("---------------------------------------------"); // check if we have a record of this in the database, if not create one DuplicateFileRepository repDups = new DuplicateFileRepository(); List<DuplicateFile> dupFiles = repDups.GetByFilePathsAndImportFolder(vlocal.FilePath, vidTemp.FilePath, vlocal.ImportFolderID, vidTemp.ImportFolderID); if (dupFiles.Count == 0) dupFiles = repDups.GetByFilePathsAndImportFolder(vidTemp.FilePath, vlocal.FilePath, vidTemp.ImportFolderID, vlocal.ImportFolderID); if (dupFiles.Count == 0) { DuplicateFile dup = new DuplicateFile(); dup.DateTimeUpdated = DateTime.Now; dup.FilePathFile1 = vlocal.FilePath; dup.FilePathFile2 = vidTemp.FilePath; dup.ImportFolderIDFile1 = vlocal.ImportFolderID; dup.ImportFolderIDFile2 = vidTemp.ImportFolderID; dup.Hash = vlocal.Hash; repDups.Save(dup); } repVidLocal.Delete(vidTemp.VideoLocalID); } } repVidLocal.Save(vlocal); // also save the filename to hash record // replace the existing records just in case it was corrupt FileNameHash fnhash = null; List<FileNameHash> fnhashes2 = repFNHash.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize); if (fnhashes2 != null && fnhashes2.Count > 1) { // if we have more than one record it probably means there is some sort of corruption // lets delete the local records foreach (FileNameHash fnh in fnhashes2) { repFNHash.Delete(fnh.FileNameHashID); } } if (fnhashes2 != null && fnhashes2.Count == 1) fnhash = fnhashes2[0]; else fnhash = new FileNameHash(); fnhash.FileName = Path.GetFileName(vlocal.FilePath); fnhash.FileSize = vlocal.FileSize; fnhash.Hash = vlocal.Hash; fnhash.DateTimeUpdated = DateTime.Now; repFNHash.Save(fnhash); } // now check if we have stored a VideoInfo record bool refreshMediaInfo = false; VideoInfoRepository repVidInfo = new VideoInfoRepository(); VideoInfo vinfo = repVidInfo.GetByHash(vlocal.Hash); if (vinfo == null) { refreshMediaInfo = true; vinfo = new VideoInfo(); vinfo.Hash = vlocal.Hash; vinfo.Duration = 0; vinfo.FileSize = fi.Length; vinfo.DateTimeUpdated = DateTime.Now; vinfo.FileName = filePath; vinfo.AudioBitrate = ""; vinfo.AudioCodec = ""; vinfo.VideoBitrate = ""; vinfo.VideoBitDepth = ""; vinfo.VideoCodec = ""; vinfo.VideoFrameRate = ""; vinfo.VideoResolution = ""; repVidInfo.Save(vinfo); } else { // check if we need to update the media info if (vinfo.VideoCodec.Trim().Length == 0) refreshMediaInfo = true; else refreshMediaInfo = false; } if (refreshMediaInfo) { logger.Trace("Getting media info for: {0}", FileName); MediaInfoResult mInfo = FileHashHelper.GetMediaInfo(FileName, true); vinfo.AudioBitrate = string.IsNullOrEmpty(mInfo.AudioBitrate) ? "" : mInfo.AudioBitrate; vinfo.AudioCodec = string.IsNullOrEmpty(mInfo.AudioCodec) ? "" : mInfo.AudioCodec; vinfo.DateTimeUpdated = vlocal.DateTimeUpdated; vinfo.Duration = mInfo.Duration; vinfo.FileName = filePath; vinfo.FileSize = fi.Length; vinfo.VideoBitrate = string.IsNullOrEmpty(mInfo.VideoBitrate) ? "" : mInfo.VideoBitrate; vinfo.VideoBitDepth = string.IsNullOrEmpty(mInfo.VideoBitDepth) ? "" : mInfo.VideoBitDepth; vinfo.VideoCodec = string.IsNullOrEmpty(mInfo.VideoCodec) ? "" : mInfo.VideoCodec; vinfo.VideoFrameRate = string.IsNullOrEmpty(mInfo.VideoFrameRate) ? "" : mInfo.VideoFrameRate; vinfo.VideoResolution = string.IsNullOrEmpty(mInfo.VideoResolution) ? "" : mInfo.VideoResolution; vinfo.FullInfo = string.IsNullOrEmpty(mInfo.FullInfo) ? "" : mInfo.FullInfo; repVidInfo.Save(vinfo); } // now add a command to process the file CommandRequest_ProcessFile cr_procfile = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false); cr_procfile.Save(); return vlocal; }
public List<Contract_VideoDetailed> GetVideoDetailedContracts(int userID) { VideoLocalRepository repVids = new VideoLocalRepository(); List<Contract_VideoDetailed> contracts = new List<Contract_VideoDetailed>(); // get all the cross refs foreach (CrossRef_File_Episode xref in FileCrossRefs) { Contract_VideoDetailed contract = new Contract_VideoDetailed(); contract.Percentage = xref.Percentage; contract.EpisodeOrder = xref.EpisodeOrder; contract.CrossRefSource = xref.CrossRefSource; contract.AnimeEpisodeID = this.AnimeEpisodeID; // get the video file // we will assume that it is unique by hash/episodeid VideoLocal vid = repVids.GetByHash(xref.Hash); if (vid != null) { contract.VideoLocal_FilePath = vid.FilePath; contract.VideoLocal_Hash = vid.Hash; contract.VideoLocal_FileSize = vid.FileSize; contract.VideoLocalID = vid.VideoLocalID; contract.VideoLocal_MD5 = vid.MD5; contract.VideoLocal_SHA1 = vid.SHA1; contract.VideoLocal_CRC32 = vid.CRC32; contract.VideoLocal_HashSource = vid.HashSource; VideoLocal_User vidUser = vid.GetUserRecord(userID); //AnimeEpisode_User userRecord = this.GetUserRecord(userID); if (vidUser == null) { contract.VideoLocal_IsWatched = 0; contract.VideoLocal_WatchedDate = null; } else { contract.VideoLocal_IsWatched = 1; contract.VideoLocal_WatchedDate = vidUser.WatchedDate; } contract.VideoLocal_IsIgnored = vid.IsIgnored; contract.VideoLocal_IsVariation = vid.IsVariation; // Import Folder ImportFolder ns = vid.ImportFolder; // to prevent multiple db calls contract.ImportFolderID = ns.ImportFolderID; contract.ImportFolderLocation = ns.ImportFolderLocation; contract.ImportFolderName = ns.ImportFolderName; // video info VideoInfo vi = vid.VideoInfo; // to prevent multiple db calls contract.VideoInfo_AudioBitrate = vi.AudioBitrate; contract.VideoInfo_AudioCodec = vi.AudioCodec; contract.VideoInfo_Duration = vi.Duration; contract.VideoInfo_VideoBitrate = vi.VideoBitrate; contract.VideoInfo_VideoBitDepth = vi.VideoBitDepth; contract.VideoInfo_VideoCodec = vi.VideoCodec; contract.VideoInfo_VideoFrameRate = vi.VideoFrameRate; contract.VideoInfo_VideoResolution = vi.VideoResolution; contract.VideoInfo_VideoInfoID = vi.VideoInfoID; // AniDB File AniDB_File anifile = vid.GetAniDBFile(); // to prevent multiple db calls if (anifile != null) { contract.AniDB_Anime_GroupName = anifile.Anime_GroupName; contract.AniDB_Anime_GroupNameShort = anifile.Anime_GroupNameShort; contract.AniDB_AnimeID = anifile.AnimeID; contract.AniDB_CRC = anifile.CRC; contract.AniDB_Episode_Rating = anifile.Episode_Rating; contract.AniDB_Episode_Votes = anifile.Episode_Votes; contract.AniDB_File_AudioCodec = anifile.File_AudioCodec; contract.AniDB_File_Description = anifile.File_Description; contract.AniDB_File_FileExtension = anifile.File_FileExtension; contract.AniDB_File_LengthSeconds = anifile.File_LengthSeconds; contract.AniDB_File_ReleaseDate = anifile.File_ReleaseDate; contract.AniDB_File_Source = anifile.File_Source; contract.AniDB_File_VideoCodec = anifile.File_VideoCodec; contract.AniDB_File_VideoResolution = anifile.File_VideoResolution; contract.AniDB_FileID = anifile.FileID; contract.AniDB_GroupID = anifile.GroupID; contract.AniDB_MD5 = anifile.MD5; contract.AniDB_SHA1 = anifile.SHA1; contract.AniDB_File_FileVersion = anifile.FileVersion; contract.AniDB_File_IsCensored = anifile.IsCensored; contract.AniDB_File_IsDeprecated = anifile.IsDeprecated; contract.AniDB_File_InternalVersion = anifile.InternalVersion; // languages contract.LanguagesAudio = anifile.LanguagesRAW; contract.LanguagesSubtitle = anifile.SubtitlesRAW; } else { contract.AniDB_Anime_GroupName = ""; contract.AniDB_Anime_GroupNameShort = ""; contract.AniDB_CRC = ""; contract.AniDB_File_AudioCodec = ""; contract.AniDB_File_Description = ""; contract.AniDB_File_FileExtension = ""; contract.AniDB_File_Source = ""; contract.AniDB_File_VideoCodec = ""; contract.AniDB_File_VideoResolution = ""; contract.AniDB_MD5 = ""; contract.AniDB_SHA1 = ""; contract.AniDB_File_FileVersion = 1; // languages contract.LanguagesAudio = ""; contract.LanguagesSubtitle = ""; } AniDB_ReleaseGroup relGroup = vid.ReleaseGroup; // to prevent multiple db calls if (relGroup != null) contract.ReleaseGroup = relGroup.ToContract(); else contract.ReleaseGroup = null; contracts.Add(contract); } } 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; } }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_AddFileToMyList: {0}", Hash); try { VideoLocalRepository repVids = new VideoLocalRepository(); AnimeEpisodeRepository repEpisodes = new AnimeEpisodeRepository(); vid = repVids.GetByHash(this.Hash); List<AnimeEpisode> animeEpisodes = new List<AnimeEpisode>(); if (vid != null) animeEpisodes = vid.GetAnimeEpisodes(); if (vid != null) { // when adding a file via the API, newWatchedStatus will return with current watched status on AniDB // if the file is already on the user's list bool isManualLink = false; List<CrossRef_File_Episode> xrefs = vid.EpisodeCrossRefs; if (xrefs.Count > 0) isManualLink = xrefs[0].CrossRefSource != (int)CrossRefSource.AniDB; // mark the video file as watched DateTime? watchedDate = null; bool newWatchedStatus = false; if (isManualLink) newWatchedStatus = JMMService.AnidbProcessor.AddFileToMyList(xrefs[0].AnimeID, xrefs[0].Episode.EpisodeNumber, ref watchedDate); else newWatchedStatus = JMMService.AnidbProcessor.AddFileToMyList(vid, ref watchedDate); // do for all AniDB users JMMUserRepository repUsers = new JMMUserRepository(); List<JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); if (aniDBUsers.Count > 0) { JMMUser juser = aniDBUsers[0]; vid.ToggleWatchedStatus(newWatchedStatus, false, watchedDate, false, false, juser.JMMUserID, false, true); logger.Info("Adding file to list: {0} - {1}", vid.ToString(), watchedDate); // if the the episode is watched we may want to set the file to watched as well if (ServerSettings.Import_UseExistingFileWatchedStatus && !newWatchedStatus) { if (animeEpisodes.Count > 0) { AnimeEpisode ep = animeEpisodes[0]; AnimeEpisode_User epUser = null; foreach (JMMUser tempuser in aniDBUsers) { // only find the first user who watched this if (epUser == null) epUser = ep.GetUserRecord(tempuser.JMMUserID); } if (epUser != null) { logger.Info("Setting file as watched, because episode was already watched: {0} - user: {1}", vid.ToString(), juser.Username); vid.ToggleWatchedStatus(true, true, epUser.WatchedDate, false, false, epUser.JMMUserID, false, true); } } } } AnimeSeries ser = animeEpisodes[0].GetAnimeSeries(); // all the eps should belong to the same anime ser.QueueUpdateStats(); //StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); // lets also try adding to the users trakt collecion if (ser != null && ServerSettings.Trakt_IsEnabled && !string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken)) { foreach (AnimeEpisode aep in animeEpisodes) { CommandRequest_TraktCollectionEpisode cmdSyncTrakt = new CommandRequest_TraktCollectionEpisode(aep.AnimeEpisodeID, TraktSyncAction.Add); cmdSyncTrakt.Save(); } } // sync the series on MAL if (ser != null && !string.IsNullOrEmpty(ServerSettings.MAL_Username) && !string.IsNullOrEmpty(ServerSettings.MAL_Password)) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_AddFileToMyList: {0} - {1}", Hash, ex.ToString()); return; } }