|
|
|
@ -1,10 +1,11 @@
|
|
|
|
|
use crate::endpoints::adding_tags::{AddTagsRequestBuilder, TagAction};
|
|
|
|
|
use crate::endpoints::common::{FileIdentifier, FileMetadataInfo, FileRecord};
|
|
|
|
|
use crate::error::Result;
|
|
|
|
|
use crate::error::{Error, Result};
|
|
|
|
|
use crate::service::ServiceName;
|
|
|
|
|
use crate::tag::Tag;
|
|
|
|
|
use crate::utils::tag_list_to_string_list;
|
|
|
|
|
use crate::Client;
|
|
|
|
|
use mime::Mime;
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
|
|
|
@ -77,25 +78,6 @@ impl HydrusFile {
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the metadata for the given file
|
|
|
|
|
/// if there's already known metadata about the file it uses that
|
|
|
|
|
async fn metadata(&mut self) -> Result<&FileMetadataInfo> {
|
|
|
|
|
if self.metadata.is_none() {
|
|
|
|
|
let metadata = self
|
|
|
|
|
.client
|
|
|
|
|
.get_file_metadata_by_identifier(self.id.clone())
|
|
|
|
|
.await?;
|
|
|
|
|
self.status = if metadata.is_trashed {
|
|
|
|
|
FileStatus::Deleted
|
|
|
|
|
} else {
|
|
|
|
|
FileStatus::InDatabase
|
|
|
|
|
};
|
|
|
|
|
self.metadata = Some(metadata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(self.metadata.as_ref().unwrap())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the hash of the file
|
|
|
|
|
/// if the file identifier is an id it calls hydrus to resolve the file
|
|
|
|
|
pub async fn hash(&mut self) -> Result<String> {
|
|
|
|
@ -108,6 +90,84 @@ impl HydrusFile {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the file size in bytes
|
|
|
|
|
pub async fn size(&mut self) -> Result<Option<u64>> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
|
|
|
|
|
Ok(metadata.size.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the mime of the file
|
|
|
|
|
pub async fn mime(&mut self) -> Result<Mime> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
let mime = metadata
|
|
|
|
|
.mime
|
|
|
|
|
.as_str()
|
|
|
|
|
.parse()
|
|
|
|
|
.map_err(|_| Error::InvalidMime(metadata.mime.clone()))?;
|
|
|
|
|
|
|
|
|
|
Ok(mime)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Return the file extension
|
|
|
|
|
pub async fn ext(&mut self) -> Result<String> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
|
|
|
|
|
Ok(metadata.ext.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the dimensions of the file in pixels
|
|
|
|
|
pub async fn dimensions(&mut self) -> Result<Option<(u32, u32)>> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
if let (Some(width), Some(height)) = (&metadata.width, &metadata.height) {
|
|
|
|
|
Ok(Some((*width, *height)))
|
|
|
|
|
} else {
|
|
|
|
|
Ok(None)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the duration of the file in seconds if it's a video
|
|
|
|
|
pub async fn duration(&mut self) -> Result<Option<u64>> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
|
|
|
|
|
Ok(metadata.duration.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the number of frames of the file if it's a video
|
|
|
|
|
pub async fn num_frames(&mut self) -> Result<Option<u64>> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
|
|
|
|
|
Ok(metadata.num_frames.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns if the file has audio
|
|
|
|
|
pub async fn has_audio(&mut self) -> Result<bool> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
|
|
|
|
|
Ok(metadata.has_audio.unwrap_or(false))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns if the file is currently in the inbox
|
|
|
|
|
pub async fn in_inbox(&mut self) -> Result<bool> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
|
|
|
|
|
Ok(metadata.is_inbox)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns if the file is stored locally
|
|
|
|
|
pub async fn stored_locally(&mut self) -> Result<bool> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
|
|
|
|
|
Ok(metadata.is_local)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns if the file has been moved to the trash
|
|
|
|
|
pub async fn moved_to_trashed(&mut self) -> Result<bool> {
|
|
|
|
|
let metadata = self.metadata().await?;
|
|
|
|
|
|
|
|
|
|
Ok(metadata.is_trashed)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Associates the file with a list of urls
|
|
|
|
|
pub async fn associate_urls(&mut self, urls: Vec<String>) -> Result<()> {
|
|
|
|
|
let hash = self.hash().await?;
|
|
|
|
@ -182,4 +242,23 @@ impl HydrusFile {
|
|
|
|
|
pub async fn retrieve(&self) -> Result<FileRecord> {
|
|
|
|
|
self.client.get_file(self.id.clone()).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the metadata for the given file
|
|
|
|
|
/// if there's already known metadata about the file it uses that
|
|
|
|
|
async fn metadata(&mut self) -> Result<&FileMetadataInfo> {
|
|
|
|
|
if self.metadata.is_none() {
|
|
|
|
|
let metadata = self
|
|
|
|
|
.client
|
|
|
|
|
.get_file_metadata_by_identifier(self.id.clone())
|
|
|
|
|
.await?;
|
|
|
|
|
self.status = if metadata.is_trashed {
|
|
|
|
|
FileStatus::Deleted
|
|
|
|
|
} else {
|
|
|
|
|
FileStatus::InDatabase
|
|
|
|
|
};
|
|
|
|
|
self.metadata = Some(metadata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(self.metadata.as_ref().unwrap())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|