started gitea api impl #2
+14
-4
@@ -1,9 +1,10 @@
|
|||||||
use axum::body::{Bytes, to_bytes};
|
use axum::body::{Bytes, to_bytes};
|
||||||
use axum::extract::{FromRef, FromRequest};
|
use axum::extract::{FromRef, FromRequest, State};
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::IntoResponse;
|
||||||
use axum::routing::{get, post};
|
use axum::routing::{get, post};
|
||||||
use axum::{Json, Router};
|
use axum::{Json, Router};
|
||||||
use hmac::{Hmac, KeyInit, Mac};
|
use hmac::{Hmac, KeyInit, Mac};
|
||||||
|
use reqwest::StatusCode;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use subtle::ConstantTimeEq;
|
use subtle::ConstantTimeEq;
|
||||||
@@ -31,8 +32,17 @@ async fn root() -> &'static str {
|
|||||||
"Hi, i'm Herald :)"
|
"Hi, i'm Herald :)"
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn webhook(WebhookExtract(wb): WebhookExtract) -> Result<Response, AppError> {
|
async fn webhook(
|
||||||
Ok("lol".into_response())
|
State(app_state): State<AppState>,
|
||||||
|
WebhookExtract(wb): WebhookExtract,
|
||||||
|
) -> Result<impl IntoResponse, AppError> {
|
||||||
|
app_state
|
||||||
|
.bot_tx
|
||||||
|
.send(wb)
|
||||||
|
.await
|
||||||
|
.map_err(anyhow::Error::from)?;
|
||||||
|
|
||||||
|
Ok((StatusCode::CREATED, "Task started"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WebhookExtract(pub WebhookType);
|
pub struct WebhookExtract(pub WebhookType);
|
||||||
|
|||||||
+36
-3
@@ -1,13 +1,46 @@
|
|||||||
use crate::{env::EnvConfig, gitea::WebhookType};
|
use crate::{
|
||||||
|
env::EnvConfig,
|
||||||
|
errors::AppError,
|
||||||
|
gitea::{GiteaAPI, ReviewPayload, WebhookType},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Bot {
|
pub struct Bot {
|
||||||
config: EnvConfig,
|
config: EnvConfig,
|
||||||
|
gitea_api: GiteaAPI,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bot {
|
impl Bot {
|
||||||
pub fn new(config: EnvConfig) -> Self {
|
pub fn new(config: EnvConfig) -> Self {
|
||||||
Self { config }
|
Self {
|
||||||
|
gitea_api: GiteaAPI::new(&config.gitea_url),
|
||||||
|
config,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn exec(&self, webhook: WebhookType) {}
|
pub async fn start(
|
||||||
|
&self,
|
||||||
|
mut rx: tokio::sync::mpsc::Receiver<WebhookType>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
while let Some(wb) = rx.recv().await {
|
||||||
|
self.exec(wb).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn exec(&self, webhook: WebhookType) {
|
||||||
|
let exec_result = match webhook {
|
||||||
|
WebhookType::Review(review_payload) => self.exec_review(review_payload),
|
||||||
|
}
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match exec_result {
|
||||||
|
Ok(_) => println!("Task completed"),
|
||||||
|
Err(_) => println!("Task errored"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn exec_review(&self, review_payload: ReviewPayload) -> Result<(), AppError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ pub struct EnvConfig {
|
|||||||
pub webhook_secret: String,
|
pub webhook_secret: String,
|
||||||
pub open_router_api_key: String,
|
pub open_router_api_key: String,
|
||||||
pub bot_name: String,
|
pub bot_name: String,
|
||||||
|
pub gitea_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_config() -> anyhow::Result<EnvConfig> {
|
pub fn load_config() -> anyhow::Result<EnvConfig> {
|
||||||
@@ -16,12 +17,14 @@ pub fn load_config() -> anyhow::Result<EnvConfig> {
|
|||||||
let bot_name = try_get_env("BOT_NAME")?;
|
let bot_name = try_get_env("BOT_NAME")?;
|
||||||
let webhook_secret = try_get_env("WEBHOOK_SIG_HEADER_SECRET")?;
|
let webhook_secret = try_get_env("WEBHOOK_SIG_HEADER_SECRET")?;
|
||||||
let open_router_api_key = try_get_env("OPEN_ROUTER_API_KEY")?;
|
let open_router_api_key = try_get_env("OPEN_ROUTER_API_KEY")?;
|
||||||
|
let gitea_url = try_get_env("GITEA_URL")?;
|
||||||
|
|
||||||
Ok(EnvConfig {
|
Ok(EnvConfig {
|
||||||
http_port,
|
http_port,
|
||||||
webhook_secret,
|
webhook_secret,
|
||||||
bot_name,
|
bot_name,
|
||||||
open_router_api_key,
|
open_router_api_key,
|
||||||
|
gitea_url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,26 @@ use serde_json::Value;
|
|||||||
|
|
||||||
use crate::errors::AppError;
|
use crate::errors::AppError;
|
||||||
|
|
||||||
|
pub struct GiteaAPI {
|
||||||
|
base_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GiteaAPI {
|
||||||
|
pub fn new(base_url: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
base_url: String::from(base_url),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn comment(&self, full_name: &str, index: u64) -> anyhow::Result<u64> {
|
||||||
|
Ok(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn edit_comment(&self, full_name: &str, id: u64) -> anyhow::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum WebhookType {
|
pub enum WebhookType {
|
||||||
Review(ReviewPayload),
|
Review(ReviewPayload),
|
||||||
@@ -12,6 +32,7 @@ pub enum WebhookType {
|
|||||||
pub struct ReviewPayload {
|
pub struct ReviewPayload {
|
||||||
pub action: String,
|
pub action: String,
|
||||||
pub pull_request: PullRequest,
|
pub pull_request: PullRequest,
|
||||||
|
pub repository: Repository,
|
||||||
pub comment: Comment,
|
pub comment: Comment,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +54,11 @@ pub struct User {
|
|||||||
pub id: u64,
|
pub id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct Repository {
|
||||||
|
pub full_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
impl WebhookType {
|
impl WebhookType {
|
||||||
pub fn from_event(event: &str, bot_name: &str, json: Value) -> Result<Self, AppError> {
|
pub fn from_event(event: &str, bot_name: &str, json: Value) -> Result<Self, AppError> {
|
||||||
let wb = match event {
|
let wb = match event {
|
||||||
|
|||||||
+10
-9
@@ -1,8 +1,4 @@
|
|||||||
use std::sync::Arc;
|
use crate::{bot::Bot, gitea::WebhookType, state::AppState};
|
||||||
|
|
||||||
use tokio::sync::Mutex;
|
|
||||||
|
|
||||||
use crate::{bot::Bot, state::AppState};
|
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
mod bot;
|
mod bot;
|
||||||
@@ -15,11 +11,16 @@ mod state;
|
|||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let config = env::load_config()?;
|
let config = env::load_config()?;
|
||||||
|
let bot = Bot::new(config.clone());
|
||||||
|
|
||||||
|
let (tx, rx) = tokio::sync::mpsc::channel::<WebhookType>(1);
|
||||||
|
|
||||||
let app_state = AppState {
|
let app_state = AppState {
|
||||||
bot: Arc::new(Mutex::new(Bot::new(config.clone()))),
|
bot_tx: tx,
|
||||||
config: config,
|
config,
|
||||||
};
|
};
|
||||||
|
|
||||||
api::start(app_state).await
|
tokio::try_join!(bot.start(rx), api::start(app_state))?;
|
||||||
}
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
+2
-5
@@ -1,10 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use crate::{env::EnvConfig, gitea::WebhookType};
|
||||||
use tokio::sync::Mutex;
|
|
||||||
|
|
||||||
use crate::{bot::Bot, env::EnvConfig};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub bot: Arc<Mutex<Bot>>,
|
pub bot_tx: tokio::sync::mpsc::Sender<WebhookType>,
|
||||||
pub config: EnvConfig,
|
pub config: EnvConfig,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user