rustfmt
This commit is contained in:
parent
f21e4e055f
commit
2150241ae1
8 changed files with 635 additions and 588 deletions
|
@ -52,9 +52,8 @@ pub fn get_api_handler(collection: Arc<Collection>) -> Mount {
|
||||||
|
|
||||||
{
|
{
|
||||||
let collection = collection.clone();
|
let collection = collection.clone();
|
||||||
api_handler.mount("/auth/", move |request: &mut Request| {
|
api_handler.mount("/auth/",
|
||||||
self::auth(request, collection.deref())
|
move |request: &mut Request| self::auth(request, collection.deref()));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -189,7 +188,7 @@ fn serve(request: &mut Request, collection: &Collection) -> IronResult<Response>
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_song(real_path.as_path()) {
|
if is_song(real_path.as_path()) {
|
||||||
return Ok(Response::with((status::Ok, real_path)))
|
return Ok(Response::with((status::Ok, real_path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_image(real_path.as_path()) {
|
if is_image(real_path.as_path()) {
|
||||||
|
@ -203,6 +202,6 @@ fn art(_: &mut Request, real_path: &Path) -> IronResult<Response> {
|
||||||
let thumb = get_thumbnail(real_path, 400);
|
let thumb = get_thumbnail(real_path, 400);
|
||||||
match thumb {
|
match thumb {
|
||||||
Ok(path) => Ok(Response::with((status::Ok, path))),
|
Ok(path) => Ok(Response::with((status::Ok, path))),
|
||||||
Err(e) => Err(IronError::from(e))
|
Err(e) => Err(IronError::from(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -188,8 +188,10 @@ impl Config {
|
||||||
};
|
};
|
||||||
|
|
||||||
let host = try!(ddns.get(CONFIG_DDNS_HOST).ok_or(ConfigError::DDNSParseError)).as_str();
|
let host = try!(ddns.get(CONFIG_DDNS_HOST).ok_or(ConfigError::DDNSParseError)).as_str();
|
||||||
let username = try!(ddns.get(CONFIG_DDNS_USERNAME).ok_or(ConfigError::DDNSParseError)).as_str();
|
let username = try!(ddns.get(CONFIG_DDNS_USERNAME).ok_or(ConfigError::DDNSParseError))
|
||||||
let password = try!(ddns.get(CONFIG_DDNS_PASSWORD).ok_or(ConfigError::DDNSParseError)).as_str();
|
.as_str();
|
||||||
|
let password = try!(ddns.get(CONFIG_DDNS_PASSWORD).ok_or(ConfigError::DDNSParseError))
|
||||||
|
.as_str();
|
||||||
|
|
||||||
let host = try!(host.ok_or(ConfigError::DDNSParseError));
|
let host = try!(host.ok_or(ConfigError::DDNSParseError));
|
||||||
let username = try!(username.ok_or(ConfigError::DDNSParseError));
|
let username = try!(username.ok_or(ConfigError::DDNSParseError));
|
||||||
|
|
|
@ -50,7 +50,7 @@ fn update_my_ip(ip: &String, config: &DDNSConfig) -> Result<(), DDNSError> {
|
||||||
let full_url = format!("{}?host={}&ip={}", url, host, ip);
|
let full_url = format!("{}?host={}&ip={}", url, host, ip);
|
||||||
let auth_header = Authorization(Basic {
|
let auth_header = Authorization(Basic {
|
||||||
username: config.username.clone(),
|
username: config.username.clone(),
|
||||||
password: Some(config.password.to_owned())
|
password: Some(config.password.to_owned()),
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = try!(client.get(full_url.as_str()).header(auth_header).send());
|
let res = try!(client.get(full_url.as_str()).header(auth_header).send());
|
||||||
|
@ -68,9 +68,7 @@ pub fn run(config: DDNSConfig) {
|
||||||
Err(e) => println!("Dynamic DNS Error: {:?}", e),
|
Err(e) => println!("Dynamic DNS Error: {:?}", e),
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
};
|
};
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
println!("Dynamic DNS Error: could not retrieve our own IP address");
|
println!("Dynamic DNS Error: could not retrieve our own IP address");
|
||||||
}
|
}
|
||||||
thread::sleep(time::Duration::from_secs(60 * 30));
|
thread::sleep(time::Duration::from_secs(60 * 30));
|
||||||
|
|
98
src/index.rs
98
src/index.rs
|
@ -88,7 +88,7 @@ impl SongTags {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,8 +174,14 @@ impl<'db> IndexBuilder<'db> {
|
||||||
IndexBuilder {
|
IndexBuilder {
|
||||||
queue: queue,
|
queue: queue,
|
||||||
db: db,
|
db: db,
|
||||||
insert_directory: db.prepare("INSERT OR REPLACE INTO directories (path, parent, artwork, year, artist, album) VALUES (?, ?, ?, ?, ?, ?)").unwrap(),
|
insert_directory:
|
||||||
insert_song: db.prepare("INSERT OR REPLACE INTO songs (path, parent, track_number, title, year, album_artist, artist, album, artwork) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)").unwrap(),
|
db.prepare("INSERT OR REPLACE INTO directories (path, parent, artwork, year, \
|
||||||
|
artist, album) VALUES (?, ?, ?, ?, ?, ?)")
|
||||||
|
.unwrap(),
|
||||||
|
insert_song:
|
||||||
|
db.prepare("INSERT OR REPLACE INTO songs (path, parent, track_number, title, year, \
|
||||||
|
album_artist, artist, album, artwork) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
||||||
|
.unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,12 +206,18 @@ impl<'db> IndexBuilder<'db> {
|
||||||
self.insert_directory.reset().ok();
|
self.insert_directory.reset().ok();
|
||||||
self.insert_directory.bind(1, &Value::String(directory.path)).unwrap();
|
self.insert_directory.bind(1, &Value::String(directory.path)).unwrap();
|
||||||
self.insert_directory.bind(2, &string_option_to_value(parent)).unwrap();
|
self.insert_directory.bind(2, &string_option_to_value(parent)).unwrap();
|
||||||
self.insert_directory.bind(3, &string_option_to_value(directory.artwork)).unwrap();
|
self.insert_directory
|
||||||
|
.bind(3, &string_option_to_value(directory.artwork))
|
||||||
|
.unwrap();
|
||||||
self.insert_directory.bind(4, &i32_option_to_value(directory.year)).unwrap();
|
self.insert_directory.bind(4, &i32_option_to_value(directory.year)).unwrap();
|
||||||
self.insert_directory.bind(5, &string_option_to_value(directory.artist)).unwrap();
|
self.insert_directory
|
||||||
self.insert_directory.bind(6, &string_option_to_value(directory.album)).unwrap();
|
.bind(5, &string_option_to_value(directory.artist))
|
||||||
|
.unwrap();
|
||||||
|
self.insert_directory
|
||||||
|
.bind(6, &string_option_to_value(directory.album))
|
||||||
|
.unwrap();
|
||||||
self.insert_directory.next().ok();
|
self.insert_directory.next().ok();
|
||||||
},
|
}
|
||||||
|
|
||||||
// Insert song
|
// Insert song
|
||||||
CollectionFile::Song(song) => {
|
CollectionFile::Song(song) => {
|
||||||
|
@ -243,8 +255,10 @@ impl<'db> Drop for IndexBuilder<'db> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index {
|
impl Index {
|
||||||
|
pub fn new(path: &Path,
|
||||||
pub fn new(path: &Path, vfs: Arc<Vfs>, album_art_pattern: &Option<Regex>) -> Result<Index, PError> {
|
vfs: Arc<Vfs>,
|
||||||
|
album_art_pattern: &Option<Regex>)
|
||||||
|
-> Result<Index, PError> {
|
||||||
|
|
||||||
let index = Index {
|
let index = Index {
|
||||||
path: path.to_string_lossy().deref().to_string(),
|
path: path.to_string_lossy().deref().to_string(),
|
||||||
|
@ -271,36 +285,45 @@ impl Index {
|
||||||
|
|
||||||
CREATE TABLE version
|
CREATE TABLE version
|
||||||
( id INTEGER PRIMARY KEY NOT NULL
|
( id INTEGER PRIMARY KEY NOT NULL
|
||||||
, number INTEGER NULL
|
, number \
|
||||||
|
INTEGER NULL
|
||||||
);
|
);
|
||||||
INSERT INTO version (number) VALUES(1);
|
INSERT INTO version (number) VALUES(1);
|
||||||
|
|
||||||
CREATE TABLE directories
|
CREATE \
|
||||||
|
TABLE directories
|
||||||
( id INTEGER PRIMARY KEY NOT NULL
|
( id INTEGER PRIMARY KEY NOT NULL
|
||||||
, path TEXT NOT NULL
|
, path TEXT NOT \
|
||||||
|
NULL
|
||||||
, parent TEXT
|
, parent TEXT
|
||||||
, artist TEXT
|
, artist TEXT
|
||||||
, year INTEGER
|
, year INTEGER
|
||||||
, album TEXT
|
, album TEXT
|
||||||
|
\
|
||||||
, artwork TEXT
|
, artwork TEXT
|
||||||
, UNIQUE(path)
|
, UNIQUE(path)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE songs
|
CREATE TABLE songs
|
||||||
( id INTEGER PRIMARY KEY NOT NULL
|
( id \
|
||||||
|
INTEGER PRIMARY KEY NOT NULL
|
||||||
, path TEXT NOT NULL
|
, path TEXT NOT NULL
|
||||||
, parent TEXT NOT NULL
|
, parent TEXT NOT \
|
||||||
|
NULL
|
||||||
, track_number INTEGER
|
, track_number INTEGER
|
||||||
, title TEXT
|
, title TEXT
|
||||||
, artist TEXT
|
, artist TEXT
|
||||||
, album_artist TEXT
|
, \
|
||||||
|
album_artist TEXT
|
||||||
, year INTEGER
|
, year INTEGER
|
||||||
, album TEXT
|
, album TEXT
|
||||||
, artwork TEXT
|
, artwork TEXT
|
||||||
, UNIQUE(path)
|
, \
|
||||||
|
UNIQUE(path)
|
||||||
);
|
);
|
||||||
|
|
||||||
").unwrap();
|
")
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connect(&self) -> Connection {
|
fn connect(&self) -> Connection {
|
||||||
|
@ -314,7 +337,8 @@ impl Index {
|
||||||
println!("Beginning library index update");
|
println!("Beginning library index update");
|
||||||
self.clean(db);
|
self.clean(db);
|
||||||
self.populate(db);
|
self.populate(db);
|
||||||
println!("Library index update took {} seconds", start.elapsed().as_secs());
|
println!("Library index update took {} seconds",
|
||||||
|
start.elapsed().as_secs());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean(&self, db: &Connection) {
|
fn clean(&self, db: &Connection) {
|
||||||
|
@ -408,20 +432,26 @@ impl Index {
|
||||||
if let Some(file_path_string) = file_path.to_str() {
|
if let Some(file_path_string) = file_path.to_str() {
|
||||||
if let Ok(tags) = SongTags::read(file_path.as_path()) {
|
if let Ok(tags) = SongTags::read(file_path.as_path()) {
|
||||||
if tags.year.is_some() {
|
if tags.year.is_some() {
|
||||||
inconsistent_directory_year |= directory_year.is_some() && directory_year != tags.year;
|
inconsistent_directory_year |= directory_year.is_some() &&
|
||||||
|
directory_year != tags.year;
|
||||||
directory_year = tags.year;
|
directory_year = tags.year;
|
||||||
}
|
}
|
||||||
|
|
||||||
if tags.album.is_some() {
|
if tags.album.is_some() {
|
||||||
inconsistent_directory_album |= directory_album.is_some() && directory_album != tags.album;
|
inconsistent_directory_album |= directory_album.is_some() &&
|
||||||
|
directory_album != tags.album;
|
||||||
directory_album = Some(tags.album.as_ref().unwrap().clone());
|
directory_album = Some(tags.album.as_ref().unwrap().clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
if tags.album_artist.is_some() {
|
if tags.album_artist.is_some() {
|
||||||
inconsistent_directory_artist |= directory_artist.is_some() && directory_artist != tags.album_artist;
|
inconsistent_directory_artist |= directory_artist.is_some() &&
|
||||||
directory_artist = Some(tags.album_artist.as_ref().unwrap().clone());
|
directory_artist !=
|
||||||
|
tags.album_artist;
|
||||||
|
directory_artist =
|
||||||
|
Some(tags.album_artist.as_ref().unwrap().clone());
|
||||||
} else if tags.artist.is_some() {
|
} else if tags.artist.is_some() {
|
||||||
inconsistent_directory_artist |= directory_artist.is_some() && directory_artist != tags.artist;
|
inconsistent_directory_artist |= directory_artist.is_some() &&
|
||||||
|
directory_artist != tags.artist;
|
||||||
directory_artist = Some(tags.artist.as_ref().unwrap().clone());
|
directory_artist = Some(tags.artist.as_ref().unwrap().clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,8 +494,7 @@ impl Index {
|
||||||
builder.push(CollectionFile::Directory(directory));
|
builder.push(CollectionFile::Directory(directory));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&self)
|
pub fn run(&self) {
|
||||||
{
|
|
||||||
loop {
|
loop {
|
||||||
{
|
{
|
||||||
let db = self.connect();
|
let db = self.connect();
|
||||||
|
@ -496,7 +525,9 @@ impl Index {
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
let artwork = artwork.as_string().map(|p| Path::new(p)).and_then(|p| self.vfs.real_to_virtual(p).ok());
|
let artwork = artwork.as_string()
|
||||||
|
.map(|p| Path::new(p))
|
||||||
|
.and_then(|p| self.vfs.real_to_virtual(p).ok());
|
||||||
|
|
||||||
let song = Song {
|
let song = Song {
|
||||||
path: song_path.to_str().unwrap().to_owned(),
|
path: song_path.to_str().unwrap().to_owned(),
|
||||||
|
@ -520,7 +551,10 @@ impl Index {
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
|
|
||||||
let path_string = real_path.to_string_lossy();
|
let path_string = real_path.to_string_lossy();
|
||||||
let mut select = db.prepare("SELECT path, artwork, year, artist, album FROM directories WHERE parent = ? ORDER BY path COLLATE NOCASE ASC").unwrap();
|
let mut select =
|
||||||
|
db.prepare("SELECT path, artwork, year, artist, album FROM directories WHERE \
|
||||||
|
parent = ? ORDER BY path COLLATE NOCASE ASC")
|
||||||
|
.unwrap();
|
||||||
select.bind(1, &Value::String(path_string.deref().to_owned())).unwrap();
|
select.bind(1, &Value::String(path_string.deref().to_owned())).unwrap();
|
||||||
|
|
||||||
while let State::Row = select.next().unwrap() {
|
while let State::Row = select.next().unwrap() {
|
||||||
|
@ -558,7 +592,10 @@ impl Index {
|
||||||
fn browse_songs(&self, real_path: &Path) -> Vec<CollectionFile> {
|
fn browse_songs(&self, real_path: &Path) -> Vec<CollectionFile> {
|
||||||
let db = self.connect();
|
let db = self.connect();
|
||||||
let path_string = real_path.to_string_lossy();
|
let path_string = real_path.to_string_lossy();
|
||||||
let mut select = db.prepare("SELECT path, track_number, title, year, album_artist, artist, album, artwork FROM songs WHERE parent = ? ORDER BY path COLLATE NOCASE ASC").unwrap();
|
let mut select =
|
||||||
|
db.prepare("SELECT path, track_number, title, year, album_artist, artist, album, \
|
||||||
|
artwork FROM songs WHERE parent = ? ORDER BY path COLLATE NOCASE ASC")
|
||||||
|
.unwrap();
|
||||||
select.bind(1, &Value::String(path_string.deref().to_owned())).unwrap();
|
select.bind(1, &Value::String(path_string.deref().to_owned())).unwrap();
|
||||||
self.select_songs(&mut select).into_iter().map(|s| CollectionFile::Song(s)).collect()
|
self.select_songs(&mut select).into_iter().map(|s| CollectionFile::Song(s)).collect()
|
||||||
}
|
}
|
||||||
|
@ -596,7 +633,10 @@ impl Index {
|
||||||
let db = self.connect();
|
let db = self.connect();
|
||||||
let real_path = try!(self.vfs.virtual_to_real(virtual_path));
|
let real_path = try!(self.vfs.virtual_to_real(virtual_path));
|
||||||
let path_string = real_path.to_string_lossy().into_owned() + "%";
|
let path_string = real_path.to_string_lossy().into_owned() + "%";
|
||||||
let mut select = db.prepare("SELECT path, track_number, title, year, album_artist, artist, album, artwork FROM songs WHERE path LIKE ? ORDER BY path COLLATE NOCASE ASC").unwrap();
|
let mut select =
|
||||||
|
db.prepare("SELECT path, track_number, title, year, album_artist, artist, album, \
|
||||||
|
artwork FROM songs WHERE path LIKE ? ORDER BY path COLLATE NOCASE ASC")
|
||||||
|
.unwrap();
|
||||||
select.bind(1, &Value::String(path_string.deref().to_owned())).unwrap();
|
select.bind(1, &Value::String(path_string.deref().to_owned())).unwrap();
|
||||||
Ok(self.select_songs(&mut select))
|
Ok(self.select_songs(&mut select))
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,8 @@ fn main() {
|
||||||
// Init index
|
// Init index
|
||||||
println!("Starting up index");
|
println!("Starting up index");
|
||||||
let index_path = path::Path::new(INDEX_FILE_NAME);
|
let index_path = path::Path::new(INDEX_FILE_NAME);
|
||||||
let index = Arc::new(index::Index::new(&index_path, vfs.clone(), &config.album_art_pattern).unwrap());
|
let index = Arc::new(index::Index::new(&index_path, vfs.clone(), &config.album_art_pattern)
|
||||||
|
.unwrap());
|
||||||
let index_ref = index.clone();
|
let index_ref = index.clone();
|
||||||
std::thread::spawn(move || index_ref.run());
|
std::thread::spawn(move || index_ref.run());
|
||||||
|
|
||||||
|
@ -104,7 +105,7 @@ fn main() {
|
||||||
std::thread::spawn(|| {
|
std::thread::spawn(|| {
|
||||||
ddns::run(ddns_config);
|
ddns::run(ddns_config);
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
None => (),
|
None => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,15 +41,22 @@ pub fn get_thumbnail(real_path: &Path, max_dimension: u32) -> Result<PathBuf, PE
|
||||||
let source_aspect_ratio: f32 = source_width as f32 / source_height as f32;
|
let source_aspect_ratio: f32 = source_width as f32 / source_height as f32;
|
||||||
if source_aspect_ratio < 0.8 || source_aspect_ratio > 1.2 {
|
if source_aspect_ratio < 0.8 || source_aspect_ratio > 1.2 {
|
||||||
let mut cropped_image = ImageBuffer::new(cropped_dimension, cropped_dimension);
|
let mut cropped_image = ImageBuffer::new(cropped_dimension, cropped_dimension);
|
||||||
cropped_image.copy_from(&source_image, (cropped_dimension - source_width)/2, (cropped_dimension - source_height)/2);
|
cropped_image.copy_from(&source_image,
|
||||||
let out_image = resize(&cropped_image, out_dimension, out_dimension, FilterType::Lanczos3);
|
(cropped_dimension - source_width) / 2,
|
||||||
|
(cropped_dimension - source_height) / 2);
|
||||||
|
let out_image = resize(&cropped_image,
|
||||||
|
out_dimension,
|
||||||
|
out_dimension,
|
||||||
|
FilterType::Lanczos3);
|
||||||
try!(out_image.save(out_path.as_path()));
|
try!(out_image.save(out_path.as_path()));
|
||||||
} else {
|
} else {
|
||||||
let out_image = resize(&source_image, out_dimension, out_dimension, FilterType::Lanczos3);
|
let out_image = resize(&source_image,
|
||||||
|
out_dimension,
|
||||||
|
out_dimension,
|
||||||
|
FilterType::Lanczos3);
|
||||||
try!(out_image.save(out_path.as_path()));
|
try!(out_image.save(out_path.as_path()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(out_path)
|
Ok(out_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/vfs.rs
10
src/vfs.rs
|
@ -11,9 +11,7 @@ pub struct VfsConfig {
|
||||||
|
|
||||||
impl VfsConfig {
|
impl VfsConfig {
|
||||||
pub fn new() -> VfsConfig {
|
pub fn new() -> VfsConfig {
|
||||||
VfsConfig {
|
VfsConfig { mount_points: HashMap::new() }
|
||||||
mount_points: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,11 +41,13 @@ impl Vfs {
|
||||||
for (name, target) in &self.mount_points {
|
for (name, target) in &self.mount_points {
|
||||||
let mount_path = Path::new(&name);
|
let mount_path = Path::new(&name);
|
||||||
match virtual_path.strip_prefix(mount_path) {
|
match virtual_path.strip_prefix(mount_path) {
|
||||||
Ok(p) => return if p.components().count() == 0 {
|
Ok(p) => {
|
||||||
|
return if p.components().count() == 0 {
|
||||||
Ok(target.clone())
|
Ok(target.clone())
|
||||||
} else {
|
} else {
|
||||||
Ok(target.join(p))
|
Ok(target.join(p))
|
||||||
},
|
}
|
||||||
|
}
|
||||||
Err(_) => (),
|
Err(_) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue