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
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -23,4 +23,9 @@ dist-ssr
|
|||
*.sln
|
||||
*.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]
|
||||
chrono = "0.4.38"
|
||||
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;
|
||||
mod chrono;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::fmt::Display;
|
||||
use chrono::Local;
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn debug(&self, msg: &str) {
|
||||
pub fn debug(&self, msg: impl Into<String> + Display) {
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn warn(&self, msg: &str) {
|
||||
pub fn warn(&self, msg: impl Into<String> + Display) {
|
||||
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();
|
||||
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