diff --git a/PocketSharp.Tests/AddTests.cs b/PocketSharp.Tests/AddTests.cs index 8c60188..e2cb716 100644 --- a/PocketSharp.Tests/AddTests.cs +++ b/PocketSharp.Tests/AddTests.cs @@ -6,8 +6,21 @@ using PocketSharp.Models; namespace PocketSharp.Tests { - class AddTests : TestsBase + public class AddTests : TestsBase { public AddTests() : base() { } + + + [Fact] + public async Task AddSimpleItemWithUriOnly() + { + var uri = new Uri("http://frontendplay.com"); + + PocketItem item = await client.Add(uri); + + Assert.Equal(uri, item.Uri); + + itemsToDelete.Add(item.ID); + } } } diff --git a/PocketSharp.Tests/RetrieveTests.cs b/PocketSharp.Tests/RetrieveTests.cs index 4ebee4c..d175d93 100644 --- a/PocketSharp.Tests/RetrieveTests.cs +++ b/PocketSharp.Tests/RetrieveTests.cs @@ -6,10 +6,9 @@ using PocketSharp.Models; namespace PocketSharp.Tests { - public class RetrieveTests : TestsBase { - public RetrieveTests() : base() {} + public RetrieveTests() : base() { } [Fact] @@ -21,20 +20,20 @@ namespace PocketSharp.Tests } - [Fact] - public async Task ItemContainsUri() - { - List items = await client.Retrieve(new RetrieveParameters() - { - Count = 1 - }); + //[Fact] + //public async Task ItemContainsUri() + //{ + // List items = await client.Retrieve(new RetrieveParameters() + // { + // Count = 1 + // }); - Assert.True(items.Count == 1); + // Assert.True(items.Count == 1); - PocketItem item = items[0]; + // PocketItem item = items[0]; - Assert.True(item.Uri.ToString().StartsWith("http")); - } + // Assert.True(item.Uri.ToString().StartsWith("http")); + //} [Fact] diff --git a/PocketSharp.Tests/TestsBase.cs b/PocketSharp.Tests/TestsBase.cs index f43ff6e..d49777f 100644 --- a/PocketSharp.Tests/TestsBase.cs +++ b/PocketSharp.Tests/TestsBase.cs @@ -10,6 +10,8 @@ namespace PocketSharp.Tests { protected PocketClient client; + protected List itemsToDelete = new List(); + // setup public TestsBase() @@ -24,9 +26,12 @@ namespace PocketSharp.Tests // teardown - public void Dispose() + public void Dispose() { - + itemsToDelete.ForEach(async id => + { + await client.Delete(id); + }); } } } diff --git a/PocketSharp/Components/Authentification.cs b/PocketSharp/Components/Authentification.cs index 75a7757..9261012 100644 --- a/PocketSharp/Components/Authentification.cs +++ b/PocketSharp/Components/Authentification.cs @@ -1,5 +1,6 @@ using PocketSharp.Models; using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace PocketSharp @@ -22,7 +23,10 @@ namespace PocketSharp } // do request - RequestCode response = await Request("oauth/request", Utilities.CreateParamInList("redirect_uri", CallbackUri)); + RequestCode response = await Request("oauth/request", new Dictionary() + { + { "redirect_uri", CallbackUri } + }); // save code to client RequestCode = response.Code; @@ -74,7 +78,10 @@ namespace PocketSharp } // do request - AccessCode response = await Request("oauth/authorize", Utilities.CreateParamInList("code", RequestCode)); + AccessCode response = await Request("oauth/authorize", new Dictionary() + { + { "code", RequestCode } + }); // save code to client AccessCode = response.Code; diff --git a/PocketSharp/Components/Retrieve.cs b/PocketSharp/Components/Retrieve.cs index cb79ab3..d928fda 100644 --- a/PocketSharp/Components/Retrieve.cs +++ b/PocketSharp/Components/Retrieve.cs @@ -14,7 +14,7 @@ namespace PocketSharp /// /// parameters, which are mapped to the officials from http://getpocket.com/developer/docs/v3/retrieve /// - public async Task> Retrieve(RetrieveParameters parameters) + internal async Task> Retrieve(RetrieveParameters parameters) { Retrieve response = await Request("get", parameters.Convert(), true); diff --git a/PocketSharp/Models/Parameters/ActionParameter.cs b/PocketSharp/Models/Parameters/ActionParameter.cs index d44ce32..3c0e802 100644 --- a/PocketSharp/Models/Parameters/ActionParameter.cs +++ b/PocketSharp/Models/Parameters/ActionParameter.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using System.Runtime.Serialization; namespace PocketSharp.Models { /// /// All parameters which can be passed for a modify action /// + [DataContract] public class ActionParameter { /// @@ -14,6 +16,7 @@ namespace PocketSharp.Models /// /// The action. /// + [DataMember(Name = "action")] public string Action { get; set; } /// @@ -22,6 +25,7 @@ namespace PocketSharp.Models /// /// The ID. /// + [DataMember(Name = "item_id")] public int ID { get; set; } /// @@ -30,6 +34,7 @@ namespace PocketSharp.Models /// /// The time. /// + [DataMember(Name = "time")] public DateTime? Time { get; set; } // specific params @@ -40,6 +45,7 @@ namespace PocketSharp.Models /// /// The tags. /// + [DataMember(Name = "tags")] public string[] Tags { get; set; } /// @@ -48,6 +54,7 @@ namespace PocketSharp.Models /// /// The old tag. /// + [DataMember(Name = "old_tag")] public string OldTag { get; set; } /// @@ -56,6 +63,7 @@ namespace PocketSharp.Models /// /// The new tag. /// + [DataMember(Name = "new_tag")] public string NewTag { get; set; } @@ -63,7 +71,7 @@ namespace PocketSharp.Models /// Converts this instance to a parameter list. /// /// - public object Convert() + public Dictionary Convert() { Dictionary parameters = new Dictionary { diff --git a/PocketSharp/Models/Parameters/AddParameters.cs b/PocketSharp/Models/Parameters/AddParameters.cs index 00b3f42..c640794 100644 --- a/PocketSharp/Models/Parameters/AddParameters.cs +++ b/PocketSharp/Models/Parameters/AddParameters.cs @@ -1,12 +1,16 @@ using System; using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Serialization; +using System.Linq; namespace PocketSharp.Models { /// /// All parameters which can be passed to add a new item /// - public class AddParameters + [DataContract] + internal class AddParameters : Parameters { /// /// Gets or sets the URI. @@ -14,6 +18,7 @@ namespace PocketSharp.Models /// /// The URI. /// + [DataMember(Name="url")] public Uri Uri { get; set; } /// @@ -22,6 +27,7 @@ namespace PocketSharp.Models /// /// The title. /// + [DataMember(Name="title")] public string Title { get; set; } /// @@ -30,6 +36,7 @@ namespace PocketSharp.Models /// /// The tags. /// + [DataMember(Name="tags")] public string[] Tags { get; set; } /// @@ -38,21 +45,7 @@ namespace PocketSharp.Models /// /// The tweet ID. /// + [DataMember(Name="tweet_id")] public string TweetID { get; set; } - - /// - /// Converts this instance to a parameter list. - /// - /// - public List Convert() - { - return new List() - { - Utilities.CreateParam("url", Uri.ToString() ), - Utilities.CreateParam("title", Title), - Utilities.CreateParam("tags", String.Join(",", Tags)), - Utilities.CreateParam("tweet_id", TweetID) - }; - } } } diff --git a/PocketSharp/Models/Parameters/ModifyParameters.cs b/PocketSharp/Models/Parameters/ModifyParameters.cs index 558c512..e0838b8 100644 --- a/PocketSharp/Models/Parameters/ModifyParameters.cs +++ b/PocketSharp/Models/Parameters/ModifyParameters.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; +using System.Runtime.Serialization; namespace PocketSharp.Models { /// /// All parameters which can be passed to modify an item /// - public class ModifyParameters + [DataContract] + internal class ModifyParameters : Parameters { /// /// Gets or sets the actions. @@ -13,23 +15,7 @@ namespace PocketSharp.Models /// /// The actions. /// + [DataMember(Name = "actions")] public List Actions { get; set; } - - - /// - /// Converts this instance to a parameter list. - /// - /// - public List Convert() - { - List actions = new List(); - - //Actions.ForEach(action => actions.Add(action.Convert())); - - return new List() - { - // Utilities.CreateParam("actions", JsonSerializer.SerializeToString(actions)) - }; - } } } diff --git a/PocketSharp/Models/Parameters/Parameters.cs b/PocketSharp/Models/Parameters/Parameters.cs new file mode 100644 index 0000000..5ed1a1e --- /dev/null +++ b/PocketSharp/Models/Parameters/Parameters.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Serialization; +using System.Linq; + +namespace PocketSharp.Models +{ + /// + /// Parameter + /// + internal class Parameters + { + + /// + /// Converts an object to a list of HTTP Post parameters. + /// + /// + public Dictionary Convert() + { + // store HTTP parameters here + Dictionary parameterDict = new Dictionary(); + + // get object properties + IEnumerable properties = this.GetType() + .GetProperties(BindingFlags.Instance | BindingFlags.Public) + .Where(p => Attribute.IsDefined(p, typeof(DataMemberAttribute))); + + // gather attributes of object + foreach (PropertyInfo propertyInfo in properties) + { + DataMemberAttribute attribute = (DataMemberAttribute)propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute‌), false).FirstOrDefault(); + string name = attribute.Name ?? propertyInfo.Name.ToLower(); + + if (propertyInfo.GetValue(this, null) != null) + { + parameterDict.Add(name, propertyInfo.GetValue(this, null).ToString()); + } + } + + return parameterDict; + } + } +} \ No newline at end of file diff --git a/PocketSharp/Models/Parameters/RetrieveParameters.cs b/PocketSharp/Models/Parameters/RetrieveParameters.cs index a762220..e844008 100644 --- a/PocketSharp/Models/Parameters/RetrieveParameters.cs +++ b/PocketSharp/Models/Parameters/RetrieveParameters.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Serialization; namespace PocketSharp.Models { /// /// All parameters which can be passed for item retrieval /// - public class RetrieveParameters + [DataContract] + internal class RetrieveParameters : Parameters { /// /// Gets or sets the state. @@ -14,6 +17,7 @@ namespace PocketSharp.Models /// /// The state. /// + [DataMember(Name = "state")] public State? State { get; set; } /// @@ -22,6 +26,7 @@ namespace PocketSharp.Models /// /// The favorite. /// + [DataMember(Name = "favorite")] public bool? Favorite { get; set; } /// @@ -30,6 +35,7 @@ namespace PocketSharp.Models /// /// The tag. /// + [DataMember(Name = "tag")] public string Tag { get; set; } /// @@ -38,6 +44,7 @@ namespace PocketSharp.Models /// /// The type of the content. /// + [DataMember(Name = "contentType")] public ContentType? ContentType { get; set; } /// @@ -46,6 +53,7 @@ namespace PocketSharp.Models /// /// The sort. /// + [DataMember(Name = "sort")] public Sort? Sort { get; set; } /// @@ -54,6 +62,7 @@ namespace PocketSharp.Models /// /// The type of the detail. /// + [DataMember(Name="detailType")] public DetailType? DetailType { get; set; } /// @@ -62,6 +71,7 @@ namespace PocketSharp.Models /// /// The search. /// + [DataMember(Name = "search")] public string Search { get; set; } /// @@ -70,6 +80,7 @@ namespace PocketSharp.Models /// /// The domain. /// + [DataMember(Name = "domain")] public string Domain { get; set; } /// @@ -78,6 +89,7 @@ namespace PocketSharp.Models /// /// The since. /// + [DataMember(Name = "since")] public DateTime? Since { get; set; } /// @@ -86,6 +98,7 @@ namespace PocketSharp.Models /// /// The count. /// + [DataMember(Name = "count")] public int? Count { get; set; } /// @@ -94,30 +107,8 @@ namespace PocketSharp.Models /// /// The offset. /// + [DataMember(Name = "offset")] public int? Offset { get; set; } - - - /// - /// Converts this instance to a parameter list. - /// - /// - public List Convert() - { - return new List() - { - Utilities.CreateParam("state", State != null ? State.ToString() : null ), - Utilities.CreateParam("favorite", Favorite != null ? (bool)Favorite ? "1" : "0" : null), - Utilities.CreateParam("tag", Tag), - Utilities.CreateParam("contentType", ContentType != null ? ContentType.ToString() : null), - Utilities.CreateParam("sort", Sort != null ? Sort.ToString() : null), - Utilities.CreateParam("detailType", DetailType != null ? DetailType.ToString() : null), - Utilities.CreateParam("search", Search), - Utilities.CreateParam("domain", Domain), - Utilities.CreateParam("since", Utilities.GetUnixTimestamp(Since)), - Utilities.CreateParam("count", Count), - Utilities.CreateParam("offset", Offset) - }; - } } diff --git a/PocketSharp/Models/PocketItem.cs b/PocketSharp/Models/PocketItem.cs index 770abd6..aad9793 100644 --- a/PocketSharp/Models/PocketItem.cs +++ b/PocketSharp/Models/PocketItem.cs @@ -37,7 +37,29 @@ namespace PocketSharp.Models /// The title. /// [JsonProperty("resolved_title")] - public string Title { get; set; } + private string _ResolvedTitle { get; set; } + + /// + /// Gets or sets the title. + /// + /// + /// The title. + /// + [JsonProperty("title")] + private string _InternalTitle { get; set; } + + /// + /// Gets or sets the title. + /// + /// + /// The title. + /// + [JsonIgnore] + public string Title + { + get { return _InternalTitle ?? _ResolvedTitle; } + set { _InternalTitle = value; _ResolvedTitle = value; } + } /// /// Gets or sets the full title. @@ -183,7 +205,7 @@ namespace PocketSharp.Models /// The _ tag dictionary. /// [JsonProperty("tags")] - public Dictionary TagDictionary { get; set; } + private Dictionary _TagDictionary { get; set; } /// /// Gets or sets the _ image dictionary. @@ -192,7 +214,7 @@ namespace PocketSharp.Models /// The _ image dictionary. /// [JsonProperty("images")] - public Dictionary ImageDictionary { get; set; } + private Dictionary _ImageDictionary { get; set; } /// /// Gets or sets the _ video dictionary. @@ -201,7 +223,7 @@ namespace PocketSharp.Models /// The _ video dictionary. /// [JsonProperty("videos")] - public Dictionary VideoDictionary { get; set; } + private Dictionary _VideoDictionary { get; set; } /// /// Gets or sets the _ author dictionary. @@ -210,7 +232,7 @@ namespace PocketSharp.Models /// The _ author dictionary. /// [JsonProperty("authors")] - public Dictionary AuthorDictionary { get; set; } + private Dictionary _AuthorDictionary { get; set; } /// @@ -222,7 +244,7 @@ namespace PocketSharp.Models [JsonIgnore] public List Tags { - get { return Utilities.DictionaryToList(TagDictionary); } + get { return Utilities.DictionaryToList(_TagDictionary); } } /// @@ -234,7 +256,7 @@ namespace PocketSharp.Models [JsonIgnore] public List Images { - get { return Utilities.DictionaryToList(ImageDictionary); } + get { return Utilities.DictionaryToList(_ImageDictionary); } } /// @@ -246,7 +268,7 @@ namespace PocketSharp.Models [JsonIgnore] public PocketImage LeadImage { - get { return Images != null ? Images[0] : null; } + get { return Images.Count > 0 ? Images[0] : null; } } /// @@ -258,7 +280,7 @@ namespace PocketSharp.Models [JsonIgnore] public List Videos { - get { return Utilities.DictionaryToList(VideoDictionary); } + get { return Utilities.DictionaryToList(_VideoDictionary); } } /// @@ -270,7 +292,7 @@ namespace PocketSharp.Models [JsonIgnore] public List Authors { - get { return Utilities.DictionaryToList(AuthorDictionary); } + get { return Utilities.DictionaryToList(_AuthorDictionary); } } } } diff --git a/PocketSharp/PocketClient.cs b/PocketSharp/PocketClient.cs index 8c72a51..3f8c536 100644 --- a/PocketSharp/PocketClient.cs +++ b/PocketSharp/PocketClient.cs @@ -94,50 +94,27 @@ namespace PocketSharp } - /// - /// Fetches a typed resource - /// - /// - /// Requested method (path after /v3/) - /// Additional POST parameters - /// if set to true [require auth]. - /// - /// No access token available. Use authentification first. - protected async Task Request(string method, List parameters = null, bool requireAuth = false) where T : class, new() + protected async Task Request(string method, Dictionary parameters = null, bool requireAuth = false) where T : class, new() { if (requireAuth && AccessCode == null) { throw new PocketException("SDK error: No access token available. Use authentification first."); } - // convert parameters - Dictionary parameterDict = new Dictionary(); - - if (parameters != null) - { - foreach (Parameter item in parameters) - { - if (item.Value != null) - { - parameterDict.Add(item.Name, item.Value.ToString()); - } - } - } - // every single Pocket API endpoint requires HTTP POST data HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, method); // add consumer key to each request - parameterDict.Add("consumer_key", ConsumerKey); + parameters.Add("consumer_key", ConsumerKey); // add access token (necessary for all requests except authentification) if (AccessCode != null) { - parameterDict.Add("access_token", AccessCode); + parameters.Add("access_token", AccessCode); } // content of the request - request.Content = new FormUrlEncodedContent(parameterDict); + request.Content = new FormUrlEncodedContent(parameters); // make async request HttpResponseMessage response = await _restClient.SendAsync(request); @@ -148,9 +125,11 @@ namespace PocketSharp // read response var responseString = await response.Content.ReadAsStringAsync(); + responseString = responseString.Replace("[]", "{}"); + // deserialize object T parsedResponse = JsonConvert.DeserializeObject( - responseString, + responseString, new JsonSerializerSettings { Error = (object sender, ErrorEventArgs args) => diff --git a/PocketSharp/PocketSharp.csproj b/PocketSharp/PocketSharp.csproj index b3370d4..e5a82be 100644 --- a/PocketSharp/PocketSharp.csproj +++ b/PocketSharp/PocketSharp.csproj @@ -49,7 +49,7 @@ - + diff --git a/PocketSharp/Utilities.cs b/PocketSharp/Utilities.cs index e5edeeb..5d88324 100644 --- a/PocketSharp/Utilities.cs +++ b/PocketSharp/Utilities.cs @@ -25,32 +25,6 @@ namespace PocketSharp } - /// - /// Creates a Parameter object. - /// - /// The name. - /// The value. - /// The type. - /// - public static Parameter CreateParam(string name, object value) - { - return new Parameter() { Name = name, Value = value }; - } - - - /// - /// Creates a Parameter object within a list. - /// - /// The name. - /// The value. - /// The type. - /// - public static List CreateParamInList(string name, object value) - { - return new List() { CreateParam(name, value) }; - } - - /// /// Convert a dictionary to a list ///