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 mod import_utils;
|
||||
|
||||
pub use users::User;
|
||||
pub use watches::{ShowKind, Watch, WatchQuest};
|
||||
|
||||
// everything else is private to the crate
|
||||
mod db;
|
||||
mod db_id;
|
||||
|
@ -24,10 +27,7 @@ mod watches;
|
|||
// things we want in the crate namespace
|
||||
use optional_optional_user::OptionalOptionalUser;
|
||||
use templates::*;
|
||||
use users::User;
|
||||
use watches::{templates::*, ShowKind, Watch};
|
||||
|
||||
use crate::watches::handlers::get_watch;
|
||||
use watches::templates::*;
|
||||
|
||||
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 signup::{get_create_user, get_signup_success, post_create_user};
|
||||
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,
|
||||
};
|
||||
|
||||
|
|
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>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
|
@ -35,3 +35,17 @@ where
|
|||
.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 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
|
||||
|
@ -116,25 +120,50 @@ pub async fn post_add_new_watch(
|
|||
{
|
||||
let watch_id = DbId::new();
|
||||
let witch_watch_id = DbId::new();
|
||||
let release_date = form.year.map(|year| match year.trim().parse::<i32>() {
|
||||
Ok(year) => {
|
||||
let years = (year - 1970) as i64;
|
||||
let days = (years as f32 * 365.2425) as i64;
|
||||
Some(days * 24 * 60 * 60)
|
||||
let release_date = year_to_epoch(form.year.as_deref());
|
||||
let watch = Watch {
|
||||
id: watch_id,
|
||||
title: form.title,
|
||||
kind: form.kind,
|
||||
metadata_url: form.metadata_url,
|
||||
length: None,
|
||||
release_date,
|
||||
added_by: user.id,
|
||||
};
|
||||
let quest = WatchQuest {
|
||||
id: witch_watch_id,
|
||||
user: user.id,
|
||||
watch: watch_id,
|
||||
is_public: !form.private,
|
||||
already_watched: form.watched_already,
|
||||
};
|
||||
|
||||
add_new_watch_impl(&pool, &watch, Some(quest)).await?;
|
||||
|
||||
let location = format!("/watch/{watch_id}");
|
||||
Ok(Redirect::to(&location))
|
||||
}
|
||||
Err(_) => None,
|
||||
});
|
||||
let mut tx = pool
|
||||
} else {
|
||||
Err(WatchAddErrorKind::NotSignedIn.into())
|
||||
}
|
||||
}
|
||||
|
||||
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(&form.title)
|
||||
.bind(form.kind)
|
||||
.bind(release_date)
|
||||
.bind(form.metadata_url)
|
||||
.bind(user.id)
|
||||
.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| {
|
||||
|
@ -142,28 +171,26 @@ pub async fn post_add_new_watch(
|
|||
WatchAddErrorKind::UnknownDBError
|
||||
})?;
|
||||
|
||||
if let Some(quest) = quest {
|
||||
query(ADD_WITCH_WATCH_QUERY)
|
||||
.bind(witch_watch_id)
|
||||
.bind(user.id)
|
||||
.bind(watch_id)
|
||||
.bind(!form.private)
|
||||
.bind(form.watched_already)
|
||||
.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
|
||||
})?;
|
||||
let location = format!("/watch/{watch_id}");
|
||||
Ok(Redirect::to(&location))
|
||||
}
|
||||
} else {
|
||||
Err(WatchAddErrorKind::NotSignedIn.into())
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a Watch to your watchlist by selecting it with a checkbox
|
||||
|
|
|
@ -52,6 +52,9 @@ impl From<i64> for ShowKind {
|
|||
}
|
||||
}
|
||||
|
||||
//-************************************************************************
|
||||
/// Something able to be watched.
|
||||
//-************************************************************************
|
||||
#[derive(
|
||||
Debug,
|
||||
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