Example #1
0
		public void Setup()
		{
			_mediaFile = new Bitmap(10, 10);
			_tempFile = TempFile.WithExtension("png");
			_mediaFile.Save(_tempFile.Path);
		   _outgoing = Metadata.FromFile(_tempFile.Path);
		 }
Example #2
0
        public static void CopyImageMetadataToWholeBook(string folderPath, HtmlDom dom, Metadata metadata, IProgress progress)
        {
            progress.WriteStatus("Starting...");

            //First update the images themselves

            int completed = 0;
            var imgElements = GetImagePaths(folderPath);
            foreach (string path in imgElements)
            {
                progress.ProgressIndicator.PercentCompleted = (int)(100.0 * (float)completed / imgElements.Count());
                progress.WriteStatus("Copying to " + Path.GetFileName(path));

                try
                {
                    metadata.WriteIntellectualPropertyOnly(path);
                }
                catch (TagLib.CorruptFileException e)
                {
                    NonFatalProblem.Report(ModalIf.Beta, PassiveIf.All,"Image metadata problem", "Bloom had a problem accessing the metadata portion of this image " + path+ "  ref(BL-3214)", e);
                }

                ++completed;
            }

            //Now update the html attributes which echo some of it, and is used by javascript to overlay displays related to
            //whether the info is there or missing or whatever.

            foreach (XmlElement img in dom.SafeSelectNodes("//img"))
            {
                UpdateImgMetdataAttributesToMatchImage(folderPath, img, progress, metadata);
            }
        }
Example #3
0
		/// <summary>
		/// Create a MetadataAccess by reading an existing media file
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		public static Metadata FromFile(string path)
		{
			var m = new Metadata();
			m._path = path;

			LoadProperties(path, m);
			return m;
		}
		public void ShowFullDialog()
		{
			var m = new Metadata();
			using (var dlg = new MetadataEditorDialog(m))
			{
				dlg.ShowDialog();
			}
		}
		public void ShowControl()
		{
			var m = new Metadata();
			m.CopyrightNotice = "copyright me";
			m.Creator = "you";
			m.AttributionUrl = "http://google.com";
			m.License = new CreativeCommonsLicense(true, false, CreativeCommonsLicense.DerivativeRules.DerivativesWithShareAndShareAlike);
			var c = new MetadataDisplayControl();
			c.SetMetadata(m);
			var dlg = new Form();
			c.Dock = DockStyle.Fill;
			dlg.Controls.Add(c);
			dlg.ShowDialog();
		}
        /// <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;
        }
		public void ShowControl_NoLicense()
		{
			var m = new Metadata();
			m.CopyrightNotice = "copyright me";
			m.Creator = "you";
			m.AttributionUrl = "http://google.com";
			m.License = new NullLicense();
			var c = new MetadataEditorControl();
			c.Metadata = m;
			var dlg = new Form();
			dlg.Height = c.Height;
			dlg.Width = c.Width + 20;
			c.Dock = DockStyle.Fill;
			dlg.Controls.Add(c);
			dlg.ShowDialog();
		}
Example #8
0
		/// <summary>
		/// NB: this is used in 2 places; one is loading from the image we are linked to, the other from a sample image we are copying metadata from
		/// </summary>
		/// <param name="path"></param>
		/// <param name="destinationMetadata"></param>
		private static void LoadProperties(string path, Metadata destinationMetadata)
		{
			try
			{
				destinationMetadata._originalTaglibMetadata = TagLib.File.Create(path) as TagLib.Image.File;
			}
			catch (TagLib.UnsupportedFormatException)
			{
				// TagLib throws this exception when the file doesn't have any metadata, sigh.
				// So since I don't see a way to differentiate between that case and the case
				// where something really is wrong, we're just gonna have to swallow this,
				// even in DEBUG mode, because else a lot of simple image tests fail
				return;
			}
			LoadProperties(destinationMetadata._originalTaglibMetadata.ImageTag, destinationMetadata);
		}
		public void ShowFullDialogTwiceToCheckRoundTripping()
		{
			var m = new Metadata();
			m.License = CreativeCommonsLicense.FromToken("by");
			m.License.RightsStatement = "some restrictions";

			using (var dlg = new MetadataEditorDialog(m))
			{
				dlg.ShowDialog();
				m = dlg.Metadata;
			}

			using (var dlg = new MetadataEditorDialog(m))
			{
				dlg.ShowDialog();
			}
		}
Example #10
0
		public PalasoImage()
		{
			Metadata = new Metadata();
		}
Example #11
0
		/// <summary>
		/// Load the properties of the specified MetaData object from the specified ImageTag.
		/// tagMain may be a CombinedImageTag (when working with a real image file) or an XmpTag (when working with an XMP file).
		/// Most of the data is read simply from the XmpTag (which is the Xmp property of the combined tag, if it is not tagMain itself).
		/// But, we don't want to pass combinedTag.Xmp when working with a file, because some files may have CopyRightNotice or Creator
		/// stored (only) in some other tag;
		/// and we need to handle the case where we only have an XmpTag, because there appears to be no way to create a
		/// combinedTag that just has an XmpTag inside it (or indeed any way to create any combinedTag except as part of
		/// reading a real image file).
		/// </summary>
		private static void LoadProperties(ImageTag tagMain, Metadata destinationMetadata)
		{
			destinationMetadata.CopyrightNotice = tagMain.Copyright;
			destinationMetadata.Creator = tagMain.Creator;
			XmpTag xmpTag = tagMain as XmpTag;
			if (xmpTag == null)
				xmpTag = ((CombinedImageTag) tagMain).Xmp;
			var licenseProperties = new Dictionary<string, string>();
			if (xmpTag != null)
			{
				destinationMetadata.CollectionUri = xmpTag.GetTextNode(kNsCollections,
					"CollectionURI");
				destinationMetadata.CollectionName = xmpTag.GetTextNode(
					kNsCollections,
					"CollectionName");
				destinationMetadata.AttributionUrl = xmpTag.GetTextNode(kNsCc, "attributionURL");

				var licenseUrl = xmpTag.GetTextNode(kNsCc, "license");
				if (!string.IsNullOrWhiteSpace(licenseUrl))
					licenseProperties["license"] = licenseUrl;
				var rights = GetRights(xmpTag);
				if (rights != null)
					licenseProperties["rights (en)"] = rights;
			}
			destinationMetadata.License = LicenseInfo.FromXmp(licenseProperties);

			//NB: we're loosing non-ascii somewhere... the copyright symbol is just the most obvious
			if (!string.IsNullOrEmpty(destinationMetadata.CopyrightNotice))
			{
				destinationMetadata.CopyrightNotice = destinationMetadata.CopyrightNotice.Replace("Copyright �", "Copyright ©");
			}

			//clear out the change-setting we just caused, because as of right now, we are clean with respect to what is on disk, no need to save.
			destinationMetadata.HasChanges = false;
		}
Example #12
0
		/// <summary>
		/// For use on a hyperlink/button
		/// </summary>
		/// <returns></returns>
		static public string GetStoredExemplarSummaryString(FileCategory category)
		{
			try
			{
				var m = new Metadata();
				m.LoadFromStoredExemplar(category);
				return string.Format("{0}/{1}/{2}", m.Creator, m.CopyrightNotice, m.License.ToString());
			}
			catch (Exception)
			{
				return string.Empty;
			}
		}
Example #13
0
		public PalasoImage(Image image)
		{
			Image = image;
			FileName = null;
			Metadata = new Metadata();
		}
Example #14
0
		public void GetCopyrightYear_Empty_ReturnsEmptyString()
		{
			var m = new Metadata();
			m.CopyrightNotice = "";
			Assert.AreEqual("", m.GetCopyrightYear());
		}
Example #15
0
		public void LoadXmpFile_ValuesCopiedFromOtherFile()
		{
			var original = new Metadata();
			var another = new Metadata();
			original.Creator = "John";
			original.License = new CreativeCommonsLicense(true, true, CreativeCommonsLicense.DerivativeRules.Derivatives);
			using(var f = TempFile.WithExtension("xmp"))
			{
				original.SaveXmpFile(f.Path);
				another.LoadXmpFile(f.Path);
			}
			Assert.AreEqual("John", another.Creator);
			Assert.AreEqual(original.License.Url, another.License.Url);
		}
Example #16
0
		public void ChangeLicenseObject_HasChanges_True()
		{
			var m = new Metadata();
			m.License = new CreativeCommonsLicense(true, true, CreativeCommonsLicense.DerivativeRules.Derivatives);
			m.HasChanges = false;
			m.License = new NullLicense();
			Assert.IsTrue(m.HasChanges);
		}
Example #17
0
		public void ChangeLicenseDetails_HasChanges_True()
		{
			var m = new Metadata();
			m.License = new CreativeCommonsLicense(true, true, CreativeCommonsLicense.DerivativeRules.Derivatives);
			m.HasChanges = false;
			((CreativeCommonsLicense) m.License).CommercialUseAllowed = false;
			Assert.IsTrue(m.HasChanges);
		}
        private static Metadata GetMetadataWithDefaultCopyrightAndLicense(string brandingNameOrPath)
        {
            var metadata = new Metadata();
            Logger.WriteEvent("For BL-3166 Investigation: GetMetadata() setting to default license");
            metadata.License = new CreativeCommonsLicense(true, true, CreativeCommonsLicense.DerivativeRules.Derivatives);

            //OK, that's all we need, the rest is blank. That is, unless we are we are working with a brand
            //that has declared some defaults in a settings.json file:
            var settings = BrandingApi.GetSettings(brandingNameOrPath);
            if(settings != null)
            {
                if(!string.IsNullOrEmpty(settings.CopyrightNotice))
                {
                    metadata.CopyrightNotice = settings.CopyrightNotice;
                }
                if(!string.IsNullOrEmpty(settings.LicenseUrl))
                {
                    metadata.License = CreativeCommonsLicense.FromLicenseUrl(settings.LicenseUrl);
                }
                if(!string.IsNullOrEmpty(settings.LicenseUrl))
                {
                    metadata.License.RightsStatement = settings.LicenseRightsStatement;
                }
            }
            return metadata;
        }
Example #19
0
		public void GetCopyrightBy_HasSymbolNoComma_ReturnsCopyrightHolder()
		{
			var m = new Metadata();
			m.CopyrightNotice = "© 2012 SIL International";
			Assert.AreEqual("SIL International", m.GetCopyrightBy());
		}
Example #20
0
		public void GetCopyrightBy_HasCOPYRIGHTAndSymbolNoYear_ReturnsCopyrightHolder()
		{
			var m = new Metadata();
			m.CopyrightNotice = "COPYRIGHT © SIL International";
			Assert.AreEqual("SIL International", m.GetCopyrightBy());
		}
Example #21
0
		public void DeepCopy()
		{
			var m = new Metadata();
			m.License = new CreativeCommonsLicense(true, true,
												   CreativeCommonsLicense.DerivativeRules.
													   DerivativesWithShareAndShareAlike);
			Metadata copy = m.DeepCopy();
			Assert.AreEqual(m.License.Url,copy.License.Url);
		}
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			PalasoImage palasoImage1 = new PalasoImage();
			Metadata metadata1 = new Metadata();
			this._cancelButton = new System.Windows.Forms.Button();
			this._okButton = new System.Windows.Forms.Button();
			this._imageToolboxControl = new ImageToolboxControl();
			this._L10NSharpExtender = new L10NSharp.UI.L10NSharpExtender(this.components);
			((System.ComponentModel.ISupportInitialize)(this._L10NSharpExtender)).BeginInit();
			this.SuspendLayout();
			//
			// _cancelButton
			//
			this._cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this._cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this._L10NSharpExtender.SetLocalizableToolTip(this._cancelButton, null);
			this._L10NSharpExtender.SetLocalizationComment(this._cancelButton, null);
			this._L10NSharpExtender.SetLocalizingId(this._cancelButton, "Common.CancelButton");
			this._cancelButton.Location = new System.Drawing.Point(799, 457);
			this._cancelButton.Name = "_cancelButton";
			this._cancelButton.Size = new System.Drawing.Size(75, 23);
			this._cancelButton.TabIndex = 1;
			this._cancelButton.Text = "&Cancel";
			this._cancelButton.UseVisualStyleBackColor = true;
			this._cancelButton.Click += new System.EventHandler(this._cancelButton_Click);
			//
			// _okButton
			//
			this._okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this._L10NSharpExtender.SetLocalizableToolTip(this._okButton, null);
			this._L10NSharpExtender.SetLocalizationComment(this._okButton, null);
			this._L10NSharpExtender.SetLocalizingId(this._okButton, "Common.OKButton");
			this._okButton.Location = new System.Drawing.Point(718, 457);
			this._okButton.Name = "_okButton";
			this._okButton.Size = new System.Drawing.Size(75, 23);
			this._okButton.TabIndex = 2;
			this._okButton.Text = "&OK";
			this._okButton.UseVisualStyleBackColor = true;
			this._okButton.Click += new System.EventHandler(this._okButton_Click);
			//
			// imageToolboxControl1
			//
			this._imageToolboxControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
			| System.Windows.Forms.AnchorStyles.Left)
			| System.Windows.Forms.AnchorStyles.Right)));
			this._imageToolboxControl.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
			this._imageToolboxControl.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			palasoImage1.Image = null;
			metadata1.AttributionUrl = null;
			metadata1.CollectionName = null;
			metadata1.CollectionUri = null;
			metadata1.CopyrightNotice = "";
			metadata1.Creator = null;
			metadata1.HasChanges = true;
			metadata1.License = null;
			palasoImage1.Metadata = metadata1;
			palasoImage1.MetadataLocked = false;
			this._imageToolboxControl.ImageInfo = palasoImage1;
			this._imageToolboxControl.InitialSearchString = null;
			this._L10NSharpExtender.SetLocalizableToolTip(this._imageToolboxControl, null);
			this._L10NSharpExtender.SetLocalizationComment(this._imageToolboxControl, null);
			this._L10NSharpExtender.SetLocalizationPriority(this._imageToolboxControl, L10NSharp.LocalizationPriority.NotLocalizable);
			this._L10NSharpExtender.SetLocalizingId(this._imageToolboxControl, "ImageToolbox.ImageToolboxDialog.ImageToolboxControl");
			this._imageToolboxControl.Location = new System.Drawing.Point(1, 1);
			this._imageToolboxControl.Name = "_imageToolboxControl";
			this._imageToolboxControl.Size = new System.Drawing.Size(873, 450);
			this._imageToolboxControl.TabIndex = 3;
			//
			// _L10NSharpExtender
			//
			this._L10NSharpExtender.LocalizationManagerId = "Palaso";
			this._L10NSharpExtender.PrefixForNewItems = "ImageToolbox";
			//
			// ImageToolboxDialog
			//
			this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
			this.CancelButton = this._cancelButton;
			this.ClientSize = new System.Drawing.Size(886, 485);
			this.Controls.Add(this._imageToolboxControl);
			this.Controls.Add(this._okButton);
			this.Controls.Add(this._cancelButton);
			this._L10NSharpExtender.SetLocalizableToolTip(this, null);
			this._L10NSharpExtender.SetLocalizationComment(this, null);
			this._L10NSharpExtender.SetLocalizingId(this, "ImageToolbox.ImageToolboxWindowTitle");
			this.MinimumSize = new System.Drawing.Size(732, 432);
			this.Name = "ImageToolboxDialog";
			this.ShowIcon = false;
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
			this.Text = "Image Toolbox";
			this.Load += new System.EventHandler(this.ImageToolboxDialog_Load);
			((System.ComponentModel.ISupportInitialize)(this._L10NSharpExtender)).EndInit();
			this.ResumeLayout(false);

		}
Example #23
0
		public void GetCopyrightBy_NoSymbolOrYear_ReturnsCopyrightHolder()
		{
			var m = new Metadata();
			m.CopyrightNotice = "SIL International";
			Assert.AreEqual("SIL International", m.GetCopyrightBy());
		}
Example #24
0
		public void SetHasChangesFalse_AlsoClearsLicenseHasChanges()
		{
			var m = new Metadata();
			m.License = new CreativeCommonsLicense(true, true, CreativeCommonsLicense.DerivativeRules.Derivatives);
			 ((CreativeCommonsLicense)m.License).CommercialUseAllowed = false;
			 Assert.IsTrue(m.HasChanges);
			 m.HasChanges = false;
			 Assert.IsFalse(m.License.HasChanges);
			 Assert.IsFalse(m.HasChanges);
		}
 /// <summary>
 /// Get the license from the metadata and save it.
 /// </summary>
 private static void UpdateBookLicenseIcon(Metadata metadata, string bookFolderPath)
 {
     var licenseImage = metadata.License.GetImage();
     var imagePath = bookFolderPath.CombineForPath("license.png");
     // Don't try to overwrite the license image for a template book.  (See BL-3284.)
     if (RobustFile.Exists(imagePath) && BloomFileLocator.IsInstalledFileOrDirectory(imagePath))
         return;
     try
     {
         if(licenseImage != null)
         {
             using(Stream fs = new FileStream(imagePath, FileMode.Create))
             {
                 SIL.IO.RobustIO.SaveImage(licenseImage, fs, ImageFormat.Png);
             }
         }
         else
         {
             if(RobustFile.Exists(imagePath))
                 RobustFile.Delete(imagePath);
         }
     }
     catch(Exception error)
     {
         // BL-3227 Occasionally get The process cannot access the file '...\license.png' because it is being used by another process.
         // That's worth a toast, since the user might like a hint why the license image isn't up to date.
         // However, if the problem is a MISSING icon in the installed templates, which on Linux or if an allUsers install
         // the system will never let us write, is not worth bothering the user at all. We can't fix it. Too bad.
         if (BloomFileLocator.IsInstalledFileOrDirectory(imagePath))
             return;
         NonFatalProblem.Report(ModalIf.None, PassiveIf.All, "Could not update license image (BL-3227).", "Image was at" +imagePath, exception: error);
     }
 }
Example #26
0
		public void GetCopyrightYear_HasCopyrightAndSymbolAndComma_ReturnsCopyrightYear()
		{
			var m = new Metadata();
			m.CopyrightNotice = "Copyright © 2012, SIL International";
			Assert.AreEqual("2012", m.GetCopyrightYear());
		}
        /// <summary>
        /// Call this when we have a new set of metadata to use. It
        /// 1) sets the bloomDataDiv with the data,
        /// 2) causes any template fields in the book to get the new values
        /// 3) updates the license image on disk
        /// </summary>
        public static void SetMetadata(Metadata metadata, HtmlDom dom, string bookFolderPath, CollectionSettings collectionSettings)
        {
            dom.SetBookSetting("copyright","*",metadata.CopyrightNotice);
            dom.SetBookSetting("licenseUrl","*",metadata.License.Url);
            // This is for backwards compatibility. The book may have  licenseUrl in 'en' created by an earlier version of Bloom.
            // For backwards compatibiilty, GetMetaData will read that if it doesn't find a '*' license first. So now that we're
            // setting a licenseUrl for '*', we must make sure the 'en' one is gone, because if we're setting a non-CC license,
            // the new URL will be empty and the '*' one will go away, possibly exposing the 'en' one to be used by mistake.
            // See BL-3166.
            dom.SetBookSetting("licenseUrl", "en", null);
            string languageUsedForDescription;

            //This part is unfortunate... the license description, which is always localized, doesn't belong in the datadiv; it
            //could instead just be generated when we update the page. However, for backwards compatibility (prior to 3.6),
            //we localize it and place it in the datadiv.
            dom.RemoveBookSetting("licenseDescription");
            var description = metadata.License.GetDescription(collectionSettings.LicenseDescriptionLanguagePriorities, out languageUsedForDescription);
            dom.SetBookSetting("licenseDescription", languageUsedForDescription, ConvertNewLinesToHtmlBreaks(description));

            // Book may have old licenseNotes, typically in 'en'. This can certainly show up again if licenseNotes in '*' is removed,
            // and maybe anyway. Safest to remove it altogether if we are setting it using the new scheme.
            dom.RemoveBookSetting("licenseNotes");
            dom.SetBookSetting("licenseNotes", "*", ConvertNewLinesToHtmlBreaks(metadata.License.RightsStatement));

            // we could do away with licenseImage in the bloomDataDiv, since the name is always the same, but we keep it for backward compatibility
            if (metadata.License is CreativeCommonsLicense)
            {
                dom.SetBookSetting("licenseImage", "*", "license.png");
            }
            else
            {
                //CC licenses are the only ones we know how to show an image for
                dom.RemoveBookSetting("licenseImage");
            }

            UpdateDomFromDataDiv(dom, bookFolderPath, collectionSettings);
        }
Example #28
0
		public void GetCopyrightYear_NoSymbolOrComma_ReturnsCopyrightYear()
		{
			var m = new Metadata();
			m.CopyrightNotice = "2012 SIL International";
			Assert.AreEqual("2012", m.GetCopyrightYear());
		}
Example #29
0
 public void SetLicenseAndCopyrightMetadata(Metadata metadata)
 {
     License = metadata.License.Token;
     Copyright = metadata.CopyrightNotice;
     // obfuscate any emails in the license notes.
     var notes = metadata.License.RightsStatement;
     if (notes != null)
     {
         // recommended at http://www.regular-expressions.info/email.html.
         // This purposely does not handle non-ascii emails, or ones with special characters, which he says few servers will handle anyway.
         // It is also not picky about exactly valid top-level domains (or country codes), and will exclude the rare 'museum' top-level domain.
         // There are several more complex options we could use there. Just be sure to add () around the bit up to (and including) the @,
         // and another pair around the rest.
         var regex = new Regex("\\b([A-Z0-9._%+-]+@)([A-Z0-9.-]+.[A-Z]{2,4})\\b", RegexOptions.IgnoreCase);
         // We keep the existing email up to 2 characters after the @, and replace the rest with a message.
         // Not making the message localizable as yet, since the web site isn't, and I'm not sure what we would need
         // to put to make it so. A fixed string seems more likely to be something we can replace with a localized version,
         // in the language of the web site user rather than the language of the uploader.
         notes = regex.Replace(notes,
             new MatchEvaluator(
                 m =>
                     m.Groups[1].Value + m.Groups[2].Value.Substring(0, 2) +
                     "(download book to read full email address)"));
         LicenseNotes = notes;
     }
 }
Example #30
0
		public void GetCopyrightYear_NoYear_ReturnsEmptyString()
		{
			var m = new Metadata();
			m.CopyrightNotice = "SIL International";
			Assert.AreEqual("", m.GetCopyrightYear());
		}