This commit is contained in:
jude 2024-04-20 19:10:49 +01:00
parent 2bd75c1c06
commit a102fecc2e
9 changed files with 67 additions and 16 deletions

View File

@ -13,17 +13,14 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="52900e09-9584-4b6c-95ff-fbd4ed5d8b2c" name="Changes" comment="Add interface package. Start adding auth stuff for refreshing tokens."> <list default="true" id="52900e09-9584-4b6c-95ff-fbd4ed5d8b2c" name="Changes" comment="Add interface package. Start adding auth stuff for refreshing tokens.">
<change afterPath="$PROJECT_DIR$/src/daemon/create_playlists.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/sqldialects.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/sqldialects.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/daemon/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/daemon/mod.rs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/etc/playlistd.toml" beforeDir="false" afterPath="$PROJECT_DIR$/etc/playlistd/playlistd.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/daemon/update_playlists.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/daemon/update_playlists.rs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/daemon/create_playlists.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/daemon/create_playlists.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/listenbrainz.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/listenbrainz.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.rs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/models.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/models.rs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/models.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/models.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/subsonic.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/subsonic.rs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/systemd/playlistd.service" beforeDir="false" afterPath="$PROJECT_DIR$/systemd/playlistd.service" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -102,6 +99,7 @@
<recent name="$PROJECT_DIR$/navidrome/src/client" /> <recent name="$PROJECT_DIR$/navidrome/src/client" />
</key> </key>
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/etc/playlistd" />
<recent name="$PROJECT_DIR$/src/daemon" /> <recent name="$PROJECT_DIR$/src/daemon" />
<recent name="$PROJECT_DIR$/navidrome/src/models" /> <recent name="$PROJECT_DIR$/navidrome/src/models" />
</key> </key>
@ -166,7 +164,8 @@
<workItem from="1713372315382" duration="4924000" /> <workItem from="1713372315382" duration="4924000" />
<workItem from="1713385358427" duration="2705000" /> <workItem from="1713385358427" duration="2705000" />
<workItem from="1713465993328" duration="1750000" /> <workItem from="1713465993328" duration="1750000" />
<workItem from="1713469457285" duration="6504000" /> <workItem from="1713469457285" duration="6588000" />
<workItem from="1713609379678" duration="6626000" />
</task> </task>
<task id="LOCAL-00001" summary="Structure"> <task id="LOCAL-00001" summary="Structure">
<created>1692008860369</created> <created>1692008860369</created>

2
Cargo.lock generated
View File

@ -1456,7 +1456,7 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]] [[package]]
name = "playlistd" name = "playlistd"
version = "0.1.0" version = "0.2.2"
dependencies = [ dependencies = [
"chrono", "chrono",
"config", "config",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "playlistd" name = "playlistd"
version = "0.1.0" version = "0.2.2"
edition = "2021" edition = "2021"
authors = ["Jude Southworth (judesouthworth@pm.me)"] authors = ["Jude Southworth (judesouthworth@pm.me)"]
license = "AGPL-3.0 only" license = "AGPL-3.0 only"
@ -24,10 +24,12 @@ chrono = "0.4.38"
depends = "$auto" depends = "$auto"
assets = [ assets = [
["target/release/playlistd", "usr/bin/playlistd", "755"], ["target/release/playlistd", "usr/bin/playlistd", "755"],
["etc/playlistd.toml", "etc/playlistd.toml", "600"], ["etc/playlistd/playlistd.toml", "etc/playlistd/playlistd.toml", "600"],
["etc/playlistd/Rocket.toml", "etc/playlistd/Rocket.toml", "600"],
] ]
conf-files = [ conf-files = [
"/etc/playlistd.toml", "/etc/playlistd/playlistd.toml",
"/etc/playlistd/Rocket.toml",
] ]
[package.metadata.deb.systemd-units] [package.metadata.deb.systemd-units]

View File

@ -0,0 +1,3 @@
[default]
# port = 0
# address = "localhost"

View File

@ -2,11 +2,9 @@ use crate::models::CreateTrackedPlaylist;
use crate::subsonic::Subsonic; use crate::subsonic::Subsonic;
use crate::CONFIG; use crate::CONFIG;
use chrono::Local; use chrono::Local;
use log::error;
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
use thiserror::Error;
use tokio::time::{interval, MissedTickBehavior}; use tokio::time::{interval, MissedTickBehavior};
use uuid::Uuid; use uuid::Uuid;

View File

@ -6,7 +6,9 @@ mod subsonic;
mod track; mod track;
use crate::daemon::{create_playlists_daemon, update_playlists_daemon}; use crate::daemon::{create_playlists_daemon, update_playlists_daemon};
use crate::models::{PartialTrackedPlaylist, TrackedPlaylist}; use crate::models::{
CreateTrackedPlaylist, PartialCreateTrackedPlaylist, PartialTrackedPlaylist, TrackedPlaylist,
};
use crate::subsonic::{Subsonic, SubsonicBuilder}; use crate::subsonic::{Subsonic, SubsonicBuilder};
use config::Config; use config::Config;
use rocket::serde::json::{json, Json}; use rocket::serde::json::{json, Json};
@ -24,7 +26,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
CONFIG CONFIG
.set( .set(
Config::builder() Config::builder()
.add_source(config::File::with_name("/etc/playlistd").required(false)) .add_source(config::File::with_name("playlistd").required(false))
.add_source(config::Environment::default().separator("_")) .add_source(config::Environment::default().separator("_"))
.build() .build()
.unwrap(), .unwrap(),
@ -71,6 +73,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
create_tracking_playlist, create_tracking_playlist,
add_tracking_playlist, add_tracking_playlist,
all_playlists, all_playlists,
create_tracking_playlist_rule,
], ],
) )
.launch() .launch()
@ -114,6 +117,18 @@ pub struct CreatePlaylist {
pub tracking_type: Option<String>, pub tracking_type: Option<String>,
} }
/// Create a new playlist and attach a tracker
#[post("/rule", data = "<create_playlist_rule>")]
async fn create_tracking_playlist_rule(
pool: &State<PgPool>,
create_playlist_rule: Json<PartialCreateTrackedPlaylist>,
) -> Json<Response<CreateTrackedPlaylist>> {
match create_playlist_rule.record(pool.inner()).await {
Ok(playlist) => Json(Response::Success(playlist)),
Err(e) => Json(Response::Error(e.into())),
}
}
/// Create a new playlist and attach a tracker /// Create a new playlist and attach a tracker
#[post("/create", data = "<create_playlist>")] #[post("/create", data = "<create_playlist>")]
async fn create_tracking_playlist( async fn create_tracking_playlist(

View File

@ -68,6 +68,40 @@ impl TrackedPlaylist {
} }
} }
#[derive(Deserialize)]
pub struct PartialCreateTrackedPlaylist {
pub name_template: String,
pub playlist_size: i32,
pub tracking_user: Option<String>,
pub tracking_type: Option<String>,
}
impl PartialCreateTrackedPlaylist {
pub async fn record(
&self,
pool: impl Executor<'_, Database = Postgres> + Copy,
) -> Result<CreateTrackedPlaylist, Error> {
let uuid = Uuid::new_v4();
sqlx::query!(
r#"
INSERT INTO "create_tracked_playlist"
(id, name_template, playlist_size, tracking_user, tracking_type)
VALUES ($1, $2, $3, $4, $5)
"#,
uuid,
self.name_template,
self.playlist_size,
self.tracking_user,
self.tracking_type,
)
.execute(pool)
.await?;
CreateTrackedPlaylist::rule(pool, uuid).await
}
}
#[derive(Serialize)] #[derive(Serialize)]
pub struct CreateTrackedPlaylist { pub struct CreateTrackedPlaylist {
pub id: Uuid, pub id: Uuid,

View File

@ -4,7 +4,7 @@ Description=Playlistd
[Service] [Service]
Type=simple Type=simple
ExecStart=/usr/bin/playlistd ExecStart=/usr/bin/playlistd
WorkingDirectory=/etc/ WorkingDirectory=/etc/playlistd
Restart=always Restart=always
RestartSec=20 RestartSec=20