Initial api implementation

This commit is contained in:
2024-03-15 11:46:28 -03:00
parent e701f20c1a
commit fdb135051b
10 changed files with 282 additions and 46 deletions

View File

@ -31,10 +31,19 @@ path = "src/lib.rs"
#actix = ["tribufu-actix"]
[dependencies]
tribufu-api = { version = "0.1.0", path = "./src/api" }
#tribufu-actix = { version = "0.1.0", path = "./src/actix", optional = true }
alnilam-consts = { version = "0.0.4" }
anyhow = "1.0.75"
base64 = "0.21.5"
chrono = { version = "0.4.22", features = ["serde", "rustc-serialize"] }
derive_more = "0.99.17"
mintaka-error = { version = "0.0.1" }
reqwest = { version = "0.11.18", features = ["json", "stream"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["raw_value"] }
serde_with = "3.4.0"
tribufu-constants = { version = "0.1.0", path = "./src/constants" }
tribufu-types = { version = "0.1.0", path = "./src/types" }
#tribufu-actix = { version = "0.1.0", path = "./src/actix", optional = true }
[dev-dependencies]
dotenv = "0.15.0"

View File

@ -14,6 +14,6 @@ crate-type = ["rlib"]
path = "lib.rs"
[dependencies]
#tribufu-api = { path = "../api" }
actix-web = { version = "4", features = ["rustls"] }
mintaka-error = { version = "0.0.1" }
tribufu-api = { path = "../api" }

118
src/api.rs Normal file
View File

@ -0,0 +1,118 @@
// Copyright (c) Tribufu. All Rights Reserved.
use std::env;
use reqwest::{
header::{HeaderMap, HeaderValue, AUTHORIZATION},
Client as HttpClient,
};
use tribufu_constants::{TRIBUFU_API_URL, TRIBUFU_VERSION};
#[derive(Debug, Default)]
pub enum TribufuApiOptions {
#[default]
Anonymous,
ApiKey {
api_key: String,
},
Token {
access_token: String,
refresh_token: Option<String>,
expires_in: Option<u64>,
},
}
/// **Tribufu API**
///
/// Use this class to interact with the Tribufu API.
///
/// *There are three ways to use the Tribufu API:*
/// - A api key give you public read only access to the Tribufu API.
/// - A bot give you read and write access to the Tribufu API as a bot account.
/// - A client give you read and write access to the Tribufu API as a client application.
pub struct TribufuApi {
pub(crate) http: HttpClient,
pub(crate) options: TribufuApiOptions,
}
impl Default for TribufuApi {
fn default() -> Self {
Self::new(TribufuApiOptions::Anonymous)
}
}
impl TribufuApi {
pub fn new(options: TribufuApiOptions) -> Self {
let http = HttpClient::builder()
.default_headers(Self::default_headers())
.build()
.unwrap();
TribufuApi { http, options }
}
pub fn with_api_key(api_key: String) -> Self {
Self::new(TribufuApiOptions::ApiKey { api_key })
}
pub fn from_env(prefix: Option<&str>) -> Option<Self> {
let prefix = if let Some(prefix) = prefix {
format!("{}_", prefix)
} else {
"".to_string()
};
if let Ok(api_key) = env::var(format!("{prefix}API_KEY")) {
Some(Self::with_api_key(api_key))
} else {
None
}
}
pub fn from_env_or_default(prefix: Option<&str>) -> Self {
Self::from_env(prefix).unwrap_or_default()
}
pub(crate) fn debug_enabled() -> bool {
return cfg!(debug_assertions);
}
#[inline]
pub(crate) fn get_base_url() -> String {
if Self::debug_enabled() {
return env::var("TRIBUFU_API_URL").unwrap_or(TRIBUFU_API_URL.to_string());
}
TRIBUFU_API_URL.to_string()
}
#[inline]
fn default_headers() -> HeaderMap {
let mut headers = HeaderMap::new();
headers.insert("X-Tribufu-Language", "rust".parse().unwrap());
headers.insert("X-Tribufu-Version", TRIBUFU_VERSION.parse().unwrap());
headers
}
pub(crate) fn headers(&self) -> HeaderMap {
let mut headers = TribufuApi::default_headers();
match &self.options {
TribufuApiOptions::ApiKey { api_key } => {
headers.insert(
"Authorization",
HeaderValue::from_str(&format!("ApiKey {}", api_key)).unwrap(),
);
}
TribufuApiOptions::Token { access_token, .. } => {
headers.insert(
"Authorization",
HeaderValue::from_str(&format!("Bearer {}", access_token)).unwrap(),
);
}
_ => {}
}
headers
}
}

View File

@ -1,28 +0,0 @@
[package]
name = "tribufu-api"
version = "0.1.0"
description = "Tribufu API"
repository = "https://github.com/Tribufu/TribufuRust"
authors = ["Tribufu <contact@tribufu.com>"]
license = "MIT"
edition = "2021"
publish = true
[lib]
name = "tribufu_api"
crate-type = ["rlib"]
path = "lib.rs"
[dependencies]
tribufu-constants = { version = "0.1.0", path = "../constants" }
tribufu-types = { version = "0.1.0", path = "../types" }
base64 = "0.21.5"
mintaka-error = { version = "0.0.1" }
alnilam-consts = { version = "0.0.4" }
anyhow = "1.0.75"
chrono = { version = "0.4.22", features = ["serde", "rustc-serialize"] }
derive_more = "0.99.17"
reqwest = { version = "0.11.18", features = ["json", "stream"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["raw_value"] }
serde_with = "3.4.0"

View File

@ -5,7 +5,7 @@ use mintaka_error::{Error, Result};
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};
use reqwest::Client;
use std::env;
use tribufu_constants::VERSION;
use tribufu_constants::TRIBUFU_VERSION;
use tribufu_types::games::Game;
use tribufu_types::oauth2::{OAuth2GrantType, OAuth2TokenRequest, OAuth2TokenResponse};
use tribufu_types::users::*;
@ -35,16 +35,7 @@ pub enum Token {
}
pub struct TribufuApi {
base_url: String,
credentials: Credentials,
token: Option<Token>,
http: Client,
}
impl Default for TribufuApi {
fn default() -> Self {
Self::new(Credentials::Anonymous)
}
}
impl TribufuApi {
@ -73,7 +64,7 @@ impl TribufuApi {
fn user_agent() -> String {
format!(
"Tribufu/{} (+https://api.tribufu.com; {})",
VERSION, TARGET_TRIPLE
TRIBUFU_VERSION, TARGET_TRIPLE
)
}
@ -81,7 +72,10 @@ impl TribufuApi {
fn default_headers() -> HeaderMap {
let mut headers = HeaderMap::new();
headers.insert("X-Tribufu-Language", HeaderValue::from_static("rust"));
headers.insert("X-Tribufu-Version", HeaderValue::from_static(VERSION));
headers.insert(
"X-Tribufu-Version",
HeaderValue::from_static(TRIBUFU_VERSION),
);
headers
}

1
src/bot.rs Normal file
View File

@ -0,0 +1 @@
// Copyright (c) Tribufu. All Rights Reserved.

83
src/client.rs Normal file
View File

@ -0,0 +1,83 @@
// Copyright (c) Tribufu. All Rights Reserved.
use std::env;
use reqwest::header::{HeaderMap, HeaderValue};
use crate::{TribufuApi, TribufuApiOptions};
pub struct TribufuClient {
client_id: u64,
client_secret: String,
api: TribufuApi,
}
impl TribufuClient {
pub fn new(client_id: u64, client_secret: impl Into<String>) -> Self {
Self {
client_id,
client_secret: client_secret.into(),
api: TribufuApi::default(),
}
}
pub fn from_env(prefix: Option<&str>) -> Option<Self> {
let prefix = if let Some(prefix) = prefix {
format!("{}_", prefix)
} else {
"".to_string()
};
let client_id = env::var(format!("{prefix}CLIENT_ID"));
let client_secret = env::var(format!("{prefix}CLIENT_SECRET"));
if let (Ok(client_id), Ok(client_secret)) = (client_id, client_secret) {
Some(Self::new(client_id.parse().unwrap(), client_secret))
} else {
None
}
}
pub(crate) fn set_tokens(
&mut self,
access_token: String,
refresh_token: Option<String>,
expires_in: Option<u64>,
) {
self.api.options = TribufuApiOptions::Token {
access_token,
refresh_token,
expires_in,
};
}
pub(crate) fn clear_tokens(&mut self) {
self.api.options = TribufuApiOptions::Anonymous;
}
#[inline]
fn oauth_headers(&self) -> HeaderMap {
let mut headers = self.api.headers();
headers.insert("Authorization", HeaderValue::from_str("Basic").unwrap());
headers.insert(
"Content-Type",
HeaderValue::from_str("application/x-www-form-urlencoded").unwrap(),
);
headers
}
pub fn api(&self) -> &TribufuApi {
&self.api
}
pub fn api_mut(&mut self) -> &mut TribufuApi {
&mut self.api
}
pub fn client_id(&self) -> u64 {
self.client_id
}
}

View File

@ -1,3 +1,13 @@
// Copyright (c) Tribufu. All Rights Reserved.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
/// The version of the Tribufu SDK.
pub const TRIBUFU_VERSION: &'static str = env!("CARGO_PKG_VERSION");
/// The default Tribufu API URL.
pub const TRIBUFU_API_URL: &'static str = "https://api.tribufu.com";
/// The default Tribufu WEB URL.
pub const TRIBUFU_WEB_URL: &'static str = "https://www.tribufu.com";
/// The default Tribufu CDN URL.
pub const TRIBUFU_CDN_URL: &'static str = "https://cdn.tribufu.com";

View File

@ -1,5 +1,17 @@
// Copyright (c) Tribufu. All Rights Reserved.
pub use tribufu_api::*;
pub use tribufu_constants::VERSION;
#![allow(dead_code)]
#![allow(unused_imports)]
pub use tribufu_constants::TRIBUFU_VERSION;
pub use tribufu_types as types;
mod api;
mod bot;
mod client;
mod server;
pub use api::*;
pub use bot::*;
pub use client::*;
pub use server::*;

37
src/server.rs Normal file
View File

@ -0,0 +1,37 @@
// Copyright (c) Tribufu. All Rights Reserved.
use crate::{TribufuApi, TribufuClient};
pub struct TribufuServer {
server_id: u64,
client: TribufuClient,
}
impl TribufuServer {
pub fn new(server_id: u64, client_id: u64, client_secret: impl Into<String>) -> Self {
Self {
server_id,
client: TribufuClient::new(client_id, client_secret),
}
}
pub fn api(&self) -> &TribufuApi {
self.client.api()
}
pub fn api_mut(&mut self) -> &mut TribufuApi {
self.client.api_mut()
}
pub fn client(&self) -> &TribufuClient {
&self.client
}
pub fn client_mut(&mut self) -> &mut TribufuClient {
&mut self.client
}
pub fn server_id(&self) -> u64 {
self.server_id
}
}