private SVR_AniDB_File TryGetAniDBFileFromAniDB(SVR_VideoLocal vidLocal, Dictionary <int, bool> animeIDs)
        {
            // check if we already have a record
            SVR_AniDB_File aniFile = RepoFactory.AniDB_File.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize);

            if (aniFile == null || aniFile.FileSize != vlocal.FileSize)
            {
                ForceAniDB = true;
            }

            if (ForceAniDB)
            {
                if (!ShokoService.AnidbProcessor.IsUdpBanned)
                {
                    // get info from AniDB
                    logger.Debug("Getting AniDB_File record from AniDB....");
                    Raw_AniDB_File fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vidLocal);
                    if (fileInfo != null)
                    {
                        aniFile ??= new SVR_AniDB_File();
                        SVR_AniDB_File.Populate(aniFile, fileInfo);
                    }
                }
                else
                {
                    CommandRequest_GetFile fileCommand = new CommandRequest_GetFile(vlocal.VideoLocalID, true);
                    fileCommand.Save();
                }
            }

            if (aniFile == null)
            {
                return(null);
            }
            //overwrite with local file name
            string localFileName = vidLocal.GetBestVideoLocalPlace()?.FullServerPath;

            localFileName = !string.IsNullOrEmpty(localFileName)
                ? Path.GetFileName(localFileName)
                : vidLocal.FileName;
            aniFile.FileName = localFileName;

            RepoFactory.AniDB_File.Save(aniFile, false);
            aniFile.CreateLanguages();
            aniFile.CreateCrossEpisodes(localFileName);

            aniFile.Episodes.Select(a => a.AnimeID).Distinct().ForEach(animeID =>
            {
                if (animeIDs.ContainsKey(animeID))
                {
                    animeIDs[animeID] = false;
                }
                else
                {
                    animeIDs.Add(animeID, false);
                }
            });

            return(aniFile);
        }
Exemple #2
0
        private void ProcessFile_AniDB(SVR_VideoLocal vidLocal)
        {
            logger.Trace($"Checking for AniDB_File record for: {vidLocal.Hash} --- {vidLocal.FileName}");
            // check if we already have this AniDB_File info in the database

            lock (vidLocal)
            {
                SVR_AniDB_File aniFile = null;

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

                    if (aniFile == null)
                    {
                        logger.Trace("AniDB_File record not found");
                    }
                }
                // If cross refs were wiped, but the AniDB_File was not, we unfortunately need to requery the info
                List <CrossRef_File_Episode> crossRefs = RepoFactory.CrossRef_File_Episode.GetByHash(vidLocal.Hash);
                if (crossRefs == null || crossRefs.Count == 0)
                {
                    aniFile = null;
                }

                int animeID = 0;

                if (aniFile == null)
                {
                    // get info from AniDB
                    logger.Debug("Getting AniDB_File record from AniDB....");

                    // check if we already have a record
                    aniFile = RepoFactory.AniDB_File.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize);

                    if (aniFile == null)
                    {
                        aniFile    = new SVR_AniDB_File();
                        ForceAniDB = true;
                    }

                    if (ForceAniDB)
                    {
                        if (!ShokoService.AnidbProcessor.IsUdpBanned)
                        {
                            Raw_AniDB_File fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vidLocal);
                            if (fileInfo != null)
                            {
                                SVR_AniDB_File.Populate(aniFile, fileInfo);
                            }
                            else
                            {
                                aniFile = null;
                            }
                        }
                        else
                        {
                            CommandRequest_GetFile fileCommand = new CommandRequest_GetFile(vlocal.VideoLocalID, true);
                            fileCommand.Save();
                        }
                    }

                    if (aniFile != null)
                    {
                        //overwrite with local file name
                        string localFileName = vidLocal.GetBestVideoLocalPlace()?.FullServerPath;
                        localFileName = !string.IsNullOrEmpty(localFileName)
                            ? Path.GetFileName(localFileName)
                            : vidLocal.FileName;
                        aniFile.FileName = localFileName;

                        RepoFactory.AniDB_File.Save(aniFile, false);
                        aniFile.CreateLanguages();
                        aniFile.CreateCrossEpisodes(localFileName);

                        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
                    crossRefs = RepoFactory.CrossRef_File_Episode.GetByHash(vidLocal.Hash);
                    if (crossRefs == null || crossRefs.Count == 0)
                    {
                        // lets see if we can find the episode/anime info from the web cache
                        if (ServerSettings.Instance.WebCache.Enabled && ServerSettings.Instance.WebCache.XRefFileEpisode_Get)
                        {
                            List <Azure_CrossRef_File_Episode> xrefs =
                                AzureWebAPI.Get_CrossRefFileEpisode(vidLocal);

                            crossRefs = new List <CrossRef_File_Episode>();
                            if (xrefs == null || xrefs.Count == 0)
                            {
                                logger.Debug(
                                    $"Cannot find AniDB_File record or get cross ref from web cache record so exiting: {vidLocal.ED2KHash}");
                                return;
                            }
                            string fileName = vidLocal.GetBestVideoLocalPlace()?.FullServerPath;
                            fileName = !string.IsNullOrEmpty(fileName) ? Path.GetFileName(fileName) : vidLocal.FileName;
                            foreach (Azure_CrossRef_File_Episode xref in xrefs)
                            {
                                CrossRef_File_Episode xrefEnt = new CrossRef_File_Episode
                                {
                                    Hash           = vidLocal.ED2KHash,
                                    FileName       = fileName,
                                    FileSize       = vidLocal.FileSize,
                                    CrossRefSource = (int)CrossRefSource.WebCache,
                                    AnimeID        = xref.AnimeID,
                                    EpisodeID      = xref.EpisodeID,
                                    Percentage     = xref.Percentage,
                                    EpisodeOrder   = xref.EpisodeOrder
                                };
                                bool duplicate = false;

                                foreach (CrossRef_File_Episode xrefcheck in crossRefs)
                                {
                                    if (xrefcheck.AnimeID == xrefEnt.AnimeID &&
                                        xrefcheck.EpisodeID == xrefEnt.EpisodeID &&
                                        xrefcheck.Hash == xrefEnt.Hash)
                                    {
                                        duplicate = true;
                                    }
                                }

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

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

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

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

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

                            animeID = xref.AnimeID;
                        }
                    }
                }

                // get from DB
                SVR_AniDB_Anime anime  = RepoFactory.AniDB_Anime.GetByAnimeID(animeID);
                var             update = RepoFactory.AniDB_AnimeUpdate.GetByAnimeID(animeID);
                bool            animeRecentlyUpdated = false;

                if (anime != null && update != null)
                {
                    TimeSpan ts = DateTime.Now - update.UpdatedAt;
                    if (ts.TotalHours < 4)
                    {
                        animeRecentlyUpdated = true;
                    }
                }
                else
                {
                    missingEpisodes = true;
                }

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

                // create the group/series/episode records if needed
                if (anime != null)
                {
                    logger.Debug("Creating groups, series and episodes....");
                    // check if there is an AnimeSeries Record associated with this AnimeID
                    var ser = RepoFactory.AnimeSeries.GetByAnimeID(animeID) ?? anime.CreateAnimeSeriesAndGroup();

                    ser.CreateAnimeEpisodes();

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

                    // update stats
                    ser.EpisodeAddedDate = DateTime.Now;
                    RepoFactory.AnimeSeries.Save(ser, false, false);

                    foreach (SVR_AnimeGroup grp in ser.AllGroupsAbove)
                    {
                        grp.EpisodeAddedDate = DateTime.Now;
                        RepoFactory.AnimeGroup.Save(grp, true, false);
                    }

                    // We do this inside, as the info will not be available as needed otherwise
                    List <SVR_VideoLocal> videoLocals =
                        aniFile?.EpisodeIDs?.SelectMany(a => RepoFactory.VideoLocal.GetByAniDBEpisodeID(a))
                        .Where(b => b != null)
                        .ToList();
                    if (videoLocals != null)
                    {
                        if (ServerSettings.Instance.Import.UseExistingFileWatchedStatus)
                        {
                            // Copy over watched states
                            foreach (var user in RepoFactory.JMMUser.GetAll())
                            {
                                var watchedVideo = videoLocals.FirstOrDefault(a =>
                                                                              a?.GetUserRecord(user.JMMUserID)?.WatchedDate != null);
                                // No files that are watched
                                if (watchedVideo == null)
                                {
                                    continue;
                                }

                                var watchedRecord = watchedVideo.GetUserRecord(user.JMMUserID);
                                var userrecord    = vidLocal.GetUserRecord(user.JMMUserID) ?? new VideoLocal_User
                                {
                                    JMMUserID    = user.JMMUserID,
                                    VideoLocalID = vidLocal.VideoLocalID,
                                };

                                userrecord.WatchedDate    = watchedRecord.WatchedDate;
                                userrecord.ResumePosition = watchedRecord.ResumePosition;

                                RepoFactory.VideoLocalUser.Save(userrecord);
                            }
                        }

                        if (ServerSettings.Instance.FileQualityFilterEnabled)
                        {
                            videoLocals.Sort(FileQualityFilter.CompareTo);
                            List <SVR_VideoLocal> keep = videoLocals
                                                         .Take(FileQualityFilter.Settings.MaxNumberOfFilesToKeep)
                                                         .ToList();
                            foreach (SVR_VideoLocal vl2 in keep)
                            {
                                videoLocals.Remove(vl2);
                            }
                            if (!FileQualityFilter.Settings.AllowDeletionOfImportedFiles &&
                                videoLocals.Contains(vidLocal))
                            {
                                videoLocals.Remove(vidLocal);
                            }
                            videoLocals = videoLocals.Where(a => !FileQualityFilter.CheckFileKeep(a)).ToList();

                            videoLocals.ForEach(a => a.Places.ForEach(b => b.RemoveAndDeleteFile()));
                        }
                    }

                    // update stats for groups and series
                    // update all the groups above this series in the heirarchy
                    SVR_AniDB_Anime.UpdateStatsByAnimeID(animeID);
                }
                else
                {
                    logger.Warn($"Unable to create AniDB_Anime for file: {vidLocal.FileName}");
                    logger.Warn($"Queuing GET for AniDB_Anime: {animeID}");
                    CommandRequest_GetAnimeHTTP animeCommand = new CommandRequest_GetAnimeHTTP(animeID, true, true);
                    animeCommand.Save();
                }
                vidLocal.Places.ForEach(a => { a.RenameAndMoveAsRequired(); });

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