make the api compile and get data from the curseforge api. allow the logger to take both types of strings.
This commit is contained in:
parent
0149ff3069
commit
b390425552
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -24,3 +24,8 @@ dist-ssr
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
target/
|
target/
|
||||||
|
|
||||||
|
Cargo.lock
|
||||||
|
yarn.lock
|
||||||
|
package.lock
|
||||||
|
velux_api/.config.yaml
|
||||||
853
Cargo.lock
generated
853
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
23
velux_api/Cargo.toml
Normal file
23
velux_api/Cargo.toml
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
[package]
|
||||||
|
name = "velux_api"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
actix-web = "4"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
reqwest = { version = "0.12.4", features = ["json"] }
|
||||||
|
serde_json = "1.0.116"
|
||||||
|
serde_yaml = "0.9.34+deprecated"
|
||||||
|
serde_repr = "0.1.19"
|
||||||
|
velux_core = { path = '../velux_core' }
|
||||||
|
|
||||||
|
[dependencies.serde]
|
||||||
|
version="1.0.198"
|
||||||
|
features = ["derive"]
|
||||||
|
|
||||||
|
[dependencies.chrono]
|
||||||
|
version = "0.4.38"
|
||||||
|
features = ["serde"]
|
||||||
22
velux_api/example.config.yaml
Normal file
22
velux_api/example.config.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Rename this file to .config.yaml with the appropriate settings configured
|
||||||
|
|
||||||
|
curseforge:
|
||||||
|
api_key: # curseforge for studios api key
|
||||||
|
|
||||||
|
#sql information
|
||||||
|
sql:
|
||||||
|
auth:
|
||||||
|
username: velux_api
|
||||||
|
password: $velux$.api
|
||||||
|
keyspace: velux
|
||||||
|
|
||||||
|
api:
|
||||||
|
#the apis that this instance supports.
|
||||||
|
supported_apis:
|
||||||
|
- velux
|
||||||
|
# supported options:
|
||||||
|
# velux, curseforge, modrinth, ftb
|
||||||
|
|
||||||
|
# the ip and port the api is hosted from.
|
||||||
|
port: 1429
|
||||||
|
ip: 127.0.0.1
|
||||||
5
velux_api/src/core.rs
Normal file
5
velux_api/src/core.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use velux_core::logger::Logger;
|
||||||
|
lazy_static!(
|
||||||
|
pub static ref API_LOGGER: Logger = Logger::new("Velux API");
|
||||||
|
);
|
||||||
36
velux_api/src/data/application_config.rs
Normal file
36
velux_api/src/data/application_config.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct ConfigurationBase {
|
||||||
|
pub curseforge: CurseforgeConfig,
|
||||||
|
pub sql: SqlConfig,
|
||||||
|
pub api: ApiConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct CurseforgeConfig {
|
||||||
|
pub api_key: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct SqlConfig {
|
||||||
|
pub auth: SqlAuthConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct SqlAuthConfig {
|
||||||
|
pub username: String,
|
||||||
|
pub password: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct ApiConfig {
|
||||||
|
pub supported_apis: Vec<String>,
|
||||||
|
pub port: u16,
|
||||||
|
pub ip: String
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref APPLICATION_CONFIG: ConfigurationBase = serde_yaml::from_str(include_str!("../../.config.yaml")).unwrap();
|
||||||
|
}
|
||||||
6
velux_api/src/data/categories.rs
Normal file
6
velux_api/src/data/categories.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
This is a Category struct used by the database.
|
||||||
|
*/
|
||||||
|
pub struct RawCategory {
|
||||||
|
|
||||||
|
}
|
||||||
6
velux_api/src/data/mod.rs
Normal file
6
velux_api/src/data/mod.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
pub mod modpack_defintiions;
|
||||||
|
pub mod categories;
|
||||||
|
pub mod application_config;
|
||||||
|
|
||||||
|
// This is the curseforge API ID for Minecraft.
|
||||||
|
pub const CURSEFORGE_MINECRAFT_GAME_ID: u32 = 432;
|
||||||
13
velux_api/src/data/modpack_defintiions.rs
Normal file
13
velux_api/src/data/modpack_defintiions.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
pub enum Distributor {
|
||||||
|
CurseForge,
|
||||||
|
Modrinth,
|
||||||
|
Velux,
|
||||||
|
FTB
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ModPack {
|
||||||
|
name: String,
|
||||||
|
project_id: String,
|
||||||
|
distributor: Distributor,
|
||||||
|
description: String
|
||||||
|
}
|
||||||
56
velux_api/src/main.rs
Normal file
56
velux_api/src/main.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
mod routes;
|
||||||
|
mod data;
|
||||||
|
mod core;
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
use actix_web::{App, HttpResponse, HttpServer, Responder, web};
|
||||||
|
use reqwest::{Client, RequestBuilder};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::core::API_LOGGER;
|
||||||
|
use crate::data::application_config::APPLICATION_CONFIG;
|
||||||
|
use crate::data::CURSEFORGE_MINECRAFT_GAME_ID;
|
||||||
|
use crate::routes::curseforge::cf_mods::CurseForgeApiMod;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct CurseForgeTestQuery {
|
||||||
|
game_id: u32,
|
||||||
|
sort_field: u32,
|
||||||
|
sort_order: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct CurseForgeApiSearchResponse {
|
||||||
|
data: Vec<CurseForgeApiMod>
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn test() -> impl Responder {
|
||||||
|
let query = CurseForgeTestQuery {
|
||||||
|
game_id: CURSEFORGE_MINECRAFT_GAME_ID,
|
||||||
|
sort_field: 1,
|
||||||
|
sort_order: "desc".to_string()
|
||||||
|
};
|
||||||
|
let client = Client::new();
|
||||||
|
let req = client.get("https://api.curseforge.com/v1/mods/search")
|
||||||
|
.header("x-api-key", &APPLICATION_CONFIG.curseforge.api_key)
|
||||||
|
.query(&query);
|
||||||
|
println!("{:?}", req);
|
||||||
|
let res = req.send().await.unwrap().text().await.unwrap();
|
||||||
|
let data = serde_json::from_str::<CurseForgeApiSearchResponse>(res.as_str());
|
||||||
|
|
||||||
|
println!("{:?}", data);
|
||||||
|
|
||||||
|
HttpResponse::Ok().body("{}")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
API_LOGGER.log(format!("Attempting to start on http://{}:{}", APPLICATION_CONFIG.api.ip, APPLICATION_CONFIG.api.port));
|
||||||
|
HttpServer::new(|| {
|
||||||
|
App::new()
|
||||||
|
.route("/", web::get().to(test))
|
||||||
|
})
|
||||||
|
.bind((APPLICATION_CONFIG.api.ip.as_str(), APPLICATION_CONFIG.api.port))?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
||||||
15
velux_api/src/routes/curseforge/cf_categories.rs
Normal file
15
velux_api/src/routes/curseforge/cf_categories.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use chrono::serde::ts_seconds;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CurseForgeApiCategory {
|
||||||
|
id: u32,
|
||||||
|
name: String,
|
||||||
|
slug: String,
|
||||||
|
icon_url: String,
|
||||||
|
#[serde(with = "ts_seconds")]
|
||||||
|
date_modified: DateTime<Utc>,
|
||||||
|
parent_category_id: u32,
|
||||||
|
}
|
||||||
43
velux_api/src/routes/curseforge/cf_file.rs
Normal file
43
velux_api/src/routes/curseforge/cf_file.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use chrono::serde::ts_seconds;
|
||||||
|
use serde::{Deserialize};
|
||||||
|
use serde_repr::Deserialize_repr;
|
||||||
|
|
||||||
|
#[derive(Deserialize_repr, PartialEq, Debug)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum CurseForgeApiFileReleaseType {
|
||||||
|
Release = 1,
|
||||||
|
Beta = 2,
|
||||||
|
Alpha = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize_repr, PartialEq, Debug)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum CurseForgeApiHashAlgorithm {
|
||||||
|
Sha1 = 1,
|
||||||
|
Md5 = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CurseForgeApiFileHash {
|
||||||
|
value: String,
|
||||||
|
algo: CurseForgeApiHashAlgorithm
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CurseForgeApiFile {
|
||||||
|
id: u32,
|
||||||
|
mod_id: u32,
|
||||||
|
is_available: bool,
|
||||||
|
display_name: String,
|
||||||
|
file_name: String,
|
||||||
|
release_type: CurseForgeApiFileReleaseType,
|
||||||
|
// hashes: Vec<CurseForgeApiFileHash>,
|
||||||
|
// file_date: DateTime<Utc>,
|
||||||
|
// file_length: u64,
|
||||||
|
// download_count: u64,
|
||||||
|
// file_size_on_disk: Option<u64>,
|
||||||
|
// download_url: String,
|
||||||
|
}
|
||||||
47
velux_api/src/routes/curseforge/cf_mods.rs
Normal file
47
velux_api/src/routes/curseforge/cf_mods.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize};
|
||||||
|
use chrono::serde::ts_seconds;
|
||||||
|
use crate::routes::curseforge::cf_file::CurseForgeApiFile;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CurseForgeApiModLinks {
|
||||||
|
pub website_url: Option<String>,
|
||||||
|
pub wiki_url: Option<String>,
|
||||||
|
pub issues_url: Option<String>,
|
||||||
|
pub source_url: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CurseForgeApiAuthor {
|
||||||
|
pub id: u32,
|
||||||
|
pub name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CurseForgeApiModAsset {
|
||||||
|
id: u32,
|
||||||
|
url: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CurseForgeApiMod {
|
||||||
|
pub id: u32,
|
||||||
|
pub name: String,
|
||||||
|
pub slug: String,
|
||||||
|
pub links: CurseForgeApiModLinks,
|
||||||
|
pub summary: String,
|
||||||
|
pub status: u32,
|
||||||
|
pub download_count: u64,
|
||||||
|
pub authors: Vec<CurseForgeApiAuthor>,
|
||||||
|
pub logo: CurseForgeApiModAsset,
|
||||||
|
pub screenshots: Vec<CurseForgeApiModAsset>,
|
||||||
|
pub main_file_id: u32,
|
||||||
|
pub latest_files: Vec<CurseForgeApiFile>,
|
||||||
|
pub date_created: DateTime<Utc>,
|
||||||
|
pub date_modified: DateTime<Utc>,
|
||||||
|
pub date_released: DateTime<Utc>,
|
||||||
|
}
|
||||||
3
velux_api/src/routes/curseforge/mod.rs
Normal file
3
velux_api/src/routes/curseforge/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod cf_mods;
|
||||||
|
mod cf_categories;
|
||||||
|
mod cf_file;
|
||||||
1
velux_api/src/routes/mod.rs
Normal file
1
velux_api/src/routes/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod curseforge;
|
||||||
|
|
@ -8,3 +8,4 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4.38"
|
chrono = "0.4.38"
|
||||||
colored = "2.1.0"
|
colored = "2.1.0"
|
||||||
|
serde = "1.0.198"
|
||||||
0
velux_core/src/chrono.rs
Normal file
0
velux_core/src/chrono.rs
Normal file
|
|
@ -1,4 +1,7 @@
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
pub mod logger;
|
pub mod logger;
|
||||||
|
mod chrono;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::fmt::Display;
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use colored::{Color, Colorize};
|
use colored::{Color, Colorize};
|
||||||
|
|
||||||
|
|
@ -13,23 +14,23 @@ impl Logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log(&self, msg: &str) {
|
pub fn log(&self, msg: impl Into<String> + Display) {
|
||||||
self.print_out("General Info", msg, Color::BrightBlue);
|
self.print_out("General Info", msg, Color::BrightBlue);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug(&self, msg: &str) {
|
pub fn debug(&self, msg: impl Into<String> + Display) {
|
||||||
self.print_out("Debug", msg, Color::Magenta);
|
self.print_out("Debug", msg, Color::Magenta);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(&self, msg: &str) {
|
pub fn error(&self, msg: impl Into<String> + Display) {
|
||||||
self.print_out("!ERROR!", msg, Color::BrightRed);
|
self.print_out("!ERROR!", msg, Color::BrightRed);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn warn(&self, msg: &str) {
|
pub fn warn(&self, msg: impl Into<String> + Display) {
|
||||||
self.print_out("Warning", msg, Color::Yellow);
|
self.print_out("Warning", msg, Color::Yellow);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_out(&self, log_type: &str, msg: &str, color: Color) {
|
fn print_out(&self, log_type: &str, msg: impl Into<String> + Display, color: Color) {
|
||||||
let date = Local::now();
|
let date = Local::now();
|
||||||
println!("{}", format!("({}) [{log_type} @ {}] -> {msg}", date.format("%m/%d/%Y %H:%M:%S"), self.name).color(color));
|
println!("{}", format!("({}) [{log_type} @ {}] -> {msg}", date.format("%m/%d/%Y %H:%M:%S"), self.name).color(color));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user