Make it easier to add watches from a CLI tool.
This commit is contained in:
parent
04549fd7a5
commit
83da336a3f
4 changed files with 104 additions and 48 deletions
10
src/lib.rs
10
src/lib.rs
|
@ -10,6 +10,9 @@ pub use db::get_db_pool;
|
||||||
pub use db_id::DbId;
|
pub use db_id::DbId;
|
||||||
pub mod import_utils;
|
pub mod import_utils;
|
||||||
|
|
||||||
|
pub use users::User;
|
||||||
|
pub use watches::{ShowKind, Watch, WatchQuest};
|
||||||
|
|
||||||
// everything else is private to the crate
|
// everything else is private to the crate
|
||||||
mod db;
|
mod db;
|
||||||
mod db_id;
|
mod db_id;
|
||||||
|
@ -24,10 +27,7 @@ mod watches;
|
||||||
// things we want in the crate namespace
|
// things we want in the crate namespace
|
||||||
use optional_optional_user::OptionalOptionalUser;
|
use optional_optional_user::OptionalOptionalUser;
|
||||||
use templates::*;
|
use templates::*;
|
||||||
use users::User;
|
use watches::templates::*;
|
||||||
use watches::{templates::*, ShowKind, Watch};
|
|
||||||
|
|
||||||
use crate::watches::handlers::get_watch;
|
|
||||||
|
|
||||||
type AuthContext = axum_login::extractors::AuthContext<DbId, User, axum_login::SqliteStore<User>>;
|
type AuthContext = axum_login::extractors::AuthContext<DbId, User, axum_login::SqliteStore<User>>;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ pub async fn app(db_pool: sqlx::SqlitePool, session_secret: &[u8]) -> axum::Rout
|
||||||
use login::{get_login, get_logout, post_login, post_logout};
|
use login::{get_login, get_logout, post_login, post_logout};
|
||||||
use signup::{get_create_user, get_signup_success, post_create_user};
|
use signup::{get_create_user, get_signup_success, post_create_user};
|
||||||
use watches::handlers::{
|
use watches::handlers::{
|
||||||
get_add_new_watch, get_search_watch, get_watches, post_add_existing_watch,
|
get_add_new_watch, get_search_watch, get_watch, get_watches, post_add_existing_watch,
|
||||||
post_add_new_watch,
|
post_add_new_watch,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
16
src/util.rs
16
src/util.rs
|
@ -20,7 +20,7 @@ pub fn validate_optional_length<E: Error>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serde deserialization decorator to map empty Strings to None,
|
/// Serde deserialization decorator to map empty Strings to None
|
||||||
pub fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
|
pub fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
|
@ -35,3 +35,17 @@ where
|
||||||
.map(Some),
|
.map(Some),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a stringy number like "1999" to a 64-bit signed unix epoch-based
|
||||||
|
/// timestamp
|
||||||
|
pub fn year_to_epoch(year: Option<&str>) -> Option<i64> {
|
||||||
|
year?
|
||||||
|
.trim()
|
||||||
|
.parse::<i32>()
|
||||||
|
.map(|year| {
|
||||||
|
let years = (year - 1970) as f32;
|
||||||
|
let days = (years * 365.2425) as i64;
|
||||||
|
days * 24 * 60 * 60
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,11 @@ use serde::Deserialize;
|
||||||
use sqlx::{query, query_as, SqlitePool};
|
use sqlx::{query, query_as, SqlitePool};
|
||||||
|
|
||||||
use super::templates::{AddNewWatchPage, GetWatchPage, SearchWatchesPage};
|
use super::templates::{AddNewWatchPage, GetWatchPage, SearchWatchesPage};
|
||||||
use crate::{db_id::DbId, util::empty_string_as_none, AuthContext, MyWatchesPage, ShowKind, Watch};
|
use crate::{
|
||||||
|
db_id::DbId,
|
||||||
|
util::{empty_string_as_none, year_to_epoch},
|
||||||
|
AuthContext, MyWatchesPage, ShowKind, Watch, WatchQuest,
|
||||||
|
};
|
||||||
|
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
// Constants
|
// Constants
|
||||||
|
@ -116,48 +120,26 @@ pub async fn post_add_new_watch(
|
||||||
{
|
{
|
||||||
let watch_id = DbId::new();
|
let watch_id = DbId::new();
|
||||||
let witch_watch_id = DbId::new();
|
let witch_watch_id = DbId::new();
|
||||||
let release_date = form.year.map(|year| match year.trim().parse::<i32>() {
|
let release_date = year_to_epoch(form.year.as_deref());
|
||||||
Ok(year) => {
|
let watch = Watch {
|
||||||
let years = (year - 1970) as i64;
|
id: watch_id,
|
||||||
let days = (years as f32 * 365.2425) as i64;
|
title: form.title,
|
||||||
Some(days * 24 * 60 * 60)
|
kind: form.kind,
|
||||||
}
|
metadata_url: form.metadata_url,
|
||||||
Err(_) => None,
|
length: None,
|
||||||
});
|
release_date,
|
||||||
let mut tx = pool
|
added_by: user.id,
|
||||||
.begin()
|
};
|
||||||
.await
|
let quest = WatchQuest {
|
||||||
.map_err(|_| WatchAddErrorKind::UnknownDBError)?;
|
id: witch_watch_id,
|
||||||
query(ADD_WATCH_QUERY)
|
user: user.id,
|
||||||
.bind(watch_id)
|
watch: watch_id,
|
||||||
.bind(&form.title)
|
is_public: !form.private,
|
||||||
.bind(form.kind)
|
already_watched: form.watched_already,
|
||||||
.bind(release_date)
|
};
|
||||||
.bind(form.metadata_url)
|
|
||||||
.bind(user.id)
|
add_new_watch_impl(&pool, &watch, Some(quest)).await?;
|
||||||
.execute(&mut tx)
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
tracing::error!("Got error: {err}");
|
|
||||||
WatchAddErrorKind::UnknownDBError
|
|
||||||
})?;
|
|
||||||
|
|
||||||
query(ADD_WITCH_WATCH_QUERY)
|
|
||||||
.bind(witch_watch_id)
|
|
||||||
.bind(user.id)
|
|
||||||
.bind(watch_id)
|
|
||||||
.bind(!form.private)
|
|
||||||
.bind(form.watched_already)
|
|
||||||
.execute(&mut tx)
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
tracing::error!("Got error: {err}");
|
|
||||||
WatchAddErrorKind::UnknownDBError
|
|
||||||
})?;
|
|
||||||
tx.commit().await.map_err(|err| {
|
|
||||||
tracing::error!("Got error: {err}");
|
|
||||||
WatchAddErrorKind::UnknownDBError
|
|
||||||
})?;
|
|
||||||
let location = format!("/watch/{watch_id}");
|
let location = format!("/watch/{watch_id}");
|
||||||
Ok(Redirect::to(&location))
|
Ok(Redirect::to(&location))
|
||||||
}
|
}
|
||||||
|
@ -166,6 +148,51 @@ pub async fn post_add_new_watch(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn add_new_watch_impl(
|
||||||
|
db_pool: &SqlitePool,
|
||||||
|
watch: &Watch,
|
||||||
|
quest: Option<WatchQuest>,
|
||||||
|
) -> Result<(), WatchAddError> {
|
||||||
|
let mut tx = db_pool
|
||||||
|
.begin()
|
||||||
|
.await
|
||||||
|
.map_err(|_| WatchAddErrorKind::UnknownDBError)?;
|
||||||
|
query(ADD_WATCH_QUERY)
|
||||||
|
.bind(watch.id)
|
||||||
|
.bind(&watch.title)
|
||||||
|
.bind(watch.kind)
|
||||||
|
.bind(watch.release_date)
|
||||||
|
.bind(&watch.metadata_url)
|
||||||
|
.bind(watch.added_by)
|
||||||
|
.execute(&mut tx)
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
tracing::error!("Got error: {err}");
|
||||||
|
WatchAddErrorKind::UnknownDBError
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(quest) = quest {
|
||||||
|
query(ADD_WITCH_WATCH_QUERY)
|
||||||
|
.bind(quest.id)
|
||||||
|
.bind(quest.user)
|
||||||
|
.bind(quest.watch)
|
||||||
|
.bind(quest.is_public)
|
||||||
|
.bind(quest.already_watched)
|
||||||
|
.execute(&mut tx)
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
tracing::error!("Got error: {err}");
|
||||||
|
WatchAddErrorKind::UnknownDBError
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
tx.commit().await.map_err(|err| {
|
||||||
|
tracing::error!("Got error: {err}");
|
||||||
|
WatchAddErrorKind::UnknownDBError
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a Watch to your watchlist by selecting it with a checkbox
|
/// Add a Watch to your watchlist by selecting it with a checkbox
|
||||||
pub async fn post_add_existing_watch(
|
pub async fn post_add_existing_watch(
|
||||||
_auth: AuthContext,
|
_auth: AuthContext,
|
||||||
|
|
|
@ -52,6 +52,9 @@ impl From<i64> for ShowKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-************************************************************************
|
||||||
|
/// Something able to be watched.
|
||||||
|
//-************************************************************************
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
Default,
|
Default,
|
||||||
|
@ -86,3 +89,15 @@ impl Watch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-************************************************************************
|
||||||
|
/// Something a user wants to watch
|
||||||
|
//-************************************************************************
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct WatchQuest {
|
||||||
|
pub id: DbId,
|
||||||
|
pub user: DbId,
|
||||||
|
pub watch: DbId,
|
||||||
|
pub is_public: bool,
|
||||||
|
pub already_watched: bool,
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue