using PocketSharp.Models;
using RestSharp;
using RestSharp.Contrib;
using System;
using System.Collections.Generic;
using System.Net;
namespace PocketSharp
{
///
/// PocketClient
///
public partial class PocketClient
{
///
/// REST client used for the API communication
///
protected readonly RestClient _restClient;
///
/// The base URL for the Pocket API
///
protected static Uri baseUri = new Uri("https://getpocket.com/v3/");
///
/// The authentification URL
///
protected string authentificationUri = "https://getpocket.com/auth/authorize?request_token={0}&redirect_uri={1}";
///
/// callback URL for API calls
///
protected string CallbackUri { get; set; }
///
/// Accessor for the Pocket API key
/// see: http://getpocket.com/developer
///
public string ConsumerKey { get; set; }
///
/// Returns all associated data from the last request
///
public IRestResponse LastRequestData { get; private set; }
///
/// Code retrieved on authentification
///
public string RequestCode { get; set; }
///
/// Code retrieved on authentification-success
///
public string AccessCode { get; set; }
///
/// Initializes a new instance of the class.
///
/// The API key
/// Provide an access code if the user is already authenticated
/// The callback URL is called by Pocket after authentication
public PocketClient(string consumerKey, string accessCode = null, string callbackUri = null)
{
// assign public properties
ConsumerKey = consumerKey;
// assign access code if submitted
if (accessCode != null)
{
AccessCode = accessCode.ToString();
}
// assign callback uri if submitted
if (callbackUri != null)
{
CallbackUri = HttpUtility.UrlEncode(callbackUri.ToString());
}
// initialize REST client
_restClient = new RestClient(baseUri.ToString());
// add default parameters to each request
_restClient.AddDefaultParameter("consumer_key", ConsumerKey);
// Pocket needs this specific Accept header :-S
_restClient.AddDefaultHeader("Accept", "*/*");
// defines the response format (according to the Pocket docs)
_restClient.AddDefaultHeader("X-Accept", "application/json");
// custom JSON deserializer (ServiceStack.Text)
_restClient.AddHandler("application/json", new JsonDeserializer());
// add custom deserialization lambdas
JsonDeserializer.AddCustomDeserialization();
}
///
/// Makes a HTTP REST request to the API
///
/// The request.
///
protected string Request(RestRequest request)
{
IRestResponse response = _restClient.Execute(request);
LastRequestData = response;
ValidateResponse(response);
return response.Content;
}
///
/// Makes a typed HTTP REST request to the API
///
///
/// The request.
///
protected T Request(RestRequest request) where T : new()
{
IRestResponse response = _restClient.Execute(request);
LastRequestData = response;
ValidateResponse(response);
return response.Data;
}
///
/// 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 T Get(string method, List parameters = null, bool requireAuth = false) where T : class, new()
{
if (requireAuth && AccessCode == null)
{
throw new APIException("No access token available. Use authentification first.");
}
// every single Pocket API endpoint requires HTTP POST data
var request = new RestRequest(method, Method.POST);
// add access token (necessary for all requests except authentification)
if (AccessCode != null)
{
request.AddParameter("access_token", AccessCode);
}
// enumeration for params
if (parameters != null)
{
parameters.ForEach(delegate(Parameter param)
{
request.AddParameter(param);
});
}
// do the request
return Request(request);
}
///
/// Puts an action
///
/// The action parameter.
///
protected bool PutSendAction(ActionParameter actionParameter)
{
ModifyParameters parameters = new ModifyParameters()
{
Actions = new List() { actionParameter }
};
return Get("send", parameters.Convert(), true).Status;
}
///
/// Validates the response.
///
/// The response.
///
///
/// Error retrieving response
///
protected void ValidateResponse(IRestResponse response)
{
if (response.StatusCode != HttpStatusCode.OK)
{
// get pocket error headers
Parameter error = response.Headers[1];
Parameter errorCode = response.Headers[2];
string exceptionString = response.Content;
bool isPocketError = error.Name == "X-Error";
// update message to include pocket response data
if (isPocketError)
{
exceptionString = exceptionString + "\nPocketResponse: (" + errorCode.Value + ") " + error.Value;
}
// create exception
APIException exception = new APIException(exceptionString, response.ErrorException);
if (isPocketError)
{
// add custom pocket fields
exception.PocketError = error.Value.ToString();
exception.PocketErrorCode = Convert.ToInt32(errorCode.Value);
// add to generic exception data
exception.Data.Add(error.Name, error.Value);
exception.Data.Add(errorCode.Name, errorCode.Value);
}
throw exception;
}
else if (response.ErrorException != null)
{
throw new APIException("Error retrieving response", response.ErrorException);
}
}
}
}