Skip to content

Commit

Permalink
Added member votes endpoint.
Browse files Browse the repository at this point in the history
  • Loading branch information
babelshift committed Feb 16, 2017
1 parent 26771f2 commit 4c06a41
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 3 deletions.
18 changes: 18 additions & 0 deletions ProPublicaCongressAPI/AutoMapperConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,24 @@ public static void Initialize()
x.CreateMap<InternalModels.NewMembersContainer, Contracts.NewMembersContainer>();
x.CreateMap<InternalModels.CurrentMember, Contracts.CurrentMember>();
x.CreateMap<InternalModels.MemberVoteBill, Contracts.MemberVoteBill>();
x.CreateMap<InternalModels.MemberVote, Contracts.MemberVote>()
.ForMember(dest => dest.DateTimeVoted, opts => opts.ResolveUsing(source =>
{
string rawDateTimeVoted = source.DateVoted;
if(!String.IsNullOrWhiteSpace(source.TimeVoted))
{
rawDateTimeVoted += " " + source.TimeVoted;
}
DateTime dateTimeVoted;
DateTime.TryParse(rawDateTimeVoted, out dateTimeVoted);
return dateTimeVoted;
}));
x.CreateMap<InternalModels.MemberVotesContainer, Contracts.MemberVotesContainer>();
});

}
Expand Down
27 changes: 27 additions & 0 deletions ProPublicaCongressAPI/Contracts/MemberVote.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;

namespace ProPublicaCongressAPI.Contracts
{
public class MemberVote
{
public string MemberId { get; set; }

public string Chamber { get; set; }

public int Congress { get; set; }

public int Session { get; set; }

public int RollCall { get; set; }

public MemberVoteBill Bill { get; set; }

public string Description { get; set; }

public string Question { get; set; }

public DateTime DateTimeVoted { get; set; }

public string Position { get; set; }
}
}
13 changes: 13 additions & 0 deletions ProPublicaCongressAPI/Contracts/MemberVoteBill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace ProPublicaCongressAPI.Contracts
{
public class MemberVoteBill
{
public string Number { get; set; }

public string BillUrl { get; set; }

public string Title { get; set; }

public string LatestAction { get; set; }
}
}
15 changes: 15 additions & 0 deletions ProPublicaCongressAPI/Contracts/MemberVotesContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;

namespace ProPublicaCongressAPI.Contracts
{
public class MemberVotesContainer
{
public string MemberId { get; set; }

public int TotalVotes { get; set; }

public int Offset { get; set; }

public IReadOnlyCollection<MemberVote> Votes { get; set; }
}
}
40 changes: 40 additions & 0 deletions ProPublicaCongressAPI/InternalModels/MemberVote.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Newtonsoft.Json;

namespace ProPublicaCongressAPI.InternalModels
{
internal class MemberVote
{
[JsonProperty("member_id")]
public string MemberId { get; set; }

[JsonProperty("chamber")]
public string Chamber { get; set; }

[JsonProperty("congress")]
public int Congress { get; set; }

[JsonProperty("session")]
public int Session { get; set; }

[JsonProperty("roll_call")]
public int RollCall { get; set; }

[JsonProperty("bill")]
public MemberVoteBill Bill { get; set; }

[JsonProperty("description")]
public string Description { get; set; }

[JsonProperty("question")]
public string Question { get; set; }

[JsonProperty("date")]
public string DateVoted { get; set; }

[JsonProperty("time")]
public string TimeVoted { get; set; }

[JsonProperty("position")]
public string Position { get; set; }
}
}
19 changes: 19 additions & 0 deletions ProPublicaCongressAPI/InternalModels/MemberVoteBill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Newtonsoft.Json;

namespace ProPublicaCongressAPI.InternalModels
{
internal class MemberVoteBill
{
[JsonProperty("number")]
public string Number { get; set; }

[JsonProperty("bill_uri")]
public string BillUrl { get; set; }

[JsonProperty("title")]
public string Title { get; set; }

[JsonProperty("latest_action")]
public string LatestAction { get; set; }
}
}
20 changes: 20 additions & 0 deletions ProPublicaCongressAPI/InternalModels/MemberVotesContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Newtonsoft.Json;
using System.Collections.Generic;

namespace ProPublicaCongressAPI.InternalModels
{
internal class MemberVotesContainer
{
[JsonProperty("member_id")]
public string MemberId { get; set; }

[JsonProperty("total_votes")]
public int TotalVotes { get; set; }

[JsonProperty("offset")]
public int Offset { get; set; }

[JsonProperty("votes")]
public IReadOnlyCollection<MemberVote> Votes { get; set; }
}
}
6 changes: 6 additions & 0 deletions ProPublicaCongressAPI/ProPublicaCongressAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,15 @@
<Compile Include="AutoMapperConfiguration.cs" />
<Compile Include="Contracts\Chamber.cs" />
<Compile Include="Contracts\CurrentMember.cs" />
<Compile Include="Contracts\MemberVote.cs" />
<Compile Include="Contracts\MemberVoteBill.cs" />
<Compile Include="Contracts\MemberVotesContainer.cs" />
<Compile Include="Contracts\NewMember.cs" />
<Compile Include="Contracts\NewMembersContainer.cs" />
<Compile Include="InternalModels\CurrentMember.cs" />
<Compile Include="InternalModels\MemberVote.cs" />
<Compile Include="InternalModels\MemberVoteBill.cs" />
<Compile Include="InternalModels\MemberVotesContainer.cs" />
<Compile Include="InternalModels\NewMember.cs" />
<Compile Include="InternalModels\NewMembersContainer.cs" />
<Compile Include="ProPublicaCongressApiClient.cs" />
Expand Down
49 changes: 46 additions & 3 deletions ProPublicaCongressAPI/ProPublicaCongressApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using ProPublicaCongressAPI.Contracts;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text;
Expand Down Expand Up @@ -44,8 +45,39 @@ public ProPublicaCongressApiClient(string apiKey)
AutoMapperConfiguration.Initialize();
}

public async Task<IReadOnlyCollection<Contracts.CurrentMember>> GetCurrentMembers(Chamber chamber, string state, int? district = null)
public async Task<Contracts.MemberVotesContainer> GetMemberVotesAsync(string memberId)
{
if (String.IsNullOrWhiteSpace(memberId))
{
throw new ArgumentNullException("memberId", "Member ID is required.");
}

string url = apiBaseUrl + String.Format(memberVotesUrl, memberId);

var result = await GetDataAsync<InternalModels.MemberVotesContainer>(url);

if (result == null || result.Results == null || result.Results.Count == 0)
{
return null;
}

var contract = AutoMapperConfiguration.Mapper.Map<InternalModels.MemberVotesContainer, Contracts.MemberVotesContainer>(result.Results.ElementAt(0));

return contract;
}

public async Task<IReadOnlyCollection<Contracts.CurrentMember>> GetCurrentMembersAsync(Chamber chamber, string state, int? district = null)
{
if(chamber == Chamber.Unknown)
{
throw new ArgumentException("Chamber must be 'House' or 'Senate'.");
}

if(String.IsNullOrWhiteSpace(state))
{
throw new ArgumentNullException("state", "State is required.");
}

string url = apiBaseUrl;

if(district.HasValue)
Expand All @@ -71,7 +103,7 @@ public ProPublicaCongressApiClient(string apiKey)
return contract;
}

public async Task<Contracts.NewMembersContainer> GetNewMembers()
public async Task<Contracts.NewMembersContainer> GetNewMembersAsync()
{
string url = apiBaseUrl + newMembersUrl;

Expand All @@ -93,8 +125,13 @@ public ProPublicaCongressApiClient(string apiKey)
/// <param name="congress">Number of Congress to query (ie. 2017 is the 115th Congress).</param>
/// <param name="chamber">Chamber of Congress such as "house" or "senate".</param>
/// <returns></returns>
public async Task<Contracts.MembersContainer> GetMembersAsync(int congress, string chamber)
public async Task<Contracts.MembersContainer> GetMembersAsync(int congress, Chamber chamber)
{
if (chamber == Chamber.Unknown)
{
throw new ArgumentException("Chamber must be 'House' or 'Senate'.");
}

string url = apiBaseUrl + String.Format(membersUrl, congress, chamber.ToString().ToLower());

var result = await GetDataAsync<InternalModels.MembersContainer>(url);
Expand All @@ -116,6 +153,11 @@ public ProPublicaCongressApiClient(string apiKey)
/// <returns>A specific Member of Congress.</returns>
public async Task<Contracts.Member> GetMemberAsync(string memberId)
{
if(String.IsNullOrWhiteSpace(memberId))
{
throw new ArgumentNullException("memberId", "Member ID is required.");
}

string url = apiBaseUrl + String.Format(specificMemberUrl, memberId);

var result = await GetDataAsync<InternalModels.Member>(url);
Expand All @@ -138,6 +180,7 @@ public ProPublicaCongressApiClient(string apiKey)
/// <returns></returns>
private async Task<ApiResponse<T>> GetDataAsync<T>(string url)
{
Debug.Assert(!String.IsNullOrWhiteSpace(url));
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("X-API-Key", apiKey);
var membersJson = await httpClient.GetStringAsync(url);
Expand Down

0 comments on commit 4c06a41

Please sign in to comment.