A decentralized music tracking and discovery platform built on AT Protocol 🎵

refactoring dropbox and googledrive services

+206 -128
+2
Cargo.lock
··· 1271 1271 "anyhow", 1272 1272 "async-nats", 1273 1273 "chrono", 1274 + "clap", 1274 1275 "ctr", 1275 1276 "dotenv", 1276 1277 "futures", ··· 1665 1666 "anyhow", 1666 1667 "async-nats", 1667 1668 "chrono", 1669 + "clap", 1668 1670 "ctr", 1669 1671 "dotenv", 1670 1672 "futures",
+1
crates/dropbox/Cargo.toml
··· 12 12 anyhow = "1.0.96" 13 13 async-nats = "0.39.0" 14 14 chrono = { version = "0.4.39", features = ["serde"] } 15 + clap = "4.5.31" 15 16 ctr = "0.9.2" 16 17 dotenv = "0.15.0" 17 18 futures = "0.3.31"
+2
crates/dropbox/src/cmd/mod.rs
··· 1 + pub mod scan; 2 + pub mod serve;
+15
crates/dropbox/src/cmd/scan.rs
··· 1 + use std::{env, sync::Arc}; 2 + 3 + use anyhow::Error; 4 + use sqlx::postgres::PgPoolOptions; 5 + 6 + use crate::scan::scan_dropbox; 7 + 8 + pub async fn scan() -> Result<(), Error> { 9 + let pool = PgPoolOptions::new().max_connections(5).connect(&env::var("XATA_POSTGRES_URL")?).await?; 10 + let conn = Arc::new(pool); 11 + 12 + scan_dropbox(conn).await?; 13 + 14 + Ok(()) 15 + }
+58
crates/dropbox/src/cmd/serve.rs
··· 1 + use std::{env, sync::Arc}; 2 + 3 + use actix_web::{get, post, web::{self, Data}, App, HttpRequest, HttpResponse, HttpServer, Responder}; 4 + use anyhow::Error; 5 + use owo_colors::OwoColorize; 6 + use serde_json::json; 7 + use sqlx::{postgres::PgPoolOptions, Pool, Postgres}; 8 + 9 + use crate::handlers::handle; 10 + 11 + 12 + #[get("/")] 13 + async fn index(_req: HttpRequest) -> HttpResponse { 14 + HttpResponse::Ok().json(json!({ 15 + "server": "Rocksky Dropbox Server", 16 + "version": "0.1.0", 17 + })) 18 + } 19 + 20 + #[post("/{method}")] 21 + async fn call_method( 22 + data: web::Data<Arc<Pool<Postgres>>>, 23 + mut payload: web::Payload, 24 + req: HttpRequest) -> Result<impl Responder, actix_web::Error> { 25 + let method = req.match_info().get("method").unwrap_or("unknown"); 26 + println!("Method: {}", method.bright_green()); 27 + 28 + let conn = data.get_ref().clone(); 29 + handle(method, &mut payload, &req, conn).await 30 + .map_err(actix_web::error::ErrorInternalServerError) 31 + } 32 + 33 + 34 + pub async fn serve() -> Result<(), Error> { 35 + let host = env::var("GOOGLE_DRIVE_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); 36 + let port = env::var("GOOGLE_DRIVE_PORT_PORT").unwrap_or_else(|_| "7881".to_string()); 37 + let addr = format!("{}:{}", host, port); 38 + 39 + let url = format!("http://{}", addr); 40 + println!("Listening on {}", url.bright_green()); 41 + 42 + let pool = PgPoolOptions::new().max_connections(5).connect(&env::var("XATA_POSTGRES_URL")?).await?; 43 + let conn = Arc::new(pool); 44 + 45 + let conn = conn.clone(); 46 + HttpServer::new(move || { 47 + App::new() 48 + .app_data(Data::new(conn.clone())) 49 + .service(index) 50 + .service(call_method) 51 + }) 52 + .bind(&addr)? 53 + .run() 54 + .await 55 + .map_err(Error::new)?; 56 + 57 + Ok(()) 58 + }
+26 -64
crates/dropbox/src/main.rs
··· 1 - use std::{env, sync::Arc, thread}; 2 - use actix_web::{get, post, web::{self, Data}, App, HttpRequest, HttpResponse, HttpServer, Responder}; 3 - use anyhow::Error; 1 + use clap::Command; 2 + use cmd::{serve::serve, scan::scan}; 4 3 use dotenv::dotenv; 5 - use handlers::handle; 6 - use owo_colors::OwoColorize; 7 - use scan::scan_dropbox; 8 - use serde_json::json; 9 - use sqlx::{postgres::PgPoolOptions, Pool, Postgres}; 10 4 5 + pub mod types; 11 6 pub mod xata; 12 - pub mod crypto; 7 + pub mod cmd; 13 8 pub mod handlers; 14 9 pub mod repo; 15 - pub mod types; 16 10 pub mod client; 11 + pub mod crypto; 12 + pub mod token; 17 13 pub mod consts; 18 14 pub mod scan; 19 - pub mod token; 20 15 21 - #[get("/")] 22 - async fn index(_req: HttpRequest) -> HttpResponse { 23 - HttpResponse::Ok().json(json!({ 24 - "server": "Rocksky Dropbox Server", 25 - "version": "0.1.0", 26 - })) 27 - } 28 - 29 - #[post("/{method}")] 30 - async fn call_method( 31 - data: web::Data<Arc<Pool<Postgres>>>, 32 - mut payload: web::Payload, 33 - req: HttpRequest) -> Result<impl Responder, actix_web::Error> { 34 - let method = req.match_info().get("method").unwrap_or("unknown"); 35 - println!("Method: {}", method.bright_green()); 36 - 37 - let conn = data.get_ref().clone(); 38 - handle(method, &mut payload, &req, conn).await 39 - .map_err(actix_web::error::ErrorInternalServerError) 16 + fn cli() -> Command { 17 + Command::new("dropbox") 18 + .version(env!("CARGO_PKG_VERSION")) 19 + .about("Rocksky Dropbox Service") 20 + .subcommand( 21 + Command::new("scan") 22 + .about("Scan Dropbox Music Folder") 23 + ) 24 + .subcommand( 25 + Command::new("serve") 26 + .about("Serve Rocksky Dropbox API") 27 + ) 40 28 } 41 29 42 30 #[tokio::main] 43 31 async fn main() -> Result<(), Box<dyn std::error::Error>> { 44 - dotenv().ok(); 32 + dotenv().ok(); 45 33 46 - let host = env::var("DROPBOX_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); 47 - let port = env::var("DROPBOX_PORT").unwrap_or_else(|_| "7881".to_string()); 48 - let addr = format!("{}:{}", host, port); 34 + let args = cli().get_matches(); 49 35 50 - let url = format!("http://{}", addr); 51 - println!("Listening on {}", url.bright_green()); 36 + match args.subcommand() { 37 + Some(("scan", _)) => scan().await?, 38 + Some(("serve", _)) => serve().await?, 39 + _ => serve().await?, 40 + } 52 41 53 - let pool = PgPoolOptions::new().max_connections(5).connect(&env::var("XATA_POSTGRES_URL")?).await?; 54 - let conn = Arc::new(pool); 55 - 56 - let cloned_conn = conn.clone(); 57 - 58 - thread::spawn(move || { 59 - let rt = tokio::runtime::Runtime::new().unwrap(); 60 - rt.block_on( 61 - scan_dropbox(cloned_conn) 62 - )?; 63 - Ok::<(), Error>(()) 64 - }); 65 - 66 - let conn = conn.clone(); 67 - HttpServer::new(move || { 68 - App::new() 69 - .app_data(Data::new(conn.clone())) 70 - .service(index) 71 - .service(call_method) 72 - }) 73 - .bind(&addr)? 74 - .run() 75 - .await 76 - .map_err(Error::new)?; 77 - 78 - 79 - Ok(()) 42 + Ok(()) 80 43 } 81 -
+1
crates/googledrive/Cargo.toml
··· 12 12 anyhow = "1.0.96" 13 13 async-nats = "0.39.0" 14 14 chrono = { version = "0.4.39", features = ["serde"] } 15 + clap = "4.5.31" 15 16 ctr = "0.9.2" 16 17 dotenv = "0.15.0" 17 18 futures = "0.3.31"
+2
crates/googledrive/src/cmd/mod.rs
··· 1 + pub mod scan; 2 + pub mod serve;
+15
crates/googledrive/src/cmd/scan.rs
··· 1 + use std::{env, sync::Arc}; 2 + 3 + use anyhow::Error; 4 + use sqlx::postgres::PgPoolOptions; 5 + 6 + use crate::scan::scan_googledrive; 7 + 8 + pub async fn scan() -> Result<(), Error> { 9 + let pool = PgPoolOptions::new().max_connections(5).connect(&env::var("XATA_POSTGRES_URL")?).await?; 10 + let conn = Arc::new(pool); 11 + 12 + scan_googledrive(conn).await?; 13 + 14 + Ok(()) 15 + }
+57
crates/googledrive/src/cmd/serve.rs
··· 1 + use std::{env, sync::Arc}; 2 + 3 + use actix_web::{get, post, web::{self, Data}, App, HttpRequest, HttpResponse, HttpServer, Responder}; 4 + use anyhow::Error; 5 + use owo_colors::OwoColorize; 6 + use serde_json::json; 7 + use sqlx::{postgres::PgPoolOptions, Pool, Postgres}; 8 + 9 + use crate::handlers::handle; 10 + 11 + 12 + #[get("/")] 13 + async fn index(_req: HttpRequest) -> HttpResponse { 14 + HttpResponse::Ok().json(json!({ 15 + "server": "Rocksky GoogleDrive Server", 16 + "version": "0.1.0", 17 + })) 18 + } 19 + 20 + #[post("/{method}")] 21 + async fn call_method( 22 + data: web::Data<Arc<Pool<Postgres>>>, 23 + mut payload: web::Payload, 24 + req: HttpRequest) -> Result<impl Responder, actix_web::Error> { 25 + let method = req.match_info().get("method").unwrap_or("unknown"); 26 + println!("Method: {}", method.bright_green()); 27 + 28 + let conn = data.get_ref().clone(); 29 + handle(method, &mut payload, &req, conn).await 30 + .map_err(actix_web::error::ErrorInternalServerError) 31 + } 32 + 33 + pub async fn serve() -> Result<(), Error> { 34 + let host = env::var("GOOGLE_DRIVE_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); 35 + let port = env::var("GOOGLE_DRIVE_PORT_PORT").unwrap_or_else(|_| "7880".to_string()); 36 + let addr = format!("{}:{}", host, port); 37 + 38 + let url = format!("http://{}", addr); 39 + println!("Listening on {}", url.bright_green()); 40 + 41 + let pool = PgPoolOptions::new().max_connections(5).connect(&env::var("XATA_POSTGRES_URL")?).await?; 42 + let conn = Arc::new(pool); 43 + 44 + let conn = conn.clone(); 45 + HttpServer::new(move || { 46 + App::new() 47 + .app_data(Data::new(conn.clone())) 48 + .service(index) 49 + .service(call_method) 50 + }) 51 + .bind(&addr)? 52 + .run() 53 + .await 54 + .map_err(Error::new)?; 55 + 56 + Ok(()) 57 + }
+27 -64
crates/googledrive/src/main.rs
··· 1 - use std::{env, sync::Arc, thread}; 2 - use actix_web::{get, post, web::{self, Data}, App, HttpRequest, HttpResponse, HttpServer, Responder}; 3 - use anyhow::Error; 1 + use clap::Command; 2 + use cmd::{serve::serve, scan::scan}; 4 3 use dotenv::dotenv; 5 - use handlers::handle; 6 - use owo_colors::OwoColorize; 7 - use scan::scan_googledrive; 8 - use serde_json::json; 9 - use sqlx::{postgres::PgPoolOptions, Pool, Postgres}; 10 4 11 - pub mod token; 5 + pub mod types; 12 6 pub mod xata; 13 - pub mod crypto; 7 + pub mod cmd; 14 8 pub mod handlers; 15 9 pub mod repo; 16 - pub mod types; 17 10 pub mod client; 11 + pub mod crypto; 12 + pub mod token; 18 13 pub mod consts; 19 14 pub mod scan; 20 15 21 - #[get("/")] 22 - async fn index(_req: HttpRequest) -> HttpResponse { 23 - HttpResponse::Ok().json(json!({ 24 - "server": "Rocksky GoogleDrive Server", 25 - "version": "0.1.0", 26 - })) 16 + fn cli() -> Command { 17 + Command::new("googledrive") 18 + .version(env!("CARGO_PKG_VERSION")) 19 + .about("Rocksky Google Drive Service") 20 + .subcommand( 21 + Command::new("scan") 22 + .about("Scan Google Drive Music Folder") 23 + ) 24 + .subcommand( 25 + Command::new("serve") 26 + .about("Serve Rocksky Google Drive API") 27 + ) 27 28 } 28 29 29 - #[post("/{method}")] 30 - async fn call_method( 31 - data: web::Data<Arc<Pool<Postgres>>>, 32 - mut payload: web::Payload, 33 - req: HttpRequest) -> Result<impl Responder, actix_web::Error> { 34 - let method = req.match_info().get("method").unwrap_or("unknown"); 35 - println!("Method: {}", method.bright_green()); 36 - 37 - let conn = data.get_ref().clone(); 38 - handle(method, &mut payload, &req, conn).await 39 - .map_err(actix_web::error::ErrorInternalServerError) 40 - } 41 - 42 - 43 30 #[tokio::main] 44 31 async fn main() -> Result<(), Box<dyn std::error::Error>> { 45 - dotenv().ok(); 32 + dotenv().ok(); 46 33 47 - let host = env::var("GOOGLE_DRIVE_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); 48 - let port = env::var("GOOGLE_DRIVE_PORT_PORT").unwrap_or_else(|_| "7880".to_string()); 49 - let addr = format!("{}:{}", host, port); 34 + let args = cli().get_matches(); 50 35 51 - let url = format!("http://{}", addr); 52 - println!("Listening on {}", url.bright_green()); 36 + match args.subcommand() { 37 + Some(("scan", _)) => scan().await?, 38 + Some(("serve", _)) => serve().await?, 39 + _ => serve().await?, 40 + } 53 41 54 - let pool = PgPoolOptions::new().max_connections(5).connect(&env::var("XATA_POSTGRES_URL")?).await?; 55 - let conn = Arc::new(pool); 56 - 57 - let cloned_conn = conn.clone(); 58 - 59 - thread::spawn(move || { 60 - let rt = tokio::runtime::Runtime::new().unwrap(); 61 - rt.block_on( 62 - scan_googledrive(cloned_conn) 63 - )?; 64 - Ok::<(), Error>(()) 65 - }); 66 - 67 - let conn = conn.clone(); 68 - HttpServer::new(move || { 69 - App::new() 70 - .app_data(Data::new(conn.clone())) 71 - .service(index) 72 - .service(call_method) 73 - }) 74 - .bind(&addr)? 75 - .run() 76 - .await 77 - .map_err(Error::new)?; 78 - 79 - Ok(()) 80 - } 42 + Ok(()) 43 + }