Skip to content

Commit 3a3c72f

Browse files
committed
Add ability to view and filter mod log
Add default .gitattributes file to avoid issues with line endings
1 parent 72e86d8 commit 3a3c72f

File tree

6 files changed

+293
-19
lines changed

6 files changed

+293
-19
lines changed

.gitattributes

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
###############################################################################
2+
# Set default behavior to automatically normalize line endings.
3+
###############################################################################
4+
* text=auto
5+
6+
###############################################################################
7+
# Set default behavior for command prompt diff.
8+
#
9+
# This is need for earlier builds of msysgit that does not have it on by
10+
# default for csharp files.
11+
# Note: This is only used by command line
12+
###############################################################################
13+
#*.cs diff=csharp
14+
15+
###############################################################################
16+
# Set the merge driver for project and solution files
17+
#
18+
# Merging from the command prompt will add diff markers to the files if there
19+
# are conflicts (Merging from VS is not affected by the settings below, in VS
20+
# the diff markers are never inserted). Diff markers may cause the following
21+
# file extensions to fail to load in VS. An alternative would be to treat
22+
# these files as binary and thus will always conflict and require user
23+
# intervention with every merge. To do so, just uncomment the entries below
24+
###############################################################################
25+
#*.sln merge=binary
26+
#*.csproj merge=binary
27+
#*.vbproj merge=binary
28+
#*.vcxproj merge=binary
29+
#*.vcproj merge=binary
30+
#*.dbproj merge=binary
31+
#*.fsproj merge=binary
32+
#*.lsproj merge=binary
33+
#*.wixproj merge=binary
34+
#*.modelproj merge=binary
35+
#*.sqlproj merge=binary
36+
#*.wwaproj merge=binary
37+
38+
###############################################################################
39+
# behavior for image files
40+
#
41+
# image files are treated as binary by default.
42+
###############################################################################
43+
#*.jpg binary
44+
#*.png binary
45+
#*.gif binary
46+
47+
###############################################################################
48+
# diff behavior for common document formats
49+
#
50+
# Convert binary document formats to text before diffing them. This feature
51+
# is only available from the command line. Turn it on by uncommenting the
52+
# entries below.
53+
###############################################################################
54+
#*.doc diff=astextplain
55+
#*.DOC diff=astextplain
56+
#*.docx diff=astextplain
57+
#*.DOCX diff=astextplain
58+
#*.dot diff=astextplain
59+
#*.DOT diff=astextplain
60+
#*.pdf diff=astextplain
61+
#*.PDF diff=astextplain
62+
#*.rtf diff=astextplain
63+
#*.RTF diff=astextplain

RedditSharp/ModActionType.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
4+
namespace RedditSharp
5+
{
6+
public enum ModActionType
7+
{
8+
BanUser,
9+
UnBanUser,
10+
RemoveLink,
11+
ApproveLink,
12+
RemoveComment,
13+
ApproveComment,
14+
AddModerator,
15+
InviteModerator,
16+
UnInviteModerator,
17+
AcceptModeratorInvite,
18+
RemoveModerator,
19+
AddContributor,
20+
RemoveContributor,
21+
EditSettings,
22+
EditFlair,
23+
Distinguish,
24+
MarkNSFW,
25+
WikiBanned,
26+
WikiContributor,
27+
WikiUnBanned,
28+
WikiPageListed,
29+
RemoveWikiContributor,
30+
WikiRevise,
31+
WikiPermlevel,
32+
IgnoreReports,
33+
UnIgnoreReports,
34+
SetPermissions,
35+
SetSuggestedsort,
36+
Sticky,
37+
UnSticky,
38+
SetContestMode,
39+
UnSetContestMode,
40+
LockPost, //actual value is "Lock" but it's a reserved word
41+
Unlock,
42+
MuteUser,
43+
UnMuteUser
44+
}
45+
46+
public class ModActionTypeConverter : JsonConverter
47+
{
48+
/// <summary>
49+
/// Replaces "LockPost" with "lock" since "lock" is a reserved word and can't be used in the enum
50+
/// </summary>
51+
/// <returns>String representation of enum value recognized by Reddit's api</returns>
52+
public static string GetRedditParamName(ModActionType action)
53+
{
54+
if (action == ModActionType.LockPost) return "lock";
55+
else return action.ToString("g").ToLower();
56+
}
57+
public override bool CanConvert(Type objectType)
58+
{
59+
return objectType == typeof(ModActionType);
60+
}
61+
62+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
63+
{
64+
string value = reader.Value.ToString();
65+
if (value.ToLower() == "lock")
66+
{
67+
return ModActionType.LockPost;
68+
}
69+
else
70+
{
71+
return Enum.Parse(typeof(ModActionType), value);
72+
}
73+
74+
}
75+
76+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
77+
{
78+
if (value == null) writer.WriteNull();
79+
else writer.WriteValue(GetRedditParamName((ModActionType) value));
80+
}
81+
}
82+
}

RedditSharp/RedditSharp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
<Reference Include="System.Xml" />
5252
</ItemGroup>
5353
<ItemGroup>
54+
<Compile Include="ModActionType.cs" />
55+
<Compile Include="Things\ModAction.cs" />
5456
<Compile Include="Utils\DateTimeExtensions.cs" />
5557
<Compile Include="SpamFilterSettings.cs" />
5658
<Compile Include="Things\AuthenticatedUser.cs" />

RedditSharp/Things/ModAction.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using Newtonsoft.Json;
2+
using Newtonsoft.Json.Linq;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace RedditSharp.Things
10+
{
11+
public class ModAction : Thing
12+
{
13+
14+
[JsonProperty("action")]
15+
[JsonConverter(typeof(ModActionTypeConverter))]
16+
public ModActionType Action { get; set; }
17+
18+
[JsonProperty("created_utc")]
19+
[JsonConverter(typeof(UnixTimestampConverter))]
20+
public DateTime? TimeStamp { get; set; }
21+
22+
[JsonProperty("details")]
23+
public string Details { get; set; }
24+
25+
[JsonProperty("mod")]
26+
public string ModeratorName { get; set; }
27+
28+
[JsonProperty("target_author")]
29+
public string TargetAuthorName { get; set; }
30+
31+
[JsonProperty("target_fullname")]
32+
public string TargetThingFullname { get; set; }
33+
34+
[JsonProperty("target_permalink")]
35+
public string TargetThingPermalink { get; set; }
36+
37+
[JsonIgnore]
38+
public RedditUser TargetAuthor
39+
{
40+
get
41+
{
42+
return Reddit.GetUser(TargetAuthorName);
43+
}
44+
}
45+
46+
[JsonIgnore]
47+
public Thing TargetThing
48+
{
49+
get
50+
{
51+
return Reddit.GetThingByFullname(TargetThingFullname);
52+
}
53+
}
54+
55+
[JsonIgnore]
56+
private Reddit Reddit { get; set; }
57+
58+
[JsonIgnore]
59+
private IWebAgent WebAgent { get; set; }
60+
61+
public ModAction Init(Reddit reddit, JToken json, IWebAgent webAgent)
62+
{
63+
CommonInit(reddit, json, webAgent);
64+
JsonConvert.PopulateObject(json["data"].ToString(), this, reddit.JsonSerializerSettings);
65+
return this;
66+
}
67+
public async Task<ModAction> InitAsync(Reddit reddit, JToken post, IWebAgent webAgent)
68+
{
69+
CommonInit(reddit, post, webAgent);
70+
await Task.Factory.StartNew(() => JsonConvert.PopulateObject(post["data"].ToString(), this, reddit.JsonSerializerSettings));
71+
return this;
72+
}
73+
74+
private void CommonInit(Reddit reddit, JToken json, IWebAgent webAgent)
75+
{
76+
base.Init(json);
77+
Reddit = reddit;
78+
WebAgent = webAgent;
79+
}
80+
81+
}
82+
}

RedditSharp/Things/Subreddit.cs

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class Subreddit : Thing
1515
private const string SubredditPostUrl = "/r/{0}.json";
1616
private const string SubredditNewUrl = "/r/{0}/new.json?sort=new";
1717
private const string SubredditHotUrl = "/r/{0}/hot.json";
18-
private const string SubredditRisingUrl = "/r/{0}/rising.json";
18+
private const string SubredditRisingUrl = "/r/{0}/rising.json";
1919
private const string SubredditTopUrl = "/r/{0}/top.json?t={1}";
2020
private const string SubscribeUrl = "/api/subscribe";
2121
private const string GetSettingsUrl = "/r/{0}/about/edit.json";
@@ -40,6 +40,7 @@ public class Subreddit : Thing
4040
private const string CommentsUrl = "/r/{0}/comments.json";
4141
private const string SearchUrl = "/r/{0}/search.json?q={1}&restrict_sr=on&sort={2}&t={3}";
4242
private const string SearchUrlDate = "/r/{0}/search.json?q=timestamp:{1}..{2}&restrict_sr=on&sort={3}&syntax=cloudsearch";
43+
private const string ModLogUrl = "/r/{0}/about/log.json";
4344

4445
[JsonIgnore]
4546
private Reddit Reddit { get; set; }
@@ -157,17 +158,17 @@ public Listing<Post> Hot
157158
return new Listing<Post>(Reddit, "/.json", WebAgent);
158159
return new Listing<Post>(Reddit, string.Format(SubredditHotUrl, Name), WebAgent);
159160
}
160-
}
161-
public Listing<Post> Rising
162-
{
163-
get
164-
{
165-
if (Name == "/")
166-
return new Listing<Post>(Reddit, "/.json", WebAgent);
167-
return new Listing<Post>(Reddit, string.Format(SubredditRisingUrl, Name), WebAgent);
168-
}
169-
}
170-
161+
}
162+
public Listing<Post> Rising
163+
{
164+
get
165+
{
166+
if (Name == "/")
167+
return new Listing<Post>(Reddit, "/.json", WebAgent);
168+
return new Listing<Post>(Reddit, string.Format(SubredditRisingUrl, Name), WebAgent);
169+
}
170+
}
171+
171172
public Listing<VotableThing> ModQueue
172173
{
173174
get
@@ -191,8 +192,8 @@ public Listing<Post> Search(string terms)
191192

192193
public Listing<Post> Search(DateTime from, DateTime to, Sorting sortE = Sorting.New)
193194
{
194-
string sort = sortE.ToString().ToLower();
195-
195+
string sort = sortE.ToString().ToLower();
196+
196197
return new Listing<Post>(Reddit, string.Format(SearchUrlDate, Name, from.DateTimeToUnixTimestamp(), to.DateTimeToUnixTimestamp(), sort), WebAgent);
197198
}
198199

@@ -661,7 +662,39 @@ public Post SubmitTextPost(string title, string text, string captchaId = "", str
661662
Captcha = captchaAnswer
662663
});
663664
}
664-
665+
/// <summary>
666+
/// Gets the moderation log of the current subreddit
667+
/// </summary>
668+
public Listing<ModAction> GetModerationLog()
669+
{
670+
return new Listing<ModAction>(Reddit, string.Format(ModLogUrl, this.Name), WebAgent);
671+
}
672+
/// <summary>
673+
/// Gets the moderation log of the current subreddit filtered by the action taken
674+
/// </summary>
675+
/// <param name="action">ModActionType of action performed</param>
676+
public Listing<ModAction> GetModerationLog(ModActionType action)
677+
{
678+
return new Listing<ModAction>(Reddit, string.Format(ModLogUrl + "?type={1}", Name, ModActionTypeConverter.GetRedditParamName(action)), WebAgent);
679+
}
680+
/// <summary>
681+
/// Gets the moderation log of the current subreddit filtered by moderator(s) who performed the action
682+
/// </summary>
683+
/// <param name="mods">String array of mods to filter by</param>
684+
public Listing<ModAction> GetModerationLog(string[] mods)
685+
{
686+
return new Listing<ModAction>(Reddit, string.Format(ModLogUrl + "?mod={1}", Name, string.Join(",", mods)), WebAgent);
687+
}
688+
/// <summary>
689+
/// Gets the moderation log of the current subreddit filtered by the action taken and moderator(s) who performed the action
690+
/// </summary>
691+
/// <param name="action">ModActionType of action performed</param>
692+
/// <param name="mods">String array of mods to filter by</param>
693+
/// <returns></returns>
694+
public Listing<ModAction> GetModerationLog(ModActionType action, string[] mods)
695+
{
696+
return new Listing<ModAction>(Reddit, string.Format(ModLogUrl + "?type={1}&mod={2}", Name, ModActionTypeConverter.GetRedditParamName(action), string.Join(",", mods)), WebAgent);
697+
}
665698
#region Obsolete Getter Methods
666699

667700
[Obsolete("Use Posts property instead")]

RedditSharp/Things/Thing.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public static Thing Parse(Reddit reddit, JToken json, IWebAgent webAgent)
2121
return new PrivateMessage().Init(reddit, json, webAgent);
2222
case "t5":
2323
return new Subreddit().Init(reddit, json, webAgent);
24+
case "modaction":
25+
return new ModAction().Init(reddit, json, webAgent);
2426
default:
2527
return null;
2628
}
@@ -36,6 +38,10 @@ public static Thing Parse<T>(Reddit reddit, JToken json, IWebAgent webAgent) whe
3638
{
3739
return new WikiPageRevision().Init(reddit, json, webAgent);
3840
}
41+
else if (typeof(T) == typeof(ModAction))
42+
{
43+
return new ModAction().Init(reddit, json, webAgent);
44+
}
3945
}
4046
return result;
4147
}
@@ -82,15 +88,17 @@ public static async Task<Thing> ParseAsync(Reddit reddit, JToken json, IWebAgent
8288
switch (kind)
8389
{
8490
case "t1":
85-
return await new Comment().InitAsync(reddit, json, webAgent, null);
91+
return await new Comment().InitAsync(reddit, json, webAgent, null);
8692
case "t2":
87-
return await new RedditUser().InitAsync(reddit, json, webAgent);
93+
return await new RedditUser().InitAsync(reddit, json, webAgent);
8894
case "t3":
89-
return await new Post().InitAsync(reddit, json, webAgent);
95+
return await new Post().InitAsync(reddit, json, webAgent);
9096
case "t4":
91-
return await new PrivateMessage().InitAsync(reddit, json, webAgent);
97+
return await new PrivateMessage().InitAsync(reddit, json, webAgent);
9298
case "t5":
9399
return await new Subreddit().InitAsync(reddit, json, webAgent);
100+
case "modaction":
101+
return await new ModAction().InitAsync(reddit, json, webAgent);
94102
default:
95103
return null;
96104
}
@@ -106,6 +114,10 @@ public static async Task<Thing> ParseAsync<T>(Reddit reddit, JToken json, IWebAg
106114
{
107115
return await new WikiPageRevision().InitAsync(reddit, json, webAgent);
108116
}
117+
else if (typeof(T) == typeof(ModAction))
118+
{
119+
return await new ModAction().InitAsync(reddit, json, webAgent);
120+
}
109121
}
110122
return result;
111123
}

0 commit comments

Comments
 (0)