Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Specialized;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Runtime.Serialization;
- using System.Security.Cryptography;
- using System.Text;
- using System.Threading.Tasks;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- namespace SharpDig
- {
- /// <summary>
- /// Klasa reprezentująca aplikację dla WykopAPI
- /// </summary>
- public sealed class ApiLayer
- {
- private readonly string _appkey;
- private readonly string _secretkey;
- /// <summary>
- /// Tworzy instancję klasy opakowywującej aplikację dla WykopAPI
- /// </summary>
- /// <param name="appkey">Klucz publiczny aplikacji</param>
- /// <param name="secretkey">Klucz prywatny aplikacji</param>
- public ApiLayer(string appkey, string secretkey)
- {
- AppKey = appkey;
- _secretkey = secretkey;
- }
- /// <summary>
- /// Klucz publiczny aplikacji
- /// </summary>
- public string AppKey { get; private set; }
- /// <summary>
- /// Oblicza podpis dla żądania
- /// </summary>
- /// <param name="url">URL żądania</param>
- /// <param name="postdata">Dane dla metody POST</param>
- /// <param name="filedata">Dane typu plik</param>
- private string CreateSign(string url, NameValueCollection postdata = null, NameValueCollection filedata = null)
- {
- using (MD5 md5 = MD5.Create())
- {
- var inputbuilder = new StringBuilder(_secretkey + url);
- if (postdata != null)
- inputbuilder.Append(string.Join(",",
- postdata.AllKeys.OrderBy(s => s).Select(key => postdata[key]).ToList
- ()));
- byte[] rawhash = md5.ComputeHash(Encoding.ASCII.GetBytes(inputbuilder.ToString()));
- var hashbuilder = new StringBuilder();
- foreach (byte b in rawhash)
- hashbuilder.Append(b.ToString("x2")); // x2, bo 4 bity * 2 == bajt
- return hashbuilder.ToString();
- }
- }
- /// <summary>
- /// Wykonuje surowe żądanie na podstawie ciągu żądania i danych do przesłania poprzez metodę POST
- /// </summary>
- /// <param name="builder">Ciąg znaków reprezentujący ciąg żądania</param>
- /// <param name="postdata">Kolekcja zawierająca danę do przesłania poprzez metodę POST</param>
- /// <returns>Typ HttpWebResponse</returns>
- private HttpWebResponse DoRawRequest(string builder, NameValueCollection postdata = null)
- {
- HttpWebRequest req = WebRequest.CreateHttp("http://a.wykop.pl/" + builder);
- req.Headers.Add("apisign", CreateSign("http://a.wykop.pl/" + builder, postdata)); // podpisanie
- req.Method = WebRequestMethods.Http.Post;
- req.ContentType = "application/x-www-form-urlencoded";
- if (postdata != null)
- {
- using (Stream stream = req.GetRequestStream())
- {
- byte[] bytepostdata =
- Encoding.UTF8.GetBytes(string.Join("&",
- postdata.AllKeys.Select(key => key + '=' + postdata[key])));
- stream.Write(bytepostdata, 0, bytepostdata.Length);
- }
- }
- return (HttpWebResponse) req.GetResponse();
- }
- /// <summary>
- /// Wykonuje surowe żądanie asynchronicznie
- /// </summary>
- /// <param name="builder">Ciąg znaków reprezentujący ciąg żądania</param>
- /// <param name="postdata">Kolekcja zawierająca danę do przesłania poprzez metodę POST</param>
- /// <returns>Typ HttpWebResponse</returns>
- private async Task<HttpWebResponse> DoRawRequestAsync(string builder, NameValueCollection postdata = null)
- {
- HttpWebRequest req = WebRequest.CreateHttp("http://a.wykop.pl/" + builder);
- req.Headers.Add("apisign", CreateSign("http://a.wykop.pl/" + builder, postdata)); // podpisanie
- req.Method = WebRequestMethods.Http.Post;
- req.ContentType = "application/x-www-form-urlencoded";
- if (postdata != null)
- {
- using (Stream stream = await req.GetRequestStreamAsync())
- {
- byte[] bytepostdata =
- Encoding.UTF8.GetBytes(string.Join("&",
- postdata.AllKeys.Select(key => key + '=' + postdata[key])));
- stream.Write(bytepostdata, 0, bytepostdata.Length);
- }
- }
- return (HttpWebResponse) req.GetResponse();
- }
- /// <summary>
- /// Wykonuje dowolne żądanie na podstawie zadanego ciągu żądania (bez http://a.wykop.pl) i danych do wysłania poprzez metodę POST
- /// </summary>
- /// <param name="builder">Ciąg znaków reprezentujący ciąg żądania</param>
- /// <param name="postdata">Kolekcja zawierająca danę do przesłania poprzez metodę POST</param>
- /// <returns>Typ T, jako żądany obiekt</returns>
- public T DoCustomRequest<T>(string builder, NameValueCollection postdata = null) where T : class
- {
- HttpWebResponse resp = DoRawRequest(builder, postdata);
- using (var reader = new StreamReader(resp.GetResponseStream()))
- {
- string str = reader.ReadToEnd();
- Debug.Print(str);
- var o = JToken.Parse(str) as JObject;
- JToken jToken;
- if (o != null && o.TryGetValue("error", out jToken))
- throw new ApiErrorException((string) jToken["message"], (int) jToken["code"]);
- return JsonConvert.DeserializeObject<T>(str);
- }
- }
- /// <summary>
- /// Wykonywuję dowolne żądanie asynchronicznie
- /// </summary>
- /// <param name="builder">Ciąg znaków reprezentujący ciąg żądania</param>
- /// <param name="postdata">Kolekcja zawierająca danę do przesłania poprzez metodę POST</param>
- /// <returns>Typ T, jako jako żądany obiekt</returns>
- public async Task<T> DoCustomRequestAsync<T>(string builder, NameValueCollection postdata = null) where T : class
- {
- HttpWebResponse resp = await DoRawRequestAsync(builder, postdata);
- using (var reader = new StreamReader(resp.GetResponseStream()))
- {
- string str = reader.ReadToEnd();
- Debug.Print(str);
- var o = JToken.Parse(str) as JObject;
- JToken jToken;
- if (o != null && o.TryGetValue("error", out jToken))
- throw new ApiErrorException((string) jToken["message"], (int) jToken["code"]);
- return JsonConvert.DeserializeObject<T>(str);
- }
- }
- }
- [Serializable]
- public class ApiErrorException : Exception
- {
- public ApiErrorException()
- {
- }
- public ApiErrorException(string message)
- : base(message)
- {
- }
- public ApiErrorException(string message, Exception inner)
- : base(message, inner)
- {
- }
- public ApiErrorException(string message, int code)
- : base(message)
- {
- ErrorCode = code;
- }
- protected ApiErrorException(
- SerializationInfo info,
- StreamingContext context)
- : base(info, context)
- {
- }
- public int ErrorCode { get; private set; }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment