From 05d11426a8e60fa060733eb8ae7843bc2ae9725c Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 10 Jun 2024 15:28:36 +0200 Subject: apply many clippy issue --- base/src/assetfed.rs | 4 +- base/src/cache.rs | 4 +- base/src/database.rs | 1 + base/src/federation.rs | 5 +- base/src/lib.rs | 2 +- base/src/permission.rs | 8 ++-- common/src/helpers.rs | 10 +++- common/src/lib.rs | 10 ++-- common/src/user.rs | 12 ++--- import/src/db.rs | 7 +-- import/src/lib.rs | 20 ++++---- import/src/trakt.rs | 2 +- matroska/src/bin/mkvdump.rs | 4 +- matroska/src/read.rs | 6 +-- remuxer/src/extract.rs | 6 +-- remuxer/src/fragment.rs | 2 +- remuxer/src/remux.rs | 6 +-- remuxer/src/seek_index.rs | 81 ++++++++++++++------------------ remuxer/src/segment_extractor.rs | 2 +- server/src/main.rs | 3 +- server/src/routes/stream.rs | 18 +++---- server/src/routes/ui/account/settings.rs | 1 - server/src/routes/ui/admin/log.rs | 28 ++++------- server/src/routes/ui/admin/mod.rs | 12 ++--- server/src/routes/ui/admin/user.rs | 4 +- server/src/routes/ui/assets.rs | 12 ++--- server/src/routes/ui/error.rs | 2 +- server/src/routes/ui/home.rs | 2 +- server/src/routes/ui/layout.rs | 4 +- server/src/routes/ui/node.rs | 21 ++++----- server/src/routes/ui/player.rs | 7 ++- server/src/routes/ui/search.rs | 4 +- server/src/routes/ui/sort.rs | 2 +- stream/src/fragment.rs | 2 +- stream/src/hls.rs | 2 +- stream/src/jhls.rs | 2 +- stream/src/webvtt.rs | 4 +- tool/src/add.rs | 14 ++++-- tool/src/migrate.rs | 6 +-- transcoder/src/fragment.rs | 8 ++-- transcoder/src/image.rs | 4 +- transcoder/src/thumbnail.rs | 16 +++---- 42 files changed, 175 insertions(+), 195 deletions(-) diff --git a/base/src/assetfed.rs b/base/src/assetfed.rs index 4ca587b..bb39bbd 100644 --- a/base/src/assetfed.rs +++ b/base/src/assetfed.rs @@ -38,7 +38,7 @@ impl AssetInner { pub fn ser(&self) -> Asset { let mut plaintext = Vec::new(); plaintext.extend(u32::to_le_bytes(VERSION)); - plaintext.extend(bincode::encode_to_vec(&self, bincode::config::standard()).unwrap()); + plaintext.extend(bincode::encode_to_vec(self, bincode::config::standard()).unwrap()); while plaintext.len() % 16 == 0 { plaintext.push(0); @@ -53,7 +53,7 @@ impl AssetInner { Asset(base64::engine::general_purpose::URL_SAFE.encode(&ciphertext)) } pub fn deser(s: &str) -> anyhow::Result { - let ciphertext = base64::engine::general_purpose::URL_SAFE.decode(&s)?; + let ciphertext = base64::engine::general_purpose::URL_SAFE.decode(s)?; let (ciphertext, nonce) = ciphertext.split_at(ciphertext.len() - 12); let plaintext = ASSET_KEY .decrypt(nonce.into(), ciphertext) diff --git a/base/src/cache.rs b/base/src/cache.rs index 68f191e..5ded6f8 100644 --- a/base/src/cache.rs +++ b/base/src/cache.rs @@ -110,7 +110,7 @@ where return Err(e); } } - rename(temp_path, &location.abs()).context("rename cache")?; + rename(temp_path, location.abs()).context("rename cache")?; } drop(_guard); Ok(location) @@ -150,7 +150,7 @@ where .context("encoding cache object")?; Ok(()) })?; - let mut file = std::fs::File::open(&location.abs())?; + let mut file = std::fs::File::open(location.abs())?; let object = bincode::decode_from_std_read::(&mut file, bincode::config::standard()) .context("decoding cache object")?; let object = Arc::new(object); diff --git a/base/src/database.rs b/base/src/database.rs index d890956..e57ea3e 100644 --- a/base/src/database.rs +++ b/base/src/database.rs @@ -35,6 +35,7 @@ pub const T_INVITE: TableDefinition<&str, Ser<()>> = TableDefinition::new("invit pub const T_NODE: TableDefinition<&str, Ser> = TableDefinition::new("node"); pub const T_NODE_EXTENDED: TableDefinition<&str, Ser> = TableDefinition::new("node-ext"); +#[allow(clippy::type_complexity)] pub const T_NODE_IMPORT: TableDefinition<&str, Ser, Node)>>> = TableDefinition::new("node-import"); diff --git a/base/src/federation.rs b/base/src/federation.rs index 75c16e7..662a7ac 100644 --- a/base/src/federation.rs +++ b/base/src/federation.rs @@ -32,10 +32,7 @@ impl Federation { } pub fn get_instance(&self, host: &String) -> anyhow::Result<&Instance> { - Ok(self - .instances - .get(host) - .ok_or(anyhow!("unknown instance"))?) + self.instances.get(host).ok_or(anyhow!("unknown instance")) } pub async fn get_session(&self, host: &String) -> anyhow::Result> { diff --git a/base/src/lib.rs b/base/src/lib.rs index 3eb77e2..1ffaa10 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -30,7 +30,7 @@ pub fn load_config() -> GlobalConfig { serde_yaml::from_reader( std::fs::File::open(std::env::var("JELLYTHING_CONFIG").unwrap_or_else(|_| { if std::env::args() - .nth(0) + .next() .unwrap_or_default() .ends_with("jellything") { diff --git a/base/src/permission.rs b/base/src/permission.rs index 15b24a9..358202f 100644 --- a/base/src/permission.rs +++ b/base/src/permission.rs @@ -21,9 +21,9 @@ pub trait PermissionSetExt { impl PermissionSetExt for PermissionSet { fn check_explicit(&self, perm: &UserPermission) -> Option { self.0 - .get(&perm) - .or(CONF.default_permission_set.0.get(&perm)) - .map(|v| *v) + .get(perm) + .or(CONF.default_permission_set.0.get(perm)) + .copied() } fn assert(&self, perm: &UserPermission) -> Result<(), anyhow::Error> { if self.check(perm) { @@ -61,6 +61,6 @@ fn check_node_permission(perms: &PermissionSet, node: &Node) -> bool { return v; } } - return true; + true } } diff --git a/common/src/helpers.rs b/common/src/helpers.rs index 92595e0..54f5479 100644 --- a/common/src/helpers.rs +++ b/common/src/helpers.rs @@ -5,15 +5,21 @@ */ use std::ops::Deref; -#[derive(PartialEq, PartialOrd)] +#[derive(PartialEq)] pub struct SortAnyway(pub T); impl Eq for SortAnyway { fn assert_receiver_is_total_eq(&self) {} } +#[allow(clippy::non_canonical_partial_ord_impl)] +impl PartialOrd for SortAnyway { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } +} impl Ord for SortAnyway { fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.partial_cmp(&other).unwrap() + self.partial_cmp(other).unwrap() } } diff --git a/common/src/lib.rs b/common/src/lib.rs index d06c40c..7403347 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -3,6 +3,7 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2024 metamuffin */ +#![allow(clippy::needless_borrows_for_generic_args)] pub mod config; pub mod helpers; pub mod r#impl; @@ -282,17 +283,16 @@ impl TraktKind { } } } -impl ToString for TraktKind { - fn to_string(&self) -> String { - match self { +impl Display for TraktKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { TraktKind::Movie => "Movie", TraktKind::Show => "Show", TraktKind::Season => "Season", TraktKind::Episode => "Episode", TraktKind::Person => "Person", TraktKind::User => "User", - } - .to_string() + }) } } impl Display for ObjectIds { diff --git a/common/src/user.rs b/common/src/user.rs index 5f2b0e4..1a527b9 100644 --- a/common/src/user.rs +++ b/common/src/user.rs @@ -129,19 +129,19 @@ impl UserPermission { impl Display for UserPermission { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&match self { - UserPermission::ManageSelf => format!("manage self (password, display name, etc.)"), - UserPermission::FederatedContent => format!("access to federated content"), - UserPermission::Admin => format!("administrative rights"), + UserPermission::ManageSelf => "manage self (password, display name, etc.)".to_string(), + UserPermission::FederatedContent => "access to federated content".to_string(), + UserPermission::Admin => "administrative rights".to_string(), UserPermission::StreamFormat(StreamFormat::Original) => { - format!("downloading the original media") + "downloading the original media".to_string() } UserPermission::StreamFormat(StreamFormat::Matroska) => { - format!("downloading a remuxed WebM/Matroska version of the media ") + "downloading a remuxed WebM/Matroska version of the media ".to_string() } UserPermission::StreamFormat(x) => { format!("downloading media via {x:?}") } - UserPermission::Transcode => format!("transcoding"), + UserPermission::Transcode => "transcoding".to_string(), // UserPermission::ManageUsers => format!("management of all users"), // UserPermission::GenerateInvite => format!("inviting new users"), UserPermission::AccessNode(s) => format!("access to library node {s:?}"), diff --git a/import/src/db.rs b/import/src/db.rs index 87350ac..7a3636c 100644 --- a/import/src/db.rs +++ b/import/src/db.rs @@ -62,7 +62,7 @@ impl ImportStorage for DatabaseStorage<'_> { Ok(value.value().0) } fn insert_complete_node(&self, id: &str, node: Node) -> anyhow::Result<()> { - insert_complete_node(&self.db, id, node) + insert_complete_node(self.db, id, node) } fn add_partial_node(&self, id: &str, index_path: &[usize], node: Node) -> anyhow::Result<()> { @@ -106,9 +106,10 @@ impl ImportStorage for DatabaseStorage<'_> { } } +pub type Parts = RwLock, Node)>>>; pub(crate) struct MemoryStorage<'a> { pub db: &'a DataAcid, - pub parts: RwLock, Node)>>>, + pub parts: Parts, } impl<'a> MemoryStorage<'a> { pub fn new(db: &'a DataAcid) -> Self { @@ -148,7 +149,7 @@ impl ImportStorage for MemoryStorage<'_> { .to_owned()) } fn insert_complete_node(&self, id: &str, node: Node) -> anyhow::Result<()> { - insert_complete_node(&self.db, id, node) + insert_complete_node(self.db, id, node) } fn add_partial_node(&self, id: &str, index_path: &[usize], node: Node) -> anyhow::Result<()> { diff --git a/import/src/lib.rs b/import/src/lib.rs index f0644fd..544937c 100644 --- a/import/src/lib.rs +++ b/import/src/lib.rs @@ -59,7 +59,7 @@ struct Apis { } pub fn is_importing() -> bool { - IMPORT_SEM.available_permits() <= 0 + IMPORT_SEM.available_permits() == 0 } pub async fn import(db: &DataAcid, fed: &Federation) -> anyhow::Result<()> { @@ -213,8 +213,8 @@ async fn import_path( .read_dir()? .map(Result::unwrap) .filter_map(|e| { - if e.path().extension() == Some(&OsStr::new("yaml")) - || e.path().extension() == Some(&OsStr::new("jelly")) + if e.path().extension() == Some(OsStr::new("yaml")) + || e.path().extension() == Some(OsStr::new("jelly")) || e.metadata().unwrap().is_dir() { Some(e.path()) @@ -344,12 +344,12 @@ async fn process_source( } } // TODO lazy assets - for (_, ps) in &mut node_ext.people { + for ps in node_ext.people.values_mut() { for p in ps { if let Some(id) = p.person.ids.tmdb { if let Some(tmdb) = &ap.tmdb { let k = tmdb.person_image(id).await?; - if let Some(prof) = k.profiles.get(0) { + if let Some(prof) = k.profiles.first() { p.person.headshot = Some( AssetInner::Cache(tmdb.image(&prof.file_path).await?).ser(), ); @@ -401,10 +401,10 @@ async fn process_source( // TODO lazy assets if let Some(poster) = &details.poster_path { - node.public.poster = Some(AssetInner::Cache(tmdb.image(&poster).await?).ser()); + node.public.poster = Some(AssetInner::Cache(tmdb.image(poster).await?).ser()); } if let Some(backdrop) = &details.backdrop_path { - node.public.backdrop = Some(AssetInner::Cache(tmdb.image(&backdrop).await?).ser()); + node.public.backdrop = Some(AssetInner::Cache(tmdb.image(backdrop).await?).ser()); } node.public.tagline = details.tagline.clone(); @@ -583,7 +583,7 @@ async fn process_source( .map(|e| e.path()) .filter(|e| { e.extension() == Some(OsStr::new("yaml")) - || e.extension() == Some(&OsStr::new("jelly")) + || e.extension() == Some(OsStr::new("jelly")) }); let mut children = Vec::new(); @@ -613,7 +613,7 @@ async fn process_source( Ok(errors) } -const RE_YOUTUBE_ID: LazyLock = +static RE_YOUTUBE_ID: LazyLock = LazyLock::new(|| Regex::new(r#"\[([A-Za-z0-9_-]{11})\]"#).unwrap()); pub fn infer_id_from_path(path: &Path) -> anyhow::Result { @@ -791,7 +791,7 @@ async fn import_remote( }; make_opt_asset_federated(host, &mut node.public.backdrop)?; make_opt_asset_federated(host, &mut node.public.poster)?; - for (_, g) in &mut node_ext.people { + for g in node_ext.people.values_mut() { for a in g { make_opt_asset_federated(host, &mut a.person.headshot)?; } diff --git a/import/src/trakt.rs b/import/src/trakt.rs index 2bcf45f..19c50bc 100644 --- a/import/src/trakt.rs +++ b/import/src/trakt.rs @@ -269,7 +269,7 @@ impl Display for TraktSearchResult { "{} ({}) \x1b[2m{} [{}]\x1b[0m", self.inner.inner().title, self.inner.inner().year.unwrap_or(0), - self.r#type.to_string(), + self.r#type, self.inner.inner().ids )) } diff --git a/matroska/src/bin/mkvdump.rs b/matroska/src/bin/mkvdump.rs index b58adcc..c40e325 100644 --- a/matroska/src/bin/mkvdump.rs +++ b/matroska/src/bin/mkvdump.rs @@ -9,9 +9,9 @@ use std::{fs::File, io::BufReader}; fn main() { env_logger::init_from_env("LOG"); let path = std::env::args().nth(1).unwrap(); - let mut r = EbmlReader::new(BufReader::new(File::open(path).unwrap())); + let r = EbmlReader::new(BufReader::new(File::open(path).unwrap())); - while let Some(tag) = r.next() { + for tag in r { let (position, tag) = tag.unwrap(); match tag { MatroskaTag::SimpleBlock(b) | MatroskaTag::Block(b) => { diff --git a/matroska/src/read.rs b/matroska/src/read.rs index 536f2f8..42fbd73 100644 --- a/matroska/src/read.rs +++ b/matroska/src/read.rs @@ -83,7 +83,7 @@ impl EbmlReader { #[inline] pub fn read_utf8(&mut self, size: impl Into) -> Result { let b = self.read_buf(size)?; - Ok(String::from_utf8(b).map_err(|_| Error::InvalidUTF8)?) + String::from_utf8(b).map_err(|_| Error::InvalidUTF8) } #[inline] @@ -160,7 +160,7 @@ impl EbmlReader { ); self.queue.clear(); self.position = position; - self.inner.seek(SeekFrom::Start(position as u64))?; + self.inner.seek(SeekFrom::Start(position))?; self.stack = path .iter() .map(|id| StackTag { id: *id, end: None }) @@ -257,7 +257,7 @@ impl ReadValue for Vec { } impl ReadValue for String { fn from_buf(buf: &[u8]) -> Result { - Ok(String::from_utf8(Vec::from(buf)).map_err(|_| Error::InvalidUTF8)?) + String::from_utf8(Vec::from(buf)).map_err(|_| Error::InvalidUTF8) } } impl ReadValue for Master { diff --git a/remuxer/src/extract.rs b/remuxer/src/extract.rs index e70adf4..a9b4835 100644 --- a/remuxer/src/extract.rs +++ b/remuxer/src/extract.rs @@ -10,10 +10,8 @@ use jellymatroska::{block::Block, read::EbmlReader, Master, MatroskaTag}; use log::debug; use std::{fs::File, io::BufReader, path::PathBuf}; -pub fn extract_track( - path_base: PathBuf, - track_info: LocalTrack, -) -> anyhow::Result, Vec)>> { +pub type TrackExtract = Vec<(u64, Option, Vec)>; +pub fn extract_track(path_base: PathBuf, track_info: LocalTrack) -> anyhow::Result { let source_path = path_base.join(track_info.path); let file = File::open(&source_path)?; let mut reader = EbmlReader::new(BufReader::new(file)); diff --git a/remuxer/src/fragment.rs b/remuxer/src/fragment.rs index cd395f9..872b1e0 100644 --- a/remuxer/src/fragment.rs +++ b/remuxer/src/fragment.rs @@ -186,7 +186,7 @@ pub fn write_fragment_into( let mut blocks = vec![MatroskaTag::Timestamp(start_block.pts)]; for i in start_block_index..end_block_index { let index_block = &index.blocks[i]; - let (mut block, duration) = reader.next()?; + let (mut block, duration) = reader.next_block()?; assert_eq!(index_block.size, block.data.len(), "seek index is wrong"); diff --git a/remuxer/src/remux.rs b/remuxer/src/remux.rs index 733dc49..9419847 100644 --- a/remuxer/src/remux.rs +++ b/remuxer/src/remux.rs @@ -305,7 +305,7 @@ pub fn remux_stream_into( for (block_track, index_block) in cluster.blocks { let track_reader = &mut track_readers[block_track]; // TODO handle duration - let mut block = track_reader.stream.next()?.0; + let mut block = track_reader.stream.next_block()?.0; assert_eq!(index_block.size, block.data.len(), "seek index is wrong"); @@ -326,8 +326,8 @@ fn find_first_cluster_with_off( skip: usize, track: usize, ) -> Option { - for skip in skip..segment_layout.len() { - if let Some(off) = segment_layout[skip].source_offsets[track] { + for cluster in segment_layout.iter().skip(skip) { + if let Some(off) = cluster.source_offsets[track] { return Some(off); } } diff --git a/remuxer/src/seek_index.rs b/remuxer/src/seek_index.rs index 5bec6e6..7008696 100644 --- a/remuxer/src/seek_index.rs +++ b/remuxer/src/seek_index.rs @@ -18,7 +18,7 @@ use std::{collections::BTreeMap, fs::File, io::BufReader, path::Path, sync::Arc} pub fn get_seek_index(path: &Path) -> anyhow::Result>>> { cache_memory(&["seekindex", path.to_str().unwrap()], move || { info!("generating seek index for {path:?}"); - let input = File::open(&path).context("opening source file")?; + let input = File::open(path).context("opening source file")?; let mut input = EbmlReader::new(BufReader::new(input)); let index = import_seek_index(&mut input)?; info!("done"); @@ -67,52 +67,43 @@ fn import_seek_index_segment( MatroskaTag::Cluster(_) => { let mut children = children.unwrap(); let mut pts = 0; - loop { - if let Some(Ok(Unflat { - children, - item, - position, - })) = children.n() - { - match item { - MatroskaTag::Timestamp(ts) => pts = ts, - MatroskaTag::BlockGroup(_) => { - trace!("group"); - let mut children = children.unwrap(); - while let Some(Ok(Unflat { - children: _, item, .. - })) = children.n() - { - match item { - MatroskaTag::Block(ref block) => { - debug!( - "block: track={} tso={}", - block.track, block.timestamp_off - ); - seek_index_add( - seek_index, - &block, - position.unwrap(), - pts, - ); - } - _ => trace!("{item:?}"), + while let Some(Ok(Unflat { + children, + item, + position, + })) = children.n() + { + match item { + MatroskaTag::Timestamp(ts) => pts = ts, + MatroskaTag::BlockGroup(_) => { + trace!("group"); + let mut children = children.unwrap(); + while let Some(Ok(Unflat { + children: _, item, .. + })) = children.n() + { + match item { + MatroskaTag::Block(ref block) => { + debug!( + "block: track={} tso={}", + block.track, block.timestamp_off + ); + seek_index_add(seek_index, block, position.unwrap(), pts); } + _ => trace!("{item:?}"), } } - MatroskaTag::SimpleBlock(block) => { - trace!( - "simple block: track={} tso={}", - block.track, - block.timestamp_off - ); - trace!("{pts} {}", block.timestamp_off); - seek_index_add(seek_index, &block, position.unwrap(), pts); - } - _ => trace!("(rsc) tag ignored: {item:?}"), } - } else { - break; + MatroskaTag::SimpleBlock(block) => { + trace!( + "simple block: track={} tso={}", + block.track, + block.timestamp_off + ); + trace!("{pts} {}", block.timestamp_off); + seek_index_add(seek_index, &block, position.unwrap(), pts); + } + _ => trace!("(rsc) tag ignored: {item:?}"), } } } @@ -142,9 +133,7 @@ fn seek_index_add( // } // } - let trs = seek_index - .entry(block.track) - .or_insert(SeekIndex::default()); + let trs = seek_index.entry(block.track).or_default(); if block.keyframe { trs.keyframes.push(trs.blocks.len()); diff --git a/remuxer/src/segment_extractor.rs b/remuxer/src/segment_extractor.rs index 2a12802..ca9e90f 100644 --- a/remuxer/src/segment_extractor.rs +++ b/remuxer/src/segment_extractor.rs @@ -18,7 +18,7 @@ impl<'a> SegmentExtractIter<'a> { } /// Returns the next block and sometimes its duration too. - pub fn next(&mut self) -> Result<(Block, Option)> { + pub fn next_block(&mut self) -> Result<(Block, Option)> { let mut duration = None; let mut group = false; let mut saved_block = None; diff --git a/server/src/main.rs b/server/src/main.rs index 8721e39..dae2da4 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -4,6 +4,7 @@ Copyright (C) 2024 metamuffin */ #![feature(int_roundings, let_chains)] +#![allow(clippy::needless_borrows_for_generic_args)] use crate::routes::ui::{account::hash_password, admin::log::enable_logging}; use anyhow::Context; @@ -46,7 +47,7 @@ async fn main() { Ser(User { admin: true, name: username.clone(), - password: hash_password(&username, &password), + password: hash_password(username, password), ..admin.unwrap_or_else(|| User { display_name: "Admin".to_string(), ..Default::default() diff --git a/server/src/routes/stream.rs b/server/src/routes/stream.rs index ecfa3e7..756c502 100644 --- a/server/src/routes/stream.rs +++ b/server/src/routes/stream.rs @@ -54,7 +54,7 @@ pub async fn r_stream( spec: StreamSpec, ) -> Result, MyError> { let node = T_NODE - .get(&db, id)? + .get(db, id)? .only_if_permitted(&session.user.permissions) .ok_or(anyhow!("node does not exist"))?; let source = node @@ -86,7 +86,7 @@ pub async fn r_stream( .ok_or(anyhow!("no credentials on the server-side"))?; info!("creating session on {host}"); - let instance = federation.get_instance(&host)?.to_owned(); + let instance = federation.get_instance(host)?.to_owned(); let session = instance .login(CreateSessionParams { username: username.to_owned(), @@ -116,12 +116,12 @@ pub async fn r_stream( range .as_ref() .map(|r| r.to_cr_hv()) - .unwrap_or(format!("none")) + .unwrap_or("none".to_string()) ); let urange = match &range { Some(r) => { - let r = r.0.get(0).unwrap_or(&(None..None)); + let r = r.0.first().unwrap_or(&(None..None)); r.start.unwrap_or(0)..r.end.unwrap_or(isize::MAX as usize) } None => 0..(isize::MAX as usize), @@ -192,14 +192,8 @@ impl RequestRange { assert_eq!(self.0.len(), 1); format!( "bytes {}-{}/*", - self.0[0] - .start - .map(|e| format!("{e}")) - .unwrap_or(String::new()), - self.0[0] - .end - .map(|e| format!("{e}")) - .unwrap_or(String::new()) + self.0[0].start.map(|e| e.to_string()).unwrap_or_default(), + self.0[0].end.map(|e| e.to_string()).unwrap_or_default() ) } pub fn from_hv(s: &str) -> Result { diff --git a/server/src/routes/ui/account/settings.rs b/server/src/routes/ui/account/settings.rs index 492e8ca..7d54d75 100644 --- a/server/src/routes/ui/account/settings.rs +++ b/server/src/routes/ui/account/settings.rs @@ -98,7 +98,6 @@ fn settings_page(session: Session, flash: Option>) -> DynLayout p { "The secret can be found in " code{"$XDG_CONFIG_HOME/jellynative_secret"} " or by clicking " a.button[href="jellynative://show-secret-v1"] { "Show Secret" } "." } } }, - ..Default::default() } } diff --git a/server/src/routes/ui/admin/log.rs b/server/src/routes/ui/admin/log.rs index 5b81a52..884ad7a 100644 --- a/server/src/routes/ui/admin/log.rs +++ b/server/src/routes/ui/admin/log.rs @@ -22,7 +22,7 @@ use std::{ const MAX_LOG_LEN: usize = 4096; -static LOGGER: LazyLock = LazyLock::new(Log::new); +static LOGGER: LazyLock = LazyLock::new(Log::default); pub fn enable_logging() { log::set_logger(&*LOGGER).unwrap(); @@ -63,9 +63,8 @@ pub fn r_admin_log<'a>(_session: AdminSession, warnonly: bool) -> MyResult Self { +impl Default for Log { + fn default() -> Self { Self { inner: env_logger::builder() .filter_level(log::LevelFilter::Warn) @@ -74,6 +73,8 @@ impl Log { log: Default::default(), } } +} +impl Log { fn should_log(&self, metadata: &log::Metadata) -> bool { let level = metadata.level(); level @@ -152,18 +153,11 @@ fn format_level(level: Level) -> impl markup::Render { markup::new! { span[style=format!("color:{c}")] {@s} } } +#[derive(Default)] pub struct HtmlOut { s: String, color: bool, } -impl Default for HtmlOut { - fn default() -> Self { - Self { - color: false, - s: String::new(), - } - } -} impl HtmlOut { pub fn set_color(&mut self, [r, g, b]: [u8; 3]) { self.reset_color(); @@ -184,16 +178,12 @@ impl vte::Perform for HtmlOut { x => write!(self.s, "&#{};", x as u32).unwrap(), } } - fn execute(&mut self, _byte: u8) {} fn hook(&mut self, _params: &vte::Params, _i: &[u8], _ignore: bool, _a: char) {} fn put(&mut self, _byte: u8) {} fn unhook(&mut self) {} fn osc_dispatch(&mut self, _params: &[&[u8]], _bell_terminated: bool) {} - fn esc_dispatch(&mut self, _intermediates: &[u8], _ignore: bool, _byte: u8) { - // self.s += &format!(" {:?} ", (_intermediates, _byte)) - } - + fn esc_dispatch(&mut self, _intermediates: &[u8], _ignore: bool, _byte: u8) {} fn csi_dispatch( &mut self, params: &vte::Params, @@ -202,9 +192,9 @@ impl vte::Perform for HtmlOut { action: char, ) { let mut k = params.iter(); - // self.s += &format!(" {:?} ", (params, action)); + #[allow(clippy::single_match)] match action { - 'm' => match k.next().unwrap_or(&[0]).get(0).unwrap_or(&0) { + 'm' => match k.next().unwrap_or(&[0]).first().unwrap_or(&0) { c @ (30..=37 | 40..=47) => { let c = if *c >= 40 { *c - 10 } else { *c }; self.set_color(match c { diff --git a/server/src/routes/ui/admin/mod.rs b/server/src/routes/ui/admin/mod.rs index 540ac72..25f1f42 100644 --- a/server/src/routes/ui/admin/mod.rs +++ b/server/src/routes/ui/admin/mod.rs @@ -134,7 +134,7 @@ pub async fn r_admin_invite( database: &State, ) -> MyResult> { let i = format!("{}", rand::thread_rng().gen::()); - T_INVITE.insert(&database, &*i, ())?; + T_INVITE.insert(database, &*i, ())?; admin_dashboard(database, Some(Ok(format!("Invite: {}", i)))).await } @@ -152,7 +152,7 @@ pub async fn r_admin_remove_invite( ) -> MyResult> { drop(session); T_INVITE - .remove(&database, form.invite.as_str())? + .remove(database, form.invite.as_str())? .ok_or(anyhow!("invite did not exist"))?; admin_dashboard(database, Some(Ok("Invite invalidated".into()))).await @@ -166,9 +166,9 @@ pub async fn r_admin_import( ) -> MyResult> { drop(session); let t = Instant::now(); - let r = import(&database, &federation).await; + let r = import(database, federation).await; admin_dashboard( - &database, + database, Some( r.map_err(|e| e.into()) .map(|_| format!("Import successful; took {:?}", t.elapsed())), @@ -187,7 +187,7 @@ pub async fn r_admin_delete_cache( let r = tokio::fs::remove_dir_all(&CONF.cache_path).await; tokio::fs::create_dir(&CONF.cache_path).await?; admin_dashboard( - &database, + database, Some( r.map_err(|e| e.into()) .map(|_| format!("Cache deleted; took {:?}", t.elapsed())), @@ -233,7 +233,7 @@ pub async fn r_admin_transcode_posters( drop(_permit); admin_dashboard( - &database, + database, Some(Ok(format!( "All posters pre-transcoded; took {:?}", t.elapsed() diff --git a/server/src/routes/ui/admin/user.rs b/server/src/routes/ui/admin/user.rs index e456894..6cd2ba3 100644 --- a/server/src/routes/ui/admin/user.rs +++ b/server/src/routes/ui/admin/user.rs @@ -76,7 +76,7 @@ fn manage_single_user<'a>( name: String, ) -> MyResult> { let user = T_USER - .get(&database, &*name)? + .get(database, &*name)? .ok_or(anyhow!("user does not exist"))?; let flash = flash.map(|f| f.map_err(|e| format!("{e:?}"))); @@ -193,7 +193,7 @@ pub fn r_admin_remove_user( ) -> MyResult> { drop(session); T_USER - .remove(&database, form.name.as_str())? + .remove(database, form.name.as_str())? .ok_or(anyhow!("user did not exist"))?; user_management(database, Some(Ok("User removed".into()))) } diff --git a/server/src/routes/ui/assets.rs b/server/src/routes/ui/assets.rs index c278a31..ad31240 100644 --- a/server/src/routes/ui/assets.rs +++ b/server/src/routes/ui/assets.rs @@ -75,7 +75,7 @@ pub async fn r_item_assets( width: Option, ) -> MyResult { let node = T_NODE - .get(&db, id)? + .get(db, id)? .only_if_permitted(&session.user.permissions) .ok_or(anyhow!("node does not exist"))?; @@ -83,10 +83,10 @@ pub async fn r_item_assets( AssetRole::Backdrop => node.public.backdrop, AssetRole::Poster => node.public.poster, }; - if let None = asset { + if asset.is_none() { if let Some(parent) = &node.public.path.last() { let parent = T_NODE - .get(&db, parent.as_str())? + .get(db, parent.as_str())? .ok_or(anyhow!("node does not exist"))?; asset = match role { AssetRole::Backdrop => parent.public.backdrop, @@ -113,7 +113,7 @@ pub async fn r_person_asset( width: Option, ) -> MyResult { T_NODE - .get(&db, id)? + .get(db, id)? .only_if_permitted(&session.user.permissions) .ok_or(anyhow!("node does not exist"))?; @@ -129,7 +129,7 @@ pub async fn r_person_asset( .person .headshot .to_owned() - .unwrap_or(AssetInner::Assets(format!("fallback-Person.avif").into()).ser()); + .unwrap_or(AssetInner::Assets("fallback-Person.avif".into()).ser()); Ok(Redirect::temporary(rocket::uri!(r_asset(asset.0, width)))) } @@ -146,7 +146,7 @@ pub async fn r_node_thumbnail( width: Option, ) -> MyResult { let node = T_NODE - .get(&db, id)? + .get(db, id)? .only_if_permitted(&session.user.permissions) .ok_or(anyhow!("node does not exist"))?; diff --git a/server/src/routes/ui/error.rs b/server/src/routes/ui/error.rs index b8a132d..ba1dc88 100644 --- a/server/src/routes/ui/error.rs +++ b/server/src/routes/ui/error.rs @@ -41,7 +41,7 @@ pub fn r_catch<'a>(status: Status, _request: &Request) -> DynLayoutPage<'a> { } #[catch(default)] -pub fn r_api_catch<'a>(status: Status, _request: &Request) -> Value { +pub fn r_api_catch(status: Status, _request: &Request) -> Value { json!({ "error": format!("{status}") }) } diff --git a/server/src/routes/ui/home.rs b/server/src/routes/ui/home.rs index 2fa9212..0a1089a 100644 --- a/server/src/routes/ui/home.rs +++ b/server/src/routes/ui/home.rs @@ -50,7 +50,7 @@ pub fn r_home(sess: Session, db: &State) -> MyResult { .collect::>(); let toplevel = T_NODE - .get(&db, "library")? + .get(db, "library")? .context("root node missing")? .public .children diff --git a/server/src/routes/ui/layout.rs b/server/src/routes/ui/layout.rs index 1696ac4..9f9038c 100644 --- a/server/src/routes/ui/layout.rs +++ b/server/src/routes/ui/layout.rs @@ -74,7 +74,7 @@ markup::define! { @if let Some(flash) = &flash { @match flash { Ok(mesg) => { section.message { p.success { @mesg } } } - Err(err) => { section.message { p.error { @format!("{err}") } } } + Err(err) => { section.message { p.error { @err } } } } } } @@ -110,7 +110,7 @@ impl<'r, Main: Render> Responder<'r, 'static> for LayoutPage
{ title: self.title, class: &format!( "{} theme-{:?}", - self.class.as_deref().unwrap_or(""), + self.class.unwrap_or(""), session .as_ref() .map(|s| s.user.theme) diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs index bd839fb..d99ddb7 100644 --- a/server/src/routes/ui/node.rs +++ b/server/src/routes/ui/node.rs @@ -47,7 +47,7 @@ pub async fn r_library_node_ext<'a>( db: &'a State, ) -> MyResult> { T_NODE - .get(&db, id)? + .get(db, id)? .only_if_permitted(&session.user.permissions) .ok_or(anyhow!("node does not exist"))?; @@ -63,14 +63,14 @@ pub async fn r_library_node_filter<'a>( filter: NodeFilterSort, ) -> MyResult, Json>> { let node = T_NODE - .get(&db, id)? + .get(db, id)? .only_if_permitted(&session.user.permissions) .ok_or(anyhow!("node does not exist"))? .public; let node_ext = T_NODE_EXTENDED.get(db, id)?.unwrap_or_default(); let udata = T_USER_NODE - .get(&db, &(session.user.name.as_str(), id))? + .get(db, &(session.user.name.as_str(), id))? .unwrap_or_default(); if *aj { @@ -80,7 +80,7 @@ pub async fn r_library_node_filter<'a>( let mut children = node .children .iter() - .map(|c| Ok(db.get_node_with_userdata(c, &session)?)) + .map(|c| db.get_node_with_userdata(c, &session)) .collect::>>()? .into_iter() .collect(); @@ -113,7 +113,7 @@ pub async fn r_library_node_filter<'a>( Ok(Either::Left(LayoutPage { title: node.title.clone().unwrap_or_default(), content: markup::new! { - @NodePage { node: &node, id: &id, udata: &udata, children: &children, path: &path, filter: &filter, node_ext: &node_ext } + @NodePage { node: &node, id, udata: &udata, children: &children, path: &path, filter: &filter, node_ext: &node_ext } }, ..Default::default() })) @@ -220,10 +220,10 @@ markup::define! { } .title { @pe.person.name br; - @if let Some(c) = pe.characters.get(0) { + @if let Some(c) = pe.characters.first() { .subtitle { @c } } - @if let Some(c) = pe.jobs.get(0) { + @if let Some(c) = pe.jobs.first() { .subtitle { @c } } } @@ -359,11 +359,8 @@ impl MediaInfoExt for MediaInfo { fn resolution_name(&self) -> &'static str { let mut maxdim = 0; for t in &self.tracks { - match &t.kind { - SourceTrackKind::Video { width, height, .. } => { - maxdim = maxdim.max(*width.max(height)) - } - _ => (), + if let SourceTrackKind::Video { width, height, .. } = &t.kind { + maxdim = maxdim.max(*width.max(height)) } } diff --git a/server/src/routes/ui/player.rs b/server/src/routes/ui/player.rs index 69445ed..55e1303 100644 --- a/server/src/routes/ui/player.rs +++ b/server/src/routes/ui/player.rs @@ -108,9 +108,9 @@ pub fn r_player<'a>( let spec = StreamSpec { track: None .into_iter() - .chain(conf.v.into_iter()) - .chain(conf.a.into_iter()) - .chain(conf.s.into_iter()) + .chain(conf.v) + .chain(conf.a) + .chain(conf.s) .collect::>(), format: StreamFormat::Matroska, webm: Some(true), @@ -131,7 +131,6 @@ pub fn r_player<'a>( } @conf }, - ..Default::default() })) } diff --git a/server/src/routes/ui/search.rs b/server/src/routes/ui/search.rs index 4ea5716..5ca4b51 100644 --- a/server/src/routes/ui/search.rs +++ b/server/src/routes/ui/search.rs @@ -49,12 +49,12 @@ pub async fn r_search<'a>( let id = doc.get_first(db.node_index.id).unwrap().as_str().unwrap(); let node = T_NODE - .get(&db, id)? + .get(db, id)? .only_if_permitted(&session.user.permissions) .ok_or(anyhow!("node does not exist"))? .public; let udata = T_USER_NODE - .get(&db, &(session.user.name.as_str(), id))? + .get(db, &(session.user.name.as_str(), id))? .unwrap_or_default(); results.push((id.to_owned(), node, udata)); diff --git a/server/src/routes/ui/sort.rs b/server/src/routes/ui/sort.rs index a779b15..88f262b 100644 --- a/server/src/routes/ui/sort.rs +++ b/server/src/routes/ui/sort.rs @@ -220,7 +220,7 @@ markup::define! { .category { h3 { @cname } @for (value, label) in *cat { - label { input[type="checkbox", name="filter_kind", value=value, checked=f.filter_kind.as_ref().map(|k|k.contains(&value)).unwrap_or(true)]; @label } br; + label { input[type="checkbox", name="filter_kind", value=value, checked=f.filter_kind.as_ref().map(|k|k.contains(value)).unwrap_or(true)]; @label } br; } } } diff --git a/stream/src/fragment.rs b/stream/src/fragment.rs index 16bb703..1082e1c 100644 --- a/stream/src/fragment.rs +++ b/stream/src/fragment.rs @@ -29,7 +29,7 @@ pub async fn fragment_stream( let n = spec.index.ok_or(anyhow!("segment index missing"))?; let local_track = local_tracks - .get(0) + .first() .ok_or(anyhow!("track missing"))? .to_owned(); diff --git a/stream/src/hls.rs b/stream/src/hls.rs index b5a78ef..342cbde 100644 --- a/stream/src/hls.rs +++ b/stream/src/hls.rs @@ -55,7 +55,7 @@ pub async fn hls_variant_stream( mut spec: StreamSpec, mut b: DuplexStream, ) -> Result<()> { - let local_track = local_tracks.get(0).ok_or(anyhow!("no track"))?.to_owned(); + let local_track = local_tracks.first().ok_or(anyhow!("no track"))?.to_owned(); let track_index = spec.track[0]; let media_info = node.public.media.to_owned().ok_or(anyhow!("no media?"))?; let frags = spawn_blocking(move || { diff --git a/stream/src/jhls.rs b/stream/src/jhls.rs index ac1a3e5..2e45378 100644 --- a/stream/src/jhls.rs +++ b/stream/src/jhls.rs @@ -21,7 +21,7 @@ pub async fn jhls_index( perms: &PermissionSet, ) -> Result<()> { let local_track = local_tracks - .get(0) + .first() .ok_or(anyhow!("track missing"))? .to_owned(); diff --git a/stream/src/webvtt.rs b/stream/src/webvtt.rs index b29c7c5..316e224 100644 --- a/stream/src/webvtt.rs +++ b/stream/src/webvtt.rs @@ -21,8 +21,8 @@ pub async fn vtt_stream( // TODO should use fragments too? big films take too long... - let tracki = *spec.track.get(0).ok_or(anyhow!("no track selected"))?; - let local_track = local_tracks.get(0).ok_or(anyhow!("no tracks"))?.clone(); + let tracki = *spec.track.first().ok_or(anyhow!("no track selected"))?; + let local_track = local_tracks.first().ok_or(anyhow!("no tracks"))?.clone(); let track = &node.public.media.unwrap().tracks[tracki]; let cp = local_track.codec_private.clone(); diff --git a/tool/src/add.rs b/tool/src/add.rs index dfec40d..7b3861e 100644 --- a/tool/src/add.rs +++ b/tool/src/add.rs @@ -55,6 +55,14 @@ pub async fn add(action: Action) -> anyhow::Result<()> { default = i }; } + TraktKind::Show => { + if let Some(i) = directories + .iter() + .position(|d| d.0.to_str().unwrap().contains("shows")) + { + default = i + }; + } _ => (), } } @@ -71,7 +79,7 @@ pub async fn add(action: Action) -> anyhow::Result<()> { let (last_search, trakt_object, trakt_kind) = loop { let name: String = Input::with_theme(&theme) .with_prompt("Search by title") - .default(media.as_ref().map(path_to_query).unwrap_or_default()) + .default(media.as_ref().map(|p| path_to_query(p)).unwrap_or_default()) .interact_text() .unwrap(); @@ -155,7 +163,7 @@ pub async fn add(action: Action) -> anyhow::Result<()> { } fn validate_id(s: &String) -> anyhow::Result<()> { - if &make_id(&s) == s { + if &make_id(s) == s { Ok(()) } else { bail!("invalid id") @@ -174,7 +182,7 @@ fn make_id(s: &str) -> String { out } -fn path_to_query(path: &PathBuf) -> String { +fn path_to_query(path: &Path) -> String { path.file_stem() .unwrap() .to_str() diff --git a/tool/src/migrate.rs b/tool/src/migrate.rs index 0412430..fe369d4 100644 --- a/tool/src/migrate.rs +++ b/tool/src/migrate.rs @@ -112,7 +112,7 @@ pub fn migrate(action: Action) -> anyhow::Result<()> { let table = txn.open_table(T_USER)?; let len = table.len()?; - for r in table.iter()?.progress_count(len.try_into().unwrap()) { + for r in table.iter()?.progress_count(len) { let (k, v) = r?; serde_json::to_writer(&mut o, &(k.value(), v.value().0))?; writeln!(&mut o)?; @@ -161,7 +161,7 @@ pub fn migrate(action: Action) -> anyhow::Result<()> { let table = txn.open_table(T_USER_NODE)?; let len = table.len()?; - for r in table.iter()?.progress_count(len.try_into().unwrap()) { + for r in table.iter()?.progress_count(len) { let (k, v) = r?; serde_json::to_writer(&mut o, &(k.value(), v.value().0))?; writeln!(&mut o)?; @@ -213,7 +213,7 @@ pub fn migrate(action: Action) -> anyhow::Result<()> { let table = txn.open_table(T_INVITE)?; let len = table.len()?; - for r in table.iter()?.progress_count(len.try_into().unwrap()) { + for r in table.iter()?.progress_count(len) { let (k, v) = r?; serde_json::to_writer(&mut o, &(k.value(), v.value().0))?; writeln!(&mut o)?; diff --git a/transcoder/src/fragment.rs b/transcoder/src/fragment.rs index 7695a48..ecb73d5 100644 --- a/transcoder/src/fragment.rs +++ b/transcoder/src/fragment.rs @@ -22,7 +22,7 @@ pub async fn transcode( enc: &EncodingProfile, input: impl FnOnce(ChildStdin), ) -> anyhow::Result { - Ok(async_cache_file( + async_cache_file( &["frag-tc", key, &format!("{enc:?}")], move |mut output| async move { let _permit = LOCAL_VIDEO_TRANSCODING_TASKS.acquire().await?; @@ -78,9 +78,9 @@ pub async fn transcode( let mut proc = Command::new("ffmpeg") .stdin(Stdio::piped()) .stdout(Stdio::piped()) - .args(&["-f", "matroska", "-i", "pipe:0"]) + .args(["-f", "matroska", "-i", "pipe:0"]) .args(args) - .args(&["-f", "webm", "pipe:1"]) + .args(["-f", "webm", "pipe:1"]) .spawn()?; // let mut proc = Command::new("cat") // .stdin(Stdio::piped()) @@ -98,5 +98,5 @@ pub async fn transcode( Ok(()) }, ) - .await?) + .await } diff --git a/transcoder/src/image.rs b/transcoder/src/image.rs index 3589ab9..3d7cb2d 100644 --- a/transcoder/src/image.rs +++ b/transcoder/src/image.rs @@ -22,7 +22,7 @@ pub async fn transcode( speed: u8, width: usize, ) -> anyhow::Result { - Ok(async_cache_file( + async_cache_file( &[ "image-tc", path.clone().as_os_str().to_str().unwrap(), @@ -96,5 +96,5 @@ pub async fn transcode( Ok(()) }, ) - .await?) + .await } diff --git a/transcoder/src/thumbnail.rs b/transcoder/src/thumbnail.rs index 9661fd0..c8bfb1c 100644 --- a/transcoder/src/thumbnail.rs +++ b/transcoder/src/thumbnail.rs @@ -5,7 +5,7 @@ use std::{path::Path, process::Stdio}; use tokio::{io::copy, process::Command}; pub async fn create_thumbnail(path: &Path, time: f64) -> anyhow::Result { - Ok(async_cache_file( + async_cache_file( &["thumb", path.to_str().unwrap(), &format!("{time}")], move |mut output| async move { let _permit = LOCAL_IMAGE_TRANSCODING_TASKS.acquire().await?; @@ -13,12 +13,12 @@ pub async fn create_thumbnail(path: &Path, time: f64) -> anyhow::Result anyhow::Result