private SVR_AniDB_File TryGetAniDBFileFromAniDB(SVR_VideoLocal vidLocal, Dictionary <int, bool> animeIDs) { // check if we already have a record SVR_AniDB_File aniFile = RepoFactory.AniDB_File.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null || aniFile.FileSize != vlocal.FileSize) { ForceAniDB = true; } if (ForceAniDB) { if (!ShokoService.AnidbProcessor.IsUdpBanned) { // get info from AniDB logger.Debug("Getting AniDB_File record from AniDB...."); Raw_AniDB_File fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vidLocal); if (fileInfo != null) { aniFile ??= new SVR_AniDB_File(); SVR_AniDB_File.Populate(aniFile, fileInfo); } } else { CommandRequest_GetFile fileCommand = new CommandRequest_GetFile(vlocal.VideoLocalID, true); fileCommand.Save(); } } if (aniFile == null) { return(null); } //overwrite with local file name string localFileName = vidLocal.GetBestVideoLocalPlace()?.FullServerPath; localFileName = !string.IsNullOrEmpty(localFileName) ? Path.GetFileName(localFileName) : vidLocal.FileName; aniFile.FileName = localFileName; RepoFactory.AniDB_File.Save(aniFile, false); aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(localFileName); aniFile.Episodes.Select(a => a.AnimeID).Distinct().ForEach(animeID => { if (animeIDs.ContainsKey(animeID)) { animeIDs[animeID] = false; } else { animeIDs.Add(animeID, false); } }); return(aniFile); }
public void Populate(Raw_AniDB_File fileInfo) { this.Anime_GroupName = fileInfo.Anime_GroupName; this.Anime_GroupNameShort = fileInfo.Anime_GroupNameShort; this.AnimeID = fileInfo.AnimeID; this.CRC = fileInfo.CRC; this.DateTimeUpdated = DateTime.Now; this.Episode_Rating = fileInfo.Episode_Rating; this.Episode_Votes = fileInfo.Episode_Votes; this.File_AudioCodec = fileInfo.File_AudioCodec; this.File_Description = fileInfo.File_Description; this.File_FileExtension = fileInfo.File_FileExtension; this.File_LengthSeconds = fileInfo.File_LengthSeconds; this.File_ReleaseDate = fileInfo.File_ReleaseDate; this.File_Source = fileInfo.File_Source; this.File_VideoCodec = fileInfo.File_VideoCodec; this.File_VideoResolution = fileInfo.File_VideoResolution; this.FileID = fileInfo.FileID; this.FileName = fileInfo.FileName; this.FileSize = fileInfo.FileSize; this.GroupID = fileInfo.GroupID; this.Hash = fileInfo.ED2KHash; this.IsWatched = fileInfo.IsWatched; this.MD5 = fileInfo.MD5; this.SHA1 = fileInfo.SHA1; this.FileVersion = fileInfo.FileVersion; this.IsCensored = fileInfo.IsCensored; this.IsDeprecated = fileInfo.IsDeprecated; this.InternalVersion = fileInfo.InternalVersion; this.languagesRAW = fileInfo.LanguagesRAW; this.subtitlesRAW = fileInfo.SubtitlesRAW; this.episodesPercentRAW = fileInfo.EpisodesPercentRAW; this.episodesRAW = fileInfo.EpisodesRAW; }
public void Populate_RA(Raw_AniDB_File fileInfo) { Anime_GroupName = fileInfo.Anime_GroupName; Anime_GroupNameShort = fileInfo.Anime_GroupNameShort; AnimeID = fileInfo.AnimeID; CRC = fileInfo.CRC; DateTimeUpdated = DateTime.Now; Episode_Rating = fileInfo.Episode_Rating; Episode_Votes = fileInfo.Episode_Votes; File_AudioCodec = fileInfo.File_AudioCodec; File_Description = fileInfo.File_Description; File_FileExtension = fileInfo.File_FileExtension; File_LengthSeconds = fileInfo.File_LengthSeconds; File_ReleaseDate = fileInfo.File_ReleaseDate; File_Source = fileInfo.File_Source; File_VideoCodec = fileInfo.File_VideoCodec; File_VideoResolution = fileInfo.File_VideoResolution; FileID = fileInfo.FileID; FileName = fileInfo.FileName; FileSize = fileInfo.FileSize; GroupID = fileInfo.GroupID; Hash = fileInfo.ED2KHash; IsWatched = fileInfo.IsWatched; MD5 = fileInfo.MD5; SHA1 = fileInfo.SHA1; FileVersion = fileInfo.FileVersion; IsCensored = fileInfo.IsCensored; IsDeprecated = fileInfo.IsDeprecated; IsChaptered = fileInfo.IsChaptered; InternalVersion = fileInfo.InternalVersion; languagesRAW = fileInfo.LanguagesRAW; subtitlesRAW = fileInfo.SubtitlesRAW; episodesPercentRAW = fileInfo.EpisodesPercentRAW; episodesRAW = fileInfo.EpisodesRAW; }
public static void Populate(SVR_AniDB_File anidbfile, Raw_AniDB_File fileInfo) { anidbfile.Anime_GroupName = fileInfo.Anime_GroupName; anidbfile.Anime_GroupNameShort = fileInfo.Anime_GroupNameShort; anidbfile.AnimeID = fileInfo.AnimeID; anidbfile.CRC = fileInfo.CRC; anidbfile.DateTimeUpdated = DateTime.Now; anidbfile.Episode_Rating = fileInfo.Episode_Rating; anidbfile.Episode_Votes = fileInfo.Episode_Votes; anidbfile.File_AudioCodec = fileInfo.File_AudioCodec; anidbfile.File_Description = fileInfo.File_Description; anidbfile.File_FileExtension = fileInfo.File_FileExtension; anidbfile.File_LengthSeconds = fileInfo.File_LengthSeconds; anidbfile.File_ReleaseDate = fileInfo.File_ReleaseDate; anidbfile.File_Source = fileInfo.File_Source; anidbfile.File_VideoCodec = fileInfo.File_VideoCodec; anidbfile.File_VideoResolution = fileInfo.File_VideoResolution; anidbfile.FileID = fileInfo.FileID; anidbfile.FileName = fileInfo.FileName; anidbfile.FileSize = fileInfo.FileSize; anidbfile.GroupID = fileInfo.GroupID; anidbfile.Hash = fileInfo.ED2KHash; anidbfile.IsWatched = fileInfo.IsWatched; anidbfile.MD5 = fileInfo.MD5; anidbfile.SHA1 = fileInfo.SHA1; anidbfile.FileVersion = fileInfo.FileVersion; anidbfile.IsCensored = fileInfo.IsCensored; anidbfile.IsDeprecated = fileInfo.IsDeprecated; anidbfile.InternalVersion = fileInfo.InternalVersion; anidbfile.languagesRAW = fileInfo.LanguagesRAW; anidbfile.subtitlesRAW = fileInfo.SubtitlesRAW; anidbfile.episodesPercentRAW = fileInfo.EpisodesPercentRAW; anidbfile.episodesRAW = fileInfo.EpisodesRAW; }
public override void ProcessCommand() { logger.Info("Get AniDB file info: {0}", VideoLocalID); try { if (vlocal == null) { vlocal = RepoFactory.VideoLocal.GetByID(VideoLocalID); } if (vlocal == null) { return; } lock (vlocal) { SVR_AniDB_File aniFile = RepoFactory.AniDB_File.GetByHashAndFileSize(vlocal.Hash, vlocal.FileSize); Raw_AniDB_File fileInfo = null; if (aniFile == null || ForceAniDB) { fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vlocal); } if (fileInfo != null) { // save to the database if (aniFile == null) { aniFile = new SVR_AniDB_File(); } SVR_AniDB_File.Populate(aniFile, fileInfo); //overwrite with local file name string localFileName = vlocal.FileName; aniFile.FileName = localFileName; RepoFactory.AniDB_File.Save(aniFile, false); aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(localFileName); SVR_AniDB_Anime anime = RepoFactory.AniDB_Anime.GetByAnimeID(aniFile.AnimeID); if (anime != null) { RepoFactory.AniDB_Anime.Save(anime); } SVR_AnimeSeries series = RepoFactory.AnimeSeries.GetByAnimeID(aniFile.AnimeID); series.UpdateStats(true, true, true); } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_GetFile: {0} - {1}", VideoLocalID, ex); } }
public override void ProcessCommand() { logger.Info("Get AniDB file info: {0}", VideoLocalID); try { if (vlocal == null) { vlocal = Repo.Instance.VideoLocal.GetByID(VideoLocalID); } if (vlocal == null) { return; } lock (vlocal) { SVR_AniDB_File aniFile = Repo.Instance.AniDB_File.GetByHashAndFileSize(vlocal.Hash, vlocal.FileSize); Raw_AniDB_File fileInfo = null; if (aniFile == null || ForceAniDB) { fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vlocal); } if (fileInfo != null) { using (var upd = Repo.Instance.AniDB_File.BeginAddOrUpdate(() => aniFile)) { upd.Entity.Populate_RA(fileInfo); //overwrite with local file name string localFileName = vlocal.FileName; upd.Entity.FileName = localFileName; aniFile = upd.Commit(); } aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(vlocal.FileName); //TODO: Look at why this might be worth it? //SVR_AniDB_Anime anime = Repo.Instance.AniDB_Anime.GetByAnimeID(aniFile.AnimeID); //if (anime != null) Repo.Instance.AniDB_Anime.Save(anime); SVR_AnimeSeries series = Repo.Instance.AnimeSeries.GetByAnimeID(aniFile.AnimeID); series.UpdateStats(true, true, true); } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_GetFile: {0} - {1}", VideoLocalID, ex); } }
public virtual enHelperActivityType Process(ref Socket soUDP, ref IPEndPoint remoteIpEndPoint, string sessionID, Encoding enc) { ProcessCommand(ref soUDP, ref remoteIpEndPoint, sessionID, enc); // handle 555 BANNED and 598 - UNKNOWN COMMAND if (ResponseCode == 598) { return(enHelperActivityType.UnknownCommand_598); } if (ResponseCode == 555) { return(enHelperActivityType.Banned_555); } if (errorOccurred) { return(enHelperActivityType.FileDoesNotExist); } //BaseConfig.MyAnimeLog.Write("AniDBCommand_GetFileInfo.Process: Response: {0}", socketResponse); // Process Response string sMsgType = socketResponse.Substring(0, 3); switch (sMsgType) { case "220": { // 220 FILE INFO // the first 9 characters should be "220 FILE " // the rest of the information should be the data list fileInfo = new Raw_AniDB_File(socketResponse); //episodeInfo = new Raw_AniDB_Episode(socketResponse, enEpisodeSourceType.File); return(enHelperActivityType.GotFileInfo); } case "320": { return(enHelperActivityType.FileDoesNotExist); } case "501": { return(enHelperActivityType.LoginRequired); } } return(enHelperActivityType.FileDoesNotExist); }
public virtual enHelperActivityType Process(ref Socket soUDP, ref IPEndPoint remoteIpEndPoint, string sessionID, Encoding enc) { ProcessCommand(ref soUDP, ref remoteIpEndPoint, sessionID, enc); // handle 555 BANNED and 598 - UNKNOWN COMMAND if (ResponseCode == 598) return enHelperActivityType.UnknownCommand_598; if (ResponseCode == 555) return enHelperActivityType.Banned_555; if (errorOccurred) return enHelperActivityType.FileDoesNotExist; //BaseConfig.MyAnimeLog.Write("AniDBCommand_GetFileInfo.Process: Response: {0}", socketResponse); // Process Response string sMsgType = socketResponse.Substring(0, 3); switch (sMsgType) { case "220": { // 220 FILE INFO // the first 9 characters should be "220 FILE " // the rest of the information should be the data list fileInfo = new Raw_AniDB_File(socketResponse); //episodeInfo = new Raw_AniDB_Episode(socketResponse, enEpisodeSourceType.File); return enHelperActivityType.GotFileInfo; } case "320": { return enHelperActivityType.FileDoesNotExist; } case "501": { return enHelperActivityType.LoginRequired; } } return enHelperActivityType.FileDoesNotExist; }
private void ProcessFile_AniDB(SVR_VideoLocal vidLocal) { logger.Trace($"Checking for AniDB_File record for: {vidLocal.Hash} --- {vidLocal.FileName}"); // check if we already have this AniDB_File info in the database lock (vidLocal) { SVR_AniDB_File aniFile = null; if (!ForceAniDB) { aniFile = Repo.Instance.AniDB_File.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null) { logger.Trace("AniDB_File record not found"); } } // If cross refs were wiped, but the AniDB_File was not, we unfortunately need to requery the info List <CrossRef_File_Episode> crossRefs = Repo.Instance.CrossRef_File_Episode.GetByHash(vidLocal.Hash); if (crossRefs == null || crossRefs.Count == 0) { aniFile = null; } int animeID = 0; if (aniFile == null) { // get info from AniDB logger.Debug("Getting AniDB_File record from AniDB...."); // check if we already have a record using (var upd = Repo.Instance.AniDB_File.BeginAddOrUpdate(() => Repo.Instance.AniDB_File.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize))) { bool skip = false; if (!upd.IsUpdate) { Raw_AniDB_File fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vidLocal); if (fileInfo != null) { upd.Entity.Populate_RA(fileInfo); } else { skip = true; } } if (!skip) { //overwrite with local file name string localFileName = vidLocal.GetBestVideoLocalPlace()?.FullServerPath; localFileName = !string.IsNullOrEmpty(localFileName) ? Path.GetFileName(localFileName) : vidLocal.FileName; upd.Entity.FileName = localFileName; aniFile = upd.Commit(false); aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(localFileName); animeID = aniFile.AnimeID; } upd.Commit(); } } 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 crossRefs = Repo.Instance.CrossRef_File_Episode.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.Instance.WebCache.XRefFileEpisode_Get) { List <Azure_CrossRef_File_Episode> xrefs = AzureWebAPI.Get_CrossRefFileEpisode(vidLocal); crossRefs = new List <CrossRef_File_Episode>(); if (xrefs == null || xrefs.Count == 0) { logger.Debug( $"Cannot find AniDB_File record or get cross ref from web cache record so exiting: {vidLocal.ED2KHash}"); return; } string fileName = vidLocal.GetBestVideoLocalPlace()?.FullServerPath; fileName = !string.IsNullOrEmpty(fileName) ? Path.GetFileName(fileName) : vidLocal.FileName; foreach (Azure_CrossRef_File_Episode xref in xrefs) { CrossRef_File_Episode xrefEnt = new CrossRef_File_Episode { Hash = vidLocal.ED2KHash, FileName = fileName, FileSize = vidLocal.FileSize, CrossRefSource = (int)CrossRefSource.WebCache, AnimeID = xref.AnimeID, EpisodeID = xref.EpisodeID, Percentage = xref.Percentage, EpisodeOrder = xref.EpisodeOrder }; bool duplicate = false; foreach (CrossRef_File_Episode xrefcheck in crossRefs) { if (xrefcheck.AnimeID == xrefEnt.AnimeID && xrefcheck.EpisodeID == xrefEnt.EpisodeID && xrefcheck.Hash == xrefEnt.Hash) { duplicate = true; } } if (!duplicate) { crossRefs.Add(xrefEnt); // in this case we need to save the cross refs manually as AniDB did not provide them Repo.Instance.CrossRef_File_Episode.BeginAdd(xrefEnt).Commit(); } } } else { logger.Debug($"Cannot get AniDB_File record so exiting: {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 = Repo.Instance.AniDB_Episode.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: {vidLocal.ED2KHash}"); missingEpisodes = true; } else { foreach (CrossRef_File_Episode xref in aniFile.EpisodeCrossRefs) { AniDB_Episode ep = Repo.Instance.AniDB_Episode.GetByEpisodeID(xref.EpisodeID); if (ep == null) { missingEpisodes = true; } animeID = xref.AnimeID; } } } // get from DB SVR_AniDB_Anime anime = Repo.Instance.AniDB_Anime.GetByAnimeID(animeID); var update = Repo.Instance.AniDB_AnimeUpdate.GetByAnimeID(animeID); bool animeRecentlyUpdated = false; if (anime != null && update != null) { TimeSpan ts = DateTime.Now - update.UpdatedAt; if (ts.TotalHours < 4) { animeRecentlyUpdated = true; } } else { missingEpisodes = 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...."); anime = ShokoService.AnidbProcessor.GetAnimeInfoHTTP(animeID, true, ServerSettings.Instance.AutoGroupSeries || ServerSettings.Instance.AniDb.DownloadRelatedAnime); } // create the group/series/episode records if needed if (anime != null) { logger.Debug("Creating groups, series and episodes...."); // check if there is an AnimeSeries Record associated with this AnimeID SVR_AnimeSeries ser; using (var upd = Repo.Instance.AnimeSeries.BeginAddOrUpdate( () => Repo.Instance.AnimeSeries.GetByAnimeID(animeID), () => anime.CreateAnimeSeriesAndGroup() )) { upd.Entity.CreateAnimeEpisodes(); // check if we have any group status data for this associated anime // if not we will download it now if (Repo.Instance.AniDB_GroupStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(); } // update stats upd.Entity.EpisodeAddedDate = DateTime.Now; ser = upd.Commit(); } Repo.Instance.AnimeGroup.BatchAction(ser.AllGroupsAbove, ser.AllGroupsAbove.Count, (grp, _) => grp.EpisodeAddedDate = DateTime.Now, (true, false, false)); // We do this inside, as the info will not be available as needed otherwise List <SVR_VideoLocal> videoLocals = aniFile?.EpisodeIDs?.SelectMany(a => Repo.Instance.VideoLocal.GetByAniDBEpisodeID(a)) .Where(b => b != null) .ToList(); if (videoLocals != null) { // Copy over watched states foreach (var user in Repo.Instance.JMMUser.GetAll()) { var watchedVideo = videoLocals.FirstOrDefault(a => a?.GetUserRecord(user.JMMUserID)?.WatchedDate != null); // No files that are watched if (watchedVideo == null) { continue; } var watchedRecord = watchedVideo.GetUserRecord(user.JMMUserID); using (var upd = Repo.Instance.VideoLocal_User.BeginAddOrUpdate( () => vidLocal.GetUserRecord(user.JMMUserID), () => new VideoLocal_User { JMMUserID = user.JMMUserID, VideoLocalID = vidLocal.VideoLocalID } )) { upd.Entity.WatchedDate = watchedRecord.WatchedDate; upd.Entity.ResumePosition = watchedRecord.ResumePosition; upd.Commit(); } } if (ServerSettings.Instance.FileQualityFilterEnabled) { videoLocals.Sort(FileQualityFilter.CompareTo); List <SVR_VideoLocal> keep = videoLocals .Take(FileQualityFilter.Settings.MaxNumberOfFilesToKeep) .ToList(); foreach (SVR_VideoLocal vl2 in keep) { videoLocals.Remove(vl2); } if (!FileQualityFilter.Settings.AllowDeletionOfImportedFiles && videoLocals.Contains(vidLocal)) { videoLocals.Remove(vidLocal); } videoLocals = videoLocals.Where(a => !FileQualityFilter.CheckFileKeep(a)).ToList(); videoLocals.ForEach(a => a.Places.ForEach(b => b.RemoveAndDeleteFile())); } } // update stats for groups and series // update all the groups above this series in the heirarchy SVR_AniDB_Anime.UpdateStatsByAnimeID(animeID); } else { logger.Warn($"Unable to create AniDB_Anime for file: {vidLocal.FileName}"); } vidLocal.Places.ForEach(a => { a.RenameAndMoveAsRequired(); }); // Add this file to the users list if (ServerSettings.Instance.AniDb.MyList_AddFiles) { CommandRequest_AddFileToMyList cmd = new CommandRequest_AddFileToMyList(vidLocal.ED2KHash); cmd.Save(); } } }
public override void ProcessCommand() { logger.Info("Get AniDB file info: {0}", VideoLocalID); try { vlocal = RepoFactory.VideoLocal.GetByID(VideoLocalID); if (vlocal == null) { return; } lock (vlocal) { SVR_AniDB_File aniFile = RepoFactory.AniDB_File.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 = ShokoService.AnidbProcessor.GetFileInfo(vlocal); } if (fileInfo != null) { // save to the database if (aniFile == null) { aniFile = new SVR_AniDB_File(); } SVR_AniDB_File.Populate(aniFile, fileInfo); //overwrite with local file name string localFileName = vlocal.FileName; aniFile.FileName = localFileName; RepoFactory.AniDB_File.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(); } } } SVR_AniDB_Anime anime = RepoFactory.AniDB_Anime.GetByAnimeID(aniFile.AnimeID); if (anime != null) { using (var session = DatabaseFactory.SessionFactory.OpenSession()) { anime.UpdateContractDetailed(session.Wrap()); } } SVR_AnimeSeries series = RepoFactory.AnimeSeries.GetByAnimeID(aniFile.AnimeID); series.UpdateStats(false, true, true); // StatsCache.Instance.UpdateUsingAniDBFile(vlocal.Hash); } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_GetFile: {0} - {1}", VideoLocalID, ex.ToString()); return; } }
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; } }
private void ProcessFile_AniDB(SVR_VideoLocal vidLocal) { logger.Trace("Checking for AniDB_File record for: {0} --- {1}", vidLocal.Hash, vidLocal.FileName); // check if we already have this AniDB_File info in the database lock (vidLocal) { SVR_AniDB_File aniFile = null; if (!ForceAniDB) { aniFile = RepoFactory.AniDB_File.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 = ShokoService.AnidbProcessor.GetFileInfo(vidLocal); if (fileInfo != null) { // check if we already have a record aniFile = RepoFactory.AniDB_File.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null) { aniFile = new SVR_AniDB_File(); } SVR_AniDB_File.Populate(aniFile, fileInfo); //overwrite with local file name string localFileName = vidLocal.FileName; aniFile.FileName = localFileName; RepoFactory.AniDB_File.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 = RepoFactory.CrossRef_File_Episode.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) { List <Shoko.Models.Azure.Azure_CrossRef_File_Episode> xrefs = AzureWebAPI.Get_CrossRefFileEpisode(vidLocal); crossRefs = new List <CrossRef_File_Episode>(); if (xrefs == null || xrefs.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 (Shoko.Models.Azure.Azure_CrossRef_File_Episode xref in xrefs) { CrossRef_File_Episode xrefEnt = new CrossRef_File_Episode(); xrefEnt.Hash = vidLocal.ED2KHash; xrefEnt.FileName = vidLocal.FileName; xrefEnt.FileSize = vidLocal.FileSize; xrefEnt.CrossRefSource = (int)CrossRefSource.WebCache; xrefEnt.AnimeID = xref.AnimeID; xrefEnt.EpisodeID = xref.EpisodeID; xrefEnt.Percentage = xref.Percentage; xrefEnt.EpisodeOrder = xref.EpisodeOrder; bool duplicate = false; foreach (CrossRef_File_Episode xrefcheck in crossRefs) { if (xrefcheck.AnimeID == xrefEnt.AnimeID && xrefcheck.EpisodeID == xrefEnt.EpisodeID && xrefcheck.Hash == xrefEnt.Hash) { duplicate = true; } } if (!duplicate) { crossRefs.Add(xrefEnt); // in this case we need to save the cross refs manually as AniDB did not provide them RepoFactory.CrossRef_File_Episode.Save(xrefEnt); } } } } 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 = RepoFactory.AniDB_Episode.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 = RepoFactory.AniDB_Episode.GetByEpisodeID(xref.EpisodeID); if (ep == null) { missingEpisodes = true; } animeID = xref.AnimeID; } } } // get from DB SVR_AniDB_Anime anime = RepoFactory.AniDB_Anime.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...."); anime = ShokoService.AnidbProcessor.GetAnimeInfoHTTP(animeID, true, ServerSettings.AutoGroupSeries); } // create the group/series/episode records if needed SVR_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 = RepoFactory.AnimeSeries.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 if (RepoFactory.AniDB_GroupStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(); } // update stats ser.EpisodeAddedDate = DateTime.Now; RepoFactory.AnimeSeries.Save(ser, false, false); foreach (SVR_AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; RepoFactory.AnimeGroup.Save(grp, true, false); } if (ServerSettings.FileQualityFilterEnabled) { // We do this inside, as the info will not be available as needed otherwise List <SVR_VideoLocal> videoLocals = aniFile?.EpisodeIDs?.SelectMany(a => RepoFactory.VideoLocal.GetByAniDBEpisodeID(a)) .Where(b => b != null) .ToList(); if (videoLocals != null) { videoLocals.Sort(FileQualityFilter.CompareTo); List <SVR_VideoLocal> keep = videoLocals .Take(FileQualityFilter.Settings.MaxNumberOfFilesToKeep) .ToList(); foreach (SVR_VideoLocal vl2 in keep) { videoLocals.Remove(vl2); } if (!FileQualityFilter.Settings.AllowDeletionOfImportedFiles && videoLocals.Contains(vidLocal)) { videoLocals.Remove(vidLocal); } videoLocals = videoLocals.Where(a => !FileQualityFilter.CheckFileKeep(a)).ToList(); foreach (SVR_VideoLocal toDelete in videoLocals) { toDelete.Places.ForEach(a => a.RemoveAndDeleteFile()); } } } } vidLocal.Places.ForEach(a => { a.RenameAndMoveAsRequired(); }); // update stats for groups and series if (ser != null) { // update all the groups above this series in the heirarchy ser.QueueUpdateStats(); //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(); } } }
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) { List <JMMServer.Providers.Azure.CrossRef_File_Episode> xrefs = JMMServer.Providers.Azure.AzureWebAPI.Get_CrossRefFileEpisode(vidLocal); crossRefs = new List <CrossRef_File_Episode>(); if (xrefs == null || xrefs.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 (JMMServer.Providers.Azure.CrossRef_File_Episode xref in xrefs) { CrossRef_File_Episode xrefEnt = new CrossRef_File_Episode(); xrefEnt.Hash = vidLocal.ED2KHash; xrefEnt.FileName = Path.GetFileName(vidLocal.FullServerPath); xrefEnt.FileSize = vidLocal.FileSize; xrefEnt.CrossRefSource = (int)JMMServer.CrossRefSource.WebCache; xrefEnt.AnimeID = animeID; xrefEnt.EpisodeID = xref.EpisodeID; xrefEnt.Percentage = xref.Percentage; xrefEnt.EpisodeOrder = xref.EpisodeOrder; crossRefs.Add(xrefEnt); // in this case we need to save the cross refs manually as AniDB did not provide them repXrefFE.Save(xrefEnt); } } } 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...."); 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) { if (ServerSettings.WebCache_Trakt_Send && !string.IsNullOrEmpty(ServerSettings.Trakt_Username)) { 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(); } }
public override void Run(IProgress <ICommand> progress = null) { logger.Info("Get AniDB file info: {0}", VideoLocalID); try { ReportInit(progress); if (vlocal == null) { vlocal = Repo.Instance.VideoLocal.GetByID(VideoLocalID); } if (vlocal == null) { ReportError(progress, $"VideoLocal with id {VideoLocalID} not found"); return; } lock (vlocal) { SVR_AniDB_File aniFile = Repo.Instance.AniDB_File.GetByHashAndFileSize(vlocal.Hash, vlocal.FileSize); ReportUpdate(progress, 20); Raw_AniDB_File fileInfo = null; if (aniFile == null || ForceAniDB) { fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vlocal); } ReportUpdate(progress, 40); if (fileInfo != null) { SVR_AniDB_File file = aniFile; using (var upd = Repo.Instance.AniDB_File.BeginAddOrUpdate(file)) { upd.Entity.Populate_RA(fileInfo); //overwrite with local file name string localFileName = vlocal.Info; upd.Entity.FileName = localFileName; aniFile = upd.Commit(); } ReportUpdate(progress, 55); aniFile.CreateLanguages(); ReportUpdate(progress, 70); aniFile.CreateCrossEpisodes(vlocal.Info); ReportUpdate(progress, 85); //TODO: Look at why this might be worth it? //SVR_AniDB_Anime anime = Repo.Instance.AniDB_Anime.GetByAnimeID(aniFile.AnimeID); //if (anime != null) Repo.Instance.AniDB_Anime.Save(anime); SVR_AnimeSeries series = Repo.Instance.AnimeSeries.GetByAnimeID(aniFile.AnimeID); series.UpdateStats(true, true, true); } ReportFinish(progress); } } catch (Exception ex) { ReportError(progress, $"Error processing Command AniDb.GetFile: {VideoLocalID} - {ex}", ex); } }