9 Commits

Author SHA1 Message Date
swcs f231231f4e fix readme formatting issue 2013-09-29 23:28:06 +02:00
swcs a1a5076895 update website 2013-09-29 23:24:07 +02:00
swcs 11769d65fd update readme 2013-09-29 23:22:03 +02:00
swcs 2aa7e3de90 update assembly version 2013-09-28 19:22:24 +02:00
swcs 7564855597 update comments 2013-09-27 09:34:55 +02:00
swcs 3564bc8273 allow dashes in username 2013-09-27 01:08:13 +02:00
swcs 2154740550 add account registration 2013-09-27 01:03:02 +02:00
swcs 966a35e2c6 add statistics API 2013-09-27 00:12:02 +02:00
swcs 90199ebe1f add Whats Next section to readme 2013-09-22 18:26:12 +02:00
14 changed files with 341 additions and 37 deletions
+59
View File
@@ -0,0 +1,59 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests
{
public class AccountTests : TestsBase
{
public AccountTests() : base() { }
[Fact]
public async Task IsUserRegistered()
{
string randomId = ((int)((DateTime)DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds).ToString();
bool success = await client.RegisterAccount("pocket-" + randomId, String.Format("pocketsharp-{0}@outlook.com", randomId), "mypassword");
Assert.True(success);
}
[Fact]
public async Task AreInvalidRegistrationsBlocked()
{
await ThrowsAsync<FormatException>(async () =>
{
await client.RegisterAccount("abcdefghijklmnopqrstuvwxyz", "pocketsharp@outlook.com", "mypassword");
});
await ThrowsAsync<FormatException>(async () =>
{
await client.RegisterAccount("oiu_my:o;", "pocketsharp@outlook.com", "mypassword");
});
await ThrowsAsync<FormatException>(async () =>
{
await client.RegisterAccount("myusername", "pocketsharpoutlook.com", "mypassword");
});
await ThrowsAsync<FormatException>(async () =>
{
await client.RegisterAccount("myusername", "pocketsharp@outlook", "mypassword");
});
await ThrowsAsync<FormatException>(async () =>
{
await client.RegisterAccount("myusername", "pocketsharp@outlook,com", "mypassword");
});
await ThrowsAsync<ArgumentNullException>(async () =>
{
await client.RegisterAccount("myusername", null, "mypassword");
});
}
}
}
-13
View File
@@ -1,13 +0,0 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests
{
class AuthenticationTests : TestsBase
{
public AuthenticationTests() : base() { }
}
}
+1 -1
View File
@@ -67,7 +67,7 @@
</Choose>
<ItemGroup>
<Compile Include="AddTests.cs" />
<Compile Include="AuthenticationTests.cs" />
<Compile Include="AccountTests.cs" />
<Compile Include="ModifyTagsTests.cs" />
<Compile Include="ModifyTests.cs" />
<Compile Include="RetrieveTests.cs" />
+9
View File
@@ -142,5 +142,14 @@ namespace PocketSharp.Tests
Assert.False(items.Count > 0);
}
[Fact]
public async Task AreStatisticsRetrieved()
{
PocketStatistics statistics = await client.Statistics();
Assert.True(statistics.CountAll > 0);
}
}
}
+18 -1
View File
@@ -20,7 +20,7 @@ namespace PocketSharp.Tests
client = new PocketClient(
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
callbackUri: "http://frontendplay.com",
accessCode: "2c62cd50-b78a-5558-918b-65adae"
accessCode: "80acf6c5-c198-03c0-b94c-e74402"
);
}
@@ -33,5 +33,22 @@ namespace PocketSharp.Tests
await client.Delete(id);
});
}
// async throws
public static async Task ThrowsAsync<TException>(Func<Task> func)
{
var expected = typeof(TException);
Type actual = null;
try
{
await func();
}
catch (Exception e)
{
actual = e.GetType();
}
Assert.Equal(expected, actual);
}
}
}
+20 -6
View File
@@ -33,7 +33,7 @@
<p class="app-description">
PocketSharp is a C#.NET class library, that integrates the Pocket API v3
<br><br>
Current version: <b>1.4.0</b><br>
Current version: <b>1.5.0</b><br>
<a href="https://www.nuget.org/packages/PocketSharp/">@ nuget</a>
</p>
<div class="app-nuget">
@@ -48,8 +48,8 @@
<div class="app-main">
<nav class="app-nav">
<a href="#" data-id="gettingstarted" class="is-active">Getting Started</a>
<a href="#" data-id="authentication">Authentication</a>
<a href="#" data-id="retrieve">Retrieve</a>
<a href="#" data-id="account">Account</a>
<a href="#" data-id="get">Get</a>
<a href="#" data-id="add">Add</a>
<a href="#" data-id="modify">Modify</a>
</nav>
@@ -125,6 +125,7 @@ using PocketSharp.Models;</code></pre>
<h2>Release History</h2>
<ul>
<li><b>1.5.0</b> (2013-09-28) add statistics and registration API</li>
<li><b>1.4.0</b> (2013-09-21) rename <code>Retrieve</code> to <code>Get</code> + update IntelliSense documentation + add <code>GetTags</code> method
<li><b>1.3.0</b> (2013-09-19) get Item by ID + tag modification bugfixes</li>
<li><b>1.2.1</b> (2013-09-18) correct parameter conversion for DateTime and Boolean</li>
@@ -152,7 +153,7 @@ using PocketSharp.Models;</code></pre>
<div data-part="authentication">
<div data-part="account">
<h2>Authentication</h2>
@@ -188,12 +189,20 @@ Note that <code>GetAccessCode</code> can only be called with an existing <em>req
Without it you would always have to redo the authentication process.
</p>
<h2>Account Registration</h2>
<p>The <code>RegisterAccount</code> method exists in Pocket API v3, but is currently undocumented.
<br>The user cannot authenticate directly after registration, as the account has to be activated via an opt-in link, which is sent to the e-mail address.</p>
<pre class="language-clike"><code>bool isSuccess = await _client.RegisterAccount(&quot;myUsername&quot;, &quot;me@mymail.com&quot;, &quot;mypassword&quot;);
</code></pre>
<p>After registration you have to remind the user to check his/her mail account.</p>
</div>
<div data-part="retrieve">
<div data-part="get">
<h2>Retrieve</h2>
<h2>Get</h2>
<p>Get list of all items:</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Get();
@@ -226,6 +235,11 @@ Note that <code>GetAccessCode</code> can only be called with an existing <em>req
// returns favorites only</code></pre></p>
<p>The RetrieveFilter Enum is specified as follows:</p>
<p><pre class="language-clike"><code>enum RetrieveFilter { All, Unread, Archive, Favorite, Article, Video, Image }</code></pre></p>
<h2>Statistics</h2>
<p>The Pocket API supports retrieval of a simple statistics object.</p>
<pre class="language-clike"><code>PocketStatistics statistics = await client.Statistics();
// PocketStatistics: [CountAll], [CountRead], [CountUnread]
</code></pre>
</div>
<div data-part="add">
@@ -1,6 +1,7 @@
using PocketSharp.Models;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace PocketSharp
@@ -95,5 +96,53 @@ namespace PocketSharp
return AccessCode;
}
/// <summary>
/// Registers a new account.
/// Account has to be activated via a activation email sent by Pocket.
/// </summary>
/// <param name="username">The username.</param>
/// <param name="email">The email.</param>
/// <param name="password">The password.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">All parameters are required</exception>
/// <exception cref="System.FormatException">
/// Invalid email address.
/// or
/// Invalid username. Please only use letters, numbers, and/or dashes and between 1-20 characters.
/// </exception>
/// <exception cref="PocketException"></exception>
public async Task<bool> RegisterAccount(string username, string email, string password)
{
if (username == null || email == null || password == null)
{
throw new ArgumentNullException("All parameters are required");
}
Match matchEmail = Regex.Match(email, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,10}))$");
Match matchUsername = Regex.Match(username, @"^([\w\-_]{1,20})$");
if (!matchEmail.Success)
{
throw new FormatException("(1) Invalid email address.");
}
if (!matchUsername.Success)
{
throw new FormatException("(2) Invalid username. Please only use letters, numbers, and/or dashes and between 1-20 characters.");
}
RegisterParameters parameters = new RegisterParameters()
{
Username = username,
Email = email,
Password = password
};
ResponseBase response = await Request<ResponseBase>("signup", parameters.Convert(), false);
return response.Status;
}
}
}
+22
View File
@@ -0,0 +1,22 @@
using PocketSharp.Models;
using System;
using System.Threading.Tasks;
namespace PocketSharp
{
/// <summary>
/// PocketClient
/// </summary>
public partial class PocketClient
{
/// <summary>
/// Statistics from the user account.
/// </summary>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<PocketStatistics> Statistics()
{
return await Request<PocketStatistics>("stats");
}
}
}
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using System.Linq;
namespace PocketSharp.Models
{
/// <summary>
/// All parameters which can be passed to register a user
/// </summary>
[DataContract]
internal class RegisterParameters : Parameters
{
/// <summary>
/// Gets or sets the username.
/// </summary>
/// <value>
/// The username.
/// </value>
[DataMember(Name = "username")]
public string Username { get; set; }
/// <summary>
/// Gets or sets the E-Mail.
/// </summary>
/// <value>
/// The E-Mail.
/// </value>
[DataMember(Name = "email")]
public string Email { get; set; }
/// <summary>
/// Gets or sets the password.
/// </summary>
/// <value>
/// The password.
/// </value>
[DataMember(Name = "password")]
public string Password { get; set; }
}
}
+39
View File
@@ -0,0 +1,39 @@
using Newtonsoft.Json;
using System.Runtime.Serialization;
namespace PocketSharp.Models
{
/// <summary>
/// Statistics
/// </summary>
[JsonObject]
public class PocketStatistics
{
/// <summary>
/// Gets or sets all items.
/// </summary>
/// <value>
/// All items count.
/// </value>
[JsonProperty("count_list")]
public int CountAll { get; set; }
/// <summary>
/// Gets or sets all read items.
/// </summary>
/// <value>
/// Read items count.
/// </value>
[JsonProperty("count_read")]
public int CountRead { get; set; }
/// <summary>
/// Gets or sets all unread items.
/// </summary>
/// <value>
/// Unread items count.
/// </value>
[JsonProperty("count_unread")]
public int CountUnread { get; set; }
}
}
+5
View File
@@ -113,6 +113,11 @@ namespace PocketSharp
// every single Pocket API endpoint requires HTTP POST data
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, method);
if (parameters == null)
{
parameters = new Dictionary<string, string>();
}
// add consumer key to each request
parameters.Add("consumer_key", ConsumerKey);
+4 -1
View File
@@ -39,9 +39,12 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="Components\Statistics.cs" />
<Compile Include="Models\Parameters\RegisterParameters.cs" />
<Compile Include="Models\PocketStatistics.cs" />
<Compile Include="PocketException.cs" />
<Compile Include="Components\Add.cs" />
<Compile Include="Components\Authentification.cs" />
<Compile Include="Components\Account.cs" />
<Compile Include="Components\Modify.cs" />
<Compile Include="Components\ModifyTags.cs" />
<Compile Include="Components\Get.cs" />
+2 -2
View File
@@ -25,5 +25,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.4.0")]
[assembly: AssemblyFileVersion("1.4.0")]
[assembly: AssemblyVersion("1.5.0")]
[assembly: AssemblyFileVersion("1.5.0")]
+70 -13
View File
@@ -1,17 +1,27 @@
![PocketSharp](https://raw.github.com/ceee/PocketSharp/master/PocketSharp.Website/Assets/Images/github-header.png)
**PocketSharp** is a C#.NET class library, that integrates the [Pocket API v3](http://getpocket.com/developer) and consists of 4 parts: [Authentication](#authentication), [Retrieve](#retrieve), [Modify](#modify) and [Add](#add).
**PocketSharp** is a C#.NET class library, that integrates the [Pocket API v3](http://getpocket.com/developer).
**Website:** [pocketsharp.frontendplay.com](http://pocketsharp.frontendplay.com/)
<br>
**NuGet:** [nuget.org/packages/PocketSharp](https://www.nuget.org/packages/PocketSharp/)
## Install using NuGet
```
Install-Package PocketSharp
```
## Components
- [Get](#get) - Retrieve and search for items
- [Modify](#modify) - Modify items and its tags
- [Add](#add) - Add new items
- [Authentication](#account-authentication) - Authenticate users
- [Registration](#account-registration) - Register new users
- [Statistics](#statistics) - Retrieve account statistics
## Supported platforms
PocketSharp is a **Portable Class Library** (since 1.0.0), therefore it's compatible with multiple platforms:
@@ -29,6 +39,12 @@ All public methods, which communicate with the Pocket servers are asynchronous.
_In PocketSharp versions < 1.0.0 all methods lacked async support and were blocking._
## What's next?
In the next version I will implement the **Article View API**, but not the official by Pocket, because it is not available for everyone and doesn't satisfy my needs.
Maybe I will try to add behavior to PocketItems as a next step, for example: `myPocketItem.Archive();`
## Usage Example
Request a [Consumer Key on Pocket.](http://getpocket.com/developer/apps/)
@@ -97,7 +113,7 @@ _client.AccessCode = "[YOU_ACCESS_CODE]";
<br>
**After authentication** you will need to provide the `accessCode`.
## Authentication
## Account Authentication
In order to communicate with a Pocket User, you will need a consumer key (which is generated by [creating a new application on Pocket](http://getpocket.com/developer/apps/)) and an **Access Code**.
@@ -138,7 +154,18 @@ Note that `GetAccessCode` can only be called with an existing _request code_. If
<br>
Without it you would always have to redo the authentication process.
## Retrieve
## Account Registration
The `RegisterAccount` method exists in Pocket API v3, but is currently undocumented.
<br>The user cannot authenticate directly after registration, as the account has to be activated via an opt-in link, which is sent to the e-mail address.
```csharp
bool isSuccess = await _client.RegisterAccount("myUsername", "me@mymail.com", "mypassword");
```
After registration you have to remind the user to check his/her mail account.
## Get
Get list of all items:
@@ -235,50 +262,80 @@ All Modify methods accept either the itemID (as int) or a `PocketItem` as parame
Archive the specified item:
bool isSuccess = await _client.Archive(myPocketItem);
```csharp
bool isSuccess = await _client.Archive(myPocketItem);
```
Un-archive the specified item:
bool isSuccess = await _client.Unarchive(myPocketItem);
```csharp
bool isSuccess = await _client.Unarchive(myPocketItem);
```
Favorites the specified item:
bool isSuccess = await _client.Favorite(myPocketItem);
```csharp
bool isSuccess = await _client.Favorite(myPocketItem);
```
Un-favorites the specified item:
bool isSuccess = await _client.Unfavorite(myPocketItem);
```csharp
bool isSuccess = await _client.Unfavorite(myPocketItem);
```
Deletes the specified item:
bool isSuccess = await _client.Delete(myPocketItem);
```csharp
bool isSuccess = await _client.Delete(myPocketItem);
```
#### Modify tags
Add tags to the specified item:
bool isSuccess = await _client.AddTags(myPocketItem, new string[] { "css", "2013" });
```csharp
bool isSuccess = await _client.AddTags(myPocketItem, new string[] { "css", "2013" });
```
Remove tags from the specified item:
bool isSuccess = await _client.RemoveTags(myPocketItem, new string[] { "css", "2013" });
```csharp
bool isSuccess = await _client.RemoveTags(myPocketItem, new string[] { "css", "2013" });
```
Remove all tags from the specified item:
bool isSuccess = await _client.RemoveTags(myPocketItem);
```csharp
bool isSuccess = await _client.RemoveTags(myPocketItem);
```
Replaces all existing tags with new ones for the specified item:
bool isSuccess = await _client.ReplaceTags(myPocketItem, new string[] { "css", "2013" });
```csharp
bool isSuccess = await _client.ReplaceTags(myPocketItem, new string[] { "css", "2013" });
```
Renames a tag for the specified item:
bool isSuccess = await _client.RenameTag(myPocketItem, "oldTagName", "newTagName");
```csharp
bool isSuccess = await _client.RenameTag(myPocketItem, "oldTagName", "newTagName");
```
## Statistics
The Pocket API supports retrieval of a simple statistics object.
```csharp
PocketStatistics statistics = await client.Statistics();
// PocketStatistics: [CountAll], [CountRead], [CountUnread]
```
---
## Release History
- **1.5.0** (2013-09-28) add statistics and registration API
- **1.4.0** (2013-09-21) rename `Retrieve` to `Get` + update IntelliSense documentation + add `GetTags` method
- **1.3.0** (2013-09-19) get Item by ID + tag modification bugfixes
- **1.2.1** (2013-09-18) correct parameter conversion for DateTime and Boolean