public static async Task RefreshBaordsAsync(IEnumerable <Board> boards, CancellationToken cancellationToken) { Debug.Assert(boards != null); // Fetch comment content. // You can even fetch posts from different sites. foreach (var sitePosts in boards.GroupBy(p => p.Site)) { var site = sitePosts.Key; var titleLimit = site.AccountInfo.HasRight(UserRights.ApiHighLimits) ? 500 : 50; foreach (var partition in sitePosts.Partition(titleLimit)) { Debug.Assert(partition.All(p => p.Page.HasId || p.Page.HasTitle)); var boardsWithTitle = partition.Where(b => b.Page.HasTitle).ToList(); if (boardsWithTitle.Count > 0) { var stubs = await WikiPageStub.FromPageTitles(site, boardsWithTitle.Select(b => b.Page.Title)) .ToList(cancellationToken); for (int i = 0; i < boardsWithTitle.Count; i++) { boardsWithTitle[i].LoadFromPageStub(stubs[i]); } } var boardsWithId = partition.Where(b => !b.Page.HasTitle).ToList(); if (boardsWithId.Count > 0) { var stubs = await WikiPageStub.FromPageTitles(site, boardsWithId.Select(b => b.Page.Title)) .ToList(cancellationToken); for (int i = 0; i < boardsWithId.Count; i++) { boardsWithId[i].LoadFromPageStub(stubs[i]); } } } } }
public async Task <FeatureCollection> GetById(string id) { var language = id.Split('_').First(); var pageId = id.Split('_').Last(); var site = _wikiSites[language]; var stub = await WikiPageStub.FromPageIds(site, new[] { int.Parse(pageId) }).First(); var page = new WikiPage(site, stub.Title); await page.RefreshAsync(new WikiPageQueryProvider { Properties = { new ExtractsPropertyProvider { AsPlainText = true, IntroductionOnly = true, MaxSentences = 1 }, new PageImagesPropertyProvider { QueryOriginalImage = true }, new GeoCoordinatesPropertyProvider { QueryPrimaryCoordinate = true } } }); var geoCoordinate = page.GetPropertyGroup <GeoCoordinatesPropertyGroup>().PrimaryCoordinate; var coordinate = new Coordinate(geoCoordinate.Longitude, geoCoordinate.Latitude); var attributes = GetAttributes(coordinate, page.Title, id, language); attributes.Add(FeatureAttributes.DESCRIPTION, page.GetPropertyGroup <ExtractsPropertyGroup>().Extract ?? string.Empty); attributes.Add(FeatureAttributes.IMAGE_URL, page.GetPropertyGroup <PageImagesPropertyGroup>().OriginalImage.Url); attributes.Add(FeatureAttributes.WEBSITE, $"https://{language}.wikipedia.org/?curid={page.Id}"); return(new FeatureCollection(new Collection <IFeature> { new Feature(new Point(coordinate), attributes) })); }
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[13..];
public static async Task <Post> PostCommentAsync(WikiaSite site, object scopeInst, WikiPageStub owner, int?parentId, string content, CancellationToken cancellationToken) { Debug.Assert(site != null); Debug.Assert(owner.HasTitle); using (site.BeginActionScope(scopeInst, owner, parentId)) { var jresult = await site.InvokeWikiaAjaxAsync(new WikiaQueryRequestMessage(new { article = owner.Id, rs = "ArticleCommentsAjax", method = "axPost", token = await site.GetTokenAsync("edit", cancellationToken), convertToFormat = "", parentId = parentId, wpArticleComment = content, }, true), WikiaJsonResponseParser.Default, cancellationToken); if (((int?)jresult["error"] ?? 0) != 0) { throw new OperationFailedException((string)jresult["msg"]); } var text = (string)jresult["text"]; var doc = new HtmlDocument(); doc.LoadHtml(text); var node = doc.DocumentNode.SelectSingleNode("li"); if (node == null) { throw new UnexpectedDataException("Cannot locate the text node in the Wikia API response."); } return(Post.FromHtmlNode(site, owner, node)); } }
internal void LoadFromPageStub(WikiPageStub stub) { Page = stub; Exists = !stub.IsMissing; }
/// <summary> /// Initializes a new instance of <see cref="Board"/> from site and page ID. /// </summary> /// <param name="site">The Wikia site.</param> /// <param name="pageId">Page ID of the board.</param> /// <exception cref="ArgumentNullException"><paramref name="site"/> is <c>null</c>.</exception> public Board(WikiaSite site, int pageId) { Site = site ?? throw new ArgumentNullException(nameof(site)); Page = new WikiPageStub(pageId); }
public static async Task <Post> ReplyWallMessageAsync(WikiaSite site, object scopeInst, WikiPageStub owner, int parentId, string messageBody, CancellationToken cancellationToken) { Debug.Assert(site != null); using (site.BeginActionScope(scopeInst, owner, parentId)) { var tokenPurged = false; BEGIN: var jresult = await site.InvokeNirvanaAsync(new WikiaQueryRequestMessage(new { controller = "WallExternal", method = "replyToMessage", format = "json", token = await site.GetTokenAsync("edit", cancellationToken), pagenamespace = WikiaNamespaces.Thread, pagetitle = parentId, parent = parentId, body = messageBody, convertToFormat = "", }, 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 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)); } }
private async Task <Feature> PageToFeature(WikiPageStub pageStub) { var page = await GetPageContent(pageStub).ConfigureAwait(false); if (string.IsNullOrEmpty(page?.Content)) { return(null); } if (page.Content.Contains("קטגוריה:לבדיקה")) { // this page should not be displayed as it is still in editing. return(null); } if (!page.Content.Contains("{{נקודת עניין") && !page.Content.Contains("{{שמורת טבע") && !page.Content.Contains("{{גן לאומי") && !page.Content.Contains("{{אתר לאומי") && !page.Content.Contains("{{מסלולי טיול")) { // non-POI return(null); } if (page.Content.Contains("{{מסלולי טיול למפרסמים")) { // Remove advertised routes return(null); } var shareMatch = Regex.Match(page.Content, @"israelhiking\.osm\.org\.il/share/(.*?)[""']", RegexOptions.IgnoreCase); if (page.Content.Contains("{{מסלולי טיול") && !shareMatch.Success) { return(null); } var descriptionMatch = Regex.Match(page.Content, @"סקירה=(.*)"); if (!descriptionMatch.Success) { return(null); } var description = descriptionMatch.Groups[1].Value; var match = Regex.Match(page.Content, @"נצ=(\d+\.\d+)\s*,\s*(\d+\.\d+)"); if (!match.Success) { return(null); } var geoLocation = new LatLng(double.Parse(match.Groups[1].Value), double.Parse(match.Groups[2].Value)); var geoLocationTable = new AttributesTable { { FeatureAttributes.LAT, geoLocation.Lat }, { FeatureAttributes.LON, geoLocation.Lng } }; var feature = new Feature(new Point(geoLocation.ToCoordinate()), new AttributesTable { { FeatureAttributes.POI_GEOLOCATION, geoLocationTable }, { FeatureAttributes.DESCRIPTION + ":" + Languages.HEBREW, description }, { FeatureAttributes.NAME, page.Title }, { FeatureAttributes.NAME + ":" + Languages.HEBREW, page.Title }, { FeatureAttributes.ID, page.Id.ToString() }, { FeatureAttributes.POI_SOURCE, Sources.INATURE }, { FeatureAttributes.POI_LANGUAGE, Languages.HEBREW }, { FeatureAttributes.POI_SEARCH_FACTOR, 1.0 }, { FeatureAttributes.WEBSITE, _wikiSite.SiteInfo.MakeArticleUrl(page.Title) }, { FeatureAttributes.POI_SOURCE_IMAGE_URL, "https://user-images.githubusercontent.com/3269297/37312048-2d6e7488-2652-11e8-9dbe-c1465ff2e197.png" } }); var image = await GetPageImageUrl(page).ConfigureAwait(false); if (!string.IsNullOrWhiteSpace(image)) { feature.Attributes.Add(FeatureAttributes.IMAGE_URL, image); } if (shareMatch.Success) { feature.Attributes[FeatureAttributes.NAME] += " - טבע ונופים"; feature.Attributes[FeatureAttributes.NAME + ":" + Languages.HEBREW] += " - טבע ונופים"; feature.Attributes.Add(FeatureAttributes.POI_CATEGORY, Categories.ROUTE_HIKE); feature.Attributes.Add(FeatureAttributes.POI_ICON, "icon-hike"); feature.Attributes.Add(FeatureAttributes.POI_ICON_COLOR, "black"); feature.Attributes.Add(FeatureAttributes.POI_SHARE_REFERENCE, shareMatch.Groups[1].Value); } else { feature.Attributes.Add(FeatureAttributes.POI_ICON, "icon-inature"); feature.Attributes.Add(FeatureAttributes.POI_ICON_COLOR, "#116C00"); feature.Attributes.Add(FeatureAttributes.POI_CATEGORY, Categories.INATURE); } feature.SetTitles(); feature.SetId(); return(feature); }