/// <summary>
 /// Creates and initializes an new instance.
 /// </summary>
 /// <param name="resourceAccessor">The resource accessor to the media item to be handled by the instance.</param>
 /// <returns>The new instance.</returns>
 public static BassMODFileInputSource Create(IFileSystemResourceAccessor resourceAccessor)
 {
   resourceAccessor.PrepareStreamAccess();
   BassMODFileInputSource inputSource = new BassMODFileInputSource(resourceAccessor);
   inputSource.Initialize();
   return inputSource;
 }
 /// <summary>
 /// Creates a new instance of this class which is based on the given <paramref name="baseAccessor"/>.
 /// </summary>
 /// <param name="key">Key which is used for this instance.</param>
 /// <param name="baseAccessor">Filesystem resource to mound.</param>
 public MountingDataProxy(string key, IFileSystemResourceAccessor baseAccessor)
 {
   _key = key;
   _baseAccessor = baseAccessor;
   if (!MountResource())
     throw new EnvironmentException("Cannot mount resource '{0}' to local file system", baseAccessor);
 }
 /// <summary>
 /// Constructs a <see cref="ResourceAccessorTextureImageSource"/> for the given data.
 /// </summary>
 /// <param name="resourceAccessor">The resource accessor to load the texture data from.</param>
 /// <param name="rotation">Desired rotation for the given image.</param>
 public ResourceAccessorTextureImageSource(IFileSystemResourceAccessor resourceAccessor, RightAngledRotation rotation)
 {
   _key = resourceAccessor.CanonicalLocalResourcePath.Serialize();
   _resourceAccessor = resourceAccessor;
   _stream = _resourceAccessor.OpenRead();
   _rotation = rotation;
 }
Beispiel #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;
    }
 public void Dispose()
 {
   if (_baseAccessor == null)
     // Already disposed
     return;
   if (!UnmountResource())
     // The ownership was transferred to the resource mounting service, so if unmounting was succesful, we must not dispose our base accessor
     _baseAccessor.Dispose();
   _baseAccessor = null;
 }
Beispiel #6
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.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;
    }
 /// <summary>
 /// Returns all child directories of the given directory.
 /// </summary>
 /// <remarks>
 /// This will return all native child directories of the given directory together with all virtual child
 /// directories. The native child directories are taken directly from the given <paramref name="directoryAccessor"/>,
 /// the virtual child directories are obtained by taking the root directories of each chained resource provider applied
 /// to the child files of the given directory.
 /// If, for example, the given <paramref name="directoryAccessor"/> contains a child directory "A" and a child
 /// archive file "B" which can work as input for an installed archive provider, providing the root directory "C"
 /// of that archive, this method will return the resource accessors for directories "A" and "C".
 /// </remarks>
 /// <param name="directoryAccessor">Directory resource accessor to get all child directories for.</param>
 /// <param name="showSystemResources">If set to <c>true</c>, system resources like the virtual drives and directories of the
 /// <see cref="IResourceMountingService"/> will also be returned, else removed from the result value.</param>
 /// <returns>Collection of directory accessors for all native and virtual child directories or <c>null</c>,
 /// if the given <paramref name="directoryAccessor"/> does not point to a directory and
 /// if there is no chained resource provider to unfold the given file.</returns>
 public static ICollection<IFileSystemResourceAccessor> GetChildDirectories(IFileSystemResourceAccessor directoryAccessor, bool showSystemResources)
 {
   IResourceMountingService resourceMountingService = ServiceRegistration.Get<IResourceMountingService>();
   IFileSystemResourceAccessor chainedResourceAccesor; // Needed in multiple source locations, that's why we declare it here
   
   // If directoryAccessor points to a directory, we return all actual subdirectories and the virtual subdirectories
   // we can create by using all available ChainedResourceProviders on all contained files.
   if (!directoryAccessor.IsFile)
   {
     ICollection<IFileSystemResourceAccessor> childDirectories = directoryAccessor.GetChildDirectories();
     ICollection<IFileSystemResourceAccessor> result = new List<IFileSystemResourceAccessor>();
     if (childDirectories != null)
       // Directories are maybe filtered and then just added
       foreach (IFileSystemResourceAccessor childDirectoryAccessor in childDirectories)
       {
         if (!showSystemResources && resourceMountingService.IsVirtualResource(childDirectoryAccessor.CanonicalLocalResourcePath))
         {
           childDirectoryAccessor.Dispose();
           continue;
         }
         result.Add(childDirectoryAccessor);
       }
     ICollection<IFileSystemResourceAccessor> files = directoryAccessor.GetFiles();
     if (files != null)
       // For files, we try to chain up chained resource providers
       foreach (IFileSystemResourceAccessor fileAccessor in files)
         using (fileAccessor)
         {
           if (!showSystemResources && resourceMountingService.IsVirtualResource(fileAccessor.CanonicalLocalResourcePath))
             continue;
           if (TryUnfold(fileAccessor, out chainedResourceAccesor))
             if (!chainedResourceAccesor.IsFile)
               result.Add(chainedResourceAccesor);
             else
               chainedResourceAccesor.Dispose();
           // Simply ignore files because we only want to return directories
         }
     return result;
   }
   
   // Try to unfold file resource
   if (TryUnfold(directoryAccessor, out chainedResourceAccesor))
   {
     if (!chainedResourceAccesor.IsFile)
       return new List<IFileSystemResourceAccessor>(new IFileSystemResourceAccessor[] {chainedResourceAccesor});
     chainedResourceAccesor.Dispose();
     return new List<IFileSystemResourceAccessor>();
   }
   return null;
 }
    private DateTime _dateOfLastImport; // only valid for refresh imports

    #endregion

    #region Constructor

    public PendingImportResourceNewGen(ResourcePath parentDirectory, IFileSystemResourceAccessor resourceAccessor, String currentBlock, ImportJobController parentImportJobController, Guid? parentDirectoryId = null, Guid? mediaItemId = null)
    {
      _parentDirectoryId = parentDirectoryId;
      _mediaItemId = mediaItemId;
      _parentDirectoryResourcePathString = (parentDirectory == null) ? "" : parentDirectory.Serialize();
      _resourceAccessor = resourceAccessor;      
      _currentBlock = currentBlock;
      _parentImportJobController = parentImportJobController;
      _pendingImportResourceNumber = _parentImportJobController.GetNumberOfNextPendingImportResource();

      _isValid = (_resourceAccessor != null);

      _parentImportJobController.RegisterPendingImportResource(this);
    }
 public virtual void Dispose()
 {
   foreach (FileHandle handle in _fileHandles)
     handle.Cleanup();
   if (_resourceAccessor != null)
     try
     {
       _resourceAccessor.Dispose();
     }
     catch (Exception e)
     {
       ServiceRegistration.Get<ILogger>().Warn("Dokan virtual filesystem resource: Error disposing resource accessor '{0}'", e, _resourceAccessor);
     }
   _resourceAccessor = null;
 }
 public ZipResourceProxy(string key, IFileSystemResourceAccessor zipFileAccessor)
 {
   _key = key;
   _zipFileResourceAccessor = zipFileAccessor;
   _zipFileStream = _zipFileResourceAccessor.OpenRead(); // Not sure if the ZipFile closes the stream appropriately, so we keep a reference to it
   try
   {
     _zipFile = new ZipFile(_zipFileStream);
   }
   catch
   {
     _zipFileStream.Dispose();
     throw;
   }
 }
    public IsoResourceProxy(string key, IFileSystemResourceAccessor isoFileResourceAccessor)
    {
      _key = key;
      _isoFileResourceAccessor = isoFileResourceAccessor;

      _underlayingStream = _isoFileResourceAccessor.OpenRead();
      try
      {
        _diskFileSystem = GetFileSystem(_underlayingStream);
      }
      catch
      {
        _underlayingStream.Dispose();
        throw;
      }
    }
 public static bool ConnectFileSystem(string nativeSystemId, ResourcePath nativeResourcePath, out IFileSystemResourceAccessor result)
 {
   IRemoteResourceInformationService rris = ServiceRegistration.Get<IRemoteResourceInformationService>();
   result = null;
   bool isFileSystemResource;
   bool isFile;
   string resourcePathName;
   string resourceName;
   long size;
   DateTime lastChanged;
   if (!rris.GetResourceInformation(nativeSystemId, nativeResourcePath, out isFileSystemResource, out isFile,
       out resourcePathName, out resourceName, out lastChanged, out size) || !isFileSystemResource)
     return false;
   result = new RemoteFileSystemResourceAccessor(nativeSystemId, nativeResourcePath, isFile,
       resourcePathName, resourceName, size, lastChanged);
   return true;
 }
 public void Dispose()
 {
   foreach (string tempFilePath in _tempFilePaths.Values)
     try
     {
       File.Delete(tempFilePath);
     }
     catch (Exception e)
     {
       ServiceRegistration.Get<ILogger>().Warn("ZipResourceProxy: Unable to delete temp file '{0}'", e, tempFilePath);
     }
   _tempFilePaths.Clear();
   CloseZipFile();
   if (_zipFileResourceAccessor != null)
   {
     _zipFileResourceAccessor.Dispose();
     _zipFileResourceAccessor= null;
   }
 }
        /// <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> > ProcessDirectory(PendingImportResourceNewGen importResource)
        {
            var result = new HashSet <PendingImportResourceNewGen> {
                importResource
            };

            try
            {
                ICollection <IFileSystemResourceAccessor> files;
                ICollection <IFileSystemResourceAccessor> stubFiles           = new HashSet <IFileSystemResourceAccessor>();
                IDictionary <ResourcePath, DateTime>      path2LastImportDate = new Dictionary <ResourcePath, DateTime>();
                IDictionary <ResourcePath, Guid>          path2MediaItem      = new Dictionary <ResourcePath, Guid>();
                IEnumerable <MediaItem> mediaItems = null;
                if (importResource.IsSingleResource)
                {
                    files = new HashSet <IFileSystemResourceAccessor> {
                        importResource.ResourceAccessor
                    };
                    MediaItem mi = await LoadLocalItem(importResource.PendingResourcePath, PROVIDERRESOURCE_IMPORTER_MIA_ID_ENUMERATION, null).ConfigureAwait(false);

                    if (mi != null)
                    {
                        mediaItems = new List <MediaItem>(new MediaItem[] { mi });
                        importResource.MediaItemId = mi.MediaItemId;
                    }
                }
                else
                {
                    files = FileSystemResourceNavigator.GetFiles(importResource.ResourceAccessor, false, false) ?? new HashSet <IFileSystemResourceAccessor>();
                    SingleMediaItemAspect directoryAspect;
                    // ReSharper disable once PossibleInvalidOperationException
                    // TODO: Rework this
                    mediaItems = (await Browse(importResource.MediaItemId.Value, PROVIDERRESOURCE_IMPORTER_MIA_ID_ENUMERATION, DIRECTORY_MIA_ID_ENUMERATION).ConfigureAwait(false))
                                 .Where(mi => !MediaItemAspect.TryGetAspect(mi.Aspects, DirectoryAspect.Metadata, out directoryAspect));
                }
                if (mediaItems != null)
                {
                    foreach (MediaItem mi in mediaItems)
                    {
                        //Check metadata and files:
                        // 1. Last import date is lower than file change date => Refresh needed
                        // 2. Media item ID is empty => Reimport/import needed
                        // 3. Media item is dirty => Reimport/import needed
                        IList <MultipleMediaItemAspect> providerAspects = null;
                        if (MediaItemAspect.TryGetAspects(mi.Aspects, ProviderResourceAspect.Metadata, out providerAspects))
                        {
                            foreach (var pra in providerAspects)
                            {
                                bool         isStub = pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_STUB;
                                ResourcePath path   = ResourcePath.Deserialize(pra.GetAttributeValue <String>(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH));
                                if (!path2LastImportDate.ContainsKey(path) && importResource.PendingResourcePath.IsSameOrParentOf(path))
                                {
                                    //If last refresh is equal to added date, it has never been through the refresh cycle, so set low last change date
                                    //All media items must be added because the paths are later used to delete no longer existing media items
                                    var lastImportDate = mi.Aspects[ImporterAspect.ASPECT_ID][0].GetAttributeValue <DateTime>(ImporterAspect.ATTR_LAST_IMPORT_DATE);
                                    if (mi.Aspects[ImporterAspect.ASPECT_ID][0].GetAttributeValue <bool>(ImporterAspect.ATTR_DIRTY)) //If it is dirty, refresh is needed
                                    {
                                        path2LastImportDate.Add(path, DateTime.MinValue);
                                    }
                                    else
                                    {
                                        path2LastImportDate.Add(path, lastImportDate);
                                    }
                                }
                                if (!importResource.IsSingleResource && !isStub && !path2MediaItem.ContainsKey(path))
                                {
                                    path2MediaItem.Add(path, mi.MediaItemId);
                                }

                                // Stub items need their media item id because the do no have a unique path
                                // So add them now as long as the needed info is known
                                if (isStub)
                                {
                                    IFileSystemResourceAccessor file = null;
                                    try
                                    {
                                        IResourceAccessor ra;
                                        if (path.TryCreateLocalResourceAccessor(out ra))
                                        {
                                            file = ra as IFileSystemResourceAccessor;
                                        }
                                    }
                                    catch { }

                                    // Only add it if it still exists
                                    if (files.Where(f => file != null && f.CanonicalLocalResourcePath == file.CanonicalLocalResourcePath).Any())
                                    {
                                        stubFiles.Add(file);

                                        DateTime dateTime;
                                        PendingImportResourceNewGen pir = new PendingImportResourceNewGen(importResource.ResourceAccessor.CanonicalLocalResourcePath, file, ToString(),
                                                                                                          ParentImportJobController, importResource.MediaItemId, mi.MediaItemId, true);
                                        pir.ExistingAspects = mi.Aspects;
                                        if (ImportJobInformation.JobType == ImportJobType.Refresh)
                                        {
                                            if (path2LastImportDate.TryGetValue(pir.PendingResourcePath, out dateTime))
                                            {
                                                pir.DateOfLastImport = dateTime;
                                            }
                                        }
                                        result.Add(pir);
                                    }
                                }
                            }
                        }
                    }
                    await DeleteNoLongerExistingFilesFromMediaLibrary(files, path2LastImportDate.Keys).ConfigureAwait(false);
                }

                //Add new stub items
                foreach (var file in files.Where(f => !path2LastImportDate.Keys.Contains(f.CanonicalLocalResourcePath)))
                {
                    if (await IsStubResource(file).ConfigureAwait(false))
                    {
                        stubFiles.Add(file);

                        DateTime dateTime;
                        var      stubAspects = await ExtractStubItems(file).ConfigureAwait(false);

                        if (stubAspects != null)
                        {
                            foreach (var aspects in stubAspects)
                            {
                                PendingImportResourceNewGen pir = new PendingImportResourceNewGen(importResource.ResourceAccessor.CanonicalLocalResourcePath, file, ToString(),
                                                                                                  ParentImportJobController, importResource.MediaItemId, null, true);
                                pir.ExistingAspects = aspects;
                                if (ImportJobInformation.JobType == ImportJobType.Refresh)
                                {
                                    if (path2LastImportDate.TryGetValue(pir.PendingResourcePath, out dateTime))
                                    {
                                        pir.DateOfLastImport = dateTime;
                                    }
                                }
                                result.Add(pir);
                            }
                        }
                    }
                }

                //Remove stub files from files collection so they don't get added again
                foreach (IFileSystemResourceAccessor file in stubFiles)
                {
                    IFileSystemResourceAccessor stub = files.Where(f => f.CanonicalLocalResourcePath == file.CanonicalLocalResourcePath).FirstOrDefault();
                    if (stub != null)
                    {
                        files.Remove(stub);
                    }
                }

                //Add importers for files if any
                if (!importResource.IsSingleResource)
                {
                    if (ImportJobInformation.JobType == ImportJobType.Import)
                    {
                        //Only import new files so only add non existing paths
                        result.UnionWith(files.Where(f => !path2LastImportDate.Keys.Contains(f.CanonicalLocalResourcePath)).
                                         Select(f => new PendingImportResourceNewGen(importResource.ResourceAccessor.CanonicalLocalResourcePath, f, ToString(), ParentImportJobController, importResource.MediaItemId)));
                    }
                    else
                    {
                        result.UnionWith(files.Select(f => new PendingImportResourceNewGen(importResource.ResourceAccessor.CanonicalLocalResourcePath, f, ToString(), ParentImportJobController, importResource.MediaItemId,
                                                                                           path2MediaItem.ContainsKey(f.CanonicalLocalResourcePath) ? path2MediaItem[f.CanonicalLocalResourcePath] : (Guid?)null)));
                    }
                    // We set the directory resource as invalid because directories have no need for further processing
                    importResource.IsValid = false;
                }

                // If this is a RefreshImport and we found files of the current directory in the MediaLibrary,
                // store the DateOfLastImport in the PendingImportResource
                if (ImportJobInformation.JobType == ImportJobType.Refresh)
                {
                    DateTime dateTime;
                    if (path2LastImportDate != null)
                    {
                        foreach (var pir in result)
                        {
                            if (path2LastImportDate.TryGetValue(pir.PendingResourcePath, out dateTime))
                            {
                                pir.DateOfLastImport = dateTime;
                            }
                        }
                    }
                }

                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);
            }
        }
Beispiel #15
0
        /// <summary>
        /// Creates a local resource provider chain for this resource path, if it is a local path
        /// (see <see cref="CheckValidLocalPath"/>), and returns its result in a <see cref="IResourceAccessor"/> instance.
        /// </summary>
        /// <param name="result">Returns the resource accessor to access the resource represented by this path, if the
        /// return value is <c>true</c>. Else, this parameter doesn't return a meaningful value.</param>
        /// <returns><c>true</c>, if a resource accessor could successfully be built for this path.</returns>
        /// <exception cref="IllegalCallException">If one of the referenced resource providers is not available in the system or
        /// has the wrong type.</exception>
        /// <exception cref="UnexpectedStateException">If this path is empty.</exception>
        public bool TryCreateLocalResourceAccessor(out IResourceAccessor result)
        {
            IResourceAccessor resourceAccessor = null;

            if (USE_RA_CACHE)
            {
                if (TryGetCloneFromCache(this, out resourceAccessor))
                {
                    result = resourceAccessor;
                    return(true);
                }
            }
            IMediaAccessor mediaAccessor             = ServiceRegistration.Get <IMediaAccessor>();
            IEnumerator <ProviderPathSegment> enumer = _pathSegments.GetEnumerator();

            if (!enumer.MoveNext())
            {
                throw new UnexpectedStateException("Cannot build resource accessor for an empty resource path");
            }
            try
            {
                do
                {
                    ProviderPathSegment pathSegment = enumer.Current;
                    IResourceProvider   resourceProvider;
                    if (!mediaAccessor.LocalResourceProviders.TryGetValue(pathSegment.ProviderId, out resourceProvider))
                    {
                        throw new IllegalCallException("The resource provider with id '{0}' is not accessible in the current system", pathSegment.ProviderId);
                    }
                    if (resourceAccessor == null)
                    {
                        IBaseResourceProvider baseProvider = resourceProvider as IBaseResourceProvider;
                        if (baseProvider == null)
                        {
                            throw new IllegalCallException("The resource provider with id '{0}' does not implement the {1} interface", pathSegment.ProviderId, typeof(IBaseResourceProvider).Name);
                        }
                        if (!baseProvider.TryCreateResourceAccessor(pathSegment.Path, out resourceAccessor))
                        {
                            result = null;
                            return(false);
                        }
                    }
                    else
                    {
                        IChainedResourceProvider chainedProvider = resourceProvider as IChainedResourceProvider;
                        if (chainedProvider == null)
                        {
                            throw new IllegalCallException("The resource provider with id '{0}' does not implement the {1} interface", pathSegment.ProviderId, typeof(IChainedResourceProvider).Name);
                        }
                        IFileSystemResourceAccessor fsra = resourceAccessor as IFileSystemResourceAccessor;
                        if (fsra == null)
                        {
                            throw new IllegalCallException("Cannot chain up a resource provider to resource of type {0} (Path: '{1}')", resourceAccessor.GetType(), ToString());
                        }
                        IFileSystemResourceAccessor chainedRa;
                        if (!chainedProvider.TryChainUp(fsra, pathSegment.Path, out chainedRa))
                        {
                            resourceAccessor.Dispose();
                            result = null;
                            return(false);
                        }
                        resourceAccessor = chainedRa;
                    }
                } while (enumer.MoveNext());
            }
            catch (Exception)
            {
                if (resourceAccessor != null)
                {
                    resourceAccessor.Dispose();
                }
                throw;
            }
            if (USE_RA_CACHE)
            {
                AddToCache(this, resourceAccessor);
            }
            result = resourceAccessor;
            return(true);
        }
Beispiel #16
0
 public void Dispose()
 {
     _resourceAccessor.Dispose();
     _resourceAccessor = null;
 }
    /// <summary>
    /// Tries to find a nfo-file for the given <param name="mediaFsra"></param>
    /// </summary>
    /// <param name="miNumber">Unique number for logging purposes</param>
    /// <param name="mediaFsra">FileSystemResourceAccessor for which we search a nfo-file</param>
    /// <param name="nfoFsra">FileSystemResourceAccessor of the nfo-file or <c>null</c> if no nfo-file was found</param>
    /// <returns><c>true</c> if a nfo-file was found, otherwise <c>false</c></returns>
    private bool TryGetNfoSResourceAccessor(long miNumber, IFileSystemResourceAccessor mediaFsra, out IFileSystemResourceAccessor nfoFsra)
    {
      nfoFsra = null;

      // Determine the directory, in which we look for the nfo-file
      // We cannot use mediaFsra.GetResource, because for ChainedResourceProviders the parent directory
      // may be located in the ParentResourceProvider. For details see the comments for the ResourcePathHelper class.
      
      // First get the ResourcePath of the parent directory
      // The parent directory is
      // - for an IFilesystemResourceAcessor pointing to a file:
      //   the directory in which the file is located;
      // - for an IFilesystemResourceAcessor pointing to a root directory of a ChainedResourceProvider (e.g. in case of a DVD iso-file):
      //   the directory in which the file that was unfolded by the ChainedResourceProvider is located;
      // - for an IFilesystemResourceAcessor pointing to any other directory (e.g. DVD directories):
      //   the parent directory of such directory.
      var nfoDirectoryResourcePath = ResourcePathHelper.Combine(mediaFsra.CanonicalLocalResourcePath, "../");
      _debugLogger.Info("[#{0}]: nfo-directory: '{1}'", miNumber, nfoDirectoryResourcePath);

      // Then try to create an IFileSystemResourceAccessor for this directory
      IResourceAccessor nfoDirectoryRa;
      nfoDirectoryResourcePath.TryCreateLocalResourceAccessor(out nfoDirectoryRa);
      var nfoDirectoryFsra = nfoDirectoryRa as IFileSystemResourceAccessor;
      if (nfoDirectoryFsra == null)
      {
        _debugLogger.Info("[#{0}]: Cannot extract metadata; nfo-directory not accessible'", miNumber, nfoDirectoryResourcePath);
        if (nfoDirectoryRa != null)
          nfoDirectoryRa.Dispose();
        return false;
      }

      // Finally try to find a nfo-file in that directory
      using (nfoDirectoryFsra)
      {
        var nfoFileNames = GetNfoFileNames(mediaFsra);
        foreach (var nfoFileName in nfoFileNames)
          if (nfoDirectoryFsra.ResourceExists(nfoFileName))
          {
            _debugLogger.Info("[#{0}]: nfo-file found: '{1}'", miNumber, nfoFileName);
            nfoFsra = nfoDirectoryFsra.GetResource(nfoFileName);
            return true;
          }
          else
            _debugLogger.Info("[#{0}]: nfo-file '{1}' not found; checking next possible file...", miNumber, nfoFileName);
      }

      _debugLogger.Info("[#{0}]: Cannot extract metadata; No nfo-file found", miNumber);
      return false;
    }
Beispiel #18
0
        public override bool Process(MediaItem mediaItem, out ContentDirectoryMessaging.MediaItemChangeType changeType)
        {
            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;
            bool removeFromML    = IsManagedByMediaLibrary(mediaItem) && cd != null;

            changeType = ContentDirectoryMessaging.MediaItemChangeType.None;

            // Support multi-resource media items and secondary resources
            IList <MultipleMediaItemAspect> providerAspects;

            if (!MediaItemAspect.TryGetAspects(mediaItem.Aspects, ProviderResourceAspect.Metadata, out providerAspects))
            {
                return(false);
            }

            foreach (MultipleMediaItemAspect providerAspect in providerAspects)
            {
                string systemId             = (string)providerAspect[ProviderResourceAspect.ATTR_SYSTEM_ID];
                string resourceAccessorPath = (string)providerAspect[ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH];
                var    rl = new ResourceLocator(systemId, ResourcePath.Deserialize(resourceAccessorPath));
                using (var ra = rl.CreateAccessor())
                {
                    var rad = ra as IResourceDeletor;
                    if (rad == null)
                    {
                        return(false);
                    }

                    // First try to delete the file from storage.
                    if (!rad.Delete())
                    {
                        return(false);
                    }

                    changeType = ContentDirectoryMessaging.MediaItemChangeType.Deleted;

                    // If the MediaItem was loaded from ML, remove it there as well.
                    if (removeFromML)
                    {
                        cd.DeleteMediaItemOrPath(rl.NativeSystemId, rl.NativeResourcePath, true);
                    }
                }
            }

            // Check for special cases here:
            // 1) Recordings have an additional .xml attached
            // 2) Deleting files could lead to empty folders that should be also removed
            foreach (DeleteRule rule in _defaultRules.Where(r => r.IsEnabled))
            {
                if (mediaItem.Aspects.ContainsKey(rule.HasAspectGuid))
                {
                    var tsPath = mediaItem.GetResourceLocator().NativeResourcePath.ToString();
                    foreach (string otherExtension in rule.DeleteOtherExtensions)
                    {
                        string            otherFilePath = ProviderPathHelper.ChangeExtension(tsPath, otherExtension);
                        IResourceAccessor ra;
                        if (!ResourcePath.Deserialize(otherFilePath).TryCreateLocalResourceAccessor(out ra))
                        {
                            continue;
                        }

                        // Delete other file. We do not check here for existance of file, the Delete needs to handle this.
                        using (ra)
                        {
                            var rad = ra as IResourceDeletor;
                            rad?.Delete();
                        }
                    }

                    if (rule.DeleteEmptyFolders)
                    {
                        var folderPath = ProviderPathHelper.GetDirectoryName(tsPath);
                        IResourceAccessor ra;
                        if (!ResourcePath.Deserialize(folderPath).TryCreateLocalResourceAccessor(out ra))
                        {
                            continue;
                        }

                        // Delete folder if empty
                        using (ra)
                        {
                            IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;
                            if (fsra != null)
                            {
                                var isEmpty = fsra.GetFiles().Count == 0 && fsra.GetChildDirectories().Count == 0;
                                if (isEmpty)
                                {
                                    var rad = ra as IResourceDeletor;
                                    rad?.Delete();
                                }
                            }
                        }
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Gets a list of <see cref="FanArtImage"/>s for a requested <paramref name="mediaType"/>, <paramref name="fanArtType"/> and <paramref name="name"/>.
        /// The name can be: Series name, Actor name, Artist name depending on the <paramref name="mediaType"/>.
        /// </summary>
        /// <param name="mediaType">Requested FanArtMediaType</param>
        /// <param name="fanArtType">Requested FanArtType</param>
        /// <param name="name">Requested name of Series, Actor, Artist...</param>
        /// <param name="maxWidth">Maximum width for image. <c>0</c> returns image in original size.</param>
        /// <param name="maxHeight">Maximum height for image. <c>0</c> returns image in original size.</param>
        /// <param name="singleRandom">If <c>true</c> only one random image URI will be returned</param>
        /// <param name="result">Result if return code is <c>true</c>.</param>
        /// <returns><c>true</c> if at least one match was found.</returns>
        public bool TryGetFanArt(string mediaType, string fanArtType, string name, int maxWidth, int maxHeight, bool singleRandom, out IList <IResourceLocator> result)
        {
            result = null;
            Guid mediaItemId;

            if (mediaType != FanArtMediaTypes.Artist && mediaType != FanArtMediaTypes.Album && mediaType != FanArtMediaTypes.Audio)
            {
                return(false);
            }

            // Don't try to load "fanart" for images
            if (!Guid.TryParse(name, out mediaItemId))
            {
                return(false);
            }

            IMediaLibrary mediaLibrary = ServiceRegistration.Get <IMediaLibrary>(false);

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

            IFilter           filter        = null;
            IList <MediaItem> items         = null;
            List <Guid>       necessaryMias = new List <Guid>(NECESSARY_MIAS);

            if (mediaType == FanArtMediaTypes.Artist)
            {
                necessaryMias.Add(AudioAspect.ASPECT_ID);
                necessaryMias.Add(RelationshipAspect.ASPECT_ID);
                filter = new RelationshipFilter(AudioAspect.ROLE_TRACK, PersonAspect.ROLE_ALBUMARTIST, mediaItemId);
            }
            else if (fanArtType == FanArtTypes.FanArt)
            {
                if (mediaType == FanArtMediaTypes.Album)
                {
                    //Might be a request for album FanArt which doesn't exist. Artist FanArt is used instead.
                    filter = new RelationshipFilter(AudioAspect.ROLE_TRACK, AudioAlbumAspect.ROLE_ALBUM, mediaItemId);
                }
                else if (mediaType == FanArtMediaTypes.Audio)
                {
                    //Might be a request for track FanArt which doesn't exist. Artist FanArt is used instead.
                    necessaryMias.Add(AudioAspect.ASPECT_ID);
                    filter = new MediaItemIdFilter(mediaItemId);
                }
            }
            else
            {
                return(false);
            }

            MediaItemQuery mediaQuery = new MediaItemQuery(necessaryMias, filter);

            mediaQuery.Limit = 1;
            items            = mediaLibrary.Search(mediaQuery, false, null, false);
            if (items == null || items.Count == 0)
            {
                return(false);
            }

            MediaItem mediaItem = items.First();

            // Virtual resources won't have any local fanart
            if (mediaItem.IsVirtual)
            {
                return(false);
            }
            var mediaIteamLocator = mediaItem.GetResourceLocator();
            var fanArtPaths       = new List <ResourcePath>();
            var files             = new List <IResourceLocator>();

            string artistName    = null;
            var    mediaItemPath = mediaIteamLocator.NativeResourcePath;
            var    albumMediaItemDirectoryPath = ResourcePathHelper.Combine(mediaItemPath, "../");
            var    artistMediaItemyPath        = ResourcePathHelper.Combine(mediaItemPath, "../../");
            string album = null;

            if (MediaItemAspect.TryGetAttribute(mediaItem.Aspects, AudioAspect.ATTR_ALBUM, out album) && LocalFanartHelper.IsDiscFolder(album, albumMediaItemDirectoryPath.FileName))
            {
                //Probably a CD folder so try next parent
                albumMediaItemDirectoryPath = ResourcePathHelper.Combine(mediaItemPath, "../../");
                artistMediaItemyPath        = ResourcePathHelper.Combine(mediaItemPath, "../../../");
            }
            if (mediaType == FanArtMediaTypes.Artist && (fanArtType == FanArtTypes.Undefined || fanArtType == FanArtTypes.Thumbnail))
            {
                SingleMediaItemAspect audioAspect;
                List <string>         artists = new List <string>();
                if (MediaItemAspect.TryGetAspect(mediaItem.Aspects, AudioAspect.Metadata, out audioAspect))
                {
                    IEnumerable <object> artistObjects = audioAspect.GetCollectionAttribute <object>(AudioAspect.ATTR_ALBUMARTISTS);
                    if (artistObjects != null)
                    {
                        artists.AddRange(artistObjects.Cast <string>());
                    }
                }

                IList <MultipleMediaItemAspect> relationAspects;
                if (MediaItemAspect.TryGetAspects(mediaItem.Aspects, RelationshipAspect.Metadata, out relationAspects))
                {
                    foreach (MultipleMediaItemAspect relation in relationAspects)
                    {
                        if ((Guid?)relation[RelationshipAspect.ATTR_LINKED_ROLE] == PersonAspect.ROLE_ALBUMARTIST && (Guid?)relation[RelationshipAspect.ATTR_LINKED_ID] == mediaItemId)
                        {
                            int?index = (int?)relation[RelationshipAspect.ATTR_RELATIONSHIP_INDEX];
                            if (index.HasValue && artists.Count > index.Value && index.Value >= 0)
                            {
                                artistName = artists[index.Value];
                            }
                        }
                    }
                }
            }

            // File based access
            try
            {
                var mediaItemFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(mediaItemPath.ToString()).ToLowerInvariant();
                var mediaItemExtension = ResourcePathHelper.GetExtension(mediaItemPath.ToString());

                using (var directoryRa = new ResourceLocator(mediaIteamLocator.NativeSystemId, artistMediaItemyPath).CreateAccessor())
                {
                    var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                    if (directoryFsra != null)
                    {
                        var potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(directoryFsra);

                        if (fanArtType == FanArtTypes.Poster || fanArtType == FanArtTypes.Thumbnail)
                        {
                            fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.ARTIST_FILENAMES));
                            fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.POSTER_FILENAMES));
                            fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.THUMB_FILENAMES));
                        }

                        if (fanArtType == FanArtTypes.Banner)
                        {
                            fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.BANNER_FILENAMES));
                        }


                        if (fanArtType == FanArtTypes.Logo)
                        {
                            fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.LOGO_FILENAMES));
                        }

                        if (fanArtType == FanArtTypes.ClearArt)
                        {
                            fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.CLEARART_FILENAMES));
                        }

                        if (fanArtType == FanArtTypes.FanArt)
                        {
                            fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.BACKDROP_FILENAMES));

                            if (directoryFsra.ResourceExists("ExtraFanArt/"))
                            {
                                using (var extraFanArtDirectoryFsra = directoryFsra.GetResource("ExtraFanArt/"))
                                    fanArtPaths.AddRange(LocalFanartHelper.GetPotentialFanArtFiles(extraFanArtDirectoryFsra));
                            }
                        }

                        files.AddRange(fanArtPaths.Select(path => new ResourceLocator(mediaIteamLocator.NativeSystemId, path)));
                    }
                }

                if (!string.IsNullOrEmpty(artistName)) //Only one artist was found
                {
                    using (var directoryRa = new ResourceLocator(mediaIteamLocator.NativeSystemId, albumMediaItemDirectoryPath).CreateAccessor())
                    {
                        var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                        if (directoryFsra != null)
                        {
                            //Get Artists thumbs
                            IFileSystemResourceAccessor alternateArtistMediaItemDirectory = directoryFsra.GetResource(".artists");
                            if (alternateArtistMediaItemDirectory != null)
                            {
                                var potentialArtistFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(alternateArtistMediaItemDirectory);

                                foreach (ResourcePath thumbPath in
                                         from potentialFanArtFile in potentialArtistFanArtFiles
                                         let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString())
                                                                                       where potentialFanArtFileNameWithoutExtension.StartsWith(artistName.Replace(" ", "_"), StringComparison.InvariantCultureIgnoreCase)
                                                                                       select potentialFanArtFile)
                                {
                                    files.Add(new ResourceLocator(mediaIteamLocator.NativeSystemId, thumbPath));
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
#if DEBUG
                ServiceRegistration.Get <ILogger>().Warn("LocalArtistFanArtProvider: Error while searching fanart of type '{0}' for '{1}'", ex, fanArtType, mediaIteamLocator);
#endif
            }
            result = files;
            return(files.Count > 0);
        }
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData, bool importOnly, bool forceQuickMode)
        {
            try
            {
                if (!(mediaItemAccessor is IFileSystemResourceAccessor))
                {
                    return(false);
                }

                if (extractedAspectData.ContainsKey(VideoAspect.ASPECT_ID))
                {
                    return(false);
                }

                using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                {
                    if (!rah.LocalFsResourceAccessor.IsFile && rah.LocalFsResourceAccessor.ResourceExists("BDMV"))
                    {
                        using (IFileSystemResourceAccessor fsraBDMV = rah.LocalFsResourceAccessor.GetResource("BDMV"))
                            if (fsraBDMV != null && fsraBDMV.ResourceExists("index.bdmv"))
                            {
                                MultipleMediaItemAspect providerResourceAspect = MediaItemAspect.CreateAspect(extractedAspectData, ProviderResourceAspect.Metadata);
                                // Calling EnsureLocalFileSystemAccess not necessary; only string operation
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_INDEX, 0);
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_PRIMARY, true);
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "video/bluray"); // BluRay disc
                                providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, mediaItemAccessor.CanonicalLocalResourcePath.Serialize());

                                // This line is important to keep in, if no VideoAspect is created here, the MediaItems is not detected as Video!
                                SingleMediaItemAspect videoAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, VideoAspect.Metadata);
                                videoAspect.SetAttribute(VideoAspect.ATTR_ISDVD, true);

                                MultipleMediaItemAspect videoStreamAspect = MediaItemAspect.CreateAspect(extractedAspectData, VideoStreamAspect.Metadata);
                                videoStreamAspect.SetAttribute(VideoStreamAspect.ATTR_RESOURCE_INDEX, 0);
                                videoStreamAspect.SetAttribute(VideoStreamAspect.ATTR_STREAM_INDEX, -1);

                                MediaItemAspect mediaAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MediaAspect.Metadata);
                                mediaAspect.SetAttribute(MediaAspect.ATTR_ISVIRTUAL, false);

                                using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess())
                                {
                                    BDInfoExt bdinfo = new BDInfoExt(rah.LocalFsResourceAccessor.LocalFileSystemPath);
                                    string    title  = bdinfo.GetTitle();
                                    if (title == null)
                                    {
                                        try
                                        {
                                            title = mediaItemAccessor.ResourceName;
                                            if (title.StartsWith($"[{rah.LocalFsResourceAccessor.Path.Substring(1)}] "))
                                            {
                                                title = title.Substring(rah.LocalFsResourceAccessor.Path.Length + 2).Trim();
                                            }
                                        }
                                        catch
                                        {
                                            title = mediaItemAccessor.ResourceName;
                                        }
                                    }
                                    mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, title);

                                    // Check for BD disc thumbs
                                    FileInfo thumbnail = bdinfo.GetBiggestThumb();
                                    if (thumbnail != null)
                                    {
                                        try
                                        {
                                            using (FileStream fileStream = new FileStream(thumbnail.FullName, FileMode.Open, FileAccess.Read))
                                                using (MemoryStream resized = (MemoryStream)ImageUtilities.ResizeImage(fileStream, ImageFormat.Jpeg, MAX_COVER_WIDTH, MAX_COVER_HEIGHT))
                                                {
                                                    MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, resized.ToArray());
                                                }
                                        }
                                        // Decoding of invalid image data can fail, but main MediaItem is correct.
                                        catch
                                        {
                                        }
                                    }
                                }
                                return(true);
                            }
                    }
                }
                return(false);
            }
            catch
            {
                // Only log at the info level here - And simply return false. This makes the importer know that we
                // couldn't perform our task here
                if (mediaItemAccessor != null)
                {
                    ServiceRegistration.Get <ILogger>().Info("BluRayMetadataExtractor: Exception reading source '{0}'", mediaItemAccessor.ResourcePathName);
                }
                return(false);
            }
        }
        /// <summary>
        /// Tries to parse one or more images from a single <see cref="XElement"/> and add them to an existing HashSet of byte[]
        /// </summary>
        /// <param name="element"><see cref="XElement"/> to read from</param>
        /// <param name="values">HashSet of byte[] to which new entries should be added</param>
        /// <param name="nfoDirectoryFsra"><see cref="IFileSystemResourceAccessor"/> pointing to the parent directory of the nfo-file</param>
        /// <returns>A HashSet of byte[] with the new and old images or <c>null</c> if there are neither old nor new values</returns>
        protected async Task <HashSet <byte[]> > ParseMultipleImagesAsync(XElement element, HashSet <byte[]> values, IFileSystemResourceAccessor nfoDirectoryFsra)
        {
            // Examples of valid elements:
            // 1:
            // <element.Name>[ImageString]</element.Name>
            // 2:
            // <element.Name>
            //   <thumb>[ImageString]</thumb>
            // </element.Name>
            // The <element.Name> element may contain multiple <thumb> child elements
            // For examples of valid [ImageString] values see the comment of NfoReaderBase.ParseSimpleImageAsync
            if (element == null)
            {
                return(values);
            }
            var newValues = new HashSet <byte[]>();

            if (!element.HasElements)
            {
                // Example 1:
                var value = await ParseSimpleImageAsync(element, nfoDirectoryFsra).ConfigureAwait(false);

                if (value != null)
                {
                    newValues.Add(value);
                }
            }
            else
            {
                // Example 2:
                foreach (var childElement in element.Elements())
                {
                    if (childElement.Name == "thumb")
                    {
                        var value = await ParseSimpleImageAsync(childElement, nfoDirectoryFsra).ConfigureAwait(false);

                        if (value != null)
                        {
                            newValues.Add(value);
                        }
                    }
                    else
                    {
                        _debugLogger.Warn("[#{0}]: Unknown child element {1}", _miNumber, childElement);
                    }
                }
            }

            if (!newValues.Any())
            {
                return(values);
            }

            if (values == null)
            {
                values = new HashSet <byte[]>(newValues);
            }
            else
            {
                foreach (var value in newValues)
                {
                    values.Add(value);
                }
            }
            return(values);
        }
        /// <summary>
        /// Tries to read a simple image from <paramref name="element"/>.Value
        /// </summary>
        /// <param name="element"><see cref="XElement"/> to read from</param>
        /// <param name="nfoDirectoryFsra"><see cref="IFileSystemResourceAccessor"/> pointing to the parent directory of the nfo-file</param>
        /// <returns>
        /// <c>null</c> if
        ///   - <see cref="_importOnly"/> is <c>true</c>; or
        ///   - <see cref="_forceQuickMode"/> is <c>true</c>; or
        ///   - a call to <see cref="ParseSimpleString"/> for <paramref name="element"/> returns <c>null</c>
        ///   - <paramref name="element"/>.Value does not contain a valid and existing (absolute) http URL to an image; or
        ///   - <paramref name="element"/>.Value does contain a valid and existing (relative) file path or <paramref name="nfoDirectoryFsra"/> is <c>null</c>;
        /// otherwise the image file read as byte array.
        /// </returns>
        /// <remarks>
        /// <paramref name="element.Value"/> can be
        ///   - a file name:
        ///     <example>folder.jpg</example>
        ///     The file must then be in the same directory as the nfo-file
        ///   - a relative file path:
        ///     <example>extrafanart\fanart1.jpg</example>
        ///     <example>..\thumbs\fanart.jpg</example>
        ///     The path must be relative to the parent directory of the nfo-file
        ///   - an absolute http URL
        ///     <example>http://image.tmdb.org/t/p/original/1rre3m7WsI2QavNZD4aUa8LzzcK.jpg</example>
        /// </remarks>
        protected async Task <byte[]> ParseSimpleImageAsync(XElement element, IFileSystemResourceAccessor nfoDirectoryFsra)
        {
            if (_forceQuickMode)
            {
                return(null);
            }
            if (_importOnly)
            {
                return(null);
            }

            var imageFileString = ParseSimpleString(element);

            if (imageFileString == null)
            {
                return(null);
            }

            // First check whether it is a local file
            if (nfoDirectoryFsra != null)
            {
                var imageFsra = nfoDirectoryFsra.GetResource(imageFileString);
                if (imageFsra != null)
                {
                    using (imageFsra)
                        using (var imageStream = await imageFsra.OpenReadAsync().ConfigureAwait(false))
                        {
                            var result = new byte[imageStream.Length];
                            await imageStream.ReadAsync(result, 0, (int)imageStream.Length).ConfigureAwait(false);

                            return(result);
                        }
                }
            }
            else
            {
                _debugLogger.Error("[#{0}]: The nfo-file's parent directory's fsra could not be created", _miNumber);
            }

            // Then check if we have a valid http URL
            Uri imageFileUri;

            if (!Uri.TryCreate(imageFileString, UriKind.Absolute, out imageFileUri) || imageFileUri.Scheme != Uri.UriSchemeHttp)
            {
                _debugLogger.Warn("[#{0}]: The following element does neither contain an exsisting file name nor a valid http URL: {1}", _miNumber, element);
                return(null);
            }

            // Finally try to download the image from the internet
            try
            {
                var response = await _httpDownloadClient.GetAsync(imageFileUri).ConfigureAwait(false);

                if (response.IsSuccessStatusCode)
                {
                    return(await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false));
                }
                _debugLogger.Warn("[#{0}]: Http status code {1} ({2}) when trying to download image file: {3}", _miNumber, (int)response.StatusCode, response.StatusCode, element);
            }
            catch (Exception e)
            {
                _debugLogger.Warn("[#{0}]: The following image file could not be downloaded: {1}", e, _miNumber, element);
            }
            return(null);
        }
        /// <summary>
        /// Calls the appropriate <see cref="TryReadElementDelegate"/> or <see cref="TryReadElementAsyncDelegate"/>for each element of root
        /// </summary>
        /// <param name="nfoDocument"><see cref="XDocument"/> containing the respective nfo-file</param>
        /// <param name="nfoFsra"><see cref="IFileSystemResourceAccessor"/> to the nfo-file</param>
        /// <returns><c>true</c> if any usable metadata was found; else <c>false</c></returns>
        private async Task <bool> TryReadNfoDocumentAsync(XDocument nfoDocument, IFileSystemResourceAccessor nfoFsra)
        {
            // Checks the structure of the nfo document
            if (!IsValidNfoDocument(nfoDocument))
            {
                return(false);
            }

            _stubs.Clear();
            var result = false;

            // Create an IFileSystemResourceAccessor to the parent directory of the nfo-file
            var nfoDirectoryResourcePath = ResourcePathHelper.Combine(nfoFsra.CanonicalLocalResourcePath, "../");
            IResourceAccessor           nfoDirectoryRa;
            IFileSystemResourceAccessor nfoDirectoryFsra = null;

            if (nfoDirectoryResourcePath.TryCreateLocalResourceAccessor(out nfoDirectoryRa))
            {
                nfoDirectoryFsra = nfoDirectoryRa as IFileSystemResourceAccessor;
                if (nfoDirectoryFsra == null)
                {
                    nfoDirectoryRa.Dispose();
                }
            }

            using (nfoDirectoryFsra)
            {
                // IsValidNfoDocument returns false if nfoRootDocument is null
                // ReSharper disable once PossibleNullReferenceException
                foreach (var itemRoot in nfoDocument.Root.Elements().Where(CanReadItemRootElementTree))
                {
                    _currentStub = new TStub();
                    var metadataFound = false;
                    foreach (var element in itemRoot.Elements())
                    {
                        Delegate readDelegate;
                        if (_supportedElements.TryGetValue(element.Name, out readDelegate))
                        {
                            try
                            {
                                if ((readDelegate is TryReadElementDelegate && (readDelegate as TryReadElementDelegate).Invoke(element)) ||
                                    (readDelegate is TryReadElementAsyncDelegate && await(readDelegate as TryReadElementAsyncDelegate).Invoke(element, nfoDirectoryFsra).ConfigureAwait(false)))
                                {
                                    metadataFound = true;
                                }
                            }
                            catch (Exception e)
                            {
                                _debugLogger.Error("[#{0}]: Exception while reading element {1}", e, _miNumber, element);
                            }
                        }
                        else
                        {
                            _debugLogger.Warn("[#{0}]: Unknown element {1}", _miNumber, element);
                        }
                    }
                    if (metadataFound)
                    {
                        _stubs.Add(_currentStub);
                        result = true;
                    }
                }
                _currentStub = default(TStub);
            }
            return(result);
        }
 public PendingImportResource(Guid parentDirectory, IFileSystemResourceAccessor resourceAccessor)
 {
   _parentDirectory = parentDirectory;
   _resourceAccessor = resourceAccessor;
 }
    public bool IsResource(IFileSystemResourceAccessor baseResourceAccessor, string path)
    {
      string entryPath = ZipResourceAccessor.ToEntryPath(path);

      lock (_syncObj)
      {
        string key = baseResourceAccessor.CanonicalLocalResourcePath.Serialize();
        try
        {
          ZipResourceProxy proxy;
          if (_zipUsages.TryGetValue(key, out proxy))
            return path.Equals("/") || ZipResourceAccessor.IsResource(proxy.ZipFile, entryPath);
        }
        catch (Exception)
        {
          return false;
        }
      }

      using (Stream resourceStream = baseResourceAccessor.OpenRead()) // Not sure if the ZipFile will close the stream so we dispose it here
        try
        {
          using (ZipFile zFile = new ZipFile(resourceStream))
            return path.Equals("/") || ZipResourceAccessor.IsResource(zFile, entryPath);
        }
        catch (Exception)
        {
          return false;
        }
    }
        /// <summary>
        /// Returns all child directories of the given directory.
        /// </summary>
        /// <remarks>
        /// This will return all native child directories of the given directory together with all virtual child
        /// directories. The native child directories are taken directly from the given <paramref name="directoryAccessor"/>,
        /// the virtual child directories are obtained by taking the root directories of each chained resource provider applied
        /// to the child files of the given directory.
        /// If, for example, the given <paramref name="directoryAccessor"/> contains a child directory "A" and a child
        /// archive file "B" which can work as input for an installed archive provider, providing the root directory "C"
        /// of that archive, this method will return the resource accessors for directories "A" and "C".
        /// </remarks>
        /// <param name="directoryAccessor">Directory resource accessor to get all child directories for.</param>
        /// <param name="showSystemResources">If set to <c>true</c>, system resources like the virtual drives and directories of the
        /// <see cref="IResourceMountingService"/> will also be returned, else removed from the result value.</param>
        /// <returns>Collection of directory accessors for all native and virtual child directories or <c>null</c>,
        /// if the given <paramref name="directoryAccessor"/> is not a <see cref="IFileSystemResourceAccessor"/> and
        /// if there is no chained resource provider to unfold the given directory.</returns>
        public static ICollection <IFileSystemResourceAccessor> GetChildDirectories(IResourceAccessor directoryAccessor, bool showSystemResources)
        {
            IResourceMountingService resourceMountingService = ServiceRegistration.Get <IResourceMountingService>();
            IResourceAccessor        chainedResourceAccesor; // Needed in multiple source locations, that's why we declare it here

            if (directoryAccessor is IFileSystemResourceAccessor)
            {
                IFileSystemResourceAccessor dirFsra = (IFileSystemResourceAccessor)directoryAccessor;
                ICollection <IFileSystemResourceAccessor> childDirectories = dirFsra.GetChildDirectories();
                ICollection <IFileSystemResourceAccessor> result           = new List <IFileSystemResourceAccessor>();
                if (childDirectories != null)
                {
                    // Directories are maybe filtered and then just added
                    foreach (IFileSystemResourceAccessor childDirectoryAccessor in childDirectories)
                    {
                        if (!showSystemResources && resourceMountingService.IsVirtualResource(childDirectoryAccessor.CanonicalLocalResourcePath))
                        {
                            childDirectoryAccessor.Dispose();
                            continue;
                        }
                        result.Add(childDirectoryAccessor);
                    }
                }
                ICollection <IFileSystemResourceAccessor> files = dirFsra.GetFiles();
                if (files != null)
                {
                    // For files, we try to chain up chained resource providers
                    foreach (IFileSystemResourceAccessor fileAccessor in files)
                    {
                        if (!showSystemResources && resourceMountingService.IsVirtualResource(fileAccessor.CanonicalLocalResourcePath))
                        {
                            fileAccessor.Dispose();
                            continue;
                        }
                        if (TryUnfold(fileAccessor, out chainedResourceAccesor))
                        {
                            IFileSystemResourceAccessor chainedFsra = chainedResourceAccesor as IFileSystemResourceAccessor;
                            if (chainedFsra != null)
                            {
                                result.Add(chainedFsra);
                            }
                            else
                            {
                                chainedResourceAccesor.Dispose();
                            }
                        }
                        else
                        {
                            fileAccessor.Dispose();
                        }
                    }
                }
                return(result);
            }
            // Try to unfold simple resource
            IResourceAccessor dra = directoryAccessor.Clone();

            try
            {
                if (TryUnfold(dra, out chainedResourceAccesor))
                {
                    IFileSystemResourceAccessor chainedFsra = chainedResourceAccesor as IFileSystemResourceAccessor;
                    if (chainedFsra != null)
                    {
                        return(new List <IFileSystemResourceAccessor>(new IFileSystemResourceAccessor[] { chainedFsra }));
                    }
                    chainedResourceAccesor.Dispose();
                }
                else
                {
                    dra.Dispose();
                }
            }
            catch
            {
                dra.Dispose();
                throw;
            }
            return(null);
        }
 protected VirtualFileSystemResource(string name, IFileSystemResourceAccessor resourceAccessor)
 {
   _name = name;
   _resourceAccessor = resourceAccessor;
   _creationTime = DateTime.Now;
 }
        /// <summary>
        /// Tries to find a nfo-file for the given <param name="mediaFsra"></param>
        /// </summary>
        /// <param name="miNumber">Unique number for logging purposes</param>
        /// <param name="mediaFsra">FileSystemResourceAccessor for which we search a nfo-file</param>
        /// <param name="nfoFsra">FileSystemResourceAccessor of the nfo-file or <c>null</c> if no nfo-file was found</param>
        /// <returns><c>true</c> if a nfo-file was found, otherwise <c>false</c></returns>
        private bool TryGetNfoSResourceAccessor(long miNumber, IFileSystemResourceAccessor mediaFsra, out IFileSystemResourceAccessor nfoFsra)
        {
            nfoFsra = null;

            // Determine the directory, in which we look for the nfo-file
            // We cannot use mediaFsra.GetResource, because for ChainedResourceProviders the parent directory
            // may be located in the ParentResourceProvider. For details see the comments for the ResourcePathHelper class.

            // First get the ResourcePath of the parent directory
            // The parent directory is
            // - for an IFilesystemResourceAcessor pointing to a file:
            //   the directory in which the file is located;
            // - for an IFilesystemResourceAcessor pointing to a root directory of a ChainedResourceProvider (e.g. in case of a DVD iso-file):
            //   the directory in which the file that was unfolded by the ChainedResourceProvider is located;
            // - for an IFilesystemResourceAcessor pointing to any other directory (e.g. DVD directories):
            //   the parent directory of such directory.
            var nfoDirectoryResourcePath = ResourcePathHelper.Combine(mediaFsra.CanonicalLocalResourcePath, "../");

            _debugLogger.Info("[#{0}]: nfo-directory: '{1}'", miNumber, nfoDirectoryResourcePath);

            // Then try to create an IFileSystemResourceAccessor for this directory
            IResourceAccessor nfoDirectoryRa;

            nfoDirectoryResourcePath.TryCreateLocalResourceAccessor(out nfoDirectoryRa);
            var nfoDirectoryFsra = nfoDirectoryRa as IFileSystemResourceAccessor;

            if (nfoDirectoryFsra == null)
            {
                _debugLogger.Info("[#{0}]: Cannot extract metadata; nfo-directory not accessible'", miNumber, nfoDirectoryResourcePath);
                if (nfoDirectoryRa != null)
                {
                    nfoDirectoryRa.Dispose();
                }
                return(false);
            }

            // Finally try to find a nfo-file in that directory
            using (nfoDirectoryFsra)
            {
                var nfoFileNames = GetNfoFileNames(mediaFsra);
                foreach (var nfoFileName in nfoFileNames)
                {
                    if (nfoDirectoryFsra.ResourceExists(nfoFileName))
                    {
                        _debugLogger.Info("[#{0}]: nfo-file found: '{1}'", miNumber, nfoFileName);
                        nfoFsra = nfoDirectoryFsra.GetResource(nfoFileName);
                        return(true);
                    }
                    else
                    {
                        _debugLogger.Info("[#{0}]: nfo-file '{1}' not found; checking next possible file...", miNumber, nfoFileName);
                    }
                }
            }

            _debugLogger.Info("[#{0}]: Cannot extract metadata; No nfo-file found", miNumber);
            return(false);
        }
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            try
            {
                VideoResult result = null;
                IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;
                if (fsra == null)
                {
                    return(false);
                }
                if (!fsra.IsFile && fsra.ResourceExists("VIDEO_TS"))
                {
                    IFileSystemResourceAccessor fsraVideoTs = fsra.GetResource("VIDEO_TS");
                    if (fsraVideoTs != null && fsraVideoTs.ResourceExists("VIDEO_TS.IFO"))
                    {
                        // Video DVD
                        using (MediaInfoWrapper videoTsInfo = ReadMediaInfo(fsraVideoTs.GetResource("VIDEO_TS.IFO")))
                        {
                            if (!videoTsInfo.IsValid || videoTsInfo.GetVideoCount() == 0)
                            {
                                return(false); // Invalid video_ts.ifo file
                            }
                            result = VideoResult.CreateDVDInfo(fsra.ResourceName, videoTsInfo);
                        }
                        // Iterate over all video files; MediaInfo finds different audio/video metadata for each .ifo file
                        ICollection <IFileSystemResourceAccessor> files = fsraVideoTs.GetFiles();
                        if (files != null)
                        {
                            foreach (IFileSystemResourceAccessor file in files)
                            {
                                string lowerPath = (file.ResourcePathName ?? string.Empty).ToLowerInvariant();
                                if (!lowerPath.EndsWith(".ifo") || lowerPath.EndsWith("video_ts.ifo"))
                                {
                                    continue;
                                }
                                using (MediaInfoWrapper mediaInfo = ReadMediaInfo(file))
                                {
                                    // Before we start evaluating the file, check if it is a video at all
                                    if (mediaInfo.IsValid && mediaInfo.GetVideoCount() == 0)
                                    {
                                        continue;
                                    }
                                    result.AddMediaInfo(mediaInfo);
                                }
                            }
                        }
                    }
                }
                else if (fsra.IsFile)
                {
                    string filePath = fsra.ResourcePathName;
                    if (!HasVideoExtension(filePath))
                    {
                        return(false);
                    }
                    using (MediaInfoWrapper fileInfo = ReadMediaInfo(fsra))
                    {
                        // Before we start evaluating the file, check if it is a video at all
                        if (!fileInfo.IsValid || (fileInfo.GetVideoCount() == 0 && !IsWorkaroundRequired(filePath)))
                        {
                            return(false);
                        }

                        string mediaTitle = DosPathHelper.GetFileNameWithoutExtension(fsra.ResourceName);
                        result = VideoResult.CreateFileInfo(mediaTitle, fileInfo);
                    }
                    using (Stream stream = fsra.OpenRead())
                        result.MimeType = MimeTypeDetector.GetMimeType(stream, DEFAULT_MIMETYPE);
                }
                if (result != null)
                {
                    result.UpdateMetadata(extractedAspectData);

                    ILocalFsResourceAccessor disposeLfsra = null;
                    try
                    {
                        ILocalFsResourceAccessor lfsra = fsra as ILocalFsResourceAccessor;
                        if (lfsra == null && !forceQuickMode)
                        { // In case forceQuickMode, we only want local browsing
                            IFileSystemResourceAccessor localFsra = (IFileSystemResourceAccessor)fsra.Clone();
                            try
                            {
                                lfsra        = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(localFsra);
                                disposeLfsra = lfsra; // Remember to dispose the extra resource accessor instance
                            }
                            catch (Exception)
                            {
                                localFsra.Dispose();
                            }
                        }
                        if (lfsra != null)
                        {
                            string localFsPath = lfsra.LocalFileSystemPath;
                            ExtractMatroskaTags(localFsPath, extractedAspectData, forceQuickMode);
                            ExtractMp4Tags(localFsPath, extractedAspectData, forceQuickMode);
                            ExtractThumbnailData(localFsPath, extractedAspectData, forceQuickMode);
                        }
                    }
                    finally
                    {
                        if (disposeLfsra != null)
                        {
                            disposeLfsra.Dispose();
                        }
                    }
                    return(true);
                }
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This lets the caller know that we
                // couldn't perform our task here.
                ServiceRegistration.Get <ILogger>().Info("VideoMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message);
            }
            return(false);
        }
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;

            if (fsra == null)
            {
                return(false);
            }
            if (!fsra.IsFile)
            {
                return(false);
            }
            string fileName = fsra.ResourceName;

            if (!HasAudioExtension(fileName))
            {
                return(false);
            }

            MediaItemAspect mediaAspect          = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MediaAspect.Metadata);
            MediaItemAspect audioAspect          = MediaItemAspect.GetOrCreateAspect(extractedAspectData, AudioAspect.Metadata);
            MediaItemAspect thumbnailSmallAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ThumbnailSmallAspect.Metadata);
            MediaItemAspect thumbnailLargeAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ThumbnailLargeAspect.Metadata);

            try
            {
                File tag;
                try
                {
                    ByteVector.UseBrokenLatin1Behavior = true; // Otherwise we have problems retrieving non-latin1 chars
                    tag = File.Create(new ResourceProviderFileAbstraction(fsra));
                }
                catch (CorruptFileException)
                {
                    // Only log at the info level here - And simply return false. This makes the importer know that we
                    // couldn't perform our task here.
                    ServiceRegistration.Get <ILogger>().Info("AudioMetadataExtractor: Audio file '{0}' seems to be broken", fsra.CanonicalLocalResourcePath);
                    return(false);
                }

                // Some file extensions like .mp4 can contain audio and video. Do not handle files with video content here.
                if (tag.Properties.VideoHeight > 0 && tag.Properties.VideoWidth > 0)
                {
                    return(false);
                }

                fileName = ProviderPathHelper.GetFileNameWithoutExtension(fileName) ?? string.Empty;
                string title;
                string artist;
                uint?  trackNo;
                GuessMetadataFromFileName(fileName, out title, out artist, out trackNo);
                if (!string.IsNullOrEmpty(tag.Tag.Title))
                {
                    title = tag.Tag.Title;
                }
                IEnumerable <string> artists;
                if (tag.Tag.Performers.Length > 0)
                {
                    artists = tag.Tag.Performers;
                    if ((tag.TagTypes & TagTypes.Id3v2) != 0)
                    {
                        artists = PatchID3v23Enumeration(artists);
                    }
                }
                else
                {
                    artists = artist == null ? null : new string[] { artist }
                };
                if (tag.Tag.Track != 0)
                {
                    trackNo = tag.Tag.Track;
                }
                mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, title);
                // FIXME Albert: tag.MimeType returns taglib/mp3 for an MP3 file. This is not what we want and collides with the
                // mimetype handling in the BASS player, which expects audio/xxx.
                //mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, tag.MimeType);
                audioAspect.SetCollectionAttribute(AudioAspect.ATTR_ARTISTS, ApplyAdditionalSeparator(artists));
                audioAspect.SetAttribute(AudioAspect.ATTR_ALBUM, StringUtils.TrimToNull(tag.Tag.Album));
                IEnumerable <string> albumArtists = tag.Tag.AlbumArtists;
                if ((tag.TagTypes & TagTypes.Id3v2) != 0)
                {
                    albumArtists = PatchID3v23Enumeration(albumArtists);
                }
                audioAspect.SetCollectionAttribute(AudioAspect.ATTR_ALBUMARTISTS, ApplyAdditionalSeparator(albumArtists));
                audioAspect.SetAttribute(AudioAspect.ATTR_BITRATE, tag.Properties.AudioBitrate);
                mediaAspect.SetAttribute(MediaAspect.ATTR_COMMENT, StringUtils.TrimToNull(tag.Tag.Comment));
                IEnumerable <string> composers = tag.Tag.Composers;
                if ((tag.TagTypes & TagTypes.Id3v2) != 0)
                {
                    composers = PatchID3v23Enumeration(composers);
                }
                audioAspect.SetCollectionAttribute(AudioAspect.ATTR_COMPOSERS, ApplyAdditionalSeparator(composers));

                audioAspect.SetAttribute(AudioAspect.ATTR_DURATION, tag.Properties.Duration.TotalSeconds);
                if (tag.Tag.Genres.Length > 0)
                {
                    IEnumerable <string> genres = tag.Tag.Genres;
                    if ((tag.TagTypes & TagTypes.Id3v2) != 0)
                    {
                        genres = PatchID3v23Enumeration(genres);
                    }
                    audioAspect.SetCollectionAttribute(AudioAspect.ATTR_GENRES, ApplyAdditionalSeparator(genres));
                }
                if (trackNo.HasValue)
                {
                    audioAspect.SetAttribute(AudioAspect.ATTR_TRACK, (int)trackNo.Value);
                }
                if (tag.Tag.TrackCount != 0)
                {
                    audioAspect.SetAttribute(AudioAspect.ATTR_NUMTRACKS, (int)tag.Tag.TrackCount);
                }
                int year = (int)tag.Tag.Year;
                if (year >= 30 && year <= 99)
                {
                    year += 1900;
                }
                if (year >= 1930 && year <= 2030)
                {
                    mediaAspect.SetAttribute(MediaAspect.ATTR_RECORDINGTIME, new DateTime(year, 1, 1));
                }


                // The following code gets cover art images from file (embedded) or from windows explorer cache (supports folder.jpg).
                IPicture[] pics = tag.Tag.Pictures;
                if (pics.Length > 0)
                {
                    thumbnailLargeAspect.SetAttribute(ThumbnailLargeAspect.ATTR_THUMBNAIL, pics[0].Data.Data);
                }
                else
                {
                    // In quick mode only allow thumbs taken from cache.
                    bool cachedOnly = forceQuickMode;

                    // Thumbnail extraction
                    fileName = mediaItemAccessor.ResourcePathName;
                    IThumbnailGenerator generator = ServiceRegistration.Get <IThumbnailGenerator>();
                    byte[]    thumbData;
                    ImageType imageType;
                    if (generator.GetThumbnail(fileName, 96, 96, cachedOnly, out thumbData, out imageType))
                    {
                        thumbnailSmallAspect.SetAttribute(ThumbnailSmallAspect.ATTR_THUMBNAIL, thumbData);
                    }
                    if (generator.GetThumbnail(fileName, 256, 256, cachedOnly, out thumbData, out imageType))
                    {
                        thumbnailLargeAspect.SetAttribute(ThumbnailLargeAspect.ATTR_THUMBNAIL, thumbData);
                    }
                }
                return(true);
            }
            catch (UnsupportedFormatException)
            {
                ServiceRegistration.Get <ILogger>().Info("AudioMetadataExtractor: Unsupported audio file '{0}'", fsra.CanonicalLocalResourcePath);
                return(false);
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This makes the importer know that we
                // couldn't perform our task here
                ServiceRegistration.Get <ILogger>().Info("AudioMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", fsra.CanonicalLocalResourcePath, e.Message);
            }
            return(false);
        }
 protected VirtualFileSystemResource(string name, IFileSystemResourceAccessor resourceAccessor)
 {
     _name             = name;
     _resourceAccessor = resourceAccessor;
     _creationTime     = DateTime.Now;
 }
 public ResourceProviderFileAbstraction(IFileSystemResourceAccessor resourceAccessor)
 {
     _resourceAccessor = resourceAccessor;
 }
Beispiel #33
0
        public bool TryChainUp(IFileSystemResourceAccessor potentialBaseResourceAccessor, string path, out IFileSystemResourceAccessor resultResourceAccessor)
        {
            resultResourceAccessor = null;
            string resourcePathName = potentialBaseResourceAccessor.ResourcePathName;

            if (string.IsNullOrEmpty(resourcePathName) || !potentialBaseResourceAccessor.IsFile ||
                !".iso".Equals(DosPathHelper.GetExtension(resourcePathName), StringComparison.OrdinalIgnoreCase))
            {
                return(false);
            }

            lock (_syncObj)
            {
                string key = potentialBaseResourceAccessor.CanonicalLocalResourcePath.Serialize();
                try
                {
                    IsoResourceProxy proxy;
                    if (!_isoUsages.TryGetValue(key, out proxy))
                    {
                        _isoUsages.Add(key, proxy = CreateIsoResourceProxy(key, potentialBaseResourceAccessor));
                    }
                    resultResourceAccessor = new IsoResourceAccessor(this, proxy, path);
                }
                catch (Exception e)
                {
                    ServiceRegistration.Get <ILogger>().Warn("IsoResourceProvider: Error chaining up to '{0}'", e, potentialBaseResourceAccessor.CanonicalLocalResourcePath);
                    return(false);
                }
                return(true);
            }
        }
Beispiel #34
0
 /// <summary>
 /// Convenience method for <see cref="GetLocalFsResourceAccessor(IFileSystemResourceAccessor,string)"/> for the root path (<c>"/"</c>).
 /// </summary>
 /// <param name="baseResourceAccessor">Resource accessor which is used to provide the resource contents.</param>
 /// <returns>Resource accessor which implements <see cref="ILocalFsResourceAccessor"/>.</returns>
 public static ILocalFsResourceAccessor GetLocalFsResourceAccessor(IFileSystemResourceAccessor baseResourceAccessor)
 {
     return(GetLocalFsResourceAccessor(baseResourceAccessor, "/"));
 }
Beispiel #35
0
 protected override ViewSpecification NavigateCreateViewSpecification(string systemId, IFileSystemResourceAccessor viewRa)
 {
     return(new LocalDirectoryViewSpecification(null, viewRa.CanonicalLocalResourcePath, _necessaryMIATypeIds, _optionalMIATypeIds));
 }
        private void ExtractFolderImages(IResourceLocator mediaItemLocater, Guid?episodeMediaItemId, Guid?seriesMediaItemId, Guid?seasonMediaItemId, EpisodeInfo episode, SeriesInfo series, SeasonInfo season, IDictionary <Guid, string> actorMediaItems)
        {
            string fileSystemPath = string.Empty;

            // File based access
            try
            {
                if (mediaItemLocater != null)
                {
                    fileSystemPath = mediaItemLocater.NativeResourcePath.FileName;
                    var mediaItemPath                = mediaItemLocater.NativeResourcePath;
                    var mediaItemFileName            = ResourcePathHelper.GetFileNameWithoutExtension(mediaItemPath.ToString()).ToLowerInvariant();
                    var seasonMediaItemDirectoryPath = ResourcePathHelper.Combine(mediaItemPath, "../");
                    var seriesMediaItemDirectoryPath = ResourcePathHelper.Combine(mediaItemPath, "../../");

                    //Series fanart
                    var fanArtPaths   = new List <ResourcePath>();
                    var posterPaths   = new List <ResourcePath>();
                    var bannerPaths   = new List <ResourcePath>();
                    var logoPaths     = new List <ResourcePath>();
                    var clearArtPaths = new List <ResourcePath>();
                    var discArtPaths  = new List <ResourcePath>();
                    if (seriesMediaItemId.HasValue)
                    {
                        using (var directoryRa = new ResourceLocator(mediaItemLocater.NativeSystemId, seriesMediaItemDirectoryPath).CreateAccessor())
                        {
                            var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                            if (directoryFsra != null)
                            {
                                if (actorMediaItems.Count > 0)
                                {
                                    //Get Actor thumbs
                                    IFileSystemResourceAccessor actorMediaItemDirectory = directoryFsra.GetResource(".actors");
                                    if (actorMediaItemDirectory != null)
                                    {
                                        foreach (var actor in actorMediaItems)
                                        {
                                            var potentialArtistFanArtFiles = GetPotentialFanArtFiles(actorMediaItemDirectory);

                                            foreach (ResourcePath thumbPath in
                                                     from potentialFanArtFile in potentialArtistFanArtFiles
                                                     let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString())
                                                                                                   where potentialFanArtFileNameWithoutExtension.StartsWith(actor.Value.Replace(" ", "_"), StringComparison.InvariantCultureIgnoreCase)
                                                                                                   select potentialFanArtFile)
                                            {
                                                SaveFolderFile(mediaItemLocater, thumbPath, FanArtTypes.Thumbnail, actor.Key, actor.Value);
                                            }
                                        }
                                    }
                                }

                                var potentialFanArtFiles = GetPotentialFanArtFiles(directoryFsra);

                                posterPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "poster" || potentialFanArtFileNameWithoutExtension == "folder" || potentialFanArtFileNameWithoutExtension == "cover"
                                                                                  select potentialFanArtFile);

                                logoPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "logo"
                                                                                  select potentialFanArtFile);

                                clearArtPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "clearart"
                                                                                  select potentialFanArtFile);

                                discArtPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "discart" || potentialFanArtFileNameWithoutExtension == "disc"
                                                                                  select potentialFanArtFile);

                                bannerPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "banner"
                                                                                  select potentialFanArtFile);

                                fanArtPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "backdrop" || potentialFanArtFileNameWithoutExtension == "fanart"
                                                                                  select potentialFanArtFile);

                                if (directoryFsra.ResourceExists("ExtraFanArt/"))
                                {
                                    using (var extraFanArtDirectoryFsra = directoryFsra.GetResource("ExtraFanArt/"))
                                        fanArtPaths.AddRange(GetPotentialFanArtFiles(extraFanArtDirectoryFsra));
                                }
                            }
                        }
                        foreach (ResourcePath posterPath in posterPaths)
                        {
                            SaveFolderFile(mediaItemLocater, posterPath, FanArtTypes.Poster, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath logoPath in logoPaths)
                        {
                            SaveFolderFile(mediaItemLocater, logoPath, FanArtTypes.Logo, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath clearArtPath in clearArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, clearArtPath, FanArtTypes.ClearArt, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath discArtPath in discArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, discArtPath, FanArtTypes.DiscArt, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath bannerPath in bannerPaths)
                        {
                            SaveFolderFile(mediaItemLocater, bannerPath, FanArtTypes.Banner, seriesMediaItemId.Value, series.ToString());
                        }
                        foreach (ResourcePath fanartPath in fanArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, fanartPath, FanArtTypes.FanArt, seriesMediaItemId.Value, series.ToString());
                        }
                    }

                    //Season fanart
                    fanArtPaths.Clear();
                    posterPaths.Clear();
                    bannerPaths.Clear();
                    logoPaths.Clear();
                    clearArtPaths.Clear();
                    discArtPaths.Clear();
                    if (seasonMediaItemId.HasValue)
                    {
                        using (var directoryRa = new ResourceLocator(mediaItemLocater.NativeSystemId, seasonMediaItemDirectoryPath).CreateAccessor())
                        {
                            var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                            if (directoryFsra != null)
                            {
                                if (actorMediaItems.Count > 0)
                                {
                                    //Get Actor thumbs
                                    IFileSystemResourceAccessor actorMediaItemDirectory = directoryFsra.GetResource(".actors");
                                    if (actorMediaItemDirectory != null)
                                    {
                                        foreach (var actor in actorMediaItems)
                                        {
                                            var potentialArtistFanArtFiles = GetPotentialFanArtFiles(actorMediaItemDirectory);

                                            foreach (ResourcePath thumbPath in
                                                     from potentialFanArtFile in potentialArtistFanArtFiles
                                                     let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString())
                                                                                                   where potentialFanArtFileNameWithoutExtension.StartsWith(actor.Value.Replace(" ", "_"), StringComparison.InvariantCultureIgnoreCase)
                                                                                                   select potentialFanArtFile)
                                            {
                                                SaveFolderFile(mediaItemLocater, thumbPath, FanArtTypes.Thumbnail, actor.Key, actor.Value);
                                            }
                                        }
                                    }
                                }

                                var potentialFanArtFiles = GetPotentialFanArtFiles(directoryFsra);

                                posterPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "poster" || potentialFanArtFileNameWithoutExtension == "folder" || potentialFanArtFileNameWithoutExtension == "cover"
                                                                                  select potentialFanArtFile);

                                bannerPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "banner"
                                                                                  select potentialFanArtFile);

                                fanArtPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension == "backdrop" || potentialFanArtFileNameWithoutExtension == "fanart"
                                                                                  select potentialFanArtFile);

                                if (directoryFsra.ResourceExists("ExtraFanArt/"))
                                {
                                    using (var extraFanArtDirectoryFsra = directoryFsra.GetResource("ExtraFanArt/"))
                                        fanArtPaths.AddRange(GetPotentialFanArtFiles(extraFanArtDirectoryFsra));
                                }
                            }
                        }
                        using (var directoryRa = new ResourceLocator(mediaItemLocater.NativeSystemId, seriesMediaItemDirectoryPath).CreateAccessor())
                        {
                            var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                            if (directoryFsra != null && season.SeasonNumber.HasValue)
                            {
                                var           potentialFanArtFiles = GetPotentialFanArtFiles(directoryFsra);
                                List <string> prefixes             = new List <string>();
                                prefixes.Add(string.Format("season{0:00}-", season.SeasonNumber.Value));
                                if (season.SeasonNumber.Value == 0)
                                {
                                    prefixes.Add("season-specials-");
                                }
                                else
                                {
                                    prefixes.Add("season-all-");
                                }

                                foreach (string prefix in prefixes)
                                {
                                    if (posterPaths.Count == 0)
                                    {
                                        posterPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "poster"
                                                                                          select potentialFanArtFile);
                                    }

                                    if (logoPaths.Count == 0)
                                    {
                                        logoPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "logo"
                                                                                          select potentialFanArtFile);
                                    }

                                    if (clearArtPaths.Count == 0)
                                    {
                                        clearArtPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "clearart"
                                                                                          select potentialFanArtFile);
                                    }

                                    if (bannerPaths.Count == 0)
                                    {
                                        bannerPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "banner"
                                                                                          select potentialFanArtFile);
                                    }

                                    if (fanArtPaths.Count == 0)
                                    {
                                        fanArtPaths.AddRange(
                                            from potentialFanArtFile in potentialFanArtFiles
                                            let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                          where potentialFanArtFileNameWithoutExtension == prefix + "fanart"
                                                                                          select potentialFanArtFile);
                                    }
                                }
                            }
                        }
                        foreach (ResourcePath posterPath in posterPaths)
                        {
                            SaveFolderFile(mediaItemLocater, posterPath, FanArtTypes.Poster, seasonMediaItemId.Value, season.ToString());
                        }
                        foreach (ResourcePath logoPath in logoPaths)
                        {
                            SaveFolderFile(mediaItemLocater, logoPath, FanArtTypes.Logo, seasonMediaItemId.Value, season.ToString());
                        }
                        foreach (ResourcePath clearArtPath in clearArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, clearArtPath, FanArtTypes.ClearArt, seasonMediaItemId.Value, season.ToString());
                        }
                        foreach (ResourcePath bannerPath in bannerPaths)
                        {
                            SaveFolderFile(mediaItemLocater, bannerPath, FanArtTypes.Banner, seasonMediaItemId.Value, season.ToString());
                        }
                        foreach (ResourcePath fanartPath in fanArtPaths)
                        {
                            SaveFolderFile(mediaItemLocater, fanartPath, FanArtTypes.FanArt, seasonMediaItemId.Value, season.ToString());
                        }
                    }

                    //Episode fanart
                    //Also saved by the video MDE but saved here again in case of the offline option being different
                    var thumbPaths = new List <ResourcePath>();
                    if (episodeMediaItemId.HasValue)
                    {
                        using (var directoryRa = new ResourceLocator(mediaItemLocater.NativeSystemId, seasonMediaItemDirectoryPath).CreateAccessor())
                        {
                            var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                            if (directoryFsra != null)
                            {
                                var potentialFanArtFiles = GetPotentialFanArtFiles(directoryFsra);

                                thumbPaths.AddRange(
                                    from potentialFanArtFile in potentialFanArtFiles
                                    let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString()).ToLowerInvariant()
                                                                                  where potentialFanArtFileNameWithoutExtension.StartsWith(mediaItemFileName + "-thumb") || potentialFanArtFileNameWithoutExtension == "thumb"
                                                                                  select potentialFanArtFile);
                            }
                        }
                        foreach (ResourcePath thumbPath in thumbPaths)
                        {
                            SaveFolderFile(mediaItemLocater, thumbPath, FanArtTypes.Thumbnail, episodeMediaItemId.Value, episode.ToString());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Warn("SeriesFanArtHandler: Exception while reading folder images for '{0}'", ex, fileSystemPath);
            }
        }
Beispiel #37
0
        /// <summary>
        /// Sets the data of the new image to be played.
        /// </summary>
        /// <param name="locator">Resource locator of the image item.</param>
        /// <param name="mediaItemTitle">Title of the image item.</param>
        /// <param name="rotation">Rotation of the image.</param>
        /// <param name="flipX">Flipping in horizontal direction.</param>
        /// <param name="flipY">Flipping in vertical direction.</param>
        public void SetMediaItemData(IResourceLocator locator, string mediaItemTitle, RightAngledRotation rotation, bool flipX, bool flipY)
        {
            if (locator == null)
            {
                lock (_syncObj)
                {
                    _currentLocator = null;
                    return;
                }
            }

            using (IResourceAccessor ra = locator.CreateAccessor())
            {
                IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;
                if (fsra == null)
                {
                    return;
                }
                using (Stream stream = fsra.OpenRead())
                {
                    string key = fsra.CanonicalLocalResourcePath.Serialize();
                    _texture = ContentManager.Instance.GetTexture(stream, key, true);
                    if (_texture == null)
                    {
                        return;
                    }
                    if (!_texture.IsAllocated)
                    {
                        _texture.Allocate();
                    }
                    if (!_texture.IsAllocated)
                    {
                        return;
                    }
                }
            }
            lock (_syncObj)
            {
                ReloadSettings();
                _state = PlayerState.Active;

                _currentLocator = locator;
                _mediaItemTitle = mediaItemTitle;
                _rotation       = rotation;
                _flipX          = flipX;
                _flipY          = flipY;
                SurfaceDescription desc = _texture.Texture.GetLevelDescription(0);
                _textureMaxUV = new SizeF(_texture.Width / (float)desc.Width, _texture.Height / (float)desc.Height);

                // Reset animation
                _animator.Initialize();

                if (_slideShowTimer != null)
                {
                    _slideShowTimer.Change(_slideShowImageDuration, TS_INFINITE);
                }
                else
                {
                    CheckTimer();
                }
                _playbackStartTime = DateTime.Now;
                if (_pauseTime.HasValue)
                {
                    _pauseTime = _playbackStartTime;
                }
            }
        }
 /// <summary>
 /// Adds all media items which are found in the directory to the given <paramref name="directoryRA"/> or in any sub directory to
 /// the <paramref name="mediaItems"/> collection.
 /// </summary>
 /// <param name="directoryRA">Directory resource to be recursively examined.</param>
 /// <param name="mediaItems">Collection where the found media items are added.</param>
 /// <param name="metadataExtractorIds">Ids of the metadata extractors to be applied to the resources.
 /// See <see cref="IMediaAccessor.LocalMetadataExtractors"/>.</param>
 /// <param name="mediaAccessor">The media accessor of the system.</param>
 public static void AddLocalMediaItemsRecursive(IFileSystemResourceAccessor directoryRA, ICollection<MediaItem> mediaItems,
     IEnumerable<Guid> metadataExtractorIds, IMediaAccessor mediaAccessor)
 {
   ICollection<IFileSystemResourceAccessor> directoryRAs = FileSystemResourceNavigator.GetChildDirectories(directoryRA, false);
   if (directoryRAs != null)
     foreach (IFileSystemResourceAccessor subDirectoryRA in directoryRAs)
       using (subDirectoryRA)
         AddLocalMediaItemsRecursive(subDirectoryRA, mediaItems, metadataExtractorIds, mediaAccessor);
   ICollection<IFileSystemResourceAccessor> fileRAs = FileSystemResourceNavigator.GetFiles(directoryRA, false);
   if (fileRAs != null)
     foreach (IFileSystemResourceAccessor fileRA in fileRAs)
       using (fileRA)
       {
         MediaItem item = mediaAccessor.CreateLocalMediaItem(fileRA, metadataExtractorIds);
         if (item != null)
           mediaItems.Add(item);
       }
 }
        /// <summary>
        /// Returns all child directories of the given directory.
        /// </summary>
        /// <remarks>
        /// This will return all native child directories of the given directory together with all virtual child
        /// directories. The native child directories are taken directly from the given <paramref name="directoryAccessor"/>,
        /// the virtual child directories are obtained by taking the root directories of each chained resource provider applied
        /// to the child files of the given directory.
        /// If, for example, the given <paramref name="directoryAccessor"/> contains a child directory "A" and a child
        /// archive file "B" which can work as input for an installed archive provider, providing the root directory "C"
        /// of that archive, this method will return the resource accessors for directories "A" and "C".
        /// </remarks>
        /// <param name="directoryAccessor">Directory resource accessor to get all child directories for.</param>
        /// <param name="showSystemResources">If set to <c>true</c>, system resources like the virtual drives and directories of the
        /// <see cref="IResourceMountingService"/> will also be returned, else removed from the result value.</param>
        /// <returns>Collection of directory accessors for all native and virtual child directories or <c>null</c>,
        /// if the given <paramref name="directoryAccessor"/> is not a <see cref="IFileSystemResourceAccessor"/> and
        /// if there is no chained resource provider to unfold the given directory.</returns>
        public static ICollection <IFileSystemResourceAccessor> GetChildDirectories(IFileSystemResourceAccessor directoryAccessor, bool showSystemResources)
        {
            IResourceMountingService    resourceMountingService = ServiceRegistration.Get <IResourceMountingService>();
            IFileSystemResourceAccessor chainedResourceAccesor; // Needed in multiple source locations, that's why we declare it here
            ICollection <IFileSystemResourceAccessor> childDirectories = directoryAccessor.GetChildDirectories();
            ICollection <IFileSystemResourceAccessor> result           = new List <IFileSystemResourceAccessor>();

            if (childDirectories != null)
            {
                // Directories are maybe filtered and then just added
                foreach (IFileSystemResourceAccessor childDirectoryAccessor in childDirectories)
                {
                    if (!showSystemResources && resourceMountingService.IsVirtualResource(childDirectoryAccessor.CanonicalLocalResourcePath))
                    {
                        childDirectoryAccessor.Dispose();
                        continue;
                    }
                    result.Add(childDirectoryAccessor);
                }
            }
            ICollection <IFileSystemResourceAccessor> files = directoryAccessor.GetFiles();

            if (files != null)
            {
                // For files, we try to chain up chained resource providers
                foreach (IFileSystemResourceAccessor fileAccessor in files)
                {
                    using (fileAccessor)
                    {
                        if (!showSystemResources && resourceMountingService.IsVirtualResource(fileAccessor.CanonicalLocalResourcePath))
                        {
                            continue;
                        }
                        if (TryUnfold(fileAccessor, out chainedResourceAccesor))
                        {
                            if (!chainedResourceAccesor.IsFile)
                            {
                                result.Add(chainedResourceAccesor);
                            }
                            else
                            {
                                chainedResourceAccesor.Dispose();
                            }
                        }
                        // Simply ignore files because we only want to return directories
                    }
                }
            }
            if (result.Count > 0)
            {
                return(result);
            }
            // Try to unfold simple resource
            if (TryUnfold(directoryAccessor, out chainedResourceAccesor))
            {
                if (!chainedResourceAccesor.IsFile)
                {
                    return(new List <IFileSystemResourceAccessor>(new IFileSystemResourceAccessor[] { chainedResourceAccesor }));
                }
                chainedResourceAccesor.Dispose();
            }
            return(null);
        }
 /// <summary>
 /// Tries to unfold the given <paramref name="fileAccessor"/> to a virtual directory.
 /// </summary>
 /// <param name="fileAccessor">File resource accessor to be used as input for a potential chained provider.
 /// The ownership of this resource accessor remains at the caller.</param>
 /// <param name="resultResourceAccessor">Chained resource accessor which was chained upon the given file resource.</param>
 public static bool TryUnfold(IFileSystemResourceAccessor fileAccessor, out IFileSystemResourceAccessor resultResourceAccessor)
 {
   IMediaAccessor mediaAccessor = ServiceRegistration.Get<IMediaAccessor>();
   foreach (IChainedResourceProvider cmp in mediaAccessor.LocalChainedResourceProviders)
     if (cmp.TryChainUp(fileAccessor, "/", out resultResourceAccessor))
       return true;
   resultResourceAccessor = null;
   return false;
 }
    public bool TryChainUp(IFileSystemResourceAccessor potentialBaseResourceAccessor, string path, out IFileSystemResourceAccessor resultResourceAccessor)
    {
      resultResourceAccessor = null;
      string resourcePathName = potentialBaseResourceAccessor.ResourcePathName;
      if (string.IsNullOrEmpty(resourcePathName) || !potentialBaseResourceAccessor.IsFile ||
          !".zip".Equals(DosPathHelper.GetExtension(resourcePathName), StringComparison.OrdinalIgnoreCase))
        return false;

      lock (_syncObj)
      {
        string key = potentialBaseResourceAccessor.CanonicalLocalResourcePath.Serialize();
        try
        {
          ZipResourceProxy proxy;
          if (!_zipUsages.TryGetValue(key, out proxy))
            _zipUsages.Add(key, proxy = CreateZipResourceProxy(key, potentialBaseResourceAccessor));
          resultResourceAccessor = new ZipResourceAccessor(this, proxy, path);
        }
        catch (Exception e)
        {
          ServiceRegistration.Get<ILogger>().Warn("ZipResourceProvider: Error chaining up to '{0}'", e, potentialBaseResourceAccessor.CanonicalLocalResourcePath);
          return false;
        }
        return true;
      }
    }
Beispiel #42
0
        /// <summary>
        /// Method that processes the Uri.
        /// </summary>
        public override async Task Invoke(IOwinContext context)
        {
            var          request  = context.Request;
            var          response = context.Response;
            ResourcePath resourcePath;
            Uri          uri = request.Uri;

            if (!uri.AbsolutePath.StartsWith(ResourceHttpAccessUrlUtils.RESOURCE_SERVER_BASE_PATH) || !uri.AbsolutePath.Contains(ResourceHttpAccessUrlUtils.RESOURCE_ACCESS_PATH))
            {
                await Next.Invoke(context);

                return;
            }
            if (!ResourceHttpAccessUrlUtils.ParseResourceURI(uri, out resourcePath))
            {
                response.StatusCode   = (int)HttpStatusCode.BadRequest;
                response.ReasonPhrase = string.Format("Illegal request syntax. Correct syntax is '{0}'", ResourceHttpAccessUrlUtils.SYNTAX);
                return;
            }
            if (!IsAllowedToAccess(resourcePath))
            {
                ServiceRegistration.Get <ILogger>().Warn("ResourceAccessModule: Client tries to access forbidden resource '{0}'", resourcePath);
                response.StatusCode   = (int)HttpStatusCode.Forbidden;
                response.ReasonPhrase = string.Format("Access of resource '{0}' not allowed", resourcePath);
                return;
            }

            try
            {
                IFileSystemResourceAccessor fsra = GetResourceAccessor(resourcePath);
                using (Stream resourceStream = fsra.OpenRead())
                {
                    response.ContentType = GuessMimeType(resourceStream, resourcePath.FileName);

                    if (!string.IsNullOrEmpty(request.Headers["If-Modified-Since"]))
                    {
                        DateTime lastRequest = DateTime.Parse(request.Headers["If-Modified-Since"], System.Globalization.CultureInfo.InvariantCulture);
                        if (lastRequest.CompareTo(fsra.LastChanged) <= 0)
                        {
                            response.StatusCode = (int)HttpStatusCode.NotModified;
                        }
                    }

                    response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r");

                    string        byteRangesSpecifier = request.Headers["Range"];
                    IList <Range> ranges      = ParseRanges(byteRangesSpecifier, resourceStream.Length);
                    bool          onlyHeaders = request.Method == "Headers" || response.StatusCode == (int)HttpStatusCode.NotModified;

                    CancellationTokenSource cts = new CancellationTokenSource();
                    if (ranges != null && ranges.Count == 1)
                    {
                        // We only support one range
                        await SendRange(response, resourceStream, ranges[0], onlyHeaders, cts.Token);
                    }
                    else
                    {
                        await SendWholeFile(response, resourceStream, onlyHeaders, cts.Token);
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                response.StatusCode   = (int)HttpStatusCode.InternalServerError;
                response.ReasonPhrase = string.Format("Failed to proccess resource '{0}': {1}", resourcePath, ex.Message);
            }
        }
 internal ZipResourceProxy CreateZipResourceProxy(string key, IFileSystemResourceAccessor zipFileResourceAccessor)
 {
   ZipResourceProxy result = new ZipResourceProxy(key, zipFileResourceAccessor);
   result.Orphaned += OnZipResourceProxyOrphaned;
   return result;
 }
    protected override ViewSpecification NavigateCreateViewSpecification(string systemId, IFileSystemResourceAccessor viewRA)
    {
      IServerConnectionManager serverConnectionManager = ServiceRegistration.Get<IServerConnectionManager>();

      IContentDirectory cd = serverConnectionManager.ContentDirectory;
      if (cd == null)
        return null;

      ResourcePath directoryPath = viewRA.CanonicalLocalResourcePath;
      MediaItem directoryItem = cd.LoadItem(systemId, directoryPath,
          SystemSharesViewSpecification.DIRECTORY_MIA_ID_ENUMERATION, SystemSharesViewSpecification.EMPTY_ID_ENUMERATION);
      if (directoryItem == null)
        return null;
      return new MediaLibraryBrowseViewSpecification(viewRA.ResourceName, directoryItem.MediaItemId, systemId,
          directoryPath, _necessaryMIATypeIds, _optionalMIATypeIds);
    }
    /// <summary>
    /// Determines all possible file names for the nfo-file based on the respective NfoMovieMetadataExtractorSettings
    /// </summary>
    /// <param name="mediaFsra">IFilesystemResourceAccessor to the media file for which we search an nfo-file</param>
    /// <returns>IEnumerable of strings containing the possible nfo-file names</returns>
    IEnumerable<string> GetNfoFileNames(IFileSystemResourceAccessor mediaFsra)
    {
      var result = new List<string>();
      
      // Always consider the file or directory name of the media item
      string mediaFileOrDirectoryName;
      
      // If the MediaItem is a file, we simply take the filename without extension
      if (mediaFsra.IsFile)
        mediaFileOrDirectoryName = ResourcePathHelper.GetFileNameWithoutExtension(mediaFsra.CanonicalLocalResourcePath.Serialize());
      else
      {
        // if the media is a directory (such as a DVD or BluRay) we start with the ResourcePath
        mediaFileOrDirectoryName = mediaFsra.CanonicalLocalResourcePath.Serialize();
        
        // In case of the root path of a ChainedResourceProvider (such as for DVD- or BluRay-Iso-Files), we remove the last
        // ChainedResourceProvider, leaving us with the full path of the file, the ChainedResourceProvider has unfolded
        if (mediaFileOrDirectoryName.EndsWith(":///") && mediaFileOrDirectoryName.Contains(">"))
          mediaFileOrDirectoryName = mediaFileOrDirectoryName.Substring(0, mediaFileOrDirectoryName.LastIndexOf(">", StringComparison.Ordinal) - 1);

        // If it's a directory in a BaseResourceProvider, we just remove the last "/" so that the following
        // GetFileNameWithoutExtension considers the directory as a file.
        else
          mediaFileOrDirectoryName = StringUtils.RemoveSuffixIfPresent(mediaFileOrDirectoryName, "/");

        // Finally we get the file name without extension
        mediaFileOrDirectoryName = ResourcePathHelper.GetFileNameWithoutExtension(mediaFileOrDirectoryName);
      }

      // Combine the mediaFileOrDirectoryName and potentially further MovieNfoFileNames from the settings with
      // the NfoFileNameExtensions from the settings
      foreach (var extension in _settings.NfoFileNameExtensions)
      {
        result.Add(mediaFileOrDirectoryName + extension);
        result.AddRange(_settings.MovieNfoFileNames.Select(movieNfoFileName => movieNfoFileName + extension));
      }
      return result;
    }
    /// <summary>
    /// Returns a resource accessor instance of interface <see cref="ILocalFsResourceAccessor"/>. This instance will return the
    /// given <paramref name="baseResourceAccessor"/>, casted to <see cref="ILocalFsResourceAccessor"/> if possible, or
    /// a new instance of <see cref="StreamedResourceToLocalFsAccessBridge"/> to provide the <see cref="ILocalFsResourceAccessor"/>
    /// instance.
    /// </summary>
    /// <remarks>
    /// The ownership of the given <paramref name="baseResourceAccessor"/> is transferred from the caller to the returned
    /// result value. That means, if this method succeeds, the caller must dispose the result value, it must not dispose
    /// the given <paramref name="baseResourceAccessor"/> any more.
    /// </remarks>
    /// <param name="baseResourceAccessor">Resource accessor which is used to provide the resource contents.</param>
    /// <param name="path">Relative path based on the given baseResourceAccessor.</param>
    /// <returns>Resource accessor which implements <see cref="ILocalFsResourceAccessor"/>.</returns>
    public static ILocalFsResourceAccessor GetLocalFsResourceAccessor(IFileSystemResourceAccessor baseResourceAccessor, string path)
    {
      // Try to get an ILocalFsResourceAccessor
      ILocalFsResourceAccessor result = baseResourceAccessor as ILocalFsResourceAccessor;
      if (result != null)
          // Simple case: The media item is located in the local file system or the resource provider returns
          // an ILocalFsResourceAccessor from elsewhere - simply return it
        return result;

      // Set up a resource bridge mapping the remote or complex resource to a local file or directory
      string key = baseResourceAccessor.CanonicalLocalResourcePath.Serialize();
      MountingDataProxy md;
      bool dispose = false;
      lock (_syncObj)
      {
        if (_activeMounts.TryGetValue(key, out md))
            // Base accessor not needed - we use our cached accessor
          dispose = true;
        else
          _activeMounts.Add(key, md = CreateMountingDataProxy(key, baseResourceAccessor));
      }
      if (dispose)
        baseResourceAccessor.Dispose();
      return new StreamedResourceToLocalFsAccessBridge(md, path);
    }
Beispiel #47
0
 public VirtualFile(string name, IFileSystemResourceAccessor resourceAccessor) :
     base(name, resourceAccessor)
 {
 }
Beispiel #48
0
 public CachedResource(IFileSystemResourceAccessor resourceAccessor)
 {
     _lastTimeUsed     = DateTime.Now;
     _resourceAccessor = resourceAccessor;
 }
 /// <summary>
 /// Returns all files in the given directory.
 /// </summary>
 /// <remarks>
 /// This method simply returns the files files of the given <paramref name="directoryAccessor"/>, filtered
 /// if <paramref name="showSystemResources"/> is set to <c>true</c>.
 /// </remarks>
 /// <param name="directoryAccessor">Directory resource accessor to get all files for.</param>
 /// <param name="showSystemResources">If set to <c>true</c>, system resources like the virtual drives and directories of the
 /// <see cref="IResourceMountingService"/> will also be returned, else removed from the result value.</param>
 /// <returns>Collection of accessors for all files or <c>null</c>,
 /// if the given <paramref name="directoryAccessor"/> is not a <see cref="IFileSystemResourceAccessor"/>.</returns>
 public static ICollection<IFileSystemResourceAccessor> GetFiles(IFileSystemResourceAccessor directoryAccessor, bool showSystemResources)
 {
   IResourceMountingService resourceMountingService = ServiceRegistration.Get<IResourceMountingService>();
   ICollection<IFileSystemResourceAccessor> result = new List<IFileSystemResourceAccessor>();
   foreach (IFileSystemResourceAccessor fileAccessor in directoryAccessor.GetFiles())
   {
     if (!showSystemResources && resourceMountingService.IsVirtualResource(fileAccessor.CanonicalLocalResourcePath))
     {
       fileAccessor.Dispose();
       continue;
     }
     result.Add(fileAccessor);
   }
   return result;
 }
Beispiel #50
0
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            string fileName = mediaItemAccessor.ResourceName;

            if (!HasImageExtension(fileName))
            {
                return(false);
            }

            MediaItemAspect mediaAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MediaAspect.Metadata);
            MediaItemAspect imageAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, ImageAspect.Metadata);

            try
            {
                if (!(mediaItemAccessor is IFileSystemResourceAccessor))
                {
                    return(false);
                }
                IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;
                // Open a stream for media item to detect mimeType.
                using (Stream mediaStream = fsra.OpenRead())
                {
                    string mimeType = MimeTypeDetector.GetMimeType(mediaStream) ?? DEFAULT_MIMETYPE;
                    mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, mimeType);
                    mediaAspect.SetAttribute(MediaAspect.ATTR_SIZE, fsra.Size);
                }
                // Extract EXIF information from media item.
                using (ExifMetaInfo.ExifMetaInfo exif = new ExifMetaInfo.ExifMetaInfo(fsra))
                {
                    mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, ProviderPathHelper.GetFileNameWithoutExtension(fileName));
                    mediaAspect.SetAttribute(MediaAspect.ATTR_RECORDINGTIME, exif.OriginalDate != DateTime.MinValue ? exif.OriginalDate : fsra.LastChanged);
                    mediaAspect.SetAttribute(MediaAspect.ATTR_COMMENT, StringUtils.TrimToNull(exif.ImageDescription));

                    if (exif.PixXDim.HasValue)
                    {
                        imageAspect.SetAttribute(ImageAspect.ATTR_WIDTH, (int)exif.PixXDim);
                    }
                    if (exif.PixYDim.HasValue)
                    {
                        imageAspect.SetAttribute(ImageAspect.ATTR_HEIGHT, (int)exif.PixYDim);
                    }
                    imageAspect.SetAttribute(ImageAspect.ATTR_MAKE, StringUtils.TrimToNull(exif.EquipMake));
                    imageAspect.SetAttribute(ImageAspect.ATTR_MODEL, StringUtils.TrimToNull(exif.EquipModel));
                    if (exif.ExposureBias.HasValue)
                    {
                        imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_BIAS, ((double)exif.ExposureBias).ToString());
                    }
                    imageAspect.SetAttribute(ImageAspect.ATTR_EXPOSURE_TIME, exif.ExposureTime);
                    imageAspect.SetAttribute(ImageAspect.ATTR_FLASH_MODE, StringUtils.TrimToNull(exif.FlashMode));
                    if (exif.FNumber.HasValue)
                    {
                        imageAspect.SetAttribute(ImageAspect.ATTR_FNUMBER, string.Format("F {0}", (double)exif.FNumber));
                    }
                    imageAspect.SetAttribute(ImageAspect.ATTR_ISO_SPEED, StringUtils.TrimToNull(exif.ISOSpeed));
                    imageAspect.SetAttribute(ImageAspect.ATTR_ORIENTATION, (Int32)(exif.OrientationType ?? 0));
                    imageAspect.SetAttribute(ImageAspect.ATTR_METERING_MODE, exif.MeteringMode.ToString());

                    if (exif.Latitude.HasValue && exif.Longitude.HasValue)
                    {
                        imageAspect.SetAttribute(ImageAspect.ATTR_LATITUDE, exif.Latitude);
                        imageAspect.SetAttribute(ImageAspect.ATTR_LONGITUDE, exif.Longitude);

                        CivicAddress locationInfo;
                        if (!forceQuickMode && GeoLocationService.Instance.TryLookup(new GeoCoordinate(exif.Latitude.Value, exif.Longitude.Value), out locationInfo))
                        {
                            imageAspect.SetAttribute(ImageAspect.ATTR_CITY, locationInfo.City);
                            imageAspect.SetAttribute(ImageAspect.ATTR_STATE, locationInfo.StateProvince);
                            imageAspect.SetAttribute(ImageAspect.ATTR_COUNTRY, locationInfo.CountryRegion);
                        }
                    }

                    using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                    {
                        string localFsResourcePath = rah.LocalFsResourceAccessor.LocalFileSystemPath;
                        if (localFsResourcePath != null)
                        {
                            // In quick mode only allow thumbs taken from cache.
                            bool cachedOnly = forceQuickMode;

                            // Thumbnail extraction
                            IThumbnailGenerator generator = ServiceRegistration.Get <IThumbnailGenerator>();
                            byte[]    thumbData;
                            ImageType imageType;
                            if (generator.GetThumbnail(localFsResourcePath, 256, 256, cachedOnly, out thumbData, out imageType))
                            {
                                MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, thumbData);
                            }
                        }
                    }
                }
                return(true);
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This makes the importer know that we
                // couldn't perform our task here.
                ServiceRegistration.Get <ILogger>().Info("ImageMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message);
            }
            return(false);
        }
 protected AbstractBassResourceInputSource(IFileSystemResourceAccessor resourceAccessor)
 {
   _accessor = resourceAccessor;
 }
Beispiel #52
0
 /// <summary>
 /// Checks if the gived <paramref name="mediaItemAccessor"/> points to a directory and if it is considered a "single item" media source (like DVD or BD folders on hard drive).
 /// </summary>
 /// <param name="mediaItemAccessor">Local FS accessor</param>
 /// <returns><c>true</c> if it is a single item.</returns>
 protected async Task <bool> IsSingleResource(IFileSystemResourceAccessor mediaItemAccessor)
 {
     //ToDo: Replace this with a call to IsSingleResource once this method is implemented in the MetadataExtractors
     return(mediaItemAccessor.IsFile || await ExtractMetadata(mediaItemAccessor, null, true, true) != null);
 }
 /// <summary>
 /// Creates and initializes an new instance.
 /// </summary>
 /// <param name="resourceAccessor">The resource accessor to the media item to be handled by the instance.</param>
 /// <returns>The new instance.</returns>
 public static BassAudioFileInputSource Create(IFileSystemResourceAccessor resourceAccessor)
 {
   BassAudioFileInputSource inputSource = new BassAudioFileInputSource(resourceAccessor);
   inputSource.Initialize();
   return inputSource;
 }
Beispiel #54
0
        protected internal override void ReLoadItemsAndSubViewSpecifications(out IList <MediaItem> mediaItems, out IList <ViewSpecification> subViewSpecifications)
        {
            mediaItems            = new List <MediaItem>();
            subViewSpecifications = new List <ViewSpecification>();
            IMediaAccessor     mediaAccessor        = ServiceRegistration.Get <IMediaAccessor>();
            IEnumerable <Guid> metadataExtractorIds = mediaAccessor.GetMetadataExtractorsForMIATypes(_necessaryMIATypeIds.Union(_optionalMIATypeIds));
            IResourceAccessor  baseResourceAccessor;

            if (!_viewPath.TryCreateLocalResourceAccessor(out baseResourceAccessor))
            {
                ServiceRegistration.Get <ILogger>().Warn("LocalDirectoryViewSpecification.ReLoadItemsAndSubViewSpecifications: Cannot access local view path '{0}'", _viewPath);
                return;
            }
            using (baseResourceAccessor)
            {
                IFileSystemResourceAccessor fsra = baseResourceAccessor as IFileSystemResourceAccessor;
                if (fsra == null)
                {
                    ServiceRegistration.Get <ILogger>().Warn("LocalDirectoryViewSpecification.ReLoadItemsAndSubViewSpecifications: Cannot access local view path '{0}' - no local file system resource", _viewPath);
                    return;
                }
                // Add all items at the specified path
                ICollection <IFileSystemResourceAccessor> files = FileSystemResourceNavigator.GetFiles(fsra, false);
                if (files != null)
                {
                    foreach (IFileSystemResourceAccessor childAccessor in files)
                    {
                        using (childAccessor)
                            try
                            {
                                MediaItem result = mediaAccessor.CreateLocalMediaItem(childAccessor, metadataExtractorIds);
                                if (result != null)
                                {
                                    mediaItems.Add(result);
                                }
                            }
                            catch (Exception e)
                            {
                                ServiceRegistration.Get <ILogger>().Warn("LocalDirectoryViewSpecification: Error creating local media item for '{0}'", e, childAccessor);
                            }
                    }
                }
                ICollection <IFileSystemResourceAccessor> directories = FileSystemResourceNavigator.GetChildDirectories(fsra, false);
                if (directories != null)
                {
                    foreach (IFileSystemResourceAccessor childAccessor in directories)
                    {
                        using (childAccessor)
                            try
                            {
                                MediaItem result = mediaAccessor.CreateLocalMediaItem(childAccessor, metadataExtractorIds);
                                if (result == null)
                                {
                                    subViewSpecifications.Add(new LocalDirectoryViewSpecification(null, childAccessor.CanonicalLocalResourcePath,
                                                                                                  _necessaryMIATypeIds, _optionalMIATypeIds));
                                }
                                else
                                {
                                    mediaItems.Add(result);
                                }
                            }
                            catch (Exception e)
                            {
                                ServiceRegistration.Get <ILogger>().Warn("LocalDirectoryViewSpecification: Error creating media item or view specification for '{0}'", e, childAccessor);
                            }
                    }
                }
            }
        }
 static internal MountingDataProxy CreateMountingDataProxy(string key, IFileSystemResourceAccessor baseResourceAccessor)
 {
   MountingDataProxy result = new MountingDataProxy(key, baseResourceAccessor);
   result.MountingDataOrphaned += OnMountingDataOrphaned;
   return result;
 }
 protected VirtualBaseDirectory(string name, IFileSystemResourceAccessor resourceAccessor) : base(name, resourceAccessor)
 {
 }
 /// <summary>
 /// Convenience method for <see cref="GetLocalFsResourceAccessor(IFileSystemResourceAccessor,string)"/> for the root path (<c>"/"</c>).
 /// </summary>
 /// <param name="baseResourceAccessor">Resource accessor which is used to provide the resource contents.</param>
 /// <returns>Resource accessor which implements <see cref="ILocalFsResourceAccessor"/>.</returns>
 public static ILocalFsResourceAccessor GetLocalFsResourceAccessor(IFileSystemResourceAccessor baseResourceAccessor)
 {
   return GetLocalFsResourceAccessor(baseResourceAccessor, "/");
 }
Beispiel #58
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);
        }
 private BassMODFileInputSource(IFileSystemResourceAccessor resourceAccessor) : base(resourceAccessor) { }
        /// <summary>
        /// Gets a list of <see cref="FanArtImage"/>s for a requested <paramref name="mediaType"/>, <paramref name="fanArtType"/> and <paramref name="name"/>.
        /// The name can be: Series name, Actor name, Artist name depending on the <paramref name="mediaType"/>.
        /// </summary>
        /// <param name="mediaType">Requested FanArtMediaType</param>
        /// <param name="fanArtType">Requested FanArtType</param>
        /// <param name="name">Requested name of Series, Actor, Artist...</param>
        /// <param name="maxWidth">Maximum width for image. <c>0</c> returns image in original size.</param>
        /// <param name="maxHeight">Maximum height for image. <c>0</c> returns image in original size.</param>
        /// <param name="singleRandom">If <c>true</c> only one random image URI will be returned</param>
        /// <param name="result">Result if return code is <c>true</c>.</param>
        /// <returns><c>true</c> if at least one match was found.</returns>
        public bool TryGetFanArt(string mediaType, string fanArtType, string name, int maxWidth, int maxHeight, bool singleRandom, out IList <IResourceLocator> result)
        {
            result = null;
            Guid mediaItemId;

            if (mediaType != FanArtMediaTypes.Actor || (fanArtType != FanArtTypes.Undefined && fanArtType != FanArtTypes.Thumbnail))
            {
                return(false);
            }

            // Don't try to load "fanart" for images
            if (!Guid.TryParse(name, out mediaItemId))
            {
                return(false);
            }

            IMediaLibrary mediaLibrary = ServiceRegistration.Get <IMediaLibrary>(false);

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

            IFilter           filter        = new RelationshipFilter(MovieAspect.ROLE_MOVIE, PersonAspect.ROLE_ACTOR, mediaItemId);
            IList <MediaItem> items         = null;
            List <Guid>       necessaryMias = new List <Guid>(NECESSARY_MIAS);
            MediaItemQuery    mediaQuery    = new MediaItemQuery(necessaryMias, filter);

            mediaQuery.Limit = 1;
            items            = mediaLibrary.Search(mediaQuery, false, null, false);
            if (items == null || items.Count == 0)
            {
                return(false);
            }

            MediaItem mediaItem = items.First();

            // Virtual resources won't have any local fanart
            if (mediaItem.IsVirtual)
            {
                return(false);
            }
            var mediaIteamLocator = mediaItem.GetResourceLocator();
            var fanArtPaths       = new List <ResourcePath>();
            var files             = new List <IResourceLocator>();

            string actorName = null;
            SingleMediaItemAspect videoAspect;
            List <string>         actors = new List <string>();

            if (MediaItemAspect.TryGetAspect(mediaItem.Aspects, VideoAspect.Metadata, out videoAspect))
            {
                IEnumerable <object> actorObjects = videoAspect.GetCollectionAttribute <object>(VideoAspect.ATTR_ACTORS);
                if (actorObjects != null)
                {
                    actors.AddRange(actorObjects.Cast <string>());
                }
            }

            IList <MultipleMediaItemAspect> relationAspects;

            if (MediaItemAspect.TryGetAspects(mediaItem.Aspects, RelationshipAspect.Metadata, out relationAspects))
            {
                foreach (MultipleMediaItemAspect relation in relationAspects)
                {
                    if ((Guid?)relation[RelationshipAspect.ATTR_LINKED_ROLE] == PersonAspect.ROLE_ACTOR && (Guid?)relation[RelationshipAspect.ATTR_LINKED_ID] == mediaItemId)
                    {
                        int?index = (int?)relation[RelationshipAspect.ATTR_RELATIONSHIP_INDEX];
                        if (index.HasValue && actors.Count > index.Value && index.Value >= 0)
                        {
                            actorName = actors[index.Value];
                        }
                    }
                }
            }

            // File based access
            try
            {
                var mediaItemPath          = mediaIteamLocator.NativeResourcePath;
                var mediaItemDirectoryPath = ResourcePathHelper.Combine(mediaItemPath, "../");

                if (!string.IsNullOrEmpty(actorName))
                {
                    using (var directoryRa = new ResourceLocator(mediaIteamLocator.NativeSystemId, mediaItemDirectoryPath).CreateAccessor())
                    {
                        var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                        if (directoryFsra != null)
                        {
                            //Get Artists thumbs
                            IFileSystemResourceAccessor actorMediaItemDirectory = directoryFsra.GetResource(".actors");
                            if (actorMediaItemDirectory != null)
                            {
                                var potentialArtistFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(actorMediaItemDirectory);

                                foreach (ResourcePath thumbPath in
                                         from potentialFanArtFile in potentialArtistFanArtFiles
                                         let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString())
                                                                                       where potentialFanArtFileNameWithoutExtension.StartsWith(actorName.Replace(" ", "_"), StringComparison.InvariantCultureIgnoreCase)
                                                                                       select potentialFanArtFile)
                                {
                                    files.Add(new ResourceLocator(mediaIteamLocator.NativeSystemId, thumbPath));
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
#if DEBUG
                ServiceRegistration.Get <ILogger>().Warn("LocalMovieActorFanArtProvider: Error while searching fanart of type '{0}' for '{1}'", ex, fanArtType, mediaIteamLocator);
#endif
            }
            result = files;
            return(files.Count > 0);
        }