Productivity bot for Discord
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

175 lines
8.1KB

  1. use std::env;
  2. use std::str::FromStr;
  3. extern crate serenity;
  4. use serenity::{
  5. model::channel::Message,
  6. //model::channel::Attachment,
  7. prelude::*,
  8. utils::MessageBuilder,
  9. utils::Colour,
  10. };
  11. extern crate regex;
  12. use regex::{Regex, RegexBuilder};
  13. extern crate swagger;
  14. use swagger::apis;
  15. //use swagger::apis::RepositoryApi;
  16. extern crate hyper;
  17. use hyper::{Client, Uri};
  18. extern crate hyper_tls;
  19. use hyper_tls::HttpsConnector;
  20. extern crate tokio_core;
  21. use tokio_core::reactor::Core;
  22. extern crate futures;
  23. use futures::prelude::Future;
  24. use crate::traits::Command;
  25. pub struct CmdGitea {
  26. format: Regex,
  27. help_format: Regex,
  28. }
  29. impl Command for CmdGitea {
  30. fn execute(&mut self, ctx: &Context, msg: &Message) {
  31. if let Some(parsed) = self.format.captures(&msg.content) {
  32. if let Some(op) = parsed.get(1) {
  33. if op.as_str() != "release" {
  34. let response = MessageBuilder::new()
  35. .push("Invalid operation specified. Supported operations are `release`")
  36. .build();
  37. if let Err(why) = msg.channel_id.say(&ctx.http, response) {
  38. println!("Failed to send gitea invalid option message {:?}", why);
  39. }
  40. }
  41. if let Some(full_url) = parsed.get(2) {
  42. let token = env::var("GITEA_TOKEN").expect("Expected a Gitea API token in GITEA_TOKEN environment variable");
  43. let core = Core::new().unwrap();
  44. let https = HttpsConnector::new();
  45. let client = Client::configure()
  46. .connector(HttpsConnector::new(4, &core.handle()).unwrap())
  47. .build(&core.handle());
  48. let mut config = apis::configuration::Configuration::new(client);
  49. config.api_key = Some(apis::configuration::ApiKey {
  50. prefix: Some("token ".to_string()),
  51. key: token,
  52. });
  53. println!("Url {}", full_url.as_str());
  54. match Uri::from_str(full_url.as_str()) {
  55. Err(why) => {
  56. let response = MessageBuilder::new()
  57. .push(format!("Could not parse repository URL {:?}", why))
  58. .build();
  59. if let Err(why) = msg.channel_id.say(&ctx.http, response) {
  60. println!("Failed to send gitea error message {:?}", why);
  61. return;
  62. }
  63. }
  64. Ok(url) => {
  65. config.base_path = url.scheme().unwrap().to_owned() + "://" + url.host().unwrap() + "/api/v1/";
  66. println!("Base Url {}", config.base_path);
  67. let client = apis::client::APIClient::new(config);
  68. if let Some(owner) = parsed.get(3) {
  69. if let Some(repo_name) = parsed.get(4) {
  70. println!("owner {} repo {}", owner.as_str(), repo_name.as_str());
  71. let future = client.repository_api().repo_list_releases(owner.as_str(), repo_name.as_str(), 1, 5);
  72. match future.wait() {
  73. Ok(items) => {
  74. // items is Vec of release
  75. if items.len() > 0 {
  76. println!("Release info {:?}", items[0]);
  77. // releases found, use first one (most recent)
  78. if let Err(why) = msg.channel_id.send_message(&ctx.http, |m| {
  79. return m.embed(|e| {
  80. return e.colour(Colour::from_rgb(0, 200, 0))
  81. .title(items[0].tag_name().unwrap())
  82. .description(items[0].body().unwrap())
  83. .author(|a| {
  84. return a.name(items[0].name().unwrap())
  85. .url(full_url.as_str().to_owned() + "/releases");
  86. })
  87. });
  88. }) {
  89. println!("Failed to send gitea release message {:?}", why);
  90. return;
  91. }
  92. } else {
  93. let response = MessageBuilder::new()
  94. .push(format!("No releases found for <{}>", full_url.as_str()))
  95. .build();
  96. if let Err(why) = msg.channel_id.say(&ctx.http, response) {
  97. println!("Failed to send gitea error message {:?}", why);
  98. return;
  99. }
  100. }
  101. }
  102. Err(reason) => {
  103. println!("Gitea API request failed {:?}", reason);
  104. let response = MessageBuilder::new()
  105. .push(format!("Gitea API request failed {:?}", reason))
  106. .build();
  107. if let Err(why) = msg.channel_id.say(&ctx.http, response) {
  108. println!("Failed to send gitea error message {:?}", why);
  109. return;
  110. }
  111. }
  112. }
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. }
  120. let response = MessageBuilder::new()
  121. .push(format!("Unknown error occurred"))
  122. .build();
  123. if let Err(why) = msg.channel_id.say(&ctx.http, response) {
  124. println!("Failed to send gitea unknown error message {:?}", why);
  125. return;
  126. }
  127. }
  128. fn valid(&self, _ctx: &Context, msg: &Message) -> bool {
  129. return self.format.is_match(&msg.content) && !msg.author.bot;
  130. }
  131. fn help(&self, ctx: &Context, msg:&Message) {
  132. let mut response = MessageBuilder::new();
  133. response.push("**Access the gitea API**\n!gitea release (repository URL)");
  134. if let Err(why) = msg.channel_id.say(&ctx.http, &response.build()) {
  135. println!("Failed to send gitea help message {:?}", why);
  136. }
  137. }
  138. fn valid_help(&self, _ctx: &Context, msg: &Message) -> bool {
  139. return self.help_format.is_match(&msg.content);
  140. }
  141. }
  142. impl CmdGitea {
  143. pub fn new() -> CmdGitea {
  144. return CmdGitea {
  145. format:
  146. RegexBuilder::new(r#"^!gitea\s+(release)\s+<?(https?://[^/\s]+/([^/\s]+)/([^/\s]+))>?"#)
  147. .multi_line(true)
  148. .case_insensitive(true)
  149. .build()
  150. .unwrap(),
  151. help_format:
  152. RegexBuilder::new(r#"^!help\s*(?:gitea)"#)
  153. .case_insensitive(true)
  154. .build()
  155. .unwrap(),
  156. };
  157. }
  158. }