public GetBookSetting ( string key ) : MultiTextBase | ||
key | string | |
return | MultiTextBase |
private static bool ShouldSetToDefaultCopyrightAndLicense(HtmlDom dom) { var hasCopyright = !dom.GetBookSetting("copyright").Empty; var hasLicenseUrl = !dom.GetBookSetting("licenseUrl").Empty; var hasLicenseNotes = !dom.GetBookSetting("licenseNotes").Empty; //Enhance: this logic is perhaps overly restrictive? return(!hasCopyright && !hasLicenseUrl && !hasLicenseNotes); }
private static void CopyItemToFieldsInPages(HtmlDom dom, string key, string valueAttribute = null, string[] languagePreferences = null) { if (languagePreferences == null) { languagePreferences = new[] { "*", "en" } } ; MultiTextBase source = dom.GetBookSetting(key); if (key == "copyright") { // For CC0, we store the "copyright", but don't display it in the text of the book. var licenseUrl = dom.GetBookSetting("licenseUrl").GetExactAlternative("*"); if (licenseUrl == CreativeCommonsLicense.CC0Url) { source = new MultiTextBase(); } } foreach (XmlElement target in dom.SafeSelectNodes("//*[@data-derived='" + key + "']")) { //just put value into the text of the element if (string.IsNullOrEmpty(valueAttribute)) { //clear out what's there now target.RemoveAttribute("lang"); target.InnerText = ""; var form = source.GetBestAlternative(languagePreferences); if (form != null && !string.IsNullOrWhiteSpace(form.Form)) { // HtmlDom.GetBookSetting(key) returns the result of XmlNode.InnerXml which will be Html encoded (& < etc). // HtmlDom.SetElementFromUserStringPreservingLineBreaks() calls XmlNode.InnerText, which Html encodes if necessary. // So we need to decode here to prevent double encoding. See http://issues.bloomlibrary.org/youtrack/issue/BL-4585. // Note that HtmlDom.SetElementFromUserStringPreservingLineBreaks() handles embedded <br/> elements, but makes no // effort to handle p or div elements. var decoded = System.Web.HttpUtility.HtmlDecode(form.Form); HtmlDom.SetElementFromUserStringSafely(target, decoded); target.SetAttribute("lang", form.WritingSystemId); //this allows us to set the font to suit the language } } else //Put the value into an attribute. The license image goes through this path. { target.SetAttribute(valueAttribute, source.GetBestAlternativeString(languagePreferences)); if (source.Empty) { //if the license image is empty, make sure we don't have some alternative text //about the image being missing or slow to load target.SetAttribute("alt", ""); //over in javascript land, @alt will get set appropriately when the image url is not empty. } } } }
/// <summary> /// Create a Clearshare.Metadata object by reading values out of the dom's bloomDataDiv /// </summary> /// <param name="brandingNameOrFolderPath"> Normally, the branding is just a name, which we look up in the official branding folder //but unit tests can instead provide a path to the folder. /// </param> public static Metadata GetMetadata(HtmlDom dom, string brandingNameOrFolderPath = "") { if (ShouldSetToDefaultCopyrightAndLicense(dom)) { return GetMetadataWithDefaultCopyrightAndLicense(brandingNameOrFolderPath); } var metadata = new Metadata(); var copyright = dom.GetBookSetting("copyright"); if (!copyright.Empty) { metadata.CopyrightNotice = WebUtility.HtmlDecode(copyright.GetFirstAlternative()); } var licenseUrl = dom.GetBookSetting("licenseUrl").GetBestAlternativeString(new[] { "*", "en" }); if (string.IsNullOrWhiteSpace(licenseUrl)) { //NB: we are mapping "RightsStatement" (which comes from XMP-dc:Rights) to "LicenseNotes" in the html. //custom licenses live in this field, so if we have notes (and no URL) it is a custom one. var licenseNotes = dom.GetBookSetting("licenseNotes"); if (!licenseNotes.Empty) { metadata.License = new CustomLicense { RightsStatement = WebUtility.HtmlDecode(licenseNotes.GetFirstAlternative()) }; } else { // The only remaining current option is a NullLicense metadata.License = new NullLicense(); //"contact the copyright owner } } else // there is a licenseUrl, which means it is a CC license { try { metadata.License = CreativeCommonsLicense.FromLicenseUrl(licenseUrl); } catch (Exception e) { throw new ApplicationException("Bloom had trouble parsing this license url: '" + licenseUrl + "'. (ref BL-4108)", e); } //are there notes that go along with that? var licenseNotes = dom.GetBookSetting("licenseNotes"); if(!licenseNotes.Empty) { var s = WebUtility.HtmlDecode(licenseNotes.GetFirstAlternative()); metadata.License.RightsStatement = HtmlDom.ConvertHtmlBreaksToNewLines(s); } } return metadata; }
/// <summary> /// Copy the copyright & license info to the originalCopyrightAndLicense, /// then remove the copyright so the translator can put in their own if they /// want. We retain the license, but the translator is allowed to change that. /// If the source is already a translation (already has original copyright or license) /// we keep them unchanged. /// </summary> public static void SetOriginalCopyrightAndLicense(HtmlDom dom, BookData bookData, CollectionSettings collectionSettings) { // At least one of these should exist if the source was a derivative, since we don't allow a // book to have no license, nor to be uploaded without copyright...unless of course it was derived // before 3.9, when we started doing this. In that case the best we can do is record the earliest // information we have for this and later adaptations. if (bookData.GetMultiTextVariableOrEmpty("originalLicenseUrl").Count > 0 || bookData.GetMultiTextVariableOrEmpty("originalLicenseNotes").Count > 0 || bookData.GetMultiTextVariableOrEmpty("originalCopyright").Count > 0) { return; //leave the original there. } // If there's no copyright information in a source-collection book, we're presumably making // a new original book, and shouldn't try to record any original copyright and license information. // This is somewhat redundant with the check in BookStarter.SetupNewDocumentContents(), the one // non-unit-test current caller of this method, that doesn't call this at all if the source is // a template book. I was trying for a minimal reasonable change for BL-5131, and therefore // put in this extra check, since previously this method was simply NEVER called in a source // collection. var copyrightNotice = GetMetadata(dom).CopyrightNotice; if (string.IsNullOrEmpty(copyrightNotice) && collectionSettings.IsSourceCollection) { return; } bookData.Set("originalLicenseUrl", GetLicenseUrl(dom), "*"); bookData.Set("originalCopyright", System.Web.HttpUtility.HtmlEncode(copyrightNotice), "*"); bookData.Set("originalLicenseNotes", dom.GetBookSetting("licenseNotes").GetFirstAlternative(), "*"); bookData.RemoveAllForms("copyright"); // RemoveAllForms does modify the dom }
/// <summary> /// Create a Clearshare.Metadata object by reading values out of the dom's bloomDataDiv /// </summary> /// <param name="brandingNameOrFolderPath"> Normally, the branding is just a name, which we look up in the official branding folder //but unit tests can instead provide a path to the folder. /// </param> public static Metadata GetMetadata(HtmlDom dom, string brandingNameOrFolderPath = "") { if (ShouldSetToDefaultCopyrightAndLicense(dom)) { return(GetMetadataWithDefaultCopyrightAndLicense(brandingNameOrFolderPath)); } return(CreateMetadata(dom.GetBookSetting("copyright"), GetLicenseUrl(dom), dom.GetBookSetting("licenseNotes"))); }
/// <summary> /// Create a Clearshare.Metadata object by reading values out of the dom's bloomDataDiv /// </summary> public static Metadata GetMetadata(HtmlDom dom, BookData bookData) { if (ShouldSetToDefaultCopyrightAndLicense(dom)) { return(GetMetadataWithDefaultCopyrightAndLicense()); } return(CreateMetadata(dom.GetBookSetting("copyright"), GetLicenseUrl(dom), dom.GetBookSetting("licenseNotes"), bookData)); }
private static bool ShouldSetToDefaultCopyrightAndLicense(HtmlDom dom) { //Enhance: this logic is perhaps overly restrictive? foreach (var setting in SettingsToCheckForDefaultCopyright) { if (!dom.GetBookSetting(setting).Empty) { return(false); } } return(true); }
internal static string GetOriginalCopyrightAndLicenseNotice(BookData bookData, HtmlDom dom) { var originalMetadata = GetOriginalMetadata(dom, bookData); // As of BL-7898, we are using the existence of an original copyright/license to determine if we are working with a derivative. if (!IsDerivative(originalMetadata)) { return(null); } // The originalTitle strategy used here is not ideal. We would prefer to have a placeholder specifically for it // in both EditTab.FrontMatter.OriginalCopyrightSentence and EditTab.FrontMatter.OriginalHadNoCopyrightSentence. // But we don't want to require a new set of translations if we can avoid it. var encodedTitle = dom.GetBookSetting("originalTitle")?.GetExactAlternative("*"); var originalTitle = HttpUtility.HtmlDecode(encodedTitle); var titleCitation = "<cite data-book=\"originalTitle\"" + (string.IsNullOrEmpty(originalTitle) ? " class=\"missingOriginalTitle\">" : ">") + originalTitle + "</cite>"; var languagePriorityIdsNotLang1 = bookData.GetLanguagePrioritiesForLocalizedTextOnPage(false); var originalLicenseSentence = GetOriginalLicenseSentence(languagePriorityIdsNotLang1, originalMetadata.License, out string licenseOnly); var rawCopyright = originalMetadata.CopyrightNotice; // If we have all the pieces available, we want to use this one. // At the very least it's easier to localize into the format the language wants to use. var fullFormatString = LocalizationManager.GetString( "EditTab.FrontMatter.FullOriginalCopyrightLicenseSentence", "Adapted from original, {0}, {1}. Licensed under {2}.", "On the Credits page of a book being translated, Bloom shows the original copyright. {0} is original title, {1} is original copyright, and {2} is license information.", languagePriorityIdsNotLang1, out string langUsed); // The last condition here (langUsed ==...) is meant to detect if the string has been translated // into the current language or not. if (!string.IsNullOrEmpty(originalTitle) && !string.IsNullOrEmpty(rawCopyright) && !string.IsNullOrEmpty(licenseOnly) && langUsed == languagePriorityIdsNotLang1.First()) { return(string.Format(fullFormatString, titleCitation, rawCopyright, licenseOnly)); } var copyrightNotice = GetOriginalCopyrightSentence( languagePriorityIdsNotLang1, rawCopyright, titleCitation).Trim(); return((copyrightNotice + " " + originalLicenseSentence).Trim()); }
private static void CopyItemToFieldsInPages(HtmlDom dom, string key, string valueAttribute = null, string[] languagePreferences = null) { if (languagePreferences == null) { languagePreferences = new[] { "*", "en" } } ; MultiTextBase source = dom.GetBookSetting(key); var target = dom.SelectSingleNode("//*[@data-derived='" + key + "']"); if (target == null) { return; } //just put value into the text of the element if (string.IsNullOrEmpty(valueAttribute)) { //clear out what's there now target.RemoveAttribute("lang"); target.InnerText = ""; var form = source.GetBestAlternative(languagePreferences); if (form != null && !string.IsNullOrWhiteSpace(form.Form)) { HtmlDom.SetElementFromUserStringPreservingLineBreaks(target, form.Form); target.SetAttribute("lang", form.WritingSystemId); //this allows us to set the font to suit the language } } else //Put the value into an attribute. The license image goes through this path. { target.SetAttribute(valueAttribute, source.GetBestAlternativeString(languagePreferences)); if (source.Empty) { //if the license image is empty, make sure we don't have some alternative text //about the image being missing or slow to load target.SetAttribute("alt", ""); //over in javascript land, @alt will get set appropriately when the image url is not empty. } } }
/// <summary> /// Copy the copyright & license info to the originalCopyrightAndLicense, /// then remove the copyright so the translator can put in their own if they /// want. We retain the license, but the translator is allowed to change that. /// If the source is already a translation (already has original copyright or license) /// we keep them unchanged. /// </summary> public static void SetOriginalCopyrightAndLicense(HtmlDom dom, BookData bookData, CollectionSettings collectionSettings) { // If it already has some of this information, just keep it. if (bookData.BookIsDerivative()) { return; //leave the original there. } // If there's no copyright information in a source-collection book, we're presumably making // a new original book, and shouldn't try to record any original copyright and license information. // This is somewhat redundant with the check in BookStarter.SetupNewDocumentContents(), the one // non-unit-test current caller of this method, that doesn't call this at all if the source is // a template book. I was trying for a minimal reasonable change for BL-5131, and therefore // put in this extra check, since previously this method was simply NEVER called in a source // collection. var copyrightNotice = BookCopyrightAndLicense.GetMetadata(dom).CopyrightNotice; if (String.IsNullOrEmpty(copyrightNotice) && collectionSettings.IsSourceCollection) { return; } bookData.Set("originalLicenseUrl", BookCopyrightAndLicense.GetLicenseUrl(dom), "*"); bookData.Set("originalCopyright", System.Web.HttpUtility.HtmlEncode(copyrightNotice), "*"); bookData.Set("originalLicenseNotes", dom.GetBookSetting("licenseNotes").GetFirstAlternative(), "*"); }
public static void LogMetdata(HtmlDom dom) { Logger.WriteEvent("LicenseUrl: " + dom.GetBookSetting("licenseUrl")); Logger.WriteEvent("LicenseNotes: " + dom.GetBookSetting("licenseNotes")); Logger.WriteEvent(""); }
public static string GetLicenseUrl(HtmlDom dom) { return(dom.GetBookSetting("licenseUrl").GetBestAlternativeString(new[] { "*", "en" })); }
public void GetBookSetting_TwoVariationsWereThere_ReturnsBoth() { var bookDom = new HtmlDom(@"<html ><head></head><body> <div id='bloomDataDiv'> <div data-book='leaveMe' lang='en'>something unique</div> <div data-book='getMe' lang='id'>Buku</div> <div data-book='getMe' lang='tpi'>Buk</div> </div> </body></html>"); var result = bookDom.GetBookSetting("getMe"); Assert.AreEqual(2,result.Count); Assert.AreEqual("Buk", result["tpi"]); Assert.AreEqual("Buku", result["id"]); }
public void GetBookSetting_NotThere_ReturnsEmptyMultistring() { var bookDom = new HtmlDom(@"<html ><head></head><body> <div id='bloomDataDiv'> </div> </body></html>"); var result = bookDom.GetBookSetting("getMe"); Assert.AreEqual(0, result.Count); }
private static bool ShouldSetToDefaultCopyrightAndLicense(HtmlDom dom) { var hasCopyright = !dom.GetBookSetting("copyright").Empty; var hasLicenseUrl = !dom.GetBookSetting("licenseUrl").Empty; var hasLicenseNotes = !dom.GetBookSetting("licenseNotes").Empty; //Enhance: this logic is perhaps overly restrictive? return !hasCopyright && !hasLicenseUrl && !hasLicenseNotes; }
internal static string GetOriginalCopyrightAndLicenseNotice(CollectionSettings collectionSettings, HtmlDom dom) { var originalMetadata = GetOriginalMetadata(dom); // As of BL-7898, we are using the existence of an original copyright/license to determine if we are working with a derivative. if (!IsDerivative(originalMetadata)) { return(null); } string idOfLanguageUsed; var languagePriorityIds = collectionSettings.LicenseDescriptionLanguagePriorities; var license = originalMetadata.License.GetMinimalFormForCredits(languagePriorityIds, out idOfLanguageUsed); string originalLicenseSentence; var preferredLanguageIds = new[] { collectionSettings.Language2Iso639Code, LocalizationManager.UILanguageId, "en" }; // The originalTitle strategy used here is not ideal. We would prefer to have a placeholder specifically for it // in both EditTab.FrontMatter.OriginalCopyrightSentence and EditTab.FrontMatter.OriginalHadNoCopyrightSentence. // But we don't want to require a new set of translations if we can avoid it. string encodedTitle = dom.GetBookSetting("originalTitle")?.GetExactAlternative("*"); string originalTitle = HttpUtility.HtmlDecode(encodedTitle); // Used when we insert into the no-copyright string, typically "Adapted from an original with no copyright" var originalTitleBeforePeriod = ", <cite data-book=\"originalTitle\">" + originalTitle + "</cite>"; // Used when we insert into the usual string, typicall "Adapted from original, {0}" ahead of the copyright and license // as part of the {0} replacement. var originalTitleAfterComma = "<cite data-book=\"originalTitle\">" + originalTitle + "</cite>, "; if (string.IsNullOrEmpty(originalTitle)) { // We need to add the "missingOriginalTitle class. originalTitleBeforePeriod = ", <cite data-book=\"originalTitle\" class=\"missingOriginalTitle\"></cite>"; originalTitleAfterComma = "<cite data-book=\"originalTitle\" class=\"missingOriginalTitle\"></cite>, "; } if (originalMetadata.License is CustomLicense) { // I can imagine being more fancy... something like "Licensed under custom license:", and get localizations // for that... but sheesh, these are even now very rare in Bloom-land and should become more rare. // So for now, let's just print the custom license contents. originalLicenseSentence = license; } else { var licenseSentenceTemplate = LocalizationManager.GetString("EditTab.FrontMatter.OriginalLicenseSentence", "Licensed under {0}.", "On the Credits page of a book being translated, Bloom puts texts like 'Licensed under CC-BY', so that we have a record of what the license was for the original book. Put {0} in the translation, where the license should go in the sentence.", preferredLanguageIds, out idOfLanguageUsed); originalLicenseSentence = string.IsNullOrWhiteSpace(license) ? "" : string.Format(licenseSentenceTemplate, license); originalLicenseSentence = originalLicenseSentence.Replace("..", "."); // in case had notes which also had a period. } string copyrightNotice; if (string.IsNullOrWhiteSpace(originalMetadata.CopyrightNotice)) { var noCopyrightSentence = LocalizationManager.GetString("EditTab.FrontMatter.OriginalHadNoCopyrightSentence", "Adapted from original without a copyright notice.", "On the Credits page of a book being translated, Bloom shows this if the original book did not have a copyright notice.", preferredLanguageIds, out idOfLanguageUsed); noCopyrightSentence = noCopyrightSentence.Substring(0, noCopyrightSentence.Length - 1) + originalTitleBeforePeriod + "."; copyrightNotice = noCopyrightSentence + " " + originalLicenseSentence; } else { var originalCopyrightSentence = LocalizationManager.GetString("EditTab.FrontMatter.OriginalCopyrightSentence", "Adapted from original, {0}.", "On the Credits page of a book being translated, Bloom shows the original copyright. Put {0} in the translation where the copyright notice should go. For example in English, 'Adapted from original, {0}.' comes out like 'Adapted from original, Copyright 2011 SIL'.", preferredLanguageIds, out idOfLanguageUsed); copyrightNotice = String.Format(originalCopyrightSentence, originalTitleAfterComma + originalMetadata.CopyrightNotice.Trim()) + " " + originalLicenseSentence; } return(copyrightNotice.Trim()); }
public static Metadata GetOriginalMetadata(HtmlDom dom, string brandingNameOrFolderPath = "") { return(CreateMetadata(dom.GetBookSetting("originalCopyright"), dom.GetBookSetting("originalLicenseUrl").GetExactAlternative("*"), dom.GetBookSetting("originalLicenseNotes"))); }
public static void LogMetdata(HtmlDom dom) { Logger.WriteEvent("LicenseUrl: " + dom.GetBookSetting("licenseUrl")); Logger.WriteEvent("LicenseNotes: " + dom.GetBookSetting("licenseNotes")); Logger.WriteEvent(""); }
/// <summary> /// Create a Clearshare.Metadata object by reading values out of the dom's bloomDataDiv /// </summary> /// <param name="brandingNameOrFolderPath"> Normally, the branding is just a name, which we look up in the official branding folder //but unit tests can instead provide a path to the folder. /// </param> public static Metadata GetMetadata(HtmlDom dom, string brandingNameOrFolderPath = "") { if (ShouldSetToDefaultCopyrightAndLicense(dom)) { return(GetMetadataWithDefaultCopyrightAndLicense(brandingNameOrFolderPath)); } var metadata = new Metadata(); var copyright = dom.GetBookSetting("copyright"); if (!copyright.Empty) { metadata.CopyrightNotice = WebUtility.HtmlDecode(copyright.GetFirstAlternative()); } var licenseUrl = dom.GetBookSetting("licenseUrl").GetBestAlternativeString(new[] { "*", "en" }); if (string.IsNullOrWhiteSpace(licenseUrl)) { //NB: we are mapping "RightsStatement" (which comes from XMP-dc:Rights) to "LicenseNotes" in the html. //custom licenses live in this field, so if we have notes (and no URL) it is a custom one. var licenseNotes = dom.GetBookSetting("licenseNotes"); if (!licenseNotes.Empty) { metadata.License = new CustomLicense { RightsStatement = WebUtility.HtmlDecode(licenseNotes.GetFirstAlternative()) }; } else { // The only remaining current option is a NullLicense metadata.License = new NullLicense(); //"contact the copyright owner } } else // there is a licenseUrl, which means it is a CC license { try { metadata.License = CreativeCommonsLicense.FromLicenseUrl(licenseUrl); } catch (IndexOutOfRangeException) { // Need to handle urls which do not end with the version number. // Simply set it to the default version. if (!licenseUrl.EndsWith("/")) { licenseUrl += "/"; } licenseUrl += CreativeCommonsLicense.kDefaultVersion; metadata.License = CreativeCommonsLicense.FromLicenseUrl(licenseUrl); } catch (Exception e) { throw new ApplicationException("Bloom had trouble parsing this license url: '" + licenseUrl + "'. (ref BL-4108)", e); } //are there notes that go along with that? var licenseNotes = dom.GetBookSetting("licenseNotes"); if (!licenseNotes.Empty) { var s = WebUtility.HtmlDecode(licenseNotes.GetFirstAlternative()); metadata.License.RightsStatement = HtmlDom.ConvertHtmlBreaksToNewLines(s); } } return(metadata); }
public static Metadata GetOriginalMetadata(HtmlDom dom, BookData bookData) { return(CreateMetadata(dom.GetBookSetting("originalCopyright"), dom.GetBookSetting("originalLicenseUrl").GetExactAlternative("*"), dom.GetBookSetting("originalLicenseNotes"), bookData)); }
private static void CopyItemToFieldsInPages(HtmlDom dom, string key, string valueAttribute = null, string[] languagePreferences= null) { if (languagePreferences == null) languagePreferences = new[] {"*", "en"}; MultiTextBase source = dom.GetBookSetting(key); var target = dom.SelectSingleNode("//*[@data-derived='" + key + "']"); if (target == null) { return; } //just put value into the text of the element if (string.IsNullOrEmpty(valueAttribute)) { //clear out what's there now target.RemoveAttribute("lang"); target.InnerText = ""; var form = source.GetBestAlternative(languagePreferences); if (form != null && !string.IsNullOrWhiteSpace(form.Form)) { HtmlDom.SetElementFromUserStringPreservingLineBreaks(target, form.Form); target.SetAttribute("lang", form.WritingSystemId); //this allows us to set the font to suit the language } } else //Put the value into an attribute. The license image goes through this path. { target.SetAttribute(valueAttribute, source.GetBestAlternativeString(languagePreferences)); if (source.Empty) { //if the license image is empty, make sure we don't have some alternative text //about the image being missing or slow to load target.SetAttribute("alt", ""); //over in javascript land, @alt will get set appropriately when the image url is not empty. } } }