mirror of
https://github.com/JonasunderscoreJones/jonas_jones-api.git
synced 2025-10-22 16:59:17 +02:00
some updates
This commit is contained in:
parent
b852500513
commit
f93e034373
12 changed files with 265 additions and 20 deletions
59
Cargo.lock
generated
59
Cargo.lock
generated
|
@ -527,8 +527,11 @@ dependencies = [
|
||||||
"lastfm",
|
"lastfm",
|
||||||
"log",
|
"log",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"toml",
|
||||||
"warp",
|
"warp",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1030,6 +1033,15 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -1185,9 +1197,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.34.0"
|
version = "1.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9"
|
checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -1260,6 +1272,40 @@ dependencies = [
|
||||||
"tracing",
|
"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]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
@ -1693,6 +1739,15 @@ version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.5.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.50.0"
|
version = "0.50.0"
|
||||||
|
|
|
@ -9,8 +9,11 @@ edition = "2021"
|
||||||
warp = "0.3.6"
|
warp = "0.3.6"
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
tokio = { version = "1.34", features = ["macros"] }
|
tokio = { version = "1.35", features = ["macros"] }
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
lastfm = "0.6.1"
|
lastfm = "0.6.1"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
chrono = "0.4.31"
|
chrono = "0.4.31"
|
||||||
|
toml = "0.8.8"
|
||||||
|
reqwest = { version = "0.11.22", features = ["json"] }
|
||||||
|
serde_json = "1.0.108"
|
||||||
|
|
36
README.md
36
README.md
|
@ -1,2 +1,36 @@
|
||||||
# jonas_jones-api
|
# 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
10
config.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[server]
|
||||||
|
host = "localhost"
|
||||||
|
port = 8080
|
||||||
|
|
||||||
|
[lastfm]
|
||||||
|
api_key = ""
|
||||||
|
api_secret = ""
|
||||||
|
|
||||||
|
[database]
|
||||||
|
host = ""
|
84
src/config/mod.rs
Normal file
84
src/config/mod.rs
Normal 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
1
src/db/apps/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub fn main() {}
|
0
src/db/mod.rs
Normal file
0
src/db/mod.rs
Normal file
0
src/db/users/mod.rs
Normal file
0
src/db/users/mod.rs
Normal 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;
|
use warp::Filter;
|
||||||
|
|
||||||
pub fn get_builtin_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
|
pub fn get_builtin_routes() -> impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
|
||||||
warp::path("v1")
|
warp::path("v1")
|
||||||
.and((warp::path("help").map(|| "help"))
|
.and((warp::path("help").map(|| "help"))
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
8
src/v1/kcomebacks/upcoming/mod.rs
Normal file
8
src/v1/kcomebacks/upcoming/mod.rs
Normal 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))
|
||||||
|
}
|
|
@ -1,7 +1,12 @@
|
||||||
mod builtin;
|
mod builtin;
|
||||||
|
mod kcomebacks;
|
||||||
|
|
||||||
pub use builtin::get_builtin_routes as get_v1_builtin_routes;
|
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 {
|
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());
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue