Spaces:
Paused
Paused
Upload main.rs
Browse files- src/main.rs +1 -56
src/main.rs
CHANGED
|
@@ -1250,7 +1250,6 @@ async fn pair_page(Query(q): Query<PairPageQuery>) -> impl IntoResponse {
|
|
| 1250 |
.box{{max-width:420px;margin:0 auto;background:#151515;padding:18px;border-radius:12px}}\
|
| 1251 |
input{{width:100%;padding:12px 14px;margin:10px 0;border-radius:10px;border:1px solid #333;background:#0f0f0f;color:#fff;font-size:16px}}\
|
| 1252 |
button{{width:100%;padding:12px 14px;border-radius:10px;border:0;background:#1db954;color:#000;font-weight:700;font-size:16px}}\
|
| 1253 |
-
.secondary{{background:#2b2b2b;color:#fff}}\
|
| 1254 |
.muted{{color:#aaa;font-size:13px;line-height:1.35}}</style>\
|
| 1255 |
</head><body><div class=\"box\">\
|
| 1256 |
<h2 style=\"margin:0 0 6px\">Вход Deezer</h2>\
|
|
@@ -1262,14 +1261,6 @@ async fn pair_page(Query(q): Query<PairPageQuery>) -> impl IntoResponse {
|
|
| 1262 |
<button type=\"submit\">Войти</button>\
|
| 1263 |
</form>\
|
| 1264 |
<p class=\"muted\" style=\"margin:12px 0 0\">Пароль используется только для получения токена доступа и не сохраняется.</p>\
|
| 1265 |
-
<hr style=\"border:0;border-top:1px solid #2a2a2a;margin:16px 0\">\
|
| 1266 |
-
<h3 style=\"margin:0 0 6px;font-size:16px\">ARL (для полного аудио)</h3>\
|
| 1267 |
-
<div class=\"muted\">Если сервер не может автоматически получить ARL (ошибка 503/502), вставь ARL сюда — с телефона это быстрее, чем на ТВ.</div>\
|
| 1268 |
-
<form method=\"POST\" action=\"/pair/arl\">\
|
| 1269 |
-
<input type=\"hidden\" name=\"code\" value=\"{safe_code}\">\
|
| 1270 |
-
<input name=\"arl\" type=\"text\" placeholder=\"arl=...\" autocomplete=\"off\">\
|
| 1271 |
-
<button class=\"secondary\" type=\"submit\">Отправить ARL</button>\
|
| 1272 |
-
</form>\
|
| 1273 |
</div></body></html>"
|
| 1274 |
);
|
| 1275 |
Html(html)
|
|
@@ -1282,12 +1273,6 @@ struct PairCompleteForm {
|
|
| 1282 |
password: String,
|
| 1283 |
}
|
| 1284 |
|
| 1285 |
-
#[derive(Deserialize)]
|
| 1286 |
-
struct PairArlForm {
|
| 1287 |
-
code: String,
|
| 1288 |
-
arl: String,
|
| 1289 |
-
}
|
| 1290 |
-
|
| 1291 |
fn htmlesc(s: &str) -> String {
|
| 1292 |
s.replace('&', "&")
|
| 1293 |
.replace('<', "<")
|
|
@@ -1296,27 +1281,6 @@ fn htmlesc(s: &str) -> String {
|
|
| 1296 |
.replace('\'', "'")
|
| 1297 |
}
|
| 1298 |
|
| 1299 |
-
async fn pair_arl(State(state): State<AppState>, Form(f): Form<PairArlForm>) -> impl IntoResponse {
|
| 1300 |
-
let code = f.code.trim().to_string();
|
| 1301 |
-
let arl = f.arl.trim().to_string();
|
| 1302 |
-
if code.is_empty() {
|
| 1303 |
-
return Html("<h3>Нужен code</h3>".to_string()).into_response();
|
| 1304 |
-
}
|
| 1305 |
-
if arl.len() < 20 {
|
| 1306 |
-
return Html("<h3>ARL выглядит неверно</h3>".to_string()).into_response();
|
| 1307 |
-
}
|
| 1308 |
-
|
| 1309 |
-
let mut map = state.pair.write().await;
|
| 1310 |
-
let Some(sess) = map.get_mut(&code) else {
|
| 1311 |
-
return Html("<h3>Код не найден или истёк</h3>".to_string()).into_response();
|
| 1312 |
-
};
|
| 1313 |
-
sess.arl = Some(arl);
|
| 1314 |
-
sess.error = None;
|
| 1315 |
-
|
| 1316 |
-
Html("<h3>ARL сохранён</h3><p>Вернись на ТВ — треки должны стать полными.</p>".to_string())
|
| 1317 |
-
.into_response()
|
| 1318 |
-
}
|
| 1319 |
-
|
| 1320 |
async fn api_deezer_get(
|
| 1321 |
client: &reqwest::Client,
|
| 1322 |
path: &str,
|
|
@@ -1435,25 +1399,7 @@ async fn pair_complete(State(state): State<AppState>, Form(f): Form<PairComplete
|
|
| 1435 |
}
|
| 1436 |
}
|
| 1437 |
|
| 1438 |
-
|
| 1439 |
-
let sess_arl = map.get(&code).and_then(|s| s.arl.clone()).unwrap_or_default();
|
| 1440 |
-
if sess_arl.len() > 20 {
|
| 1441 |
-
return Html("<h3>Готово</h3><p>Вернись на ТВ — плагин подключится автоматически.</p>".to_string())
|
| 1442 |
-
.into_response();
|
| 1443 |
-
}
|
| 1444 |
-
|
| 1445 |
-
let safe_code = htmlesc(&code);
|
| 1446 |
-
Html(format!(
|
| 1447 |
-
"<h3>Вход выполнен</h3>\
|
| 1448 |
-
<p>Токен получен, но ARL сервер автоматически не вытащил (из‑за блокировки/ошибок на хостинге).</p>\
|
| 1449 |
-
<p>Чтобы включить полные треки, вставь ARL (с телефона):</p>\
|
| 1450 |
-
<form method=\"POST\" action=\"/pair/arl\">\
|
| 1451 |
-
<input type=\"hidden\" name=\"code\" value=\"{safe_code}\">\
|
| 1452 |
-
<input name=\"arl\" type=\"text\" placeholder=\"arl=...\" autocomplete=\"off\" style=\"width:100%;padding:12px 14px;border-radius:10px;border:1px solid #333;background:#0f0f0f;color:#fff;font-size:16px\">\
|
| 1453 |
-
<button type=\"submit\" style=\"margin-top:10px;width:100%;padding:12px 14px;border-radius:10px;border:0;background:#2b2b2b;color:#fff;font-weight:700;font-size:16px\">Отправить ARL</button>\
|
| 1454 |
-
</form>"
|
| 1455 |
-
))
|
| 1456 |
-
.into_response()
|
| 1457 |
}
|
| 1458 |
|
| 1459 |
#[derive(Debug, Deserialize)]
|
|
@@ -1715,7 +1661,6 @@ async fn main() {
|
|
| 1715 |
.route("/pair/status", get(pair_status))
|
| 1716 |
.route("/pair", get(pair_page))
|
| 1717 |
.route("/pair/complete", post(pair_complete))
|
| 1718 |
-
.route("/pair/arl", post(pair_arl))
|
| 1719 |
.route("/oauth/me", post(oauth_me))
|
| 1720 |
.route("/oauth/playlists", post(oauth_playlists))
|
| 1721 |
.route("/oauth/playlist_tracks", post(oauth_playlist_tracks))
|
|
|
|
| 1250 |
.box{{max-width:420px;margin:0 auto;background:#151515;padding:18px;border-radius:12px}}\
|
| 1251 |
input{{width:100%;padding:12px 14px;margin:10px 0;border-radius:10px;border:1px solid #333;background:#0f0f0f;color:#fff;font-size:16px}}\
|
| 1252 |
button{{width:100%;padding:12px 14px;border-radius:10px;border:0;background:#1db954;color:#000;font-weight:700;font-size:16px}}\
|
|
|
|
| 1253 |
.muted{{color:#aaa;font-size:13px;line-height:1.35}}</style>\
|
| 1254 |
</head><body><div class=\"box\">\
|
| 1255 |
<h2 style=\"margin:0 0 6px\">Вход Deezer</h2>\
|
|
|
|
| 1261 |
<button type=\"submit\">Войти</button>\
|
| 1262 |
</form>\
|
| 1263 |
<p class=\"muted\" style=\"margin:12px 0 0\">Пароль используется только для получения токена доступа и не сохраняется.</p>\
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1264 |
</div></body></html>"
|
| 1265 |
);
|
| 1266 |
Html(html)
|
|
|
|
| 1273 |
password: String,
|
| 1274 |
}
|
| 1275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1276 |
fn htmlesc(s: &str) -> String {
|
| 1277 |
s.replace('&', "&")
|
| 1278 |
.replace('<', "<")
|
|
|
|
| 1281 |
.replace('\'', "'")
|
| 1282 |
}
|
| 1283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1284 |
async fn api_deezer_get(
|
| 1285 |
client: &reqwest::Client,
|
| 1286 |
path: &str,
|
|
|
|
| 1399 |
}
|
| 1400 |
}
|
| 1401 |
|
| 1402 |
+
Html("<h3>Готово</h3><p>Вернись на ТВ — плагин подключится автоматически.</p>".to_string()).into_response()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1403 |
}
|
| 1404 |
|
| 1405 |
#[derive(Debug, Deserialize)]
|
|
|
|
| 1661 |
.route("/pair/status", get(pair_status))
|
| 1662 |
.route("/pair", get(pair_page))
|
| 1663 |
.route("/pair/complete", post(pair_complete))
|
|
|
|
| 1664 |
.route("/oauth/me", post(oauth_me))
|
| 1665 |
.route("/oauth/playlists", post(oauth_playlists))
|
| 1666 |
.route("/oauth/playlist_tracks", post(oauth_playlist_tracks))
|