Beispiel #1
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);
        }
Beispiel #2
0
        private void SaveWatchedStatus(bool watched, int userID, DateTime?watchedDate, bool updateWatchedDate)
        {
            VideoLocal_User vidUserRecord = GetUserRecord(userID);

            if (watched)
            {
                if (vidUserRecord == null)
                {
                    vidUserRecord = new VideoLocal_User();
                }
                vidUserRecord.WatchedDate  = DateTime.Now;
                vidUserRecord.JMMUserID    = userID;
                vidUserRecord.VideoLocalID = VideoLocalID;

                if (watchedDate.HasValue)
                {
                    if (updateWatchedDate)
                    {
                        vidUserRecord.WatchedDate = watchedDate.Value;
                    }
                }

                RepoFactory.VideoLocalUser.Save(vidUserRecord);
            }
            else
            {
                if (vidUserRecord != null)
                {
                    vidUserRecord.WatchedDate = null;
                    RepoFactory.VideoLocalUser.Save(vidUserRecord);
                }
            }
        }
Beispiel #3
0
 public void Save(VideoLocal_User obj)
 {
     using (var session = JMMService.SessionFactory.OpenSession())
     {
         // populate the database
         using (var transaction = session.BeginTransaction())
         {
             session.SaveOrUpdate(obj);
             transaction.Commit();
         }
     }
 }
Beispiel #4
0
        public VideoLocal_User GetByUserIDAndVideoLocalID(int userid, int vidid)
        {
            using (var session = JMMService.SessionFactory.OpenSession())
            {
                VideoLocal_User obj = session
                                      .CreateCriteria(typeof(VideoLocal_User))
                                      .Add(Restrictions.Eq("JMMUserID", userid))
                                      .Add(Restrictions.Eq("VideoLocalID", vidid))
                                      .UniqueResult <VideoLocal_User>();

                return(obj);
            }
        }
Beispiel #5
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 Intenationalization
                Title                 = Path.GetFileNameWithoutExtension(v.Info),
                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;
            }
            Media m = v.Media;

            if (m?.Duration != 0)
            {
                SVR_VideoLocal_Place pl = v.GetBestVideoLocalPlace();
                if (pl != null)
                {
                    using (var upd = Repo.Instance.VideoLocal.BeginAddOrUpdate(v))
                    {
                        if (pl.RefreshMediaInfo(upd.Entity))
                        {
                            upd.Commit(true);
                        }
                    }
                }
                m = v.Media;
            }
            if (m != null)
            {
                l.Medias.Add(m);
                l.Duration = m.Duration;
            }
            AddLinksToAnimeEpisodeVideo(prov, l, userid);
            return(l);
        }
Beispiel #6
0
        public static Video VideoFromVideoLocal(IProvider prov, SVR_VideoLocal v, int userid)
        {
            Video l = new Video();

            l.AnimeType             = AnimeTypes.AnimeFile.ToString();
            l.Id                    = v.VideoLocalID.ToString();
            l.Type                  = "episode";
            l.Summary               = "Episode Overview Not Available"; //TODO Intenationalization
            l.Title                 = Path.GetFileNameWithoutExtension(v.FileName);
            l.AddedAt               = v.DateTimeCreated.ToUnixTime();
            l.UpdatedAt             = v.DateTimeUpdated.ToUnixTime();
            l.OriginallyAvailableAt = v.DateTimeCreated.ToPlexDate();
            l.Year                  = v.DateTimeCreated.Year.ToString();
            l.Medias                = new List <Media>();
            VideoLocal_User vlr = v.GetUserRecord(userid);

            if (vlr != null)
            {
                if (vlr.WatchedDate.HasValue)
                {
                    l.LastViewedAt = vlr.WatchedDate.Value.ToUnixTime();
                }
                if (vlr.ResumePosition > 0)
                {
                    l.ViewOffset = vlr.ResumePosition.ToString();
                }
            }
            Media m = v.Media;

            if (string.IsNullOrEmpty(m?.Duration))
            {
                SVR_VideoLocal_Place pl = v.GetBestVideoLocalPlace();
                if (pl != null)
                {
                    if (pl.RefreshMediaInfo())
                    {
                        RepoFactory.VideoLocal.Save(v, true);
                    }
                }
                m = v.Media;
            }
            if (m != null)
            {
                l.Medias.Add(m);
                l.Duration = m.Duration;
            }
            AddLinksToAnimeEpisodeVideo(prov, l, userid);
            return(l);
        }
Beispiel #7
0
        public static VideoLocal_User GetVideoLocalUserRecord(this CrossRef_File_Episode cross, int userID)
        {
            SVR_VideoLocal vid = RepoFactory.VideoLocal.GetByHash(cross.Hash);

            if (vid != null)
            {
                VideoLocal_User vidUser = vid.GetUserRecord(userID);
                if (vidUser != null)
                {
                    return(vidUser);
                }
            }

            return(null);
        }
Beispiel #8
0
 public void Delete(int id)
 {
     using (var session = JMMService.SessionFactory.OpenSession())
     {
         // populate the database
         using (var transaction = session.BeginTransaction())
         {
             VideoLocal_User cr = GetByID(id);
             if (cr != null)
             {
                 session.Delete(cr);
                 transaction.Commit();
             }
         }
     }
 }
Beispiel #9
0
        public void SetResumePosition(long resumeposition, int userID)
        {
            VideoLocal_User vuser = GetUserRecord(userID);

            if (vuser == null)
            {
                vuser                = new VideoLocal_User();
                vuser.JMMUserID      = userID;
                vuser.VideoLocalID   = VideoLocalID;
                vuser.ResumePosition = resumeposition;
            }
            else
            {
                vuser.ResumePosition = resumeposition;
            }
            RepoFactory.VideoLocalUser.Save(vuser);
        }
Beispiel #10
0
        public static void AddResumePosition(this Video v, IProvider prov, int userid)
        {
            switch (
                (Shoko.Models.PlexAndKodi.AnimeTypes)
                Enum.Parse(typeof(Shoko.Models.PlexAndKodi.AnimeTypes), v.AnimeType, true))
            {
            case Shoko.Models.PlexAndKodi.AnimeTypes.AnimeEpisode:
                if (v.Medias != null)
                {
                    VideoLocal_User vl = v.Medias.Select(a => RepoFactory.VideoLocal.GetByID(int.Parse(a.Id)))
                                         .Where(a => a != null)
                                         .Select(a => a.GetUserRecord(userid))
                                         .Where(a => a != null)
                                         .OrderByDescending(a => a.ResumePosition)
                                         .FirstOrDefault();
                    if (vl != null && vl.ResumePosition > 0)
                    {
                        v.ViewOffset = vl.ResumePosition.ToString();
                        if (vl.WatchedDate.HasValue)
                        {
                            v.LastViewedAt = vl.WatchedDate.Value.ToUnixTime();
                        }
                    }
                }
                break;

            case Shoko.Models.PlexAndKodi.AnimeTypes.AnimeFile:
                int             vid = int.Parse(v.Id); //This suxx, but adding regeneration at videolocal_user is worst.
                VideoLocal_User vl2 = RepoFactory.VideoLocal.GetByID(vid)?.GetUserRecord(userid);
                if (vl2 != null && vl2.ResumePosition > 0)
                {
                    v.ViewOffset = vl2.ResumePosition.ToString();
                    if (vl2.WatchedDate.HasValue)
                    {
                        v.LastViewedAt = vl2.WatchedDate.Value.ToUnixTime();
                    }
                }
                break;
            }
        }
Beispiel #11
0
        public static void AddResumePosition(this Video v, IProvider prov, int userid)
        {
            switch (
                (AnimeTypes)
                Enum.Parse(typeof(AnimeTypes), v.AnimeType, true))
            {
            case AnimeTypes.AnimeEpisode:
                if (v.Medias != null)
                {
                    VideoLocal_User vl = v.Medias.Select(a => RepoFactory.VideoLocal.GetByID(a.Id))
                                         .Where(a => a != null)
                                         .Select(a => a.GetUserRecord(userid))
                                         .Where(a => a != null)
                                         .OrderByDescending(a => a.ResumePosition)
                                         .FirstOrDefault();
                    if (vl != null && vl.ResumePosition > 0)
                    {
                        v.ViewOffset = vl.ResumePosition;
                        if (vl.WatchedDate.HasValue)
                        {
                            v.LastViewedAt = vl.WatchedDate.Value.ToUnixTime();
                        }
                    }
                }
                break;

            case AnimeTypes.AnimeFile:
                VideoLocal_User vl2 = RepoFactory.VideoLocal.GetByID(v.Id)?.GetUserRecord(userid);
                if (vl2 != null && vl2.ResumePosition > 0)
                {
                    v.ViewOffset = vl2.ResumePosition;
                    if (vl2.WatchedDate.HasValue)
                    {
                        v.LastViewedAt = vl2.WatchedDate.Value.ToUnixTime();
                    }
                }
                break;
            }
        }
Beispiel #12
0
        public CL_VideoLocal ToClient(int userID)
        {
            CL_VideoLocal cl = new CL_VideoLocal
            {
                CRC32           = CRC32,
                DateTimeUpdated = DateTimeUpdated,
                FileName        = FileName,
                FileSize        = FileSize,
                Hash            = Hash,
                HashSource      = HashSource,
                IsIgnored       = IsIgnored,
                IsVariation     = IsVariation,
                Duration        = Duration,
                MD5             = MD5,
                SHA1            = SHA1,
                VideoLocalID    = VideoLocalID,
                Places          = Places.Select(a => a.ToClient()).ToList()
            };
            VideoLocal_User userRecord = GetUserRecord(userID);

            if (userRecord?.WatchedDate == null)
            {
                cl.IsWatched   = 0;
                cl.WatchedDate = null;
            }
            else
            {
                cl.IsWatched   = 1;
                cl.WatchedDate = userRecord.WatchedDate;
            }
            if (userRecord != null)
            {
                cl.ResumePosition = userRecord.ResumePosition;
            }
            cl.Media = GetMediaFromUser(userID);
            return(cl);
        }
Beispiel #13
0
        public CL_VideoLocal ToClient(int userID)
        {
            CL_VideoLocal cl = new CL_VideoLocal();

            cl.CRC32           = this.CRC32;
            cl.DateTimeUpdated = this.DateTimeUpdated;
            cl.FileName        = this.FileName;
            cl.FileSize        = this.FileSize;
            cl.Hash            = this.Hash;
            cl.HashSource      = this.HashSource;
            cl.IsIgnored       = this.IsIgnored;
            cl.IsVariation     = this.IsVariation;
            cl.Duration        = this.Duration;
            cl.MD5             = this.MD5;
            cl.SHA1            = this.SHA1;
            cl.VideoLocalID    = this.VideoLocalID;
            cl.Places          = Places.Select(a => a.ToClient()).ToList();
            VideoLocal_User userRecord = this.GetUserRecord(userID);

            if (userRecord?.WatchedDate == null)
            {
                cl.IsWatched   = 0;
                cl.WatchedDate = null;
            }
            else
            {
                cl.IsWatched   = 1;
                cl.WatchedDate = userRecord.WatchedDate;
            }
            if (userRecord != null)
            {
                cl.ResumePosition = userRecord.ResumePosition;
            }
            cl.Media = GetMediaFromUser(userID);
            return(cl);
        }
Beispiel #14
0
        public CL_VideoLocal_ManualLink ToContractManualLink(int userID)
        {
            CL_VideoLocal_ManualLink cl = new CL_VideoLocal_ManualLink();

            cl.CRC32           = this.CRC32;
            cl.DateTimeUpdated = this.DateTimeUpdated;
            cl.FileName        = this.FileName;
            cl.FileSize        = this.FileSize;
            cl.Hash            = this.Hash;
            cl.HashSource      = this.HashSource;
            cl.IsIgnored       = this.IsIgnored;
            cl.IsVariation     = this.IsVariation;
            cl.MD5             = this.MD5;
            cl.SHA1            = this.SHA1;
            cl.VideoLocalID    = this.VideoLocalID;
            cl.Places          = Places.Select(a => a.ToClient()).ToList();

            VideoLocal_User userRecord = this.GetUserRecord(userID);

            if (userRecord?.WatchedDate == null)
            {
                cl.IsWatched      = 0;
                cl.WatchedDate    = null;
                cl.ResumePosition = 0;
            }
            else
            {
                cl.IsWatched   = userRecord.WatchedDate.HasValue ? 1 : 0;
                cl.WatchedDate = userRecord.WatchedDate;
            }
            if (userRecord != null)
            {
                cl.ResumePosition = userRecord.ResumePosition;
            }
            return(cl);
        }
Beispiel #15
0
        public CL_VideoLocal_ManualLink ToContractManualLink(int userID)
        {
            CL_VideoLocal_ManualLink cl = new CL_VideoLocal_ManualLink
            {
                CRC32           = CRC32,
                DateTimeUpdated = DateTimeUpdated,
                FileName        = FileName,
                FileSize        = FileSize,
                Hash            = Hash,
                HashSource      = HashSource,
                IsIgnored       = IsIgnored,
                IsVariation     = IsVariation,
                MD5             = MD5,
                SHA1            = SHA1,
                VideoLocalID    = VideoLocalID,
                Places          = Places.Select(a => a.ToClient()).ToList()
            };
            VideoLocal_User userRecord = GetUserRecord(userID);

            if (userRecord?.WatchedDate == null)
            {
                cl.IsWatched      = 0;
                cl.WatchedDate    = null;
                cl.ResumePosition = 0;
            }
            else
            {
                cl.IsWatched   = userRecord.WatchedDate.HasValue ? 1 : 0;
                cl.WatchedDate = userRecord.WatchedDate;
            }
            if (userRecord != null)
            {
                cl.ResumePosition = userRecord.ResumePosition;
            }
            return(cl);
        }
Beispiel #16
0
        public void ToggleWatchedStatus(bool watched, bool updateOnline, DateTime?watchedDate, bool updateStats,
                                        bool updateStatsCache, int userID,
                                        bool syncTrakt, bool updateWatchedDate)
        {
            SVR_JMMUser user = RepoFactory.JMMUser.GetByID(userID);

            if (user == null)
            {
                return;
            }

            List <SVR_JMMUser> aniDBUsers = RepoFactory.JMMUser.GetAniDBUsers();

            // update the video file to watched
            int mywatched = watched ? 1 : 0;

            if (user.IsAniDBUser == 0)
            {
                SaveWatchedStatus(watched, userID, watchedDate, updateWatchedDate);
            }
            else
            {
                // if the user is AniDB user we also want to update any other AniDB
                // users to keep them in sync
                foreach (SVR_JMMUser juser in aniDBUsers)
                {
                    if (juser.IsAniDBUser == 1)
                    {
                        SaveWatchedStatus(watched, juser.JMMUserID, watchedDate, updateWatchedDate);
                    }
                }
            }


            // now lets find all the associated AniDB_File record if there is one
            if (user.IsAniDBUser == 1)
            {
                SVR_AniDB_File aniFile = RepoFactory.AniDB_File.GetByHash(Hash);
                if (aniFile != null)
                {
                    aniFile.IsWatched = mywatched;

                    if (watched)
                    {
                        if (watchedDate.HasValue)
                        {
                            aniFile.WatchedDate = watchedDate;
                        }
                        else
                        {
                            aniFile.WatchedDate = DateTime.Now;
                        }
                    }
                    else
                    {
                        aniFile.WatchedDate = null;
                    }


                    RepoFactory.AniDB_File.Save(aniFile, false);
                }

                if (updateOnline)
                {
                    if ((watched && ServerSettings.AniDB_MyList_SetWatched) ||
                        (!watched && ServerSettings.AniDB_MyList_SetUnwatched))
                    {
                        CommandRequest_UpdateMyListFileStatus cmd = new CommandRequest_UpdateMyListFileStatus(
                            Hash, watched, false,
                            watchedDate.HasValue ? AniDB.GetAniDBDateAsSeconds(watchedDate) : 0);
                        cmd.Save();
                    }
                }
            }

            // now find all the episode records associated with this video file
            // but we also need to check if theer are any other files attached to this episode with a watched
            // status,


            SVR_AnimeSeries ser = null;
            // get all files associated with this episode
            List <CrossRef_File_Episode>      xrefs          = RepoFactory.CrossRef_File_Episode.GetByHash(Hash);
            Dictionary <int, SVR_AnimeSeries> toUpdateSeries = new Dictionary <int, SVR_AnimeSeries>();

            if (watched)
            {
                // find the total watched percentage
                // eg one file can have a % = 100
                // or if 2 files make up one episodes they will each have a % = 50

                foreach (CrossRef_File_Episode xref in xrefs)
                {
                    // get the episodes for this file, may be more than one (One Piece x Toriko)
                    SVR_AnimeEpisode ep = RepoFactory.AnimeEpisode.GetByAniDBEpisodeID(xref.EpisodeID);
                    // get all the files for this episode
                    int epPercentWatched = 0;
                    foreach (CrossRef_File_Episode filexref in ep.FileCrossRefs)
                    {
                        VideoLocal_User vidUser = filexref.GetVideoLocalUserRecord(userID);
                        if (vidUser != null && vidUser.WatchedDate.HasValue)
                        {
                            // if not null means it is watched
                            epPercentWatched += filexref.Percentage;
                        }

                        if (epPercentWatched > 95)
                        {
                            break;
                        }
                    }

                    if (epPercentWatched > 95)
                    {
                        ser = ep.GetAnimeSeries();
                        if (!toUpdateSeries.ContainsKey(ser.AnimeSeriesID))
                        {
                            toUpdateSeries.Add(ser.AnimeSeriesID, ser);
                        }
                        if (user.IsAniDBUser == 0)
                        {
                            ep.SaveWatchedStatus(true, userID, watchedDate, updateWatchedDate);
                        }
                        else
                        {
                            // if the user is AniDB user we also want to update any other AniDB
                            // users to keep them in sync
                            foreach (SVR_JMMUser juser in aniDBUsers)
                            {
                                if (juser.IsAniDBUser == 1)
                                {
                                    ep.SaveWatchedStatus(true, juser.JMMUserID, watchedDate, updateWatchedDate);
                                }
                            }
                        }

                        if (syncTrakt && ServerSettings.Trakt_IsEnabled &&
                            !string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken))
                        {
                            CommandRequest_TraktHistoryEpisode cmdSyncTrakt =
                                new CommandRequest_TraktHistoryEpisode(ep.AnimeEpisodeID, TraktSyncAction.Add);
                            cmdSyncTrakt.Save();
                        }

                        if (!string.IsNullOrEmpty(ServerSettings.MAL_Username) &&
                            !string.IsNullOrEmpty(ServerSettings.MAL_Password))
                        {
                            CommandRequest_MALUpdatedWatchedStatus cmdMAL =
                                new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID);
                            cmdMAL.Save();
                        }
                    }
                }
            }
            else
            {
                // if setting a file to unwatched only set the episode unwatched, if ALL the files are unwatched
                foreach (CrossRef_File_Episode xrefEp in xrefs)
                {
                    // get the episodes for this file, may be more than one (One Piece x Toriko)
                    SVR_AnimeEpisode ep = RepoFactory.AnimeEpisode.GetByAniDBEpisodeID(xrefEp.EpisodeID);
                    ser = ep.GetAnimeSeries();
                    if (!toUpdateSeries.ContainsKey(ser.AnimeSeriesID))
                    {
                        toUpdateSeries.Add(ser.AnimeSeriesID, ser);
                    }
                    // get all the files for this episode
                    int epPercentWatched = 0;
                    foreach (CrossRef_File_Episode filexref in ep.FileCrossRefs)
                    {
                        VideoLocal_User vidUser = filexref.GetVideoLocalUserRecord(userID);
                        if (vidUser != null && vidUser.WatchedDate.HasValue)
                        {
                            epPercentWatched += filexref.Percentage;
                        }

                        if (epPercentWatched > 95)
                        {
                            break;
                        }
                    }

                    if (epPercentWatched < 95)
                    {
                        if (user.IsAniDBUser == 0)
                        {
                            ep.SaveWatchedStatus(false, userID, watchedDate, true);
                        }
                        else
                        {
                            // if the user is AniDB user we also want to update any other AniDB
                            // users to keep them in sync
                            foreach (SVR_JMMUser juser in aniDBUsers)
                            {
                                if (juser.IsAniDBUser == 1)
                                {
                                    ep.SaveWatchedStatus(false, juser.JMMUserID, watchedDate, true);
                                }
                            }
                        }

                        if (syncTrakt && ServerSettings.Trakt_IsEnabled &&
                            !string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken))
                        {
                            CommandRequest_TraktHistoryEpisode cmdSyncTrakt =
                                new CommandRequest_TraktHistoryEpisode(ep.AnimeEpisodeID, TraktSyncAction.Remove);
                            cmdSyncTrakt.Save();
                        }
                    }
                }
                if (!string.IsNullOrEmpty(ServerSettings.MAL_Username) &&
                    !string.IsNullOrEmpty(ServerSettings.MAL_Password))
                {
                    CommandRequest_MALUpdatedWatchedStatus cmdMAL =
                        new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID);
                    cmdMAL.Save();
                }
            }


            // update stats for groups and series
            if (toUpdateSeries.Count > 0 && updateStats)
            {
                foreach (SVR_AnimeSeries s in toUpdateSeries.Values)
                {
                    // update all the groups above this series in the heirarchy
                    s.UpdateStats(true, true, true);
                }
                //ser.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true);
            }

            //if (ser != null && updateStatsCache)
            //StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID);
        }
Beispiel #17
0
        public RawFile(NancyContext ctx, SVR_VideoLocal vl, int level, int uid)
        {
            if (vl != null)
            {
                id = vl.VideoLocalID;

                crc32    = vl.CRC32;
                ed2khash = vl.ED2KHash;
                md5      = vl.MD5;
                sha1     = vl.SHA1;

                created  = vl.DateTimeCreated;
                updated  = vl.DateTimeUpdated;
                duration = vl.Duration;

                if (vl.ReleaseGroup != null)
                {
                    group_full  = vl.ReleaseGroup.GroupName;
                    group_short = vl.ReleaseGroup.GroupNameShort;
                    group_id    = vl.ReleaseGroup.AniDB_ReleaseGroupID;
                }

                size        = vl.FileSize;
                hash        = vl.Hash;
                hash_source = vl.HashSource;

                is_ignored = vl.IsIgnored;
                VideoLocal_User vl_user = vl.GetUserRecord(uid);
                if (vl_user != null)
                {
                    offset = vl_user.ResumePosition;
                }
                else
                {
                    offset = 0;
                }

                VideoLocal_Place place = vl.GetBestVideoLocalPlace();
                if (place != null)
                {
                    filename            = place.FilePath;
                    videolocal_place_id = place.VideoLocal_Place_ID;
                    import_folder_id    = place.ImportFolderID;
                }

                if (vl.EpisodeCrossRefs.Count == 0)
                {
                    recognized = false;
                }
                else
                {
                    recognized = true;
                }

                if (vl.Media != null && (level > 1 || level == 0))
                {
                    media = new MediaInfo();

                    url = APIHelper.ConstructVideoLocalStream(ctx, uid, vl.Media.Id, "file." + vl.Media.Container, false);

                    MediaInfo new_media = new MediaInfo();

                    new_media.AddGeneral(MediaInfo.General.format, vl.Media.Container);
                    new_media.AddGeneral(MediaInfo.General.duration, vl.Media.Duration);
                    new_media.AddGeneral(MediaInfo.General.id, vl.Media.Id);
                    new_media.AddGeneral(MediaInfo.General.overallbitrate, vl.Media.Bitrate);

                    if (vl.Media.Parts != null)
                    {
                        new_media.AddGeneral(MediaInfo.General.size, vl.Media.Parts[0].Size);

                        foreach (Shoko.Models.PlexAndKodi.Stream p in vl.Media.Parts[0].Streams)
                        {
                            switch (p.StreamType)
                            {
                            //video
                            case "1":
                                new_media.AddVideo(p);
                                break;

                            //audio
                            case "2":
                                new_media.AddAudio(p);
                                break;

                            //subtitle
                            case "3":
                                new_media.AddSubtitle(p);
                                break;

                            //menu
                            case "4":
                                Dictionary <string, string> mdict = new Dictionary <string, string>();
                                //TODO APIv2: menu object could be usefull for external players
                                new_media.AddMenu(mdict);
                                break;
                            }
                        }
                    }

                    media = new_media;
                }
            }
        }
Beispiel #18
0
        public CL_VideoDetailed ToClientDetailed(int userID)
        {
            CL_VideoDetailed cl = new CL_VideoDetailed();

            // get the cross ref episode
            List <CrossRef_File_Episode> xrefs = EpisodeCrossRefs;

            if (xrefs.Count == 0)
            {
                return(null);
            }

            cl.Percentage     = xrefs[0].Percentage;
            cl.EpisodeOrder   = xrefs[0].EpisodeOrder;
            cl.CrossRefSource = xrefs[0].CrossRefSource;
            cl.AnimeEpisodeID = xrefs[0].EpisodeID;

            cl.VideoLocal_FileName    = FileName;
            cl.VideoLocal_Hash        = Hash;
            cl.VideoLocal_FileSize    = FileSize;
            cl.VideoLocalID           = VideoLocalID;
            cl.VideoLocal_IsIgnored   = IsIgnored;
            cl.VideoLocal_IsVariation = IsVariation;
            cl.Places = Places.Select(a => a.ToClient()).ToList();

            cl.VideoLocal_MD5        = MD5;
            cl.VideoLocal_SHA1       = SHA1;
            cl.VideoLocal_CRC32      = CRC32;
            cl.VideoLocal_HashSource = HashSource;

            VideoLocal_User userRecord = GetUserRecord(userID);

            if (userRecord?.WatchedDate == null)
            {
                cl.VideoLocal_IsWatched      = 0;
                cl.VideoLocal_WatchedDate    = null;
                cl.VideoLocal_ResumePosition = 0;
            }
            else
            {
                cl.VideoLocal_IsWatched   = userRecord.WatchedDate.HasValue ? 1 : 0;
                cl.VideoLocal_WatchedDate = userRecord.WatchedDate;
            }
            if (userRecord != null)
            {
                cl.VideoLocal_ResumePosition = userRecord.ResumePosition;
            }
            cl.VideoInfo_AudioBitrate    = AudioBitrate;
            cl.VideoInfo_AudioCodec      = AudioCodec;
            cl.VideoInfo_Duration        = Duration;
            cl.VideoInfo_VideoBitrate    = VideoBitrate;
            cl.VideoInfo_VideoBitDepth   = VideoBitDepth;
            cl.VideoInfo_VideoCodec      = VideoCodec;
            cl.VideoInfo_VideoFrameRate  = VideoFrameRate;
            cl.VideoInfo_VideoResolution = VideoResolution;

            // AniDB File
            SVR_AniDB_File anifile = GetAniDBFile(); // to prevent multiple db calls

            if (anifile != null)
            {
                cl.AniDB_Anime_GroupName      = anifile.Anime_GroupName;
                cl.AniDB_Anime_GroupNameShort = anifile.Anime_GroupNameShort;
                cl.AniDB_AnimeID              = anifile.AnimeID;
                cl.AniDB_CRC                  = anifile.CRC;
                cl.AniDB_Episode_Rating       = anifile.Episode_Rating;
                cl.AniDB_Episode_Votes        = anifile.Episode_Votes;
                cl.AniDB_File_AudioCodec      = anifile.File_AudioCodec;
                cl.AniDB_File_Description     = anifile.File_Description;
                cl.AniDB_File_FileExtension   = anifile.File_FileExtension;
                cl.AniDB_File_LengthSeconds   = anifile.File_LengthSeconds;
                cl.AniDB_File_ReleaseDate     = anifile.File_ReleaseDate;
                cl.AniDB_File_Source          = anifile.File_Source;
                cl.AniDB_File_VideoCodec      = anifile.File_VideoCodec;
                cl.AniDB_File_VideoResolution = anifile.File_VideoResolution;
                cl.AniDB_FileID               = anifile.FileID;
                cl.AniDB_GroupID              = anifile.GroupID;
                cl.AniDB_MD5                  = anifile.MD5;
                cl.AniDB_SHA1                 = anifile.SHA1;
                cl.AniDB_File_FileVersion     = anifile.FileVersion;
                cl.AniDB_File_IsCensored      = anifile.IsCensored;
                cl.AniDB_File_IsChaptered     = anifile.IsChaptered;
                cl.AniDB_File_IsDeprecated    = anifile.IsDeprecated;
                cl.AniDB_File_InternalVersion = anifile.InternalVersion;

                // languages
                cl.LanguagesAudio    = anifile.LanguagesRAW;
                cl.LanguagesSubtitle = anifile.SubtitlesRAW;
            }
            else
            {
                cl.AniDB_Anime_GroupName      = string.Empty;
                cl.AniDB_Anime_GroupNameShort = string.Empty;
                cl.AniDB_CRC                  = string.Empty;
                cl.AniDB_File_AudioCodec      = string.Empty;
                cl.AniDB_File_Description     = string.Empty;
                cl.AniDB_File_FileExtension   = string.Empty;
                cl.AniDB_File_Source          = string.Empty;
                cl.AniDB_File_VideoCodec      = string.Empty;
                cl.AniDB_File_VideoResolution = string.Empty;
                cl.AniDB_MD5                  = string.Empty;
                cl.AniDB_SHA1                 = string.Empty;
                cl.AniDB_File_FileVersion     = 1;

                // languages
                cl.LanguagesAudio    = string.Empty;
                cl.LanguagesSubtitle = string.Empty;
            }


            AniDB_ReleaseGroup relGroup = ReleaseGroup; // to prevent multiple db calls

            if (relGroup != null)
            {
                cl.ReleaseGroup = relGroup;
            }
            else
            {
                cl.ReleaseGroup = null;
            }
            cl.Media = GetMediaFromUser(userID);
            return(cl);
        }
Beispiel #19
0
        public override void ProcessCommand()
        {
            logger.Info("Processing CommandRequest_SyncMyList");

            try
            {
                // we will always assume that an anime was downloaded via http first
                ScheduledUpdateRepository repSched     = new ScheduledUpdateRepository();
                AniDB_FileRepository      repAniFile   = new AniDB_FileRepository();
                VideoLocalRepository      repVidLocals = new VideoLocalRepository();

                ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBMyListSync);
                if (sched == null)
                {
                    sched               = new ScheduledUpdate();
                    sched.UpdateType    = (int)ScheduledUpdateType.AniDBMyListSync;
                    sched.UpdateDetails = "";
                }
                else
                {
                    int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_MyList_UpdateFrequency);

                    // if we have run this in the last 24 hours and are not forcing it, then exit
                    TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate;
                    if (tsLastRun.TotalHours < freqHours)
                    {
                        if (!ForceRefresh)
                        {
                            return;
                        }
                    }
                }

                AniDBHTTPCommand_GetMyList cmd = new AniDBHTTPCommand_GetMyList();
                cmd.Init(ServerSettings.AniDB_Username, ServerSettings.AniDB_Password);
                enHelperActivityType ev = cmd.Process();
                if (ev == enHelperActivityType.GotMyListHTTP && cmd.MyListItems.Count > 1)
                {
                    int    totalItems    = 0;
                    int    watchedItems  = 0;
                    int    modifiedItems = 0;
                    double pct           = 0;

                    // 2. find files locally for the user, which are not recorded on anidb
                    //    and then add them to anidb
                    Dictionary <int, Raw_AniDB_MyListFile> onlineFiles = new Dictionary <int, Raw_AniDB_MyListFile>();
                    foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems)
                    {
                        onlineFiles[myitem.FileID] = myitem;
                    }

                    Dictionary <string, AniDB_File> dictAniFiles = new Dictionary <string, AniDB_File>();
                    List <AniDB_File> allAniFiles = repAniFile.GetAll();
                    foreach (AniDB_File anifile in allAniFiles)
                    {
                        dictAniFiles[anifile.Hash] = anifile;
                    }

                    int missingFiles = 0;
                    foreach (VideoLocal vid in repVidLocals.GetAll())
                    {
                        if (!dictAniFiles.ContainsKey(vid.Hash))
                        {
                            continue;
                        }

                        int fileID = dictAniFiles[vid.Hash].FileID;

                        if (!onlineFiles.ContainsKey(fileID))
                        {
                            // means we have found a file in our local collection, which is not recorded online
                            CommandRequest_AddFileToMyList cmdAddFile = new CommandRequest_AddFileToMyList(vid.Hash);
                            cmdAddFile.Save();
                            missingFiles++;
                        }
                    }
                    logger.Info(string.Format("MYLIST Missing Files: {0} Added to queue for inclusion", missingFiles));

                    JMMUserRepository repUsers   = new JMMUserRepository();
                    List <JMMUser>    aniDBUsers = repUsers.GetAniDBUsers();

                    VideoLocal_UserRepository       repVidUsers = new VideoLocal_UserRepository();
                    CrossRef_File_EpisodeRepository repFileEp   = new CrossRef_File_EpisodeRepository();

                    // 1 . sync mylist items
                    foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems)
                    {
                        // ignore files mark as deleted by the user
                        if (myitem.State == (int)AniDBFileStatus.Deleted)
                        {
                            continue;
                        }

                        totalItems++;
                        if (myitem.IsWatched)
                        {
                            watchedItems++;
                        }

                        //calculate percentage
                        pct = (double)totalItems / (double)cmd.MyListItems.Count * (double)100;
                        string spct = pct.ToString("#0.0");

                        string hash = string.Empty;

                        AniDB_File anifile = repAniFile.GetByFileID(myitem.FileID);
                        if (anifile != null)
                        {
                            hash = anifile.Hash;
                        }
                        else
                        {
                            // look for manually linked files
                            List <CrossRef_File_Episode> xrefs = repFileEp.GetByEpisodeID(myitem.EpisodeID);
                            foreach (CrossRef_File_Episode xref in xrefs)
                            {
                                if (xref.CrossRefSource != (int)CrossRefSource.AniDB)
                                {
                                    hash = xref.Hash;
                                    break;
                                }
                            }
                        }


                        if (!string.IsNullOrEmpty(hash))
                        {
                            // find the video associated with this record
                            VideoLocal vl = repVidLocals.GetByHash(hash);
                            if (vl == null)
                            {
                                continue;
                            }

                            foreach (JMMUser juser in aniDBUsers)
                            {
                                bool localStatus = false;
                                int? jmmUserID   = null;

                                // doesn't matter which anidb user we use
                                jmmUserID = juser.JMMUserID;
                                VideoLocal_User userRecord = vl.GetUserRecord(juser.JMMUserID);
                                if (userRecord != null)
                                {
                                    localStatus = true;
                                }

                                string action = "";
                                if (localStatus != myitem.IsWatched)
                                {
                                    if (localStatus == true)
                                    {
                                        // local = watched, anidb = unwatched
                                        if (ServerSettings.AniDB_MyList_ReadUnwatched)
                                        {
                                            modifiedItems++;
                                            if (jmmUserID.HasValue)
                                            {
                                                vl.ToggleWatchedStatus(myitem.IsWatched, false, myitem.WatchedDate,
                                                                       false, false, jmmUserID.Value, false,
                                                                       true);
                                            }
                                            action = "Used AniDB Status";
                                        }
                                    }
                                    else
                                    {
                                        // means local is un-watched, and anidb is watched
                                        if (ServerSettings.AniDB_MyList_ReadWatched)
                                        {
                                            modifiedItems++;
                                            if (jmmUserID.HasValue)
                                            {
                                                vl.ToggleWatchedStatus(true, false, myitem.WatchedDate, false, false,
                                                                       jmmUserID.Value, false, true);
                                            }
                                            action = "Updated Local record to Watched";
                                        }
                                    }

                                    string msg =
                                        string.Format(
                                            "MYLISTDIFF:: File {0} - Local Status = {1}, AniDB Status = {2} --- {3}",
                                            vl.FullServerPath, localStatus, myitem.IsWatched, action);
                                    logger.Info(msg);
                                }
                            }


                            //string msg = string.Format("MYLIST:: File {0} - Local Status = {1}, AniDB Status = {2} --- {3}",
                            //	vl.FullServerPath, localStatus, myitem.IsWatched, action);
                            //logger.Info(msg);
                        }
                    }


                    // now update all stats
                    Importer.UpdateAllStats();

                    logger.Info("Process MyList: {0} Items, {1} Watched, {2} Modified", totalItems, watchedItems,
                                modifiedItems);

                    sched.LastUpdate = DateTime.Now;
                    repSched.Save(sched);
                }
            }
            catch (Exception ex)
            {
                logger.Error("Error processing CommandRequest_SyncMyList: {0} ", ex.ToString());
                return;
            }
        }
        public override void ProcessCommand()
        {
            logger.Info("Processing CommandRequest_SyncMyList");

            try
            {
                // we will always assume that an anime was downloaded via http first
                ScheduledUpdate sched =
                    RepoFactory.ScheduledUpdate.GetByUpdateType((int)ScheduledUpdateType.AniDBMyListSync);
                if (sched == null)
                {
                    sched = new ScheduledUpdate
                    {
                        UpdateType    = (int)ScheduledUpdateType.AniDBMyListSync,
                        UpdateDetails = string.Empty
                    };
                }
                else
                {
                    int freqHours = Utils.GetScheduledHours(ServerSettings.Instance.AniDb.MyList_UpdateFrequency);

                    // if we have run this in the last 24 hours and are not forcing it, then exit
                    TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate;
                    if (tsLastRun.TotalHours < freqHours)
                    {
                        if (!ForceRefresh)
                        {
                            return;
                        }
                    }
                }

                // Get the list from AniDB
                AniDBHTTPCommand_GetMyList cmd = new AniDBHTTPCommand_GetMyList();
                cmd.Init(ServerSettings.Instance.AniDb.Username, ServerSettings.Instance.AniDb.Password);
                AniDBUDPResponseCode ev = cmd.Process();
                if (ev != AniDBUDPResponseCode.GotMyListHTTP)
                {
                    logger.Warn("AniDB did not return a successful code: " + ev);
                    return;
                }

                int totalItems    = 0;
                int watchedItems  = 0;
                int modifiedItems = 0;

                // Add missing files on AniDB
                var onlineFiles  = cmd.MyListItems.ToLookup(a => a.FileID);
                var dictAniFiles = RepoFactory.AniDB_File.GetAll().ToLookup(a => a.Hash);

                int missingFiles = 0;
                foreach (SVR_VideoLocal vid in RepoFactory.VideoLocal.GetAll()
                         .Where(a => !string.IsNullOrEmpty(a.Hash)).ToList())
                {
                    // Does it have a linked AniFile
                    if (!dictAniFiles.Contains(vid.Hash))
                    {
                        continue;
                    }

                    int fileID = dictAniFiles[vid.Hash].FirstOrDefault()?.FileID ?? 0;
                    if (fileID == 0)
                    {
                        continue;
                    }
                    // Is it in MyList
                    if (onlineFiles.Contains(fileID))
                    {
                        Raw_AniDB_MyListFile file = onlineFiles[fileID].FirstOrDefault(a => a != null);

                        if (file != null)
                        {
                            if (vid.MyListID == 0)
                            {
                                vid.MyListID = file.ListID;
                                RepoFactory.VideoLocal.Save(vid);
                            }

                            // Update file state if deleted
                            if (file.State != (int)ServerSettings.Instance.AniDb.MyList_StorageState)
                            {
                                int seconds = Commons.Utils.AniDB.GetAniDBDateAsSeconds(file.WatchedDate);
                                CommandRequest_UpdateMyListFileStatus cmdUpdateFile =
                                    new CommandRequest_UpdateMyListFileStatus(vid.Hash, file.WatchedDate.HasValue,
                                                                              false,
                                                                              seconds);
                                cmdUpdateFile.Save();
                            }

                            continue;
                        }
                    }

                    // means we have found a file in our local collection, which is not recorded online
                    if (ServerSettings.Instance.AniDb.MyList_AddFiles)
                    {
                        CommandRequest_AddFileToMyList cmdAddFile = new CommandRequest_AddFileToMyList(vid.Hash);
                        cmdAddFile.Save();
                    }
                    missingFiles++;
                }
                logger.Info($"MYLIST Missing Files: {missingFiles} Added to queue for inclusion");

                List <SVR_JMMUser> aniDBUsers = RepoFactory.JMMUser.GetAniDBUsers();
                LinkedHashSet <SVR_AnimeSeries> modifiedSeries = new LinkedHashSet <SVR_AnimeSeries>();

                // Remove Missing Files and update watched states (single loop)
                List <int> filesToRemove = new List <int>();
                foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems)
                {
                    try
                    {
                        totalItems++;
                        if (myitem.IsWatched)
                        {
                            watchedItems++;
                        }

                        string hash = string.Empty;

                        SVR_AniDB_File anifile = RepoFactory.AniDB_File.GetByFileID(myitem.FileID);
                        if (anifile != null)
                        {
                            hash = anifile.Hash;
                        }
                        else
                        {
                            // look for manually linked files
                            List <CrossRef_File_Episode> xrefs =
                                RepoFactory.CrossRef_File_Episode.GetByEpisodeID(myitem.EpisodeID);
                            foreach (CrossRef_File_Episode xref in xrefs)
                            {
                                if (xref.CrossRefSource == (int)CrossRefSource.AniDB)
                                {
                                    continue;
                                }
                                hash = xref.Hash;
                                break;
                            }
                        }

                        // We couldn't evem find a hash, so remove it
                        if (string.IsNullOrEmpty(hash))
                        {
                            filesToRemove.Add(myitem.ListID);
                            continue;
                        }

                        // If there's no video local, we don't have it
                        SVR_VideoLocal vl = RepoFactory.VideoLocal.GetByHash(hash);
                        if (vl == null)
                        {
                            filesToRemove.Add(myitem.ListID);
                            continue;
                        }

                        foreach (SVR_JMMUser juser in aniDBUsers)
                        {
                            bool localStatus = false;

                            // doesn't matter which anidb user we use
                            int             jmmUserID  = juser.JMMUserID;
                            VideoLocal_User userRecord = vl.GetUserRecord(juser.JMMUserID);
                            if (userRecord != null)
                            {
                                localStatus = userRecord.WatchedDate.HasValue;
                            }

                            string action = string.Empty;
                            if (localStatus == myitem.IsWatched)
                            {
                                continue;
                            }

                            // localStatus and AniDB Status are different
                            DateTime?watchedDate = myitem.WatchedDate ?? DateTime.Now;
                            if (localStatus)
                            {
                                // local = watched, anidb = unwatched
                                if (ServerSettings.Instance.AniDb.MyList_ReadUnwatched)
                                {
                                    modifiedItems++;
                                    vl.ToggleWatchedStatus(false, false, watchedDate,
                                                           false, jmmUserID, false,
                                                           true);
                                    action = "Used AniDB Status";
                                }
                                else if (ServerSettings.Instance.AniDb.MyList_SetWatched)
                                {
                                    vl.ToggleWatchedStatus(true, true, userRecord.WatchedDate, false, jmmUserID,
                                                           false, true);
                                }
                            }
                            else
                            {
                                // means local is un-watched, and anidb is watched
                                if (ServerSettings.Instance.AniDb.MyList_ReadWatched)
                                {
                                    modifiedItems++;
                                    vl.ToggleWatchedStatus(true, false, watchedDate, false,
                                                           jmmUserID, false, true);
                                    action = "Updated Local record to Watched";
                                }
                                else if (ServerSettings.Instance.AniDb.MyList_SetUnwatched)
                                {
                                    vl.ToggleWatchedStatus(false, true, watchedDate, false, jmmUserID,
                                                           false, true);
                                }
                            }

                            vl.GetAnimeEpisodes().Select(a => a.GetAnimeSeries()).Where(a => a != null)
                            .DistinctBy(a => a.AnimeSeriesID).ForEach(a => modifiedSeries.Add(a));
                            logger.Info(
                                $"MYLISTDIFF:: File {vl.FileName} - Local Status = {localStatus}, AniDB Status = {myitem.IsWatched} --- {action}");
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error($"A MyList Item threw an error while syncing: {ex}");
                    }
                }

                // Actually remove the files
                if (filesToRemove.Count > 0)
                {
                    foreach (int listID in filesToRemove)
                    {
                        CommandRequest_DeleteFileFromMyList deleteCommand =
                            new CommandRequest_DeleteFileFromMyList(listID);
                        deleteCommand.Save();
                    }
                    logger.Info($"MYLIST Missing Files: {filesToRemove.Count} Added to queue for deletion");
                }

                modifiedSeries.ForEach(a => a.QueueUpdateStats());

                logger.Info($"Process MyList: {totalItems} Items, {missingFiles} Added, {filesToRemove.Count} Deleted, {watchedItems} Watched, {modifiedItems} Modified");

                sched.LastUpdate = DateTime.Now;
                RepoFactory.ScheduledUpdate.Save(sched);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Error processing CommandRequest_SyncMyList: {0} ", ex);
            }
        }