Compare commits
117 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b8d211e151 | |||
| c31b771cdb | |||
| e0f96a092c | |||
| 0301bbaf10 | |||
| 5266f220e9 | |||
| c83971b4cc | |||
| 1567709ace | |||
| 342f16fb8e | |||
| 423be2df5f | |||
| 1605740107 | |||
| b7b92d87ed | |||
| 01c36a047a | |||
| 140e645e86 | |||
| 97919cdd18 | |||
| 761d670c65 | |||
| 1ca93bf07f | |||
| 556e8004f3 | |||
| 7cad855f9c | |||
| 366908a070 | |||
| d141c7b255 | |||
| 8531d20162 | |||
| 4f42ed719a | |||
| b46cc56362 | |||
| 500bd1c65d | |||
| a207ca7ca4 | |||
| 07c9f06f75 | |||
| a1ff132ba9 | |||
| 82896d6fb4 | |||
| 36683c7402 | |||
| 4e5a8ab096 | |||
| 47baa0fd97 | |||
| ec25258de9 | |||
| 6999185c96 | |||
| 7669d8880e | |||
| 38b6a62686 | |||
| 0f7f626d15 | |||
| 81f099d419 | |||
| ec006b298d | |||
| 4fa0ee29fe | |||
| c21abd5f21 | |||
| facba2894d | |||
| 585c203f9a | |||
| 07357b9327 | |||
| 75e6a23905 | |||
| 44c4bc11db | |||
| d3d8937c60 | |||
| b2113eb065 | |||
| 13664c4201 | |||
| 13c98e2d59 | |||
| 7b14044c53 | |||
| 0be1efb2df | |||
| 13e029a98a | |||
| c6cf19ba4d | |||
| 50c15ad6ce | |||
| 670fecb1e0 | |||
| 85c4ca2c65 | |||
| 0183a727ce | |||
| 25bb5028a5 | |||
| 3201160d66 | |||
| 996755ef50 | |||
| 6e6cef138a | |||
| bcb833ad0d | |||
| e33ec074fe | |||
| 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 |
+72
-3
@@ -1,3 +1,72 @@
|
||||
### 4.1.6 (2014-08-28)
|
||||
|
||||
- Fix DateTime conversion issue (from local to UTC)
|
||||
|
||||
### 4.1.5 (2014-07-27)
|
||||
|
||||
- Fix StackOverflow bug in PocketItem equality overload (fixes #28)
|
||||
|
||||
### 4.1.4 (2014-07-18)
|
||||
|
||||
- Implement WebAuthenticationBroker-view toggle
|
||||
|
||||
### 4.1.3 (2014-06-25)
|
||||
|
||||
- Only dispose response if available
|
||||
|
||||
### 4.1.2 (2014-06-18)
|
||||
|
||||
- Add force param to login+registration
|
||||
|
||||
### 4.1.1 (2014-06-17)
|
||||
|
||||
- Fix batch adding bug
|
||||
|
||||
|
||||
### 4.1.0 (2014-06-16)
|
||||
|
||||
- Include access to the Article View API
|
||||
|
||||
### 4.0.0 (2014-04-03)
|
||||
|
||||
- Support for Universal apps (dropped SL and WP7 support)
|
||||
|
||||
### 3.2.0 (2014-03-13)
|
||||
|
||||
- add raw JSON to each PocketItem (PR #22)
|
||||
|
||||
### 3.1.1 (2014-02-23)
|
||||
|
||||
- fix SendActions when sending _add_ requests (fixes #20)
|
||||
- try to normalize URIs retrieved in video array
|
||||
|
||||
### 3.1.0 (2014-02-07)
|
||||
|
||||
- Use FullTitle if no other title props are available
|
||||
- Default mobile authentication screen with toggle for desktop (fixes #17)
|
||||
- Use new registration endpoint
|
||||
|
||||
### 3.0.2 (2013-12-27)
|
||||
|
||||
- assign given_url to `Uri` when item couldn't be resolved by Pocket
|
||||
|
||||
### 3.0.1 (2013-12-15)
|
||||
|
||||
- added `PreRequest` to interface
|
||||
|
||||
### 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 +78,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
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013 cee, Tobias Klika
|
||||
Copyright (c) 2014 cee, Tobias Klika
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="PocketSharp.Silverlight.App"
|
||||
>
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
|
||||
public App()
|
||||
{
|
||||
this.Startup += this.Application_Startup;
|
||||
this.Exit += this.Application_Exit;
|
||||
this.UnhandledException += this.Application_UnhandledException;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Application_Startup(object sender, StartupEventArgs e)
|
||||
{
|
||||
this.RootVisual = new MainPage();
|
||||
}
|
||||
|
||||
private void Application_Exit(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
|
||||
{
|
||||
// If the app is running outside of the debugger then report the exception using
|
||||
// the browser's exception mechanism. On IE this will display it a yellow alert
|
||||
// icon in the status bar and Firefox will display a script error.
|
||||
if (!System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
|
||||
// NOTE: This will allow the application to continue running after an exception has been thrown
|
||||
// but not handled.
|
||||
// For production applications this error handling should be replaced with something that will
|
||||
// report the error to the website and stop the application.
|
||||
e.Handled = true;
|
||||
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
|
||||
}
|
||||
}
|
||||
|
||||
private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
|
||||
errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");
|
||||
|
||||
System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<UserControl
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="PocketSharp.Silverlight.MainPage"
|
||||
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"/>
|
||||
|
||||
<sdk:DataGrid x:Name="Content" HorizontalAlignment="Left" Height="241" Margin="10,49,0,0" VerticalAlignment="Top" Width="380" FrozenColumnCount="2"/>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,68 +0,0 @@
|
||||
using System;
|
||||
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
|
||||
{
|
||||
public partial class MainPage : UserControl
|
||||
{
|
||||
ObservableCollection<Site> _Sites = new ObservableCollection<Site>();
|
||||
|
||||
public ObservableCollection<Site> Sites { get { return _Sites; } }
|
||||
|
||||
public class Site
|
||||
{
|
||||
public string Url { get; set; }
|
||||
public string Content { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
private async void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// !! please don't misuse this account !!
|
||||
PocketClient client = new PocketClient(
|
||||
consumerKey: "15396-f6f92101d72c8e270a6c9bb3",
|
||||
callbackUri: "http://frontendplay.com",
|
||||
accessCode: "2c62cd50-b78a-5558-918b-65adae"
|
||||
);
|
||||
|
||||
List<PocketSharp.Models.PocketItem> items = null;
|
||||
|
||||
try
|
||||
{
|
||||
items = await client.Get();
|
||||
|
||||
items.ForEach(item =>
|
||||
{
|
||||
Sites.Add(new Site()
|
||||
{
|
||||
Content = item.Title,
|
||||
Url = item.Uri.ToString()
|
||||
});
|
||||
});
|
||||
|
||||
Content.ItemsSource = Sites;
|
||||
}
|
||||
catch (PocketException ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}</ProjectGuid>
|
||||
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PocketSharp.Silverlight</RootNamespace>
|
||||
<AssemblyName>PocketSharp.Silverlight</AssemblyName>
|
||||
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
|
||||
<SilverlightApplication>true</SilverlightApplication>
|
||||
<SupportedCultures>
|
||||
</SupportedCultures>
|
||||
<XapOutputs>true</XapOutputs>
|
||||
<GenerateSilverlightManifest>true</GenerateSilverlightManifest>
|
||||
<XapFilename>PocketSharp.Silverlight.xap</XapFilename>
|
||||
<SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate>
|
||||
<SilverlightAppEntry>PocketSharp.Silverlight.App</SilverlightAppEntry>
|
||||
<TestPageFileName>PocketSharp.SilverlightTestPage.html</TestPageFileName>
|
||||
<CreateTestPage>true</CreateTestPage>
|
||||
<ValidateXaml>true</ValidateXaml>
|
||||
<EnableOutOfBrowser>false</EnableOutOfBrowser>
|
||||
<OutOfBrowserSettingsFile>Properties\OutOfBrowserSettings.xml</OutOfBrowserSettingsFile>
|
||||
<UsePlatformExtensions>false</UsePlatformExtensions>
|
||||
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
|
||||
<LinkedServerProject>
|
||||
</LinkedServerProject>
|
||||
<ExpressionBlendVersion>12.0.40612.10</ExpressionBlendVersion>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
</PropertyGroup>
|
||||
<!-- This property group is only here to support building this project using the
|
||||
MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs
|
||||
to set the TargetFrameworkVersion to v3.5 -->
|
||||
<PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>Bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<NoConfig>true</NoConfig>
|
||||
<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;SILVERLIGHT</DefineConstants>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<NoConfig>true</NoConfig>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Threading.Tasks">
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.16\lib\sl4\Microsoft.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions">
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.16\lib\sl4\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions.Silverlight">
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.16\lib\sl4\Microsoft.Threading.Tasks.Extensions.Silverlight.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.IO, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.1.1.3\lib\sl5\System.IO.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>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks, Version=2.6.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.1.1.3\lib\sl5\System.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows" />
|
||||
<Reference Include="system" />
|
||||
<Reference Include="System.Core">
|
||||
<HintPath>$(TargetFrameworkDirectory)System.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Windows.Controls.Data" />
|
||||
<Reference Include="System.Windows.Controls.Data.Input" />
|
||||
<Reference Include="System.Windows.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Windows.Browser" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MainPage.xaml.cs">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="MainPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\AppManifest.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\PocketSharp\PocketSharp.csproj">
|
||||
<Project>{817200c3-a327-4e35-9b5f-63a51c088577}</Project>
|
||||
<Name>PocketSharp</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
|
||||
<!-- 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>
|
||||
-->
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
|
||||
<SilverlightProjectProperties />
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>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=322105. The missing file is {0}.</ErrorText>
|
||||
</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>
|
||||
</Project>
|
||||
@@ -1,6 +0,0 @@
|
||||
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
>
|
||||
<Deployment.Parts>
|
||||
</Deployment.Parts>
|
||||
</Deployment>
|
||||
@@ -1,35 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 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.Silverlight")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("PocketSharp.Silverlight")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("656345d2-af4c-4f88-9c9f-ebf54d7691db")]
|
||||
|
||||
// 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 Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<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" />
|
||||
</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>
|
||||
@@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Resources;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Navigation;
|
||||
using Microsoft.Phone.Controls;
|
||||
using Microsoft.Phone.Controls;
|
||||
using Microsoft.Phone.Shell;
|
||||
using PocketSharp.WP8.Resources;
|
||||
using PocketSharp.WP8.ViewModels;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
namespace PocketSharp.WP8
|
||||
{
|
||||
|
||||
@@ -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,8 @@
|
||||
</DesignData>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\AppManifest.xml" />
|
||||
<None Include="Properties\WMAppManifest.xml">
|
||||
<SubType>Designer</SubType>
|
||||
@@ -178,6 +180,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 +209,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,11 @@
|
||||
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;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.WP8.ViewModels
|
||||
{
|
||||
@@ -68,14 +68,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()).ToList();
|
||||
|
||||
items.ForEach(item =>
|
||||
{
|
||||
|
||||
+2
-2
@@ -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.7.0" newVersion="2.6.7.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.7.0" newVersion="2.6.7.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
@@ -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,8 @@
|
||||
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;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Wpf
|
||||
{
|
||||
@@ -35,14 +34,14 @@ 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;
|
||||
|
||||
try
|
||||
{
|
||||
items = await client.Get();
|
||||
items = (await client.Get()).ToList();
|
||||
|
||||
items.ForEach(item =>
|
||||
{
|
||||
|
||||
@@ -39,23 +39,25 @@
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</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.Data" />
|
||||
<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="System.Xml" />
|
||||
@@ -129,10 +131,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.
|
||||
|
||||
@@ -5,7 +5,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,7 +1,7 @@
|
||||
<?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" />
|
||||
</packages>
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -12,48 +10,14 @@ namespace PocketSharp.Tests
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task IsUserRegistered()
|
||||
public async Task IsRegistrationURLSuccessfullyCreated()
|
||||
{
|
||||
string randomId = ((int)((DateTime)DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds).ToString();
|
||||
string requestCode = await client.GetRequestCode();
|
||||
|
||||
bool success = await client.RegisterAccount("pocket-" + randomId, String.Format("pocketsharp-{0}@outlook.com", randomId), "mypassword");
|
||||
Uri uri = client.GenerateRegistrationUri(requestCode);
|
||||
|
||||
Assert.True(success);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task AreInvalidRegistrationsBlocked()
|
||||
{
|
||||
await ThrowsAsync<FormatException>(async () =>
|
||||
{
|
||||
await client.RegisterAccount("abcdefghijklmnopqrstuvwxyz", "pocketsharp@outlook.com", "mypassword");
|
||||
});
|
||||
|
||||
await ThrowsAsync<FormatException>(async () =>
|
||||
{
|
||||
await client.RegisterAccount("oiu_my:o;", "pocketsharp@outlook.com", "mypassword");
|
||||
});
|
||||
|
||||
await ThrowsAsync<FormatException>(async () =>
|
||||
{
|
||||
await client.RegisterAccount("myusername", "pocketsharpoutlook.com", "mypassword");
|
||||
});
|
||||
|
||||
await ThrowsAsync<FormatException>(async () =>
|
||||
{
|
||||
await client.RegisterAccount("myusername", "pocketsharp@outlook", "mypassword");
|
||||
});
|
||||
|
||||
await ThrowsAsync<FormatException>(async () =>
|
||||
{
|
||||
await client.RegisterAccount("myusername", "pocketsharp@outlook,com", "mypassword");
|
||||
});
|
||||
|
||||
await ThrowsAsync<ArgumentNullException>(async () =>
|
||||
{
|
||||
await client.RegisterAccount("myusername", null, "mypassword");
|
||||
});
|
||||
Assert.True(uri.OriginalString.Contains(requestCode));
|
||||
Assert.True(uri.OriginalString.Contains("force=signup"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -24,6 +25,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.NotNull(item);
|
||||
|
||||
itemsToDelete.Add(item.ID);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task AddComplexItem()
|
||||
{
|
||||
@@ -34,12 +48,12 @@ namespace PocketSharp.Tests
|
||||
tweetID: "380051788172632065"
|
||||
);
|
||||
|
||||
List<PocketItem> items = await client.Get();
|
||||
List<PocketItem> items = (await client.Get()).ToList();
|
||||
PocketItem itemDesired = null;
|
||||
|
||||
items.ForEach(itm =>
|
||||
{
|
||||
if(itm.ID == item.ID)
|
||||
if (itm.ID == item.ID)
|
||||
{
|
||||
itemDesired = itm;
|
||||
}
|
||||
@@ -47,9 +61,65 @@ namespace PocketSharp.Tests
|
||||
|
||||
Assert.NotNull(itemDesired);
|
||||
Assert.Equal(itemDesired.ID, item.ID);
|
||||
Assert.Equal(itemDesired.Tags.Count, 3);
|
||||
Assert.Equal(itemDesired.Tags.Count(), 3);
|
||||
|
||||
itemsToDelete.Add(item.ID);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ItemViaActionsIsAdded()
|
||||
{
|
||||
List<PocketAction> actions = new List<PocketAction>();
|
||||
|
||||
actions.Add(new PocketAction()
|
||||
{
|
||||
Uri = new Uri("http://frontendplay.com/story/4015/string-indexer-for-text-resources-in-nancy"),
|
||||
Action = "add",
|
||||
Time = DateTime.Now
|
||||
});
|
||||
|
||||
bool success = await client.SendActions(actions);
|
||||
|
||||
Assert.True(success);
|
||||
|
||||
IEnumerable<PocketItem> items = await client.Search("in nancy");
|
||||
|
||||
Assert.NotNull(items);
|
||||
Assert.True(items.Count() > 0);
|
||||
|
||||
itemsToDelete.Add(items.First().ID);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ItemsViaActionsIsAdded()
|
||||
{
|
||||
List<PocketAction> actions = new List<PocketAction>();
|
||||
|
||||
actions.Add(new PocketAction()
|
||||
{
|
||||
Uri = new Uri("http://frontendplay.com/story/4015/string-indexer-for-text-resources-in-nancy"),
|
||||
Action = "add",
|
||||
Time = DateTime.Now
|
||||
});
|
||||
actions.Add(new PocketAction()
|
||||
{
|
||||
Uri = new Uri("http://frontendplay.com/story/4013/build-a-custom-razor-viewbase-in-nancy"),
|
||||
Action = "add",
|
||||
Time = DateTime.Now
|
||||
});
|
||||
|
||||
bool success = await client.SendActions(actions);
|
||||
|
||||
Assert.True(success);
|
||||
|
||||
IEnumerable<PocketItem> items = await client.Search("in nancy");
|
||||
|
||||
Assert.NotNull(items);
|
||||
Assert.True(items.Count() == 2);
|
||||
|
||||
itemsToDelete.AddRange(items.Select(item => item.ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
+173
-31
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -14,8 +17,7 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task AreItemsRetrieved()
|
||||
{
|
||||
List<PocketItem> items = await client.Get();
|
||||
|
||||
List<PocketItem> items = (await client.Get()).ToList();
|
||||
Assert.True(items.Count > 0);
|
||||
}
|
||||
|
||||
@@ -23,7 +25,7 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task IsItemRetrievedById()
|
||||
{
|
||||
List<PocketItem> items = await client.Get();
|
||||
List<PocketItem> items = (await client.Get()).ToList();
|
||||
PocketItem item = items[0];
|
||||
PocketItem itemDuplicate = await client.Get(item.ID);
|
||||
|
||||
@@ -31,20 +33,37 @@ namespace PocketSharp.Tests
|
||||
Assert.True(item.Uri == itemDuplicate.Uri);
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
// public async Task IsItemJsonPopulated()
|
||||
// {
|
||||
// List<PocketItem> items = (await client.Get()).ToList();
|
||||
// string schemaJson = @"{
|
||||
// 'description': 'PocketItem',
|
||||
// 'type': 'object'
|
||||
// }";
|
||||
|
||||
// JsonSchema schema = JsonSchema.Parse(schemaJson);
|
||||
// foreach (var pocketItem in items)
|
||||
// {
|
||||
// Assert.True(!string.IsNullOrWhiteSpace(pocketItem.Json));
|
||||
// var jObject = JObject.Parse(pocketItem.Json);
|
||||
// Assert.True(jObject.IsValid(schema));
|
||||
// }
|
||||
// }
|
||||
|
||||
[Fact]
|
||||
public async Task AreFilteredItemsRetrieved()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(RetrieveFilter.Favorite);
|
||||
IEnumerable<PocketItem> items = await client.Get(RetrieveFilter.Favorite);
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task RetrieveWithMultipleFilters()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(
|
||||
IEnumerable<PocketItem> items = await client.Get(
|
||||
state: State.unread,
|
||||
tag: "pocket",
|
||||
sort: Sort.title,
|
||||
@@ -52,78 +71,78 @@ namespace PocketSharp.Tests
|
||||
count: 2
|
||||
);
|
||||
|
||||
Assert.InRange<int>(items.Count, 0, 2);
|
||||
Assert.InRange<int>(items.Count(), 0, 2);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ItemContainsUri()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(count: 1);
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 1);
|
||||
|
||||
Assert.True(items.Count == 1);
|
||||
Assert.True(items[0].Uri.ToString().StartsWith("http"));
|
||||
Assert.True(items.Count() == 1);
|
||||
Assert.True(items.First().Uri.ToString().StartsWith("http"));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task InvalidRetrievalReturnsNoResults()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(
|
||||
IEnumerable<PocketItem> items = await client.Get(
|
||||
favorite: true,
|
||||
search: "xoiu987a#;"
|
||||
);
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
Assert.False(items.Count() > 0);
|
||||
|
||||
PocketItem item = await client.Get(99999999);
|
||||
PocketItem item = await client.Get("99999999");
|
||||
|
||||
Assert.Null(item);
|
||||
|
||||
items = await client.Get(RetrieveFilter.Video);
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
Assert.False(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task SearchReturnsResult()
|
||||
{
|
||||
List<PocketItem> items = await client.Search("pocket");
|
||||
IEnumerable<PocketItem> items = await client.Search("pocket");
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items[0].FullTitle.ToLower().Contains("pocket"));
|
||||
Assert.True(items.Count() > 0);
|
||||
Assert.True(items.First().FullTitle.ToLower().Contains("pocket"));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task InvalidSearchReturnsNoResult()
|
||||
{
|
||||
List<PocketItem> items = await client.Search("adsüasd-opiu2;.398dfyx");
|
||||
IEnumerable<PocketItem> items = await client.Search("adsüasd-opiu2;.398dfyx");
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
Assert.False(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task RetrieveTagsReturnsResult()
|
||||
{
|
||||
List<PocketTag> items = await client.GetTags();
|
||||
IEnumerable<PocketTag> items = await client.GetTags();
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task SearchByTagsReturnsResult()
|
||||
{
|
||||
List<PocketItem> items = await client.SearchByTag("pocket");
|
||||
IEnumerable<PocketItem> items = await client.SearchByTag("pocket");
|
||||
|
||||
Assert.True(items.Count == 1);
|
||||
Assert.True(items.Count() == 1);
|
||||
|
||||
bool found = false;
|
||||
|
||||
items[0].Tags.ForEach(tag =>
|
||||
items.First().Tags.ToList().ForEach(tag =>
|
||||
{
|
||||
if (tag.Name.Contains("pocket"))
|
||||
{
|
||||
@@ -138,16 +157,16 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task InvalidSearchByTagsReturnsNoResult()
|
||||
{
|
||||
List<PocketItem> items = await client.SearchByTag("adsüasd-opiu2;.398dfyx");
|
||||
IEnumerable<PocketItem> items = await client.SearchByTag("adsüasd-opiu2;.398dfyx");
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
Assert.False(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task AreStatisticsRetrieved()
|
||||
{
|
||||
PocketStatistics statistics = await client.Statistics();
|
||||
PocketStatistics statistics = await client.GetUserStatistics();
|
||||
|
||||
Assert.True(statistics.CountAll > 0);
|
||||
}
|
||||
@@ -160,5 +179,128 @@ namespace PocketSharp.Tests
|
||||
|
||||
Assert.True(limits.RateLimitForConsumerKey > 9999);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task IsNewPocketItemListGeneratorWorking()
|
||||
{
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 1, tag: "pocket");
|
||||
PocketItem item = items.First();
|
||||
|
||||
Assert.True(item.Tags.ToList().Find(i => i.Name == "pocket") != null);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task IsSinceParameterWorkingOnAddTags()
|
||||
{
|
||||
DateTime since = DateTime.Now;
|
||||
|
||||
IEnumerable<PocketItem> items = await client.Get(state: State.all);
|
||||
PocketItem itemToModify = items.First();
|
||||
|
||||
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.Now;//1409221736
|
||||
|
||||
IEnumerable<PocketItem> items = await client.Get(state: State.all);
|
||||
PocketItem itemToModify = items.First();
|
||||
|
||||
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.Now;
|
||||
|
||||
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 IsUTCSinceParameterWorking()
|
||||
{
|
||||
DateTime since = DateTime.UtcNow;
|
||||
|
||||
IEnumerable<PocketItem> items = await client.Get(state: State.all);
|
||||
PocketItem itemToModify = items.First();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task IsSinceParameterWorkingOnAddAndDelete()
|
||||
{
|
||||
DateTime since = DateTime.UtcNow;
|
||||
|
||||
PocketItem item = await client.Add(new Uri("http://frontendplay.com"));
|
||||
|
||||
IEnumerable<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.First().IsDeleted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AreUncachedItemsProperlyResolved()
|
||||
{
|
||||
PocketItem item = await client.Add(new Uri("http://de.ign.com/m/feature/21608/die-20-besten-kurzfilme-des-jahres-2013?bust=1"));
|
||||
|
||||
IEnumerable<PocketItem> items = await client.Get(state: State.all);
|
||||
|
||||
Assert.NotNull(item.Uri);
|
||||
Assert.NotNull(items.First().Uri);
|
||||
Assert.Equal(item.Uri, items.First().Uri);
|
||||
|
||||
itemsToDelete.Add(item.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
using PocketSharp.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
public class MiscTests : TestsBase
|
||||
{
|
||||
private int Incrementor = 0;
|
||||
|
||||
public MiscTests()
|
||||
: base()
|
||||
{
|
||||
client.PreRequest = method => Incrementor++;
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task CheckPreRequestAction()
|
||||
{
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 1);
|
||||
PocketItem item = items.First();
|
||||
|
||||
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
|
||||
{
|
||||
@@ -21,7 +21,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
item = await GetItemById(item.ID);
|
||||
|
||||
Assert.True(item.Tags.Count >= 2);
|
||||
Assert.True(item.Tags.Count() >= 2);
|
||||
|
||||
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "test_tag"));
|
||||
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "test_tag2"));
|
||||
@@ -44,7 +44,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
item = await GetItemById(item.ID);
|
||||
|
||||
Assert.True(item.Tags.Count >= 2);
|
||||
Assert.True(item.Tags.Count() >= 2);
|
||||
|
||||
Assert.True(await client.RemoveTags(item));
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
item = await GetItemById(item.ID);
|
||||
|
||||
Assert.Equal(item.Tags.Count, 2);
|
||||
Assert.Equal(item.Tags.Count(), 2);
|
||||
|
||||
Assert.NotNull(item.Tags.SingleOrDefault<PocketTag>(tag => tag.Name == "test_tag"));
|
||||
Assert.NotNull(item.Tags.SingleOrDefault<PocketTag>(tag => tag.Name == "test_tag2"));
|
||||
@@ -83,9 +83,9 @@ namespace PocketSharp.Tests
|
||||
}
|
||||
|
||||
|
||||
private async Task<PocketItem> GetItemById(int id, bool archive = false)
|
||||
private async Task<PocketItem> GetItemById(string id, bool archive = false)
|
||||
{
|
||||
List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread);
|
||||
List<PocketItem> items = (await client.Get(state: archive ? State.archive : State.unread)).ToList();
|
||||
PocketItem itemDesired = null;
|
||||
|
||||
items.ForEach(itm =>
|
||||
|
||||
@@ -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,65 @@ 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 }
|
||||
});
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task AreMultipleAddActionsSent()
|
||||
{
|
||||
PocketItem item = await Setup();
|
||||
|
||||
bool success = await client.SendActions(new List<PocketAction>()
|
||||
{
|
||||
new PocketAction() { Action = "add", Uri = new Uri("http://msdn.microsoft.com/en-us/library/windows/apps/jj841126.aspx") },
|
||||
new PocketAction() { Action = "add", Uri = new Uri("http://pokiapp.com/changelog") }
|
||||
});
|
||||
|
||||
Assert.True(success);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task AreMultipleActionsOnOneItemPerformed()
|
||||
{
|
||||
PocketItem item = await Setup();
|
||||
|
||||
bool success = await client.SendActions(new List<PocketAction>()
|
||||
{
|
||||
new PocketAction() { Action = "unarchive", ID = item.ID },
|
||||
new PocketAction() { Action = "archive", ID = item.ID },
|
||||
new PocketAction() { Action = "unfavorite", ID = item.ID }
|
||||
});
|
||||
|
||||
Assert.True(success);
|
||||
|
||||
item = await client.Get(item.ID);
|
||||
|
||||
Assert.False(item.IsFavorite);
|
||||
Assert.True(item.IsArchive);
|
||||
}
|
||||
|
||||
|
||||
private async Task<PocketItem> Setup()
|
||||
{
|
||||
PocketItem item = await client.Add(
|
||||
@@ -75,9 +135,9 @@ namespace PocketSharp.Tests
|
||||
}
|
||||
|
||||
|
||||
private async Task<PocketItem> GetItemById(int id, bool archive = false)
|
||||
private async Task<PocketItem> GetItemById(string id, bool archive = false)
|
||||
{
|
||||
List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread);
|
||||
List<PocketItem> items = (await client.Get(state: archive ? State.archive : State.unread)).ToList();
|
||||
PocketItem itemDesired = null;
|
||||
|
||||
items.ForEach(itm =>
|
||||
|
||||
@@ -37,22 +37,31 @@
|
||||
<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.166\lib\net40\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.166\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
|
||||
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.166\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Newtonsoft.Json.6.0.2\lib\net45\Newtonsoft.Json.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.19.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.19\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.19.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.19\lib\net45\System.Net.Http.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="xunit">
|
||||
@@ -68,13 +77,14 @@
|
||||
<Otherwise />
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="MiscTests.cs" />
|
||||
<Compile Include="AddTests.cs" />
|
||||
<Compile Include="AccountTests.cs" />
|
||||
<Compile Include="ModifyTagsTests.cs" />
|
||||
<Compile Include="ModifyTests.cs" />
|
||||
<Compile Include="GetTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReadTests.cs" />
|
||||
<Compile Include="StressTests.cs" />
|
||||
<Compile Include="TestsBase.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -86,6 +96,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 +126,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.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\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.14\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.14\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,59 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using PocketSharp.Models;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
public class ReadTests : TestsBase
|
||||
{
|
||||
private PocketReader reader;
|
||||
|
||||
|
||||
public ReadTests() : base()
|
||||
{
|
||||
reader = new PocketReader();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ReadArticleTest()
|
||||
{
|
||||
PocketArticle result = await reader.Read(new PocketItem()
|
||||
{
|
||||
ID = 99,
|
||||
Uri = new Uri("http://frontendplay.com/story/4/http-caching-demystified-part-2-implementation")
|
||||
});
|
||||
|
||||
Assert.True(result.Content.Length > 15000);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ReadArticleWithInvalidUriTest()
|
||||
{
|
||||
await ThrowsAsync<PocketException>(async () =>
|
||||
{
|
||||
await reader.Read(new PocketItem()
|
||||
{
|
||||
ID = 99,
|
||||
Uri = new Uri("http://frontendplayyyyy.com")
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task IsBodyOnlyProperlyResolved()
|
||||
{
|
||||
PocketArticle result = await reader.Read(new PocketItem()
|
||||
{
|
||||
ID = 99,
|
||||
Uri = new Uri("http://calebjacob.com/tooltipster/")
|
||||
});
|
||||
|
||||
Assert.True(result.Content.Substring(0, 4) == "<div");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,131 @@
|
||||
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()
|
||||
{
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 100, state: State.all);
|
||||
Assert.True(items.Count() == 100);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Are1000ItemsRetrievedProperly()
|
||||
{
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 1000, state: State.all);
|
||||
Assert.True(items.Count() == 1000);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Are2500ItemsRetrievedProperly()
|
||||
{
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 2500, state: State.all);
|
||||
Assert.True(items.Count() == 2500);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Are5000ItemsRetrievedProperly()
|
||||
{
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 5000, state: State.all);
|
||||
Assert.True(items.Count() == 5000);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IsSearchSuccessfullyOnBigList()
|
||||
{
|
||||
IEnumerable<PocketItem> items = await client.Get(search: "google");
|
||||
|
||||
Assert.True(items.Count() > 0);
|
||||
Assert.True(items.First().Title.ToLower().Contains("google") || items.First().Uri.ToString().ToLower().Contains("google"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IsTagSearchSuccessfullyOnBigList()
|
||||
{
|
||||
IEnumerable<PocketItem> items = await client.SearchByTag(tags[0]);
|
||||
|
||||
Assert.True(items.Count() > 1);
|
||||
|
||||
bool found = false;
|
||||
|
||||
items.First().Tags.ToList().ForEach(tag =>
|
||||
{
|
||||
if (tag.Name.Contains(tags[0]))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
|
||||
Assert.True(found);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RetrieveTagsReturnsResultOnBigList()
|
||||
{
|
||||
List<PocketTag> items = (await client.GetTags()).ToList();
|
||||
|
||||
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();
|
||||
|
||||
var items = urls.Skip(offset).Take(count)
|
||||
.Select((value, idx) => new { Value = value, Index = idx })
|
||||
.GroupBy(item => item.Index / 100, item => item.Value)
|
||||
.Cast<IEnumerable<string>>();
|
||||
|
||||
foreach (IEnumerable<string> urlGroup in items)
|
||||
{
|
||||
await Task.WhenAll(urlGroup.Select(url =>
|
||||
{
|
||||
r = rnd.Next(tags.Length);
|
||||
r2 = rnd.Next(tags.Length);
|
||||
tag = new string[] { tags[r], tags[r2] };
|
||||
return client.Add(new Uri("http://" + url), tag);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task Fillll()
|
||||
//{
|
||||
// await FillAccount(11000, 89999);
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -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.19.0" newVersion="4.2.19.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?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.7" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.166" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.19" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="6.0.2" 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
+11
-44
@@ -1,20 +1,9 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp", "PocketSharp\PocketSharp.csproj", "{817200C3-A327-4E35-9B5F-63A51C088577}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Wpf", "PocketSharp.Examples\PocketSharp.Wpf\PocketSharp.Wpf.csproj", "{775569C2-987F-4AC4-8BA5-A315A21ED1B7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{817200C3-A327-4E35-9B5F-63A51C088577} = {817200C3-A327-4E35-9B5F-63A51C088577}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.30324.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PocketSharp.Examples", "PocketSharp.Examples", "{AFD4E3F1-B23C-4924-BA5B-D917FBADB8FA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Silverlight", "PocketSharp.Examples\PocketSharp.Silverlight\PocketSharp.Silverlight.csproj", "{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.WP8", "PocketSharp.Examples\PocketSharp.WP8\PocketSharp.WP8.csproj", "{47721A56-2128-4C5A-8B92-995FFC353304}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Tests", "PocketSharp.Tests\PocketSharp.Tests.csproj", "{CA3C491B-A8CA-426C-A0BB-E91636767467}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{19DD45B5-B849-49E7-89D6-16C89B9B96C7}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.nuget\NuGet.Config = .nuget\NuGet.Config
|
||||
@@ -22,11 +11,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{19DD45
|
||||
.nuget\NuGet.targets = .nuget\NuGet.targets
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NReadability", "PortablePorts\NReadability\NReadability.csproj", "{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp", "PocketSharp\PocketSharp.csproj", "{817200C3-A327-4E35-9B5F-63A51C088577}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SgmlReader", "PortablePorts\SgmlReader\SgmlReader.csproj", "{9112414C-E2D1-43BA-A298-A89F77D94332}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Wpf", "PocketSharp.Examples\PocketSharp.Wpf\PocketSharp.Wpf.csproj", "{775569C2-987F-4AC4-8BA5-A315A21ED1B7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{817200C3-A327-4E35-9B5F-63A51C088577} = {817200C3-A327-4E35-9B5F-63A51C088577}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PortablePorts", "PortablePorts", "{82F79DE3-76D7-4FCB-AA7E-16BA7E363E0D}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.WP8", "PocketSharp.Examples\PocketSharp.WP8\PocketSharp.WP8.csproj", "{47721A56-2128-4C5A-8B92-995FFC353304}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PocketSharp.Tests", "PocketSharp.Tests\PocketSharp.Tests.csproj", "{CA3C491B-A8CA-426C-A0BB-E91636767467}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -55,14 +49,6 @@ Global
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{47721A56-2128-4C5A-8B92-995FFC353304}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{47721A56-2128-4C5A-8B92-995FFC353304}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{47721A56-2128-4C5A-8B92-995FFC353304}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
@@ -89,31 +75,12 @@ Global
|
||||
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{CA3C491B-A8CA-426C-A0BB-E91636767467}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7} = {AFD4E3F1-B23C-4924-BA5B-D917FBADB8FA}
|
||||
{656345D2-AF4C-4F88-9C9F-EBF54D7691DB} = {AFD4E3F1-B23C-4924-BA5B-D917FBADB8FA}
|
||||
{47721A56-2128-4C5A-8B92-995FFC353304} = {AFD4E3F1-B23C-4924-BA5B-D917FBADB8FA}
|
||||
{9112414C-E2D1-43BA-A298-A89F77D94332} = {82F79DE3-76D7-4FCB-AA7E-16BA7E363E0D}
|
||||
{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2} = {82F79DE3-76D7-4FCB-AA7E-16BA7E363E0D}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
@@ -14,10 +14,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 +27,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,45 +49,57 @@ 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;
|
||||
}
|
||||
|
||||
return new Uri(string.Format(authentificationUri, RequestCode, CallbackUri));
|
||||
return new Uri(String.Format(authentificationUri, RequestCode, CallbackUri, isMobileClient ? "1" : "0", "login", useInsideWebAuthenticationBroker ? "1" : "0"));
|
||||
}
|
||||
|
||||
|
||||
/// <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.
|
||||
/// Generate registration URI from requestCode
|
||||
/// Follow the steps as with GenerateAuthenticationUri, but for unregistered users
|
||||
/// </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>
|
||||
/// <returns>A valid URI to redirect the user to.</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)
|
||||
public Uri GenerateRegistrationUri(string requestCode = null)
|
||||
{
|
||||
await GetUser(requestCode);
|
||||
return AccessCode;
|
||||
// check if request code is available
|
||||
if (RequestCode == null && requestCode == null)
|
||||
{
|
||||
throw new NullReferenceException("Call GetRequestCode() first to receive a request_code");
|
||||
}
|
||||
|
||||
// override property with given param if available
|
||||
if (requestCode != null)
|
||||
{
|
||||
RequestCode = requestCode;
|
||||
}
|
||||
|
||||
return new Uri(String.Format(authentificationUri, RequestCode, CallbackUri, isMobileClient ? "1" : "0", "signup", useInsideWebAuthenticationBroker ? "1" : "0"));
|
||||
}
|
||||
|
||||
|
||||
/// <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 +114,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);
|
||||
@@ -111,60 +124,5 @@ namespace PocketSharp
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Registers a new account.
|
||||
/// Account has to be activated via a activation email sent by Pocket.
|
||||
/// </summary>
|
||||
/// <param name="username">The username.</param>
|
||||
/// <param name="email">The email.</param>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="System.ArgumentNullException">All parameters are required</exception>
|
||||
/// <exception cref="System.FormatException">
|
||||
/// Invalid email address.
|
||||
/// or
|
||||
/// Invalid username. Please only use letters, numbers, and/or dashes and between 1-20 characters.
|
||||
/// or
|
||||
/// Invalid password.
|
||||
/// </exception>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<bool> RegisterAccount(string username, string email, string password)
|
||||
{
|
||||
if (username == null || email == null || password == null)
|
||||
{
|
||||
throw new ArgumentNullException("All parameters are required");
|
||||
}
|
||||
|
||||
Match matchEmail = Regex.Match(email, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,10}))$");
|
||||
Match matchUsername = Regex.Match(username, @"^([\w\-_]{1,20})$");
|
||||
|
||||
if (!matchEmail.Success)
|
||||
{
|
||||
throw new FormatException("(1) Invalid email address.");
|
||||
}
|
||||
|
||||
if (!matchUsername.Success)
|
||||
{
|
||||
throw new FormatException("(2) Invalid username. Please only use letters, numbers, and/or dashes and between 1-20 characters.");
|
||||
}
|
||||
|
||||
if (password.Length < 3)
|
||||
{
|
||||
throw new FormatException("(3) Invalid password.");
|
||||
}
|
||||
|
||||
RegisterParameters parameters = new RegisterParameters()
|
||||
{
|
||||
Username = username,
|
||||
Email = email,
|
||||
Password = password
|
||||
};
|
||||
|
||||
ResponseBase response = await Request<ResponseBase>("signup", 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;
|
||||
}
|
||||
|
||||
+100
-64
@@ -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,23 +12,24 @@ 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>
|
||||
public async Task<List<PocketItem>> Get(
|
||||
/// <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<IEnumerable<PocketItem>> Get(
|
||||
State? state = null,
|
||||
bool? favorite = null,
|
||||
string tag = 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()
|
||||
@@ -50,14 +53,12 @@ namespace PocketSharp
|
||||
DetailType = DetailType.complete,
|
||||
Search = search,
|
||||
Domain = domain,
|
||||
Since = since,
|
||||
Since = since.HasValue ? ((DateTime)since).ToUniversalTime() : since,
|
||||
Count = count,
|
||||
Offset = offset
|
||||
};
|
||||
|
||||
Retrieve response = await Request<Retrieve>("get", parameters.Convert());
|
||||
|
||||
return response.Items;
|
||||
return (await Request<Retrieve>("get", cancellationToken, parameters.Convert())).Items ?? new List<PocketItem>();
|
||||
}
|
||||
|
||||
|
||||
@@ -66,15 +67,15 @@ 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
|
||||
);
|
||||
|
||||
return items.SingleOrDefault<PocketItem>(item => item.ID == itemID);
|
||||
return (await Get(
|
||||
cancellationToken: cancellationToken,
|
||||
state: State.all
|
||||
)).SingleOrDefault<PocketItem>(item => item.ID == itemID);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,13 +83,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<IEnumerable<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
RetrieveParameters parameters = new RetrieveParameters();
|
||||
|
||||
switch(filter)
|
||||
switch (filter)
|
||||
{
|
||||
case RetrieveFilter.Article:
|
||||
parameters.ContentType = ContentType.article;
|
||||
@@ -115,9 +117,19 @@ namespace PocketSharp
|
||||
|
||||
parameters.DetailType = DetailType.complete;
|
||||
|
||||
Retrieve response = await Request<Retrieve>("get", parameters.Convert());
|
||||
return (await Request<Retrieve>("get", cancellationToken, parameters.Convert())).Items;
|
||||
}
|
||||
|
||||
return response.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Converts a raw JSON response to a PocketItem list
|
||||
/// </summary>
|
||||
/// <param name="itemsJSON">The raw JSON response.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public IEnumerable<PocketItem> ConvertJsonToList(string itemsJSON)
|
||||
{
|
||||
return DeserializeJson<Retrieve>(itemsJSON).Items;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,19 +137,22 @@ 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<IEnumerable<PocketTag>> GetTags(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
List<PocketItem> items = await Get(
|
||||
IEnumerable<PocketItem> items = await Get(
|
||||
cancellationToken: cancellationToken,
|
||||
state: State.all
|
||||
);
|
||||
|
||||
return items.Where(item => item.Tags != null)
|
||||
.SelectMany(item => item.Tags)
|
||||
.GroupBy(item => item.Name)
|
||||
.Select(item => item.First())
|
||||
.ToList<PocketTag>();
|
||||
return items
|
||||
.Where(item => item.Tags != null)
|
||||
.SelectMany(item => item.Tags)
|
||||
.GroupBy(item => item.Name)
|
||||
.Select(item => item.First())
|
||||
.ToList<PocketTag>();
|
||||
}
|
||||
|
||||
|
||||
@@ -145,11 +160,16 @@ 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<IEnumerable<PocketItem>> SearchByTag(string tag, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return await Get(tag: tag);
|
||||
return await Get(
|
||||
state: State.all,
|
||||
cancellationToken: cancellationToken,
|
||||
tag: tag
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -157,36 +177,52 @@ namespace PocketSharp
|
||||
/// Retrieves items which match the specified search string in title and URI
|
||||
/// </summary>
|
||||
/// <param name="searchString">The search string.</param>
|
||||
/// <param name="tag">Filter by tag.</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<IEnumerable<PocketItem>> Search(string searchString, string tag = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
List<PocketItem> items = await Get(RetrieveFilter.All);
|
||||
|
||||
return Search(items, searchString);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Finds the specified search string in title and URI for an available list of items
|
||||
/// </summary>
|
||||
/// <param name="availableItems">The available items.</param>
|
||||
/// <param name="searchString">The search string.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public List<PocketItem> Search(List<PocketItem> availableItems, string searchString)
|
||||
{
|
||||
if (searchString.Length < 2)
|
||||
if (String.IsNullOrEmpty(searchString) || searchString.Length < 2)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Search string length has to be a minimum of 2 chars");
|
||||
}
|
||||
|
||||
return availableItems.Where(item => (
|
||||
(!String.IsNullOrEmpty(item.FullTitle) && item.FullTitle.ToLower().Contains(searchString))
|
||||
|| item.Uri.ToString().ToLower().Contains(searchString)
|
||||
)).ToList();
|
||||
return await Get(
|
||||
state: State.all,
|
||||
search: searchString,
|
||||
tag: tag,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the article content from an URI
|
||||
/// WARNING:
|
||||
/// You have to pass the parseUri in the PocketClient ctor for this method to work.
|
||||
/// This is a private API and can only be used by authenticated users.
|
||||
/// </summary>
|
||||
/// <param name="uri">The article URI.</param>
|
||||
/// <param name="includeImages">Include images into content or use placeholder.</param>
|
||||
/// <param name="includeVideos">Include videos into content or use placeholder.</param>
|
||||
/// <param name="forceRefresh">Force refresh of the content (don't use cache).</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<PocketArticle> GetArticle(Uri uri, bool includeImages = true, bool includeVideos = true, bool forceRefresh = false, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
Dictionary<string, string> parameters = new Dictionary<string, string>()
|
||||
{
|
||||
{ "url", uri.OriginalString },
|
||||
{ "images", includeImages ? "1" : "0" },
|
||||
{ "videos", includeVideos ? "1" : "0" },
|
||||
{ "refresh", forceRefresh ? "1" : "0" },
|
||||
{ "output", "json" }
|
||||
};
|
||||
|
||||
return await Request<PocketArticle>("", cancellationToken, parameters, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
@@ -8,15 +11,44 @@ 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(IEnumerable<PocketAction> actions, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return await Send(actions, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sends an action.
|
||||
/// See: http://getpocket.com/developer/docs/v3/modify
|
||||
/// </summary>
|
||||
/// <param name="action">The action.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<bool> SendAction(PocketAction action, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return await Send(new List<PocketAction>() { action }, 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 +56,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 +69,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 +82,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 +95,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 +108,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 +121,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 +134,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()
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Choose>
|
||||
<When Condition="$(NCrunchOriginalSolutionDir) != '' And $(NCrunchOriginalSolutionDir) != '*Undefined*'">
|
||||
<PropertyGroup>
|
||||
<FodySolutionDir>$(NCrunchOriginalSolutionDir)</FodySolutionDir>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<When Condition="$(SolutionDir) != '' And $(SolutionDir) != '*Undefined*'">
|
||||
<PropertyGroup>
|
||||
<FodySolutionDir>$(SolutionDir)</FodySolutionDir>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<When Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">
|
||||
<PropertyGroup>
|
||||
<FodySolutionDir>$(MSBuildProjectDirectory)\..\</FodySolutionDir>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<Choose>
|
||||
<When Condition="$(KeyOriginatorFile) != '' And $(KeyOriginatorFile) != '*Undefined*'">
|
||||
<PropertyGroup>
|
||||
<FodyKeyFilePath>$(KeyOriginatorFile)</FodyKeyFilePath>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<When Condition="$(AssemblyOriginatorKeyFile) != '' And $(AssemblyOriginatorKeyFile) != '*Undefined*'">
|
||||
<PropertyGroup>
|
||||
<FodyKeyFilePath>$(AssemblyOriginatorKeyFile)</FodyKeyFilePath>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<Otherwise >
|
||||
<PropertyGroup>
|
||||
<FodyKeyFilePath></FodyKeyFilePath>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<PropertyGroup>
|
||||
<IntermediateDir>$(ProjectDir)$(IntermediateOutputPath)</IntermediateDir>
|
||||
<FodyMessageImportance Condition="$(FodyMessageImportance) == '' Or $(FodyMessageImportance) == '*Undefined*'">Low</FodyMessageImportance>
|
||||
<FodySignAssembly Condition="$(FodySignAssembly) == '' Or $(FodySignAssembly) == '*Undefined*'">$(SignAssembly)</FodySignAssembly>
|
||||
<FodyPath Condition="$(FodyPath) == '' Or $(FodyPath) == '*Undefined*'">$(MSBuildThisFileDirectory)</FodyPath>
|
||||
</PropertyGroup>
|
||||
<UsingTask
|
||||
TaskName="Fody.WeavingTask"
|
||||
AssemblyFile="$(FodyPath)\Fody.dll" />
|
||||
<Target
|
||||
AfterTargets="AfterCompile"
|
||||
Name="WinFodyTarget"
|
||||
Condition=" '$(OS)' == 'Windows_NT'">
|
||||
|
||||
<Fody.WeavingTask
|
||||
AssemblyPath="@(IntermediateAssembly)"
|
||||
IntermediateDir="$(IntermediateDir)"
|
||||
KeyFilePath="$(FodyKeyFilePath)"
|
||||
MessageImportance="$(FodyMessageImportance)"
|
||||
ProjectDirectory="$(ProjectDir)"
|
||||
SolutionDir="$(FodySolutionDir)"
|
||||
References="@(ReferencePath)"
|
||||
SignAssembly="$(FodySignAssembly)"
|
||||
ReferenceCopyLocalPaths="@(ReferenceCopyLocalPaths)"
|
||||
DefineConstants="$(DefineConstants)"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
<Target
|
||||
AfterTargets="AfterBuild"
|
||||
Name="NonWinFodyTarget"
|
||||
Condition=" '$(OS)' != 'Windows_NT'">
|
||||
<Fody.WeavingTask
|
||||
AssemblyPath="$(TargetPath)"
|
||||
IntermediateDir="$(IntermediateDir)"
|
||||
KeyFilePath="$(FodyKeyFilePath)"
|
||||
MessageImportance="$(FodyMessageImportance)"
|
||||
ProjectDirectory="$(ProjectDir)"
|
||||
SolutionDir="$(FodySolutionDir)"
|
||||
References="@(ReferencePath)"
|
||||
SignAssembly="$(FodySignAssembly)"
|
||||
ReferenceCopyLocalPaths="$(ReferenceCopyLocalPaths)"
|
||||
DefineConstants="$(DefineConstants)"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
|
||||
<!--Support for ncrunch-->
|
||||
<ItemGroup>
|
||||
<None Include="$(FodyPath)\*.*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Weavers>
|
||||
<PropertyChanged />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,464 @@
|
||||
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; }
|
||||
|
||||
/// <summary>
|
||||
/// Action which is executed before every request
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The pre request callback.
|
||||
/// </value>
|
||||
Action<string> PreRequest { 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>
|
||||
/// Generate registration 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 GenerateRegistrationUri(string requestCode = null);
|
||||
#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<IEnumerable<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<IEnumerable<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Converts a raw JSON response to a PocketItem list
|
||||
/// </summary>
|
||||
/// <param name="itemsJSON">The raw JSON response.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
IEnumerable<PocketItem> ConvertJsonToList(string itemsJSON);
|
||||
|
||||
/// <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<IEnumerable<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<IEnumerable<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="tag">Filter by tag.</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<IEnumerable<PocketItem>> Search(string searchString, string tag = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the article content from an URI
|
||||
/// WARNING:
|
||||
/// You have to pass the parseUri in the PocketClient ctor for this method to work.
|
||||
/// This is a private API and can only be used by authenticated users.
|
||||
/// </summary>
|
||||
/// <param name="tag">The article URI.</param>
|
||||
/// <param name="includeImages">Include images into content or use placeholder.</param>
|
||||
/// <param name="includeVideos">Include videos into content or use placeholder.</param>
|
||||
/// <param name="forceRefresh">Force refresh of the content (don't use cache).</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
Task<PocketArticle> GetArticle(Uri uri, bool includeImages = true, bool includeVideos = true, bool forceRefresh = false, CancellationToken cancellationToken = default(CancellationToken));
|
||||
#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(IEnumerable<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
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
void Dispose();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,6 @@ namespace PocketSharp.Models
|
||||
/// The actions.
|
||||
/// </value>
|
||||
[DataMember(Name = "actions")]
|
||||
public List<Dictionary<string, string>> Actions { get; set; }
|
||||
public IEnumerable<Dictionary<string, string>> Actions { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,16 +23,26 @@ namespace PocketSharp.Models
|
||||
Dictionary<string, string> parameterDict = new Dictionary<string, string>();
|
||||
|
||||
// get object properties
|
||||
IEnumerable<PropertyInfo> properties = this.GetType()
|
||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Where(p => Attribute.IsDefined(p, typeof(DataMemberAttribute)));
|
||||
IEnumerable<MemberInfo> properties = this.GetType()
|
||||
.GetTypeInfo()
|
||||
.DeclaredMembers
|
||||
.Where(p => p.CustomAttributes.FirstOrDefault(a => a.AttributeType == typeof(DataMemberAttribute)) != null);
|
||||
|
||||
// gather attributes of object
|
||||
foreach (PropertyInfo propertyInfo in properties)
|
||||
foreach (MemberInfo memberInfo in properties)
|
||||
{
|
||||
DataMemberAttribute attribute = (DataMemberAttribute)propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), false).FirstOrDefault();
|
||||
string name = attribute.Name ?? propertyInfo.Name.ToLower();
|
||||
object value = propertyInfo.GetValue(this, null);
|
||||
DataMemberAttribute attribute = (DataMemberAttribute)memberInfo.GetCustomAttributes(typeof(DataMemberAttribute), false).FirstOrDefault();
|
||||
string name = attribute.Name ?? memberInfo.Name.ToLower();
|
||||
object value = null;
|
||||
|
||||
if (memberInfo is FieldInfo)
|
||||
{
|
||||
value = ((FieldInfo)memberInfo).GetValue(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = ((PropertyInfo)memberInfo).GetValue(this, null);
|
||||
}
|
||||
|
||||
// invalid parameter
|
||||
if (value == null)
|
||||
@@ -55,7 +65,7 @@ namespace PocketSharp.Models
|
||||
// convert DateTime to UNIX timestamp
|
||||
if (value is DateTime)
|
||||
{
|
||||
value = (int)((DateTime)value - new DateTime(1970, 1, 1)).TotalSeconds;
|
||||
value = (int)((DateTime)value - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
|
||||
}
|
||||
|
||||
parameterDict.Add(name, value.ToString());
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// All parameters which can be passed to register a user
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
internal class RegisterParameters : Parameters
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the username.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The username.
|
||||
/// </value>
|
||||
[DataMember(Name = "username")]
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the E-Mail.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The E-Mail.
|
||||
/// </value>
|
||||
[DataMember(Name = "email")]
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The password.
|
||||
/// </value>
|
||||
[DataMember(Name = "password")]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
+42
-7
@@ -1,14 +1,15 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// All parameters which can be passed for a modify action
|
||||
/// 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 +21,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 +99,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 (!String.IsNullOrEmpty(ID) && ID != "0")
|
||||
parameters.Add("item_id", ID.ToString());
|
||||
if (Time != null)
|
||||
parameters.Add("time", Time != null ? Utilities.GetUnixTimestamp(Time).ToString() : null);
|
||||
if (Tags != null)
|
||||
@@ -87,6 +116,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("url", Uri.OriginalString);
|
||||
|
||||
return parameters;
|
||||
}
|
||||
@@ -1,44 +1,165 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Readable article
|
||||
/// Article
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketArticle
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the pocket item ID.
|
||||
/// Gets or sets the response Code (200 = OK).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The pocket item ID.
|
||||
/// The response Code.
|
||||
/// </value>
|
||||
public int PocketItemID { get; set; }
|
||||
[JsonProperty("responseCode")]
|
||||
public string ResponseCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content.
|
||||
/// Gets or sets the ID.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The content.
|
||||
/// The ID.
|
||||
/// </value>
|
||||
public string Content { get; set; }
|
||||
[JsonProperty("resolved_id")]
|
||||
public string ID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title.
|
||||
/// Gets or sets the URI.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The title.
|
||||
/// The URI.
|
||||
/// </value>
|
||||
[JsonProperty("resolvedUrl")]
|
||||
public Uri Uri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URI.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The URI.
|
||||
/// </value>
|
||||
[JsonProperty("timePublished")]
|
||||
public DateTime? PublishedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the word count.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The word count.
|
||||
/// </value>
|
||||
[JsonProperty("wordCount")]
|
||||
public int WordCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is article.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is article; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("isArticle")]
|
||||
public bool IsArticle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is video.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is video; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("isVideo")]
|
||||
public bool IsVideo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is index.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is index; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("isIndex")]
|
||||
public bool IsIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance used fallback.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance used fallback; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("usedFallback")]
|
||||
public bool UsedFallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance requires login.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance requires login; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("requiresLogin")]
|
||||
public bool RequiresLogin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the images.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The images.
|
||||
/// </value>
|
||||
[JsonProperty("images")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketImage>))]
|
||||
public IEnumerable<PocketImage> Images { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the videos.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The videos.
|
||||
/// </value>
|
||||
[JsonProperty("videos")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketVideo>))]
|
||||
public IEnumerable<PocketVideo> Videos { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the authors.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The authors.
|
||||
/// </value>
|
||||
[JsonProperty("authors")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketAuthor>))]
|
||||
public IEnumerable<PocketAuthor> Authors { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the article title.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The Title.
|
||||
/// </value>
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the next page URL.
|
||||
/// Gets or sets the Excerpt.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The next page URL.
|
||||
/// The Excerpt.
|
||||
/// </value>
|
||||
public Uri NextPage { get; set; }
|
||||
[JsonProperty("excerpt")]
|
||||
public string Excerpt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Content.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The Content.
|
||||
/// </value>
|
||||
[JsonProperty("article")]
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
internal enum PocketBoolean
|
||||
{
|
||||
No = 0,
|
||||
Yes = 1,
|
||||
IsType = 2
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Newtonsoft.Json;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PropertyChanged;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -11,7 +13,8 @@ namespace PocketSharp.Models
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketItem
|
||||
[DebuggerDisplay("Uri = {Uri}, Title = {Title}")]
|
||||
public class PocketItem : IComparable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
@@ -20,7 +23,43 @@ 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 given URI.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The given URI.
|
||||
/// </value>
|
||||
[JsonProperty("given_url")]
|
||||
private Uri _GivenUri { 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 +67,12 @@ namespace PocketSharp.Models
|
||||
/// <value>
|
||||
/// The URI.
|
||||
/// </value>
|
||||
[JsonProperty("resolved_url")]
|
||||
public Uri Uri { get; set; }
|
||||
[JsonIgnore]
|
||||
public Uri Uri
|
||||
{
|
||||
get { return _ResolvedUri ?? _GivenUri ?? _NormalUri; }
|
||||
set { _NormalUri = value; _ResolvedUri = value; _GivenUri = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title.
|
||||
@@ -58,7 +101,7 @@ namespace PocketSharp.Models
|
||||
[JsonIgnore]
|
||||
public string Title
|
||||
{
|
||||
get { return _InternalTitle ?? _ResolvedTitle; }
|
||||
get { return _InternalTitle ?? _ResolvedTitle ?? FullTitle; }
|
||||
set { _InternalTitle = value; _ResolvedTitle = value; }
|
||||
}
|
||||
|
||||
@@ -125,15 +168,6 @@ namespace PocketSharp.Models
|
||||
[JsonProperty("is_article")]
|
||||
public bool IsArticle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance has image.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance has image; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("has_image")]
|
||||
public bool HasImage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance has video.
|
||||
/// </summary>
|
||||
@@ -141,7 +175,37 @@ 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 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 or sets the word count.
|
||||
@@ -181,84 +245,56 @@ namespace PocketSharp.Models
|
||||
public DateTime? UpdateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the read time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The read time.
|
||||
/// </value>
|
||||
[JsonProperty("time_read")]
|
||||
public DateTime? ReadTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the favorite time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The favorite time.
|
||||
/// </value>
|
||||
[JsonProperty("time_favorited")]
|
||||
public DateTime? FavoriteTime { get; set; }
|
||||
|
||||
|
||||
/// <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 as comma-separated strings.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The tags.
|
||||
/// </value>
|
||||
[JsonIgnore]
|
||||
public List<PocketTag> Tags
|
||||
public string TagsString
|
||||
{
|
||||
get { return Utilities.DictionaryToList<PocketTag>(_TagDictionary); }
|
||||
get { return Tags != null ? String.Join(",", Tags.Select(tag => tag.Name)) : ""; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the images.
|
||||
/// Gets or sets the tags.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The tags.
|
||||
/// </value>
|
||||
[JsonProperty("tags")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketTag>))]
|
||||
public IEnumerable<PocketTag> Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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 IEnumerable<PocketImage> Images { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the videos.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The videos.
|
||||
/// </value>
|
||||
[JsonProperty("videos")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketVideo>))]
|
||||
public IEnumerable<PocketVideo> Videos { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the authors.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The authors.
|
||||
/// </value>
|
||||
[JsonProperty("authors")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketAuthor>))]
|
||||
public IEnumerable<PocketAuthor> Authors { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the lead image.
|
||||
@@ -269,31 +305,116 @@ namespace PocketSharp.Models
|
||||
[JsonIgnore]
|
||||
public PocketImage LeadImage
|
||||
{
|
||||
get { return Images != null && Images.Count > 0 ? Images[0] : null; }
|
||||
get { return Images != null && Images.Count() > 0 ? Images.First() : null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the videos.
|
||||
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The videos.
|
||||
/// </value>
|
||||
[JsonIgnore]
|
||||
public List<PocketVideo> Videos
|
||||
/// <param name="obj">An object to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj" /> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj" />. Greater than zero This instance follows <paramref name="obj" /> in the sort order.
|
||||
/// </returns>
|
||||
int IComparable.CompareTo(object obj)
|
||||
{
|
||||
get { return Utilities.DictionaryToList<PocketVideo>(_VideoDictionary); }
|
||||
PocketItem item = (PocketItem)obj;
|
||||
|
||||
if (!AddTime.HasValue)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (!item.AddTime.HasValue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return DateTime.Compare(AddTime.Value, item.AddTime.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authors.
|
||||
/// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The authors.
|
||||
/// </value>
|
||||
[JsonIgnore]
|
||||
public List<PocketAuthor> Authors
|
||||
/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
get { return Utilities.DictionaryToList<PocketAuthor>(_AuthorDictionary); }
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PocketItem item = (PocketItem)obj;
|
||||
|
||||
if ((Object)item == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ID == item.ID;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="a">A.</param>
|
||||
/// <param name="b">The b.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator ==(PocketItem a, PocketItem b)
|
||||
{
|
||||
if (Object.ReferenceEquals(a, b))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PocketItem itemA = (PocketItem)a;
|
||||
PocketItem itemB = (PocketItem)b;
|
||||
|
||||
if ((Object)itemA == null || (Object)itemB == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return itemA.ID == itemB.ID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="a">A.</param>
|
||||
/// <param name="b">The b.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator !=(PocketItem a, PocketItem b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ID.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,29 @@ 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item iD.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
[JsonProperty("item_id")]
|
||||
public string ItemID { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
|
||||
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 IEnumerable<PocketItem> Items { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
+200
-36
@@ -1,29 +1,41 @@
|
||||
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;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// PocketClient
|
||||
/// </summary>
|
||||
public partial class PocketClient
|
||||
public partial class PocketClient : IPocketClient, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// REST client used for the API communication
|
||||
/// </summary>
|
||||
protected readonly HttpClient _restClient;
|
||||
|
||||
/// <summary>
|
||||
/// REST client used for the API communication with the Text Parser API
|
||||
/// </summary>
|
||||
protected readonly HttpClient _restParserClient;
|
||||
|
||||
/// <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
|
||||
@@ -33,42 +45,95 @@ namespace PocketSharp
|
||||
/// <summary>
|
||||
/// The authentification URL
|
||||
/// </summary>
|
||||
protected string authentificationUri = "https://getpocket.com/auth/authorize?request_token={0}&redirect_uri={1}";
|
||||
protected string authentificationUri = "https://getpocket.com/auth/authorize?request_token={0}&redirect_uri={1}&mobile={2}&force={3}&webauthenticationbroker={4}";
|
||||
|
||||
/// <summary>
|
||||
/// callback URL for API calls
|
||||
/// Indicates, whether this client is used for mobile or desktop
|
||||
/// </summary>
|
||||
protected bool isMobileClient = true;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates, whether this client is used inside a broker (on Windows 8)
|
||||
/// </summary>
|
||||
protected bool useInsideWebAuthenticationBroker = true;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates, whether the last HTTP response is cached
|
||||
/// </summary>
|
||||
protected bool cacheHTTPResponseData;
|
||||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
/// <param name="isMobileClient">Indicates, whether this client is used for mobile or desktop</param>
|
||||
/// <param name="useInsideWebAuthenticationBroker">Indicates, whether this client is used inside a broker (on Windows 8), see: http://getpocket.com/developer/docs/getstarted/windows8 </param>
|
||||
/// <param name="parserUri">Enables the wrapper for the private Text Parser API</param>
|
||||
/// <param name="cacheHTTPResponseData">Caches the last HTTP response in public properties</param>
|
||||
public PocketClient(
|
||||
string consumerKey,
|
||||
string accessCode = null,
|
||||
string callbackUri = null,
|
||||
HttpMessageHandler handler = null,
|
||||
int? timeout = null,
|
||||
bool isMobileClient = true,
|
||||
bool useInsideWebAuthenticationBroker = false,
|
||||
Uri parserUri = null,
|
||||
bool cacheHTTPResponseData = true)
|
||||
{
|
||||
// assign public properties
|
||||
ConsumerKey = consumerKey;
|
||||
|
||||
this.isMobileClient = isMobileClient;
|
||||
this.useInsideWebAuthenticationBroker = useInsideWebAuthenticationBroker;
|
||||
this.cacheHTTPResponseData = cacheHTTPResponseData;
|
||||
|
||||
// assign access code if submitted
|
||||
if (accessCode != null)
|
||||
{
|
||||
@@ -81,12 +146,34 @@ namespace PocketSharp
|
||||
CallbackUri = Uri.EscapeUriString(callbackUri.ToString());
|
||||
}
|
||||
|
||||
// assign text parser if parserUri submitted
|
||||
if (parserUri != null)
|
||||
{
|
||||
_restParserClient = new HttpClient(handler ?? new HttpClientHandler()
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
|
||||
});
|
||||
_restParserClient.BaseAddress = parserUri;
|
||||
_restParserClient.DefaultRequestHeaders.Add("Accept", "*/*");
|
||||
_restParserClient.DefaultRequestHeaders.Add("X-Accept", "application/json");
|
||||
|
||||
if (timeout.HasValue)
|
||||
{
|
||||
_restParserClient.Timeout = TimeSpan.FromSeconds(timeout.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// 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,20 +190,36 @@ 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,
|
||||
bool isReaderRequest = false) 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.");
|
||||
}
|
||||
|
||||
// rewrite base if it is a request to the Parser API
|
||||
if (isReaderRequest)
|
||||
{
|
||||
if (_restParserClient == null)
|
||||
{
|
||||
throw new PocketException("Please pass the parserUri in the PocketClient ctor.");
|
||||
}
|
||||
}
|
||||
|
||||
// every single Pocket API endpoint requires HTTP POST data
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, method);
|
||||
HttpResponseMessage response = null;
|
||||
string responseString = null;
|
||||
|
||||
if (parameters == null)
|
||||
{
|
||||
@@ -127,7 +230,7 @@ namespace PocketSharp
|
||||
parameters.Add("consumer_key", ConsumerKey);
|
||||
|
||||
// add access token (necessary for all requests except authentification)
|
||||
if (AccessCode != null)
|
||||
if (AccessCode != null && requireAuth)
|
||||
{
|
||||
parameters.Add("access_token", AccessCode);
|
||||
}
|
||||
@@ -135,30 +238,78 @@ 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);
|
||||
if (isReaderRequest)
|
||||
{
|
||||
response = await _restParserClient.SendAsync(request, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
response = await _restClient.SendAsync(request, cancellationToken);
|
||||
}
|
||||
|
||||
// validate HTTP response
|
||||
ValidateResponse(response);
|
||||
|
||||
// cache headers
|
||||
if (cacheHTTPResponseData)
|
||||
{
|
||||
lastHeaders = response.Headers;
|
||||
}
|
||||
|
||||
// read response
|
||||
responseString = await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
catch (HttpRequestException exc)
|
||||
{
|
||||
throw new PocketException(exc.Message, exc);
|
||||
}
|
||||
catch (PocketException exc)
|
||||
{
|
||||
throw exc;
|
||||
}
|
||||
finally
|
||||
{
|
||||
request.Dispose();
|
||||
|
||||
// validate HTTP response
|
||||
ValidateResponse(response);
|
||||
if (response != null)
|
||||
{
|
||||
response.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// cache headers
|
||||
lastHeaders = response.Headers;
|
||||
// cache response
|
||||
if (cacheHTTPResponseData)
|
||||
{
|
||||
lastResponseData = responseString;
|
||||
}
|
||||
|
||||
// read response
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
return DeserializeJson<T>(responseString);
|
||||
}
|
||||
|
||||
responseString = responseString.Replace("[]", "{}");
|
||||
|
||||
/// <summary>
|
||||
/// Converts JSON to Pocket objects
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="json">Raw JSON response</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException">Parse error.</exception>
|
||||
protected T DeserializeJson<T>(string json) where T : class, new()
|
||||
{
|
||||
json = json.Replace("[]", "{}");
|
||||
|
||||
// deserialize object
|
||||
T parsedResponse = JsonConvert.DeserializeObject<T>(
|
||||
responseString,
|
||||
json,
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
Error = (object sender, ErrorEventArgs args) =>
|
||||
@@ -167,8 +318,11 @@ namespace PocketSharp
|
||||
},
|
||||
Converters =
|
||||
{
|
||||
new PocketItemConverter(),
|
||||
new BoolConverter(),
|
||||
new UnixDateTimeConverter()
|
||||
new UnixDateTimeConverter(),
|
||||
new NullableIntConverter(),
|
||||
new UriConverter()
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -182,22 +336,18 @@ 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(IEnumerable<PocketAction> actionParameters, CancellationToken cancellationToken)
|
||||
{
|
||||
List<Dictionary<string, object>> actionParamList = new List<Dictionary<string, object>>();
|
||||
|
||||
foreach (var action in actionParameters)
|
||||
foreach (PocketAction action in actionParameters)
|
||||
{
|
||||
actionParamList.Add(action.Convert());
|
||||
action.Time = action.Time.HasValue ? ((DateTime)action.Time).ToUniversalTime() : action.Time;
|
||||
}
|
||||
|
||||
Dictionary<string, string> parameters = new Dictionary<string, string>() {{
|
||||
"actions", JsonConvert.SerializeObject(actionParamList)
|
||||
"actions", JsonConvert.SerializeObject(actionParameters.Select(action => action.Convert()))
|
||||
}};
|
||||
|
||||
Modify response = await Request<Modify>("send", parameters);
|
||||
|
||||
return response.Status;
|
||||
return (await Request<Modify>("send", cancellationToken, parameters)).Status;
|
||||
}
|
||||
|
||||
|
||||
@@ -206,10 +356,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -293,5 +442,20 @@ namespace PocketSharp
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_restClient.Dispose();
|
||||
lastHeaders = null;
|
||||
|
||||
if (_restParserClient != null)
|
||||
{
|
||||
_restParserClient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// REST client used for HTML retrieval
|
||||
/// </summary>
|
||||
protected readonly HttpClient _httpClient;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PocketReader"/> class.
|
||||
/// </summary>
|
||||
public PocketReader()
|
||||
{
|
||||
// initialize HTTP client
|
||||
_httpClient = new HttpClient(new HttpClientHandler()
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
||||
AllowAutoRedirect = true
|
||||
});
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <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>
|
||||
/// <returns>A Pocket article with extracted content and title.</returns>
|
||||
/// <exception cref="PocketRequestException"></exception>
|
||||
public async Task<PocketArticle> Read(Uri uri)
|
||||
{
|
||||
return await Read(new PocketItem()
|
||||
{
|
||||
ID = 0,
|
||||
Uri = uri
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <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>
|
||||
/// <returns>A Pocket article with extracted content and title.</returns>
|
||||
/// <exception cref="PocketRequestException"></exception>
|
||||
public async Task<PocketArticle> Read(PocketItem item)
|
||||
{
|
||||
// initialize transcoder
|
||||
NReadabilityTranscoder transcoder = new NReadabilityTranscoder(
|
||||
dontStripUnlikelys: false,
|
||||
dontNormalizeSpacesInTextContent: true,
|
||||
dontWeightClasses: false,
|
||||
readingStyle: ReadingStyle.Ebook,
|
||||
readingMargin: ReadingMargin.Narrow,
|
||||
readingSize: ReadingSize.Medium
|
||||
);
|
||||
|
||||
// get HTML string from URI
|
||||
string htmlResponse = await Request(item.Uri);
|
||||
|
||||
// set properties for processing
|
||||
TranscodingInput transcodingInput = new TranscodingInput(htmlResponse)
|
||||
{
|
||||
Url = item.Uri.ToString(),
|
||||
DomSerializationParams = new DomSerializationParams()
|
||||
{
|
||||
BodyOnly = true,
|
||||
PrettyPrint = true,
|
||||
DontIncludeContentTypeMetaElement = true,
|
||||
DontIncludeMobileSpecificMetaElements = true,
|
||||
DontIncludeDocTypeMetaElement = true,
|
||||
DontIncludeGeneratorMetaElement = true
|
||||
}
|
||||
};
|
||||
|
||||
// process/transcode HTML
|
||||
TranscodingResult transcodingResult = transcoder.Transcode(transcodingInput);
|
||||
|
||||
return new PocketArticle()
|
||||
{
|
||||
Content = transcodingResult.ExtractedContent,
|
||||
Title = transcodingResult.ExtractedTitle,
|
||||
NextPage = transcodingResult.NextPageUrl != null ? new Uri(transcodingResult.NextPageUrl, UriKind.Absolute) : null,
|
||||
PocketItemID = item.ID
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a resource
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI.</param>
|
||||
/// <returns></returns>
|
||||
protected async Task<string> Request(Uri uri)
|
||||
{
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
HttpResponseMessage response = null;
|
||||
|
||||
// make async request
|
||||
try
|
||||
{
|
||||
response = await _httpClient.SendAsync(request);
|
||||
}
|
||||
catch (HttpRequestException exc)
|
||||
{
|
||||
throw new PocketException(exc.Message, exc);
|
||||
}
|
||||
|
||||
// validate HTTP response
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
string exceptionString = String.Format("Request error: {0} ({1})", response.ReasonPhrase, (int)response.StatusCode);
|
||||
|
||||
throw new PocketException(exceptionString);
|
||||
}
|
||||
|
||||
// read response
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<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>
|
||||
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{817200C3-A327-4E35-9B5F-63A51C088577}</ProjectGuid>
|
||||
@@ -10,13 +10,33 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PocketSharp</RootNamespace>
|
||||
<AssemblyName>PocketSharp</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>Profile96</TargetFrameworkProfile>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>Profile259</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>
|
||||
<FodyPath>..\packages\Fody.1.17.4.0</FodyPath>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<NuGetPackageImportStamp>06ad0893</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -37,15 +57,16 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||
<None Include="Fody.targets" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Components\Statistics.cs" />
|
||||
<Compile Include="Models\Parameters\RegisterParameters.cs" />
|
||||
<Compile Include="IPocketClient.cs" />
|
||||
<Compile Include="Models\PocketArticle.cs" />
|
||||
<Compile Include="Models\PocketBoolean.cs" />
|
||||
<Compile Include="Models\PocketLimits.cs" />
|
||||
<Compile Include="Models\PocketStatistics.cs" />
|
||||
<Compile Include="Utilities\PocketAuthException.cs" />
|
||||
<Compile Include="Utilities\PocketException.cs" />
|
||||
<Compile Include="Components\Add.cs" />
|
||||
<Compile Include="Components\Account.cs" />
|
||||
@@ -53,7 +74,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,51 +91,43 @@
|
||||
<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\PocketLimitException.cs" />
|
||||
<Compile Include="Utilities\PocketRequestException.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>
|
||||
</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>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll</HintPath>
|
||||
<HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PropertyChanged">
|
||||
<HintPath>..\packages\PropertyChanged.Fody.1.41.0.0\Lib\portable-net4+sl4+wp7+win8+MonoAndroid16+MonoTouch40\PropertyChanged.dll</HintPath>
|
||||
<HintPath>..\packages\PropertyChanged.Fody.1.48.3\Lib\portable-net4+sl4+wp8+win8+wpa81+MonoAndroid16+MonoTouch40\PropertyChanged.dll</HintPath>
|
||||
<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>
|
||||
</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.22\lib\portable-net40+sl4+win8+wp71+wpa81\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.22\lib\portable-net40+sl4+win8+wp71+wpa81\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>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime">
|
||||
<HintPath>..\packages\Microsoft.Bcl.1.1.3\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.Net.Http.2.2.22\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Primitives.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>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
@@ -123,13 +136,14 @@
|
||||
<ErrorText>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=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Fody.1.24.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.24.0\build\Fody.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.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\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.14\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.14\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\Fody.1.24.0\build\Fody.targets" Condition="Exists('..\packages\Fody.1.24.0\build\Fody.targets')" />
|
||||
<!-- 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">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
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 Reader Article SDK Pockem</tags>
|
||||
<copyright>Copyright by cee, 2014</copyright>
|
||||
<tags>PocketAPI Pocket API PocketSharp Tobias Klika cee Scott Lovegrove scottisafool NReadability SgmlReader Reader Article SDK Pockem</tags>
|
||||
</metadata>
|
||||
</package>
|
||||
</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
|
||||
@@ -11,7 +8,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("cee")]
|
||||
[assembly: AssemblyProduct("PocketSharp")]
|
||||
[assembly: AssemblyCopyright("Copyright © cee 2013")]
|
||||
[assembly: AssemblyCopyright("Copyright © cee 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -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("4.1.6.0")]
|
||||
[assembly: AssemblyFileVersion("4.1.6.0")]
|
||||
@@ -1,6 +1,9 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PocketSharp.Models;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
@@ -14,7 +17,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)
|
||||
@@ -29,20 +32,173 @@ namespace PocketSharp
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
DateTime epoc = new DateTime(1970, 1, 1);
|
||||
var delta = (DateTime)value - epoc;
|
||||
DateTime date = ((DateTime)value).ToUniversalTime();
|
||||
DateTime epoc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
var delta = date.Subtract(epoc);
|
||||
|
||||
writer.WriteValue((long)delta.TotalSeconds);
|
||||
writer.WriteValue((int)Math.Truncate(delta.TotalSeconds));
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if(reader.Value.ToString() == "0")
|
||||
if (reader.Value.ToString() == "0")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(Convert.ToDouble(reader.Value)).ToLocalTime();
|
||||
if (reader.Value.ToString().StartsWith("-"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(reader.Value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string value = reader.Value.ToString();
|
||||
|
||||
if (Uri.IsWellFormedUriString(value, UriKind.Absolute))
|
||||
{
|
||||
return new Uri(value);
|
||||
}
|
||||
else if (value.StartsWith("//") && Uri.IsWellFormedUriString("http:" + value, UriKind.Absolute))
|
||||
{
|
||||
return new Uri("http:" + value);
|
||||
}
|
||||
else if (value.StartsWith("www.") && Uri.IsWellFormedUriString("http://" + value, UriKind.Absolute))
|
||||
{
|
||||
return new Uri("http://" + value);
|
||||
}
|
||||
|
||||
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<IEnumerable<T>> where T : new()
|
||||
{
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
JObject jObject;
|
||||
List<T> results = new List<T>();
|
||||
|
||||
// object is an array
|
||||
if (reader.TokenType == JsonToken.StartArray)
|
||||
{
|
||||
return serializer.Deserialize<IEnumerable<T>>(reader);
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
jObject = JObject.Load(reader);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Populate the object properties
|
||||
foreach (KeyValuePair<string, JToken> item in jObject)
|
||||
{
|
||||
results.Add(
|
||||
serializer.Deserialize<T>(item.Value.CreateReader())
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override IEnumerable<T> Create(Type objectType)
|
||||
{
|
||||
return new List<T>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class PocketItemConverter : CustomCreationConverter<PocketItem>
|
||||
{
|
||||
|
||||
public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
|
||||
{
|
||||
var jObject = JObject.ReadFrom(reader);
|
||||
var pocketItem = new PocketItem();
|
||||
serializer.Populate(jObject.CreateReader(), pocketItem);
|
||||
//pocketItem.Json = jObject.ToString();
|
||||
|
||||
return pocketItem;
|
||||
}
|
||||
|
||||
public override PocketItem Create(Type objectType)
|
||||
{
|
||||
return new PocketItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
public class PocketAuthException : PocketException
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
public class PocketLimitException : PocketException
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
public class PocketRequestException : PocketException
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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,9 @@
|
||||
<?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="Newtonsoft.Json" version="5.0.8" targetFramework="portable-net45+sl40+wp71+win" />
|
||||
<package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="portable-net403+sl40+wp71+win" />
|
||||
<package id="Fody" version="1.24.0" targetFramework="portable-net45+win+wpa81+wp80" developmentDependency="true" />
|
||||
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="portable-net45+win+wpa81+wp80" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="portable-net403+sl50+win+wpa81+wp80" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.22" targetFramework="portable-net45+win+wpa81+wp80" />
|
||||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="portable-net45+win+wpa81+wp80" />
|
||||
<package id="PropertyChanged.Fody" version="1.48.3" targetFramework="portable-net45+win+wpa81+wp80" developmentDependency="true" />
|
||||
</packages>
|
||||
@@ -1,11 +0,0 @@
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class AttributeTransformationInput
|
||||
{
|
||||
public string AttributeValue { get; set; }
|
||||
|
||||
public XElement Element { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class AttributeTransformationResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Result of the transformation.
|
||||
/// </summary>
|
||||
public string TransformedValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the attribute that will be used to store the original value. Can be null.
|
||||
/// </summary>
|
||||
public string OriginalValueAttributeName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
internal class ChildNodesTraverser
|
||||
{
|
||||
private readonly Action<XNode> _childNodeVisitor;
|
||||
|
||||
#region Constructor(s)
|
||||
|
||||
public ChildNodesTraverser(Action<XNode> childNodeVisitor)
|
||||
{
|
||||
if (childNodeVisitor == null)
|
||||
{
|
||||
throw new ArgumentNullException("childNodeVisitor");
|
||||
}
|
||||
|
||||
_childNodeVisitor = childNodeVisitor;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
|
||||
public void Traverse(XNode node)
|
||||
{
|
||||
if (!(node is XContainer))
|
||||
{
|
||||
throw new ArgumentException("The node must be an XContainer in order to traverse its children.");
|
||||
}
|
||||
|
||||
var childNode = ((XContainer)node).FirstNode;
|
||||
|
||||
while (childNode != null)
|
||||
{
|
||||
var nextChildNode = childNode.NextNode;
|
||||
|
||||
_childNodeVisitor(childNode);
|
||||
|
||||
childNode = nextChildNode;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public static class Consts
|
||||
{
|
||||
private static readonly string _nReadabilityFullName;
|
||||
|
||||
#region Constructor(s)
|
||||
|
||||
static Consts()
|
||||
{
|
||||
_nReadabilityFullName = string.Format("NReadability {0}", Assembly.GetExecutingAssembly().FullName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public static string NReadabilityFullName
|
||||
{
|
||||
get { return _nReadabilityFullName; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,303 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public static class DomExtensions
|
||||
{
|
||||
#region XDocument extensions
|
||||
|
||||
public static XElement GetBody(this XDocument document)
|
||||
{
|
||||
if (document == null)
|
||||
{
|
||||
throw new ArgumentNullException("document");
|
||||
}
|
||||
|
||||
var documentRoot = document.Root;
|
||||
|
||||
if (documentRoot == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return documentRoot.GetElementsByTagName("body").FirstOrDefault();
|
||||
}
|
||||
|
||||
public static string GetTitle(this XDocument document)
|
||||
{
|
||||
if (document == null)
|
||||
{
|
||||
throw new ArgumentNullException("document");
|
||||
}
|
||||
|
||||
var documentRoot = document.Root;
|
||||
|
||||
if (documentRoot == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var headElement = documentRoot.GetElementsByTagName("head").FirstOrDefault();
|
||||
|
||||
if (headElement == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
var titleElement = headElement.GetChildrenByTagName("title").FirstOrDefault();
|
||||
|
||||
if (titleElement == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return (titleElement.Value ?? "").Trim();
|
||||
}
|
||||
|
||||
public static XElement GetElementById(this XDocument document, string id)
|
||||
{
|
||||
if (document == null)
|
||||
{
|
||||
throw new ArgumentNullException("document");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(id))
|
||||
{
|
||||
throw new ArgumentNullException("id");
|
||||
}
|
||||
|
||||
return
|
||||
(from element in document.Descendants()
|
||||
let idAttribute = element.Attribute("id")
|
||||
where idAttribute != null && idAttribute.Value == id
|
||||
select element).SingleOrDefault();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region XElement extensions
|
||||
|
||||
public static string GetId(this XElement element)
|
||||
{
|
||||
return element.GetAttributeValue("id", "");
|
||||
}
|
||||
|
||||
public static void SetId(this XElement element, string id)
|
||||
{
|
||||
element.SetAttributeValue("id", id);
|
||||
}
|
||||
|
||||
public static string GetClass(this XElement element)
|
||||
{
|
||||
return element.GetAttributeValue("class", "");
|
||||
}
|
||||
|
||||
public static void SetClass(this XElement element, string @class)
|
||||
{
|
||||
element.SetAttributeValue("class", @class);
|
||||
}
|
||||
|
||||
public static string GetStyle(this XElement element)
|
||||
{
|
||||
return element.GetAttributeValue("style", "");
|
||||
}
|
||||
|
||||
public static void SetStyle(this XElement element, string style)
|
||||
{
|
||||
element.SetAttributeValue("style", style);
|
||||
}
|
||||
|
||||
public static string GetAttributeValue(this XElement element, string attributeName, string defaultValue)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
throw new ArgumentNullException("element");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(attributeName))
|
||||
{
|
||||
throw new ArgumentNullException("attributeName");
|
||||
}
|
||||
|
||||
var attribute = element.Attribute(attributeName);
|
||||
|
||||
return attribute != null
|
||||
? (attribute.Value ?? defaultValue)
|
||||
: defaultValue;
|
||||
}
|
||||
|
||||
public static void SetAttributeValue(this XElement element, string attributeName, string value)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
throw new ArgumentNullException("element");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(attributeName))
|
||||
{
|
||||
throw new ArgumentNullException("attributeName");
|
||||
}
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
var attribute = element.Attribute(attributeName);
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
attribute.Remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
element.SetAttributeValue(attributeName, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetAttributesString(this XElement element, string separator)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
throw new ArgumentNullException("element");
|
||||
}
|
||||
|
||||
if (separator == null)
|
||||
{
|
||||
throw new ArgumentNullException("separator");
|
||||
}
|
||||
|
||||
var resultSb = new StringBuilder();
|
||||
bool isFirst = true;
|
||||
|
||||
element.Attributes().Aggregate(
|
||||
resultSb,
|
||||
(sb, attribute) =>
|
||||
{
|
||||
string attributeValue = attribute.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(attributeValue))
|
||||
{
|
||||
return sb;
|
||||
}
|
||||
|
||||
if (!isFirst)
|
||||
{
|
||||
resultSb.Append(separator);
|
||||
}
|
||||
|
||||
isFirst = false;
|
||||
|
||||
sb.Append(attribute.Value);
|
||||
|
||||
return sb;
|
||||
});
|
||||
|
||||
return resultSb.ToString();
|
||||
}
|
||||
|
||||
public static string GetInnerHtml(this XContainer container)
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
throw new ArgumentNullException("container");
|
||||
}
|
||||
|
||||
var resultSb = new StringBuilder();
|
||||
|
||||
foreach (var childNode in container.Nodes())
|
||||
{
|
||||
resultSb.Append(childNode.ToString(SaveOptions.DisableFormatting));
|
||||
}
|
||||
|
||||
return resultSb.ToString();
|
||||
}
|
||||
|
||||
public static void SetInnerHtml(this XElement element, string html)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
throw new ArgumentNullException("element");
|
||||
}
|
||||
|
||||
if (html == null)
|
||||
{
|
||||
throw new ArgumentNullException("html");
|
||||
}
|
||||
|
||||
element.RemoveAll();
|
||||
|
||||
var tmpElement = new SgmlDomBuilder().BuildDocument(html);
|
||||
|
||||
if (tmpElement.Root == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var node in tmpElement.Root.Nodes())
|
||||
{
|
||||
element.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region XContainer extensions
|
||||
|
||||
public static IEnumerable<XElement> GetElementsByTagName(this XContainer container, string tagName)
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
throw new ArgumentNullException("container");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(tagName))
|
||||
{
|
||||
throw new ArgumentNullException("tagName");
|
||||
}
|
||||
|
||||
return container.Descendants()
|
||||
.Where(e => tagName.Equals(e.Name.LocalName, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public static IEnumerable<XElement> GetChildrenByTagName(this XContainer container, string tagName)
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
throw new ArgumentNullException("container");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(tagName))
|
||||
{
|
||||
throw new ArgumentNullException("tagName");
|
||||
}
|
||||
|
||||
return container.Elements()
|
||||
.Where(e => e.Name != null && tagName.Equals(e.Name.LocalName, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class DomSerializationParams
|
||||
{
|
||||
#region Factory methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of DomSerializationParams with parameters set to their defaults.
|
||||
/// </summary>
|
||||
public static DomSerializationParams CreateDefault()
|
||||
{
|
||||
return new DomSerializationParams();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the output will be formatted.
|
||||
/// </summary>
|
||||
public bool PrettyPrint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether DOCTYPE will be included at the beginning of the output.
|
||||
/// </summary>
|
||||
public bool DontIncludeContentTypeMetaElement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether mobile-specific elements (such as eg. meta HandheldFriendly) will be added/replaced in the output.
|
||||
/// </summary>
|
||||
public bool DontIncludeMobileSpecificMetaElements { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a meta tag with a content-type specification will be added/replaced in the output.
|
||||
/// </summary>
|
||||
public bool DontIncludeDocTypeMetaElement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a meta tag with a generator specification will be added/replaced in the output.
|
||||
/// </summary>
|
||||
public bool DontIncludeGeneratorMetaElement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Render complete Website or only the Body
|
||||
/// </summary>
|
||||
public bool BodyOnly { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class ElementsTraverser
|
||||
{
|
||||
private readonly Action<XElement> _elementVisitor;
|
||||
|
||||
#region Constructor(s)
|
||||
|
||||
public ElementsTraverser(Action<XElement> elementVisitor)
|
||||
{
|
||||
if (elementVisitor == null)
|
||||
{
|
||||
throw new ArgumentNullException("elementVisitor");
|
||||
}
|
||||
|
||||
_elementVisitor = elementVisitor;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
|
||||
public void Traverse(XElement element)
|
||||
{
|
||||
_elementVisitor(element);
|
||||
|
||||
var childNode = element.FirstNode;
|
||||
|
||||
while (childNode != null)
|
||||
{
|
||||
var nextChildNode = childNode.NextNode;
|
||||
|
||||
if (childNode is XElement)
|
||||
{
|
||||
Traverse((XElement)childNode);
|
||||
}
|
||||
|
||||
childNode = nextChildNode;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
internal class EncodedStringWriter : StringWriter
|
||||
{
|
||||
private static readonly Encoding _DefaultEncoding = Encoding.UTF8;
|
||||
|
||||
private readonly Encoding _encoding;
|
||||
|
||||
#region Constructor(s)
|
||||
|
||||
public EncodedStringWriter(StringBuilder sb, Encoding encoding)
|
||||
: base(sb)
|
||||
{
|
||||
if (encoding == null)
|
||||
{
|
||||
throw new ArgumentNullException("encoding");
|
||||
}
|
||||
|
||||
_encoding = encoding;
|
||||
}
|
||||
|
||||
public EncodedStringWriter(StringBuilder sb)
|
||||
: this(sb, _DefaultEncoding)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public override Encoding Encoding
|
||||
{
|
||||
get { return _encoding; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the only one element in the sequence or default(T) if either the sequence doesn't contain any elements or it contains more than one element.
|
||||
/// </summary>
|
||||
public static T SingleOrNone<T>(this IEnumerable<T> enumerable)
|
||||
where T : class
|
||||
{
|
||||
// ReSharper disable PossibleMultipleEnumeration
|
||||
|
||||
if (enumerable == null)
|
||||
{
|
||||
throw new ArgumentNullException("enumerable");
|
||||
}
|
||||
|
||||
T firstElement = enumerable.FirstOrDefault();
|
||||
|
||||
if (firstElement == null)
|
||||
{
|
||||
// no elements
|
||||
return null;
|
||||
}
|
||||
|
||||
T secondElement = enumerable.Skip(1).FirstOrDefault();
|
||||
|
||||
if (secondElement != null)
|
||||
{
|
||||
// more than one element
|
||||
return null;
|
||||
}
|
||||
|
||||
return firstElement;
|
||||
|
||||
// ReSharper restore PossibleMultipleEnumeration
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines how the extracted article will be styled.
|
||||
/// </summary>
|
||||
public enum ReadingStyle
|
||||
{
|
||||
/// <summary>
|
||||
/// Newspaper style.
|
||||
/// </summary>
|
||||
Newspaper,
|
||||
|
||||
/// <summary>
|
||||
/// Novel style.
|
||||
/// </summary>
|
||||
Novel,
|
||||
|
||||
/// <summary>
|
||||
/// Ebook style.
|
||||
/// </summary>
|
||||
Ebook,
|
||||
|
||||
/// <summary>
|
||||
/// Terminal style.
|
||||
/// </summary>
|
||||
Terminal,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines how wide the margin of the extracted article will be.
|
||||
/// </summary>
|
||||
public enum ReadingMargin
|
||||
{
|
||||
/// <summary>
|
||||
/// Extra-narrow margin.
|
||||
/// </summary>
|
||||
XNarrow,
|
||||
|
||||
/// <summary>
|
||||
/// Narrow margin.
|
||||
/// </summary>
|
||||
Narrow,
|
||||
|
||||
/// <summary>
|
||||
/// Medium margin.
|
||||
/// </summary>
|
||||
Medium,
|
||||
|
||||
/// <summary>
|
||||
/// Wide margin.
|
||||
/// </summary>
|
||||
Wide,
|
||||
|
||||
/// <summary>
|
||||
/// Extra-wide margin.
|
||||
/// </summary>
|
||||
XWide,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines how large the font of the extracted article will be.
|
||||
/// </summary>
|
||||
public enum ReadingSize
|
||||
{
|
||||
/// <summary>
|
||||
/// Extra-small font.
|
||||
/// </summary>
|
||||
XSmall,
|
||||
|
||||
/// <summary>
|
||||
/// Small font.
|
||||
/// </summary>
|
||||
Small,
|
||||
|
||||
/// <summary>
|
||||
/// Medium font.
|
||||
/// </summary>
|
||||
Medium,
|
||||
|
||||
/// <summary>
|
||||
/// Large font.
|
||||
/// </summary>
|
||||
Large,
|
||||
|
||||
/// <summary>
|
||||
/// Extra-large font.
|
||||
/// </summary>
|
||||
XLarge,
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public static class HtmlUtils
|
||||
{
|
||||
public static string RemoveScriptTags(string htmlContent)
|
||||
{
|
||||
if (htmlContent == null)
|
||||
{
|
||||
throw new ArgumentNullException("htmlContent");
|
||||
}
|
||||
|
||||
if (htmlContent.Length == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int indexOfScriptTagStart = htmlContent.IndexOf("<script", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (indexOfScriptTagStart == -1)
|
||||
{
|
||||
return htmlContent;
|
||||
}
|
||||
|
||||
int indexOfScriptTagEnd = htmlContent.IndexOf("</script>", indexOfScriptTagStart, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (indexOfScriptTagEnd == -1)
|
||||
{
|
||||
return htmlContent.Substring(0, indexOfScriptTagStart);
|
||||
}
|
||||
|
||||
string strippedHtmlContent =
|
||||
htmlContent.Substring(0, indexOfScriptTagStart) +
|
||||
htmlContent.Substring(indexOfScriptTagEnd + "</script>".Length);
|
||||
|
||||
return RemoveScriptTags(strippedHtmlContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
/// <summary>
|
||||
/// An exception that is thrown when an internal error occurrs in the application.
|
||||
/// Internal error in the application means that there is a bug in the application.
|
||||
/// </summary>
|
||||
public class InternalErrorException : Exception
|
||||
{
|
||||
#region Constructor(s)
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the InternalErrorException class with a specified error message and a reference to the inner exception that is the cause of this exception.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
|
||||
public InternalErrorException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the InternalErrorException class with a specified error message.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
public InternalErrorException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the InternalErrorException class.
|
||||
/// </summary>
|
||||
public InternalErrorException()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
<?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>{14C3EE6A-54A4-4A37-8B56-D52A3802F1C2}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PocketSharp.Ports.NReadability</RootNamespace>
|
||||
<AssemblyName>PocketSharp.Ports.NReadability</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>Profile96</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
</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 -->
|
||||
<EmbeddedResource Include="Resources\readability.css" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AttributeTransformationInput.cs" />
|
||||
<Compile Include="AttributeTransformationResult.cs" />
|
||||
<Compile Include="ChildNodesTraverser.cs" />
|
||||
<Compile Include="Consts.cs" />
|
||||
<Compile Include="DomExtensions.cs" />
|
||||
<Compile Include="DomSerializationParams.cs" />
|
||||
<Compile Include="ElementsTraverser.cs" />
|
||||
<Compile Include="EncodedStringWriter.cs" />
|
||||
<Compile Include="EnumerableExtensions.cs" />
|
||||
<Compile Include="Enums.cs" />
|
||||
<Compile Include="HtmlUtils.cs" />
|
||||
<Compile Include="InternalErrorException.cs" />
|
||||
<Compile Include="NReadabilityTranscoder.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SgmlDomBuilder.cs" />
|
||||
<Compile Include="SgmlDomSerializer.cs" />
|
||||
<Compile Include="TranscodingInput.cs" />
|
||||
<Compile Include="TranscodingResult.cs" />
|
||||
<Compile Include="UtilityExtensions.cs" />
|
||||
<Compile Include="WebTranscodingInput.cs" />
|
||||
<Compile Include="WebTranscodingResult.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SgmlReader\SgmlReader.csproj">
|
||||
<Project>{9112414c-e2d1-43ba-a298-a89f77d94332}</Project>
|
||||
<Name>SgmlReader</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<!-- 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>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
||||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 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("NReadabilityPCL")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("NReadabilityPCL")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
||||
// 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("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,82 +0,0 @@
|
||||
/* Document */
|
||||
body {font-size: 100%;}
|
||||
#readability-logo,#arc90-logo,.footer-twitterLink,#readTools a,a.rdbTK-powered span{background-color:transparent!important;background-image:url(http://lab.arc90.com/experiments/readability/images/sprite-readability.png)!important;background-repeat:no-repeat!important;}
|
||||
#readOverlay {display:block;position:absolute;top:0;left:0;width:100%;}
|
||||
#readInner {line-height:1.4em;max-width:800px;margin:1em auto;}
|
||||
#readInner a {color:#039;text-decoration:none;}
|
||||
#readInner a:hover {text-decoration:underline;}
|
||||
#readInner img {float:left;clear:both;margin: 0 12px 12px 0;}
|
||||
#readInner h1 {display:block;width:100%;border-bottom:1px solid #333;font-size:1.2em;padding-bottom:.5em;margin-top:0;margin-bottom:.75em;}
|
||||
#readInner sup{line-height:.8em;}
|
||||
#readInner .page-separator{clear:both;display:block;font-size:.85em;filter:alpha(opacity=20);opacity:.20;text-align:center;}
|
||||
.style-apertura #readInner h1 {border-bottom-color:#ededed;}
|
||||
#readInner blockquote {margin-left:3em;margin-right:3em;}
|
||||
#readability-inner * {margin-bottom:16px;border:none;background:none;}
|
||||
/* Footer */
|
||||
#readFooter {display:block;border-top:1px solid #333;text-align:center;clear:both;overflow:hidden;}
|
||||
.style-apertura #readFooter {border-top-color:#ededed;}
|
||||
#rdb-footer-left {display:inline;float:left;margin-top:15px;width:285px;background-position:0 -36px;}
|
||||
.rdbTypekit #rdb-footer-left {width:475px;}
|
||||
#rdb-footer-left a,#rdb-footer-left a:link {float:left;}
|
||||
#readability-logo {display:inline;background-position:0 -36px;height:29px;width:189px;text-indent:-9000px;}
|
||||
#arc90-logo {display:inline;background-position:right -36px;height:29px;width:96px;text-indent:-9000px;}
|
||||
#readability-url {display:none;}
|
||||
.style-apertura #readability-logo {background-position:0 -67px;}
|
||||
.style-apertura #arc90-logo {background-position:right -67px;}
|
||||
#rdb-footer-right {display:inline;float:right;text-align:right;font-size:.75em;margin-top:18px;}
|
||||
#rdb-footer-right a {display:inline-block;float:left;overflow:visible;line-height:16px;vertical-align:baseline;}
|
||||
.footer-twitterLink {height:20px;margin-left:20px;padding:4px 0 0 28px;background-position:0 -123px;font-size:12px;}
|
||||
#rdb-footer-left .footer-twitterLink {display:none;margin-top:1px;padding-top:2px;}
|
||||
.rdbTypekit #rdb-footer-right .footer-twitterLink {display:none;}
|
||||
.rdbTypekit #rdb-footer-left .footer-twitterLink {display:inline-block!important;}
|
||||
a.rdbTK-powered,a.rdbTK-powered:link,a.rdbTK-powered:hover {font-size:16px;color:#858789!important;text-decoration:none!important;}
|
||||
a.rdbTK-powered span {display:inline-block;height:22px;margin-left:2px;padding:4px 0 0 26px;background-position:0 -146px!important;}
|
||||
.style-apertura #rdb-inverse,.style-athelas #rdb-athelas {display:block;}
|
||||
span.version {display:none;}
|
||||
/* Tools */
|
||||
#readTools {width:34px;height:150px;position:fixed;z-index:100;top:10px;left:10px;}
|
||||
#readTools a {overflow:hidden;margin-bottom:8px;display:block;opacity:.4;text-indent:-99999px;height:34px;width:34px;text-decoration:none;filter:alpha(opacity=40);}
|
||||
#reload-page {background-position:0 0;}
|
||||
#print-page {background-position:-36px 0;}
|
||||
#email-page {background-position:-72px 0;}
|
||||
#kindle-page {background-position:-108px 0;}
|
||||
#readTools a:hover {opacity:1;filter:alpha(opacity=100);}
|
||||
/* -- USER-CONFIGURABLE STYLING -- */
|
||||
/* Size */
|
||||
.size-x-small {font-size:.75em;}
|
||||
.size-small {font-size:.938em;}
|
||||
.size-medium {font-size:1.125em;}
|
||||
.size-large {font-size:1.375em;}
|
||||
.size-x-large {font-size:1.75em;}
|
||||
/* Style */
|
||||
.style-newspaper {font-family:"Times New Roman", Times, serif;background:#fbfbfb;color:#080000;}
|
||||
.style-newspaper h1 {text-transform:capitalize;font-family:Georgia, "Times New Roman", Times, serif;}
|
||||
.style-newspaper #readInner a {color:#0924e1;}
|
||||
.style-novel {font-family:"Palatino Linotype", "Book Antiqua", Palatino, serif;background:#f4eed9;color:#1d1916;}
|
||||
.style-novel #readInner a {color:#1856ba;}
|
||||
.style-ebook {font-family:Arial, Helvetica, sans-serif;background:#edebe8;color:#2c2d32;}
|
||||
.style-ebook #readInner a {color:#187dc9;}
|
||||
.style-ebook h1 {font-family:"Arial Black", Gadget, sans-serif;font-weight:400;}
|
||||
.style-terminal {font-family:"Lucida Console", Monaco, monospace;background:#1d4e2c;color:#c6ffc6;}
|
||||
.style-terminal #readInner a {color:#093;}
|
||||
/* Typekit */
|
||||
.style-apertura {font-family:"apertura-1", "apertura-2", sans-serif;background-color:#2d2828;color:#eae8e9;}
|
||||
.style-apertura #readInner a {color:#58b0ff;}
|
||||
.style-athelas {font-family:"athelas-1", "athelas-2", "Palatino Linotype", "Book Antiqua", Palatino, serif;background-color:#f7f7f7;color:#2b373d;}
|
||||
.style-athelas #readInner a {color:#1e83cb;}
|
||||
/* Margin */
|
||||
.margin-x-narrow {width:95%;}
|
||||
.margin-narrow {width:85%;}
|
||||
.margin-medium {width:75%;}
|
||||
.margin-wide {width:55%;}
|
||||
.margin-x-wide {width:35%;}
|
||||
/* -- USER-CONFIGURABLE STYLING -- */
|
||||
/* -- DEBUG -- */
|
||||
.bug-green {background:#bbf9b0;border:4px solid green;}
|
||||
.bug-red {background:red;}
|
||||
.bug-yellow {background:#ffff8e;}
|
||||
.bug-blue {background:#bfdfff;}
|
||||
/* -- EMAIL / KINDLE POP UP -- */
|
||||
#kindle-container, #email-container {position:fixed;top:60px;left:50%;width:500px;height:490px;border:solid 3px #666;background-color:#fff;z-index:100!important;overflow:hidden;margin:0 0 0 -240px;padding:0;}
|
||||
/* Override html styling attributes */
|
||||
table, tr, td { background-color: transparent !important; }
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using PocketSharp.Ports.Sgml;
|
||||
using System.IO;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
/// <summary>
|
||||
/// A class for constructing a DOM from HTML markup.
|
||||
/// </summary>
|
||||
public class SgmlDomBuilder
|
||||
{
|
||||
#region Public methods
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a DOM (System.Xml.Linq.XDocument) from HTML markup.
|
||||
/// </summary>
|
||||
/// <param name="htmlContent">HTML markup from which the DOM is to be constructed.</param>
|
||||
/// <returns>System.Linq.Xml.XDocument instance which is a DOM of the provided HTML markup.</returns>
|
||||
public XDocument BuildDocument(string htmlContent)
|
||||
{
|
||||
if (htmlContent == null)
|
||||
{
|
||||
throw new ArgumentNullException("htmlContent");
|
||||
}
|
||||
|
||||
if (htmlContent.Trim().Length == 0)
|
||||
{
|
||||
return new XDocument();
|
||||
}
|
||||
|
||||
// "trim end" htmlContent to ...</html>$ (codinghorror.com puts some scripts after the </html> - sic!)
|
||||
const string htmlEnd = "</html";
|
||||
int indexOfHtmlEnd = htmlContent.LastIndexOf(htmlEnd);
|
||||
|
||||
if (indexOfHtmlEnd != -1)
|
||||
{
|
||||
int indexOfHtmlEndBracket = htmlContent.IndexOf('>', indexOfHtmlEnd);
|
||||
|
||||
if (indexOfHtmlEndBracket != -1)
|
||||
{
|
||||
htmlContent = htmlContent.Substring(0, indexOfHtmlEndBracket + 1);
|
||||
}
|
||||
}
|
||||
|
||||
XDocument document;
|
||||
|
||||
try
|
||||
{
|
||||
document = LoadDocument(htmlContent);
|
||||
}
|
||||
catch (InvalidOperationException exc)
|
||||
{
|
||||
// sometimes SgmlReader doesn't handle <script> tags well and XDocument.Load() throws,
|
||||
// so we can retry with the html content with <script> tags stripped off
|
||||
|
||||
if (!exc.Message.Contains("EndOfFile"))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
htmlContent = HtmlUtils.RemoveScriptTags(htmlContent);
|
||||
|
||||
document = LoadDocument(htmlContent);
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XDocument LoadDocument(string htmlContent)
|
||||
{
|
||||
using (var sgmlReader = new SgmlReader())
|
||||
{
|
||||
sgmlReader.CaseFolding = CaseFolding.ToLower;
|
||||
sgmlReader.DocType = "HTML";
|
||||
sgmlReader.WhitespaceHandling = WhitespaceHandling.None;
|
||||
|
||||
using (var sr = new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(htmlContent))))
|
||||
{
|
||||
sgmlReader.InputStream = sr;
|
||||
|
||||
var document = XDocument.Load(sgmlReader);
|
||||
|
||||
return document;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
/// <summary>
|
||||
/// A class for serializing a DOM to string.
|
||||
/// </summary>
|
||||
public class SgmlDomSerializer
|
||||
{
|
||||
#region Public methods
|
||||
|
||||
/// <summary>
|
||||
/// Serializes given DOM (System.Xml.Linq.XDocument object) to a string.
|
||||
/// </summary>
|
||||
/// <param name="document">System.Xml.Linq.XDocument instance containing the DOM to be serialized.</param>
|
||||
/// <param name="domSerializationParams">Contains parameters that modify the behaviour of the output serialization.</param>
|
||||
/// <param name="bodyOnly">if set to <c>true</c> [returns body only].</param>
|
||||
/// <returns>
|
||||
/// Serialized representation of the DOM.
|
||||
/// </returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// The document must have a root.
|
||||
/// or
|
||||
/// The document's root must be an html element.
|
||||
/// </exception>
|
||||
public string SerializeDocument(XDocument document, DomSerializationParams domSerializationParams)
|
||||
{
|
||||
if (!domSerializationParams.DontIncludeContentTypeMetaElement
|
||||
|| !domSerializationParams.DontIncludeMobileSpecificMetaElements
|
||||
|| !domSerializationParams.DontIncludeGeneratorMetaElement)
|
||||
{
|
||||
var documentRoot = document.Root;
|
||||
|
||||
if (documentRoot == null)
|
||||
{
|
||||
throw new ArgumentException("The document must have a root.");
|
||||
}
|
||||
|
||||
if (documentRoot.Name == null || !"html".Equals(documentRoot.Name.LocalName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("The document's root must be an html element.");
|
||||
}
|
||||
|
||||
// add <head> element if not present
|
||||
var headElement = documentRoot.GetChildrenByTagName("head").FirstOrDefault();
|
||||
|
||||
if (headElement == null)
|
||||
{
|
||||
headElement = new XElement("head");
|
||||
documentRoot.AddFirst(headElement);
|
||||
}
|
||||
|
||||
ProcessMetaElements(headElement, domSerializationParams);
|
||||
}
|
||||
|
||||
string result = document.ToString(domSerializationParams.PrettyPrint ? SaveOptions.None : SaveOptions.DisableFormatting);
|
||||
|
||||
if (!domSerializationParams.DontIncludeDocTypeMetaElement)
|
||||
{
|
||||
result = "<!DOCTYPE html>\r\n" + result;
|
||||
}
|
||||
|
||||
if (domSerializationParams.BodyOnly && document.Root != null)
|
||||
{
|
||||
var body = document.Root.GetElementsByTagName("body").FirstOrDefault();
|
||||
|
||||
if (body != null)
|
||||
{
|
||||
result = body.GetInnerHtml();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes given DOM (System.Xml.Linq.XDocument object) to a string.
|
||||
/// </summary>
|
||||
/// <param name="document">System.Xml.Linq.XDocument instance containing the DOM to be serialized.</param>
|
||||
/// <returns>Serialized representation of the DOM.</returns>
|
||||
public string SerializeDocument(XDocument document)
|
||||
{
|
||||
return SerializeDocument(document, DomSerializationParams.CreateDefault());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private helper methods
|
||||
|
||||
private static void ProcessMetaElements(XElement headElement, DomSerializationParams domSerializationParams)
|
||||
{
|
||||
ProcessMetaContentTypeElement(headElement, domSerializationParams);
|
||||
ProcessMobileSpecificMetaElements(headElement, domSerializationParams);
|
||||
ProcessMetaGeneratorElement(headElement, domSerializationParams);
|
||||
}
|
||||
|
||||
private static void ProcessMetaContentTypeElement(XElement headElement, DomSerializationParams domSerializationParams)
|
||||
{
|
||||
if (!domSerializationParams.DontIncludeContentTypeMetaElement)
|
||||
{
|
||||
XElement metaContentTypeElement =
|
||||
(from metaElement in headElement.GetChildrenByTagName("meta")
|
||||
where "content-type".Equals(metaElement.GetAttributeValue("http-equiv", ""), StringComparison.OrdinalIgnoreCase)
|
||||
select metaElement).FirstOrDefault();
|
||||
|
||||
// remove meta 'http-equiv' element if present
|
||||
if (metaContentTypeElement != null)
|
||||
{
|
||||
metaContentTypeElement.Remove();
|
||||
}
|
||||
|
||||
// add <meta name="http-equiv" ... /> element
|
||||
metaContentTypeElement =
|
||||
new XElement(
|
||||
XName.Get("meta", headElement.Name != null ? (headElement.Name.NamespaceName ?? "") : ""),
|
||||
new XAttribute("http-equiv", "Content-Type"),
|
||||
new XAttribute("content", "text/html; charset=utf-8"));
|
||||
|
||||
headElement.AddFirst(metaContentTypeElement);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessMobileSpecificMetaElements(XElement headElement, DomSerializationParams domSerializationParams)
|
||||
{
|
||||
XElement metaViewportElement =
|
||||
(from metaElement in headElement.GetChildrenByTagName("meta")
|
||||
where "viewport".Equals(metaElement.GetAttributeValue("name", ""), StringComparison.OrdinalIgnoreCase)
|
||||
select metaElement).FirstOrDefault();
|
||||
|
||||
// remove meta 'viewport' element if present
|
||||
if (metaViewportElement != null)
|
||||
{
|
||||
metaViewportElement.Remove();
|
||||
}
|
||||
|
||||
XElement metaHandheldFriendlyElement =
|
||||
(from metaElement in headElement.GetChildrenByTagName("meta")
|
||||
where "HandheldFriendly".Equals(metaElement.GetAttributeValue("name", ""), StringComparison.OrdinalIgnoreCase)
|
||||
select metaElement).FirstOrDefault();
|
||||
|
||||
// remove meta 'HandheldFriendly' element if present
|
||||
if (metaHandheldFriendlyElement != null)
|
||||
{
|
||||
metaHandheldFriendlyElement.Remove();
|
||||
}
|
||||
|
||||
if (!domSerializationParams.DontIncludeMobileSpecificMetaElements)
|
||||
{
|
||||
// add <meta name="HandheldFriendly" ... /> element
|
||||
metaHandheldFriendlyElement = new XElement(
|
||||
XName.Get("meta", headElement.Name != null ? (headElement.Name.NamespaceName ?? "") : ""),
|
||||
new XAttribute("name", "HandheldFriendly"),
|
||||
new XAttribute("content", "true"));
|
||||
|
||||
headElement.AddFirst(metaHandheldFriendlyElement);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessMetaGeneratorElement(XElement headElement, DomSerializationParams domSerializationParams)
|
||||
{
|
||||
if (!domSerializationParams.DontIncludeGeneratorMetaElement)
|
||||
{
|
||||
XElement metaGeneratorElement =
|
||||
(from metaElement in headElement.GetChildrenByTagName("meta")
|
||||
where "Generator".Equals(metaElement.GetAttributeValue("name", ""), StringComparison.OrdinalIgnoreCase)
|
||||
select metaElement).FirstOrDefault();
|
||||
|
||||
// remove meta 'generator' element if present
|
||||
if (metaGeneratorElement != null)
|
||||
{
|
||||
metaGeneratorElement.Remove();
|
||||
}
|
||||
|
||||
// add <meta name="Generator" ... /> element
|
||||
metaGeneratorElement = new XElement(
|
||||
XName.Get("meta", headElement.Name != null ? (headElement.Name.NamespaceName ?? "") : ""),
|
||||
new XAttribute("name", "Generator"),
|
||||
new XAttribute("content", Consts.NReadabilityFullName));
|
||||
|
||||
headElement.AddFirst(metaGeneratorElement);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class TranscodingInput
|
||||
{
|
||||
private DomSerializationParams _domSerializationParams;
|
||||
|
||||
public TranscodingInput(string htmlContent)
|
||||
{
|
||||
if (string.IsNullOrEmpty(htmlContent))
|
||||
{
|
||||
throw new ArgumentException("Argument can't be null nor empty.", "htmlContent");
|
||||
}
|
||||
|
||||
HtmlContent = htmlContent;
|
||||
}
|
||||
|
||||
public string HtmlContent { get; private set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public DomSerializationParams DomSerializationParams
|
||||
{
|
||||
get { return _domSerializationParams ?? (_domSerializationParams = DomSerializationParams.CreateDefault()); }
|
||||
set { _domSerializationParams = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class TranscodingResult
|
||||
{
|
||||
public TranscodingResult(bool contentExtracted, bool titleExtracted)
|
||||
{
|
||||
ContentExtracted = contentExtracted;
|
||||
TitleExtracted = titleExtracted;
|
||||
}
|
||||
|
||||
public bool ContentExtracted { get; private set; }
|
||||
|
||||
public bool TitleExtracted { get; private set; }
|
||||
|
||||
public string ExtractedContent { get; set; }
|
||||
|
||||
public string ExtractedTitle { get; set; }
|
||||
|
||||
public string NextPageUrl { get; set; }
|
||||
|
||||
public XDocument RawDocument { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* NReadability
|
||||
* http://code.google.com/p/nreadability/
|
||||
*
|
||||
* Copyright 2010 Marek Stój
|
||||
* http://immortal.pl/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
internal static class UtilityExtensions
|
||||
{
|
||||
#region Public methods
|
||||
|
||||
public static bool IsCloseToZero(this float x)
|
||||
{
|
||||
return Math.Abs(x) < float.Epsilon;
|
||||
}
|
||||
|
||||
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
|
||||
{
|
||||
foreach (var element in enumerable)
|
||||
{
|
||||
action(element);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class WebTranscodingInput
|
||||
{
|
||||
private DomSerializationParams _domSerializationParams;
|
||||
|
||||
public WebTranscodingInput(string url)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
{
|
||||
throw new ArgumentException("Argument can't be null nor empty.", "url");
|
||||
}
|
||||
|
||||
Url = url;
|
||||
}
|
||||
|
||||
public string Url { get; private set; }
|
||||
|
||||
public DomSerializationParams DomSerializationParams
|
||||
{
|
||||
get { return _domSerializationParams ?? (_domSerializationParams = DomSerializationParams.CreateDefault()); }
|
||||
set { _domSerializationParams = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class WebTranscodingResult
|
||||
{
|
||||
public WebTranscodingResult(bool contentExtracted, bool titleExtracted)
|
||||
{
|
||||
ContentExtracted = contentExtracted;
|
||||
TitleExtracted = titleExtracted;
|
||||
}
|
||||
|
||||
public bool ContentExtracted { get; private set; }
|
||||
|
||||
public bool TitleExtracted { get; private set; }
|
||||
|
||||
public string ExtractedContent { get; set; }
|
||||
|
||||
public string ExtractedTitle { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
<!-- Special characters for HTML -->
|
||||
|
||||
<!-- Character entity set. Typical invocation:
|
||||
<!ENTITY % HTMLspecial PUBLIC
|
||||
"-//W3C//ENTITIES Special//EN//HTML">
|
||||
%HTMLspecial; -->
|
||||
|
||||
<!-- Portions (C) International Organization for Standardization 1986:
|
||||
Permission to copy in any form is granted for use with
|
||||
conforming SGML systems and applications as defined in
|
||||
ISO 8879, provided this notice is included in all copies.
|
||||
-->
|
||||
|
||||
<!-- Relevant ISO entity set is given unless names are newly introduced.
|
||||
New names (i.e., not in ISO 8879 list) do not clash with any
|
||||
existing ISO 8879 entity names. ISO 10646 character numbers
|
||||
are given for each character, in hex. CDATA values are decimal
|
||||
conversions of the ISO 10646 values and refer to the document
|
||||
character set. Names are ISO 10646 names.
|
||||
|
||||
-->
|
||||
|
||||
<!-- C0 Controls and Basic Latin -->
|
||||
<!ENTITY quot CDATA """ -- quotation mark = APL quote,
|
||||
U+0022 ISOnum -->
|
||||
<!ENTITY amp CDATA "&" -- ampersand, U+0026 ISOnum -->
|
||||
<!ENTITY lt CDATA "<" -- less-than sign, U+003C ISOnum -->
|
||||
<!ENTITY gt CDATA ">" -- greater-than sign, U+003E ISOnum -->
|
||||
|
||||
<!-- Latin Extended-A -->
|
||||
<!ENTITY OElig CDATA "Œ" -- latin capital ligature OE,
|
||||
U+0152 ISOlat2 -->
|
||||
<!ENTITY oelig CDATA "œ" -- latin small ligature oe, U+0153 ISOlat2 -->
|
||||
<!-- ligature is a misnomer, this is a separate character in some languages -->
|
||||
<!ENTITY Scaron CDATA "Š" -- latin capital letter S with caron,
|
||||
U+0160 ISOlat2 -->
|
||||
<!ENTITY scaron CDATA "š" -- latin small letter s with caron,
|
||||
U+0161 ISOlat2 -->
|
||||
<!ENTITY Yuml CDATA "Ÿ" -- latin capital letter Y with diaeresis,
|
||||
U+0178 ISOlat2 -->
|
||||
|
||||
<!-- Spacing Modifier Letters -->
|
||||
<!ENTITY circ CDATA "ˆ" -- modifier letter circumflex accent,
|
||||
U+02C6 ISOpub -->
|
||||
<!ENTITY tilde CDATA "˜" -- small tilde, U+02DC ISOdia -->
|
||||
|
||||
<!-- General Punctuation -->
|
||||
<!ENTITY ensp CDATA " " -- en space, U+2002 ISOpub -->
|
||||
<!ENTITY emsp CDATA " " -- em space, U+2003 ISOpub -->
|
||||
<!ENTITY thinsp CDATA " " -- thin space, U+2009 ISOpub -->
|
||||
<!ENTITY zwnj CDATA "‌" -- zero width non-joiner,
|
||||
U+200C NEW RFC 2070 -->
|
||||
<!ENTITY zwj CDATA "‍" -- zero width joiner, U+200D NEW RFC 2070 -->
|
||||
<!ENTITY lrm CDATA "‎" -- left-to-right mark, U+200E NEW RFC 2070 -->
|
||||
<!ENTITY rlm CDATA "‏" -- right-to-left mark, U+200F NEW RFC 2070 -->
|
||||
<!ENTITY ndash CDATA "–" -- en dash, U+2013 ISOpub -->
|
||||
<!ENTITY mdash CDATA "—" -- em dash, U+2014 ISOpub -->
|
||||
<!ENTITY lsquo CDATA "‘" -- left single quotation mark,
|
||||
U+2018 ISOnum -->
|
||||
<!ENTITY rsquo CDATA "’" -- right single quotation mark,
|
||||
U+2019 ISOnum -->
|
||||
<!ENTITY sbquo CDATA "‚" -- single low-9 quotation mark, U+201A NEW -->
|
||||
<!ENTITY ldquo CDATA "“" -- left double quotation mark,
|
||||
U+201C ISOnum -->
|
||||
<!ENTITY rdquo CDATA "”" -- right double quotation mark,
|
||||
U+201D ISOnum -->
|
||||
<!ENTITY bdquo CDATA "„" -- double low-9 quotation mark, U+201E NEW -->
|
||||
<!ENTITY dagger CDATA "†" -- dagger, U+2020 ISOpub -->
|
||||
<!ENTITY Dagger CDATA "‡" -- double dagger, U+2021 ISOpub -->
|
||||
<!ENTITY permil CDATA "‰" -- per mille sign, U+2030 ISOtech -->
|
||||
<!ENTITY lsaquo CDATA "‹" -- single left-pointing angle quotation mark,
|
||||
U+2039 ISO proposed -->
|
||||
<!-- lsaquo is proposed but not yet ISO standardized -->
|
||||
<!ENTITY rsaquo CDATA "›" -- single right-pointing angle quotation mark,
|
||||
U+203A ISO proposed -->
|
||||
<!-- rsaquo is proposed but not yet ISO standardized -->
|
||||
<!ENTITY euro CDATA "€" -- euro sign, U+20AC NEW -->
|
||||
@@ -1,241 +0,0 @@
|
||||
<!-- Mathematical, Greek and Symbolic characters for HTML -->
|
||||
|
||||
<!-- Character entity set. Typical invocation:
|
||||
<!ENTITY % HTMLsymbol PUBLIC
|
||||
"-//W3C//ENTITIES Symbols//EN//HTML">
|
||||
%HTMLsymbol; -->
|
||||
|
||||
<!-- Portions (C) International Organization for Standardization 1986:
|
||||
Permission to copy in any form is granted for use with
|
||||
conforming SGML systems and applications as defined in
|
||||
ISO 8879, provided this notice is included in all copies.
|
||||
-->
|
||||
|
||||
<!-- Relevant ISO entity set is given unless names are newly introduced.
|
||||
New names (i.e., not in ISO 8879 list) do not clash with any
|
||||
existing ISO 8879 entity names. ISO 10646 character numbers
|
||||
are given for each character, in hex. CDATA values are decimal
|
||||
conversions of the ISO 10646 values and refer to the document
|
||||
character set. Names are ISO 10646 names.
|
||||
|
||||
-->
|
||||
|
||||
<!-- Latin Extended-B -->
|
||||
<!ENTITY fnof CDATA "ƒ" -- latin small f with hook = function
|
||||
= florin, U+0192 ISOtech -->
|
||||
|
||||
<!-- Greek -->
|
||||
<!ENTITY Alpha CDATA "Α" -- greek capital letter alpha, U+0391 -->
|
||||
<!ENTITY Beta CDATA "Β" -- greek capital letter beta, U+0392 -->
|
||||
<!ENTITY Gamma CDATA "Γ" -- greek capital letter gamma,
|
||||
U+0393 ISOgrk3 -->
|
||||
<!ENTITY Delta CDATA "Δ" -- greek capital letter delta,
|
||||
U+0394 ISOgrk3 -->
|
||||
<!ENTITY Epsilon CDATA "Ε" -- greek capital letter epsilon, U+0395 -->
|
||||
<!ENTITY Zeta CDATA "Ζ" -- greek capital letter zeta, U+0396 -->
|
||||
<!ENTITY Eta CDATA "Η" -- greek capital letter eta, U+0397 -->
|
||||
<!ENTITY Theta CDATA "Θ" -- greek capital letter theta,
|
||||
U+0398 ISOgrk3 -->
|
||||
<!ENTITY Iota CDATA "Ι" -- greek capital letter iota, U+0399 -->
|
||||
<!ENTITY Kappa CDATA "Κ" -- greek capital letter kappa, U+039A -->
|
||||
<!ENTITY Lambda CDATA "Λ" -- greek capital letter lambda,
|
||||
U+039B ISOgrk3 -->
|
||||
<!ENTITY Mu CDATA "Μ" -- greek capital letter mu, U+039C -->
|
||||
<!ENTITY Nu CDATA "Ν" -- greek capital letter nu, U+039D -->
|
||||
<!ENTITY Xi CDATA "Ξ" -- greek capital letter xi, U+039E ISOgrk3 -->
|
||||
<!ENTITY Omicron CDATA "Ο" -- greek capital letter omicron, U+039F -->
|
||||
<!ENTITY Pi CDATA "Π" -- greek capital letter pi, U+03A0 ISOgrk3 -->
|
||||
<!ENTITY Rho CDATA "Ρ" -- greek capital letter rho, U+03A1 -->
|
||||
<!-- there is no Sigmaf, and no U+03A2 character either -->
|
||||
<!ENTITY Sigma CDATA "Σ" -- greek capital letter sigma,
|
||||
U+03A3 ISOgrk3 -->
|
||||
<!ENTITY Tau CDATA "Τ" -- greek capital letter tau, U+03A4 -->
|
||||
<!ENTITY Upsilon CDATA "Υ" -- greek capital letter upsilon,
|
||||
U+03A5 ISOgrk3 -->
|
||||
<!ENTITY Phi CDATA "Φ" -- greek capital letter phi,
|
||||
U+03A6 ISOgrk3 -->
|
||||
<!ENTITY Chi CDATA "Χ" -- greek capital letter chi, U+03A7 -->
|
||||
<!ENTITY Psi CDATA "Ψ" -- greek capital letter psi,
|
||||
U+03A8 ISOgrk3 -->
|
||||
<!ENTITY Omega CDATA "Ω" -- greek capital letter omega,
|
||||
U+03A9 ISOgrk3 -->
|
||||
|
||||
<!ENTITY alpha CDATA "α" -- greek small letter alpha,
|
||||
U+03B1 ISOgrk3 -->
|
||||
<!ENTITY beta CDATA "β" -- greek small letter beta, U+03B2 ISOgrk3 -->
|
||||
<!ENTITY gamma CDATA "γ" -- greek small letter gamma,
|
||||
U+03B3 ISOgrk3 -->
|
||||
<!ENTITY delta CDATA "δ" -- greek small letter delta,
|
||||
U+03B4 ISOgrk3 -->
|
||||
<!ENTITY epsilon CDATA "ε" -- greek small letter epsilon,
|
||||
U+03B5 ISOgrk3 -->
|
||||
<!ENTITY zeta CDATA "ζ" -- greek small letter zeta, U+03B6 ISOgrk3 -->
|
||||
<!ENTITY eta CDATA "η" -- greek small letter eta, U+03B7 ISOgrk3 -->
|
||||
<!ENTITY theta CDATA "θ" -- greek small letter theta,
|
||||
U+03B8 ISOgrk3 -->
|
||||
<!ENTITY iota CDATA "ι" -- greek small letter iota, U+03B9 ISOgrk3 -->
|
||||
<!ENTITY kappa CDATA "κ" -- greek small letter kappa,
|
||||
U+03BA ISOgrk3 -->
|
||||
<!ENTITY lambda CDATA "λ" -- greek small letter lambda,
|
||||
U+03BB ISOgrk3 -->
|
||||
<!ENTITY mu CDATA "μ" -- greek small letter mu, U+03BC ISOgrk3 -->
|
||||
<!ENTITY nu CDATA "ν" -- greek small letter nu, U+03BD ISOgrk3 -->
|
||||
<!ENTITY xi CDATA "ξ" -- greek small letter xi, U+03BE ISOgrk3 -->
|
||||
<!ENTITY omicron CDATA "ο" -- greek small letter omicron, U+03BF NEW -->
|
||||
<!ENTITY pi CDATA "π" -- greek small letter pi, U+03C0 ISOgrk3 -->
|
||||
<!ENTITY rho CDATA "ρ" -- greek small letter rho, U+03C1 ISOgrk3 -->
|
||||
<!ENTITY sigmaf CDATA "ς" -- greek small letter final sigma,
|
||||
U+03C2 ISOgrk3 -->
|
||||
<!ENTITY sigma CDATA "σ" -- greek small letter sigma,
|
||||
U+03C3 ISOgrk3 -->
|
||||
<!ENTITY tau CDATA "τ" -- greek small letter tau, U+03C4 ISOgrk3 -->
|
||||
<!ENTITY upsilon CDATA "υ" -- greek small letter upsilon,
|
||||
U+03C5 ISOgrk3 -->
|
||||
<!ENTITY phi CDATA "φ" -- greek small letter phi, U+03C6 ISOgrk3 -->
|
||||
<!ENTITY chi CDATA "χ" -- greek small letter chi, U+03C7 ISOgrk3 -->
|
||||
<!ENTITY psi CDATA "ψ" -- greek small letter psi, U+03C8 ISOgrk3 -->
|
||||
<!ENTITY omega CDATA "ω" -- greek small letter omega,
|
||||
U+03C9 ISOgrk3 -->
|
||||
<!ENTITY thetasym CDATA "ϑ" -- greek small letter theta symbol,
|
||||
U+03D1 NEW -->
|
||||
<!ENTITY upsih CDATA "ϒ" -- greek upsilon with hook symbol,
|
||||
U+03D2 NEW -->
|
||||
<!ENTITY piv CDATA "ϖ" -- greek pi symbol, U+03D6 ISOgrk3 -->
|
||||
|
||||
<!-- General Punctuation -->
|
||||
<!ENTITY bull CDATA "•" -- bullet = black small circle,
|
||||
U+2022 ISOpub -->
|
||||
<!-- bullet is NOT the same as bullet operator, U+2219 -->
|
||||
<!ENTITY hellip CDATA "…" -- horizontal ellipsis = three dot leader,
|
||||
U+2026 ISOpub -->
|
||||
<!ENTITY prime CDATA "′" -- prime = minutes = feet, U+2032 ISOtech -->
|
||||
<!ENTITY Prime CDATA "″" -- double prime = seconds = inches,
|
||||
U+2033 ISOtech -->
|
||||
<!ENTITY oline CDATA "‾" -- overline = spacing overscore,
|
||||
U+203E NEW -->
|
||||
<!ENTITY frasl CDATA "⁄" -- fraction slash, U+2044 NEW -->
|
||||
|
||||
<!-- Letterlike Symbols -->
|
||||
<!ENTITY weierp CDATA "℘" -- script capital P = power set
|
||||
= Weierstrass p, U+2118 ISOamso -->
|
||||
<!ENTITY image CDATA "ℑ" -- blackletter capital I = imaginary part,
|
||||
U+2111 ISOamso -->
|
||||
<!ENTITY real CDATA "ℜ" -- blackletter capital R = real part symbol,
|
||||
U+211C ISOamso -->
|
||||
<!ENTITY trade CDATA "™" -- trade mark sign, U+2122 ISOnum -->
|
||||
<!ENTITY alefsym CDATA "ℵ" -- alef symbol = first transfinite cardinal,
|
||||
U+2135 NEW -->
|
||||
<!-- alef symbol is NOT the same as hebrew letter alef,
|
||||
U+05D0 although the same glyph could be used to depict both characters -->
|
||||
|
||||
<!-- Arrows -->
|
||||
<!ENTITY larr CDATA "←" -- leftwards arrow, U+2190 ISOnum -->
|
||||
<!ENTITY uarr CDATA "↑" -- upwards arrow, U+2191 ISOnum-->
|
||||
<!ENTITY rarr CDATA "→" -- rightwards arrow, U+2192 ISOnum -->
|
||||
<!ENTITY darr CDATA "↓" -- downwards arrow, U+2193 ISOnum -->
|
||||
<!ENTITY harr CDATA "↔" -- left right arrow, U+2194 ISOamsa -->
|
||||
<!ENTITY crarr CDATA "↵" -- downwards arrow with corner leftwards
|
||||
= carriage return, U+21B5 NEW -->
|
||||
<!ENTITY lArr CDATA "⇐" -- leftwards double arrow, U+21D0 ISOtech -->
|
||||
<!-- ISO 10646 does not say that lArr is the same as the 'is implied by' arrow
|
||||
but also does not have any other character for that function. So ? lArr can
|
||||
be used for 'is implied by' as ISOtech suggests -->
|
||||
<!ENTITY uArr CDATA "⇑" -- upwards double arrow, U+21D1 ISOamsa -->
|
||||
<!ENTITY rArr CDATA "⇒" -- rightwards double arrow,
|
||||
U+21D2 ISOtech -->
|
||||
<!-- ISO 10646 does not say this is the 'implies' character but does not have
|
||||
another character with this function so ?
|
||||
rArr can be used for 'implies' as ISOtech suggests -->
|
||||
<!ENTITY dArr CDATA "⇓" -- downwards double arrow, U+21D3 ISOamsa -->
|
||||
<!ENTITY hArr CDATA "⇔" -- left right double arrow,
|
||||
U+21D4 ISOamsa -->
|
||||
|
||||
<!-- Mathematical Operators -->
|
||||
<!ENTITY forall CDATA "∀" -- for all, U+2200 ISOtech -->
|
||||
<!ENTITY part CDATA "∂" -- partial differential, U+2202 ISOtech -->
|
||||
<!ENTITY exist CDATA "∃" -- there exists, U+2203 ISOtech -->
|
||||
<!ENTITY empty CDATA "∅" -- empty set = null set = diameter,
|
||||
U+2205 ISOamso -->
|
||||
<!ENTITY nabla CDATA "∇" -- nabla = backward difference,
|
||||
U+2207 ISOtech -->
|
||||
<!ENTITY isin CDATA "∈" -- element of, U+2208 ISOtech -->
|
||||
<!ENTITY notin CDATA "∉" -- not an element of, U+2209 ISOtech -->
|
||||
<!ENTITY ni CDATA "∋" -- contains as member, U+220B ISOtech -->
|
||||
<!-- should there be a more memorable name than 'ni'? -->
|
||||
<!ENTITY prod CDATA "∏" -- n-ary product = product sign,
|
||||
U+220F ISOamsb -->
|
||||
<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though
|
||||
the same glyph might be used for both -->
|
||||
<!ENTITY sum CDATA "∑" -- n-ary sumation, U+2211 ISOamsb -->
|
||||
<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
|
||||
though the same glyph might be used for both -->
|
||||
<!ENTITY minus CDATA "−" -- minus sign, U+2212 ISOtech -->
|
||||
<!ENTITY lowast CDATA "∗" -- asterisk operator, U+2217 ISOtech -->
|
||||
<!ENTITY radic CDATA "√" -- square root = radical sign,
|
||||
U+221A ISOtech -->
|
||||
<!ENTITY prop CDATA "∝" -- proportional to, U+221D ISOtech -->
|
||||
<!ENTITY infin CDATA "∞" -- infinity, U+221E ISOtech -->
|
||||
<!ENTITY ang CDATA "∠" -- angle, U+2220 ISOamso -->
|
||||
<!ENTITY and CDATA "∧" -- logical and = wedge, U+2227 ISOtech -->
|
||||
<!ENTITY or CDATA "∨" -- logical or = vee, U+2228 ISOtech -->
|
||||
<!ENTITY cap CDATA "∩" -- intersection = cap, U+2229 ISOtech -->
|
||||
<!ENTITY cup CDATA "∪" -- union = cup, U+222A ISOtech -->
|
||||
<!ENTITY int CDATA "∫" -- integral, U+222B ISOtech -->
|
||||
<!ENTITY there4 CDATA "∴" -- therefore, U+2234 ISOtech -->
|
||||
<!ENTITY sim CDATA "∼" -- tilde operator = varies with = similar to,
|
||||
U+223C ISOtech -->
|
||||
<!-- tilde operator is NOT the same character as the tilde, U+007E,
|
||||
although the same glyph might be used to represent both -->
|
||||
<!ENTITY cong CDATA "≅" -- approximately equal to, U+2245 ISOtech -->
|
||||
<!ENTITY asymp CDATA "≈" -- almost equal to = asymptotic to,
|
||||
U+2248 ISOamsr -->
|
||||
<!ENTITY ne CDATA "≠" -- not equal to, U+2260 ISOtech -->
|
||||
<!ENTITY equiv CDATA "≡" -- identical to, U+2261 ISOtech -->
|
||||
<!ENTITY le CDATA "≤" -- less-than or equal to, U+2264 ISOtech -->
|
||||
<!ENTITY ge CDATA "≥" -- greater-than or equal to,
|
||||
U+2265 ISOtech -->
|
||||
<!ENTITY sub CDATA "⊂" -- subset of, U+2282 ISOtech -->
|
||||
<!ENTITY sup CDATA "⊃" -- superset of, U+2283 ISOtech -->
|
||||
<!-- note that nsup, 'not a superset of, U+2283' is not covered by the Symbol
|
||||
font encoding and is not included. Should it be, for symmetry?
|
||||
It is in ISOamsn -->
|
||||
<!ENTITY nsub CDATA "⊄" -- not a subset of, U+2284 ISOamsn -->
|
||||
<!ENTITY sube CDATA "⊆" -- subset of or equal to, U+2286 ISOtech -->
|
||||
<!ENTITY supe CDATA "⊇" -- superset of or equal to,
|
||||
U+2287 ISOtech -->
|
||||
<!ENTITY oplus CDATA "⊕" -- circled plus = direct sum,
|
||||
U+2295 ISOamsb -->
|
||||
<!ENTITY otimes CDATA "⊗" -- circled times = vector product,
|
||||
U+2297 ISOamsb -->
|
||||
<!ENTITY perp CDATA "⊥" -- up tack = orthogonal to = perpendicular,
|
||||
U+22A5 ISOtech -->
|
||||
<!ENTITY sdot CDATA "⋅" -- dot operator, U+22C5 ISOamsb -->
|
||||
<!-- dot operator is NOT the same character as U+00B7 middle dot -->
|
||||
|
||||
<!-- Miscellaneous Technical -->
|
||||
<!ENTITY lceil CDATA "⌈" -- left ceiling = apl upstile,
|
||||
U+2308 ISOamsc -->
|
||||
<!ENTITY rceil CDATA "⌉" -- right ceiling, U+2309 ISOamsc -->
|
||||
<!ENTITY lfloor CDATA "⌊" -- left floor = apl downstile,
|
||||
U+230A ISOamsc -->
|
||||
<!ENTITY rfloor CDATA "⌋" -- right floor, U+230B ISOamsc -->
|
||||
<!ENTITY lang CDATA "〈" -- left-pointing angle bracket = bra,
|
||||
U+2329 ISOtech -->
|
||||
<!-- lang is NOT the same character as U+003C 'less than'
|
||||
or U+2039 'single left-pointing angle quotation mark' -->
|
||||
<!ENTITY rang CDATA "〉" -- right-pointing angle bracket = ket,
|
||||
U+232A ISOtech -->
|
||||
<!-- rang is NOT the same character as U+003E 'greater than'
|
||||
or U+203A 'single right-pointing angle quotation mark' -->
|
||||
|
||||
<!-- Geometric Shapes -->
|
||||
<!ENTITY loz CDATA "◊" -- lozenge, U+25CA ISOpub -->
|
||||
|
||||
<!-- Miscellaneous Symbols -->
|
||||
<!ENTITY spades CDATA "♠" -- black spade suit, U+2660 ISOpub -->
|
||||
<!-- black here seems to mean filled as opposed to hollow -->
|
||||
<!ENTITY clubs CDATA "♣" -- black club suit = shamrock,
|
||||
U+2663 ISOpub -->
|
||||
<!ENTITY hearts CDATA "♥" -- black heart suit = valentine,
|
||||
U+2665 ISOpub -->
|
||||
<!ENTITY diams CDATA "♦" -- black diamond suit, U+2666 ISOpub -->
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
||||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 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("SgmlReader")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SgmlReader")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
||||
// 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("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user