PageRenderTime 55ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/ShareX.UploadersLib/FileUploaders/Minus.cs

https://gitlab.com/billyprice1/ShareX
C# | 394 lines | 314 code | 60 blank | 20 comment | 32 complexity | 41eebdddf897e3d390a5f03b53cd0d19 MD5 | raw file
  1. #region License Information (GPL v3)
  2. /*
  3. ShareX - A program that allows you to take screenshots and share any file type
  4. Copyright (c) 2007-2016 ShareX Team
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. Optionally you can also view the license at <http://www.gnu.org/licenses/>.
  17. */
  18. #endregion License Information (GPL v3)
  19. using Newtonsoft.Json;
  20. using ShareX.HelpersLib;
  21. using ShareX.UploadersLib.Properties;
  22. using System;
  23. using System.Collections.Generic;
  24. using System.Drawing;
  25. using System.IO;
  26. using System.Windows.Forms;
  27. namespace ShareX.UploadersLib.FileUploaders
  28. {
  29. public class MinusFileUploaderService : FileUploaderService
  30. {
  31. public override FileDestination EnumValue { get; } = FileDestination.Minus;
  32. public override Icon ServiceIcon => Resources.Minus;
  33. public override bool CheckConfig(UploadersConfig config)
  34. {
  35. return config.MinusConfig != null && config.MinusConfig.MinusUser != null;
  36. }
  37. public override GenericUploader CreateUploader(UploadersConfig config, TaskReferenceHelper taskInfo)
  38. {
  39. return new Minus(config.MinusConfig, config.MinusOAuth2Info);
  40. }
  41. public override TabPage GetUploadersConfigTabPage(UploadersConfigForm form) => form.tpMinus;
  42. }
  43. public class Minus : FileUploader
  44. {
  45. private const string URL_HOST = "https://minus.com";
  46. private const string URL_OAUTH_TOKEN = URL_HOST + "/oauth/token";
  47. private const string URL_API = URL_HOST + "/api/v2";
  48. public MinusOptions Config { get; set; }
  49. public OAuth2Info AuthInfo { get; set; }
  50. public Minus(MinusOptions config, OAuth2Info auth)
  51. {
  52. Config = config;
  53. AuthInfo = auth;
  54. }
  55. public bool GetAccessToken()
  56. {
  57. Dictionary<string, string> args = new Dictionary<string, string>();
  58. args.Add("grant_type", "password");
  59. args.Add("client_id", AuthInfo.Client_ID);
  60. args.Add("client_secret", AuthInfo.Client_Secret);
  61. args.Add("scope", "read_public read_all upload_new modify_all");
  62. args.Add("username", Config.Username);
  63. args.Add("password", Config.Password);
  64. string response = SendRequest(HttpMethod.POST, URL_OAUTH_TOKEN, args);
  65. if (!string.IsNullOrEmpty(response))
  66. {
  67. OAuth2Token token = JsonConvert.DeserializeObject<OAuth2Token>(response);
  68. if (token != null && !string.IsNullOrEmpty(token.access_token))
  69. {
  70. token.UpdateExpireDate();
  71. AuthInfo.Token = token;
  72. return true;
  73. }
  74. }
  75. return false;
  76. }
  77. public bool RefreshAccessToken()
  78. {
  79. if (OAuth2Info.CheckOAuth(AuthInfo) && !string.IsNullOrEmpty(AuthInfo.Token.refresh_token))
  80. {
  81. Dictionary<string, string> args = new Dictionary<string, string>();
  82. args.Add("grant_type", "refresh_token");
  83. args.Add("client_id", AuthInfo.Client_ID);
  84. args.Add("client_secret", AuthInfo.Client_Secret);
  85. args.Add("scope", AuthInfo.Token.scope);
  86. args.Add("refresh_token", AuthInfo.Token.refresh_token);
  87. string response = SendRequest(HttpMethod.POST, URL_OAUTH_TOKEN, args);
  88. if (!string.IsNullOrEmpty(response))
  89. {
  90. OAuth2Token token = JsonConvert.DeserializeObject<OAuth2Token>(response);
  91. if (token != null && !string.IsNullOrEmpty(token.access_token))
  92. {
  93. token.UpdateExpireDate();
  94. AuthInfo.Token = token;
  95. return true;
  96. }
  97. }
  98. }
  99. return false;
  100. }
  101. public bool CheckAuthorization()
  102. {
  103. if (OAuth2Info.CheckOAuth(AuthInfo))
  104. {
  105. if (AuthInfo.Token.IsExpired && !RefreshAccessToken())
  106. {
  107. Errors.Add("Refresh access token failed.");
  108. return false;
  109. }
  110. }
  111. else
  112. {
  113. Errors.Add("Login is required.");
  114. return false;
  115. }
  116. return true;
  117. }
  118. private string GetActiveUserFolderURL()
  119. {
  120. MinusUser user = Config.MinusUser ?? (Config.MinusUser = GetActiveUser());
  121. return URL_API + "/users/" + user.slug + "/folders?bearer_token=" + AuthInfo.Token.access_token;
  122. }
  123. public MinusUser GetActiveUser()
  124. {
  125. string url = URL_API + "/activeuser?bearer_token=" + AuthInfo.Token.access_token;
  126. string response = SendRequest(HttpMethod.GET, url);
  127. return JsonConvert.DeserializeObject<MinusUser>(response);
  128. }
  129. private MinusFolderListResponse GetUserFolderList()
  130. {
  131. string response = SendRequest(HttpMethod.GET, GetActiveUserFolderURL());
  132. return JsonConvert.DeserializeObject<MinusFolderListResponse>(response);
  133. }
  134. public List<MinusFolder> ReadFolderList()
  135. {
  136. MinusFolderListResponse mflr = GetUserFolderList();
  137. if (mflr.results != null && mflr.results.Length > 0)
  138. {
  139. Config.FolderList.Clear();
  140. foreach (MinusFolder minusFolder in mflr.results)
  141. {
  142. Config.FolderList.Add(minusFolder);
  143. }
  144. }
  145. else
  146. {
  147. MinusFolder mf = CreateFolder("ShareX", true);
  148. if (mf != null)
  149. {
  150. Config.FolderList.Add(mf);
  151. }
  152. }
  153. Config.FolderID = 0;
  154. return Config.FolderList;
  155. }
  156. public MinusFolder CreateFolder(string name, bool is_public)
  157. {
  158. Dictionary<string, string> args = new Dictionary<string, string>();
  159. args.Add("name", name);
  160. args.Add("is_public", is_public.ToString().ToLower());
  161. MinusFolder dir;
  162. string response = SendRequest(HttpMethod.POST, GetActiveUserFolderURL(), args);
  163. if (!string.IsNullOrEmpty(response))
  164. {
  165. dir = JsonConvert.DeserializeObject<MinusFolder>(response);
  166. if (dir != null && !string.IsNullOrEmpty(dir.id))
  167. {
  168. Config.FolderList.Add(dir);
  169. return dir;
  170. }
  171. }
  172. return null;
  173. }
  174. public bool DeleteFolder(int index)
  175. {
  176. if (index >= 0 && index < Config.FolderList.Count)
  177. {
  178. MinusFolder folder = Config.FolderList[index];
  179. string url = string.Format("{0}/folders/{1}?bearer_token={2}", URL_API, folder.id, AuthInfo.Token.access_token);
  180. try
  181. {
  182. string response = SendRequest(HttpMethod.DELETE, url);
  183. }
  184. catch
  185. {
  186. return false;
  187. }
  188. Config.FolderList.RemoveAt(index);
  189. return true;
  190. }
  191. return false;
  192. }
  193. public override UploadResult Upload(Stream stream, string fileName)
  194. {
  195. if (!CheckAuthorization())
  196. {
  197. return null;
  198. }
  199. string url = string.Format("{0}/folders/{1}/files?bearer_token={2}", URL_API, Config.GetActiveFolder().id, AuthInfo.Token.access_token);
  200. Dictionary<string, string> args = new Dictionary<string, string>();
  201. args.Add("caption", fileName);
  202. args.Add("filename", fileName);
  203. UploadResult result = UploadData(stream, url, fileName, "file", args);
  204. if (result.IsSuccess)
  205. {
  206. MinusFile minusFile = JsonConvert.DeserializeObject<MinusFile>(result.Response);
  207. if (minusFile != null)
  208. {
  209. string ext = Path.GetExtension(minusFile.name);
  210. switch (Config.LinkType)
  211. {
  212. case MinusLinkType.Direct:
  213. result.URL = string.Format("http://i.minus.com/i{0}{1}", minusFile.id, ext);
  214. break;
  215. case MinusLinkType.Page:
  216. result.URL = string.Format("http://minus.com/l{0}", minusFile.id);
  217. break;
  218. case MinusLinkType.Raw:
  219. result.URL = minusFile.url_rawfile;
  220. break;
  221. }
  222. result.ShortenedURL = string.Format("http://i.min.us/i{0}{1}", minusFile.id, ext);
  223. result.ThumbnailURL = string.Format("http://i.minus.com/j{0}_xs{1}", minusFile.id, ext);
  224. }
  225. }
  226. return result;
  227. }
  228. }
  229. public enum MinusLinkType
  230. {
  231. Direct,
  232. Page,
  233. Raw
  234. }
  235. public abstract class MinusListResponse
  236. {
  237. public int page { get; set; }
  238. public string next { get; set; }
  239. public int per_page { get; set; }
  240. public int total { get; set; }
  241. public int pages { get; set; }
  242. public string previous { get; set; }
  243. }
  244. public class MinusFolderListResponse : MinusListResponse
  245. {
  246. public MinusFolder[] results { get; set; }
  247. }
  248. public class MinusFileListResponse : MinusListResponse
  249. {
  250. public MinusFile[] results { get; set; }
  251. }
  252. public class MinusOptions
  253. {
  254. public string Username { get; set; }
  255. public string Password { get; set; }
  256. public MinusUser MinusUser { get; set; }
  257. public List<MinusFolder> FolderList { get; set; }
  258. public int FolderID { get; set; }
  259. public MinusLinkType LinkType { get; set; }
  260. public MinusOptions()
  261. {
  262. FolderList = new List<MinusFolder>();
  263. LinkType = MinusLinkType.Direct;
  264. }
  265. public MinusFolder GetActiveFolder()
  266. {
  267. return FolderList.ReturnIfValidIndex(FolderID);
  268. }
  269. }
  270. public class MinusUser
  271. {
  272. public string username { get; set; }
  273. public string display_name { get; set; }
  274. public string description { get; set; }
  275. public string email { get; set; }
  276. public string slug { get; set; }
  277. public string fb_profile_link { get; set; }
  278. public string fb_username { get; set; }
  279. public string twitter_screen_name { get; set; }
  280. public int visits { get; set; }
  281. public int karma { get; set; }
  282. public int shared { get; set; }
  283. public string folders { get; set; }
  284. public string url { get; set; }
  285. public string avatar { get; set; }
  286. public long storage_used { get; set; }
  287. public long storage_quota { get; set; }
  288. public override string ToString()
  289. {
  290. return username;
  291. }
  292. }
  293. public class MinusFolder
  294. {
  295. public string id { get; set; }
  296. public string thumbnail_url { get; set; }
  297. public string name { get; set; }
  298. public bool is_public { get; set; }
  299. public int view_count { get; set; }
  300. public string creator { get; set; }
  301. public int file_count { get; set; }
  302. public DateTime date_last_updated { get; set; }
  303. public string files { get; set; }
  304. public string url { get; set; }
  305. public override string ToString()
  306. {
  307. return name;
  308. }
  309. }
  310. public class MinusFile
  311. {
  312. public string id { get; set; }
  313. public string name { get; set; }
  314. public string title { get; set; }
  315. public string caption { get; set; }
  316. public int width { get; set; }
  317. public int height { get; set; }
  318. public int filesize { get; set; }
  319. public string mimetype { get; set; }
  320. public string folder { get; set; }
  321. public string url { get; set; }
  322. public DateTime uploaded { get; set; }
  323. public string url_rawfile { get; set; }
  324. public string url_thumbnail { get; set; }
  325. public override string ToString()
  326. {
  327. return url_rawfile;
  328. }
  329. }
  330. }