[API-1] feat: search and spotify service
This commit is contained in:
parent
52ef924f12
commit
57588c7e13
10 changed files with 495 additions and 4 deletions
|
@ -5,6 +5,7 @@ mod middlewares;
|
|||
mod models;
|
||||
mod routes;
|
||||
mod schema;
|
||||
mod services;
|
||||
|
||||
use crate::helpers::db;
|
||||
use actix_web::{web, App, HttpServer};
|
||||
|
@ -22,6 +23,7 @@ async fn main() -> std::io::Result<()> {
|
|||
.service(routes::auth::login)
|
||||
.service(routes::me::routes())
|
||||
.service(routes::users::routes())
|
||||
.service(routes::search::routes())
|
||||
})
|
||||
.bind(("127.0.0.1", 9000))?
|
||||
.run()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub mod artists;
|
||||
pub mod playlists;
|
||||
pub mod spotify;
|
||||
pub mod tracks;
|
||||
pub mod user;
|
||||
|
|
5
src/models/spotify.rs
Normal file
5
src/models/spotify.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
pub struct Track {}
|
||||
|
||||
pub struct Artist {}
|
||||
|
||||
pub struct Album {}
|
|
@ -1,4 +1,5 @@
|
|||
pub mod auth;
|
||||
pub mod me;
|
||||
pub mod playlists;
|
||||
pub mod search;
|
||||
pub mod users;
|
||||
|
|
26
src/routes/search.rs
Normal file
26
src/routes/search.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use crate::middlewares::error::ErrorResponse;
|
||||
use crate::services::spotify;
|
||||
use actix_web::{get, web, HttpResponse, Result, Scope};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub fn routes() -> Scope {
|
||||
web::scope("/search").service(search)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SearchQuery {
|
||||
q: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct SearchResponse {
|
||||
track: (),
|
||||
}
|
||||
|
||||
#[get("")]
|
||||
async fn search(query: web::Query<SearchQuery>) -> Result<HttpResponse, ErrorResponse> {
|
||||
let spotify = spotify::instance().await;
|
||||
let track = spotify.search(&query.q).await;
|
||||
|
||||
Ok(HttpResponse::Ok().json(SearchResponse { track }))
|
||||
}
|
2
src/services/mod.rs
Normal file
2
src/services/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
mod service;
|
||||
pub mod spotify;
|
9
src/services/service.rs
Normal file
9
src/services/service.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
pub trait Service: Send + Sync {
|
||||
fn get_token(&self) -> &String;
|
||||
|
||||
async fn fetch_token(&mut self) -> &String;
|
||||
// async fn get_track_by_isrc(&self, isrc: &str);
|
||||
}
|
82
src/services/spotify.rs
Normal file
82
src/services/spotify.rs
Normal file
|
@ -0,0 +1,82 @@
|
|||
use crate::services::service::Service;
|
||||
use actix_web::http::Method;
|
||||
use async_trait::async_trait;
|
||||
use reqwest::{Client, RequestBuilder};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SpotifyResponse {
|
||||
access_token: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Spotify {
|
||||
token: String,
|
||||
}
|
||||
|
||||
pub async fn instance<'a>() -> Spotify {
|
||||
Spotify::new().await
|
||||
}
|
||||
|
||||
impl Spotify {
|
||||
pub async fn new() -> Spotify {
|
||||
let mut spotify = Spotify {
|
||||
token: String::new(),
|
||||
};
|
||||
spotify.fetch_token().await;
|
||||
spotify
|
||||
}
|
||||
|
||||
fn api(&self, url: &str, method: Method) -> RequestBuilder {
|
||||
let client = Client::new();
|
||||
|
||||
client
|
||||
.request(method, &format!("https://api.spotify.com/v1{url}"))
|
||||
.bearer_auth(self.get_token())
|
||||
}
|
||||
|
||||
// pub async fn get_track(self, spotify_id: &str) {
|
||||
// let spotify = &SPOTIFY;
|
||||
// }
|
||||
|
||||
pub async fn get_artist(self, spotify_id: &str) {}
|
||||
|
||||
pub async fn get_track_by_isrc(self, isrc: &str) {}
|
||||
|
||||
pub async fn search(self, search: &str) {}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Service for Spotify {
|
||||
fn get_token(&self) -> &String {
|
||||
&self.token
|
||||
}
|
||||
|
||||
async fn fetch_token(&mut self) -> &String {
|
||||
let response = Client::new()
|
||||
.post("https://accounts.spotify.com/api/token")
|
||||
.basic_auth(
|
||||
get_env("SPOTIFY_CLIENT_ID"),
|
||||
Some(get_env("SPOTIFY_CLIENT_SECRET")),
|
||||
)
|
||||
.form(&[("grant_type", "client_credentials")])
|
||||
.send()
|
||||
.await;
|
||||
|
||||
match response {
|
||||
Ok(res) => {
|
||||
let data: Result<SpotifyResponse, _> = res.json().await;
|
||||
|
||||
self.token = data.unwrap().access_token.into();
|
||||
&self.token
|
||||
}
|
||||
Err(_) => {
|
||||
panic!("Invalid response (Spotify Token)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_env(key: &str) -> String {
|
||||
std::env::var(key).unwrap()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue