28 Commits

Author SHA1 Message Date
swcs c2b6eab709 update version 2013-09-30 23:30:16 +02:00
swcs f19fdd227b fix RetrieveFilter.All; improve search speed 2013-09-30 23:24:18 +02:00
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
swcs 208b157465 update website 2013-09-21 21:11:52 +02:00
swcs 54a82ea215 remove retrieve file 2013-09-21 21:06:38 +02:00
swcs 5136fe0ac4 update Microsoft.Net.HTTP package; update version and docs 2013-09-21 21:06:18 +02:00
swcs 74063723df ability to retrieve all tags 2013-09-21 20:48:50 +02:00
swcs cb6fc4e113 rename Retrieve => Get; add overload for Get for filters 2013-09-21 20:20:50 +02:00
swcs f8eaf47f80 update method documentation 2013-09-21 00:06:56 +02:00
swcs a8cc4c14de invalid retrieval Tests 2013-09-20 23:20:44 +02:00
swcs d7e324129c update version 2013-09-19 18:24:56 +02:00
swcs 1912563cc3 RemoveTag method; fix tag conversion; add modify tests 2013-09-19 18:08:41 +02:00
swcs 64c74b11d7 add item retrieval by ID 2013-09-19 12:13:07 +02:00
swcs e9699caf4e remove actionresults from response due to inconsistent behaviour 2013-09-19 11:47:57 +02:00
swcs 76af7fec0e add modification tests 2013-09-19 11:47:23 +02:00
swcs 4e40aaa0dc update readme 2013-09-18 21:19:38 +02:00
swcs 242428f94c bump version 2013-09-18 21:17:56 +02:00
swcs d009afd033 correct serialization of DateTime and Boolean values 2013-09-18 21:14:07 +02:00
swcs de1e4efc70 update retrieve tests 2013-09-18 21:01:51 +02:00
swcs e198ecdd6b update docs 2013-09-17 23:28:28 +02:00
33 changed files with 1079 additions and 335 deletions
@@ -46,7 +46,7 @@ namespace PocketSharp.Silverlight
try
{
items = await client.Retrieve();
items = await client.Get();
items.ForEach(item =>
{
@@ -112,6 +112,7 @@
</Page>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\AppManifest.xml" />
</ItemGroup>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.5.19.0" newVersion="2.5.19.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.5.19.0" newVersion="2.5.19.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -75,7 +75,7 @@ namespace PocketSharp.WP8.ViewModels
try
{
items = await client.Retrieve().ConfigureAwait(false);
items = await client.Get().ConfigureAwait(false);
items.ForEach(item =>
{
@@ -42,7 +42,7 @@ namespace PocketSharp.Wpf
try
{
items = await client.Retrieve();
items = await client.Get();
items.ForEach(item =>
{
+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");
});
}
}
}
+1 -1
View File
@@ -34,7 +34,7 @@ namespace PocketSharp.Tests
tweetID: "380051788172632065"
);
List<PocketItem> items = await client.Retrieve();
List<PocketItem> items = await client.Get();
PocketItem itemDesired = null;
items.ForEach(itm =>
-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() { }
}
}
+155
View File
@@ -0,0 +1,155 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests
{
public class GetTests : TestsBase
{
public GetTests() : base() { }
[Fact]
public async Task AreItemsRetrieved()
{
List<PocketItem> items = await client.Get();
Assert.True(items.Count > 0);
}
[Fact]
public async Task IsItemRetrievedById()
{
List<PocketItem> items = await client.Get();
PocketItem item = items[0];
PocketItem itemDuplicate = await client.Get(item.ID);
Assert.True(item.ID == itemDuplicate.ID);
Assert.True(item.Uri == itemDuplicate.Uri);
}
[Fact]
public async Task AreFilteredItemsRetrieved()
{
List<PocketItem> items = await client.Get(RetrieveFilter.Favorite);
Assert.True(items.Count > 0);
}
[Fact]
public async Task RetrieveWithMultipleFilters()
{
List<PocketItem> items = await client.Get(
state: State.unread,
tag: "pocket",
sort: Sort.title,
since: new DateTime(2010, 12, 10),
count: 2
);
Assert.InRange<int>(items.Count, 0, 2);
}
[Fact]
public async Task ItemContainsUri()
{
List<PocketItem> items = await client.Get(count: 1);
Assert.True(items.Count == 1);
Assert.True(items[0].Uri.ToString().StartsWith("http"));
}
[Fact]
public async Task InvalidRetrievalReturnsNoResults()
{
List<PocketItem> items = await client.Get(
favorite: true,
search: "xoiu987a#;"
);
Assert.False(items.Count > 0);
PocketItem item = await client.Get(99999999);
Assert.Null(item);
items = await client.Get(RetrieveFilter.Video);
Assert.False(items.Count > 0);
}
[Fact]
public async Task SearchReturnsResult()
{
List<PocketItem> items = await client.Search("pocket");
Assert.True(items.Count > 0);
Assert.True(items[0].FullTitle.ToLower().Contains("pocket"));
}
[Fact]
public async Task InvalidSearchReturnsNoResult()
{
List<PocketItem> items = await client.Search("adsüasd-opiu2;.398dfyx");
Assert.False(items.Count > 0);
}
[Fact]
public async Task RetrieveTagsReturnsResult()
{
List<PocketTag> items = await client.GetTags();
Assert.True(items.Count > 0);
}
[Fact]
public async Task SearchByTagsReturnsResult()
{
List<PocketItem> items = await client.SearchByTag("pocket");
Assert.True(items.Count == 1);
bool found = false;
items[0].Tags.ForEach(tag =>
{
if (tag.Name.Contains("pocket"))
{
found = true;
}
});
Assert.True(found);
}
[Fact]
public async Task InvalidSearchByTagsReturnsNoResult()
{
List<PocketItem> items = await client.SearchByTag("adsüasd-opiu2;.398dfyx");
Assert.False(items.Count > 0);
}
[Fact]
public async Task AreStatisticsRetrieved()
{
PocketStatistics statistics = await client.Statistics();
Assert.True(statistics.CountAll > 0);
}
}
}
+90 -1
View File
@@ -3,11 +3,100 @@ using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
using System.Linq;
namespace PocketSharp.Tests
{
class ModifyTagsTests : TestsBase
public class ModifyTagsTests : TestsBase
{
public ModifyTagsTests() : base() { }
[Fact]
public async Task AreTagsAddedAndDeletedToAnItem()
{
PocketItem item = await Setup();
Assert.True(await client.AddTags(item, new string[] { "test_tag", "test_tag2" }));
item = await GetItemById(item.ID);
Assert.True(item.Tags.Count >= 2);
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "test_tag"));
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "test_tag2"));
Assert.True(await client.RemoveTags(item, new string[] { "test_tag", "test_tag2" }));
item = await GetItemById(item.ID);
Assert.Null(item.Tags.SingleOrDefault<PocketTag>(tag => tag.Name == "test_tag"));
Assert.Null(item.Tags.SingleOrDefault<PocketTag>(tag => tag.Name == "test_tag2"));
}
[Fact]
public async Task AreAllTagsRemovedFromItem()
{
PocketItem item = await Setup();
Assert.True(await client.AddTags(item, new string[] { "test_tag", "test_tag2" }));
item = await GetItemById(item.ID);
Assert.True(item.Tags.Count >= 2);
Assert.True(await client.RemoveTags(item));
item = await GetItemById(item.ID);
Assert.Null(item.Tags);
}
[Fact]
public async Task AreTagsReplaced()
{
PocketItem item = await Setup();
Assert.True(await client.ReplaceTags(item.ID, new string[] { "test_tag", "test_tag2" }));
item = await GetItemById(item.ID);
Assert.Equal(item.Tags.Count, 2);
Assert.NotNull(item.Tags.SingleOrDefault<PocketTag>(tag => tag.Name == "test_tag"));
Assert.NotNull(item.Tags.SingleOrDefault<PocketTag>(tag => tag.Name == "test_tag2"));
}
private async Task<PocketItem> Setup()
{
PocketItem item = await client.Add(
uri: new Uri("https://github.com"),
tags: new string[] { "github", "code", "social" }
);
itemsToDelete.Add(item.ID);
return await GetItemById(item.ID);
}
private async Task<PocketItem> GetItemById(int id, bool archive = false)
{
List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread);
PocketItem itemDesired = null;
items.ForEach(itm =>
{
if (itm.ID == id)
{
itemDesired = itm;
}
});
return itemDesired;
}
}
}
+82 -1
View File
@@ -6,8 +6,89 @@ using PocketSharp.Models;
namespace PocketSharp.Tests
{
class ModifyTests : TestsBase
public class ModifyTests : TestsBase
{
public ModifyTests() : base() { }
[Fact]
public async Task IsAnItemArchivedAndUnarchived()
{
PocketItem item = await Setup();
Assert.True(await client.Archive(item));
item = await GetItemById(item.ID, true);
Assert.True(item.IsArchive);
Assert.True(await client.Unarchive(item));
item = await GetItemById(item.ID);
Assert.False(item.IsArchive);
}
[Fact]
public async Task IsAnItemFavoritedAndUnfavorited()
{
PocketItem item = await Setup();
Assert.True(await client.Favorite(item));
item = await GetItemById(item.ID);
Assert.True(item.IsFavorite);
Assert.True(await client.Unfavorite(item));
item = await GetItemById(item.ID);
Assert.False(item.IsFavorite);
}
[Fact]
public async Task IsAnItemDeleted()
{
PocketItem item = await Setup();
Assert.True(await client.Delete(item));
item = await GetItemById(item.ID);
Assert.Null(item);
}
private async Task<PocketItem> Setup()
{
PocketItem item = await client.Add(
uri: new Uri("https://github.com"),
tags: new string[] { "github", "code", "social" }
);
itemsToDelete.Add(item.ID);
return await GetItemById(item.ID);
}
private async Task<PocketItem> GetItemById(int id, bool archive = false)
{
List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread);
PocketItem itemDesired = null;
items.ForEach(itm =>
{
if (itm.ID == id)
{
itemDesired = itm;
}
});
return itemDesired;
}
}
}
+2 -2
View File
@@ -67,10 +67,10 @@
</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" />
<Compile Include="GetTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestsBase.cs" />
</ItemGroup>
-63
View File
@@ -1,63 +0,0 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests
{
public class RetrieveTests : TestsBase
{
public RetrieveTests() : base() { }
[Fact]
public async Task AreItemsRetrieved()
{
List<PocketItem> items = await client.Retrieve();
Assert.True(items.Count > 0);
}
[Fact]
public async Task ItemContainsUri()
{
List<PocketItem> items = await client.Retrieve(count: 1);
Assert.True(items.Count == 1);
Assert.True(items[0].Uri.ToString().StartsWith("http"));
}
[Fact]
public async Task SearchReturnsResult()
{
List<PocketItem> items = await client.Search("pocket");
Assert.True(items.Count > 0);
Assert.True(items[0].FullTitle.ToLower().Contains("pocket"));
}
[Fact]
public async Task SearchByTagsReturnsResult()
{
List<PocketItem> items = await client.SearchByTag("pocket");
Assert.True(items.Count == 1);
bool found = false;
items[0].Tags.ForEach(tag =>
{
if (tag.Name.Contains("pocket"))
{
found = true;
}
});
Assert.True(found);
}
}
}
+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);
}
}
}
+67 -46
View File
@@ -16,7 +16,7 @@
<meta property="og:site_name" content="PocketSharp" />
<meta property="og:description" content="PocketSharp is a C#.NET class library that integrates the Pocket API" />
<meta property="og:image" content="http://frontendplay.com/Content/Images/frontendplay-200.png" />
<meta property="og:image" content="http://pocketsharp.frontendplay.com/Assets/Images/pocketsharp.png" />
<link rel="icon" type="image/png" href="/Assets/Images/pocketsharp.png" />
<link rel="image_src" href="/Assets/Images/pocketsharp.png" />
@@ -32,6 +32,9 @@
</h1>
<p class="app-description">
PocketSharp is a C#.NET class library, that integrates the Pocket API v3
<br><br>
Current version: <b>1.5.1</b><br>
<a href="https://www.nuget.org/packages/PocketSharp/">@ nuget</a>
</p>
<div class="app-nuget">
<code>Install-Package PocketSharp</code>
@@ -45,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>
@@ -122,12 +125,19 @@ using PocketSharp.Models;</code></pre>
<h2>Release History</h2>
<ul>
<li>2013-09-15 v1.0.0 convert to PCL &amp; implement async</li>
<li>2013-08-16 v0.3.2 tag modification fixed and full retrieval of items for Retrieve method</li>
<li>2013-07-07 v0.3.1 authentication fixes</li>
<li>2013-07-02 v0.3.0 update authentication process </li>
<li>2013-06-27 v0.2.0 add, modify item &amp; modify tags</li>
<li>2013-06-26 v0.1.0 authentication &amp; retrieve functionality</li>
<li><b>1.5.1</b> (2013-09-30) <code>RetrieveFilter.All</code> didn't work; improve search speed</li>
<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>
<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>
<li><b>1.2.0</b> (2013-09-17) simplified retrieve methods</li>
<li><b>1.1.0</b> (2013-09-17) fix modification requests</li>
<li><b>1.0.0</b> (2013-09-15) convert to PCL &amp; implement async</li>
<li><b>0.3.2</b> (2013-08-16) tag modification fixed and full retrieval of items for Retrieve method</li>
<li><b>0.3.1</b> (2013-07-07) authentication fixes</li>
<li><b>0.3.0</b> (2013-07-02) update authentication process </li>
<li><b>0.2.0</b> (2013-06-27) add, modify item &amp; modify tags</li>
<li><b>0.1.0</b> (2013-06-26) authentication &amp; retrieve functionality</li>
</ul>
<h2>Used Packages</h2>
<ul>
@@ -144,7 +154,7 @@ using PocketSharp.Models;</code></pre>
<div data-part="authentication">
<div data-part="account">
<h2>Authentication</h2>
@@ -180,48 +190,59 @@ 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>
<p>Get list of all items:</p>
<h2>Get</h2>
<pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Retrieve();
// equivalent to: await _client.Retrieve(RetrieveFilter.All)</code></pre>
<p>Find items by a tag:</p>
<pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.SearchByTag(&quot;tutorial&quot;);</code></pre>
<p>Find items by a search string:</p>
<pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Search(&quot;css&quot;);</code></pre>
<p>Find items by a filter:</p>
<pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Retrieve(RetrieveFilter.Favorite); // only favorites</code></pre>
<p>The RetrieveFilter Enum is specified as follows:</p>
<pre class="language-clike"><code>enum RetrieveFilter { All, Unread, Archive, Favorite, Article, Video, Image }</code></pre>
<h4>Custom Parameters</h4>
<p>You can create a completely custom parameter list for retrieval with the POCO <code>RetrieveParameters</code>:</p>
<pre class="language-clike"><code>
var parameters = new RetrieveParameters()
{
Count = 50,
Offset = 100,
Sort = SortEnum.oldest
...
};
List&lt;pocketitem&gt; items = await _client.Retrieve(parameters);
<p>Get list of all items:</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Get();
// equivalent to: await _client.Get(RetrieveFilter.All)</code></pre></p>
<p>Get a list with specific parameters (explanation in the <a href="http://getpocket.com/developer/docs/v3/retrieve">Pocket Docs</a>):</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Get(
State? state = null,
bool? favorite = null,
string tag = null,
ContentType? contentType = null,
Sort? sort = null,
string search = null,
string domain = null,
DateTime? since = null,
int? count = null,
int? offset = null
);</code></pre></p>
<p>It's best to use parameters as <em>named parameters</em>, to avoid typing <code>null</code> values:</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Get(count: 10, offset: 20, sort: Sort.oldest);</code></pre></p>
<p>Get item by ID:</p>
<p><pre class="language-clike"><code>PocketItem item = await _client.Get(1298198);</code></pre></p>
<p>Find items by a tag:</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.SearchByTag(&quot;tutorial&quot;);</code></pre></p>
<p>Find items by a search string.<br>PocketSharp uses an internal search, which is significantly faster than the Search API by Pocket.</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Search(&quot;css&quot;);</code></pre></p>
<p>Find items by a search string by already available items:</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Search(myPocketItemList, &quot;css&quot;);</code></pre></p>
<p>Get all tags:</p>
<p><pre class="language-clike"><code>List&lt;PocketTag&gt; items = await _client.GetTags();</code></pre></p>
<p>Get a filtered list:</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Get(RetrieveFilter.Favorite);
// 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">
+148
View File
@@ -0,0 +1,148 @@
using PocketSharp.Models;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace PocketSharp
{
/// <summary>
/// PocketClient
/// </summary>
public partial class PocketClient
{
/// <summary>
/// Retrieves the requestCode from Pocket, which is used to generate the Authentication URI to authenticate the user
/// </summary>
/// <returns></returns>
/// <exception cref="System.NullReferenceException">Authentication methods need a callbackUri on initialization of the PocketClient class</exception>
/// <exception cref="PocketException"></exception>
public async Task<string> GetRequestCode()
{
// check if request code is available
if (CallbackUri == null)
{
throw new NullReferenceException("Authentication methods need a callbackUri on initialization of the PocketClient class");
}
// do request
RequestCode response = await Request<RequestCode>("oauth/request", new Dictionary<string, string>()
{
{ "redirect_uri", CallbackUri }
}, false);
// save code to client
RequestCode = response.Code;
// generate redirection URI and return
return RequestCode;
}
/// <summary>
/// Generate Authentication URI from requestCode
/// </summary>
/// <param name="requestCode">The requestCode. If no requestCode is supplied, the property from the PocketClient intialization is used.</param>
/// <returns>A valid URI to redirect the user to.</returns>
/// <exception cref="System.NullReferenceException">Call GetRequestCode() first to receive a request_code</exception>
public Uri GenerateAuthenticationUri(string requestCode = null)
{
// check if request code is available
if(RequestCode == null && requestCode == null)
{
throw new NullReferenceException("Call GetRequestCode() first to receive a request_code");
}
// override property with given param if available
if(requestCode != null)
{
RequestCode = requestCode;
}
return new Uri(string.Format(authentificationUri, RequestCode, CallbackUri));
}
/// <summary>
/// Requests the access code after authentication
/// The access code has to permanently be stored within the users session, and should be added as a parameter for all future PocketClient initializations.
/// </summary>
/// <param name="requestCode">The requestCode. If no requestCode is supplied, the property from the PocketClient intialization is used.</param>
/// <returns>The permanent access code, which is used to authenticate the user with the application</returns>
/// <exception cref="System.NullReferenceException">Call GetRequestCode() first to receive a request_code</exception>
/// <exception cref="PocketException"></exception>
public async Task<string> GetAccessCode(string requestCode = null)
{
// check if request code is available
if(RequestCode == null && requestCode == null)
{
throw new NullReferenceException("Call GetRequestCode() first to receive a request_code");
}
// override property with given param if available
if(requestCode != null)
{
RequestCode = requestCode;
}
// do request
AccessCode response = await Request<AccessCode>("oauth/authorize", new Dictionary<string, string>()
{
{ "code", RequestCode }
}, false);
// save code to client
AccessCode = response.Code;
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;
}
}
}
+2 -12
View File
@@ -16,7 +16,8 @@ namespace PocketSharp
/// <param name="tags">A comma-separated list of tags to apply to the item</param>
/// <param name="title">This can be included for cases where an item does not have a title, which is typical for image or PDF URLs. If Pocket detects a title from the content of the page, this parameter will be ignored.</param>
/// <param name="tweetID">If you are adding Pocket support to a Twitter client, please send along a reference to the tweet status id. This allows Pocket to show the original tweet alongside the article.</param>
/// <returns></returns>
/// <returns>A simple representation of the saved item which doesn't contain all data (is only returned by calling the Retrieve method)</returns>
/// <exception cref="PocketException"></exception>
public async Task<PocketItem> Add(Uri uri, string[] tags = null, string title = null, string tweetID = null)
{
AddParameters parameters = new AddParameters()
@@ -31,16 +32,5 @@ namespace PocketSharp
return response.Item;
}
/// <summary>
/// Adds a new item to pocket
/// </summary>
/// <param name="uri">The URL of the item you want to save</param>
/// <returns></returns>
public async Task<PocketItem> Add(Uri uri)
{
return await Add(uri, null);
}
}
}
@@ -1,92 +0,0 @@
using PocketSharp.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace PocketSharp
{
/// <summary>
/// PocketClient
/// </summary>
public partial class PocketClient
{
/// <summary>
/// Retrieves the requestCode from Pocket.
/// </summary>
/// <returns></returns>
public async Task<string> GetRequestCode()
{
// check if request code is available
if (CallbackUri == null)
{
throw new PocketException("Authentication methods need a callbackUri on initialization of the PocketClient class");
}
// do request
RequestCode response = await Request<RequestCode>("oauth/request", new Dictionary<string, string>()
{
{ "redirect_uri", CallbackUri }
}, false);
// save code to client
RequestCode = response.Code;
// generate redirection URI and return
return RequestCode;
}
/// <summary>
/// Generate Authentication URI from requestCode
/// </summary>
/// <param name="requestCode">The requestCode.</param>
/// <returns></returns>
public Uri GenerateAuthenticationUri(string requestCode = null)
{
// check if request code is available
if(RequestCode == null && requestCode == null)
{
throw new PocketException("Call GetRequestCode() first to receive a request_code");
}
// override property with given param if available
if(requestCode != null)
{
RequestCode = requestCode;
}
return new Uri(string.Format(authentificationUri, RequestCode, CallbackUri));
}
/// <summary>
/// Requests the access code after authentification
/// </summary>
/// <returns></returns>
public async Task<string> GetAccessCode(string requestCode = null)
{
// check if request code is available
if(RequestCode == null && requestCode == null)
{
throw new PocketException("Call GetRequestCode() first to receive a request_code");
}
// override property with given param if available
if(requestCode != null)
{
RequestCode = requestCode;
}
// do request
AccessCode response = await Request<AccessCode>("oauth/authorize", new Dictionary<string, string>()
{
{ "code", RequestCode }
}, false);
// save code to client
AccessCode = response.Code;
return AccessCode;
}
}
}
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace PocketSharp
{
@@ -11,11 +12,13 @@ namespace PocketSharp
public partial class PocketClient
{
/// <summary>
/// Retrieves all items from pocket
/// Retrieves items from pocket
/// with the given filters
/// </summary>
/// <param name="parameters">parameters, which are mapped to the officials from http://getpocket.com/developer/docs/v3/retrieve </param>
/// <returns></returns>
public async Task<List<PocketItem>> Retrieve(
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> Get(
State? state = null,
bool? favorite = null,
string tag = null,
@@ -50,11 +53,29 @@ namespace PocketSharp
/// <summary>
/// Retrieves all items with a filter from pocket
/// Retrieves an item by a given ID
/// Note: The Pocket API contains no method, which allows to retrieve a single item, so all items are retrieved and filtered locally by the ID.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<PocketItem> Get(int itemID)
{
List<PocketItem> items = await Get(
state: State.all
);
return items.SingleOrDefault<PocketItem>(item => item.ID == itemID);
}
/// <summary>
/// Retrieves all items by a given filter
/// </summary>
/// <param name="filter">The filter.</param>
/// <returns></returns>
public async Task<List<PocketItem>> RetrieveByFilter(RetrieveFilter filter = RetrieveFilter.All)
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> Get(RetrieveFilter filter)
{
RetrieveParameters parameters = new RetrieveParameters();
@@ -78,6 +99,9 @@ namespace PocketSharp
case RetrieveFilter.Archive:
parameters.State = State.archive;
break;
case RetrieveFilter.All:
parameters.State = State.all;
break;
}
parameters.DetailType = DetailType.complete;
@@ -89,24 +113,71 @@ namespace PocketSharp
/// <summary>
/// Retrieves items by tag from pocket
/// Retrieves all available tags.
/// Note: The Pocket API contains no method, which allows to retrieve all tags, so all items are retrieved and the associated tags extracted.
/// </summary>
/// <param name="tag">The tag.</param>
/// <returns></returns>
public async Task<List<PocketItem>> SearchByTag(string tag)
/// <exception cref="PocketException"></exception>
public async Task<List<PocketTag>> GetTags()
{
return await Retrieve(tag: tag);
List<PocketItem> items = await Get(
state: State.all
);
return items.Where(item => item.Tags != null)
.SelectMany(item => item.Tags)
.GroupBy(item => item.Name)
.Select(item => item.First())
.ToList<PocketTag>();
}
/// <summary>
/// Retrieves items from pocket which match the specified search string in title or content
/// Retrieves items by tag
/// </summary>
/// <param name="tag">The tag.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> SearchByTag(string tag)
{
return await Get(tag: tag);
}
/// <summary>
/// Retrieves items which match the specified search string in title and URI
/// </summary>
/// <param name="searchString">The search string.</param>
/// <returns></returns>
public async Task<List<PocketItem>> Search(string searchString)
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> Search(string searchString, bool searchInUri = true)
{
return await Retrieve(search: searchString);
List<PocketItem> items = await Get(RetrieveFilter.All);
return Search(items, searchString);
}
/// <summary>
/// Finds the specified search string in title and URI for an available list of items
/// </summary>
/// <param name="availableItems">The available items.</param>
/// <param name="searchString">The search string.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
/// <exception cref="PocketException"></exception>
public List<PocketItem> Search(List<PocketItem> availableItems, string searchString)
{
if (searchString.Length < 2)
{
throw new ArgumentOutOfRangeException("Search string length has to be a minimum of 2 chars");
}
return availableItems.Where(item => (
(!String.IsNullOrEmpty(item.FullTitle) && item.FullTitle.ToLower().Contains(searchString))
|| item.Uri.ToString().ToLower().Contains(searchString)
)).ToList();
}
}
+9
View File
@@ -14,6 +14,7 @@ namespace PocketSharp
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Archive(int itemID)
{
return await SendDefault(itemID, "archive");
@@ -25,6 +26,7 @@ namespace PocketSharp
/// </summary>
/// <param name="item">The item.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Archive(PocketItem item)
{
return await Archive(item.ID);
@@ -36,6 +38,7 @@ namespace PocketSharp
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Unarchive(int itemID)
{
return await SendDefault(itemID, "readd");
@@ -47,6 +50,7 @@ namespace PocketSharp
/// </summary>
/// <param name="item">The item.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Unarchive(PocketItem item)
{
return await Unarchive(item.ID);
@@ -58,6 +62,7 @@ namespace PocketSharp
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Favorite(int itemID)
{
return await SendDefault(itemID, "favorite");
@@ -69,6 +74,7 @@ namespace PocketSharp
/// </summary>
/// <param name="item">The item.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Favorite(PocketItem item)
{
return await Favorite(item.ID);
@@ -80,6 +86,7 @@ namespace PocketSharp
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Unfavorite(int itemID)
{
return await SendDefault(itemID, "unfavorite");
@@ -91,6 +98,7 @@ namespace PocketSharp
/// </summary>
/// <param name="item">The item.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Unfavorite(PocketItem item)
{
return await Unfavorite(item.ID);
@@ -102,6 +110,7 @@ namespace PocketSharp
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> Delete(int itemID)
{
return await SendDefault(itemID, "delete");
+49 -11
View File
@@ -1,5 +1,7 @@
using PocketSharp.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace PocketSharp
{
@@ -9,11 +11,12 @@ namespace PocketSharp
public partial class PocketClient
{
/// <summary>
/// Adds the specified tags.
/// Adds the specified tags to an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="tags">The tags.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> AddTags(int itemID, string[] tags)
{
return await SendTags(itemID, "tags_add", tags);
@@ -21,11 +24,12 @@ namespace PocketSharp
/// <summary>
/// Adds the specified tags.
/// Adds the specified tags to an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="tags">The tags.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> AddTags(PocketItem item, string[] tags)
{
return await AddTags(item.ID, tags);
@@ -33,11 +37,12 @@ namespace PocketSharp
/// <summary>
/// Removes the specified tags.
/// Removes the specified tags from an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="tags">The tags.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTags(int itemID, string[] tags)
{
return await SendTags(itemID, "tags_remove", tags);
@@ -45,11 +50,12 @@ namespace PocketSharp
/// <summary>
/// Removes the specified tags.
/// Removes the specified tags from an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="tags">The tags.</param>
/// <param name="tags">The tag.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTags(PocketItem item, string[] tags)
{
return await RemoveTags(item.ID, tags);
@@ -57,10 +63,37 @@ namespace PocketSharp
/// <summary>
/// Clears all tags.
/// Removes a tag from an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="tags">The tag.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTag(int itemID, string tag)
{
return await SendTags(itemID, "tags_remove", new string[] { tag });
}
/// <summary>
/// Removes a tag from an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="tags">The tags.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTag(PocketItem item, string tag)
{
return await RemoveTag(item.ID, tag);
}
/// <summary>
/// Clears all tags from an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTags(int itemID)
{
return await SendDefault(itemID, "tags_clear");
@@ -68,10 +101,11 @@ namespace PocketSharp
/// <summary>
/// Clears all tags.
/// Clears all tags from an item.
/// </summary>
/// <param name="item">The item.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTags(PocketItem item)
{
return await RemoveTags(item.ID);
@@ -79,11 +113,12 @@ namespace PocketSharp
/// <summary>
/// Replaces all existing tags with new ones.
/// Replaces all existing tags with the given tags in an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="tags">The tags.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> ReplaceTags(int itemID, string[] tags)
{
return await SendTags(itemID, "tags_replace", tags);
@@ -91,11 +126,12 @@ namespace PocketSharp
/// <summary>
/// Replaces all existing tags with new ones.
/// Replaces all existing tags with the given new ones in an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="tags">The tags.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> ReplaceTags(PocketItem item, string[] tags)
{
return await ReplaceTags(item.ID, tags);
@@ -103,12 +139,13 @@ namespace PocketSharp
/// <summary>
/// Renames a tag.
/// Renames a tag in an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="oldTag">The old tag.</param>
/// <param name="newTag">The new tag name.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> RenameTag(int itemID, string oldTag, string newTag)
{
return await Send(new ActionParameter()
@@ -122,12 +159,13 @@ namespace PocketSharp
/// <summary>
/// Renames a tag.
/// Renames a tag in an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="oldTag">The old tag.</param>
/// <param name="newTag">The new tag name.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> RenameTag(PocketItem item, string oldTag, string newTag)
{
return await RenameTag(item.ID, oldTag, newTag);
+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");
}
}
}
@@ -1,4 +1,5 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
@@ -8,7 +9,7 @@ namespace PocketSharp.Models
/// All parameters which can be passed for a modify action
/// </summary>
[DataContract]
internal class ActionParameter : Parameters
internal class ActionParameter
{
/// <summary>
/// Gets or sets the action.
@@ -67,28 +68,28 @@ namespace PocketSharp.Models
public string NewTag { get; set; }
///// <summary>
///// Converts this instance to a parameter list.
///// </summary>
///// <returns></returns>
//public Dictionary<string, object> Convert()
//{
// Dictionary<string, object> parameters = new Dictionary<string, object>
// {
// { "item_id", ID },
// { "action", Action }
// };
/// <summary>
/// Converts this instance to a parameter list.
/// </summary>
/// <returns></returns>
public Dictionary<string, object> Convert()
{
Dictionary<string, object> parameters = new Dictionary<string, object>
{
{ "item_id", ID.ToString() },
{ "action", Action }
};
// if (Time != null)
// parameters.Add("time", Utilities.GetUnixTimestamp(Time));
// if (Tags != null)
// parameters.Add("tags", Tags);
// if (OldTag != null)
// parameters.Add("old_tag", OldTag);
// if (NewTag != null)
// parameters.Add("new_tag", NewTag);
if (Time != null)
parameters.Add("time", Time != null ? Utilities.GetUnixTimestamp(Time).ToString() : null);
if (Tags != null)
parameters.Add("tags", Tags);
if (OldTag != null)
parameters.Add("old_tag", OldTag);
if (NewTag != null)
parameters.Add("new_tag", NewTag);
// return parameters;
//}
return parameters;
}
}
}
@@ -35,16 +35,30 @@ namespace PocketSharp.Models
string name = attribute.Name ?? propertyInfo.Name.ToLower();
object value = propertyInfo.GetValue(this, null);
// invalid parameter
if (value == null)
{
continue;
}
// convert array to comma-seperated list
if (value is IEnumerable && value.GetType().GetElementType() == typeof(string))
{
value = string.Join(",", ((IEnumerable)value).Cast<object>().Select(x => x.ToString()).ToArray());
}
// convert booleans
if (value is bool)
{
value = System.Convert.ToBoolean(value) ? "1" : "0";
}
// convert DateTime to UNIX timestamp
if (value is DateTime)
{
value = (int)((DateTime)value - new DateTime(1970, 1, 1)).TotalSeconds;
}
parameterDict.Add(name, value.ToString());
}
@@ -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; }
}
}
+2 -2
View File
@@ -15,7 +15,7 @@ namespace PocketSharp.Models
/// <value>
/// The action results.
/// </value>
[JsonProperty("action_results")]
public bool[] ActionResults { get; set; }
//[JsonProperty("action_results")]
//public bool[] ActionResults { get; set; }
}
}
+6 -2
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);
@@ -144,7 +149,6 @@ namespace PocketSharp
Error = (object sender, ErrorEventArgs args) =>
{
throw new PocketException(String.Format("Parse error: {0}", args.ErrorContext.Error.Message));
args.ErrorContext.Handled = true;
},
Converters =
{
@@ -165,7 +169,7 @@ namespace PocketSharp
/// <returns></returns>
internal async Task<bool> Send(List<ActionParameter> actionParameters)
{
List<Dictionary<string, string>> actionParamList = new List<Dictionary<string, string>>();
List<Dictionary<string, object>> actionParamList = new List<Dictionary<string, object>>();
foreach (var action in actionParameters)
{
+8 -5
View File
@@ -39,12 +39,15 @@
<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\Retrieve.cs" />
<Compile Include="Components\Get.cs" />
<Compile Include="JsonExtensions.cs" />
<Compile Include="Models\Parameters\ActionParameter.cs" />
<Compile Include="Models\Parameters\AddParameters.cs" />
@@ -80,13 +83,13 @@
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\portable-net40+sl4+win8+wp71\System.IO.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http">
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\portable-net40+sl4+win8+wp71\System.Net.Http.dll</HintPath>
<HintPath>..\packages\Microsoft.Net.Http.2.2.15\lib\portable-net40+sl4+win8+wp71\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Extensions">
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Extensions.dll</HintPath>
<HintPath>..\packages\Microsoft.Net.Http.2.2.15\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Primitives">
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Primitives.dll</HintPath>
<HintPath>..\packages\Microsoft.Net.Http.2.2.15\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Runtime">
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\portable-net40+sl4+win8+wp71\System.Runtime.dll</HintPath>
+1 -1
View File
@@ -10,7 +10,7 @@
<projectUrl>http://pocketsharp.frontendplay.com</projectUrl>
<iconUrl>http://pocketsharp.frontendplay.com/Assets/Images/pocketsharp.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
<description>PocketSharp is a .NET class library, that integrates the Pocket API v3</description>
<language>en-US</language>
<releaseNotes>
<![CDATA[
+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.0.0")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyVersion("1.5.1")]
[assembly: AssemblyFileVersion("1.5.1")]
+1 -1
View File
@@ -3,6 +3,6 @@
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="portable-net45+sl40+wp71+win" />
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="portable-net45+sl40+wp71+win" />
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="portable-net45+sl40+wp71+win" />
<package id="Microsoft.Net.Http" version="2.2.13" targetFramework="portable-net45+sl40+wp71+win" />
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="portable-net403+sl40+wp71+win" />
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="portable-net403+sl40+wp71+win" />
</packages>
+134 -42
View File
@@ -1,8 +1,11 @@
![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/)
[pocketsharp.frontendplay.com](http://pocketsharp.frontendplay.com/)
## Install using NuGet
@@ -10,6 +13,15 @@
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:
@@ -19,7 +31,7 @@ PocketSharp is a **Portable Class Library** (since 1.0.0), therefore it's compat
- **Windows Phone** >= 7.5
- **Windows Store**
You can find examples for Silverlight 5, WP8 and WPF in the `PocketSharp.Examples` folder.
You can find examples for Silverlight 5, WP8 and WPF in the `PocketSharp.Examples` ([@github](https://github.com/ceee/PocketSharp/tree/master/PocketSharp.Examples)) folder.
## Async Support
@@ -27,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/)
@@ -95,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**.
@@ -136,13 +154,53 @@ 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:
```csharp
List<PocketItem> items = await _client.Retrieve();
// equivalent to: await _client.Retrieve(RetrieveFilter.All)
List<PocketItem> items = await _client.Get();
// equivalent to: await _client.Get(RetrieveFilter.All)
```
Get a list with specific parameters (explanation in the [Pocket Docs](http://getpocket.com/developer/docs/v3/retrieve)):
```csharp
List<PocketItem> items = await _client.Get(
State? state = null,
bool? favorite = null,
string tag = null,
ContentType? contentType = null,
Sort? sort = null,
string search = null,
string domain = null,
DateTime? since = null,
int? count = null,
int? offset = null
);
```
It's best to use parameters as _named parameters_, to avoid typing `null` values:
```csharp
List<PocketItem> items = await _client.Get(count: 10, offset: 20, sort: Sort.oldest);
```
Get item by ID:
```csharp
PocketItem item = await _client.Get(1298198);
```
Find items by a tag:
@@ -151,16 +209,30 @@ Find items by a tag:
List<PocketItem> items = await _client.SearchByTag("tutorial");
```
Find items by a search string:
Find items by a search string.
<br>PocketSharp uses an internal search, which is significantly faster than the Search API by Pocket.
```csharp
List<PocketItem> items = await _client.Search("css");
```
Find items by a filter:
Find items by a search string by already available items:
```csharp
List<PocketItem> items = await _client.Retrieve(RetrieveFilter.Favorite); // only favorites
List<PocketItem> items = await _client.Search(myPocketItemList, "css");
```
Get all tags:
```csharp
List<PocketTag> items = await _client.GetTags();
```
Get a filtered list:
```csharp
List<PocketItem> items = await _client.Get(RetrieveFilter.Favorite);
// returns favorites only
```
The RetrieveFilter Enum is specified as follows:
@@ -169,22 +241,6 @@ The RetrieveFilter Enum is specified as follows:
enum RetrieveFilter { All, Unread, Archive, Favorite, Article, Video, Image }
```
#### Custom Parameters
You can create a completely custom parameter list for retrieval with the POCO `RetrieveParameters`:
```csharp
var parameters = new RetrieveParameters()
{
Count = 50,
Offset = 100,
Sort = Sort.oldest
...
};
List<PocketItem> items = await _client.Retrieve(parameters);
```
## Add
Adds a new item to your pocket list.
@@ -213,56 +269,92 @@ 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
- 2013-09-15 v1.0.0 convert to PCL & implement async
- 2013-08-16 v0.3.2 tag modification fixed and full retrieval of items for Retrieve method
- 2013-07-07 v0.3.1 authentication fixes
- 2013-07-02 v0.3.0 update authentication process
- 2013-06-27 v0.2.0 add, modify item & modify tags
- 2013-06-26 v0.1.0 authentication & retrieve functionality
- **1.5.1** (2013-09-30) `RetrieveFilter.All` didn't work; improve search speed
- **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
- **1.2.0** (2013-09-17) simplified retrieve methods
- **1.1.0** (2013-09-17) fix modification requests
- **1.0.0** (2013-09-15) convert to PCL & implement async
- **0.3.2** (2013-08-16) tag modification fixed and full retrieval of items for Retrieve method
- **0.3.1** (2013-07-07) authentication fixes
- **0.3.0** (2013-07-02) update authentication process
- **0.2.0** (2013-06-27) add, modify item & modify tags
- **0.1.0** (2013-06-26) authentication & retrieve functionality
## Dependencies