25 Commits

Author SHA1 Message Date
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
swcs fb92cb19c8 update retrieve methods - work with named parameters 2013-09-17 23:08:15 +02:00
swcs 79184d194e fix tag parameter conversion; lead image generation; add complex item test; 2013-09-17 22:48:35 +02:00
swcs 9d0fb6484f fix modification requests 2013-09-17 21:43:31 +02:00
swcs e45414bd51 remove depr. classes 2013-09-16 23:34:26 +02:00
swcs e522c8e30a simplify parameter creation; fix several deserialization issues 2013-09-16 23:34:13 +02:00
swcs 6cf9892f78 disposable base for tests; classes for other tests 2013-09-15 21:52:28 +02:00
swcs d3c40c1a76 add tests for Retrieve methods 2013-09-15 21:44:09 +02:00
swcs c01098af04 update website and docs 2013-09-15 15:46:13 +02:00
40 changed files with 1073 additions and 453 deletions
BIN
View File
Binary file not shown.
+8 -5
View File
@@ -18,9 +18,9 @@
<ItemGroup Condition=" '$(PackageSources)' == '' ">
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
<!-- The official NuGet package source (https://nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
<!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
<!--
<PackageSource Include="https://nuget.org/api/v2/" />
<PackageSource Include="https://www.nuget.org/api/v2/" />
<PackageSource Include="https://my-nuget-source/nuget/" />
-->
</ItemGroup>
@@ -50,9 +50,12 @@
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
<NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
<!-- Commands -->
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir "$(SolutionDir) " </RestoreCommand>
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties Configuration=$(Configuration) $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
<!-- We need to ensure packages are restored prior to assembly resolve -->
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
@@ -118,7 +121,7 @@
Log.LogMessage("Downloading latest version of NuGet.exe...");
WebClient webClient = new WebClient();
webClient.DownloadFile("https://nuget.org/nuget.exe", OutputFilename);
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
return true;
}
@@ -35,8 +35,6 @@ namespace PocketSharp.Silverlight
private async void Button_Click(object sender, RoutedEventArgs e)
{
// User: pocketsharp-tests
// PW: pocketsharp
// !! please don't misuse this account !!
PocketClient client = new PocketClient(
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
@@ -48,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>
@@ -64,8 +64,6 @@ namespace PocketSharp.WP8.ViewModels
/// </summary>
public async Task LoadData()
{
// User: pocketsharp-tests
// PW: pocketsharp
// !! please don't misuse this account !!
PocketClient client = new PocketClient(
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
@@ -77,7 +75,7 @@ namespace PocketSharp.WP8.ViewModels
try
{
items = await client.Retrieve().ConfigureAwait(false);
items = await client.Get().ConfigureAwait(false);
items.ForEach(item =>
{
@@ -31,8 +31,6 @@ namespace PocketSharp.Wpf
private async void Button_Click(object sender, RoutedEventArgs e)
{
// User: pocketsharp-tests
// PW: pocketsharp
// !! please don't misuse this account !!
PocketClient client = new PocketClient(
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
@@ -44,7 +42,7 @@ namespace PocketSharp.Wpf
try
{
items = await client.Retrieve();
items = await client.Get();
items.ForEach(item =>
{
+55
View File
@@ -0,0 +1,55 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests
{
public class AddTests : TestsBase
{
public AddTests() : base() { }
[Fact]
public async Task AddSimpleItemWithUriOnly()
{
var uri = new Uri("http://frontendplay.com");
PocketItem item = await client.Add(uri);
Assert.Equal<Uri>(uri, item.Uri);
itemsToDelete.Add(item.ID);
}
[Fact]
public async Task AddComplexItem()
{
PocketItem item = await client.Add(
uri: new Uri("http://frontendplay.com"),
tags: new string[] { "blog", "frontend", "cee" },
title: "ignored title",
tweetID: "380051788172632065"
);
List<PocketItem> items = await client.Get();
PocketItem itemDesired = null;
items.ForEach(itm =>
{
if(itm.ID == item.ID)
{
itemDesired = itm;
}
});
Assert.NotNull(itemDesired);
Assert.Equal(itemDesired.ID, item.ID);
Assert.Equal(itemDesired.Tags.Count, 3);
itemsToDelete.Add(item.ID);
}
}
}
+13
View File
@@ -0,0 +1,13 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests
{
class AuthenticationTests : TestsBase
{
public AuthenticationTests() : base() { }
}
}
+102
View File
@@ -0,0 +1,102 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
using System.Linq;
namespace PocketSharp.Tests
{
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;
}
}
}
+94
View File
@@ -0,0 +1,94 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests
{
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;
}
}
}
+26 -41
View File
@@ -3,12 +3,12 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F1CEA363-7039-40BA-9744-0071F46BB90C}</ProjectGuid>
<ProjectGuid>{CA3C491B-A8CA-426C-A0BB-E91636767467}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PocketSharp.Tests</RootNamespace>
<AssemblyName>PocketSharp.Tests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
@@ -37,46 +37,24 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
<Reference Include="Microsoft.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net45\Microsoft.Threading.Tasks.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.16.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
<Reference Include="Microsoft.Threading.Tasks.Extensions">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net45\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.IO">
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\net40\System.IO.dll</HintPath>
</Reference>
<Reference Include="System.Net" />
<Reference Include="System.Net.Http, Version=2.2.13.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\net40\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Extensions">
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\net40\System.Net.Http.Extensions.dll</HintPath>
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\net45\System.Net.Http.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=2.2.13.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\net40\System.Net.Http.Primitives.dll</HintPath>
<Reference Include="System.Net.Http.Primitives">
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\net45\System.Net.Http.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest, Version=2.2.13.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\net40\System.Net.Http.WebRequest.dll</HintPath>
</Reference>
<Reference Include="System.Runtime">
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\net40\System.Runtime.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\net40\System.Threading.Tasks.dll</HintPath>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="xunit">
<HintPath>..\packages\xunit.1.9.2\lib\net20\xunit.dll</HintPath>
</Reference>
</ItemGroup>
<Choose>
@@ -85,15 +63,22 @@
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
</ItemGroup>
</Otherwise>
<Otherwise />
</Choose>
<ItemGroup>
<Compile Include="UnitTest1.cs" />
<Compile Include="AddTests.cs" />
<Compile Include="AuthenticationTests.cs" />
<Compile Include="ModifyTagsTests.cs" />
<Compile Include="ModifyTests.cs" />
<Compile Include="RetrieveTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestsBase.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PocketSharp\PocketSharp.csproj">
<Project>{817200c3-a327-4e35-9b5f-63a51c088577}</Project>
<Name>PocketSharp</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
+1 -1
View File
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("fbe5a0d2-d0de-44b1-8b8a-cf8cd3ac2230")]
[assembly: Guid("87fcf138-5e6e-4584-ac3b-58c8ee6fccaa")]
// Version information for an assembly consists of the following four values:
//
+146
View File
@@ -0,0 +1,146 @@
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.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);
}
}
}
+37
View File
@@ -0,0 +1,37 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests
{
public class TestsBase : IDisposable
{
protected PocketClient client;
protected List<int> itemsToDelete = new List<int>();
// setup
public TestsBase()
{
// !! please don't misuse this account !!
client = new PocketClient(
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
callbackUri: "http://frontendplay.com",
accessCode: "2c62cd50-b78a-5558-918b-65adae"
);
}
// teardown
public void Dispose()
{
itemsToDelete.ForEach(async id =>
{
await client.Delete(id);
});
}
}
}
-16
View File
@@ -1,16 +0,0 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;
namespace PocketSharp.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
}
}
}
+2 -6
View File
@@ -3,12 +3,8 @@
<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.6.3.0" newVersion="2.6.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.3.0" newVersion="2.6.3.0" />
<assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.13.0" newVersion="4.2.13.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
+5 -4
View File
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="net40" />
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="net40" />
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="net40" />
<package id="Microsoft.Net.Http" version="2.2.13" targetFramework="net40" />
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="net45" />
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.13" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" />
</packages>
+83 -64
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.4.0</b><br>
<a href="https://www.nuget.org/packages/PocketSharp/">@ nuget</a>
</p>
<div class="app-nuget">
<code>Install-Package PocketSharp</code>
@@ -53,6 +56,19 @@
<article class="article">
<div data-part="gettingstarted">
<h2>Supported platforms</h2>
<p>PocketSharp is a <strong>Portable Class Library</strong> (since 1.0.0), therefore it's compatible with multiple platforms:</p>
<ul>
<li><strong>.NET</strong> &gt;= 4.0.3 (including WPF)</li>
<li><strong>Silverlight</strong> &gt;= 4</li>
<li><strong>Windows Phone</strong> &gt;= 7.5</li>
<li><strong>Windows Store</strong></li>
</ul>
<p>You can find examples for Silverlight 5, WP8 and WPF in the <code>PocketSharp.Examples</code> folder.</p>
<h2>Async Support</h2>
<p>All public methods, which communicate with the Pocket servers are asynchronous. So they should be called with the preceding <code>await</code> keyword, and the encapsulated method marked with <code>async</code>.</p>
<p><em>In PocketSharp versions &lt; 1.0.0 all methods lacked async support and were blocking.</em></p>
<h2>Getting Started</h2>
<p>Request a <a href="http://getpocket.com/developer/apps/">Consumer Key on Pocket.</a></p>
<p>Include the PocketSharp namespace and it's associated models (you will need them later):</p>
@@ -66,8 +82,8 @@ using PocketSharp.Models;</code></pre>
<p>Do a simple request - e.g. a search for <code>CSS</code>:</p>
<pre class="language-clike"><code>_client.Search(&quot;css&quot;).ForEach(
item =&gt; Console.WriteLine(item.ID + &quot; | &quot; + item.Title)
<pre class="language-clike"><code>await _client.Search(&quot;css&quot;).ForEach(
item =&gt; Debug.WriteLine(item.ID + &quot; | &quot; + item.Title)
);</code></pre>
<p>Which will output:</p>
@@ -109,16 +125,23 @@ using PocketSharp.Models;</code></pre>
<h2>Release History</h2>
<ul>
<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.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>
<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>
<li><a href="http://restsharp.org/">RestSharp</a></li>
<li><a href="https://github.com/ServiceStack/ServiceStack.Text">ServiceStack.Text</a></li>
<li><a href="https://www.nuget.org/packages/Microsoft.Bcl.Async/">Microsoft.Bcl.Async</a></li>
<li><a href="https://www.nuget.org/packages/Microsoft.Net.Http/">Microsoft.Net.Http</a></li>
<li><a href="https://www.nuget.org/packages/Newtonsoft.Json/">Newtonsoft.Json</a></li>
</ul>
<h2>Contributors</h2>
<p>
@@ -138,7 +161,7 @@ using PocketSharp.Models;</code></pre>
<h4>1) Generate authentication URI</h4>
<p>Receive the <strong>request code</strong> and <strong>authentication URI</strong> from the library by calling <code>string GetRequestCode()</code>:</p>
<pre class="language-clike"><code>string requestCode = _client.GetRequestCode();
<pre class="language-clike"><code>string requestCode = await _client.GetRequestCode();
// 0f453f2d-1605-8584-28fd-39af8e
Uri authenticationUri = _client.GenerateAuthenticationUri();
// https://getpocket.com/auth/authorize?request_token=0f453f2d-1605-8584-28fd-39af8e&amp;redirect_uri=http%253a%252f%252fceecore.com</code></pre>
@@ -149,9 +172,9 @@ Uri authenticationUri = _client.GenerateAuthenticationUri();
<p>
<img src="https://raw.github.com/ceee/PocketSharp/master/PocketSharp/authentication-screen.png" alt="authentication screen" /></p>
<h4>3) Get Access Code</h4>
<p>Call <code>string GetAccessCode(string requestCode = null)</code></p>
<p>Call <code>Task&lt;string&gt; GetAccessCode(string requestCode = null)</code></p>
<pre class="language-clike"><code>string accessCode = _client.GetAccessCode();
<pre class="language-clike"><code>string accessCode = await _client.GetAccessCode();
// fa8bfc16-69b3-4d22-7db7-84a58d</code></pre>
<p>
@@ -164,49 +187,45 @@ Note that <code>GetAccessCode</code> can only be called with an existing <em>req
<br>
Without it you would always have to redo the authentication process.
</p>
</div>
<div data-part="retrieve">
<h2>Retrieve</h2>
<p>Get list of all items:</p>
<pre class="language-clike"><code>List&lt;PocketItem&gt; items = _client.Retrieve();
// equivalent to: _client.Retrieve(RetrieveFilter.All)</code></pre>
<p>Find items by a tag:</p>
<pre class="language-clike"><code>List&lt;PocketItem&gt; items = _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 = _client.Search(&quot;css&quot;);</code></pre>
<p>Find items by a filter:</p>
<pre class="language-clike"><code>List&lt;PocketItem&gt; items = _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 = _client.Retrieve(parameters);
</code></pre>
<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:</p>
<p><pre class="language-clike"><code>List&lt;PocketItem&gt; items = await _client.Search(&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>
</div>
<div data-part="add">
@@ -217,63 +236,63 @@ List&lt;pocketitem&gt; items = _client.Retrieve(parameters);
Accepts four parameters, with <code>uri</code> being required.
</p>
<pre class="language-clike"><code>PocketItem Add(Uri uri, string[] tags = null, string title = null, string tweetID = null)</code></pre>
<pre class="language-clike"><code>Task&lt;PocketItem&gt; Add(Uri uri, string[] tags = null, string title = null, string tweetID = null)</code></pre>
<p>Example:</p>
<pre class="language-clike"><code>PocketItem newItem = _client.Add(
<pre class="language-clike"><code>PocketItem newItem = await _client.Add(
new Uri(&quot;http:&frasl;&frasl;www.neowin.net/news/full-build-2013-conference-sessions-listing-revealed&quot;),
new string[] { &quot;microsoft&quot;, &quot;neowin&quot;, &quot;build&quot; }
);</code></pre>
<p>The title 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.</p>
<p>If you are adding Pocket support to a Twitter client, please send along a reference to the tweet status id (with the tweetID). This allows Pocket to show the original tweet alongside the article.</p>
</div>
<div data-part="modify">
<h2>Modify</h2>
<p>All Modify methods accept either the itemID (as int) or a <code>PocketItem</code> as parameter.</p>
<p>Archive the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.Archive(myPocketItem);
<pre class="language-clike"><code>bool isSuccess = await _client.Archive(myPocketItem);
</code></pre>
<p>Un-archive the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.Unarchive(myPocketItem);
<pre class="language-clike"><code>bool isSuccess = await _client.Unarchive(myPocketItem);
</code></pre>
<p>Favorites the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.Favorite(myPocketItem);
<pre class="language-clike"><code>bool isSuccess = await _client.Favorite(myPocketItem);
</code></pre>
<p>Un-favorites the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.Unfavorite(myPocketItem);
<pre class="language-clike"><code>bool isSuccess = await _client.Unfavorite(myPocketItem);
</code></pre>
<p>Deletes the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.Delete(myPocketItem);
<pre class="language-clike"><code>bool isSuccess = await _client.Delete(myPocketItem);
</code></pre>
<h4>Modify tags</h4>
<p>Add tags to the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.AddTags(myPocketItem, new string[] { &quot;css&quot;, &quot;2013&quot; });
<pre class="language-clike"><code>bool isSuccess = await _client.AddTags(myPocketItem, new string[] { &quot;css&quot;, &quot;2013&quot; });
</code></pre>
<p>Remove tags from the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.RemoveTags(myPocketItem, new string[] { &quot;css&quot;, &quot;2013&quot; });
<pre class="language-clike"><code>bool isSuccess = await _client.RemoveTags(myPocketItem, new string[] { &quot;css&quot;, &quot;2013&quot; });
</code></pre>
<p>Remove all tags from the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.RemoveTags(myPocketItem);
<pre class="language-clike"><code>bool isSuccess = await _client.RemoveTags(myPocketItem);
</code></pre>
<p>Replaces all existing tags with new ones for the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.ReplaceTags(myPocketItem, new string[] { &quot;css&quot;, &quot;2013&quot; });
<pre class="language-clike"><code>bool isSuccess = await _client.ReplaceTags(myPocketItem, new string[] { &quot;css&quot;, &quot;2013&quot; });
</code></pre>
<p>Renames a tag for the specified item:</p>
<pre class="language-clike"><code>bool isSuccess = _client.RenameTag(myPocketItem, &quot;oldTagName&quot;, &quot;newTagName&quot;);
<pre class="language-clike"><code>bool isSuccess = await _client.RenameTag(myPocketItem, &quot;oldTagName&quot;, &quot;newTagName&quot;);
</code></pre>
</div>
+17 -10
View File
@@ -1,7 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Tests", "PocketSharp.Tests\PocketSharp.Tests.csproj", "{F1CEA363-7039-40BA-9744-0071F46BB90C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp", "PocketSharp\PocketSharp.csproj", "{817200C3-A327-4E35-9B5F-63A51C088577}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Wpf", "PocketSharp.Examples\PocketSharp.Wpf\PocketSharp.Wpf.csproj", "{775569C2-987F-4AC4-8BA5-A315A21ED1B7}"
@@ -15,6 +13,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Silverlight", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.WP8", "PocketSharp.Examples\PocketSharp.WP8\PocketSharp.WP8.csproj", "{47721A56-2128-4C5A-8B92-995FFC353304}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Tests", "PocketSharp.Tests\PocketSharp.Tests.csproj", "{CA3C491B-A8CA-426C-A0BB-E91636767467}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{19DD45B5-B849-49E7-89D6-16C89B9B96C7}"
ProjectSection(SolutionItems) = preProject
.nuget\NuGet.Config = .nuget\NuGet.Config
.nuget\NuGet.exe = .nuget\NuGet.exe
.nuget\NuGet.targets = .nuget\NuGet.targets
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -25,14 +32,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F1CEA363-7039-40BA-9744-0071F46BB90C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F1CEA363-7039-40BA-9744-0071F46BB90C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F1CEA363-7039-40BA-9744-0071F46BB90C}.Debug|ARM.ActiveCfg = Debug|Any CPU
{F1CEA363-7039-40BA-9744-0071F46BB90C}.Debug|x86.ActiveCfg = Debug|Any CPU
{F1CEA363-7039-40BA-9744-0071F46BB90C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1CEA363-7039-40BA-9744-0071F46BB90C}.Release|Any CPU.Build.0 = Release|Any CPU
{F1CEA363-7039-40BA-9744-0071F46BB90C}.Release|ARM.ActiveCfg = Release|Any CPU
{F1CEA363-7039-40BA-9744-0071F46BB90C}.Release|x86.ActiveCfg = Release|Any CPU
{817200C3-A327-4E35-9B5F-63A51C088577}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{817200C3-A327-4E35-9B5F-63A51C088577}.Debug|Any CPU.Build.0 = Debug|Any CPU
{817200C3-A327-4E35-9B5F-63A51C088577}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -75,6 +74,14 @@ Global
{47721A56-2128-4C5A-8B92-995FFC353304}.Release|x86.ActiveCfg = Release|x86
{47721A56-2128-4C5A-8B92-995FFC353304}.Release|x86.Build.0 = Release|x86
{47721A56-2128-4C5A-8B92-995FFC353304}.Release|x86.Deploy.0 = Release|x86
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Debug|ARM.ActiveCfg = Debug|Any CPU
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Debug|x86.ActiveCfg = Debug|Any CPU
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Release|Any CPU.Build.0 = Release|Any CPU
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Release|ARM.ActiveCfg = Release|Any CPU
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+3 -13
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()
@@ -27,20 +28,9 @@ namespace PocketSharp
TweetID = tweetID
};
Add response = await Request<Add>("add", parameters.Convert(), true);
Add response = await Request<Add>("add", parameters.Convert());
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);
}
}
}
+24 -10
View File
@@ -1,5 +1,6 @@
using PocketSharp.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace PocketSharp
@@ -10,19 +11,24 @@ namespace PocketSharp
public partial class PocketClient
{
/// <summary>
/// Retrieves the requestCode from Pocket.
/// 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 PocketException("Authentication methods need a callbackUri on initialization of the PocketClient class");
throw new NullReferenceException("Authentication methods need a callbackUri on initialization of the PocketClient class");
}
// do request
RequestCode response = await Request<RequestCode>("oauth/request", Utilities.CreateParamInList("redirect_uri", CallbackUri));
RequestCode response = await Request<RequestCode>("oauth/request", new Dictionary<string, string>()
{
{ "redirect_uri", CallbackUri }
}, false);
// save code to client
RequestCode = response.Code;
@@ -35,14 +41,15 @@ namespace PocketSharp
/// <summary>
/// Generate Authentication URI from requestCode
/// </summary>
/// <param name="requestCode">The requestCode.</param>
/// <returns></returns>
/// <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 PocketException("Call GetRequestCode() first to receive a request_code");
throw new NullReferenceException("Call GetRequestCode() first to receive a request_code");
}
// override property with given param if available
@@ -56,15 +63,19 @@ namespace PocketSharp
/// <summary>
/// Requests the access code after authentification
/// 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>
/// <returns></returns>
/// <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 PocketException("Call GetRequestCode() first to receive a request_code");
throw new NullReferenceException("Call GetRequestCode() first to receive a request_code");
}
// override property with given param if available
@@ -74,7 +85,10 @@ namespace PocketSharp
}
// do request
AccessCode response = await Request<AccessCode>("oauth/authorize", Utilities.CreateParamInList("code", RequestCode));
AccessCode response = await Request<AccessCode>("oauth/authorize", new Dictionary<string, string>()
{
{ "code", RequestCode }
}, false);
// save code to client
AccessCode = response.Code;
@@ -1,6 +1,8 @@
using PocketSharp.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace PocketSharp
{
@@ -10,24 +12,70 @@ 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(RetrieveParameters parameters)
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> 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
)
{
Retrieve response = await Request<Retrieve>("get", parameters.Convert(), true);
RetrieveParameters parameters = new RetrieveParameters()
{
State = state,
Favorite = favorite,
Tag = tag,
ContentType = contentType,
Sort = sort,
DetailType = DetailType.complete,
Search = search,
Domain = domain,
Since = since,
Count = count,
Offset = offset
};
Retrieve response = await Request<Retrieve>("get", parameters.Convert());
return response.Items;
}
/// <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>> Retrieve(RetrieveFilter filter = RetrieveFilter.All)
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> Get(RetrieveFilter filter)
{
RetrieveParameters parameters = new RetrieveParameters();
@@ -55,47 +103,53 @@ namespace PocketSharp
parameters.DetailType = DetailType.complete;
Retrieve response = await Request<Retrieve>("get", parameters.Convert(), true);
Retrieve response = await Request<Retrieve>("get", parameters.Convert());
return response.Items;
}
/// <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>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<List<PocketTag>> GetTags()
{
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 by tag
/// </summary>
/// <param name="tag">The tag.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> SearchByTag(string tag)
{
RetrieveParameters parameters = new RetrieveParameters()
{
Tag = tag,
DetailType = DetailType.complete
};
Retrieve response = await Request<Retrieve>("get", parameters.Convert(), true);
return response.Items;
return await Get(tag: tag);
}
/// <summary>
/// Retrieves items from pocket which match the specified search string in title or content
/// Retrieves items which match the specified search string in title or content
/// </summary>
/// <param name="searchString">The search string.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> Search(string searchString)
{
RetrieveParameters parameters = new RetrieveParameters()
{
Search = searchString,
DetailType = DetailType.complete
};
Retrieve response = await Request<Retrieve>("get", parameters.Convert(), true);
return response.Items;
return await Get(search: searchString);
}
}
+17 -7
View File
@@ -1,4 +1,5 @@
using PocketSharp.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace PocketSharp
@@ -13,9 +14,10 @@ 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 PutSendActionDefault(itemID, "archive");
return await SendDefault(itemID, "archive");
}
@@ -24,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);
@@ -35,9 +38,10 @@ 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 PutSendActionDefault(itemID, "readd");
return await SendDefault(itemID, "readd");
}
@@ -46,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);
@@ -57,9 +62,10 @@ 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 PutSendActionDefault(itemID, "favorite");
return await SendDefault(itemID, "favorite");
}
@@ -68,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);
@@ -79,9 +86,10 @@ 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 PutSendActionDefault(itemID, "unfavorite");
return await SendDefault(itemID, "unfavorite");
}
@@ -90,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);
@@ -101,9 +110,10 @@ 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 PutSendActionDefault(itemID, "delete");
return await SendDefault(itemID, "delete");
}
@@ -124,9 +134,9 @@ namespace PocketSharp
/// <param name="itemID">The item ID.</param>
/// <param name="action">The action.</param>
/// <returns></returns>
protected async Task<bool> PutSendActionDefault(int itemID, string action)
protected async Task<bool> SendDefault(int itemID, string action)
{
return await PutSendAction(new ActionParameter()
return await Send(new ActionParameter()
{
Action = action,
ID = itemID
+57 -19
View File
@@ -1,5 +1,7 @@
using PocketSharp.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace PocketSharp
{
@@ -9,23 +11,25 @@ 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 PutSendActionForTags(itemID, "tags_add", tags);
return await SendTags(itemID, "tags_add", tags);
}
/// <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,23 +37,25 @@ 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 PutSendActionForTags(itemID, "tags_remove", tags);
return await SendTags(itemID, "tags_remove", tags);
}
/// <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,21 +63,49 @@ 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>
public async Task<bool> RemoveTags(int itemID)
/// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTag(int itemID, string tag)
{
return await PutSendActionDefault(itemID, "tags_clear");
return await SendTags(itemID, "tags_remove", new string[] { tag });
}
/// <summary>
/// Clears all tags.
/// 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");
}
/// <summary>
/// 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,23 +113,25 @@ 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 PutSendActionForTags(itemID, "tags_replace", tags);
return await SendTags(itemID, "tags_replace", tags);
}
/// <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,15 +139,16 @@ 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 PutSendAction(new ActionParameter()
return await Send(new ActionParameter()
{
Action = "tag_rename",
ID = itemID,
@@ -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);
@@ -141,9 +179,9 @@ namespace PocketSharp
/// <param name="action">The action.</param>
/// <param name="tags">The tags.</param>
/// <returns></returns>
protected async Task<bool> PutSendActionForTags(int itemID, string action, string[] tags)
protected async Task<bool> SendTags(int itemID, string action, string[] tags)
{
return await PutSendAction(new ActionParameter()
return await Send(new ActionParameter()
{
Action = action,
ID = itemID,
@@ -1,12 +1,15 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace PocketSharp.Models
{
/// <summary>
/// All parameters which can be passed for a modify action
/// </summary>
public class ActionParameter
[DataContract]
internal class ActionParameter
{
/// <summary>
/// Gets or sets the action.
@@ -14,6 +17,7 @@ namespace PocketSharp.Models
/// <value>
/// The action.
/// </value>
[DataMember(Name = "action")]
public string Action { get; set; }
/// <summary>
@@ -22,6 +26,7 @@ namespace PocketSharp.Models
/// <value>
/// The ID.
/// </value>
[DataMember(Name = "item_id")]
public int ID { get; set; }
/// <summary>
@@ -30,6 +35,7 @@ namespace PocketSharp.Models
/// <value>
/// The time.
/// </value>
[DataMember(Name = "time")]
public DateTime? Time { get; set; }
// specific params
@@ -40,6 +46,7 @@ namespace PocketSharp.Models
/// <value>
/// The tags.
/// </value>
[DataMember(Name = "tags")]
public string[] Tags { get; set; }
/// <summary>
@@ -48,6 +55,7 @@ namespace PocketSharp.Models
/// <value>
/// The old tag.
/// </value>
[DataMember(Name = "old_tag")]
public string OldTag { get; set; }
/// <summary>
@@ -56,6 +64,7 @@ namespace PocketSharp.Models
/// <value>
/// The new tag.
/// </value>
[DataMember(Name = "new_tag")]
public string NewTag { get; set; }
@@ -63,16 +72,16 @@ namespace PocketSharp.Models
/// Converts this instance to a parameter list.
/// </summary>
/// <returns></returns>
public object Convert()
public Dictionary<string, object> Convert()
{
Dictionary<string, object> parameters = new Dictionary<string, object>
{
{ "item_id", ID },
{ "item_id", ID.ToString() },
{ "action", Action }
};
if (Time != null)
parameters.Add("time", Utilities.GetUnixTimestamp(Time));
parameters.Add("time", Time != null ? Utilities.GetUnixTimestamp(Time).ToString() : null);
if (Tags != null)
parameters.Add("tags", Tags);
if (OldTag != null)
+9 -16
View File
@@ -1,12 +1,16 @@
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 add a new item
/// </summary>
public class AddParameters
[DataContract]
internal class AddParameters : Parameters
{
/// <summary>
/// Gets or sets the URI.
@@ -14,6 +18,7 @@ namespace PocketSharp.Models
/// <value>
/// The URI.
/// </value>
[DataMember(Name="url")]
public Uri Uri { get; set; }
/// <summary>
@@ -22,6 +27,7 @@ namespace PocketSharp.Models
/// <value>
/// The title.
/// </value>
[DataMember(Name="title")]
public string Title { get; set; }
/// <summary>
@@ -30,6 +36,7 @@ namespace PocketSharp.Models
/// <value>
/// The tags.
/// </value>
[DataMember(Name="tags")]
public string[] Tags { get; set; }
/// <summary>
@@ -38,21 +45,7 @@ namespace PocketSharp.Models
/// <value>
/// The tweet ID.
/// </value>
[DataMember(Name="tweet_id")]
public string TweetID { get; set; }
/// <summary>
/// Converts this instance to a parameter list.
/// </summary>
/// <returns></returns>
public List<Parameter> Convert()
{
return new List<Parameter>()
{
Utilities.CreateParam("url", Uri.ToString() ),
Utilities.CreateParam("title", Title),
Utilities.CreateParam("tags", String.Join(",", Tags)),
Utilities.CreateParam("tweet_id", TweetID)
};
}
}
}
@@ -1,11 +1,13 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace PocketSharp.Models
{
/// <summary>
/// All parameters which can be passed to modify an item
/// </summary>
public class ModifyParameters
[DataContract]
internal class ModifyParameters : Parameters
{
/// <summary>
/// Gets or sets the actions.
@@ -13,23 +15,7 @@ namespace PocketSharp.Models
/// <value>
/// The actions.
/// </value>
public List<ActionParameter> Actions { get; set; }
/// <summary>
/// Converts this instance to a parameter list.
/// </summary>
/// <returns></returns>
public List<Parameter> Convert()
{
List<object> actions = new List<object>();
//Actions.ForEach(action => actions.Add(action.Convert()));
return new List<Parameter>()
{
// Utilities.CreateParam("actions", JsonSerializer.SerializeToString(actions))
};
}
[DataMember(Name = "actions")]
public List<Dictionary<string, string>> Actions { get; set; }
}
}
@@ -1,28 +0,0 @@
namespace PocketSharp.Models
{
/// <summary>
/// Parameter
/// </summary>
public class Parameter
{
/// <summary>
/// Name of the parameter
/// </summary>
public string Name { get; set; }
/// <summary>
/// Value of the parameter
/// </summary>
public object Value { get; set; }
/// <summary>
/// Return a human-readable representation of this parameter
/// </summary>
/// <returns>String</returns>
public override string ToString()
{
return string.Format("{0}={1}", Name, Value);
}
}
}
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using System.Linq;
using System.Collections;
using Newtonsoft.Json;
namespace PocketSharp.Models
{
/// <summary>
/// Parameter
/// </summary>
internal class Parameters
{
/// <summary>
/// Converts an object to a list of HTTP Post parameters.
/// </summary>
/// <returns></returns>
public Dictionary<string, string> Convert()
{
// store HTTP parameters here
Dictionary<string, string> parameterDict = new Dictionary<string, string>();
// get object properties
IEnumerable<PropertyInfo> properties = this.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => Attribute.IsDefined(p, typeof(DataMemberAttribute)));
// gather attributes of object
foreach (PropertyInfo propertyInfo in properties)
{
DataMemberAttribute attribute = (DataMemberAttribute)propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), false).FirstOrDefault();
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());
}
return parameterDict;
}
}
}
@@ -1,12 +1,15 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
namespace PocketSharp.Models
{
/// <summary>
/// All parameters which can be passed for item retrieval
/// </summary>
public class RetrieveParameters
[DataContract]
internal class RetrieveParameters : Parameters
{
/// <summary>
/// Gets or sets the state.
@@ -14,6 +17,7 @@ namespace PocketSharp.Models
/// <value>
/// The state.
/// </value>
[DataMember(Name = "state")]
public State? State { get; set; }
/// <summary>
@@ -22,6 +26,7 @@ namespace PocketSharp.Models
/// <value>
/// The favorite.
/// </value>
[DataMember(Name = "favorite")]
public bool? Favorite { get; set; }
/// <summary>
@@ -30,6 +35,7 @@ namespace PocketSharp.Models
/// <value>
/// The tag.
/// </value>
[DataMember(Name = "tag")]
public string Tag { get; set; }
/// <summary>
@@ -38,6 +44,7 @@ namespace PocketSharp.Models
/// <value>
/// The type of the content.
/// </value>
[DataMember(Name = "contentType")]
public ContentType? ContentType { get; set; }
/// <summary>
@@ -46,6 +53,7 @@ namespace PocketSharp.Models
/// <value>
/// The sort.
/// </value>
[DataMember(Name = "sort")]
public Sort? Sort { get; set; }
/// <summary>
@@ -54,6 +62,7 @@ namespace PocketSharp.Models
/// <value>
/// The type of the detail.
/// </value>
[DataMember(Name="detailType")]
public DetailType? DetailType { get; set; }
/// <summary>
@@ -62,6 +71,7 @@ namespace PocketSharp.Models
/// <value>
/// The search.
/// </value>
[DataMember(Name = "search")]
public string Search { get; set; }
/// <summary>
@@ -70,6 +80,7 @@ namespace PocketSharp.Models
/// <value>
/// The domain.
/// </value>
[DataMember(Name = "domain")]
public string Domain { get; set; }
/// <summary>
@@ -78,6 +89,7 @@ namespace PocketSharp.Models
/// <value>
/// The since.
/// </value>
[DataMember(Name = "since")]
public DateTime? Since { get; set; }
/// <summary>
@@ -86,6 +98,7 @@ namespace PocketSharp.Models
/// <value>
/// The count.
/// </value>
[DataMember(Name = "count")]
public int? Count { get; set; }
/// <summary>
@@ -94,30 +107,8 @@ namespace PocketSharp.Models
/// <value>
/// The offset.
/// </value>
[DataMember(Name = "offset")]
public int? Offset { get; set; }
/// <summary>
/// Converts this instance to a parameter list.
/// </summary>
/// <returns></returns>
public List<Parameter> Convert()
{
return new List<Parameter>()
{
Utilities.CreateParam("state", State != null ? State.ToString() : null ),
Utilities.CreateParam("favorite", Favorite != null ? (bool)Favorite ? "1" : "0" : null),
Utilities.CreateParam("tag", Tag),
Utilities.CreateParam("contentType", ContentType != null ? ContentType.ToString() : null),
Utilities.CreateParam("sort", Sort != null ? Sort.ToString() : null),
Utilities.CreateParam("detailType", DetailType != null ? DetailType.ToString() : null),
Utilities.CreateParam("search", Search),
Utilities.CreateParam("domain", Domain),
Utilities.CreateParam("since", Utilities.GetUnixTimestamp(Since)),
Utilities.CreateParam("count", Count),
Utilities.CreateParam("offset", Offset)
};
}
}
+32 -10
View File
@@ -37,7 +37,29 @@ namespace PocketSharp.Models
/// The title.
/// </value>
[JsonProperty("resolved_title")]
public string Title { get; set; }
private string _ResolvedTitle { get; set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>
/// The title.
/// </value>
[JsonProperty("title")]
private string _InternalTitle { get; set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>
/// The title.
/// </value>
[JsonIgnore]
public string Title
{
get { return _InternalTitle ?? _ResolvedTitle; }
set { _InternalTitle = value; _ResolvedTitle = value; }
}
/// <summary>
/// Gets or sets the full title.
@@ -183,7 +205,7 @@ namespace PocketSharp.Models
/// The _ tag dictionary.
/// </value>
[JsonProperty("tags")]
public Dictionary<string, PocketTag> TagDictionary { get; set; }
private Dictionary<string, PocketTag> _TagDictionary { get; set; }
/// <summary>
/// Gets or sets the _ image dictionary.
@@ -192,7 +214,7 @@ namespace PocketSharp.Models
/// The _ image dictionary.
/// </value>
[JsonProperty("images")]
public Dictionary<string, PocketImage> ImageDictionary { get; set; }
private Dictionary<string, PocketImage> _ImageDictionary { get; set; }
/// <summary>
/// Gets or sets the _ video dictionary.
@@ -201,7 +223,7 @@ namespace PocketSharp.Models
/// The _ video dictionary.
/// </value>
[JsonProperty("videos")]
public Dictionary<string, PocketVideo> VideoDictionary { get; set; }
private Dictionary<string, PocketVideo> _VideoDictionary { get; set; }
/// <summary>
/// Gets or sets the _ author dictionary.
@@ -210,7 +232,7 @@ namespace PocketSharp.Models
/// The _ author dictionary.
/// </value>
[JsonProperty("authors")]
public Dictionary<string, PocketAuthor> AuthorDictionary { get; set; }
private Dictionary<string, PocketAuthor> _AuthorDictionary { get; set; }
/// <summary>
@@ -222,7 +244,7 @@ namespace PocketSharp.Models
[JsonIgnore]
public List<PocketTag> Tags
{
get { return Utilities.DictionaryToList<PocketTag>(TagDictionary); }
get { return Utilities.DictionaryToList<PocketTag>(_TagDictionary); }
}
/// <summary>
@@ -234,7 +256,7 @@ namespace PocketSharp.Models
[JsonIgnore]
public List<PocketImage> Images
{
get { return Utilities.DictionaryToList<PocketImage>(ImageDictionary); }
get { return Utilities.DictionaryToList<PocketImage>(_ImageDictionary); }
}
/// <summary>
@@ -246,7 +268,7 @@ namespace PocketSharp.Models
[JsonIgnore]
public PocketImage LeadImage
{
get { return Images != null ? Images[0] : null; }
get { return Images != null && Images.Count > 0 ? Images[0] : null; }
}
/// <summary>
@@ -258,7 +280,7 @@ namespace PocketSharp.Models
[JsonIgnore]
public List<PocketVideo> Videos
{
get { return Utilities.DictionaryToList<PocketVideo>(VideoDictionary); }
get { return Utilities.DictionaryToList<PocketVideo>(_VideoDictionary); }
}
/// <summary>
@@ -270,7 +292,7 @@ namespace PocketSharp.Models
[JsonIgnore]
public List<PocketAuthor> Authors
{
get { return Utilities.DictionaryToList<PocketAuthor>(AuthorDictionary); }
get { return Utilities.DictionaryToList<PocketAuthor>(_AuthorDictionary); }
}
}
}
+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; }
}
}
+35 -30
View File
@@ -103,41 +103,27 @@ namespace PocketSharp
/// <param name="requireAuth">if set to <c>true</c> [require auth].</param>
/// <returns></returns>
/// <exception cref="PocketException">No access token available. Use authentification first.</exception>
protected async Task<T> Request<T>(string method, List<Parameter> parameters = null, bool requireAuth = false) where T : class, new()
protected async Task<T> Request<T>(string method, Dictionary<string, string> parameters = null, bool requireAuth = true) where T : class, new()
{
if (requireAuth && AccessCode == null)
{
throw new PocketException("SDK error: No access token available. Use authentification first.");
}
// convert parameters
Dictionary<string, string> parameterDict = new Dictionary<string, string>();
if (parameters != null)
{
foreach (Parameter item in parameters)
{
if (item.Value != null)
{
parameterDict.Add(item.Name, item.Value.ToString());
}
}
}
// every single Pocket API endpoint requires HTTP POST data
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, method);
// add consumer key to each request
parameterDict.Add("consumer_key", ConsumerKey);
parameters.Add("consumer_key", ConsumerKey);
// add access token (necessary for all requests except authentification)
if (AccessCode != null)
{
parameterDict.Add("access_token", AccessCode);
parameters.Add("access_token", AccessCode);
}
// content of the request
request.Content = new FormUrlEncodedContent(parameterDict);
request.Content = new FormUrlEncodedContent(parameters);
// make async request
HttpResponseMessage response = await _restClient.SendAsync(request);
@@ -148,15 +134,16 @@ namespace PocketSharp
// read response
var responseString = await response.Content.ReadAsStringAsync();
responseString = responseString.Replace("[]", "{}");
// deserialize object
T parsedResponse = JsonConvert.DeserializeObject<T>(
responseString,
responseString,
new JsonSerializerSettings
{
Error = (object sender, ErrorEventArgs args) =>
{
throw new PocketException(String.Format("Parse error: {0}", args.ErrorContext.Error.Message));
args.ErrorContext.Handled = true;
},
Converters =
{
@@ -171,20 +158,38 @@ namespace PocketSharp
/// <summary>
/// Puts an action
/// Sends a list of actions
/// </summary>
/// <param name="actionParameters">The action parameters.</param>
/// <returns></returns>
internal async Task<bool> Send(List<ActionParameter> actionParameters)
{
List<Dictionary<string, object>> actionParamList = new List<Dictionary<string, object>>();
foreach (var action in actionParameters)
{
actionParamList.Add(action.Convert());
}
Dictionary<string, string> parameters = new Dictionary<string, string>() {{
"actions", JsonConvert.SerializeObject(actionParamList)
}};
Modify response = await Request<Modify>("send", parameters);
return response.Status;
}
/// <summary>
/// Sends an action
/// </summary>
/// <param name="actionParameter">The action parameter.</param>
/// <returns></returns>
protected async Task<bool> PutSendAction(ActionParameter actionParameter)
internal async Task<bool> Send(ActionParameter actionParameter)
{
ModifyParameters parameters = new ModifyParameters()
{
Actions = new List<ActionParameter>() { actionParameter }
};
Modify response = await Request<Modify>("send", parameters.Convert(), true);
return response.Status;
bool response = await Send(new List<ActionParameter>() { actionParameter });
return response;
}
+5 -5
View File
@@ -44,12 +44,12 @@
<Compile Include="Components\Authentification.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" />
<Compile Include="Models\Parameters\ModifyParameters.cs" />
<Compile Include="Models\Parameters\Parameter.cs" />
<Compile Include="Models\Parameters\Parameters.cs" />
<Compile Include="Models\Parameters\RetrieveParameters.cs" />
<Compile Include="Models\PocketAuthor.cs" />
<Compile Include="Models\PocketImage.cs" />
@@ -80,13 +80,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.4.0")]
[assembly: AssemblyFileVersion("1.4.0")]
-26
View File
@@ -25,32 +25,6 @@ namespace PocketSharp
}
/// <summary>
/// Creates a Parameter object.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
/// <param name="type">The type.</param>
/// <returns></returns>
public static Parameter CreateParam(string name, object value)
{
return new Parameter() { Name = name, Value = value };
}
/// <summary>
/// Creates a Parameter object within a list.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
/// <param name="type">The type.</param>
/// <returns></returns>
public static List<Parameter> CreateParamInList(string name, object value)
{
return new List<Parameter>() { CreateParam(name, value) };
}
/// <summary>
/// Convert a dictionary to a list
/// </summary>
+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>
+95 -53
View File
@@ -1,13 +1,10 @@
![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:
**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).
- Authentication
- Retrieve
- Modify
- Add
[pocketsharp.frontendplay.com](http://pocketsharp.frontendplay.com/)
**Website:** [pocketsharp.frontendplay.com](http://pocketsharp.frontendplay.com/)
<br>
**NuGet:** [nuget.org/packages/PocketSharp](https://www.nuget.org/packages/PocketSharp/)
## Install using NuGet
@@ -15,6 +12,23 @@
Install-Package PocketSharp
```
## Supported platforms
PocketSharp is a **Portable Class Library** (since 1.0.0), therefore it's compatible with multiple platforms:
- **.NET** >= 4.0.3 (including WPF)
- **Silverlight** >= 4
- **Windows Phone** >= 7.5
- **Windows Store**
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
All public methods, which communicate with the Pocket servers are asynchronous. So they should be called with the preceding `await` keyword, and the encapsulated method marked with `async`.
_In PocketSharp versions < 1.0.0 all methods lacked async support and were blocking._
## Usage Example
Request a [Consumer Key on Pocket.](http://getpocket.com/developer/apps/)
@@ -35,8 +49,9 @@ PocketClient _client = new PocketClient("[YOUR_CONSUMER_KEY]", "[YOUR_ACCESS_COD
Do a simple request - e.g. a search for `CSS`:
```csharp
_client.Search("css").ForEach(
item => Console.WriteLine(item.ID + " | " + item.Title)
var items = await _client.Search("css");
items.ForEach(
item => Debug.WriteLine(item.ID + " | " + item.Title)
);
```
@@ -93,7 +108,7 @@ The authentication is a 3-step process:
Receive the **request code** and **authentication URI** from the library by calling `string GetRequestCode()`:
```csharp
string requestCode = _client.GetRequestCode();
string requestCode = await _client.GetRequestCode();
// 0f453f2d-1605-8584-28fd-39af8e
Uri authenticationUri = _client.GenerateAuthenticationUri();
// https://getpocket.com/auth/authorize?request_token=0f453f2d-1605-8584-28fd-39af8e&redirect_uri=http%253a%252f%252fceecore.com
@@ -107,10 +122,10 @@ Next you need to redirect the user to the `authenticationUri`, which displays a
![authentication screen](https://raw.github.com/ceee/PocketSharp/master/PocketSharp/authentication-screen.png)
#### 3) Get Access Code
Call `string GetAccessCode(string requestCode = null)`
Call `Task<string> GetAccessCode(string requestCode = null)`
```csharp
string accessCode = _client.GetAccessCode();
string accessCode = await _client.GetAccessCode();
// fa8bfc16-69b3-4d22-7db7-84a58d
```
@@ -128,26 +143,62 @@ Without it you would always have to redo the authentication process.
Get list of all items:
```csharp
List<PocketItem> items = _client.Retrieve();
// equivalent to: _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:
```csharp
List<PocketItem> items = _client.SearchByTag("tutorial");
List<PocketItem> items = await _client.SearchByTag("tutorial");
```
Find items by a search string:
```csharp
List<PocketItem> items = _client.Search("css");
List<PocketItem> items = await _client.Search("css");
```
Find items by a filter:
Get all tags:
```csharp
List<PocketItem> items = _client.Retrieve(RetrieveFilter.Favorite); // only favorites
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:
@@ -156,35 +207,19 @@ 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 = _client.Retrieve(parameters);
```
## Add
Adds a new item to your pocket list.
Accepts four parameters, with `uri` being required.
```csharp
PocketItem Add(Uri uri, string[] tags = null, string title = null, string tweetID = null)
Task<PocketItem> Add(Uri uri, string[] tags = null, string title = null, string tweetID = null)
```
Example:
```csharp
PocketItem newItem = _client.Add(
PocketItem newItem = await _client.Add(
new Uri("http://www.neowin.net/news/full-build-2013-conference-sessions-listing-revealed"),
new string[] { "microsoft", "neowin", "build" }
);
@@ -200,60 +235,67 @@ All Modify methods accept either the itemID (as int) or a `PocketItem` as parame
Archive the specified item:
bool isSuccess = _client.Archive(myPocketItem);
bool isSuccess = await _client.Archive(myPocketItem);
Un-archive the specified item:
bool isSuccess = _client.Unarchive(myPocketItem);
bool isSuccess = await _client.Unarchive(myPocketItem);
Favorites the specified item:
bool isSuccess = _client.Favorite(myPocketItem);
bool isSuccess = await _client.Favorite(myPocketItem);
Un-favorites the specified item:
bool isSuccess = _client.Unfavorite(myPocketItem);
bool isSuccess = await _client.Unfavorite(myPocketItem);
Deletes the specified item:
bool isSuccess = _client.Delete(myPocketItem);
bool isSuccess = await _client.Delete(myPocketItem);
#### Modify tags
Add tags to the specified item:
bool isSuccess = _client.AddTags(myPocketItem, new string[] { "css", "2013" });
bool isSuccess = await _client.AddTags(myPocketItem, new string[] { "css", "2013" });
Remove tags from the specified item:
bool isSuccess = _client.RemoveTags(myPocketItem, new string[] { "css", "2013" });
bool isSuccess = await _client.RemoveTags(myPocketItem, new string[] { "css", "2013" });
Remove all tags from the specified item:
bool isSuccess = _client.RemoveTags(myPocketItem);
bool isSuccess = await _client.RemoveTags(myPocketItem);
Replaces all existing tags with new ones for the specified item:
bool isSuccess = _client.ReplaceTags(myPocketItem, new string[] { "css", "2013" });
bool isSuccess = await _client.ReplaceTags(myPocketItem, new string[] { "css", "2013" });
Renames a tag for the specified item:
bool isSuccess = _client.RenameTag(myPocketItem, "oldTagName", "newTagName");
bool isSuccess = await _client.RenameTag(myPocketItem, "oldTagName", "newTagName");
---
## Release History
- 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.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
- [RestSharp](http://restsharp.org/)
- [ServiceStack.Text](https://github.com/ServiceStack/ServiceStack.Text)
- [Microsoft.Bcl.Async](https://www.nuget.org/packages/Microsoft.Bcl.Async/)
- [Microsoft.Net.Http](https://www.nuget.org/packages/Microsoft.Net.Http/)
- [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/)
## Contributors
| [![twitter/artistandsocial](http://gravatar.com/avatar/9c61b1f4307425f12f05d3adb930ba66?s=70)](http://twitter.com/artistandsocial "Follow @artistandsocial on Twitter") |