using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; using Pathoschild.Http.Client; namespace StardewModdingAPI.Web.Framework.LogParser { /// An API client for Pastebin. internal class PastebinClient : IDisposable { /********* ** Properties *********/ /// The underlying HTTP client. private readonly IClient Client; /// The user key used to authenticate with the Pastebin API. private readonly string UserKey; /// The developer key used to authenticate with the Pastebin API. private readonly string DevKey; /********* ** Public methods *********/ /// Construct an instance. /// The base URL for the Pastebin API. /// The user agent for the API client. /// The user key used to authenticate with the Pastebin API. /// The developer key used to authenticate with the Pastebin API. public PastebinClient(string baseUrl, string userAgent, string userKey, string devKey) { this.Client = new FluentClient(baseUrl).SetUserAgent(userAgent); this.UserKey = userKey; this.DevKey = devKey; } /// Fetch a saved paste. /// The paste ID. public async Task GetAsync(string id) { try { // get from API string content = await this.Client .GetAsync($"raw/{id}") .AsString(); // handle Pastebin errors if (string.IsNullOrWhiteSpace(content)) return new GetPasteResponse { Error = "Received an empty response from Pastebin." }; if (content.StartsWith(" PostAsync(string content) { try { // validate if (string.IsNullOrWhiteSpace(content)) return new SavePasteResponse { Error = "The log content can't be empty." }; // post to API string response = await this.Client .PostAsync("api/api_post.php") .WithBodyContent(new FormUrlEncodedContent(new Dictionary { ["api_option"] = "paste", ["api_user_key"] = this.UserKey, ["api_dev_key"] = this.DevKey, ["api_paste_private"] = "1", // unlisted ["api_paste_name"] = $"SMAPI log {DateTime.UtcNow:s}", ["api_paste_expire_date"] = "1W", // one week ["api_paste_code"] = content })) .AsString(); // handle Pastebin errors if (string.IsNullOrWhiteSpace(response)) return new SavePasteResponse { Error = "Received an empty response from Pastebin." }; if (response.StartsWith("Bad API request")) return new SavePasteResponse { Error = response }; if (!response.Contains("/")) return new SavePasteResponse { Error = $"Received an unknown response: {response}" }; // return paste ID string pastebinID = response.Split("/").Last(); return new SavePasteResponse { Success = true, ID = pastebinID }; } catch (Exception ex) { return new SavePasteResponse { Success = false, Error = ex.ToString() }; } } /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. public void Dispose() { this.Client.Dispose(); } } }