public bool RefreshMediaInfo()
        {
            try
            {
                logger.Trace("Getting media info for: {0}", FullServerPath ?? VideoLocal_Place_ID.ToString());
                MediaContainer m = null;
                if (VideoLocal == null)
                {
                    logger.Error($"VideoLocal for {FullServerPath ?? VideoLocal_Place_ID.ToString()} failed to be retrived for MediaInfo");
                    return(false);
                }

                if (FullServerPath != null)
                {
                    if (GetFile() == null)
                    {
                        logger.Error($"File {FullServerPath ?? VideoLocal_Place_ID.ToString()} failed to be retrived for MediaInfo");
                        return(false);
                    }

                    string name = FullServerPath.Replace("/", $"{Path.DirectorySeparatorChar}");
                    m = Utilities.MediaInfoLib.MediaInfo.GetMediaInfo(name); //Mediainfo should have libcurl.dll for http
                    var duration = m?.GeneralStream?.Duration ?? 0;
                    if (duration == 0)
                    {
                        m = null;
                    }
                }


                if (m != null)
                {
                    SVR_VideoLocal info = VideoLocal;

                    List <TextStream> subs = SubtitleHelper.GetSubtitleStreams(this);
                    if (subs.Count > 0)
                    {
                        m.media.track.AddRange(subs);
                    }
                    info.Media = m;
                    return(true);
                }
                logger.Error($"File {FullServerPath ?? VideoLocal_Place_ID.ToString()} failed to read MediaInfo");
            }
            catch (Exception e)
            {
                logger.Error($"Unable to read the media information of file {FullServerPath ?? VideoLocal_Place_ID.ToString()} ERROR: {e}");
            }
            return(false);
        }
        // returns false if we should retry
        private bool MoveFileIfRequired(bool deleteEmpty = true)
        {
            // TODO move A LOT of this into renamer helper methods. A renamer can do them optionally
            if (!ServerSettings.Instance.Import.MoveOnImport)
            {
                logger.Trace($"Skipping move of \"{this.FullServerPath}\" as move on import is disabled");
                return(true);
            }

            // TODO Make this take an argument to disable removing empty dirs. It's slow, and should only be done if needed
            try
            {
                logger.Trace($"Attempting to MOVE file: \"{FullServerPath ?? VideoLocal_Place_ID.ToString()}\"");

                if (FullServerPath == null)
                {
                    logger.Error($"Could not find or access the file to move: {VideoLocal_Place_ID}");
                    return(true);
                }

                // check if this file is in the drop folder
                // otherwise we don't need to move it
                if (ImportFolder.IsDropSource == 0)
                {
                    logger.Trace($"Not moving file as it is NOT in the drop folder: \"{FullServerPath}\"");
                    return(true);
                }

                if (!File.Exists(FullServerPath))
                {
                    logger.Error($"Could not find or access the file to move: \"{FullServerPath}\"");
                    // this can happen due to file locks, so retry
                    return(false);
                }
                var sourceFile = new FileInfo(FullServerPath);

                // find the default destination
                (var destImpl, string newFolderPath) = RenameFileHelper.GetDestination(this, null);

                if (!(destImpl is SVR_ImportFolder destFolder))
                {
                    // In this case, an error string was returned, but we'll suppress it and give an error elsewhere
                    if (newFolderPath != null)
                    {
                        return(true);
                    }
                    logger.Error($"Could not find a valid destination: \"{FullServerPath}\"");
                    return(true);
                }

                // keep the original drop folder for later (take a copy, not a reference)
                SVR_ImportFolder dropFolder = ImportFolder;

                if (string.IsNullOrEmpty(newFolderPath))
                {
                    return(true);
                }

                // We've already resolved FullServerPath, so it doesn't need to be checked
                string newFilePath       = Path.Combine(newFolderPath, Path.GetFileName(FullServerPath));
                string newFullServerPath = Path.Combine(destFolder.ImportFolderLocation, newFilePath);

                var destFullTree = Path.Combine(destFolder.ImportFolderLocation, newFolderPath);
                if (!Directory.Exists(destFullTree))
                {
                    try
                    {
                        Directory.CreateDirectory(destFullTree);
                    }
                    catch (Exception e)
                    {
                        logger.Error(e);
                        return(true);
                    }
                }

                // Last ditch effort to ensure we aren't moving a file unto itself
                if (newFullServerPath.Equals(FullServerPath, StringComparison.InvariantCultureIgnoreCase))
                {
                    logger.Error($"Resolved to move \"{newFullServerPath}\" unto itself. NOT MOVING");
                    return(true);
                }

                var originalFileName = FullServerPath;
                var textStreams      = SubtitleHelper.GetSubtitleStreams(this);

                if (File.Exists(newFullServerPath))
                {
                    // A file with the same name exists at the destination.
                    // Handle Duplicate Files, A duplicate file record won't exist yet,
                    // so we'll check the old fashioned way
                    logger.Trace("A file already exists at the new location, checking it for duplicate");
                    var destVideoLocalPlace = RepoFactory.VideoLocalPlace.GetByFilePathAndImportFolderID(newFilePath,
                                                                                                         destFolder.ImportFolderID);
                    var destVideoLocal = destVideoLocalPlace?.VideoLocal;
                    if (destVideoLocal == null)
                    {
                        logger.Error("The existing file at the new location does not have a VideoLocal. Not moving");
                        return(true);
                    }
                    if (destVideoLocal.Hash == VideoLocal.Hash)
                    {
                        logger.Info($"Not moving file as it already exists at the new location, deleting source file instead: \"{FullServerPath}\" --- \"{newFullServerPath}\"");

                        // if the file already exists, we can just delete the source file instead
                        // this is safer than deleting and moving
                        try
                        {
                            sourceFile.Delete();
                        }
                        catch (Exception e)
                        {
                            logger.Warn($"Unable to DELETE file: \"{FullServerPath}\" error {e}");
                            RemoveRecord(false);

                            // check for any empty folders in drop folder
                            // only for the drop folder
                            if (dropFolder.IsDropSource != 1)
                            {
                                return(true);
                            }
                            RecursiveDeleteEmptyDirectories(dropFolder?.ImportFolderLocation, true);
                            return(true);
                        }
                    }

                    // Not a dupe, don't delete it
                    logger.Trace("A file already exists at the new location, checking it for version and group");
                    var destinationExistingAniDBFile = destVideoLocal.GetAniDBFile();
                    if (destinationExistingAniDBFile == null)
                    {
                        logger.Error("The existing file at the new location does not have AniDB info. Not moving.");
                        return(true);
                    }

                    var aniDBFile = VideoLocal.GetAniDBFile();
                    if (aniDBFile == null)
                    {
                        logger.Error("The file does not have AniDB info. Not moving.");
                        return(true);
                    }

                    if (destinationExistingAniDBFile.Anime_GroupName == aniDBFile.Anime_GroupName &&
                        destinationExistingAniDBFile.FileVersion < aniDBFile.FileVersion)
                    {
                        // This is a V2 replacing a V1 with the same name.
                        // Normally we'd let the Multiple Files Utility handle it, but let's just delete the V1
                        logger.Info("The existing file is a V1 from the same group. Replacing it.");
                        // Delete the destination
                        (bool success, string _) = destVideoLocalPlace.RemoveAndDeleteFile();
                        if (!success)
                        {
                            return(false);
                        }

                        // Move
                        ShokoServer.PauseWatchingFiles();
                        logger.Info($"Moving file from \"{FullServerPath}\" to \"{newFullServerPath}\"");
                        try
                        {
                            sourceFile.MoveTo(newFullServerPath);
                        }
                        catch (Exception e)
                        {
                            logger.Error($"Unable to MOVE file: \"{FullServerPath}\" to \"{newFullServerPath}\" error {e}");
                            ShokoServer.UnpauseWatchingFiles();
                            return(false);
                        }

                        // Handle Duplicate Files
                        var dups = RepoFactory.DuplicateFile.GetByFilePathAndImportFolder(FilePath, ImportFolderID).ToList();

                        foreach (var dup in dups)
                        {
                            // Move source
                            if (dup.FilePathFile1.Equals(FilePath) && dup.ImportFolderIDFile1 == ImportFolderID)
                            {
                                dup.FilePathFile1       = newFilePath;
                                dup.ImportFolderIDFile1 = destFolder.ImportFolderID;
                            }
                            else if (dup.FilePathFile2.Equals(FilePath) && dup.ImportFolderIDFile2 == ImportFolderID)
                            {
                                dup.FilePathFile2       = newFilePath;
                                dup.ImportFolderIDFile2 = destFolder.ImportFolderID;
                            }
                            // validate the dup file
                            // There are cases where a dup file was not cleaned up before, so we'll do it here, too
                            if (!dup.GetFullServerPath1()
                                .Equals(dup.GetFullServerPath2(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                RepoFactory.DuplicateFile.Save(dup);
                            }
                            else
                            {
                                RepoFactory.DuplicateFile.Delete(dup);
                            }
                        }

                        ImportFolderID = destFolder.ImportFolderID;
                        FilePath       = newFilePath;
                        RepoFactory.VideoLocalPlace.Save(this);

                        // check for any empty folders in drop folder
                        // only for the drop folder
                        if (dropFolder.IsDropSource == 1 && deleteEmpty)
                        {
                            RecursiveDeleteEmptyDirectories(dropFolder?.ImportFolderLocation, true);
                        }
                    }
                }
                else
                {
                    ShokoServer.PauseWatchingFiles();
                    logger.Info($"Moving file from \"{FullServerPath}\" to \"{newFullServerPath}\"");
                    try
                    {
                        sourceFile.MoveTo(newFullServerPath);
                    }
                    catch (Exception e)
                    {
                        logger.Error($"Unable to MOVE file: \"{FullServerPath}\" to \"{newFullServerPath}\" error {e}");
                        ShokoServer.UnpauseWatchingFiles();
                        return(false);
                    }

                    // Handle Duplicate Files
                    var dups = RepoFactory.DuplicateFile.GetByFilePathAndImportFolder(FilePath, ImportFolderID).ToList();

                    foreach (var dup in dups)
                    {
                        // Move source
                        if (dup.FilePathFile1.Equals(FilePath) && dup.ImportFolderIDFile1 == ImportFolderID)
                        {
                            dup.FilePathFile1       = newFilePath;
                            dup.ImportFolderIDFile1 = destFolder.ImportFolderID;
                        }
                        else if (dup.FilePathFile2.Equals(FilePath) && dup.ImportFolderIDFile2 == ImportFolderID)
                        {
                            dup.FilePathFile2       = newFilePath;
                            dup.ImportFolderIDFile2 = destFolder.ImportFolderID;
                        }
                        // validate the dup file
                        // There are cases where a dup file was not cleaned up before, so we'll do it here, too
                        if (!dup.GetFullServerPath1()
                            .Equals(dup.GetFullServerPath2(), StringComparison.InvariantCultureIgnoreCase))
                        {
                            RepoFactory.DuplicateFile.Save(dup);
                        }
                        else
                        {
                            RepoFactory.DuplicateFile.Delete(dup);
                        }
                    }

                    ImportFolderID = destFolder.ImportFolderID;
                    FilePath       = newFilePath;
                    RepoFactory.VideoLocalPlace.Save(this);

                    // check for any empty folders in drop folder
                    // only for the drop folder
                    if (dropFolder.IsDropSource == 1 && deleteEmpty)
                    {
                        RecursiveDeleteEmptyDirectories(dropFolder?.ImportFolderLocation, true);
                    }
                }

                try
                {
                    // move any subtitle files
                    foreach (TextStream subtitleFile in textStreams)
                    {
                        if (string.IsNullOrEmpty(subtitleFile.Filename))
                        {
                            continue;
                        }
                        var newParent = Path.GetDirectoryName(newFullServerPath);
                        var srcParent = Path.GetDirectoryName(originalFileName);
                        if (string.IsNullOrEmpty(newParent) || string.IsNullOrEmpty(srcParent))
                        {
                            continue;
                        }
                        var subPath = Path.Combine(srcParent, subtitleFile.Filename);
                        if (!File.Exists(subPath))
                        {
                            continue;
                        }
                        var    subFile    = new FileInfo(subPath);
                        string newSubPath = Path.Combine(newParent, subFile.Name);
                        if (File.Exists(newSubPath))
                        {
                            try
                            {
                                File.Delete(newSubPath);
                            }
                            catch (Exception e)
                            {
                                logger.Warn($"Unable to DELETE file: \"{subtitleFile}\" error {e}");
                            }
                        }

                        try
                        {
                            subFile.MoveTo(newSubPath);
                        }
                        catch (Exception e)
                        {
                            logger.Error($"Unable to MOVE file: \"{subtitleFile}\" to \"{newSubPath}\" error {e}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.Error(ex, ex.ToString());
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, $"Could not MOVE file: \"{FullServerPath ?? VideoLocal_Place_ID.ToString()}\" -- {ex}");
            }
            ShokoServer.UnpauseWatchingFiles();
            return(true);
        }
        public void RemoveAndDeleteFileWithOpenTransaction(ISession session, HashSet <SVR_AnimeSeries> seriesToUpdate)
        {
            // TODO Make this take an argument to disable removing empty dirs. It's slow, and should only be done if needed
            try
            {
                logger.Info("Deleting video local place record and file: {0}", (FullServerPath ?? VideoLocal_Place_ID.ToString()));


                if (!File.Exists(FullServerPath))
                {
                    logger.Info($"Unable to find file. Removing Record: {FullServerPath}");
                    RemoveRecordWithOpenTransaction(session, seriesToUpdate);
                    return;
                }

                try
                {
                    File.Delete(FullServerPath);
                }
                catch (Exception ex)
                {
                    if (ex is FileNotFoundException)
                    {
                        RecursiveDeleteEmptyDirectories(ImportFolder?.ImportFolderLocation, true);
                        RemoveRecordWithOpenTransaction(session, seriesToUpdate);
                        return;
                    }

                    logger.Error($"Unable to delete file '{FullServerPath}': {ex}");
                    return;
                }
                RecursiveDeleteEmptyDirectories(ImportFolder?.ImportFolderLocation, true);
                RemoveRecordWithOpenTransaction(session, seriesToUpdate);
                // For deletion of files from Trakt, we will rely on the Daily sync
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.ToString());
            }
        }
        public void RemoveRecordAndDeletePhysicalFile(bool deleteFolder = true)
        {
            logger.Info("Deleting video local place record and file: {0}", (FullServerPath ?? VideoLocal_Place_ID.ToString()));

            if (!File.Exists(FullServerPath))
            {
                logger.Info($"Unable to find file. Removing Record: {FullServerPath ?? FilePath}");
                RemoveRecord();
                return;
            }

            try
            {
                File.Delete(FullServerPath);
            }
            catch (FileNotFoundException)
            {
                if (deleteFolder)
                {
                    RecursiveDeleteEmptyDirectories(ImportFolder?.ImportFolderLocation, true);
                }
                RemoveRecord();
                return;
            }
            catch (Exception ex)
            {
                logger.Error($"Unable to delete file '{FullServerPath}': {ex}");
                throw;
            }
            if (deleteFolder)
            {
                RecursiveDeleteEmptyDirectories(ImportFolder?.ImportFolderLocation, true);
            }
            RemoveRecord();
        }
        public (bool, string) RemoveAndDeleteFile(bool deleteFolder = true)
        {
            // TODO Make this take an argument to disable removing empty dirs. It's slow, and should only be done if needed
            try
            {
                logger.Info("Deleting video local place record and file: {0}", (FullServerPath ?? VideoLocal_Place_ID.ToString()));

                if (!File.Exists(FullServerPath))
                {
                    logger.Info($"Unable to find file. Removing Record: {FullServerPath ?? FilePath}");
                    RemoveRecord();
                    return(true, string.Empty);
                }

                try
                {
                    File.Delete(FullServerPath);
                }
                catch (Exception ex)
                {
                    if (ex is FileNotFoundException)
                    {
                        if (deleteFolder)
                        {
                            RecursiveDeleteEmptyDirectories(ImportFolder?.ImportFolderLocation, true);
                        }
                        RemoveRecord();
                        return(true, string.Empty);
                    }

                    logger.Error($"Unable to delete file '{FullServerPath}': {ex}");
                    return(false, $"Unable to delete file '{FullServerPath}'");
                }
                if (deleteFolder)
                {
                    RecursiveDeleteEmptyDirectories(ImportFolder?.ImportFolderLocation, true);
                }
                RemoveRecord();
                // For deletion of files from Trakt, we will rely on the Daily sync
                return(true, string.Empty);
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.ToString());
                return(false, ex.Message);
            }
        }
        public void RemoveRecordWithOpenTransaction(ISession session, ICollection <SVR_AnimeSeries> seriesToUpdate, bool updateMyListStatus = true, bool removeDuplicateFileEntries = true)
        {
            logger.Info("Removing VideoLocal_Place record for: {0}", FullServerPath ?? VideoLocal_Place_ID.ToString());
            SVR_VideoLocal v = VideoLocal;

            List <DuplicateFile> dupFiles = null;

            if (!string.IsNullOrEmpty(FilePath) && removeDuplicateFileEntries)
            {
                dupFiles = RepoFactory.DuplicateFile.GetByFilePathAndImportFolder(FilePath, ImportFolderID);
            }

            if (v?.Places?.Count <= 1)
            {
                if (updateMyListStatus)
                {
                    CommandRequest_DeleteFileFromMyList cmdDel =
                        new CommandRequest_DeleteFileFromMyList(v.MyListID);
                    cmdDel.Save();
                }

                List <SVR_AnimeEpisode> eps = v?.GetAnimeEpisodes()?.Where(a => a != null).ToList();
                eps?.DistinctBy(a => a.AnimeSeriesID).Select(a => a.GetAnimeSeries()).ToList().ForEach(seriesToUpdate.Add);
                using (var transaction = session.BeginTransaction())
                {
                    RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this);
                    RepoFactory.VideoLocal.DeleteWithOpenTransaction(session, v);
                    dupFiles?.ForEach(a => RepoFactory.DuplicateFile.DeleteWithOpenTransaction(session, a));

                    transaction.Commit();
                }
            }
            else
            {
                using (var transaction = session.BeginTransaction())
                {
                    RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this);
                    dupFiles?.ForEach(a => RepoFactory.DuplicateFile.DeleteWithOpenTransaction(session, a));
                    transaction.Commit();
                }
            }
        }
예제 #7
0
        // returns false if we should retry
        private bool MoveFileIfRequired()
        {
            try
            {
                logger.Trace("Attempting to MOVE file: {0}", FullServerPath ?? VideoLocal_Place_ID.ToString());

                if (FullServerPath == null)
                {
                    logger.Error("Could not find or access the file to move: {0}",
                                 VideoLocal_Place_ID);
                    return(true);
                }

                // check if this file is in the drop folder
                // otherwise we don't need to move it
                if (ImportFolder.IsDropSource == 0)
                {
                    logger.Trace("Not moving file as it is NOT in the drop folder: {0}", FullServerPath);
                    return(true);
                }
                IFileSystem f = ImportFolder.FileSystem;
                if (f == null)
                {
                    logger.Trace("Unable to MOVE, filesystem not working: {0}", FullServerPath);
                    return(true);
                }

                FileSystemResult <IObject> fsrresult = f.Resolve(FullServerPath);
                if (fsrresult == null || !fsrresult.IsOk)
                {
                    logger.Error("Could not find or access the file to move: {0}", FullServerPath);
                    // this can happen due to file locks, so retry
                    return(false);
                }
                IFile source_file = fsrresult.Result as IFile;
                if (source_file == null)
                {
                    logger.Error("Could not move the file (it isn't a file): {0}", FullServerPath);
                    // this means it isn't a file, but something else, so don't retry
                    return(true);
                }

                // find the default destination
                (var destImpl, string newFullPath) = RenameFileHelper.GetRenamerWithFallback()?.GetDestinationFolder(this) ?? (null, null);

                if (!(destImpl is SVR_ImportFolder destFolder))
                {
                    // In this case, an error string was returned, but we'll suppress it and give an error elsewhere
                    if (newFullPath != null)
                    {
                        return(true);
                    }
                    logger.Error("Could not find a valid destination: {0}", FullServerPath);
                    return(true);
                }

                // keep the original drop folder for later (take a copy, not a reference)
                SVR_ImportFolder dropFolder = ImportFolder;

                if (string.IsNullOrEmpty(newFullPath))
                {
                    return(true);
                }

                // We've already resolved FullServerPath, so it doesn't need to be checked
                string relativeFilePath  = Path.Combine(newFullPath, Path.GetFileName(FullServerPath));
                string newFullServerPath = Path.Combine(destFolder.ImportFolderLocation, relativeFilePath);

                IDirectory destination;

                fsrresult = destFolder.FileSystem.Resolve(Path.Combine(destFolder.ImportFolderLocation, newFullPath));
                if (fsrresult != null && fsrresult.IsOk)
                {
                    destination = fsrresult.Result as IDirectory;
                }
                else
                {
                    //validate the directory tree.
                    destination = destFolder.BaseDirectory;
                    {
                        var dir = Path.GetDirectoryName(relativeFilePath);

                        foreach (var part in dir.Split(Path.DirectorySeparatorChar))
                        {
                            var wD = destination.Directories.FirstOrDefault(d => d.Name == part);
                            if (wD == null)
                            {
                                var result = destination.CreateDirectory(part, null);
                                if (!result.IsOk)
                                {
                                    logger.Error(
                                        $"Unable to create directory {part} in {destination.FullName}: {result.Error}");
                                    return(true);
                                }
                                destination = result.Result;
                                continue;
                            }

                            destination = wD;
                        }
                    }
                }


                // Last ditch effort to ensure we aren't moving a file unto itself
                if (newFullServerPath.Equals(FullServerPath, StringComparison.InvariantCultureIgnoreCase))
                {
                    logger.Error($"Resolved to move {newFullServerPath} unto itself. NOT MOVING");
                    return(true);
                }

                FileSystemResult <IObject> dst = f.Resolve(newFullServerPath);
                if (dst != null && dst.IsOk)
                {
                    logger.Info(
                        "Not moving file as it already exists at the new location, deleting source file instead: {0} --- {1}",
                        FullServerPath, newFullServerPath);

                    // if the file already exists, we can just delete the source file instead
                    // this is safer than deleting and moving
                    FileSystemResult fr = new FileSystemResult();
                    try
                    {
                        fr = source_file.Delete(false);
                        if (fr == null || !fr.IsOk)
                        {
                            logger.Warn("Unable to DELETE file: {0} error {1}", FullServerPath,
                                        fr?.Error ?? string.Empty);
                            return(false);
                        }
                        RemoveRecord();

                        // check for any empty folders in drop folder
                        // only for the drop folder
                        if (dropFolder.IsDropSource != 1)
                        {
                            return(true);
                        }
                        FileSystemResult <IObject> dd = f.Resolve(dropFolder.ImportFolderLocation);
                        if (dd != null && dd.IsOk && dd.Result is IDirectory)
                        {
                            RecursiveDeleteEmptyDirectories((IDirectory)dd.Result, true);
                        }
                        return(true);
                    }
                    catch
                    {
                        logger.Error("Unable to DELETE file: {0} error {1}", FullServerPath,
                                     fr?.Error ?? string.Empty);
                    }
                }
                else
                {
                    logger.Info("Moving file from {0} to {1}", FullServerPath, newFullServerPath);
                    FileSystemResult fr = source_file.Move(destination);
                    if (fr == null || !fr.IsOk)
                    {
                        logger.Error("Unable to MOVE file: {0} to {1} error {2}", FullServerPath,
                                     newFullServerPath, fr?.Error ?? "No Error String");
                        return(false);
                    }

/*
 *                  // Pause FileWatchDog
 *                  ShokoServer._pauseFileWatchDog.Reset();
 *                  foreach (System.IO.FileSystemEventArgs evt in ShokoServer.queueFileEvents)
 *                  {
 *                      try
 *                      {
 *                          // this shouldn't happend but w/e
 *                          if (evt?.ChangeType == System.IO.WatcherChangeTypes.Created)
 *                          {
 *                              // check if we know the fine by exact name
 *                              if (RepoFactory.VideoLocal.GetByName(Path.GetFileName(evt.Name)) != null)
 *                              {
 *                                  logger.Info("This file is known: {0}", evt.Name);
 *                                  // delete it from queue for hashing
 *                                  ShokoServer.queueFileEvents.Remove(evt);
 *                                  break;
 *                              }
 *                          }
 *                      }
 *                      catch { }
 *                  }
 *                  // Resume FileWatchDog
 *                  ShokoServer._pauseFileWatchDog.Set();
 */
                    string originalFileName = FullServerPath;

                    ImportFolderID = destFolder.ImportFolderID;
                    FilePath       = relativeFilePath;
                    RepoFactory.VideoLocalPlace.Save(this);

                    try
                    {
                        // move any subtitle files
                        foreach (string subtitleFile in Utils.GetPossibleSubtitleFiles(originalFileName))
                        {
                            FileSystemResult <IObject> src = f.Resolve(subtitleFile);
                            if (src == null || !src.IsOk || !(src.Result is IFile))
                            {
                                continue;
                            }
                            string newSubPath = Path.Combine(Path.GetDirectoryName(newFullServerPath),
                                                             ((IFile)src.Result).Name);
                            dst = f.Resolve(newSubPath);
                            if (dst != null && dst.IsOk && dst.Result is IFile)
                            {
                                FileSystemResult fr2 = src.Result.Delete(false);
                                if (fr2 == null || !fr2.IsOk)
                                {
                                    logger.Warn("Unable to DELETE file: {0} error {1}", subtitleFile,
                                                fr2?.Error ?? string.Empty);
                                }
                            }
                            else
                            {
                                FileSystemResult fr2 = ((IFile)src.Result).Move(destination);
                                if (fr2 == null || !fr2.IsOk)
                                {
                                    logger.Error("Unable to MOVE file: {0} to {1} error {2)", subtitleFile,
                                                 newSubPath, fr2?.Error ?? string.Empty);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, ex.ToString());
                    }

                    // check for any empty folders in drop folder
                    // only for the drop folder
                    if (dropFolder.IsDropSource == 1)
                    {
                        FileSystemResult <IObject> dd = f.Resolve(dropFolder.ImportFolderLocation);
                        if (dd != null && dd.IsOk && dd.Result is IDirectory)
                        {
                            RecursiveDeleteEmptyDirectories((IDirectory)dd.Result, true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string msg = $"Could not MOVE file: {FullServerPath ?? VideoLocal_Place_ID.ToString()} -- {ex}";
                logger.Error(ex, msg);
            }
            return(true);
        }
        public void RemoveRecord(bool updateMyListStatus = true)
        {
            logger.Info("Removing VideoLocal_Place record for: {0}", FullServerPath ?? VideoLocal_Place_ID.ToString());
            List <SVR_AnimeSeries> seriesToUpdate = new List <SVR_AnimeSeries>();
            SVR_VideoLocal         v        = VideoLocal;
            List <DuplicateFile>   dupFiles = null;

            if (!string.IsNullOrEmpty(FilePath))
            {
                dupFiles = RepoFactory.DuplicateFile.GetByFilePathAndImportFolder(FilePath, ImportFolderID);
            }

            using (var session = DatabaseFactory.SessionFactory.OpenSession())
            {
                if (v?.Places?.Count <= 1)
                {
                    if (updateMyListStatus)
                    {
                        CommandRequest_DeleteFileFromMyList cmdDel =
                            new CommandRequest_DeleteFileFromMyList(v.MyListID);
                        cmdDel.Save();
                    }

                    using (var transaction = session.BeginTransaction())
                    {
                        RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this);

                        seriesToUpdate.AddRange(v.GetAnimeEpisodes().DistinctBy(a => a.AnimeSeriesID)
                                                .Select(a => a.GetAnimeSeries()));
                        RepoFactory.VideoLocal.DeleteWithOpenTransaction(session, v);

                        dupFiles?.ForEach(a => RepoFactory.DuplicateFile.DeleteWithOpenTransaction(session, a));
                        transaction.Commit();
                    }
                }
                else
                {
                    using (var transaction = session.BeginTransaction())
                    {
                        RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this);
                        dupFiles?.ForEach(a => RepoFactory.DuplicateFile.DeleteWithOpenTransaction(session, a));
                        transaction.Commit();
                    }
                }
            }
            foreach (SVR_AnimeSeries ser in seriesToUpdate)
            {
                ser?.QueueUpdateStats();
            }
        }
예제 #9
0
        public void RemoveAndDeleteFileWithOpenTransaction(ISession session, HashSet <SVR_AnimeEpisode> episodesToUpdate, HashSet <SVR_AnimeSeries> seriesToUpdate)
        {
            try
            {
                logger.Info("Deleting video local place record and file: {0}", (FullServerPath ?? VideoLocal_Place_ID.ToString()));

                IFileSystem fileSystem = ImportFolder?.FileSystem;
                if (fileSystem == null)
                {
                    logger.Error("Unable to delete file, filesystem not found. Removing record.");
                    RemoveRecordWithOpenTransaction(session, episodesToUpdate, seriesToUpdate);
                    return;
                }
                if (FullServerPath == null)
                {
                    logger.Error("Unable to delete file, fullserverpath is null. Removing record.");
                    RemoveRecordWithOpenTransaction(session, episodesToUpdate, seriesToUpdate);
                    return;
                }
                FileSystemResult <IObject> fr = fileSystem.Resolve(FullServerPath);
                if (fr == null || !fr.IsOk)
                {
                    logger.Error($"Unable to find file. Removing Record: {FullServerPath}");
                    RemoveRecordWithOpenTransaction(session, episodesToUpdate, seriesToUpdate);
                    return;
                }
                IFile file = fr.Result as IFile;
                if (file == null)
                {
                    logger.Error($"Seems '{FullServerPath}' is a directory.");
                    RemoveRecordWithOpenTransaction(session, episodesToUpdate, seriesToUpdate);
                    return;
                }
                FileSystemResult fs = file.Delete(false);
                if (fs == null || !fs.IsOk)
                {
                    logger.Error($"Unable to delete file '{FullServerPath}'");
                    return;
                }
                RemoveRecordWithOpenTransaction(session, episodesToUpdate, seriesToUpdate);
                // For deletion of files from Trakt, we will rely on the Daily sync
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.ToString());
            }
        }
예제 #10
0
        public string RemoveAndDeleteFileWithMessage()
        {
            try
            {
                logger.Info("Deleting video local place record and file: {0}", (FullServerPath ?? VideoLocal_Place_ID.ToString()));

                IFileSystem fileSystem = ImportFolder?.FileSystem;
                if (fileSystem == null)
                {
                    logger.Error("Unable to delete file, filesystem not found. Removing record.");
                    RemoveRecord();
                    return("Unable to delete file, filesystem not found. Removing record.");
                }
                if (FullServerPath == null)
                {
                    logger.Error("Unable to delete file, fullserverpath is null. Removing record.");
                    RemoveRecord();
                    return("Unable to delete file, fullserverpath is null. Removing record.");
                }
                FileSystemResult <IObject> fr = fileSystem.Resolve(FullServerPath);
                if (fr == null || !fr.IsOk)
                {
                    logger.Error($"Unable to find file. Removing Record: {FullServerPath}");
                    RemoveRecord();
                    return($"Unable to find file. Removing Record: {FullServerPath}");
                }
                IFile file = fr.Result as IFile;
                if (file == null)
                {
                    logger.Error($"Seems '{FullServerPath}' is a directory.");
                    RemoveRecord();
                    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}'");
                }
                RemoveRecord();
                // For deletion of files from Trakt, we will rely on the Daily sync
                return("");
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.ToString());
                return(ex.Message);
            }
        }
예제 #11
0
        public bool RefreshMediaInfo()
        {
            try
            {
                logger.Trace("Getting media info for: {0}", FullServerPath ?? VideoLocal_Place_ID.ToString());
                Media m = null;
                List <Azure_Media> webmedias = AzureWebAPI.Get_Media(VideoLocal.ED2KHash);
                if (webmedias != null && webmedias.Count > 0 && webmedias.FirstOrDefault(a => a != null) != null)
                {
                    m = webmedias.FirstOrDefault(a => a != null).ToMedia();
                }
                if (m == null && FullServerPath != null)
                {
                    string name = (ImportFolder?.CloudID == null)
                        ? FullServerPath.Replace("/", "\\")
                        : ((IProvider)null).ReplaceSchemeHost(((IProvider)null).ConstructVideoLocalStream(0,
                                                                                                          VideoLocalID.ToString(), "file", false));
                    m = MediaConvert.Convert(name, GetFile()); //Mediainfo should have libcurl.dll for http
                    if (string.IsNullOrEmpty(m?.Duration))
                    {
                        m = null;
                    }
                    if (m != null)
                    {
                        AzureWebAPI.Send_Media(VideoLocal.ED2KHash, m);
                    }
                }


                if (m != null)
                {
                    SVR_VideoLocal info = VideoLocal;
                    FillVideoInfoFromMedia(info, m);

                    m.Id = VideoLocalID.ToString();
                    List <Stream> subs = SubtitleHelper.GetSubtitleStreams(this);
                    if (subs.Count > 0)
                    {
                        m.Parts[0].Streams.AddRange(subs);
                    }
                    foreach (Part p in m.Parts)
                    {
                        p.Id         = null;
                        p.Accessible = "1";
                        p.Exists     = "1";
                        bool vid = false;
                        bool aud = false;
                        bool txt = false;
                        foreach (Stream ss in p.Streams.ToArray())
                        {
                            if (ss.StreamType == "1" && !vid)
                            {
                                vid = true;
                            }
                            if (ss.StreamType == "2" && !aud)
                            {
                                aud         = true;
                                ss.Selected = "1";
                            }
                            if (ss.StreamType == "3" && !txt)
                            {
                                txt         = true;
                                ss.Selected = "1";
                            }
                        }
                    }
                    info.Media = m;
                    return(true);
                }
                logger.Error($"File {FullServerPath ?? VideoLocal_Place_ID.ToString()} does not exist, unable to read media information from it");
            }
            catch (Exception e)
            {
                logger.Error($"Unable to read the media information of file {FullServerPath ?? VideoLocal_Place_ID.ToString()} ERROR: {e}");
            }
            return(false);
        }
예제 #12
0
        public void RemoveRecordWithOpenTransaction(ISession session, ICollection <SVR_AnimeEpisode> episodesToUpdate,
                                                    ICollection <SVR_AnimeSeries> seriesToUpdate)
        {
            logger.Info("Removing VideoLocal_Place recoord for: {0}", FullServerPath ?? VideoLocal_Place_ID.ToString());
            SVR_VideoLocal v = VideoLocal;

            List <DuplicateFile> dupFiles =
                RepoFactory.DuplicateFile.GetByFilePathAndImportFolder(FilePath, ImportFolderID);

            if (v?.Places?.Count <= 1)
            {
                List <SVR_AnimeEpisode> 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);
                    RepoFactory.VideoLocal.DeleteWithOpenTransaction(session, v);
                    dupFiles.ForEach(a => RepoFactory.DuplicateFile.DeleteWithOpenTransaction(session, a));
                    transaction.Commit();
                }
                CommandRequest_DeleteFileFromMyList cmdDel =
                    new CommandRequest_DeleteFileFromMyList(v.Hash, v.FileSize);
                cmdDel.Save();
            }
            else
            {
                using (var transaction = session.BeginTransaction())
                {
                    RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this);
                    dupFiles.ForEach(a => RepoFactory.DuplicateFile.DeleteWithOpenTransaction(session, a));
                    transaction.Commit();
                }
            }
        }
예제 #13
0
        public void RemoveRecord()
        {
            logger.Info("Removing VideoLocal_Place recoord for: {0}", FullServerPath ?? VideoLocal_Place_ID.ToString());
            List <SVR_AnimeEpisode> episodesToUpdate = new List <SVR_AnimeEpisode>();
            List <SVR_AnimeSeries>  seriesToUpdate   = new List <SVR_AnimeSeries>();
            SVR_VideoLocal          v        = VideoLocal;
            List <DuplicateFile>    dupFiles =
                RepoFactory.DuplicateFile.GetByFilePathAndImportFolder(FilePath, ImportFolderID);

            using (var session = DatabaseFactory.SessionFactory.OpenSession())
            {
                if (v.Places.Count <= 1)
                {
                    episodesToUpdate.AddRange(v.GetAnimeEpisodes());
                    seriesToUpdate.AddRange(v.GetAnimeEpisodes().Select(a => a.GetAnimeSeries()));

                    using (var transaction = session.BeginTransaction())
                    {
                        RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this);
                        RepoFactory.VideoLocal.DeleteWithOpenTransaction(session, v);
                        dupFiles?.ForEach(a => RepoFactory.DuplicateFile.DeleteWithOpenTransaction(session, a));
                        transaction.Commit();
                    }
                    CommandRequest_DeleteFileFromMyList cmdDel =
                        new CommandRequest_DeleteFileFromMyList(v.Hash, v.FileSize);
                    cmdDel.Save();
                }
                else
                {
                    using (var transaction = session.BeginTransaction())
                    {
                        RepoFactory.VideoLocalPlace.DeleteWithOpenTransaction(session, this);
                        dupFiles.ForEach(a => RepoFactory.DuplicateFile.DeleteWithOpenTransaction(session, a));
                        transaction.Commit();
                    }
                }
            }
            episodesToUpdate = episodesToUpdate.DistinctBy(a => a.AnimeEpisodeID).ToList();
            foreach (SVR_AnimeEpisode ep in episodesToUpdate)
            {
                try
                {
                    RepoFactory.AnimeEpisode.Save(ep);
                }
                catch (Exception ex)
                {
                    LogManager.GetCurrentClassLogger().Error(ex, ex.ToString());
                }
            }
            seriesToUpdate = seriesToUpdate.DistinctBy(a => a.AnimeSeriesID).ToList();
            foreach (SVR_AnimeSeries ser in seriesToUpdate)
            {
                ser.QueueUpdateStats();
            }
        }