Skip to content

Commit

Permalink
Add Post class, as children of Topic.
Browse files Browse the repository at this point in the history
  • Loading branch information
CXuesong committed Oct 11, 2017
1 parent 7c611b9 commit 435681d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 20 deletions.
5 changes: 4 additions & 1 deletion UnitTestProject1/Tests/FlowTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ public async Task BoardTest()
var board = new Board(await WpBetaSiteAsync, "Talk:Flow QA");
await board.RefreshAsync();
ShallowTrace(board);
var x = await board.EnumTopicsAsync(20).Take(10).ToArray();
var y = await board.EnumTopicsAsync(10).ToArray();
var topics = await board.EnumTopicsAsync(10).Take(10).ToArray();
ShallowTrace(topics);
ShallowTrace(topics, 3);
Assert.DoesNotContain(null, topics);
}

}
Expand Down
11 changes: 7 additions & 4 deletions WikiClientLibrary/Flow/Board.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public Board(WikiSite site, string title)

/// <summary>Latest header content revision.</summary>
public Revision HeaderRevision { get; private set; }

/// <inheritdoc cref="RefreshAsync(CancellationToken)"/>
public Task RefreshAsync()
{
Expand Down Expand Up @@ -104,11 +104,14 @@ public IAsyncEnumerable<Topic> EnumTopicsAsync(int pageSize)
{
if (eof) return null;
var jresult = await Site.GetJsonAsync(new WikiFormRequestMessage(queryParams), ct);
var jtopiclist = (JObject) jresult["flow"]["view-topiclist"]["result"]["topiclist"];
var topics = Topic.FromJsonTopicList(Site, jtopiclist);
var jtopiclist = (JObject)jresult["flow"]["view-topiclist"]["result"]["topiclist"];
// ISSUE directly return SelectArrayIterator<TSource, TResult> via Enumerable.Select
// can cause strange behavior when chained with other async LINQ methods. See
// https://github.com/CXuesong/WikiClientLibrary/issues/27
var topics = Topic.FromJsonTopicList(Site, jtopiclist).ToList();
// TODO Implement Pagination
eof = true;
return Tuple.Create(topics, eof);
return Tuple.Create((IEnumerable<Topic>)topics, true);
});
return ienu.SelectMany(t => t.ToAsyncEnumerable());
}
Expand Down
89 changes: 89 additions & 0 deletions WikiClientLibrary/Flow/Post.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;
using WikiClientLibrary.Sites;

namespace WikiClientLibrary.Flow
{
/// <summary>
/// Represents a normal flow post.
/// </summary>
public sealed class Post
{

internal static readonly IList<Post> EmptyPosts = new Post[] { };

/// <summary>
/// Initializes a new <see cref="Post"/> instance from MW site and post workflow ID.
/// </summary>
/// <param name="site">MediaWiki site.</param>
/// <param name="workflowId">Full page title of the Flow discussion board, including <c>Topic:</c> namespace prefix.</param>
public Post(WikiSite site, string workflowId)
{
Site = site ?? throw new ArgumentNullException(nameof(site));
WorkflowId = workflowId ?? throw new ArgumentNullException(nameof(workflowId));
}

/// <summary>
/// The MediaWiki site hosting this post.
/// </summary>
public WikiSite Site { get; }

/// <summary>
/// Workflow ID of the post.
/// </summary>
public string WorkflowId { get; private set; }

/// <summary>
/// Gets the last revision of the post.
/// </summary>
public Revision LastRevision { get; private set; }

/// <summary>
/// Gets a read-only view of the replies.
/// </summary>
public IList<Post> Replies { get; private set; } = EmptyPosts;

internal static Post FromJson(WikiSite site, JObject topicList, string workflowId)
{
var post = new Post(site, workflowId);
post.LoadFromJsonTopicList(topicList, workflowId);
return post;
}

// topicList: The topiclist node of a view-topiclist query result.
internal void LoadFromJsonTopicList(JObject topicList, string workflowId)
{
var revisionId = (string)topicList["posts"][workflowId]?.First;
if (revisionId == null)
throw new ArgumentException("Cannot find workflow ID " + workflowId + " in [posts] array.", nameof(workflowId));
var jrevision = (JObject)topicList["revisions"][revisionId];
if (jrevision == null)
throw new UnexpectedDataException("Cannot find revision " + revisionId + " in [revisions] array.");
var rev = jrevision.ToObject<Revision>(FlowUtility.FlowJsonSerializer);
if (rev.ReplyIds == null || rev.ReplyIds.Count == 0)
{
Replies = EmptyPosts;
}
else
{
var posts = new List<Post>(rev.ReplyIds.Count);
posts.AddRange(rev.ReplyIds.Select(pid => FromJson(Site, topicList, pid)));
Replies = new ReadOnlyCollection<Post>(posts);
}
WorkflowId = workflowId;
}

/// <inheritdoc />
public override string ToString()
{
var result = "[" + WorkflowId + "]";
if (Replies.Count > 0) result += "[Re:" + Replies.Count + "]";
return result;
}
}
}
7 changes: 4 additions & 3 deletions WikiClientLibrary/Flow/Revision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ private string RawChangeType
//[JsonProperty]
//public DateFormats DateFormats { get; private set; }

// Can be JObject, or empty JArray
[JsonProperty]
public JObject Properties { get; private set; }
public JToken Properties { get; private set; }

[JsonProperty]
public bool IsOriginalContent { get; private set; }
Expand Down Expand Up @@ -102,8 +103,8 @@ private string RawChangeType
/// <summary>
/// Workflow ID of the replies.
/// </summary>
[JsonProperty]
public IList<string> Replies { get; private set; }
[JsonProperty("replies")]
public IList<string> ReplyIds { get; private set; }

/// <summary>
/// HTML links to show different views.
Expand Down
25 changes: 13 additions & 12 deletions WikiClientLibrary/Flow/Topic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,24 @@ public class Topic : IWikiClientLoggable
{
private ILoggerFactory _LoggerFactory;
private ILogger logger = NullLogger.Instance;
private readonly List<Revision> _Posts = new List<Revision>();

/// <summary>
/// Initializes a new <see cref="Board"/> instance from MW site and board page title.
/// Initializes a new <see cref="Topic"/> instance from MW site and topic page title.
/// </summary>
/// <param name="site">MediaWiki site.</param>
/// <param name="title">Full page title of the Flow discussion board, including namespace prefix.</param>
/// <param name="title">Full page title of the Flow discussion board, including <c>Topic:</c> namespace prefix.</param>
public Topic(WikiSite site, string title)
{
Site = site ?? throw new ArgumentNullException(nameof(site));
Title = title ?? throw new ArgumentNullException(nameof(title));
LoggerFactory = site.LoggerFactory;
Posts = new ReadOnlyCollection<Revision>(_Posts);
}

internal Topic(WikiSite site)
private Topic(WikiSite site)
{
Debug.Assert(site != null);
Site = site;
LoggerFactory = site.LoggerFactory;
Posts = new ReadOnlyCollection<Revision>(_Posts);
}

/// <summary>
Expand Down Expand Up @@ -74,10 +71,8 @@ internal static IEnumerable<Topic> FromJsonTopicList(WikiSite site, JObject topi
// topicList: The topiclist node of a view-topiclist query result.
internal void LoadFromJsonTopicList(JObject topicList, string workflowId)
{
_Posts.Clear();
TopicTitleRevision = null;
WorkflowId = null;
if (_Posts.Capacity < topicList.Count) _Posts.Capacity = topicList.Count;
var revisionId = (string)topicList["posts"][workflowId]?.First;
if (revisionId == null)
throw new ArgumentException("Cannot find workflow ID " + workflowId + " in [posts] array.", nameof(workflowId));
Expand All @@ -89,14 +84,20 @@ internal void LoadFromJsonTopicList(JObject topicList, string workflowId)
TopicTitleRevision = rev;
Title = TopicTitleRevision.ArticleTitle;
WorkflowId = TopicTitleRevision.WorkflowId;
// TODO Parse the replies.
foreach (var replyIds in rev.Replies)
if (rev.ReplyIds == null || rev.ReplyIds.Count == 0)
{

Posts = Post.EmptyPosts;
}
else
{
var posts = new List<Post>(rev.ReplyIds.Count);
posts.AddRange(rev.ReplyIds.Select(pid => Post.FromJson(Site, topicList, pid)));
Posts = new ReadOnlyCollection<Post>(posts);
}
WorkflowId = workflowId;
}

public IList<Revision> Posts { get; }
public IList<Post> Posts { get; private set; }

/// <summary>
/// Workflow ID of the topic.
Expand Down

0 comments on commit 435681d

Please sign in to comment.