public async Task WikiLinkTest1() { var WpTestSite = await WpTest2SiteAsync; var link1 = WikiLink.Parse(WpTestSite, "____proJEct__talk_:___sandbox_"); var link2 = WikiLink.Parse(WpTestSite, "__ _pROject_ _talk_:___sandbox_", BuiltInNamespaces.Category); var link3 = WikiLink.Parse(WpTestSite, "___sandbox_ test__", BuiltInNamespaces.Category); var link4 = WikiLink.Parse(WpTestSite, "__: sandbox test ", BuiltInNamespaces.Template); var link5 = WikiLink.Parse(WpTestSite, "___lZh__:project:test|", BuiltInNamespaces.Template); Assert.Equal("Wikipedia talk:Sandbox", link1.ToString()); Assert.Equal("Wikipedia talk", link1.NamespaceName); Assert.Equal("Sandbox", link1.Title); Assert.Equal("Wikipedia talk:Sandbox", link1.Target); Assert.Equal("Wikipedia talk:Sandbox", link1.DisplayText); Assert.Equal("https://test2.wikipedia.org/wiki/Wikipedia%20talk:Sandbox", link1.TargetUrl); Assert.Null(link1.InterwikiPrefix); Assert.Null(link1.Section); Assert.Null(link1.Anchor); Assert.Equal("Wikipedia talk:Sandbox", link2.ToString()); Assert.Equal("Category:Sandbox test", link3.ToString()); Assert.Equal("Sandbox test", link4.ToString()); Assert.Equal("lzh:Project:test|", link5.ToString()); Assert.Equal("Project:test", link5.DisplayText); Assert.Equal("lzh", link5.InterwikiPrefix); Assert.Equal("lzh:Project:test", link5.Target); Assert.Equal("", link5.Anchor); var link6 = WikiLink.Parse(WpTestSite, "sandbox#sect|anchor", BuiltInNamespaces.Template); Assert.Equal("Template:Sandbox#sect|anchor", link6.ToString()); Assert.Equal("Template:Sandbox#sect", link6.Target); Assert.Equal("sect", link6.Section); Assert.Equal("anchor", link6.Anchor); Assert.Equal("anchor", link6.DisplayText); }
/// <summary> /// Imports the Lua module with the specified name and evaluates the specified Lua code with it. /// </summary> /// <typeparam name="T">The expected evaluation return value type.</typeparam> /// <param name="site">The MediaWiki site on which to evaluate the module.</param> /// <param name="moduleName">Name of the module to be imported, with or without <c>Module:</c> prefix.</param> /// <param name="epilog">The Lua code snippet used to return value from the imported module (denoted as <c>p</c> in Lua), /// or <c>null</c> to use default epilog (<c>return p</c>).</param> /// <param name="serializer">The JsonSerializer used to deserialize the return value from JSON, or <c>null</c> to use default JSON serializer.</param> /// <param name="cancellationToken">A token used to cancel the operation.</param> /// <returns>The deserialized Lua evaluation result.</returns> public static Task <T> ScribuntoLoadDataAsync <T>(this WikiSite site, string moduleName, string?epilog, JsonSerializer?serializer, CancellationToken cancellationToken) { if (site == null) { throw new ArgumentNullException(nameof(site)); } if (string.IsNullOrEmpty(moduleName)) { throw new ArgumentException(Prompts.ExceptionArgumentNullOrEmpty, nameof(moduleName)); } cancellationToken.ThrowIfCancellationRequested(); var moduleLink = WikiLink.Parse(site, moduleName); var normalizedModuleName = moduleLink.FullTitle; if (string.IsNullOrEmpty(moduleLink.NamespaceName)) { normalizedModuleName = "Module:" + normalizedModuleName; } if (epilog == null) { epilog = "return p"; } var sb = new StringBuilder("-- ScribuntoLoadDataAsync\n\n", 64 + normalizedModuleName.Length + epilog.Length); sb.Append("local p = require([==["); sb.Append(normalizedModuleName); sb.Append("]==])\n\n"); sb.Append(epilog); sb.AppendLine(); return(ScribuntoExecuteLuaAsync <T>(site, sb.ToString(), serializer, cancellationToken)); }
protected void ReloadPageContent() { // Switch content model, if necessary. var newContentModel = WikiPage.ContentModel ?? MediaWikiUtility.InferContentModelFromTitle( WikiLink.Parse(WikiPage.Site, WikiPage.Title)); if (EditorContentModel != newContentModel) { var ls = _SettingsService.GetSettingsByWikiContentModel(newContentModel); if (string.IsNullOrEmpty(ls.LanguageName)) { TextEditor = null; } else { TextEditor = _TextEditorFactory.CreateTextEditor(ls.LanguageName, true); TextEditor.WikiSite = SiteContext; TextEditor.DocumentOutline = DocumentOutline; } EditorContentModel = newContentModel; } if (TextEditor != null) { TextEditor.TextBox.Text = WikiPage.Content; TextEditor.InvalidateDocumentOutline(true); } }
/// <summary> /// Asynchronously uploads a file in this title. /// </summary> /// <param name="site"></param> /// <param name="title"></param> /// <param name="source">Source of the file.</param> /// <param name="comment">Comment of the upload, as well as the page content if it doesn't exist.</param> /// <param name="ignoreWarnings">Ignore any warnings. This must be set to upload a new version of an existing image.</param> /// <param name="watch">Whether to add the file into your watchlist.</param> /// <param name="cancellationToken">The cancellation token that will be checked prior to completing the returned task.</param> /// <exception cref="UnauthorizedAccessException">You do not have the permission to upload the file.</exception> /// <exception cref="OperationFailedException"> /// There's an general failure while uploading the file. /// - or - /// Since MW 1.31, if you are uploading the exactly same content to the same title /// with <paramref name="ignoreWarnings"/> set to <c>true</c>, /// you will reveive this exception with <see cref="OperationFailedException.ErrorCode"/> /// set to <c>fileexists-no-change</c>. See https://gerrit.wikimedia.org/r/378702 . /// </exception> /// <exception cref="TimeoutException">Timeout specified in <see cref="WikiClient.Timeout"/> has been reached.</exception> /// <returns>An <see cref="UploadResult"/>. You need to check <see cref="UploadResult.ResultCode"/> for further action.</returns> public static async Task <UploadResult> UploadAsync(this WikiSite site, string title, WikiUploadSource source, string comment, bool ignoreWarnings, AutoWatchBehavior watch, CancellationToken cancellationToken) { if (source == null) { throw new ArgumentNullException(nameof(source)); } Debug.Assert(source != null); var link = WikiLink.Parse(site, title, BuiltInNamespaces.File); using (site.BeginActionScope(null, title, source)) { var requestFields = new Dictionary <string, object> { { "action", "upload" }, { "watchlist", watch }, { "token", WikiSiteToken.Edit }, { "filename", link.Title }, { "comment", comment }, { "ignorewarnings", ignoreWarnings }, }; foreach (var p in source.GetUploadParameters(site.SiteInfo)) { requestFields[p.Key] = p.Value; } var request = new MediaWikiFormRequestMessage(requestFields, true); site.Logger.LogDebug("Start uploading."); var jresult = await site.InvokeMediaWikiApiAsync(request, cancellationToken); var result = jresult["upload"].ToObject <UploadResult>(Utility.WikiJsonSerializer); site.Logger.LogInformation("Uploaded. Result={Result}.", result.ResultCode); return(result); } }
/// <summary> /// Initializes a new instance of <see cref="Board"/> from site and page title. /// </summary> /// <param name="site">The Wikia site.</param> /// <param name="title">Full page title of the board.</param> /// <param name="defaultNamespaceId">The default namespace ID to be used for the <paramref name="title"/>.</param> /// <exception cref="ArgumentNullException"><paramref name="site"/> or <paramref name="title"/> is <c>null</c>.</exception> public Board(WikiaSite site, string title, int defaultNamespaceId) { Site = site ?? throw new ArgumentNullException(nameof(site)); var link = WikiLink.Parse(site, title, defaultNamespaceId); Page = new WikiPageStub(link.FullTitle, link.Namespace.Id); }
public async Task RunAsync() { var apg = new AllPagesGenerator(Site) { NamespaceId = Site.Namespaces["Item"].Id, PaginationSize = 100 }; using (var writer = File.CreateText(FileName)) using (var ie = apg.EnumItemsAsync().Buffer(100).GetEnumerator()) { while (await ie.MoveNext()) { var entities = ie.Current.Select(s => new Entity(Site, WikiLink.Parse(Site, s.Title).Title)).ToList(); await entities.RefreshAsync(EntityQueryOptions.FetchLabels, new[] { "en", "zh", "zh-cn", "zh-hans" }); foreach (var entity in entities) { writer.Write(entity.Id); writer.Write('\t'); writer.Write(entity.Labels["en"]); writer.Write('\t'); writer.Write(entity.Labels["zh-cn"] ?? entity.Labels["zh-hans"] ?? entity.Labels["zh"]); writer.WriteLine(); } } } }
/// <summary> /// Initializes a new <see cref="Topic"/> instance from MW site and topic page title. /// </summary> /// <param name="site">MediaWiki site.</param> /// <param name="title">Either full page title of the Flow discussion board including <c>Topic:</c> namespace prefix, or the workflow ID of the board.</param> /// <exception cref="ArgumentNullException"><paramref name="site"/> or <paramref name="title"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException"><paramref name="title"/> is not a valid title.</exception> public Topic(WikiSite site, string title) { Site = site ?? throw new ArgumentNullException(nameof(site)); var link = WikiLink.Parse(site, title, FlowNamespaces.Topic); Title = link.ToString(); WorkflowId = link.Title.ToLowerInvariant(); }
public async Task TestMethod2() { var WikiaTestSite = await WikiaTestSiteAsync; var link1 = WikiLink.Parse(WikiaTestSite, "__ _project_ _talk_:___sandbox_", BuiltInNamespaces.Category); var link2 = WikiLink.Parse(WikiaTestSite, "part1:part2:part3", BuiltInNamespaces.Category); Assert.Equal("Mediawiki 1.19 test Wiki talk:Sandbox", link1.ToString()); Assert.Equal("Category:Part1:part2:part3", link2.ToString()); }
public static string InferContentModel(this Page page) { if (page == null) { throw new ArgumentNullException(nameof(page)); } if (page.ContentModel != null) { return(page.ContentModel); } // For older MediaWiki sites... return(InferContentModelFromTitle(WikiLink.Parse(page.Site, page.Title))); }
/// <inheritdoc /> protected override async Task ProcessRecordAsync(CancellationToken cancellationToken) { using (var fs = new FileStream(File.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 1024 * 4, FileOptions.Asynchronous | FileOptions.SequentialScan)) { var titleLink = WikiLink.Parse(WikiSite, Title, BuiltInNamespaces.File); WikiUploadSource uploadSource; if (Chunked) { if (!ShouldProcess($"{File}", "Chunked stash")) { return; } var src = new ChunkedUploadSource(WikiSite, fs, File.Name) { DefaultChunkSize = 512 * 1024 }; var progress = new ProgressRecord(0, $"Stash {File}", null); WriteProgress(progress); do { var r = await src.StashNextChunkAsync(cancellationToken); if (r.ResultCode == UploadResultCode.Warning) { WriteWarning(r.Warnings.ToString()); } progress.PercentComplete = (int)(100.0 * src.UploadedSize / src.TotalSize); } while (!src.IsStashed); progress.RecordType = ProgressRecordType.Completed; uploadSource = src; } else { uploadSource = new StreamUploadSource(fs); } if (!ShouldProcess($"{File} -> {titleLink}", "Upload")) { return; } var result = await WikiSite.UploadAsync(Title, uploadSource, Comment, Force, Utility.ParseAutoWatchBehavior(Watch), cancellationToken); if (result.ResultCode == UploadResultCode.Warning) { WriteWarning(result.Warnings.ToString()); } WriteObject(result); } }
/// <summary> /// Initializes a new instance of <see cref="WikiPage"/> from page title. /// </summary> /// <param name="site">The wiki site this page is on.</param> /// <param name="title">Page title with or without namespace prefix.</param> /// <param name="defaultNamespaceId">The default namespace ID for page title without namespace prefix.</param> /// <remarks>The initialized instance does not contain any live information from MediaWiki site. /// Use <see cref="RefreshAsync()"/> to fetch for information from server.</remarks> public WikiPage(WikiSite site, string title, int defaultNamespaceId) { if (site == null) { throw new ArgumentNullException(nameof(site)); } if (string.IsNullOrWhiteSpace(title)) { throw new ArgumentNullException(nameof(title)); } Site = site; var parsedTitle = WikiLink.Parse(site, title, defaultNamespaceId); PageStub = new WikiPageStub(parsedTitle.FullTitle, parsedTitle.Namespace !.Id); }
public WikiPage(WikiSite site, string title, int defaultNamespaceId) { if (site == null) { throw new ArgumentNullException(nameof(site)); } if (string.IsNullOrWhiteSpace(title)) { throw new ArgumentNullException(nameof(title)); } Site = site; WikiClient = Site.WikiClient; Debug.Assert(WikiClient != null); var parsedTitle = WikiLink.Parse(site, title, defaultNamespaceId); Title = parsedTitle.FullTitle; NamespaceId = parsedTitle.Namespace.Id; }
/// <summary> /// Get all possible namespace-alias - title combinations. /// </summary> private IEnumerable <string> PageTitleCombinations(string title, Site site, bool leadingColon, bool transclusion) { var link = WikiLink.Parse(site, title); if (link.Namespace.Id == BuiltInNamespaces.Main) { if (transclusion) { return new[] { ":" + link.Title } } ; return(new[] { link.Title }); } if (transclusion && link.Namespace.Id == BuiltInNamespaces.Template) { return new[] { link.Title } } ; return(link.Namespace.Aliases.Concat(new[] { link.Namespace.CanonicalName, link.Namespace.CustomName }) .Distinct().Where(n => n != null) .Select(n => (leadingColon ? ":" : null) + n + ":" + link.Title)); }
/// <summary> /// Create an instance of <see cref="WikiPage"/> or its derived class, /// depending on the namespace the page is in. /// </summary> /// <param name="site">Site instance.</param> /// <param name="title">Title of the page, with or without namespace prefix.</param> /// <param name="defaultNamespaceId"> /// The namespace id of the page used when there's no explicit namespace prefix in <paramref name="title"/>. /// See <see cref="BuiltInNamespaces"/> for a list of possible values. /// </param> /// <exception cref="ArgumentNullException">Either <paramref name="site"/> or <paramref name="title"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException"><paramref name="title"/> has invalid title patterns.</exception> /// <exception cref="InvalidOperationException"><paramref name="title"/> is an interwiki link.</exception> public static WikiPage FromTitle(WikiSite site, string title, int defaultNamespaceId) { if (site == null) { throw new ArgumentNullException(nameof(site)); } if (title == null) { throw new ArgumentNullException(nameof(title)); } WikiLink link; try { link = WikiLink.Parse(site, title, defaultNamespaceId); } catch (ArgumentException ex) { throw new ArgumentException(ex.Message, nameof(title), ex); } if (link.InterwikiPrefix != null) { throw new InvalidOperationException($"Interwiki title is not supported: {title} ."); } switch (link.Namespace.Id) { case BuiltInNamespaces.Category: return(new CategoryPage(site, title)); case BuiltInNamespaces.File: return(new CategoryPage(site, title)); default: return(new WikiPage(site, title, defaultNamespaceId)); } }
public static async Task <Post> PostWallMessageAsync(WikiaSite site, object scopeInst, WikiPageStub owner, string messageTitle, string messageBody, IEnumerable <string> relatedPages, CancellationToken cancellationToken) { Debug.Assert(site != null); Debug.Assert(owner.HasTitle); using (site.BeginActionScope(scopeInst, owner)) { var tokenPurged = false; var pageTitle = owner.Title; var pageNamespaceId = owner.NamespaceId; if (pageTitle.StartsWith("Message Wall:", StringComparison.OrdinalIgnoreCase)) { pageTitle = pageTitle.Substring(13); if (!owner.HasNamespaceId) { pageNamespaceId = WikiaNamespaces.MessageWall; } } else if (pageTitle.StartsWith("Board:", StringComparison.OrdinalIgnoreCase)) { pageTitle = pageTitle.Substring(6); if (!owner.HasNamespaceId) { pageNamespaceId = WikiaNamespaces.Thread; } } else { var link = WikiLink.Parse(site, owner.Title); pageTitle = link.Title; pageNamespaceId = link.Namespace.Id; } var queryParams = new OrderedKeyValuePairs <string, object> { { "token", null }, { "controller", "WallExternal" }, { "method", "postNewMessage" }, { "format", "json" }, { "pagenamespace", pageNamespaceId }, { "pagetitle", pageTitle }, { "messagetitle", messageTitle }, { "body", messageBody }, { "notifyeveryone", 0 }, { "convertToFormat", "" }, }; if (relatedPages != null) { foreach (var title in relatedPages) { queryParams.Add("relatedTopics[]", title); } } BEGIN: queryParams["token"] = await site.GetTokenAsync("edit", cancellationToken); var jresult = await site.InvokeNirvanaAsync(new WikiaQueryRequestMessage(queryParams, true), WikiaJsonResonseParser.Default, cancellationToken); if (!string.Equals((string)jresult["status"], "True", StringComparison.OrdinalIgnoreCase)) { var errorMessage = (string)jresult["errormsg"]; if (errorMessage != null) { if (!tokenPurged) { if (errorMessage.IndexOf("There seems to be a problem with your login session", StringComparison.OrdinalIgnoreCase) >= 0) { await site.GetTokenAsync("edit", true, cancellationToken); tokenPurged = true; goto BEGIN; } } } errorMessage = "Status code indicates a failure: " + (string)jresult["status"]; throw new OperationFailedException(errorMessage); } var text = (string)jresult["message"]; var doc = new HtmlDocument(); doc.LoadHtml(text); var node = doc.DocumentNode.SelectSingleNode("li"); if (node == null) { throw new UnexpectedDataException("Cannot locate the comment text node in the Wikia API response."); } return(Post.FromHtmlNode(site, owner, node)); } }
public async Task <WikipediaArticle> GetArticleAsync(string language, string name) { if (rateLimiter.IsRatelimited()) { return(null); } var article = new WikipediaArticle { Url = $"https://{language}.wikipedia.org/wiki/{name}" }; var page = new WikiPage(wikipediaSite, name); await page.RefreshAsync(new WikiPageQueryProvider { Properties = { new ExtractsPropertyProvider { MaxCharacters = 1024, AsPlainText = true, IntroductionOnly = true } } }); var extractGroup = page.GetPropertyGroup <ExtractsPropertyGroup>(); article.Name = page.Title; article.Url = WikiLink.Parse(wikipediaSite, name).TargetUrl; article.Description = extractGroup.Extract; if (article.Description.Length >= 1024) { var split = article.Description.Split(". ").ToList(); article.Description = string.Join(". ", split.Take(4)) + "."; } var response = await HttpWebClient.ReturnStringAsync(new System.Uri($"https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&sites={language}wiki&props=claims&titles={name}")); var jsonresp = JObject.Parse(response); var container = (JObject)jsonresp["entities"].First.Value <JProperty>().Value; var claims = container["claims"]; //P18/P154/P242/P109/P1621 JToken snak = null; if (claims["P18"] is not null) { snak = claims["P18"]; } else if (claims["P154"] is not null) { snak = claims["P154"]; } else if (claims["P242"] is not null) { snak = claims["P242"]; } else if (claims["P109"] is not null) { snak = claims["P109"]; } else if (claims["P1621"] is not null) { snak = claims["P1621"]; } if (snak is not null) { var val = snak.First["mainsnak"]["datavalue"]["value"].ToObject <string>(); val = val.Replace(" ", "_"); var md5 = val.CreateMD5(true);; article.ImageUrl = $"https://upload.wikimedia.org/wikipedia/commons/{md5[0]}/{md5[0]}{md5[1]}/{val}"; } return(article); }
//content can be // Stream file content // string url to fetch // UploadResult the previous failed upload private static async Task <UploadResult> UploadAsyncInternal(WikiSite site, object content, string title, string comment, bool ignoreWarnings, AutoWatchBehavior watch, CancellationToken cancellationToken) { if (site == null) { throw new ArgumentNullException(nameof(site)); } if (content == null) { throw new ArgumentNullException(nameof(content)); } if (title == null) { throw new ArgumentNullException(nameof(title)); } var link = WikiLink.Parse(site, title); if (link.Namespace.Id != BuiltInNamespaces.File) { throw new ArgumentException($"Invalid namespace for file title: {title} .", nameof(title)); } var token = await site.GetTokenAsync("edit"); long?streamPosition = null; HttpContent RequestFactory() { var requestContent = new MultipartFormDataContent { { new StringContent("json"), "format" }, { new StringContent("upload"), "action" }, { new StringContent(Utility.ToWikiQueryValue(watch)), "watchlist" }, { new StringContent(token), "token" }, { new StringContent(link.Title), "filename" }, { new StringContent(comment), "comment" }, }; if (content is Stream streamContent) { if (streamPosition < 0) { return(null); } // Memorize/reset the stream position. if (streamContent.CanSeek) { if (streamPosition == null) { streamPosition = streamContent.Position; } else { streamContent.Position = streamPosition.Value; } Debug.Assert(streamPosition >= 0); } else { // Mark for do-not-retry. streamPosition = -1; } requestContent.Add(new KeepAlivingStreamContent(streamContent), "file", title); } else if (content is string stringContent) { requestContent.Add(new StringContent(stringContent), "url"); } else if (content is UploadResult resultContent) { var key = (resultContent).FileKey; if (string.IsNullOrEmpty(key)) { throw new InvalidOperationException("The specified UploadResult has no valid FileKey."); } // sessionkey: Same as filekey, maintained for backward compatibility (deprecated in 1.18) requestContent.Add(new StringContent(key), site.SiteInfo.Version >= new Version(1, 18) ? "filekey" : "sessionkey"); } else { Debug.Assert(false, "Unrecognized content argument type."); } if (ignoreWarnings) { requestContent.Add(new StringContent(""), "ignorewarnings"); } return(requestContent); } site.Logger?.Info(site, $"Uploading: {link.Title} ."); var jresult = await site.PostContentAsync(RequestFactory, cancellationToken); var result = jresult["upload"].ToObject <UploadResult>(Utility.WikiJsonSerializer); site.Logger?.Info(site, $"Upload[{link.Title}]: {result}."); switch (result.ResultCode) { case UploadResultCode.Warning: throw new UploadException(result); default: // UploadResult.Result setter should have thrown an exception. Debug.Assert(result.ResultCode == UploadResultCode.Success || result.ResultCode == UploadResultCode.Continue); break; } return(result); }
private static async Task FetchLabels(WikiSite site, Func <string, Task <WikiSite> > getExternalSiteAsync, string originEntity) { var apg = new BacklinksGenerator(site, originEntity) { NamespaceIds = new[] { site.Namespaces["Item"].Id }, RedirectsFilter = PropertyFilterOption.WithoutProperty, PaginationSize = 100 }; var itemCounter = 0; var enSite = await getExternalSiteAsync("en"); await foreach (var stubs in apg.EnumItemsAsync().Buffer(100)) { var items = stubs.Select(s => new Entity(site, WikiLink.Parse(site, s.Title).Title)).ToList(); await items.RefreshAsync(EntityQueryOptions.FetchLabels | EntityQueryOptions.FetchSiteLinks, new List <string> { "en" }); var enwwPages = items.ToDictionary(i => i, i => { var enwwtitle = i.SiteLinks.ContainsKey("enwarriorswiki") ? i.SiteLinks["enwarriorswiki"].Title : null; if (string.IsNullOrEmpty(enwwtitle)) { Console.WriteLine("{0}: No enww sitelink available.", i); return(null); } return(new WikiPage(enSite, enwwtitle)); }); Console.WriteLine("Fetching language links from enww."); await enwwPages.Values.Where(p => p != null).RefreshAsync(new WikiPageQueryProvider { Properties = { new LanguageLinksPropertyProvider() } }); foreach (var item in items) { var enPage = enwwPages[item]; if (enPage == null) { continue; } foreach (var langLink in enPage.GetPropertyGroup <LanguageLinksPropertyGroup>().LanguageLinks // Wikia returns duplicate language links .Select(l => (l.Language, l.Title)).Distinct()) { if (langLink.Language == "zh") { continue; } var siteName = langLink.Language + "warriorswiki"; if (item.SiteLinks.ContainsKey(siteName)) { continue; } Console.Write("{0}: Add {1}:{2}...", item, siteName, langLink.Title); try { await item.EditAsync(new[] { new EntityEditEntry(nameof(item.SiteLinks), new EntitySiteLink(siteName, langLink.Title)) }, "Add sitelink from enwarriorswiki.", EntityEditOptions.Bot); Console.WriteLine("Success."); } catch (OperationFailedException ex) when(ex.ErrorCode == "no-external-page") { Console.WriteLine("No external page."); } catch (OperationFailedException ex) when(ex.ErrorCode == "failed-save") { Console.WriteLine("Save failed."); Console.WriteLine(ex.ErrorMessage); } } } itemCounter += items.Count; Console.WriteLine("Processed {0} items.", itemCounter); } }
/// <summary> /// Moves (renames) a page. (MediaWiki 1.12) /// </summary> public async Task MoveAsync(string newTitle, string reason, PageMovingOptions options, AutoWatchBehavior watch, CancellationToken cancellationToken) { if (newTitle == null) { throw new ArgumentNullException(nameof(newTitle)); } if (newTitle == Title) { return; } using (Site.BeginActionScope(this)) using (await Site.ModificationThrottler.QueueWorkAsync("Move: " + this, cancellationToken)) { // When passing this to the Edit API, always pass the token parameter last // (or at least after the text parameter). That way, if the edit gets interrupted, // the token won't be passed and the edit will fail. // This is done automatically by mw.Api. JToken jresult; try { jresult = await Site.InvokeMediaWikiApiAsync(new MediaWikiFormRequestMessage(new { action = "move", token = WikiSiteToken.Move, from = PageStub.HasTitle ? PageStub.Title : null, fromid = PageStub.HasTitle ? null : (int?)PageStub.Id, to = newTitle, maxlag = 5, movetalk = (options & PageMovingOptions.LeaveTalk) != PageMovingOptions.LeaveTalk, movesubpages = (options & PageMovingOptions.MoveSubpages) == PageMovingOptions.MoveSubpages, noredirect = (options & PageMovingOptions.NoRedirect) == PageMovingOptions.NoRedirect, ignorewarnings = (options & PageMovingOptions.IgnoreWarnings) == PageMovingOptions.IgnoreWarnings, watchlist = watch, reason = reason, }), cancellationToken); } catch (OperationFailedException ex) { switch (ex.ErrorCode) { case "cantmove": case "protectedpage": case "protectedtitle": throw new UnauthorizedOperationException(ex); default: if (ex.ErrorCode.StartsWith("cantmove")) { throw new UnauthorizedOperationException(ex); } throw; } } var fromTitle = (string)jresult["move"]["from"]; var toTitle = (string)jresult["move"]["to"]; Site.Logger.LogInformation("Page [[{fromTitle}]] has been moved to [[{toTitle}]].", fromTitle, toTitle); var link = WikiLink.Parse(Site, toTitle); PageStub = new WikiPageStub(PageStub.Id, toTitle, link.Namespace.Id); } }
private static async Task UpdateLabels(WikiSite site, string originEntity) { var apg = new BacklinksGenerator(site, originEntity) { NamespaceIds = new[] { site.Namespaces["Item"].Id }, RedirectsFilter = PropertyFilterOption.WithoutProperty, PaginationSize = 100 }; var itemCounter = 0; await foreach (var stubs in apg.EnumItemsAsync().Buffer(100)) { var items = stubs.Select(s => new Entity(site, WikiLink.Parse(site, s.Title).Title)).ToList(); await items.RefreshAsync(EntityQueryOptions.FetchLabels | EntityQueryOptions.FetchAliases | EntityQueryOptions.FetchSiteLinks); foreach (var item in items) { var enLabels = new HashSet <string>(); { var enSiteLink = item.SiteLinks.FirstOrDefault(sl => sl.Site == "enwarriorswiki")?.Title; if (!string.IsNullOrEmpty(enSiteLink)) { enLabels.Add(LabelFromTitle(enSiteLink)); } enLabels.Add(item.Labels["en"]); enLabels.Add(item.Labels["en-us"]); enLabels.Add(item.Labels["en-gb"]); foreach (var alias in item.Aliases["en"]) { enLabels.Add(alias); } enLabels.Remove(null); } foreach (var siteLink in item.SiteLinks.Where(sl => sl.Site.EndsWith("warriorswiki"))) { var language = siteLink.Site.Substring(0, siteLink.Site.Length - 12); if (language == "zh") { continue; } var culture = CultureInfo.GetCultureInfo(language); var label = Regex.Replace(siteLink.Title, @"(?!<=^)\s*\(.+", ""); var curLabel = item.Labels[language]; //if (language != "en") //{ // if (enLabels.Contains(curLabel)) // { // Console.Write("{0}: Remove label: {1}@{2}", item, curLabel, language); // await item.EditAsync(new[] // { // new EntityEditEntry(nameof(item.Labels), new WbMonolingualText(language, "dummy"), EntityEditEntryState.Removed) // }, "", EntityEditOptions.Bot); // Console.WriteLine(); // } // foreach (var alias in item.Aliases[language]) // { // if (enLabels.Contains(alias)) // { // Console.Write("{0}: Remove alias: {1}@{2}", item, alias, language); // await item.EditAsync(new[] // { // new EntityEditEntry(nameof(item.Aliases), new WbMonolingualText(language, alias), EntityEditEntryState.Removed) // }, "", EntityEditOptions.Bot); // Console.WriteLine(); // } // } //} if (!enLabels.Contains(label) && (curLabel == null || label.ToLower(culture) != curLabel.ToLower(culture))) { var convertToAlias = !string.IsNullOrWhiteSpace(curLabel) && !enLabels.Contains(curLabel); Console.Write("{0}: {1}: {2} -> {3}", item, language, curLabel, label); var changes = new List <EntityEditEntry> { new EntityEditEntry(nameof(item.Labels), new WbMonolingualText(language, label)) }; if (convertToAlias) { Console.Write(" (New alias)"); changes.Add(new EntityEditEntry(nameof(item.Aliases), new WbMonolingualText(language, curLabel))); } await item.EditAsync(changes, "Update label from " + siteLink.Site + ".", EntityEditOptions.Bot); Console.WriteLine(); } } } itemCounter += items.Count; Console.WriteLine("Processed {0} items.", itemCounter); } }
public async Task TestMethod4() { var site = await WpTest2SiteAsync; Assert.Throws <ArgumentException>(() => WikiLink.Parse(site, "Project:")); }