diff --git a/Shoko.Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Utilities.cs b/Shoko.Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Utilities.cs index 229b6fec9..4b43eeecc 100644 --- a/Shoko.Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Utilities.cs +++ b/Shoko.Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Utilities.cs @@ -1088,48 +1088,24 @@ public string DeleteDuplicateFile(int duplicateFileID, int fileNumber) if (fileNumber == 1 || fileNumber == 2) { - string fullserverpath = null; - SVR_ImportFolder folder = null; + SVR_VideoLocal_Place place = null; switch (fileNumber) { case 1: - fullserverpath = df.GetFullServerPath1(); - folder = df.GetImportFolder1(); + place = + RepoFactory.VideoLocalPlace.GetByFilePathAndShareID(df.FilePathFile1, + df.ImportFolderIDFile1); break; case 2: - fullserverpath = df.GetFullServerPath2(); - folder = df.GetImportFolder2(); + place = + RepoFactory.VideoLocalPlace.GetByFilePathAndShareID(df.FilePathFile2, + df.ImportFolderIDFile2); break; } - if (folder == null) return "Unable to get Import Folder"; - if (fullserverpath == null) return "Unable to get Full Server Path"; + if (place == null) return "Unable to get VideoLocal_Place"; - IFileSystem fileSystem = folder.FileSystem; - if (fileSystem == null) - { - return "Unable to delete file, filesystem not found."; - } - FileSystemResult fr = fileSystem.Resolve(fullserverpath); - if (fr == null || !fr.IsOk) - { - RepoFactory.DuplicateFile.Delete(df); - return ""; - } - IFile file = fr.Result as IFile; - if (file == null) - { - logger.Error($"Seems '{fullserverpath}' is a directory."); - return $"Seems '{fullserverpath}' is a directory."; - } - FileSystemResult fs = file.Delete(false); - if (fs == null || !fs.IsOk) - { - logger.Error($"Unable to delete file '{fullserverpath}'"); - return $"Unable to delete file '{fullserverpath}'"; - } + place.RemoveAndDeleteFile(); } - - RepoFactory.DuplicateFile.Delete(df); return ""; } catch (Exception ex) diff --git a/Shoko.Server/Models/SVR_VideoLocal_Place.cs b/Shoko.Server/Models/SVR_VideoLocal_Place.cs index 4b49c2266..896ccb1c1 100644 --- a/Shoko.Server/Models/SVR_VideoLocal_Place.cs +++ b/Shoko.Server/Models/SVR_VideoLocal_Place.cs @@ -153,9 +153,6 @@ public void RemoveRecord() } else { - episodesToUpdate.AddRange(v.GetAnimeEpisodes()); - seriesToUpdate.AddRange(v.GetAnimeEpisodes().Select(a => a.GetAnimeSeries())); - using (var transaction = session.BeginTransaction()) { RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this); @@ -196,15 +193,14 @@ public void RemoveRecord() logger.Info("RemoveRecordsWithoutPhysicalFiles : {0}", FullServerPath); SVR_VideoLocal v = VideoLocal; - List eps = v?.GetAnimeEpisodes()?.Where(a => a != null).ToList(); - eps?.ForEach(a => episodesToUpdate.Add(a)); - eps?.Select(a => a.GetAnimeSeries()).ToList().ForEach(a => seriesToUpdate.Add(a)); - List dupFiles = RepoFactory.DuplicateFile.GetByFilePathAndImportFolder(FilePath, ImportFolderID); if (v?.Places?.Count <= 1) { + List eps = v?.GetAnimeEpisodes()?.Where(a => a != null).ToList(); + eps?.ForEach(episodesToUpdate.Add); + eps?.Select(a => a.GetAnimeSeries()).ToList().ForEach(seriesToUpdate.Add); using (var transaction = session.BeginTransaction()) { RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this); @@ -230,10 +226,8 @@ public void RemoveRecord() public IFile GetFile() { IFileSystem fs = ImportFolder.FileSystem; - if (fs == null) - return null; - FileSystemResult fobj = fs.Resolve(FullServerPath); - if (!fobj.IsOk || fobj.Result is IDirectory) + FileSystemResult fobj = fs?.Resolve(FullServerPath); + if (fobj == null || !fobj?.IsOk != true || fobj.Result is IDirectory) return null; return fobj.Result as IFile; } @@ -489,6 +483,7 @@ private bool MoveFileIfRequired() // this means it isn't a file, but something else, so don't retry return true; } + // find the default destination SVR_ImportFolder destFolder = null; foreach (SVR_ImportFolder fldr in RepoFactory.ImportFolder.GetAll() @@ -500,10 +495,6 @@ private bool MoveFileIfRequired() FileSystemResult fsresult = fs?.Resolve(fldr.ImportFolderLocation); if (fsresult == null || !fsresult.IsOk) continue; - string tempNewPath = Path.Combine(fldr.ImportFolderLocation, FilePath); - fsresult = fs.Resolve(tempNewPath); - if (fsresult.IsOk) continue; - destFolder = fldr; break; } @@ -517,6 +508,11 @@ private bool MoveFileIfRequired() // keep the original drop folder for later (take a copy, not a reference) SVR_ImportFolder dropFolder = this.ImportFolder; + // 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 = ""; + // we can only move the file if it has an anime associated with it List xrefs = this.VideoLocal.EpisodeCrossRefs; if (xrefs.Count == 0) return true; @@ -526,11 +522,6 @@ private bool MoveFileIfRequired() SVR_AnimeSeries series = RepoFactory.AnimeSeries.GetByAnimeID(xref.AnimeID); if (series == null) return true; - // 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 allEps = series.GetAnimeEpisodes() .OrderByDescending(a => a.AniDB_Episode.AirDate) @@ -663,10 +654,9 @@ private bool MoveFileIfRequired() { logger.Warn("Unable to DELETE file: {0} error {1}", this.FullServerPath, fr?.Error ?? String.Empty); + return false; } - this.ImportFolderID = tup.Item1.ImportFolderID; - this.FilePath = tup.Item2; - RepoFactory.VideoLocalPlace.Save(this); + RemoveRecord(); // check for any empty folders in drop folder // only for the drop folder @@ -678,6 +668,7 @@ private bool MoveFileIfRequired() RecursiveDeleteEmptyDirectories((IDirectory) dd.Result, true); } } + return true; } catch { @@ -696,7 +687,6 @@ private bool MoveFileIfRequired() } string originalFileName = this.FullServerPath; - this.ImportFolderID = tup.Item1.ImportFolderID; this.FilePath = tup.Item2; RepoFactory.VideoLocalPlace.Save(this); @@ -707,28 +697,26 @@ private bool MoveFileIfRequired() foreach (string subtitleFile in Utils.GetPossibleSubtitleFiles(originalFileName)) { FileSystemResult src = f.Resolve(subtitleFile); - if (src.IsOk && src.Result is IFile) + if (!src.IsOk || !(src.Result is IFile)) continue; + string newSubPath = Path.Combine(Path.GetDirectoryName(newFullServerPath), + ((IFile) src.Result).Name); + dst = f.Resolve(newSubPath); + if (dst.IsOk && dst.Result is IFile) { - string newSubPath = Path.Combine(Path.GetDirectoryName(newFullServerPath), - ((IFile) src.Result).Name); - dst = f.Resolve(newSubPath); - if (dst.IsOk && dst.Result is IFile) + FileSystemResult fr2 = src.Result.Delete(false); + if (!fr2.IsOk) { - FileSystemResult fr2 = src.Result.Delete(false); - if (!fr2.IsOk) - { - logger.Warn("Unable to DELETE file: {0} error {1}", subtitleFile, - fr2?.Error ?? String.Empty); - } + logger.Warn("Unable to DELETE file: {0} error {1}", subtitleFile, + fr2?.Error ?? String.Empty); } - else + } + else + { + FileSystemResult fr2 = ((IFile) src.Result).Move(destination); + if (!fr2.IsOk) { - FileSystemResult fr2 = ((IFile) src.Result).Move(destination); - if (!fr2.IsOk) - { - logger.Error("Unable to MOVE file: {0} to {1} error {2)", subtitleFile, - newSubPath, fr2?.Error ?? String.Empty); - } + logger.Error("Unable to MOVE file: {0} to {1} error {2)", subtitleFile, + newSubPath, fr2?.Error ?? String.Empty); } } } diff --git a/Shoko.Server/Repositories/Direct/DuplicateFileRepository.cs b/Shoko.Server/Repositories/Direct/DuplicateFileRepository.cs index 07fb1fd62..e22e48ebb 100644 --- a/Shoko.Server/Repositories/Direct/DuplicateFileRepository.cs +++ b/Shoko.Server/Repositories/Direct/DuplicateFileRepository.cs @@ -39,10 +39,12 @@ public List GetByFilePathAndImportFolder(string filePath, int fol using (var session = DatabaseFactory.SessionFactory.OpenSession()) { var dfiles = session - .CreateSQLQuery( - $"SELECT * FROM DuplicateFile WHERE (FilePathFile1 = :filePath OR FilePathFile2 = :filePath) AND (ImportFolderIDFile1 = :folderID OR ImportFolderIDFile2 = :folderID)") - .SetString("filePath", filePath) - .SetInt32("folderID", folderID) + .CreateCriteria(typeof(DuplicateFile)) + .Add(Restrictions.Or( + Restrictions.And(Restrictions.Eq("FilePathFile1", filePath), + Restrictions.Eq("ImportFolderIDFile1", folderID)), + Restrictions.And(Restrictions.Eq("FilePathFile2", filePath), + Restrictions.Eq("ImportFolderIDFile2", folderID)))) .List(); return dfiles.ToList(); }