private System.IO.Stream InternalGetFile(int userid, string Id)
        {
            int id;

            if (!int.TryParse(Id, out id))
            {
                return(new MemoryStream());
            }
            KodiObject ret = new KodiObject(KodiHelper.NewMediaContainer("Unsort", true));

            if (!ret.Init())
            {
                return(new MemoryStream());
            }
            List <Video> dirs = new List <Video>();
            Video        v    = new Video();

            dirs.Add(v);
            VideoLocalRepository repVids = new VideoLocalRepository();
            VideoLocal           vi      = repVids.GetByID(id);

            if (vi == null)
            {
                return(new MemoryStream());
            }
            KodiHelper.PopulateVideo(v, vi, JMMType.File, userid);
            ret.Childrens          = dirs;
            ret.MediaContainer.Art = v.Art;
            return(ret.GetStream());
        }
        public override void ProcessCommand()
        {
            logger.Info("Processing CommandRequest_UpdateMyListFileStatus: {0}", Hash);


            try
            {
                VideoLocalRepository   repVids     = new VideoLocalRepository();
                AnimeEpisodeRepository repEpisodes = new AnimeEpisodeRepository();

                // NOTE - we might return more than one VideoLocal record here, if there are duplicates by hash
                VideoLocal vid = repVids.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)
                    {
                        JMMService.AnidbProcessor.UpdateMyListFileStatus(xrefs[0].AnimeID,
                                                                         xrefs[0].Episode.EpisodeNumber, this.Watched);
                        logger.Info("Updating file list status (GENERIC): {0} - {1}", vid.ToString(), this.Watched);
                    }
                    else
                    {
                        if (WatchedDateAsSecs > 0)
                        {
                            DateTime?watchedDate = Utils.GetAniDBDateAsDate(WatchedDateAsSecs);
                            JMMService.AnidbProcessor.UpdateMyListFileStatus(vid, this.Watched, watchedDate);
                        }
                        else
                        {
                            JMMService.AnidbProcessor.UpdateMyListFileStatus(vid, this.Watched, null);
                        }
                        logger.Info("Updating file list status: {0} - {1}", vid.ToString(), this.Watched);
                    }

                    if (UpdateSeriesStats)
                    {
                        // update watched stats
                        List <AnimeEpisode> eps = repEpisodes.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;
            }
        }
        private System.IO.Stream GetUnsort(int userid, HistoryInfo info)
        {
            PlexObject ret = new PlexObject(PlexHelper.NewMediaContainer(MediaContainerTypes.Video, info, true));

            if (!ret.Init())
            {
                return(new MemoryStream());
            }
            List <Video>         dirs    = new List <Video>();
            VideoLocalRepository repVids = new VideoLocalRepository();
            List <VideoLocal>    vids    = repVids.GetVideosWithoutEpisode();

            foreach (VideoLocal v in vids.OrderByDescending(a => a.DateTimeCreated))
            {
                Video m = new Video();
                try
                {
                    PlexHelper.PopulateVideo(m, v, JMMType.File, userid);
                    m.GrandparentKey = null;
                    if (!string.IsNullOrEmpty(m.Duration))
                    {
                        dirs.Add(m, info);
                    }
                }
                catch (Exception e)
                {
                    //Fast fix if file do not exist, and still is in db. (Xml Serialization of video info will fail on null)
                }
            }
            ret.Childrens = dirs;
            return(ret.GetStream());
        }
        private System.IO.Stream GetUnsort(int userid)
        {
            KodiObject ret = new KodiObject(KodiHelper.NewMediaContainer("Unsort", true));

            if (!ret.Init())
            {
                return(new MemoryStream());
            }
            List <Video> dirs = new List <Video>();

            ret.MediaContainer.ViewMode  = "65586";
            ret.MediaContainer.ViewGroup = "video";
            VideoLocalRepository repVids = new VideoLocalRepository();
            List <VideoLocal>    vids    = repVids.GetVideosWithoutEpisode();

            foreach (VideoLocal v in vids.OrderByDescending(a => a.DateTimeCreated))
            {
                Video m = new Video();
                try
                {
                    KodiHelper.PopulateVideo(m, v, JMMType.File, userid);
                    if (!string.IsNullOrEmpty(m.Duration))
                    {
                        dirs.Add(m);
                    }
                }
                catch (Exception e)
                {
                    //Fast fix if file do not exist, and still is in db. (Xml Serialization of video info will fail on null)
                }
            }
            ret.Childrens = dirs;
            return(ret.GetStream());
        }
Exemplo n.º 5
0
        public override void ProcessCommand()
        {
            logger.Info("Processing File: {0}", VideoLocalID);


            try
            {
                VideoLocalRepository repVids = new VideoLocalRepository();
                vlocal = repVids.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
        }
Exemplo n.º 6
0
        public static Video VideoFromVideoLocal(IProvider prov, VideoLocal v, int userid)
        {
            Video l = new Video();

            l.AnimeType             = JMMContracts.PlexAndKodi.AnimeTypes.AnimeFile.ToString();
            l.Id                    = v.VideoLocalID.ToString();
            l.Type                  = "episode";
            l.Summary               = "Episode Overview Not Available"; //TODO Intenationalization
            l.Title                 = Path.GetFileNameWithoutExtension(v.FilePath);
            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>();
            Media m = v.Media;

            if (m == null)
            {
                VideoLocalRepository lrepo = new VideoLocalRepository();
                lrepo.Save(v, true);
                m = v.Media;
            }
            if (m != null)
            {
                l.Medias.Add(m);
                l.Duration = m.Duration;
            }
            AddLinksToAnimeEpisodeVideo(prov, l, userid);
            return(l);
        }
Exemplo n.º 7
0
		public static string DeleteImportFolder(int importFolderID)
		{
			try
			{
				ImportFolderRepository repNS = new ImportFolderRepository();
				ImportFolder ns = repNS.GetByID(importFolderID);

				if (ns == null) return "Could not find Import Folder ID: " + importFolderID;

				// first delete all the files attached  to this import folder
				Dictionary<int, AnimeSeries> affectedSeries = new Dictionary<int, AnimeSeries>();

				VideoLocalRepository repVids = new VideoLocalRepository();
				foreach (VideoLocal vid in repVids.GetByImportFolder(importFolderID))
				{
					//Thread.Sleep(5000);
					logger.Info("Deleting video local record: {0}", vid.FullServerPath);

					AnimeSeries ser = null;
					List<AnimeEpisode> animeEpisodes = vid.GetAnimeEpisodes();
					if (animeEpisodes.Count > 0)
					{
						ser = animeEpisodes[0].GetAnimeSeries();
						if (ser != null && !affectedSeries.ContainsKey(ser.AnimeSeriesID))
							affectedSeries.Add(ser.AnimeSeriesID, ser);
					}

					repVids.Delete(vid.VideoLocalID);
				}

				// delete any duplicate file records which reference this folder
				DuplicateFileRepository repDupFiles = new DuplicateFileRepository();
				foreach (DuplicateFile df in repDupFiles.GetByImportFolder1(importFolderID))
					repDupFiles.Delete(df.DuplicateFileID);

				foreach (DuplicateFile df in repDupFiles.GetByImportFolder2(importFolderID))
					repDupFiles.Delete(df.DuplicateFileID);

				// delete the import folder
				repNS.Delete(importFolderID);
				ServerInfo.Instance.RefreshImportFolders();

				foreach (AnimeSeries ser in affectedSeries.Values)
				{
					ser.QueueUpdateStats();
					//StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID);
				}

				

				return "";
			}
			catch (Exception ex)
			{
				logger.ErrorException(ex.ToString(), ex);
				return ex.Message;
			}
		}
Exemplo n.º 8
0
        public void RenameFile(string renameScript)
        {
            string renamed = RenameFileHelper.GetNewFileName(this, renameScript);

            if (string.IsNullOrEmpty(renamed))
            {
                return;
            }

            ImportFolderRepository repFolders = new ImportFolderRepository();
            VideoLocalRepository   repVids    = new VideoLocalRepository();

            // actually rename the file
            string fullFileName = this.FullServerPath;

            // check if the file exists
            if (!File.Exists(fullFileName))
            {
                logger.Error("Error could not find the original file for renaming: " + fullFileName);
                return;
            }

            // actually rename the file
            string path        = Path.GetDirectoryName(fullFileName);
            string newFullName = Path.Combine(path, renamed);

            try
            {
                logger.Info(string.Format("Renaming file From ({0}) to ({1})....", fullFileName, newFullName));

                if (fullFileName.Equals(newFullName, StringComparison.InvariantCultureIgnoreCase))
                {
                    logger.Info(string.Format("Renaming file SKIPPED, no change From ({0}) to ({1})", fullFileName,
                                              newFullName));
                }
                else
                {
                    File.Move(fullFileName, newFullName);
                    logger.Info(string.Format("Renaming file SUCCESS From ({0}) to ({1})", fullFileName, newFullName));

                    string newPartialPath = "";
                    int    folderID       = this.ImportFolderID;

                    DataAccessHelper.GetShareAndPath(newFullName, repFolders.GetAll(), ref folderID, ref newPartialPath);

                    this.FilePath = newPartialPath;
                    repVids.Save(this, true);
                }
            }
            catch (Exception ex)
            {
                logger.Info(string.Format("Renaming file FAIL From ({0}) to ({1}) - {2}", fullFileName, newFullName,
                                          ex.Message));
                logger.ErrorException(ex.ToString(), ex);
            }
        }
Exemplo n.º 9
0
 public static bool RefreshIfMediaEmpty(VideoLocal vl, Video v)
 {
     if (v.Medias == null || v.Medias.Count == 0)
     {
         VideoLocalRepository lrepo = new VideoLocalRepository();
         lrepo.Save(vl, true);
         return(true);
     }
     return(false);
 }
Exemplo n.º 10
0
        public static Video VideoFromAnimeEpisode(IProvider prov, List <Contract_CrossRef_AniDB_TvDBV2> cross,
                                                  KeyValuePair <AnimeEpisode, Contract_AnimeEpisode> e, int userid)
        {
            Video v = (Video)e.Key.PlexContract?.Clone <Video>();

            if (v?.Thumb != null)
            {
                v.Thumb = ReplaceSchemeHost(v.Thumb);
            }
            if (v != null && (v.Medias == null || v.Medias.Count == 0))
            {
                List <VideoLocal> locals = e.Key.GetVideoLocals();
                if (locals.Count > 0)
                {
                    VideoLocalRepository   lrepo = new VideoLocalRepository();
                    AnimeEpisodeRepository erepo = new AnimeEpisodeRepository();
                    foreach (VideoLocal n in locals)
                    {
                        lrepo.Save(n, false);
                    }
                    erepo.Save(e.Key);
                }
                v = (Video)e.Key.PlexContract?.Clone <Video>();
            }
            if (v != null)
            {
                if (e.Value != null)
                {
                    v.ViewCount = e.Value.WatchedCount.ToString();
                    if (e.Value.WatchedDate.HasValue)
                    {
                        v.LastViewedAt = e.Value.WatchedDate.Value.ToUnixTime();
                    }
                }
                v.ParentIndex = "1";
                if (e.Key.EpisodeTypeEnum != enEpisodeType.Episode)
                {
                    v.ParentIndex = null;
                }
                if (cross != null && cross.Count > 0)
                {
                    Contract_CrossRef_AniDB_TvDBV2 c2 =
                        cross.FirstOrDefault(
                            a =>
                            a.AniDBStartEpisodeType == int.Parse(v.EpisodeType) &&
                            a.AniDBStartEpisodeNumber <= int.Parse(v.EpisodeNumber));
                    if (c2?.TvDBSeasonNumber > 0)
                    {
                        v.ParentIndex = c2.TvDBSeasonNumber.ToString();
                    }
                }
                AddLinksToAnimeEpisodeVideo(prov, v, userid);
            }
            return(v);
        }
Exemplo n.º 11
0
		public static int UpdateAniDBFileData(bool missingInfo, bool outOfDate, bool countOnly)
		{
			List<int> vidsToUpdate = new List<int>();
			try
			{
				AniDB_FileRepository repFiles = new AniDB_FileRepository();
				VideoLocalRepository repVids = new VideoLocalRepository();

				if (missingInfo)
				{
					List<VideoLocal> vids = repVids.GetByAniDBResolution("0x0");

					foreach (VideoLocal vid in vids)
					{
						if (!vidsToUpdate.Contains(vid.VideoLocalID))
							vidsToUpdate.Add(vid.VideoLocalID);
					}
				}

				if (outOfDate)
				{
					List<VideoLocal> vids = repVids.GetByInternalVersion(1);

					foreach (VideoLocal vid in vids)
					{
						if (!vidsToUpdate.Contains(vid.VideoLocalID))
							vidsToUpdate.Add(vid.VideoLocalID);
					}
				}

				if (!countOnly)
				{
					foreach (int id in vidsToUpdate)
					{
						CommandRequest_GetFile cmd = new CommandRequest_GetFile(id, true);
						cmd.Save();
					}
				}
			}
			catch (Exception ex)
			{
				logger.ErrorException(ex.ToString(), ex);
			}

			return vidsToUpdate.Count;
		}
Exemplo n.º 12
0
        public VideoLocal_User GetVideoLocalUserRecord(int userID)
        {
            VideoLocalRepository repVids = new VideoLocalRepository();

            VideoLocal vid = repVids.GetByHash(Hash);

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

            return(null);
        }
Exemplo n.º 13
0
        public static void CheckForAniDBFileUpdate(bool forceRefresh)
		{
			if (ServerSettings.AniDB_File_UpdateFrequency == ScheduledUpdateFrequency.Never && !forceRefresh) return;
			int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_File_UpdateFrequency);

			// check for any updated anime info every 12 hours
			ScheduledUpdateRepository repSched = new ScheduledUpdateRepository();
			AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository();

			ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBFileUpdates);
			if (sched != null)
			{
				// if we have run this in the last 12 hours and are not forcing it, then exit
				TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate;
				if (tsLastRun.TotalHours < freqHours)
				{
					if (!forceRefresh) return;
				}
			}

			UpdateAniDBFileData(true, false, false);

			// files which have been hashed, but don't have an associated episode
			VideoLocalRepository repVidLocals = new VideoLocalRepository();
			List<VideoLocal> filesWithoutEpisode = repVidLocals.GetVideosWithoutEpisode();

			foreach (VideoLocal vl in filesWithoutEpisode)
			{
				CommandRequest_ProcessFile cmd = new CommandRequest_ProcessFile(vl.VideoLocalID, true);
				cmd.Save();
			}

			// now check for any files which have been manually linked and are less than 30 days old


			if (sched == null)
			{
				sched = new ScheduledUpdate();
				sched.UpdateType = (int)ScheduledUpdateType.AniDBFileUpdates;
				sched.UpdateDetails = "";
			}
			sched.LastUpdate = DateTime.Now;
			repSched.Save(sched);
		}
Exemplo n.º 14
0
        private static void InitCache(this IDatabase db)
        {
            JMMUserRepository.InitCache();
            AniDB_AnimeRepository.InitCache();
            VideoInfoRepository.InitCache();
            VideoLocalRepository.InitCache();
            VideoLocal_UserRepository.InitCache();
            List <GroupFilter> recalc = GroupFilterRepository.InitCache();

            AnimeEpisodeRepository.InitCache();
            AnimeEpisode_UserRepository.InitCache();
            AnimeSeriesRepository.InitCache();
            AnimeSeries_UserRepository.InitCache();
            AnimeGroupRepository.InitCache();
            AnimeGroup_UserRepository.InitCache();
            GroupFilterRepository.InitCacheSecondPart(recalc);
            DatabaseFixes.ExecuteDatabaseFixes();
            db.CleanUpMemory();
        }
        public override void ProcessCommand()
        {
            try
            {
                VideoLocalRepository repVids = new VideoLocalRepository();
                VideoLocal           vlocal  = repVids.GetByID(VideoLocalID);
                if (vlocal == null)
                {
                    return;
                }

                XMLService.Send_FileHash(vlocal);
            }
            catch (Exception ex)
            {
                logger.Error("Error processing CommandRequest_WebCacheSendFileHash: {0} - {1}", VideoLocalID, ex.ToString());
                return;
            }
        }
Exemplo n.º 16
0
        public Media GetMediaFromUser(int userID)
        {
            Media n = null;

            if (Media == null)
            {
                if (File.Exists(FullServerPath))
                {
                    VideoLocalRepository repo = new VideoLocalRepository();
                    repo.Save(this, false);
                }
            }
            if (Media != null)
            {
                n = (Media)Media.DeepCopy();
                if (n?.Parts != null)
                {
                    foreach (Part p in n?.Parts)
                    {
                        string name = UrlSafe.Replace(Path.GetFileName(FilePath), " ").Replace("  ", " ").Replace("  ", " ").Trim();
                        name = UrlSafe2.Replace(name, string.Empty).Trim().Replace("..", ".").Replace("..", ".").Replace("__", "_").Replace("__", "_").Replace(" ", "_").Replace("_.", ".");
                        while (name.StartsWith("_"))
                        {
                            name = name.Substring(1);
                        }
                        while (name.StartsWith("."))
                        {
                            name = name.Substring(1);
                        }
                        p.Key = PlexAndKodi.Helper.ReplaceSchemeHost(PlexAndKodi.Helper.ConstructVideoLocalStream(userID, VideoLocalID.ToString(), name, false));
                        if (p.Streams != null)
                        {
                            foreach (Stream s in p.Streams.Where(a => a.File != null && a.StreamType == "3"))
                            {
                                s.Key = PlexAndKodi.Helper.ReplaceSchemeHost(PlexAndKodi.Helper.ConstructFileStream(userID, s.File, false));
                            }
                        }
                    }
                }
            }
            return(n);
        }
Exemplo n.º 17
0
		public static void RemoveRecordsWithoutPhysicalFiles()
		{
			VideoLocalRepository repVidLocals = new VideoLocalRepository();
			CrossRef_File_EpisodeRepository repXRefs = new CrossRef_File_EpisodeRepository();

			// get a full list of files
			List<VideoLocal> filesAll = repVidLocals.GetAll();
			foreach (VideoLocal vl in filesAll)
			{
				if (!File.Exists(vl.FullServerPath))
				{
                    

					// delete video local record
					logger.Info("RemoveRecordsWithoutPhysicalFiles : {0}", vl.FullServerPath);
					repVidLocals.Delete(vl.VideoLocalID);

					CommandRequest_DeleteFileFromMyList cmdDel = new CommandRequest_DeleteFileFromMyList(vl.Hash, vl.FileSize);
					cmdDel.Save();
				}
			}

			UpdateAllStats();
		}
        private System.IO.Stream InternalGetFile(int userid, string Id, HistoryInfo info)
        {
            int id;

            if (!int.TryParse(Id, out id))
            {
                return(new MemoryStream());
            }
            VideoLocalRepository repVids = new VideoLocalRepository();
            PlexObject           ret     = new PlexObject(PlexHelper.NewMediaContainer(MediaContainerTypes.File, info, true));
            VideoLocal           vi      = repVids.GetByID(id);

            if (vi == null)
            {
                return(new MemoryStream());
            }
            List <Video> dirs = new List <Video>();
            Video        v2   = new Video();

            PlexHelper.PopulateVideo(v2, vi, JMMType.File, userid);
            dirs.Add(v2, info);
            ret.MediaContainer.Childrens = dirs;
            return(ret.GetStream());
        }
Exemplo n.º 19
0
        public static void FixHashes()
        {
            try
            {
                VideoLocalRepository repVids = new VideoLocalRepository();

                foreach (VideoLocal vid in repVids.GetAll())
                {
                    bool fixedHash = false;
                    if (vid.CRC32.Equals("00000000"))
                    {
                        vid.CRC32 = null;
                        fixedHash = true;
                    }
                    if (vid.MD5.Equals("00000000000000000000000000000000"))
                    {
                        vid.MD5   = null;
                        fixedHash = true;
                    }
                    if (vid.SHA1.Equals("0000000000000000000000000000000000000000"))
                    {
                        vid.SHA1  = null;
                        fixedHash = true;
                    }
                    if (fixedHash)
                    {
                        repVids.Save(vid);
                        logger.Info("Fixed hashes on file: {0}", vid.FullServerPath);
                    }
                }
            }
            catch (Exception ex)
            {
                logger.ErrorException(ex.ToString(), ex);
            }
        }
Exemplo n.º 20
0
        public override void ProcessCommand()
        {
            logger.Info("Get AniDB file info: {0}", VideoLocalID);


            try
            {
                AniDB_FileRepository repAniFile = new AniDB_FileRepository();
                VideoLocalRepository repVids    = new VideoLocalRepository();
                vlocal = repVids.GetByID(VideoLocalID);
                if (vlocal == null)
                {
                    return;
                }

                AniDB_File aniFile = repAniFile.GetByHashAndFileSize(vlocal.Hash, vlocal.FileSize);

                /*// get anidb file info from web cache
                 * if (aniFile == null && ServerSettings.WebCache_AniDB_File_Get)
                 * {
                 *      AniDB_FileRequest fr = XMLService.Get_AniDB_File(vlocal.Hash, vlocal.FileSize);
                 *      if (fr != null)
                 *      {
                 *              aniFile = new AniDB_File();
                 *              aniFile.Populate(fr);
                 *
                 *              //overwrite with local file name
                 *              string localFileName = Path.GetFileName(vlocal.FilePath);
                 *              aniFile.FileName = localFileName;
                 *
                 *              repAniFile.Save(aniFile, false);
                 *              aniFile.CreateLanguages();
                 *              aniFile.CreateCrossEpisodes(localFileName);
                 *
                 *              StatsCache.Instance.UpdateUsingAniDBFile(vlocal.Hash);
                 *      }
                 * }*/

                Raw_AniDB_File fileInfo = null;
                if (aniFile == null || ForceAniDB)
                {
                    fileInfo = JMMService.AnidbProcessor.GetFileInfo(vlocal);
                }

                if (fileInfo != null)
                {
                    // save to the database
                    if (aniFile == null)
                    {
                        aniFile = new AniDB_File();
                    }

                    aniFile.Populate(fileInfo);

                    //overwrite with local file name
                    string localFileName = Path.GetFileName(vlocal.FilePath);
                    aniFile.FileName = localFileName;

                    repAniFile.Save(aniFile, false);
                    aniFile.CreateLanguages();
                    aniFile.CreateCrossEpisodes(localFileName);

                    if (!string.IsNullOrEmpty(fileInfo.OtherEpisodesRAW))
                    {
                        string[] epIDs = fileInfo.OtherEpisodesRAW.Split(',');
                        foreach (string epid in epIDs)
                        {
                            int id = 0;
                            if (int.TryParse(epid, out id))
                            {
                                CommandRequest_GetEpisode cmdEp = new CommandRequest_GetEpisode(id);
                                cmdEp.Save();
                            }
                        }
                    }

                    StatsCache.Instance.UpdateUsingAniDBFile(vlocal.Hash);
                }
            }
            catch (Exception ex)
            {
                logger.Error("Error processing CommandRequest_GetFile: {0} - {1}", VideoLocalID, ex.ToString());
                return;
            }
        }
Exemplo n.º 21
0
        public static Video GenerateVideoFromAnimeEpisode(AnimeEpisode ep)
        {
            Video             l    = new Video();
            List <VideoLocal> vids = ep.GetVideoLocals();

            l.Type      = "episode";
            l.Summary   = "Episode Overview Not Available"; //TODO Intenationalization
            l.Id        = ep.AnimeEpisodeID.ToString();
            l.AnimeType = JMMContracts.PlexAndKodi.AnimeTypes.AnimeEpisode.ToString();
            VideoLocalRepository repo = new VideoLocalRepository();

            if (vids.Count > 0)
            {
                l.Title                 = Path.GetFileNameWithoutExtension(vids[0].FilePath);
                l.AddedAt               = vids[0].DateTimeCreated.ToUnixTime();
                l.UpdatedAt             = vids[0].DateTimeUpdated.ToUnixTime();
                l.OriginallyAvailableAt = vids[0].DateTimeCreated.ToPlexDate();
                l.Year   = vids[0].DateTimeCreated.Year.ToString();
                l.Medias = new List <Media>();
                foreach (VideoLocal v in vids)
                {
                    Media m = v.Media;
                    if (m == null)
                    {
                        if (File.Exists(v.FullServerPath))
                        {
                            repo.Save(v, false);
                        }
                    }
                    if (m != null)
                    {
                        l.Medias.Add(m);
                        l.Duration = m.Duration;
                    }
                }
            }
            AniDB_Episode aep = ep?.AniDB_Episode;

            if (aep != null)
            {
                l.EpisodeNumber = aep.EpisodeNumber.ToString();
                l.Index         = aep.EpisodeNumber.ToString();
                l.Title         = aep.EnglishName;
                l.OriginalTitle = aep.RomajiName;
                l.EpisodeType   = aep.EpisodeType.ToString();
                l.Rating        = float.Parse(aep.Rating, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
                if (aep.AirDateAsDate.HasValue)
                {
                    l.Year = aep.AirDateAsDate.Value.Year.ToString();
                    l.OriginallyAvailableAt = aep.AirDateAsDate.Value.ToPlexDate();
                }

                //FIX THIS
                MetroContract_Anime_Episode contract = new MetroContract_Anime_Episode();
                JMMServiceImplementationMetro.SetTvDBInfo(aep.AnimeID, aep, ref contract);
                l.Thumb   = contract.GenPoster();
                l.Summary = contract.EpisodeOverview;
            }
            l.Id = ep.AnimeEpisodeID.ToString();
            return(l);
        }
Exemplo n.º 22
0
        public void ToggleWatchedStatus(bool watched, bool updateOnline, DateTime?watchedDate, bool updateStats, bool updateStatsCache, int userID,
                                        bool scrobbleTrakt, bool updateWatchedDate)
        {
            VideoLocalRepository            repVids     = new VideoLocalRepository();
            AnimeEpisodeRepository          repEpisodes = new AnimeEpisodeRepository();
            AniDB_FileRepository            repAniFile  = new AniDB_FileRepository();
            CrossRef_File_EpisodeRepository repCross    = new CrossRef_File_EpisodeRepository();
            VideoLocal_UserRepository       repVidUsers = new VideoLocal_UserRepository();
            JMMUserRepository           repUsers        = new JMMUserRepository();
            AnimeEpisode_UserRepository repEpisodeUsers = new AnimeEpisode_UserRepository();

            JMMUser user = repUsers.GetByID(userID);

            if (user == null)
            {
                return;
            }

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

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

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


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

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


                    repAniFile.Save(aniFile, false);
                }

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

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


            AnimeSeries ser = null;
            // get all files associated with this episode
            List <CrossRef_File_Episode> xrefs = repCross.GetByHash(this.Hash);

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

                foreach (CrossRef_File_Episode xref in xrefs)
                {
                    // get the episode for this file
                    AnimeEpisode ep = repEpisodes.GetByAniDBEpisodeID(xref.EpisodeID);
                    if (ep == null)
                    {
                        continue;
                    }

                    // get all the files for this episode
                    int epPercentWatched = 0;
                    foreach (CrossRef_File_Episode filexref in ep.FileCrossRefs)
                    {
                        VideoLocal_User vidUser = filexref.GetVideoLocalUserRecord(userID);
                        if (vidUser != null)
                        {
                            // if not null means it is watched
                            epPercentWatched += filexref.Percentage;
                        }

                        if (epPercentWatched > 95)
                        {
                            break;
                        }
                    }

                    if (epPercentWatched > 95)
                    {
                        ser = ep.GetAnimeSeries();

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

                        if (scrobbleTrakt && !string.IsNullOrEmpty(ServerSettings.Trakt_Username) && !string.IsNullOrEmpty(ServerSettings.Trakt_Password))
                        {
                            CommandRequest_TraktShowScrobble cmdScrobble = new CommandRequest_TraktShowScrobble(ep.AnimeEpisodeID);
                            cmdScrobble.Save();
                        }

                        if (!string.IsNullOrEmpty(ServerSettings.MAL_Username) && !string.IsNullOrEmpty(ServerSettings.MAL_Password))
                        {
                            CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID);
                            cmdMAL.Save();
                        }
                    }
                }
            }
            else
            {
                // if setting a file to unwatched only set the episode unwatched, if ALL the files are unwatched
                foreach (CrossRef_File_Episode xrefEp in xrefs)
                {
                    AnimeEpisode ep = repEpisodes.GetByAniDBEpisodeID(xrefEp.EpisodeID);
                    if (ep == null)
                    {
                        continue;
                    }
                    ser = ep.GetAnimeSeries();

                    // get all the files for this episode
                    int epPercentWatched = 0;
                    foreach (CrossRef_File_Episode filexref in ep.FileCrossRefs)
                    {
                        VideoLocal_User vidUser = filexref.GetVideoLocalUserRecord(userID);
                        if (vidUser != null)
                        {
                            epPercentWatched += filexref.Percentage;
                        }

                        if (epPercentWatched > 95)
                        {
                            break;
                        }
                    }

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

                        CommandRequest_TraktShowEpisodeUnseen cmdUnseen = new CommandRequest_TraktShowEpisodeUnseen(ep.AnimeEpisodeID);
                        cmdUnseen.Save();
                    }
                }

                if (!string.IsNullOrEmpty(ServerSettings.MAL_Username) && !string.IsNullOrEmpty(ServerSettings.MAL_Password))
                {
                    CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID);
                    cmdMAL.Save();
                }
            }


            // update stats for groups and series
            if (ser != null && updateStats)
            {
                // update all the groups above this series in the heirarchy
                ser.UpdateStats(true, true, true);
                //ser.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true);
            }

            if (ser != null && updateStatsCache)
            {
                StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID);
            }
        }
        public override void ProcessCommand()
        {
            logger.Info("Reading Media Info for File: {0}", VideoLocalID);


            try
            {
                VideoLocalRepository repVids = new VideoLocalRepository();
                VideoLocal           vlocal  = repVids.GetByID(VideoLocalID);
                if (vlocal == null)
                {
                    logger.Error("Cound not find Video: {0}", VideoLocalID);
                    return;
                }

                if (!File.Exists(vlocal.FullServerPath))
                {
                    logger.Error("Cound not find physical file: {0}", vlocal.FullServerPath);
                    return;
                }

                int nshareID = -1;

                VideoInfoRepository repVidInfo = new VideoInfoRepository();
                VideoInfo           vinfo      = repVidInfo.GetByHash(vlocal.Hash);

                ImportFolderRepository repNS  = new ImportFolderRepository();
                List <ImportFolder>    shares = repNS.GetAll();

                string fileName = vlocal.FullServerPath;
                string filePath = "";
                DataAccessHelper.GetShareAndPath(fileName, shares, ref nshareID, ref filePath);

                FileInfo fi = new FileInfo(fileName);

                if (vinfo == null)
                {
                    vinfo      = new VideoInfo();
                    vinfo.Hash = vlocal.Hash;

                    vinfo.Duration        = 0;
                    vinfo.FileSize        = fi.Length;
                    vinfo.DateTimeUpdated = DateTime.Now;
                    vinfo.FileName        = filePath;

                    vinfo.AudioBitrate    = "";
                    vinfo.AudioCodec      = "";
                    vinfo.VideoBitrate    = "";
                    vinfo.VideoBitDepth   = "";
                    vinfo.VideoCodec      = "";
                    vinfo.VideoFrameRate  = "";
                    vinfo.VideoResolution = "";
                }


                logger.Trace("Getting media info for: {0}", fileName);
                MediaInfoResult mInfo = FileHashHelper.GetMediaInfo(fileName, true);

                vinfo.AudioBitrate = string.IsNullOrEmpty(mInfo.AudioBitrate) ? "" : mInfo.AudioBitrate;
                vinfo.AudioCodec   = string.IsNullOrEmpty(mInfo.AudioCodec) ? "" : mInfo.AudioCodec;

                vinfo.DateTimeUpdated = vlocal.DateTimeUpdated;
                vinfo.Duration        = mInfo.Duration;
                vinfo.FileName        = filePath;
                vinfo.FileSize        = fi.Length;

                vinfo.VideoBitrate    = string.IsNullOrEmpty(mInfo.VideoBitrate) ? "" : mInfo.VideoBitrate;
                vinfo.VideoBitDepth   = string.IsNullOrEmpty(mInfo.VideoBitDepth) ? "" : mInfo.VideoBitDepth;
                vinfo.VideoCodec      = string.IsNullOrEmpty(mInfo.VideoCodec) ? "" : mInfo.VideoCodec;
                vinfo.VideoFrameRate  = string.IsNullOrEmpty(mInfo.VideoFrameRate) ? "" : mInfo.VideoFrameRate;
                vinfo.VideoResolution = string.IsNullOrEmpty(mInfo.VideoResolution) ? "" : mInfo.VideoResolution;
                vinfo.FullInfo        = string.IsNullOrEmpty(mInfo.FullInfo) ? "" : mInfo.FullInfo;
                repVidInfo.Save(vinfo);
            }
            catch (Exception ex)
            {
                logger.Error("Error processing CommandRequest_ReadMediaInfo: {0} - {1}", VideoLocalID, ex.ToString());
                return;
            }
        }
Exemplo n.º 24
0
        public void MoveFileIfRequired()
        {
            // check if this file is in the drop folder
            // otherwise we don't need to move it
            if (this.ImportFolder.IsDropSource == 0)
            {
                return;
            }

            if (!File.Exists(this.FullServerPath))
            {
                return;
            }

            // find the default destination
            ImportFolder           destFolder = null;
            ImportFolderRepository repFolders = new ImportFolderRepository();

            foreach (ImportFolder fldr in repFolders.GetAll())
            {
                if (fldr.IsDropDestination == 1)
                {
                    destFolder = fldr;
                    break;
                }
            }

            if (destFolder == null)
            {
                return;
            }

            if (!Directory.Exists(destFolder.ImportFolderLocation))
            {
                return;
            }

            // we can only move the file if it has an anime associated with it
            List <CrossRef_File_Episode> xrefs = this.EpisodeCrossRefs;

            if (xrefs.Count == 0)
            {
                return;
            }
            CrossRef_File_Episode xref = xrefs[0];

            // find the series associated with this episode
            AnimeSeriesRepository repSeries = new AnimeSeriesRepository();
            AnimeSeries           series    = repSeries.GetByAnimeID(xref.AnimeID);

            if (series == null)
            {
                return;
            }

            // find where the other files are stored for this series
            // if there are no other files except for this one, it means we need to create a new location
            bool   foundLocation = false;
            string newFullPath   = "";

            // sort the episodes by air date, so that we will move the file to the location of the latest episode
            List <AnimeEpisode> allEps = series.GetAnimeEpisodes();
            List <SortPropOrFieldAndDirection> sortCriteria = new List <SortPropOrFieldAndDirection>();

            sortCriteria.Add(new SortPropOrFieldAndDirection("AniDB_EpisodeID", true, SortType.eInteger));
            allEps = Sorting.MultiSort <AnimeEpisode>(allEps, sortCriteria);

            foreach (AnimeEpisode ep in allEps)
            {
                foreach (VideoLocal vid in ep.GetVideoLocals())
                {
                    if (vid.VideoLocalID != this.VideoLocalID)
                    {
                        // make sure this folder is not the drop source
                        if (vid.ImportFolder.IsDropSource == 1)
                        {
                            continue;
                        }

                        string thisFileName = vid.FullServerPath;
                        string folderName   = Path.GetDirectoryName(thisFileName);

                        if (Directory.Exists(folderName))
                        {
                            newFullPath   = folderName;
                            foundLocation = true;
                            break;
                        }
                    }
                }
                if (foundLocation)
                {
                    break;
                }
            }

            if (!foundLocation)
            {
                // we need to create a new folder
                string newFolderName = Utils.RemoveInvalidFolderNameCharacters(series.GetAnime().MainTitle);
                newFullPath = Path.Combine(destFolder.ImportFolderLocation, newFolderName);
                if (!Directory.Exists(newFullPath))
                {
                    Directory.CreateDirectory(newFullPath);
                }
            }

            int    newFolderID       = 0;
            string newPartialPath    = "";
            string newFullServerPath = Path.Combine(newFullPath, Path.GetFileName(this.FullServerPath));

            DataAccessHelper.GetShareAndPath(newFullServerPath, repFolders.GetAll(), ref newFolderID, ref newPartialPath);


            logger.Info("Moving file from {0} to {1}", this.FullServerPath, newFullServerPath);



            if (File.Exists(newFullServerPath))
            {
                // if the file already exists, we can just delete the source file instead
                // this is safer than deleting and moving
                File.Delete(this.FullServerPath);

                this.ImportFolderID = newFolderID;
                this.FilePath       = newPartialPath;
                VideoLocalRepository repVids = new VideoLocalRepository();
                repVids.Save(this);
            }
            else
            {
                string   originalFileName = this.FullServerPath;
                FileInfo fi = new FileInfo(originalFileName);

                // now move the file
                File.Move(this.FullServerPath, newFullServerPath);

                this.ImportFolderID = newFolderID;
                this.FilePath       = newPartialPath;
                VideoLocalRepository repVids = new VideoLocalRepository();
                repVids.Save(this);

                try
                {
                    // move any subtitle files
                    foreach (string subtitleFile in Utils.GetPossibleSubtitleFiles(originalFileName))
                    {
                        if (File.Exists(subtitleFile))
                        {
                            FileInfo fiSub      = new FileInfo(subtitleFile);
                            string   newSubPath = Path.Combine(Path.GetDirectoryName(newFullServerPath), fiSub.Name);
                            if (File.Exists(newSubPath))
                            {
                                // if the file already exists, we can just delete the source file instead
                                // this is safer than deleting and moving
                                File.Delete(newSubPath);
                            }
                            else
                            {
                                File.Move(subtitleFile, newSubPath);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.ErrorException(ex.ToString(), ex);
                }

                // check for any empty folders in drop folder
                // only for the drop folder
                if (this.ImportFolder.IsDropSource == 1)
                {
                    foreach (string folderName in Directory.GetDirectories(this.ImportFolder.ImportFolderLocation, "*", SearchOption.AllDirectories))
                    {
                        if (Directory.Exists(folderName))
                        {
                            if (Directory.GetFiles(folderName, "*", SearchOption.AllDirectories).Length == 0)
                            {
                                try
                                {
                                    Directory.Delete(folderName, true);
                                }

                                /*catch (IOException)
                                 * {
                                 *      Thread.Sleep(0);
                                 *      Directory.Delete(folderName, false);
                                 * }*/
                                catch (Exception ex)
                                {
                                    logger.ErrorException(ex.ToString(), ex);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 25
0
        private void ProcessFile_AniDB(VideoLocal vidLocal)
        {
            logger.Trace("Checking for AniDB_File record for: {0} --- {1}", vidLocal.Hash, vidLocal.FilePath);
            // check if we already have this AniDB_File info in the database

            AniDB_FileRepository            repAniFile   = new AniDB_FileRepository();
            AniDB_EpisodeRepository         repAniEps    = new AniDB_EpisodeRepository();
            AniDB_AnimeRepository           repAniAnime  = new AniDB_AnimeRepository();
            AnimeSeriesRepository           repSeries    = new AnimeSeriesRepository();
            VideoLocalRepository            repVidLocals = new VideoLocalRepository();
            AnimeEpisodeRepository          repEps       = new AnimeEpisodeRepository();
            CrossRef_File_EpisodeRepository repXrefFE    = new CrossRef_File_EpisodeRepository();

            AniDB_File aniFile = null;

            if (!ForceAniDB)
            {
                aniFile = repAniFile.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize);

                if (aniFile == null)
                {
                    logger.Trace("AniDB_File record not found");
                }
            }

            int animeID = 0;

            if (aniFile == null)
            {
                // get info from AniDB
                logger.Debug("Getting AniDB_File record from AniDB....");
                Raw_AniDB_File fileInfo = JMMService.AnidbProcessor.GetFileInfo(vidLocal);
                if (fileInfo != null)
                {
                    // check if we already have a record
                    aniFile = repAniFile.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize);

                    if (aniFile == null)
                    {
                        aniFile = new AniDB_File();
                    }

                    aniFile.Populate(fileInfo);

                    //overwrite with local file name
                    string localFileName = Path.GetFileName(vidLocal.FilePath);
                    aniFile.FileName = localFileName;

                    repAniFile.Save(aniFile, false);
                    aniFile.CreateLanguages();
                    aniFile.CreateCrossEpisodes(localFileName);

                    if (!string.IsNullOrEmpty(fileInfo.OtherEpisodesRAW))
                    {
                        string[] epIDs = fileInfo.OtherEpisodesRAW.Split(',');
                        foreach (string epid in epIDs)
                        {
                            int id = 0;
                            if (int.TryParse(epid, out id))
                            {
                                CommandRequest_GetEpisode cmdEp = new CommandRequest_GetEpisode(id);
                                cmdEp.Save();
                            }
                        }
                    }

                    animeID = aniFile.AnimeID;
                }
            }

            bool missingEpisodes = false;

            // if we still haven't got the AniDB_File Info we try the web cache or local records
            if (aniFile == null)
            {
                // check if we have any records from previous imports
                List <CrossRef_File_Episode> crossRefs = repXrefFE.GetByHash(vidLocal.Hash);
                if (crossRefs == null || crossRefs.Count == 0)
                {
                    // lets see if we can find the episode/anime info from the web cache
                    if (ServerSettings.WebCache_XRefFileEpisode_Get)
                    {
                        List <JMMServer.Providers.Azure.CrossRef_File_Episode> xrefs = JMMServer.Providers.Azure.AzureWebAPI.Get_CrossRefFileEpisode(vidLocal);

                        crossRefs = new List <CrossRef_File_Episode>();
                        if (xrefs == null || xrefs.Count == 0)
                        {
                            logger.Debug("Cannot find AniDB_File record or get cross ref from web cache record so exiting: {0}", vidLocal.ED2KHash);
                            return;
                        }
                        else
                        {
                            foreach (JMMServer.Providers.Azure.CrossRef_File_Episode xref in xrefs)
                            {
                                CrossRef_File_Episode xrefEnt = new CrossRef_File_Episode();
                                xrefEnt.Hash           = vidLocal.ED2KHash;
                                xrefEnt.FileName       = Path.GetFileName(vidLocal.FullServerPath);
                                xrefEnt.FileSize       = vidLocal.FileSize;
                                xrefEnt.CrossRefSource = (int)JMMServer.CrossRefSource.WebCache;
                                xrefEnt.AnimeID        = animeID;
                                xrefEnt.EpisodeID      = xref.EpisodeID;
                                xrefEnt.Percentage     = xref.Percentage;
                                xrefEnt.EpisodeOrder   = xref.EpisodeOrder;

                                crossRefs.Add(xrefEnt);
                                // in this case we need to save the cross refs manually as AniDB did not provide them
                                repXrefFE.Save(xrefEnt);
                            }
                        }
                    }
                    else
                    {
                        logger.Debug("Cannot get AniDB_File record so exiting: {0}", vidLocal.ED2KHash);
                        return;
                    }
                }

                // we assume that all episodes belong to the same anime
                foreach (CrossRef_File_Episode xref in crossRefs)
                {
                    animeID = xref.AnimeID;

                    AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID);
                    if (ep == null)
                    {
                        missingEpisodes = true;
                    }
                }
            }
            else
            {
                // check if we have the episode info
                // if we don't, we will need to re-download the anime info (which also has episode info)

                if (aniFile.EpisodeCrossRefs.Count == 0)
                {
                    animeID = aniFile.AnimeID;

                    // if we have the anidb file, but no cross refs it means something has been broken
                    logger.Debug("Could not find any cross ref records for: {0}", vidLocal.ED2KHash);
                    missingEpisodes = true;
                }
                else
                {
                    foreach (CrossRef_File_Episode xref in aniFile.EpisodeCrossRefs)
                    {
                        AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID);
                        if (ep == null)
                        {
                            missingEpisodes = true;
                        }

                        animeID = xref.AnimeID;
                    }
                }
            }

            // get from DB
            AniDB_Anime anime = repAniAnime.GetByAnimeID(animeID);
            bool        animeRecentlyUpdated = false;

            if (anime != null)
            {
                TimeSpan ts = DateTime.Now - anime.DateTimeUpdated;
                if (ts.TotalHours < 4)
                {
                    animeRecentlyUpdated = true;
                }
            }

            // even if we are missing episode info, don't get data  more than once every 4 hours
            // this is to prevent banning
            if (missingEpisodes && !animeRecentlyUpdated)
            {
                logger.Debug("Getting Anime record from AniDB....");
                anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(animeID, true, ServerSettings.AutoGroupSeries);
            }

            // create the group/series/episode records if needed
            AnimeSeries ser = null;

            if (anime != null)
            {
                logger.Debug("Creating groups, series and episodes....");
                // check if there is an AnimeSeries Record associated with this AnimeID
                ser = repSeries.GetByAnimeID(animeID);
                if (ser == null)
                {
                    // create a new AnimeSeries record
                    ser = anime.CreateAnimeSeriesAndGroup();
                }


                ser.CreateAnimeEpisodes();

                // check if we have any group status data for this associated anime
                // if not we will download it now
                AniDB_GroupStatusRepository repStatus = new AniDB_GroupStatusRepository();
                if (repStatus.GetByAnimeID(anime.AnimeID).Count == 0)
                {
                    CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false);
                    cmdStatus.Save();
                }

                // update stats
                ser.EpisodeAddedDate = DateTime.Now;
                repSeries.Save(ser);

                AnimeGroupRepository repGroups = new AnimeGroupRepository();
                foreach (AnimeGroup grp in ser.AllGroupsAbove)
                {
                    grp.EpisodeAddedDate = DateTime.Now;
                    repGroups.Save(grp);
                }
            }

            vidLocal.RenameIfRequired();
            vidLocal.MoveFileIfRequired();


            // update stats for groups and series
            if (ser != null)
            {
                // update all the groups above this series in the heirarchy
                ser.UpdateStats(true, true, true);
                StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID);
            }


            // Add this file to the users list
            if (ServerSettings.AniDB_MyList_AddFiles)
            {
                CommandRequest_AddFileToMyList cmd = new CommandRequest_AddFileToMyList(vidLocal.ED2KHash);
                cmd.Save();
            }

            // lets also try adding to the users trakt collecion by sync'ing the series
            if (ser != null)
            {
                if (ServerSettings.WebCache_Trakt_Send && !string.IsNullOrEmpty(ServerSettings.Trakt_Username))
                {
                    CommandRequest_TraktSyncCollectionSeries cmdTrakt = new CommandRequest_TraktSyncCollectionSeries(ser.AnimeSeriesID, ser.GetAnime().MainTitle);
                    cmdTrakt.Save();
                }
            }

            // sync the series on MAL
            if (ser != null)
            {
                CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID);
                cmdMAL.Save();
            }
        }
Exemplo n.º 26
0
        private void Process(System.Net.HttpListenerContext obj)
        {
            Stream org = null;

            try
            {
                bool     fname = false;
                string[] dta   = obj.Request.RawUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                if (dta.Length < 4)
                {
                    return;
                }
                string cmd  = dta[0].ToLower();
                string user = dta[1];
                string aw   = dta[2];
                string arg  = dta[3];
                string fullname;
                int    userid    = 0;
                int    autowatch = 0;
                int.TryParse(user, out userid);
                int.TryParse(aw, out autowatch);
                VideoLocal loc = null;
                if (cmd == "videolocal")
                {
                    int sid = 0;
                    int.TryParse(arg, out sid);
                    if (sid == 0)
                    {
                        obj.Response.StatusCode        = (int)HttpStatusCode.BadRequest;
                        obj.Response.StatusDescription = "Stream Id missing.";
                        return;
                    }
                    VideoLocalRepository rep = new VideoLocalRepository();
                    loc = rep.GetByID(sid);
                    if (loc == null)
                    {
                        obj.Response.StatusCode        = (int)HttpStatusCode.NotFound;
                        obj.Response.StatusDescription = "Stream Id not found.";
                        return;
                    }
                    fullname = loc.FullServerPath;
                }
                else if (cmd == "file")
                {
                    fullname = Base64DecodeUrl(arg);
                }
                else
                {
                    obj.Response.StatusCode        = (int)HttpStatusCode.BadRequest;
                    obj.Response.StatusDescription = "Not know command";
                    return;
                }

                bool range = false;

                try
                {
                    if (!File.Exists(fullname))
                    {
                        obj.Response.StatusCode        = (int)HttpStatusCode.NotFound;
                        obj.Response.StatusDescription = "File '" + fullname + "' not found.";
                        return;
                    }
                }
                catch (Exception)
                {
                    obj.Response.StatusCode        = (int)HttpStatusCode.InternalServerError;
                    obj.Response.StatusDescription = "Unable to access File '" + fullname + "'.";
                    return;
                }
                obj.Response.ContentType = GetMime(fullname);
                obj.Response.AddHeader("Accept-Ranges", "bytes");
                obj.Response.AddHeader("X-Plex-Protocol", "1.0");
                if (obj.Request.HttpMethod == "OPTIONS")
                {
                    obj.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
                    obj.Response.AddHeader("Access-Control-Max-Age", "1209600");
                    obj.Response.AddHeader("Access-Control-Allow-Headers",
                                           "accept, x-plex-token, x-plex-client-identifier, x-plex-username, x-plex-product, x-plex-device, x-plex-platform, x-plex-platform-version, x-plex-version, x-plex-device-name");
                    obj.Response.AddHeader("Cache-Control", "no-cache");
                    obj.Response.ContentType = "text/plain";
                    return;
                }
                string rangevalue = null;
                if (obj.Request.Headers.AllKeys.Contains("Range"))
                {
                    rangevalue = obj.Request.Headers["Range"].Replace("bytes=", string.Empty).Trim();
                }
                if (obj.Request.Headers.AllKeys.Contains("range"))
                {
                    rangevalue = obj.Request.Headers["range"].Replace("bytes=", string.Empty).Trim();
                }

                if (obj.Request.HttpMethod != "HEAD")
                {
                    org = new FileStream(fullname, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    long totalsize = org.Length;
                    long start     = 0;
                    long end       = 0;
                    if (!string.IsNullOrEmpty(rangevalue))
                    {
                        range = true;
                        string[] split = rangevalue.Split('-');
                        if (split.Length == 2)
                        {
                            if (string.IsNullOrEmpty(split[0]) && !string.IsNullOrEmpty(split[1]))
                            {
                                long e = long.Parse(split[1]);
                                start = totalsize - e;
                                end   = totalsize - 1;
                            }
                            else if (!string.IsNullOrEmpty(split[0]) && string.IsNullOrEmpty(split[1]))
                            {
                                start = long.Parse(split[0]);
                                end   = totalsize - 1;
                            }
                            else if (!string.IsNullOrEmpty(split[0]) && !string.IsNullOrEmpty(split[1]))
                            {
                                start = long.Parse(split[0]);
                                end   = long.Parse(split[1]);
                                if (start > totalsize - 1)
                                {
                                    start = totalsize - 1;
                                }
                                if (end > totalsize - 1)
                                {
                                    end = totalsize - 1;
                                }
                            }
                            else
                            {
                                start = 0;
                                end   = totalsize - 1;
                            }
                        }
                    }
                    SubStream outstream;
                    if (range)
                    {
                        obj.Response.StatusCode = (int)HttpStatusCode.PartialContent;
                        obj.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + totalsize);
                        outstream = new SubStream(org, start, end - start + 1);
                        obj.Response.ContentLength64 = end - start + 1;
                    }
                    else
                    {
                        outstream = new SubStream(org, 0, totalsize);
                        obj.Response.ContentLength64 = totalsize;
                        obj.Response.StatusCode      = (int)HttpStatusCode.OK;
                    }
                    if ((userid != 0) && (loc != null) && autowatch == 1)
                    {
                        outstream.CrossPosition         = (long)((double)totalsize * WatchedThreshold);
                        outstream.CrossPositionCrossed +=
                            (a) =>
                        {
                            Task.Factory.StartNew(() => { loc.ToggleWatchedStatus(true, userid); },
                                                  new CancellationToken(),
                                                  TaskCreationOptions.LongRunning, TaskScheduler.Default);
                        };
                    }
                    obj.Response.SendChunked = false;
                    outstream.CopyTo(obj.Response.OutputStream);
                    obj.Response.OutputStream.Close();
                    outstream.Close();
                }
                else
                {
                    obj.Response.SendChunked     = false;
                    obj.Response.StatusCode      = (int)HttpStatusCode.OK;
                    obj.Response.ContentLength64 = new FileInfo(fullname).Length;
                    obj.Response.KeepAlive       = false;
                    obj.Response.OutputStream.Close();
                }
            }
            catch (HttpListenerException e)
            {
            }
            catch (Exception e)
            {
                logger.Error(e.ToString);
            }
            finally
            {
                if (org != null)
                {
                    org.Close();
                }
                if ((obj != null) && (obj.Response != null) && (obj.Response.OutputStream != null))
                {
                    obj.Response.OutputStream.Close();
                }
            }
        }
Exemplo n.º 27
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;
            }
        }
Exemplo n.º 28
0
        public void UpdateStats(bool watchedStats, bool missingEpsStats, bool updateAllGroupsAbove)
        {
            DateTime start        = DateTime.Now;
            DateTime startOverall = DateTime.Now;

            logger.Info("Starting Updating STATS for SERIES {0} ({1} - {2} - {3})", this.ToString(), watchedStats, missingEpsStats, updateAllGroupsAbove);

            AnimeSeries_UserRepository      repSeriesUser  = new AnimeSeries_UserRepository();
            AnimeEpisode_UserRepository     repEpisodeUser = new AnimeEpisode_UserRepository();
            VideoLocalRepository            repVids        = new VideoLocalRepository();
            CrossRef_File_EpisodeRepository repXrefs       = new CrossRef_File_EpisodeRepository();

            JMMUserRepository repUsers = new JMMUserRepository();
            List <JMMUser>    allUsers = repUsers.GetAll();

            DateTime            startEps = DateTime.Now;
            List <AnimeEpisode> eps      = GetAnimeEpisodes();
            TimeSpan            tsEps    = DateTime.Now - startEps;

            logger.Trace("Got episodes for SERIES {0} in {1}ms", this.ToString(), tsEps.TotalMilliseconds);

            DateTime                     startVids = DateTime.Now;
            List <VideoLocal>            vidsTemp  = repVids.GetByAniDBAnimeID(this.AniDB_ID);
            List <CrossRef_File_Episode> crossRefs = repXrefs.GetByAnimeID(this.AniDB_ID);

            Dictionary <int, List <CrossRef_File_Episode> > dictCrossRefs = new Dictionary <int, List <CrossRef_File_Episode> >();

            foreach (CrossRef_File_Episode xref in crossRefs)
            {
                if (!dictCrossRefs.ContainsKey(xref.EpisodeID))
                {
                    dictCrossRefs[xref.EpisodeID] = new List <CrossRef_File_Episode>();
                }
                dictCrossRefs[xref.EpisodeID].Add(xref);
            }

            Dictionary <string, VideoLocal> dictVids = new Dictionary <string, VideoLocal>();

            foreach (VideoLocal vid in vidsTemp)
            {
                dictVids[vid.Hash] = vid;
            }

            TimeSpan tsVids = DateTime.Now - startVids;

            logger.Trace("Got video locals for SERIES {0} in {1}ms", this.ToString(), tsVids.TotalMilliseconds);


            if (watchedStats)
            {
                foreach (JMMUser juser in allUsers)
                {
                    //this.WatchedCount = 0;
                    AnimeSeries_User userRecord = GetUserRecord(juser.JMMUserID);
                    if (userRecord == null)
                    {
                        userRecord = new AnimeSeries_User(juser.JMMUserID, this.AnimeSeriesID);
                    }

                    // reset stats
                    userRecord.UnwatchedEpisodeCount = 0;
                    userRecord.WatchedEpisodeCount   = 0;
                    userRecord.WatchedCount          = 0;
                    userRecord.WatchedDate           = null;

                    DateTime startUser = DateTime.Now;
                    List <AnimeEpisode_User>            epUserRecords   = repEpisodeUser.GetByUserID(juser.JMMUserID);
                    Dictionary <int, AnimeEpisode_User> dictUserRecords = new Dictionary <int, AnimeEpisode_User>();
                    foreach (AnimeEpisode_User usrec in epUserRecords)
                    {
                        dictUserRecords[usrec.AnimeEpisodeID] = usrec;
                    }
                    TimeSpan tsUser = DateTime.Now - startUser;
                    logger.Trace("Got user records for SERIES {0}/{1} in {2}ms", this.ToString(), juser.Username, tsUser.TotalMilliseconds);

                    foreach (AnimeEpisode ep in eps)
                    {
                        // if the episode doesn't have any files then it won't count towards watched/unwatched counts
                        List <VideoLocal> epVids = new List <VideoLocal>();

                        if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID))
                        {
                            foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID])
                            {
                                if (xref.EpisodeID == ep.AniDB_EpisodeID)
                                {
                                    if (dictVids.ContainsKey(xref.Hash))
                                    {
                                        epVids.Add(dictVids[xref.Hash]);
                                    }
                                }
                            }
                        }
                        if (epVids.Count == 0)
                        {
                            continue;
                        }

                        if (ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Episode || ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Special)
                        {
                            AnimeEpisode_User epUserRecord = null;
                            if (dictUserRecords.ContainsKey(ep.AnimeEpisodeID))
                            {
                                epUserRecord = dictUserRecords[ep.AnimeEpisodeID];
                            }

                            if (epUserRecord != null && epUserRecord.WatchedDate.HasValue)
                            {
                                userRecord.WatchedEpisodeCount++;
                            }
                            else
                            {
                                userRecord.UnwatchedEpisodeCount++;
                            }

                            if (epUserRecord != null)
                            {
                                if (userRecord.WatchedDate.HasValue)
                                {
                                    if (epUserRecord.WatchedDate > userRecord.WatchedDate)
                                    {
                                        userRecord.WatchedDate = epUserRecord.WatchedDate;
                                    }
                                }
                                else
                                {
                                    userRecord.WatchedDate = epUserRecord.WatchedDate;
                                }

                                userRecord.WatchedCount += epUserRecord.WatchedCount;
                            }
                        }
                    }
                    repSeriesUser.Save(userRecord);
                }
            }

            TimeSpan ts = DateTime.Now - start;

            logger.Trace("Updated WATCHED stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds);
            start = DateTime.Now;



            if (missingEpsStats)
            {
                enAnimeType animeType   = enAnimeType.TVSeries;
                AniDB_Anime aniDB_Anime = this.GetAnime();
                if (aniDB_Anime != null)
                {
                    animeType = aniDB_Anime.AnimeTypeEnum;
                }

                MissingEpisodeCount       = 0;
                MissingEpisodeCountGroups = 0;

                // get all the group status records
                AniDB_GroupStatusRepository repGrpStat  = new AniDB_GroupStatusRepository();
                List <AniDB_GroupStatus>    grpStatuses = repGrpStat.GetByAnimeID(this.AniDB_ID);

                // find all the episodes for which the user has a file
                // from this we can determine what their latest episode number is
                // find out which groups the user is collecting

                List <int> userReleaseGroups = new List <int>();
                foreach (AnimeEpisode ep in eps)
                {
                    List <VideoLocal> vids = new List <VideoLocal>();
                    if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID))
                    {
                        foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID])
                        {
                            if (xref.EpisodeID == ep.AniDB_EpisodeID)
                            {
                                if (dictVids.ContainsKey(xref.Hash))
                                {
                                    vids.Add(dictVids[xref.Hash]);
                                }
                            }
                        }
                    }

                    //List<VideoLocal> vids = ep.VideoLocals;
                    foreach (VideoLocal vid in vids)
                    {
                        AniDB_File anifile = vid.GetAniDBFile();
                        if (anifile != null)
                        {
                            if (!userReleaseGroups.Contains(anifile.GroupID))
                            {
                                userReleaseGroups.Add(anifile.GroupID);
                            }
                        }
                    }
                }

                int         latestLocalEpNumber = 0;
                EpisodeList epReleasedList      = new EpisodeList(animeType);
                EpisodeList epGroupReleasedList = new EpisodeList(animeType);

                foreach (AnimeEpisode ep in eps)
                {
                    //List<VideoLocal> vids = ep.VideoLocals;
                    if (ep.EpisodeTypeEnum != AniDBAPI.enEpisodeType.Episode)
                    {
                        continue;
                    }

                    List <VideoLocal> vids = new List <VideoLocal>();
                    if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID))
                    {
                        foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID])
                        {
                            if (xref.EpisodeID == ep.AniDB_EpisodeID)
                            {
                                if (dictVids.ContainsKey(xref.Hash))
                                {
                                    vids.Add(dictVids[xref.Hash]);
                                }
                            }
                        }
                    }



                    AniDB_Episode aniEp     = ep.AniDB_Episode;
                    int           thisEpNum = aniEp.EpisodeNumber;

                    if (thisEpNum > latestLocalEpNumber && vids.Count > 0)
                    {
                        latestLocalEpNumber = thisEpNum;
                    }

                    // does this episode have a file released
                    // does this episode have a file released by the group the user is collecting
                    bool epReleased      = false;
                    bool epReleasedGroup = false;
                    foreach (AniDB_GroupStatus gs in grpStatuses)
                    {
                        if (gs.LastEpisodeNumber >= thisEpNum)
                        {
                            epReleased = true;
                        }
                        if (userReleaseGroups.Contains(gs.GroupID) && gs.HasGroupReleasedEpisode(thisEpNum))
                        {
                            epReleasedGroup = true;
                        }
                    }


                    try
                    {
                        epReleasedList.Add(ep, (!epReleased || vids.Count != 0));
                        epGroupReleasedList.Add(ep, (!epReleasedGroup || vids.Count != 0));
                    }
                    catch (Exception e)
                    {
                        logger.Trace("Error {0}", e.ToString());
                        throw;
                    }
                }
                foreach (EpisodeList.StatEpisodes eplst in epReleasedList)
                {
                    if (!eplst.Available)
                    {
                        MissingEpisodeCount++;
                    }
                }
                foreach (EpisodeList.StatEpisodes eplst in epGroupReleasedList)
                {
                    if (!eplst.Available)
                    {
                        MissingEpisodeCountGroups++;
                    }
                }

                this.LatestLocalEpisodeNumber = latestLocalEpNumber;
            }

            ts = DateTime.Now - start;
            logger.Trace("Updated MISSING EPS stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds);
            start = DateTime.Now;

            AnimeSeriesRepository rep = new AnimeSeriesRepository();

            rep.Save(this);

            if (updateAllGroupsAbove)
            {
                foreach (AnimeGroup grp in AllGroupsAbove)
                {
                    grp.UpdateStats(watchedStats, missingEpsStats);
                }
            }

            ts = DateTime.Now - start;
            logger.Trace("Updated GROUPS ABOVE stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds);
            start = DateTime.Now;

            TimeSpan tsOverall = DateTime.Now - startOverall;

            logger.Info("Finished Updating STATS for SERIES {0} in {1}ms ({2} - {3} - {4})", this.ToString(), tsOverall.TotalMilliseconds,
                        watchedStats, missingEpsStats, updateAllGroupsAbove);
        }
Exemplo n.º 29
0
        private VideoLocal ProcessFile_LocalInfo()
        {
            // hash and read media info for file
            int    nshareID = -1;
            string filePath = "";

            ImportFolderRepository repNS  = new ImportFolderRepository();
            List <ImportFolder>    shares = repNS.GetAll();

            DataAccessHelper.GetShareAndPath(FileName, shares, ref nshareID, ref filePath);

            if (!File.Exists(FileName))
            {
                logger.Error("File does not exist: {0}", FileName);
                return(null);
            }

            int numAttempts = 0;

            // Wait 3 minutes seconds before giving up on trying to access the file
            while ((!CanAccessFile(FileName)) && (numAttempts < 180))
            {
                numAttempts++;
                Thread.Sleep(1000);
                Console.WriteLine("Attempt # " + numAttempts.ToString());
            }

            // if we failed to access the file, get ouuta here
            if (numAttempts == 180)
            {
                logger.Error("Could not access file: " + FileName);
                return(null);
            }


            // check if we have already processed this file
            VideoLocal             vlocal      = null;
            VideoLocalRepository   repVidLocal = new VideoLocalRepository();
            FileNameHashRepository repFNHash   = new FileNameHashRepository();

            List <VideoLocal> vidLocals = repVidLocal.GetByFilePathAndShareID(filePath, nshareID);
            FileInfo          fi        = new FileInfo(FileName);

            if (vidLocals.Count > 0)
            {
                vlocal = vidLocals[0];
                logger.Trace("VideoLocal record found in database: {0}", vlocal.VideoLocalID);

                if (ForceHash)
                {
                    vlocal.FileSize        = fi.Length;
                    vlocal.DateTimeUpdated = DateTime.Now;
                }
            }
            else
            {
                logger.Trace("VideoLocal, creating new record");
                vlocal = new VideoLocal();
                vlocal.DateTimeUpdated = DateTime.Now;
                vlocal.DateTimeCreated = vlocal.DateTimeUpdated;
                vlocal.FilePath        = filePath;
                vlocal.FileSize        = fi.Length;
                vlocal.ImportFolderID  = nshareID;
                vlocal.Hash            = "";
                vlocal.CRC32           = "";
                vlocal.MD5             = "";
                vlocal.SHA1            = "";
                vlocal.IsIgnored       = 0;
                vlocal.IsVariation     = 0;
            }

            // check if we need to get a hash this file
            Hashes hashes = null;

            if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash)
            {
                // try getting the hash from the CrossRef
                if (!ForceHash)
                {
                    CrossRef_File_EpisodeRepository repCrossRefs = new CrossRef_File_EpisodeRepository();
                    List <CrossRef_File_Episode>    crossRefs    = repCrossRefs.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize);
                    if (crossRefs.Count == 1)
                    {
                        vlocal.Hash       = crossRefs[0].Hash;
                        vlocal.HashSource = (int)HashSource.DirectHash;
                    }
                }

                // try getting the hash from the LOCAL cache
                if (!ForceHash && string.IsNullOrEmpty(vlocal.Hash))
                {
                    List <FileNameHash> fnhashes = repFNHash.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize);
                    if (fnhashes != null && fnhashes.Count > 1)
                    {
                        // if we have more than one record it probably means there is some sort of corruption
                        // lets delete the local records
                        foreach (FileNameHash fnh in fnhashes)
                        {
                            repFNHash.Delete(fnh.FileNameHashID);
                        }
                    }

                    if (fnhashes != null && fnhashes.Count == 1)
                    {
                        logger.Trace("Got hash from LOCAL cache: {0} ({1})", FileName, fnhashes[0].Hash);
                        vlocal.Hash       = fnhashes[0].Hash;
                        vlocal.HashSource = (int)HashSource.WebCacheFileName;
                    }
                }

                // hash the file
                if (string.IsNullOrEmpty(vlocal.Hash) || ForceHash)
                {
                    DateTime start = DateTime.Now;
                    logger.Trace("Calculating hashes for: {0}", FileName);
                    // update the VideoLocal record with the Hash
                    hashes = FileHashHelper.GetHashInfo(FileName, true, MainWindow.OnHashProgress, ServerSettings.Hash_CRC32, ServerSettings.Hash_MD5, ServerSettings.Hash_SHA1);
                    TimeSpan ts = DateTime.Now - start;
                    logger.Trace("Hashed file in {0} seconds --- {1} ({2})", ts.TotalSeconds.ToString("#0.0"), FileName, Utils.FormatByteSize(vlocal.FileSize));

                    vlocal.Hash       = hashes.ed2k;
                    vlocal.CRC32      = hashes.crc32;
                    vlocal.MD5        = hashes.md5;
                    vlocal.SHA1       = hashes.sha1;
                    vlocal.HashSource = (int)HashSource.DirectHash;
                }

                // We should have a hash by now
                // before we save it, lets make sure there is not any other record with this hash (possible duplicate file)
                VideoLocal vidTemp = repVidLocal.GetByHash(vlocal.Hash);
                if (vidTemp != null)
                {
                    // don't delete it, if it is actually the same record
                    if (vidTemp.VideoLocalID != vlocal.VideoLocalID)
                    {
                        // delete the VideoLocal record
                        logger.Warn("Deleting duplicate video file record");
                        logger.Warn("---------------------------------------------");
                        logger.Warn("Keeping record for: {0}", vlocal.FullServerPath);
                        logger.Warn("Deleting record for: {0}", vidTemp.FullServerPath);
                        logger.Warn("---------------------------------------------");

                        // check if we have a record of this in the database, if not create one
                        DuplicateFileRepository repDups  = new DuplicateFileRepository();
                        List <DuplicateFile>    dupFiles = repDups.GetByFilePathsAndImportFolder(vlocal.FilePath, vidTemp.FilePath, vlocal.ImportFolderID, vidTemp.ImportFolderID);
                        if (dupFiles.Count == 0)
                        {
                            dupFiles = repDups.GetByFilePathsAndImportFolder(vidTemp.FilePath, vlocal.FilePath, vidTemp.ImportFolderID, vlocal.ImportFolderID);
                        }

                        if (dupFiles.Count == 0)
                        {
                            DuplicateFile dup = new DuplicateFile();
                            dup.DateTimeUpdated     = DateTime.Now;
                            dup.FilePathFile1       = vlocal.FilePath;
                            dup.FilePathFile2       = vidTemp.FilePath;
                            dup.ImportFolderIDFile1 = vlocal.ImportFolderID;
                            dup.ImportFolderIDFile2 = vidTemp.ImportFolderID;
                            dup.Hash = vlocal.Hash;
                            repDups.Save(dup);
                        }

                        repVidLocal.Delete(vidTemp.VideoLocalID);
                    }
                }

                repVidLocal.Save(vlocal);

                // also save the filename to hash record
                // replace the existing records just in case it was corrupt
                FileNameHash        fnhash    = null;
                List <FileNameHash> fnhashes2 = repFNHash.GetByFileNameAndSize(Path.GetFileName(vlocal.FilePath), vlocal.FileSize);
                if (fnhashes2 != null && fnhashes2.Count > 1)
                {
                    // if we have more than one record it probably means there is some sort of corruption
                    // lets delete the local records
                    foreach (FileNameHash fnh in fnhashes2)
                    {
                        repFNHash.Delete(fnh.FileNameHashID);
                    }
                }

                if (fnhashes2 != null && fnhashes2.Count == 1)
                {
                    fnhash = fnhashes2[0];
                }
                else
                {
                    fnhash = new FileNameHash();
                }

                fnhash.FileName        = Path.GetFileName(vlocal.FilePath);
                fnhash.FileSize        = vlocal.FileSize;
                fnhash.Hash            = vlocal.Hash;
                fnhash.DateTimeUpdated = DateTime.Now;
                repFNHash.Save(fnhash);
            }


            // now check if we have stored a VideoInfo record
            bool refreshMediaInfo = false;

            VideoInfoRepository repVidInfo = new VideoInfoRepository();
            VideoInfo           vinfo      = repVidInfo.GetByHash(vlocal.Hash);

            if (vinfo == null)
            {
                refreshMediaInfo = true;

                vinfo      = new VideoInfo();
                vinfo.Hash = vlocal.Hash;

                vinfo.Duration        = 0;
                vinfo.FileSize        = fi.Length;
                vinfo.DateTimeUpdated = DateTime.Now;
                vinfo.FileName        = filePath;

                vinfo.AudioBitrate    = "";
                vinfo.AudioCodec      = "";
                vinfo.VideoBitrate    = "";
                vinfo.VideoBitDepth   = "";
                vinfo.VideoCodec      = "";
                vinfo.VideoFrameRate  = "";
                vinfo.VideoResolution = "";

                repVidInfo.Save(vinfo);
            }
            else
            {
                // check if we need to update the media info
                if (vinfo.VideoCodec.Trim().Length == 0)
                {
                    refreshMediaInfo = true;
                }
                else
                {
                    refreshMediaInfo = false;
                }
            }



            if (refreshMediaInfo)
            {
                logger.Trace("Getting media info for: {0}", FileName);
                MediaInfoResult mInfo = FileHashHelper.GetMediaInfo(FileName, true);

                vinfo.AudioBitrate = string.IsNullOrEmpty(mInfo.AudioBitrate) ? "" : mInfo.AudioBitrate;
                vinfo.AudioCodec   = string.IsNullOrEmpty(mInfo.AudioCodec) ? "" : mInfo.AudioCodec;

                vinfo.DateTimeUpdated = vlocal.DateTimeUpdated;
                vinfo.Duration        = mInfo.Duration;
                vinfo.FileName        = filePath;
                vinfo.FileSize        = fi.Length;

                vinfo.VideoBitrate    = string.IsNullOrEmpty(mInfo.VideoBitrate) ? "" : mInfo.VideoBitrate;
                vinfo.VideoBitDepth   = string.IsNullOrEmpty(mInfo.VideoBitDepth) ? "" : mInfo.VideoBitDepth;
                vinfo.VideoCodec      = string.IsNullOrEmpty(mInfo.VideoCodec) ? "" : mInfo.VideoCodec;
                vinfo.VideoFrameRate  = string.IsNullOrEmpty(mInfo.VideoFrameRate) ? "" : mInfo.VideoFrameRate;
                vinfo.VideoResolution = string.IsNullOrEmpty(mInfo.VideoResolution) ? "" : mInfo.VideoResolution;
                vinfo.FullInfo        = string.IsNullOrEmpty(mInfo.FullInfo) ? "" : mInfo.FullInfo;
                repVidInfo.Save(vinfo);
            }

            // now add a command to process the file
            CommandRequest_ProcessFile cr_procfile = new CommandRequest_ProcessFile(vlocal.VideoLocalID, false);

            cr_procfile.Save();

            return(vlocal);
        }
        public System.IO.Stream GetFilters(string uid)
        {
            JMMUser user = KodiHelper.GetUser(uid);

            if (user == null)
            {
                return(new MemoryStream());
            }
            int        userid = user.JMMUserID;
            KodiObject ret    = new KodiObject(KodiHelper.NewMediaContainer("Anime", false));

            if (!ret.Init())
            {
                return(new MemoryStream());
            }
            List <Video> dirs = new List <Video>();

            try
            {
                using (var session = JMMService.SessionFactory.OpenSession())
                {
                    GroupFilterRepository            repGF  = new GroupFilterRepository();
                    List <GroupFilter>               allGfs = repGF.GetAll(session);
                    Dictionary <int, HashSet <int> > gstats = StatsCache.Instance.StatUserGroupFilter[userid];
                    foreach (GroupFilter gg in allGfs.ToArray())
                    {
                        if ((!StatsCache.Instance.StatUserGroupFilter.ContainsKey(userid)) ||
                            (!StatsCache.Instance.StatUserGroupFilter[userid].ContainsKey(gg.GroupFilterID)))
                        {
                            allGfs.Remove(gg);
                        }
                    }


                    AnimeGroupRepository repGroups = new AnimeGroupRepository();
                    allGfs.Insert(0, new GroupFilter()
                    {
                        GroupFilterName = "All", GroupFilterID = -999
                    });
                    foreach (GroupFilter gg in allGfs)
                    {
                        Random    rnd = new Random(123456789);
                        Directory pp  = new Directory();
                        pp.Key = KodiHelper.ServerUrl(int.Parse(ServerSettings.JMMServerPort),
                                                      MainWindow.PathAddressKodi + "/GetMetadata/" + userid + "/" +
                                                      (int)JMMType.GroupFilter + "/" + gg.GroupFilterID);
                        pp.PrimaryExtraKey = pp.Key;
                        pp.Title           = gg.GroupFilterName;
                        HashSet <int> groups;
                        groups = gg.GroupFilterID == -999 ? new HashSet <int>(repGroups.GetAllTopLevelGroups(session).Select(a => a.AnimeGroupID)) : gstats[gg.GroupFilterID];
                        if (groups.Count != 0)
                        {
                            bool repeat;
                            int  nn = 0;
                            pp.LeafCount       = groups.Count.ToString();
                            pp.ViewedLeafCount = "0";
                            do
                            {
                                repeat = true;
                                int                grp  = groups.ElementAt(rnd.Next(groups.Count));
                                AnimeGroup         ag   = repGroups.GetByID(grp);
                                List <AnimeSeries> sers = ag.GetSeries(session);
                                if (sers.Count > 0)
                                {
                                    AnimeSeries ser  = sers[rnd.Next(sers.Count)];
                                    AniDB_Anime anim = ser.GetAnime(session);
                                    if (anim != null)
                                    {
                                        ImageDetails poster = anim.GetDefaultPosterDetailsNoBlanks(session);
                                        ImageDetails fanart = anim.GetDefaultFanartDetailsNoBlanks(session);
                                        if (poster != null)
                                        {
                                            pp.Thumb = poster.GenPoster();
                                        }
                                        if (fanart != null)
                                        {
                                            pp.Art = fanart.GenArt();
                                        }
                                        if (poster != null)
                                        {
                                            repeat = false;
                                        }
                                    }
                                }
                                nn++;
                                if ((repeat) && (nn == 15))
                                {
                                    repeat = false;
                                }
                            } while (repeat);
                            dirs.Add(pp);
                        }
                    }
                    VideoLocalRepository repVids = new VideoLocalRepository();
                    List <VideoLocal>    vids    = repVids.GetVideosWithoutEpisode();
                    if (vids.Count > 0)
                    {
                        JMMContracts.KodiContracts.Directory pp = new JMMContracts.KodiContracts.Directory();
                        pp.Key = pp.PrimaryExtraKey = KodiHelper.ServerUrl(int.Parse(ServerSettings.JMMServerPort),
                                                                           MainWindow.PathAddressKodi + "/GetMetadata/0/" + (int)JMMType.GroupUnsort + "/0");
                        pp.Title = "Unsort";
                        pp.Thumb = KodiHelper.ServerUrl(int.Parse(ServerSettings.JMMServerPort),
                                                        MainWindow.PathAddressKodi + "/GetSupportImage/plex_unsort.png");
                        pp.LeafCount       = vids.Count.ToString();
                        pp.ViewedLeafCount = "0";
                        dirs.Add(pp);
                    }
                    dirs = dirs.OrderBy(a => a.Title).ToList();
                }
                ret.Childrens = dirs;
                return(ret.GetStream());
            }
            catch (Exception ex)
            {
                logger.ErrorException(ex.ToString(), ex);
                return(new MemoryStream());
            }
        }