|
|
@@ -0,0 +1,174 @@ |
|
|
|
use std::env; |
|
|
|
use std::str::FromStr; |
|
|
|
|
|
|
|
extern crate serenity; |
|
|
|
use serenity::{ |
|
|
|
model::channel::Message, |
|
|
|
//model::channel::Attachment, |
|
|
|
prelude::*, |
|
|
|
utils::MessageBuilder, |
|
|
|
utils::Colour, |
|
|
|
}; |
|
|
|
|
|
|
|
extern crate regex; |
|
|
|
use regex::{Regex, RegexBuilder}; |
|
|
|
|
|
|
|
extern crate swagger; |
|
|
|
use swagger::apis; |
|
|
|
//use swagger::apis::RepositoryApi; |
|
|
|
|
|
|
|
extern crate hyper; |
|
|
|
use hyper::{Client, Uri}; |
|
|
|
|
|
|
|
extern crate hyper_tls; |
|
|
|
use hyper_tls::HttpsConnector; |
|
|
|
|
|
|
|
extern crate tokio_core; |
|
|
|
use tokio_core::reactor::Core; |
|
|
|
|
|
|
|
extern crate futures; |
|
|
|
use futures::prelude::Future; |
|
|
|
|
|
|
|
use crate::traits::Command; |
|
|
|
|
|
|
|
pub struct CmdGitea { |
|
|
|
format: Regex, |
|
|
|
help_format: Regex, |
|
|
|
} |
|
|
|
|
|
|
|
impl Command for CmdGitea { |
|
|
|
fn execute(&mut self, ctx: &Context, msg: &Message) { |
|
|
|
if let Some(parsed) = self.format.captures(&msg.content) { |
|
|
|
if let Some(op) = parsed.get(1) { |
|
|
|
if op.as_str() != "release" { |
|
|
|
let response = MessageBuilder::new() |
|
|
|
.push("Invalid operation specified. Supported operations are `release`") |
|
|
|
.build(); |
|
|
|
if let Err(why) = msg.channel_id.say(&ctx.http, response) { |
|
|
|
println!("Failed to send gitea invalid option message {:?}", why); |
|
|
|
} |
|
|
|
} |
|
|
|
if let Some(full_url) = parsed.get(2) { |
|
|
|
let token = env::var("GITEA_TOKEN").expect("Expected a Gitea API token in GITEA_TOKEN environment variable"); |
|
|
|
let core = Core::new().unwrap(); |
|
|
|
let https = HttpsConnector::new(); |
|
|
|
let client = Client::configure() |
|
|
|
.connector(HttpsConnector::new(4, &core.handle()).unwrap()) |
|
|
|
.build(&core.handle()); |
|
|
|
let mut config = apis::configuration::Configuration::new(client); |
|
|
|
config.api_key = Some(apis::configuration::ApiKey { |
|
|
|
prefix: Some("token ".to_string()), |
|
|
|
key: token, |
|
|
|
}); |
|
|
|
println!("Url {}", full_url.as_str()); |
|
|
|
match Uri::from_str(full_url.as_str()) { |
|
|
|
Err(why) => { |
|
|
|
let response = MessageBuilder::new() |
|
|
|
.push(format!("Could not parse repository URL {:?}", why)) |
|
|
|
.build(); |
|
|
|
if let Err(why) = msg.channel_id.say(&ctx.http, response) { |
|
|
|
println!("Failed to send gitea error message {:?}", why); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
Ok(url) => { |
|
|
|
config.base_path = url.scheme().unwrap().to_owned() + "://" + url.host().unwrap() + "/api/v1/"; |
|
|
|
println!("Base Url {}", config.base_path); |
|
|
|
let client = apis::client::APIClient::new(config); |
|
|
|
if let Some(owner) = parsed.get(3) { |
|
|
|
if let Some(repo_name) = parsed.get(4) { |
|
|
|
println!("owner {} repo {}", owner.as_str(), repo_name.as_str()); |
|
|
|
let future = client.repository_api().repo_list_releases(owner.as_str(), repo_name.as_str(), 1, 5); |
|
|
|
match future.wait() { |
|
|
|
Ok(items) => { |
|
|
|
// items is Vec of release |
|
|
|
if items.len() > 0 { |
|
|
|
println!("Release info {:?}", items[0]); |
|
|
|
// releases found, use first one (most recent) |
|
|
|
if let Err(why) = msg.channel_id.send_message(&ctx.http, |m| { |
|
|
|
return m.embed(|e| { |
|
|
|
return e.colour(Colour::from_rgb(0, 200, 0)) |
|
|
|
.title(items[0].tag_name().unwrap()) |
|
|
|
.description(items[0].body().unwrap()) |
|
|
|
.author(|a| { |
|
|
|
return a.name(items[0].name().unwrap()) |
|
|
|
.url(full_url.as_str().to_owned() + "/releases"); |
|
|
|
}) |
|
|
|
}); |
|
|
|
}) { |
|
|
|
println!("Failed to send gitea release message {:?}", why); |
|
|
|
return; |
|
|
|
} |
|
|
|
} else { |
|
|
|
let response = MessageBuilder::new() |
|
|
|
.push(format!("No releases found for <{}>", full_url.as_str())) |
|
|
|
.build(); |
|
|
|
if let Err(why) = msg.channel_id.say(&ctx.http, response) { |
|
|
|
println!("Failed to send gitea error message {:?}", why); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Err(reason) => { |
|
|
|
println!("Gitea API request failed {:?}", reason); |
|
|
|
let response = MessageBuilder::new() |
|
|
|
.push(format!("Gitea API request failed {:?}", reason)) |
|
|
|
.build(); |
|
|
|
if let Err(why) = msg.channel_id.say(&ctx.http, response) { |
|
|
|
println!("Failed to send gitea error message {:?}", why); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
let response = MessageBuilder::new() |
|
|
|
.push(format!("Unknown error occurred")) |
|
|
|
.build(); |
|
|
|
if let Err(why) = msg.channel_id.say(&ctx.http, response) { |
|
|
|
println!("Failed to send gitea unknown error message {:?}", why); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn valid(&self, _ctx: &Context, msg: &Message) -> bool { |
|
|
|
return self.format.is_match(&msg.content) && !msg.author.bot; |
|
|
|
} |
|
|
|
|
|
|
|
fn help(&self, ctx: &Context, msg:&Message) { |
|
|
|
let mut response = MessageBuilder::new(); |
|
|
|
response.push("**Access the gitea API**\n!gitea release (repository URL)"); |
|
|
|
if let Err(why) = msg.channel_id.say(&ctx.http, &response.build()) { |
|
|
|
println!("Failed to send gitea help message {:?}", why); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn valid_help(&self, _ctx: &Context, msg: &Message) -> bool { |
|
|
|
return self.help_format.is_match(&msg.content); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl CmdGitea { |
|
|
|
pub fn new() -> CmdGitea { |
|
|
|
return CmdGitea { |
|
|
|
format: |
|
|
|
RegexBuilder::new(r#"^!gitea\s+(release)\s+<?(https?://[^/\s]+/([^/\s]+)/([^/\s]+))>?"#) |
|
|
|
.multi_line(true) |
|
|
|
.case_insensitive(true) |
|
|
|
.build() |
|
|
|
.unwrap(), |
|
|
|
help_format: |
|
|
|
RegexBuilder::new(r#"^!help\s*(?:gitea)"#) |
|
|
|
.case_insensitive(true) |
|
|
|
.build() |
|
|
|
.unwrap(), |
|
|
|
}; |
|
|
|
} |
|
|
|
} |