Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ca93bf07f | |||
| 556e8004f3 | |||
| 7cad855f9c | |||
| 366908a070 | |||
| d141c7b255 | |||
| 8531d20162 | |||
| 4f42ed719a | |||
| b46cc56362 | |||
| 500bd1c65d | |||
| a207ca7ca4 | |||
| 07c9f06f75 | |||
| a1ff132ba9 | |||
| 82896d6fb4 | |||
| 36683c7402 | |||
| 4e5a8ab096 | |||
| 47baa0fd97 |
@@ -1,3 +1,7 @@
|
||||
### 4.0.0 (2014-04-03)
|
||||
|
||||
- Support for Universal apps (dropped SL and WP7 support)
|
||||
|
||||
### 3.2.0 (2014-03-13)
|
||||
|
||||
- add raw JSON to each PocketItem (PR #22)
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.WP8.ViewModels
|
||||
{
|
||||
@@ -74,7 +75,7 @@ namespace PocketSharp.WP8.ViewModels
|
||||
|
||||
try
|
||||
{
|
||||
items = await client.Get();
|
||||
items = (await client.Get()).ToList();
|
||||
|
||||
items.ForEach(item =>
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Wpf
|
||||
{
|
||||
@@ -40,7 +41,7 @@ namespace PocketSharp.Wpf
|
||||
|
||||
try
|
||||
{
|
||||
items = await client.Get();
|
||||
items = (await client.Get()).ToList();
|
||||
|
||||
items.ForEach(item =>
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -47,7 +48,7 @@ namespace PocketSharp.Tests
|
||||
tweetID: "380051788172632065"
|
||||
);
|
||||
|
||||
List<PocketItem> items = await client.Get();
|
||||
List<PocketItem> items = (await client.Get()).ToList();
|
||||
PocketItem itemDesired = null;
|
||||
|
||||
items.ForEach(itm =>
|
||||
@@ -60,9 +61,65 @@ namespace PocketSharp.Tests
|
||||
|
||||
Assert.NotNull(itemDesired);
|
||||
Assert.Equal(itemDesired.ID, item.ID);
|
||||
Assert.Equal(itemDesired.Tags.Count, 3);
|
||||
Assert.Equal(itemDesired.Tags.Count(), 3);
|
||||
|
||||
itemsToDelete.Add(item.ID);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ItemViaActionsIsAdded()
|
||||
{
|
||||
List<PocketAction> actions = new List<PocketAction>();
|
||||
|
||||
actions.Add(new PocketAction()
|
||||
{
|
||||
Uri = new Uri("http://frontendplay.com/story/4015/string-indexer-for-text-resources-in-nancy"),
|
||||
Action = "add",
|
||||
Time = DateTime.Now
|
||||
});
|
||||
|
||||
bool success = await client.SendActions(actions);
|
||||
|
||||
Assert.True(success);
|
||||
|
||||
IEnumerable<PocketItem> items = await client.Search("in nancy");
|
||||
|
||||
Assert.NotNull(items);
|
||||
Assert.True(items.Count() > 0);
|
||||
|
||||
itemsToDelete.Add(items.First().ID);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ItemsViaActionsIsAdded()
|
||||
{
|
||||
List<PocketAction> actions = new List<PocketAction>();
|
||||
|
||||
actions.Add(new PocketAction()
|
||||
{
|
||||
Uri = new Uri("http://frontendplay.com/story/4015/string-indexer-for-text-resources-in-nancy"),
|
||||
Action = "add",
|
||||
Time = DateTime.Now
|
||||
});
|
||||
actions.Add(new PocketAction()
|
||||
{
|
||||
Uri = new Uri("http://frontendplay.com/story/4013/build-a-custom-razor-viewbase-in-nancy"),
|
||||
Action = "add",
|
||||
Time = DateTime.Now
|
||||
});
|
||||
|
||||
bool success = await client.SendActions(actions);
|
||||
|
||||
Assert.True(success);
|
||||
|
||||
IEnumerable<PocketItem> items = await client.Search("in nancy");
|
||||
|
||||
Assert.NotNull(items);
|
||||
Assert.True(items.Count() == 2);
|
||||
|
||||
itemsToDelete.AddRange(items.Select(item => item.ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -16,7 +17,7 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task AreItemsRetrieved()
|
||||
{
|
||||
List<PocketItem> items = await client.Get();
|
||||
List<PocketItem> items = (await client.Get()).ToList();
|
||||
Assert.True(items.Count > 0);
|
||||
}
|
||||
|
||||
@@ -24,7 +25,7 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task IsItemRetrievedById()
|
||||
{
|
||||
List<PocketItem> items = await client.Get();
|
||||
List<PocketItem> items = (await client.Get()).ToList();
|
||||
PocketItem item = items[0];
|
||||
PocketItem itemDuplicate = await client.Get(item.ID);
|
||||
|
||||
@@ -35,7 +36,7 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task IsItemJsonPopulated()
|
||||
{
|
||||
List<PocketItem> items = await client.Get();
|
||||
List<PocketItem> items = (await client.Get()).ToList();
|
||||
string schemaJson = @"{
|
||||
'description': 'PocketItem',
|
||||
'type': 'object'
|
||||
@@ -53,16 +54,16 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task AreFilteredItemsRetrieved()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(RetrieveFilter.Favorite);
|
||||
IEnumerable<PocketItem> items = await client.Get(RetrieveFilter.Favorite);
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task RetrieveWithMultipleFilters()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(
|
||||
IEnumerable<PocketItem> items = await client.Get(
|
||||
state: State.unread,
|
||||
tag: "pocket",
|
||||
sort: Sort.title,
|
||||
@@ -70,29 +71,29 @@ namespace PocketSharp.Tests
|
||||
count: 2
|
||||
);
|
||||
|
||||
Assert.InRange<int>(items.Count, 0, 2);
|
||||
Assert.InRange<int>(items.Count(), 0, 2);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task ItemContainsUri()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(count: 1);
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 1);
|
||||
|
||||
Assert.True(items.Count == 1);
|
||||
Assert.True(items[0].Uri.ToString().StartsWith("http"));
|
||||
Assert.True(items.Count() == 1);
|
||||
Assert.True(items.First().Uri.ToString().StartsWith("http"));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task InvalidRetrievalReturnsNoResults()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(
|
||||
IEnumerable<PocketItem> items = await client.Get(
|
||||
favorite: true,
|
||||
search: "xoiu987a#;"
|
||||
);
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
Assert.False(items.Count() > 0);
|
||||
|
||||
PocketItem item = await client.Get("99999999");
|
||||
|
||||
@@ -100,48 +101,48 @@ namespace PocketSharp.Tests
|
||||
|
||||
items = await client.Get(RetrieveFilter.Video);
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
Assert.False(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task SearchReturnsResult()
|
||||
{
|
||||
List<PocketItem> items = await client.Search("pocket");
|
||||
IEnumerable<PocketItem> items = await client.Search("pocket");
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items[0].FullTitle.ToLower().Contains("pocket"));
|
||||
Assert.True(items.Count() > 0);
|
||||
Assert.True(items.First().FullTitle.ToLower().Contains("pocket"));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task InvalidSearchReturnsNoResult()
|
||||
{
|
||||
List<PocketItem> items = await client.Search("adsüasd-opiu2;.398dfyx");
|
||||
IEnumerable<PocketItem> items = await client.Search("adsüasd-opiu2;.398dfyx");
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
Assert.False(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task RetrieveTagsReturnsResult()
|
||||
{
|
||||
List<PocketTag> items = await client.GetTags();
|
||||
IEnumerable<PocketTag> items = await client.GetTags();
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task SearchByTagsReturnsResult()
|
||||
{
|
||||
List<PocketItem> items = await client.SearchByTag("pocket");
|
||||
IEnumerable<PocketItem> items = await client.SearchByTag("pocket");
|
||||
|
||||
Assert.True(items.Count == 1);
|
||||
Assert.True(items.Count() == 1);
|
||||
|
||||
bool found = false;
|
||||
|
||||
items[0].Tags.ForEach(tag =>
|
||||
items.First().Tags.ToList().ForEach(tag =>
|
||||
{
|
||||
if (tag.Name.Contains("pocket"))
|
||||
{
|
||||
@@ -156,9 +157,9 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task InvalidSearchByTagsReturnsNoResult()
|
||||
{
|
||||
List<PocketItem> items = await client.SearchByTag("adsüasd-opiu2;.398dfyx");
|
||||
IEnumerable<PocketItem> items = await client.SearchByTag("adsüasd-opiu2;.398dfyx");
|
||||
|
||||
Assert.False(items.Count > 0);
|
||||
Assert.False(items.Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -183,10 +184,10 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task IsNewPocketItemListGeneratorWorking()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(count: 1, tag: "pocket");
|
||||
PocketItem item = items[0];
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 1, tag: "pocket");
|
||||
PocketItem item = items.First();
|
||||
|
||||
Assert.True(item.Tags.Find(i => i.Name == "pocket") != null);
|
||||
Assert.True(item.Tags.ToList().Find(i => i.Name == "pocket") != null);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,20 +196,20 @@ namespace PocketSharp.Tests
|
||||
{
|
||||
DateTime since = DateTime.UtcNow;
|
||||
|
||||
List<PocketItem> items = await client.Get(state: State.all);
|
||||
PocketItem itemToModify = items[0];
|
||||
IEnumerable<PocketItem> items = await client.Get(state: State.all);
|
||||
PocketItem itemToModify = items.First();
|
||||
|
||||
Assert.True(items.Count >= 3);
|
||||
Assert.True(items.Count() >= 3);
|
||||
|
||||
items = await client.Get(state: State.all, since: since);
|
||||
|
||||
Assert.True(items == null || items.Count == 0);
|
||||
Assert.True(items == null || items.Count() == 0);
|
||||
|
||||
await client.AddTags(itemToModify, new string[] { "pocketsharp" });
|
||||
|
||||
items = await client.Get(state: State.all, since: since);
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items.Count() > 0);
|
||||
|
||||
await client.RemoveTags(itemToModify, new string[] { "pocketsharp" });
|
||||
}
|
||||
@@ -219,20 +220,20 @@ namespace PocketSharp.Tests
|
||||
{
|
||||
DateTime since = DateTime.UtcNow;
|
||||
|
||||
List<PocketItem> items = await client.Get(state: State.all);
|
||||
PocketItem itemToModify = items[0];
|
||||
IEnumerable<PocketItem> items = await client.Get(state: State.all);
|
||||
PocketItem itemToModify = items.First();
|
||||
|
||||
Assert.True(items.Count >= 3);
|
||||
Assert.True(items.Count() >= 3);
|
||||
|
||||
items = await client.Get(state: State.all, since: since);
|
||||
|
||||
Assert.True(items == null || items.Count == 0);
|
||||
Assert.True(items == null || items.Count() == 0);
|
||||
|
||||
await client.Favorite(itemToModify);
|
||||
|
||||
items = await client.Get(state: State.all, since: since);
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items.Count() > 0);
|
||||
|
||||
await client.Unfavorite(itemToModify);
|
||||
|
||||
@@ -242,7 +243,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
items = await client.Get(state: State.all, since: since);
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items.Count() > 0);
|
||||
|
||||
await client.Unarchive(itemToModify);
|
||||
}
|
||||
@@ -255,7 +256,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
PocketItem item = await client.Add(new Uri("http://frontendplay.com"));
|
||||
|
||||
List<PocketItem> items = await client.Get(state: State.all, since: since);
|
||||
IEnumerable<PocketItem> items = await client.Get(state: State.all, since: since);
|
||||
|
||||
since = DateTime.UtcNow;
|
||||
|
||||
@@ -263,7 +264,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
items = await client.Get(state: State.all, since: since);
|
||||
|
||||
Assert.True(items.Count == 1 && items[0].IsDeleted);
|
||||
Assert.True(items.Count() == 1 && items.First().IsDeleted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -271,11 +272,11 @@ namespace PocketSharp.Tests
|
||||
{
|
||||
PocketItem item = await client.Add(new Uri("http://de.ign.com/m/feature/21608/die-20-besten-kurzfilme-des-jahres-2013?bust=1"));
|
||||
|
||||
List<PocketItem> items = await client.Get(state: State.all);
|
||||
IEnumerable<PocketItem> items = await client.Get(state: State.all);
|
||||
|
||||
Assert.NotNull(item.Uri);
|
||||
Assert.NotNull(items[0].Uri);
|
||||
Assert.Equal(item.Uri, items[0].Uri);
|
||||
Assert.NotNull(items.First().Uri);
|
||||
Assert.Equal(item.Uri, items.First().Uri);
|
||||
|
||||
itemsToDelete.Add(item.ID);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Tests
|
||||
{
|
||||
@@ -19,8 +20,8 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task CheckPreRequestAction()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(count: 1);
|
||||
PocketItem item = items[0];
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 1);
|
||||
PocketItem item = items.First();
|
||||
|
||||
await client.Favorite(item);
|
||||
await client.Unfavorite(item);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
item = await GetItemById(item.ID);
|
||||
|
||||
Assert.True(item.Tags.Count >= 2);
|
||||
Assert.True(item.Tags.Count() >= 2);
|
||||
|
||||
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "test_tag"));
|
||||
Assert.NotNull(item.Tags.Single<PocketTag>(tag => tag.Name == "test_tag2"));
|
||||
@@ -44,7 +44,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
item = await GetItemById(item.ID);
|
||||
|
||||
Assert.True(item.Tags.Count >= 2);
|
||||
Assert.True(item.Tags.Count() >= 2);
|
||||
|
||||
Assert.True(await client.RemoveTags(item));
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
item = await GetItemById(item.ID);
|
||||
|
||||
Assert.Equal(item.Tags.Count, 2);
|
||||
Assert.Equal(item.Tags.Count(), 2);
|
||||
|
||||
Assert.NotNull(item.Tags.SingleOrDefault<PocketTag>(tag => tag.Name == "test_tag"));
|
||||
Assert.NotNull(item.Tags.SingleOrDefault<PocketTag>(tag => tag.Name == "test_tag2"));
|
||||
@@ -85,7 +85,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
private async Task<PocketItem> GetItemById(string id, bool archive = false)
|
||||
{
|
||||
List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread);
|
||||
List<PocketItem> items = (await client.Get(state: archive ? State.archive : State.unread)).ToList();
|
||||
PocketItem itemDesired = null;
|
||||
|
||||
items.ForEach(itm =>
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace PocketSharp.Tests
|
||||
|
||||
private async Task<PocketItem> GetItemById(string id, bool archive = false)
|
||||
{
|
||||
List<PocketItem> items = await client.Get(state: archive ? State.archive : State.unread);
|
||||
List<PocketItem> items = (await client.Get(state: archive ? State.archive : State.unread)).ToList();
|
||||
PocketItem itemDesired = null;
|
||||
|
||||
items.ForEach(itm =>
|
||||
|
||||
@@ -30,50 +30,50 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task Are100ItemsRetrievedProperly()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(count: 100, state: State.all);
|
||||
Assert.True(items.Count == 100);
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 100, state: State.all);
|
||||
Assert.True(items.Count() == 100);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Are1000ItemsRetrievedProperly()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(count: 1000, state: State.all);
|
||||
Assert.True(items.Count == 1000);
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 1000, state: State.all);
|
||||
Assert.True(items.Count() == 1000);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Are2500ItemsRetrievedProperly()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(count: 2500, state: State.all);
|
||||
Assert.True(items.Count == 2500);
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 2500, state: State.all);
|
||||
Assert.True(items.Count() == 2500);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Are5000ItemsRetrievedProperly()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(count: 5000, state: State.all);
|
||||
Assert.True(items.Count == 5000);
|
||||
IEnumerable<PocketItem> items = await client.Get(count: 5000, state: State.all);
|
||||
Assert.True(items.Count() == 5000);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IsSearchSuccessfullyOnBigList()
|
||||
{
|
||||
List<PocketItem> items = await client.Get(search: "google");
|
||||
IEnumerable<PocketItem> items = await client.Get(search: "google");
|
||||
|
||||
Assert.True(items.Count > 0);
|
||||
Assert.True(items[0].Title.ToLower().Contains("google") || items[0].Uri.ToString().ToLower().Contains("google"));
|
||||
Assert.True(items.Count() > 0);
|
||||
Assert.True(items.First().Title.ToLower().Contains("google") || items.First().Uri.ToString().ToLower().Contains("google"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IsTagSearchSuccessfullyOnBigList()
|
||||
{
|
||||
List<PocketItem> items = await client.SearchByTag(tags[0]);
|
||||
IEnumerable<PocketItem> items = await client.SearchByTag(tags[0]);
|
||||
|
||||
Assert.True(items.Count > 1);
|
||||
Assert.True(items.Count() > 1);
|
||||
|
||||
bool found = false;
|
||||
|
||||
items[0].Tags.ForEach(tag =>
|
||||
items.First().Tags.ToList().ForEach(tag =>
|
||||
{
|
||||
if (tag.Name.Contains(tags[0]))
|
||||
{
|
||||
@@ -87,7 +87,7 @@ namespace PocketSharp.Tests
|
||||
[Fact]
|
||||
public async Task RetrieveTagsReturnsResultOnBigList()
|
||||
{
|
||||
List<PocketTag> items = await client.GetTags();
|
||||
List<PocketTag> items = (await client.GetTags()).ToList();
|
||||
|
||||
items.ForEach(tag =>
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<List<PocketItem>> Get(
|
||||
public async Task<IEnumerable<PocketItem>> Get(
|
||||
State? state = null,
|
||||
bool? favorite = null,
|
||||
string tag = null,
|
||||
@@ -58,9 +58,7 @@ namespace PocketSharp
|
||||
Offset = offset
|
||||
};
|
||||
|
||||
Retrieve response = await Request<Retrieve>("get", cancellationToken, parameters.Convert());
|
||||
|
||||
return response.Items;
|
||||
return (await Request<Retrieve>("get", cancellationToken, parameters.Convert())).Items;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,12 +72,10 @@ namespace PocketSharp
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<PocketItem> Get(string itemID, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
List<PocketItem> items = await Get(
|
||||
return (await Get(
|
||||
cancellationToken: cancellationToken,
|
||||
state: State.all
|
||||
);
|
||||
|
||||
return items.SingleOrDefault<PocketItem>(item => item.ID == itemID);
|
||||
)).SingleOrDefault<PocketItem>(item => item.ID == itemID);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +86,7 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<List<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task<IEnumerable<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
RetrieveParameters parameters = new RetrieveParameters();
|
||||
|
||||
@@ -121,9 +117,19 @@ namespace PocketSharp
|
||||
|
||||
parameters.DetailType = DetailType.complete;
|
||||
|
||||
Retrieve response = await Request<Retrieve>("get", cancellationToken, parameters.Convert());
|
||||
return (await Request<Retrieve>("get", cancellationToken, parameters.Convert())).Items;
|
||||
}
|
||||
|
||||
return response.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Converts a raw JSON response to a PocketItem list
|
||||
/// </summary>
|
||||
/// <param name="itemsJSON">The raw JSON response.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public IEnumerable<PocketItem> ConvertJsonToList(string itemsJSON)
|
||||
{
|
||||
return DeserializeJson<Retrieve>(itemsJSON).Items;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,18 +140,19 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<List<PocketTag>> GetTags(CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task<IEnumerable<PocketTag>> GetTags(CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
List<PocketItem> items = await Get(
|
||||
IEnumerable<PocketItem> items = await Get(
|
||||
cancellationToken: cancellationToken,
|
||||
state: State.all
|
||||
);
|
||||
|
||||
return items.Where(item => item.Tags != null)
|
||||
.SelectMany(item => item.Tags)
|
||||
.GroupBy(item => item.Name)
|
||||
.Select(item => item.First())
|
||||
.ToList<PocketTag>();
|
||||
return items
|
||||
.Where(item => item.Tags != null)
|
||||
.SelectMany(item => item.Tags)
|
||||
.GroupBy(item => item.Name)
|
||||
.Select(item => item.First())
|
||||
.ToList<PocketTag>();
|
||||
}
|
||||
|
||||
|
||||
@@ -156,9 +163,10 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<List<PocketItem>> SearchByTag(string tag, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task<IEnumerable<PocketItem>> SearchByTag(string tag, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return await Get(
|
||||
state: State.all,
|
||||
cancellationToken: cancellationToken,
|
||||
tag: tag
|
||||
);
|
||||
@@ -169,37 +177,52 @@ namespace PocketSharp
|
||||
/// Retrieves items which match the specified search string in title and URI
|
||||
/// </summary>
|
||||
/// <param name="searchString">The search string.</param>
|
||||
/// <param name="searchInUri">if set to <c>true</c> [search in URI].</param>
|
||||
/// <param name="tag">Filter by tag.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<List<PocketItem>> Search(string searchString, bool searchInUri = true, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task<IEnumerable<PocketItem>> Search(string searchString, string tag = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
List<PocketItem> items = await Get(RetrieveFilter.All, cancellationToken);
|
||||
return Search(items, searchString);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Finds the specified search string in title and URI for an available list of items
|
||||
/// </summary>
|
||||
/// <param name="availableItems">The available items.</param>
|
||||
/// <param name="searchString">The search string.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public List<PocketItem> Search(List<PocketItem> availableItems, string searchString)
|
||||
{
|
||||
if (searchString.Length < 2)
|
||||
if (String.IsNullOrEmpty(searchString) || searchString.Length < 2)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Search string length has to be a minimum of 2 chars");
|
||||
}
|
||||
|
||||
return availableItems.Where(item => (
|
||||
(!String.IsNullOrEmpty(item.FullTitle) && item.FullTitle.ToLower().Contains(searchString))
|
||||
|| item.Uri.ToString().ToLower().Contains(searchString)
|
||||
)).ToList();
|
||||
return await Get(
|
||||
state: State.all,
|
||||
search: searchString,
|
||||
tag: tag,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the article content from an URI
|
||||
/// WARNING:
|
||||
/// You have to pass the parseUri in the PocketClient ctor for this method to work.
|
||||
/// This is a private API and can only be used by authenticated users.
|
||||
/// </summary>
|
||||
/// <param name="tag">The article URI.</param>
|
||||
/// <param name="includeImages">Include images into content or use placeholder.</param>
|
||||
/// <param name="includeVideos">Include videos into content or use placeholder.</param>
|
||||
/// <param name="forceRefresh">Force refresh of the content (don't use cache).</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<PocketArticle> GetArticle(Uri uri, bool includeImages = true, bool includeVideos = true, bool forceRefresh = false, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
Dictionary<string, string> parameters = new Dictionary<string, string>()
|
||||
{
|
||||
{ "url", uri.OriginalString },
|
||||
{ "images", includeImages ? "1" : "0" },
|
||||
{ "videos", includeVideos ? "1" : "0" },
|
||||
{ "refresh", forceRefresh ? "1" : "0" },
|
||||
{ "output", "json" }
|
||||
};
|
||||
|
||||
return await Request<PocketArticle>("", cancellationToken, parameters, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using PocketSharp.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -18,7 +19,7 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
public async Task<bool> SendActions(List<PocketAction> actions, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task<bool> SendActions(IEnumerable<PocketAction> actions, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return await Send(actions, cancellationToken);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
Task<List<PocketItem>> Get(
|
||||
Task<IEnumerable<PocketItem>> Get(
|
||||
State? state = null,
|
||||
bool? favorite = null,
|
||||
string tag = null,
|
||||
@@ -158,7 +158,15 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
Task<List<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<IEnumerable<PocketItem>> Get(RetrieveFilter filter, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Converts a raw JSON response to a PocketItem list
|
||||
/// </summary>
|
||||
/// <param name="itemsJSON">The raw JSON response.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
IEnumerable<PocketItem> ConvertJsonToList(string itemsJSON);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all available tags.
|
||||
@@ -167,7 +175,7 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
Task<List<PocketTag>> GetTags(CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<IEnumerable<PocketTag>> GetTags(CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves items by tag
|
||||
@@ -176,28 +184,33 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
Task<List<PocketItem>> SearchByTag(string tag, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<IEnumerable<PocketItem>> SearchByTag(string tag, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves items which match the specified search string in title and URI
|
||||
/// </summary>
|
||||
/// <param name="searchString">The search string.</param>
|
||||
/// <param name="searchInUri">if set to <c>true</c> [search in URI].</param>
|
||||
/// <param name="tag">Filter by tag.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
Task<List<PocketItem>> Search(string searchString, bool searchInUri = true, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<IEnumerable<PocketItem>> Search(string searchString, string tag = null, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Finds the specified search string in title and URI for an available list of items
|
||||
/// Retrieves the article content from an URI
|
||||
/// WARNING:
|
||||
/// You have to pass the parseUri in the PocketClient ctor for this method to work.
|
||||
/// This is a private API and can only be used by authenticated users.
|
||||
/// </summary>
|
||||
/// <param name="availableItems">The available items.</param>
|
||||
/// <param name="searchString">The search string.</param>
|
||||
/// <param name="tag">The article URI.</param>
|
||||
/// <param name="includeImages">Include images into content or use placeholder.</param>
|
||||
/// <param name="includeVideos">Include videos into content or use placeholder.</param>
|
||||
/// <param name="forceRefresh">Force refresh of the content (don't use cache).</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Search string length has to be a minimum of 2 chars</exception>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
List<PocketItem> Search(List<PocketItem> availableItems, string searchString);
|
||||
Task<PocketArticle> GetArticle(Uri uri, bool includeImages = true, bool includeVideos = true, bool forceRefresh = false, CancellationToken cancellationToken = default(CancellationToken));
|
||||
#endregion
|
||||
|
||||
#region modify methods
|
||||
@@ -209,7 +222,7 @@ namespace PocketSharp
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException"></exception>
|
||||
Task<bool> SendActions(List<PocketAction> actions, CancellationToken cancellationToken = default(CancellationToken));
|
||||
Task<bool> SendActions(IEnumerable<PocketAction> actions, CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Archives the specified item.
|
||||
@@ -442,5 +455,10 @@ namespace PocketSharp
|
||||
/// <exception cref="PocketException"></exception>
|
||||
Task<PocketLimits> GetUsageLimits(CancellationToken cancellationToken = default(CancellationToken));
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
void Dispose();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,6 @@ namespace PocketSharp.Models
|
||||
/// The actions.
|
||||
/// </value>
|
||||
[DataMember(Name = "actions")]
|
||||
public List<Dictionary<string, string>> Actions { get; set; }
|
||||
public IEnumerable<Dictionary<string, string>> Actions { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// All parameters which can be passed to register a user
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
internal class RegisterParameters : Parameters
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the username.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The username.
|
||||
/// </value>
|
||||
[DataMember(Name = "username")]
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the E-Mail.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The E-Mail.
|
||||
/// </value>
|
||||
[DataMember(Name = "email")]
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The password.
|
||||
/// </value>
|
||||
[DataMember(Name = "password")]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
@@ -120,7 +121,7 @@ namespace PocketSharp.Models
|
||||
if (!String.IsNullOrEmpty(TweetID))
|
||||
parameters.Add("ref_id", TweetID);
|
||||
if (Uri != null)
|
||||
parameters.Add("uri", Uri.ToString());
|
||||
parameters.Add("url", Uri.OriginalString);
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
using Newtonsoft.Json;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Article
|
||||
/// </summary>
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
public class PocketArticle
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the response Code (200 = OK).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The response Code.
|
||||
/// </value>
|
||||
[JsonProperty("responseCode")]
|
||||
public string ResponseCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The ID.
|
||||
/// </value>
|
||||
[JsonProperty("resolved_id")]
|
||||
public string ID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URI.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The URI.
|
||||
/// </value>
|
||||
[JsonProperty("resolvedUrl")]
|
||||
public Uri Uri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URI.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The URI.
|
||||
/// </value>
|
||||
[JsonProperty("timePublished")]
|
||||
public DateTime? PublishedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the word count.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The word count.
|
||||
/// </value>
|
||||
[JsonProperty("wordCount")]
|
||||
public int WordCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is article.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is article; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("isArticle")]
|
||||
public bool IsArticle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is video.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is video; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("isVideo")]
|
||||
public bool IsVideo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is index.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is index; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("isIndex")]
|
||||
public bool IsIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance used fallback.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance used fallback; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("usedFallback")]
|
||||
public bool UsedFallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance requires login.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance requires login; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[JsonProperty("requiresLogin")]
|
||||
public bool RequiresLogin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the images.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The images.
|
||||
/// </value>
|
||||
[JsonProperty("images")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketImage>))]
|
||||
public IEnumerable<PocketImage> Images { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the videos.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The videos.
|
||||
/// </value>
|
||||
[JsonProperty("videos")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketVideo>))]
|
||||
public IEnumerable<PocketVideo> Videos { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the authors.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The authors.
|
||||
/// </value>
|
||||
[JsonProperty("authors")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketAuthor>))]
|
||||
public IEnumerable<PocketAuthor> Authors { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the article title.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The Title.
|
||||
/// </value>
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Excerpt.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The Excerpt.
|
||||
/// </value>
|
||||
[JsonProperty("excerpt")]
|
||||
public string Excerpt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Content.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The Content.
|
||||
/// </value>
|
||||
[JsonProperty("article")]
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using PropertyChanged;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp.Models
|
||||
{
|
||||
@@ -13,8 +14,7 @@ namespace PocketSharp.Models
|
||||
[JsonObject]
|
||||
[ImplementPropertyChanged]
|
||||
[DebuggerDisplay("Uri = {Uri}, Title = {Title}")]
|
||||
|
||||
public class PocketItem
|
||||
public class PocketItem : IComparable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
@@ -301,6 +301,17 @@ namespace PocketSharp.Models
|
||||
[JsonProperty("time_favorited")]
|
||||
public DateTime? FavoriteTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the tags as comma-separated strings.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The tags.
|
||||
/// </value>
|
||||
[JsonIgnore]
|
||||
public string TagsString
|
||||
{
|
||||
get { return Tags != null ? String.Join(",", Tags.Select(tag => tag.Name)) : ""; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the tags.
|
||||
@@ -310,7 +321,7 @@ namespace PocketSharp.Models
|
||||
/// </value>
|
||||
[JsonProperty("tags")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketTag>))]
|
||||
public List<PocketTag> Tags { get; set; }
|
||||
public IEnumerable<PocketTag> Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the images.
|
||||
@@ -320,7 +331,7 @@ namespace PocketSharp.Models
|
||||
/// </value>
|
||||
[JsonProperty("images")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketImage>))]
|
||||
public List<PocketImage> Images { get; set; }
|
||||
public IEnumerable<PocketImage> Images { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the videos.
|
||||
@@ -330,7 +341,7 @@ namespace PocketSharp.Models
|
||||
/// </value>
|
||||
[JsonProperty("videos")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketVideo>))]
|
||||
public List<PocketVideo> Videos { get; set; }
|
||||
public IEnumerable<PocketVideo> Videos { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the authors.
|
||||
@@ -340,7 +351,7 @@ namespace PocketSharp.Models
|
||||
/// </value>
|
||||
[JsonProperty("authors")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketAuthor>))]
|
||||
public List<PocketAuthor> Authors { get; set; }
|
||||
public IEnumerable<PocketAuthor> Authors { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the lead image.
|
||||
@@ -351,7 +362,7 @@ namespace PocketSharp.Models
|
||||
[JsonIgnore]
|
||||
public PocketImage LeadImage
|
||||
{
|
||||
get { return Images != null && Images.Count > 0 ? Images[0] : null; }
|
||||
get { return Images != null && Images.Count() > 0 ? Images.First() : null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -362,5 +373,114 @@ namespace PocketSharp.Models
|
||||
/// </value>
|
||||
[JsonIgnore]
|
||||
public string Json { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
|
||||
/// </summary>
|
||||
/// <param name="obj">An object to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj" /> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj" />. Greater than zero This instance follows <paramref name="obj" /> in the sort order.
|
||||
/// </returns>
|
||||
int IComparable.CompareTo(object obj)
|
||||
{
|
||||
PocketItem item = (PocketItem)obj;
|
||||
|
||||
if (!AddTime.HasValue)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (!item.AddTime.HasValue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return DateTime.Compare(AddTime.Value, item.AddTime.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PocketItem item = (PocketItem)obj;
|
||||
|
||||
if ((Object)item == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ID == item.ID;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="a">A.</param>
|
||||
/// <param name="b">The b.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator ==(PocketItem a, PocketItem b)
|
||||
{
|
||||
if (a == null || b == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PocketItem itemA = (PocketItem)a;
|
||||
PocketItem itemB = (PocketItem)b;
|
||||
|
||||
if ((Object)itemA == null || (Object)itemB == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return itemA.ID == itemB.ID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="a">A.</param>
|
||||
/// <param name="b">The b.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator !=(PocketItem a, PocketItem b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ID.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,5 +18,14 @@ namespace PocketSharp.Models
|
||||
/// </value>
|
||||
[JsonProperty("tag")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item iD.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
[JsonProperty("item_id")]
|
||||
public string ItemID { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,6 @@ namespace PocketSharp.Models
|
||||
/// </value>
|
||||
[JsonProperty("list")]
|
||||
[JsonConverter(typeof(ObjectToArrayConverter<PocketItem>))]
|
||||
public List<PocketItem> Items { get; set; }
|
||||
public IEnumerable<PocketItem> Items { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
+99
-28
@@ -8,19 +8,25 @@ using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace PocketSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// PocketClient
|
||||
/// </summary>
|
||||
public partial class PocketClient : IPocketClient
|
||||
public partial class PocketClient : IPocketClient, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// REST client used for the API communication
|
||||
/// </summary>
|
||||
protected readonly HttpClient _restClient;
|
||||
|
||||
/// <summary>
|
||||
/// REST client used for the API communication with the Text Parser API
|
||||
/// </summary>
|
||||
protected readonly HttpClient _restParserClient;
|
||||
|
||||
/// <summary>
|
||||
/// Caches HTTP headers from last response
|
||||
/// </summary>
|
||||
@@ -97,13 +103,15 @@ namespace PocketSharp
|
||||
/// <param name="handler">The HttpMessage handler.</param>
|
||||
/// <param name="timeout">Request timeout (in seconds).</param>
|
||||
/// <param name="isMobileClient">Indicates, whether this client is used for mobile or desktop</param>
|
||||
/// <param name="parserUri">Enables the wrapper for the private Text Parser API</param>
|
||||
public PocketClient(
|
||||
string consumerKey,
|
||||
string accessCode = null,
|
||||
string callbackUri = null,
|
||||
HttpMessageHandler handler = null,
|
||||
int? timeout = null,
|
||||
bool isMobileClient = true)
|
||||
bool isMobileClient = true,
|
||||
Uri parserUri = null)
|
||||
{
|
||||
// assign public properties
|
||||
ConsumerKey = consumerKey;
|
||||
@@ -122,6 +130,23 @@ namespace PocketSharp
|
||||
CallbackUri = Uri.EscapeUriString(callbackUri.ToString());
|
||||
}
|
||||
|
||||
// assign text parser if parserUri submitted
|
||||
if (parserUri != null)
|
||||
{
|
||||
_restParserClient = new HttpClient(handler ?? new HttpClientHandler()
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
|
||||
});
|
||||
_restParserClient.BaseAddress = parserUri;
|
||||
_restParserClient.DefaultRequestHeaders.Add("Accept", "*/*");
|
||||
_restParserClient.DefaultRequestHeaders.Add("X-Accept", "application/json");
|
||||
|
||||
if (timeout.HasValue)
|
||||
{
|
||||
_restParserClient.Timeout = TimeSpan.FromSeconds(timeout.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize REST client
|
||||
_restClient = new HttpClient(handler ?? new HttpClientHandler()
|
||||
{
|
||||
@@ -158,16 +183,27 @@ namespace PocketSharp
|
||||
string method,
|
||||
CancellationToken cancellationToken,
|
||||
Dictionary<string, string> parameters = null,
|
||||
bool requireAuth = true) where T : class, new()
|
||||
bool requireAuth = true,
|
||||
bool isReaderRequest = false) where T : class, new()
|
||||
{
|
||||
if (requireAuth && AccessCode == null)
|
||||
{
|
||||
throw new PocketException("SDK error: No access token available. Use authentication first.");
|
||||
}
|
||||
|
||||
// rewrite base if it is a request to the Parser API
|
||||
if (isReaderRequest)
|
||||
{
|
||||
if (_restParserClient == null)
|
||||
{
|
||||
throw new PocketException("Please pass the parserUri in the PocketClient ctor.");
|
||||
}
|
||||
}
|
||||
|
||||
// every single Pocket API endpoint requires HTTP POST data
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, method);
|
||||
HttpResponseMessage response = null;
|
||||
string responseString = null;
|
||||
|
||||
if (parameters == null)
|
||||
{
|
||||
@@ -178,7 +214,7 @@ namespace PocketSharp
|
||||
parameters.Add("consumer_key", ConsumerKey);
|
||||
|
||||
// add access token (necessary for all requests except authentification)
|
||||
if (AccessCode != null)
|
||||
if (AccessCode != null && requireAuth)
|
||||
{
|
||||
parameters.Add("access_token", AccessCode);
|
||||
}
|
||||
@@ -195,30 +231,59 @@ namespace PocketSharp
|
||||
// make async request
|
||||
try
|
||||
{
|
||||
response = await _restClient.SendAsync(request, cancellationToken);
|
||||
if (isReaderRequest)
|
||||
{
|
||||
response = await _restParserClient.SendAsync(request, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
response = await _restClient.SendAsync(request, cancellationToken);
|
||||
}
|
||||
|
||||
// validate HTTP response
|
||||
ValidateResponse(response);
|
||||
|
||||
// cache headers
|
||||
lastHeaders = response.Headers;
|
||||
|
||||
// read response
|
||||
responseString = await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
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();
|
||||
catch (PocketException exc)
|
||||
{
|
||||
throw exc;
|
||||
}
|
||||
finally
|
||||
{
|
||||
request.Dispose();
|
||||
response.Dispose();
|
||||
}
|
||||
|
||||
// cache response
|
||||
lastResponseData = responseString;
|
||||
|
||||
responseString = responseString.Replace("[]", "{}");
|
||||
return DeserializeJson<T>(responseString);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Converts JSON to Pocket objects
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="json">Raw JSON response</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="PocketException">Parse error.</exception>
|
||||
protected T DeserializeJson<T>(string json) where T : class, new()
|
||||
{
|
||||
json = json.Replace("[]", "{}");
|
||||
|
||||
// deserialize object
|
||||
T parsedResponse = JsonConvert.DeserializeObject<T>(
|
||||
responseString,
|
||||
json,
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
Error = (object sender, ErrorEventArgs args) =>
|
||||
@@ -245,22 +310,13 @@ namespace PocketSharp
|
||||
/// </summary>
|
||||
/// <param name="actionParameters">The action parameters.</param>
|
||||
/// <returns></returns>
|
||||
internal async Task<bool> Send(List<PocketAction> actionParameters, CancellationToken cancellationToken)
|
||||
internal async Task<bool> Send(IEnumerable<PocketAction> actionParameters, CancellationToken cancellationToken)
|
||||
{
|
||||
List<Dictionary<string, object>> actionParamList = new List<Dictionary<string, object>>();
|
||||
|
||||
foreach (var action in actionParameters)
|
||||
{
|
||||
actionParamList.Add(action.Convert());
|
||||
}
|
||||
|
||||
Dictionary<string, string> parameters = new Dictionary<string, string>() {{
|
||||
"actions", JsonConvert.SerializeObject(actionParamList)
|
||||
"actions", JsonConvert.SerializeObject(actionParameters.Select(action => action.Convert()))
|
||||
}};
|
||||
|
||||
Modify response = await Request<Modify>("send", cancellationToken, parameters);
|
||||
|
||||
return response.Status;
|
||||
return (await Request<Modify>("send", cancellationToken, parameters)).Status;
|
||||
}
|
||||
|
||||
|
||||
@@ -355,5 +411,20 @@ namespace PocketSharp
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_restClient.Dispose();
|
||||
lastHeaders = null;
|
||||
|
||||
if (_restParserClient != null)
|
||||
{
|
||||
_restParserClient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Components\Statistics.cs" />
|
||||
<Compile Include="IPocketClient.cs" />
|
||||
<Compile Include="Models\Parameters\RegisterParameters.cs" />
|
||||
<Compile Include="Models\PocketArticle.cs" />
|
||||
<Compile Include="Models\PocketBoolean.cs" />
|
||||
<Compile Include="Models\PocketLimits.cs" />
|
||||
<Compile Include="Models\PocketStatistics.cs" />
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
// 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("4.0.0")]
|
||||
[assembly: AssemblyFileVersion("4.0.0")]
|
||||
[assembly: AssemblyVersion("4.1.1")]
|
||||
[assembly: AssemblyFileVersion("4.1.1")]
|
||||
@@ -45,6 +45,11 @@ namespace PocketSharp
|
||||
return null;
|
||||
}
|
||||
|
||||
if (reader.Value.ToString().StartsWith("-"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(Convert.ToDouble(reader.Value)).ToLocalTime();
|
||||
}
|
||||
}
|
||||
@@ -123,22 +128,26 @@ namespace PocketSharp
|
||||
|
||||
|
||||
|
||||
public class ObjectToArrayConverter<T> : CustomCreationConverter<List<T>> where T : new()
|
||||
public class ObjectToArrayConverter<T> : CustomCreationConverter<IEnumerable<T>> where T : new()
|
||||
{
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
JObject jObject;
|
||||
List<T> result = new List<T>();
|
||||
T target;
|
||||
List<T> results = new List<T>();
|
||||
|
||||
// object is an array
|
||||
if (reader.TokenType == JsonToken.StartArray)
|
||||
{
|
||||
return serializer.Deserialize<List<T>>(reader);
|
||||
return serializer.Deserialize<IEnumerable<T>>(reader);
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -152,11 +161,12 @@ namespace PocketSharp
|
||||
// Populate the object properties
|
||||
foreach (KeyValuePair<string, JToken> item in jObject)
|
||||
{
|
||||
target = serializer.Deserialize<T>(item.Value.CreateReader());
|
||||
result.Add(target);
|
||||
results.Add(
|
||||
serializer.Deserialize<T>(item.Value.CreateReader())
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
return results;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
@@ -164,11 +174,10 @@ namespace PocketSharp
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override List<T> Create(Type objectType)
|
||||
public override IEnumerable<T> Create(Type objectType)
|
||||
{
|
||||
return new List<T>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,14 +49,15 @@ Which will output:
|
||||
|
||||
## Supported platforms
|
||||
|
||||
PocketSharp is a **Portable Class Library**, therefore it's compatible with multiple platforms:
|
||||
PocketSharp is a **Portable Class Library**, therefore it's compatible with multiple platforms and Universal Apps:
|
||||
|
||||
- **.NET** >= 4.5 (including WPF)
|
||||
- **Silverlight** >= 4
|
||||
- **Windows Phone** >= 7.5
|
||||
- **Windows Store**
|
||||
- **Windows Phone** (Silverlight + WinPRT) >= 8
|
||||
- **Windows Store** >= 8
|
||||
- **Xamarin** iOS + Android
|
||||
- _WP7 and Silverlight are dropped in 4.0, use PocketSharp < 4.0, if you want to support them_
|
||||
|
||||
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.
|
||||
You can find examples for WP8 and WPF in the `PocketSharp.Examples` ([@github](https://github.com/ceee/PocketSharp/tree/master/PocketSharp.Examples)) folder.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
||||
Reference in New Issue
Block a user