Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9b19739fc9 | |||
| ff8bbf17d3 | |||
| da892067ad | |||
| 3992a988fc | |||
| 2a98cfb0e4 | |||
| 3057612872 | |||
| 56180b5829 | |||
| 2a08adef45 | |||
| abfb9f6d78 | |||
| a1f6637e9d | |||
| 8bce874504 | |||
| 50ee8905c5 | |||
| 4d2650072f | |||
| 65e31ac2e2 | |||
| 456c4f17f2 | |||
| ee1e32b9ab | |||
| 9d677eea5a | |||
| 64098518fa | |||
| cc6aab227d | |||
| 543b3e8191 | |||
| 2186561fd8 | |||
| 8650883975 | |||
| 6ede86c367 | |||
| d373bdd9bf | |||
| b4ae55d8ab | |||
| aae43cf00d | |||
| a0e8022f1d | |||
| 4119dec95d | |||
| cf2d929d3a | |||
| e772b8df9e | |||
| d9c4b4c51f | |||
| 4222e873c7 | |||
| 6e02a797b5 | |||
| 329e16ebd5 | |||
| 52bac490b4 | |||
| 1d500d0d4b | |||
| a731a744bc | |||
| 352af4f736 | |||
| 1c74d6ebf4 | |||
| c4d6ea45ea | |||
| 649ded199d | |||
| ef10ca23a4 | |||
| 9c0cf6cb3a | |||
| dbb495ce76 | |||
| 4e6fdc33d6 | |||
| 9cc1f231d9 | |||
| 4136e4cc4b | |||
| 7aee628000 | |||
| ff3c6a6826 | |||
| 2ec09a4a67 | |||
| 266f494db6 |
+2
-8
@@ -1,21 +1,15 @@
|
||||
; This file is for unifying the coding style for different editors and IDEs
|
||||
; editorconfig.org
|
||||
|
||||
; defaults by Tobias Klika
|
||||
; 2013
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
; default settings for all files
|
||||
[*]
|
||||
end_of_line = crlf ; this is git standard, so it won't convert it anymore
|
||||
end_of_line = crlf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
### 2.2.0 (2013-10-26)
|
||||
|
||||
- Made `GetAccessCode` obsolete
|
||||
- Return username after authentication with `GetUser` (thanks to [ScottIsAFool](https://github.com/ScottIsAFool))
|
||||
|
||||
### 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))
|
||||
- Method `GetUsageLimits()` to retrieve API usage limits
|
||||
- Add PORTABLE constant to SgmlReader
|
||||
|
||||
### 2.0.1 (2013-10-19)
|
||||
|
||||
- Catch HttpRequestExceptions and provide as InnerException for PocketException
|
||||
- Read Article from URI (method overload)
|
||||
|
||||
### 2.0.0 (2013-10-17)
|
||||
|
||||
- Add Reader API _(does not use the official Article View API, which is private. The PocketReader is based on a custom PCL port of NReadability and SgmlReader)_
|
||||
|
||||
### 1.5.1 (2013-09-30)
|
||||
|
||||
- `RetrieveFilter.All` didn't work
|
||||
- improve search speed
|
||||
|
||||
### 1.5.0 (2013-09-28)
|
||||
|
||||
- add statistics API
|
||||
- add registration API
|
||||
|
||||
### 1.4.0 (2013-09-21)
|
||||
|
||||
- rename `Retrieve` to `Get`
|
||||
- update IntelliSense documentation
|
||||
- add `GetTags` method
|
||||
|
||||
### 1.3.0 (2013-09-19)
|
||||
|
||||
- get Item by ID
|
||||
- tag modification bugfixes
|
||||
|
||||
### 1.2.1 (2013-09-18)
|
||||
|
||||
- correct parameter conversion for DateTime and Boolean
|
||||
|
||||
### 1.2.0 (2013-09-17)
|
||||
|
||||
- simplified retrieve methods
|
||||
|
||||
### 1.1.0 (2013-09-17)
|
||||
|
||||
- fix modification requests
|
||||
|
||||
### 1.0.0 (2013-09-15)
|
||||
|
||||
- convert to PCL
|
||||
- implement async
|
||||
|
||||
### 0.3.2 (2013-08-16)
|
||||
|
||||
- tag modification fixed
|
||||
- full retrieval of items for Retrieve method
|
||||
|
||||
### 0.3.1 (2013-07-07)
|
||||
|
||||
- authentication fixes
|
||||
|
||||
### 0.3.0 (2013-07-02)
|
||||
|
||||
- update authentication process
|
||||
|
||||
### 0.2.0 (2013-06-27)
|
||||
|
||||
- add, modify item
|
||||
- modify tags
|
||||
|
||||
### 0.1.0 (2013-06-26)
|
||||
|
||||
- authentication
|
||||
- retrieve functionality
|
||||
@@ -74,11 +74,17 @@
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Runtime">
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.1.0.19\lib\sl5\System.Runtime.dll</HintPath>
|
||||
<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.Threading.Tasks">
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.1.0.19\lib\sl5\System.Threading.Tasks.dll</HintPath>
|
||||
<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" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Bcl" version="1.0.19" targetFramework="sl50" />
|
||||
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="sl50" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="sl50" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="sl50" />
|
||||
</packages>
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?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>
|
||||
@@ -49,12 +49,13 @@
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.Extensions">
|
||||
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.13\lib\net45\System.Net.Http.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.Primitives, Version=4.2.13.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Reference Include="System.Net.Http.Extensions, Version=2.2.15.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.13\lib\net45\System.Net.Http.Primitives.dll</HintPath>
|
||||
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.15\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">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\packages\Microsoft.Net.Http.2.2.15\lib\net45\System.Net.Http.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="System.Xml" />
|
||||
@@ -140,4 +141,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -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.13.0" newVersion="4.2.13.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.15.0" newVersion="4.2.15.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.13" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="net45" />
|
||||
</packages>
|
||||
@@ -151,5 +151,14 @@ namespace PocketSharp.Tests
|
||||
|
||||
Assert.True(statistics.CountAll > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task AreLimitsRetrieved()
|
||||
{
|
||||
PocketLimits limits = await client.GetUsageLimits();
|
||||
|
||||
Assert.True(limits.RateLimitForConsumerKey > 9999);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,13 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.Extensions">
|
||||
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\net45\System.Net.Http.Extensions.dll</HintPath>
|
||||
<Reference Include="System.Net.Http.Extensions, Version=2.2.15.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>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.Primitives">
|
||||
<HintPath>..\packages\Microsoft.Net.Http.2.2.13\lib\net45\System.Net.Http.Primitives.dll</HintPath>
|
||||
<Reference Include="System.Net.Http.Primitives, Version=4.2.15.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>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<Reference Include="xunit">
|
||||
@@ -72,6 +74,7 @@
|
||||
<Compile Include="ModifyTests.cs" />
|
||||
<Compile Include="GetTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReadTests.cs" />
|
||||
<Compile Include="TestsBase.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.13.0" newVersion="4.2.13.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.15.0" newVersion="4.2.15.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="net45" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.13" targetFramework="net45" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="net45" />
|
||||
<package id="xunit" version="1.9.2" targetFramework="net45" />
|
||||
</packages>
|
||||
@@ -33,7 +33,7 @@
|
||||
<p class="app-description">
|
||||
PocketSharp is a C#.NET class library, that integrates the Pocket API v3
|
||||
<br><br>
|
||||
Current version: <b>1.5.1</b><br>
|
||||
Current version: <b>2.0.1</b><br>
|
||||
<a href="https://www.nuget.org/packages/PocketSharp/">@ nuget</a>
|
||||
</p>
|
||||
<div class="app-nuget">
|
||||
@@ -48,10 +48,11 @@
|
||||
<div class="app-main">
|
||||
<nav class="app-nav">
|
||||
<a href="#" data-id="gettingstarted" class="is-active">Getting Started</a>
|
||||
<a href="#" data-id="account">Account</a>
|
||||
<a href="#" data-id="get">Get</a>
|
||||
<a href="#" data-id="add">Add</a>
|
||||
<a href="#" data-id="reader">Reader</a>
|
||||
<a href="#" data-id="modify">Modify</a>
|
||||
<a href="#" data-id="account">Account</a>
|
||||
</nav>
|
||||
<article class="article">
|
||||
|
||||
@@ -125,6 +126,8 @@ using PocketSharp.Models;</code></pre>
|
||||
|
||||
<h2>Release History</h2>
|
||||
<ul>
|
||||
<li><b>2.0.1</b> (2013-10-19) Catch HttpRequestExceptions and provide as InnerException for PocketException + Read Article from URI (method overload)</li>
|
||||
<li><b>2.0.0</b> (2013-10-17) Add Reader API</li>
|
||||
<li><b>1.5.1</b> (2013-09-30) <code>RetrieveFilter.All</code> didn't work; improve search speed</li>
|
||||
<li><b>1.5.0</b> (2013-09-28) add statistics and registration API</li>
|
||||
<li><b>1.4.0</b> (2013-09-21) rename <code>Retrieve</code> to <code>Get</code> + update IntelliSense documentation + add <code>GetTags</code> method</li>
|
||||
@@ -314,6 +317,40 @@ Accepts four parameters, with <code>uri</code> being required.
|
||||
|
||||
</div>
|
||||
|
||||
<div data-part="reader">
|
||||
<h2>Article Reader API</h2>
|
||||
<p>PocketSharp 2.0 implements a new <strong>Reader API</strong>.</p>
|
||||
<p>This API does _not _use the official (and private) Article View API by Pocket. It is based on a custom PCL port of NReadability and SgmlReader, which are included in the solution.</p>
|
||||
<h3>What's it all about?</h3>
|
||||
<p>The Reader API extracts the main content of a website and returns the extracted content as HTML and it's associated title (which should already be available in the <code>PocketItem</code>).</p>
|
||||
<p>This content can be encapsulated in a <code><body></code>-Tag and displayed as a readable website with a custom CSS (it's up to you!).</p>
|
||||
<h3>Implementation</h3>
|
||||
<p>As with all PocketSharp implementations you have to require the main namespace and it's model namespace:</p>
|
||||
<p><pre class="language-clike"><code>using PocketSharp;
|
||||
using PocketSharp.Models;</code></pre></p>
|
||||
<p>The <code>PocketReader</code> is a seperated class with it's own <code>HttpClient</code>. Create an instance of it:</p>
|
||||
<p><pre class="language-clike"><code>PocketReader reader = new PocketReader();</code></pre></p>
|
||||
<p><code>PocketReader</code> needs a <code>PocketItem</code> as a parameter to correctly identify its <code>ID</code> and <code>Uri</code>. With this requirement you can successfully query for an articles content.<br>
|
||||
Don't forget exception handling in case a website is down or not accessible.</p>
|
||||
<p><pre class="language-clike"><code>PocketArticle article;
|
||||
try
|
||||
{
|
||||
article = await reader.Read(myPocketItem);
|
||||
// PocketArticle: {
|
||||
// int PocketItemID
|
||||
// string Content
|
||||
// string Title
|
||||
// string NextPageUrl
|
||||
// }
|
||||
}
|
||||
catch (PocketException exc)
|
||||
{
|
||||
// handle exception
|
||||
}
|
||||
</code></pre></p>
|
||||
|
||||
</di>
|
||||
|
||||
</article>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@ 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}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SgmlReader", "PortablePorts\SgmlReader\SgmlReader.csproj", "{9112414C-E2D1-43BA-A298-A89F77D94332}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PortablePorts", "PortablePorts", "{82F79DE3-76D7-4FCB-AA7E-16BA7E363E0D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -42,6 +48,7 @@ Global
|
||||
{817200C3-A327-4E35-9B5F-63A51C088577}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{775569C2-987F-4AC4-8BA5-A315A21ED1B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -82,6 +89,22 @@ 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
|
||||
@@ -90,5 +113,7 @@ Global
|
||||
{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
|
||||
|
||||
@@ -65,36 +65,51 @@ namespace PocketSharp
|
||||
|
||||
/// <summary>
|
||||
/// Requests the access code after authentication
|
||||
/// The access code has to permanently be stored within the users session, and should be added as a parameter for all future PocketClient initializations.
|
||||
/// The access code has to permanently be stored within the users session, and should be passed in the constructor for all future PocketClient initializations.
|
||||
/// </summary>
|
||||
/// <param name="requestCode">The requestCode. If no requestCode is supplied, the property from the PocketClient intialization is used.</param>
|
||||
/// <returns>The permanent access code, which is used to authenticate the user with the application</returns>
|
||||
/// <exception cref="System.NullReferenceException">Call GetRequestCode() first to receive a request_code</exception>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
[Obsolete("Please use GetUser instead")]
|
||||
public async Task<string> GetAccessCode(string requestCode = null)
|
||||
{
|
||||
await GetUser(requestCode);
|
||||
return AccessCode;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Requests the access code and username after authentication
|
||||
/// The access code has to permanently be stored within the users session, and should be passed in the constructor for all future PocketClient initializations.
|
||||
/// </summary>
|
||||
/// <param name="requestCode">The request code.</param>
|
||||
/// <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)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
// do request
|
||||
AccessCode response = await Request<AccessCode>("oauth/authorize", new Dictionary<string, string>()
|
||||
{
|
||||
{ "code", RequestCode }
|
||||
PocketUser response = await Request<PocketUser>("oauth/authorize", new Dictionary<string, string>()
|
||||
{
|
||||
{"code", RequestCode}
|
||||
}, false);
|
||||
|
||||
// save code to client
|
||||
AccessCode = response.Code;
|
||||
|
||||
return AccessCode;
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,13 +11,22 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
public partial class PocketClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves items from pocket
|
||||
/// with the given filters
|
||||
/// </summary>
|
||||
/// <param name="parameters">parameters, which are mapped to the officials from http://getpocket.com/developer/docs/v3/retrieve </param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
/// <summary>
|
||||
/// Retrieves items from pocket
|
||||
/// with the given filters
|
||||
/// </summary>
|
||||
/// <param name="state">The state.</param>
|
||||
/// <param name="favorite">The favorite.</param>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <param name="contentType">Type of the content.</param>
|
||||
/// <param name="sort">The sort.</param>
|
||||
/// <param name="search">The search.</param>
|
||||
/// <param name="domain">The domain.</param>
|
||||
/// <param name="since">The since.</param>
|
||||
/// <param name="count">The count.</param>
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<List<PocketItem>> Get(
|
||||
State? state = null,
|
||||
bool? favorite = null,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using PocketSharp.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using PocketSharp.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
|
||||
@@ -14,9 +14,50 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<PocketStatistics> Statistics()
|
||||
public async Task<PocketStatistics> GetUserStatistics()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
/// <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>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<PocketLimits> GetUsageLimits()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return new PocketLimits()
|
||||
{
|
||||
RateLimitForConsumerKey = Convert.ToInt32(TryGetHeaderValue(lastHeaders, "X-Limit-Key-Limit")),
|
||||
RemainingCallsForConsumerKey = Convert.ToInt32(TryGetHeaderValue(lastHeaders, "X-Limit-Key-Remaining")),
|
||||
SecondsUntilLimitResetsForConsumerKey = Convert.ToInt32(TryGetHeaderValue(lastHeaders, "X-Limit-Key-Reset")),
|
||||
RateLimitForUser = Convert.ToInt32(TryGetHeaderValue(lastHeaders, "X-Limit-User-Limit")),
|
||||
RemainingCallsForUser = Convert.ToInt32(TryGetHeaderValue(lastHeaders, "X-Limit-User-Remaining")),
|
||||
SecondsUntilLimitResetsForUser = Convert.ToInt32(TryGetHeaderValue(lastHeaders, "X-Limit-User-Reset"))
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Weavers>
|
||||
<PropertyChanged />
|
||||
</Weavers>
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Readable article
|
||||
/// </summary>
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketArticle
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the pocket item ID.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The pocket item ID.
|
||||
/// </value>
|
||||
public int PocketItemID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The content.
|
||||
/// </value>
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The title.
|
||||
/// </value>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the next page URL.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The next page URL.
|
||||
/// </value>
|
||||
public Uri NextPage { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -8,6 +8,7 @@ namespace PocketSharp.Models
|
||||
/// Author
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketAuthor
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -8,6 +8,7 @@ namespace PocketSharp.Models
|
||||
/// Image
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketImage
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -10,6 +10,7 @@ namespace PocketSharp.Models
|
||||
/// see: http://getpocket.com/developer/docs/v3/retrieve
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketItem
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
using Newtonsoft.Json;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// API Limitation Statistics
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketLimits
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the rate limit.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Rate limit for current consumer key.
|
||||
/// </value>
|
||||
[JsonProperty("X-Limit-Key-Limit")]
|
||||
public int RateLimitForConsumerKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the remaining calls.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Remaining calls for current consumer key.
|
||||
/// </value>
|
||||
[JsonProperty("X-Limit-Key-Remaining")]
|
||||
public int RemainingCallsForConsumerKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reset seconds.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Seconds until limit resets for current consumer key.
|
||||
/// </value>
|
||||
[JsonProperty("X-Limit-Key-Reset")]
|
||||
public int SecondsUntilLimitResetsForConsumerKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the rate limit.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Rate limit for current user.
|
||||
/// </value>
|
||||
[JsonProperty("X-Limit-User-Limit")]
|
||||
public int RateLimitForUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the remaining calls.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Remaining calls for current user.
|
||||
/// </value>
|
||||
[JsonProperty("X-Limit-User-Remaining")]
|
||||
public int RemainingCallsForUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reset seconds.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Seconds until limit resets for current user.
|
||||
/// </value>
|
||||
[JsonProperty("X-Limit-User-Reset")]
|
||||
public int SecondsUntilLimitResetsForUser { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -7,6 +7,7 @@ namespace PocketSharp.Models
|
||||
/// Statistics
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketStatistics
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Tag
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
public class PocketTag
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// Tag
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
[JsonProperty("tag")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketTag
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
[JsonProperty("tag")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -7,7 +7,8 @@ namespace PocketSharp.Models
|
||||
/// Access Code
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
internal class AccessCode
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketUser
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the code.
|
||||
@@ -24,7 +25,7 @@ namespace PocketSharp.Models
|
||||
/// <value>
|
||||
/// The username.
|
||||
/// </value>
|
||||
[JsonProperty]
|
||||
[JsonProperty("username")]
|
||||
public string Username { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,41 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Video
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
public class PocketVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
/// Video
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The ID.
|
||||
/// </value>
|
||||
[JsonProperty("video_id")]
|
||||
public string ID { get; set; }
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketVideo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
/// </summary>
|
||||
/// <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,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
|
||||
@@ -5,9 +5,7 @@ using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace PocketSharp
|
||||
@@ -22,6 +20,11 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
protected readonly HttpClient _restClient;
|
||||
|
||||
/// <summary>
|
||||
/// Caches HTTP headers from last response
|
||||
/// </summary>
|
||||
private HttpResponseHeaders lastHeaders;
|
||||
|
||||
/// <summary>
|
||||
/// The base URL for the Pocket API
|
||||
/// </summary>
|
||||
@@ -35,7 +38,7 @@ namespace PocketSharp
|
||||
/// <summary>
|
||||
/// callback URL for API calls
|
||||
/// </summary>
|
||||
protected string CallbackUri { get; set; }
|
||||
public string CallbackUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Accessor for the Pocket API key
|
||||
@@ -54,6 +57,7 @@ namespace PocketSharp
|
||||
public string AccessCode { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PocketClient"/> class.
|
||||
/// </summary>
|
||||
@@ -112,6 +116,7 @@ namespace PocketSharp
|
||||
|
||||
// every single Pocket API endpoint requires HTTP POST data
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, method);
|
||||
HttpResponseMessage response = null;
|
||||
|
||||
if (parameters == null)
|
||||
{
|
||||
@@ -131,11 +136,21 @@ namespace PocketSharp
|
||||
request.Content = new FormUrlEncodedContent(parameters);
|
||||
|
||||
// make async request
|
||||
HttpResponseMessage response = await _restClient.SendAsync(request);
|
||||
try
|
||||
{
|
||||
response = await _restClient.SendAsync(request);
|
||||
}
|
||||
catch (HttpRequestException exc)
|
||||
{
|
||||
throw new PocketException(exc.Message, exc);
|
||||
}
|
||||
|
||||
// validate HTTP response
|
||||
ValidateResponse(response);
|
||||
|
||||
// cache headers
|
||||
lastHeaders = response.Headers;
|
||||
|
||||
// read response
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
@@ -259,6 +274,11 @@ namespace PocketSharp
|
||||
{
|
||||
string result = null;
|
||||
|
||||
if (headers == null || String.IsNullOrEmpty(key))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
{
|
||||
if (header.Key == key)
|
||||
@@ -267,6 +287,7 @@ namespace PocketSharp
|
||||
headerEnumerator.MoveNext();
|
||||
|
||||
result = headerEnumerator.Current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
<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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -36,19 +37,22 @@
|
||||
</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="Models\PocketArticle.cs" />
|
||||
<Compile Include="Models\PocketLimits.cs" />
|
||||
<Compile Include="Models\PocketStatistics.cs" />
|
||||
<Compile Include="PocketException.cs" />
|
||||
<Compile Include="Utilities\PocketException.cs" />
|
||||
<Compile Include="Components\Add.cs" />
|
||||
<Compile Include="Components\Account.cs" />
|
||||
<Compile Include="Components\Modify.cs" />
|
||||
<Compile Include="Components\ModifyTags.cs" />
|
||||
<Compile Include="Components\Get.cs" />
|
||||
<Compile Include="JsonExtensions.cs" />
|
||||
<Compile Include="Utilities\JsonExtensions.cs" />
|
||||
<Compile Include="Models\Parameters\ActionParameter.cs" />
|
||||
<Compile Include="Models\Parameters\AddParameters.cs" />
|
||||
<Compile Include="Models\Parameters\ModifyParameters.cs" />
|
||||
@@ -59,15 +63,16 @@
|
||||
<Compile Include="Models\PocketItem.cs" />
|
||||
<Compile Include="Models\PocketTag.cs" />
|
||||
<Compile Include="Models\PocketVideo.cs" />
|
||||
<Compile Include="Models\Response\AccessCode.cs" />
|
||||
<Compile Include="Models\PocketUser.cs" />
|
||||
<Compile Include="Models\Response\Add.cs" />
|
||||
<Compile Include="Models\Response\Modify.cs" />
|
||||
<Compile Include="Models\Response\RequestCode.cs" />
|
||||
<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.cs" />
|
||||
<Compile Include="Utilities\Utilities.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Threading.Tasks">
|
||||
@@ -77,7 +82,11 @@
|
||||
<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.6\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll</HintPath>
|
||||
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PropertyChanged">
|
||||
<HintPath>..\packages\PropertyChanged.Fody.1.41.0.0\Lib\portable-net4+sl4+wp7+win8+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>
|
||||
@@ -98,6 +107,15 @@
|
||||
<HintPath>..\packages\Microsoft.Bcl.1.1.3\lib\portable-net40+sl4+win8+wp71\System.Threading.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="FodyWeavers.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PortablePorts\NReadability\NReadability.csproj">
|
||||
<Project>{14c3ee6a-54a4-4a37-8b56-d52a3802f1c2}</Project>
|
||||
<Name>NReadability</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
@@ -111,6 +129,7 @@
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
|
||||
<Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.10\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
|
||||
</Target>
|
||||
<Import Project="Fody.targets" />
|
||||
<!-- 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">
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
<owners>$author$</owners>
|
||||
<licenseUrl>https://raw.github.com/ceee/PocketSharp/master/LICENSE-MIT</licenseUrl>
|
||||
<projectUrl>http://pocketsharp.frontendplay.com</projectUrl>
|
||||
<iconUrl>http://pocketsharp.frontendplay.com/Assets/Images/pocketsharp.png</iconUrl>
|
||||
<iconUrl>https://raw.github.com/ceee/PocketSharp/master/pocketsharp.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>PocketSharp is a .NET class library, that integrates the Pocket API v3</description>
|
||||
<description>PocketSharp is a C#.NET portable class library that integrates the Pocket API v3.</description>
|
||||
<language>en-US</language>
|
||||
<releaseNotes>
|
||||
<![CDATA[
|
||||
For full release notes see https://github.com/ceee/PocketSharp#release-history
|
||||
]]>
|
||||
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 RestSharp</tags>
|
||||
<tags>PocketAPI Pocket API PocketSharp Tobias Klika cee NReadability Reader Article SDK Pockem</tags>
|
||||
</metadata>
|
||||
</package>
|
||||
|
||||
@@ -7,11 +7,11 @@ using System.Runtime.InteropServices;
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("PocketSharp")]
|
||||
[assembly: AssemblyDescription("PocketSharp is a .NET class library, that integrates the Pocket API v3")]
|
||||
[assembly: AssemblyDescription("PocketSharp is a .NET class library that integrates the Pocket API v3 (support a custom Article View API)")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("cee")]
|
||||
[assembly: AssemblyProduct("PocketSharp")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyCopyright("Copyright © cee 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -25,5 +25,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.5.1")]
|
||||
[assembly: AssemblyFileVersion("1.5.1")]
|
||||
[assembly: AssemblyVersion("2.2.1")]
|
||||
[assembly: AssemblyFileVersion("2.2.1")]
|
||||
@@ -1,9 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PocketSharp.Models;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
@@ -1,8 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Fody" version="1.17.4.0" targetFramework="portable-net403+sl40+wp71+win" />
|
||||
<package id="Microsoft.Bcl" version="1.1.3" targetFramework="portable-net45+sl40+wp71+win" />
|
||||
<package id="Microsoft.Bcl.Async" version="1.0.16" targetFramework="portable-net45+sl40+wp71+win" />
|
||||
<package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="portable-net45+sl40+wp71+win" />
|
||||
<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="portable-net403+sl40+wp71+win" />
|
||||
<package id="Newtonsoft.Json" version="5.0.6" 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" />
|
||||
</packages>
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace PocketSharp.Ports.NReadability
|
||||
{
|
||||
public class AttributeTransformationInput
|
||||
{
|
||||
public string AttributeValue { get; set; }
|
||||
|
||||
public XElement Element { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?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
@@ -0,0 +1,30 @@
|
||||
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")]
|
||||
@@ -0,0 +1,82 @@
|
||||
/* 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; }
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<!-- 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 -->
|
||||
@@ -0,0 +1,241 @@
|
||||
<!-- 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
@@ -0,0 +1,30 @@
|
||||
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
@@ -0,0 +1,52 @@
|
||||
<?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>{9112414C-E2D1-43BA-A298-A89F77D94332}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PocketSharp.Ports.SgmlReader</RootNamespace>
|
||||
<AssemblyName>PocketSharp.Ports.SgmlReader</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>TRACE;DEBUG;PORTABLE</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;PORTABLE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||
<EmbeddedResource Include="Html.dtd" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SgmlParser.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SgmlReader.cs" />
|
||||
</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>
|
||||
@@ -0,0 +1,194 @@
|
||||
<!-- 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.
|
||||
-->
|
||||
<!-- Character entity set. Typical invocation:
|
||||
<!ENTITY % HTMLlat1 PUBLIC
|
||||
"-//W3C//ENTITIES Latin 1//EN//HTML">
|
||||
%HTMLlat1;
|
||||
-->
|
||||
|
||||
<!ENTITY nbsp CDATA " " -- no-break space = non-breaking space,
|
||||
U+00A0 ISOnum -->
|
||||
<!ENTITY iexcl CDATA "¡" -- inverted exclamation mark, U+00A1 ISOnum -->
|
||||
<!ENTITY cent CDATA "¢" -- cent sign, U+00A2 ISOnum -->
|
||||
<!ENTITY pound CDATA "£" -- pound sign, U+00A3 ISOnum -->
|
||||
<!ENTITY curren CDATA "¤" -- currency sign, U+00A4 ISOnum -->
|
||||
<!ENTITY yen CDATA "¥" -- yen sign = yuan sign, U+00A5 ISOnum -->
|
||||
<!ENTITY brvbar CDATA "¦" -- broken bar = broken vertical bar,
|
||||
U+00A6 ISOnum -->
|
||||
<!ENTITY sect CDATA "§" -- section sign, U+00A7 ISOnum -->
|
||||
<!ENTITY uml CDATA "¨" -- diaeresis = spacing diaeresis,
|
||||
U+00A8 ISOdia -->
|
||||
<!ENTITY copy CDATA "©" -- copyright sign, U+00A9 ISOnum -->
|
||||
<!ENTITY ordf CDATA "ª" -- feminine ordinal indicator, U+00AA ISOnum -->
|
||||
<!ENTITY laquo CDATA "«" -- left-pointing double angle quotation mark
|
||||
= left pointing guillemet, U+00AB ISOnum -->
|
||||
<!ENTITY not CDATA "¬" -- not sign, U+00AC ISOnum -->
|
||||
<!ENTITY shy CDATA "­" -- soft hyphen = discretionary hyphen,
|
||||
U+00AD ISOnum -->
|
||||
<!ENTITY reg CDATA "®" -- registered sign = registered trade mark sign,
|
||||
U+00AE ISOnum -->
|
||||
<!ENTITY macr CDATA "¯" -- macron = spacing macron = overline
|
||||
= APL overbar, U+00AF ISOdia -->
|
||||
<!ENTITY deg CDATA "°" -- degree sign, U+00B0 ISOnum -->
|
||||
<!ENTITY plusmn CDATA "±" -- plus-minus sign = plus-or-minus sign,
|
||||
U+00B1 ISOnum -->
|
||||
<!ENTITY sup2 CDATA "²" -- superscript two = superscript digit two
|
||||
= squared, U+00B2 ISOnum -->
|
||||
<!ENTITY sup3 CDATA "³" -- superscript three = superscript digit three
|
||||
= cubed, U+00B3 ISOnum -->
|
||||
<!ENTITY acute CDATA "´" -- acute accent = spacing acute,
|
||||
U+00B4 ISOdia -->
|
||||
<!ENTITY micro CDATA "µ" -- micro sign, U+00B5 ISOnum -->
|
||||
<!ENTITY para CDATA "¶" -- pilcrow sign = paragraph sign,
|
||||
U+00B6 ISOnum -->
|
||||
<!ENTITY middot CDATA "·" -- middle dot = Georgian comma
|
||||
= Greek middle dot, U+00B7 ISOnum -->
|
||||
<!ENTITY cedil CDATA "¸" -- cedilla = spacing cedilla, U+00B8 ISOdia -->
|
||||
<!ENTITY sup1 CDATA "¹" -- superscript one = superscript digit one,
|
||||
U+00B9 ISOnum -->
|
||||
<!ENTITY ordm CDATA "º" -- masculine ordinal indicator,
|
||||
U+00BA ISOnum -->
|
||||
<!ENTITY raquo CDATA "»" -- right-pointing double angle quotation mark
|
||||
= right pointing guillemet, U+00BB ISOnum -->
|
||||
<!ENTITY frac14 CDATA "¼" -- vulgar fraction one quarter
|
||||
= fraction one quarter, U+00BC ISOnum -->
|
||||
<!ENTITY frac12 CDATA "½" -- vulgar fraction one half
|
||||
= fraction one half, U+00BD ISOnum -->
|
||||
<!ENTITY frac34 CDATA "¾" -- vulgar fraction three quarters
|
||||
= fraction three quarters, U+00BE ISOnum -->
|
||||
<!ENTITY iquest CDATA "¿" -- inverted question mark
|
||||
= turned question mark, U+00BF ISOnum -->
|
||||
<!ENTITY Agrave CDATA "À" -- latin capital letter A with grave
|
||||
= latin capital letter A grave,
|
||||
U+00C0 ISOlat1 -->
|
||||
<!ENTITY Aacute CDATA "Á" -- latin capital letter A with acute,
|
||||
U+00C1 ISOlat1 -->
|
||||
<!ENTITY Acirc CDATA "Â" -- latin capital letter A with circumflex,
|
||||
U+00C2 ISOlat1 -->
|
||||
<!ENTITY Atilde CDATA "Ã" -- latin capital letter A with tilde,
|
||||
U+00C3 ISOlat1 -->
|
||||
<!ENTITY Auml CDATA "Ä" -- latin capital letter A with diaeresis,
|
||||
U+00C4 ISOlat1 -->
|
||||
<!ENTITY Aring CDATA "Å" -- latin capital letter A with ring above
|
||||
= latin capital letter A ring,
|
||||
U+00C5 ISOlat1 -->
|
||||
<!ENTITY AElig CDATA "Æ" -- latin capital letter AE
|
||||
= latin capital ligature AE,
|
||||
U+00C6 ISOlat1 -->
|
||||
<!ENTITY Ccedil CDATA "Ç" -- latin capital letter C with cedilla,
|
||||
U+00C7 ISOlat1 -->
|
||||
<!ENTITY Egrave CDATA "È" -- latin capital letter E with grave,
|
||||
U+00C8 ISOlat1 -->
|
||||
<!ENTITY Eacute CDATA "É" -- latin capital letter E with acute,
|
||||
U+00C9 ISOlat1 -->
|
||||
<!ENTITY Ecirc CDATA "Ê" -- latin capital letter E with circumflex,
|
||||
U+00CA ISOlat1 -->
|
||||
<!ENTITY Euml CDATA "Ë" -- latin capital letter E with diaeresis,
|
||||
U+00CB ISOlat1 -->
|
||||
<!ENTITY Igrave CDATA "Ì" -- latin capital letter I with grave,
|
||||
U+00CC ISOlat1 -->
|
||||
<!ENTITY Iacute CDATA "Í" -- latin capital letter I with acute,
|
||||
U+00CD ISOlat1 -->
|
||||
<!ENTITY Icirc CDATA "Î" -- latin capital letter I with circumflex,
|
||||
U+00CE ISOlat1 -->
|
||||
<!ENTITY Iuml CDATA "Ï" -- latin capital letter I with diaeresis,
|
||||
U+00CF ISOlat1 -->
|
||||
<!ENTITY ETH CDATA "Ð" -- latin capital letter ETH, U+00D0 ISOlat1 -->
|
||||
<!ENTITY Ntilde CDATA "Ñ" -- latin capital letter N with tilde,
|
||||
U+00D1 ISOlat1 -->
|
||||
<!ENTITY Ograve CDATA "Ò" -- latin capital letter O with grave,
|
||||
U+00D2 ISOlat1 -->
|
||||
<!ENTITY Oacute CDATA "Ó" -- latin capital letter O with acute,
|
||||
U+00D3 ISOlat1 -->
|
||||
<!ENTITY Ocirc CDATA "Ô" -- latin capital letter O with circumflex,
|
||||
U+00D4 ISOlat1 -->
|
||||
<!ENTITY Otilde CDATA "Õ" -- latin capital letter O with tilde,
|
||||
U+00D5 ISOlat1 -->
|
||||
<!ENTITY Ouml CDATA "Ö" -- latin capital letter O with diaeresis,
|
||||
U+00D6 ISOlat1 -->
|
||||
<!ENTITY times CDATA "×" -- multiplication sign, U+00D7 ISOnum -->
|
||||
<!ENTITY Oslash CDATA "Ø" -- latin capital letter O with stroke
|
||||
= latin capital letter O slash,
|
||||
U+00D8 ISOlat1 -->
|
||||
<!ENTITY Ugrave CDATA "Ù" -- latin capital letter U with grave,
|
||||
U+00D9 ISOlat1 -->
|
||||
<!ENTITY Uacute CDATA "Ú" -- latin capital letter U with acute,
|
||||
U+00DA ISOlat1 -->
|
||||
<!ENTITY Ucirc CDATA "Û" -- latin capital letter U with circumflex,
|
||||
U+00DB ISOlat1 -->
|
||||
<!ENTITY Uuml CDATA "Ü" -- latin capital letter U with diaeresis,
|
||||
U+00DC ISOlat1 -->
|
||||
<!ENTITY Yacute CDATA "Ý" -- latin capital letter Y with acute,
|
||||
U+00DD ISOlat1 -->
|
||||
<!ENTITY THORN CDATA "Þ" -- latin capital letter THORN,
|
||||
U+00DE ISOlat1 -->
|
||||
<!ENTITY szlig CDATA "ß" -- latin small letter sharp s = ess-zed,
|
||||
U+00DF ISOlat1 -->
|
||||
<!ENTITY agrave CDATA "à" -- latin small letter a with grave
|
||||
= latin small letter a grave,
|
||||
U+00E0 ISOlat1 -->
|
||||
<!ENTITY aacute CDATA "á" -- latin small letter a with acute,
|
||||
U+00E1 ISOlat1 -->
|
||||
<!ENTITY acirc CDATA "â" -- latin small letter a with circumflex,
|
||||
U+00E2 ISOlat1 -->
|
||||
<!ENTITY atilde CDATA "ã" -- latin small letter a with tilde,
|
||||
U+00E3 ISOlat1 -->
|
||||
<!ENTITY auml CDATA "ä" -- latin small letter a with diaeresis,
|
||||
U+00E4 ISOlat1 -->
|
||||
<!ENTITY aring CDATA "å" -- latin small letter a with ring above
|
||||
= latin small letter a ring,
|
||||
U+00E5 ISOlat1 -->
|
||||
<!ENTITY aelig CDATA "æ" -- latin small letter ae
|
||||
= latin small ligature ae, U+00E6 ISOlat1 -->
|
||||
<!ENTITY ccedil CDATA "ç" -- latin small letter c with cedilla,
|
||||
U+00E7 ISOlat1 -->
|
||||
<!ENTITY egrave CDATA "è" -- latin small letter e with grave,
|
||||
U+00E8 ISOlat1 -->
|
||||
<!ENTITY eacute CDATA "é" -- latin small letter e with acute,
|
||||
U+00E9 ISOlat1 -->
|
||||
<!ENTITY ecirc CDATA "ê" -- latin small letter e with circumflex,
|
||||
U+00EA ISOlat1 -->
|
||||
<!ENTITY euml CDATA "ë" -- latin small letter e with diaeresis,
|
||||
U+00EB ISOlat1 -->
|
||||
<!ENTITY igrave CDATA "ì" -- latin small letter i with grave,
|
||||
U+00EC ISOlat1 -->
|
||||
<!ENTITY iacute CDATA "í" -- latin small letter i with acute,
|
||||
U+00ED ISOlat1 -->
|
||||
<!ENTITY icirc CDATA "î" -- latin small letter i with circumflex,
|
||||
U+00EE ISOlat1 -->
|
||||
<!ENTITY iuml CDATA "ï" -- latin small letter i with diaeresis,
|
||||
U+00EF ISOlat1 -->
|
||||
<!ENTITY eth CDATA "ð" -- latin small letter eth, U+00F0 ISOlat1 -->
|
||||
<!ENTITY ntilde CDATA "ñ" -- latin small letter n with tilde,
|
||||
U+00F1 ISOlat1 -->
|
||||
<!ENTITY ograve CDATA "ò" -- latin small letter o with grave,
|
||||
U+00F2 ISOlat1 -->
|
||||
<!ENTITY oacute CDATA "ó" -- latin small letter o with acute,
|
||||
U+00F3 ISOlat1 -->
|
||||
<!ENTITY ocirc CDATA "ô" -- latin small letter o with circumflex,
|
||||
U+00F4 ISOlat1 -->
|
||||
<!ENTITY otilde CDATA "õ" -- latin small letter o with tilde,
|
||||
U+00F5 ISOlat1 -->
|
||||
<!ENTITY ouml CDATA "ö" -- latin small letter o with diaeresis,
|
||||
U+00F6 ISOlat1 -->
|
||||
<!ENTITY divide CDATA "÷" -- division sign, U+00F7 ISOnum -->
|
||||
<!ENTITY oslash CDATA "ø" -- latin small letter o with stroke,
|
||||
= latin small letter o slash,
|
||||
U+00F8 ISOlat1 -->
|
||||
<!ENTITY ugrave CDATA "ù" -- latin small letter u with grave,
|
||||
U+00F9 ISOlat1 -->
|
||||
<!ENTITY uacute CDATA "ú" -- latin small letter u with acute,
|
||||
U+00FA ISOlat1 -->
|
||||
<!ENTITY ucirc CDATA "û" -- latin small letter u with circumflex,
|
||||
U+00FB ISOlat1 -->
|
||||
<!ENTITY uuml CDATA "ü" -- latin small letter u with diaeresis,
|
||||
U+00FC ISOlat1 -->
|
||||
<!ENTITY yacute CDATA "ý" -- latin small letter y with acute,
|
||||
U+00FD ISOlat1 -->
|
||||
<!ENTITY thorn CDATA "þ" -- latin small letter thorn,
|
||||
U+00FE ISOlat1 -->
|
||||
<!ENTITY yuml CDATA "ÿ" -- latin small letter y with diaeresis,
|
||||
U+00FF ISOlat1 -->
|
||||
@@ -1,71 +1,28 @@
|
||||

|
||||
|
||||
**PocketSharp** is a C#.NET class library, that integrates the [Pocket API v3](http://getpocket.com/developer).
|
||||
**PocketSharp** is a C#.NET portable class library that integrates the [Pocket API v3](http://getpocket.com/developer).
|
||||
|
||||
**Website:** [pocketsharp.frontendplay.com](http://pocketsharp.frontendplay.com/)
|
||||
<br>
|
||||
**NuGet:** [nuget.org/packages/PocketSharp](https://www.nuget.org/packages/PocketSharp/)
|
||||
|
||||
|
||||
## Install using NuGet
|
||||
## Install using [NuGet](https://www.nuget.org/packages/PocketSharp/)
|
||||
|
||||
```
|
||||
Install-Package PocketSharp
|
||||
```
|
||||
|
||||
## Components
|
||||
## Documentation
|
||||
|
||||
- [Get](#get) - Retrieve and search for items
|
||||
- [Modify](#modify) - Modify items and its tags
|
||||
- [Add](#add) - Add new items
|
||||
- [Authentication](#account-authentication) - Authenticate users
|
||||
- [Registration](#account-registration) - Register new users
|
||||
- [Statistics](#statistics) - Retrieve account statistics
|
||||
See [wiki](https://github.com/ceee/PocketSharp/wiki)
|
||||
|
||||
## Supported platforms
|
||||
---
|
||||
|
||||
PocketSharp is a **Portable Class Library** (since 1.0.0), therefore it's compatible with multiple platforms:
|
||||
## Usage Example:
|
||||
|
||||
- **.NET** >= 4.0.3 (including WPF)
|
||||
- **Silverlight** >= 4
|
||||
- **Windows Phone** >= 7.5
|
||||
- **Windows Store**
|
||||
|
||||
You can find examples for Silverlight 5, WP8 and WPF in the `PocketSharp.Examples` ([@github](https://github.com/ceee/PocketSharp/tree/master/PocketSharp.Examples)) folder.
|
||||
|
||||
## Async Support
|
||||
|
||||
All public methods, which communicate with the Pocket servers are asynchronous. So they should be called with the preceding `await` keyword, and the encapsulated method marked with `async`.
|
||||
|
||||
_In PocketSharp versions < 1.0.0 all methods lacked async support and were blocking._
|
||||
|
||||
## What's next?
|
||||
|
||||
In the next version I will implement the **Article View API**, but not the official by Pocket, because it is not available for everyone and doesn't satisfy my needs.
|
||||
|
||||
Maybe I will try to add behavior to PocketItems as a next step, for example: `myPocketItem.Archive();`
|
||||
|
||||
## Usage Example
|
||||
|
||||
Request a [Consumer Key on Pocket.](http://getpocket.com/developer/apps/)
|
||||
|
||||
Include the PocketSharp namespace and it's associated models (you will need them later):
|
||||
A search for items containing `CSS`:
|
||||
|
||||
```csharp
|
||||
using PocketSharp;
|
||||
using PocketSharp.Models;
|
||||
```
|
||||
PocketClient client = new PocketClient("[YOUR_CONSUMER_KEY]", "[YOUR_ACCESS_CODE]");
|
||||
|
||||
Initialize PocketClient with:
|
||||
List<PocketItem> items = await client.Search("css");
|
||||
|
||||
```csharp
|
||||
PocketClient _client = new PocketClient("[YOUR_CONSUMER_KEY]", "[YOUR_ACCESS_CODE]");
|
||||
```
|
||||
|
||||
Do a simple request - e.g. a search for `CSS`:
|
||||
|
||||
```csharp
|
||||
var items = await _client.Search("css");
|
||||
items.ForEach(
|
||||
item => Debug.WriteLine(item.ID + " | " + item.Title)
|
||||
);
|
||||
@@ -79,293 +36,40 @@ Which will output:
|
||||
343693149 | CSS3 Transitions - Thank God We Have A Specification!
|
||||
...
|
||||
|
||||
## Create an instance
|
||||
|
||||
Constructor:
|
||||
|
||||
```csharp
|
||||
PocketClient(string consumerKey, string accessCode = null, Uri callbackUri = null)
|
||||
```
|
||||
|
||||
`consumerKey`: The API key
|
||||
<br>
|
||||
`accessCode`: Provide an access code if the user is already authenticated
|
||||
<br>
|
||||
`callbackUri`: The callback URL is called by Pocket after authentication
|
||||
|
||||
Example:
|
||||
|
||||
```csharp
|
||||
PocketClient _client = new PocketClient(
|
||||
consumerKey: "123498237423498723498723",
|
||||
callbackUri: new Uri("http://ceecore.com"),
|
||||
accessCode: "097809-oi987-izi8-jk98-oiuu89"
|
||||
);
|
||||
```
|
||||
|
||||
You can change the _Access Code_ after initialization:
|
||||
|
||||
```csharp
|
||||
_client.AccessCode = "[YOU_ACCESS_CODE]";
|
||||
```
|
||||
|
||||
**Before authentication** you will need to provide the `callbackUri` for authentication requests.
|
||||
<br>
|
||||
**After authentication** you will need to provide the `accessCode`.
|
||||
|
||||
## Account Authentication
|
||||
|
||||
In order to communicate with a Pocket User, you will need a consumer key (which is generated by [creating a new application on Pocket](http://getpocket.com/developer/apps/)) and an **Access Code**.
|
||||
|
||||
The authentication is a 3-step process:
|
||||
|
||||
#### 1) Generate authentication URI
|
||||
|
||||
Receive the **request code** and **authentication URI** from the library by calling `string GetRequestCode()`:
|
||||
|
||||
```csharp
|
||||
string requestCode = await _client.GetRequestCode();
|
||||
// 0f453f2d-1605-8584-28fd-39af8e
|
||||
Uri authenticationUri = _client.GenerateAuthenticationUri();
|
||||
// https://getpocket.com/auth/authorize?request_token=0f453f2d-1605-8584-28fd-39af8e&redirect_uri=http%253a%252f%252fceecore.com
|
||||
```
|
||||
|
||||
The _request code_ is stored internally, but you can also provide it as param in `GenerateAuthenticationUri(string requestCode = null)`.
|
||||
|
||||
#### 2) Redirect to Pocket
|
||||
Next you need to redirect the user to the `authenticationUri`, which displays a prompt to grant permissions for the application (see image). After the user granted or denied, he/she is redirected to the `callbackUri`.
|
||||
|
||||

|
||||
|
||||
#### 3) Get Access Code
|
||||
Call `Task<string> GetAccessCode(string requestCode = null)`
|
||||
|
||||
```csharp
|
||||
string accessCode = await _client.GetAccessCode();
|
||||
// fa8bfc16-69b3-4d22-7db7-84a58d
|
||||
```
|
||||
|
||||
Again, the received _access code_ is stored internally.
|
||||
Note that `GetAccessCode` can only be called with an existing _request code_. If you need to re-authenticate a user, start again with Step 1).
|
||||
|
||||
#### Important
|
||||
|
||||
**Be sure to permanently store the _Access Code_ for your user.**
|
||||
<br>
|
||||
Without it you would always have to redo the authentication process.
|
||||
|
||||
## Account Registration
|
||||
|
||||
The `RegisterAccount` method exists in Pocket API v3, but is currently undocumented.
|
||||
<br>The user cannot authenticate directly after registration, as the account has to be activated via an opt-in link, which is sent to the e-mail address.
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.RegisterAccount("myUsername", "me@mymail.com", "mypassword");
|
||||
```
|
||||
|
||||
After registration you have to remind the user to check his/her mail account.
|
||||
|
||||
## Get
|
||||
|
||||
Get list of all items:
|
||||
|
||||
```csharp
|
||||
List<PocketItem> items = await _client.Get();
|
||||
// equivalent to: await _client.Get(RetrieveFilter.All)
|
||||
```
|
||||
|
||||
Get a list with specific parameters (explanation in the [Pocket Docs](http://getpocket.com/developer/docs/v3/retrieve)):
|
||||
|
||||
```csharp
|
||||
List<PocketItem> items = await _client.Get(
|
||||
State? state = null,
|
||||
bool? favorite = null,
|
||||
string tag = null,
|
||||
ContentType? contentType = null,
|
||||
Sort? sort = null,
|
||||
string search = null,
|
||||
string domain = null,
|
||||
DateTime? since = null,
|
||||
int? count = null,
|
||||
int? offset = null
|
||||
);
|
||||
```
|
||||
|
||||
It's best to use parameters as _named parameters_, to avoid typing `null` values:
|
||||
|
||||
```csharp
|
||||
List<PocketItem> items = await _client.Get(count: 10, offset: 20, sort: Sort.oldest);
|
||||
```
|
||||
|
||||
Get item by ID:
|
||||
|
||||
```csharp
|
||||
PocketItem item = await _client.Get(1298198);
|
||||
```
|
||||
|
||||
Find items by a tag:
|
||||
|
||||
```csharp
|
||||
List<PocketItem> items = await _client.SearchByTag("tutorial");
|
||||
```
|
||||
|
||||
Find items by a search string.
|
||||
<br>PocketSharp uses an internal search, which is significantly faster than the Search API by Pocket.
|
||||
|
||||
```csharp
|
||||
List<PocketItem> items = await _client.Search("css");
|
||||
```
|
||||
|
||||
Find items by a search string by already available items:
|
||||
|
||||
```csharp
|
||||
List<PocketItem> items = await _client.Search(myPocketItemList, "css");
|
||||
```
|
||||
|
||||
Get all tags:
|
||||
|
||||
```csharp
|
||||
List<PocketTag> items = await _client.GetTags();
|
||||
```
|
||||
|
||||
Get a filtered list:
|
||||
|
||||
```csharp
|
||||
List<PocketItem> items = await _client.Get(RetrieveFilter.Favorite);
|
||||
// returns favorites only
|
||||
```
|
||||
|
||||
The RetrieveFilter Enum is specified as follows:
|
||||
|
||||
```csharp
|
||||
enum RetrieveFilter { All, Unread, Archive, Favorite, Article, Video, Image }
|
||||
```
|
||||
|
||||
## Add
|
||||
|
||||
Adds a new item to your pocket list.
|
||||
Accepts four parameters, with `uri` being required.
|
||||
|
||||
```csharp
|
||||
Task<PocketItem> Add(Uri uri, string[] tags = null, string title = null, string tweetID = null)
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```csharp
|
||||
PocketItem newItem = await _client.Add(
|
||||
new Uri("http://www.neowin.net/news/full-build-2013-conference-sessions-listing-revealed"),
|
||||
new string[] { "microsoft", "neowin", "build" }
|
||||
);
|
||||
```
|
||||
|
||||
The title can be included for cases where an item does not have a title, which is typical for image or PDF URLs. If Pocket detects a title from the content of the page, this parameter will be ignored.
|
||||
|
||||
If you are adding Pocket support to a Twitter client, please send along a reference to the tweet status id (with the tweetID). This allows Pocket to show the original tweet alongside the article.
|
||||
|
||||
## Modify
|
||||
|
||||
All Modify methods accept either the itemID (as int) or a `PocketItem` as parameter.
|
||||
|
||||
Archive the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.Archive(myPocketItem);
|
||||
```
|
||||
|
||||
Un-archive the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.Unarchive(myPocketItem);
|
||||
```
|
||||
|
||||
Favorites the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.Favorite(myPocketItem);
|
||||
```
|
||||
|
||||
Un-favorites the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.Unfavorite(myPocketItem);
|
||||
```
|
||||
|
||||
Deletes the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.Delete(myPocketItem);
|
||||
```
|
||||
|
||||
#### Modify tags
|
||||
|
||||
Add tags to the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.AddTags(myPocketItem, new string[] { "css", "2013" });
|
||||
```
|
||||
|
||||
Remove tags from the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.RemoveTags(myPocketItem, new string[] { "css", "2013" });
|
||||
```
|
||||
|
||||
Remove all tags from the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.RemoveTags(myPocketItem);
|
||||
```
|
||||
|
||||
Replaces all existing tags with new ones for the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.ReplaceTags(myPocketItem, new string[] { "css", "2013" });
|
||||
```
|
||||
|
||||
Renames a tag for the specified item:
|
||||
|
||||
```csharp
|
||||
bool isSuccess = await _client.RenameTag(myPocketItem, "oldTagName", "newTagName");
|
||||
```
|
||||
|
||||
## Statistics
|
||||
|
||||
The Pocket API supports retrieval of a simple statistics object.
|
||||
|
||||
```csharp
|
||||
PocketStatistics statistics = await client.Statistics();
|
||||
// PocketStatistics: [CountAll], [CountRead], [CountUnread]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Release History
|
||||
|
||||
- **1.5.1** (2013-09-30) `RetrieveFilter.All` didn't work; improve search speed
|
||||
- **1.5.0** (2013-09-28) add statistics and registration API
|
||||
- **1.4.0** (2013-09-21) rename `Retrieve` to `Get` + update IntelliSense documentation + add `GetTags` method
|
||||
- **1.3.0** (2013-09-19) get Item by ID + tag modification bugfixes
|
||||
- **1.2.1** (2013-09-18) correct parameter conversion for DateTime and Boolean
|
||||
- **1.2.0** (2013-09-17) simplified retrieve methods
|
||||
- **1.1.0** (2013-09-17) fix modification requests
|
||||
- **1.0.0** (2013-09-15) convert to PCL & implement async
|
||||
- **0.3.2** (2013-08-16) tag modification fixed and full retrieval of items for Retrieve method
|
||||
- **0.3.1** (2013-07-07) authentication fixes
|
||||
- **0.3.0** (2013-07-02) update authentication process
|
||||
- **0.2.0** (2013-06-27) add, modify item & modify tags
|
||||
- **0.1.0** (2013-06-26) authentication & retrieve functionality
|
||||
## Supported platforms
|
||||
|
||||
PocketSharp is a **Portable Class Library** (since 1.0.0), therefore it's compatible with multiple platforms:
|
||||
|
||||
- **.NET** >= 4.5 (including WPF)
|
||||
- **Silverlight** >= 4
|
||||
- **Windows Phone** >= 7.5
|
||||
- **Windows Store**
|
||||
|
||||
You can find examples for Silverlight 5, WP8 and WPF in the `PocketSharp.Examples` ([@github](https://github.com/ceee/PocketSharp/tree/master/PocketSharp.Examples)) folder.
|
||||
|
||||
## What's next?
|
||||
|
||||
- `cancellationToken` support for all methods
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [Microsoft.Bcl.Async](https://www.nuget.org/packages/Microsoft.Bcl.Async/)
|
||||
- [Microsoft.Net.Http](https://www.nuget.org/packages/Microsoft.Net.Http/)
|
||||
- [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/)
|
||||
- [PropertyChanged.Fody](https://github.com/Fody/PropertyChanged)
|
||||
|
||||
## Forked Dependencies
|
||||
|
||||
- [NReadability](https://github.com/marek-stoj/NReadability) - converted to a PCL with minor adaptations
|
||||
- [SgmlReader](https://github.com/MindTouch/SGMLReader) - converted to a PCL
|
||||
|
||||
## Contributors
|
||||
| [](http://twitter.com/artistandsocial "Follow @artistandsocial on Twitter") |
|
||||
|---|
|
||||
| [Tobias Klika @ceee](https://github.com/ceee) |
|
||||
| [](https://github.com/ceee "Tobias Klika") | [](https://github.com/ScottIsAFool "Scott Lovegrove") |
|
||||
|---|---|
|
||||
| [ceee](https://github.com/ceee) | [ScottIsAFool](https://github.com/ScottIsAFool) |
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
Reference in New Issue
Block a user