54 Commits

Author SHA1 Message Date
swcs a2e68af4dc update readme 2013-12-15 11:50:37 +01:00
swcs ab5361c370 bump version 2013-12-15 11:42:53 +01:00
swcs 4718faf76a HasImage and HasVideo has to be nullable for unresolved items 2013-12-15 11:10:56 +01:00
swcs f6e7594233 respect normal_uri, if submitted; PocketItem.ID as string 2013-12-15 11:00:00 +01:00
swcs c39f8ec7f0 make PocketBoolean internal 2013-12-07 20:42:12 +01:00
ScottIsAFool c1981bbb24 Fixed the HasImage and HasVideo properties 2013-12-07 17:30:53 +00:00
ScottIsAFool 425faf7a90 Added IsVideo, IsImage and ResolvedId props 2013-12-07 16:47:18 +00:00
swcs a1fae6b3ce fix PocketAction conversion 2013-12-04 22:14:29 +01:00
swcs 84981a5de3 add TweetID for Send actions 2013-12-04 20:31:23 +01:00
swcs 5480cebe49 publicly cache last response headers and data 2013-12-03 22:28:22 +01:00
swcs 3fca5a059b update tests 2013-12-02 22:51:24 +01:00
swcs 5854c0c04f rebuild issue #13 in WP8 sample (via Button click) 2013-11-23 22:45:03 +01:00
swcs e2ca21b3be add tests for the since parameter 2013-11-21 21:45:49 +01:00
swcs 178920008b fixes #12
ObjectToArrayConverter returns null when the TokenType is Null.
2013-11-20 20:45:55 +01:00
swcs 67c48839d9 fixes #12
Update ObjectToArrayConverter to return null when JObject cannot be
created
2013-11-19 19:30:59 +01:00
swcs e2bf62e506 Fix accessCode in examples 2013-11-18 23:12:30 +01:00
swcs 31c69fb12b merge 2013-11-18 22:52:39 +01:00
ScottIsAFool 42693a967e Added HttpClientHandler and timeout to ctors 2013-11-18 18:05:02 +00:00
swcs 29f57085aa add IE11 user agent for PocketReader; update to RC3 2013-11-16 15:34:36 +01:00
swcs 5ba027bafc test SendActions 2013-11-16 15:27:54 +01:00
swcs 33e6e9b02d add SendActions method 2013-11-16 15:09:21 +01:00
swcs 44376c0852 IPocketReader interface 2013-11-15 14:30:20 +01:00
swcs a643e5c556 update readme 2013-11-15 14:23:21 +01:00
swcs b2ce585966 bodyOnly and noHeadline options for PocketReader.Read 2013-11-15 14:20:56 +01:00
swcs 6f6d054044 update readme 2013-11-15 13:52:22 +01:00
swcs ff4fae1d35 add second NuGet package for PocketReader; allow user agent in PocketReader constructor 2013-11-15 13:43:27 +01:00
swcs f5c8d45013 move PocketReader into own project 2013-11-15 13:28:16 +01:00
swcs ad40a25b0b make user agent a public property in PocketReader 2013-11-14 20:02:56 +01:00
swcs eb3ac1f152 Update README.md 2013-11-14 19:53:56 +01:00
swcs 3bff4d823f update dependencies 2013-11-14 19:33:55 +01:00
swcs 0427399746 add stress tests 2013-11-13 20:23:02 +01:00
swcs ee989fc019 custom UriConverter to check for invalid URIs 2013-11-12 22:08:02 +01:00
swcs 2a9c30a69b add PreRequest action for all requests 2013-11-11 22:00:41 +01:00
swcs 95d7a5d993 make CancellationToken an optional parameter 2013-11-08 09:31:35 +01:00
swcs bf5d8a50ce cancellationToken for ALL methods - completed; remove obsolete methods in preparation for v3 2013-11-08 01:44:32 +01:00
swcs 10e9575303 cancellationToken for Modify methods 2013-11-08 01:33:32 +01:00
swcs feff91ffd8 cancellationToken for Get methods 2013-11-08 01:24:58 +01:00
swcs 50d896c670 cancellationToken for Add and Account methods 2013-11-08 01:12:34 +01:00
swcs f0ffeb5a68 Merge branch 'stress' 2013-11-08 00:56:02 +01:00
swcs 6b3819b87b require Uri to be absolute in Add method 2013-11-08 00:55:44 +01:00
swcs 8df2836563 add CancellationToken to PocketClient; methods later; 2013-11-06 20:47:53 +01:00
swcs d856e75e76 make test playlists working for XUnit update 2013-11-05 23:31:19 +01:00
swcs 82c9ecd6b5 remove Utilities.DictionaryToList - not needed 2013-11-05 23:17:45 +01:00
swcs 7147d8022e update docs 2013-11-05 23:13:14 +01:00
swcs b1888ac20e Merge branch 'master' of github.com:ceee/PocketSharp 2013-11-04 22:46:47 +01:00
swcs cb8d1d9d43 make Test playlists; refactored PocketItem inline lists (setters are working now); 2013-11-04 22:46:30 +01:00
swcs 2b932d4c07 Update README.md 2013-11-04 08:26:23 +01:00
swcs bc30ea613a Merge branch 'ScottIsAFool-master' 2013-11-03 20:24:45 +01:00
swcs b1b145204e add regions 2013-11-03 20:24:32 +01:00
swcs 01be59b347 add FillAccount method for stress tests 2013-11-03 20:18:57 +01:00
ScottIsAFool af3e2b400b Added IPocketClient interface
Any future public methods that get added in any partial files just need
adding to the interface file too.
2013-11-03 18:07:26 +00:00
swcs 396cf69a40 convert nulls for bool and int in JSOn reader; update stress tests 2013-11-03 18:27:35 +01:00
swcs 088f6a4e0e add stress test wrapper and URL csv's 2013-11-02 10:32:38 +01:00
swcs 25a25472b3 add test for too short passwords in registration 2013-11-02 10:18:33 +01:00
60 changed files with 111816 additions and 572 deletions
+16 -3
View File
@@ -1,3 +1,16 @@
### 3.0.0 (2013-12-15)
- `cancellationToken` support for all methods
- Toggle inclusion of title in PocketArticle.Content
- Make setters for inline objects in PocketItem (images, videos, ...)
- IPocketClient interface
- PreRequest callback allows injection of `Action<string>` before every request
- `lastHeaders` and `lastRequestData` in PocketClient for better debugging
- Submit multiple actions in one request with `SendActions`
- New `IsVideo`, `IsImage` and `ResolvedId` as new properties in PocketItem
- Split PocketReader into own NuGet package
- A lot of bugfixes
### 2.2.2 (2013-11-01) ### 2.2.2 (2013-11-01)
- Password validation in RegisterAccount - Password validation in RegisterAccount
@@ -9,13 +22,13 @@
### 2.2.0 (2013-10-26) ### 2.2.0 (2013-10-26)
- Made `GetAccessCode` obsolete - Made `GetAccessCode` obsolete
- Return username after authentication with `GetUser` (thanks to [ScottIsAFool](https://github.com/ScottIsAFool)) - Return username after authentication with `GetUser`
### 2.1.0 (2013-10-25) ### 2.1.0 (2013-10-25)
- Rename `Statistics()` to `GetUserStatistics()` - Rename `Statistics()` to `GetUserStatistics()`
- Made `CallbackUri` public (thanks to [ScottIsAFool](https://github.com/ScottIsAFool)) - Made `CallbackUri` public
- Added Fody/PropertyChanged (thanks to [ScottIsAFool](https://github.com/ScottIsAFool)) - Added Fody/PropertyChanged
- Method `GetUsageLimits()` to retrieve API usage limits - Method `GetUsageLimits()` to retrieve API usage limits
- Add PORTABLE constant to SgmlReader - Add PORTABLE constant to SgmlReader
@@ -7,10 +7,10 @@
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"> d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White"> <Grid x:Name="LayoutRoot" Background="White">
<Button Content="Load Items" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="380" Height="34" Click="Button_Click"/> <Button Content="Load Items" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="380" Height="34" Click="Button_Click"/>
<sdk:DataGrid x:Name="Content" HorizontalAlignment="Left" Height="241" Margin="10,49,0,0" VerticalAlignment="Top" Width="380" FrozenColumnCount="2"/> <sdk:DataGrid x:Name="Content" HorizontalAlignment="Left" Height="241" Margin="10,49,0,0" VerticalAlignment="Top" Width="380" FrozenColumnCount="2"/>
</Grid> </Grid>
</UserControl> </UserControl>
@@ -1,16 +1,8 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace PocketSharp.Silverlight namespace PocketSharp.Silverlight
{ {
@@ -39,7 +31,7 @@ namespace PocketSharp.Silverlight
PocketClient client = new PocketClient( PocketClient client = new PocketClient(
consumerKey: "15396-f6f92101d72c8e270a6c9bb3", consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
callbackUri: "http://frontendplay.com", callbackUri: "http://frontendplay.com",
accessCode: "2c62cd50-b78a-5558-918b-65adae" accessCode: "80acf6c5-c198-03c0-b94c-e74402"
); );
List<PocketSharp.Models.PocketItem> items = null; List<PocketSharp.Models.PocketItem> items = null;
@@ -78,6 +78,17 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Bcl.1.1.3\lib\sl5\System.IO.dll</HintPath> <HintPath>..\..\packages\Microsoft.Bcl.1.1.3\lib\sl5\System.IO.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Net.Http, Version=1.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.18\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.18\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=1.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.18\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Runtime, Version=2.6.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Runtime, Version=2.6.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Bcl.1.1.3\lib\sl5\System.Runtime.dll</HintPath> <HintPath>..\..\packages\Microsoft.Bcl.1.1.3\lib\sl5\System.Runtime.dll</HintPath>
@@ -4,11 +4,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.5.19.0" newVersion="2.5.19.0" /> <bindingRedirect oldVersion="0.0.0.0-2.6.3.0" newVersion="2.6.3.0" />
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.5.19.0" newVersion="2.5.19.0" /> <bindingRedirect oldVersion="0.0.0.0-2.6.3.0" newVersion="2.6.3.0" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
@@ -3,4 +3,5 @@
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="sl50" /> <package id="Microsoft.Bcl" version="1.1.3" targetFramework="sl50" />
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="sl50" /> <package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="sl50" />
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="sl50" /> <package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="sl50" />
<package id="Microsoft.Net.Http" version="2.2.18" targetFramework="sl50" />
</packages> </packages>
+9 -19
View File
@@ -1,20 +1,10 @@
<Application <Application x:Class="PocketSharp.WP8.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
x:Class="PocketSharp.WP8.App" <!--Application Resources-->
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <Application.Resources>
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" <local:LocalizedStrings xmlns:local="clr-namespace:PocketSharp.WP8" x:Key="LocalizedStrings" />
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" </Application.Resources>
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"> <Application.ApplicationLifetimeObjects>
<!--Required object that handles lifetime events for the application-->
<!--Application Resources--> <shell:PhoneApplicationService Launching="Application_Launching" Closing="Application_Closing" Activated="Application_Activated" Deactivated="Application_Deactivated" />
<Application.Resources> </Application.ApplicationLifetimeObjects>
<local:LocalizedStrings xmlns:local="clr-namespace:PocketSharp.WP8" x:Key="LocalizedStrings"/>
</Application.Resources>
<Application.ApplicationLifetimeObjects>
<!--Required object that handles lifetime events for the application-->
<shell:PhoneApplicationService
Launching="Application_Launching" Closing="Application_Closing"
Activated="Application_Activated" Deactivated="Application_Deactivated"/>
</Application.ApplicationLifetimeObjects>
</Application> </Application>
@@ -14,59 +14,33 @@
SupportedOrientations="Portrait" Orientation="Portrait" SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"> shell:SystemTray.IsVisible="True">
<!--Data context is set to sample data above and LayoutRoot contains the root grid where all other page content is placed--> <!--Data context is set to sample data above and LayoutRoot contains the root grid where all other page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent"> <Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- LOCALIZATION NOTE: <!--TitlePanel contains the name of the application and page title-->
To localize the displayed strings copy their values to appropriately named <StackPanel Grid.Row="0" Margin="12,17,0,28">
keys in the app's neutral language resource file (AppResources.resx) then <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
replace the hard-coded text value between the attributes' quotation marks <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
with the binding clause whose path points to that string name. <Button Click="Button_Click">Load Data</Button>
</StackPanel>
For example: <!--ContentPanel contains LongListSelector and LongListSelector ItemTemplate. Place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}" <phone:LongListSelector x:Name="MainLongListSelector" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainLongListSelector_SelectionChanged">
<phone:LongListSelector.ItemTemplate>
This binding points to the template's string resource named "ApplicationTitle". <DataTemplate>
<StackPanel Margin="0,0,0,17">
Adding supported languages in the Project Properties tab will create a <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
new resx file per language that can carry the translated values of your <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
UI strings. The binding in these examples will cause the value of the </StackPanel>
attributes to be drawn from the .resx file that matches the </DataTemplate>
CurrentUICulture of the app at run time. </phone:LongListSelector.ItemTemplate>
--> </phone:LongListSelector>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel contains LongListSelector and LongListSelector ItemTemplate. Place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<phone:LongListSelector x:Name="MainLongListSelector" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainLongListSelector_SelectionChanged">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
<!--Uncomment to see an alignment grid to help ensure your controls are
aligned on common boundaries. The image has a top margin of -32px to
account for the System Tray. Set this to 0 (or remove the margin altogether)
if the System Tray is hidden.
Before shipping remove this XAML and the image itself.-->
<!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" Grid.RowSpan="2" IsHitTestVisible="False" />-->
</Grid> </Grid>
</Grid>
</phone:PhoneApplicationPage> </phone:PhoneApplicationPage>
@@ -1,15 +1,9 @@
using System; using Microsoft.Phone.Controls;
using System.Collections.Generic; using PocketSharp.WP8.ViewModels;
using System.Linq; using System;
using System.Net;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Navigation; using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using PocketSharp.WP8.Resources;
using PocketSharp.WP8.ViewModels;
using System.Threading.Tasks;
namespace PocketSharp.WP8 namespace PocketSharp.WP8
{ {
@@ -22,18 +16,12 @@ namespace PocketSharp.WP8
// Set the data context of the LongListSelector control to the sample data // Set the data context of the LongListSelector control to the sample data
DataContext = App.ViewModel; DataContext = App.ViewModel;
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
} }
// Load data for the ViewModel Items // Load data for the ViewModel Items
protected async override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
if (!App.ViewModel.IsDataLoaded)
{
await App.ViewModel.LoadData();
}
} }
// Handle selection changed on LongListSelector // Handle selection changed on LongListSelector
@@ -50,20 +38,9 @@ namespace PocketSharp.WP8
MainLongListSelector.SelectedItem = null; MainLongListSelector.SelectedItem = null;
} }
// Sample code for building a localized ApplicationBar private async void Button_Click(object sender, RoutedEventArgs e)
//private void BuildLocalizedApplicationBar() {
//{ await App.ViewModel.LoadData();
// // Set the page's ApplicationBar to a new instance of ApplicationBar. }
// ApplicationBar = new ApplicationBar();
// // Create a new button and set the text value to the localized string from AppResources.
// ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative));
// appBarButton.Text = AppResources.AppBarButtonText;
// ApplicationBar.Buttons.Add(appBarButton);
// // Create a new menu item with the localized string from AppResources.
// ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText);
// ApplicationBar.MenuItems.Add(appBarMenuItem);
//}
} }
} }
@@ -130,6 +130,7 @@
</DesignData> </DesignData>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" />
<None Include="Properties\AppManifest.xml" /> <None Include="Properties\AppManifest.xml" />
<None Include="Properties\WMAppManifest.xml"> <None Include="Properties\WMAppManifest.xml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
@@ -178,6 +179,17 @@
<Reference Include="Microsoft.Threading.Tasks.Extensions.Phone"> <Reference Include="Microsoft.Threading.Tasks.Extensions.Phone">
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.16\lib\wp8\Microsoft.Threading.Tasks.Extensions.Phone.dll</HintPath> <HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.16\lib\wp8\Microsoft.Threading.Tasks.Extensions.Phone.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Net.Http, Version=1.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.18\lib\sl4-windowsphone71\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Extensions">
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.18\lib\sl4-windowsphone71\System.Net.Http.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=1.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.18\lib\sl4-windowsphone71\System.Net.Http.Primitives.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).$(TargetFrameworkVersion).Overrides.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).$(TargetFrameworkVersion).Overrides.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
@@ -196,4 +208,9 @@
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" /> <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target> </Target>
<Import Project="..\..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
</Project> </Project>
@@ -1,11 +1,10 @@
using System; using PocketSharp.WP8.Resources;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using PocketSharp.WP8.Resources;
using PocketSharp;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks;
namespace PocketSharp.WP8.ViewModels namespace PocketSharp.WP8.ViewModels
{ {
@@ -68,14 +67,14 @@ namespace PocketSharp.WP8.ViewModels
PocketClient client = new PocketClient( PocketClient client = new PocketClient(
consumerKey: "15396-f6f92101d72c8e270a6c9bb3", consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
callbackUri: "http://frontendplay.com", callbackUri: "http://frontendplay.com",
accessCode: "2c62cd50-b78a-5558-918b-65adae" accessCode: "80acf6c5-c198-03c0-b94c-e74402"
); );
List<PocketSharp.Models.PocketItem> items = null; List<PocketSharp.Models.PocketItem> items = null;
try try
{ {
items = await client.Get().ConfigureAwait(false); items = await client.Get();
items.ForEach(item => items.ForEach(item =>
{ {
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bcl" version="1.1.6" targetFramework="wp80" />
<package id="Microsoft.Bcl.Build" version="1.0.13" targetFramework="wp80" />
<package id="Microsoft.Net.Http" version="2.2.18" targetFramework="wp80" />
</packages>
@@ -1,9 +1,7 @@
using System.Windows; using System.Collections.Generic;
using System.Windows.Controls;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic; using System.Windows;
using System;
namespace PocketSharp.Wpf namespace PocketSharp.Wpf
{ {
@@ -35,7 +33,7 @@ namespace PocketSharp.Wpf
PocketClient client = new PocketClient( PocketClient client = new PocketClient(
consumerKey: "15396-f6f92101d72c8e270a6c9bb3", consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
callbackUri: "http://frontendplay.com", callbackUri: "http://frontendplay.com",
accessCode: "2c62cd50-b78a-5558-918b-65adae" accessCode: "80acf6c5-c198-03c0-b94c-e74402"
); );
List<PocketSharp.Models.PocketItem> items = null; List<PocketSharp.Models.PocketItem> items = null;
+35
View File
@@ -0,0 +1,35 @@
using PocketSharp.Models;
using System;
using System.Threading.Tasks;
namespace PocketSharp
{
public interface IPocketReader
{
/// <summary>
/// Reads article content from the given URI.
/// This method does not use the official Article View API, which is private.
/// The PocketReader is based on a custom PCL port of NReadability and SgmlReader.
/// </summary>
/// <param name="uri">An URI.</param>
/// <param name="bodyOnly">if set to <c>true</c> [only body is returned].</param>
/// <param name="noHeadline">if set to <c>true</c> [no headline (h1) is included].</param>
/// <returns>A Pocket article with extracted content and title.</returns>
/// <exception cref="PocketRequestException"></exception>
Task<PocketArticle> Read(Uri uri, bool bodyOnly = true, bool noHeadline = false);
/// <summary>
/// Reads article content from the given PocketItem.
/// This method does not use the official Article View API, which is private.
/// The PocketReader is based on a custom PCL port of NReadability and SgmlReader.
/// </summary>
/// <param name="item">The pocket item.</param>
/// <param name="bodyOnly">if set to <c>true</c> [only body is returned].</param>
/// <param name="noHeadline">if set to <c>true</c> [no headline (h1) is included].</param>
/// <returns>
/// A Pocket article with extracted content and title.
/// </returns>
/// <exception cref="PocketRequestException"></exception>
Task<PocketArticle> Read(PocketItem item, bool bodyOnly = true, bool noHeadline = false);
}
}
@@ -1,17 +1,22 @@
using PocketSharp.Ports.NReadability; using PocketSharp.Models;
using PocketSharp.Ports.NReadability;
using System; using System;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using PocketSharp.Models;
namespace PocketSharp namespace PocketSharp
{ {
/// <summary> /// <summary>
/// PocketReader /// PocketReader
/// </summary> /// </summary>
public class PocketReader public class PocketReader : IPocketReader
{ {
/// <summary>
/// Used UserAgent for HTTP request
/// </summary>
protected string _userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0; ARM; Mobile; Touch{0}) like Gecko";
/// <summary> /// <summary>
/// REST client used for HTML retrieval /// REST client used for HTML retrieval
/// </summary> /// </summary>
@@ -19,25 +24,39 @@ namespace PocketSharp
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PocketReader"/> class. /// Initializes a new instance of the <see cref="PocketReader" /> class.
/// </summary> /// </summary>
public PocketReader() /// <param name="userAgent">Custom UserAgent string.</param>
/// <param name="handler">The HttpMessage handler.</param>
/// <param name="timeout">Request timeout (in seconds).</param>
public PocketReader(string userAgent = null, HttpMessageHandler handler = null, int? timeout = null)
{ {
// override user agent
if (!string.IsNullOrEmpty(userAgent))
{
_userAgent = userAgent;
}
// initialize HTTP client // initialize HTTP client
_httpClient = new HttpClient(new HttpClientHandler() _httpClient = new HttpClient(handler ?? new HttpClientHandler()
{ {
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
AllowAutoRedirect = true AllowAutoRedirect = true
}); });
if (timeout.HasValue)
{
_httpClient.Timeout = TimeSpan.FromSeconds(timeout.Value);
}
// add accept types // add accept types
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
// add accepted encodings // add accepted encodings
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip,deflate"); _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip,deflate");
// add user agent (default for Opera with PocketSharp identifier appended) // add user agent
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.4 Safari/537.36 OPR/18.0.1284.2 PocketSharp/2.2"); _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", string.Format(_userAgent, "; PocketSharp/3.0"));
} }
@@ -48,15 +67,18 @@ namespace PocketSharp
/// The PocketReader is based on a custom PCL port of NReadability and SgmlReader. /// The PocketReader is based on a custom PCL port of NReadability and SgmlReader.
/// </summary> /// </summary>
/// <param name="uri">An URI.</param> /// <param name="uri">An URI.</param>
/// <returns>A Pocket article with extracted content and title.</returns> /// <param name="bodyOnly">if set to <c>true</c> [only body is returned].</param>
/// <exception cref="PocketRequestException"></exception> /// <param name="noHeadline">if set to <c>true</c> [no headline (h1) is included].</param>
public async Task<PocketArticle> Read(Uri uri) /// <returns>
/// A Pocket article with extracted content and title.
/// </returns>
public async Task<PocketArticle> Read(Uri uri, bool bodyOnly = true, bool noHeadline = false)
{ {
return await Read(new PocketItem() return await Read(new PocketItem()
{ {
ID = 0, ID = null,
Uri = uri Uri = uri
}); }, bodyOnly, noHeadline);
} }
@@ -67,9 +89,13 @@ namespace PocketSharp
/// The PocketReader is based on a custom PCL port of NReadability and SgmlReader. /// The PocketReader is based on a custom PCL port of NReadability and SgmlReader.
/// </summary> /// </summary>
/// <param name="item">The pocket item.</param> /// <param name="item">The pocket item.</param>
/// <returns>A Pocket article with extracted content and title.</returns> /// <param name="bodyOnly">if set to <c>true</c> [only body is returned].</param>
/// <param name="noHeadline">if set to <c>true</c> [no headline (h1) is included].</param>
/// <returns>
/// A Pocket article with extracted content and title.
/// </returns>
/// <exception cref="PocketRequestException"></exception> /// <exception cref="PocketRequestException"></exception>
public async Task<PocketArticle> Read(PocketItem item) public async Task<PocketArticle> Read(PocketItem item, bool bodyOnly = true, bool noHeadline = false)
{ {
// initialize transcoder // initialize transcoder
NReadabilityTranscoder transcoder = new NReadabilityTranscoder( NReadabilityTranscoder transcoder = new NReadabilityTranscoder(
@@ -90,11 +116,12 @@ namespace PocketSharp
Url = item.Uri.ToString(), Url = item.Uri.ToString(),
DomSerializationParams = new DomSerializationParams() DomSerializationParams = new DomSerializationParams()
{ {
BodyOnly = true, BodyOnly = bodyOnly,
NoHeadline = noHeadline,
PrettyPrint = true, PrettyPrint = true,
DontIncludeContentTypeMetaElement = true, DontIncludeContentTypeMetaElement = true,
DontIncludeMobileSpecificMetaElements = true, DontIncludeMobileSpecificMetaElements = true,
DontIncludeDocTypeMetaElement = true, DontIncludeDocTypeMetaElement = false,
DontIncludeGeneratorMetaElement = true DontIncludeGeneratorMetaElement = true
} }
}; };
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PocketSharp</RootNamespace>
<AssemblyName>PocketSharp.Reader</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile96</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="IPocketReader.cs" />
<Compile Include="PocketReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.165\lib\portable-net40+sl4+win8+wp71\Microsoft.Threading.Tasks.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.165\lib\portable-net40+sl4+win8+wp71\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.IO">
<HintPath>..\packages\Microsoft.Bcl.1.1.6\lib\portable-net40+sl4+win8+wp71\System.IO.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http">
<HintPath>..\packages\Microsoft.Net.Http.2.2.18\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.18\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.18\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Runtime">
<HintPath>..\packages\Microsoft.Bcl.1.1.6\lib\portable-net40+sl4+win8+wp71\System.Runtime.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.1.1.6\lib\portable-net40+sl4+win8+wp71\System.Threading.Tasks.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PocketSharp\PocketSharp.csproj">
<Project>{817200c3-a327-4e35-9b5f-63a51c088577}</Project>
<Name>PocketSharp</Name>
</ProjectReference>
<ProjectReference Include="..\PortablePorts\NReadability\NReadability.csproj">
<Project>{14c3ee6a-54a4-4a37-8b56-d52a3802f1c2}</Project>
<Name>NReadability</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<owners>$author$</owners>
<licenseUrl>https://raw.github.com/ceee/PocketSharp/master/LICENSE-MIT</licenseUrl>
<projectUrl>https://github.com/ceee/PocketSharp</projectUrl>
<iconUrl>https://raw.github.com/ceee/PocketSharp/master/Assets/pocketsharp.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>
<![CDATA[
PocketSharp is a C#.NET portable class library that integrates the Pocket API v3.
PocketSharp.Reader contains the reader which extracts readable content from websites.
]]>
</description>
<language>en-US</language>
<releaseNotes>
<![CDATA[
For full release notes see https://github.com/ceee/PocketSharp/blob/master/CHANGELOG.md
]]>
</releaseNotes>
<copyright>Copyright by cee, 2013</copyright>
<tags>PocketAPI Pocket API PocketSharp Tobias Klika cee NReadability SgmlReader Reader Article SDK Pockem</tags>
</metadata>
</package>
@@ -0,0 +1,26 @@
using System.Reflection;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("PocketSharp.Reader")]
[assembly: AssemblyDescription("Custom Article View API for PocketSharp")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("cee")]
[assembly: AssemblyProduct("PocketSharp.Reader")]
[assembly: AssemblyCopyright("Copyright © cee 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("3.0.0")]
[assembly: AssemblyFileVersion("3.0.0")]
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bcl" version="1.1.6" targetFramework="portable-win+net403+sl40+wp71" />
<package id="Microsoft.Bcl.Async" version="1.0.165" targetFramework="portable-win+net403+sl40+wp71" />
<package id="Microsoft.Bcl.Build" version="1.0.13" targetFramework="portable-win+net403+sl40+wp71" />
<package id="Microsoft.Net.Http" version="2.2.18" targetFramework="portable-win+net403+sl40+wp71" />
</packages>
+5
View File
@@ -50,6 +50,11 @@ namespace PocketSharp.Tests
await client.RegisterAccount("myusername", "pocketsharp@outlook,com", "mypassword"); await client.RegisterAccount("myusername", "pocketsharp@outlook,com", "mypassword");
}); });
await ThrowsAsync<FormatException>(async () =>
{
await client.RegisterAccount("myusername", "pocketsharp@outlook.com", "my");
});
await ThrowsAsync<ArgumentNullException>(async () => await ThrowsAsync<ArgumentNullException>(async () =>
{ {
await client.RegisterAccount("myusername", null, "mypassword"); await client.RegisterAccount("myusername", null, "mypassword");
+17 -4
View File
@@ -1,8 +1,8 @@
using System; using PocketSharp.Models;
using System.Threading.Tasks; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit; using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests namespace PocketSharp.Tests
{ {
@@ -24,6 +24,19 @@ namespace PocketSharp.Tests
} }
[Fact]
public async Task ItemWithInstableImagesIsAdded()
{
var uri = new Uri("http://www.valoronline.com.br");
PocketItem item = await client.Add(uri);
Assert.Equal<Uri>(uri, item.Uri);
itemsToDelete.Add(item.ID);
}
[Fact] [Fact]
public async Task AddComplexItem() public async Task AddComplexItem()
{ {
@@ -39,7 +52,7 @@ namespace PocketSharp.Tests
items.ForEach(itm => items.ForEach(itm =>
{ {
if(itm.ID == item.ID) if (itm.ID == item.ID)
{ {
itemDesired = itm; itemDesired = itm;
} }
File diff suppressed because one or more lines are too long
+92 -6
View File
@@ -1,8 +1,8 @@
using System; using PocketSharp.Models;
using System.Threading.Tasks; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit; using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests namespace PocketSharp.Tests
{ {
@@ -15,7 +15,6 @@ namespace PocketSharp.Tests
public async Task AreItemsRetrieved() public async Task AreItemsRetrieved()
{ {
List<PocketItem> items = await client.Get(); List<PocketItem> items = await client.Get();
Assert.True(items.Count > 0); Assert.True(items.Count > 0);
} }
@@ -76,7 +75,7 @@ namespace PocketSharp.Tests
Assert.False(items.Count > 0); Assert.False(items.Count > 0);
PocketItem item = await client.Get(99999999); PocketItem item = await client.Get("99999999");
Assert.Null(item); Assert.Null(item);
@@ -147,7 +146,7 @@ namespace PocketSharp.Tests
[Fact] [Fact]
public async Task AreStatisticsRetrieved() public async Task AreStatisticsRetrieved()
{ {
PocketStatistics statistics = await client.Statistics(); PocketStatistics statistics = await client.GetUserStatistics();
Assert.True(statistics.CountAll > 0); Assert.True(statistics.CountAll > 0);
} }
@@ -160,5 +159,92 @@ namespace PocketSharp.Tests
Assert.True(limits.RateLimitForConsumerKey > 9999); Assert.True(limits.RateLimitForConsumerKey > 9999);
} }
[Fact]
public async Task IsNewPocketItemListGeneratorWorking()
{
List<PocketItem> items = await client.Get(count: 1, tag: "pocket");
PocketItem item = items[0];
Assert.True(item.Tags.Find(i => i.Name == "pocket") != null);
}
[Fact]
public async Task IsSinceParameterWorkingOnAddTags()
{
DateTime since = DateTime.UtcNow;
List<PocketItem> items = await client.Get(state: State.all);
PocketItem itemToModify = items[0];
Assert.True(items.Count >= 3);
items = await client.Get(state: State.all, since: since);
Assert.True(items == null || items.Count == 0);
await client.AddTags(itemToModify, new string[] { "pocketsharp" });
items = await client.Get(state: State.all, since: since);
Assert.True(items.Count > 0);
await client.RemoveTags(itemToModify, new string[] { "pocketsharp" });
}
[Fact]
public async Task IsSinceParameterWorkingOnFavoriteAndArchiveModification()
{
DateTime since = DateTime.UtcNow;
List<PocketItem> items = await client.Get(state: State.all);
PocketItem itemToModify = items[0];
Assert.True(items.Count >= 3);
items = await client.Get(state: State.all, since: since);
Assert.True(items == null || items.Count == 0);
await client.Favorite(itemToModify);
items = await client.Get(state: State.all, since: since);
Assert.True(items.Count > 0);
await client.Unfavorite(itemToModify);
since = DateTime.UtcNow;
await client.Archive(itemToModify);
items = await client.Get(state: State.all, since: since);
Assert.True(items.Count > 0);
await client.Unarchive(itemToModify);
}
[Fact]
public async Task IsSinceParameterWorkingOnAddAndDelete()
{
DateTime since = DateTime.UtcNow;
PocketItem item = await client.Add(new Uri("http://frontendplay.com"));
List<PocketItem> items = await client.Get(state: State.all, since: since);
since = DateTime.UtcNow;
await client.Delete(item);
items = await client.Get(state: State.all, since: since);
Assert.True(items.Count == 1 && items[0].IsDeleted);
}
} }
} }
+31
View File
@@ -0,0 +1,31 @@
using PocketSharp.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;
namespace PocketSharp.Tests
{
public class MiscTests : TestsBase
{
private int Incrementor = 0;
public MiscTests()
: base()
{
client.PreRequest = method => Incrementor++;
}
[Fact]
public async Task CheckPreRequestAction()
{
List<PocketItem> items = await client.Get(count: 1);
PocketItem item = items[0];
await client.Favorite(item);
await client.Unfavorite(item);
Assert.True(Incrementor >= 3);
}
}
}
+5 -5
View File
@@ -1,9 +1,9 @@
using System; using PocketSharp.Models;
using System.Threading.Tasks; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Xunit;
using PocketSharp.Models;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace PocketSharp.Tests namespace PocketSharp.Tests
{ {
@@ -83,7 +83,7 @@ namespace PocketSharp.Tests
} }
private async Task<PocketItem> GetItemById(int id, bool archive = false) private async Task<PocketItem> GetItemById(string id, bool archive = false)
{ {
List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread); List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread);
PocketItem itemDesired = null; PocketItem itemDesired = null;
+30 -4
View File
@@ -1,8 +1,9 @@
using System; using PocketSharp.Models;
using System.Threading.Tasks; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit; using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests namespace PocketSharp.Tests
{ {
@@ -62,6 +63,31 @@ namespace PocketSharp.Tests
} }
[Fact]
public async Task AreMultipleActionsSent()
{
PocketItem item = await Setup();
bool success = await client.SendActions(new List<PocketAction>()
{
new PocketAction() { Action = "favorite", ID = item.ID },
new PocketAction() { Action = "tags_add", ID = item.ID, Tags = new string[] { "new_tag", "another_tag" } },
new PocketAction() { Action = "archive", ID = item.ID },
new PocketAction() { Action = "tag_rename", ID = item.ID, OldTag = "social", NewTag = "not_social" }
});
Assert.True(success);
item = await client.Get(item.ID);
Assert.True(item.IsFavorite);
Assert.True(item.IsArchive);
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "new_tag"));
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "another_tag"));
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "not_social"));
}
private async Task<PocketItem> Setup() private async Task<PocketItem> Setup()
{ {
PocketItem item = await client.Add( PocketItem item = await client.Add(
@@ -75,7 +101,7 @@ namespace PocketSharp.Tests
} }
private async Task<PocketItem> GetItemById(int id, bool archive = false) private async Task<PocketItem> GetItemById(string id, bool archive = false)
{ {
List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread); List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread);
PocketItem itemDesired = null; PocketItem itemDesired = null;
+21 -11
View File
@@ -37,22 +37,24 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.Threading.Tasks"> <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net45\Microsoft.Threading.Tasks.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions"> <Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net45\Microsoft.Threading.Tasks.Extensions.dll</HintPath> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Net" /> <Reference Include="System.Net" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.15.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Net.Http.Extensions, Version=2.2.18.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Net.Http.2.2.15\lib\net45\System.Net.Http.Extensions.dll</HintPath> <HintPath>..\packages\Microsoft.Net.Http.2.2.18\lib\net45\System.Net.Http.Extensions.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.15.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Net.Http.Primitives, Version=4.2.18.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Net.Http.2.2.15\lib\net45\System.Net.Http.Primitives.dll</HintPath> <HintPath>..\packages\Microsoft.Net.Http.2.2.18\lib\net45\System.Net.Http.Primitives.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Net.Http.WebRequest" /> <Reference Include="System.Net.Http.WebRequest" />
<Reference Include="xunit"> <Reference Include="xunit">
@@ -68,6 +70,7 @@
<Otherwise /> <Otherwise />
</Choose> </Choose>
<ItemGroup> <ItemGroup>
<Compile Include="MiscTests.cs" />
<Compile Include="AddTests.cs" /> <Compile Include="AddTests.cs" />
<Compile Include="AccountTests.cs" /> <Compile Include="AccountTests.cs" />
<Compile Include="ModifyTagsTests.cs" /> <Compile Include="ModifyTagsTests.cs" />
@@ -75,9 +78,14 @@
<Compile Include="GetTests.cs" /> <Compile Include="GetTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReadTests.cs" /> <Compile Include="ReadTests.cs" />
<Compile Include="StressTests.cs" />
<Compile Include="TestsBase.cs" /> <Compile Include="TestsBase.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\PocketSharp.Reader\PocketSharp.Reader.csproj">
<Project>{9d1bbd72-c263-43d3-9f2a-98f9f99235a4}</Project>
<Name>PocketSharp.Reader</Name>
</ProjectReference>
<ProjectReference Include="..\PocketSharp\PocketSharp.csproj"> <ProjectReference Include="..\PocketSharp\PocketSharp.csproj">
<Project>{817200c3-a327-4e35-9b5f-63a51c088577}</Project> <Project>{817200c3-a327-4e35-9b5f-63a51c088577}</Project>
<Name>PocketSharp</Name> <Name>PocketSharp</Name>
@@ -86,6 +94,8 @@
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="url-10000.csv" />
<None Include="url-100000.csv" />
</ItemGroup> </ItemGroup>
<Choose> <Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'"> <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
@@ -114,10 +124,10 @@
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" /> <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target> </Target>
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" /> <Import Project="..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''"> <Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" /> <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" /> <Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target> </Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
+24 -7
View File
@@ -1,8 +1,7 @@
using System; using PocketSharp.Models;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
using PocketSharp.Models;
using System.Diagnostics;
namespace PocketSharp.Tests namespace PocketSharp.Tests
{ {
@@ -11,7 +10,8 @@ namespace PocketSharp.Tests
private PocketReader reader; private PocketReader reader;
public ReadTests() : base() public ReadTests()
: base()
{ {
reader = new PocketReader(); reader = new PocketReader();
} }
@@ -22,10 +22,27 @@ namespace PocketSharp.Tests
{ {
PocketArticle result = await reader.Read(new PocketItem() PocketArticle result = await reader.Read(new PocketItem()
{ {
ID = 99, ID = "99",
Uri = new Uri("http://frontendplay.com/story/4/http-caching-demystified-part-2-implementation") Uri = new Uri("http://frontendplay.com/story/4/http-caching-demystified-part-2-implementation")
}); });
Assert.DoesNotContain("<!DOCTYPE html>", result.Content);
Assert.Contains("<h1>", result.Content);
Assert.True(result.Content.Length > 15000);
}
[Fact]
public async Task ReadArticleWithContainerNoHeadlineTest()
{
PocketArticle result = await reader.Read(new PocketItem()
{
ID = "99",
Uri = new Uri("http://frontendplay.com/story/4/http-caching-demystified-part-2-implementation")
}, false, true);
Assert.Contains("<!DOCTYPE html>", result.Content);
Assert.DoesNotContain("<h1>", result.Content);
Assert.True(result.Content.Length > 15000); Assert.True(result.Content.Length > 15000);
} }
@@ -37,7 +54,7 @@ namespace PocketSharp.Tests
{ {
await reader.Read(new PocketItem() await reader.Read(new PocketItem()
{ {
ID = 99, ID = "99",
Uri = new Uri("http://frontendplayyyyy.com") Uri = new Uri("http://frontendplayyyyy.com")
}); });
}); });
@@ -49,7 +66,7 @@ namespace PocketSharp.Tests
{ {
PocketArticle result = await reader.Read(new PocketItem() PocketArticle result = await reader.Read(new PocketItem()
{ {
ID = 99, ID = "99",
Uri = new Uri("http://calebjacob.com/tooltipster/") Uri = new Uri("http://calebjacob.com/tooltipster/")
}); });
+1
View File
@@ -0,0 +1 @@
<Playlist Version="1.0"><Add Test="PocketSharp.Tests.StressTests.Are0ItemsRetrievedProperly" /><Add Test="PocketSharp.Tests.StressTests.Are100ItemsRetrievedProperly" /><Add Test="PocketSharp.Tests.StressTests.Are10000ItemsRetrievedProperly" /><Add Test="PocketSharp.Tests.StressTests.IsSearchedSuccessfullyOn10000Items" /><Add Test="PocketSharp.Tests.StressTests.Are1000ItemsRetrievedProperly" /><Add Test="PocketSharp.Tests.StressTests.IsSearchedSuccessfullyOn10000Items (PocketSharp.Tests.StressTests.IsSearchedSuccessfullyOn10000Items (F:\Playground\CSharp\PocketSharp\PocketSharp.Tests\bin\Release\PocketSharp.Tests.dll))" /><Add Test="PocketSharp.Tests.StressTests.Are1000ItemsRetrievedProperly (PocketSharp.Tests.StressTests.Are1000ItemsRetrievedProperly (F:\Playground\CSharp\PocketSharp\PocketSharp.Tests\bin\Release\PocketSharp.Tests.dll))" /><Add Test="PocketSharp.Tests.StressTests.Are0ItemsRetrievedProperly (PocketSharp.Tests.StressTests.Are0ItemsRetrievedProperly (F:\Playground\CSharp\PocketSharp\PocketSharp.Tests\bin\Release\PocketSharp.Tests.dll))" /><Add Test="PocketSharp.Tests.StressTests.Are100ItemsRetrievedProperly (PocketSharp.Tests.StressTests.Are100ItemsRetrievedProperly (F:\Playground\CSharp\PocketSharp\PocketSharp.Tests\bin\Release\PocketSharp.Tests.dll))" /><Add Test="PocketSharp.Tests.StressTests.Are10000ItemsRetrievedProperly (PocketSharp.Tests.StressTests.Are10000ItemsRetrievedProperly (F:\Playground\CSharp\PocketSharp\PocketSharp.Tests\bin\Release\PocketSharp.Tests.dll))" /></Playlist>
+124
View File
@@ -0,0 +1,124 @@
using PocketSharp.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace PocketSharp.Tests
{
public class StressTests : TestsBase
{
private static IEnumerable<string> urls;
private static string[] tags = new string[] { "css", "js", "csharp", "windows", "microsoft" };
public StressTests()
: base()
{
// !! please don't misuse this account !!
client = new PocketClient(
consumerKey: "20000-786d0bc8c39294e9829111d6",
callbackUri: "http://frontendplay.com",
accessCode: "9b8ecb6b-7801-1a5c-7b39-2ba05b"
);
urls = File.ReadAllLines("../../url-100000.csv").Select(item => item.Split(',')[1]);
}
[Fact]
public async Task Are100ItemsRetrievedProperly()
{
List<PocketItem> items = await client.Get(count: 100, state: State.all);
Assert.True(items.Count == 100);
}
[Fact]
public async Task Are1000ItemsRetrievedProperly()
{
List<PocketItem> items = await client.Get(count: 1000, state: State.all);
Assert.True(items.Count == 1000);
}
[Fact]
public async Task Are2500ItemsRetrievedProperly()
{
List<PocketItem> items = await client.Get(count: 2500, state: State.all);
Assert.True(items.Count == 2500);
}
[Fact]
public async Task Are5000ItemsRetrievedProperly()
{
List<PocketItem> items = await client.Get(count: 5000, state: State.all);
Assert.True(items.Count == 5000);
}
[Fact]
public async Task AreItemsRetrievedProperlyWithoutLimit()
{
List<PocketItem> items = await client.Get(state: State.all);
Assert.True(items.Count > 0);
}
[Fact]
public async Task IsSearchSuccessfullyOnBigList()
{
List<PocketItem> items = await client.Get(search: "google");
Assert.True(items.Count > 0);
Assert.True(items[0].Title.ToLower().Contains("google") || items[0].Uri.ToString().ToLower().Contains("google"));
}
[Fact]
public async Task IsTagSearchSuccessfullyOnBigList()
{
List<PocketItem> items = await client.SearchByTag(tags[0]);
Assert.True(items.Count > 1);
bool found = false;
items[0].Tags.ForEach(tag =>
{
if (tag.Name.Contains(tags[0]))
{
found = true;
}
});
Assert.True(found);
}
[Fact]
public async Task RetrieveTagsReturnsResultOnBigList()
{
List<PocketTag> items = await client.GetTags();
items.ForEach(tag =>
{
Assert.True(tags.Contains(tag.Name));
});
Assert.Equal(items.Count, tags.Length);
}
private async Task FillAccount(int offset, int count)
{
int r;
int r2;
string[] tag;
Random rnd = new Random();
foreach (string url in urls.Skip(offset).Take(count))
{
r = rnd.Next(tags.Length);
r2 = rnd.Next(tags.Length);
tag = new string[] { tags[r], tags[r2] };
await client.Add(new Uri("http://" + url), tag);
}
}
}
}
+2 -3
View File
@@ -1,8 +1,7 @@
using System; using System;
using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit; using Xunit;
using PocketSharp.Models;
namespace PocketSharp.Tests namespace PocketSharp.Tests
{ {
@@ -10,7 +9,7 @@ namespace PocketSharp.Tests
{ {
protected PocketClient client; protected PocketClient client;
protected List<int> itemsToDelete = new List<int>(); protected List<string> itemsToDelete = new List<string>();
// setup // setup
+1 -1
View File
@@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.15.0" newVersion="4.2.15.0" /> <bindingRedirect oldVersion="0.0.0.0-4.2.18.0" newVersion="4.2.18.0" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
+4 -4
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="net45" /> <package id="Microsoft.Bcl" version="1.1.6" targetFramework="net45" />
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="net45" /> <package id="Microsoft.Bcl.Async" version="1.0.165" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="net45" /> <package id="Microsoft.Bcl.Build" version="1.0.13" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="net45" /> <package id="Microsoft.Net.Http" version="2.2.18" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" /> <package id="xunit" version="1.9.2" targetFramework="net45" />
</packages> </packages>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+10
View File
@@ -28,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SgmlReader", "PortablePorts
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PortablePorts", "PortablePorts", "{82F79DE3-76D7-4FCB-AA7E-16BA7E363E0D}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PortablePorts", "PortablePorts", "{82F79DE3-76D7-4FCB-AA7E-16BA7E363E0D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Reader", "PocketSharp.Reader\PocketSharp.Reader.csproj", "{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -105,6 +107,14 @@ Global
{9112414C-E2D1-43BA-A298-A89F77D94332}.Release|Any CPU.Build.0 = Release|Any CPU {9112414C-E2D1-43BA-A298-A89F77D94332}.Release|Any CPU.Build.0 = Release|Any CPU
{9112414C-E2D1-43BA-A298-A89F77D94332}.Release|ARM.ActiveCfg = Release|Any CPU {9112414C-E2D1-43BA-A298-A89F77D94332}.Release|ARM.ActiveCfg = Release|Any CPU
{9112414C-E2D1-43BA-A298-A89F77D94332}.Release|x86.ActiveCfg = Release|Any CPU {9112414C-E2D1-43BA-A298-A89F77D94332}.Release|x86.ActiveCfg = Release|Any CPU
{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}.Debug|ARM.ActiveCfg = Debug|Any CPU
{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}.Debug|x86.ActiveCfg = Debug|Any CPU
{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}.Release|Any CPU.Build.0 = Release|Any CPU
{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}.Release|ARM.ActiveCfg = Release|Any CPU
{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
+17 -29
View File
@@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PocketSharp namespace PocketSharp
@@ -14,10 +15,11 @@ namespace PocketSharp
/// <summary> /// <summary>
/// Retrieves the requestCode from Pocket, which is used to generate the Authentication URI to authenticate the user /// Retrieves the requestCode from Pocket, which is used to generate the Authentication URI to authenticate the user
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="System.NullReferenceException">Authentication methods need a callbackUri on initialization of the PocketClient class</exception> /// <exception cref="System.NullReferenceException">Authentication methods need a callbackUri on initialization of the PocketClient class</exception>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<string> GetRequestCode() public async Task<string> GetRequestCode(CancellationToken cancellationToken = default(CancellationToken))
{ {
// check if request code is available // check if request code is available
if (CallbackUri == null) if (CallbackUri == null)
@@ -26,7 +28,7 @@ namespace PocketSharp
} }
// do request // do request
RequestCode response = await Request<RequestCode>("oauth/request", new Dictionary<string, string>() RequestCode response = await Request<RequestCode>("oauth/request", cancellationToken, new Dictionary<string, string>()
{ {
{ "redirect_uri", CallbackUri } { "redirect_uri", CallbackUri }
}, false); }, false);
@@ -48,13 +50,13 @@ namespace PocketSharp
public Uri GenerateAuthenticationUri(string requestCode = null) public Uri GenerateAuthenticationUri(string requestCode = null)
{ {
// check if request code is available // check if request code is available
if(RequestCode == null && requestCode == null) if (RequestCode == null && requestCode == null)
{ {
throw new NullReferenceException("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 // override property with given param if available
if(requestCode != null) if (requestCode != null)
{ {
RequestCode = requestCode; RequestCode = requestCode;
} }
@@ -63,30 +65,17 @@ namespace PocketSharp
} }
/// <summary>
/// Requests the access code after authentication
/// The access code has to permanently be stored within the users session, and should be passed in the constructor 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>
[Obsolete("Please use GetUser instead")]
public async Task<string> GetAccessCode(string requestCode = null)
{
await GetUser(requestCode);
return AccessCode;
}
/// <summary> /// <summary>
/// Requests the access code and username after authentication /// Requests the access code and username after authentication
/// The access code has to permanently be stored within the users session, and should be passed in the constructor for all future PocketClient initializations. /// The access code has to permanently be stored within the users session, and should be passed in the constructor for all future PocketClient initializations.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="requestCode">The request code.</param> /// <param name="requestCode">The request code.</param>
/// <returns>The authenticated user</returns> /// <returns>
/// The authenticated user
/// </returns>
/// <exception cref="System.NullReferenceException">Call GetRequestCode() first to receive a request_code</exception> /// <exception cref="System.NullReferenceException">Call GetRequestCode() first to receive a request_code</exception>
public async Task<PocketUser> GetUser(string requestCode = null) public async Task<PocketUser> GetUser(string requestCode = null, CancellationToken cancellationToken = default(CancellationToken))
{ {
// check if request code is available // check if request code is available
if (RequestCode == null && requestCode == null) if (RequestCode == null && requestCode == null)
@@ -101,7 +90,7 @@ namespace PocketSharp
} }
// do request // do request
PocketUser response = await Request<PocketUser>("oauth/authorize", new Dictionary<string, string>() PocketUser response = await Request<PocketUser>("oauth/authorize", cancellationToken, new Dictionary<string, string>()
{ {
{"code", RequestCode} {"code", RequestCode}
}, false); }, false);
@@ -120,17 +109,16 @@ namespace PocketSharp
/// <param name="username">The username.</param> /// <param name="username">The username.</param>
/// <param name="email">The email.</param> /// <param name="email">The email.</param>
/// <param name="password">The password.</param> /// <param name="password">The password.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="System.ArgumentNullException">All parameters are required</exception> /// <exception cref="System.ArgumentNullException">All parameters are required</exception>
/// <exception cref="System.FormatException"> /// <exception cref="System.FormatException">Invalid email address.
/// Invalid email address.
/// or /// or
/// Invalid username. Please only use letters, numbers, and/or dashes and between 1-20 characters. /// Invalid username. Please only use letters, numbers, and/or dashes and between 1-20 characters.
/// or /// or
/// Invalid password. /// Invalid password.</exception>
/// </exception>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RegisterAccount(string username, string email, string password) public async Task<bool> RegisterAccount(string username, string email, string password, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (username == null || email == null || password == null) if (username == null || email == null || password == null)
{ {
@@ -162,7 +150,7 @@ namespace PocketSharp
Password = password Password = password
}; };
ResponseBase response = await Request<ResponseBase>("signup", parameters.Convert(), false); ResponseBase response = await Request<ResponseBase>("signup", cancellationToken, parameters.Convert(), false);
return response.Status; return response.Status;
} }
+19 -3
View File
@@ -1,5 +1,6 @@
using PocketSharp.Models; using PocketSharp.Models;
using System; using System;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PocketSharp namespace PocketSharp
@@ -16,10 +17,25 @@ namespace PocketSharp
/// <param name="tags">A comma-separated list of tags to apply to the item</param> /// <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="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> /// <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>A simple representation of the saved item which doesn't contain all data (is only returned by calling the Retrieve method)</returns> /// <param name="cancellationToken">The cancellation token.</param>
/// <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="System.FormatException">(1) Uri should be absolute.</exception>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<PocketItem> Add(Uri uri, string[] tags = null, string title = null, string tweetID = null) public async Task<PocketItem> Add(
Uri uri,
string[] tags = null,
string title = null,
string tweetID = null,
CancellationToken cancellationToken = default(CancellationToken)
)
{ {
if (!uri.IsAbsoluteUri)
{
throw new FormatException("(1) Uri should be absolute.");
}
AddParameters parameters = new AddParameters() AddParameters parameters = new AddParameters()
{ {
Uri = uri, Uri = uri,
@@ -28,7 +44,7 @@ namespace PocketSharp
TweetID = tweetID TweetID = tweetID
}; };
Add response = await Request<Add>("add", parameters.Convert()); Add response = await Request<Add>("add", cancellationToken, parameters.Convert());
return response.Item; return response.Item;
} }
+42 -29
View File
@@ -1,8 +1,9 @@
using PocketSharp.Models; using PocketSharp.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace PocketSharp namespace PocketSharp
{ {
@@ -11,22 +12,23 @@ namespace PocketSharp
/// </summary> /// </summary>
public partial class PocketClient public partial class PocketClient
{ {
/// <summary> /// <summary>
/// Retrieves items from pocket /// Retrieves items from pocket
/// with the given filters /// with the given filters
/// </summary> /// </summary>
/// <param name="state">The state.</param> /// <param name="state">The state.</param>
/// <param name="favorite">The favorite.</param> /// <param name="favorite">The favorite.</param>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <param name="contentType">Type of the content.</param> /// <param name="contentType">Type of the content.</param>
/// <param name="sort">The sort.</param> /// <param name="sort">The sort.</param>
/// <param name="search">The search.</param> /// <param name="search">The search.</param>
/// <param name="domain">The domain.</param> /// <param name="domain">The domain.</param>
/// <param name="since">The since.</param> /// <param name="since">The since.</param>
/// <param name="count">The count.</param> /// <param name="count">The count.</param>
/// <param name="offset">The offset.</param> /// <param name="offset">The offset.</param>
/// <returns></returns> /// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="PocketException"></exception> /// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> Get( public async Task<List<PocketItem>> Get(
State? state = null, State? state = null,
bool? favorite = null, bool? favorite = null,
@@ -37,7 +39,8 @@ namespace PocketSharp
string domain = null, string domain = null,
DateTime? since = null, DateTime? since = null,
int? count = null, int? count = null,
int? offset = null int? offset = null,
CancellationToken cancellationToken = default(CancellationToken)
) )
{ {
RetrieveParameters parameters = new RetrieveParameters() RetrieveParameters parameters = new RetrieveParameters()
@@ -55,7 +58,7 @@ namespace PocketSharp
Offset = offset Offset = offset
}; };
Retrieve response = await Request<Retrieve>("get", parameters.Convert()); Retrieve response = await Request<Retrieve>("get", cancellationToken, parameters.Convert());
return response.Items; return response.Items;
} }
@@ -66,11 +69,13 @@ namespace PocketSharp
/// 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. /// 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> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<PocketItem> Get(int itemID) public async Task<PocketItem> Get(string itemID, CancellationToken cancellationToken = default(CancellationToken))
{ {
List<PocketItem> items = await Get( List<PocketItem> items = await Get(
cancellationToken: cancellationToken,
state: State.all state: State.all
); );
@@ -82,13 +87,14 @@ namespace PocketSharp
/// Retrieves all items by a given filter /// Retrieves all items by a given filter
/// </summary> /// </summary>
/// <param name="filter">The filter.</param> /// <param name="filter">The filter.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> Get(RetrieveFilter filter) public async Task<List<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken))
{ {
RetrieveParameters parameters = new RetrieveParameters(); RetrieveParameters parameters = new RetrieveParameters();
switch(filter) switch (filter)
{ {
case RetrieveFilter.Article: case RetrieveFilter.Article:
parameters.ContentType = ContentType.article; parameters.ContentType = ContentType.article;
@@ -115,7 +121,7 @@ namespace PocketSharp
parameters.DetailType = DetailType.complete; parameters.DetailType = DetailType.complete;
Retrieve response = await Request<Retrieve>("get", parameters.Convert()); Retrieve response = await Request<Retrieve>("get", cancellationToken, parameters.Convert());
return response.Items; return response.Items;
} }
@@ -125,11 +131,13 @@ namespace PocketSharp
/// Retrieves all available tags. /// 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. /// Note: The Pocket API contains no method, which allows to retrieve all tags, so all items are retrieved and the associated tags extracted.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<List<PocketTag>> GetTags() public async Task<List<PocketTag>> GetTags(CancellationToken cancellationToken = default(CancellationToken))
{ {
List<PocketItem> items = await Get( List<PocketItem> items = await Get(
cancellationToken: cancellationToken,
state: State.all state: State.all
); );
@@ -145,11 +153,15 @@ namespace PocketSharp
/// Retrieves items by tag /// Retrieves items by tag
/// </summary> /// </summary>
/// <param name="tag">The tag.</param> /// <param name="tag">The tag.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> SearchByTag(string tag) public async Task<List<PocketItem>> SearchByTag(string tag, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await Get(tag: tag); return await Get(
cancellationToken: cancellationToken,
tag: tag
);
} }
@@ -157,13 +169,14 @@ namespace PocketSharp
/// Retrieves items which match the specified search string in title and URI /// Retrieves items which match the specified search string in title and URI
/// </summary> /// </summary>
/// <param name="searchString">The search string.</param> /// <param name="searchString">The search string.</param>
/// <param name="searchInUri">if set to <c>true</c> [search in URI].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception> /// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<List<PocketItem>> Search(string searchString, bool searchInUri = true) public async Task<List<PocketItem>> Search(string searchString, bool searchInUri = true, CancellationToken cancellationToken = default(CancellationToken))
{ {
List<PocketItem> items = await Get(RetrieveFilter.All); List<PocketItem> items = await Get(RetrieveFilter.All, cancellationToken);
return Search(items, searchString); return Search(items, searchString);
} }
+50 -23
View File
@@ -1,4 +1,6 @@
using PocketSharp.Models; using PocketSharp.Models;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PocketSharp namespace PocketSharp
@@ -8,15 +10,30 @@ namespace PocketSharp
/// </summary> /// </summary>
public partial class PocketClient public partial class PocketClient
{ {
/// <summary>
/// Sends multiple actions in one request.
/// See: http://getpocket.com/developer/docs/v3/modify
/// </summary>
/// <param name="actions">The actions.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
public async Task<bool> SendActions(List<PocketAction> actions, CancellationToken cancellationToken = default(CancellationToken))
{
return await Send(actions, cancellationToken);
}
/// <summary> /// <summary>
/// Archives the specified item. /// Archives the specified item.
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Archive(int itemID) public async Task<bool> Archive(string itemID, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendDefault(itemID, "archive"); return await SendDefault(cancellationToken, itemID, "archive");
} }
@@ -24,11 +41,12 @@ namespace PocketSharp
/// Archives the specified item. /// Archives the specified item.
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Archive(PocketItem item) public async Task<bool> Archive(PocketItem item, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await Archive(item.ID); return await Archive(item.ID, cancellationToken);
} }
@@ -36,11 +54,12 @@ namespace PocketSharp
/// Un-archives the specified item (alias for Readd). /// Un-archives the specified item (alias for Readd).
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Unarchive(int itemID) public async Task<bool> Unarchive(string itemID, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendDefault(itemID, "readd"); return await SendDefault(cancellationToken, itemID, "readd");
} }
@@ -48,11 +67,12 @@ namespace PocketSharp
/// Unarchives the specified item. /// Unarchives the specified item.
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Unarchive(PocketItem item) public async Task<bool> Unarchive(PocketItem item, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await Unarchive(item.ID); return await Unarchive(item.ID, cancellationToken);
} }
@@ -60,11 +80,12 @@ namespace PocketSharp
/// Favorites the specified item. /// Favorites the specified item.
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Favorite(int itemID) public async Task<bool> Favorite(string itemID, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendDefault(itemID, "favorite"); return await SendDefault(cancellationToken, itemID, "favorite");
} }
@@ -72,11 +93,12 @@ namespace PocketSharp
/// Favorites the specified item. /// Favorites the specified item.
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Favorite(PocketItem item) public async Task<bool> Favorite(PocketItem item, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await Favorite(item.ID); return await Favorite(item.ID, cancellationToken);
} }
@@ -84,11 +106,12 @@ namespace PocketSharp
/// Un-favorites the specified item. /// Un-favorites the specified item.
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Unfavorite(int itemID) public async Task<bool> Unfavorite(string itemID, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendDefault(itemID, "unfavorite"); return await SendDefault(cancellationToken, itemID, "unfavorite");
} }
@@ -96,50 +119,54 @@ namespace PocketSharp
/// Un-favorites the specified item. /// Un-favorites the specified item.
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Unfavorite(PocketItem item) public async Task<bool> Unfavorite(PocketItem item, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await Unfavorite(item.ID); return await Unfavorite(item.ID, cancellationToken);
} }
/// <summary> /// <summary>
/// Deletes the specified item. /// Deletes the specified item.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> Delete(int itemID) public async Task<bool> Delete(string itemID, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendDefault(itemID, "delete"); return await SendDefault(cancellationToken, itemID, "delete");
} }
/// <summary> /// <summary>
/// Deletes the specified item. /// Deletes the specified item.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <returns></returns> /// <returns></returns>
public async Task<bool> Delete(PocketItem item) public async Task<bool> Delete(PocketItem item, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await Delete(item.ID); return await Delete(item.ID, cancellationToken);
} }
/// <summary> /// <summary>
/// Puts an action /// Puts an action
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="action">The action.</param> /// <param name="action">The action.</param>
/// <returns></returns> /// <returns></returns>
protected async Task<bool> SendDefault(int itemID, string action) protected async Task<bool> SendDefault(CancellationToken cancellationToken, string itemID, string action)
{ {
return await Send(new ActionParameter() return await Send(new PocketAction()
{ {
Action = action, Action = action,
ID = itemID ID = itemID
}); }, cancellationToken);
} }
} }
} }
+44 -30
View File
@@ -1,4 +1,5 @@
using PocketSharp.Models; using PocketSharp.Models;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PocketSharp namespace PocketSharp
@@ -13,11 +14,12 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="tags">The tags.</param> /// <param name="tags">The tags.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> AddTags(int itemID, string[] tags) public async Task<bool> AddTags(string itemID, string[] tags, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendTags(itemID, "tags_add", tags); return await SendTags(cancellationToken, itemID, "tags_add", tags);
} }
@@ -26,11 +28,12 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="tags">The tags.</param> /// <param name="tags">The tags.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> AddTags(PocketItem item, string[] tags) public async Task<bool> AddTags(PocketItem item, string[] tags, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await AddTags(item.ID, tags); return await AddTags(item.ID, tags, cancellationToken);
} }
@@ -39,11 +42,12 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="tags">The tags.</param> /// <param name="tags">The tags.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTags(int itemID, string[] tags) public async Task<bool> RemoveTags(string itemID, string[] tags, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendTags(itemID, "tags_remove", tags); return await SendTags(cancellationToken, itemID, "tags_remove", tags);
} }
@@ -52,11 +56,12 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="tags">The tag.</param> /// <param name="tags">The tag.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTags(PocketItem item, string[] tags) public async Task<bool> RemoveTags(PocketItem item, string[] tags, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await RemoveTags(item.ID, tags); return await RemoveTags(item.ID, tags, cancellationToken);
} }
@@ -64,12 +69,13 @@ namespace PocketSharp
/// Removes a tag from an item. /// Removes a tag from an item.
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="tags">The tag.</param> /// <param name="tag">The tag.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTag(int itemID, string tag) public async Task<bool> RemoveTag(string itemID, string tag, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendTags(itemID, "tags_remove", new string[] { tag }); return await SendTags(cancellationToken, itemID, "tags_remove", new string[] { tag });
} }
@@ -77,12 +83,13 @@ namespace PocketSharp
/// Removes a tag from an item. /// Removes a tag from an item.
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="tags">The tags.</param> /// <param name="tag">The tag.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTag(PocketItem item, string tag) public async Task<bool> RemoveTag(PocketItem item, string tag, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await RemoveTag(item.ID, tag); return await RemoveTag(item.ID, tag, cancellationToken);
} }
@@ -90,11 +97,12 @@ namespace PocketSharp
/// Clears all tags from an item. /// Clears all tags from an item.
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTags(int itemID) public async Task<bool> RemoveTags(string itemID, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendDefault(itemID, "tags_clear"); return await SendDefault(cancellationToken, itemID, "tags_clear");
} }
@@ -102,11 +110,12 @@ namespace PocketSharp
/// Clears all tags from an item. /// Clears all tags from an item.
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RemoveTags(PocketItem item) public async Task<bool> RemoveTags(PocketItem item, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await RemoveTags(item.ID); return await RemoveTags(item.ID, cancellationToken);
} }
@@ -115,11 +124,12 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="tags">The tags.</param> /// <param name="tags">The tags.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> ReplaceTags(int itemID, string[] tags) public async Task<bool> ReplaceTags(string itemID, string[] tags, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await SendTags(itemID, "tags_replace", tags); return await SendTags(cancellationToken, itemID, "tags_replace", tags);
} }
@@ -128,11 +138,12 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="tags">The tags.</param> /// <param name="tags">The tags.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> ReplaceTags(PocketItem item, string[] tags) public async Task<bool> ReplaceTags(PocketItem item, string[] tags, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await ReplaceTags(item.ID, tags); return await ReplaceTags(item.ID, tags, cancellationToken);
} }
@@ -142,17 +153,18 @@ namespace PocketSharp
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="oldTag">The old tag.</param> /// <param name="oldTag">The old tag.</param>
/// <param name="newTag">The new tag name.</param> /// <param name="newTag">The new tag name.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RenameTag(int itemID, string oldTag, string newTag) public async Task<bool> RenameTag(string itemID, string oldTag, string newTag, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await Send(new ActionParameter() return await Send(new PocketAction()
{ {
Action = "tag_rename", Action = "tag_rename",
ID = itemID, ID = itemID,
OldTag = oldTag, OldTag = oldTag,
NewTag = newTag NewTag = newTag
}); }, cancellationToken);
} }
@@ -162,29 +174,31 @@ namespace PocketSharp
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <param name="oldTag">The old tag.</param> /// <param name="oldTag">The old tag.</param>
/// <param name="newTag">The new tag name.</param> /// <param name="newTag">The new tag name.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<bool> RenameTag(PocketItem item, string oldTag, string newTag) public async Task<bool> RenameTag(PocketItem item, string oldTag, string newTag, CancellationToken cancellationToken = default(CancellationToken))
{ {
return await RenameTag(item.ID, oldTag, newTag); return await RenameTag(item.ID, oldTag, newTag, cancellationToken);
} }
/// <summary> /// <summary>
/// Puts the send action for tags. /// Puts the send action for tags.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="itemID">The item ID.</param> /// <param name="itemID">The item ID.</param>
/// <param name="action">The action.</param> /// <param name="action">The action.</param>
/// <param name="tags">The tags.</param> /// <param name="tags">The tags.</param>
/// <returns></returns> /// <returns></returns>
protected async Task<bool> SendTags(int itemID, string action, string[] tags) protected async Task<bool> SendTags(CancellationToken cancellationToken, string itemID, string action, string[] tags)
{ {
return await Send(new ActionParameter() return await Send(new PocketAction()
{ {
Action = action, Action = action,
ID = itemID, ID = itemID,
Tags = tags Tags = tags
}); }, cancellationToken);
} }
} }
} }
+10 -16
View File
@@ -1,5 +1,6 @@
using PocketSharp.Models; using PocketSharp.Models;
using System; using System;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PocketSharp namespace PocketSharp
@@ -12,23 +13,12 @@ namespace PocketSharp
/// <summary> /// <summary>
/// Statistics from the user account. /// Statistics from the user account.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<PocketStatistics> GetUserStatistics() public async Task<PocketStatistics> GetUserStatistics(CancellationToken cancellationToken = default(CancellationToken))
{ {
return await Request<PocketStatistics>("stats"); return await Request<PocketStatistics>("stats", cancellationToken);
}
/// <summary>
/// Statistics from the user account.
/// </summary>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
[Obsolete("Please use GetUserStatistics instead")]
public async Task<PocketStatistics> Statistics()
{
return await GetUserStatistics();
} }
@@ -37,16 +27,20 @@ namespace PocketSharp
/// If a request was made before, the data is returned synchronously from the cache. /// If a request was made before, the data is returned synchronously from the cache.
/// Note: This method only works for authenticated users with a given AccessCode. /// Note: This method only works for authenticated users with a given AccessCode.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException"></exception> /// <exception cref="PocketException"></exception>
public async Task<PocketLimits> GetUsageLimits() public async Task<PocketLimits> GetUsageLimits(CancellationToken cancellationToken = default(CancellationToken))
{ {
string rateLimitForConsumerKey = TryGetHeaderValue(lastHeaders, "X-Limit-Key-Limit"); string rateLimitForConsumerKey = TryGetHeaderValue(lastHeaders, "X-Limit-Key-Limit");
if (rateLimitForConsumerKey == null) if (rateLimitForConsumerKey == null)
{ {
// this is the fastest way to do a non-failing request to receive the correct headers // this is the fastest way to do a non-failing request to receive the correct headers
await Get(count: 1); await Get(
cancellationToken: cancellationToken,
count: 1
);
} }
return new PocketLimits() return new PocketLimits()
+448
View File
@@ -0,0 +1,448 @@
using PocketSharp.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace PocketSharp
{
public interface IPocketClient
{
#region properties
/// <summary>
/// callback URLi for API calls
/// </summary>
/// <value>
/// The callback URI.
/// </value>
string CallbackUri { get; set; }
/// <summary>
/// Accessor for the Pocket API key
/// see: http://getpocket.com/developer
/// </summary>
/// <value>
/// The consumer key.
/// </value>
string ConsumerKey { get; set; }
/// <summary>
/// Code retrieved on authentification
/// </summary>
/// <value>
/// The request code.
/// </value>
string RequestCode { get; set; }
/// <summary>
/// Code retrieved on authentification-success
/// </summary>
/// <value>
/// The access code.
/// </value>
string AccessCode { get; set; }
#endregion
#region account methods
/// <summary>
/// Retrieves the requestCode from Pocket, which is used to generate the Authentication URI to authenticate the user
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="System.NullReferenceException">Authentication methods need a callbackUri on initialization of the PocketClient class</exception>
/// <exception cref="PocketException"></exception>
Task<string> GetRequestCode(CancellationToken cancellationToken = default(CancellationToken));
/// <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>
Uri GenerateAuthenticationUri(string requestCode = null);
/// <summary>
/// Requests the access code and username after authentication
/// The access code has to permanently be stored within the users session, and should be passed in the constructor for all future PocketClient initializations.
/// </summary>
/// <param name="requestCode">The request code.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// The authenticated user
/// </returns>
/// <exception cref="System.NullReferenceException">Call GetRequestCode() first to receive a request_code</exception>
Task<PocketUser> GetUser(string requestCode = null, CancellationToken cancellationToken = default(CancellationToken));
/// <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>
/// <param name="cancellationToken">The cancellation token.</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.
/// or
/// Invalid password.</exception>
/// <exception cref="PocketException"></exception>
Task<bool> RegisterAccount(string username, string email, string password, CancellationToken cancellationToken = default(CancellationToken));
#endregion
#region add methods
/// <summary>
/// Adds a new item to pocket
/// </summary>
/// <param name="uri">The URL of the item you want to save</param>
/// <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>
/// <param name="cancellationToken">The cancellation token.</param>
/// <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="System.FormatException">(1) Uri should be absolute.</exception>
/// <exception cref="PocketException"></exception>
Task<PocketItem> Add(Uri uri, string[] tags = null, string title = null, string tweetID = null, CancellationToken cancellationToken = default(CancellationToken));
#endregion
#region get methods
/// <summary>
/// Retrieves items from pocket
/// with the given filters
/// </summary>
/// <param name="state">The state.</param>
/// <param name="favorite">The favorite.</param>
/// <param name="tag">The tag.</param>
/// <param name="contentType">Type of the content.</param>
/// <param name="sort">The sort.</param>
/// <param name="search">The search.</param>
/// <param name="domain">The domain.</param>
/// <param name="since">The since.</param>
/// <param name="count">The count.</param>
/// <param name="offset">The offset.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
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,
CancellationToken cancellationToken = default(CancellationToken)
);
/// <summary>
/// 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>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<PocketItem> Get(string itemID, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Retrieves all items by a given filter
/// </summary>
/// <param name="filter">The filter.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<List<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// 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="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<List<PocketTag>> GetTags(CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Retrieves items by tag
/// </summary>
/// <param name="tag">The tag.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<List<PocketItem>> SearchByTag(string tag, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Retrieves items which match the specified search string in title and URI
/// </summary>
/// <param name="searchString">The search string.</param>
/// <param name="searchInUri">if set to <c>true</c> [search in URI].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
/// <exception cref="PocketException"></exception>
Task<List<PocketItem>> Search(string searchString, bool searchInUri = true, CancellationToken cancellationToken = default(CancellationToken));
/// <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>
List<PocketItem> Search(List<PocketItem> availableItems, string searchString);
#endregion
#region modify methods
/// <summary>
/// Sends multiple actions in one request.
/// See: http://getpocket.com/developer/docs/v3/modify
/// </summary>
/// <param name="actions">The actions.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> SendActions(List<PocketAction> actions, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Archives the specified item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Archive(string itemID, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Archives the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Archive(PocketItem item, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Un-archives the specified item (alias for Readd).
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Unarchive(string itemID, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Unarchives the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Unarchive(PocketItem item, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Favorites the specified item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Favorite(string itemID, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Favorites the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Favorite(PocketItem item, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Un-favorites the specified item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Unfavorite(string itemID, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Un-favorites the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Unfavorite(PocketItem item, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Deletes the specified item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> Delete(string itemID, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Deletes the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
Task<bool> Delete(PocketItem item, CancellationToken cancellationToken = default(CancellationToken));
#endregion
#region modify tags methods
/// <summary>
/// Adds the specified tags to an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="tags">The tags.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> AddTags(string itemID, string[] tags, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Adds the specified tags to an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="tags">The tags.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> AddTags(PocketItem item, string[] tags, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Removes the specified tags from an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="tags">The tags.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> RemoveTags(string itemID, string[] tags, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Removes the specified tags from an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="tags">The tag.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> RemoveTags(PocketItem item, string[] tags, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Removes a tag from an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="tag">The tag.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> RemoveTag(string itemID, string tag, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Removes a tag from an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="tag">The tag.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> RemoveTag(PocketItem item, string tag, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Clears all tags from an item.
/// </summary>
/// <param name="itemID">The item ID.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> RemoveTags(string itemID, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Clears all tags from an item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> RemoveTags(PocketItem item, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// 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>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> ReplaceTags(string itemID, string[] tags, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// 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>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> ReplaceTags(PocketItem item, string[] tags, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// 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>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> RenameTag(string itemID, string oldTag, string newTag, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// 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>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<bool> RenameTag(PocketItem item, string oldTag, string newTag, CancellationToken cancellationToken = default(CancellationToken));
#endregion
#region statistics methods
/// <summary>
/// Statistics from the user account.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<PocketStatistics> GetUserStatistics(CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Returns API usage statistics.
/// If a request was made before, the data is returned synchronously from the cache.
/// Note: This method only works for authenticated users with a given AccessCode.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns>
/// <exception cref="PocketException"></exception>
Task<PocketLimits> GetUsageLimits(CancellationToken cancellationToken = default(CancellationToken));
#endregion
}
}
@@ -5,10 +5,10 @@ using System.Runtime.Serialization;
namespace PocketSharp.Models namespace PocketSharp.Models
{ {
/// <summary> /// <summary>
/// All parameters which can be passed for a modify action /// All parameters which can be passed for a send action
/// </summary> /// </summary>
[DataContract] [DataContract]
internal class ActionParameter public class PocketAction
{ {
/// <summary> /// <summary>
/// Gets or sets the action. /// Gets or sets the action.
@@ -20,13 +20,40 @@ namespace PocketSharp.Models
public string Action { get; set; } public string Action { get; set; }
/// <summary> /// <summary>
/// Gets or sets the ID. /// Gets or sets the PocketItem ID.
/// </summary> /// </summary>
/// <value> /// <value>
/// The ID. /// The ID.
/// </value> /// </value>
[DataMember(Name = "item_id")] [DataMember(Name = "item_id")]
public int ID { get; set; } public string ID { get; set; }
/// <summary>
/// Gets or sets the URI (for adding a new item).
/// </summary>
/// <value>
/// The URI.
/// </value>
[DataMember(Name = "url")]
public Uri Uri { get; set; }
/// <summary>
/// Gets or sets the Title (for adding a new item).
/// </summary>
/// <value>
/// The Title.
/// </value>
[DataMember(Name = "title")]
public string Title { get; set; }
/// <summary>
/// Gets or sets the associated Tweet ID.
/// </summary>
/// <value>
/// The Tweet ID.
/// </value>
[DataMember(Name = "ref_id")]
public string TweetID { get; set; }
/// <summary> /// <summary>
/// Gets or sets the time. /// Gets or sets the time.
@@ -71,14 +98,15 @@ namespace PocketSharp.Models
/// Converts this instance to a parameter list. /// Converts this instance to a parameter list.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public Dictionary<string, object> Convert() internal Dictionary<string, object> Convert()
{ {
Dictionary<string, object> parameters = new Dictionary<string, object> Dictionary<string, object> parameters = new Dictionary<string, object>
{ {
{ "item_id", ID.ToString() },
{ "action", Action } { "action", Action }
}; };
if (ID != "0" && !String.IsNullOrEmpty(ID.ToString()))
parameters.Add("item_id", ID.ToString());
if (Time != null) if (Time != null)
parameters.Add("time", Time != null ? Utilities.GetUnixTimestamp(Time).ToString() : null); parameters.Add("time", Time != null ? Utilities.GetUnixTimestamp(Time).ToString() : null);
if (Tags != null) if (Tags != null)
@@ -87,6 +115,12 @@ namespace PocketSharp.Models
parameters.Add("old_tag", OldTag); parameters.Add("old_tag", OldTag);
if (NewTag != null) if (NewTag != null)
parameters.Add("new_tag", NewTag); parameters.Add("new_tag", NewTag);
if (!String.IsNullOrEmpty(Title))
parameters.Add("title", Title);
if (!String.IsNullOrEmpty(TweetID))
parameters.Add("ref_id", TweetID);
if (Uri != null)
parameters.Add("uri", Uri.ToString());
return parameters; return parameters;
} }
+3 -3
View File
@@ -1,5 +1,5 @@
using System; using PropertyChanged;
using PropertyChanged; using System;
namespace PocketSharp.Models namespace PocketSharp.Models
{ {
@@ -15,7 +15,7 @@ namespace PocketSharp.Models
/// <value> /// <value>
/// The pocket item ID. /// The pocket item ID.
/// </value> /// </value>
public int PocketItemID { get; set; } public string PocketItemID { get; set; }
/// <summary> /// <summary>
/// Gets or sets the content. /// Gets or sets the content.
+9
View File
@@ -0,0 +1,9 @@
namespace PocketSharp.Models
{
internal enum PocketBoolean
{
No = 0,
Yes = 1,
IsType = 2
}
}
+127 -79
View File
@@ -1,7 +1,8 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using PropertyChanged;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using PropertyChanged; using System.Diagnostics;
namespace PocketSharp.Models namespace PocketSharp.Models
{ {
@@ -11,6 +12,7 @@ namespace PocketSharp.Models
/// </summary> /// </summary>
[JsonObject] [JsonObject]
[ImplementPropertyChanged] [ImplementPropertyChanged]
[DebuggerDisplay("Uri = {Uri}, Title = {Title}")]
public class PocketItem public class PocketItem
{ {
/// <summary> /// <summary>
@@ -20,7 +22,34 @@ namespace PocketSharp.Models
/// The ID. /// The ID.
/// </value> /// </value>
[JsonProperty("item_id")] [JsonProperty("item_id")]
public int ID { get; set; } public string ID { get; set; }
/// <summary>
/// Gets or sets the resolved identifier.
/// </summary>
/// <value>
/// The resolved identifier.
/// </value>
[JsonProperty("resolved_id")]
public string ResolvedId { get; set; }
/// <summary>
/// Gets or sets the normal URI.
/// </summary>
/// <value>
/// The normal URI.
/// </value>
[JsonProperty("normal_url")]
private Uri _NormalUri { get; set; }
/// <summary>
/// Gets or sets the resolved URI.
/// </summary>
/// <value>
/// The resolved URI.
/// </value>
[JsonProperty("resolved_url")]
private Uri _ResolvedUri { get; set; }
/// <summary> /// <summary>
/// Gets or sets the URI. /// Gets or sets the URI.
@@ -28,8 +57,12 @@ namespace PocketSharp.Models
/// <value> /// <value>
/// The URI. /// The URI.
/// </value> /// </value>
[JsonProperty("resolved_url")] [JsonIgnore]
public Uri Uri { get; set; } public Uri Uri
{
get { return _ResolvedUri ?? _NormalUri; }
set { _NormalUri = value; _ResolvedUri = value; }
}
/// <summary> /// <summary>
/// Gets or sets the title. /// Gets or sets the title.
@@ -132,7 +165,7 @@ namespace PocketSharp.Models
/// <c>true</c> if this instance has image; otherwise, <c>false</c>. /// <c>true</c> if this instance has image; otherwise, <c>false</c>.
/// </value> /// </value>
[JsonProperty("has_image")] [JsonProperty("has_image")]
public bool HasImage { get; set; } private PocketBoolean? _HasImage { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether this instance has video. /// Gets or sets a value indicating whether this instance has video.
@@ -141,7 +174,67 @@ namespace PocketSharp.Models
/// <c>true</c> if this instance has video; otherwise, <c>false</c>. /// <c>true</c> if this instance has video; otherwise, <c>false</c>.
/// </value> /// </value>
[JsonProperty("has_video")] [JsonProperty("has_video")]
public bool HasVideo { get; set; } private PocketBoolean? _HasVideo { get; set; }
/// <summary>
/// Gets a value indicating whether [has image].
/// </summary>
/// <value>
/// <c>true</c> if [has image]; otherwise, <c>false</c>.
/// </value>
[JsonIgnore]
public bool HasImage
{
get
{
return _HasImage == PocketBoolean.Yes || _HasImage == PocketBoolean.IsType;
}
}
/// <summary>
/// Gets a value indicating whether [has video].
/// </summary>
/// <value>
/// <c>true</c> if [has video]; otherwise, <c>false</c>.
/// </value>
[JsonIgnore]
public bool HasVideo
{
get
{
return _HasVideo == PocketBoolean.Yes || _HasVideo == PocketBoolean.IsType;
}
}
/// <summary>
/// Gets a value indicating whether [is video].
/// </summary>
/// <value>
/// <c>true</c> if [is video]; otherwise, <c>false</c>.
/// </value>
[JsonIgnore]
public bool IsVideo
{
get
{
return _HasVideo == PocketBoolean.IsType;
}
}
/// <summary>
/// Gets a value indicating whether [is image].
/// </summary>
/// <value>
/// <c>true</c> if [is image]; otherwise, <c>false</c>.
/// </value>
[JsonIgnore]
public bool IsImage
{
get
{
return _HasImage == PocketBoolean.IsType;
}
}
/// <summary> /// <summary>
/// Gets or sets the word count. /// Gets or sets the word count.
@@ -200,65 +293,44 @@ namespace PocketSharp.Models
/// <summary> /// <summary>
/// Gets or sets the _ tag dictionary. /// Gets or sets the tags.
/// </summary>
/// <value>
/// The _ tag dictionary.
/// </value>
[JsonProperty("tags")]
private Dictionary<string, PocketTag> _TagDictionary { get; set; }
/// <summary>
/// Gets or sets the _ image dictionary.
/// </summary>
/// <value>
/// The _ image dictionary.
/// </value>
[JsonProperty("images")]
private Dictionary<string, PocketImage> _ImageDictionary { get; set; }
/// <summary>
/// Gets or sets the _ video dictionary.
/// </summary>
/// <value>
/// The _ video dictionary.
/// </value>
[JsonProperty("videos")]
private Dictionary<string, PocketVideo> _VideoDictionary { get; set; }
/// <summary>
/// Gets or sets the _ author dictionary.
/// </summary>
/// <value>
/// The _ author dictionary.
/// </value>
[JsonProperty("authors")]
private Dictionary<string, PocketAuthor> _AuthorDictionary { get; set; }
/// <summary>
/// Gets the tags.
/// </summary> /// </summary>
/// <value> /// <value>
/// The tags. /// The tags.
/// </value> /// </value>
[JsonIgnore] [JsonProperty("tags")]
public List<PocketTag> Tags [JsonConverter(typeof(ObjectToArrayConverter<PocketTag>))]
{ public List<PocketTag> Tags { get; set; }
get { return Utilities.DictionaryToList<PocketTag>(_TagDictionary); }
}
/// <summary> /// <summary>
/// Gets the images. /// Gets or sets the images.
/// </summary> /// </summary>
/// <value> /// <value>
/// The images. /// The images.
/// </value> /// </value>
[JsonIgnore] [JsonProperty("images")]
public List<PocketImage> Images [JsonConverter(typeof(ObjectToArrayConverter<PocketImage>))]
{ public List<PocketImage> Images { get; set; }
get { return Utilities.DictionaryToList<PocketImage>(_ImageDictionary); }
} /// <summary>
/// Gets or sets the videos.
/// </summary>
/// <value>
/// The videos.
/// </value>
[JsonProperty("videos")]
[JsonConverter(typeof(ObjectToArrayConverter<PocketVideo>))]
public List<PocketVideo> Videos { get; set; }
/// <summary>
/// Gets or sets the authors.
/// </summary>
/// <value>
/// The authors.
/// </value>
[JsonProperty("authors")]
[JsonConverter(typeof(ObjectToArrayConverter<PocketAuthor>))]
public List<PocketAuthor> Authors { get; set; }
/// <summary> /// <summary>
/// Gets the lead image. /// Gets the lead image.
@@ -271,29 +343,5 @@ namespace PocketSharp.Models
{ {
get { return Images != null && Images.Count > 0 ? Images[0] : null; } get { return Images != null && Images.Count > 0 ? Images[0] : null; }
} }
/// <summary>
/// Gets the videos.
/// </summary>
/// <value>
/// The videos.
/// </value>
[JsonIgnore]
public List<PocketVideo> Videos
{
get { return Utilities.DictionaryToList<PocketVideo>(_VideoDictionary); }
}
/// <summary>
/// Gets the authors.
/// </summary>
/// <value>
/// The authors.
/// </value>
[JsonIgnore]
public List<PocketAuthor> Authors
{
get { return Utilities.DictionaryToList<PocketAuthor>(_AuthorDictionary); }
}
} }
} }
+14 -14
View File
@@ -3,20 +3,20 @@ using PropertyChanged;
namespace PocketSharp.Models namespace PocketSharp.Models
{ {
/// <summary>
/// Tag
/// </summary>
[JsonObject]
[ImplementPropertyChanged]
public class PocketTag
{
/// <summary> /// <summary>
/// Tag /// Gets or sets the name.
/// </summary> /// </summary>
[JsonObject] /// <value>
[ImplementPropertyChanged] /// The name.
public class PocketTag /// </value>
{ [JsonProperty("tag")]
/// <summary> public string Name { get; set; }
/// Gets or sets the name. }
/// </summary>
/// <value>
/// The name.
/// </value>
[JsonProperty("tag")]
public string Name { get; set; }
}
} }
+30 -30
View File
@@ -4,38 +4,38 @@ using PropertyChanged;
namespace PocketSharp.Models namespace PocketSharp.Models
{ {
/// <summary>
/// Video
/// </summary>
[JsonObject]
[ImplementPropertyChanged]
public class PocketVideo
{
/// <summary> /// <summary>
/// Video /// Gets or sets the ID.
/// </summary> /// </summary>
[JsonObject] /// <value>
[ImplementPropertyChanged] /// The ID.
public class PocketVideo /// </value>
{ [JsonProperty("video_id")]
/// <summary> public string ID { get; set; }
/// Gets or sets the ID.
/// </summary>
/// <value>
/// The ID.
/// </value>
[JsonProperty("video_id")]
public string ID { get; set; }
/// <summary> /// <summary>
/// Gets or sets the external ID. /// Gets or sets the external ID.
/// </summary> /// </summary>
/// <value> /// <value>
/// The external ID. /// The external ID.
/// </value> /// </value>
[JsonProperty("vid")] [JsonProperty("vid")]
public string ExternalID { get; set; } public string ExternalID { get; set; }
/// <summary> /// <summary>
/// Gets or sets the URI. /// Gets or sets the URI.
/// </summary> /// </summary>
/// <value> /// <value>
/// The URI. /// The URI.
/// </value> /// </value>
[JsonProperty("src")] [JsonProperty("src")]
public Uri Uri { get; set; } public Uri Uri { get; set; }
} }
} }
+6 -16
View File
@@ -1,4 +1,5 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace PocketSharp.Models namespace PocketSharp.Models
@@ -24,17 +25,8 @@ namespace PocketSharp.Models
/// <value> /// <value>
/// The since. /// The since.
/// </value> /// </value>
[JsonProperty] [JsonProperty("since")]
public int Since { get; set; } public DateTime Since { get; set; }
/// <summary>
/// Gets or sets the _ item dictionary.
/// </summary>
/// <value>
/// The _ item dictionary.
/// </value>
[JsonProperty("list")]
public Dictionary<string, PocketItem> ItemDictionary { get; set; }
/// <summary> /// <summary>
/// Gets the items. /// Gets the items.
@@ -42,10 +34,8 @@ namespace PocketSharp.Models
/// <value> /// <value>
/// The items. /// The items.
/// </value> /// </value>
[JsonIgnore] [JsonProperty("list")]
public List<PocketItem> Items [JsonConverter(typeof(ObjectToArrayConverter<PocketItem>))]
{ public List<PocketItem> Items { get; set; }
get { return Utilities.DictionaryToList<PocketItem>(ItemDictionary); }
}
} }
} }
+66 -19
View File
@@ -1,19 +1,20 @@
using PocketSharp.Models; using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using PocketSharp.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
namespace PocketSharp namespace PocketSharp
{ {
/// <summary> /// <summary>
/// PocketClient /// PocketClient
/// </summary> /// </summary>
public partial class PocketClient public partial class PocketClient : IPocketClient
{ {
/// <summary> /// <summary>
/// REST client used for the API communication /// REST client used for the API communication
@@ -23,7 +24,12 @@ namespace PocketSharp
/// <summary> /// <summary>
/// Caches HTTP headers from last response /// Caches HTTP headers from last response
/// </summary> /// </summary>
private HttpResponseHeaders lastHeaders; public HttpResponseHeaders lastHeaders;
/// <summary>
/// Caches JSON data from last response
/// </summary>
public string lastResponseData;
/// <summary> /// <summary>
/// The base URL for the Pocket API /// The base URL for the Pocket API
@@ -36,35 +42,56 @@ namespace PocketSharp
protected string authentificationUri = "https://getpocket.com/auth/authorize?request_token={0}&redirect_uri={1}"; protected string authentificationUri = "https://getpocket.com/auth/authorize?request_token={0}&redirect_uri={1}";
/// <summary> /// <summary>
/// callback URL for API calls /// callback URLi for API calls
/// </summary> /// </summary>
/// <value>
/// The callback URI.
/// </value>
public string CallbackUri { get; set; } public string CallbackUri { get; set; }
/// <summary> /// <summary>
/// Accessor for the Pocket API key /// Accessor for the Pocket API key
/// see: http://getpocket.com/developer /// see: http://getpocket.com/developer
/// </summary> /// </summary>
/// <value>
/// The consumer key.
/// </value>
public string ConsumerKey { get; set; } public string ConsumerKey { get; set; }
/// <summary> /// <summary>
/// Code retrieved on authentification /// Code retrieved on authentification
/// </summary> /// </summary>
/// <value>
/// The request code.
/// </value>
public string RequestCode { get; set; } public string RequestCode { get; set; }
/// <summary> /// <summary>
/// Code retrieved on authentification-success /// Code retrieved on authentification-success
/// </summary> /// </summary>
/// <value>
/// The access code.
/// </value>
public string AccessCode { get; set; } public string AccessCode { get; set; }
/// <summary>
/// Action which is executed before every request
/// </summary>
/// <value>
/// The pre request callback.
/// </value>
public Action<string> PreRequest { get; set; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PocketClient"/> class. /// Initializes a new instance of the <see cref="PocketClient" /> class.
/// </summary> /// </summary>
/// <param name="consumerKey">The API key</param> /// <param name="consumerKey">The API key</param>
/// <param name="accessCode">Provide an access code if the user is already authenticated</param> /// <param name="accessCode">Provide an access code if the user is already authenticated</param>
/// <param name="callbackUri">The callback URL is called by Pocket after authentication</param> /// <param name="callbackUri">The callback URL is called by Pocket after authentication</param>
public PocketClient(string consumerKey, string accessCode = null, string callbackUri = null) /// <param name="handler">The HttpMessage handler.</param>
/// <param name="timeout">Request timeout (in seconds).</param>
public PocketClient(string consumerKey, string accessCode = null, string callbackUri = null, HttpMessageHandler handler = null, int? timeout = null)
{ {
// assign public properties // assign public properties
ConsumerKey = consumerKey; ConsumerKey = consumerKey;
@@ -82,11 +109,16 @@ namespace PocketSharp
} }
// initialize REST client // initialize REST client
_restClient = new HttpClient(new HttpClientHandler() _restClient = new HttpClient(handler ?? new HttpClientHandler()
{ {
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
}); });
if (timeout.HasValue)
{
_restClient.Timeout = TimeSpan.FromSeconds(timeout.Value);
}
// set base uri // set base uri
_restClient.BaseAddress = baseUri; _restClient.BaseAddress = baseUri;
@@ -103,15 +135,20 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="method">Requested method (path after /v3/)</param> /// <param name="method">Requested method (path after /v3/)</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="parameters">Additional POST parameters</param> /// <param name="parameters">Additional POST parameters</param>
/// <param name="requireAuth">if set to <c>true</c> [require auth].</param> /// <param name="requireAuth">if set to <c>true</c> [require auth].</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="PocketException">No access token available. Use authentification first.</exception> /// <exception cref="PocketException">No access token available. Use authentification first.</exception>
protected async Task<T> Request<T>(string method, Dictionary<string, string> parameters = null, bool requireAuth = true) where T : class, new() protected async Task<T> Request<T>(
string method,
CancellationToken cancellationToken,
Dictionary<string, string> parameters = null,
bool requireAuth = true) where T : class, new()
{ {
if (requireAuth && AccessCode == null) if (requireAuth && AccessCode == null)
{ {
throw new PocketException("SDK error: No access token available. Use authentification first."); throw new PocketException("SDK error: No access token available. Use authentication first.");
} }
// every single Pocket API endpoint requires HTTP POST data // every single Pocket API endpoint requires HTTP POST data
@@ -135,10 +172,16 @@ namespace PocketSharp
// content of the request // content of the request
request.Content = new FormUrlEncodedContent(parameters); request.Content = new FormUrlEncodedContent(parameters);
// call pre request action
if (PreRequest != null)
{
PreRequest(method);
}
// make async request // make async request
try try
{ {
response = await _restClient.SendAsync(request); response = await _restClient.SendAsync(request, cancellationToken);
} }
catch (HttpRequestException exc) catch (HttpRequestException exc)
{ {
@@ -154,6 +197,9 @@ namespace PocketSharp
// read response // read response
var responseString = await response.Content.ReadAsStringAsync(); var responseString = await response.Content.ReadAsStringAsync();
// cache response
lastResponseData = responseString;
responseString = responseString.Replace("[]", "{}"); responseString = responseString.Replace("[]", "{}");
// deserialize object // deserialize object
@@ -168,7 +214,9 @@ namespace PocketSharp
Converters = Converters =
{ {
new BoolConverter(), new BoolConverter(),
new UnixDateTimeConverter() new UnixDateTimeConverter(),
new NullableIntConverter(),
new UriConverter()
} }
} }
); );
@@ -182,7 +230,7 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <param name="actionParameters">The action parameters.</param> /// <param name="actionParameters">The action parameters.</param>
/// <returns></returns> /// <returns></returns>
internal async Task<bool> Send(List<ActionParameter> actionParameters) internal async Task<bool> Send(List<PocketAction> actionParameters, CancellationToken cancellationToken)
{ {
List<Dictionary<string, object>> actionParamList = new List<Dictionary<string, object>>(); List<Dictionary<string, object>> actionParamList = new List<Dictionary<string, object>>();
@@ -195,7 +243,7 @@ namespace PocketSharp
"actions", JsonConvert.SerializeObject(actionParamList) "actions", JsonConvert.SerializeObject(actionParamList)
}}; }};
Modify response = await Request<Modify>("send", parameters); Modify response = await Request<Modify>("send", cancellationToken, parameters);
return response.Status; return response.Status;
} }
@@ -206,10 +254,9 @@ namespace PocketSharp
/// </summary> /// </summary>
/// <param name="actionParameter">The action parameter.</param> /// <param name="actionParameter">The action parameter.</param>
/// <returns></returns> /// <returns></returns>
internal async Task<bool> Send(ActionParameter actionParameter) internal async Task<bool> Send(PocketAction actionParameter, CancellationToken cancellationToken)
{ {
bool response = await Send(new List<ActionParameter>() { actionParameter }); return await Send(new List<PocketAction>() { actionParameter }, cancellationToken);
return response;
} }
+16 -21
View File
@@ -42,8 +42,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Components\Statistics.cs" /> <Compile Include="Components\Statistics.cs" />
<Compile Include="IPocketClient.cs" />
<Compile Include="Models\Parameters\RegisterParameters.cs" /> <Compile Include="Models\Parameters\RegisterParameters.cs" />
<Compile Include="Models\PocketArticle.cs" /> <Compile Include="Models\PocketArticle.cs" />
<Compile Include="Models\PocketBoolean.cs" />
<Compile Include="Models\PocketLimits.cs" /> <Compile Include="Models\PocketLimits.cs" />
<Compile Include="Models\PocketStatistics.cs" /> <Compile Include="Models\PocketStatistics.cs" />
<Compile Include="Utilities\PocketException.cs" /> <Compile Include="Utilities\PocketException.cs" />
@@ -53,7 +55,7 @@
<Compile Include="Components\ModifyTags.cs" /> <Compile Include="Components\ModifyTags.cs" />
<Compile Include="Components\Get.cs" /> <Compile Include="Components\Get.cs" />
<Compile Include="Utilities\JsonExtensions.cs" /> <Compile Include="Utilities\JsonExtensions.cs" />
<Compile Include="Models\Parameters\ActionParameter.cs" /> <Compile Include="Models\PocketAction.cs" />
<Compile Include="Models\Parameters\AddParameters.cs" /> <Compile Include="Models\Parameters\AddParameters.cs" />
<Compile Include="Models\Parameters\ModifyParameters.cs" /> <Compile Include="Models\Parameters\ModifyParameters.cs" />
<Compile Include="Models\Parameters\Parameters.cs" /> <Compile Include="Models\Parameters\Parameters.cs" />
@@ -70,16 +72,15 @@
<Compile Include="Models\Response\ResponseBase.cs" /> <Compile Include="Models\Response\ResponseBase.cs" />
<Compile Include="Models\Response\Retrieve.cs" /> <Compile Include="Models\Response\Retrieve.cs" />
<Compile Include="PocketClient.cs" /> <Compile Include="PocketClient.cs" />
<Compile Include="PocketReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utilities\Utilities.cs" /> <Compile Include="Utilities\Utilities.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.Threading.Tasks"> <Reference Include="Microsoft.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\portable-net40+sl4+win8+wp71\Microsoft.Threading.Tasks.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.Async.1.0.165\lib\portable-net40+sl4+win8+wp71\Microsoft.Threading.Tasks.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions"> <Reference Include="Microsoft.Threading.Tasks.Extensions">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\portable-net40+sl4+win8+wp71\Microsoft.Threading.Tasks.Extensions.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.Async.1.0.165\lib\portable-net40+sl4+win8+wp71\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json"> <Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll</HintPath>
@@ -89,33 +90,27 @@
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="System.IO"> <Reference Include="System.IO">
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\portable-net40+sl4+win8+wp71\System.IO.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.6\lib\portable-net40+sl4+win8+wp71\System.IO.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Net.Http"> <Reference Include="System.Net.Http">
<HintPath>..\packages\Microsoft.Net.Http.2.2.15\lib\portable-net40+sl4+win8+wp71\System.Net.Http.dll</HintPath> <HintPath>..\packages\Microsoft.Net.Http.2.2.18\lib\portable-net40+sl4+win8+wp71\System.Net.Http.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Net.Http.Extensions"> <Reference Include="System.Net.Http.Extensions">
<HintPath>..\packages\Microsoft.Net.Http.2.2.15\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Extensions.dll</HintPath> <HintPath>..\packages\Microsoft.Net.Http.2.2.18\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Extensions.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Net.Http.Primitives"> <Reference Include="System.Net.Http.Primitives">
<HintPath>..\packages\Microsoft.Net.Http.2.2.15\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Primitives.dll</HintPath> <HintPath>..\packages\Microsoft.Net.Http.2.2.18\lib\portable-net40+sl4+win8+wp71\System.Net.Http.Primitives.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Runtime"> <Reference Include="System.Runtime">
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\portable-net40+sl4+win8+wp71\System.Runtime.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.6\lib\portable-net40+sl4+win8+wp71\System.Runtime.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Threading.Tasks"> <Reference Include="System.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\portable-net40+sl4+win8+wp71\System.Threading.Tasks.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.1.1.6\lib\portable-net40+sl4+win8+wp71\System.Threading.Tasks.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="FodyWeavers.xml" /> <Content Include="FodyWeavers.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PortablePorts\NReadability\NReadability.csproj">
<Project>{14c3ee6a-54a4-4a37-8b56-d52a3802f1c2}</Project>
<Name>NReadability</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
@@ -124,12 +119,12 @@
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" /> <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target> </Target>
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<Import Project="Fody.targets" /> <Import Project="Fody.targets" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild"> <Target Name="BeforeBuild">
+1 -1
View File
@@ -18,6 +18,6 @@
]]> ]]>
</releaseNotes> </releaseNotes>
<copyright>Copyright by cee, 2013</copyright> <copyright>Copyright by cee, 2013</copyright>
<tags>PocketAPI Pocket API PocketSharp Tobias Klika cee NReadability Reader Article SDK Pockem</tags> <tags>PocketAPI Pocket API PocketSharp Tobias Klika cee NReadability SgmlReader Reader Article SDK Pockem</tags>
</metadata> </metadata>
</package> </package>
+3 -6
View File
@@ -1,7 +1,4 @@
using System.Resources; using System.Reflection;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
@@ -25,5 +22,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.2.2")] [assembly: AssemblyVersion("3.0.0")]
[assembly: AssemblyFileVersion("2.2.2")] [assembly: AssemblyFileVersion("3.0.0")]
+112 -2
View File
@@ -1,6 +1,8 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic;
namespace PocketSharp namespace PocketSharp
{ {
@@ -14,7 +16,7 @@ namespace PocketSharp
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{ {
return reader.Value.ToString() == "1"; return reader.Value == null ? false : (reader.Value.ToString() == "1");
} }
public override bool CanConvert(Type objectType) public override bool CanConvert(Type objectType)
@@ -37,7 +39,7 @@ namespace PocketSharp
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{ {
if(reader.Value.ToString() == "0") if (reader.Value.ToString() == "0")
{ {
return null; return null;
} }
@@ -45,4 +47,112 @@ namespace PocketSharp
return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(Convert.ToDouble(reader.Value)).ToLocalTime(); return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(Convert.ToDouble(reader.Value)).ToLocalTime();
} }
} }
public class NullableIntConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
int result = 0;
if (reader.Value != null)
{
result = Convert.ToInt32(reader.Value);
}
return result;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(int);
}
}
public class UriConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String && Uri.IsWellFormedUriString(reader.Value.ToString(), UriKind.Absolute))
{
return new Uri(reader.Value.ToString());
}
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
}
else if (value is Uri)
{
writer.WriteValue(((Uri)value).OriginalString);
}
}
public override bool CanConvert(Type objectType)
{
return objectType.Equals(typeof(Uri));
}
}
public class ObjectToArrayConverter<T> : CustomCreationConverter<List<T>> where T : new()
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject;
List<T> result = new List<T>();
T target;
// object is an array
if (reader.TokenType == JsonToken.StartArray)
{
return serializer.Deserialize<List<T>>(reader);
}
else if (reader.TokenType == JsonToken.Null)
{
return null;
}
try
{
jObject = JObject.Load(reader);
}
catch
{
return null;
}
// Populate the object properties
foreach (KeyValuePair<string, JToken> item in jObject)
{
target = new T();
serializer.Populate(item.Value.CreateReader(), target);
result.Add(target);
}
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override List<T> Create(Type objectType)
{
return new List<T>();
}
}
} }
+3 -26
View File
@@ -12,7 +12,9 @@ namespace PocketSharp
/// converts DateTime to an UNIX timestamp /// converts DateTime to an UNIX timestamp
/// </summary> /// </summary>
/// <param name="dateTime">The date.</param> /// <param name="dateTime">The date.</param>
/// <returns>UNIX timestamp</returns> /// <returns>
/// UNIX timestamp
/// </returns>
public static int? GetUnixTimestamp(DateTime? dateTime) public static int? GetUnixTimestamp(DateTime? dateTime)
{ {
if (dateTime == null) if (dateTime == null)
@@ -22,30 +24,5 @@ namespace PocketSharp
return (int)((DateTime)dateTime - new DateTime(1970, 1, 1)).TotalSeconds; return (int)((DateTime)dateTime - new DateTime(1970, 1, 1)).TotalSeconds;
} }
/// <summary>
/// Convert a dictionary to a list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="items">The items.</param>
/// <returns></returns>
public static List<T> DictionaryToList<T>(Dictionary<string, T> items) where T : new()
{
if (items == null)
{
return null;
}
var itemEnumerator = items.GetEnumerator();
List<T> list = new List<T>();
while (itemEnumerator.MoveNext())
{
list.Add(itemEnumerator.Current.Value);
}
return list;
}
} }
} }
+4 -4
View File
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Fody" version="1.17.4.0" targetFramework="portable-net403+sl40+wp71+win" /> <package id="Fody" version="1.17.4.0" targetFramework="portable-net403+sl40+wp71+win" />
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="portable-net45+sl40+wp71+win" /> <package id="Microsoft.Bcl" version="1.1.6" targetFramework="portable-win+net403+sl40+wp71" />
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="portable-net45+sl40+wp71+win" /> <package id="Microsoft.Bcl.Async" version="1.0.165" targetFramework="portable-win+net403+sl40+wp71" />
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="portable-net45+sl40+wp71+win" /> <package id="Microsoft.Bcl.Build" version="1.0.13" targetFramework="portable-win+net403+sl40+wp71" />
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="portable-net403+sl40+wp71+win" /> <package id="Microsoft.Net.Http" version="2.2.18" targetFramework="portable-win+net403+sl40+wp71" />
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="portable-net45+sl40+wp71+win" /> <package id="Newtonsoft.Json" version="5.0.8" targetFramework="portable-net45+sl40+wp71+win" />
<package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="portable-net403+sl40+wp71+win" /> <package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="portable-net403+sl40+wp71+win" />
</packages> </packages>
@@ -1,5 +1,4 @@
using System;
namespace PocketSharp.Ports.NReadability namespace PocketSharp.Ports.NReadability
{ {
public class DomSerializationParams public class DomSerializationParams
@@ -48,6 +47,10 @@ namespace PocketSharp.Ports.NReadability
/// </summary> /// </summary>
public bool BodyOnly { get; set; } public bool BodyOnly { get; set; }
/// <summary>
/// Remove headline of website
/// </summary>
public bool NoHeadline { get; set; }
#endregion #endregion
} }
} }
@@ -92,6 +92,16 @@ namespace PocketSharp.Ports.NReadability
} }
} }
if (domSerializationParams.NoHeadline)
{
var h1 = document.Root.GetElementsByTagName("h1").FirstOrDefault();
if (h1 != null)
{
result = result.Replace(h1.ToString(), "");
}
}
return result; return result;
} }
+17 -13
View File
@@ -2,12 +2,18 @@
**PocketSharp** is a C#.NET portable class library that integrates the [Pocket API v3](http://getpocket.com/developer). **PocketSharp** is a C#.NET portable class library that integrates the [Pocket API v3](http://getpocket.com/developer).
## Install using [NuGet](https://www.nuget.org/packages/PocketSharp/) ## Install [PocketSharp](https://www.nuget.org/packages/PocketSharp/) using NuGet
``` ```
Install-Package PocketSharp Install-Package PocketSharp
``` ```
for the [PocketSharp.Reader](https://www.nuget.org/packages/PocketSharp.Reader/)
```
Install-Package PocketSharp.Reader
```
## Documentation ## Documentation
See [wiki](https://github.com/ceee/PocketSharp/wiki) See [wiki](https://github.com/ceee/PocketSharp/wiki)
@@ -24,7 +30,7 @@ PocketClient client = new PocketClient("[YOUR_CONSUMER_KEY]", "[YOUR_ACCESS_CODE
List<PocketItem> items = await client.Search("css"); List<PocketItem> items = await client.Search("css");
items.ForEach( items.ForEach(
item => Debug.WriteLine(item.ID + " | " + item.Title) item => Debug.WriteLine(item.ID + " | " + item.Title)
); );
``` ```
@@ -34,14 +40,14 @@ Which will output:
345541438 | Editr - HTML, CSS, JavaScript playground 345541438 | Editr - HTML, CSS, JavaScript playground
251743431 | CSS Architecture 251743431 | CSS Architecture
343693149 | CSS3 Transitions - Thank God We Have A Specification! 343693149 | CSS3 Transitions - Thank God We Have A Specification!
... ...
--- ---
## Supported platforms ## Supported platforms
PocketSharp is a **Portable Class Library** (since 1.0.0), therefore it's compatible with multiple platforms: PocketSharp is a **Portable Class Library**, therefore it's compatible with multiple platforms:
- **.NET** >= 4.5 (including WPF) - **.NET** >= 4.5 (including WPF)
- **Silverlight** >= 4 - **Silverlight** >= 4
@@ -52,21 +58,19 @@ You can find examples for Silverlight 5, WP8 and WPF in the `PocketSharp.Example
## What's next? ## What's next?
- `cancellationToken` support for all methods - [ ] Preferences API, if Pocket will ever release it to the public -.-
- support HTML injection into content from PocketArticle (maybe remove title from Article)
- benchmarking download of large lists
- benchmarking of search algorithm
- Update website and merge into plugin repository site
## Dependencies ## Dependencies
- [Microsoft.Bcl.Async](https://www.nuget.org/packages/Microsoft.Bcl.Async/) - [Microsoft.Bcl.Async](https://www.nuget.org/packages/Microsoft.Bcl.Async/) _(used in PocketSharp & PocketSharp.Reader)_
- [Microsoft.Net.Http](https://www.nuget.org/packages/Microsoft.Net.Http/) - [Microsoft.Net.Http](https://www.nuget.org/packages/Microsoft.Net.Http/) _(used in PocketSharp & PocketSharp.Reader)_
- [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/) - [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/) _(only for PocketSharp project)_
- [PropertyChanged.Fody](https://github.com/Fody/PropertyChanged) - [PropertyChanged.Fody](https://github.com/Fody/PropertyChanged) _(only for PocketSharp project)_
## Forked Dependencies ## Forked Dependencies
_used in PocketSharp.Reader_
- [NReadability](https://github.com/marek-stoj/NReadability) - converted to a PCL with minor adaptations - [NReadability](https://github.com/marek-stoj/NReadability) - converted to a PCL with minor adaptations
- [SgmlReader](https://github.com/MindTouch/SGMLReader) - converted to a PCL - [SgmlReader](https://github.com/MindTouch/SGMLReader) - converted to a PCL