serve match logs

This commit is contained in:
Ilion Beyst 2022-01-02 17:56:52 +01:00
parent 85dcf3ba2f
commit 69331eb08a
3 changed files with 46 additions and 8 deletions

View file

@ -1,5 +1,5 @@
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use diesel::{BelongingToDsl, RunQueryDsl}; use diesel::{BelongingToDsl, QueryDsl, RunQueryDsl};
use diesel::{Connection, GroupedBy, PgConnection, QueryResult}; use diesel::{Connection, GroupedBy, PgConnection, QueryResult};
use crate::schema::{match_players, matches}; use crate::schema::{match_players, matches};
@ -95,3 +95,22 @@ pub fn list_matches(conn: &PgConnection) -> QueryResult<Vec<MatchData>> {
Ok(res) Ok(res)
}) })
} }
pub fn find_match(id: i32, conn: &PgConnection) -> QueryResult<MatchData> {
conn.transaction(|| {
let match_base = matches::table.find(id).get_result::<MatchBase>(conn)?;
let match_players = MatchPlayer::belonging_to(&match_base).load::<MatchPlayer>(conn)?;
let res = MatchData {
base: match_base,
match_players,
};
Ok(res)
})
}
pub fn find_mach_base(id: i32, conn: &PgConnection) -> QueryResult<MatchBase> {
matches::table.find(id).get_result::<MatchBase>(conn)
}

View file

@ -52,6 +52,7 @@ pub async fn api() -> Router {
"/matches", "/matches",
get(routes::matches::list_matches).post(routes::matches::play_match), get(routes::matches::list_matches).post(routes::matches::play_match),
) )
.route("/matches/:match_id", get(routes::matches::get_match_log))
.layer(AddExtensionLayer::new(pool)); .layer(AddExtensionLayer::new(pool));
api api
} }

View file

@ -1,6 +1,9 @@
use std::path::PathBuf; use std::{io::Read, path::PathBuf};
use axum::{extract::Extension, Json}; use axum::{
extract::{Extension, Path},
Json,
};
use hyper::StatusCode; use hyper::StatusCode;
use planetwars_matchrunner::{run_match, MatchConfig, MatchPlayer}; use planetwars_matchrunner::{run_match, MatchConfig, MatchPlayer};
use rand::{distributions::Alphanumeric, Rng}; use rand::{distributions::Alphanumeric, Rng};
@ -30,7 +33,7 @@ pub async fn play_match(
.take(16) .take(16)
.map(char::from) .map(char::from)
.collect(); .collect();
let log_path = PathBuf::from(MATCHES_DIR).join(&format!("{}.log", slug)); let log_file_name = format!("{}.log", slug);
let mut players = Vec::new(); let mut players = Vec::new();
let mut bot_ids = Vec::new(); let mut bot_ids = Vec::new();
@ -58,22 +61,27 @@ pub async fn play_match(
let match_config = MatchConfig { let match_config = MatchConfig {
map_name: "hex".to_string(), map_name: "hex".to_string(),
map_path, map_path,
log_path: log_path.clone(), log_path: PathBuf::from(MATCHES_DIR).join(&log_file_name),
players: players, players: players,
}; };
tokio::spawn(run_match_task(match_config, bot_ids, pool.clone())); tokio::spawn(run_match_task(
match_config,
log_file_name,
bot_ids,
pool.clone(),
));
Ok(()) Ok(())
} }
async fn run_match_task( async fn run_match_task(
config: MatchConfig, config: MatchConfig,
log_file_name: String,
match_players: Vec<matches::MatchPlayerData>, match_players: Vec<matches::MatchPlayerData>,
pool: ConnectionPool, pool: ConnectionPool,
) { ) {
let log_path = config.log_path.as_os_str().to_str().unwrap().to_string();
let match_data = matches::NewMatch { let match_data = matches::NewMatch {
log_path: &log_path, log_path: &log_file_name,
}; };
run_match(config).await; run_match(config).await;
@ -119,3 +127,13 @@ pub struct BotConfig {
pub run_command: String, pub run_command: String,
pub build_command: Option<String>, pub build_command: Option<String>,
} }
pub async fn get_match_log(
Path(match_id): Path<i32>,
conn: DatabaseConnection,
) -> Result<Vec<u8>, StatusCode> {
let match_base = matches::find_mach_base(match_id, &conn).map_err(|_| StatusCode::NOT_FOUND)?;
let log_path = PathBuf::from(MATCHES_DIR).join(&match_base.log_path);
let log_contents = std::fs::read(log_path).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(log_contents)
}