public override void ProcessCommand() { try { AniDB_FileRepository rep = new AniDB_FileRepository(); AniDB_File anifile = rep.GetByID(AniDB_FileID); if (anifile == null) return; // skip if the video data is not populated if (anifile.File_VideoResolution.Equals("0x0", StringComparison.InvariantCultureIgnoreCase)) return; XMLService.Send_AniDB_File(anifile); } catch (Exception ex) { logger.Error("Error processing CommandRequest_WebCacheSendAniDB_File: {0} - {1}", AniDB_FileID, ex.ToString()); return; } }
private void ProcessFile_AniDB(VideoLocal vidLocal) { logger.Trace("Checking for AniDB_File record for: {0} --- {1}", vidLocal.Hash, vidLocal.FilePath); // check if we already have this AniDB_File info in the database AniDB_FileRepository repAniFile = new AniDB_FileRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AniDB_AnimeRepository repAniAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); VideoLocalRepository repVidLocals = new VideoLocalRepository(); AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); CrossRef_File_EpisodeRepository repXrefFE = new CrossRef_File_EpisodeRepository(); AniDB_File aniFile = null; if (!ForceAniDB) { aniFile = repAniFile.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null) logger.Trace("AniDB_File record not found"); } int animeID = 0; if (aniFile == null) { // get info from AniDB logger.Debug("Getting AniDB_File record from AniDB...."); Raw_AniDB_File fileInfo = JMMService.AnidbProcessor.GetFileInfo(vidLocal); if (fileInfo != null) { // check if we already have a record aniFile = repAniFile.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null) aniFile = new AniDB_File(); aniFile.Populate(fileInfo); //overwrite with local file name string localFileName = Path.GetFileName(vidLocal.FilePath); aniFile.FileName = localFileName; repAniFile.Save(aniFile, false); aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(localFileName); if (!string.IsNullOrEmpty(fileInfo.OtherEpisodesRAW)) { string[] epIDs = fileInfo.OtherEpisodesRAW.Split(','); foreach (string epid in epIDs) { int id = 0; if (int.TryParse(epid, out id)) { CommandRequest_GetEpisode cmdEp = new CommandRequest_GetEpisode(id); cmdEp.Save(); } } } animeID = aniFile.AnimeID; } } bool missingEpisodes = false; // if we still haven't got the AniDB_File Info we try the web cache or local records if (aniFile == null) { // check if we have any records from previous imports List<CrossRef_File_Episode> crossRefs = repXrefFE.GetByHash(vidLocal.Hash); if (crossRefs == null || crossRefs.Count == 0) { // lets see if we can find the episode/anime info from the web cache if (ServerSettings.WebCache_XRefFileEpisode_Get) { crossRefs = XMLService.Get_CrossRef_File_Episode(vidLocal); if (crossRefs == null || crossRefs.Count == 0) { logger.Debug("Cannot find AniDB_File record or get cross ref from web cache record so exiting: {0}", vidLocal.ED2KHash); return; } else { foreach (CrossRef_File_Episode xref in crossRefs) { // in this case we need to save the cross refs manually as AniDB did not provide them repXrefFE.Save(xref); } } } else { logger.Debug("Cannot get AniDB_File record so exiting: {0}", vidLocal.ED2KHash); return; } } // we assume that all episodes belong to the same anime foreach (CrossRef_File_Episode xref in crossRefs) { animeID = xref.AnimeID; AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID); if (ep == null) missingEpisodes = true; } } else { // check if we have the episode info // if we don't, we will need to re-download the anime info (which also has episode info) if (aniFile.EpisodeCrossRefs.Count == 0) { animeID = aniFile.AnimeID; // if we have the anidb file, but no cross refs it means something has been broken logger.Debug("Could not find any cross ref records for: {0}", vidLocal.ED2KHash); missingEpisodes = true; } else { foreach (CrossRef_File_Episode xref in aniFile.EpisodeCrossRefs) { AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID); if (ep == null) missingEpisodes = true; animeID = xref.AnimeID; } } } // get from DB AniDB_Anime anime = repAniAnime.GetByAnimeID(animeID); bool animeRecentlyUpdated = false; if (anime != null) { TimeSpan ts = DateTime.Now - anime.DateTimeUpdated; if (ts.TotalHours < 4) animeRecentlyUpdated = true; } // even if we are missing episode info, don't get data more than once every 4 hours // this is to prevent banning if (missingEpisodes && !animeRecentlyUpdated) { logger.Debug("Getting Anime record from AniDB...."); // try using the cache first using (var session = JMMService.SessionFactory.OpenSession()) { anime = JMMService.AnidbProcessor.GetAnimeInfoHTTPFromCache(session, animeID, ServerSettings.AutoGroupSeries); } // if not in cache try from AniDB if (anime == null) anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(animeID, true, ServerSettings.AutoGroupSeries); } // create the group/series/episode records if needed AnimeSeries ser = null; if (anime != null) { logger.Debug("Creating groups, series and episodes...."); // check if there is an AnimeSeries Record associated with this AnimeID ser = repSeries.GetByAnimeID(animeID); if (ser == null) { // create a new AnimeSeries record ser = anime.CreateAnimeSeriesAndGroup(); } ser.CreateAnimeEpisodes(); // check if we have any group status data for this associated anime // if not we will download it now AniDB_GroupStatusRepository repStatus = new AniDB_GroupStatusRepository(); if (repStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(); } // update stats ser.EpisodeAddedDate = DateTime.Now; repSeries.Save(ser); AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; repGroups.Save(grp); } } vidLocal.RenameIfRequired(); vidLocal.MoveFileIfRequired(); // update stats for groups and series if (ser != null) { // update all the groups above this series in the heirarchy ser.UpdateStats(true, true, true); StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); } // Add this file to the users list if (ServerSettings.AniDB_MyList_AddFiles) { CommandRequest_AddFileToMyList cmd = new CommandRequest_AddFileToMyList(vidLocal.ED2KHash); cmd.Save(); } // lets also try adding to the users trakt collecion by sync'ing the series if (ser != null) { CommandRequest_TraktSyncCollectionSeries cmdTrakt = new CommandRequest_TraktSyncCollectionSeries(ser.AnimeSeriesID, ser.GetAnime().MainTitle); cmdTrakt.Save(); } // sync the series on MAL if (ser != null) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } }
void btnUploadAniFileCache_Click(object sender, RoutedEventArgs e) { this.Cursor = Cursors.Wait; AniDB_FileRepository rep = new AniDB_FileRepository(); foreach (AniDB_File aniFile in rep.GetAll()) { CommandRequest_WebCacheSendAniDB_File cmd = new CommandRequest_WebCacheSendAniDB_File(aniFile.AniDB_FileID); cmd.Save(); } this.Cursor = Cursors.Arrow; MessageBox.Show("Commands are queued", "Success", MessageBoxButton.OK, MessageBoxImage.Information); }
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 string UpdateAnimeData(int animeID) { try { using (var session = JMMService.SessionFactory.OpenSession()) { JMMService.AnidbProcessor.GetAnimeInfoHTTP(session, animeID, true, false); // also find any files for this anime which don't have proper media info data // we can usually tell this if the Resolution == '0x0' VideoLocalRepository repVids = new VideoLocalRepository(); AniDB_FileRepository repFiles = new AniDB_FileRepository(); foreach (VideoLocal vid in repVids.GetByAniDBAnimeID(session, animeID)) { AniDB_File aniFile = vid.GetAniDBFile(session); if (aniFile == null) continue; if (aniFile.File_VideoResolution.Equals("0x0", StringComparison.InvariantCultureIgnoreCase)) { CommandRequest_GetFile cmd = new CommandRequest_GetFile(vid.VideoLocalID, true); cmd.Save(session); } } // update group status information CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(animeID, true); cmdStatus.Save(session); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return ""; }
public List<Contract_GroupFileSummary> GetGroupFileSummary(int animeID) { List<Contract_GroupFileSummary> vidQuals = new List<Contract_GroupFileSummary>(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); AniDB_FileRepository repAniFile = new AniDB_FileRepository(); try { AniDB_Anime anime = repAnime.GetByAnimeID(animeID); if (anime == null) return vidQuals; List<VideoLocal> vids = repVids.GetByAniDBAnimeID(animeID); foreach (VideoLocal vid in vids) { if (vid.FilePath.Contains(@"[DB]_Naruto_Shippuuden_078-079_[0DFB6FE0]")) Debug.Write("Test"); List<AnimeEpisode> eps = vid.GetAnimeEpisodes(); if (eps.Count == 0) continue; foreach (AnimeEpisode animeEp in eps) { //AnimeEpisode animeEp = eps[0]; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode || animeEp.EpisodeTypeEnum == enEpisodeType.Special) { AniDB_Episode anidbEp = animeEp.AniDB_Episode; // get the anibd file info AniDB_File aniFile = vid.GetAniDBFile(); if (aniFile != null) { // match based on group / video sorce / video res bool foundSummaryRecord = false; foreach (Contract_GroupFileSummary contract in vidQuals) { if (contract.GroupName.Equals(aniFile.Anime_GroupName, StringComparison.InvariantCultureIgnoreCase)) { foundSummaryRecord = true; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) contract.FileCountNormal++; if (animeEp.EpisodeTypeEnum == enEpisodeType.Special) contract.FileCountSpecials++; contract.TotalFileSize += aniFile.FileSize; contract.TotalRunningTime += aniFile.File_LengthSeconds; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) { if (!contract.NormalEpisodeNumbers.Contains(anidbEp.EpisodeNumber)) contract.NormalEpisodeNumbers.Add(anidbEp.EpisodeNumber); } } } if (!foundSummaryRecord) { Contract_GroupFileSummary contract = new Contract_GroupFileSummary(); contract.FileCountNormal = 0; contract.FileCountSpecials = 0; contract.TotalFileSize = 0; contract.TotalRunningTime = 0; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) contract.FileCountNormal++; if (animeEp.EpisodeTypeEnum == enEpisodeType.Special) contract.FileCountSpecials++; contract.TotalFileSize += aniFile.FileSize; contract.TotalRunningTime += aniFile.File_LengthSeconds; contract.GroupName = aniFile.Anime_GroupName; contract.GroupNameShort = aniFile.Anime_GroupNameShort; contract.NormalEpisodeNumbers = new List<int>(); if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) { if (!contract.NormalEpisodeNumbers.Contains(anidbEp.EpisodeNumber)) contract.NormalEpisodeNumbers.Add(anidbEp.EpisodeNumber); } vidQuals.Add(contract); } } else { // look at the Video Info record VideoInfo vinfo = vid.VideoInfo; if (vinfo != null) { bool foundSummaryRecord = false; foreach (Contract_GroupFileSummary contract in vidQuals) { if (contract.GroupName.Equals("NO GROUP INFO", StringComparison.InvariantCultureIgnoreCase)) { foundSummaryRecord = true; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) contract.FileCountNormal++; if (animeEp.EpisodeTypeEnum == enEpisodeType.Special) contract.FileCountSpecials++; contract.TotalFileSize += vinfo.FileSize; contract.TotalRunningTime += vinfo.Duration; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) { if (!contract.NormalEpisodeNumbers.Contains(anidbEp.EpisodeNumber)) contract.NormalEpisodeNumbers.Add(anidbEp.EpisodeNumber); } } } if (!foundSummaryRecord) { Contract_GroupFileSummary contract = new Contract_GroupFileSummary(); contract.FileCountNormal = 0; contract.FileCountSpecials = 0; contract.TotalFileSize = 0; contract.TotalRunningTime = 0; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) contract.FileCountNormal++; if (animeEp.EpisodeTypeEnum == enEpisodeType.Special) contract.FileCountSpecials++; contract.TotalFileSize += vinfo.FileSize; contract.TotalRunningTime += vinfo.Duration; contract.GroupName = "NO GROUP INFO"; contract.GroupNameShort = "NO GROUP INFO"; contract.NormalEpisodeNumbers = new List<int>(); if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) { if (!contract.NormalEpisodeNumbers.Contains(anidbEp.EpisodeNumber)) contract.NormalEpisodeNumbers.Add(anidbEp.EpisodeNumber); } vidQuals.Add(contract); } } } } } } foreach (Contract_GroupFileSummary contract in vidQuals) { contract.NormalComplete = contract.FileCountNormal >= anime.EpisodeCountNormal; contract.SpecialsComplete = (contract.FileCountSpecials >= anime.EpisodeCountSpecial) && (anime.EpisodeCountSpecial > 0); contract.NormalEpisodeNumberSummary = ""; contract.NormalEpisodeNumbers.Sort(); int lastEpNum = 0; int baseEpNum = 0; foreach (int epNum in contract.NormalEpisodeNumbers) { if (baseEpNum == 0) { baseEpNum = epNum; lastEpNum = epNum; } if (epNum == lastEpNum) continue; int epNumDiff = epNum - lastEpNum; if (epNumDiff == 1) { lastEpNum = epNum; continue; } // this means we have missed an episode if (contract.NormalEpisodeNumberSummary.Length > 0) contract.NormalEpisodeNumberSummary += ", "; if (baseEpNum == lastEpNum) contract.NormalEpisodeNumberSummary += string.Format("{0}", baseEpNum); else contract.NormalEpisodeNumberSummary += string.Format("{0}-{1}", baseEpNum, lastEpNum); lastEpNum = epNum; baseEpNum = epNum; } if (contract.NormalEpisodeNumbers.Count > 0) { if (contract.NormalEpisodeNumbers[contract.NormalEpisodeNumbers.Count - 1] >= baseEpNum) { // this means we have missed an episode if (contract.NormalEpisodeNumberSummary.Length > 0) contract.NormalEpisodeNumberSummary += ", "; if (baseEpNum == contract.NormalEpisodeNumbers[contract.NormalEpisodeNumbers.Count - 1]) contract.NormalEpisodeNumberSummary += string.Format("{0}", baseEpNum); else contract.NormalEpisodeNumberSummary += string.Format("{0}-{1}", baseEpNum, contract.NormalEpisodeNumbers[contract.NormalEpisodeNumbers.Count - 1]); } } } vidQuals.Sort(); return vidQuals; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return vidQuals; } }
public List<Contract_GroupVideoQuality> GetGroupVideoQualitySummary(int animeID) { List<Contract_GroupVideoQuality> vidQuals = new List<Contract_GroupVideoQuality>(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); AniDB_FileRepository repAniFile = new AniDB_FileRepository(); try { DateTime start = DateTime.Now; TimeSpan ts = DateTime.Now - start; double totalTiming = 0; double timingAnime = 0; double timingVids = 0; double timingEps = 0; double timingAniEps = 0; double timingAniFile = 0; double timingVidInfo = 0; double timingContracts = 0; DateTime oStart = DateTime.Now; start = DateTime.Now; AniDB_Anime anime = repAnime.GetByAnimeID(animeID); ts = DateTime.Now - start; timingAnime += ts.TotalMilliseconds; if (anime == null) return vidQuals; start = DateTime.Now; List<VideoLocal> vids = repVids.GetByAniDBAnimeID(animeID); ts = DateTime.Now - start; timingVids += ts.TotalMilliseconds; foreach (VideoLocal vid in vids) { start = DateTime.Now; List<AnimeEpisode> eps = vid.GetAnimeEpisodes(); ts = DateTime.Now - start; timingEps += ts.TotalMilliseconds; if (eps.Count == 0) continue; foreach (AnimeEpisode animeEp in eps) { //AnimeEpisode animeEp = eps[0]; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode || animeEp.EpisodeTypeEnum == enEpisodeType.Special) { start = DateTime.Now; AniDB_Episode anidbEp = animeEp.AniDB_Episode; ts = DateTime.Now - start; timingAniEps += ts.TotalMilliseconds; // get the anibd file info start = DateTime.Now; AniDB_File aniFile = vid.GetAniDBFile(); ts = DateTime.Now - start; timingAniFile += ts.TotalMilliseconds; if (aniFile != null) { start = DateTime.Now; VideoInfo vinfo = vid.VideoInfo; ts = DateTime.Now - start; timingVidInfo += ts.TotalMilliseconds; int bitDepth = 8; if (vinfo != null) { if (!int.TryParse(vinfo.VideoBitDepth, out bitDepth)) bitDepth = 8; } string vidResAniFile = Utils.GetStandardisedVideoResolution(aniFile.File_VideoResolution); // match based on group / video sorce / video res bool foundSummaryRecord = false; foreach (Contract_GroupVideoQuality contract in vidQuals) { string contractSource = SimplifyVideoSource(contract.VideoSource); string fileSource = SimplifyVideoSource(aniFile.File_Source); string vidResContract = Utils.GetStandardisedVideoResolution(contract.Resolution); if (contract.GroupName.Equals(aniFile.Anime_GroupName, StringComparison.InvariantCultureIgnoreCase) && contractSource.Equals(fileSource, StringComparison.InvariantCultureIgnoreCase) && vidResContract.Equals(vidResAniFile, StringComparison.InvariantCultureIgnoreCase) && contract.VideoBitDepth == bitDepth) { foundSummaryRecord = true; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) contract.FileCountNormal++; if (animeEp.EpisodeTypeEnum == enEpisodeType.Special) contract.FileCountSpecials++; contract.TotalFileSize += vid.FileSize; contract.TotalRunningTime += aniFile.File_LengthSeconds; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) { if (!contract.NormalEpisodeNumbers.Contains(anidbEp.EpisodeNumber)) contract.NormalEpisodeNumbers.Add(anidbEp.EpisodeNumber); } } } if (!foundSummaryRecord) { Contract_GroupVideoQuality contract = new Contract_GroupVideoQuality(); contract.FileCountNormal = 0; contract.FileCountSpecials = 0; contract.TotalFileSize = 0; contract.TotalRunningTime = 0; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) contract.FileCountNormal++; if (animeEp.EpisodeTypeEnum == enEpisodeType.Special) contract.FileCountSpecials++; contract.TotalFileSize += vid.FileSize; contract.TotalRunningTime += aniFile.File_LengthSeconds; contract.GroupName = aniFile.Anime_GroupName; contract.GroupNameShort = aniFile.Anime_GroupNameShort; contract.VideoBitDepth = bitDepth; contract.Resolution = vidResAniFile; contract.VideoSource = SimplifyVideoSource(aniFile.File_Source); contract.Ranking = Utils.GetOverallVideoSourceRanking(contract.Resolution, contract.VideoSource, bitDepth); contract.NormalEpisodeNumbers = new List<int>(); if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) { if (!contract.NormalEpisodeNumbers.Contains(anidbEp.EpisodeNumber)) contract.NormalEpisodeNumbers.Add(anidbEp.EpisodeNumber); } vidQuals.Add(contract); } } else { // look at the Video Info record VideoInfo vinfo = vid.VideoInfo; if (vinfo != null) { int bitDepth = 8; if (vinfo != null) { if (!int.TryParse(vinfo.VideoBitDepth, out bitDepth)) bitDepth = 8; } string vidResInfo = Utils.GetStandardisedVideoResolution(vinfo.VideoResolution); bool foundSummaryRecord = false; foreach (Contract_GroupVideoQuality contract in vidQuals) { string vidResContract = Utils.GetStandardisedVideoResolution(contract.Resolution); if (contract.GroupName.Equals(Constants.NO_GROUP_INFO, StringComparison.InvariantCultureIgnoreCase) && contract.VideoSource.Equals(Constants.NO_SOURCE_INFO, StringComparison.InvariantCultureIgnoreCase) && vidResContract.Equals(vidResInfo, StringComparison.InvariantCultureIgnoreCase) && contract.VideoBitDepth == bitDepth) { foundSummaryRecord = true; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) contract.FileCountNormal++; if (animeEp.EpisodeTypeEnum == enEpisodeType.Special) contract.FileCountSpecials++; contract.TotalFileSize += vinfo.FileSize; contract.TotalRunningTime += vinfo.Duration; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) { if (!contract.NormalEpisodeNumbers.Contains(anidbEp.EpisodeNumber)) contract.NormalEpisodeNumbers.Add(anidbEp.EpisodeNumber); } } } if (!foundSummaryRecord) { Contract_GroupVideoQuality contract = new Contract_GroupVideoQuality(); contract.FileCountNormal = 0; contract.FileCountSpecials = 0; contract.TotalFileSize = 0; contract.TotalRunningTime = 0; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) contract.FileCountNormal++; if (animeEp.EpisodeTypeEnum == enEpisodeType.Special) contract.FileCountSpecials++; contract.TotalFileSize += vinfo.FileSize; contract.TotalRunningTime += vinfo.Duration; contract.GroupName = Constants.NO_GROUP_INFO; contract.GroupNameShort = Constants.NO_GROUP_INFO; contract.Resolution = vidResInfo; contract.VideoSource = Constants.NO_SOURCE_INFO; contract.VideoBitDepth = bitDepth; contract.Ranking = Utils.GetOverallVideoSourceRanking(contract.Resolution, contract.VideoSource, bitDepth); contract.NormalEpisodeNumbers = new List<int>(); if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode) { if (!contract.NormalEpisodeNumbers.Contains(anidbEp.EpisodeNumber)) contract.NormalEpisodeNumbers.Add(anidbEp.EpisodeNumber); } vidQuals.Add(contract); } } } } } } start = DateTime.Now; foreach (Contract_GroupVideoQuality contract in vidQuals) { contract.NormalComplete = contract.FileCountNormal >= anime.EpisodeCountNormal; contract.SpecialsComplete = (contract.FileCountSpecials >= anime.EpisodeCountSpecial) && (anime.EpisodeCountSpecial > 0); contract.NormalEpisodeNumberSummary = ""; contract.NormalEpisodeNumbers.Sort(); int lastEpNum = 0; int baseEpNum = 0; foreach (int epNum in contract.NormalEpisodeNumbers) { if (baseEpNum == 0) { baseEpNum = epNum; lastEpNum = epNum; } if (epNum == lastEpNum) continue; int epNumDiff = epNum - lastEpNum; if (epNumDiff == 1) { lastEpNum = epNum; continue; } // this means we have missed an episode if (contract.NormalEpisodeNumberSummary.Length > 0) contract.NormalEpisodeNumberSummary += ", "; if (baseEpNum == lastEpNum) contract.NormalEpisodeNumberSummary += string.Format("{0}", baseEpNum); else contract.NormalEpisodeNumberSummary += string.Format("{0}-{1}", baseEpNum, lastEpNum); lastEpNum = epNum; baseEpNum = epNum; } if (contract.NormalEpisodeNumbers.Count > 0) { if (contract.NormalEpisodeNumbers[contract.NormalEpisodeNumbers.Count - 1] >= baseEpNum) { // this means we have missed an episode if (contract.NormalEpisodeNumberSummary.Length > 0) contract.NormalEpisodeNumberSummary += ", "; if (baseEpNum == contract.NormalEpisodeNumbers[contract.NormalEpisodeNumbers.Count - 1]) contract.NormalEpisodeNumberSummary += string.Format("{0}", baseEpNum); else contract.NormalEpisodeNumberSummary += string.Format("{0}-{1}", baseEpNum, contract.NormalEpisodeNumbers[contract.NormalEpisodeNumbers.Count - 1]); } } } ts = DateTime.Now - start; timingContracts += ts.TotalMilliseconds; ts = DateTime.Now - oStart; totalTiming = ts.TotalMilliseconds; string msg2 = string.Format("Timing for video quality {0} ({1}) : {2}/{3}/{4}/{5}/{6}/{7}/{8} (AID: {9})", anime.MainTitle, totalTiming, timingAnime, timingVids, timingEps, timingAniEps, timingAniFile, timingVidInfo, timingContracts, anime.AnimeID); logger.Debug(msg2); vidQuals.Sort(); return vidQuals; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return vidQuals; } }
public void ToggleWatchedStatus(bool watched, bool updateOnline, DateTime? watchedDate, bool updateStats, bool updateStatsCache, int userID, bool scrobbleTrakt, bool updateWatchedDate) { VideoLocalRepository repVids = new VideoLocalRepository(); AnimeEpisodeRepository repEpisodes = new AnimeEpisodeRepository(); AniDB_FileRepository repAniFile = new AniDB_FileRepository(); CrossRef_File_EpisodeRepository repCross = new CrossRef_File_EpisodeRepository(); VideoLocal_UserRepository repVidUsers = new VideoLocal_UserRepository(); JMMUserRepository repUsers = new JMMUserRepository(); AnimeEpisode_UserRepository repEpisodeUsers = new AnimeEpisode_UserRepository(); JMMUser user = repUsers.GetByID(userID); if (user == null) return; List<JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); // update the video file to watched int mywatched = watched ? 1 : 0; if (user.IsAniDBUser == 0) SaveWatchedStatus(watched, userID, watchedDate, updateWatchedDate); else { // if the user is AniDB user we also want to update any other AniDB // users to keep them in sync foreach (JMMUser juser in aniDBUsers) { if (juser.IsAniDBUser == 1) SaveWatchedStatus(watched, juser.JMMUserID, watchedDate, updateWatchedDate); } } // now lets find all the associated AniDB_File record if there is one if (user.IsAniDBUser == 1) { AniDB_File aniFile = repAniFile.GetByHash(this.Hash); if (aniFile != null) { aniFile.IsWatched = mywatched; if (watched) { if (watchedDate.HasValue) aniFile.WatchedDate = watchedDate; else aniFile.WatchedDate = DateTime.Now; } else aniFile.WatchedDate = null; repAniFile.Save(aniFile, false); } if (updateOnline) { if ((watched && ServerSettings.AniDB_MyList_SetWatched) || (!watched && ServerSettings.AniDB_MyList_SetUnwatched)) { CommandRequest_UpdateMyListFileStatus cmd = new CommandRequest_UpdateMyListFileStatus(this.Hash, watched, false, watchedDate.HasValue ? Utils.GetAniDBDateAsSeconds(watchedDate) : 0); cmd.Save(); } } } // now find all the episode records associated with this video file // but we also need to check if theer are any other files attached to this episode with a watched // status, AnimeSeries ser = null; // get all files associated with this episode List<CrossRef_File_Episode> xrefs = repCross.GetByHash(this.Hash); if (watched) { // find the total watched percentage // eg one file can have a % = 100 // or if 2 files make up one episodes they will each have a % = 50 foreach (CrossRef_File_Episode xref in xrefs) { // get the episode for this file AnimeEpisode ep = repEpisodes.GetByAniDBEpisodeID(xref.EpisodeID); if (ep == null) continue; // get all the files for this episode int epPercentWatched = 0; foreach (CrossRef_File_Episode filexref in ep.FileCrossRefs) { VideoLocal_User vidUser = filexref.GetVideoLocalUserRecord(userID); if (vidUser != null) { // if not null means it is watched epPercentWatched += filexref.Percentage; } if (epPercentWatched > 95) break; } if (epPercentWatched > 95) { ser = ep.GetAnimeSeries(); if (user.IsAniDBUser == 0) ep.SaveWatchedStatus(true, userID, watchedDate, updateWatchedDate); else { // if the user is AniDB user we also want to update any other AniDB // users to keep them in sync foreach (JMMUser juser in aniDBUsers) { if (juser.IsAniDBUser == 1) ep.SaveWatchedStatus(true, juser.JMMUserID, watchedDate, updateWatchedDate); } } if (scrobbleTrakt && !string.IsNullOrEmpty(ServerSettings.Trakt_Username) && !string.IsNullOrEmpty(ServerSettings.Trakt_Password)) { CommandRequest_TraktShowScrobble cmdScrobble = new CommandRequest_TraktShowScrobble(ep.AnimeEpisodeID); cmdScrobble.Save(); } if (!string.IsNullOrEmpty(ServerSettings.MAL_Username) && !string.IsNullOrEmpty(ServerSettings.MAL_Password)) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } } } } else { // if setting a file to unwatched only set the episode unwatched, if ALL the files are unwatched foreach (CrossRef_File_Episode xrefEp in xrefs) { AnimeEpisode ep = repEpisodes.GetByAniDBEpisodeID(xrefEp.EpisodeID); if (ep == null) continue; ser = ep.GetAnimeSeries(); // get all the files for this episode int epPercentWatched = 0; foreach (CrossRef_File_Episode filexref in ep.FileCrossRefs) { VideoLocal_User vidUser = filexref.GetVideoLocalUserRecord(userID); if (vidUser != null) epPercentWatched += filexref.Percentage; if (epPercentWatched > 95) break; } if (epPercentWatched < 95) { if (user.IsAniDBUser == 0) ep.SaveWatchedStatus(false, userID, watchedDate, true); else { // if the user is AniDB user we also want to update any other AniDB // users to keep them in sync foreach (JMMUser juser in aniDBUsers) { if (juser.IsAniDBUser == 1) ep.SaveWatchedStatus(false, juser.JMMUserID, watchedDate, true); } } CommandRequest_TraktShowEpisodeUnseen cmdUnseen = new CommandRequest_TraktShowEpisodeUnseen(ep.AnimeEpisodeID); cmdUnseen.Save(); } } if (!string.IsNullOrEmpty(ServerSettings.MAL_Username) && !string.IsNullOrEmpty(ServerSettings.MAL_Password)) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } } // update stats for groups and series if (ser != null && updateStats) { // update all the groups above this series in the heirarchy ser.UpdateStats(true, true, true); //ser.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true); } if (ser != null && updateStatsCache) StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); }
public List<Contract_VideoDetailed> GetFilesByGroupAndResolution(int animeID, string relGroupName, string resolution, string videoSource, int videoBitDepth, int userID) { List<Contract_VideoDetailed> vids = new List<Contract_VideoDetailed>(); List<Contract_GroupVideoQuality> vidQuals = new List<Contract_GroupVideoQuality>(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); AniDB_FileRepository repAniFile = new AniDB_FileRepository(); try { AniDB_Anime anime = repAnime.GetByAnimeID(animeID); if (anime == null) return vids; foreach (VideoLocal vid in repVids.GetByAniDBAnimeID(animeID)) { int thisBitDepth = 8; VideoInfo vidInfo = vid.VideoInfo; if (vidInfo != null) { int bitDepth = 0; if (int.TryParse(vidInfo.VideoBitDepth, out bitDepth)) thisBitDepth = bitDepth; } List<AnimeEpisode> eps = vid.GetAnimeEpisodes(); if (eps.Count == 0) continue; AnimeEpisode animeEp = eps[0]; if (animeEp.EpisodeTypeEnum == enEpisodeType.Episode || animeEp.EpisodeTypeEnum == enEpisodeType.Special) { // get the anibd file info AniDB_File aniFile = vid.GetAniDBFile(); if (aniFile != null) { videoSource = SimplifyVideoSource(videoSource); string fileSource = SimplifyVideoSource(aniFile.File_Source); string vidResAniFile = Utils.GetStandardisedVideoResolution(aniFile.File_VideoResolution); // match based on group / video sorce / video res if (relGroupName.Equals(aniFile.Anime_GroupName, StringComparison.InvariantCultureIgnoreCase) && videoSource.Equals(fileSource, StringComparison.InvariantCultureIgnoreCase) && resolution.Equals(vidResAniFile, StringComparison.InvariantCultureIgnoreCase) && thisBitDepth == videoBitDepth) { vids.Add(vid.ToContractDetailed(userID)); } } else { string vidResInfo = Utils.GetStandardisedVideoResolution(vidInfo.VideoResolution); // match based on group / video sorce / video res if (relGroupName.Equals(Constants.NO_GROUP_INFO, StringComparison.InvariantCultureIgnoreCase) && videoSource.Equals(Constants.NO_SOURCE_INFO, StringComparison.InvariantCultureIgnoreCase) && resolution.Equals(vidResInfo, StringComparison.InvariantCultureIgnoreCase) && thisBitDepth == videoBitDepth) { vids.Add(vid.ToContractDetailed(userID)); } } } } return vids; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return vids; } }
public void UpdateUsingAniDBFile(string hash) { try { DateTime start = DateTime.Now; AniDB_FileRepository repAniFile = new AniDB_FileRepository(); AniDB_File anifile = repAniFile.GetByHash(hash); if (anifile == null) return; UpdateUsingAnime(anifile.AnimeID); UpdateAnimeContract(anifile.AnimeID); TimeSpan ts = DateTime.Now - start; logger.Info("Updated cached stats file ({0}) in {1} ms", hash, ts.TotalMilliseconds); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }
public AniDB_File GetAniDBFile(ISession session) { AniDB_FileRepository repAniFile = new AniDB_FileRepository(); return repAniFile.GetByHash(session, Hash); }
public override void ProcessCommand() { logger.Info("Get AniDB file info: {0}", VideoLocalID); try { AniDB_FileRepository repAniFile = new AniDB_FileRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); vlocal = repVids.GetByID(VideoLocalID); if (vlocal == null) return; AniDB_File aniFile = repAniFile.GetByHashAndFileSize(vlocal.Hash, vlocal.FileSize); /*// get anidb file info from web cache if (aniFile == null && ServerSettings.WebCache_AniDB_File_Get) { AniDB_FileRequest fr = XMLService.Get_AniDB_File(vlocal.Hash, vlocal.FileSize); if (fr != null) { aniFile = new AniDB_File(); aniFile.Populate(fr); //overwrite with local file name string localFileName = Path.GetFileName(vlocal.FilePath); aniFile.FileName = localFileName; repAniFile.Save(aniFile, false); aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(localFileName); StatsCache.Instance.UpdateUsingAniDBFile(vlocal.Hash); } }*/ Raw_AniDB_File fileInfo = null; if (aniFile == null || ForceAniDB) fileInfo = JMMService.AnidbProcessor.GetFileInfo(vlocal); if (fileInfo != null) { // save to the database if (aniFile == null) aniFile = new AniDB_File(); aniFile.Populate(fileInfo); //overwrite with local file name string localFileName = Path.GetFileName(vlocal.FilePath); aniFile.FileName = localFileName; repAniFile.Save(aniFile, false); aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(localFileName); if (!string.IsNullOrEmpty(fileInfo.OtherEpisodesRAW)) { string[] epIDs = fileInfo.OtherEpisodesRAW.Split(','); foreach (string epid in epIDs) { int id = 0; if (int.TryParse(epid, out id)) { CommandRequest_GetEpisode cmdEp = new CommandRequest_GetEpisode(id); cmdEp.Save(); } } } StatsCache.Instance.UpdateUsingAniDBFile(vlocal.Hash); } } catch (Exception ex) { logger.Error("Error processing CommandRequest_GetFile: {0} - {1}", VideoLocalID, ex.ToString()); return; } }
public static int UpdateAniDBFileData(bool missingInfo, bool outOfDate, bool countOnly) { List<int> vidsToUpdate = new List<int>(); try { AniDB_FileRepository repFiles = new AniDB_FileRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); if (missingInfo) { List<VideoLocal> vids = repVids.GetByAniDBResolution("0x0"); foreach (VideoLocal vid in vids) { if (!vidsToUpdate.Contains(vid.VideoLocalID)) vidsToUpdate.Add(vid.VideoLocalID); } } if (outOfDate) { List<VideoLocal> vids = repVids.GetByInternalVersion(1); foreach (VideoLocal vid in vids) { if (!vidsToUpdate.Contains(vid.VideoLocalID)) vidsToUpdate.Add(vid.VideoLocalID); } } if (!countOnly) { foreach (int id in vidsToUpdate) { CommandRequest_GetFile cmd = new CommandRequest_GetFile(id, true); cmd.Save(); } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return vidsToUpdate.Count; }
public static void RunImport_IntegrityCheck() { VideoLocalRepository repVidLocals = new VideoLocalRepository(); AniDB_FileRepository repAniFile = new AniDB_FileRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AniDB_AnimeRepository repAniAnime = new AniDB_AnimeRepository(); // files which don't have a valid import folder List<VideoLocal> filesToDelete = repVidLocals.GetVideosWithoutImportFolder(); foreach (VideoLocal vl in filesToDelete) repVidLocals.Delete(vl.VideoLocalID); // files which have not been hashed yet // or files which do not have a VideoInfo record List<VideoLocal> filesToHash = repVidLocals.GetVideosWithoutHash(); Dictionary<int, VideoLocal> dictFilesToHash = new Dictionary<int, VideoLocal>(); foreach (VideoLocal vl in filesToHash) { dictFilesToHash[vl.VideoLocalID] = vl; CommandRequest_HashFile cmd = new CommandRequest_HashFile(vl.FullServerPath, false); cmd.Save(); } List<VideoLocal> filesToRehash = repVidLocals.GetVideosWithoutVideoInfo(); Dictionary<int, VideoLocal> dictFilesToRehash = new Dictionary<int, VideoLocal>(); foreach (VideoLocal vl in filesToHash) { dictFilesToRehash[vl.VideoLocalID] = vl; // don't use if it is in the previous list if (!dictFilesToHash.ContainsKey(vl.VideoLocalID)) { try { CommandRequest_HashFile cmd = new CommandRequest_HashFile(vl.FullServerPath, false); cmd.Save(); } catch (Exception ex) { string msg = string.Format("Error RunImport_IntegrityCheck XREF: {0} - {1}", vl.ToStringDetailed(), ex.ToString()); logger.Info(msg); } } } // files which have been hashed, but don't have an associated episode List<VideoLocal> filesWithoutEpisode = repVidLocals.GetVideosWithoutEpisode(); Dictionary<int, VideoLocal> dictFilesWithoutEpisode = new Dictionary<int, VideoLocal>(); foreach (VideoLocal vl in filesWithoutEpisode) dictFilesWithoutEpisode[vl.VideoLocalID] = vl; // check that all the episode data is populated List<VideoLocal> filesAll = repVidLocals.GetAll(); Dictionary<string, VideoLocal> dictFilesAllExisting = new Dictionary<string, VideoLocal>(); foreach (VideoLocal vl in filesAll) { try { dictFilesAllExisting[vl.FullServerPath] = vl; } catch (Exception ex) { string msg = string.Format("Error RunImport_IntegrityCheck XREF: {0} - {1}", vl.ToStringDetailed(), ex.ToString()); logger.Error(msg); continue; } // check if it has an episode if (dictFilesWithoutEpisode.ContainsKey(vl.VideoLocalID)) { CommandRequest_ProcessFile cmd = new CommandRequest_ProcessFile(vl.VideoLocalID, false); cmd.Save(); continue; } // if the file is not manually associated, then check for AniDB_File info AniDB_File aniFile = repAniFile.GetByHash(vl.Hash); foreach (CrossRef_File_Episode xref in vl.EpisodeCrossRefs) { if (xref.CrossRefSource != (int)CrossRefSource.AniDB) continue; if (aniFile == null) { CommandRequest_ProcessFile cmd = new CommandRequest_ProcessFile(vl.VideoLocalID, false); cmd.Save(); continue; } } if (aniFile == null) continue; // the cross ref is created before the actually episode data is downloaded // so lets check for that bool missingEpisodes = false; foreach (CrossRef_File_Episode xref in aniFile.EpisodeCrossRefs) { AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID); if (ep == null) missingEpisodes = true; } if (missingEpisodes) { // this will then download the anime etc CommandRequest_ProcessFile cmd = new CommandRequest_ProcessFile(vl.VideoLocalID, false); cmd.Save(); continue; } } }
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 static void UpdateWatchedStatus(int animeID, enEpisodeType epType, int lastWatchedEpNumber) { try { if (string.IsNullOrEmpty(ServerSettings.MAL_Username) || string.IsNullOrEmpty(ServerSettings.MAL_Password)) return; AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); List<AniDB_Episode> aniEps = repAniEps.GetByAnimeIDAndEpisodeTypeNumber(animeID, epType, lastWatchedEpNumber); if (aniEps.Count == 0) return; AnimeEpisodeRepository repEp = new AnimeEpisodeRepository(); AnimeEpisode ep = repEp.GetByAniDBEpisodeID(aniEps[0].EpisodeID); if (ep == null) return; MALHelper.UpdateMAL(ep); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }*/ public static void UpdateMALSeries(AnimeSeries ser) { try { if (string.IsNullOrEmpty(ServerSettings.MAL_Username) || string.IsNullOrEmpty(ServerSettings.MAL_Password)) return; // Populate MAL animelist hashtable if isNeverDecreaseWatched set Hashtable animeListHashtable = new Hashtable(); if (ServerSettings.MAL_NeverDecreaseWatchedNums) //if set, check watched number before update: take some time, as user anime list must be loaded { myanimelist malAnimeList = GetMALAnimeList(); if (malAnimeList != null && malAnimeList.anime != null) { for (int i = 0; i < malAnimeList.anime.Length; i++) { animeListHashtable.Add(malAnimeList.anime[i].series_animedb_id, malAnimeList.anime[i]); } } } // look for MAL Links List<CrossRef_AniDB_MAL> crossRefs = ser.GetAnime().GetCrossRefMAL(); if (crossRefs == null || crossRefs.Count == 0) { logger.Warn("Could not find MAL link for : {0} ({1})", ser.GetAnime().GetFormattedTitle(), ser.GetAnime().AnimeID); return; } AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AniDB_FileRepository repFiles = new AniDB_FileRepository(); List<AnimeEpisode> eps = ser.GetAnimeEpisodes(); // find the anidb user JMMUserRepository repUsers = new JMMUserRepository(); List<JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); if (aniDBUsers.Count == 0) return; JMMUser user = aniDBUsers[0]; int score = 0; if (ser.GetAnime().UserVote != null) score = (int)(ser.GetAnime().UserVote.VoteValue / 100); // e.g. // AniDB - Code Geass R2 // MAL Equivalent = AniDB Normal Eps 1 - 25 / Code Geass: Hangyaku no Lelouch R2 / hxxp://myanimelist.net/anime/2904/Code_Geass:_Hangyaku_no_Lelouch_R2 // MAL Equivalent = AniDB Special Eps 1 - 9 / Code Geass: Hangyaku no Lelouch R2 Picture Drama / hxxp://myanimelist.net/anime/5163/Code_Geass:_Hangyaku_no_Lelouch_R2_Picture_Drama // MAL Equivalent = AniDB Special Eps 9 - 18 / Code Geass: Hangyaku no Lelouch R2: Flash Specials / hxxp://myanimelist.net/anime/9591/Code_Geass:_Hangyaku_no_Lelouch_R2:_Flash_Specials // MAL Equivalent = AniDB Special Eps 20 / Code Geass: Hangyaku no Lelouch - Kiseki no Birthday Picture Drama / hxxp://myanimelist.net/anime/8728/Code_Geass:_Hangyaku_no_Lelouch_-_Kiseki_no_Birthday_Picture_Drama foreach (CrossRef_AniDB_MAL xref in crossRefs) { // look for the right MAL id int malID = -1; int epNumber = -1; int totalEpCount = -1; List<string> fanSubGroups = new List<string>(); // for each cross ref (which is a series on MAL) we need to update the data // so find all the episodes which apply to this cross ref int lastWatchedEpNumber = 0; int downloadedEps = 0; foreach (AnimeEpisode ep in eps) { int epNum = ep.AniDB_Episode.EpisodeNumber; if (xref.StartEpisodeType == (int)ep.EpisodeTypeEnum && epNum >= xref.StartEpisodeNumber && epNum <= GetUpperEpisodeLimit(crossRefs, xref)) { malID = xref.MALID; epNumber = epNum - xref.StartEpisodeNumber + 1; // find the total episode count if (totalEpCount < 0) { if (ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Episode) totalEpCount = ser.GetAnime().EpisodeCountNormal; if (ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Special) totalEpCount = ser.GetAnime().EpisodeCountSpecial; totalEpCount = totalEpCount - xref.StartEpisodeNumber + 1; } // any episodes here belong to the MAL series // find the latest watched episod enumber AnimeEpisode_User usrRecord = ep.GetUserRecord(user.JMMUserID); if (usrRecord != null && usrRecord.WatchedDate.HasValue && epNum > lastWatchedEpNumber) { lastWatchedEpNumber = epNum; } List<Contract_VideoDetailed> contracts = ep.GetVideoDetailedContracts(user.JMMUserID); // find the latest episode number in the collection if (contracts.Count > 0) downloadedEps++; foreach (Contract_VideoDetailed contract in contracts) { if (!string.IsNullOrEmpty(contract.AniDB_Anime_GroupNameShort) && !fanSubGroups.Contains(contract.AniDB_Anime_GroupNameShort)) fanSubGroups.Add(contract.AniDB_Anime_GroupNameShort); } } } string fanSubs = ""; foreach (string fgrp in fanSubGroups) { if (!string.IsNullOrEmpty(fanSubs)) fanSubs += ","; fanSubs += fgrp; } // determine status int status = 1; //watching if (animeListHashtable.ContainsKey(malID)) { myanimelistAnime animeInList = (myanimelistAnime)animeListHashtable[malID]; status = animeInList.my_status; } // over-ride is user has watched an episode // don't override on hold (3) or dropped (4) but do override plan to watch (6) if (status == 6 && lastWatchedEpNumber > 0) status = 1; //watching if (lastWatchedEpNumber == totalEpCount) status = 2; //completed if (lastWatchedEpNumber > totalEpCount) { logger.Error("updateMAL, episode number > matching anime episode total : {0} ({1}) / {2}", ser.GetAnime().GetFormattedTitle(), ser.GetAnime().AnimeID, epNumber); continue; } if (malID <= 0 || totalEpCount <= 0) { logger.Warn("Could not find MAL link for : {0} ({1})", ser.GetAnime().GetFormattedTitle(), ser.GetAnime().AnimeID); continue; } else { bool res = UpdateAnime(malID, lastWatchedEpNumber, status, score, downloadedEps, fanSubs); string confirmationMessage = string.Format("MAL successfully updated, mal id: {0}, ep: {1}, score: {2}", malID, lastWatchedEpNumber, score); if (res) logger.Trace(confirmationMessage); } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }