char-slop/tidal-dl
tidal ripper
git clone https://git.t4t.associates/char-slop/tidal-dl
3841d9b
main
1# [ derive ( Debug , Clone , Copy , PartialEq , Eq )] 2pub enum AuthMethod { 3Device , 4Pkce , 5} 6 7# [ derive ( Debug , Clone )] 8pub struct ApiKey { 9pub name : String , 10pub client_id : String , 11pub client_secret : String , 12pub auth_method : AuthMethod , 13pub scope : String , 14pub redirect_uri : String , 15} 16 17const PKCE_CLIENT_ID : & str ="3a5dzbD1VqdaUmqG" ; 18const PKCE_SCOPE : & str ="r_usr w_usr" ; 19const PKCE_REDIRECT_URI : & str ="tidal://login/auth" ; 20 21fn default_scope ( method : AuthMethod ) ->&' static str { 22match method{ 23AuthMethod :: Pkce =>PKCE_SCOPE , 24AuthMethod :: Device =>crate :: tidal:: DEVICE_SCOPE , 25} 26} 27 28fn embedded_key () ->ApiKey { 29ApiKey { 30name : "TIDAL desktop app (public client)" . to_string (), 31client_id : PKCE_CLIENT_ID . to_string (), 32client_secret : String :: new (), 33auth_method : AuthMethod :: Pkce , 34scope : PKCE_SCOPE . to_string (), 35redirect_uri : PKCE_REDIRECT_URI . to_string (), 36} 37} 38 39/// The single client to authenticate with: the embedded PKCE client, with 40/// optional overrides from the environment (see `load_dotenv`). 41pub fn load_key () ->ApiKey { 42load_dotenv (); 43let mut key =embedded_key (); 44if let Ok ( id) = std:: env:: var ( "TIDAL_CLIENT_ID" ) { 45if !id. is_empty () { 46 key. name = std:: env:: var ( "TIDAL_CLIENT_NAME" ) 47. unwrap_or_else ( |_|"Custom (env)" . to_string ()); 48 key. client_id = id; 49 key. auth_method =match std:: env:: var ( "TIDAL_AUTH_METHOD" ) 50. unwrap_or_default () 51. as_str () 52{ 53"device" =>AuthMethod :: Device , 54 _ =>AuthMethod :: Pkce , 55}; 56 key. scope =default_scope ( key. auth_method ). to_string (); 57 key. redirect_uri =PKCE_REDIRECT_URI . to_string (); 58} 59} 60if let Ok ( v) = std:: env:: var ( "TIDAL_CLIENT_SECRET" ) { 61 key. client_secret = v; 62} 63if let Ok ( v) = std:: env:: var ( "TIDAL_SCOPE" ) { 64if !v. is_empty () { 65 key. scope = v; 66} 67} 68if let Ok ( v) = std:: env:: var ( "TIDAL_REDIRECT_URI" ) { 69if !v. is_empty () { 70 key. redirect_uri = v; 71} 72} 73 key 74} 75 76fn load_dotenv () { 77let home = dirs:: home_dir (). unwrap_or_else ( ||"." . into ()); 78let candidates =[ 79 std:: env:: var ( "TIDAL_ENV_FILE" ). ok (), 80Some ( home. join ( ".tidal-dl.env" ). to_string_lossy (). into_owned ()), 81Some ( ".env" . to_string ()), 82]; 83for pathin candidates. into_iter (). flatten () { 84if let Ok ( text) = std:: fs:: read_to_string ( & path) { 85for linein text. lines () { 86let line = line. trim (); 87if line. is_empty () || line. starts_with ( '#' ) || !line. contains ( '=' ) { 88continue ; 89} 90let ( k, v) = line. split_once ( '=' ). unwrap (); 91let k = k. trim (). to_string (); 92let v = v. trim (). trim_matches ( '"' ). trim_matches ( '\'' ). to_string (); 93if !k. is_empty () && std:: env:: var ( & k). is_err () { 94 std:: env:: set_var ( k, v); 95} 96} 97break ; 98} 99} 100}