recycleactor commited on
Commit
ce63977
·
verified ·
1 Parent(s): 3ad29b0

Upload soundcloud.rs

Browse files
Files changed (1) hide show
  1. src/soundcloud.rs +28 -20
src/soundcloud.rs CHANGED
@@ -46,19 +46,21 @@ pub struct User {
46
 
47
  /// /soundcloud/search - поиск треков на SoundCloud через yt-dlp
48
  pub async fn search(Query(params): Query<SearchParams>) -> impl IntoResponse {
49
- tracing::info!("SoundCloud search: {}", params.q);
50
 
51
  // Используем yt-dlp для поиска на SoundCloud
 
 
 
52
  let output = match Command::new("yt-dlp")
53
  .args([
54
  "--quiet",
55
  "--no-warnings",
56
  "--print", "%(id)s|||%(title)s|||%(uploader)s|||%(duration)s|||%(webpage_url)s",
57
- "--default-search", "scsearch",
58
- &format!("scsearch{}:{}", params.limit, params.q),
59
  ])
60
  .stdout(Stdio::piped())
61
- .stderr(Stdio::null())
62
  .output()
63
  .await
64
  {
@@ -67,42 +69,48 @@ pub async fn search(Query(params): Query<SearchParams>) -> impl IntoResponse {
67
  tracing::error!("yt-dlp search failed: {}", e);
68
  return (
69
  StatusCode::INTERNAL_SERVER_ERROR,
70
- Json(json!({ "error": "Search failed" })),
71
  ).into_response();
72
  }
73
  };
74
 
75
  if !output.status.success() {
76
- tracing::error!("yt-dlp search exit: {}", output.status);
 
77
  return (
78
  StatusCode::INTERNAL_SERVER_ERROR,
79
- Json(json!({ "error": "Search failed" })),
80
  ).into_response();
81
  }
82
 
83
  let stdout = String::from_utf8_lossy(&output.stdout);
 
 
84
  let mut tracks = Vec::new();
85
 
86
- for line in stdout.lines() {
87
  let parts: Vec<&str> = line.split("|||").collect();
88
  if parts.len() >= 5 {
 
 
 
 
89
  if let Ok(duration) = parts[3].parse::<u64>() {
90
- if let Ok(id) = parts[0].parse::<u64>() {
91
- tracks.push(Track {
92
- id,
93
- title: parts[1].to_string(),
94
- permalink: parts[0].to_string(),
95
- permalink_url: parts[4].to_string(),
96
- duration: duration * 1000, // в миллисекундах для совместимости
97
- user: User {
98
- username: parts[2].to_string(),
99
- },
100
- });
101
- }
102
  }
103
  }
104
  }
105
 
 
106
  (StatusCode::OK, Json(json!({ "tracks": tracks }))).into_response()
107
  }
108
 
 
46
 
47
  /// /soundcloud/search - поиск треков на SoundCloud через yt-dlp
48
  pub async fn search(Query(params): Query<SearchParams>) -> impl IntoResponse {
49
+ tracing::info!("SoundCloud search: q='{}' limit={}", params.q, params.limit);
50
 
51
  // Используем yt-dlp для поиска на SoundCloud
52
+ // Формат: scsearch5:query означает "искать на SoundCloud 5 результатов по запросу query"
53
+ let search_query = format!("scsearch{}:{}", params.limit, params.q);
54
+
55
  let output = match Command::new("yt-dlp")
56
  .args([
57
  "--quiet",
58
  "--no-warnings",
59
  "--print", "%(id)s|||%(title)s|||%(uploader)s|||%(duration)s|||%(webpage_url)s",
60
+ &search_query,
 
61
  ])
62
  .stdout(Stdio::piped())
63
+ .stderr(Stdio::piped())
64
  .output()
65
  .await
66
  {
 
69
  tracing::error!("yt-dlp search failed: {}", e);
70
  return (
71
  StatusCode::INTERNAL_SERVER_ERROR,
72
+ Json(json!({ "error": format!("Search failed: {}", e) })),
73
  ).into_response();
74
  }
75
  };
76
 
77
  if !output.status.success() {
78
+ let stderr = String::from_utf8_lossy(&output.stderr);
79
+ tracing::error!("yt-dlp search exit: {} stderr: {}", output.status, stderr);
80
  return (
81
  StatusCode::INTERNAL_SERVER_ERROR,
82
+ Json(json!({ "error": format!("Search failed: exit {}", output.status) })),
83
  ).into_response();
84
  }
85
 
86
  let stdout = String::from_utf8_lossy(&output.stdout);
87
+ tracing::info!("yt-dlp output: {} lines", stdout.lines().count());
88
+
89
  let mut tracks = Vec::new();
90
 
91
+ for (idx, line) in stdout.lines().enumerate() {
92
  let parts: Vec<&str> = line.split("|||").collect();
93
  if parts.len() >= 5 {
94
+ // ID может быть числом или строкой, используем строку как permalink
95
+ let id_str = parts[0];
96
+ let id_num = id_str.parse::<u64>().unwrap_or(idx as u64);
97
+
98
  if let Ok(duration) = parts[3].parse::<u64>() {
99
+ tracks.push(Track {
100
+ id: id_num,
101
+ title: parts[1].to_string(),
102
+ permalink: id_str.to_string(),
103
+ permalink_url: parts[4].to_string(),
104
+ duration: duration * 1000, // в миллисекундах для совместимости
105
+ user: User {
106
+ username: parts[2].to_string(),
107
+ },
108
+ });
 
 
109
  }
110
  }
111
  }
112
 
113
+ tracing::info!("Found {} tracks", tracks.len());
114
  (StatusCode::OK, Json(json!({ "tracks": tracks }))).into_response()
115
  }
116