예제 #1
0
        public Media GetMediaFromUser(int userID)
        {
            Media n = null;

            if (Media == null)
            {
                SVR_VideoLocal_Place pl = GetBestVideoLocalPlace();
                if (pl?.FullServerPath != null)
                {
                    IFileSystem f = pl.ImportFolder.FileSystem;
                    FileSystemResult <IObject> src = f?.Resolve(pl.FullServerPath);
                    if (src != null && src.IsOk && src.Result is IFile)
                    {
                        if (pl.RefreshMediaInfo())
                        {
                            RepoFactory.VideoLocal.Save(pl.VideoLocal, true);
                        }
                    }
                }
            }
            if (Media == null)
            {
                return(null);
            }
            n = Media.DeepClone();
            if (n?.Parts == null)
            {
                return(n);
            }
            foreach (Part p in n.Parts)
            {
                string name = UrlSafe.Replace(Path.GetFileName(FileName), " ")
                              .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 = ((IProvider)null).ReplaceSchemeHost(
                    ((IProvider)null).ConstructVideoLocalStream(userID, VideoLocalID.ToString(), name, false));
                if (p.Streams == null)
                {
                    continue;
                }
                foreach (Stream s in p.Streams.Where(a => a.File != null && a.StreamType == "3").ToList())
                {
                    s.Key =
                        ((IProvider)null).ReplaceSchemeHost(
                            ((IProvider)null).ConstructFileStream(userID, s.File, false));
                }
            }
            return(n);
        }
예제 #2
0
        // returns false if we should retry
        private bool MoveFileIfRequired()
        {
            try
            {
                logger.Trace("Attempting to MOVE file: {0}", this.FullServerPath);

                // 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}", this.FullServerPath);
                    return(true);
                }
                IFileSystem f = this.ImportFolder.FileSystem;
                if (f == null)
                {
                    logger.Trace("Unable to MOVE, filesystem not working: {0}", this.FullServerPath);
                    return(true);
                }

                FileSystemResult <IObject> fsrresult = f.Resolve(FullServerPath);
                if (!fsrresult.IsOk)
                {
                    logger.Error("Could not find or access the file to move: {0}", this.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}", this.FullServerPath);
                    // 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()
                         .Where(a => a != null && a.CloudID == ImportFolder.CloudID).ToList())
                {
                    if (!fldr.FolderIsDropDestination)
                    {
                        continue;
                    }
                    if (fldr.FolderIsDropSource)
                    {
                        continue;
                    }
                    IFileSystem fs = fldr.FileSystem;
                    FileSystemResult <IObject> 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;
                }

                if (destFolder == null)
                {
                    logger.Error("Could not find a valid destination: {0}", this.FullServerPath);
                    return(true);
                }

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

                // we can only move the file if it has an anime associated with it
                List <CrossRef_File_Episode> xrefs = this.VideoLocal.EpisodeCrossRefs;
                if (xrefs.Count == 0)
                {
                    return(true);
                }
                CrossRef_File_Episode xref = xrefs[0];

                // find the series associated with this episode
                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 <SVR_AnimeEpisode> allEps = series.GetAnimeEpisodes()
                                                 .OrderByDescending(a => a.AniDB_Episode.AirDate)
                                                 .ToList();

                IDirectory destination = null;

                foreach (SVR_AnimeEpisode ep in allEps)
                {
                    // check if this episode belongs to more than one anime
                    // if it does we will ignore it
                    List <CrossRef_File_Episode> fileEpXrefs =
                        RepoFactory.CrossRef_File_Episode.GetByEpisodeID(ep.AniDB_EpisodeID);
                    int? animeID   = null;
                    bool crossOver = false;
                    foreach (CrossRef_File_Episode fileEpXref in fileEpXrefs)
                    {
                        if (!animeID.HasValue)
                        {
                            animeID = fileEpXref.AnimeID;
                        }
                        else
                        {
                            if (animeID.Value != fileEpXref.AnimeID)
                            {
                                crossOver = true;
                            }
                        }
                    }
                    if (crossOver)
                    {
                        continue;
                    }

                    foreach (SVR_VideoLocal vid in ep.GetVideoLocals()
                             .Where(a => a.Places.Any(b => b.ImportFolder.CloudID == destFolder.CloudID &&
                                                      b.ImportFolder.IsDropSource == 0)).ToList())
                    {
                        if (vid.VideoLocalID == this.VideoLocalID)
                        {
                            continue;
                        }

                        SVR_VideoLocal_Place place =
                            vid.Places.FirstOrDefault(a => a.ImportFolder.CloudID == destFolder.CloudID);
                        string thisFileName = place?.FullServerPath;
                        if (thisFileName == null)
                        {
                            continue;
                        }
                        string folderName = Path.GetDirectoryName(thisFileName);

                        FileSystemResult <IObject> dir = f.Resolve(folderName);
                        if (!dir.IsOk)
                        {
                            continue;
                        }
                        // ensure we aren't moving to the current directory
                        if (folderName.Equals(Path.GetDirectoryName(FullServerPath),
                                              StringComparison.InvariantCultureIgnoreCase))
                        {
                            continue;
                        }
                        destination = dir.Result as IDirectory;
                        // Not a directory
                        if (destination == null)
                        {
                            continue;
                        }
                        newFullPath   = folderName;
                        foundLocation = true;
                        break;
                    }
                    if (foundLocation)
                    {
                        break;
                    }
                }

                if (!foundLocation)
                {
                    // we need to create a new folder
                    string newFolderName = Utils.RemoveInvalidFolderNameCharacters(series.GetSeriesName());

                    newFullPath = Path.Combine(destFolder.ImportFolderLocation, newFolderName);
                    FileSystemResult <IObject> dirn = f.Resolve(newFullPath);
                    if (!dirn.IsOk)
                    {
                        dirn = f.Resolve(destFolder.ImportFolderLocation);
                        if (dirn.IsOk)
                        {
                            IDirectory d = (IDirectory)dirn.Result;
                            FileSystemResult <IDirectory> d2 = Task
                                                               .Run(async() => await d.CreateDirectoryAsync(newFolderName, null))
                                                               .Result;
                            destination = d2.Result;
                        }
                        else
                        {
                            logger.Error("Import folder couldn't be resolved: {0}", destFolder.ImportFolderLocation);
                            newFullPath = null;
                        }
                    }
                    else if (dirn.Result is IFile)
                    {
                        logger.Error("Destination folder is a file: {0}", newFolderName);
                        newFullPath = null;
                    }
                    else
                    {
                        destination = (IDirectory)dirn.Result;
                    }
                }

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

                // We've already resolved FullServerPath, so it doesn't need to be checked
                string newFullServerPath             = Path.Combine(newFullPath, Path.GetFileName(this.FullServerPath));
                Tuple <SVR_ImportFolder, string> tup = VideoLocal_PlaceRepository.GetFromFullPath(newFullServerPath);
                if (tup == null)
                {
                    logger.Error($"Unable to LOCATE file {newFullServerPath} inside the import folders");
                    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);
                }

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

                FileSystemResult <IObject> dst = f.Resolve(newFullServerPath);
                if (dst.IsOk)
                {
                    logger.Trace(
                        "Not moving file as it already exists at the new location, deleting source file instead: {0} --- {1}",
                        this.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.IsOk)
                        {
                            logger.Warn("Unable to DELETE file: {0} error {1}", this.FullServerPath,
                                        fr?.Error ?? String.Empty);
                        }
                        this.ImportFolderID = tup.Item1.ImportFolderID;
                        this.FilePath       = tup.Item2;
                        RepoFactory.VideoLocalPlace.Save(this);

                        // 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
                    {
                        logger.Error("Unable to DELETE file: {0} error {1}", this.FullServerPath,
                                     fr?.Error ?? String.Empty);
                    }
                }
                else
                {
                    FileSystemResult fr = source_file.Move(destination);
                    if (!fr.IsOk)
                    {
                        logger.Error("Unable to MOVE file: {0} to {1} error {2}", this.FullServerPath,
                                     newFullServerPath, fr?.Error ?? "No Error String");
                        return(false);
                    }
                    string originalFileName = this.FullServerPath;


                    this.ImportFolderID = tup.Item1.ImportFolderID;
                    this.FilePath       = tup.Item2;
                    RepoFactory.VideoLocalPlace.Save(this);

                    try
                    {
                        // move any subtitle files
                        foreach (string subtitleFile in Utils.GetPossibleSubtitleFiles(originalFileName))
                        {
                            FileSystemResult <IObject> src = f.Resolve(subtitleFile);
                            if (src.IsOk && src.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)
                                    {
                                        logger.Warn("Unable to DELETE file: {0} error {1}", subtitleFile,
                                                    fr2?.Error ?? String.Empty);
                                    }
                                }
                                else
                                {
                                    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);
                                    }
                                }
                            }
                        }
                    }
                    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: {this.FullServerPath} -- {ex.ToString()}";
                logger.Error(ex, msg);
            }
            return(true);
        }