예제 #1
0
        public static MediaItem CreateMediaItem(string filename)
        {
            IMediaAccessor     mediaAccessor   = ServiceRegistration.Get <IMediaAccessor>();
            IEnumerable <Guid> meIds           = mediaAccessor.GetMetadataExtractorsForMIATypes(NECESSARY_VIDEO_MIAS);
            ResourceLocator    resourceLocator = new ResourceLocator(LocalFsResourceProviderBase.ToResourcePath(filename));
            IResourceAccessor  ra = resourceLocator.CreateAccessor();

            if (ra == null)
            {
                return(null);
            }
            using (ra)
                return(mediaAccessor.CreateLocalMediaItem(ra, meIds));
        }
예제 #2
0
        protected virtual async Task <bool> SaveSubtitleAsync(SubtitleInfo subtitle, IDictionary <BaseSubtitleMatch <TId>, byte[]> downloads, bool overwriteExisting)
        {
            var mediaFile         = subtitle.MediaFiles.First();
            var namingTemplate    = ResourcePath.GetFileNameWithoutExtension(mediaFile.NativeResourcePath.FileName);
            var templatePartMatch = _regexMultiPartVideo.Match(namingTemplate);

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

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

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

                //File based access
                var resLoc = new ResourceLocator(mediaFile.NativeSystemId, subtitlePath);
                using (IResourceAccessor mediaItemAccessor = resLoc.CreateAccessor())
                    using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor))
                        using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess())
                        {
                            using (var stream = rah.LocalFsResourceAccessor.CreateOpenWrite(sub, overwriteExisting))
                            {
                                var bytes = downloads[subtitleMatch];
                                if (stream != null)
                                {
                                    await stream.WriteAsync(bytes, 0, bytes.Length);
                                }
                            }
                        }
            }
            return(true);
        }
예제 #3
0
        public override async Task <AsyncResult <ContentDirectoryMessaging.MediaItemChangeType> > ProcessAsync(MediaItem mediaItem)
        {
            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;
            bool removeFromML    = IsManagedByMediaLibrary(mediaItem) && cd != null;

            var falseResult = new AsyncResult <ContentDirectoryMessaging.MediaItemChangeType>(false, ContentDirectoryMessaging.MediaItemChangeType.None);

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

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

            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(falseResult);
                    }

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

                    // If the MediaItem was loaded from ML, remove it there as well.
                    if (removeFromML)
                    {
                        await cd.DeleteMediaItemOrPathAsync(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(new AsyncResult <ContentDirectoryMessaging.MediaItemChangeType>(true, ContentDirectoryMessaging.MediaItemChangeType.Deleted));
        }