Guest User

sharpdig

a guest
Aug 9th, 2013
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.88 KB | None | 0 0
  1. using System;
  2. using System.Collections.Specialized;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Runtime.Serialization;
  8. using System.Security.Cryptography;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using Newtonsoft.Json;
  12. using Newtonsoft.Json.Linq;
  13.  
  14. namespace SharpDig
  15. {
  16.     /// <summary>
  17.     /// Klasa reprezentująca aplikację dla WykopAPI
  18.     /// </summary>
  19.     public sealed class ApiLayer
  20.     {
  21.         private readonly string _appkey;
  22.         private readonly string _secretkey;
  23.  
  24.         /// <summary>
  25.         /// Tworzy instancję klasy opakowywującej aplikację dla WykopAPI
  26.         /// </summary>
  27.         /// <param name="appkey">Klucz publiczny aplikacji</param>
  28.         /// <param name="secretkey">Klucz prywatny aplikacji</param>
  29.         public ApiLayer(string appkey, string secretkey)
  30.         {
  31.             AppKey = appkey;
  32.             _secretkey = secretkey;
  33.         }
  34.  
  35.         /// <summary>
  36.         /// Klucz publiczny aplikacji
  37.         /// </summary>
  38.         public string AppKey { get; private set; }
  39.  
  40.         /// <summary>
  41.         /// Oblicza podpis dla żądania
  42.         /// </summary>
  43.         /// <param name="url">URL żądania</param>
  44.         /// <param name="postdata">Dane dla metody POST</param>
  45.         /// <param name="filedata">Dane typu plik</param>
  46.         private string CreateSign(string url, NameValueCollection postdata = null, NameValueCollection filedata = null)
  47.         {
  48.             using (MD5 md5 = MD5.Create())
  49.             {
  50.                 var inputbuilder = new StringBuilder(_secretkey + url);
  51.  
  52.                 if (postdata != null)
  53.                     inputbuilder.Append(string.Join(",",
  54.                                                     postdata.AllKeys.OrderBy(s => s).Select(key => postdata[key]).ToList
  55.                                                         ()));
  56.  
  57.  
  58.                 byte[] rawhash = md5.ComputeHash(Encoding.ASCII.GetBytes(inputbuilder.ToString()));
  59.                 var hashbuilder = new StringBuilder();
  60.  
  61.                 foreach (byte b in rawhash)
  62.                     hashbuilder.Append(b.ToString("x2")); // x2, bo 4 bity * 2 == bajt
  63.                 return hashbuilder.ToString();
  64.             }
  65.         }
  66.  
  67.         /// <summary>
  68.         /// Wykonuje surowe żądanie na podstawie ciągu żądania i danych do przesłania poprzez metodę POST
  69.         /// </summary>
  70.         /// <param name="builder">Ciąg znaków reprezentujący ciąg żądania</param>
  71.         /// <param name="postdata">Kolekcja zawierająca danę do przesłania poprzez metodę POST</param>
  72.         /// <returns>Typ HttpWebResponse</returns>
  73.         private HttpWebResponse DoRawRequest(string builder, NameValueCollection postdata = null)
  74.         {
  75.             HttpWebRequest req = WebRequest.CreateHttp("http://a.wykop.pl/" + builder);
  76.             req.Headers.Add("apisign", CreateSign("http://a.wykop.pl/" + builder, postdata)); // podpisanie
  77.             req.Method = WebRequestMethods.Http.Post;
  78.             req.ContentType = "application/x-www-form-urlencoded";
  79.  
  80.             if (postdata != null)
  81.             {
  82.                 using (Stream stream = req.GetRequestStream())
  83.                 {
  84.                     byte[] bytepostdata =
  85.                         Encoding.UTF8.GetBytes(string.Join("&",
  86.                                                            postdata.AllKeys.Select(key => key + '=' + postdata[key])));
  87.  
  88.                     stream.Write(bytepostdata, 0, bytepostdata.Length);
  89.                 }
  90.             }
  91.  
  92.             return (HttpWebResponse) req.GetResponse();
  93.         }
  94.  
  95.         /// <summary>
  96.         /// Wykonuje surowe żądanie asynchronicznie
  97.         /// </summary>
  98.         /// <param name="builder">Ciąg znaków reprezentujący ciąg żądania</param>
  99.         /// <param name="postdata">Kolekcja zawierająca danę do przesłania poprzez metodę POST</param>
  100.         /// <returns>Typ HttpWebResponse</returns>
  101.         private async Task<HttpWebResponse> DoRawRequestAsync(string builder, NameValueCollection postdata = null)
  102.         {
  103.             HttpWebRequest req = WebRequest.CreateHttp("http://a.wykop.pl/" + builder);
  104.             req.Headers.Add("apisign", CreateSign("http://a.wykop.pl/" + builder, postdata)); // podpisanie
  105.             req.Method = WebRequestMethods.Http.Post;
  106.             req.ContentType = "application/x-www-form-urlencoded";
  107.  
  108.             if (postdata != null)
  109.             {
  110.                 using (Stream stream = await req.GetRequestStreamAsync())
  111.                 {
  112.                     byte[] bytepostdata =
  113.                         Encoding.UTF8.GetBytes(string.Join("&",
  114.                                                            postdata.AllKeys.Select(key => key + '=' + postdata[key])));
  115.  
  116.                     stream.Write(bytepostdata, 0, bytepostdata.Length);
  117.                 }
  118.             }
  119.  
  120.             return (HttpWebResponse) req.GetResponse();
  121.         }
  122.  
  123.         /// <summary>
  124.         /// Wykonuje dowolne żądanie na podstawie zadanego ciągu żądania (bez http://a.wykop.pl) i danych do wysłania poprzez metodę POST
  125.         /// </summary>
  126.         /// <param name="builder">Ciąg znaków reprezentujący ciąg żądania</param>
  127.         /// <param name="postdata">Kolekcja zawierająca danę do przesłania poprzez metodę POST</param>
  128.         /// <returns>Typ T, jako żądany obiekt</returns>
  129.         public T DoCustomRequest<T>(string builder, NameValueCollection postdata = null) where T : class
  130.         {
  131.             HttpWebResponse resp = DoRawRequest(builder, postdata);
  132.             using (var reader = new StreamReader(resp.GetResponseStream()))
  133.             {
  134.                 string str = reader.ReadToEnd();
  135.                 Debug.Print(str);
  136.  
  137.                 var o = JToken.Parse(str) as JObject;
  138.                 JToken jToken;
  139.                 if (o != null && o.TryGetValue("error", out jToken))
  140.                     throw new ApiErrorException((string) jToken["message"], (int) jToken["code"]);
  141.  
  142.                 return JsonConvert.DeserializeObject<T>(str);
  143.             }
  144.         }
  145.  
  146.         /// <summary>
  147.         /// Wykonywuję dowolne żądanie asynchronicznie
  148.         /// </summary>
  149.         /// <param name="builder">Ciąg znaków reprezentujący ciąg żądania</param>
  150.         /// <param name="postdata">Kolekcja zawierająca danę do przesłania poprzez metodę POST</param>
  151.         /// <returns>Typ T, jako jako żądany obiekt</returns>
  152.         public async Task<T> DoCustomRequestAsync<T>(string builder, NameValueCollection postdata = null) where T : class
  153.         {
  154.             HttpWebResponse resp = await DoRawRequestAsync(builder, postdata);
  155.             using (var reader = new StreamReader(resp.GetResponseStream()))
  156.             {
  157.                 string str = reader.ReadToEnd();
  158.                 Debug.Print(str);
  159.  
  160.                 var o = JToken.Parse(str) as JObject;
  161.                 JToken jToken;
  162.                 if (o != null && o.TryGetValue("error", out jToken))
  163.                     throw new ApiErrorException((string) jToken["message"], (int) jToken["code"]);
  164.  
  165.                 return JsonConvert.DeserializeObject<T>(str);
  166.             }
  167.         }
  168.     }
  169.  
  170.     [Serializable]
  171.     public class ApiErrorException : Exception
  172.     {
  173.         public ApiErrorException()
  174.         {
  175.         }
  176.  
  177.         public ApiErrorException(string message)
  178.             : base(message)
  179.         {
  180.         }
  181.  
  182.         public ApiErrorException(string message, Exception inner)
  183.             : base(message, inner)
  184.         {
  185.         }
  186.  
  187.         public ApiErrorException(string message, int code)
  188.             : base(message)
  189.         {
  190.             ErrorCode = code;
  191.         }
  192.  
  193.         protected ApiErrorException(
  194.             SerializationInfo info,
  195.             StreamingContext context)
  196.             : base(info, context)
  197.         {
  198.         }
  199.  
  200.         public int ErrorCode { get; private set; }
  201.     }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment