Files
pixiv_downloader/src/db/traits.rs
2024-09-20 15:00:03 +00:00

303 lines
11 KiB
Rust

use super::PixivDownloaderDbConfig;
use super::PixivDownloaderDbError;
use super::{PixivArtwork, PixivArtworkLock};
#[cfg(feature = "server")]
use super::{PushConfig, PushTask, PushTaskConfig};
#[cfg(feature = "server")]
use super::{Token, User};
#[cfg(feature = "server")]
use crate::tmp_cache::TmpCacheEntry;
use chrono::{DateTime, Utc};
use flagset::FlagSet;
#[async_trait(+Sync)]
pub trait PixivDownloaderDb {
/// Create a new instance of database
/// * `cfg` - The database configuration
fn new<R: AsRef<PixivDownloaderDbConfig> + ?Sized>(
cfg: &R,
) -> Result<Self, PixivDownloaderDbError>
where
Self: Sized + Send + Sync;
/// Add/Update an artwork to the database
/// * `id` - The artwork ID
/// * `title` - The artwork title
/// * `author` - The artwork author
/// * `uid` - The author's ID
/// * `description` - The artwork description
/// * `count` - The artwork's page count
/// * `is_nsfw` - Whether the artwork is NSFW
/// * `lock` - Specify which part should not be updated.
async fn add_pixiv_artwork(
&self,
id: u64,
title: &str,
author: &str,
uid: u64,
description: &str,
count: u64,
is_nsfw: bool,
lock: &FlagSet<PixivArtworkLock>,
) -> Result<PixivArtwork, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Add a push task
/// * `config` - The task's config
/// * `push_configs` - The task's push configurations
/// * `ttl` - The task's update interval
async fn add_push_task(
&self,
config: &PushTaskConfig,
push_configs: &[PushConfig],
ttl: u64,
) -> Result<PushTask, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Add root user to database.
/// * `name` - User name
/// * `username` - Unique user name
/// * `password` - Hashed password
async fn add_root_user(
&self,
name: &str,
username: &str,
password: &[u8],
) -> Result<User, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Add a new token
/// * `user_id` - The user ID
/// * `token` - The token
/// * `created_at` - The token's expiration time
/// * `expired_at` - The token's creation time
/// # Note
/// if a token with the same user_id already exists, must return None
async fn add_token(
&self,
user_id: u64,
token: &[u8; 64],
created_at: &DateTime<Utc>,
expired_at: &DateTime<Utc>,
) -> Result<Option<Token>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Add a new user to database.
/// * `name` - User name
/// * `username` - Unique user name
/// * `password` - Hashed password
/// * `is_admin` - Whether the user is an admin
/// # Note
/// If username already exists, this function must be failed.
async fn add_user(
&self,
name: &str,
username: &str,
password: &[u8],
is_admin: bool,
) -> Result<User, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Delete tmp cache entry
/// * `url` - URL
async fn delete_tmp_cache(&self, url: &str) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Delete a token
/// * `id` - The token ID
async fn delete_token(&self, id: u64) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Delete a user
/// * `id` - User ID
/// # Note
/// All tokens of the user will be deleted.
async fn delete_user(&self, id: u64) -> Result<bool, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Extend a token's expiration time
/// * `id` - The token ID
/// * `expired_at` - The token's new expiration time
async fn extend_token(
&self,
id: u64,
expired_at: &DateTime<Utc>,
) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get all push tasks
async fn get_all_push_tasks(&self) -> Result<Vec<PushTask>, PixivDownloaderDbError>;
/// Get a config from database
/// * `key` - The config key
async fn get_config(&self, key: &str) -> Result<Option<String>, PixivDownloaderDbError>;
/// Get a config from database or set a default value to database and return
/// * `key` - The config key
/// * `default` - The function to return default value
async fn get_config_or_set_default(
&self,
key: &str,
default: fn() -> Result<String, PixivDownloaderDbError>,
) -> Result<String, PixivDownloaderDbError>;
/// Get an artwork from database
/// * `id` - The artwork ID
async fn get_pixiv_artwork(
&self,
id: u64,
) -> Result<Option<PixivArtwork>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get proxy pixiv secrets
async fn get_proxy_pixiv_secrets(&self) -> Result<String, PixivDownloaderDbError> {
self.get_config_or_set_default("proxy_pixiv_secrets", || {
let mut buf = [0; 32];
openssl::rand::rand_bytes(&mut buf)?;
Ok(base64::Engine::encode(
&base64::engine::general_purpose::STANDARD,
&buf,
))
})
.await
}
#[cfg(feature = "server")]
/// Get a push task by ID
/// * `id` - The task's ID
async fn get_push_task(&self, id: u64) -> Result<Option<PushTask>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get a push task's data
/// * `id` - The task's ID
async fn get_push_task_data(&self, id: u64) -> Result<Option<String>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get tmp cache entry via url
/// * `url` - URL
async fn get_tmp_cache(
&self,
url: &str,
) -> Result<Option<TmpCacheEntry>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get tmp cache entries should deleted
/// * `ttl` - Time to live in seconds
async fn get_tmp_caches(&self, ttl: i64) -> Result<Vec<TmpCacheEntry>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get token by ID
/// * `id` - The token ID
async fn get_token(&self, id: u64) -> Result<Option<Token>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get a user by ID
/// * `id`: The user's ID
async fn get_user(&self, id: u64) -> Result<Option<User>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get a user by username
/// * `username`: The user's username
async fn get_user_by_username(
&self,
username: &str,
) -> Result<Option<User>, PixivDownloaderDbError>;
/// Initialize the database (create tables, migrate data, etc.)
async fn init(&self) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// List users
/// * `offset` - The offset of the first user
/// * `limit` - The maximum number of users to return
async fn list_users(
&self,
offset: u64,
limit: u64,
) -> Result<Vec<User>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// List users' id
/// * `offset` - The offset of the list
/// * `count` - The maximum count of the list
async fn list_users_id(
&self,
offset: u64,
count: u64,
) -> Result<Vec<u64>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Put new tmp cache
/// * `url` - URL
/// * `path` - Path
async fn put_tmp_cache(&self, url: &str, path: &str) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Remove all expired tokens
/// Return the number of removed tokens
async fn revoke_expired_tokens(&self) -> Result<usize, PixivDownloaderDbError>;
/// Set a config
/// * `key` - The config key
/// * `value` - The config value
async fn set_config(&self, key: &str, value: &str) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Set a user's information by ID
/// * `id`: The user's ID
/// * `name`: The user's name
/// * `username`: The user's username
/// * `password`: The user's hashed password
/// * `is_admin`: Whether the user is an admin
/// # Note
/// If the user does not exist, a new user will be created and `id` must not be applied.
/// If the user's `username` is taked by another user, the operation must failed.
async fn set_user(
&self,
id: u64,
name: &str,
username: &str,
password: &[u8],
is_admin: bool,
) -> Result<User, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Set push task's data
/// * `id`: The task's ID
/// * `data`: The task's data
async fn set_push_task_data(&self, id: u64, data: &str) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Update a push task
/// * `id`: The task's ID
/// * `config`: The task's config
/// * `push_configs`: The task's push configurations
/// * `ttl`: The task's update interval
async fn update_push_task(
&self,
id: u64,
config: Option<&PushTaskConfig>,
push_configs: Option<&[PushConfig]>,
ttl: Option<u64>,
) -> Result<PushTask, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Update a push task's last updated time
/// * `id`: The task's ID
/// * `last_updated`: The task's last updated time
async fn update_push_task_last_updated(
&self,
id: u64,
last_updated: &DateTime<Utc>,
) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Update tmp cache last used time
/// * `url` - URL
async fn update_tmp_cache(&self, url: &str) -> Result<(), PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Update a user's information
/// * `id`: The user's ID
/// * `name`: The user's name
/// * `username`: The user's username
/// * `password`: The user's hashed password
/// * `is_admin`: Whether the user is an admin
/// # Note
/// If the user does not exist, the operation must failed.
/// If the user's `username` is taked by another user, the operation must failed.
async fn update_user(
&self,
id: u64,
name: &str,
username: &str,
password: &[u8],
is_admin: bool,
) -> Result<User, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Update a user's name
/// * `id`: The user's ID
/// * `name`: The user's name
async fn update_user_name(&self, id: u64, name: &str) -> Result<User, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Update a user's password
/// * `id`: The user's ID
/// * `password`: The user's hashed password
/// * `token_id`: The token ID
/// # Note
/// All tokens of the user except token_id will be revoked
async fn update_user_password(
&self,
id: u64,
password: &[u8],
token_id: u64,
) -> Result<User, PixivDownloaderDbError>;
}