示例#1
0
        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));
        }
示例#2
0
        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));
        }
示例#3
0
        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);
        }
示例#4
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);
        }
示例#5
0
        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;
            }
        }
示例#6
0
        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());
        }
示例#7
0
        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}");
            }
        }
示例#8
0
        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));
        }
示例#9
0
 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);
     }
 }
示例#10
0
        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);
            }
        }
示例#12
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#19
0
        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}");
            }
        }
示例#21
0
        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
        }
示例#22
0
        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));
        }
示例#23
0
        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>());
            }
        }
示例#24
0
        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));
        }
示例#25
0
        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);
            }
        }
示例#26
0
 public static string GetResolution(SVR_VideoLocal videoLocal, SVR_AniDB_File aniFile = null)
 {
     if (aniFile == null)
     {
         aniFile = videoLocal?.GetAniDBFile();
     }
     return(MediaInfoUtils.GetStandardResolution(GetResolutionInternal(videoLocal, aniFile)));
 }
示例#27
0
        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);
                        }
                    }
                }
            }
        }
示例#28
0
        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;
            }
        }