Exemple #1
0
        /// <summary>
        /// Main process method for the InnerBlock
        /// </summary>
        /// <remarks>
        /// - SingleResources are just passed to the next DataflowBlock
        /// - If it's not a SingleResource
        ///   - it finds all the files in the current directory,
        ///   - in case of a RefreshImport
        ///     - it deletes all the files in the MediaLibrary that do not exist anymore in the filesystem,
        ///     - it stores the DateOfLastImport of all the files in the <see cref="PendingImportResourceNewGen"/>
        /// </remarks>
        /// <param name="importResource"><see cref="PendingImportResourceNewGen"/> to be processed</param>
        /// <returns>
        /// a HashSet of <see cref="PendingImportResourceNewGen"/>s containing the current <see cref="PendingImportResource"/>
        /// after processing as well as <see cref="PendingImportResourceNewGen"/>s for all files in the current directory
        /// </returns>
        private async Task <IEnumerable <PendingImportResourceNewGen> > ProcessChanges(PendingImportResourceNewGen importResource)
        {
            var result = new HashSet <PendingImportResourceNewGen> {
                importResource
            };

            try
            {
                if (ImportJobInformation.JobType == ImportJobType.Refresh)
                {
                    // ReSharper disable once PossibleInvalidOperationException
                    IEnumerable <MediaItem> mediaItems = await GetUpdatableMediaItems(PROVIDERRESOURCE_IMPORTER_MIA_ID_ENUMERATION, null);

                    if (mediaItems != null)
                    {
                        foreach (MediaItem mi in mediaItems)
                        {
                            IList <MultipleMediaItemAspect> providerAspects = null;
                            if (MediaItemAspect.TryGetAspects(mi.Aspects, ProviderResourceAspect.Metadata, out providerAspects))
                            {
                                ResourcePath      path        = ResourcePath.Deserialize(providerAspects[0].GetAttributeValue <String>(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH));
                                Guid?             directoryId = providerAspects[0].GetAttributeValue <Guid?>(ProviderResourceAspect.ATTR_PARENT_DIRECTORY_ID);
                                IResourceAccessor ra;
                                if (path.TryCreateLocalResourceAccessor(out ra) && ra is IFileSystemResourceAccessor)
                                {
                                    IFileSystemResourceAccessor f   = ra as IFileSystemResourceAccessor;
                                    string       dirPath            = ResourcePathHelper.GetDirectoryName(ra.Path);
                                    ResourcePath dirRa              = ResourcePath.BuildBaseProviderPath(ra.ParentProvider.Metadata.ResourceProviderId, dirPath);
                                    PendingImportResourceNewGen pir = new PendingImportResourceNewGen(dirRa, f, ToString(), ParentImportJobController, directoryId, mi.MediaItemId);
                                    pir.DateOfLastImport = DateTime.MinValue; //Force update
                                    result.Add(pir);
                                }
                            }
                        }
                    }
                }
                return(result);
            }
            catch (TaskCanceledException)
            {
                return(result);
            }
            catch (Exception ex)
            {
                ServiceRegistration.Get <ILogger>().Warn("ImporterWorker.{0}.{1}: Error while processing {2}", ex, ParentImportJobController, ToString(), importResource);
                importResource.IsValid = false;
                return(result);
            }
        }
Exemple #2
0
        /// <summary>
        /// Tries to create a <see cref="IFileSystemResourceAccessor"/> for the directory of a given file.
        /// </summary>
        /// <param name="fsra">IFileSystemResourceAccessor of file.</param>
        /// <returns>IFileSystemResourceAccessor or <c>null</c>, if no fsra could be created.</returns>
        private static IFileSystemResourceAccessor GetContainingDirectory(IFileSystemResourceAccessor fsra)
        {
            string            filePath      = fsra.CanonicalLocalResourcePath.ToString();
            string            directoryPath = ResourcePathHelper.GetDirectoryName(filePath);
            IResourceAccessor metaFileAccessor;

            if (!ResourcePath.Deserialize(directoryPath).TryCreateLocalResourceAccessor(out metaFileAccessor))
            {
                return(null);
            }
            if (!(metaFileAccessor is IFileSystemResourceAccessor))
            {
                metaFileAccessor.Dispose();
                return(null);
            }
            return((IFileSystemResourceAccessor)metaFileAccessor);
        }
Exemple #3
0
        protected virtual async Task <bool> SaveSubtitleAsync(SubtitleInfo subtitle, IDictionary <BaseSubtitleMatch <TId>, byte[]> downloads, bool overwriteExisting)
        {
            var mediaFile         = subtitle.MediaFiles.First();
            var namingTemplate    = ResourcePath.GetFileNameWithoutExtension(mediaFile.NativeResourcePath.FileName);
            var templatePartMatch = _regexMultiPartVideo.Match(namingTemplate);

            foreach (var subtitleMatch in downloads.Keys)
            {
                var    subPartMatch = _regexMultiPartVideo.Match(subtitleMatch.ItemName);
                string subName      = namingTemplate;
                if (subPartMatch.Success && templatePartMatch.Success)
                {
                    if (!int.TryParse(templatePartMatch.Groups["disc"].Value, out var _) || !int.TryParse(subPartMatch.Groups["disc"].Value, out var partNum))
                    {
                        continue;
                    }

                    subName = _regexMultiPartVideo.Replace(namingTemplate, "${1}${2}${4}" + partNum + "${3}");
                }

                string       lang         = new CultureInfo(subtitleMatch.Language).EnglishName;
                var          dir          = ResourcePathHelper.GetDirectoryName(mediaFile.NativeResourcePath.Serialize());
                var          sub          = $"{subName}.{lang}{Path.GetExtension(subtitleMatch.ItemName)}";
                ResourcePath subtitlePath = ResourcePath.Deserialize(dir);

                //File based access
                var resLoc = new ResourceLocator(mediaFile.NativeSystemId, subtitlePath);
                using (IResourceAccessor mediaItemAccessor = resLoc.CreateAccessor())
                    using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                        using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess())
                        {
                            using (var stream = rah.LocalFsResourceAccessor.CreateOpenWrite(sub, overwriteExisting))
                            {
                                var bytes = downloads[subtitleMatch];
                                if (stream != null)
                                {
                                    await stream.WriteAsync(bytes, 0, bytes.Length);
                                }
                            }
                        }
            }
            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Tries to read a valid IMDB id from additional .nfo or .txt files.
        /// </summary>
        /// <param name="fsra">FileSystemResourceAccessor</param>
        /// <param name="imdbId">Returns a valid IMDB or <c>null</c></param>
        /// <returns>true if matched</returns>
        public static bool TryMatchImdbId(IFileSystemResourceAccessor fsra, out string imdbId)
        {
            imdbId = null;
            if (fsra == null)
            {
                return(false);
            }

            // First try to find a nfo file that has the same name as our main movie.
            if (fsra.IsFile)
            {
                foreach (string extension in NFO_EXTENSIONS)
                {
                    string metaFilePath = ResourcePathHelper.ChangeExtension(fsra.CanonicalLocalResourcePath.ToString(), extension);
                    if (TryRead(metaFilePath, out imdbId))
                    {
                        return(true);
                    }
                }
            }

            // Prepare a list of paths to check: for chained resource path we will also check relative parent paths (like for DVD-ISO files)
            List <string> pathsToCheck = new List <string> {
                fsra.CanonicalLocalResourcePath.ToString()
            };

            if (fsra.CanonicalLocalResourcePath.PathSegments.Count > 1)
            {
                string canocialPath = fsra.CanonicalLocalResourcePath.ToString();
                pathsToCheck.Add(canocialPath.Substring(0, canocialPath.LastIndexOf('>')));
            }

            // Then test for special named files, like "movie.nfo"
            foreach (string path in pathsToCheck)
            {
                foreach (string fileName in NFO_FILENAMES)
                {
                    string metaFilePath = ResourcePathHelper.GetDirectoryName(path);
                    metaFilePath = ResourcePathHelper.Combine(metaFilePath, fileName);
                    if (TryRead(metaFilePath, out imdbId))
                    {
                        return(true);
                    }
                }
            }

            // Now check siblings of movie for any IMDB id containing filename.
            // Morpheus_xx, 2014-01-04: disabled code because it leads to false detections if there are multiple video files in same folder. In this case the first
            // video with TT-number is wrongly used.
            // TODO: this part could be reworked based on different ideas:
            // - Exclude known video extensions from file name matching (this would require a reference to VideoMDE's settings for extension list)
            // - Only use folder lookup for chained resources, i.e. for a DVD-ISO, where any "TT000000.bla" is located next to it

            //IFileSystemResourceAccessor directoryFsra = null;
            //if (!fsra.IsFile)
            //  directoryFsra = fsra.Clone() as IFileSystemResourceAccessor;
            //if (fsra.IsFile)
            //  directoryFsra = GetContainingDirectory(fsra);

            //if (directoryFsra == null)
            //  return false;

            //using (directoryFsra)
            //  foreach (IFileSystemResourceAccessor file in directoryFsra.GetFiles())
            //    using (file)
            //      if (ImdbIdMatcher.TryMatchImdbId(file.ResourceName, out imdbId))
            //        return true;

            return(false);
        }
Exemple #5
0
        /// <summary>
        /// Tries to read a valid IMDB id from additional .nfo or .txt files.
        /// </summary>
        /// <param name="fsra">FileSystemResourceAccessor</param>
        /// <param name="imdbId">Returns a valid IMDB or <c>null</c></param>
        /// <returns>true if matched</returns>
        public static bool TryMatchImdbId(IFileSystemResourceAccessor fsra, out string imdbId)
        {
            imdbId = null;
            if (fsra == null)
            {
                return(false);
            }

            // First try to find a nfo file that has the same name as our main movie.
            if (fsra.IsFile)
            {
                foreach (string extension in NFO_EXTENSIONS)
                {
                    string metaFilePath = ResourcePathHelper.ChangeExtension(fsra.CanonicalLocalResourcePath.ToString(), extension);
                    if (TryRead(metaFilePath, out imdbId))
                    {
                        return(true);
                    }
                }
            }

            // Prepare a list of paths to check: for chained resource path we will also check relative parent paths (like for DVD-ISO files)
            List <string> pathsToCheck = new List <string> {
                fsra.CanonicalLocalResourcePath.ToString()
            };

            if (fsra.CanonicalLocalResourcePath.PathSegments.Count > 1)
            {
                string canocialPath = fsra.CanonicalLocalResourcePath.ToString();
                pathsToCheck.Add(canocialPath.Substring(0, canocialPath.LastIndexOf('>')));
            }

            // Then test for special named files, like "movie.nfo"
            foreach (string path in pathsToCheck)
            {
                foreach (string fileName in NFO_FILENAMES)
                {
                    string metaFilePath = ResourcePathHelper.GetDirectoryName(path);
                    metaFilePath = ResourcePathHelper.Combine(metaFilePath, fileName);
                    if (TryRead(metaFilePath, out imdbId))
                    {
                        return(true);
                    }
                }
            }

            // Now check siblings of movie for any IMDB id containing filename.
            IFileSystemResourceAccessor directoryFsra = null;

            if (fsra.IsDirectory)
            {
                directoryFsra = fsra.Clone() as IFileSystemResourceAccessor;
            }
            if (fsra.IsFile)
            {
                directoryFsra = GetContainingDirectory(fsra);
            }

            if (directoryFsra == null)
            {
                return(false);
            }

            using (directoryFsra)
                foreach (IFileSystemResourceAccessor file in directoryFsra.GetFiles())
                {
                    using (file)
                        if (ImdbIdMatcher.TryMatchImdbId(file.ResourceName, out imdbId))
                        {
                            return(true);
                        }
                }

            return(false);
        }