separate league logo type [refs #25]
This commit is contained in:
parent
3e201c1738
commit
41b27f2cc4
10 changed files with 211 additions and 190 deletions
|
|
@ -1,17 +1,15 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, LockResult, RwLock};
|
||||
use axum_server::tls_rustls::RustlsConfig;
|
||||
use image::imageops::FilterType;
|
||||
use image::{GenericImageView, ImageFormat, ImageReader};
|
||||
use sslo_lib::app_state::SsloAppState;
|
||||
use sslo_lib::error::SsloError;
|
||||
use sslo_lib::parameters::{DEFAULT_LOBBY_URL, LEAGUE_LOGO_MAX_DIMENSION};
|
||||
use sslo_lib::pathbuf::PathBufSslo;
|
||||
use sslo_lib::sync::command::Commander;
|
||||
use db2::DatabaseManagerData;
|
||||
use shutdown_control::ShutdownControl;
|
||||
use slot_mgr::SlotMgr;
|
||||
use config::Config;
|
||||
use crate::app_state::league_logo::LeagueLogo;
|
||||
use crate::app_state::lobby_mgr::LobbyMgr;
|
||||
|
||||
pub mod shutdown_control;
|
||||
|
|
@ -19,6 +17,7 @@ pub mod slot_mgr;
|
|||
pub mod db2;
|
||||
pub mod config;
|
||||
mod lobby_mgr;
|
||||
mod league_logo;
|
||||
|
||||
pub type AppState = SsloAppState<LeagueAppState>;
|
||||
|
||||
|
|
@ -96,6 +95,15 @@ impl LeagueAppState {
|
|||
}
|
||||
};
|
||||
|
||||
// league logo
|
||||
let (league_logo_local, league_logo_http) = match LeagueLogo::install(&database_dir, &config) {
|
||||
Ok((logo_local, logo_http)) => (Some(logo_local), Some(logo_http)),
|
||||
Err(e) => {
|
||||
log::error!("Installing league logo failed: {}", e);
|
||||
(None, None)
|
||||
}
|
||||
};
|
||||
|
||||
// setup lobby manager
|
||||
let lobby_mgr = match LobbyMgr::new(shutdown_control.clone(), &config) {
|
||||
Ok(lobby_mgr) => lobby_mgr,
|
||||
|
|
@ -112,16 +120,11 @@ impl LeagueAppState {
|
|||
database_dir,
|
||||
config,
|
||||
database,
|
||||
league_logo_http: None,
|
||||
league_logo_local: None,
|
||||
league_logo_http,
|
||||
league_logo_local,
|
||||
lobby_mgr,
|
||||
};
|
||||
|
||||
// league logo
|
||||
if let Err(e) = install_league_logo(&mut app_state) {
|
||||
log::error!("Installing league logo failed: {}", e);
|
||||
}
|
||||
|
||||
Ok(SsloAppState::new(
|
||||
app_state.database_dir.clone(),
|
||||
app_state
|
||||
|
|
@ -159,7 +162,7 @@ impl LeagueAppState {
|
|||
|
||||
/// Returns a path to the htdata/ directory
|
||||
pub fn path_htdata(&self) -> PathBuf {
|
||||
self.database_dir.clone().push_vec(&["htdata"])
|
||||
self.database_dir.clone().push_vec_str(&["htdata"])
|
||||
}
|
||||
|
||||
/// Returns the path to the league logo as relative http path
|
||||
|
|
@ -184,104 +187,3 @@ impl LeagueAppState {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// A type that stores the path to the league logo - either as svg or png
|
||||
#[derive(Clone)]
|
||||
pub enum LeagueLogo {
|
||||
Png(PathBuf),
|
||||
Svg(PathBuf),
|
||||
}
|
||||
|
||||
impl LeagueLogo {
|
||||
|
||||
/// Returns a reference to the logo path (no matter if svg or png)
|
||||
pub fn path_ref(&self) -> &Path {
|
||||
match self {
|
||||
Self::Svg(path) => path,
|
||||
Self::Png(path) => path,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn install_league_logo(app_state: &mut LeagueAppState) -> Result<(), SsloError> {
|
||||
|
||||
// image paths
|
||||
let img_src = app_state.dbpath(&app_state.config.general.logo);
|
||||
let img_dst_svg = app_state.path_htdata().push_vec(&["league_logo.svg"]);
|
||||
let img_dst_png = app_state.path_htdata().push_vec(&["league_logo.png"]);
|
||||
|
||||
// delete old logo images
|
||||
if img_dst_svg.is_file() {
|
||||
std::fs::remove_file(&img_dst_svg).inspect_err(|e| {
|
||||
log::error!("Failed removing file '{:?}': {}", &img_dst_svg, e);
|
||||
})?;
|
||||
}
|
||||
if img_dst_png.is_file() {
|
||||
std::fs::remove_file(&img_dst_png).inspect_err(|e| {
|
||||
log::error!("Failed removing file '{:?}': {}", &img_dst_png, e);
|
||||
})?;
|
||||
}
|
||||
|
||||
// process images
|
||||
match img_src.extension() {
|
||||
None => {
|
||||
log::warn!("Invalid logo path: '{}'", img_src.display());
|
||||
}
|
||||
|
||||
// svg
|
||||
Some(extension) if extension.to_ascii_lowercase() == "svg" => {
|
||||
std::fs::copy(&img_src, &img_dst_svg).inspect_err(|e| {
|
||||
log::error!("Failed copying file '{:?}': {}", &img_dst_svg, &e);
|
||||
})?;
|
||||
app_state.league_logo_http = Some(LeagueLogo::Svg(PathBuf::from("/htdata/league_logo.svg")));
|
||||
app_state.league_logo_local = Some(LeagueLogo::Svg(img_dst_svg));
|
||||
},
|
||||
|
||||
// pixel graphic
|
||||
Some(_) => {
|
||||
|
||||
// open image
|
||||
let img = match ImageReader::open(&img_src) {
|
||||
Ok(img) => match img.with_guessed_format() {
|
||||
Ok(img) => img,
|
||||
Err(e) => {
|
||||
log::error!("Failed to read image '{:?}': {}", &img_src, e);
|
||||
return Err(SsloError::GeneralError(format!("Failed to read image '{:?}': {}", &img_src, e)));
|
||||
},
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to read image '{:?}': {}", &img_src, e);
|
||||
return Err(SsloError::GeneralError(format!("Failed to read image '{:?}': {}", &img_src, e)));
|
||||
}
|
||||
};
|
||||
|
||||
// decode image
|
||||
let img = match img.decode() {
|
||||
Ok(img) => img,
|
||||
Err(e) => {
|
||||
log::error!("Failed to read image '{:?}': {}", &img_src, e);
|
||||
return Err(SsloError::GeneralError(format!("Failed to read image '{:?}': {}", &img_src, e)));
|
||||
},
|
||||
};
|
||||
|
||||
// limit size
|
||||
let (img_width, img_height) = img.dimensions();
|
||||
let max_dim = LEAGUE_LOGO_MAX_DIMENSION;
|
||||
let img = match img_width > max_dim.width || img_height > max_dim.height {
|
||||
true => img.resize(max_dim.width, max_dim.height, FilterType::Lanczos3),
|
||||
false => img,
|
||||
};
|
||||
|
||||
// save as png
|
||||
img.save_with_format(&img_dst_png, ImageFormat::Png).inspect_err(|e| {
|
||||
log::error!("Failed saving image '{:?}': {}", &img_src, e);
|
||||
})?;
|
||||
|
||||
app_state.league_logo_http = Some(LeagueLogo::Png(PathBuf::from("/htdata/league_logo.png")));
|
||||
app_state.league_logo_local = Some(LeagueLogo::Png(img_dst_png));
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
109
sslo_league/src/app_state/league_logo.rs
Normal file
109
sslo_league/src/app_state/league_logo.rs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use image::imageops::FilterType;
|
||||
use image::{GenericImageView, ImageFormat, ImageReader};
|
||||
use sslo_lib::error::SsloError;
|
||||
use sslo_lib::parameters::LEAGUE_LOGO_MAX_DIMENSION;
|
||||
use sslo_lib::pathbuf::PathBufSslo;
|
||||
use crate::app_state::config::Config;
|
||||
|
||||
/// A type that stores the path to the league logo - either as svg or png
|
||||
#[derive(Clone)]
|
||||
pub enum LeagueLogo {
|
||||
Png(PathBuf),
|
||||
Svg(PathBuf),
|
||||
}
|
||||
|
||||
impl LeagueLogo {
|
||||
|
||||
/// Returns a reference to the logo path (no matter if svg or png)
|
||||
pub fn path_ref(&self) -> &Path {
|
||||
match self {
|
||||
Self::Svg(path) => path,
|
||||
Self::Png(path) => path,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns two instances: Local-Logo-Path and Http-Logo-Path on success
|
||||
pub fn install(database_dir: &PathBuf, config: &Config) -> Result<(Self, Self), SsloError> {
|
||||
|
||||
// image paths
|
||||
let img_src = database_dir.clone().push_vec_path(&[&config.general.logo]);
|
||||
let img_dst_svg = database_dir.clone().push_vec_str(&["htdata", "league_logo.svg"]);
|
||||
let img_dst_png = database_dir.clone().push_vec_str(&["htdata", "league_logo.png"]);
|
||||
|
||||
// delete old logo images
|
||||
if img_dst_svg.is_file() {
|
||||
std::fs::remove_file(&img_dst_svg).inspect_err(|e| {
|
||||
log::error!("Failed removing file '{:?}': {}", &img_dst_svg, e);
|
||||
})?;
|
||||
}
|
||||
if img_dst_png.is_file() {
|
||||
std::fs::remove_file(&img_dst_png).inspect_err(|e| {
|
||||
log::error!("Failed removing file '{:?}': {}", &img_dst_png, e);
|
||||
})?;
|
||||
}
|
||||
|
||||
// process images
|
||||
match img_src.extension() {
|
||||
None => {
|
||||
log::warn!("Invalid logo path: '{}'", img_src.display());
|
||||
Err(SsloError::GeneralError(format!("Invalid logo path (no extension): {}", img_src.display())))
|
||||
}
|
||||
|
||||
// svg
|
||||
Some(extension) if extension.to_ascii_lowercase() == "svg" => {
|
||||
std::fs::copy(&img_src, &img_dst_svg).inspect_err(|e| {
|
||||
log::error!("Failed copying file '{:?}': {}", &img_dst_svg, &e);
|
||||
})?;
|
||||
let logo_http = LeagueLogo::Svg(PathBuf::from("/htdata/league_logo.svg"));
|
||||
let logo_local = LeagueLogo::Svg(img_dst_svg);
|
||||
Ok((logo_local, logo_http))
|
||||
},
|
||||
|
||||
// pixel graphic
|
||||
Some(_) => {
|
||||
|
||||
// open image
|
||||
let img = match ImageReader::open(&img_src) {
|
||||
Ok(img) => match img.with_guessed_format() {
|
||||
Ok(img) => img,
|
||||
Err(e) => {
|
||||
log::error!("Failed to read image '{:?}': {}", &img_src, e);
|
||||
return Err(SsloError::GeneralError(format!("Failed to read image '{:?}': {}", &img_src, e)));
|
||||
},
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to read image '{:?}': {}", &img_src, e);
|
||||
return Err(SsloError::GeneralError(format!("Failed to read image '{:?}': {}", &img_src, e)));
|
||||
}
|
||||
};
|
||||
|
||||
// decode image
|
||||
let img = match img.decode() {
|
||||
Ok(img) => img,
|
||||
Err(e) => {
|
||||
log::error!("Failed to read image '{:?}': {}", &img_src, e);
|
||||
return Err(SsloError::GeneralError(format!("Failed to read image '{:?}': {}", &img_src, e)));
|
||||
},
|
||||
};
|
||||
|
||||
// limit size
|
||||
let (img_width, img_height) = img.dimensions();
|
||||
let max_dim = LEAGUE_LOGO_MAX_DIMENSION;
|
||||
let img = match img_width > max_dim.width || img_height > max_dim.height {
|
||||
true => img.resize(max_dim.width, max_dim.height, FilterType::Lanczos3),
|
||||
false => img,
|
||||
};
|
||||
|
||||
// save as png
|
||||
img.save_with_format(&img_dst_png, ImageFormat::Png).inspect_err(|e| {
|
||||
log::error!("Failed saving image '{:?}': {}", &img_src, e);
|
||||
})?;
|
||||
|
||||
let logo_http = LeagueLogo::Png(PathBuf::from("/htdata/league_logo.png"));
|
||||
let logo_local = LeagueLogo::Png(img_dst_png);
|
||||
Ok((logo_local, logo_http))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -215,7 +215,7 @@ pub async fn handler_edit(State(app_state): State<AppState>,
|
|||
};
|
||||
|
||||
// save image
|
||||
let mut img_path = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "classes"]);
|
||||
let mut img_path = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "classes"]);
|
||||
if let Err(e) = img_path.mkdirs() {
|
||||
log::error!("Creating directory {:?} failed: {}", &img_path, e);
|
||||
return ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, "Could not save image").into_response();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use crate::app_state::db2::content::countries::CountryItem;
|
|||
pub async fn install_assetto_corsa(app_state: AppState) -> Result<(), SsloError> {
|
||||
|
||||
// check if install package exist
|
||||
let pkg_dir = app_state.substate().database_dir.clone().push_vec(&["package", "assetto_corsa"]);
|
||||
let pkg_dir = app_state.substate().database_dir.clone().push_vec_str(&["package", "assetto_corsa"]);
|
||||
if !pkg_dir.is_dir() {
|
||||
log::warn!("Skip Assetto Corsa installation, because not found in package");
|
||||
return Ok(());
|
||||
|
|
@ -219,7 +219,7 @@ async fn scan_cars(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
let tbl_liveries = app_state.substate().database.db_content().await.tbl_liveries().await;
|
||||
|
||||
// crate sorted list of car directories
|
||||
let cars_dir = ac_pkg_dir.clone().push_vec(&["content", "cars"]);
|
||||
let cars_dir = ac_pkg_dir.clone().push_vec_str(&["content", "cars"]);
|
||||
let mut car_dirs: Vec<std::fs::DirEntry> = cars_dir.read_dir().map_err(|e| {
|
||||
log::error!("Failed reading dir '{:?}': {}", &cars_dir, e);
|
||||
return;
|
||||
|
|
@ -253,7 +253,7 @@ async fn scan_cars(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
pbar.inc(1);
|
||||
|
||||
// parse ui_car.json
|
||||
let ui_car = match UiCarJson::from_file(car_dir.path().push_vec(&["ui", "ui_car.json"])) {
|
||||
let ui_car = match UiCarJson::from_file(car_dir.path().push_vec_str(&["ui", "ui_car.json"])) {
|
||||
Ok(json) => json,
|
||||
Err(e) => {
|
||||
log::warn!("Failed to install car {}: {}", car_id, e);
|
||||
|
|
@ -270,9 +270,9 @@ async fn scan_cars(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
}
|
||||
};
|
||||
if brand.set_deprecated(false).await.is_err() { continue; }
|
||||
let badge = car_dir.path().push_vec(&["ui", "badge.png"]);
|
||||
let badge = car_dir.path().push_vec_str(&["ui", "badge.png"]);
|
||||
if badge.is_file() {
|
||||
let dst = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "brands", &format!("{}.png", brand.id().await)]);
|
||||
let dst = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "brands", &format!("{}.png", brand.id().await)]);
|
||||
if let Err(e) = badge.copy_file(&dst) {
|
||||
log::error!("Failed copying '{:?}' to '{:?}': {}", &badge, &dst, e);
|
||||
}
|
||||
|
|
@ -288,10 +288,10 @@ async fn scan_cars(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
};
|
||||
if car.set_name(&ui_car.name).await.is_err() { continue; }
|
||||
if car.set_deprecated(false).await.is_err() { continue; }
|
||||
let car_image = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "cars", &format!("{}.jpg", car.id().await)]);
|
||||
let car_image = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "cars", &format!("{}.jpg", car.id().await)]);
|
||||
scan_car_skins(&app_state, &car_dir.path(), &car).await;
|
||||
for livery in tbl_liveries.list_by_car(&car).await {
|
||||
let livery_image = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "liveries", &format!("{}.jpg", livery.id().await)]);
|
||||
let livery_image = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "liveries", &format!("{}.jpg", livery.id().await)]);
|
||||
if livery_image.is_file() {
|
||||
if let Err(e) = livery_image.copy_file(&car_image) {
|
||||
log::error!("Copying file from '{:?}' to '{:?}' failed: {}", &livery_image, &car_image, e);
|
||||
|
|
@ -307,7 +307,7 @@ async fn scan_cars(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
|
||||
async fn scan_car_skins(app_state: &AppState, ac_pkg_car_dir: &PathBuf, car: &CarItem) {
|
||||
let tbl_livs = app_state.substate().database.db_content().await.tbl_liveries().await;
|
||||
let skins_dir = ac_pkg_car_dir.clone().push_vec(&["skins"]);
|
||||
let skins_dir = ac_pkg_car_dir.clone().push_vec_str(&["skins"]);
|
||||
let skins_dir_iterator = match skins_dir.read_dir() {
|
||||
Ok(i) => i,
|
||||
Err(e) => {
|
||||
|
|
@ -328,7 +328,7 @@ async fn scan_car_skins(app_state: &AppState, ac_pkg_car_dir: &PathBuf, car: &Ca
|
|||
// log::debug!("installing livery: {}", skin_id);
|
||||
|
||||
// parse ui_skin.json
|
||||
let ui_skin = match UiSkinJson::from_file(skin_dir.clone().push_vec(&["ui_skin.json"])) {
|
||||
let ui_skin = match UiSkinJson::from_file(skin_dir.clone().push_vec_str(&["ui_skin.json"])) {
|
||||
Ok(json) => json,
|
||||
Err(e) => {
|
||||
log::warn!("Failed to install car/skin {}/{}: {}", car.sim_data().await, skin_id, e);
|
||||
|
|
@ -349,9 +349,9 @@ async fn scan_car_skins(app_state: &AppState, ac_pkg_car_dir: &PathBuf, car: &Ca
|
|||
if livery.set_deprecated(false).await.is_err() { continue; }
|
||||
|
||||
// check for preview
|
||||
let preview = skin_dir.clone().push_vec(&["preview.jpg"]);
|
||||
let preview = skin_dir.clone().push_vec_str(&["preview.jpg"]);
|
||||
if preview.is_file() {
|
||||
let dst = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "liveries", &format!("{}.jpg", livery.id().await)]);
|
||||
let dst = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "liveries", &format!("{}.jpg", livery.id().await)]);
|
||||
if let Err(e) = preview.copy_file(&dst) {
|
||||
log::error!("Failed to copy livery image from '{:?}' to '{:?}': {}", &preview, &dst, e);
|
||||
continue;
|
||||
|
|
@ -374,7 +374,7 @@ async fn scan_tracks(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
let tbl_tracks = app_state.substate().database.db_content().await.tbl_tracks().await;
|
||||
|
||||
// create sorted list of track directories
|
||||
let tracks_dir = ac_pkg_dir.clone().push_vec(&["content", "tracks"]);
|
||||
let tracks_dir = ac_pkg_dir.clone().push_vec_str(&["content", "tracks"]);
|
||||
let mut track_dirs: Vec<std::fs::DirEntry> = tracks_dir.read_dir().map_err(|e| {
|
||||
log::error!("Failed reading dir '{:?}': {}", &tracks_dir, e);
|
||||
return;
|
||||
|
|
@ -406,7 +406,7 @@ async fn scan_tracks(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
pbar.inc(1);
|
||||
|
||||
// parse ui_track.json
|
||||
let file_ui_track = track_dir.path().push_vec(&["ui", "ui_track.json"]);
|
||||
let file_ui_track = track_dir.path().push_vec_str(&["ui", "ui_track.json"]);
|
||||
if file_ui_track.is_file() {
|
||||
let ui_track = match UiTrackJson::from_file(file_ui_track) {
|
||||
Ok(json) => json,
|
||||
|
|
@ -451,9 +451,9 @@ async fn scan_tracks(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
log::error!("Failed to update location: {}", e);
|
||||
continue;
|
||||
}
|
||||
let preview = track_dir.path().push_vec(&["ui", "preview.png"]);
|
||||
let preview = track_dir.path().push_vec_str(&["ui", "preview.png"]);
|
||||
if preview.is_file() {
|
||||
let dst = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "locations", &format!("{}.png", location.id().await)]);
|
||||
let dst = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "locations", &format!("{}.png", location.id().await)]);
|
||||
if let Err(e) = preview.copy_file(&dst) {
|
||||
log::error!("Failed to copy preview image from '{:?}' to '{:?}': {}", &preview, &dst, e);
|
||||
continue;
|
||||
|
|
@ -475,7 +475,7 @@ async fn scan_tracks(app_state: AppState, ac_pkg_dir: &PathBuf) {
|
|||
|
||||
// install preview
|
||||
if preview.is_file() {
|
||||
let dst = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "tracks", &format!("{}.png", track.id().await)]);
|
||||
let dst = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "tracks", &format!("{}.png", track.id().await)]);
|
||||
if let Err(e) = preview.copy_file(&dst) {
|
||||
log::error!("Failed to copy preview image from '{:?}' to '{:?}': {}", &preview, &dst, e);
|
||||
continue;
|
||||
|
|
@ -498,7 +498,7 @@ async fn scan_track_variants(app_state: AppState, ac_track_dir: &PathBuf) {
|
|||
// gather all ui_track jsons
|
||||
let mut ui_tracks: Vec<UiTrackJson> = Vec::new();
|
||||
for track_variant_dir in ac_track_dir.clone()
|
||||
.push_vec(&["ui"])
|
||||
.push_vec_str(&["ui"])
|
||||
.read_dir()
|
||||
.map_err(|e| { log::error!("Failed reading '{:?}/ui': {}", ac_track_dir, e); return; }).unwrap() {
|
||||
if let Ok(track_variant_dir) = track_variant_dir {
|
||||
|
|
@ -509,7 +509,7 @@ async fn scan_track_variants(app_state: AppState, ac_track_dir: &PathBuf) {
|
|||
// };
|
||||
|
||||
// parse ui_track.json
|
||||
let file_ui_track = track_variant_dir.path().push_vec(&["ui_track.json"]);
|
||||
let file_ui_track = track_variant_dir.path().push_vec_str(&["ui_track.json"]);
|
||||
if file_ui_track.is_file() {
|
||||
match UiTrackJson::from_file(file_ui_track.clone()) {
|
||||
Ok(json) => ui_tracks.push(json),
|
||||
|
|
@ -585,7 +585,7 @@ async fn scan_track_variants(app_state: AppState, ac_track_dir: &PathBuf) {
|
|||
return;
|
||||
}
|
||||
if let Some(preview) = location_preview {
|
||||
let dst = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "locations", &format!("{}.png", location.id().await)]);
|
||||
let dst = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "locations", &format!("{}.png", location.id().await)]);
|
||||
if let Err(e) = preview.copy_file(&dst) {
|
||||
log::error!("Failed to copy preview image from '{:?}' to '{:?}': {}", &preview, &dst, e);
|
||||
return;
|
||||
|
|
@ -617,9 +617,9 @@ async fn scan_track_variants(app_state: AppState, ac_track_dir: &PathBuf) {
|
|||
if track.set_deprecated(false).await.is_err() {continue;}
|
||||
|
||||
// install preview
|
||||
let preview = ui_track.path.parent().unwrap().to_path_buf().push_vec(&["preview.png"]);
|
||||
let preview = ui_track.path.parent().unwrap().to_path_buf().push_vec_str(&["preview.png"]);
|
||||
if preview.is_file() {
|
||||
let dst = app_state.substate().database_dir.clone().push_vec(&["htdata", "db_content", "tracks", &format!("{}.png", track.id().await)]);
|
||||
let dst = app_state.substate().database_dir.clone().push_vec_str(&["htdata", "db_content", "tracks", &format!("{}.png", track.id().await)]);
|
||||
if let Err(e) = preview.copy_file(&dst) {
|
||||
log::error!("Failed to copy preview image from '{:?}' to '{:?}': {}", &preview, &dst, e);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ where T: Clone
|
|||
}
|
||||
|
||||
// locate file
|
||||
let abs_filepath = app_state.database_path().clone().push_vec(&["htdata", &filepath]);
|
||||
let abs_filepath = app_state.database_path().clone().push_vec_str(&["htdata", &filepath]);
|
||||
if !abs_filepath.is_file() {
|
||||
log::warn!("Invalid file requested: {:?}", &filepath);
|
||||
return Err(StatusCode::NOT_FOUND)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ use crate::error::SsloError;
|
|||
pub trait PathBufSslo {
|
||||
|
||||
/// push multiple sub paths into this PathBuf
|
||||
fn push_vec(self, appendix: &[&str]) -> Self;
|
||||
fn push_vec_str(self, appendix: &[&str]) -> Self;
|
||||
|
||||
/// push multiple sub paths into this PathBuf
|
||||
fn push_vec_path(self, appendix: &[&Path]) -> Self;
|
||||
|
||||
/// When Self is an existing file, it will be copied to dst_file
|
||||
fn copy_file(&self, dst_file: &Path) -> Result<(), SsloError>;
|
||||
|
|
@ -15,7 +18,14 @@ pub trait PathBufSslo {
|
|||
|
||||
impl PathBufSslo for PathBuf {
|
||||
|
||||
fn push_vec(mut self, appendix: &[&str]) -> Self {
|
||||
fn push_vec_str(mut self, appendix: &[&str]) -> Self {
|
||||
for apx in appendix {
|
||||
self.push(apx);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn push_vec_path(mut self, appendix: &[&Path]) -> Self {
|
||||
for apx in appendix {
|
||||
self.push(apx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,6 @@ impl LobbyAppState {
|
|||
|
||||
/// Returns a path to the htdata/ directory
|
||||
pub fn path_htdata(&self) -> PathBuf {
|
||||
self.database_dir.clone().push_vec(&["htdata"])
|
||||
self.database_dir.clone().push_vec_str(&["htdata"])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ impl LeagueItem {
|
|||
item_data.row.upsert(&pool).await?
|
||||
}
|
||||
|
||||
let img_path = path_htdata.push_vec(&["db_content", "leagues", &format!("{}.svg", item_data.row.rowid)]);;
|
||||
let img_path = path_htdata.push_vec_str(&["db_content", "leagues", &format!("{}.svg", item_data.row.rowid)]);;
|
||||
let mut file = File::create(&img_path).await.inspect_err(|e| {
|
||||
log::error!("Creating file '{}' failed: {}", img_path.display(), e);
|
||||
})?;
|
||||
|
|
@ -199,7 +199,7 @@ impl LeagueItem {
|
|||
item_data.row.upsert(&pool).await?
|
||||
}
|
||||
|
||||
let img_path = path_htdata.push_vec(&["db_content", "leagues", &format!("{}.svg", item_data.row.rowid)]);;
|
||||
let img_path = path_htdata.push_vec_str(&["db_content", "leagues", &format!("{}.svg", item_data.row.rowid)]);;
|
||||
img.save_with_format(&img_path, ImageFormat::Png).inspect_err(|e| {
|
||||
log::error!("Saving image to {:?} failed: {}", &img_path, e);
|
||||
})?;
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ pub async fn handler_update_league_logo(State(app_state): State<AppState>,
|
|||
}
|
||||
|
||||
// image path (without actual filename)
|
||||
let mut img_path = app_state.substate().path_htdata().push_vec(&["db_content", "leagues"]);;
|
||||
let mut img_path = app_state.substate().path_htdata().push_vec_str(&["db_content", "leagues"]);;
|
||||
if let Err(e) = img_path.mkdirs() {
|
||||
log::error!("Creating directory {:?} failed: {}", &img_path, e);
|
||||
return ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, "Could not save image").into_response();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ pub async fn work(app_state: AppState) -> Result<(), SsloError> {
|
|||
if let Some(config_sim) = &app_state.config.assetto_corsa {
|
||||
|
||||
// check if ac exe could be found
|
||||
let path_expected_ac = config_sim.install_path.clone().push_vec(&["AssettoCorsa.exe"]);
|
||||
let path_expected_ac = config_sim.install_path.clone().push_vec_str(&["AssettoCorsa.exe"]);
|
||||
match std::fs::exists(&path_expected_ac) {
|
||||
Ok(true) => {},
|
||||
Ok(false) => {
|
||||
|
|
@ -35,15 +35,15 @@ pub async fn work(app_state: AppState) -> Result<(), SsloError> {
|
|||
})?;
|
||||
|
||||
// server
|
||||
let dir_ac_srv = config_sim.install_path.clone().push_vec(&["server"]);
|
||||
let dir_pkg_srv = path_pkg_ac.clone().push_vec(&["server"]);
|
||||
let dir_ac_srv = config_sim.install_path.clone().push_vec_str(&["server"]);
|
||||
let dir_pkg_srv = path_pkg_ac.clone().push_vec_str(&["server"]);
|
||||
if let Err(e) = package_server(&dir_ac_srv, &dir_pkg_srv).await {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
// tracks
|
||||
let dir_tracks_ac: PathBuf = config_sim.install_path.clone().push_vec(&["content", "tracks"]);
|
||||
let dir_tracks_pkg = path_pkg_ac.clone().push_vec(&["content", "tracks"]);
|
||||
let dir_tracks_ac: PathBuf = config_sim.install_path.clone().push_vec_str(&["content", "tracks"]);
|
||||
let dir_tracks_pkg = path_pkg_ac.clone().push_vec_str(&["content", "tracks"]);
|
||||
std::fs::create_dir_all(&dir_tracks_pkg).map_err(|e| {
|
||||
log::error!("Failed to create directory '{:?}': {}", &path_pkg_ac, e);
|
||||
SsloError::DirCreateError(path_pkg_ac.clone())
|
||||
|
|
@ -51,8 +51,8 @@ pub async fn work(app_state: AppState) -> Result<(), SsloError> {
|
|||
scan_tracks(&dir_tracks_ac, &dir_tracks_pkg).await?;
|
||||
|
||||
// cars
|
||||
let dir_cars_ac: PathBuf = config_sim.install_path.clone().push_vec(&["content", "cars"]);
|
||||
let dir_cars_pkg = path_pkg_ac.clone().push_vec(&["content", "cars"]);
|
||||
let dir_cars_ac: PathBuf = config_sim.install_path.clone().push_vec_str(&["content", "cars"]);
|
||||
let dir_cars_pkg = path_pkg_ac.clone().push_vec_str(&["content", "cars"]);
|
||||
std::fs::create_dir_all(&dir_cars_ac).map_err(|e| {
|
||||
log::error!("Failed to create directory '{:?}': {}", &path_pkg_ac, e);
|
||||
SsloError::DirCreateError(path_pkg_ac.clone())
|
||||
|
|
@ -100,18 +100,18 @@ async fn package_server(dir_ac_server: &PathBuf, dir_pkg_server: &PathBuf) -> Re
|
|||
let mut no_erros = true;
|
||||
|
||||
// copy acServer
|
||||
let src = dir_ac_server.clone().push_vec(&["acServer"]);
|
||||
let dst = dir_pkg_server.clone().push_vec(&["acServer"]);
|
||||
let src = dir_ac_server.clone().push_vec_str(&["acServer"]);
|
||||
let dst = dir_pkg_server.clone().push_vec_str(&["acServer"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy acServer.exe
|
||||
let src = dir_ac_server.clone().push_vec(&["acServer.exe"]);
|
||||
let dst = dir_pkg_server.clone().push_vec(&["acServer.exe"]);
|
||||
let src = dir_ac_server.clone().push_vec_str(&["acServer.exe"]);
|
||||
let dst = dir_pkg_server.clone().push_vec_str(&["acServer.exe"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy surfaces.ini
|
||||
let src = dir_ac_server.clone().push_vec(&["system", "data", "surfaces.ini"]);
|
||||
let dst = dir_pkg_server.clone().push_vec(&["system", "data", "surfaces.ini"]);
|
||||
let src = dir_ac_server.clone().push_vec_str(&["system", "data", "surfaces.ini"]);
|
||||
let dst = dir_pkg_server.clone().push_vec_str(&["system", "data", "surfaces.ini"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// check for errors
|
||||
|
|
@ -176,38 +176,38 @@ fn package_track(ac_track_dir: &PathBuf, pkg_track_dir: &PathBuf) -> Result<(),
|
|||
let mut no_erros = true;
|
||||
|
||||
// check non-variant
|
||||
let path_ui_json = ac_track_dir.clone().push_vec(&["ui", "ui_track.json"]);
|
||||
let path_ui_json = ac_track_dir.clone().push_vec_str(&["ui", "ui_track.json"]);
|
||||
if path_ui_json.is_file() {
|
||||
|
||||
// copy ui.json
|
||||
let dst = pkg_track_dir.clone().push_vec(&["ui", "ui_track.json"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["ui", "ui_track.json"]);
|
||||
no_erros &= path_ui_json.copy_file(&dst).is_ok();
|
||||
|
||||
// copy surfaces.ini
|
||||
let src = ac_track_dir.clone().push_vec(&["data", "surfaces.ini"]);
|
||||
let dst = pkg_track_dir.clone().push_vec(&["data", "surfaces.ini"]);
|
||||
let src = ac_track_dir.clone().push_vec_str(&["data", "surfaces.ini"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["data", "surfaces.ini"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy drs_zones.ini
|
||||
let src = ac_track_dir.clone().push_vec(&["data", "drs_zones.ini"]);
|
||||
let src = ac_track_dir.clone().push_vec_str(&["data", "drs_zones.ini"]);
|
||||
if src.is_file() {
|
||||
let dst = pkg_track_dir.clone().push_vec(&["data", "drs_zones.ini"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["data", "drs_zones.ini"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
}
|
||||
|
||||
// copy outline.png
|
||||
let src = ac_track_dir.clone().push_vec(&["ui", "outline.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec(&["ui", "outline.png"]);
|
||||
let src = ac_track_dir.clone().push_vec_str(&["ui", "outline.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["ui", "outline.png"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy preview.png
|
||||
let src = ac_track_dir.clone().push_vec(&["ui", "preview.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec(&["ui", "preview.png"]);
|
||||
let src = ac_track_dir.clone().push_vec_str(&["ui", "preview.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["ui", "preview.png"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy map.png
|
||||
let src = ac_track_dir.clone().push_vec(&["map.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec(&["map.png"]);
|
||||
let src = ac_track_dir.clone().push_vec_str(&["map.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["map.png"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// check for errors
|
||||
|
|
@ -217,7 +217,7 @@ fn package_track(ac_track_dir: &PathBuf, pkg_track_dir: &PathBuf) -> Result<(),
|
|||
}
|
||||
|
||||
// check for variants
|
||||
let track_ui_dir = ac_track_dir.clone().push_vec(&["ui"]);
|
||||
let track_ui_dir = ac_track_dir.clone().push_vec_str(&["ui"]);
|
||||
if no_erros && track_ui_dir.is_dir() {
|
||||
for track_variant_ui in track_ui_dir.read_dir().map_err(|e| {
|
||||
log::error!("Failed reading dir '{:?}': {}", &ac_track_dir, e);
|
||||
|
|
@ -239,39 +239,39 @@ fn package_track(ac_track_dir: &PathBuf, pkg_track_dir: &PathBuf) -> Result<(),
|
|||
};
|
||||
|
||||
// copy surfaces.ini
|
||||
let src = ac_track_dir.clone().push_vec(&[&track_variant_name, "data", "surfaces.ini"]);
|
||||
let src = ac_track_dir.clone().push_vec_str(&[&track_variant_name, "data", "surfaces.ini"]);
|
||||
if !src.is_file() {
|
||||
log::warn!("Skip packaging track, because of missing file {:?}", src);
|
||||
continue;
|
||||
}
|
||||
let dst = pkg_track_dir.clone().push_vec(&[&track_variant_name, "data", "surfaces.ini"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&[&track_variant_name, "data", "surfaces.ini"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy drs_zones.ini
|
||||
let src = ac_track_dir.clone().push_vec(&[&track_variant_name, "data", "drs_zones.ini"]);
|
||||
let src = ac_track_dir.clone().push_vec_str(&[&track_variant_name, "data", "drs_zones.ini"]);
|
||||
if src.is_file() { // not all tracks have DRS
|
||||
let dst = pkg_track_dir.clone().push_vec(&[&track_variant_name, "data", "drs_zones.ini"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&[&track_variant_name, "data", "drs_zones.ini"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
}
|
||||
|
||||
// copy map.png
|
||||
let src = ac_track_dir.clone().push_vec(&[&track_variant_name, "map.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec(&[&track_variant_name, "map.png"]);
|
||||
let src = ac_track_dir.clone().push_vec_str(&[&track_variant_name, "map.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&[&track_variant_name, "map.png"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy ui_track.json
|
||||
let src = track_variant_ui.path().push_vec(&["ui_track.json"]);
|
||||
let dst = pkg_track_dir.clone().push_vec(&["ui", &track_variant_name, "ui_track.json"]);
|
||||
let src = track_variant_ui.path().push_vec_str(&["ui_track.json"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["ui", &track_variant_name, "ui_track.json"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy outline.png
|
||||
let src = track_variant_ui.path().push_vec(&["outline.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec(&["ui", &track_variant_name, "outline.png"]);
|
||||
let src = track_variant_ui.path().push_vec_str(&["outline.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["ui", &track_variant_name, "outline.png"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy preview.png
|
||||
let src = track_variant_ui.path().push_vec(&["preview.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec(&["ui", &track_variant_name, "preview.png"]);
|
||||
let src = track_variant_ui.path().push_vec_str(&["preview.png"]);
|
||||
let dst = pkg_track_dir.clone().push_vec_str(&["ui", &track_variant_name, "preview.png"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// check for errors
|
||||
|
|
@ -345,23 +345,23 @@ fn package_car(ac_car_dir: &PathBuf, pkg_car_dir: &PathBuf) -> Result<(), SsloEr
|
|||
let mut no_erros = true;
|
||||
|
||||
// copy path_data_acd
|
||||
let src = ac_car_dir.clone().push_vec(&["data.acd"]);
|
||||
let dst = pkg_car_dir.clone().push_vec(&["data.acd"]);
|
||||
let src = ac_car_dir.clone().push_vec_str(&["data.acd"]);
|
||||
let dst = pkg_car_dir.clone().push_vec_str(&["data.acd"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy ui_car.json
|
||||
let src = ac_car_dir.clone().push_vec(&["ui", "ui_car.json"]);
|
||||
let dst = pkg_car_dir.clone().push_vec(&["ui", "ui_car.json"]);
|
||||
let src = ac_car_dir.clone().push_vec_str(&["ui", "ui_car.json"]);
|
||||
let dst = pkg_car_dir.clone().push_vec_str(&["ui", "ui_car.json"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy badge.png
|
||||
let src = ac_car_dir.clone().push_vec(&["ui", "badge.png"]);
|
||||
let dst = pkg_car_dir.clone().push_vec(&["ui", "badge.png"]);
|
||||
let src = ac_car_dir.clone().push_vec_str(&["ui", "badge.png"]);
|
||||
let dst = pkg_car_dir.clone().push_vec_str(&["ui", "badge.png"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// scan skins
|
||||
if no_erros {
|
||||
let skins_dir = ac_car_dir.clone().push_vec(&["skins"]);
|
||||
let skins_dir = ac_car_dir.clone().push_vec_str(&["skins"]);
|
||||
for skin_entry in skins_dir.read_dir().map_err(|e| {
|
||||
log::error!("Failed on dir '{:?}': {}", &skins_dir, e);
|
||||
SsloError::DirReadError(skins_dir.clone())
|
||||
|
|
@ -380,17 +380,17 @@ fn package_car(ac_car_dir: &PathBuf, pkg_car_dir: &PathBuf) -> Result<(), SsloEr
|
|||
};
|
||||
|
||||
// copy ui_skin.json
|
||||
let src = skin_entry.path().push_vec(&["ui_skin.json"]);
|
||||
let src = skin_entry.path().push_vec_str(&["ui_skin.json"]);
|
||||
if !src.is_file() {
|
||||
log::warn!("Skiping skin, because of missing file: '{:?}'", src);
|
||||
continue;
|
||||
}
|
||||
let dst = pkg_car_dir.clone().push_vec(&["skins", &skin_name, "ui_skin.json"]);
|
||||
let dst = pkg_car_dir.clone().push_vec_str(&["skins", &skin_name, "ui_skin.json"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
|
||||
// copy preview.jpg
|
||||
let src = skin_entry.path().push_vec(&["preview.jpg"]);
|
||||
let dst = pkg_car_dir.clone().push_vec(&["skins", &skin_name, "preview.jpg"]);
|
||||
let src = skin_entry.path().push_vec_str(&["preview.jpg"]);
|
||||
let dst = pkg_car_dir.clone().push_vec_str(&["skins", &skin_name, "preview.jpg"]);
|
||||
no_erros &= src.copy_file(&dst).is_ok();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue