diff --git a/Shoko.Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Utilities.cs b/Shoko.Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Utilities.cs index 39e94bc3b..5e4995f02 100644 --- a/Shoko.Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Utilities.cs +++ b/Shoko.Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Utilities.cs @@ -613,7 +613,7 @@ public CL_VideoLocal_Renamed RenameAndMoveFile(int videoLocalID, string scriptNa ret.VideoLocal = null; ret.Success = false; ret.NewFileName = errorString; - ShokoServer.StartWatchingFiles(); + ShokoServer.StartWatchingFiles(false); return ret; } vid.FileName = name; @@ -630,7 +630,7 @@ public CL_VideoLocal_Renamed RenameAndMoveFile(int videoLocalID, string scriptNa ret.NewFileName = $"ERROR: {ex.Message}"; ret.Success = false; } - ShokoServer.StartWatchingFiles(); + ShokoServer.StartWatchingFiles(false); return ret; } diff --git a/Shoko.Server/AniDBHelper.cs b/Shoko.Server/AniDBHelper.cs index 79bd5c015..57f10aa45 100644 --- a/Shoko.Server/AniDBHelper.cs +++ b/Shoko.Server/AniDBHelper.cs @@ -1028,13 +1028,19 @@ public SVR_AniDB_Anime GetAnimeInfoHTTP(ISession session, int animeID, bool forc SVR_AniDB_Anime anime; ISessionWrapper sessionWrapper = session.Wrap(); + anime = RepoFactory.AniDB_Anime.GetByAnimeID(sessionWrapper, animeID); bool skip = true; - if (forceRefresh) - skip = false; - else + bool animeRecentlyUpdated = false; + if (anime != null) { - anime = RepoFactory.AniDB_Anime.GetByAnimeID(sessionWrapper, animeID); - if (anime == null) skip = false; + TimeSpan ts = DateTime.Now - anime.DateTimeUpdated; + if (ts.TotalHours < 4) animeRecentlyUpdated = true; + } + if (!animeRecentlyUpdated) + { + if (forceRefresh) + skip = false; + else if (anime == null) skip = false; } if (skip) diff --git a/Shoko.Server/Commands/Import/CommandRequest_HashFile.cs b/Shoko.Server/Commands/Import/CommandRequest_HashFile.cs index 449aad7ed..f78d10753 100644 --- a/Shoko.Server/Commands/Import/CommandRequest_HashFile.cs +++ b/Shoko.Server/Commands/Import/CommandRequest_HashFile.cs @@ -146,7 +146,7 @@ private SVR_VideoLocal_Place ProcessFile_LocalInfo() { numAttempts++; Thread.Sleep(1000); - Console.WriteLine($"Attempt # {numAttempts}"); + Console.WriteLine($@"Attempt # {numAttempts}"); } // if we failed to access the file, get ouuta here @@ -181,18 +181,22 @@ private SVR_VideoLocal_Place ProcessFile_LocalInfo() if (vlocalplace.FullServerPath == null) { - if (vlocal.Places.Count == 1) RepoFactory.VideoLocal.Delete(vlocal); + if (vlocal.Places.Count == 1) + { + RepoFactory.VideoLocal.Delete(vlocal); + vlocal = null; + } RepoFactory.VideoLocalPlace.Delete(vlocalplace); vlocalplace = null; - vlocal = null; - } else if (ForceHash) + } + if (vlocal != null && ForceHash) { vlocal.FileSize = filesize; vlocal.DateTimeUpdated = DateTime.Now; } } - if (vlocalplace == null) + if (vlocal == null) { logger.Trace("VideoLocal, creating temporary record"); vlocal = new SVR_VideoLocal @@ -208,13 +212,18 @@ private SVR_VideoLocal_Place ProcessFile_LocalInfo() IsIgnored = 0, IsVariation = 0 }; + } + if (vlocalplace == null) + { vlocalplace = new SVR_VideoLocal_Place { FilePath = filePath, ImportFolderID = nshareID, ImportFolderType = folder.ImportFolderType }; + // Male sure we have an ID + RepoFactory.VideoLocalPlace.Save(vlocalplace); } // check if we need to get a hash this file diff --git a/Shoko.Server/Commands/Import/CommandRequest_ProcessFile.cs b/Shoko.Server/Commands/Import/CommandRequest_ProcessFile.cs index 54b9ccb45..c595e458d 100644 --- a/Shoko.Server/Commands/Import/CommandRequest_ProcessFile.cs +++ b/Shoko.Server/Commands/Import/CommandRequest_ProcessFile.cs @@ -8,6 +8,7 @@ using Shoko.Models.Server; using Shoko.Server.Commands.AniDB; using NutzCode.CloudFileSystem; +using Pri.LongPath; using Shoko.Commons.Queue; using Shoko.Models.Queue; using Shoko.Server.Models; @@ -113,36 +114,49 @@ private void ProcessFile_AniDB(SVR_VideoLocal vidLocal) { // get info from AniDB logger.Debug("Getting AniDB_File record from AniDB...."); - Raw_AniDB_File fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vidLocal); - if (fileInfo != null) - { - // check if we already have a record - aniFile = RepoFactory.AniDB_File.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); - if (aniFile == null) - aniFile = new SVR_AniDB_File(); + // 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; + } - SVR_AniDB_File.Populate(aniFile, fileInfo); + if (ForceAniDB) + { + Raw_AniDB_File fileInfo = ShokoService.AnidbProcessor.GetFileInfo(vidLocal); + if (fileInfo != null) + { + SVR_AniDB_File.Populate(aniFile, fileInfo); + if (!string.IsNullOrEmpty(fileInfo.OtherEpisodesRAW)) + { + string[] epIDs = fileInfo.OtherEpisodesRAW.Split(','); + foreach (string epid in epIDs) + { + if (!int.TryParse(epid, out int id)) continue; + CommandRequest_GetEpisode cmdEp = new CommandRequest_GetEpisode(id); + cmdEp.Save(); + } + } + } + else aniFile = null; + } + if (aniFile != null) + { //overwrite with local file name - string localFileName = vidLocal.FileName; + 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); - if (!string.IsNullOrEmpty(fileInfo.OtherEpisodesRAW)) - { - string[] epIDs = fileInfo.OtherEpisodesRAW.Split(','); - foreach (string epid in epIDs) - { - if (!int.TryParse(epid, out int id)) continue; - CommandRequest_GetEpisode cmdEp = new CommandRequest_GetEpisode(id); - cmdEp.Save(); - } - } - animeID = aniFile.AnimeID; } } @@ -170,12 +184,14 @@ private void ProcessFile_AniDB(SVR_VideoLocal vidLocal) vidLocal.ED2KHash); return; } + string fileName = vidLocal.GetBestVideoLocalPlace().FullServerPath; + fileName = !string.IsNullOrEmpty(fileName) ? Path.GetFileName(fileName) : vidLocal.FileName; foreach (Shoko.Models.Azure.Azure_CrossRef_File_Episode xref in xrefs) { CrossRef_File_Episode xrefEnt = new CrossRef_File_Episode { Hash = vidLocal.ED2KHash, - FileName = vidLocal.FileName, + FileName = fileName, FileSize = vidLocal.FileSize, CrossRefSource = (int)CrossRefSource.WebCache, AnimeID = xref.AnimeID, diff --git a/Shoko.Server/Models/SVR_VideoLocal_Place.cs b/Shoko.Server/Models/SVR_VideoLocal_Place.cs index 2535a5dcb..b7006637f 100644 --- a/Shoko.Server/Models/SVR_VideoLocal_Place.cs +++ b/Shoko.Server/Models/SVR_VideoLocal_Place.cs @@ -122,7 +122,7 @@ private bool RenameFile() { logger.Info( $"Renaming file FAILED! From ({fullFileName}) to ({newFullName}) - {r?.Error ?? "Result is null"}"); - ShokoServer.StartWatchingFiles(); + ShokoServer.StartWatchingFiles(false); return false; } @@ -131,7 +131,7 @@ private bool RenameFile() if (tup == null) { logger.Error($"Unable to LOCATE file {newFullName} inside the import folders"); - ShokoServer.StartWatchingFiles(); + ShokoServer.StartWatchingFiles(false); return false; } @@ -178,7 +178,7 @@ private bool RenameFile() logger.Info($"Renaming file FAILED! From ({fullFileName}) to ({newFullName}) - {ex.Message}"); logger.Error(ex, ex.ToString()); } - ShokoServer.StartWatchingFiles(); + ShokoServer.StartWatchingFiles(false); return true; } @@ -693,8 +693,8 @@ public string MoveWithResultString(FileSystemResult fileSystemResult, s { logger.Error("Unable to MOVE file: {0} to {1} error {2}", FullServerPath, newFullServerPath, fr?.Error ?? "No Error String"); - ShokoServer.StartWatchingFiles(); - return "ERROR: " + fr?.Error ?? "Error moving filebut no error string"; + ShokoServer.StartWatchingFiles(false); + return "ERROR: " + (fr?.Error ?? "Error moving file, but no error string"); } string originalFileName = FullServerPath; @@ -746,7 +746,7 @@ public string MoveWithResultString(FileSystemResult fileSystemResult, s if (dd != null && dd.IsOk && dd.Result is IDirectory) RecursiveDeleteEmptyDirectories((IDirectory) dd.Result, true); } - ShokoServer.StartWatchingFiles(); + ShokoServer.StartWatchingFiles(false); return newFolderPath; } @@ -905,7 +905,7 @@ private bool MoveFileIfRequired() { logger.Error("Unable to MOVE file: {0} to {1} error {2}", FullServerPath, newFullServerPath, fr?.Error ?? "No Error String"); - ShokoServer.StartWatchingFiles(); + ShokoServer.StartWatchingFiles(false); return false; } @@ -958,7 +958,7 @@ private bool MoveFileIfRequired() if (dd != null && dd.IsOk && dd.Result is IDirectory) RecursiveDeleteEmptyDirectories((IDirectory) dd.Result, true); } - ShokoServer.StartWatchingFiles(); + ShokoServer.StartWatchingFiles(false); } } catch (Exception ex) diff --git a/Shoko.Server/Repositories/Cached/VideoLocal_PlaceRepository.cs b/Shoko.Server/Repositories/Cached/VideoLocal_PlaceRepository.cs index 260f7eda2..dcdedad85 100644 --- a/Shoko.Server/Repositories/Cached/VideoLocal_PlaceRepository.cs +++ b/Shoko.Server/Repositories/Cached/VideoLocal_PlaceRepository.cs @@ -56,6 +56,10 @@ public List GetByFilePathAndImportFolderType(string filePa public override void Delete(SVR_VideoLocal_Place obj) { + // Remove associated duplicate file records + var dups = RepoFactory.DuplicateFile.GetByFilePathAndImportFolder(obj.FilePath, obj.ImportFolderID); + if (dups != null && dups.Count > 0) dups.ForEach(RepoFactory.DuplicateFile.Delete); + base.Delete(obj); foreach (SVR_AnimeEpisode ep in obj.VideoLocal.GetAnimeEpisodes()) { diff --git a/Shoko.Server/ShokoServer.cs b/Shoko.Server/ShokoServer.cs index c62331263..2aede6b79 100644 --- a/Shoko.Server/ShokoServer.cs +++ b/Shoko.Server/ShokoServer.cs @@ -1351,7 +1351,7 @@ static void AutoUpdateTimer_Elapsed(object sender, ElapsedEventArgs e) Importer.SendUserInfoUpdate(false); } - public static void StartWatchingFiles() + public static void StartWatchingFiles(bool log = true) { StopWatchingFiles(); StopCloudWatchTimer(); @@ -1361,13 +1361,13 @@ public static void StartWatchingFiles() { try { - if (share.FolderIsWatched) + if (share.FolderIsWatched && log) { logger.Info($"Watching ImportFolder: {share.ImportFolderName} || {share.ImportFolderLocation}"); } if (share.CloudID == null && Directory.Exists(share.ImportFolderLocation) && share.FolderIsWatched) { - logger.Info($"Parsed ImportFolderLocation: {share.ImportFolderLocation}"); + if (log) logger.Info($"Parsed ImportFolderLocation: {share.ImportFolderLocation}"); RecoveringFileSystemWatcher fsw = new RecoveringFileSystemWatcher { Path = share.ImportFolderLocation @@ -1385,7 +1385,7 @@ public static void StartWatchingFiles() } else if (!share.FolderIsWatched) { - logger.Info("ImportFolder found but not watching: {0} || {1}", share.ImportFolderName, + if (log) logger.Info("ImportFolder found but not watching: {0} || {1}", share.ImportFolderName, share.ImportFolderLocation); } }