Skip to content

Commit

Permalink
Merge pull request #22 from Shiroechi/dev
Browse files Browse the repository at this point in the history
BooruDex v2
  • Loading branch information
Shiroechi authored Nov 28, 2020
2 parents 328e761 + 8ae34f2 commit 0ff7f7e
Show file tree
Hide file tree
Showing 19 changed files with 838 additions and 618 deletions.
153 changes: 108 additions & 45 deletions Booru/Booru.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Xml;

using BooruDex.Exceptions;
using BooruDex.Models;

using Litdex.Security.RNG;
using Litdex.Security.RNG.PRNG;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace BooruDex.Booru
{
/// <summary>
Expand All @@ -23,22 +23,22 @@ public abstract class Booru
#region Member

/// <summary>
/// Browser
/// Http client to send reuquest and receive response.
/// </summary>
private HttpClient _HttpClient;

/// <summary>
/// Base API request URL.
/// </summary>
protected Uri _BaseUrl;

/// <summary>
/// Max retrieved post for each request.
/// </summary>
protected byte _PostLimit;

/// <summary>
/// Max tags to use for search a post.
/// Max allowed <see cref="Tag"/>s to use for search a <see cref="Post"/>.
/// </summary>
protected byte _TagsLimit;

Expand All @@ -57,7 +57,7 @@ public abstract class Booru
/// functions that modify the content).
/// </summary>
protected string _Username;

/// <summary>
/// Your user password in plain text (Required only
/// for functions that modify the content).
Expand Down Expand Up @@ -90,7 +90,7 @@ public abstract class Booru
/// <param name="domain">URL of booru based sites.</param>
public Booru(string domain) : this(domain, null, new SplitMix64())
{

}

/// <summary>
Expand All @@ -100,7 +100,7 @@ public abstract class Booru
/// <param name="httpClient">Client for sending and receive http response.</param>
public Booru(string domain, HttpClient httpClient = null) : this(domain, httpClient, new SplitMix64())
{

}

/// <summary>
Expand All @@ -123,7 +123,11 @@ public Booru(string domain, HttpClient httpClient, IRNG rng)
/// </summary>
~Booru()
{

this._BaseUrl = null;
this._ApiVersion =
this._Password =
this._PasswordSalt =
this._Username = null;
}

#endregion Constructor & Destructor
Expand Down Expand Up @@ -181,10 +185,10 @@ private set
/// <summary>
/// Gets or sets maximum page number for booru.
/// </summary>
public byte PageLimit
protected byte PageLimit
{
set
{
{
if (value < 10)
{
this._PageLimit = 10;
Expand Down Expand Up @@ -214,7 +218,7 @@ public void AddHttpHeader()
{
if (this._HttpClient == null)
{
return;
return;
}

if (this._HttpClient.DefaultRequestHeaders.UserAgent.Count == 0)
Expand Down Expand Up @@ -245,6 +249,9 @@ public void AddHttpHeader()
/// <exception cref="TaskCanceledException">
/// The request failed due timeout.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
protected async Task<T> GetJsonResponseAsync<T>(string url)
{
try
Expand All @@ -255,7 +262,14 @@ protected async Task<T> GetJsonResponseAsync<T>(string url)
{
if (response.IsSuccessStatusCode)
{
return this.DeserializeJsonFromStream<T>(stream);
try
{
return await JsonSerializer.DeserializeAsync<T>(stream);
}
catch (JsonException e)
{
throw e;
}
}

throw new HttpResponseException(
Expand Down Expand Up @@ -318,27 +332,6 @@ protected async Task<string> GetStringResponseAsync(string url)
}
}

/// <summary>
/// Deserializes the JSON structure into an instance of the specified type.
/// </summary>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <param name="stream"></param>
/// <returns>The instance of <typeparamref name="T"/> being deserialized.</returns>
protected T DeserializeJsonFromStream<T>(Stream stream)
{
if (stream == null || stream.CanRead == false)
{
return default(T);
}

using (var sr = new StreamReader(stream))
using (JsonReader reader = new JsonTextReader(sr))
{
JsonSerializer serializer = new JsonSerializer();
return serializer.Deserialize<T>(reader);
}
}

/// <summary>
/// Deserializes response into string.
/// </summary>
Expand All @@ -348,7 +341,7 @@ protected Task<string> DeserializeStringFromStreamAsync(Stream stream)
{
if (stream != null)
{
using (var sr = new StreamReader(stream))
using (var sr = new StreamReader(stream, Encoding.UTF8))
{
return sr.ReadToEndAsync();
}
Expand All @@ -357,6 +350,49 @@ protected Task<string> DeserializeStringFromStreamAsync(Stream stream)
return null;
}

/// <summary>
/// Get max number of <see cref="Post"/> with
/// the given <see cref="Tag"/> the site have.
/// </summary>
/// <param name="url">Url of the requested <see cref="Post"/>.</param>
/// <returns>Number of <see cref="Post"/>.</returns>
/// <exception cref="XmlException">
/// There is a load or parse error in the XML.
/// </exception>
/// <exception cref="FormatException">
/// Can't convert to <see cref="uint"/>.
/// </exception>
protected async Task<uint> GetPostCountAsync(string url)
{
try
{
var xml = new XmlDocument();
xml.LoadXml(await this.GetStringResponseAsync(url));
return uint.Parse(xml.ChildNodes.Item(1).Attributes[0].InnerXml);
}
catch (XmlException e)
{
throw e;
}
catch (FormatException e)
{
throw e;
}
}

/// <summary>
/// Check the property of JSON object exist or not.
/// </summary>
/// <param name="json">JSON object.</param>
/// <param name="propertyName">The name of the property to find.</param>
/// <returns>
/// <see langword="true"/> if the property was found; otherwise, <see langword="false"/>.
/// </returns>
protected bool PropertyExist(JsonElement json, string propertyName)
{
return json.TryGetProperty(propertyName, out _);
}

/// <summary>
/// Create base API call url.
/// </summary>
Expand All @@ -372,7 +408,7 @@ protected Task<string> DeserializeStringFromStreamAsync(Stream stream)
/// <returns></returns>
protected Rating ConvertRating(string rating)
{
switch (rating.ToString()[0])
switch (rating.ToLower()[0])
{
case 'e':
return Rating.Explicit;
Expand All @@ -393,7 +429,7 @@ protected Rating ConvertRating(string rating)
/// <exception cref="NotImplementedException">
/// Method is not implemented yet.
/// </exception>
protected virtual Artist ReadArtist(JToken json)
protected virtual Artist ReadArtist(JsonElement json)
{
throw new NotImplementedException($"Method { nameof(ReadArtist) } is not implemented yet.");
}
Expand All @@ -406,7 +442,7 @@ protected virtual Artist ReadArtist(JToken json)
/// <exception cref="NotImplementedException">
/// Method is not implemented yet.
/// </exception>
protected virtual Pool ReadPool(JToken json)
protected virtual Pool ReadPool(JsonElement json)
{
throw new NotImplementedException($"Method { nameof(ReadPool) } is not implemented yet.");
}
Expand All @@ -419,7 +455,7 @@ protected virtual Pool ReadPool(JToken json)
/// <exception cref="NotImplementedException">
/// Method is not implemented yet.
/// </exception>
protected virtual Post ReadPost(JToken json)
protected virtual Post ReadPost(JsonElement json)
{
throw new NotImplementedException($"Method { nameof(ReadPost) } is not implemented yet.");
}
Expand All @@ -432,7 +468,7 @@ protected virtual Post ReadPost(JToken json)
/// <exception cref="NotImplementedException">
/// Method is not implemented yet.
/// </exception>
protected virtual Tag ReadTag(JToken json)
protected virtual Tag ReadTag(JsonElement json)
{
throw new NotImplementedException($"Method { nameof(ReadTag) } is not implemented yet.");
}
Expand All @@ -445,7 +481,7 @@ protected virtual Tag ReadTag(JToken json)
/// <exception cref="NotImplementedException">
/// Method is not implemented yet.
/// </exception>
protected virtual TagRelated ReadTagRelated(JToken json)
protected virtual TagRelated ReadTagRelated(JsonElement json)
{
throw new NotImplementedException($"Method { nameof(ReadTagRelated) } is not implemented yet.");
}
Expand All @@ -458,7 +494,7 @@ protected virtual TagRelated ReadTagRelated(JToken json)
/// <exception cref="NotImplementedException">
/// Method is not implemented yet.
/// </exception>
protected virtual Wiki ReadWiki(JToken json)
protected virtual Wiki ReadWiki(JsonElement json)
{
throw new NotImplementedException($"Method { nameof(ReadWiki) } is not implemented yet.");
}
Expand All @@ -473,7 +509,7 @@ protected virtual Wiki ReadWiki(JToken json)
/// <param name="username">Your username.</param>
/// <param name="password">Your password.</param>
/// <returns></returns>
public bool Authenticate(string username, string password)
protected bool Authenticate(string username, string password)
{
throw new NotImplementedException($"Method { nameof(Authenticate) } is not implemented yet.");
this._Username = username;
Expand Down Expand Up @@ -507,6 +543,9 @@ public bool Authenticate(string username, string password)
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="Artist"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<Artist[]> ArtistListAsync(string name, uint page = 0, bool sort = false)
{
throw new NotImplementedException($"Method { nameof(ArtistListAsync) } is not implemented yet.");
Expand Down Expand Up @@ -538,6 +577,9 @@ public virtual Task<Artist[]> ArtistListAsync(string name, uint page = 0, bool s
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="Pool"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<Pool[]> PoolList(string title, uint page = 0)
{
throw new NotImplementedException($"Method { nameof(PoolList) } is not implemented yet.");
Expand All @@ -564,6 +606,9 @@ public virtual Task<Pool[]> PoolList(string title, uint page = 0)
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="Post"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<Post[]> PoolPostList(uint poolId)
{
throw new NotImplementedException($"Method { nameof(PoolPostList) } is not implemented yet.");
Expand Down Expand Up @@ -598,6 +643,9 @@ public virtual Task<Post[]> PoolPostList(uint poolId)
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="Post"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<Post[]> PostListAsync(uint limit, string[] tags, uint page = 0)
{
throw new NotImplementedException($"Method { nameof(PostListAsync) } is not implemented yet.");
Expand Down Expand Up @@ -626,6 +674,9 @@ public virtual Task<Post[]> PostListAsync(uint limit, string[] tags, uint page =
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="Post"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<Post> GetRandomPostAsync(string[] tags = null)
{
throw new NotImplementedException($"Method { nameof(GetRandomPostAsync) } is not implemented yet.");
Expand Down Expand Up @@ -655,6 +706,9 @@ public virtual Task<Post> GetRandomPostAsync(string[] tags = null)
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="Post"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<Post[]> GetRandomPostAsync(uint limit, string[] tags = null)
{
throw new NotImplementedException($"Method { nameof(GetRandomPostAsync) } is not implemented yet.");
Expand Down Expand Up @@ -687,6 +741,9 @@ public virtual Task<Post[]> GetRandomPostAsync(uint limit, string[] tags = null)
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="Tag"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<Tag[]> TagListAsync(string name)
{
throw new NotImplementedException($"Method { nameof(TagListAsync) } is not implemented yet.");
Expand Down Expand Up @@ -716,6 +773,9 @@ public virtual Task<Tag[]> TagListAsync(string name)
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="TagRelated"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<TagRelated[]> TagRelatedAsync(string name, TagType type = TagType.General)
{
throw new NotImplementedException($"Method { nameof(TagRelatedAsync) } is not implemented yet.");
Expand Down Expand Up @@ -748,6 +808,9 @@ public virtual Task<TagRelated[]> TagRelatedAsync(string name, TagType type = Ta
/// <exception cref="SearchNotFoundException">
/// The search result is empty. No <see cref="Wiki"/> is found.
/// </exception>
/// <exception cref="JsonException">
/// The JSON is invalid.
/// </exception>
public virtual Task<Wiki[]> WikiListAsync(string title)
{
throw new NotImplementedException($"Method { nameof(WikiListAsync) } is not implemented yet.");
Expand Down
1 change: 0 additions & 1 deletion Booru/Client/DanbooruDonmai.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@ public DanbooruDonmai(HttpClient httpClient = null) : base("https://danbooru.don
}

#endregion Constructor & Destructor

}
}
Loading

0 comments on commit 0ff7f7e

Please sign in to comment.