Spaces:
Paused
Paused
Upload main.rs
Browse files- src/main.rs +159 -0
src/main.rs
CHANGED
|
@@ -1702,6 +1702,160 @@ async fn oauth_flow(Json(req): Json<OauthFlowReq>) -> impl IntoResponse {
|
|
| 1702 |
}
|
| 1703 |
}
|
| 1704 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1705 |
#[tokio::main]
|
| 1706 |
async fn main() {
|
| 1707 |
let bind_addr = std::env::var("BIND_ADDR").unwrap_or("[::]".to_string());
|
|
@@ -1740,6 +1894,11 @@ async fn main() {
|
|
| 1740 |
.route("/oauth/playlist_tracks", post(oauth_playlist_tracks))
|
| 1741 |
.route("/oauth/arl", post(oauth_arl))
|
| 1742 |
.route("/oauth/flow", post(oauth_flow))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1743 |
.with_state(state)
|
| 1744 |
.layer(cors)
|
| 1745 |
.layer(CompressionLayer::new())
|
|
|
|
| 1702 |
}
|
| 1703 |
}
|
| 1704 |
|
| 1705 |
+
#[derive(Debug, Deserialize)]
|
| 1706 |
+
struct OauthRecoReq {
|
| 1707 |
+
access_token: String,
|
| 1708 |
+
index: Option<u32>,
|
| 1709 |
+
limit: Option<u32>,
|
| 1710 |
+
}
|
| 1711 |
+
|
| 1712 |
+
async fn oauth_reco_playlists(Json(req): Json<OauthRecoReq>) -> impl IntoResponse {
|
| 1713 |
+
let token = req.access_token.trim().to_string();
|
| 1714 |
+
if token.is_empty() {
|
| 1715 |
+
return json_error(StatusCode::BAD_REQUEST, "access_token required");
|
| 1716 |
+
}
|
| 1717 |
+
let index = req.index.unwrap_or(0).to_string();
|
| 1718 |
+
let limit = req.limit.unwrap_or(20).clamp(1, 50).to_string();
|
| 1719 |
+
let client = reqwest::Client::builder()
|
| 1720 |
+
.timeout(std::time::Duration::from_secs(15))
|
| 1721 |
+
.build()
|
| 1722 |
+
.unwrap();
|
| 1723 |
+
|
| 1724 |
+
let me = match api_deezer_get(&client, "/user/me", &token, &[]).await {
|
| 1725 |
+
Ok(v) => v,
|
| 1726 |
+
Err(e) => return json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1727 |
+
};
|
| 1728 |
+
let uid = me.get("id").and_then(|x| x.as_i64()).unwrap_or(0);
|
| 1729 |
+
if uid <= 0 {
|
| 1730 |
+
return json_error(StatusCode::SERVICE_UNAVAILABLE, "api:no_user_id");
|
| 1731 |
+
}
|
| 1732 |
+
let path = format!("/user/{uid}/recommendations/playlists");
|
| 1733 |
+
let extra = [("index", index), ("limit", limit)];
|
| 1734 |
+
match api_deezer_get(&client, &path, &token, &extra).await {
|
| 1735 |
+
Ok(v) => (StatusCode::OK, Json(v)).into_response(),
|
| 1736 |
+
Err(e) => json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1737 |
+
}
|
| 1738 |
+
}
|
| 1739 |
+
|
| 1740 |
+
async fn oauth_reco_albums(Json(req): Json<OauthRecoReq>) -> impl IntoResponse {
|
| 1741 |
+
let token = req.access_token.trim().to_string();
|
| 1742 |
+
if token.is_empty() {
|
| 1743 |
+
return json_error(StatusCode::BAD_REQUEST, "access_token required");
|
| 1744 |
+
}
|
| 1745 |
+
let index = req.index.unwrap_or(0).to_string();
|
| 1746 |
+
let limit = req.limit.unwrap_or(20).clamp(1, 50).to_string();
|
| 1747 |
+
let client = reqwest::Client::builder()
|
| 1748 |
+
.timeout(std::time::Duration::from_secs(15))
|
| 1749 |
+
.build()
|
| 1750 |
+
.unwrap();
|
| 1751 |
+
|
| 1752 |
+
let me = match api_deezer_get(&client, "/user/me", &token, &[]).await {
|
| 1753 |
+
Ok(v) => v,
|
| 1754 |
+
Err(e) => return json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1755 |
+
};
|
| 1756 |
+
let uid = me.get("id").and_then(|x| x.as_i64()).unwrap_or(0);
|
| 1757 |
+
if uid <= 0 {
|
| 1758 |
+
return json_error(StatusCode::SERVICE_UNAVAILABLE, "api:no_user_id");
|
| 1759 |
+
}
|
| 1760 |
+
let path = format!("/user/{uid}/recommendations/albums");
|
| 1761 |
+
let extra = [("index", index), ("limit", limit)];
|
| 1762 |
+
match api_deezer_get(&client, &path, &token, &extra).await {
|
| 1763 |
+
Ok(v) => (StatusCode::OK, Json(v)).into_response(),
|
| 1764 |
+
Err(e) => json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1765 |
+
}
|
| 1766 |
+
}
|
| 1767 |
+
|
| 1768 |
+
async fn oauth_reco_artists(Json(req): Json<OauthRecoReq>) -> impl IntoResponse {
|
| 1769 |
+
let token = req.access_token.trim().to_string();
|
| 1770 |
+
if token.is_empty() {
|
| 1771 |
+
return json_error(StatusCode::BAD_REQUEST, "access_token required");
|
| 1772 |
+
}
|
| 1773 |
+
let index = req.index.unwrap_or(0).to_string();
|
| 1774 |
+
let limit = req.limit.unwrap_or(20).clamp(1, 50).to_string();
|
| 1775 |
+
let client = reqwest::Client::builder()
|
| 1776 |
+
.timeout(std::time::Duration::from_secs(15))
|
| 1777 |
+
.build()
|
| 1778 |
+
.unwrap();
|
| 1779 |
+
|
| 1780 |
+
let me = match api_deezer_get(&client, "/user/me", &token, &[]).await {
|
| 1781 |
+
Ok(v) => v,
|
| 1782 |
+
Err(e) => return json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1783 |
+
};
|
| 1784 |
+
let uid = me.get("id").and_then(|x| x.as_i64()).unwrap_or(0);
|
| 1785 |
+
if uid <= 0 {
|
| 1786 |
+
return json_error(StatusCode::SERVICE_UNAVAILABLE, "api:no_user_id");
|
| 1787 |
+
}
|
| 1788 |
+
let path = format!("/user/{uid}/recommendations/artists");
|
| 1789 |
+
let extra = [("index", index), ("limit", limit)];
|
| 1790 |
+
match api_deezer_get(&client, &path, &token, &extra).await {
|
| 1791 |
+
Ok(v) => (StatusCode::OK, Json(v)).into_response(),
|
| 1792 |
+
Err(e) => json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1793 |
+
}
|
| 1794 |
+
}
|
| 1795 |
+
|
| 1796 |
+
async fn oauth_reco_tracks(Json(req): Json<OauthRecoReq>) -> impl IntoResponse {
|
| 1797 |
+
let token = req.access_token.trim().to_string();
|
| 1798 |
+
if token.is_empty() {
|
| 1799 |
+
return json_error(StatusCode::BAD_REQUEST, "access_token required");
|
| 1800 |
+
}
|
| 1801 |
+
let index = req.index.unwrap_or(0).to_string();
|
| 1802 |
+
let limit = req.limit.unwrap_or(40).clamp(1, 100).to_string();
|
| 1803 |
+
let client = reqwest::Client::builder()
|
| 1804 |
+
.timeout(std::time::Duration::from_secs(15))
|
| 1805 |
+
.build()
|
| 1806 |
+
.unwrap();
|
| 1807 |
+
|
| 1808 |
+
let me = match api_deezer_get(&client, "/user/me", &token, &[]).await {
|
| 1809 |
+
Ok(v) => v,
|
| 1810 |
+
Err(e) => return json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1811 |
+
};
|
| 1812 |
+
let uid = me.get("id").and_then(|x| x.as_i64()).unwrap_or(0);
|
| 1813 |
+
if uid <= 0 {
|
| 1814 |
+
return json_error(StatusCode::SERVICE_UNAVAILABLE, "api:no_user_id");
|
| 1815 |
+
}
|
| 1816 |
+
let path = format!("/user/{uid}/recommendations/tracks");
|
| 1817 |
+
let extra = [("index", index), ("limit", limit)];
|
| 1818 |
+
match api_deezer_get(&client, &path, &token, &extra).await {
|
| 1819 |
+
Ok(v) => (StatusCode::OK, Json(v)).into_response(),
|
| 1820 |
+
Err(e) => json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1821 |
+
}
|
| 1822 |
+
}
|
| 1823 |
+
|
| 1824 |
+
#[derive(Debug, Deserialize)]
|
| 1825 |
+
struct OauthHistoryReq {
|
| 1826 |
+
access_token: String,
|
| 1827 |
+
index: Option<u32>,
|
| 1828 |
+
limit: Option<u32>,
|
| 1829 |
+
}
|
| 1830 |
+
|
| 1831 |
+
async fn oauth_history(Json(req): Json<OauthHistoryReq>) -> impl IntoResponse {
|
| 1832 |
+
let token = req.access_token.trim().to_string();
|
| 1833 |
+
if token.is_empty() {
|
| 1834 |
+
return json_error(StatusCode::BAD_REQUEST, "access_token required");
|
| 1835 |
+
}
|
| 1836 |
+
let index = req.index.unwrap_or(0).to_string();
|
| 1837 |
+
let limit = req.limit.unwrap_or(50).clamp(1, 100).to_string();
|
| 1838 |
+
let client = reqwest::Client::builder()
|
| 1839 |
+
.timeout(std::time::Duration::from_secs(15))
|
| 1840 |
+
.build()
|
| 1841 |
+
.unwrap();
|
| 1842 |
+
|
| 1843 |
+
let me = match api_deezer_get(&client, "/user/me", &token, &[]).await {
|
| 1844 |
+
Ok(v) => v,
|
| 1845 |
+
Err(e) => return json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1846 |
+
};
|
| 1847 |
+
let uid = me.get("id").and_then(|x| x.as_i64()).unwrap_or(0);
|
| 1848 |
+
if uid <= 0 {
|
| 1849 |
+
return json_error(StatusCode::SERVICE_UNAVAILABLE, "api:no_user_id");
|
| 1850 |
+
}
|
| 1851 |
+
let path = format!("/user/{uid}/history");
|
| 1852 |
+
let extra = [("index", index), ("limit", limit)];
|
| 1853 |
+
match api_deezer_get(&client, &path, &token, &extra).await {
|
| 1854 |
+
Ok(v) => (StatusCode::OK, Json(v)).into_response(),
|
| 1855 |
+
Err(e) => json_error(StatusCode::SERVICE_UNAVAILABLE, e),
|
| 1856 |
+
}
|
| 1857 |
+
}
|
| 1858 |
+
|
| 1859 |
#[tokio::main]
|
| 1860 |
async fn main() {
|
| 1861 |
let bind_addr = std::env::var("BIND_ADDR").unwrap_or("[::]".to_string());
|
|
|
|
| 1894 |
.route("/oauth/playlist_tracks", post(oauth_playlist_tracks))
|
| 1895 |
.route("/oauth/arl", post(oauth_arl))
|
| 1896 |
.route("/oauth/flow", post(oauth_flow))
|
| 1897 |
+
.route("/oauth/reco_playlists", post(oauth_reco_playlists))
|
| 1898 |
+
.route("/oauth/reco_albums", post(oauth_reco_albums))
|
| 1899 |
+
.route("/oauth/reco_artists", post(oauth_reco_artists))
|
| 1900 |
+
.route("/oauth/reco_tracks", post(oauth_reco_tracks))
|
| 1901 |
+
.route("/oauth/history", post(oauth_history))
|
| 1902 |
.with_state(state)
|
| 1903 |
.layer(cors)
|
| 1904 |
.layer(CompressionLayer::new())
|