From 1a4ffaa99d011011e1344d9fdc629d7017e0dfc5 Mon Sep 17 00:00:00 2001
From: Joe Ardent
+Hello, {{ usr.username }}! It's nice to see you.
+ Here are your things to watch:
+
Date: Mon, 5 Jun 2023 16:32:42 -0700
Subject: [PATCH 1/6] adds Watches struct
---
migrations/20230426221940_init.up.sql | 10 ++--
src/lib.rs | 1 +
src/main.rs | 4 +-
src/watches/handlers.rs | 1 +
src/watches/mod.rs | 74 +++++++++++++++++++++++++++
5 files changed, 84 insertions(+), 6 deletions(-)
create mode 100644 src/watches/handlers.rs
create mode 100644 src/watches/mod.rs
diff --git a/migrations/20230426221940_init.up.sql b/migrations/20230426221940_init.up.sql
index 7d53573..f94e598 100644
--- a/migrations/20230426221940_init.up.sql
+++ b/migrations/20230426221940_init.up.sql
@@ -20,11 +20,13 @@ create table if not exists watches (
id blob not null primary key,
typ int not null, -- enum for movie or tv show or whatev
title text not null,
- imdb text, -- possible url for imdb or other metadata-esque site to show the user
- runtime int,
+ metadata_url text, -- possible url for imdb or other metadata-esque site to show the user
+ length int,
release_date int,
+ added_by blob not null, -- ID of the user that added it
created_at int not null default (unixepoch()),
- last_updated int not null default (unixepoch())
+ last_updated int not null default (unixepoch()),
+ foreign key (added_by) references witches (id)
);
-- table of what people want to watch
@@ -68,6 +70,6 @@ create table if not exists watch_notes (
-- indices, not needed for covens
create index if not exists witch_dex on witches ( username, email );
-create index if not exists watch_dex on watches ( title, runtime, release_date );
+create index if not exists watch_dex on watches ( title, length, release_date, added_by );
create index if not exists ww_dex on witch_watch ( witch, watch, public );
create index if not exists note_dex on watch_notes ( witch, watch, public );
diff --git a/src/lib.rs b/src/lib.rs
index 6638c22..e4b88d5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -17,6 +17,7 @@ pub mod signup;
pub(crate) mod templates;
pub mod users;
pub(crate) mod util;
+pub mod watches;
#[cfg(test)]
pub mod test_utils;
diff --git a/src/main.rs b/src/main.rs
index 7418799..5aa68c4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -25,10 +25,10 @@ async fn main() {
let app = witch_watch::app(pool, &secret).await;
- let addr = ([127, 0, 0, 1], 3000);
+ let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
tracing::debug!("binding to {addr:?}");
- axum::Server::bind(&SocketAddr::from(addr))
+ axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
diff --git a/src/watches/handlers.rs b/src/watches/handlers.rs
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/watches/handlers.rs
@@ -0,0 +1 @@
+
diff --git a/src/watches/mod.rs b/src/watches/mod.rs
new file mode 100644
index 0000000..62ebe09
--- /dev/null
+++ b/src/watches/mod.rs
@@ -0,0 +1,74 @@
+use serde::{Deserialize, Serialize};
+use uuid::Uuid;
+
+mod handlers;
+
+pub use handlers::*;
+
+#[derive(
+ Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, sqlx::Type,
+)]
+#[repr(i32)]
+pub enum ShowKind {
+ Movie = 0,
+ Series = 1,
+ LimitedSeries = 2,
+ Short = 3,
+ Unknown = 4,
+}
+
+impl Default for ShowKind {
+ fn default() -> Self {
+ Self::Unknown
+ }
+}
+
+impl From
Date: Tue, 6 Jun 2023 14:08:49 -0700
Subject: [PATCH 2/6] tweak the db model for watches, add handler skeletons
---
src/watches/handlers.rs | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/watches/handlers.rs b/src/watches/handlers.rs
index 8b13789..c0578a8 100644
--- a/src/watches/handlers.rs
+++ b/src/watches/handlers.rs
@@ -1 +1,14 @@
+/// Add a Watch to the whole system
+pub async fn post_add_watch() {}
+/// A single Watch
+pub async fn get_watch() {}
+
+/// everything the user has saved
+pub async fn get_my_watches() {}
+
+/// Add a Watch to user's to-watch list
+pub async fn post_add_to_mine() {}
+
+/// list of all watches?
+pub async fn get_watches() {}
From 9505266ef955764362568382453afa43c4dafab3 Mon Sep 17 00:00:00 2001
From: Joe Ardent
Date: Thu, 8 Jun 2023 09:16:38 -0700
Subject: [PATCH 3/6] minor re-org and rename of main page template struct.
---
src/generic_handlers.rs | 4 ++--
src/lib.rs | 3 +++
src/login.rs | 10 +++-------
src/signup.rs | 7 ++-----
src/templates.rs | 2 +-
src/watches/templates.rs | 1 +
templates/get_watches.rs | 0
7 files changed, 12 insertions(+), 15 deletions(-)
create mode 100644 src/watches/templates.rs
create mode 100644 templates/get_watches.rs
diff --git a/src/generic_handlers.rs b/src/generic_handlers.rs
index 09e0cd1..a344808 100644
--- a/src/generic_handlers.rs
+++ b/src/generic_handlers.rs
@@ -1,6 +1,6 @@
use axum::response::{IntoResponse, Redirect};
-use crate::{templates::Index, AuthContext};
+use crate::{AuthContext, MainPage};
pub async fn handle_slash_redir() -> impl IntoResponse {
Redirect::to("/")
@@ -13,7 +13,7 @@ pub async fn handle_slash(auth: AuthContext) -> impl IntoResponse {
} else {
tracing::debug!("Not logged in.");
}
- Index {
+ MainPage {
user: auth.current_user,
}
}
diff --git a/src/lib.rs b/src/lib.rs
index e4b88d5..87f46a3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -18,6 +18,9 @@ pub(crate) mod templates;
pub mod users;
pub(crate) mod util;
pub mod watches;
+pub use templates::*;
+pub use watches::templates::*;
+use watches::{ShowKind, Watch};
#[cfg(test)]
pub mod test_utils;
diff --git a/src/login.rs b/src/login.rs
index f9532f2..5467de1 100644
--- a/src/login.rs
+++ b/src/login.rs
@@ -10,11 +10,7 @@ use axum::{
};
use sqlx::SqlitePool;
-use crate::{
- templates::{LoginGet, LoginPost, LogoutGet, LogoutPost},
- util::form_decode,
- AuthContext, User,
-};
+use crate::{util::form_decode, AuthContext, LoginGet, LoginPost, LogoutGet, LogoutPost, User};
//-************************************************************************
// Constants
@@ -104,7 +100,7 @@ pub async fn post_logout(mut auth: AuthContext) -> impl IntoResponse {
#[cfg(test)]
mod test {
use crate::{
- templates::{Index, LoginGet, LogoutGet, LogoutPost},
+ templates::{LoginGet, LogoutGet, LogoutPost, MainPage},
test_utils::{get_test_user, massage, server, FORM_CONTENT_TYPE},
};
@@ -198,7 +194,7 @@ mod test {
.await;
assert_eq!(resp.status_code(), 303);
- let logged_in = Index {
+ let logged_in = MainPage {
user: Some(get_test_user()),
}
.to_string();
diff --git a/src/signup.rs b/src/signup.rs
index 71e2369..523e28e 100644
--- a/src/signup.rs
+++ b/src/signup.rs
@@ -11,10 +11,7 @@ use sqlx::{query_as, SqlitePool};
use unicode_segmentation::UnicodeSegmentation;
use uuid::Uuid;
-use crate::{
- templates::{CreateUser, CreateUserSuccess},
- User,
-};
+use crate::{CreateUser, CreateUserSuccess, User};
pub(crate) const CREATE_QUERY: &str =
"insert into witches (id, username, displayname, email, pwhash) values ($1, $2, $3, $4, $5)";
@@ -29,7 +26,7 @@ const ID_QUERY: &str = "select * from witches where id = $1";
pub struct CreateUserError(#[from] CreateUserErrorKind);
impl IntoResponse for CreateUserError {
- fn into_response(self) -> askama_axum::Response {
+ fn into_response(self) -> Response {
match self.0 {
CreateUserErrorKind::UnknownDBError => {
(StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response()
diff --git a/src/templates.rs b/src/templates.rs
index 9f8748d..4d624f6 100644
--- a/src/templates.rs
+++ b/src/templates.rs
@@ -41,6 +41,6 @@ pub struct LogoutPost;
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "index.html")]
-pub struct Index {
+pub struct MainPage {
pub user: Option
Date: Thu, 8 Jun 2023 09:17:11 -0700
Subject: [PATCH 4/6] tweak endpoints
---
src/watches/handlers.rs | 43 +++++++++++++++++++++++++++++++++++------
src/watches/mod.rs | 5 ++---
2 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/src/watches/handlers.rs b/src/watches/handlers.rs
index c0578a8..2676320 100644
--- a/src/watches/handlers.rs
+++ b/src/watches/handlers.rs
@@ -1,3 +1,36 @@
+use axum::{
+ extract::{Form, Path, State},
+ http::StatusCode,
+ response::{IntoResponse, Response},
+};
+use sqlx::{query_as, SqlitePool};
+use uuid::Uuid;
+
+use crate::{ShowKind, User, Watch};
+
+//-************************************************************************
+// Error types for Watch creation
+//-************************************************************************
+
+#[Error]
+pub struct WatchAddError(#[from] WatchAddErrorKind);
+
+#[Error]
+#[non_exhaustive]
+pub enum WatchAddErrorKind {
+ UnknownDBError,
+}
+
+impl IntoResponse for WatchAddError {
+ fn into_response(self) -> Response {
+ match self.0 {
+ WatchAddErrorKind::UnknownDBError => {
+ (StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response()
+ }
+ }
+ }
+}
+
/// Add a Watch to the whole system
pub async fn post_add_watch() {}
@@ -5,10 +38,8 @@ pub async fn post_add_watch() {}
pub async fn get_watch() {}
/// everything the user has saved
-pub async fn get_my_watches() {}
-
-/// Add a Watch to user's to-watch list
-pub async fn post_add_to_mine() {}
-
-/// list of all watches?
pub async fn get_watches() {}
+
+pub async fn get_search_watch() {}
+
+pub async fn post_search_watch() {}
diff --git a/src/watches/mod.rs b/src/watches/mod.rs
index 62ebe09..f92df12 100644
--- a/src/watches/mod.rs
+++ b/src/watches/mod.rs
@@ -1,9 +1,8 @@
use serde::{Deserialize, Serialize};
use uuid::Uuid;
-mod handlers;
-
-pub use handlers::*;
+pub mod handlers;
+pub mod templates;
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, sqlx::Type,
From c44c89005c03e5f503700156ceafe550e3d5db27 Mon Sep 17 00:00:00 2001
From: Joe Ardent
Date: Thu, 8 Jun 2023 15:45:34 -0700
Subject: [PATCH 5/6] add working endpoints for getting your watches
---
src/lib.rs | 8 +++-
src/watches/handlers.rs | 29 +++++++++++++--
src/watches/mod.rs | 6 +++
src/watches/templates.rs | 10 +++++
...get_watches.rs => get_search_watches.html} | 0
templates/get_watches.html | 37 +++++++++++++++++++
templates/index.html | 2 +-
templates/macros.html | 10 +++++
8 files changed, 97 insertions(+), 5 deletions(-)
rename templates/{get_watches.rs => get_search_watches.html} (100%)
create mode 100644 templates/get_watches.html
create mode 100644 templates/macros.html
diff --git a/src/lib.rs b/src/lib.rs
index 87f46a3..ccba9a6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -20,7 +20,10 @@ pub(crate) mod util;
pub mod watches;
pub use templates::*;
pub use watches::templates::*;
-use watches::{ShowKind, Watch};
+use watches::{
+ handlers::{get_search_watch, get_watches, post_search_watch, put_add_watch},
+ ShowKind, Watch,
+};
#[cfg(test)]
pub mod test_utils;
@@ -37,6 +40,9 @@ pub async fn app(db_pool: SqlitePool, secret: &[u8]) -> Router {
.route("/signup_success/:id", get(handle_signup_success))
.route("/login", get(get_login).post(post_login))
.route("/logout", get(get_logout).post(post_logout))
+ .route("/watches", get(get_watches))
+ .route("/search", get(get_search_watch).post(post_search_watch))
+ .route("/add", get(get_search_watch).put(put_add_watch))
.fallback(handle_slash_redir)
.layer(middleware::from_fn_with_state(
db_pool.clone(),
diff --git a/src/watches/handlers.rs b/src/watches/handlers.rs
index 2676320..bc103ad 100644
--- a/src/watches/handlers.rs
+++ b/src/watches/handlers.rs
@@ -6,7 +6,14 @@ use axum::{
use sqlx::{query_as, SqlitePool};
use uuid::Uuid;
-use crate::{ShowKind, User, Watch};
+use crate::{AuthContext, GetWatches, ShowKind, User, Watch};
+
+//-************************************************************************
+// Constants
+//-************************************************************************
+
+const GET_WATCHES_QUERY: &str =
+ "select * from watches left join witch_watch on $1 = witch_watch.witch and watches.id = witch_watch.watch";
//-************************************************************************
// Error types for Watch creation
@@ -32,13 +39,29 @@ impl IntoResponse for WatchAddError {
}
/// Add a Watch to the whole system
-pub async fn post_add_watch() {}
+pub async fn put_add_watch() {}
/// A single Watch
pub async fn get_watch() {}
/// everything the user has saved
-pub async fn get_watches() {}
+pub async fn get_watches(auth: AuthContext, State(pool): State
Whatcha Watchin?
+
+{% match user %}
+ {% when Some with (usr) %}
+
+ {% for watch in watches %}
+
+
+ Heya, why don't you log in or sign up? +
+{% endmatch %} + +{% endblock %} diff --git a/templates/index.html b/templates/index.html index e7c47f2..92c44f3 100644 --- a/templates/index.html +++ b/templates/index.html @@ -9,7 +9,7 @@ {% match user %} {% when Some with (usr) %}-Hello, {{ usr.username }}! It's nice to see you. + Hello, {{ usr.username }}! It's nice to see you. Let's get watchin'!
diff --git a/templates/macros.html b/templates/macros.html
new file mode 100644
index 0000000..78ce461
--- /dev/null
+++ b/templates/macros.html
@@ -0,0 +1,10 @@
+{% macro get_or_default(val, def) %}
+
+{% match val %}
+{% when Some with (v) %}
+{{v}}
+{% else %}
+{{def}}
+{% endmatch %}
+
+{% endmacro %}
From dd9a32dfd71903ad2523620cfde607ebb86c07d2 Mon Sep 17 00:00:00 2001
From: Joe Ardent
Date: Fri, 9 Jun 2023 12:51:06 -0700
Subject: [PATCH 6/6] minor mod and visibility re-org
---
src/db.rs | 5 ++--
src/generic_handlers.rs | 4 +--
src/lib.rs | 66 ++++++++++++++++++++++++-----------------
src/main.rs | 4 +--
src/signup.rs | 24 +++++++--------
src/test_utils.rs | 2 +-
6 files changed, 58 insertions(+), 47 deletions(-)
diff --git a/src/db.rs b/src/db.rs
index a6e374c..7e9d39e 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -20,7 +20,7 @@ const MIN_CONNS: u32 = 5;
const TIMEOUT: u64 = 11;
const SESSION_TTL: Duration = Duration::from_secs((365.2422 * 24. * 3600.0) as u64);
-pub async fn get_pool() -> SqlitePool {
+pub async fn get_db_pool() -> SqlitePool {
let db_filename = {
std::env::var("DATABASE_FILE").unwrap_or_else(|_| {
#[cfg(not(test))]
@@ -115,7 +115,7 @@ mod tests {
#[tokio::test]
async fn it_migrates_the_db() {
- let db = super::get_pool().await;
+ let db = super::get_db_pool().await;
let r = sqlx::query("select count(*) from witches")
.fetch_one(&db)
.await;
@@ -130,6 +130,7 @@ mod tests {
//-************************************************************************
// Session store sub-module, not a public lib.
//-************************************************************************
+#[allow(dead_code)]
mod session_store {
use async_session::{async_trait, chrono::Utc, log, serde_json, Result, Session};
use sqlx::{pool::PoolConnection, Sqlite};
diff --git a/src/generic_handlers.rs b/src/generic_handlers.rs
index a344808..cbefcb1 100644
--- a/src/generic_handlers.rs
+++ b/src/generic_handlers.rs
@@ -26,7 +26,7 @@ mod test {
#[tokio::test]
async fn slash_is_ok() {
- let pool = db::get_pool().await;
+ let pool = db::get_db_pool().await;
let secret = [0u8; 64];
let app = crate::app(pool.clone(), &secret).await.into_make_service();
@@ -37,7 +37,7 @@ mod test {
#[tokio::test]
async fn not_found_is_303() {
- let pool = db::get_pool().await;
+ let pool = db::get_db_pool().await;
let secret = [0u8; 64];
let app = crate::app(pool, &secret).await.into_make_service();
diff --git a/src/lib.rs b/src/lib.rs
index ccba9a6..482ba6a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,40 +1,45 @@
#[macro_use]
extern crate justerror;
-use axum::{middleware, routing::get, Router};
-use axum_login::SqliteStore;
-use generic_handlers::{handle_slash, handle_slash_redir};
-use login::{get_login, get_logout, post_login, post_logout};
-use signup::{get_create_user, handle_signup_success, post_create_user};
-use sqlx::SqlitePool;
-pub use users::User;
-use uuid::Uuid;
-
-pub mod db;
-pub mod generic_handlers;
-pub mod login;
-pub mod signup;
-pub(crate) mod templates;
-pub mod users;
-pub(crate) mod util;
-pub mod watches;
-pub use templates::*;
-pub use watches::templates::*;
-use watches::{
- handlers::{get_search_watch, get_watches, post_search_watch, put_add_watch},
- ShowKind, Watch,
-};
-
#[cfg(test)]
pub mod test_utils;
-pub type AuthContext = axum_login::extractors::AuthContext