private static int CompareSubStreamCountTo(SVR_VideoLocal newFile, SVR_VideoLocal oldFile) { int newStreamCount = newFile?.Media?.TextStreams?.Count ?? 0; int oldStreamCount = oldFile?.Media?.TextStreams?.Count ?? 0; return(oldStreamCount.CompareTo(newStreamCount)); }
private static int CompareVersionTo(SVR_VideoLocal newFile, SVR_VideoLocal oldFile) { AniDB_File newAni = newFile?.GetAniDBFile(); AniDB_File oldAni = oldFile?.GetAniDBFile(); if (newAni == null || oldAni == null) { return(0); } if (!newAni.Anime_GroupName.Equals(oldAni.Anime_GroupName)) { return(0); } if (!newAni.File_VideoResolution.Equals(oldAni.File_VideoResolution)) { return(0); } if (!(newFile.Media?.VideoStream?.BitDepth).Equals(oldFile.Media?.VideoStream?.BitDepth)) { return(0); } if (!string.Equals(newFile.Media?.VideoStream?.CodecID, oldFile.Media?.VideoStream?.CodecID)) { return(0); } return(oldAni.FileVersion.CompareTo(newAni.FileVersion)); }
private static int CompareAudioCodecTo(SVR_VideoLocal newFile, SVR_VideoLocal oldFile) { string[] newCodecs = newFile?.Media?.AudioStreams?.Select(LegacyMediaUtils.TranslateCodec) .Where(a => a != null).OrderBy(a => a).ToArray() ?? new string[] { }; string[] oldCodecs = oldFile?.Media?.AudioStreams?.Select(LegacyMediaUtils.TranslateCodec) .Where(a => a != null).OrderBy(a => a).ToArray() ?? new string[] { }; // compare side by side, average codec quality would be vague and annoying, defer to number of audio tracks if (newCodecs.Length != oldCodecs.Length) { return(0); } for (int i = 0; i < Math.Min(newCodecs.Length, oldCodecs.Length); i++) { string newCodec = newCodecs[i]; string oldCodec = oldCodecs[i]; int newIndex = Settings.PreferredAudioCodecs.IndexOf(newCodec); int oldIndex = Settings.PreferredAudioCodecs.IndexOf(oldCodec); if (newIndex < 0 || oldIndex < 0) { continue; } int result = newIndex.CompareTo(oldIndex); if (result != 0) { return(result); } } return(0); }
/*public static List<CrossRef_File_Episode> Get_CrossRefFileEpisode() * { * //if (!ServerSettings.WebCache_XRefFileEpisode_Get) return null; * * //string username = ServerSettings.AniDB_Username; * //if (ServerSettings.WebCache_Anonymous) * // username = Constants.AnonWebCacheUsername; * * string uri = string.Format(@"http://{0}/api/CrossRef_File_Episode/{1}?p={2}", azureHostBaseAddress, "88D29145F18DCEA4D4C41EF94B950378", "Ilast"); * string msg = string.Format("Getting File/Episode Cross Ref From Cache: {0}", "88D29145F18DCEA4D4C41EF94B950378"); * * DateTime start = DateTime.Now; * JMMService.LogToSystem(Constants.DBLogType.APIAzureHTTP, msg); * * string json = GetDataJson(uri); * * TimeSpan ts = DateTime.Now - start; * msg = string.Format("Got File/Episode Cross Ref From Cache: {0} - {1}", "88D29145F18DCEA4D4C41EF94B950378", ts.TotalMilliseconds); * JMMService.LogToSystem(Constants.DBLogType.APIAzureHTTP, msg); * * List<CrossRef_File_Episode> xrefs = JSONHelper.Deserialize<List<CrossRef_File_Episode>>(json); * * return xrefs; * }*/ public static List <Azure_CrossRef_File_Episode> Get_CrossRefFileEpisode(SVR_VideoLocal vid) { if (!ServerSettings.WebCache_XRefFileEpisode_Get) { return(null); } string username = ServerSettings.AniDB_Username; if (ServerSettings.WebCache_Anonymous) { username = Constants.AnonWebCacheUsername; } string uri = string.Format(@"http://{0}/api/CrossRef_File_Episode/{1}?p={2}", azureHostBaseAddress, vid.Hash, username); string msg = string.Format("Getting File/Episode Cross Ref From Cache: {0}", vid.Hash); DateTime start = DateTime.Now; ShokoService.LogToSystem(Constants.DBLogType.APIAzureHTTP, msg); string json = GetDataJson(uri); TimeSpan ts = DateTime.Now - start; msg = string.Format("Got File/Episode Cross Ref From Cache: {0} - {1}", vid.Hash, ts.TotalMilliseconds); ShokoService.LogToSystem(Constants.DBLogType.APIAzureHTTP, msg); List <Azure_CrossRef_File_Episode> xrefs = JSONHelper.Deserialize <List <Azure_CrossRef_File_Episode> >(json); return(xrefs); }
public override void ProcessCommand() { logger.Info("Reading Media Info for File: {0}", VideoLocalID); try { SVR_VideoLocal vlocal = RepoFactory.VideoLocal.GetByID(VideoLocalID); SVR_VideoLocal_Place place = vlocal?.GetBestVideoLocalPlace(); if (place == null) { logger.Error("Cound not find Video: {0}", VideoLocalID); return; } if (place.RefreshMediaInfo()) { RepoFactory.VideoLocal.Save(place.VideoLocal, true); } } catch (Exception ex) { logger.Error("Error processing CommandRequest_ReadMediaInfo: {0} - {1}", VideoLocalID, ex.ToString()); return; } }
private ActionResult ScrobbleStatusOnFile(SVR_VideoLocal file, bool?watched, long?resumePosition) { if (!(watched ?? false) && resumePosition != null) { var safeRP = resumePosition ?? 0; if (safeRP < 0) { safeRP = 0; } if (safeRP >= file.Duration) { watched = true; } else { file.SetResumePosition(safeRP, User.JMMUserID); } } if (watched != null) { var safeWatched = watched ?? false; file.ToggleWatchedStatus(safeWatched, User.JMMUserID); if (safeWatched) { file.SetResumePosition(0, User.JMMUserID); } } return(Ok()); }
public override void ProcessCommand() { logger.Trace($"Processing File: {VideoLocalID}"); try { if (vlocal == null) { vlocal = RepoFactory.VideoLocal.GetByID(VideoLocalID); } if (vlocal == null) { return; } //now that we have all the has info, we can get the AniDB Info ProcessFile_AniDB(vlocal); vlocal.Places.ForEach(a => { a.RenameAndMoveAsRequired(); }); ShokoEventHandler.Instance.OnFileMatched(vlocal.GetBestVideoLocalPlace()); } catch (Exception ex) { logger.Error($"Error processing CommandRequest_ProcessFile: {VideoLocalID} - {ex}"); } }
private static Tuple <int, int> GetResolutionInternal(SVR_VideoLocal videoLocal, SVR_AniDB_File aniFile) { string[] res = aniFile?.File_VideoResolution?.Split('x'); int oldHeight = 0, oldWidth = 0; if (res != null && res.Length == 2 && res[0] == "0" && res[1] == "0") { int.TryParse(res[0], out oldWidth); int.TryParse(res[1], out oldHeight); } if (oldHeight == 0 || oldWidth == 0) { var stream = videoLocal?.Media?.Parts?.SelectMany(a => a.Streams) .FirstOrDefault(a => a.StreamType == 1); if (stream != null) { oldWidth = stream.Width; oldHeight = stream.Height; } } if (oldHeight == 0 || oldWidth == 0) { return(null); } return(new Tuple <int, int>(oldWidth, oldHeight)); }
private InfoResult ResolveVideoLocal(int videolocalid, int?userId, bool?autowatch) { try { InfoResult r = new InfoResult(); SVR_VideoLocal loc = Repo.Instance.VideoLocal.GetByID(videolocalid); if (loc == null) { r.Status = HttpStatusCode.NotFound; r.StatusDescription = "Video Not Found"; return(r); } r.VideoLocal = loc; r.File = loc.GetBestFileLink(); return(FinishResolve(r, userId, autowatch)); } catch (Exception e) { logger.Error("An error occurred while serving a file: " + e); var resp = new InfoResult(); resp.Status = HttpStatusCode.InternalServerError; resp.StatusDescription = e.Message; return(resp); } }
private static Tuple <int, int> GetResolutionInternal(SVR_VideoLocal videoLocal, SVR_AniDB_File aniFile) { string[] res = aniFile?.File_VideoResolution?.Split('x'); if (res == null || res.Length != 2 || res[0] == "0" && res[1] == "0") { var stream = videoLocal?.Media?.Parts?.SelectMany(a => a.Streams) ?.FirstOrDefault(a => a.StreamType == "1"); if (stream != null) { res = new[] { stream.Width, stream.Height } } ; } if (res == null || res.Length != 2 || res[0] == "0" && res[1] == "0") { return(null); } if (!int.TryParse(res[0], out int oldWidth)) { return(null); } if (!int.TryParse(res[1], out int oldHeight)) { return(null); } if (oldWidth == 0 || oldHeight == 0) { return(null); } return(new Tuple <int, int>(oldWidth, oldHeight)); } #endregion }
public override void ProcessCommand() { logger.Info("Reading Media Info for File: {0}", VideoLocalID); try { SVR_VideoLocal vlocal = Repo.Instance.VideoLocal.GetByID(VideoLocalID); SVR_VideoLocal_Place place = vlocal?.GetBestVideoLocalPlace(true); if (place == null) { logger.Error("Cound not find Video: {0}", VideoLocalID); return; } using (var txn = Repo.Instance.VideoLocal.BeginAddOrUpdate(() => place.VideoLocal)) { if (place.RefreshMediaInfo(txn.Entity)) { txn.Commit(); } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_ReadMediaInfo: {0} - {1}", VideoLocalID, ex); } }
public static Video VideoFromVideoLocal(IProvider prov, SVR_VideoLocal v, int userid) { Video l = new Video { AnimeType = AnimeTypes.AnimeFile.ToString(), Id = v.VideoLocalID, Type = "episode", Summary = "Episode Overview Not Available", //TODO Internationalization Title = Path.GetFileNameWithoutExtension(v.FileName), AddedAt = v.DateTimeCreated.ToUnixTime(), UpdatedAt = v.DateTimeUpdated.ToUnixTime(), OriginallyAvailableAt = v.DateTimeCreated.ToPlexDate(), Year = v.DateTimeCreated.Year, Medias = new List <Media>() }; VideoLocal_User vlr = v.GetUserRecord(userid); if (vlr?.WatchedDate != null) { l.LastViewedAt = vlr.WatchedDate.Value.ToUnixTime(); } if (vlr?.ResumePosition > 0) { l.ViewOffset = vlr.ResumePosition; } if (v.Media != null) { Media m = new Media(v.VideoLocalID, v.Media); l.Medias.Add(m); l.Duration = m.Duration; } AddLinksToAnimeEpisodeVideo(prov, l, userid); return(l); }
public override bool LoadFromDBCommand(CommandRequest cq) { CommandID = cq.CommandID; CommandRequestID = cq.CommandRequestID; Priority = cq.Priority; CommandDetails = cq.CommandDetails; DateTimeUpdated = cq.DateTimeUpdated; // read xml to get parameters if (CommandDetails.Trim().Length <= 0) { return(true); } XmlDocument docCreator = new XmlDocument(); docCreator.LoadXml(CommandDetails); // populate the fields VideoLocalID = int.Parse(TryGetProperty(docCreator, "CommandRequest_ProcessFile", "VideoLocalID")); ForceAniDB = bool.Parse(TryGetProperty(docCreator, "CommandRequest_ProcessFile", "ForceAniDB")); SkipMyList = bool.Parse(TryGetProperty(docCreator, "CommandRequest_ProcessFile", "SkipMyList")); vlocal = RepoFactory.VideoLocal.GetByID(VideoLocalID); return(true); }
public override bool LoadFromDBCommand(CommandRequest cq) { CommandID = cq.CommandID; CommandRequestID = cq.CommandRequestID; Priority = cq.Priority; CommandDetails = cq.CommandDetails; DateTimeUpdated = cq.DateTimeUpdated; // read xml to get parameters if (CommandDetails.Trim().Length > 0) { XmlDocument docCreator = new XmlDocument(); docCreator.LoadXml(CommandDetails); // populate the fields VideoLocalID = int.Parse(TryGetProperty(docCreator, "CommandRequest_LinkFileManually", "VideoLocalID")); EpisodeID = int.Parse(TryGetProperty(docCreator, "CommandRequest_LinkFileManually", "EpisodeID")); Percentage = int.Parse(TryGetProperty(docCreator, "CommandRequest_LinkFileManually", "Percentage")); vlocal = RepoFactory.VideoLocal.GetByID(VideoLocalID); if (null == vlocal) { logger.Info("videolocal object {0} not found", VideoLocalID); return(false); } episode = RepoFactory.AnimeEpisode.GetByID(EpisodeID); } return(true); }
public override void ProcessCommand() { foreach (int section in ServerSettings.Plex_Libraries) { var allSeries = PlexHelper.GetForUser(_jmmuser).GetPlexSeries(section); foreach (PlexSeries series in allSeries) { foreach (PlexEpisode episode in series.Episodes) { var animeEpisode = episode.AnimeEpisode; var isWatched = episode.WatchCount > 0; var lastWatched = FromUnixTime(episode.LastWatched); SVR_VideoLocal video = animeEpisode?.GetVideoLocals()?.FirstOrDefault(); if (video == null) { continue; } var alreadyWatched = animeEpisode.GetVideoLocals() .Where(x => x.GetAniDBFile() != null) .Any(x => x.GetAniDBFile().IsWatched > 0); if (alreadyWatched && !isWatched) { episode.Scrobble(); } if (isWatched && !alreadyWatched) { video.ToggleWatchedStatus(true, true, lastWatched, true, true, _jmmuser.JMMUserID, true, true); } } } } }
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 override bool InitFromDB(CommandRequest cq) { CommandID = cq.CommandID; CommandRequestID = cq.CommandRequestID; CommandType = cq.CommandType; Priority = cq.Priority; CommandDetails = cq.CommandDetails; DateTimeUpdated = cq.DateTimeUpdated; // read xml to get parameters if (CommandDetails.Trim().Length > 0) { XmlDocument docCreator = new XmlDocument(); docCreator.LoadXml(CommandDetails); // populate the fields Hash = TryGetProperty(docCreator, "CommandRequest_AddFileToMyList", "Hash"); } if (Hash.Trim().Length <= 0) { return(false); } vid = RepoFactory.VideoLocal.GetByHash(Hash); return(true); }
public override bool LoadFromDBCommand(CommandRequest cq) { CommandID = cq.CommandID; CommandRequestID = cq.CommandRequestID; Priority = cq.Priority; CommandDetails = cq.CommandDetails; DateTimeUpdated = cq.DateTimeUpdated; // read xml to get parameters if (CommandDetails.Trim().Length > 0) { XmlDocument docCreator = new XmlDocument(); docCreator.LoadXml(CommandDetails); // populate the fields Hash = TryGetProperty(docCreator, "CommandRequest_AddFileToMyList", "Hash"); string read = TryGetProperty(docCreator, "CommandRequest_AddFileToMyList", "ReadStates"); if (!bool.TryParse(read, out bool read_states)) { read_states = true; } ReadStates = read_states; } if (Hash.Trim().Length <= 0) { return(false); } vid = RepoFactory.VideoLocal.GetByHash(Hash); return(true); }
private static bool CheckSubStreamCount(SVR_VideoLocal file) { int streamCount = file?.Media?.TextStreams.Count ?? -1; if (streamCount == -1) { return(true); } FileQualityFilterOperationType operationType = Settings.RequiredSubStreamCount.Operator; switch (operationType) { case FileQualityFilterOperationType.EQUALS: return(streamCount == Settings.RequiredSubStreamCount.Value); case FileQualityFilterOperationType.GREATER_EQ: return(streamCount >= Settings.RequiredSubStreamCount.Value); case FileQualityFilterOperationType.LESS_EQ: return(streamCount <= Settings.RequiredSubStreamCount.Value); } return(true); }
public override void ProcessCommand() { logger.Trace($"Processing File: {VideoLocalID}"); Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(ServerSettings.Instance.Culture); try { if (vlocal == null) { vlocal = Repo.Instance.VideoLocal.GetByID(VideoLocalID); } if (vlocal == null) { return; } //now that we have all the has info, we can get the AniDB Info ProcessFile_AniDB(vlocal); } catch (Exception ex) { logger.Error($"Error processing CommandRequest_ProcessFile: {VideoLocalID} - {ex}"); } }
public override void ProcessCommand() { logger.Trace("Processing File: {0}", VideoLocalID); Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(ServerSettings.Culture); try { vlocal = RepoFactory.VideoLocal.GetByID(VideoLocalID); if (vlocal == null) { return; } //now that we have all the has info, we can get the AniDB Info ProcessFile_AniDB(vlocal); } catch (Exception ex) { logger.Error("Error processing CommandRequest_ProcessFile: {0} - {1}", VideoLocalID, ex.ToString()); return; } // TODO update stats for group and series // TODO check for TvDB }
private static int CompareSubStreamCountTo(SVR_VideoLocal newFile, SVR_VideoLocal oldFile) { int newStreamCount = newFile.Media.Parts.Where(a => a.Streams.Any(b => b.StreamType == "3")).ToList().Count; int oldStreamCount = oldFile.Media.Parts.Where(a => a.Streams.Any(b => b.StreamType == "3")).ToList().Count; return(oldStreamCount.CompareTo(newStreamCount)); }
public static List <Azure_CrossRef_File_Episode> Get_CrossRefFileEpisode(SVR_VideoLocal vid) { try { if (!ServerSettings.Instance.WebCache.XRefFileEpisode_Get) { return(new List <Azure_CrossRef_File_Episode>()); } string username = Constants.AnonWebCacheUsername; string uri = $@"http://{azureHostBaseAddress}/api/CrossRef_File_Episode/{vid.Hash}?p={username}"; string msg = $"Getting File/Episode Cross Ref From Cache: {vid.Hash}"; DateTime start = DateTime.Now; ShokoService.LogToSystem(Constants.DBLogType.APIAzureHTTP, msg); string json = GetDataJson(uri); TimeSpan ts = DateTime.Now - start; msg = $"Got File/Episode Cross Ref From Cache: {vid.Hash} - {ts.TotalMilliseconds}"; ShokoService.LogToSystem(Constants.DBLogType.APIAzureHTTP, msg); List <Azure_CrossRef_File_Episode> xrefs = JSONHelper.Deserialize <List <Azure_CrossRef_File_Episode> >(json); return(xrefs ?? new List <Azure_CrossRef_File_Episode>()); } catch { return(new List <Azure_CrossRef_File_Episode>()); } }
private static int CompareAudioStreamCountTo(SVR_VideoLocal newFile, SVR_VideoLocal oldFile) { int newStreamCount = newFile.Media?.Parts?.SelectMany(a => a.Streams).Count(a => a.StreamType == "2") ?? 0; int oldStreamCount = oldFile.Media?.Parts?.SelectMany(a => a.Streams).Count(a => a.StreamType == "2") ?? 0; return(oldStreamCount.CompareTo(newStreamCount)); }
public override void Run(IProgress <ICommand> progress = null) { logger.Info("Reading Media Info for File: {0}", VideoLocalID); try { ReportInit(progress); SVR_VideoLocal vlocal = Repo.Instance.VideoLocal.GetByID(VideoLocalID); SVR_VideoLocal_Place place = vlocal?.GetBestVideoLocalPlace(true); ReportUpdate(progress, 50); if (place == null) { ReportError(progress, $"Could not find VideoLocal: {VideoLocalID}"); return; } using (var txn = Repo.Instance.VideoLocal.BeginAddOrUpdate(place.VideoLocalID)) { if (place.RefreshMediaInfo(txn.Entity)) { txn.Commit(); } } ReportFinish(progress); } catch (Exception ex) { ReportError(progress, $"Error processing ServerReadMediaInfo: {VideoLocalID} - {ex}", ex); } }
public static string GetResolution(SVR_VideoLocal videoLocal, SVR_AniDB_File aniFile = null) { if (aniFile == null) { aniFile = videoLocal?.GetAniDBFile(); } return(MediaInfoUtils.GetStandardResolution(GetResolutionInternal(videoLocal, aniFile))); }
public override void ProcessCommand() { logger.Info($"Syncing watched videos for: {_jmmuser.Username}, if nothing happens make sure you have your libraries configured in Shoko."); foreach (var section in PlexHelper.GetForUser(_jmmuser).GetDirectories()) { if (!ServerSettings.Instance.Plex.Libraries.Contains(section.Key)) { continue; } var allSeries = ((SVR_Directory)section).GetShows(); foreach (var series in allSeries) { var episodes = ((SVR_PlexLibrary)series)?.GetEpisodes()?.Where(s => s != null); if (episodes == null) { continue; } foreach (var ep in episodes) { var episode = (SVR_Episode)ep; var animeEpisode = episode.AnimeEpisode; if (animeEpisode == null) { continue; } var userRecord = animeEpisode.GetUserRecord(_jmmuser.JMMUserID); var isWatched = episode.ViewCount != null && episode.ViewCount > 0; var lastWatched = userRecord?.WatchedDate; if (userRecord?.WatchedCount == 0 && isWatched && episode.LastViewedAt != null) { lastWatched = FromUnixTime((long)episode.LastViewedAt); } SVR_VideoLocal video = animeEpisode.GetVideoLocals()?.FirstOrDefault(); if (video == null) { continue; } var alreadyWatched = animeEpisode.GetVideoLocals() .Where(x => x.GetAniDBFile() != null) .Any(x => x.GetAniDBFile().IsWatched > 0); if (alreadyWatched && !isWatched) { episode.Scrobble(); } if (isWatched && !alreadyWatched) { video.ToggleWatchedStatus(true, true, lastWatched, true, _jmmuser.JMMUserID, true, true); } } } } }
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); } }
private void FillMissingHashes(SVR_VideoLocal vlocal) { bool needcrc32 = string.IsNullOrEmpty(vlocal.CRC32); bool needmd5 = string.IsNullOrEmpty(vlocal.MD5); bool needsha1 = string.IsNullOrEmpty(vlocal.SHA1); if (needcrc32 || needmd5 || needsha1) { FillVideoHashes(vlocal); } needcrc32 = string.IsNullOrEmpty(vlocal.CRC32); needmd5 = string.IsNullOrEmpty(vlocal.MD5); needsha1 = string.IsNullOrEmpty(vlocal.SHA1); if (needcrc32 || needmd5 || needsha1) { ShokoService.CmdProcessorHasher.QueueState = PrettyDescriptionHashing; DateTime start = DateTime.Now; List <string> tp = new List <string>(); if (needsha1) { tp.Add("SHA1"); } if (needmd5) { tp.Add("MD5"); } if (needcrc32) { tp.Add("CRC32"); } logger.Trace("Calculating missing {1} hashes for: {0}", FileName, string.Join(",", tp)); // update the VideoLocal record with the Hash, since cloud support we calculate everything Hashes hashes = FileHashHelper.GetHashInfo(FileName.Replace("/", $"{System.IO.Path.DirectorySeparatorChar}"), true, ShokoServer.OnHashProgress, needcrc32, needmd5, needsha1); TimeSpan ts = DateTime.Now - start; logger.Trace("Hashed file in {0:#0.0} seconds --- {1} ({2})", ts.TotalSeconds, FileName, Utils.FormatByteSize(vlocal.FileSize)); if (String.IsNullOrEmpty(vlocal.Hash)) { vlocal.Hash = hashes.ED2K?.ToUpperInvariant(); } if (needsha1) { vlocal.SHA1 = hashes.SHA1?.ToUpperInvariant(); } if (needmd5) { vlocal.MD5 = hashes.MD5?.ToUpperInvariant(); } if (needcrc32) { vlocal.CRC32 = hashes.CRC32?.ToUpperInvariant(); } AzureWebAPI.Send_FileHash(new List <SVR_VideoLocal> { vlocal }); } }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_UpdateMyListFileStatus: {0}", Hash); try { // NOTE - we might return more than one VideoLocal record here, if there are duplicates by hash SVR_VideoLocal vid = RepoFactory.VideoLocal.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) { ShokoService.AnidbProcessor.UpdateMyListFileStatus(xrefs[0].AnimeID, xrefs[0].GetEpisode().EpisodeNumber, this.Watched); logger.Info("Updating file list status (GENERIC): {0} - {1}", vid.ToString(), this.Watched); } else { if (WatchedDateAsSecs > 0) { DateTime?watchedDate = Commons.Utils.AniDB.GetAniDBDateAsDate(WatchedDateAsSecs); ShokoService.AnidbProcessor.UpdateMyListFileStatus(vid, this.Watched, watchedDate); } else { ShokoService.AnidbProcessor.UpdateMyListFileStatus(vid, this.Watched, null); } logger.Info("Updating file list status: {0} - {1}", vid.ToString(), this.Watched); } if (UpdateSeriesStats) { // update watched stats List <SVR_AnimeEpisode> eps = RepoFactory.AnimeEpisode.GetByHash(vid.ED2KHash); if (eps.Count > 0) { // all the eps should belong to the same anime eps[0].GetAnimeSeries().QueueUpdateStats(); //eps[0].AnimeSeries.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, false); } } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_UpdateMyListFileStatus: {0} - {1}", Hash, ex.ToString()); return; } }