public ActionResult Add(int id) { if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage image profiles"))) return new HttpUnauthorizedResult(); var viewModel = new FilterAddViewModel {Id = id, Filters = _processingManager.DescribeFilters()}; return View(viewModel); }
public ActionResult Edit(int id) { if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to edit media profiles"))) { return(new HttpUnauthorizedResult()); } var profile = _profileService.GetImageProfile(id); var viewModel = new AdminEditViewModel { Id = profile.Id, Name = profile.Name }; var filterEntries = new List <FilterEntry>(); var allFilters = _imageProcessingManager.DescribeFilters().SelectMany(x => x.Descriptors).ToList(); foreach (var filter in profile.Filters.OrderBy(f => f.Position)) { var category = filter.Category; var type = filter.Type; var f = allFilters.FirstOrDefault(x => category == x.Category && type == x.Type); if (f != null) { filterEntries.Add( new FilterEntry { Category = f.Category, Type = f.Type, FilterRecordId = filter.Id, DisplayText = String.IsNullOrWhiteSpace(filter.Description) ? f.Display(new FilterContext { State = FormParametersHelper.ToDynamic(filter.State) }).Text : filter.Description }); } } viewModel.Filters = filterEntries; return(View(viewModel)); }
public string GetImageProfileUrl(string path, string profileName, ContentItem contentItem, params FilterRecord[] customFilters) { // path is the publicUrl of the media, so it might contain url-encoded chars // try to load the processed filename from cache var filePath = _fileNameProvider.GetFileName(profileName, System.Web.HttpUtility.UrlDecode(path)); bool process = false; //after reboot the app cache is empty so we reload the image in the cache if it exists in the _Profiles folder if (string.IsNullOrEmpty(filePath)) { var profileFilePath = _storageProvider.Combine("_Profiles", FormatProfilePath(profileName, System.Web.HttpUtility.UrlDecode(path))); if (_storageProvider.FileExists(profileFilePath)) { _fileNameProvider.UpdateFileName(profileName, System.Web.HttpUtility.UrlDecode(path), profileFilePath); filePath = profileFilePath; } } // if the filename is not cached, process it if (string.IsNullOrEmpty(filePath)) { Logger.Debug("FilePath is null, processing required, profile {0} for image {1}", profileName, path); process = true; } // the processd file doesn't exist anymore, process it else if (!_storageProvider.FileExists(filePath)) { Logger.Debug("Processed file no longer exists, processing required, profile {0} for image {1}", profileName, path); process = true; } // if the original file is more recent, process it else { DateTime pathLastUpdated; if (TryGetImageLastUpdated(path, out pathLastUpdated)) { var filePathLastUpdated = _storageProvider.GetFile(filePath).GetLastUpdated(); if (pathLastUpdated > filePathLastUpdated) { Logger.Debug("Original file more recent, processing required, profile {0} for image {1}", profileName, path); process = true; } } } // todo: regenerate the file if the profile is newer, by deleting the associated filename cache entries. if (process) { Logger.Debug("Processing profile {0} for image {1}", profileName, path); ImageProfilePart profilePart; if (customFilters == null || !customFilters.Any(c => c != null)) { profilePart = _profileService.GetImageProfileByName(profileName); if (profilePart == null) { return(String.Empty); } } else { profilePart = _services.ContentManager.New <ImageProfilePart>("ImageProfile"); profilePart.Name = profileName; foreach (var customFilter in customFilters) { profilePart.Filters.Add(customFilter); } } // prevent two requests from processing the same file at the same time // this is only thread safe at the machine level, so there is a try/catch later // to handle cross machines concurrency lock (String.Intern(path)) { using (var image = GetImage(path)) { if (image == null) { return(null); } var filterContext = new FilterContext { Media = image, FilePath = _storageProvider.Combine("_Profiles", FormatProfilePath(profileName, System.Web.HttpUtility.UrlDecode(path))) }; var tokens = new Dictionary <string, object>(); // if a content item is provided, use it while tokenizing if (contentItem != null) { tokens.Add("Content", contentItem); } foreach (var filter in profilePart.Filters.OrderBy(f => f.Position)) { var descriptor = _processingManager.DescribeFilters().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == filter.Category && x.Type == filter.Type); if (descriptor == null) { continue; } var tokenized = _tokenizer.Replace(filter.State, tokens); filterContext.State = FormParametersHelper.ToDynamic(tokenized); descriptor.Filter(filterContext); } _fileNameProvider.UpdateFileName(profileName, System.Web.HttpUtility.UrlDecode(path), filterContext.FilePath); if (!filterContext.Saved) { try { var newFile = _storageProvider.OpenOrCreate(filterContext.FilePath); using (var imageStream = newFile.OpenWrite()) { using (var sw = new BinaryWriter(imageStream)) { if (filterContext.Media.CanSeek) { filterContext.Media.Seek(0, SeekOrigin.Begin); } using (var sr = new BinaryReader(filterContext.Media)) { int count; var buffer = new byte[8192]; while ((count = sr.Read(buffer, 0, buffer.Length)) != 0) { sw.Write(buffer, 0, count); } } } } } catch (Exception e) { Logger.Error(e, "A profile could not be processed: " + path); } } filterContext.Media.Dispose(); filePath = filterContext.FilePath; } } } // generate a timestamped url to force client caches to update if the file has changed var publicUrl = _storageProvider.GetPublicUrl(filePath); var timestamp = _storageProvider.GetFile(filePath).GetLastUpdated().Ticks; return(publicUrl + "?v=" + timestamp.ToString(CultureInfo.InvariantCulture)); }
public string GetImageProfileUrl(string path, string profileName, FilterRecord customFilter, ContentItem contentItem) { // try to load the processed filename from cache var filePath = _fileNameProvider.GetFileName(profileName, path); bool process = false; // if the filename is not cached, process it if (string.IsNullOrEmpty(filePath)) { Logger.Debug("FilePath is null, processing required, profile {0} for image {1}", profileName, path); process = true; } // the processd file doesn't exist anymore, process it else if (!_storageProvider.FileExists(filePath)) { Logger.Debug("Processed file no longer exists, processing required, profile {0} for image {1}", profileName, path); process = true; } // if the original file is more recent, process it else { DateTime pathLastUpdated; if (TryGetImageLastUpdated(path, out pathLastUpdated)) { var filePathLastUpdated = _storageProvider.GetFile(filePath).GetLastUpdated(); if (pathLastUpdated > filePathLastUpdated) { Logger.Debug("Original file more recent, processing required, profile {0} for image {1}", profileName, path); process = true; } } } // todo: regenerate the file if the profile is newer, by deleting the associated filename cache entries. if (process) { Logger.Debug("Processing profile {0} for image {1}", profileName, path); ImageProfilePart profilePart; if (customFilter == null) { profilePart = _profileService.GetImageProfileByName(profileName); if (profilePart == null) { return(String.Empty); } } else { profilePart = _services.ContentManager.New <ImageProfilePart>("ImageProfile"); profilePart.Name = profileName; profilePart.Filters.Add(customFilter); } using (var image = GetImage(path)) { var filterContext = new FilterContext { Media = image, FilePath = _storageProvider.Combine("_Profiles", _storageProvider.Combine(profileName, CreateDefaultFileName(path))) }; var tokens = new Dictionary <string, object>(); // if a content item is provided, use it while tokenizing if (contentItem != null) { tokens.Add("Content", contentItem); } foreach (var filter in profilePart.Filters.OrderBy(f => f.Position)) { var descriptor = _processingManager.DescribeFilters().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == filter.Category && x.Type == filter.Type); if (descriptor == null) { continue; } var tokenized = _tokenizer.Replace(filter.State, tokens); filterContext.State = FormParametersHelper.ToDynamic(tokenized); descriptor.Filter(filterContext); } _fileNameProvider.UpdateFileName(profileName, path, filterContext.FilePath); if (!filterContext.Saved) { _storageProvider.TryCreateFolder(_storageProvider.Combine("_Profiles", profilePart.Name)); var newFile = _storageProvider.OpenOrCreate(filterContext.FilePath); using (var imageStream = newFile.OpenWrite()) { using (var sw = new BinaryWriter(imageStream)) { if (filterContext.Media.CanSeek) { filterContext.Media.Seek(0, SeekOrigin.Begin); } using (var sr = new BinaryReader(filterContext.Media)) { int count; var buffer = new byte[8192]; while ((count = sr.Read(buffer, 0, buffer.Length)) != 0) { sw.Write(buffer, 0, count); } } } } } filterContext.Media.Dispose(); filePath = filterContext.FilePath; } } // generate a timestamped url to force client caches to update if the file has changed var publicUrl = _storageProvider.GetPublicUrl(filePath); var timestamp = _storageProvider.GetFile(filePath).GetLastUpdated().Ticks; return(publicUrl + "?v=" + timestamp.ToString(CultureInfo.InvariantCulture)); }