/// <summary> /// Ensures the list. /// </summary> /// <param name="url">The URL.</param> /// <param name="file">The file.</param> /// <param name="httpClient">The HTTP client.</param> /// <param name="fileSystem">The file system.</param> /// <param name="semaphore">The semaphore.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> public static async Task EnsureList(string url, string file, IHttpClient httpClient, IFileSystem fileSystem, SemaphoreSlim semaphore, CancellationToken cancellationToken) { var fileInfo = fileSystem.GetFileInfo(file); if (!fileInfo.Exists || (DateTime.UtcNow - fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays > 1) { await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { var temp = await httpClient.GetTempFile(new HttpRequestOptions { CancellationToken = cancellationToken, Progress = new Progress<double>(), Url = url }).ConfigureAwait(false); fileSystem.CreateDirectory(Path.GetDirectoryName(file)); fileSystem.CopyFile(temp, file, true); } finally { semaphore.Release(); } } }
public LocalFileStream(IFileSystem fileSystem, string relativePath, string contentType) : base(contentType) { Contract.Requires(fileSystem != null); RelativePath = relativePath; _fileInfo = fileSystem.GetFileInfo(relativePath); _stream = new Lazy<Stream>(() => fileSystem.Open(relativePath, FileMode.Open)); }
public static Project FromFile(string input, IFileSystem fileSystem) { var jObject = JsonConvert.DeserializeObject<Dictionary<string, JToken>>(input); var project = new Project(); foreach (var entry in jObject) { var kindObj = entry.Key; string[] list; if (entry.Value is JArray) list = entry.Value.ToObject<string[]>(); else list = new[] {entry.Value.ToObject<string>()}; foreach (var item in list) { var info = fileSystem.GetFileInfo(PathInfo.Create(item)); if (info == null) { var globPattern = GlobPattern.Create(item); if (!globPattern.IsWildcard) throw new InvalidProjectFileException($"Could not find file {item}."); var items = fileSystem.GetFiles(globPattern); foreach (var file in items) { var fileItem = new FileProjectItem(kindObj, file, fileSystem); ProjectItem existing; if (!project.TryGetItemById(fileItem.Identifier, out existing)) project.AddItem(fileItem); } project.AddSubscription(fileSystem.Subscribe(globPattern, a => { HandleChange(a, project, kindObj, fileSystem); })); } else { AddFile(fileSystem, project, kindObj, info, item); } } } return project; }
public async Task <FileOrganizationResult> OrganizeMovieFile(string path, MovieFileOrganizationOptions options, bool overwriteExisting, CancellationToken cancellationToken) { _logger.Info("Sorting file {0}", path); var result = new FileOrganizationResult { Date = DateTime.UtcNow, OriginalPath = path, OriginalFileName = Path.GetFileName(path), Type = FileOrganizerType.Unknown, FileSize = _fileSystem.GetFileInfo(path).Length }; try { if (_libraryMonitor.IsPathLocked(path)) { result.Status = FileSortingStatus.Failure; result.StatusMessage = "Path is locked by other processes. Please try again later."; _logger.Info("Auto-organize Path is locked by other processes. Please try again later."); return(result); } var namingOptions = GetNamingOptionsInternal(); var resolver = new VideoResolver(namingOptions); var movieInfo = resolver.Resolve(path, false) ?? new VideoFileInfo(); var movieName = movieInfo.Name; if (!string.IsNullOrEmpty(movieName)) { var movieYear = movieInfo.Year; _logger.Debug("Extracted information from {0}. Movie {1}, Year {2}", path, movieName, movieYear); await OrganizeMovie(path, movieName, movieYear, options, overwriteExisting, result, cancellationToken).ConfigureAwait(false); } else { var msg = string.Format("Unable to determine movie name from {0}", path); result.Status = FileSortingStatus.Failure; result.StatusMessage = msg; _logger.Warn(msg); } // Handle previous result var previousResult = _organizationService.GetResultBySourcePath(path); if ((previousResult != null && result.Type == FileOrganizerType.Unknown) || (previousResult?.Status == result.Status && previousResult?.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)) { // Don't keep saving the same result over and over if nothing has changed return(previousResult); } } catch (Exception ex) { result.Status = FileSortingStatus.Failure; result.StatusMessage = ex.Message; _logger.ErrorException("Error organizing file", ex); } await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); return(result); }
/// <summary> /// Fetches the data from XML node. /// </summary> /// <param name="reader">The reader.</param> /// <param name="result">The result.</param> protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult <Episode> result) { var item = result.Item; switch (reader.Name) { case "Episode": //MB generated metadata is within an "Episode" node using (var subTree = reader.ReadSubtree()) { subTree.MoveToContent(); // Loop through each element while (subTree.Read()) { if (subTree.NodeType == XmlNodeType.Element) { FetchDataFromXmlNode(subTree, result); } } } break; case "filename": { var filename = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(filename)) { // Strip off everything but the filename. Some metadata tools like MetaBrowser v1.0 will have an 'episodes' prefix // even though it's actually using the metadata folder. filename = Path.GetFileName(filename); var parentFolder = Path.GetDirectoryName(_xmlPath); filename = Path.Combine(parentFolder, filename); var file = _fileSystem.GetFileInfo(filename); if (file.Exists) { _imagesFound.Add(new LocalImageInfo { Type = ImageType.Primary, FileInfo = file }); } } break; } case "SeasonNumber": { var number = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(number)) { int num; if (int.TryParse(number, out num)) { item.ParentIndexNumber = num; } } break; } case "EpisodeNumber": { var number = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(number)) { int num; if (int.TryParse(number, out num)) { item.IndexNumber = num; } } break; } case "EpisodeNumberEnd": { var number = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(number)) { int num; if (int.TryParse(number, out num)) { item.IndexNumberEnd = num; } } break; } case "absolute_number": { var val = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(val)) { int rval; // int.TryParse is local aware, so it can be probamatic, force us culture if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval)) { item.AbsoluteEpisodeNumber = rval; } } break; } case "DVD_episodenumber": { var number = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(number)) { float num; if (float.TryParse(number, NumberStyles.Any, UsCulture, out num)) { item.DvdEpisodeNumber = num; } } break; } case "DVD_season": { var number = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(number)) { float num; if (float.TryParse(number, NumberStyles.Any, UsCulture, out num)) { item.DvdSeasonNumber = Convert.ToInt32(num); } } break; } case "airsbefore_episode": { var val = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(val)) { int rval; // int.TryParse is local aware, so it can be probamatic, force us culture if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval)) { item.AirsBeforeEpisodeNumber = rval; } } break; } case "airsafter_season": { var val = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(val)) { int rval; // int.TryParse is local aware, so it can be probamatic, force us culture if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval)) { item.AirsAfterSeasonNumber = rval; } } break; } case "airsbefore_season": { var val = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(val)) { int rval; // int.TryParse is local aware, so it can be probamatic, force us culture if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval)) { item.AirsBeforeSeasonNumber = rval; } } break; } case "EpisodeName": { var name = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(name)) { item.Name = name; } break; } default: base.FetchDataFromXmlNode(reader, result); break; } }
/// <inheritdoc /> public async Task <IEnumerable <RemoteSubtitleInfo> > Search(SubtitleSearchRequest request, CancellationToken cancellationToken) { var imdbIdText = request.GetProviderId(MetadataProvider.Imdb); long imdbId = 0; switch (request.ContentType) { case VideoContentType.Episode: if (!request.IndexNumber.HasValue || !request.ParentIndexNumber.HasValue || string.IsNullOrEmpty(request.SeriesName)) { _logger.LogDebug("Episode information missing"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } break; case VideoContentType.Movie: if (string.IsNullOrEmpty(request.Name)) { _logger.LogDebug("Movie name missing"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } if (string.IsNullOrWhiteSpace(imdbIdText) || !long.TryParse(imdbIdText.TrimStart('t'), NumberStyles.Any, UsCulture, out imdbId)) { _logger.LogDebug("Imdb id missing"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } break; } if (string.IsNullOrEmpty(request.MediaPath)) { _logger.LogDebug("Path Missing"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } await Login(cancellationToken).ConfigureAwait(false); var subLanguageId = NormalizeLanguage(request.Language); string hash; using (var fileStream = File.OpenRead(request.MediaPath)) { hash = Utilities.ComputeHash(fileStream); } var fileInfo = _fileSystem.GetFileInfo(request.MediaPath); var movieByteSize = fileInfo.Length; var searchImdbId = request.ContentType == VideoContentType.Movie ? imdbId.ToString(UsCulture) : string.Empty; var subtitleSearchParameters = request.ContentType == VideoContentType.Episode ? new List <SubtitleSearchParameters> { new SubtitleSearchParameters( subLanguageId, query: request.SeriesName, season: request.ParentIndexNumber !.Value.ToString(UsCulture), episode: request.IndexNumber !.Value.ToString(UsCulture)) }
private List <FileSystemMetadata> GetEpisodeXmlFiles(int?seasonNumber, int?episodeNumber, int?endingEpisodeNumber, string seriesDataPath) { var files = new List <FileSystemMetadata>(); if (episodeNumber == null) { return(files); } var usingAbsoluteData = false; if (seasonNumber.HasValue) { var file = Path.Combine(seriesDataPath, string.Format("episode-{0}-{1}.xml", seasonNumber.Value, episodeNumber)); var fileInfo = _fileSystem.GetFileInfo(file); if (fileInfo.Exists) { files.Add(fileInfo); } } else { usingAbsoluteData = true; var file = Path.Combine(seriesDataPath, string.Format("episode-abs-{0}.xml", episodeNumber)); var fileInfo = _fileSystem.GetFileInfo(file); if (fileInfo.Exists) { files.Add(fileInfo); } } var end = endingEpisodeNumber ?? episodeNumber; episodeNumber++; while (episodeNumber <= end) { string file; if (usingAbsoluteData) { file = Path.Combine(seriesDataPath, string.Format("episode-abs-{0}.xml", episodeNumber)); } else { file = Path.Combine(seriesDataPath, string.Format("episode-{0}-{1}.xml", seasonNumber.Value, episodeNumber)); } var fileInfo = _fileSystem.GetFileInfo(file); if (fileInfo.Exists) { files.Add(fileInfo); } else { break; } episodeNumber++; } return(files); }
private async Task DownloadBackdrops(BaseItem item, LibraryOptions libraryOptions, ImageType imageType, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable <RemoteImageInfo> images, int minWidth, CancellationToken cancellationToken) { foreach (var image in images.Where(i => i.Type == imageType)) { if (item.GetImages(imageType).Count() >= limit) { break; } if (image.Width.HasValue && image.Width.Value < minWidth) { continue; } var url = image.Url; if (EnableImageStub(item, libraryOptions)) { SaveImageStub(item, imageType, new[] { url }); result.UpdateType |= ItemUpdateType.ImageUpdate; continue; } try { using var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false); // If there's already an image of the same size, skip it if (response.Content.Headers.ContentLength.HasValue) { try { if (item.GetImages(imageType).Any(i => _fileSystem.GetFileInfo(i.Path).Length == response.Content.Headers.ContentLength.Value)) { response.Content.Dispose(); continue; } } catch (IOException ex) { _logger.LogError(ex, "Error examining images"); } } await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); await _providerManager.SaveImage( item, stream, response.Content.Headers.ContentType.MediaType, imageType, null, cancellationToken).ConfigureAwait(false); result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; } catch (HttpRequestException ex) { // Sometimes providers send back bad urls. Just move onto the next image if (ex.StatusCode.HasValue && (ex.StatusCode.Value == HttpStatusCode.NotFound || ex.StatusCode.Value == HttpStatusCode.Forbidden)) { continue; } break; } } }
/// <summary> /// Runs the specified progress. /// </summary> /// <param name="progress">The progress.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> public async Task Run(IProgress <double> progress, CancellationToken cancellationToken) { var seriesConfig = _config.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, typeof(Series).Name, StringComparison.OrdinalIgnoreCase)); if (seriesConfig != null && seriesConfig.DisabledMetadataFetchers.Contains(TvdbSeriesProvider.Current.Name, StringComparer.OrdinalIgnoreCase)) { progress.Report(100); return; } var path = TvdbSeriesProvider.GetSeriesDataPath(_config.CommonApplicationPaths); _fileSystem.CreateDirectory(path); var timestampFile = Path.Combine(path, "time.txt"); var timestampFileInfo = _fileSystem.GetFileInfo(timestampFile); // Don't check for tvdb updates anymore frequently than 24 hours if (timestampFileInfo.Exists && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(timestampFileInfo)).TotalDays < 1) { return; } // Find out the last time we queried tvdb for updates var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty; string newUpdateTime; var existingDirectories = _fileSystem.GetDirectoryPaths(path) .Select(Path.GetFileName) .ToList(); var seriesList = _libraryManager.GetItemList(new InternalItemsQuery() { IncludeItemTypes = new[] { typeof(Series).Name }, Recursive = true, GroupByPresentationUniqueKey = false, DtoOptions = new DtoOptions(false) { EnableImages = false } }).Cast <Series>() .ToList(); var seriesIdsInLibrary = seriesList .Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) .Select(i => i.GetProviderId(MetadataProviders.Tvdb)) .ToList(); var missingSeries = seriesIdsInLibrary.Except(existingDirectories, StringComparer.OrdinalIgnoreCase) .ToList(); var enableInternetProviders = seriesList.Count == 0 ? false : seriesList[0].IsInternetMetadataEnabled(); if (!enableInternetProviders) { progress.Report(100); return; } // If this is our first time, update all series if (string.IsNullOrEmpty(lastUpdateTime)) { // First get tvdb server time using (var stream = await _httpClient.Get(new HttpRequestOptions { Url = ServerTimeUrl, CancellationToken = cancellationToken, EnableHttpCompression = true, BufferContent = false }).ConfigureAwait(false)) { newUpdateTime = GetUpdateTime(stream); } existingDirectories.AddRange(missingSeries); await UpdateSeries(existingDirectories, path, null, progress, cancellationToken).ConfigureAwait(false); } else { var seriesToUpdate = await GetSeriesIdsToUpdate(existingDirectories, lastUpdateTime, cancellationToken).ConfigureAwait(false); newUpdateTime = seriesToUpdate.Item2; long lastUpdateValue; long.TryParse(lastUpdateTime, NumberStyles.Any, UsCulture, out lastUpdateValue); var nullableUpdateValue = lastUpdateValue == 0 ? (long?)null : lastUpdateValue; var listToUpdate = seriesToUpdate.Item1.ToList(); listToUpdate.AddRange(missingSeries); await UpdateSeries(listToUpdate, path, nullableUpdateValue, progress, cancellationToken).ConfigureAwait(false); } _fileSystem.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8); progress.Report(100); }
public async Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int?imageIndex, bool?saveLocallyWithMedia, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(mimeType)) { throw new ArgumentNullException("mimeType"); } var saveLocally = item.SupportsLocalMetadata && item.IsSaveLocalMetadataEnabled() && !item.IsOwnedItem && !(item is Audio); if (item is User) { saveLocally = true; } if (type != ImageType.Primary && item is Episode) { saveLocally = false; } var locationType = item.LocationType; if (locationType == LocationType.Remote || locationType == LocationType.Virtual) { saveLocally = false; var season = item as Season; // If season is virtual under a physical series, save locally if using compatible convention if (season != null && _config.Configuration.ImageSavingConvention == ImageSavingConvention.Compatible) { var series = season.Series; if (series != null && series.SupportsLocalMetadata && series.IsSaveLocalMetadataEnabled()) { saveLocally = true; } } } if (saveLocallyWithMedia.HasValue && !saveLocallyWithMedia.Value) { saveLocally = saveLocallyWithMedia.Value; } if (!imageIndex.HasValue && item.AllowsMultipleImages(type)) { imageIndex = item.GetImages(type).Count(); } var index = imageIndex ?? 0; var paths = GetSavePaths(item, type, imageIndex, mimeType, saveLocally); var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false); // If there are more than one output paths, the stream will need to be seekable var memoryStream = _memoryStreamProvider.CreateNew(); using (source) { await source.CopyToAsync(memoryStream).ConfigureAwait(false); } source = memoryStream; var currentImage = GetCurrentImage(item, type, index); var currentImageIsLocalFile = currentImage != null && currentImage.IsLocalFile; var currentImagePath = currentImage == null ? null : currentImage.Path; var savedPaths = new List <string>(); using (source) { var currentPathIndex = 0; foreach (var path in paths) { source.Position = 0; string retryPath = null; if (paths.Length == retryPaths.Length) { retryPath = retryPaths[currentPathIndex]; } var savedPath = await SaveImageToLocation(source, path, retryPath, cancellationToken).ConfigureAwait(false); savedPaths.Add(savedPath); currentPathIndex++; } } // Set the path into the item SetImagePath(item, type, imageIndex, savedPaths[0]); // Delete the current path if (currentImageIsLocalFile && !savedPaths.Contains(currentImagePath, StringComparer.OrdinalIgnoreCase)) { var currentPath = currentImagePath; _logger.Debug("Deleting previous image {0}", currentPath); _libraryMonitor.ReportFileSystemChangeBeginning(currentPath); try { var currentFile = _fileSystem.GetFileInfo(currentPath); // This will fail if the file is hidden if (currentFile.Exists) { if (currentFile.IsHidden) { _fileSystem.SetHidden(currentFile.FullName, false); } _fileSystem.DeleteFile(currentFile.FullName); } } finally { _libraryMonitor.ReportFileSystemChangeComplete(currentPath, false); } } }
public async Task <FileOrganizationResult> OrganizeEpisodeFile(string path, AutoOrganizeOptions options, bool overwriteExisting, CancellationToken cancellationToken) { _logger.Info("Sorting file {0}", path); var result = new FileOrganizationResult { Date = DateTime.UtcNow, OriginalPath = path, OriginalFileName = Path.GetFileName(path), Type = FileOrganizerType.Episode, FileSize = _fileSystem.GetFileInfo(path).Length }; try { if (_libraryMonitor.IsPathLocked(path)) { result.Status = FileSortingStatus.Failure; result.StatusMessage = "Path is locked by other processes. Please try again later."; return(result); } var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); var resolver = new EpisodeResolver(namingOptions, new NullLogger()); var episodeInfo = resolver.Resolve(path, false) ?? new MediaBrowser.Naming.TV.EpisodeInfo(); var seriesName = episodeInfo.SeriesName; if (!string.IsNullOrEmpty(seriesName)) { var seasonNumber = episodeInfo.SeasonNumber; result.ExtractedSeasonNumber = seasonNumber; // Passing in true will include a few extra regex's var episodeNumber = episodeInfo.EpisodeNumber; result.ExtractedEpisodeNumber = episodeNumber; var premiereDate = episodeInfo.IsByDate ? new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : (DateTime?)null; if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) { if (episodeInfo.IsByDate) { _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); } else { _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); } var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; await OrganizeEpisode(path, seriesName, seasonNumber, episodeNumber, endingEpisodeNumber, premiereDate, options, overwriteExisting, false, result, cancellationToken).ConfigureAwait(false); } else { var msg = string.Format("Unable to determine episode number from {0}", path); result.Status = FileSortingStatus.Failure; result.StatusMessage = msg; _logger.Warn(msg); } } else { var msg = string.Format("Unable to determine series name from {0}", path); result.Status = FileSortingStatus.Failure; result.StatusMessage = msg; _logger.Warn(msg); } var previousResult = _organizationService.GetResultBySourcePath(path); if (previousResult != null) { // Don't keep saving the same result over and over if nothing has changed if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success) { return(previousResult); } } await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { result.Status = FileSortingStatus.Failure; result.StatusMessage = ex.Message; } return(result); }
private bool IsFileReference(string reference) { var fileInfo = _fileSystem.GetFileInfo(reference); return(fileInfo.Exists && fileInfo.Extension.Equals(".dll", StringComparison.InvariantCultureIgnoreCase)); }
protected void InsertFileContent(object sender, WriterCommandEventArgs args) { if (args.Mode == WriterCommandEventMode.QueryState) { args.Enabled = args.DocumentControler != null && args.Document != null && args.DocumentControler.CanInsertElementAtCurrentPosition( typeof(DomElement)); } else if (args.Mode == WriterCommandEventMode.Invoke) { args.Result = false; DomDocument document = null; string fileName = null; if (args.Parameter is string) { fileName = (string)args.Parameter; } else if (args.Parameter is DomDocument) { document = (DomDocument)args.Parameter; } if (document == null) { IFileSystem fs = args.Host.FileSystems.Docuemnt; if (fs != null) { if (args.ShowUI) { // 浏览文件 fileName = fs.BrowseOpen(args.Host.Services, fileName); } if (string.IsNullOrEmpty(fileName)) { return; } VFileInfo info = fs.GetFileInfo(args.Host.Services, fileName); if (info.Exists == false) { // 文件不存在 return; } //打开文件 if (args.Host.Debuger != null) { args.Host.Debuger.DebugLoadingFile(fileName); } System.IO.Stream stream = fs.Open(args.Host.Services, fileName); if (stream != null) { FileFormat format = WriterUtils.ParseFileFormat(info.Format); using (stream) { // 读取文件,加载文档对象 document = new DomDocument(); document.Options = args.Document.Options; document.ServerObject = args.Document.ServerObject; document.Load(stream, format); if (args.Host.Debuger != null) { args.Host.Debuger.DebugLoadFileComplete((int)stream.Length); } } } } } if (document != null && document.Body != null && document.Body.Elements.Count > 0) { // 导入文档内容 DomElementList list = document.Body.Elements; args.Document.ImportElements(list); args.DocumentControler.InsertElements(list); args.Result = list; } } }
private async Task DownloadMultiImages(BaseItem item, ImageType imageType, ImageRefreshOptions refreshOptions, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable <RemoteImageInfo> images, int minWidth, CancellationToken cancellationToken) { foreach (var image in images.Where(i => i.Type == imageType)) { if (item.GetImages(imageType).Count() >= limit) { break; } if (image.Width.HasValue && image.Width.Value < minWidth) { continue; } var url = image.Url; if (EnableImageStub(item)) { SaveImageStub(item, imageType, new[] { url }); result.UpdateType |= ItemUpdateType.ImageUpdate; continue; } try { using var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false); // Sometimes providers send back bad urls. Just move to the next image if (response.StatusCode == HttpStatusCode.NotFound || response.StatusCode == HttpStatusCode.Forbidden) { _logger.LogDebug("{Url} returned {StatusCode}, ignoring", url, response.StatusCode); continue; } if (!response.IsSuccessStatusCode) { _logger.LogWarning("{Url} returned {StatusCode}, skipping all remaining requests", url, response.StatusCode); break; } // If there's already an image of the same file size, skip it unless doing a full refresh if (response.Content.Headers.ContentLength.HasValue && !refreshOptions.IsReplacingImage(imageType)) { try { if (item.GetImages(imageType).Any(i => _fileSystem.GetFileInfo(i.Path).Length == response.Content.Headers.ContentLength.Value)) { response.Content.Dispose(); continue; } } catch (IOException ex) { _logger.LogError(ex, "Error examining images"); } } await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); await _providerManager.SaveImage( item, stream, response.Content.Headers.ContentType?.MediaType, imageType, null, cancellationToken).ConfigureAwait(false); result.UpdateType |= ItemUpdateType.ImageUpdate; } catch (HttpRequestException) { break; } } }
/// <summary> /// 获取图片 /// </summary> /// <param name="url">地址</param> /// <param name="type">类型</param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task <HttpResponseInfo> GetImageResponse(string url, ImageType type, CancellationToken cancellationToken) { // /emby/Plugins/JavScraper/Image?url=&type=xx if (url.IndexOf("Plugins/JavScraper/Image", StringComparison.OrdinalIgnoreCase) >= 0) //本地的链接 { var uri = new Uri(url); var q = HttpUtility.ParseQueryString(uri.Query); var url2 = q["url"]; if (url2.IsWebUrl()) { url = url2; var tt = q.Get("type"); if (!string.IsNullOrWhiteSpace(tt) && Enum.TryParse <ImageType>(tt.Trim(), out var t2)) { type = t2; } } } logger?.Info($"{nameof(GetImageResponse)}-{url}"); var key = WebUtility.UrlEncode(url); var cache_file = Path.Combine(appPaths.GetImageCachePath().ToString(), key); byte[] bytes = null; //尝试从缓存中读取 try { var fi = fileSystem.GetFileInfo(cache_file); //图片文件存在,且是24小时之内的 if (fi.Exists && fileSystem.GetFileInfo(cache_file).LastWriteTimeUtc > DateTime.Now.AddDays(-1).ToUniversalTime()) { bytes = await fileSystem.ReadAllBytesAsync(cache_file); logger?.Info($"Hit image cache {url} {cache_file}"); if (type == ImageType.Primary) { var ci = await CutImage(bytes, url); if (ci != null) { return(ci); } } fileExtensionContentTypeProvider.TryGetContentType(url, out var contentType); return(new HttpResponseInfo() { Content = new MemoryStream(bytes), ContentLength = bytes.Length, ContentType = contentType ?? "image/jpeg", StatusCode = HttpStatusCode.OK, }); } } catch (Exception ex) { logger?.Warn($"Read image cache error. {url} {cache_file} {ex.Message}"); } try { var resp = await client.GetAsync(url, cancellationToken); if (resp.IsSuccessStatusCode == false) { return(await Parse(resp)); } try { fileSystem.WriteAllBytes(cache_file, await resp.Content.ReadAsByteArrayAsync()); logger?.Info($"Save image cache {url} {cache_file} "); } catch (Exception ex) { logger?.Warn($"Save image cache error. {url} {cache_file} {ex.Message}"); } if (type == ImageType.Primary) { var ci = await CutImage(await resp.Content.ReadAsByteArrayAsync(), url); if (ci != null) { return(ci); } } return(await Parse(resp)); } catch (Exception ex) { logger?.Error(ex.ToString()); } return(new HttpResponseInfo()); }
public async Task <IEnumerable <RemoteSubtitleInfo> > Search(SubtitleSearchRequest request, CancellationToken cancellationToken) { var imdbIdText = request.GetProviderId(MetadataProviders.Imdb); long imdbId = 0; switch (request.ContentType) { case VideoContentType.Episode: if (!request.IndexNumber.HasValue || !request.ParentIndexNumber.HasValue || string.IsNullOrEmpty(request.SeriesName)) { _logger.LogDebug("Episode information missing"); return(new List <RemoteSubtitleInfo>()); } break; case VideoContentType.Movie: if (string.IsNullOrEmpty(request.Name)) { _logger.LogDebug("Movie name missing"); return(new List <RemoteSubtitleInfo>()); } if (string.IsNullOrWhiteSpace(imdbIdText) || !long.TryParse(imdbIdText.TrimStart('t'), NumberStyles.Any, _usCulture, out imdbId)) { _logger.LogDebug("Imdb id missing"); return(new List <RemoteSubtitleInfo>()); } break; } if (string.IsNullOrEmpty(request.MediaPath)) { _logger.LogDebug("Path Missing"); return(new List <RemoteSubtitleInfo>()); } await Login(cancellationToken).ConfigureAwait(false); var subLanguageId = NormalizeLanguage(request.Language); string hash; using (var fileStream = _fileSystem.OpenRead(request.MediaPath)) { hash = Utilities.ComputeHash(fileStream); } var fileInfo = _fileSystem.GetFileInfo(request.MediaPath); var movieByteSize = fileInfo.Length; var searchImdbId = request.ContentType == VideoContentType.Movie ? imdbId.ToString(_usCulture) : ""; var subtitleSearchParameters = request.ContentType == VideoContentType.Episode ? new List <SubtitleSearchParameters> { new SubtitleSearchParameters(subLanguageId, query: request.SeriesName, season: request.ParentIndexNumber.Value.ToString(_usCulture), episode: request.IndexNumber.Value.ToString(_usCulture)) } : new List <SubtitleSearchParameters> { new SubtitleSearchParameters(subLanguageId, imdbid: searchImdbId), new SubtitleSearchParameters(subLanguageId, query: request.Name, imdbid: searchImdbId) }; var parms = new List <SubtitleSearchParameters> { new SubtitleSearchParameters(subLanguageId, movieHash: hash, movieByteSize: movieByteSize, imdbid: searchImdbId), }; parms.AddRange(subtitleSearchParameters); var result = await OpenSubtitles.SearchSubtitlesAsync(parms.ToArray(), cancellationToken).ConfigureAwait(false); if (!(result is MethodResponseSubtitleSearch)) { _logger.LogError("Invalid response type"); return(new List <RemoteSubtitleInfo>()); } Predicate <SubtitleSearchResult> mediaFilter = x => request.ContentType == VideoContentType.Episode ? !string.IsNullOrEmpty(x.SeriesSeason) && !string.IsNullOrEmpty(x.SeriesEpisode) && int.Parse(x.SeriesSeason, _usCulture) == request.ParentIndexNumber && int.Parse(x.SeriesEpisode, _usCulture) == request.IndexNumber : !string.IsNullOrEmpty(x.IDMovieImdb) && long.Parse(x.IDMovieImdb, _usCulture) == imdbId; var results = ((MethodResponseSubtitleSearch)result).Results; // Avoid implicitly captured closure var hasCopy = hash; return(results.Where(x => x.SubBad == "0" && mediaFilter(x) && (!request.IsPerfectMatch || string.Equals(x.MovieHash, hash, StringComparison.OrdinalIgnoreCase))) .OrderBy(x => (string.Equals(x.MovieHash, hash, StringComparison.OrdinalIgnoreCase) ? 0 : 1)) .ThenBy(x => Math.Abs(long.Parse(x.MovieByteSize, _usCulture) - movieByteSize)) .ThenByDescending(x => int.Parse(x.SubDownloadsCnt, _usCulture)) .ThenByDescending(x => double.Parse(x.SubRating, _usCulture)) .Select(i => new RemoteSubtitleInfo { Author = i.UserNickName, Comment = i.SubAuthorComment, CommunityRating = float.Parse(i.SubRating, _usCulture), DownloadCount = int.Parse(i.SubDownloadsCnt, _usCulture), Format = i.SubFormat, ProviderName = Name, ThreeLetterISOLanguageName = i.SubLanguageID, Id = i.SubFormat + "-" + i.SubLanguageID + "-" + i.IDSubtitleFile, Name = i.SubFileName, DateCreated = DateTime.Parse(i.SubAddDate, _usCulture), IsHashMatch = i.MovieHash == hasCopy }).Where(i => !string.Equals(i.Format, "sub", StringComparison.OrdinalIgnoreCase) && !string.Equals(i.Format, "idx", StringComparison.OrdinalIgnoreCase))); }
public async Task <FileOrganizationResult> OrganizeEpisodeFile( string path, TvFileOrganizationOptions options, CancellationToken cancellationToken) { _logger.Info("Sorting file {0}", path); var result = new FileOrganizationResult { Date = DateTime.UtcNow, OriginalPath = path, OriginalFileName = Path.GetFileName(path), Type = FileOrganizerType.Unknown, FileSize = _fileSystem.GetFileInfo(path).Length }; try { if (_libraryMonitor.IsPathLocked(path)) { result.Status = FileSortingStatus.Failure; result.StatusMessage = "Path is locked by other processes. Please try again later."; _logger.Info("Auto-organize Path is locked by other processes. Please try again later."); return(result); } var namingOptions = GetNamingOptionsInternal(); var resolver = new EpisodeResolver(namingOptions); var episodeInfo = resolver.Resolve(path, false) ?? new Naming.TV.EpisodeInfo(); var seriesName = episodeInfo.SeriesName; int?seriesYear = null; if (!string.IsNullOrEmpty(seriesName)) { var seriesParseResult = _libraryManager.ParseName(seriesName); seriesName = seriesParseResult.Name; seriesYear = seriesParseResult.Year; } if (string.IsNullOrWhiteSpace(seriesName)) { seriesName = episodeInfo.SeriesName; } if (!string.IsNullOrEmpty(seriesName)) { var seasonNumber = episodeInfo.SeasonNumber; result.ExtractedSeasonNumber = seasonNumber; // Passing in true will include a few extra regex's var episodeNumber = episodeInfo.EpisodeNumber; result.ExtractedEpisodeNumber = episodeNumber; var premiereDate = episodeInfo.IsByDate ? new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) : (DateTime?)null; if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue)) { if (episodeInfo.IsByDate) { _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value); } else { _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber); } // We detected an airdate or (an season number and an episode number) // We have all the chance that the media type is an Episode // if an earlier result exist with an different type, we update it result.Type = CurrentFileOrganizerType; var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber; result.ExtractedEndingEpisodeNumber = endingEpisodeNumber; await OrganizeEpisode(path, seriesName, seriesYear, seasonNumber, episodeNumber, endingEpisodeNumber, premiereDate, options, false, result, cancellationToken).ConfigureAwait(false); } else { var msg = string.Format("Unable to determine episode number from {0}", path); result.Status = FileSortingStatus.Failure; result.StatusMessage = msg; _logger.Warn(msg); } } else { var msg = string.Format("Unable to determine series name from {0}", path); result.Status = FileSortingStatus.Failure; result.StatusMessage = msg; _logger.Warn(msg); } // Handle previous result var previousResult = _organizationService.GetResultBySourcePath(path); if ((previousResult != null && result.Type == FileOrganizerType.Unknown) || (previousResult?.Status == result.Status && previousResult?.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)) { // Don't keep saving the same result over and over if nothing has changed return(previousResult); } } catch (OrganizationException ex) { result.Status = FileSortingStatus.Failure; result.StatusMessage = ex.Message; } catch (Exception ex) { result.Status = FileSortingStatus.Failure; result.StatusMessage = ex.Message; _logger.ErrorException("Error organizing file", ex); } await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false); return(result); }
private bool IsThrottleAllowed(TranscodingJobDto job, int thresholdSeconds) { var bytesDownloaded = job.BytesDownloaded; var transcodingPositionTicks = job.TranscodingPositionTicks ?? 0; var downloadPositionTicks = job.DownloadPositionTicks ?? 0; var path = job.Path ?? throw new ArgumentException("Path can't be null."); var gapLengthInTicks = TimeSpan.FromSeconds(thresholdSeconds).Ticks; if (downloadPositionTicks > 0 && transcodingPositionTicks > 0) { // HLS - time-based consideration var targetGap = gapLengthInTicks; var gap = transcodingPositionTicks - downloadPositionTicks; if (gap < targetGap) { _logger.LogDebug("Not throttling transcoder gap {0} target gap {1}", gap, targetGap); return(false); } _logger.LogDebug("Throttling transcoder gap {0} target gap {1}", gap, targetGap); return(true); } if (bytesDownloaded > 0 && transcodingPositionTicks > 0) { // Progressive Streaming - byte-based consideration try { var bytesTranscoded = job.BytesTranscoded ?? _fileSystem.GetFileInfo(path).Length; // Estimate the bytes the transcoder should be ahead double gapFactor = gapLengthInTicks; gapFactor /= transcodingPositionTicks; var targetGap = bytesTranscoded * gapFactor; var gap = bytesTranscoded - bytesDownloaded; if (gap < targetGap) { _logger.LogDebug("Not throttling transcoder gap {0} target gap {1} bytes downloaded {2}", gap, targetGap, bytesDownloaded); return(false); } _logger.LogDebug("Throttling transcoder gap {0} target gap {1} bytes downloaded {2}", gap, targetGap, bytesDownloaded); return(true); } catch (Exception ex) { _logger.LogError(ex, "Error getting output size"); return(false); } } _logger.LogDebug("No throttle data for {Path}", path); return(false); }
async Task <IEnumerable <RemoteSubtitleInfo> > ISubtitleProvider.Search(SubtitleSearchRequest request, CancellationToken cancellationToken) { var imdbIdText = request.GetProviderId(MetadataProviders.Imdb); long imdbId = 0; _logger.LogDebug($"{ToDump(request)}"); //_logger.LogDebug($"Imdb id: {imdbIdText}"); switch (request.ContentType) { case VideoContentType.Episode: if (!request.IndexNumber.HasValue || !request.ParentIndexNumber.HasValue || string.IsNullOrEmpty(request.SeriesName)) { _logger.LogDebug("Episode information missing"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } break; case VideoContentType.Movie: if (string.IsNullOrEmpty(request.Name)) { _logger.LogDebug("Movie name missing"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } if (string.IsNullOrWhiteSpace(imdbIdText) || !long.TryParse(imdbIdText.TrimStart('t'), NumberStyles.Any, _usCulture, out imdbId)) { //_logger.LogDebug($"Imdb id: `{imdbIdText}` - media name: {request.Name}"); _logger.LogDebug("Imdb id missing"); //return Enumerable.Empty<RemoteSubtitleInfo>(); } break; } if (string.IsNullOrEmpty(request.MediaPath)) { _logger.LogDebug("Path Missing"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } await Login(cancellationToken).ConfigureAwait(false); var subLanguageId = NormalizeLanguage(request.Language); string hash; using (var fileStream = File.OpenRead(request.MediaPath)) { hash = Utilities.ComputeHash(fileStream); } var fileInfo = _fileSystem.GetFileInfo(request.MediaPath); var movieByteSize = fileInfo.Length; //For movies, the imdb id is ued. var searchImdbId = request.ContentType == VideoContentType.Movie && imdbId != 0 ? imdbId.ToString(_usCulture) : ""; var subtitleSearchParameters = new List <SubtitleSearchParameters>(); switch (request.ContentType) { case VideoContentType.Episode: subtitleSearchParameters = new List <SubtitleSearchParameters> { new SubtitleSearchParameters(subLanguageId, query: request.SeriesName, season: request.ParentIndexNumber.Value.ToString(_usCulture), episode: request.IndexNumber.Value.ToString(_usCulture)) }; break; case VideoContentType.Movie: subtitleSearchParameters = new List <SubtitleSearchParameters> { }; if (!string.IsNullOrEmpty(searchImdbId)) { subtitleSearchParameters.Add(new SubtitleSearchParameters(subLanguageId, imdbid: searchImdbId)); subtitleSearchParameters.Add(new SubtitleSearchParameters(subLanguageId, query: request.Name, imdbid: searchImdbId)); } else { subtitleSearchParameters.Add(new SubtitleSearchParameters(subLanguageId, query: request.Name)); } break; } var parms = new List <SubtitleSearchParameters> { new SubtitleSearchParameters(subLanguageId, movieHash: hash, movieByteSize: movieByteSize, imdbid: searchImdbId), }; parms.AddRange(subtitleSearchParameters); if (_rateLimitLeft == 0) { await Task.Delay(1000); } //_logger.LogDebug($"Search params: {ToDump(parms)}"); IMethodResponse searchResult = null; try { var searchResponse = await OpenSubtitlesHandler.OpenSubtitles .SearchSubtitlesAsync(parms.ToArray(), cancellationToken) .ConfigureAwait(false); searchResult = searchResponse.Item1; //_logger.LogDebug($"Search result: {ToDump(searchResult)}"); _rateLimitLeft = searchResponse.Item2 ?? _rateLimitLeft; if (searchResponse.Item2 != null) { if (_rateLimitLeft <= 4) { await Task.Delay(250); } } } catch (Exception ex) { _logger.LogError($"Error while fetching subtitles from opensubtitles.\n{ex}\n{ex.StackTrace}"); } if (!(searchResult is MethodResponseSubtitleSearch)) { _logger.LogError("Invalid response type"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } //Check if we got a 401 error from opensubtitles if (searchResult.Status.Contains("401")) { _logger.LogError("Not authorized to OpenSubtitles"); return(Enumerable.Empty <RemoteSubtitleInfo>()); } Predicate <SubtitleSearchResult> mediaFilter = x => { switch (request.ContentType) { case VideoContentType.Episode: return(!string.IsNullOrEmpty(x.SeriesSeason) && !string.IsNullOrEmpty(x.SeriesEpisode) && int.Parse(x.SeriesSeason, _usCulture) == request.ParentIndexNumber && int.Parse(x.SeriesEpisode, _usCulture) == request.IndexNumber); case VideoContentType.Movie: if (imdbId == 0) { return(x.MovieName.Contains(request.Name)); } else { return(!string.IsNullOrEmpty(x.IDMovieImdb) && long.Parse(x.IDMovieImdb, _usCulture) == imdbId); } } return(false); }; var results = ((MethodResponseSubtitleSearch)searchResult).Results; // Avoid implicitly captured closure var hasCopy = hash; return(results.Where(x => x.SubBad == "0" && mediaFilter(x) && (!request.IsPerfectMatch || string.Equals(x.MovieHash, hash, StringComparison.OrdinalIgnoreCase))) .OrderBy(x => (string.Equals(x.MovieHash, hash, StringComparison.OrdinalIgnoreCase) ? 0 : 1)) .ThenBy(x => Math.Abs(long.Parse(x.MovieByteSize, _usCulture) - movieByteSize)) .ThenByDescending(x => int.Parse(x.SubDownloadsCnt, _usCulture)) .ThenByDescending(x => double.Parse(x.SubRating, _usCulture)) .Select(i => new RemoteSubtitleInfo { Author = i.UserNickName, Comment = i.SubAuthorComment, CommunityRating = float.Parse(i.SubRating, _usCulture), DownloadCount = int.Parse(i.SubDownloadsCnt, _usCulture), Format = i.SubFormat, ProviderName = Name, ThreeLetterISOLanguageName = i.SubLanguageID, Id = i.SubFormat + "-" + i.SubLanguageID + "-" + i.IDSubtitleFile, Name = i.SubFileName, DateCreated = DateTime.Parse(i.SubAddDate, _usCulture), IsHashMatch = i.MovieHash == hasCopy }).Where(i => !string.Equals(i.Format, "sub", StringComparison.OrdinalIgnoreCase) && !string.Equals(i.Format, "idx", StringComparison.OrdinalIgnoreCase))); }
private bool VerifyResource(VerifyInfo verifyInfo) { if (verifyInfo.UseFileSystem) { IFileSystem fileSystem = m_ResourceManager.GetFileSystem(verifyInfo.FileSystemName, false); string fileName = verifyInfo.ResourceName.FullName; FileSystem.FileInfo fileInfo = fileSystem.GetFileInfo(fileName); if (!fileInfo.IsValid) { return(false); } int length = fileInfo.Length; if (length == verifyInfo.Length) { m_ResourceManager.PrepareCachedStream(); fileSystem.ReadFile(fileName, m_ResourceManager.m_CachedStream); m_ResourceManager.m_CachedStream.Position = 0L; int hashCode = 0; if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) { Utility.Converter.GetBytes(verifyInfo.HashCode, m_CachedHashBytes); if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt) { hashCode = Utility.Verifier.GetCrc32(m_ResourceManager.m_CachedStream, m_CachedHashBytes, Utility.Encryption.QuickEncryptLength); } else if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) { hashCode = Utility.Verifier.GetCrc32(m_ResourceManager.m_CachedStream, m_CachedHashBytes, length); } Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength); } else { hashCode = Utility.Verifier.GetCrc32(m_ResourceManager.m_CachedStream); } if (hashCode == verifyInfo.HashCode) { return(true); } } fileSystem.DeleteFile(fileName); return(false); } else { string resourcePath = Utility.Path.GetRegularPath(Path.Combine(m_ResourceManager.ReadWritePath, verifyInfo.ResourceName.FullName)); if (!File.Exists(resourcePath)) { return(false); } using (FileStream fileStream = new FileStream(resourcePath, FileMode.Open, FileAccess.Read)) { int length = (int)fileStream.Length; if (length == verifyInfo.Length) { int hashCode = 0; if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) { Utility.Converter.GetBytes(verifyInfo.HashCode, m_CachedHashBytes); if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt) { hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, Utility.Encryption.QuickEncryptLength); } else if (verifyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || verifyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) { hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, length); } Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength); } else { hashCode = Utility.Verifier.GetCrc32(fileStream); } if (hashCode == verifyInfo.HashCode) { return(true); } } } File.Delete(resourcePath); return(false); } }
private async Task RefreshGuestNames(List <ServerUserAuthorizationResponse> list, bool refreshImages) { var users = _userManager.Users .Where(i => !string.IsNullOrEmpty(i.ConnectUserId) && i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest) .ToList(); foreach (var user in users) { var authorization = list.FirstOrDefault(i => string.Equals(i.UserId, user.ConnectUserId, StringComparison.Ordinal)); if (authorization == null) { _logger.Warn("Unable to find connect authorization record for user {0}", user.Name); continue; } var syncConnectName = true; var syncConnectImage = true; if (syncConnectName) { var changed = !string.Equals(authorization.UserName, user.Name, StringComparison.OrdinalIgnoreCase); if (changed) { await user.Rename(authorization.UserName).ConfigureAwait(false); } } if (syncConnectImage) { var imageUrl = authorization.UserImageUrl; if (!string.IsNullOrWhiteSpace(imageUrl)) { var changed = false; if (!user.HasImage(ImageType.Primary)) { changed = true; } else if (refreshImages) { using (var response = await _httpClient.SendAsync(new HttpRequestOptions { Url = imageUrl, BufferContent = false }, "HEAD").ConfigureAwait(false)) { var length = response.ContentLength; if (length != _fileSystem.GetFileInfo(user.GetImageInfo(ImageType.Primary, 0).Path).Length) { changed = true; } } } if (changed) { await _providerManager.SaveImage(user, imageUrl, ImageType.Primary, null, CancellationToken.None).ConfigureAwait(false); await user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) { ForceSave = true, }, CancellationToken.None).ConfigureAwait(false); } } } } }
public async Task <HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) { logger?.Info($"{nameof(GetImageResponse)}-{url}"); int type = 0; var i = url.IndexOf(image_type_param_name, StringComparison.OrdinalIgnoreCase); if (i > 0) { try { var p = url.Substring(i + image_type_param_name.Length).Trim('=').Trim(); url = url.Substring(0, i - 1);//减去一个连接符 int.TryParse(p, out type); } catch (Exception ex) { logger?.Error(ex.ToString()); } } var key = WebUtility.UrlEncode(url); var cache_file = Path.Combine(appPaths.GetImageCachePath().ToString(), key); byte[] bytes = null; //尝试从缓存中读取 try { var fi = fileSystem.GetFileInfo(cache_file); //图片文件存在,且是24小时之内的 if (fi.Exists && fileSystem.GetFileInfo(cache_file).LastWriteTimeUtc > DateTime.Now.AddDays(-1).ToUniversalTime()) { bytes = await fileSystem.ReadAllBytesAsync(cache_file); logger?.Info($"Hit image cache {url} {cache_file}"); if (type == 1) { var ci = await CutImage(bytes); if (ci != null) { return(ci); } } fileExtensionContentTypeProvider.TryGetContentType(url, out var contentType); return(new HttpResponseInfo() { Content = new MemoryStream(bytes), ContentLength = bytes.Length, ContentType = contentType ?? "image/jpeg", StatusCode = HttpStatusCode.OK, }); } } catch (Exception ex) { logger?.Warn($"Read image cache error. {url} {cache_file} {ex.Message}"); } try { var resp = await client.GetAsync(url, cancellationToken); if (resp.IsSuccessStatusCode == false) { return(await Parse(resp)); } try { fileSystem.WriteAllBytes(cache_file, await resp.Content.ReadAsByteArrayAsync()); logger?.Info($"Save image cache {url} {cache_file} "); } catch (Exception ex) { logger?.Warn($"Save image cache error. {url} {cache_file} {ex.Message}"); } if (type == 1) { var ci = await CutImage(await resp.Content.ReadAsByteArrayAsync()); if (ci != null) { return(ci); } } return(await Parse(resp)); } catch (Exception ex) { logger?.Error(ex.ToString()); } return(new HttpResponseInfo()); }
/// <summary> /// Sets the image path. /// </summary> /// <param name="item">The item.</param> /// <param name="type">The type.</param> /// <param name="imageIndex">Index of the image.</param> /// <param name="path">The path.</param> /// <exception cref="System.ArgumentNullException">imageIndex /// or /// imageIndex</exception> private void SetImagePath(IHasImages item, ImageType type, int?imageIndex, string path) { item.SetImagePath(type, imageIndex ?? 0, _fileSystem.GetFileInfo(path)); }
private void InnerFileOpen(object sender, WriterCommandEventArgs args) { if (args.Mode == WriterCommandEventMode.QueryState) { args.Enabled = args.Document != null && args.EditorControl != null; } if (args.Mode == WriterCommandEventMode.Invoke) { IFileSystem fs = args.Host.FileSystems.Docuemnt; args.Result = false; if (args.Document.Modified) { if (QuerySave(args) == false) { return; } } if (args.Parameter is System.IO.Stream) { // 用户参数为一个文件流对象,则以XML的格式从这个流中加载数据 System.IO.Stream stream = (System.IO.Stream)args.Parameter; args.EditorControl.LoadDocument(stream, FileFormat.XML); args.Document.FileName = null; args.Result = true; args.Document.OnSelectionChanged(); args.Document.OnDocumentContentChanged(); return; } string fileName = null; if (args.Parameter is string) { // 用户指定文件名了 fileName = (string)args.Parameter; if (fileName.StartsWith("rawxml:")) { // 认为是原生态的XML字符串 fileName = fileName.Substring("rawxml:".Length); System.IO.StringReader myStr = new System.IO.StringReader(fileName); args.EditorControl.LoadDocument(myStr, FileFormat.XML); args.Document.FileName = null; args.Result = true; args.Document.OnSelectionChanged(); args.Document.OnDocumentContentChanged(); return; } } if (args.ShowUI) { fileName = fs.BrowseOpen(args.Host.Services, fileName); if (string.IsNullOrEmpty(fileName)) { // 用户取消操作 return; } } VFileInfo info = fs.GetFileInfo(args.Host.Services, fileName); if (info.Exists) { FileFormat format = WriterUtils.ParseFileFormat(info.Format); System.IO.Stream stream = fs.Open(args.Host.Services, fileName); if (args.Host.Debuger != null) { args.Host.Debuger.DebugLoadingFile(fileName); } if (stream != null) { int length = 0; using (stream) { //args.Document.FileName = fileName; args.EditorControl.Document.BaseUrl = System.IO.Path.GetDirectoryName(fileName) + "\\"; args.Document.FileName = fileName; args.EditorControl.LoadDocument(stream, format); args.Document.FileName = fileName; length = (int)stream.Length; } if (args.Host.Debuger != null) { args.Host.Debuger.DebugLoadFileComplete(length); } args.Document.OnSelectionChanged(); args.Document.OnDocumentContentChanged(); args.Document.FileName = fileName; args.Result = true; args.RefreshLevel = UIStateRefreshLevel.All; } else { args.Result = false; args.RefreshLevel = UIStateRefreshLevel.None; return; } } else { if (args.ShowUI) { MessageBox.Show( args.EditorControl, string.Format(WriterStrings.FileNotExist_FileName, fileName), WriterStrings.SystemAlert, MessageBoxButtons.OK, MessageBoxIcon.Information); } args.Result = false; } } }