This commit is contained in:
+9
-9
@@ -30,7 +30,7 @@ pub struct MediaFile {
|
||||
pub sha256_hash: LimitedString<64>,
|
||||
// Audio-specific fields (NULL for non-audio files)
|
||||
/// e.g. "mp3", "flac", "ogg", "wav"
|
||||
pub audio_format: Option<LimitedString<32>>,
|
||||
pub audio_format: Option<String>,
|
||||
/// Bitrate in kbps
|
||||
pub audio_bitrate: Option<i32>,
|
||||
/// Sample rate in Hz
|
||||
@@ -57,7 +57,7 @@ pub struct Artist {
|
||||
pub image_file_id: Option<i64>,
|
||||
pub is_hidden: bool,
|
||||
/// NULL = human-created, non-NULL = LLM model that created it
|
||||
pub model_name: Option<LimitedString<128>>,
|
||||
pub model_name: Option<String>,
|
||||
pub created_at: LimitedString<32>,
|
||||
pub updated_at: LimitedString<32>,
|
||||
}
|
||||
@@ -91,7 +91,7 @@ impl Artist {
|
||||
name_sort: LimitedString::new(&normalize_name(name)).unwrap(),
|
||||
image_file_id: None,
|
||||
is_hidden: false,
|
||||
model_name: model_name.map(|s| LimitedString::new(s).unwrap()),
|
||||
model_name: model_name.map(str::to_owned),
|
||||
created_at: now.clone(),
|
||||
updated_at: now,
|
||||
};
|
||||
@@ -173,7 +173,7 @@ pub struct Release {
|
||||
pub total_discs: Option<i32>,
|
||||
pub is_hidden: bool,
|
||||
/// NULL = human-created, non-NULL = LLM model that created it
|
||||
pub model_name: Option<LimitedString<128>>,
|
||||
pub model_name: Option<String>,
|
||||
pub created_at: LimitedString<32>,
|
||||
pub updated_at: LimitedString<32>,
|
||||
}
|
||||
@@ -206,7 +206,7 @@ impl Release {
|
||||
total_tracks: None,
|
||||
total_discs: None,
|
||||
is_hidden: false,
|
||||
model_name: model_name.map(|s| LimitedString::new(s).unwrap()),
|
||||
model_name: model_name.map(str::to_owned),
|
||||
created_at: now.clone(),
|
||||
updated_at: now,
|
||||
};
|
||||
@@ -355,7 +355,7 @@ pub struct Track {
|
||||
pub year: Option<i32>,
|
||||
pub is_hidden: bool,
|
||||
/// NULL = human-created, non-NULL = LLM model that created it
|
||||
pub model_name: Option<LimitedString<128>>,
|
||||
pub model_name: Option<String>,
|
||||
pub created_at: LimitedString<32>,
|
||||
pub updated_at: LimitedString<32>,
|
||||
}
|
||||
@@ -585,7 +585,7 @@ impl Track {
|
||||
cover_file_id: None,
|
||||
year,
|
||||
is_hidden: false,
|
||||
model_name: model_name.map(|s| LimitedString::new(s).unwrap()),
|
||||
model_name: model_name.map(str::to_owned),
|
||||
created_at: now.clone(),
|
||||
updated_at: now,
|
||||
};
|
||||
@@ -622,7 +622,7 @@ impl MediaFile {
|
||||
mime_type: LimitedString::new(mime_type).unwrap(),
|
||||
file_size_bytes,
|
||||
sha256_hash: LimitedString::new(sha256_hash).unwrap(),
|
||||
audio_format: audio_format.map(|s| LimitedString::new(s).unwrap()),
|
||||
audio_format: audio_format.map(str::to_owned),
|
||||
audio_bitrate,
|
||||
audio_sample_rate,
|
||||
audio_bit_depth,
|
||||
@@ -674,7 +674,7 @@ impl MediaFile {
|
||||
}
|
||||
|
||||
pub fn audio_format_str(&self) -> &str {
|
||||
self.audio_format.as_ref().map_or("", |s| s.as_str())
|
||||
self.audio_format.as_deref().unwrap_or("")
|
||||
}
|
||||
|
||||
pub fn created_at_str(&self) -> &str {
|
||||
|
||||
+15
-18
@@ -20,8 +20,8 @@ pub struct ScheduledJob {
|
||||
pub description: String,
|
||||
pub cron_expression: LimitedString<100>,
|
||||
pub enabled: bool,
|
||||
pub last_run_at: Option<LimitedString<32>>,
|
||||
pub next_run_at: Option<LimitedString<32>>,
|
||||
pub last_run_at: Option<String>,
|
||||
pub next_run_at: Option<String>,
|
||||
pub created_at: LimitedString<32>,
|
||||
pub updated_at: LimitedString<32>,
|
||||
}
|
||||
@@ -51,8 +51,7 @@ impl ScheduledJob {
|
||||
"Updating cron expression"
|
||||
);
|
||||
existing.cron_expression = LimitedString::new(cron_expression).unwrap();
|
||||
existing.next_run_at = compute_next_run(cron_expression)
|
||||
.map(|s| LimitedString::new(&s).unwrap());
|
||||
existing.next_run_at = compute_next_run(cron_expression);
|
||||
changed = true;
|
||||
}
|
||||
if existing.description != description {
|
||||
@@ -73,7 +72,7 @@ impl ScheduledJob {
|
||||
cron_expression: LimitedString::new(cron_expression).unwrap(),
|
||||
enabled: true,
|
||||
last_run_at: None,
|
||||
next_run_at: next.map(|s| LimitedString::new(&s).unwrap()),
|
||||
next_run_at: next,
|
||||
created_at: now.clone(),
|
||||
updated_at: now,
|
||||
};
|
||||
@@ -98,11 +97,11 @@ impl ScheduledJob {
|
||||
}
|
||||
|
||||
pub fn last_run_at_str(&self) -> &str {
|
||||
self.last_run_at.as_ref().map_or("", |v| v.as_str())
|
||||
self.last_run_at.as_deref().unwrap_or("")
|
||||
}
|
||||
|
||||
pub fn next_run_at_str(&self) -> &str {
|
||||
self.next_run_at.as_ref().map_or("", |v| v.as_str())
|
||||
self.next_run_at.as_deref().unwrap_or("")
|
||||
}
|
||||
|
||||
pub async fn delete_by_name(db: &Database, name: &str) -> cot::db::Result<()> {
|
||||
@@ -127,7 +126,7 @@ pub struct JobRun {
|
||||
pub job_name: LimitedString<100>,
|
||||
pub status: LimitedString<32>,
|
||||
pub started_at: LimitedString<32>,
|
||||
pub finished_at: Option<LimitedString<32>>,
|
||||
pub finished_at: Option<String>,
|
||||
pub duration_ms: Option<i64>,
|
||||
pub log_output: Option<String>,
|
||||
pub error_message: Option<String>,
|
||||
@@ -154,7 +153,7 @@ impl JobRun {
|
||||
|
||||
pub async fn set_completed(&mut self, db: &Database, duration_ms: i64, log: &str) -> cot::db::Result<()> {
|
||||
self.status = LimitedString::new("completed").unwrap();
|
||||
self.finished_at = Some(now_iso());
|
||||
self.finished_at = Some(now_iso().to_string());
|
||||
self.duration_ms = Some(duration_ms);
|
||||
self.log_output = Some(log.to_owned());
|
||||
self.save(db).await
|
||||
@@ -162,7 +161,7 @@ impl JobRun {
|
||||
|
||||
pub async fn set_failed(&mut self, db: &Database, duration_ms: i64, log: &str, error: &str) -> cot::db::Result<()> {
|
||||
self.status = LimitedString::new("failed").unwrap();
|
||||
self.finished_at = Some(now_iso());
|
||||
self.finished_at = Some(now_iso().to_string());
|
||||
self.duration_ms = Some(duration_ms);
|
||||
self.log_output = Some(log.to_owned());
|
||||
self.error_message = Some(error.to_owned());
|
||||
@@ -224,7 +223,7 @@ impl JobRun {
|
||||
}
|
||||
|
||||
pub fn finished_at_str(&self) -> &str {
|
||||
self.finished_at.as_ref().map_or("", |v| v.as_str())
|
||||
self.finished_at.as_deref().unwrap_or("")
|
||||
}
|
||||
|
||||
pub fn duration_display(&self) -> String {
|
||||
@@ -277,7 +276,7 @@ impl JobRunRow {
|
||||
job_name: LimitedString::new(&self.job_name).unwrap(),
|
||||
status: LimitedString::new(&self.status).unwrap(),
|
||||
started_at: LimitedString::new(&self.started_at).unwrap(),
|
||||
finished_at: self.finished_at.map(|s| LimitedString::new(&s).unwrap()),
|
||||
finished_at: self.finished_at,
|
||||
duration_ms: self.duration_ms,
|
||||
log_output: self.log_output,
|
||||
error_message: self.error_message,
|
||||
@@ -968,7 +967,7 @@ impl SchedulerHandle {
|
||||
}
|
||||
|
||||
if let Ok(Some(mut sched_job)) = ScheduledJob::get_by_name(db, job_name).await {
|
||||
sched_job.last_run_at = Some(now_iso());
|
||||
sched_job.last_run_at = Some(now_iso().to_string());
|
||||
sched_job.updated_at = now_iso();
|
||||
let _ = sched_job.save(db).await;
|
||||
}
|
||||
@@ -993,8 +992,7 @@ impl SchedulerHandle {
|
||||
// Update DB
|
||||
if let Ok(Some(mut sched_job)) = ScheduledJob::get_by_name(&self.shared_db, job_name).await {
|
||||
sched_job.cron_expression = LimitedString::new(new_cron).unwrap();
|
||||
sched_job.next_run_at = compute_next_run(new_cron)
|
||||
.map(|s| LimitedString::new(&s).unwrap());
|
||||
sched_job.next_run_at = compute_next_run(new_cron);
|
||||
sched_job.updated_at = now_iso();
|
||||
let _ = sched_job.save(&self.shared_db).await;
|
||||
}
|
||||
@@ -1024,8 +1022,7 @@ impl SchedulerHandle {
|
||||
|
||||
sched_job.enabled = enabled;
|
||||
if enabled {
|
||||
sched_job.next_run_at = compute_next_run(sched_job.cron_expression_str())
|
||||
.map(|s| LimitedString::new(&s).unwrap());
|
||||
sched_job.next_run_at = compute_next_run(sched_job.cron_expression_str());
|
||||
}
|
||||
sched_job.updated_at = now_iso();
|
||||
let _ = sched_job.save(&self.shared_db).await;
|
||||
@@ -1312,7 +1309,7 @@ pub async fn trigger_job_now(
|
||||
}
|
||||
|
||||
if let Ok(Some(mut sched_job)) = ScheduledJob::get_by_name(db, job_name).await {
|
||||
sched_job.last_run_at = Some(now_iso());
|
||||
sched_job.last_run_at = Some(now_iso().to_string());
|
||||
sched_job.updated_at = now_iso();
|
||||
let _ = sched_job.save(db).await;
|
||||
}
|
||||
|
||||
+22
-23
@@ -13,9 +13,9 @@ pub struct User {
|
||||
id: Auto<i64>,
|
||||
#[model(unique)]
|
||||
username: LimitedString<255>,
|
||||
password: Option<PasswordHash>,
|
||||
email: Option<LimitedString<255>>,
|
||||
display_name: Option<LimitedString<255>>,
|
||||
password: Option<String>,
|
||||
email: Option<String>,
|
||||
display_name: Option<String>,
|
||||
avatar_url: Option<String>,
|
||||
role: LimitedString<32>,
|
||||
is_active: bool,
|
||||
@@ -49,9 +49,9 @@ impl User {
|
||||
let mut user = Self {
|
||||
id: Auto::auto(),
|
||||
username: LimitedString::new(username).unwrap(),
|
||||
password: Some(hash),
|
||||
email: email.map(|e| LimitedString::new(e).unwrap()),
|
||||
display_name: display_name.map(|d| LimitedString::new(d).unwrap()),
|
||||
password: Some(hash.into_string()),
|
||||
email: email.map(str::to_owned),
|
||||
display_name: display_name.map(str::to_owned),
|
||||
avatar_url: None,
|
||||
role: LimitedString::new(role).unwrap(),
|
||||
is_active: true,
|
||||
@@ -72,10 +72,10 @@ impl User {
|
||||
role: &str,
|
||||
) -> cot::db::Result<()> {
|
||||
self.username = LimitedString::new(username).unwrap();
|
||||
self.email = email.map(|e| LimitedString::new(e).unwrap());
|
||||
self.display_name = display_name.map(|d| LimitedString::new(d).unwrap());
|
||||
self.email = email.map(str::to_owned);
|
||||
self.display_name = display_name.map(str::to_owned);
|
||||
if let Some(pw) = new_password {
|
||||
self.password = Some(PasswordHash::from_password(&Password::new(pw)));
|
||||
self.password = Some(PasswordHash::from_password(&Password::new(pw)).into_string());
|
||||
}
|
||||
self.role = LimitedString::new(role).unwrap();
|
||||
self.save(db).await
|
||||
@@ -95,8 +95,10 @@ impl User {
|
||||
}
|
||||
|
||||
/// Return a reference to the password hash, if set.
|
||||
pub fn password_ref(&self) -> Option<&PasswordHash> {
|
||||
self.password.as_ref()
|
||||
pub fn password_ref(&self) -> Option<PasswordHash> {
|
||||
self.password
|
||||
.as_ref()
|
||||
.and_then(|hash| PasswordHash::new(hash.clone()).ok())
|
||||
}
|
||||
|
||||
/// Parse the stored role code into a `Role`, defaulting to `User`.
|
||||
@@ -142,8 +144,8 @@ impl User {
|
||||
id: Auto::auto(),
|
||||
username: LimitedString::new(username).unwrap(),
|
||||
password: None,
|
||||
email: email.map(|e| LimitedString::new(e).unwrap()),
|
||||
display_name: display_name.map(|d| LimitedString::new(d).unwrap()),
|
||||
email: email.map(str::to_owned),
|
||||
display_name: display_name.map(str::to_owned),
|
||||
avatar_url: None,
|
||||
role: LimitedString::new(role).unwrap(),
|
||||
is_active: true,
|
||||
@@ -160,10 +162,7 @@ impl User {
|
||||
|
||||
/// Find a user by email address.
|
||||
pub async fn get_by_email(db: &Database, email: &str) -> cot::db::Result<Option<Self>> {
|
||||
let Ok(email) = LimitedString::<255>::new(email) else {
|
||||
return Ok(None);
|
||||
};
|
||||
cot::db::query!(User, $email == Some(email)).get(db).await
|
||||
cot::db::query!(User, $email == Some(email.to_owned())).get(db).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,8 +178,8 @@ pub struct OidcLink {
|
||||
user_id: i64,
|
||||
issuer: LimitedString<255>,
|
||||
sub: LimitedString<255>,
|
||||
email: Option<LimitedString<255>>,
|
||||
name: Option<LimitedString<255>>,
|
||||
email: Option<String>,
|
||||
name: Option<String>,
|
||||
avatar_url: Option<String>,
|
||||
}
|
||||
|
||||
@@ -220,8 +219,8 @@ impl OidcLink {
|
||||
user_id,
|
||||
issuer: LimitedString::new(issuer).unwrap(),
|
||||
sub: LimitedString::new(sub).unwrap(),
|
||||
email: email.map(|e| LimitedString::new(e).unwrap()),
|
||||
name: name.map(|n| LimitedString::new(n).unwrap()),
|
||||
email: email.map(str::to_owned),
|
||||
name: name.map(str::to_owned),
|
||||
avatar_url: None,
|
||||
};
|
||||
link.insert(db).await?;
|
||||
@@ -235,8 +234,8 @@ impl OidcLink {
|
||||
email: Option<&str>,
|
||||
name: Option<&str>,
|
||||
) -> cot::db::Result<()> {
|
||||
self.email = email.map(|e| LimitedString::new(e).unwrap());
|
||||
self.name = name.map(|n| LimitedString::new(n).unwrap());
|
||||
self.email = email.map(str::to_owned);
|
||||
self.name = name.map(str::to_owned);
|
||||
self.save(db).await
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user