Skip to content

Commit

Permalink
add repo and basic parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
zaknesler committed Apr 24, 2024
1 parent 4c22f88 commit bb090fb
Show file tree
Hide file tree
Showing 22 changed files with 125 additions and 131 deletions.

This file was deleted.

This file was deleted.

12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ edition = { workspace = true }

[dependencies]
blend-config = { path = "./crates/blend-config" }
blend-context = { path = "./crates/blend-context" }
blend-db = { path = "./crates/blend-db" }
blend-web = { path = "./crates/blend-web" }
clap = { version = "4", features = ["derive"] }
Expand Down
9 changes: 9 additions & 0 deletions crates/blend-context/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "blend-context"
version.workspace = true
edition.workspace = true

[dependencies]
blend-config = { path = "../blend-config" }
thiserror = { workspace = true }
sqlx = { workspace = true, features = ["sqlite"] }
File renamed without changes.
1 change: 1 addition & 0 deletions crates/blend-db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition.workspace = true

[dependencies]
blend-config = { path = "../blend-config" }
blend-context = { path = "../blend-context" }
chrono = { workspace = true, features = ["serde"] }
futures = "0"
serde = { workspace = true, features = ["derive"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ CREATE TABLE IF NOT EXISTS feeds (
id INTEGER PRIMARY KEY NOT NULL,
title TEXT,
url TEXT,
published_at TEXT,
updated_at TEXT
published_at DATETIME,
updated_at DATETIME
);
1 change: 1 addition & 0 deletions crates/blend-db/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod client;
pub mod error;
pub mod model;
pub mod repo;
11 changes: 5 additions & 6 deletions crates/blend-db/src/model/feed.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use sqlx::prelude::FromRow;
use ts_rs::TS;

#[derive(TS)]
#[ts(export, export_to = "../../../ui/src/types/bindings/feed.ts")]
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, FromRow)]
pub struct Feed {
pub id: i64,
pub url: Option<String>,
pub title: Option<String>,
pub published_at: Option<String>,
pub updated_at: Option<String>,
// published_at: Option<chrono::DateTime<chrono::Utc>>,
// updated_at: Option<chrono::DateTime<chrono::Utc>>,
// entries: Vec<Entry>,
pub published_at: Option<NaiveDateTime>,
pub updated_at: Option<NaiveDateTime>,
}
46 changes: 46 additions & 0 deletions crates/blend-db/src/repo/feed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use crate::{error::DbResult, model};
use chrono::{DateTime, Utc};

pub struct FeedRepo {
ctx: blend_context::Context,
}

pub struct CreateFeedParams {
pub title: Option<String>,
pub url: Option<String>,
pub published_at: Option<DateTime<Utc>>,
pub updated_at: Option<DateTime<Utc>>,
}

impl FeedRepo {
pub fn new(ctx: blend_context::Context) -> Self {
Self { ctx }
}

pub async fn get_feeds(&self) -> DbResult<Vec<model::Feed>> {
sqlx::query_as!(model::Feed, "SELECT * FROM feeds")
.fetch_all(&self.ctx.db)
.await
.map_err(|err| err.into())
}

pub async fn create_feed(&self, data: CreateFeedParams) -> DbResult<i64> {
let mut conn = self.ctx.db.acquire().await?;

let id: i64 = sqlx::query!(
r#"
INSERT INTO feeds ( title, url, published_at, updated_at )
VALUES ( ?1, ?2, ?3, ?4 )
"#,
data.title,
data.url,
data.published_at,
data.updated_at,
)
.execute(&mut *conn)
.await?
.last_insert_rowid();

Ok(id)
}
}
1 change: 1 addition & 0 deletions crates/blend-db/src/repo/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod feed;
1 change: 1 addition & 0 deletions crates/blend-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition.workspace = true

[dependencies]
blend-config = { path = "../blend-config" }
blend-context = { path = "../blend-context" }
blend-crypto = { path = "../blend-crypto" }
blend-parse = { path = "../blend-parse" }
blend-db = { path = "../blend-db" }
Expand Down
3 changes: 3 additions & 0 deletions crates/blend-web/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ pub enum WebError {
#[error(transparent)]
CryptoError(#[from] blend_crypto::error::CryptoError),

#[error(transparent)]
DbError(#[from] blend_db::error::DbError),

#[error(transparent)]
ParseError(#[from] blend_parse::error::ParseError),
}
4 changes: 1 addition & 3 deletions crates/blend-web/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
use self::error::WebResult;
use axum::http::{header, HeaderValue, Method};
use context::Context;
use tokio::net::TcpListener;
use tower_cookies::CookieManagerLayer;
use tower_http::{cors, trace::TraceLayer};

pub mod context;
pub mod error;
mod middleware;
mod response;
mod router;
mod util;

pub async fn serve(ctx: Context) -> WebResult<()> {
pub async fn serve(ctx: blend_context::Context) -> WebResult<()> {
tracing::info!(
"Starting web server on {}:{}",
ctx.blend.config.web.host,
Expand Down
4 changes: 2 additions & 2 deletions crates/blend-web/src/middleware/auth.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::{context::Context, error::WebResult, router::JWT_COOKIE};
use crate::{error::WebResult, router::JWT_COOKIE};
use axum::{body::Body, extract::State, http::Request, middleware::Next, response::IntoResponse};
use blend_crypto::jwt;
use tower_cookies::Cookies;

pub async fn middleware(
cookies: Cookies,
State(ctx): State<Context>,
State(ctx): State<blend_context::Context>,
req: Request<Body>,
next: Next,
) -> WebResult<impl IntoResponse> {
Expand Down
64 changes: 21 additions & 43 deletions crates/blend-web/src/router/feed.rs
Original file line number Diff line number Diff line change
@@ -1,71 +1,49 @@
use crate::{context::Context, error::WebResult};
use crate::error::WebResult;
use axum::{
extract::State,
response::IntoResponse,
routing::{get, post},
Json, Router,
};
use blend_db::model;
use serde::{Deserialize, Serialize};
use blend_db::repo;
use serde::Deserialize;
use serde_json::json;

pub fn router(ctx: Context) -> Router {
pub fn router(ctx: blend_context::Context) -> Router {
Router::new()
.route("/", get(index))
.route("/create", get(create))
.route("/parse", post(parse))
.route("/add", post(add))
// .route_layer(middleware::from_fn_with_state(
// ctx.clone(),
// crate::middleware::auth::middleware,
// ))
.with_state(ctx)
}

async fn index(State(ctx): State<Context>) -> WebResult<impl IntoResponse> {
let feeds: Vec<model::Feed> = sqlx::query_as!(model::Feed, "SELECT * FROM feeds")
.fetch_all(&ctx.db)
.await?;

async fn index(State(ctx): State<blend_context::Context>) -> WebResult<impl IntoResponse> {
let feeds = repo::feed::FeedRepo::new(ctx).get_feeds().await?;
Ok(Json(json!({ "data": feeds })))
}

async fn create(State(ctx): State<Context>) -> WebResult<impl IntoResponse> {
let mut conn = ctx.db.acquire().await?;

let title = "Rust Blog";
let url = "https://blog.rust-lang.org/feed.xml";

// Insert the task, then obtain the ID of this row
sqlx::query!(
r#"
INSERT INTO feeds ( title, url )
VALUES ( ?1, ?2 )
"#,
title,
url
)
.execute(&mut *conn)
.await?
.last_insert_rowid();

Ok("ok")
}

#[derive(Debug, Deserialize)]
struct ParseFeedParams {
struct AddFeedParams {
url: String,
}

async fn parse(Json(data): Json<ParseFeedParams>) -> WebResult<impl IntoResponse> {
async fn add(
State(ctx): State<blend_context::Context>,
Json(data): Json<AddFeedParams>,
) -> WebResult<impl IntoResponse> {
let parsed = blend_parse::parse_url(&data.url).await?;

let title = parsed.title.map(|title| title.content);

#[derive(Debug, Serialize)]
struct Response {
title: Option<String>,
}
let feed = repo::feed::FeedRepo::new(ctx)
.create_feed(repo::feed::CreateFeedParams {
title: parsed.title.map(|title| title.content),
url: Some("https://blog.rust-lang.org/feed.xml".to_string()),
published_at: parsed.published,
updated_at: parsed.updated,
})
.await?;

let res = Response { title };
Ok(Json(json!({"data": res})))
Ok(Json(json!({ "data": feed })))
}
5 changes: 2 additions & 3 deletions crates/blend-web/src/router/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::error::WebResult;
use crate::context::Context;
use axum::{response::IntoResponse, routing::get, Router};

mod feed;
Expand All @@ -9,14 +8,14 @@ mod user;
pub const JWT_COOKIE: &str = "blend_jwt";
// pub const CSRF_COOKIE: &str = "blend_csrf";

pub fn router(ctx: Context) -> Router {
pub fn router(ctx: blend_context::Context) -> Router {
Router::new()
.with_state(ctx.clone())
.nest("/api", api_router(ctx))
.merge(ui::router())
}

pub fn api_router(ctx: Context) -> Router {
pub fn api_router(ctx: blend_context::Context) -> Router {
Router::new()
.route("/", get(index))
.with_state(ctx.clone())
Expand Down
3 changes: 1 addition & 2 deletions crates/blend-web/src/router/user.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::context::Context;
use axum::{middleware, response::IntoResponse, routing::get, Router};

pub fn router(ctx: Context) -> Router {
pub fn router(ctx: blend_context::Context) -> Router {
Router::new()
.route("/", get(index))
.route_layer(middleware::from_fn_with_state(
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async fn main() -> error::BlendResult<()> {
crate::args::Command::Web => {
let blend = blend_config::parse(args.config)?;
let db = blend_db::client::init(blend.clone()).await?;
let context = blend_web::context::Context { blend, db };
let context = blend_context::Context { blend, db };

blend_web::serve(context).await?;
}
Expand Down
Loading

0 comments on commit bb090fb

Please sign in to comment.