recycleactor commited on
Commit
e684487
·
verified ·
1 Parent(s): 3c6742e

Upload main.rs

Browse files
Files changed (1) hide show
  1. src/main.rs +56 -5
src/main.rs CHANGED
@@ -297,6 +297,27 @@ async fn fetch_media_url(
297
  ))
298
  }
299
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  async fn media_url_for_track(
301
  client: &mut APIClient,
302
  id: u64,
@@ -399,9 +420,26 @@ async fn media_url_for_track(
399
  }
400
 
401
  fn upstream_bases() -> Vec<String> {
402
- Vec::new()
403
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
 
 
 
405
  fn upstream_get_url_endpoint(base: &str) -> String {
406
  let b = base.trim_end_matches('/');
407
  if b.ends_with("/get_url") {
@@ -410,6 +448,7 @@ fn upstream_get_url_endpoint(base: &str) -> String {
410
  format!("{b}/get_url")
411
  }
412
  }
 
413
 
414
  async fn upstream_get_url_text(formats: &Vec<Format>, ids: &Vec<u64>) -> Result<String, String> {
415
  let bases = upstream_bases();
@@ -678,8 +717,14 @@ async fn stream_info(State(state): State<AppState>, Query(q): Query<StreamParams
678
  let mut used: String = String::new();
679
  let mut last_err: Option<String> = None;
680
 
 
 
 
 
 
 
681
  // Upstream (опционально — если DZMEDIA_UPSTREAM задан)
682
- if let Ok(text) = upstream_get_url_text(&formats, &vec![q.id]).await {
683
  if let Ok(v) = serde_json::from_str::<serde_json::Value>(&text) {
684
  let format_strings: Vec<String> = formats.iter().map(|f| format!("{:?}", f)).collect();
685
  let format_strs: Vec<&str> = format_strings.iter().map(|s| s.as_str()).collect();
@@ -782,7 +827,6 @@ async fn stream(
782
  .filter(|s| !s.is_empty());
783
 
784
  let mut url: Option<String> = None;
785
- let mut decrypt_id = q.id;
786
  let mut last_err: Option<String> = None;
787
 
788
  if arl_key.is_none() {
@@ -790,6 +834,13 @@ async fn stream(
790
  return (StatusCode::SERVICE_UNAVAILABLE, "arl required").into_response();
791
  }
792
 
 
 
 
 
 
 
 
793
  for attempt in 0..2u8 {
794
  if url.is_some() { break; }
795
 
@@ -810,7 +861,7 @@ async fn stream(
810
  continue;
811
  }
812
  }
813
- match timeout(Duration::from_secs(12), media_url_for_track(&mut c, q.id, &formats)).await {
814
  Ok(v) => v,
815
  Err(_) => Err("timeout".to_string()),
816
  }
 
297
  ))
298
  }
299
 
300
+ async fn resolve_fallback_id(client: &mut APIClient, id: u64) -> u64 {
301
+ if client.license_token.is_empty() {
302
+ let _ = client.force_renew().await;
303
+ }
304
+ let q_json = serde_json::json!({"sng_ids":[id],"array_default":["SNG_ID","FALLBACK"]});
305
+ if let Ok(r) = client.api_call::<serde_json::Value, serde_json::Value>("song.getListData", &q_json).await {
306
+ if let Some(item) = r.pointer("/data/0") {
307
+ if let Some(fallback) = item.get("FALLBACK") {
308
+ if let Some(fid) = fallback.get("SNG_ID").and_then(|v| {
309
+ if let Some(s) = v.as_str() { s.parse::<u64>().ok() }
310
+ else if let Some(n) = v.as_u64() { Some(n) }
311
+ else { None }
312
+ }) {
313
+ if fid > 0 { return fid; }
314
+ }
315
+ }
316
+ }
317
+ }
318
+ id
319
+ }
320
+
321
  async fn media_url_for_track(
322
  client: &mut APIClient,
323
  id: u64,
 
420
  }
421
 
422
  fn upstream_bases() -> Vec<String> {
423
+ let mut out: Vec<String> = Vec::new();
424
+
425
+ let env = std::env::var("DZMEDIA_UPSTREAM").ok().unwrap_or_default();
426
+ let env = env.trim();
427
+ if env == "-" {
428
+ return out;
429
+ }
430
+
431
+ if !env.is_empty() {
432
+ for part in env.split(',') {
433
+ let s = part.trim();
434
+ if s.is_empty() {
435
+ continue;
436
+ }
437
+ out.push(s.trim_end_matches('/').to_string());
438
+ }
439
+ }
440
 
441
+ out
442
+ }
443
  fn upstream_get_url_endpoint(base: &str) -> String {
444
  let b = base.trim_end_matches('/');
445
  if b.ends_with("/get_url") {
 
448
  format!("{b}/get_url")
449
  }
450
  }
451
+ }
452
 
453
  async fn upstream_get_url_text(formats: &Vec<Format>, ids: &Vec<u64>) -> Result<String, String> {
454
  let bases = upstream_bases();
 
717
  let mut used: String = String::new();
718
  let mut last_err: Option<String> = None;
719
 
720
+ let client = api_client_for_arl(&state, q.arl.clone()).await;
721
+ let target_id = {
722
+ let mut c = client.lock().await;
723
+ resolve_fallback_id(&mut c, q.id).await
724
+ };
725
+
726
  // Upstream (опционально — если DZMEDIA_UPSTREAM задан)
727
+ if let Ok(text) = upstream_get_url_text(&formats, &vec![target_id]).await {
728
  if let Ok(v) = serde_json::from_str::<serde_json::Value>(&text) {
729
  let format_strings: Vec<String> = formats.iter().map(|f| format!("{:?}", f)).collect();
730
  let format_strs: Vec<&str> = format_strings.iter().map(|s| s.as_str()).collect();
 
827
  .filter(|s| !s.is_empty());
828
 
829
  let mut url: Option<String> = None;
 
830
  let mut last_err: Option<String> = None;
831
 
832
  if arl_key.is_none() {
 
834
  return (StatusCode::SERVICE_UNAVAILABLE, "arl required").into_response();
835
  }
836
 
837
+ let client = api_client_for_arl(&state, arl_key.clone()).await;
838
+ let target_id = {
839
+ let mut c = client.lock().await;
840
+ resolve_fallback_id(&mut c, q.id).await
841
+ };
842
+ let mut decrypt_id = target_id;
843
+
844
  for attempt in 0..2u8 {
845
  if url.is_some() { break; }
846
 
 
861
  continue;
862
  }
863
  }
864
+ match timeout(Duration::from_secs(12), media_url_for_track(&mut c, target_id, &formats)).await {
865
  Ok(v) => v,
866
  Err(_) => Err("timeout".to_string()),
867
  }