aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--common/Cargo.toml1
-rw-r--r--common/src/lib.rs4
-rw-r--r--import/src/infojson.rs21
-rw-r--r--import/src/main.rs16
-rw-r--r--server/src/routes/ui/node.rs3
-rw-r--r--server/src/routes/ui/sort.rs7
7 files changed, 51 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8d5a5bb..d34f2e1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1415,6 +1415,7 @@ name = "jellycommon"
version = "0.1.0"
dependencies = [
"bincode 2.0.0-rc.3",
+ "chrono",
"rocket",
"serde",
]
diff --git a/common/Cargo.toml b/common/Cargo.toml
index b38b962..437fb0b 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2021"
serde = { version = "1.0.188", features = ["derive"] }
bincode = { version = "2.0.0-rc.3", features = ["derive"] }
rocket = { workspace = true, optional = true }
+chrono = { version = "0.4.31", features = ["serde"] }
[features]
rocket = ["dep:rocket"]
diff --git a/common/src/lib.rs b/common/src/lib.rs
index 2bde0b9..8292e87 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -11,6 +11,9 @@ pub mod seek_index;
pub mod stream;
pub mod user;
+pub use chrono;
+
+use chrono::{DateTime, Utc};
#[cfg(feature = "rocket")]
use rocket::{FromFormField, UriDisplayQuery};
use serde::{Deserialize, Serialize};
@@ -42,6 +45,7 @@ pub struct NodePublic {
#[serde(default)] pub children: Vec<String>,
#[serde(default)] pub tagline: Option<String>,
#[serde(default)] pub description: Option<String>,
+ #[serde(default)] pub release_date: Option<DateTime<Utc>>,
#[serde(default)] pub index: Option<usize>,
#[serde(default)] pub media: Option<MediaInfo>,
#[serde(default)] pub ratings: BTreeMap<Rating, f64>,
diff --git a/import/src/infojson.rs b/import/src/infojson.rs
index ca02551..dd2151b 100644
--- a/import/src/infojson.rs
+++ b/import/src/infojson.rs
@@ -4,6 +4,8 @@
Copyright (C) 2023 metamuffin <metamuffin.org>
*/
+use anyhow::Context;
+use jellycommon::chrono::{format::Parsed, DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@@ -120,3 +122,22 @@ pub struct YHeatmapSample {
pub end_time: f64,
pub value: f64,
}
+
+pub fn parse_upload_date(d: &str) -> anyhow::Result<DateTime<Utc>> {
+ let (year, month, day) = (&d[0..4], &d[4..6], &d[6..8]);
+ let (year, month, day) = (
+ year.parse().context("parsing year")?,
+ month.parse().context("parsing month")?,
+ day.parse().context("parsing day")?,
+ );
+
+ let mut p = Parsed::new();
+ p.year = Some(year);
+ p.month = Some(month);
+ p.day = Some(day);
+ p.hour_div_12 = Some(0);
+ p.hour_mod_12 = Some(0);
+ p.minute = Some(0);
+ p.second = Some(0);
+ Ok(p.to_datetime_with_timezone(&Utc)?)
+}
diff --git a/import/src/main.rs b/import/src/main.rs
index 57e6b99..c274e54 100644
--- a/import/src/main.rs
+++ b/import/src/main.rs
@@ -11,7 +11,7 @@ pub mod tmdb;
use anyhow::Context;
use base64::Engine;
use clap::{Parser, Subcommand};
-use infojson::YVideo;
+use infojson::{parse_upload_date, YVideo};
use jellycommon::{
config::GlobalConfig, AssetLocation, LocalTrack, MediaInfo, MediaSource, Node, NodeKind,
NodePrivate, NodePublic, Rating,
@@ -22,6 +22,7 @@ use log::{info, warn};
use rand::random;
use std::{
collections::BTreeMap,
+ fmt::Debug,
fs::{remove_file, File},
io::{stdin, BufReader, Write},
path::PathBuf,
@@ -354,6 +355,9 @@ fn main() -> anyhow::Result<()> {
duration: m.duration,
tracks: m.tracks.clone(),
}),
+ release_date: infojson
+ .as_ref()
+ .and_then(|j| ok_or_warn(parse_upload_date(&j.upload_date))),
..Default::default()
},
};
@@ -399,3 +403,13 @@ fn make_ident(s: &str) -> String {
}
out
}
+
+fn ok_or_warn<T, E: Debug>(r: Result<T, E>) -> Option<T> {
+ match r {
+ Ok(t) => Some(t),
+ Err(e) => {
+ warn!("{e:?}");
+ None
+ }
+ }
+}
diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs
index 6256c77..bb97146 100644
--- a/server/src/routes/ui/node.rs
+++ b/server/src/routes/ui/node.rs
@@ -179,6 +179,9 @@ markup::define! {
Rating::Imdb => { "IMDb Rating: " @value }
} }
}
+ @if let Some(d) = &node.release_date {
+ p { "Released " @d.to_rfc2822() }
+ }
}
}
}
diff --git a/server/src/routes/ui/sort.rs b/server/src/routes/ui/sort.rs
index da5061d..e1af9d5 100644
--- a/server/src/routes/ui/sort.rs
+++ b/server/src/routes/ui/sort.rs
@@ -53,11 +53,16 @@ pub fn filter_and_sort_nodes(f: &NodeFilterSort, nodes: &mut Vec<(String, NodePu
if let Some(kind) = &f.filter_kind {
o &= kind.contains(&node.kind)
}
+ if let Some(SortProperty::ReleaseDate) = &f.sort_by {
+ o &= node.release_date.is_some()
+ }
o
});
if let Some(sort_prop) = &f.sort_by {
match sort_prop {
- SortProperty::ReleaseDate => nodes.sort_by_key(|(_, _n)| 0), // TODO
+ SortProperty::ReleaseDate => {
+ nodes.sort_by_key(|(_, n)| n.release_date.expect("asserted above"))
+ }
SortProperty::Title => nodes.sort_by(|(_, a), (_, b)| a.title.cmp(&b.title)),
SortProperty::RatingRottenTomatoes => nodes.sort_by_cached_key(|(_, n)| {
SortAnyway(*n.ratings.get(&Rating::RottenTomatoes).unwrap_or(&0.))