Skip to content

Commit

Permalink
merge: Branch 'devel'.
Browse files Browse the repository at this point in the history
  • Loading branch information
Starciad committed Feb 6, 2024
2 parents 6643f92 + 9c9f6fe commit 6c5b8ee
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 151 deletions.
38 changes: 1 addition & 37 deletions .github/docs/entities/posts.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,43 +91,7 @@ foreach(R34Post post in posts.Data)

## `3.` FILTERING POSTS

Eventually, it may be useful to filter posts based on specific conditions, for example, you only want videos instead of images, and for that, you can use the system library **System.Linq** to filter all types of posts.

Observe the example below and see that, using the **Where** method, I filter all the contents of the request to only have videos.

<br/>

- _Import of the system library namespace;_
```cs
using System.Linq;
```

<br/>

- _Example of post filtering;_
```cs
// Execution of the request.
R34Posts posts = await client.Posts.GetPostsAsync(new R34PostsSearchBuilder()
{
Limit = 1000,
Tags = new R34TagModel[] {
new R34TagModel("Bowser"),
},
});

// Filter the collection to only hold videos.
IEnumerable<R34Post> filteredPosts = posts.Data.Where(x => x.FileMediaType == FileMediaType.Video);

// Reads the name of all posts from the enumeration.
foreach (R34Post post in filteredPosts)
{
Console.WriteLine(post.FileName);
}
```

<br/>

With this example, you can observe the amount of possibilities that are provided to you for your own manipulation of posts.
For detailed information on how to filter and improve post searches, see **search_cheatsheet.md** in the utilities directory.

## `4.` SEARCHING FOR POST OFFSET
As you develop and create new things, it might be interesting to go beyond 1000 posts, let's assume you want to request 2000 posts this time, how could you do that if the allowed limit is 1000? Simple, using **Search Offsets**.
Expand Down
102 changes: 102 additions & 0 deletions .github/docs/utilities/search_cheatsheet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<br/>
<h1 align="center"> ✨ ● CHEATSHEET ● ✨ </h1>

## Credits

You can check the original page [by clicking here](https://rule34.xxx/index.php?page=help&topic=cheatsheet).

## Settings

### Combining Tags

`tag1 tag2`
Search for posts that have tag1 and tag2.

### Logical OR

`( tag1 ~ tag2 )`
Search for posts that have tag1 or tag2. The parentheses are important to group the tags between which the "or" counts. The spaces between the parentheses and tags are also important because some tags end in parentheses!

### Fuzzy Search

`night~`
Fuzzy search for the tag night. This will return results such as night fight bright and so on according to the Levenshtein distance.

### Excluding Tags

`-tag1`
Search for posts that don't have tag1.

### Wildcard Search

`ta*1`
Search for posts with tags that start with "ta" and end with "1".

### User Specific

`user:bob`
Search for posts uploaded by the user Bob.

### MD5 Hash Search

`md5:foo`
Search for posts with the MD5 hash foo.

### MD5 Hash Prefix Search

`md5:foo*`
Search for posts whose MD5 starts with the MD5 hash foo.

### Questionable Rating

`rating:questionable`
Search for posts that are rated questionable.

### Exclude Questionable Rating

`-rating:questionable`
Search for posts that are not rated questionable.

### Parent Post Search

`parent:1234`
Search for posts that have 1234 as a parent (and include post 1234).

### Combined Rating Search

`rating:questionable rating:safe`
In general, combining the same metatags (the ones that have colons in them) will not work.

### Combined Metatags

`rating:questionable parent:100`
You can combine different metatags, however.

### Dimensional Search

`width:>=1000 height:>1000`
Find images with a width greater than or equal to 1000 and a height greater than 1000.

### Score Threshold

`score:>=10`
Find images with a score greater than or equal to 10. This value is updated once daily at 12AM CST.

### Sort by Updated Date

`sort:updated:desc`
Sort posts by their most recently updated order.

### Other Sortable Types

- id
- score
- rating
- user
- height
- width
- parent
- source
- updated
-
Can be sorted by both asc or desc.
3 changes: 2 additions & 1 deletion src/R34Sharp.Experimental/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ private static async Task Main()
Tags = new R34FormattedTag[]
{
new("Bara"),
new("-Video"),
},
};

Console.Clear();
Console.WriteLine(" [ STARTING ] ");
Console.WriteLine($"Path: {AssetsDirectory}");

R34Posts posts = await _client.Posts.GetPostsByFilterAsync(searchBuilder, x => x.FileType == R34FileType.Image);
R34Posts posts = await _client.Posts.GetPostsAsync(searchBuilder);
Console.WriteLine($"Request Completed!");

int count = 0;
Expand Down
20 changes: 1 addition & 19 deletions src/R34Sharp.Tests/Posts/R34PostsTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using R34Sharp.Entities.Posts;
using R34Sharp.Enums;
using R34Sharp.Models;
using R34Sharp.Search;

Expand All @@ -11,10 +10,7 @@ public class R34PostsTests
private static readonly R34FormattedTag[] tagsPrefab = new R34FormattedTag[]
{
new("Little Mac"),
};
private static readonly R34FormattedTag[] blockedTagsPrefab = new R34FormattedTag[]
{
new("Looking At Viewer"),
new("-Looking At Viewer"),
};

[Fact]
Expand All @@ -29,27 +25,13 @@ public async Task Get_One_Post_Async()
Assert.Equal<ulong>(1, posts.Count);
}

[Fact]
public async Task Filter_All_Posts_To_Get_Videos_Async()
{
R34Posts posts = await _client.Posts.GetPostsByFilterAsync(new()
{
Limit = 1000,
Tags = tagsPrefab

}, x => x.FileType == R34FileType.Video);

Assert.All(posts.Data, x => Assert.True(x.FileType == R34FileType.Video));
}

[Fact]
public async Task Blocking_Posts_That_Contain_Certain_Tags_Async()
{
R34Posts posts = await _client.Posts.GetPostsAsync(new()
{
Limit = 1000,
Tags = tagsPrefab,
BlockedTags = blockedTagsPrefab,
});

Assert.All(posts.Data, x => Assert.False(x.HasTag(new("Looking At Viewer"))));
Expand Down
16 changes: 0 additions & 16 deletions src/R34Sharp.Tests/Search/R34PostsSearchBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public void Constructor_DefaultValues_Success()
Assert.Equal(0ul, searchBuilder.Id.Value);
Assert.Equal(0, searchBuilder.Offset.Value);
Assert.Empty(searchBuilder.Tags);
Assert.Empty(searchBuilder.BlockedTags);
}

[Fact]
Expand Down Expand Up @@ -76,21 +75,6 @@ public void WithTags_ValidValue_ReturnsBuilderWithTags()
Assert.Same(searchBuilder, result);
}

[Fact]
public void WithBlockedTags_ValidValue_ReturnsBuilderWithBlockedTags()
{
// Arrange
R34PostsSearchBuilder searchBuilder = new();
R34FormattedTag[] blockedTags = new R34FormattedTag[] { new("blocked1"), new("blocked2") };

// Act
R34PostsSearchBuilder result = searchBuilder.WithBlockedTags(blockedTags);

// Assert
Assert.Equal(blockedTags, searchBuilder.BlockedTags);
Assert.Same(searchBuilder, result);
}

[Theory]
[InlineData(1)]
[InlineData(1000)]
Expand Down
54 changes: 0 additions & 54 deletions src/R34Sharp/Components/R34PostsComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
using R34Sharp.Url;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Serialization;

Expand Down Expand Up @@ -49,59 +47,7 @@ public async Task<R34Posts> GetPostsAsync(R34PostsSearchBuilder searchBuilder)

R34Posts postsResult = await GetAsync<R34Posts>(urlBuilder.Build(), this._postsXmlSerializer).ConfigureAwait(false);

if (searchBuilder.BlockedTags.Length > 0)
{
postsResult.Data = postsResult.Data.Where(x => !x.HasTags(searchBuilder.BlockedTags)).ToArray();
}

return postsResult;
}

/// <summary>
/// Get a complete list of Posts up to the selected limit based on a specified filter.
/// </summary>
/// <remarks>
/// This method performs multiple searches until it finds all posts (specified in the search limit) or until there is no more content. Depending on the types of conditions selected the method can introduce significant delay and result in a possible TimeOut, so use it wisely.<br/><br/>
/// If your filter is very trivial, it is recommended to use <see cref="GetPostsAsync"/>.
/// </remarks>
/// <param name="searchBuilder">Search builder for Rule34 Posts.</param>
/// <param name="filter">The filter that will be applied to each request result.</param>
/// <returns>A collection of Rule34 posts.</returns>
/// <exception cref="IndexOutOfRangeException" />
/// <exception cref="ArgumentException" />
public async Task<R34Posts> GetPostsByFilterAsync(R34PostsSearchBuilder searchBuilder, Func<R34Post, bool> filter)
{
List<R34Post> foundPosts = new();

// Requests
int currentChunk = 0;
int currentOffset = 0;

while (true)
{
currentOffset += currentChunk;
R34Posts posts = await GetPostsAsync(searchBuilder).ConfigureAwait(false);

if (posts == null || posts.Data == null || posts.Count == 0)
{
break;
}

foundPosts.AddRange(posts.Data.Where(filter));
if (foundPosts.Count >= searchBuilder.Limit)
{
break;
}

currentChunk++;
}

// Return
return new R34Posts
{
Data = foundPosts.Take(searchBuilder.Limit).ToArray(),
Offset = (currentOffset + currentChunk) / 2,
};
}
}
}
2 changes: 1 addition & 1 deletion src/R34Sharp/R34Sharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<PropertyGroup>
<Description>An unofficial .NET Core wrapper for the Rule34 API.</Description>
<PackageReleaseNotes>General changes and reorganizations of the project, aiming at performance and process optimization.</PackageReleaseNotes>
<PackageReleaseNotes>Removal of dangerous/redundant functions.</PackageReleaseNotes>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageReadmeFile>README.md</PackageReadmeFile>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
Expand Down
22 changes: 0 additions & 22 deletions src/R34Sharp/Search/R34PostsSearchBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,8 @@ public int Limit
/// </summary>
public R34FormattedTag[] Tags { get => this._tags; set => this._tags = value; }

/// <summary>
/// The tags that will be ignored when searching for Posts.
/// </summary>
public R34FormattedTag[] BlockedTags { get => this._blockedTags; set => this._blockedTags = value; }

private int _limit;
private R34FormattedTag[] _tags;
private R34FormattedTag[] _blockedTags;

/// <summary>
/// Build a custom search for Rule34 Posts.
Expand All @@ -69,7 +63,6 @@ public R34PostsSearchBuilder()
{
_ = WithLimit(100);
_ = WithTags(Array.Empty<R34FormattedTag>());
_ = WithBlockedTags(Array.Empty<R34FormattedTag>());

this.Id = new();
this.Offset = new();
Expand All @@ -79,10 +72,6 @@ internal string GetTagsString()
{
return ConvertTagsToString(this._tags);
}
internal string GetBlockedTagsString()
{
return ConvertTagsToString(this._blockedTags);
}

/// <summary>
/// Set the post search limit.
Expand Down Expand Up @@ -128,17 +117,6 @@ public R34PostsSearchBuilder WithTags(R34FormattedTag[] tags)
return this;
}

/// <summary>
/// Define the blocked tags that will be ignored in the search.
/// </summary>
/// <param name="tags">The tags collection.</param>
/// <returns>This search builder.</returns>
public R34PostsSearchBuilder WithBlockedTags(R34FormattedTag[] tags)
{
this.BlockedTags = tags;
return this;
}

private static string ConvertTagsToString(R34FormattedTag[] tags)
{
return string.Join('+', tags.Where(tag => tag != null).Select(tag => tag.Name));
Expand Down
2 changes: 1 addition & 1 deletion src/Targets/Project_Infos.targets
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

<!-- VERSION -->
<PropertyGroup>
<Version>2.5.0</Version>
<Version>3.0.0</Version>
<VersionPrefix></VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
Expand Down

0 comments on commit 6c5b8ee

Please sign in to comment.