commit
98f22ef1c5
@ -1,2 +1,3 @@
|
||||
pub mod import_builder;
|
||||
pub mod tagging_builder;
|
||||
pub mod tag_builder;
|
||||
|
@ -0,0 +1,479 @@
|
||||
use crate::utils::{format_datetime, format_duration};
|
||||
use crate::wrapper::service::ServiceName;
|
||||
use crate::wrapper::tag::Tag;
|
||||
use chrono::{Datelike, Duration};
|
||||
use mime::Mime;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TagBuilder {
|
||||
negated: bool,
|
||||
name: String,
|
||||
namespace: Option<String>,
|
||||
}
|
||||
|
||||
impl TagBuilder {
|
||||
pub fn new<S: ToString>(name: S) -> Self {
|
||||
Self {
|
||||
negated: false,
|
||||
name: name.to_string(),
|
||||
namespace: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a namespace for the tag
|
||||
pub fn namespace<S: ToString>(mut self, namespace: S) -> Self {
|
||||
self.namespace = Some(namespace.to_string());
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Converts the builder into a system tag builder
|
||||
pub fn system(self) -> SystemTagBuilder {
|
||||
SystemTagBuilder {
|
||||
negated: false,
|
||||
name: self.name,
|
||||
}
|
||||
}
|
||||
|
||||
/// Negates the tag.
|
||||
/// if it has already been negated it will be positive again
|
||||
pub fn negate(mut self) -> Self {
|
||||
self.negated = !self.negated;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Tag {
|
||||
Tag {
|
||||
negated: self.negated,
|
||||
name: self.name,
|
||||
namespace: self.namespace,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SystemTagBuilder {
|
||||
name: String,
|
||||
negated: bool,
|
||||
}
|
||||
|
||||
impl SystemTagBuilder {
|
||||
pub fn new() -> SystemTagBuilder {
|
||||
SystemTagBuilder {
|
||||
name: String::new(),
|
||||
negated: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(self) -> Tag {
|
||||
Tag {
|
||||
negated: self.negated,
|
||||
name: self.name,
|
||||
namespace: Some(String::from("system")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Negates the tag.
|
||||
/// if it has already been negated it will be positive again
|
||||
pub fn negate(mut self) -> Self {
|
||||
self.negated = !self.negated;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// All files stored in the client
|
||||
pub fn everything(self) -> Self {
|
||||
self.change_name("everything")
|
||||
}
|
||||
|
||||
/// Files stored in the inbox
|
||||
pub fn inbox(self) -> Self {
|
||||
self.change_name("inbox")
|
||||
}
|
||||
|
||||
/// Archived files
|
||||
pub fn archive(self) -> Self {
|
||||
self.change_name("archive")
|
||||
}
|
||||
|
||||
/// Files that have a duration (e.g. videos)
|
||||
pub fn has_duration(self) -> Self {
|
||||
self.change_name("has duration")
|
||||
}
|
||||
|
||||
/// Files that don't have a duration
|
||||
pub fn no_duration(self) -> Self {
|
||||
self.change_name("no duration")
|
||||
}
|
||||
|
||||
/// Files with a specific duration
|
||||
pub fn duration(self, comparator: Comparator, value: u64, unit: DurationUnit) -> Self {
|
||||
self.change_name(format!("duration {} {} {}", comparator, value, unit))
|
||||
}
|
||||
|
||||
/// Files that have the best quality in their duplicate group
|
||||
pub fn best_duplicate_quality(self) -> Self {
|
||||
self.change_name("best quality of group")
|
||||
}
|
||||
|
||||
/// Files that don't have the best quality in their duplicate group
|
||||
pub fn not_best_duplicate_quality(self) -> Self {
|
||||
self.change_name("isn't best quality of group")
|
||||
}
|
||||
|
||||
/// Files with audio
|
||||
pub fn has_audio(self) -> Self {
|
||||
self.change_name("has audio")
|
||||
}
|
||||
|
||||
/// Files without audio
|
||||
pub fn no_audio(self) -> Self {
|
||||
self.change_name("no audio")
|
||||
}
|
||||
|
||||
/// Files with tags
|
||||
pub fn has_tags(self) -> Self {
|
||||
self.change_name("has tags")
|
||||
}
|
||||
|
||||
/// Files without tags
|
||||
pub fn no_tags(self) -> Self {
|
||||
self.change_name("no tags")
|
||||
}
|
||||
|
||||
/// Untagged files
|
||||
pub fn untagged(self) -> Self {
|
||||
self.change_name("untagged")
|
||||
}
|
||||
|
||||
/// Files with a specific number of tags
|
||||
pub fn number_of_tags(self, comparator: Comparator, value: u64) -> Self {
|
||||
self.change_name(format!("number of tags {} {}", comparator, value))
|
||||
}
|
||||
|
||||
/// Files with a specific height
|
||||
pub fn height(self, comparator: Comparator, value: u64) -> Self {
|
||||
self.change_name(format!("height {} {}", comparator, value))
|
||||
}
|
||||
|
||||
/// Files with a specific width
|
||||
pub fn width(self, comparator: Comparator, value: u64) -> Self {
|
||||
self.change_name(format!("width {} {}", comparator, value))
|
||||
}
|
||||
|
||||
/// Files with a specific filesize
|
||||
pub fn filesize(self, comparator: Comparator, value: u64, unit: FileSizeUnit) -> Self {
|
||||
self.change_name(format!("filesize {} {} {}", comparator, value, unit))
|
||||
}
|
||||
|
||||
/// Files that are similar to a list of other files with a specific [hamming distance](https://en.wikipedia.org/wiki/Hamming_distance)
|
||||
pub fn similar_to(self, hashes: Vec<String>, distance: u32) -> Self {
|
||||
self.change_name(format!(
|
||||
"similar to {} with distance {}",
|
||||
hashes.join(", "),
|
||||
distance
|
||||
))
|
||||
}
|
||||
|
||||
/// Limit the number of returned files
|
||||
pub fn limit(self, value: u64) -> Self {
|
||||
self.change_name(format!("limit = {}", value))
|
||||
}
|
||||
|
||||
/// Files with a specific mimetype
|
||||
pub fn filetype(self, mimes: Vec<Mime>) -> Self {
|
||||
self.change_name(format!(
|
||||
"filetype = {}",
|
||||
mimes
|
||||
.into_iter()
|
||||
.map(|m| m.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
))
|
||||
}
|
||||
|
||||
/// Files with a specific hash
|
||||
pub fn hash(self, hashes: Vec<String>) -> Self {
|
||||
self.change_name(format!("hash = {}", hashes.join(" ")))
|
||||
}
|
||||
|
||||
/// Files that have been modified before / after / at / around a specific date and time
|
||||
pub fn date_modified<D: Datelike>(self, comparator: Comparator, datetime: D) -> Self {
|
||||
self.change_name(format!(
|
||||
"modified date {} {}",
|
||||
comparator,
|
||||
format_datetime(datetime)
|
||||
))
|
||||
}
|
||||
|
||||
/// Files with a specific import time
|
||||
pub fn time_imported<D: Datelike>(self, comparator: Comparator, datetime: D) -> Self {
|
||||
self.change_name(format!(
|
||||
"time imported {} {}",
|
||||
comparator,
|
||||
format_datetime(datetime)
|
||||
))
|
||||
}
|
||||
|
||||
/// Files that are in a file service or pending to it
|
||||
pub fn file_service(
|
||||
self,
|
||||
comparator: IsComparator,
|
||||
cur_pen: CurrentlyOrPending,
|
||||
service: ServiceName,
|
||||
) -> Self {
|
||||
self.change_name(format!(
|
||||
"file service {} {} {}",
|
||||
comparator, cur_pen, service
|
||||
))
|
||||
}
|
||||
|
||||
/// Files that have a specific number of relationships
|
||||
pub fn number_of_relationships(
|
||||
self,
|
||||
comparator: Comparator,
|
||||
value: u64,
|
||||
relationship: FileRelationshipType,
|
||||
) -> Self {
|
||||
self.change_name(format!(
|
||||
"num file relationships {} {} {}",
|
||||
comparator, value, relationship
|
||||
))
|
||||
}
|
||||
|
||||
/// Files with a specific aspect ratio
|
||||
pub fn ratio(self, wte: WiderTallerEqual, value: (u64, u64)) -> Self {
|
||||
self.change_name(format!("ratio {} {}:{}", wte, value.0, value.1))
|
||||
}
|
||||
|
||||
/// Files with a specific number of pixels
|
||||
pub fn number_of_pixels(self, comparator: Comparator, value: u64, unit: PixelUnit) -> Self {
|
||||
self.change_name(format!("num pixels {} {} {}", comparator, value, unit))
|
||||
}
|
||||
|
||||
/// Files that have been viewed a specific number of times
|
||||
pub fn views(self, view_type: ViewType, comparator: Comparator, value: u64) -> Self {
|
||||
self.change_name(format!("{} views {} {}", view_type, comparator, value))
|
||||
}
|
||||
|
||||
/// Files that have been viewed for a specific number of times
|
||||
pub fn viewtime(self, view_type: ViewType, comparator: Comparator, duration: Duration) -> Self {
|
||||
self.change_name(format!(
|
||||
"{} viewtime {} {}",
|
||||
view_type,
|
||||
comparator,
|
||||
format_duration(duration)
|
||||
))
|
||||
}
|
||||
|
||||
/// Files that have associated urls that match a defined regex
|
||||
pub fn has_url_matching_regex<S: Display>(self, regex: S) -> Self {
|
||||
self.change_name(format!("has url matching regex {}", regex))
|
||||
}
|
||||
|
||||
/// Files that don't have an url that matches a defined regex
|
||||
pub fn does_not_have_url_matching_regex<S: Display>(self, regex: S) -> Self {
|
||||
self.change_name(format!("does not have url matching regex {}", regex))
|
||||
}
|
||||
|
||||
/// Files that have an url that matches a class (e.g. 'safebooru file page')
|
||||
pub fn has_url_with_class<S: Display>(self, class: S) -> Self {
|
||||
self.change_name(format!("has url with class {}", class))
|
||||
}
|
||||
|
||||
/// Files that don't have an url that matches a class (e.g. 'safebooru file page')
|
||||
pub fn does_not_have_url_with_class<S: Display>(self, class: S) -> Self {
|
||||
self.change_name(format!("does not have url with class {}", class))
|
||||
}
|
||||
|
||||
/// Converts a tag namespace (e.g. 'page') into a number and compares it
|
||||
pub fn tag_namespace_as_number<S: Display>(
|
||||
self,
|
||||
namespace: S,
|
||||
comparator: Comparator,
|
||||
value: u64,
|
||||
) -> Self {
|
||||
self.change_name(format!(
|
||||
"tag as number {} {} {}",
|
||||
namespace, comparator, value
|
||||
))
|
||||
}
|
||||
|
||||
fn change_name<S: ToString>(mut self, value: S) -> Self {
|
||||
self.name = value.to_string();
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum Comparator {
|
||||
/// rhs > lhs
|
||||
Greater,
|
||||
/// rhs < lhs
|
||||
Less,
|
||||
/// rhs == lhs
|
||||
Equal,
|
||||
/// If the rhs is in a +-15% range of the lhs
|
||||
Approximate,
|
||||
}
|
||||
|
||||
impl Display for Comparator {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let symbol = match self {
|
||||
Comparator::Greater => ">",
|
||||
Comparator::Less => "<",
|
||||
Comparator::Equal => "=",
|
||||
Comparator::Approximate => "~=",
|
||||
};
|
||||
symbol.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum FileSizeUnit {
|
||||
Bytes,
|
||||
Kilobytes,
|
||||
Megabytes,
|
||||
Gigabytes,
|
||||
}
|
||||
|
||||
impl Display for FileSizeUnit {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self {
|
||||
FileSizeUnit::Bytes => "B",
|
||||
FileSizeUnit::Kilobytes => "KB",
|
||||
FileSizeUnit::Megabytes => "MB",
|
||||
FileSizeUnit::Gigabytes => "GB",
|
||||
};
|
||||
name.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum DurationUnit {
|
||||
Hours,
|
||||
Minutes,
|
||||
Seconds,
|
||||
Milliseconds,
|
||||
}
|
||||
|
||||
impl Display for DurationUnit {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self {
|
||||
DurationUnit::Hours => "hours",
|
||||
DurationUnit::Minutes => "minutes",
|
||||
DurationUnit::Seconds => "seconds",
|
||||
DurationUnit::Milliseconds => "milliseconds",
|
||||
};
|
||||
name.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum IsComparator {
|
||||
Is,
|
||||
IsNot,
|
||||
}
|
||||
|
||||
impl Display for IsComparator {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self {
|
||||
IsComparator::Is => "is",
|
||||
IsComparator::IsNot => "is not",
|
||||
};
|
||||
name.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum CurrentlyOrPending {
|
||||
CurrentlyIn,
|
||||
PendingTo,
|
||||
}
|
||||
|
||||
impl Display for CurrentlyOrPending {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self {
|
||||
CurrentlyOrPending::CurrentlyIn => "currently in",
|
||||
CurrentlyOrPending::PendingTo => "pending to",
|
||||
};
|
||||
name.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum WiderTallerEqual {
|
||||
Wider,
|
||||
Taller,
|
||||
Equal,
|
||||
}
|
||||
|
||||
impl Display for WiderTallerEqual {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self {
|
||||
WiderTallerEqual::Wider => "wider than",
|
||||
WiderTallerEqual::Taller => "taller than",
|
||||
WiderTallerEqual::Equal => "is",
|
||||
};
|
||||
name.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum PixelUnit {
|
||||
Pixels,
|
||||
Kilopixels,
|
||||
Megapixels,
|
||||
}
|
||||
|
||||
impl Display for PixelUnit {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self {
|
||||
PixelUnit::Pixels => "pixels",
|
||||
PixelUnit::Kilopixels => "kilopixels",
|
||||
PixelUnit::Megapixels => "megapixels",
|
||||
};
|
||||
name.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum ViewType {
|
||||
Media,
|
||||
Preview,
|
||||
All,
|
||||
}
|
||||
|
||||
impl Display for ViewType {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self {
|
||||
ViewType::Media => "media",
|
||||
ViewType::Preview => "preview",
|
||||
ViewType::All => "all",
|
||||
};
|
||||
name.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub enum FileRelationshipType {
|
||||
Alternates,
|
||||
FalsePositives,
|
||||
Duplicates,
|
||||
PotentialDuplicates,
|
||||
}
|
||||
|
||||
impl Display for FileRelationshipType {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self {
|
||||
FileRelationshipType::Alternates => "alternates",
|
||||
FileRelationshipType::FalsePositives => "false positives",
|
||||
FileRelationshipType::Duplicates => "duplicates",
|
||||
FileRelationshipType::PotentialDuplicates => "potential duplicates",
|
||||
};
|
||||
name.fmt(f)
|
||||
}
|
||||
}
|
@ -0,0 +1,413 @@
|
||||
use super::super::common;
|
||||
use chrono::{Duration, Local};
|
||||
use hydrus_api::error::Result;
|
||||
use hydrus_api::wrapper::builders::tag_builder::{
|
||||
Comparator, CurrentlyOrPending, FileRelationshipType, FileSizeUnit, IsComparator, PixelUnit,
|
||||
SystemTagBuilder, ViewType, WiderTallerEqual,
|
||||
};
|
||||
use hydrus_api::wrapper::service::ServiceName;
|
||||
use hydrus_api::wrapper::tag::Tag;
|
||||
|
||||
async fn retrieve_single_tag(tag: Tag) -> Result<()> {
|
||||
let hydrus = common::get_hydrus();
|
||||
hydrus.search(vec![tag]).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_everything() {
|
||||
let tag = SystemTagBuilder::new().everything().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_everything_negated() {
|
||||
let tag = SystemTagBuilder::new().everything().negate().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_the_inbox() {
|
||||
let tag = SystemTagBuilder::new().inbox().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_archived_files() {
|
||||
let tag = SystemTagBuilder::new().archive().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_duration() {
|
||||
let tag = SystemTagBuilder::new().has_duration().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_without_duration() {
|
||||
let tag = SystemTagBuilder::new().no_duration().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_the_best_from_duplicates() {
|
||||
let tag = SystemTagBuilder::new().best_duplicate_quality().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_worse_duplicates() {
|
||||
let tag = SystemTagBuilder::new().not_best_duplicate_quality().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_audio() {
|
||||
let tag = SystemTagBuilder::new().has_audio().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_without_audio() {
|
||||
let tag = SystemTagBuilder::new().no_audio().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_tags() {
|
||||
let tag = SystemTagBuilder::new().has_tags().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_without_tags() {
|
||||
let tag = SystemTagBuilder::new().no_tags().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_untagged_files() {
|
||||
let tag = SystemTagBuilder::new().untagged().build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_tags() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.number_of_tags(Comparator::Greater, 12)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_height() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.height(Comparator::Approximate, 200)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_width() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.width(Comparator::Equal, 200)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_size_in_gigabytes() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.filesize(Comparator::Less, 200, FileSizeUnit::Gigabytes)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_size_in_megabytes() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.filesize(Comparator::Less, 200, FileSizeUnit::Megabytes)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_size_in_kilobytes() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.filesize(Comparator::Less, 200, FileSizeUnit::Kilobytes)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_size_in_bytes() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.filesize(Comparator::Less, 200, FileSizeUnit::Bytes)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_that_are_similar_to_others() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.similar_to(
|
||||
vec![String::from(
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
)],
|
||||
20,
|
||||
)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_limits_results() {
|
||||
let tag = SystemTagBuilder::new().limit(50).build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_modification_date() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.date_modified(Comparator::Greater, Local::now())
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_import_time() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.time_imported(Comparator::Less, Local::now())
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_of_a_service() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.file_service(
|
||||
IsComparator::Is,
|
||||
CurrentlyOrPending::CurrentlyIn,
|
||||
ServiceName::my_files(),
|
||||
)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_that_are_not_of_a_service() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.file_service(
|
||||
IsComparator::IsNot,
|
||||
CurrentlyOrPending::CurrentlyIn,
|
||||
ServiceName::my_files(),
|
||||
)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_pending_to_service() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.file_service(
|
||||
IsComparator::Is,
|
||||
CurrentlyOrPending::PendingTo,
|
||||
ServiceName::my_files(),
|
||||
)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_not_pending_to_service() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.file_service(
|
||||
IsComparator::IsNot,
|
||||
CurrentlyOrPending::PendingTo,
|
||||
ServiceName::my_files(),
|
||||
)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_alternate_relationships() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.number_of_relationships(Comparator::Approximate, 3, FileRelationshipType::Alternates)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_duplicate_relationships() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.number_of_relationships(Comparator::Approximate, 3, FileRelationshipType::Duplicates)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_false_positive_relationships() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.number_of_relationships(
|
||||
Comparator::Approximate,
|
||||
3,
|
||||
FileRelationshipType::FalsePositives,
|
||||
)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_potential_duplicate_relationships() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.number_of_relationships(
|
||||
Comparator::Approximate,
|
||||
3,
|
||||
FileRelationshipType::PotentialDuplicates,
|
||||
)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_wider_than_a_specific_ratio() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.ratio(WiderTallerEqual::Wider, (40, 50))
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_taller_than_a_specific_ratio() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.ratio(WiderTallerEqual::Taller, (40, 50))
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_taller_with_specific_ratio() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.ratio(WiderTallerEqual::Equal, (40, 50))
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_megapixels() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.number_of_pixels(Comparator::Less, 50, PixelUnit::Megapixels)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_kilopixels() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.number_of_pixels(Comparator::Equal, 50, PixelUnit::Kilopixels)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_pixels() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.number_of_pixels(Comparator::Greater, 50, PixelUnit::Pixels)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_views() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.views(ViewType::All, Comparator::Less, 1000)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_preview_views() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.views(ViewType::Preview, Comparator::Equal, 1000)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_number_of_media_views() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.views(ViewType::Media, Comparator::Greater, 1000)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_preview_viewtime() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.viewtime(
|
||||
ViewType::Preview,
|
||||
Comparator::Greater,
|
||||
Duration::minutes(10),
|
||||
)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_media_viewtime() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.viewtime(ViewType::Media, Comparator::Equal, Duration::minutes(10))
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_a_specific_viewtime() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.viewtime(ViewType::All, Comparator::Less, Duration::hours(10))
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_urls_matching_a_regex() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.has_url_matching_regex(".*pixiv.net.*")
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_urls_not_matching_a_regex() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.does_not_have_url_matching_regex(".*pixiv.net.*")
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_urls_matching_a_class() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.has_url_with_class("pixiv file page")
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_urls_not_matching_a_class() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.does_not_have_url_with_class("pixiv file page")
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn it_returns_files_with_namespace_properties() {
|
||||
let tag = SystemTagBuilder::new()
|
||||
.tag_namespace_as_number("page", Comparator::Approximate, 5)
|
||||
.build();
|
||||
retrieve_single_tag(tag).await.unwrap();
|
||||
}
|
Loading…
Reference in New Issue