some updates

This commit is contained in:
Jonas_Jones 2023-12-13 04:19:04 +01:00
parent b852500513
commit f93e034373
12 changed files with 265 additions and 20 deletions

59
Cargo.lock generated
View file

@ -527,8 +527,11 @@ dependencies = [
"lastfm",
"log",
"parking_lot",
"reqwest",
"serde",
"serde_json",
"tokio",
"toml",
"warp",
]
@ -1030,6 +1033,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -1185,9 +1197,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.34.0"
version = "1.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9"
checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c"
dependencies = [
"backtrace",
"bytes",
@ -1260,6 +1272,40 @@ dependencies = [
"tracing",
]
[[package]]
name = "toml"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "tower-service"
version = "0.3.2"
@ -1693,6 +1739,15 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "winnow"
version = "0.5.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.50.0"

View file

@ -9,8 +9,11 @@ edition = "2021"
warp = "0.3.6"
parking_lot = "0.12.1"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.34", features = ["macros"] }
tokio = { version = "1.35", features = ["macros"] }
dotenv = "0.15.0"
lastfm = "0.6.1"
log = "0.4.20"
chrono = "0.4.31"
toml = "0.8.8"
reqwest = { version = "0.11.22", features = ["json"] }
serde_json = "1.0.108"

View file

@ -1,2 +1,36 @@
# jonas_jones-api
api used for my website
API supporting the Jonas_Jones project infrastructure.
## Installation
As of now, the project has no proper production build and unless the proper environment variables are set, the API will not work.
Clone the repository and install the dependencies.
```bash
$ git clone git@github.com:J-onasJones/jonas_jones-api.git
$ cd jonas_jones-api
$ cargo build
```
## Usage
To run the API, simply run the following command.
```bash
$ cargo run
```
If you want to run the API in a production environment, you will need to set the following environment variables.
- API_PORT
- API_IP =
- LASTFM_API_KEY
- LASTFM_API_SECRET
```bash
$ export API_PORT={port}
$ export API_IP={ip_address}
$ export LASTFM_API_KEY={lastfm_api_key}
$ export LASTFM_API_SECRET={lastfm_api_secret}
```

10
config.toml Normal file
View file

@ -0,0 +1,10 @@
[server]
host = "localhost"
port = 8080
[lastfm]
api_key = ""
api_secret = ""
[database]
host = ""

84
src/config/mod.rs Normal file
View file

@ -0,0 +1,84 @@
use std::fs::{File, OpenOptions};
use std::io::prelude::*;
use serde::{Deserialize, Serialize};
use crate::Logger;
#[derive(Debug, Deserialize, Serialize)]
pub struct ServerConfig {
host: String,
port: u32,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct LastFMConfig {
api_key: String,
api_secret: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct DatabaseConfig {
host: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Config {
server: ServerConfig,
lastfm: LastFMConfig,
database: DatabaseConfig,
}
pub fn load_config() -> (ServerConfig, LastFMConfig, DatabaseConfig) {
// load config.toml. create new one if it doesn't exist
// return config
let config_path = "config.toml";
if !std::path::Path::new(config_path).exists() {
// If it doesn't exist, create a new config file with default values
create_default_config(config_path);
}
// Read the configuration file
let mut config_file = File::open("config.toml").expect({Logger::panic("Failed to open config file"); std::process::exit(1)});
let mut config_toml = String::new();
config_file
.read_to_string(&mut config_toml)
.expect("Failed to read config file");
// Deserialize the TOML into the AppConfig struct
let config: Config = toml::from_str(&config_toml).expect({Logger::panic("Failed to deserialize config file"); std::process::exit(1)});
// Return the config
return (config.server, config.lastfm, config.database);
}
fn create_default_config(path: &str) {
// Create default Config
let default_config = Config {
server: ServerConfig {
host: String::from("localhost"),
port: 8080,
},
lastfm: LastFMConfig {
api_key: String::from(""),
api_secret: String::from(""),
},
database: DatabaseConfig {
host: String::from(""),
},
};
// Serialize default config to TOML
let toml_string = toml::to_string_pretty(&default_config).expect("Failed to serialize config");
// Write the TOML string to the config file
let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)
.expect("Failed to open config file for writing");
file.write_all(toml_string.as_bytes())
.expect("Failed to write to config file");
}

1
src/db/apps/mod.rs Normal file
View file

@ -0,0 +1 @@
pub fn main() {}

0
src/db/mod.rs Normal file
View file

0
src/db/users/mod.rs Normal file
View file

View file

@ -1,16 +1,5 @@
// pub fn help() -> warp::reply::Response {
// return warp::reply::Reply::with_header(
// warp::reply::html(""),
// "Content-Type",
// "text/html",
// );
// }
// create a function help() that returns a response with a ststus code of 200 and a body of "help"
use warp::Filter;
pub fn get_builtin_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path("v1")
.and((warp::path("help").map(|| "help"))

View file

@ -1,3 +1,59 @@
pub fn main() {
use std::convert::Infallible;
use warp::Filter;
use reqwest::Error;
pub fn get_kcomebacks_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path("v1").and(warp::path("kcomebacks"))
// - /v1/kcomebacks/last_update
// - /v1/kcomebacks/start_update with token
// - /v1/kcomebacks/upcoming/today?limit={0-50}&offset={n}
// - /v1/kcomebacks/upcoming/week?limit={0-50}&offset={n}
// - /v1/kcomebacks/upcoming/month?limit={0-50}&offset={n}
// - /v1/kcomebacks/filter/id?id={n}
// - /v1/kcomebacks/filter/daterange?start={date: YYYY-MM-DD}&end={date: YYYY-MM-DD}&limit={0-50}&offset={n}
// - /v1/kcomebacks/filter/artist?artist={artist}&limit={0-50}&offset={n}
// - /v1/kcomebacks/filter/first
// - /v1/kcomebacks/filter/last
// - /v1/kcomebacks/filter/title?title={title}&limit={0-50}&offset={n}
// - /v1/kcomebacks/filter/type?type={type}&limit={0-50}&offset={n}
// - /v1/kcomebacks/filter/gettypes
.and(warp::path("last_update").and(warp::get()).and_then(last_update_handler)
.or(warp::path("start_update").map(|| "Not implemented yet")))
}
// get json data from https://cdn.jonasjones.dev/api/kcomebacks/rkpop_data.json
async fn fetch_data() -> Result<serde_json::Value, Error> {
let url = "https://cdn.jonasjones.dev/api/kcomebacks/rkpop_data.json";
let response = reqwest::get(url).await?;
if response.status().is_success() {
// Parse the JSON response
let json_data: serde_json::Value = response.json().await?;
return Ok(json_data);
} else {
// Handle non-successful status codes
Err(response.error_for_status().unwrap_err())
}
}
async fn last_update_handler() -> Result<impl warp::Reply, warp::Rejection> {
match last_update().await {
Ok(last_update_value) => Ok(warp::reply::json(&last_update_value)),
Err(_) => {
#[derive(Debug)]
struct InternalServerError;
impl warp::reject::Reject for InternalServerError {}
Err(warp::reject::custom(InternalServerError))
}
}
}
async fn last_update() -> Result<serde_json::Value, Error> {
// get the value of last_update of the first element of the json that fetch_data() returns
let last_update_value = fetch_data().await?.get(0).unwrap().get("last_update").unwrap().clone();
return Ok(last_update_value);
}

View file

@ -0,0 +1,8 @@
pub fn get_kcomebacks_upcoming_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
warp::path("upcoming")
.and(warp::path("today").and(warp::get()).and_then(upcoming_today_handler))
.or(warp::path("week").and(warp::get()).and_then(upcoming_week_handler))
.or(warp::path("month").and(warp::get()).and_then(upcoming_month_handler))
}

View file

@ -1,7 +1,12 @@
mod builtin;
mod kcomebacks;
pub use builtin::get_builtin_routes as get_v1_builtin_routes;
pub use kcomebacks::get_kcomebacks_routes as get_v1_kcomebacks_routes;
use warp::Filter;
pub fn get_v1_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
return get_v1_builtin_routes();
return get_v1_builtin_routes()
.or(get_v1_kcomebacks_routes());
}