mirror of
https://github.com/Dummi26/musicdb.git
synced 2025-03-10 14:13:53 +01:00
server/lib: can now have custom-files which clients can access if they know the path.
This commit is contained in:
parent
f61f52fdc7
commit
273eac4b43
@ -26,6 +26,12 @@ pub struct Database {
|
|||||||
albums: HashMap<AlbumId, Album>,
|
albums: HashMap<AlbumId, Album>,
|
||||||
songs: HashMap<SongId, Song>,
|
songs: HashMap<SongId, Song>,
|
||||||
covers: HashMap<CoverId, Cover>,
|
covers: HashMap<CoverId, Cover>,
|
||||||
|
/// clients can access files in this directory if they know the relative path.
|
||||||
|
/// can be used to embed custom images in tags of songs/albums/artists.
|
||||||
|
/// None -> no access
|
||||||
|
/// Some(None) -> access to lib_directory
|
||||||
|
/// Some(Some(path)) -> access to path
|
||||||
|
pub custom_files: Option<Option<PathBuf>>,
|
||||||
// These will be used for autosave once that gets implemented
|
// These will be used for autosave once that gets implemented
|
||||||
db_data_file_change_first: Option<Instant>,
|
db_data_file_change_first: Option<Instant>,
|
||||||
db_data_file_change_last: Option<Instant>,
|
db_data_file_change_last: Option<Instant>,
|
||||||
@ -374,6 +380,7 @@ impl Database {
|
|||||||
albums: HashMap::new(),
|
albums: HashMap::new(),
|
||||||
songs: HashMap::new(),
|
songs: HashMap::new(),
|
||||||
covers: HashMap::new(),
|
covers: HashMap::new(),
|
||||||
|
custom_files: None,
|
||||||
db_data_file_change_first: None,
|
db_data_file_change_first: None,
|
||||||
db_data_file_change_last: None,
|
db_data_file_change_last: None,
|
||||||
queue: QueueContent::Folder(0, vec![], String::new()).into(),
|
queue: QueueContent::Folder(0, vec![], String::new()).into(),
|
||||||
@ -392,6 +399,7 @@ impl Database {
|
|||||||
albums: HashMap::new(),
|
albums: HashMap::new(),
|
||||||
songs: HashMap::new(),
|
songs: HashMap::new(),
|
||||||
covers: HashMap::new(),
|
covers: HashMap::new(),
|
||||||
|
custom_files: None,
|
||||||
db_data_file_change_first: None,
|
db_data_file_change_first: None,
|
||||||
db_data_file_change_last: None,
|
db_data_file_change_last: None,
|
||||||
queue: QueueContent::Folder(0, vec![], String::new()).into(),
|
queue: QueueContent::Folder(0, vec![], String::new()).into(),
|
||||||
@ -412,6 +420,7 @@ impl Database {
|
|||||||
albums: ToFromBytes::from_bytes(&mut file)?,
|
albums: ToFromBytes::from_bytes(&mut file)?,
|
||||||
songs: ToFromBytes::from_bytes(&mut file)?,
|
songs: ToFromBytes::from_bytes(&mut file)?,
|
||||||
covers: ToFromBytes::from_bytes(&mut file)?,
|
covers: ToFromBytes::from_bytes(&mut file)?,
|
||||||
|
custom_files: None,
|
||||||
db_data_file_change_first: None,
|
db_data_file_change_first: None,
|
||||||
db_data_file_change_last: None,
|
db_data_file_change_last: None,
|
||||||
queue: QueueContent::Folder(0, vec![], String::new()).into(),
|
queue: QueueContent::Folder(0, vec![], String::new()).into(),
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
fs,
|
||||||
io::BufRead,
|
io::BufRead,
|
||||||
io::{BufReader, Read, Write},
|
io::{BufReader, Read, Write},
|
||||||
|
path::Path,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -118,16 +120,24 @@ pub fn handle_one_connection_as_get(
|
|||||||
writeln!(connection.get_mut(), "no data")?;
|
writeln!(connection.get_mut(), "no data")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"song-file-blocking" => {
|
"custom-file" => {
|
||||||
if let Some(bytes) =
|
if let Some(bytes) = request.next().and_then(|path| {
|
||||||
request
|
|
||||||
.next()
|
|
||||||
.and_then(|id| id.parse().ok())
|
|
||||||
.and_then(|id| {
|
|
||||||
let db = db.lock().unwrap();
|
let db = db.lock().unwrap();
|
||||||
db.get_song(&id).and_then(|song| song.cached_data_now(&db))
|
let mut parent = match &db.custom_files {
|
||||||
})
|
None => None,
|
||||||
{
|
Some(None) => Some(db.lib_directory.clone()),
|
||||||
|
Some(Some(p)) => Some(p.clone()),
|
||||||
|
};
|
||||||
|
// check for malicious paths
|
||||||
|
if Path::new(path).is_absolute() {
|
||||||
|
parent = None;
|
||||||
|
}
|
||||||
|
if let Some(parent) = parent {
|
||||||
|
fs::read(parent.join(path)).ok()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}) {
|
||||||
writeln!(connection.get_mut(), "len: {}", bytes.len())?;
|
writeln!(connection.get_mut(), "len: {}", bytes.len())?;
|
||||||
connection.get_mut().write_all(&bytes)?;
|
connection.get_mut().write_all(&bytes)?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -31,13 +31,17 @@ struct Args {
|
|||||||
/// requires the `assets/` folder to be present!
|
/// requires the `assets/` folder to be present!
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
web: Option<SocketAddr>,
|
web: Option<SocketAddr>,
|
||||||
|
|
||||||
|
/// allow clients to access files in this directory, or the lib_dir if not specified.
|
||||||
|
#[arg(long)]
|
||||||
|
custom_files: Option<Option<PathBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
// parse args
|
// parse args
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let database = if args.init {
|
let mut database = if args.init {
|
||||||
Database::new_empty(args.dbfile, args.lib_dir)
|
Database::new_empty(args.dbfile, args.lib_dir)
|
||||||
} else {
|
} else {
|
||||||
match Database::load_database(args.dbfile.clone(), args.lib_dir.clone()) {
|
match Database::load_database(args.dbfile.clone(), args.lib_dir.clone()) {
|
||||||
@ -51,6 +55,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
database.custom_files = args.custom_files;
|
||||||
// database can be shared by multiple threads using Arc<Mutex<_>>
|
// database can be shared by multiple threads using Arc<Mutex<_>>
|
||||||
let database = Arc::new(Mutex::new(database));
|
let database = Arc::new(Mutex::new(database));
|
||||||
if args.tcp.is_some() || args.web.is_some() {
|
if args.tcp.is_some() || args.web.is_some() {
|
||||||
|
Loading…
Reference in New Issue
Block a user