2020-11-29 20:22:40 +00:00
#![ warn (clippy::pedantic) ]
2020-11-01 03:17:11 +00:00
use std ::{
2021-03-15 20:34:32 +00:00
fs ::File ,
2021-03-21 19:07:09 +00:00
path ::{ Path , PathBuf } ,
2020-11-01 03:17:11 +00:00
} ;
use structopt ::StructOpt ;
2020-11-27 00:50:22 +00:00
use ptth_server ::{
load_toml ,
2021-07-11 13:12:32 +00:00
prelude ::* ,
2020-11-27 00:50:22 +00:00
run_server ,
} ;
2020-11-06 04:18:47 +00:00
2020-11-01 03:17:11 +00:00
#[ derive (Debug, StructOpt) ]
struct Opt {
2021-03-15 20:34:32 +00:00
#[ structopt (long) ]
auto_gen_key : bool ,
2021-03-21 02:49:44 +00:00
#[ structopt (long) ]
2021-03-21 15:43:15 +00:00
throttle_upload : bool ,
2021-03-21 02:49:44 +00:00
2021-03-15 20:02:37 +00:00
#[ structopt (long) ]
file_server_root : Option < PathBuf > ,
2020-11-18 22:48:15 +00:00
2021-03-15 19:55:12 +00:00
#[ structopt (long) ]
asset_root : Option < PathBuf > ,
2020-11-01 03:17:11 +00:00
#[ structopt (long) ]
2020-11-18 22:48:15 +00:00
config_path : Option < PathBuf > ,
2020-11-18 23:24:47 +00:00
#[ structopt (long) ]
2021-03-15 19:55:12 +00:00
name : Option < String > ,
2020-11-24 23:56:43 +00:00
#[ structopt (long) ]
print_tripcode : bool ,
2021-03-15 19:55:12 +00:00
#[ structopt (long) ]
relay_url : Option < String > ,
}
#[ derive (Default, serde::Deserialize) ]
pub struct ConfigFile {
pub name : Option < String > ,
pub api_key : String ,
pub relay_url : Option < String > ,
pub file_server_root : Option < PathBuf > ,
2020-11-01 03:17:11 +00:00
}
2020-10-30 22:53:03 +00:00
2021-04-10 00:30:45 +00:00
fn gen_and_save_key ( path : & Path ) -> anyhow ::Result < ( ) > {
2021-04-10 00:43:15 +00:00
let api_key = ptth_core ::gen_key ( ) ;
2021-03-21 19:07:09 +00:00
2021-07-11 13:12:32 +00:00
let mut f = File ::create ( path ) . with_context ( | | format! ( " Can't create config file ` {:?} ` " , path ) ) ? ;
#[ cfg (unix) ]
2021-03-21 19:07:09 +00:00
{
2021-07-11 13:12:32 +00:00
use std ::os ::unix ::fs ::PermissionsExt ;
2021-03-21 19:07:09 +00:00
2021-07-11 13:12:32 +00:00
let metadata = f . metadata ( ) ? ;
let mut permissions = metadata . permissions ( ) ;
permissions . set_mode ( 0o600 ) ;
f . set_permissions ( permissions ) ? ;
}
#[ cfg (not (unix)) ]
{
tracing ::warn! ( " Error VR6VW5QT: API keys aren't protected from clients on non-Unix OSes yet " ) ;
2021-03-21 19:07:09 +00:00
}
2021-07-11 13:12:32 +00:00
f . write_all ( format! ( " api_key = \" {} \" \n " , api_key ) . as_bytes ( ) ) ? ;
2021-03-21 19:07:09 +00:00
Ok ( ( ) )
}
2021-03-15 20:34:32 +00:00
#[ tokio::main ]
async fn main ( ) -> Result < ( ) , anyhow ::Error > {
2021-03-15 19:55:12 +00:00
tracing_subscriber ::fmt ::init ( ) ;
2020-11-18 22:48:15 +00:00
let opt = Opt ::from_args ( ) ;
2021-03-15 19:55:12 +00:00
let asset_root = opt . asset_root ;
2020-11-18 22:48:15 +00:00
2020-11-18 23:24:47 +00:00
let path = opt . config_path . clone ( ) . unwrap_or_else ( | | PathBuf ::from ( " ./config/ptth_server.toml " ) ) ;
2021-03-15 20:34:32 +00:00
2021-07-13 21:02:49 +00:00
let config_file : ConfigFile = if opt . auto_gen_key {
// If we're in autonomous mode, try harder to fix things
match load_toml ::load ( & path ) {
Err ( _ ) = > {
gen_and_save_key ( & path ) ? ;
load_toml ::load ( & path ) ?
} ,
Ok ( x ) = > x ,
}
}
else {
match load_toml ::load ( & path ) {
Err ( ptth_server ::errors ::LoadTomlError ::Io ( _ ) ) = > bail! ( " API key not provided in config file and auto-gen-key not provided " ) ,
Ok ( x ) = > x ,
Err ( e ) = > return Err ( e . into ( ) ) ,
2021-03-15 20:34:32 +00:00
}
} ;
2020-11-06 05:03:33 +00:00
2021-03-15 19:55:12 +00:00
let config_file = ptth_server ::ConfigFile {
2021-07-11 13:12:32 +00:00
name : opt . name . or ( config_file . name ) . ok_or ( anyhow ::anyhow! ( " `name` must be provided in command line or config file " ) ) ? ,
2021-03-15 19:55:12 +00:00
api_key : config_file . api_key ,
2021-07-11 13:12:32 +00:00
relay_url : opt . relay_url . or ( config_file . relay_url ) . ok_or ( anyhow ::anyhow! ( " `--relay-url` must be provided in command line or `relay_url` in config file " ) ) ? ,
2021-03-15 20:02:37 +00:00
file_server_root : opt . file_server_root . or ( config_file . file_server_root ) ,
2021-03-21 15:43:15 +00:00
throttle_upload : opt . throttle_upload ,
2021-03-15 19:55:12 +00:00
} ;
2020-11-24 23:56:43 +00:00
if opt . print_tripcode {
2020-11-30 16:15:27 +00:00
println! ( r # "name = "{}""# , config_file . name ) ;
println! ( r # "tripcode = "{}""# , config_file . tripcode ( ) ) ;
2020-11-24 23:56:43 +00:00
return Ok ( ( ) ) ;
}
2021-03-15 20:34:32 +00:00
run_server (
config_file ,
ptth_core ::graceful_shutdown ::init ( ) ,
Some ( path ) ,
asset_root
) . await ? ;
2020-11-09 00:53:07 +00:00
Ok ( ( ) )
2020-10-30 22:53:03 +00:00
}