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:
Nepgfurmixpro 2024-04-25 00:58:18 -04:00
parent 0149ff3069
commit b390425552
19 changed files with 1142 additions and 9 deletions

5
.gitignore vendored
View File

@ -24,3 +24,8 @@ dist-ssr
*.sw?
target/
Cargo.lock
yarn.lock
package.lock
velux_api/.config.yaml

853
Cargo.lock generated

File diff suppressed because it is too large Load Diff

23
velux_api/Cargo.toml Normal file
View 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"]

View 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
View 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");
);

View 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();
}

View File

@ -0,0 +1,6 @@
/*
This is a Category struct used by the database.
*/
pub struct RawCategory {
}

View 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;

View 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
View 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
}

View 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,
}

View 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,
}

View 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>,
}

View File

@ -0,0 +1,3 @@
pub mod cf_mods;
mod cf_categories;
mod cf_file;

View File

@ -0,0 +1 @@
pub mod curseforge;

View File

@ -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
View File

View File

@ -1,4 +1,7 @@
extern crate core;
pub mod logger;
mod chrono;
#[cfg(test)]
mod tests {

View File

@ -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));
}