Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a2e68af4dc | |||
| ab5361c370 | |||
| 4718faf76a | |||
| f6e7594233 | |||
| c39f8ec7f0 | |||
| c1981bbb24 | |||
| 425faf7a90 | |||
| a1fae6b3ce | |||
| 84981a5de3 | |||
| 5480cebe49 | |||
| 3fca5a059b | |||
| 5854c0c04f | |||
| e2ca21b3be | |||
| 178920008b | |||
| 67c48839d9 | |||
| e2bf62e506 | |||
| 31c69fb12b | |||
| 42693a967e | |||
| 29f57085aa | |||
| 5ba027bafc | |||
| 33e6e9b02d | |||
| 44376c0852 | |||
| a643e5c556 | |||
| b2ce585966 | |||
| 6f6d054044 | |||
| ff4fae1d35 | |||
| f5c8d45013 | |||
| ad40a25b0b | |||
| eb3ac1f152 | |||
| 3bff4d823f | |||
| 0427399746 | |||
| ee989fc019 | |||
| 2a9c30a69b | |||
| 95d7a5d993 | |||
| bf5d8a50ce | |||
| 10e9575303 | |||
| feff91ffd8 | |||
| 50d896c670 | |||
| f0ffeb5a68 | |||
| 6b3819b87b | |||
| 8df2836563 | |||
| d856e75e76 | |||
| 82c9ecd6b5 | |||
| 7147d8022e | |||
| b1888ac20e | |||
| cb8d1d9d43 | |||
| 2b932d4c07 | |||
| bc30ea613a | |||
| b1b145204e | |||
| 01be59b347 | |||
| af3e2b400b | |||
| 396cf69a40 | |||
| 088f6a4e0e | |||
| 25a25472b3 |
+16
-3
@@ -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)
|
||||
|
||||
- Password validation in RegisterAccount
|
||||
@@ -9,13 +22,13 @@
|
||||
### 2.2.0 (2013-10-26)
|
||||
|
||||
- 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)
|
||||
|
||||
- Rename `Statistics()` to `GetUserStatistics()`
|
||||
- Made `CallbackUri` public (thanks to [ScottIsAFool](https://github.com/ScottIsAFool))
|
||||
- Added Fody/PropertyChanged (thanks to [ScottIsAFool](https://github.com/ScottIsAFool))
|
||||
- Made `CallbackUri` public
|
||||
- Added Fody/PropertyChanged
|
||||
- Method `GetUsageLimits()` to retrieve API usage limits
|
||||
- Add PORTABLE constant to SgmlReader
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="400">
|
||||
|
||||
<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"/>
|
||||
<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"/>
|
||||
|
||||
<sdk:DataGrid x:Name="Content" HorizontalAlignment="Left" Height="241" Margin="10,49,0,0" VerticalAlignment="Top" Width="380" FrozenColumnCount="2"/>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
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
|
||||
{
|
||||
@@ -39,7 +31,7 @@ namespace PocketSharp.Silverlight
|
||||
PocketClient client = new PocketClient(
|
||||
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
|
||||
callbackUri: "http://frontendplay.com",
|
||||
accessCode: "2c62cd50-b78a-5558-918b-65adae"
|
||||
accessCode: "80acf6c5-c198-03c0-b94c-e74402"
|
||||
);
|
||||
|
||||
List<PocketSharp.Models.PocketItem> items = null;
|
||||
|
||||
@@ -78,6 +78,17 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.1.1.3\lib\sl5\System.IO.dll</HintPath>
|
||||
</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">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<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">
|
||||
<dependentAssembly>
|
||||
<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>
|
||||
<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>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
<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.Build" version="1.0.10" targetFramework="sl50" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.18" targetFramework="sl50" />
|
||||
</packages>
|
||||
@@ -1,20 +1,10 @@
|
||||
<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">
|
||||
|
||||
<!--Application Resources-->
|
||||
<Application.Resources>
|
||||
<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 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">
|
||||
<!--Application Resources-->
|
||||
<Application.Resources>
|
||||
<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>
|
||||
@@ -14,59 +14,33 @@
|
||||
SupportedOrientations="Portrait" Orientation="Portrait"
|
||||
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-->
|
||||
<Grid x:Name="LayoutRoot" Background="Transparent">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<!--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.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- LOCALIZATION NOTE:
|
||||
To localize the displayed strings copy their values to appropriately named
|
||||
keys in the app's neutral language resource file (AppResources.resx) then
|
||||
replace the hard-coded text value between the attributes' quotation marks
|
||||
with the binding clause whose path points to that string name.
|
||||
<!--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}"/>
|
||||
<Button Click="Button_Click">Load Data</Button>
|
||||
</StackPanel>
|
||||
|
||||
For example:
|
||||
|
||||
Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"
|
||||
|
||||
This binding points to the template's string resource named "ApplicationTitle".
|
||||
|
||||
Adding supported languages in the Project Properties tab will create a
|
||||
new resx file per language that can carry the translated values of your
|
||||
UI strings. The binding in these examples will cause the value of the
|
||||
attributes to be drawn from the .resx file that matches the
|
||||
CurrentUICulture of the app at run time.
|
||||
-->
|
||||
|
||||
<!--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" />-->
|
||||
<!--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>
|
||||
</Grid>
|
||||
|
||||
</phone:PhoneApplicationPage>
|
||||
@@ -1,15 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Microsoft.Phone.Controls;
|
||||
using PocketSharp.WP8.ViewModels;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
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
|
||||
{
|
||||
@@ -22,18 +16,12 @@ namespace PocketSharp.WP8
|
||||
|
||||
// Set the data context of the LongListSelector control to the sample data
|
||||
DataContext = App.ViewModel;
|
||||
|
||||
// Sample code to localize the ApplicationBar
|
||||
//BuildLocalizedApplicationBar();
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -50,20 +38,9 @@ namespace PocketSharp.WP8
|
||||
MainLongListSelector.SelectedItem = null;
|
||||
}
|
||||
|
||||
// Sample code for building a localized ApplicationBar
|
||||
//private void BuildLocalizedApplicationBar()
|
||||
//{
|
||||
// // 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);
|
||||
//}
|
||||
private async void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await App.ViewModel.LoadData();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,6 +130,7 @@
|
||||
</DesignData>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\AppManifest.xml" />
|
||||
<None Include="Properties\WMAppManifest.xml">
|
||||
<SubType>Designer</SubType>
|
||||
@@ -178,6 +179,17 @@
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions.Phone">
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.16\lib\wp8\Microsoft.Threading.Tasks.Extensions.Phone.dll</HintPath>
|
||||
</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>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).$(TargetFrameworkVersion).Overrides.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
|
||||
@@ -196,4 +208,9 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||
</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>
|
||||
@@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using PocketSharp.WP8.Resources;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using PocketSharp.WP8.Resources;
|
||||
using PocketSharp;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp.WP8.ViewModels
|
||||
{
|
||||
@@ -68,14 +67,14 @@ namespace PocketSharp.WP8.ViewModels
|
||||
PocketClient client = new PocketClient(
|
||||
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
|
||||
callbackUri: "http://frontendplay.com",
|
||||
accessCode: "2c62cd50-b78a-5558-918b-65adae"
|
||||
accessCode: "80acf6c5-c198-03c0-b94c-e74402"
|
||||
);
|
||||
|
||||
List<PocketSharp.Models.PocketItem> items = null;
|
||||
|
||||
try
|
||||
{
|
||||
items = await client.Get().ConfigureAwait(false);
|
||||
items = await client.Get();
|
||||
|
||||
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.Windows.Controls;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace PocketSharp.Wpf
|
||||
{
|
||||
@@ -35,7 +33,7 @@ namespace PocketSharp.Wpf
|
||||
PocketClient client = new PocketClient(
|
||||
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
|
||||
callbackUri: "http://frontendplay.com",
|
||||
accessCode: "2c62cd50-b78a-5558-918b-65adae"
|
||||
accessCode: "80acf6c5-c198-03c0-b94c-e74402"
|
||||
);
|
||||
|
||||
List<PocketSharp.Models.PocketItem> items = null;
|
||||
|
||||
@@ -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.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using PocketSharp.Models;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// PocketReader
|
||||
/// </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>
|
||||
/// REST client used for HTML retrieval
|
||||
/// </summary>
|
||||
@@ -19,25 +24,39 @@ namespace PocketSharp
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PocketReader"/> class.
|
||||
/// Initializes a new instance of the <see cref="PocketReader" /> class.
|
||||
/// </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
|
||||
_httpClient = new HttpClient(new HttpClientHandler()
|
||||
_httpClient = new HttpClient(handler ?? new HttpClientHandler()
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
||||
AllowAutoRedirect = true
|
||||
});
|
||||
|
||||
if (timeout.HasValue)
|
||||
{
|
||||
_httpClient.Timeout = TimeSpan.FromSeconds(timeout.Value);
|
||||
}
|
||||
|
||||
// add accept types
|
||||
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
|
||||
// add accepted encodings
|
||||
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip,deflate");
|
||||
|
||||
// add user agent (default for Opera with PocketSharp identifier appended)
|
||||
_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");
|
||||
// add user agent
|
||||
_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.
|
||||
/// </summary>
|
||||
/// <param name="uri">An URI.</param>
|
||||
/// <returns>A Pocket article with extracted content and title.</returns>
|
||||
/// <exception cref="PocketRequestException"></exception>
|
||||
public async Task<PocketArticle> Read(Uri uri)
|
||||
/// <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>
|
||||
public async Task<PocketArticle> Read(Uri uri, bool bodyOnly = true, bool noHeadline = false)
|
||||
{
|
||||
return await Read(new PocketItem()
|
||||
{
|
||||
ID = 0,
|
||||
ID = null,
|
||||
Uri = uri
|
||||
});
|
||||
}, bodyOnly, noHeadline);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +89,13 @@ namespace PocketSharp
|
||||
/// The PocketReader is based on a custom PCL port of NReadability and SgmlReader.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
public async Task<PocketArticle> Read(PocketItem item)
|
||||
public async Task<PocketArticle> Read(PocketItem item, bool bodyOnly = true, bool noHeadline = false)
|
||||
{
|
||||
// initialize transcoder
|
||||
NReadabilityTranscoder transcoder = new NReadabilityTranscoder(
|
||||
@@ -90,18 +116,19 @@ namespace PocketSharp
|
||||
Url = item.Uri.ToString(),
|
||||
DomSerializationParams = new DomSerializationParams()
|
||||
{
|
||||
BodyOnly = true,
|
||||
BodyOnly = bodyOnly,
|
||||
NoHeadline = noHeadline,
|
||||
PrettyPrint = true,
|
||||
DontIncludeContentTypeMetaElement = true,
|
||||
DontIncludeMobileSpecificMetaElements = true,
|
||||
DontIncludeDocTypeMetaElement = true,
|
||||
DontIncludeDocTypeMetaElement = false,
|
||||
DontIncludeGeneratorMetaElement = true
|
||||
}
|
||||
};
|
||||
|
||||
// process/transcode HTML
|
||||
TranscodingResult transcodingResult = transcoder.Transcode(transcodingInput);
|
||||
|
||||
|
||||
return new PocketArticle()
|
||||
{
|
||||
Content = transcodingResult.ExtractedContent,
|
||||
@@ -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")]
|
||||
@@ -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>
|
||||
@@ -50,6 +50,11 @@ namespace PocketSharp.Tests
|
||||
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 client.RegisterAccount("myusername", null, "mypassword");
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
|
||||
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]
|
||||
public async Task AddComplexItem()
|
||||
{
|
||||
@@ -39,7 +52,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
items.ForEach(itm =>
|
||||
{
|
||||
if(itm.ID == item.ID)
|
||||
if (itm.ID == item.ID)
|
||||
{
|
||||
itemDesired = itm;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -15,7 +15,6 @@ namespace PocketSharp.Tests
|
||||
public async Task AreItemsRetrieved()
|
||||
{
|
||||
List<PocketItem> items = await client.Get();
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
}
|
||||
|
||||
@@ -76,7 +75,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
|
||||
PocketItem item = await client.Get(99999999);
|
||||
PocketItem item = await client.Get("99999999");
|
||||
|
||||
Assert.Null(item);
|
||||
|
||||
@@ -147,7 +146,7 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task AreStatisticsRetrieved()
|
||||
{
|
||||
PocketStatistics statistics = await client.Statistics();
|
||||
PocketStatistics statistics = await client.GetUserStatistics();
|
||||
|
||||
Assert.True(statistics.CountAll > 0);
|
||||
}
|
||||
@@ -160,5 +159,92 @@ namespace PocketSharp.Tests
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
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);
|
||||
PocketItem itemDesired = null;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
|
||||
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()
|
||||
{
|
||||
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);
|
||||
PocketItem itemDesired = null;
|
||||
|
||||
@@ -37,22 +37,24 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Threading.Tasks">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net45\Microsoft.Threading.Tasks.dll</HintPath>
|
||||
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.16\lib\net45\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Net" />
|
||||
<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>
|
||||
<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 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>
|
||||
<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 Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="xunit">
|
||||
@@ -68,6 +70,7 @@
|
||||
<Otherwise />
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="MiscTests.cs" />
|
||||
<Compile Include="AddTests.cs" />
|
||||
<Compile Include="AccountTests.cs" />
|
||||
<Compile Include="ModifyTagsTests.cs" />
|
||||
@@ -75,9 +78,14 @@
|
||||
<Compile Include="GetTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReadTests.cs" />
|
||||
<Compile Include="StressTests.cs" />
|
||||
<Compile Include="TestsBase.cs" />
|
||||
</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">
|
||||
<Project>{817200c3-a327-4e35-9b5f-63a51c088577}</Project>
|
||||
<Name>PocketSharp</Name>
|
||||
@@ -86,6 +94,8 @@
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="url-10000.csv" />
|
||||
<None Include="url-100000.csv" />
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||
@@ -114,10 +124,10 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||
</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)' == ''">
|
||||
<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" />
|
||||
<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.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -11,7 +10,8 @@ namespace PocketSharp.Tests
|
||||
private PocketReader reader;
|
||||
|
||||
|
||||
public ReadTests() : base()
|
||||
public ReadTests()
|
||||
: base()
|
||||
{
|
||||
reader = new PocketReader();
|
||||
}
|
||||
@@ -22,10 +22,27 @@ namespace PocketSharp.Tests
|
||||
{
|
||||
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")
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -37,7 +54,7 @@ namespace PocketSharp.Tests
|
||||
{
|
||||
await reader.Read(new PocketItem()
|
||||
{
|
||||
ID = 99,
|
||||
ID = "99",
|
||||
Uri = new Uri("http://frontendplayyyyy.com")
|
||||
});
|
||||
});
|
||||
@@ -49,7 +66,7 @@ namespace PocketSharp.Tests
|
||||
{
|
||||
PocketArticle result = await reader.Read(new PocketItem()
|
||||
{
|
||||
ID = 99,
|
||||
ID = "99",
|
||||
Uri = new Uri("http://calebjacob.com/tooltipster/")
|
||||
});
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -10,7 +9,7 @@ namespace PocketSharp.Tests
|
||||
{
|
||||
protected PocketClient client;
|
||||
|
||||
protected List<int> itemsToDelete = new List<int>();
|
||||
protected List<string> itemsToDelete = new List<string>();
|
||||
|
||||
|
||||
// setup
|
||||
@@ -26,7 +25,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
|
||||
// teardown
|
||||
public void Dispose()
|
||||
public void Dispose()
|
||||
{
|
||||
itemsToDelete.ForEach(async id =>
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<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>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl" version="1.1.6" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.165" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.13" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.18" targetFramework="net45" />
|
||||
<package id="xunit" version="1.9.2" targetFramework="net45" />
|
||||
</packages>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SgmlReader", "PortablePorts
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PortablePorts", "PortablePorts", "{82F79DE3-76D7-4FCB-AA7E-16BA7E363E0D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Reader", "PocketSharp.Reader\PocketSharp.Reader.csproj", "{9D1BBD72-C263-43D3-9F2A-98F9F99235A4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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|ARM.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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
@@ -14,10 +15,11 @@ namespace PocketSharp
|
||||
/// <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>
|
||||
public async Task<string> GetRequestCode()
|
||||
public async Task<string> GetRequestCode(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
// check if request code is available
|
||||
if (CallbackUri == null)
|
||||
@@ -26,7 +28,7 @@ namespace PocketSharp
|
||||
}
|
||||
|
||||
// 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 }
|
||||
}, false);
|
||||
@@ -48,13 +50,13 @@ namespace PocketSharp
|
||||
public Uri GenerateAuthenticationUri(string requestCode = null)
|
||||
{
|
||||
// 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");
|
||||
}
|
||||
|
||||
// override property with given param if available
|
||||
if(requestCode != null)
|
||||
if (requestCode != null)
|
||||
{
|
||||
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>
|
||||
/// 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>
|
||||
/// <param name="cancellationToken">The cancellation token.</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>
|
||||
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
|
||||
if (RequestCode == null && requestCode == null)
|
||||
@@ -101,7 +90,7 @@ namespace PocketSharp
|
||||
}
|
||||
|
||||
// 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}
|
||||
}, false);
|
||||
@@ -120,21 +109,20 @@ namespace PocketSharp
|
||||
/// <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.
|
||||
/// <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>
|
||||
/// Invalid password.</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)
|
||||
{
|
||||
throw new ArgumentNullException("All parameters are required");
|
||||
throw new ArgumentNullException("All parameters are required");
|
||||
}
|
||||
|
||||
Match matchEmail = Regex.Match(email, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,10}))$");
|
||||
@@ -162,7 +150,7 @@ namespace PocketSharp
|
||||
Password = password
|
||||
};
|
||||
|
||||
ResponseBase response = await Request<ResponseBase>("signup", parameters.Convert(), false);
|
||||
ResponseBase response = await Request<ResponseBase>("signup", cancellationToken, parameters.Convert(), false);
|
||||
|
||||
return response.Status;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
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="title">This can be included for cases where an item does not have a title, which is typical for image or PDF URLs. If Pocket detects a title from the content of the page, this parameter will be ignored.</param>
|
||||
/// <param name="tweetID">If you are adding Pocket support to a Twitter client, please send along a reference to the tweet status id. This allows Pocket to show the original tweet alongside the article.</param>
|
||||
/// <returns>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>
|
||||
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()
|
||||
{
|
||||
Uri = uri,
|
||||
@@ -28,7 +44,7 @@ namespace PocketSharp
|
||||
TweetID = tweetID
|
||||
};
|
||||
|
||||
Add response = await Request<Add>("add", parameters.Convert());
|
||||
Add response = await Request<Add>("add", cancellationToken, parameters.Convert());
|
||||
|
||||
return response.Item;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
@@ -11,22 +12,23 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
public partial class PocketClient
|
||||
{
|
||||
/// <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>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
/// <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>
|
||||
public async Task<List<PocketItem>> Get(
|
||||
State? state = null,
|
||||
bool? favorite = null,
|
||||
@@ -37,7 +39,8 @@ namespace PocketSharp
|
||||
string domain = null,
|
||||
DateTime? since = null,
|
||||
int? count = null,
|
||||
int? offset = null
|
||||
int? offset = null,
|
||||
CancellationToken cancellationToken = default(CancellationToken)
|
||||
)
|
||||
{
|
||||
RetrieveParameters parameters = new RetrieveParameters()
|
||||
@@ -55,7 +58,7 @@ namespace PocketSharp
|
||||
Offset = offset
|
||||
};
|
||||
|
||||
Retrieve response = await Request<Retrieve>("get", parameters.Convert());
|
||||
Retrieve response = await Request<Retrieve>("get", cancellationToken, parameters.Convert());
|
||||
|
||||
return response.Items;
|
||||
}
|
||||
@@ -66,14 +69,16 @@ 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.
|
||||
/// </summary>
|
||||
/// <param name="itemID">The item ID.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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(
|
||||
state: State.all
|
||||
cancellationToken: cancellationToken,
|
||||
state: State.all
|
||||
);
|
||||
|
||||
|
||||
return items.SingleOrDefault<PocketItem>(item => item.ID == itemID);
|
||||
}
|
||||
|
||||
@@ -82,13 +87,14 @@ namespace PocketSharp
|
||||
/// 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>
|
||||
public async Task<List<PocketItem>> Get(RetrieveFilter filter)
|
||||
public async Task<List<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
RetrieveParameters parameters = new RetrieveParameters();
|
||||
|
||||
switch(filter)
|
||||
switch (filter)
|
||||
{
|
||||
case RetrieveFilter.Article:
|
||||
parameters.ContentType = ContentType.article;
|
||||
@@ -115,7 +121,7 @@ namespace PocketSharp
|
||||
|
||||
parameters.DetailType = DetailType.complete;
|
||||
|
||||
Retrieve response = await Request<Retrieve>("get", parameters.Convert());
|
||||
Retrieve response = await Request<Retrieve>("get", cancellationToken, parameters.Convert());
|
||||
|
||||
return response.Items;
|
||||
}
|
||||
@@ -125,11 +131,13 @@ namespace PocketSharp
|
||||
/// 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>
|
||||
public async Task<List<PocketTag>> GetTags()
|
||||
public async Task<List<PocketTag>> GetTags(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
List<PocketItem> items = await Get(
|
||||
cancellationToken: cancellationToken,
|
||||
state: State.all
|
||||
);
|
||||
|
||||
@@ -145,11 +153,15 @@ namespace PocketSharp
|
||||
/// Retrieves items by tag
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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
|
||||
/// </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>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using PocketSharp.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
@@ -8,15 +10,30 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
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>
|
||||
/// 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>
|
||||
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.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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).
|
||||
/// </summary>
|
||||
/// <param name="itemID">The item ID.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="itemID">The item ID.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="itemID">The item ID.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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>
|
||||
/// Deletes the specified item.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="itemID">The item ID.</param>
|
||||
/// <returns></returns>
|
||||
/// <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>
|
||||
/// Deletes the specified item.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <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>
|
||||
/// Puts an action
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="itemID">The item ID.</param>
|
||||
/// <param name="action">The action.</param>
|
||||
/// <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,
|
||||
ID = itemID
|
||||
});
|
||||
}, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using PocketSharp.Models;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
@@ -13,11 +14,12 @@ namespace PocketSharp
|
||||
/// </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>
|
||||
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>
|
||||
/// <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>
|
||||
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>
|
||||
/// <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>
|
||||
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>
|
||||
/// <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>
|
||||
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.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="itemID">The item ID.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <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>
|
||||
/// <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>
|
||||
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>
|
||||
/// <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>
|
||||
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="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>
|
||||
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",
|
||||
ID = itemID,
|
||||
OldTag = oldTag,
|
||||
NewTag = newTag
|
||||
});
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
@@ -162,29 +174,31 @@ namespace PocketSharp
|
||||
/// <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>
|
||||
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>
|
||||
/// Puts the send action for tags.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="itemID">The item ID.</param>
|
||||
/// <param name="action">The action.</param>
|
||||
/// <param name="tags">The tags.</param>
|
||||
/// <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,
|
||||
ID = itemID,
|
||||
Tags = tags
|
||||
});
|
||||
}, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
@@ -12,23 +13,12 @@ namespace PocketSharp
|
||||
/// <summary>
|
||||
/// Statistics from the user account.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<PocketStatistics> GetUserStatistics()
|
||||
public async Task<PocketStatistics> GetUserStatistics(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return await Request<PocketStatistics>("stats");
|
||||
}
|
||||
|
||||
|
||||
/// <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();
|
||||
return await Request<PocketStatistics>("stats", cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,16 +27,20 @@ namespace PocketSharp
|
||||
/// 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>
|
||||
public async Task<PocketLimits> GetUsageLimits()
|
||||
public async Task<PocketLimits> GetUsageLimits(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
string rateLimitForConsumerKey = TryGetHeaderValue(lastHeaders, "X-Limit-Key-Limit");
|
||||
|
||||
if (rateLimitForConsumerKey == null)
|
||||
{
|
||||
// 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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
+40
-6
@@ -5,10 +5,10 @@ using System.Runtime.Serialization;
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// All parameters which can be passed for a modify action
|
||||
/// All parameters which can be passed for a send action
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
internal class ActionParameter
|
||||
public class PocketAction
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the action.
|
||||
@@ -20,13 +20,40 @@ namespace PocketSharp.Models
|
||||
public string Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
/// Gets or sets the PocketItem ID.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The ID.
|
||||
/// </value>
|
||||
[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>
|
||||
/// Gets or sets the time.
|
||||
@@ -71,14 +98,15 @@ namespace PocketSharp.Models
|
||||
/// Converts this instance to a parameter list.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Dictionary<string, object> Convert()
|
||||
internal Dictionary<string, object> Convert()
|
||||
{
|
||||
Dictionary<string, object> parameters = new Dictionary<string, object>
|
||||
{
|
||||
{ "item_id", ID.ToString() },
|
||||
{ "action", Action }
|
||||
};
|
||||
|
||||
if (ID != "0" && !String.IsNullOrEmpty(ID.ToString()))
|
||||
parameters.Add("item_id", ID.ToString());
|
||||
if (Time != null)
|
||||
parameters.Add("time", Time != null ? Utilities.GetUnixTimestamp(Time).ToString() : null);
|
||||
if (Tags != null)
|
||||
@@ -87,6 +115,12 @@ namespace PocketSharp.Models
|
||||
parameters.Add("old_tag", OldTag);
|
||||
if (NewTag != null)
|
||||
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;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using PropertyChanged;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -15,7 +15,7 @@ namespace PocketSharp.Models
|
||||
/// <value>
|
||||
/// The pocket item ID.
|
||||
/// </value>
|
||||
public int PocketItemID { get; set; }
|
||||
public string PocketItemID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content.
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
internal enum PocketBoolean
|
||||
{
|
||||
No = 0,
|
||||
Yes = 1,
|
||||
IsType = 2
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
using Newtonsoft.Json;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PropertyChanged;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -11,6 +12,7 @@ namespace PocketSharp.Models
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
[DebuggerDisplay("Uri = {Uri}, Title = {Title}")]
|
||||
public class PocketItem
|
||||
{
|
||||
/// <summary>
|
||||
@@ -20,7 +22,34 @@ namespace PocketSharp.Models
|
||||
/// The ID.
|
||||
/// </value>
|
||||
[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>
|
||||
/// Gets or sets the URI.
|
||||
@@ -28,8 +57,12 @@ namespace PocketSharp.Models
|
||||
/// <value>
|
||||
/// The URI.
|
||||
/// </value>
|
||||
[JsonProperty("resolved_url")]
|
||||
public Uri Uri { get; set; }
|
||||
[JsonIgnore]
|
||||
public Uri Uri
|
||||
{
|
||||
get { return _ResolvedUri ?? _NormalUri; }
|
||||
set { _NormalUri = value; _ResolvedUri = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title.
|
||||
@@ -132,7 +165,7 @@ namespace PocketSharp.Models
|
||||
/// <c>true</c> if this instance has image; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("has_image")]
|
||||
public bool HasImage { get; set; }
|
||||
private PocketBoolean? _HasImage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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>.
|
||||
/// </value>
|
||||
[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>
|
||||
/// Gets or sets the word count.
|
||||
@@ -200,65 +293,44 @@ namespace PocketSharp.Models
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the _ tag dictionary.
|
||||
/// </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.
|
||||
/// Gets or sets the tags.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The tags.
|
||||
/// </value>
|
||||
[JsonIgnore]
|
||||
public List<PocketTag> Tags
|
||||
{
|
||||
get { return Utilities.DictionaryToList<PocketTag>(_TagDictionary); }
|
||||
}
|
||||
[JsonProperty("tags")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketTag>))]
|
||||
public List<PocketTag> Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the images.
|
||||
/// Gets or sets the images.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The images.
|
||||
/// </value>
|
||||
[JsonIgnore]
|
||||
public List<PocketImage> Images
|
||||
{
|
||||
get { return Utilities.DictionaryToList<PocketImage>(_ImageDictionary); }
|
||||
}
|
||||
[JsonProperty("images")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketImage>))]
|
||||
public List<PocketImage> Images { get; set; }
|
||||
|
||||
/// <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>
|
||||
/// Gets the lead image.
|
||||
@@ -271,29 +343,5 @@ namespace PocketSharp.Models
|
||||
{
|
||||
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); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Tag
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketTag
|
||||
{
|
||||
/// <summary>
|
||||
/// Tag
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketTag
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
[JsonProperty("tag")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
[JsonProperty("tag")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,38 +4,38 @@ using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Video
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Video
|
||||
/// Gets or sets the ID.
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The ID.
|
||||
/// </value>
|
||||
[JsonProperty("video_id")]
|
||||
public string ID { get; set; }
|
||||
/// <value>
|
||||
/// The ID.
|
||||
/// </value>
|
||||
[JsonProperty("video_id")]
|
||||
public string ID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the external ID.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The external ID.
|
||||
/// </value>
|
||||
[JsonProperty("vid")]
|
||||
public string ExternalID { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the external ID.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The external ID.
|
||||
/// </value>
|
||||
[JsonProperty("vid")]
|
||||
public string ExternalID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URI.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The URI.
|
||||
/// </value>
|
||||
[JsonProperty("src")]
|
||||
public Uri Uri { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the URI.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The URI.
|
||||
/// </value>
|
||||
[JsonProperty("src")]
|
||||
public Uri Uri { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
@@ -24,17 +25,8 @@ namespace PocketSharp.Models
|
||||
/// <value>
|
||||
/// The since.
|
||||
/// </value>
|
||||
[JsonProperty]
|
||||
public int 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; }
|
||||
[JsonProperty("since")]
|
||||
public DateTime Since { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the items.
|
||||
@@ -42,10 +34,8 @@ namespace PocketSharp.Models
|
||||
/// <value>
|
||||
/// The items.
|
||||
/// </value>
|
||||
[JsonIgnore]
|
||||
public List<PocketItem> Items
|
||||
{
|
||||
get { return Utilities.DictionaryToList<PocketItem>(ItemDictionary); }
|
||||
}
|
||||
[JsonProperty("list")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketItem>))]
|
||||
public List<PocketItem> Items { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
+66
-19
@@ -1,19 +1,20 @@
|
||||
using PocketSharp.Models;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// PocketClient
|
||||
/// </summary>
|
||||
public partial class PocketClient
|
||||
public partial class PocketClient : IPocketClient
|
||||
{
|
||||
/// <summary>
|
||||
/// REST client used for the API communication
|
||||
@@ -23,7 +24,12 @@ namespace PocketSharp
|
||||
/// <summary>
|
||||
/// Caches HTTP headers from last response
|
||||
/// </summary>
|
||||
private HttpResponseHeaders lastHeaders;
|
||||
public HttpResponseHeaders lastHeaders;
|
||||
|
||||
/// <summary>
|
||||
/// Caches JSON data from last response
|
||||
/// </summary>
|
||||
public string lastResponseData;
|
||||
|
||||
/// <summary>
|
||||
/// 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}";
|
||||
|
||||
/// <summary>
|
||||
/// callback URL for API calls
|
||||
/// callback URLi for API calls
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The callback URI.
|
||||
/// </value>
|
||||
public string CallbackUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Accessor for the Pocket API key
|
||||
/// see: http://getpocket.com/developer
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The consumer key.
|
||||
/// </value>
|
||||
public string ConsumerKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Code retrieved on authentification
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The request code.
|
||||
/// </value>
|
||||
public string RequestCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Code retrieved on authentification-success
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The access code.
|
||||
/// </value>
|
||||
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>
|
||||
/// Initializes a new instance of the <see cref="PocketClient"/> class.
|
||||
/// Initializes a new instance of the <see cref="PocketClient" /> class.
|
||||
/// </summary>
|
||||
/// <param name="consumerKey">The API key</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>
|
||||
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
|
||||
ConsumerKey = consumerKey;
|
||||
@@ -82,11 +109,16 @@ namespace PocketSharp
|
||||
}
|
||||
|
||||
// initialize REST client
|
||||
_restClient = new HttpClient(new HttpClientHandler()
|
||||
_restClient = new HttpClient(handler ?? new HttpClientHandler()
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
|
||||
});
|
||||
|
||||
if (timeout.HasValue)
|
||||
{
|
||||
_restClient.Timeout = TimeSpan.FromSeconds(timeout.Value);
|
||||
}
|
||||
|
||||
// set base uri
|
||||
_restClient.BaseAddress = baseUri;
|
||||
|
||||
@@ -103,15 +135,20 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <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="requireAuth">if set to <c>true</c> [require auth].</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException">No access token available. Use authentification first.</exception>
|
||||
protected async Task<T> Request<T>(string method, 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)
|
||||
{
|
||||
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
|
||||
@@ -135,10 +172,16 @@ namespace PocketSharp
|
||||
// content of the request
|
||||
request.Content = new FormUrlEncodedContent(parameters);
|
||||
|
||||
// call pre request action
|
||||
if (PreRequest != null)
|
||||
{
|
||||
PreRequest(method);
|
||||
}
|
||||
|
||||
// make async request
|
||||
try
|
||||
{
|
||||
response = await _restClient.SendAsync(request);
|
||||
response = await _restClient.SendAsync(request, cancellationToken);
|
||||
}
|
||||
catch (HttpRequestException exc)
|
||||
{
|
||||
@@ -154,6 +197,9 @@ namespace PocketSharp
|
||||
// read response
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// cache response
|
||||
lastResponseData = responseString;
|
||||
|
||||
responseString = responseString.Replace("[]", "{}");
|
||||
|
||||
// deserialize object
|
||||
@@ -168,7 +214,9 @@ namespace PocketSharp
|
||||
Converters =
|
||||
{
|
||||
new BoolConverter(),
|
||||
new UnixDateTimeConverter()
|
||||
new UnixDateTimeConverter(),
|
||||
new NullableIntConverter(),
|
||||
new UriConverter()
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -182,7 +230,7 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
/// <param name="actionParameters">The action parameters.</param>
|
||||
/// <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>>();
|
||||
|
||||
@@ -195,7 +243,7 @@ namespace PocketSharp
|
||||
"actions", JsonConvert.SerializeObject(actionParamList)
|
||||
}};
|
||||
|
||||
Modify response = await Request<Modify>("send", parameters);
|
||||
Modify response = await Request<Modify>("send", cancellationToken, parameters);
|
||||
|
||||
return response.Status;
|
||||
}
|
||||
@@ -206,10 +254,9 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
/// <param name="actionParameter">The action parameter.</param>
|
||||
/// <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 response;
|
||||
return await Send(new List<PocketAction>() { actionParameter }, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,8 +42,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Components\Statistics.cs" />
|
||||
<Compile Include="IPocketClient.cs" />
|
||||
<Compile Include="Models\Parameters\RegisterParameters.cs" />
|
||||
<Compile Include="Models\PocketArticle.cs" />
|
||||
<Compile Include="Models\PocketBoolean.cs" />
|
||||
<Compile Include="Models\PocketLimits.cs" />
|
||||
<Compile Include="Models\PocketStatistics.cs" />
|
||||
<Compile Include="Utilities\PocketException.cs" />
|
||||
@@ -53,7 +55,7 @@
|
||||
<Compile Include="Components\ModifyTags.cs" />
|
||||
<Compile Include="Components\Get.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\ModifyParameters.cs" />
|
||||
<Compile Include="Models\Parameters\Parameters.cs" />
|
||||
@@ -70,16 +72,15 @@
|
||||
<Compile Include="Models\Response\ResponseBase.cs" />
|
||||
<Compile Include="Models\Response\Retrieve.cs" />
|
||||
<Compile Include="PocketClient.cs" />
|
||||
<Compile Include="PocketReader.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utilities\Utilities.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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 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 Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll</HintPath>
|
||||
@@ -89,33 +90,27 @@
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<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 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 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 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 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 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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="FodyWeavers.xml" />
|
||||
</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="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
@@ -124,12 +119,12 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||
</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="..\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">
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
]]>
|
||||
</releaseNotes>
|
||||
<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>
|
||||
</package>
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Reflection;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// 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
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.2.2")]
|
||||
[assembly: AssemblyFileVersion("2.2.2")]
|
||||
[assembly: AssemblyVersion("3.0.0")]
|
||||
[assembly: AssemblyFileVersion("3.0.0")]
|
||||
@@ -1,6 +1,8 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
@@ -14,7 +16,7 @@ namespace PocketSharp
|
||||
|
||||
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)
|
||||
@@ -37,7 +39,7 @@ namespace PocketSharp
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if(reader.Value.ToString() == "0")
|
||||
if (reader.Value.ToString() == "0")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -45,4 +47,112 @@ namespace PocketSharp
|
||||
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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ namespace PocketSharp
|
||||
/// converts DateTime to an UNIX timestamp
|
||||
/// </summary>
|
||||
/// <param name="dateTime">The date.</param>
|
||||
/// <returns>UNIX timestamp</returns>
|
||||
/// <returns>
|
||||
/// UNIX timestamp
|
||||
/// </returns>
|
||||
public static int? GetUnixTimestamp(DateTime? dateTime)
|
||||
{
|
||||
if (dateTime == null)
|
||||
@@ -22,30 +24,5 @@ namespace PocketSharp
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<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.Async" version="1.0.16" targetFramework="portable-net45+sl40+wp71+win" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="portable-net45+sl40+wp71+win" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="portable-net403+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.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" />
|
||||
<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" />
|
||||
</packages>
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class DomSerializationParams
|
||||
@@ -48,6 +47,10 @@ namespace PocketSharp.Ports.NReadability
|
||||
/// </summary>
|
||||
public bool BodyOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Remove headline of website
|
||||
/// </summary>
|
||||
public bool NoHeadline { get; set; }
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,18 @@
|
||||
|
||||
**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
|
||||
```
|
||||
|
||||
for the [PocketSharp.Reader](https://www.nuget.org/packages/PocketSharp.Reader/)
|
||||
|
||||
```
|
||||
Install-Package PocketSharp.Reader
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
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");
|
||||
|
||||
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
|
||||
251743431 | CSS Architecture
|
||||
343693149 | CSS3 Transitions - Thank God We Have A Specification!
|
||||
...
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
|
||||
## 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)
|
||||
- **Silverlight** >= 4
|
||||
@@ -52,21 +58,19 @@ You can find examples for Silverlight 5, WP8 and WPF in the `PocketSharp.Example
|
||||
|
||||
## What's next?
|
||||
|
||||
- `cancellationToken` support for all methods
|
||||
- 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
|
||||
- [ ] Preferences API, if Pocket will ever release it to the public -.-
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [Microsoft.Bcl.Async](https://www.nuget.org/packages/Microsoft.Bcl.Async/)
|
||||
- [Microsoft.Net.Http](https://www.nuget.org/packages/Microsoft.Net.Http/)
|
||||
- [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/)
|
||||
- [PropertyChanged.Fody](https://github.com/Fody/PropertyChanged)
|
||||
- [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/) _(used in PocketSharp & PocketSharp.Reader)_
|
||||
- [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/) _(only for PocketSharp project)_
|
||||
- [PropertyChanged.Fody](https://github.com/Fody/PropertyChanged) _(only for PocketSharp project)_
|
||||
|
||||
## Forked Dependencies
|
||||
|
||||
_used in PocketSharp.Reader_
|
||||
|
||||
- [NReadability](https://github.com/marek-stoj/NReadability) - converted to a PCL with minor adaptations
|
||||
- [SgmlReader](https://github.com/MindTouch/SGMLReader) - converted to a PCL
|
||||
|
||||
|
||||
Reference in New Issue
Block a user