public ApiRequest(IRequestInfo requestinfo, CollectionSettings currentCollectionSettings, Book.Book currentBook) { _requestInfo = requestinfo; CurrentCollectionSettings = currentCollectionSettings; CurrentBook = currentBook; Parameters = requestinfo.GetQueryParameters(); }
/// <summary> /// Check for files that may be missing but that we know aren't important enough to complain about. /// Includes files marked "?optional=true" (not currently used, but may be useful some day) and image files in the CurrentBook folder. /// </summary> protected static bool ShouldReportFailedRequest(IRequestInfo info, string currentBookFolderPath = null) { // images with src derived from Branding API img elements get this marker // in XMatterHelper.CleanupBrandingImages() to prevent spurious reports of // images that are intentionally optional. var hasOptionalQueryParam = info.GetQueryParameters().Get("optional") == "true"; if (hasOptionalQueryParam) { return(false); } var localPath = GetLocalPathWithoutQuery(info); // We don't need even a toast for missing images in the book folder. That's the user's problem and should be adequately // documented by the browser message saying the file is missing. if (currentBookFolderPath != null && localPath.StartsWith(currentBookFolderPath.Replace("\\", "/"))) { return(false); } var stuffToIgnore = new[] { // browser/debugger stuff "favicon.ico", ".map", // Audio files may well be missing because we look for them as soon // as we define an audio ID, but they wont' exist until we record something. "/audio/", // PageTemplatesApi creates a path containing this for a missing template. // it gets reported inside the page chooser dialog. "missingpagetemplate", // Branding image files are expected to be missing in the normal case. Only organizations that care about branding would have these images. "/branding/image", // This is readium stuff that we don't ship with, because they are needed by the original reader to support display and implementation // of controls we hide for things like adding books to collection, displaying the collection, playing audio (that last we might want back one day). EpubMaker.kEPUBExportFolder.ToLowerInvariant() }; return(!stuffToIgnore.Any(s => localPath.ToLowerInvariant().Contains(s))); }
public static bool HandleRequest(string localPath, IRequestInfo info, CollectionSettings currentCollectionSettings) { var lastSep = localPath.IndexOf("/", System.StringComparison.Ordinal); var lastSegment = (lastSep > -1) ? localPath.Substring(lastSep + 1) : localPath; switch (lastSegment) { case "loadStrings": while (_localizing) { Thread.Sleep(0); } try { _localizing = true; var d = new Dictionary <string, string>(); var post = info.GetPostDataWhenFormEncoded(); if (post != null) { foreach (string key in post.Keys) { try { if (d.ContainsKey(key)) { continue; } // Now that end users can create templates, it's annoying to report that their names, // page labels, and page descriptions don't have localizations. if (IsTemplateBookKey(key)) { continue; } var translation = GetTranslationDefaultMayNotBeEnglish(key, post[key]); d.Add(key, translation); } catch (Exception error) { Debug.Fail("Debug Only:" + error.Message + Environment.NewLine + "A bug reported at this location is BL-923"); //Until BL-923 is fixed (hard... it's a race condition, it's better to swallow this for users } } } info.ContentType = "application/json"; info.WriteCompleteOutput(JsonConvert.SerializeObject(d)); return(true); } finally { _localizing = false; } break; case "translate": var parameters = info.GetQueryParameters(); string id = parameters["key"]; string englishText = parameters["englishText"]; string langId = parameters["langId"]; langId = langId.Replace("V", currentCollectionSettings.Language1Iso639Code); langId = langId.Replace("N1", currentCollectionSettings.Language2Iso639Code); langId = langId.Replace("N2", currentCollectionSettings.Language3Iso639Code); langId = langId.Replace("UI", LocalizationManager.UILanguageId); if (LocalizationManager.GetIsStringAvailableForLangId(id, langId)) { info.ContentType = "text/plain"; info.WriteCompleteOutput(LocalizationManager.GetDynamicStringOrEnglish("Bloom", id, englishText, null, langId)); return(true); } else { // Don't report missing strings if they are numbers // Enhance: We might get the Javascript to do locale specific numbers someday // The C# side doesn't currently have the smarts to do DigitSubstitution // See Remark at https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.digitsubstitution(v=vs.110).aspx if (IsInteger(id)) { englishText = id; } else { // Now that end users can create templates, it's annoying to report that their names, // page labels, and page descriptions don't have localizations. if (IsTemplateBookKey(id)) { englishText = englishText.Trim(); } else { // it's ok if we don't have a translation, but if the string isn't even in the list of things that need translating, // then we want to remind the developer to add it to the english xlf file. if (!LocalizationManager.GetIsStringAvailableForLangId(id, "en")) { ReportL10NMissingString(id, englishText, UrlPathString.CreateFromUrlEncodedString(parameters["comment"] ?? "").NotEncoded); } else { //ok, so we don't have it translated yet. Make sure it's at least listed in the things that can be translated. // And return the English string, which is what we would do the next time anyway. (BL-3374) LocalizationManager.GetDynamicString("Bloom", id, englishText); } } } info.ContentType = "text/plain"; info.WriteCompleteOutput(englishText); return(true); } break; } return(false); }
public static bool HandleRequest(string localPath, IRequestInfo info, CollectionSettings currentCollectionSettings) { var lastSep = localPath.IndexOf("/", System.StringComparison.Ordinal); var lastSegment = (lastSep > -1) ? localPath.Substring(lastSep + 1) : localPath; switch (lastSegment) { case "loadStrings": while (_localizing) { Thread.Sleep(0); } try { _localizing = true; var d = new Dictionary<string, string>(); var post = info.GetPostDataWhenFormEncoded(); if (post != null) { foreach (string key in post.Keys) { try { if (!d.ContainsKey(key)) { var translation = GetTranslationDefaultMayNotBeEnglish(key, post[key]); d.Add(key, translation); } } catch (Exception error) { Debug.Fail("Debug Only:" +error.Message+Environment.NewLine+"A bug reported at this location is BL-923"); //Until BL-923 is fixed (hard... it's a race condition, it's better to swallow this for users } } } info.ContentType = "application/json"; info.WriteCompleteOutput(JsonConvert.SerializeObject(d)); return true; } finally { _localizing = false; } break; case "translate": var parameters = info.GetQueryParameters(); string id = parameters["key"]; string englishText = parameters["englishText"]; string langId = parameters["langId"]; langId = langId.Replace("V", currentCollectionSettings.Language1Iso639Code); langId = langId.Replace("N1", currentCollectionSettings.Language2Iso639Code); langId = langId.Replace("N2", currentCollectionSettings.Language3Iso639Code); langId = langId.Replace("UI", LocalizationManager.UILanguageId); if (LocalizationManager.GetIsStringAvailableForLangId(id, langId)) { info.ContentType = "text/plain"; info.WriteCompleteOutput(LocalizationManager.GetDynamicStringOrEnglish("Bloom", id, englishText, null, langId)); return true; } else { // Don't report missing strings if they are numbers // Enhance: We might get the Javascript to do locale specific numbers someday // The C# side doesn't currently have the smarts to do DigitSubstitution // See Remark at https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.digitsubstitution(v=vs.110).aspx if (IsInteger(id)) { englishText = id; } else { // it's ok if we don't have a translation, but if the string isn't even in the list of things that need translating, // then we want to remind the developer to add it to the english tmx file. if (!LocalizationManager.GetIsStringAvailableForLangId(id, "en")) { ReportL10NMissingString(id, englishText); } else { //ok, so we don't have it translated yet. Make sure it's at least listed in the things that can be translated. // And return the English string, which is what we would do the next time anyway. (BL-3374) LocalizationManager.GetDynamicString("Bloom", id, englishText); } } info.ContentType = "text/plain"; info.WriteCompleteOutput(englishText); return true; } break; } return false; }
protected override bool ProcessRequest(IRequestInfo info) { if (base.ProcessRequest(info)) { return(true); } if (!_useCache) { return(false); } var imageFile = GetLocalPathWithoutQuery(info); // only process images var isSvg = imageFile.EndsWith(".svg", StringComparison.OrdinalIgnoreCase); if (!IsImageTypeThatCanBeDegraded(imageFile) && !isSvg) { return(false); } imageFile = imageFile.Replace("thumbnail", ""); var processImage = !isSvg; if (imageFile.StartsWith(OriginalImageMarker + "/")) { processImage = false; imageFile = imageFile.Substring((OriginalImageMarker + "/").Length); if (!RobustFile.Exists(imageFile)) { // We didn't find the file here, and don't want to use the following else if or we could errantly // find it in the browser root. For example, this outer if (imageFile.StartsWith...) was added because // we were accidentally finding license.png in a template book. See BL-4290. return(false); } } // This happens with the new way we are serving css files else if (!RobustFile.Exists(imageFile)) { var fileName = Path.GetFileName(imageFile); var sourceDir = FileLocator.GetDirectoryDistributedWithApplication(BloomFileLocator.BrowserRoot); imageFile = Directory.EnumerateFiles(sourceDir, fileName, SearchOption.AllDirectories).FirstOrDefault(); // image file not found if (string.IsNullOrEmpty(imageFile)) { return(false); } // BL-2368: Do not process files from the BloomBrowserUI directory. These files are already in the state we // want them. Running them through _cache.GetPathToResizedImage() is not necessary, and in PNG files // it converts all white areas to transparent. This is resulting in icons which only contain white // (because they are rendered on a dark background) becoming completely invisible. processImage = false; } var originalImageFile = imageFile; if (processImage) { // thumbnail requests have the thumbnail parameter set in the query string var thumb = info.GetQueryParameters()["thumbnail"] != null; imageFile = _cache.GetPathToResizedImage(imageFile, thumb); if (string.IsNullOrEmpty(imageFile)) { return(false); } } info.ReplyWithImage(imageFile, originalImageFile); return(true); }
protected override bool ProcessRequest(IRequestInfo info) { if (base.ProcessRequest(info)) return true; if (!_useCache) return false; var imageFile = GetLocalPathWithoutQuery(info); // only process images var isSvg = imageFile.EndsWith(".svg", StringComparison.OrdinalIgnoreCase); if (!IsImageTypeThatCanBeDegraded(imageFile) && !isSvg) return false; imageFile = imageFile.Replace("thumbnail", ""); var processImage = !isSvg; // This happens with the new way we are serving css files if (!RobustFile.Exists(imageFile)) { var fileName = Path.GetFileName(imageFile); var sourceDir = FileLocator.GetDirectoryDistributedWithApplication(BloomFileLocator.BrowserRoot); imageFile = Directory.EnumerateFiles(sourceDir, fileName, SearchOption.AllDirectories).FirstOrDefault(); // image file not found if (string.IsNullOrEmpty(imageFile)) return false; // BL-2368: Do not process files from the BloomBrowserUI directory. These files are already in the state we // want them. Running them through _cache.GetPathToResizedImage() is not necessary, and in PNG files // it converts all white areas to transparent. This is resulting in icons which only contain white // (because they are rendered on a dark background) becoming completely invisible. processImage = false; } if (processImage) { // thumbnail requests have the thumbnail parameter set in the query string var thumb = info.GetQueryParameters()["thumbnail"] != null; imageFile = _cache.GetPathToResizedImage(imageFile, thumb); if (string.IsNullOrEmpty(imageFile)) return false; } info.ReplyWithImage(imageFile); return true; }