void DownloadAndProcess() { Invoke((MethodInvoker) delegate() { // enable those controls which are initially disabled btnTransfer.Enabled = txtNormName.Enabled = chkDeleteAfter.Enabled = chkIgnoreWarnings.Enabled = toolBarLinks.Enabled = coolCat.Enabled = true; txtLocalText.Text = txtCommonsText.Text = lblName.Text = lblRevision.Text = lblDimensions.Text = ""; coolCat.ClearCategories(); pictureBox1.Image = null; pictureBox1.Cursor = Cursors.Default; lblPastRevisions.Visible = btnPastRevisions.Visible = lblViewExif.Visible = btnViewExif.Visible = false; lstFileLinks.ForeColor = SystemColors.GrayText; lstFileLinks.Items.Clear(); chkIgnoreWarnings.Checked = false; ClearWarnings(); lnkCommonsFile.Enabled = lnkLocalFile.Enabled = lnkGoogleImageSearch.Enabled = lnkGoToFileLink.Enabled = false; SetTransferButtonDownloading(true); textBox1.Text = textBox1.Text.Trim(); }); if (ImageDataDownloader != null) ImageDataDownloader.CancelAsync(); CurrentFileName = Regex.Replace(textBox1.Text, @"^\w+:", "", RegexOptions.IgnoreCase); EnableForm(false); ImageInfos = null; ImageDatas = null; string text = ""; MorebitsDotNet.ActionCompleted sentry = new MorebitsDotNet.ActionCompleted(2); sentry.Done += new MorebitsDotNet.ActionCompleted.Action(delegate() { if (ImageInfos == null) return; // too much on at once // identify potential problems string textLowercase = text.ToLower(); List<string> potentialProblems = new List<string>(); if (Regex.IsMatch(text, "{{((db-)?now ?commons|" + Regex.Escape(LocalWikiData.NowCommonsTag) + ")", RegexOptions.IgnoreCase)) { potentialProblems.Add("• " + Localization.GetString("NowCommonsPotentialProblem")); if (CurrentFileSource == FileSources.Category) { RandomBlacklist.Add(RandomCurrentIndex); // don't turn up this file again RandomImage(null, null); return; } } foreach (LocalWikiData.PotentialProblem problem in LocalWikiData.PotentialProblems) { try { if (problem.IsRegex ? Regex.IsMatch(text, problem.Test, RegexOptions.IgnoreCase) : textLowercase.Contains(problem.Test.ToLower())) { potentialProblems.Add("• " + problem.Message); } } catch (ArgumentException e) { ErrorHandler(Localization.GetString("LocalWikiDataError") + "\n\n" + Localization.GetString("LocalWikiDataRegexError", "PotentialProblem IfRegex") + "\n\n" + e.Message); } } if (potentialProblems.Count > 0) { Invoke((MethodInvoker) delegate() { foreach (string i in potentialProblems) AddWarning(i, WarningBoxType.Warning); }); } // start building the new file description page string origUploader = ImageInfos[ImageInfos.Count - 1].Attributes["user"].Value; // clean up local templates, etc. string prefix = GetCurrentInterwikiPrefix(false); try { text = Regex.Replace(text, LocalWikiData.CopyToCommonsRegex, "", RegexOptions.IgnoreCase | RegexOptions.Compiled); } catch (ArgumentException e) { ErrorHandler(Localization.GetString("LocalWikiDataError") + "\n\n" + Localization.GetString("LocalWikiDataRegexError", "CopyToCommonsRegex") + "\n\n" + e.Message); } //text = Regex.Replace(text, "== ?(Summary|Licensing:?) ?== *\n", "\n"); text = Regex.Replace(text, "== ?((" + LocalWikiData.Summary + ")|{{int:filedesc}}) ?== *\n", "", RegexOptions.IgnoreCase); text = Regex.Replace(text, "\n?\n?== ?((" + LocalWikiData.Licensing + ")|{{int:license}}) ?== *\n", "\n\n== {{int:license-header}} ==\n", RegexOptions.IgnoreCase); text = Regex.Replace(text, @"\[\[:?", "[[" + prefix + ":", RegexOptions.Compiled); text = Regex.Replace(text, @"\[\[" + prefix + @":([^\|\]]+)\]\]", new MatchEvaluator(delegate(Match m) { string linktext = m.Groups[1].Value; string linktextLower = linktext.ToLower(); if (!(linktextLower.StartsWith("category:")) && !(linktextLower.StartsWith(LocalWikiData.CategoryNamespace.ToLower()))) return "[[" + prefix + ":" + linktext + "|" + linktext + "]]"; return "<!-- [[" + linktext + "]] -->"; // comment out categories }), RegexOptions.Compiled); // this next one is redundant to the above BUT still needed for categories with sortkeys (?!) text = Regex.Replace(text, @"\[\[" + prefix + @":(Category:[^\]]+\]\])", "<!-- [[$1 -->", RegexOptions.Compiled); // per-wiki cleanup foreach (KeyValuePair<string, string> replacement in LocalWikiData.Replacements) { try { text = Regex.Replace(text, replacement.Key, replacement.Value.Replace("\\n", "\n"), RegexOptions.IgnoreCase); } catch (ArgumentException e) { ErrorHandler(Localization.GetString("LocalWikiDataError") + "\n\n" + Localization.GetString("LocalWikiDataRegexError", "Replacement") + "\n\n" + e.Message); } } // amend self-license tags string beforeSelfTagCheck = text; foreach (KeyValuePair<string, string> replacement in LocalWikiData.SelfLicenseReplacements) { try { text = Regex.Replace(text, replacement.Key, replacement.Value.Replace("\\n", "\n") .Replace("%%OriginalUploader%%", origUploader).Replace("%%InterwikiLinkPrefix%%", prefix), RegexOptions.IgnoreCase); } catch (ArgumentException e) { ErrorHandler(Localization.GetString("LocalWikiDataError") + "\n\n" + Localization.GetString("LocalWikiDataRegexError", "SelfLicenseReplacement") + "\n\n" + e.Message); } } bool selfLicense = (text != beforeSelfTagCheck); text = text.Trim(); // the character index at which the information tag finishes (doesn't have to be exact) int infoTagEnd = 0; string languageCode = GetCurrentLanguageCode(); if (!textLowercase.Contains("{{information") && !Regex.IsMatch(text, "{{" + LocalWikiData.Information, RegexOptions.IgnoreCase)) { string detectedDesc = Regex.Replace(text, "{{[^}]*}}", "", RegexOptions.IgnoreCase); detectedDesc = Regex.Replace(detectedDesc, "==[^=]*==", "", RegexOptions.IgnoreCase); detectedDesc = detectedDesc.Split('\n')[0]; if (detectedDesc.Length > 0) text = text.Replace(detectedDesc, ""); XmlNode exifDateNode = ImageInfos[ImageInfos.Count - 1].SelectSingleNode("metadata/metadata[@name=\"DateTime\"]"); string exifDate = null; if (exifDateNode != null) { exifDate = exifDateNode.Attributes["value"].Value; if (Regex.IsMatch(exifDate, @"^\d\d\d\d:\d\d:\d\d") && !exifDate.StartsWith("0000")) exifDate = exifDate.Substring(0, 10).Replace(':', '-'); else exifDate = null; } // Note: pipe replacement was commented out because it caused problems with piped wikilinks in the // detected description. Of course, now any literal pipes will cause problems... var infoTag = "== {{int:filedesc}} ==\n" + "{{Information\n" + "|Description = " + (languageCode.Length > 0 ? ("{{" + languageCode + "|1=" + detectedDesc.Trim()/*.Replace("|", "|")*/ + "}}") : detectedDesc.Trim().Replace("|", "|")) + "\n" + "|Date = " + (exifDate != null ? "{{according to EXIF data|" + exifDate + "}}\n" : "{{original upload date|" + FormatIsoDate(ImageInfos[ImageInfos.Count - 1]) + "}}\n") + "|Source = {{own work by original uploader}} <!-- " + Localization.GetString("ChangeIfNotOwnWork") + " -->\n" + "|Author = " + (selfLicense ? ("[[" + prefix + ":User:"******"user"].Value + "|]]\n") : "\n") + "|Permission = \n" + "|Other_versions = \n" + "}}\n\n"; text = infoTag + text; infoTagEnd = infoTag.Length - 8; // -8 for sanity } else { text = "== {{int:filedesc}} ==\n" + text; string errorTopicText = ""; try { errorTopicText = "Information"; text = Regex.Replace(text, @"{{\s*(" + LocalWikiData.Information + @")", "{{Information", RegexOptions.IgnoreCase); string paramStart = @"({{Information({{[^{}]*}}|[^{}])*)\|\s*("; string paramEnd = @")\s*= *"; errorTopicText = "Description"; text = Regex.Replace(text, paramStart + LocalWikiData.Description + paramEnd, "$1|Description = ", RegexOptions.IgnoreCase); errorTopicText = "Date"; text = Regex.Replace(text, paramStart + LocalWikiData.Date + paramEnd, "$1|Date = ", RegexOptions.IgnoreCase); errorTopicText = "Source"; text = Regex.Replace(text, paramStart + LocalWikiData.Source + paramEnd, "$1|Source = ", RegexOptions.IgnoreCase); errorTopicText = "Author"; text = Regex.Replace(text, paramStart + LocalWikiData.Author + paramEnd, "$1|Author = ", RegexOptions.IgnoreCase); errorTopicText = "Permission"; text = Regex.Replace(text, paramStart + LocalWikiData.Permission + paramEnd, "$1|Permission = ", RegexOptions.IgnoreCase); errorTopicText = "Other_versions"; text = Regex.Replace(text, paramStart + LocalWikiData.Other_versions + paramEnd, "$1|Other_versions = ", RegexOptions.IgnoreCase); } catch (ArgumentException e) { ErrorHandler(Localization.GetString("LocalWikiDataError") + "\n\n" + Localization.GetString("LocalWikiDataRegexError", errorTopicText) + "\n\n" + e.Message); } if (languageCode.Length > 0 && !text.Contains("{{" + languageCode + "|")) text = Regex.Replace(text, @"({{Information[\r\n]* *\| ?Description *= *)([^\r\n ][^\r\n]+)([\r\n])", "$1{{" + languageCode + "|1=$2}}$3", RegexOptions.IgnoreCase); Match infoTagMatch = Regex.Match(text, @"{{\s*information\s*(\|({{[^{}]*}}|[^{}])*)?}}", RegexOptions.IgnoreCase); infoTagEnd = infoTagMatch.Index + infoTagMatch.Length - 8; // -8 for sanity } // assume first template is a license tag if (!text.Contains("{{int:license-header}}")) { bool hadAnySuccessYet = false; text = Regex.Replace(text, "\n?\n?{{", delegate(Match m) { if (m.Index < infoTagEnd || hadAnySuccessYet) return m.Groups[0].Value; hadAnySuccessYet = true; return "\n\n== {{int:license-header}} ==\n{{"; }); } text += "\n\n== {{Original upload log}} =="; if (Settings.CommonsDomain == Settings.DefaultCommonsDomain) { text += "\n\n{{transferred from|" + Settings.LocalDomain + "||ftcg}} {{original description page|" + Settings.LocalDomain + "|" + Uri.EscapeDataString(CurrentFileName.Replace(' ', '_')) + "}}"; } text += "\n\n{| class=\"wikitable\"\n! {{int:filehist-datetime}} !! {{int:filehist-dimensions}} !! {{int:filehist-user}} !! {{int:filehist-comment}}"; foreach (XmlNode n in ImageInfos) { text += "\n|-\n| " + FormatTimestamp(n) + " || " + FormatDimensions(n) + " || "; // check if the username has been RevDel'd (for admins, the user attribute // will be present, and we don't want to copy the hidden username to Commons, // so we need to check the userhidden attribute) if (n.Attributes["userhidden"] != null || n.Attributes["user"] == null) text += "<span class=\"history-deleted\">{{int:rev-deleted-user}}</span>"; else text += "{{uv|" + n.Attributes["user"].Value + "|" + GetCurrentInterwikiPrefix(true) + ":}}"; text += " || "; // same deal for comment/commenthidden if (n.Attributes["commenthidden"] != null || n.Attributes["comment"] == null) text += "<span class=\"history-deleted\">{{int:rev-deleted-comment}}</span>"; else text += "<nowiki>" + n.Attributes["comment"].Value + "</nowiki>"; } text += "\n|}"; // remove multiple line breaks text = Regex.Replace(text, @"[\r\n]{3,}", "\n\n"); Invoke((MethodInvoker) delegate() { txtCommonsText.Text = text.Replace("\n", "\r\n"); lnkLocalFile.Enabled = lnkGoogleImageSearch.Enabled = true; lnkCommonsFile.Enabled = false; lblFileLinks.Visible = lstFileLinks.Visible = true; if (lstFileLinks.ForeColor == SystemColors.GrayText) { lstFileLinks.Items.Clear(); lstFileLinks.Items.Add(Localization.GetString("Loading")); } EnableForm(true); }); }); sentry.Finally += new MorebitsDotNet.ActionCompleted.Action(delegate() { Invoke((MethodInvoker) delegate() { EnableForm(true); }); }); // download image file StringDictionary query = new StringDictionary { { "action", "query" }, { "prop", "imageinfo|info" }, { "iiprop", "comment|timestamp|user|url|size|mime|metadata" }, { "iilimit", "500" }, { "iiurlwidth", pictureBox1.Width.ToString() }, { "iiurlheight", pictureBox1.Height.ToString() }, { "titles", "File:" + CurrentFileName + "|File talk:" + CurrentFileName }, { "redirects", "true" } }; MorebitsDotNet.PostApi(Wiki.Local, query, delegate(XmlDocument doc) { XmlNode filePage = doc.SelectSingleNode("//page[@ns=6]"); // was doc.GetElementsByTagName("page")[0] switch (filePage.Attributes["imagerepository"].Value) { case "shared": ErrorHandler(Localization.GetString("AlreadyCommons")); sentry.Fail(); return; case "": if (filePage.Attributes["missing"] != null) ErrorHandler(Localization.GetString("ImageMissing")); else ErrorHandler(Localization.GetString("NoFile")); sentry.Fail(); return; } ImageInfos = doc.GetElementsByTagName("ii"); ImageDatas = new byte[ImageInfos.Count][]; Invoke((MethodInvoker) delegate() { lblName.Text = filePage.Attributes["title"].Value; if (ImageInfos.Count > 1) { lblPastRevisions.Visible = btnPastRevisions.Visible = true; lblPastRevisions.Text = ((ImageInfos.Count == 2) ? Localization.GetString("OneEarlierVersion_Label") : Localization.GetString("EarlierVersions_Format", (ImageInfos.Count - 1).ToString())); } else lblPastRevisions.Visible = btnPastRevisions.Visible = false; }); // notify about presence of file talk page (if it is over 120 bytes in size) XmlNode fileTalkPage = doc.SelectSingleNode("//page[@ns=7]"); if (fileTalkPage.Attributes["missing"] == null) { string warningtext = "• " + Localization.GetString("ContentOnTalkPage"); if (fileTalkPage.Attributes["length"] != null && int.Parse(fileTalkPage.Attributes["length"].Value) > int.Parse(LocalWikiData.FileTalkMinimumSize)) { warningtext = warningtext.Replace("{1}", " (" + int.Parse(fileTalkPage.Attributes["length"].Value). ToString("n0", CultureInfo.InvariantCulture) + " bytes)"); AddWarningLink(warningtext, Localization.GetString("TalkPage"), delegate(object sender, LinkLabelLinkClickedEventArgs e) { try { Process.Start(MorebitsDotNet.GetProtocol() + "://" + Settings.LocalDomain + ".org/wiki/File_talk:" + CurrentFileName); } catch (Exception) { ErrorHandler(Localization.GetString("LinkVisitFailed")); } }, WarningBoxType.Warning); } } // download the file and display a thumbnail (also display metadata) SelectedRevisions = new int[] { 0 }; DownloadFileAndDisplayThumb(); sentry.DoneOne(); }, ErrorHandler, WebRequestMethods.Http.Get); // get wikitext of file description page query = new StringDictionary { { "action", "query" }, { "prop", "revisions" }, { "rvprop", "content" }, { "titles", "File:" + CurrentFileName }, { "redirects", "true" } }; MorebitsDotNet.PostApi(Wiki.Local, query, delegate(XmlDocument doc) { if (doc.GetElementsByTagName("page")[0].Attributes["missing"] != null) { // MessageBox.Show("Image does not exist on enwiki"); don't need to tell user twice sentry.Fail(); return; } text = doc.GetElementsByTagName("rev")[0].InnerText; Invoke((MethodInvoker) delegate() { txtLocalText.Text = text.Replace("\n", "\r\n"); }); XmlNodeList ns = doc.GetElementsByTagName("n"); if (ns.Count > 0) Invoke((MethodInvoker) delegate() { CurrentFileName = ns[0].Attributes["to"].Value; CurrentFileName = CurrentFileName.Substring(CurrentFileName.IndexOf(':') + 1); }); Invoke((MethodInvoker) delegate() { txtNormName.Text = "File:" + CurrentFileName; }); sentry.DoneOne(); }, ErrorHandler, WebRequestMethods.Http.Get); // get file links (not in sentry) query = new StringDictionary { { "action", "query" }, { "list", "imageusage" }, { "iulimit", "20" }, { "iutitle", "File:" + CurrentFileName }, { "rawcontinue", "" }, }; // prevent race conditions object current = new object(); Invoke((MethodInvoker) delegate() { lstFileLinks.Tag = current; }); MorebitsDotNet.PostApi(Wiki.Local, query, delegate(XmlDocument doc) { if (lstFileLinks.Tag != current) return; Invoke((MethodInvoker) delegate() { lstFileLinks.Items.Clear(); XmlNodeList ius = doc.GetElementsByTagName("iu"); if (ius.Count == 0) { lstFileLinks.Items.Add(Localization.GetString("NoImageUsages_Label")); return; } lstFileLinks.ForeColor = SystemColors.ControlText; foreach (XmlNode i in ius) lstFileLinks.Items.Add(i.Attributes["title"].Value); if (doc.GetElementsByTagName("query-continue").Count > 0) lstFileLinks.Items.Add("<<" + Localization.GetString("SeeWikiForFullList_Label") + ">>"); }); }, ErrorHandler, WebRequestMethods.Http.Get); }
void DownloadAndProcess() { Invoke(new Action(delegate() { textBox2.Text = textBox3.Text = lblName.Text = lblRevision.Text = lblDimensions.Text = ""; pictureBox1.Image = null; pictureBox1.Cursor = Cursors.Default; lblPastRevisions.Visible = btnPastRevisions.Visible = lblViewExif.Visible = btnViewExif.Visible = false; lstFileLinks.ForeColor = SystemColors.GrayText; lstFileLinks.Items.Clear(); chkIgnoreWarnings.Checked = false; HideWarningBox(); lnkCommonsFile.Enabled = lnkLocalFile.Enabled = lnkGoogleImageSearch.Enabled = lnkGoToFileLink.Enabled = false; textBox1.Text = textBox1.Text.Trim(); })); if (cl != null) cl.CancelAsync(); filename = "File:" + Regex.Replace(textBox1.Text, @"^\w+:", "", RegexOptions.IgnoreCase); EnableForm(false); iis = null; ImageData = null; string text = ""; MorebitsDotNet.ActionCompleted sentry = new MorebitsDotNet.ActionCompleted(2); sentry.Done += new Action(delegate() { if (iis == null) return; // too much on at once // identify potential problems string textLowercase = text.ToLower(); List<string> potentialProblems = new List<string>(); if (Regex.IsMatch(text, "{{((db-)?now ?commons|" + Regex.Escape(LocalWikiData.NowCommonsTag) + ")", RegexOptions.IgnoreCase)) { potentialProblems.Add("• " + Localization.GetString("NowCommonsPotentialProblem")); if (CurrentFileSource == FileSources.Category) { RandomBlacklist.Add(RandomCurrentIndex); // don't turn up this file again RandomImage(null, null); return; } } foreach (LocalWikiData.PotentialProblem problem in LocalWikiData.PotentialProblems) { if (problem.IsRegex ? Regex.IsMatch(text, problem.Test, RegexOptions.IgnoreCase) : textLowercase.Contains(problem.Test.ToLower())) { potentialProblems.Add("• " + problem.Message); } } if (potentialProblems.Count > 0) { Invoke(new Action(delegate() { ShowWarningBox(false, String.Join("\n", potentialProblems.ToArray())); })); } // start building the new file description page string origUploader = iis[iis.Count - 1].Attributes["user"].Value; // clean up local templates, etc. string prefix = GetCurrentInterwikiPrefix(false); text = Regex.Replace(text, LocalWikiData.CopyToCommonsRegex, "", RegexOptions.IgnoreCase | RegexOptions.Compiled); //text = Regex.Replace(text, "== ?(Summary|Licensing:?) ?== *\n", "\n"); text = Regex.Replace(text, "== ?(" + LocalWikiData.Summary + ") ?== *\n", "", RegexOptions.IgnoreCase);//"== {{int:filedesc}} ==\n"); text = Regex.Replace(text, "\n?\n?== ?(" + LocalWikiData.Licensing + ") ?== *\n", "\n\n== {{int:license-header}} ==\n", RegexOptions.IgnoreCase); text = Regex.Replace(text, @"\[\[:?", "[[" + prefix + ":", RegexOptions.Compiled); text = Regex.Replace(text, @"\[\[" + prefix + @":([^\|\]]+)\]\]", new MatchEvaluator(delegate(Match m) { string linktext = m.Groups[1].Value; string linktextLower = linktext.ToLower(); if (!(linktextLower.StartsWith("category:")) && !(linktextLower.StartsWith(LocalWikiData.CategoryNamespace.ToLower()))) return "[[" + prefix + ":" + linktext + "|" + linktext + "]]"; return "<!-- [[" + linktext + "]] -->"; // comment out categories }), RegexOptions.Compiled); // this next one is redundant to the above BUT still needed for categories with sortkeys (?!) text = Regex.Replace(text, @"\[\[" + prefix + @":(Category:[^\]]+\]\])", "<!-- [[$1 -->", RegexOptions.Compiled); // per-wiki cleanup foreach (string replacement in LocalWikiData.Replacements.Keys) { text = Regex.Replace(text, replacement, LocalWikiData.Replacements[replacement], RegexOptions.IgnoreCase); } //text = Regex.Replace(text, "{{orphan image.*}}\n?", "", RegexOptions.IgnoreCase); //text = text.Replace("{{needs commons category}}", ""); // seems to always be lowercase with no params // amend self-license tags string beforeSelfTagCheck = text; foreach (string replacement in LocalWikiData.SelfLicenseReplacements.Keys) { text = Regex.Replace(text, replacement, LocalWikiData.SelfLicenseReplacements[replacement] .Replace("%%OriginalUploader%%", origUploader) .Replace("%%InterwikiLinkPrefix%%", prefix), RegexOptions.IgnoreCase); } //text = Regex.Replace(text, "{{PD-self.*}}", "{{PD-user|" + origUploader + "|en}}", RegexOptions.IgnoreCase); //text = Regex.Replace(text, @"{{GFDL-self-with-disclaimers([^\}]*)}}", "{{GFDL-user-en-with-disclaimers|" + origUploader + "$1}}", RegexOptions.IgnoreCase); //text = Regex.Replace(text, @"{{GFDL-self([^\}]*)}}", "{{GFDL-user|" + origUploader + "|en$1}}", RegexOptions.IgnoreCase); //text = Regex.Replace(text, @"{{self([^\}]*)}}", "{{self$1|author=[[" + prefix + ":" + origUploader + "|]]}}", RegexOptions.IgnoreCase); bool selfLicense = (text != beforeSelfTagCheck); text = text.Trim(); if (!textLowercase.Contains("{{information") && !Regex.IsMatch(text, "{{" + LocalWikiData.Information, RegexOptions.IgnoreCase)) { string detectedDesc = Regex.Replace(text, "{{[^}]*}}", "", RegexOptions.IgnoreCase); detectedDesc = Regex.Replace(detectedDesc, "==[^=]*==", "", RegexOptions.IgnoreCase); detectedDesc = detectedDesc.Split('\n')[0]; text = Regex.Replace(text, Regex.Escape(detectedDesc), "", RegexOptions.IgnoreCase); XmlNode exifDateNode = iis[iis.Count - 1].SelectSingleNode("metadata/metadata[@name=\"DateTime\"]"); string exifDate = null; if (exifDateNode != null) { exifDate = exifDateNode.Attributes["value"].Value; if (Regex.IsMatch(exifDate, @"^\d\d\d\d:\d\d:\d\d")) exifDate = exifDate.Substring(0, 10).Replace(':', '-'); else exifDate = null; } string languageCode = GetCurrentLanguageCode(); var infoTag = "== {{int:filedesc}} ==\n" + "{{Information\n" + "|Description = " + (languageCode.Length > 0 ? ("{{" + languageCode + "|1=" + detectedDesc.Trim().Replace("|", "|") + "}}") : detectedDesc.Trim().Replace("|", "|")) + "\n" + "|Date = " + (exifDate != null ? "{{according to EXIF data|" + exifDate + "}}\n" : "{{original upload date|" + FormatIsoDate(iis[iis.Count - 1]) + "}}\n") + "|Source = {{own}} <!-- " + Localization.GetString("ChangeIfNotOwnWork") + " -->\n" + "|Author = " + (selfLicense ? ("[[" + prefix + ":User:"******"user"].Value + "|]]\n") : "\n") + "|Permission = \n" + "|Other_versions = \n" + "}}\n\n"; text = infoTag + text; // assume first template is a license tag if (!text.Contains("{{int:license-header}}")) { bool hadAnySuccessYet = false; text = Regex.Replace(text, "\n?\n?{{", delegate(Match m) { if (m.Index < infoTag.Length || hadAnySuccessYet) return m.Groups[0].Value; hadAnySuccessYet = true; return "\n\n== {{int:license-header}} ==\n{{"; }); } } else { text = "== {{int:filedesc}} ==\n" + text; if (!text.Contains("{{" + GetCurrentLanguageCode() + "|")) text = Regex.Replace(text, @"({{Information[\r\n]* *\| ?Description *= *)([^\r\n ][^\r\n]+)([\r\n])", "$1{{" + GetCurrentLanguageCode() + "|1=$2}}$3", RegexOptions.IgnoreCase); if (!LocalWikiData.LocalDomain.StartsWith("en.wikipedia")) // speed boost - this is unneeded on enwiki { text = Regex.Replace(text, @"{{\s*" + LocalWikiData.Information, "{{Information", RegexOptions.IgnoreCase); text = Regex.Replace(text, @"\|\s*" + LocalWikiData.Description + @"\s*=", "|Description =", RegexOptions.IgnoreCase); text = Regex.Replace(text, @"\|\s*" + LocalWikiData.Date + @"\s*=", "|Date =", RegexOptions.IgnoreCase); text = Regex.Replace(text, @"\|\s*" + LocalWikiData.Source + @"\s*=", "|Source =", RegexOptions.IgnoreCase); text = Regex.Replace(text, @"\|\s*" + LocalWikiData.Author + @"\s*=", "|Author =", RegexOptions.IgnoreCase); text = Regex.Replace(text, @"\|\s*" + LocalWikiData.Permission + @"\s*=", "|Permission =", RegexOptions.IgnoreCase); text = Regex.Replace(text, @"\|\s*" + LocalWikiData.Other_versions + @"\s*=", "|Other_versions =", RegexOptions.IgnoreCase); } //text = Regex.Replace(text, @"= *I .*created this (image|work) entirely by myself.?", "= {{own}} <!-- change this if not own work -->", RegexOptions.IgnoreCase); } text += "\n\n== {{Original upload log}} ==\n\n{{transferred from|" + Settings.LocalDomain + "||[[:en:WP:FTCG|For the Common Good]]}} {{original description page|" + Settings.LocalDomain + "|" + Uri.EscapeDataString(filename.Substring(filename.IndexOf(':') + 1).Replace(' ', '_')) + "}}"; text += "\n\n{| class=\"wikitable\"\n! {{int:filehist-datetime}} !! {{int:filehist-dimensions}} !! {{int:filehist-user}} !! {{int:filehist-comment}}"; foreach (XmlNode n in iis) { text += "\n|-\n| " + FormatTimestamp(n) + " || " + FormatDimensions(n); text += " || {{uv|" + n.Attributes["user"].Value + "|" + GetCurrentInterwikiPrefix(true) + ":}} || ''<nowiki>(" + n.Attributes["comment"].Value + ")</nowiki>''"; } text += "\n|}"; // remove multiple line breaks text = Regex.Replace(text, @"[\r\n]{3,}", "\n\n"); Invoke(new Action(delegate() { textBox3.Text = text.Replace("\n", "\r\n"); lnkLocalFile.Enabled = lnkGoogleImageSearch.Enabled = true; lnkCommonsFile.Enabled = false; lblFileLinks.Visible = lstFileLinks.Visible = true; if (lstFileLinks.ForeColor == SystemColors.GrayText) { lstFileLinks.Items.Clear(); lstFileLinks.Items.Add(Localization.GetString("Loading")); } EnableForm(true); })); }); sentry.Finally += new Action(delegate() { Invoke(new Action(delegate() { EnableForm(true); })); }); // download image file StringDictionary query = new StringDictionary { { "action", "query" }, { "prop", "imageinfo" }, { "iiprop", "comment|timestamp|user|url|size|mime|metadata" }, { "iilimit", "500" }, { "iiurlwidth", pictureBox1.Width.ToString() }, { "iiurlheight", pictureBox1.Height.ToString() }, { "titles", filename }, { "redirects", "true" } }; MorebitsDotNet.PostApi(Wiki.Local, query, delegate(XmlDocument doc) { switch (doc.GetElementsByTagName("page")[0].Attributes["imagerepository"].Value) { case "shared": MessageBox.Show(Localization.GetString("AlreadyCommons")); sentry.Fail(); return; case "": if (doc.GetElementsByTagName("page")[0].Attributes["missing"] != null) MessageBox.Show(Localization.GetString("ImageMissing")); else MessageBox.Show(Localization.GetString("NoFile")); sentry.Fail(); return; } iis = doc.GetElementsByTagName("ii"); Invoke(new Action(delegate() { lblName.Text = doc.GetElementsByTagName("page")[0].Attributes["title"].Value; if (iis.Count > 1) { lblPastRevisions.Visible = btnPastRevisions.Visible = true; lblPastRevisions.Text = ((iis.Count == 2) ? Localization.GetString("OneEarlierVersion_Label") : Localization.GetString("EarlierVersions_Format", (iis.Count - 1).ToString())); } else lblPastRevisions.Visible = btnPastRevisions.Visible = false; })); // download the file and display a thumbnail (also display metadata) DownloadFileAndDisplayThumb(iis[0]); sentry.DoneOne(); }, ErrorHandler); // get wikitext of file description page query = new StringDictionary { { "action", "query" }, { "prop", "revisions" }, { "rvprop", "content" }, { "titles", filename }, { "redirects", "true" } }; MorebitsDotNet.PostApi(Wiki.Local, query, delegate(XmlDocument doc) { if (doc.GetElementsByTagName("page")[0].Attributes["missing"] != null) { // MessageBox.Show("Image does not exist on enwiki"); don't need to tell user twice sentry.Fail(); return; } text = doc.GetElementsByTagName("rev")[0].InnerText; Invoke(new Action(delegate() { textBox2.Text = text.Replace("\n", "\r\n"); })); XmlNodeList ns = doc.GetElementsByTagName("n"); if (ns.Count > 0) Invoke(new Action(delegate() { filename = ns[0].Attributes["to"].Value; })); Invoke(new Action(delegate() { txtNormName.Text = Regex.Replace(filename, @"^\w+:", "File:"); })); sentry.DoneOne(); }, ErrorHandler); // get file links (not in sentry) query = new StringDictionary { { "action", "query" }, { "list", "imageusage" }, { "iulimit", "20" }, { "iutitle", filename } }; // prevent race conditions object current = new object(); Invoke(new Action(delegate() { lstFileLinks.Tag = current; })); MorebitsDotNet.PostApi(Wiki.Local, query, delegate(XmlDocument doc) { if (lstFileLinks.Tag != current) return; Invoke(new Action(delegate() { lstFileLinks.Items.Clear(); XmlNodeList ius = doc.GetElementsByTagName("iu"); if (ius.Count == 0) { lstFileLinks.Items.Add(Localization.GetString("NoImageUsages_Label")); return; } lstFileLinks.ForeColor = SystemColors.ControlText; foreach (XmlNode i in ius) lstFileLinks.Items.Add(i.Attributes["title"].Value); if (doc.GetElementsByTagName("query-continue").Count > 0) lstFileLinks.Items.Add("<<" + Localization.GetString("SeeWikiForFullList_Label") + ">>"); })); }, ErrorHandler); }