Slash commands are cool
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.

197 lines
6.9KB

  1. use crate::gitea::{get_releases, get_issue_by_index};
  2. use crate::discord::{Interaction, InteractionResponse, InteractionApplicationCommandCallbackData, Embed, EmbedFooter, EmbedAuthor, EmbedField, CommandValue};
  3. pub fn gitea_release(interaction: &Interaction) -> InteractionResponse {
  4. let cmd = interaction.cmd().unwrap();
  5. let mut username = String::new();
  6. let mut repo_name = String::new();
  7. for opt in &cmd.data.options.unwrap() {
  8. match &opt.name as &str {
  9. "username" => username = opt.value.clone().unwrap().to_string(),
  10. "repo" => repo_name = opt.value.clone().unwrap().to_string(),
  11. _ => {}
  12. }
  13. }
  14. let res = get_releases(&username, &repo_name);
  15. if let Ok(resp) = res {
  16. if resp.is_empty() {
  17. // no release in this repo
  18. return InteractionResponse::ChannelMessage {
  19. data: Some(InteractionApplicationCommandCallbackData {
  20. tts: false,
  21. content: format!("No releases found for {}'s {} repository", &username, &repo_name),
  22. embeds: None,
  23. allowed_mentions: None,
  24. flags: None,
  25. })
  26. }
  27. }
  28. // releases found, use most recent (0th index)
  29. let release = &resp[0];
  30. // build downloads field
  31. let mut asset_str = String::new();
  32. if let Some(assets) = &release.assets {
  33. for f in assets {
  34. asset_str += &format!("[{}]({})\n", f.name, f.browser_download_url);
  35. }
  36. }
  37. // limit description to 2000 characters
  38. let mut desc = release.body.clone();
  39. if desc.len() > 2000 {
  40. desc = desc[..2000].to_string() + "...";
  41. }
  42. // assemble embed
  43. let embed = Embed {
  44. title: Some(format!("{} {}", &repo_name, &release.tag_name)),
  45. type_: None,
  46. description: Some(desc),
  47. url: None,
  48. timestamp: None,
  49. color: Some(0x00C800), // Colour::from_rgb(0, 200, 0)
  50. footer: Some(EmbedFooter {
  51. text: release.author.login.clone(),
  52. icon_url: Some(release.author.avatar_url.clone()),
  53. proxy_icon_url: None
  54. }),
  55. image: None,
  56. thumbnail: None,
  57. video: None,
  58. provider: None,
  59. author: Some(EmbedAuthor {
  60. name: Some(release.name.clone()),
  61. url: Some(format!("https://git.exmods.org/{}/{}", &username, &repo_name)),
  62. icon_url: None,
  63. proxy_icon_url: None
  64. }),
  65. fields: Some(vec![
  66. EmbedField {
  67. name: "Download".to_string(),
  68. value: asset_str,
  69. inline: Some(true)
  70. }
  71. ])
  72. };
  73. return InteractionResponse::ChannelMessageWithSource {
  74. data: Some(InteractionApplicationCommandCallbackData {
  75. tts: false,
  76. content: "".to_string(),
  77. embeds: Some(vec![embed]),
  78. allowed_mentions: None,
  79. flags: None,
  80. })
  81. }
  82. } else {
  83. return InteractionResponse::ChannelMessageWithSource {
  84. data: Some(InteractionApplicationCommandCallbackData {
  85. tts: false,
  86. content: format!("Gitea error: `{}`", res.err().unwrap()),
  87. embeds: None,
  88. allowed_mentions: None,
  89. flags: None,
  90. })
  91. }
  92. }
  93. }
  94. pub fn gitea_issue(interaction: &Interaction) -> InteractionResponse {
  95. let cmd = interaction.cmd().unwrap();
  96. // these should always be populated, but Rust doesn't know that
  97. let mut username = String::new();
  98. let mut repo_name = String::new();
  99. let mut index = 0;
  100. for opt in &cmd.data.options.unwrap() {
  101. match &opt.name as &str {
  102. "username" => {
  103. if let CommandValue::StrVal(v) = opt.value.clone().unwrap() {
  104. username = v;
  105. }
  106. },
  107. "repo" => {
  108. if let CommandValue::StrVal(v) = opt.value.clone().unwrap() {
  109. repo_name = v;
  110. }
  111. },
  112. "issue" => {
  113. if let CommandValue::IntVal(v) = opt.value.clone().unwrap() {
  114. index = v;
  115. }
  116. }
  117. _ => {}
  118. }
  119. }
  120. let res = get_issue_by_index(&username, &repo_name, index);
  121. if let Ok(resp) = res {
  122. // limit description to 2000 characters
  123. let mut desc = resp.body.clone();
  124. if desc.len() > 2000 {
  125. desc = desc[..2000].to_string() + "...";
  126. }
  127. // build tags field
  128. let mut tags = Vec::new();
  129. for t in resp.labels {
  130. tags.push(format!("{}", &t.name));
  131. }
  132. let tag_str = if tags.is_empty() {
  133. "<none>".to_string()
  134. } else {
  135. tags.join(", ")
  136. };
  137. // build embed
  138. let embed = Embed {
  139. title: Some(format!("Issue #{}", index)),
  140. type_: None,
  141. description: Some(desc),
  142. url: None,
  143. timestamp: None,
  144. color: Some(0x00C800), // Colour::from_rgb(0, 200, 0)
  145. footer: Some(EmbedFooter {
  146. text: resp.user.login.clone(),
  147. icon_url: Some(resp.user.avatar_url.clone()),
  148. proxy_icon_url: None
  149. }),
  150. image: None,
  151. thumbnail: None,
  152. video: None,
  153. provider: None,
  154. author: Some(EmbedAuthor {
  155. name: Some(resp.title.clone()),
  156. url: Some(resp.html_url),
  157. icon_url: None,
  158. proxy_icon_url: None
  159. }),
  160. //fields: None,
  161. fields: Some(vec![
  162. EmbedField {
  163. name: "Labels".to_string(),
  164. value: tag_str,
  165. inline: Some(true)
  166. },
  167. EmbedField {
  168. name: "Repository".to_string(),
  169. value: format!("[{}](https://git.exmods.org/{}/{})", resp.repository.name, &username, &repo_name),
  170. inline: Some(true)
  171. },
  172. ])
  173. };
  174. return InteractionResponse::ChannelMessageWithSource {
  175. data: Some(InteractionApplicationCommandCallbackData {
  176. tts: false,
  177. content: "".to_string(),
  178. embeds: Some(vec![embed]),
  179. allowed_mentions: None,
  180. flags: None,
  181. })
  182. }
  183. } else {
  184. return InteractionResponse::ChannelMessageWithSource {
  185. data: Some(InteractionApplicationCommandCallbackData {
  186. tts: false,
  187. content: format!("Gitea error: `{}`", res.err().unwrap()),
  188. embeds: None,
  189. allowed_mentions: None,
  190. flags: None,
  191. })
  192. }
  193. }
  194. }