diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..fc88e23 --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +#PLAYER_BUS="org.mpris.MediaPlayer2.mpv" +USERNAME="ILoveLastDotFm" +PASSWORD="lastfm4lyfe" +API_KEY="t8mb4e0kn9it150amaeezbcfe3iusy8o" +API_SECRET="jd47iz6h1u2kbnbfm8c763lzrj1o89h3" diff --git a/Cargo.lock b/Cargo.lock index 64556b2..03b5af1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,25 +136,10 @@ dependencies = [ ] [[package]] -name = "dirs" -version = "5.0.1" +name = "dotenvy" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "enum-kinds" @@ -167,6 +152,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "envconfig" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea81cc7e21f55a9d9b1efb6816904978d0bfbe31a50347cb24b2e75564bcac9b" +dependencies = [ + "envconfig_derive", +] + +[[package]] +name = "envconfig_derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfca278e5f84b45519acaaff758ebfa01f18e96998bc24b8f1b722dd804b9bf" +dependencies = [ + "proc-macro2", + "quote 1.0.36", + "syn 1.0.109", +] + [[package]] name = "errno" version = "0.3.9" @@ -174,7 +179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -244,17 +249,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "heck" version = "0.3.3" @@ -302,11 +296,10 @@ name = "lastfmpris" version = "0.1.0" dependencies = [ "anyhow", - "dirs", + "dotenvy", + "envconfig", "mpris", "rustfm-scrobble-proxy", - "serde", - "serde_ini", "tracing", "tracing-subscriber", ] @@ -332,16 +325,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags", - "libc", -] - [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -465,12 +448,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - [[package]] name = "overload" version = "0.1.1" @@ -519,23 +496,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "result" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194d8e591e405d1eecf28819740abed6d719d1a2db87fc0bcdedee9a26d55560" - [[package]] name = "rustfm-scrobble-proxy" version = "2.0.0" @@ -559,7 +519,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -574,7 +534,7 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -602,35 +562,24 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.209" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote 1.0.36", "syn 2.0.72", ] -[[package]] -name = "serde_ini" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb236687e2bb073a7521c021949be944641e671b8505a94069ca37b656c81139" -dependencies = [ - "result", - "serde", - "void", -] - [[package]] name = "serde_json" version = "1.0.122" @@ -728,7 +677,7 @@ dependencies = [ "fastrand", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -889,18 +838,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - [[package]] name = "winapi" version = "0.3.9" @@ -923,37 +860,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -962,46 +875,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1014,48 +909,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" diff --git a/Cargo.toml b/Cargo.toml index 02f6db4..d8ca9f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,9 @@ edition = "2021" [dependencies] anyhow = "1.0.86" -dirs = "5.0.1" +dotenvy = "0.15.7" +envconfig = "0.10.0" mpris = "2.0.1" rustfm-scrobble-proxy = "2.0.0" -serde = "1.0.209" -serde_ini = "0.2.0" tracing = "0.1.40" tracing-subscriber = "0.3.18" diff --git a/README.md b/README.md index da0e424..c48b96c 100644 --- a/README.md +++ b/README.md @@ -6,52 +6,34 @@ a rust application to scrobble your currently playing song on last.fm with mpris unfortunately, because of how most mpris players work, the [Track_Id](https://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html#Simple-Type:Track_Id) (unique identifier for every song in the tracklist) object is very rarely supported, or, if supported, implemented incorrectly (looking at you, [Cider](https://cider.sh/)) meaning it is impossible to tell if the track has been played twice in a row. this means you cannot have succssive scrobbles of the same song, sorry! besides this, i'd say the program is feature complete. -also you can't configure the program through nix yet because i'm lazy, i'll do that sometime!! - ## configuration -either run the program once and navigate to `.config/lastmpris/config.ini` or create the file and copy it from the `config.example.ini` file provided in this directory. once you do that, configure your authentication methods. the api keys are available [here](https://www.last.fm/login?next=/api/account/create) +copy the values from `.env.example` into a `.env` file and configure your api keys, and the api keys are available [here](https://www.last.fm/login?next=/api/account/create) you also have the option to define your mpris bus name, which will instead wait for your specified player instead of waiting for the first active player ## how to install -you have two methods of installation +*if you're on a setup that uses nix, you can just use `nix build` or the provided devshell to build the application.* -1. install with cargo + your package manager of choice - - 1. obtain dependencies (this will vary on your package manager) - ```sh - sudo apk add install pkgconf openssl dbus - ``` - 2. run/build - ```sh - cargo build --release - ``` -2. install using nix +first, clone repository: - simply run it with nix: +```sh +git clone https://git.reidlab.pink/reidlab/lastfmpris && cd lastfmpris +``` - ```sh - nix run git+https://git.reidlab.pink/reidlab/lastfmpris - ``` +second, obtain dependencies (this will vary on your package manager, here, alpine is used) - or put it into your flake as such: +```sh +sudo apk add install pkgconf openssl dbus +``` - ```nix - # add this into your flake inputs: - lastfmpris.url = "git+https://git.reidlab.pink/reidlab/lastfmpris"; - # add this to your `homeConfiguration`: - imports = [ - inputs.lastfmpris.nixosModules.lastfmpris - ]; - ``` +finally, run/build - and then just add this to use it as a home-manager option: - - ```nix - # add this to your home-manager configuration: - services.lastfmpris = { - enable = true; - } - ``` \ No newline at end of file +```sh +cargo run +``` + +```sh +cargo build --release +``` \ No newline at end of file diff --git a/config.example.ini b/config.example.ini deleted file mode 100644 index d262c6c..0000000 --- a/config.example.ini +++ /dev/null @@ -1,5 +0,0 @@ -; player_bus = org.mpris.MediaPlayer2.mpv -username = ILoveLastDotFm -password = lastfm4lyfe -api_key = t8mb4e0kn9it150amaeezbcfe3iusy8o -api_secret = jd47iz6h1u2kbnbfm8c763lzrj1o89h3 diff --git a/flake.nix b/flake.nix index 2d8268f..d7eaf09 100644 --- a/flake.nix +++ b/flake.nix @@ -30,7 +30,7 @@ # uncomment this and let the build fail, then get the current hash # very scuffed but endorsed! #cargoSha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; - cargoSha256 = "sha256-KOMEvg3iGjmMEFxsrIqD4SaDw63ojiNNNqCfzRlbYLw="; + cargoSha256 = "sha256-2bDHxZc5Zg7jmA8BenSbTF3fBJEB7QDEVBQLkI8qyRc="; buildInputs = with pkgs; [ pkg-config ]; @@ -54,37 +54,5 @@ RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library"; }; - }) // { - homeManagerModules = { - lastfmpris = { config, lib, pkgs, ... }: - with lib; - let - cfg = config.services.lastfmpris; - in { - options.services.lastfmpris = { - enable = mkEnableOption "enables the lastmpris scrobbler"; - - package = mkOption { - type = types.package; - default = self.defaultPackage.${pkgs.system}; - }; - }; - - config = mkIf cfg.enable { - home.packages = [ cfg.package ]; - systemd.user.services.lastfmpris = { - Unit = { - Description = "Lastfmpris scrobbling daemon"; - After = [ "graphical-session-pre.target" ]; - }; - Service = { - Type = "Simple"; - ExecStart = "${lib.getExe cfg.package}"; - Restart = "on-failure"; - }; - }; - }; - }; - }; - }; + }); } diff --git a/src/config.rs b/src/config.rs index c056979..1af799b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,55 +1,19 @@ -use anyhow::{Context, Result}; -use serde::Deserialize; -use std::fs; -use std::fs::{create_dir_all, OpenOptions}; -use std::io::Write; -use std::process; -use tracing::info; +use envconfig::Envconfig; -#[derive(Deserialize)] +#[derive(Envconfig)] pub struct Config { + #[envconfig(from = "PLAYER_BUS")] pub player_bus: Option, + + #[envconfig(from = "USERNAME")] pub username: String, + + #[envconfig(from = "PASSWORD")] pub password: String, + + #[envconfig(from = "API_KEY")] pub api_key: String, + + #[envconfig(from = "API_SECRET")] pub api_secret: String -} - -pub fn load_config() -> Result { - let path = dirs::config_dir() - .context("failed to get config directory")? - .join("lastfmpris") - .join("config.ini"); - - // create file if it doesnt exist and exit - if !path.exists() { - info!("configuration file doesn't exist, creating boilerplate"); - - // create underline paths and files - if let Some(parent) = path.parent() { - create_dir_all(parent) - .context("failed to create config file folder(s)")?; - } - let mut file = OpenOptions::new() - .write(true) - .create(true) - .open(&path) - .context("failed to create config file")?; - - // write into the config file with the example configuration - // we put inside the base working directory for the project - file.write_all(include_str!("../config.example.ini").as_bytes()) - .context("failed to write boilerplate config")?; - - info!("configuration boilerplate generation completed: see file: {}", path.display()); - // success, exit - process::exit(0) - } - - let content = fs::read_to_string(path) - .context("failed to read config content")?; - let config: Config = serde_ini::from_str(&content) - .context("failed to deserialize ini into a readable format")?; - - Ok(config) } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 033f331..6df96f8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,11 +6,14 @@ mod main_loop; mod player; mod track; +use crate::config::Config; use crate::lastfm::get_scrobbler; use anyhow::{Context, Result}; +use envconfig::Envconfig; use tracing::{debug, Level}; fn main() -> Result<()> { + dotenvy::dotenv()?; tracing_subscriber::fmt() .with_max_level(if cfg!(debug_assertions) { Level::DEBUG } else { Level::INFO }) .init(); @@ -21,8 +24,8 @@ fn main() -> Result<()> { env!("CARGO_PKG_DESCRIPTION") ); - let config = config::load_config() - .context("failed to initiate configuration object!")?; + let config = Config::init_from_env() + .context("failed to initiate configuration from .env")?; let scrobbler = get_scrobbler(&config) .context("failed to create scrobbler")?;