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.

176 lines
6.3KB

  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. })
  25. }
  26. }
  27. // releases found, use most recent (0th index)
  28. let release = &resp[0];
  29. // build downloads field
  30. let mut asset_str = String::new();
  31. if let Some(assets) = &release.assets {
  32. for f in assets {
  33. asset_str += &format!("[{}]({})\n", f.name, f.browser_download_url);
  34. }
  35. }
  36. // limit description to 2000 characters
  37. let mut desc = release.body.clone();
  38. if desc.len() > 2000 {
  39. desc = desc[..2000].to_string() + "...";
  40. }
  41. // assemble embed
  42. let embed = Embed {
  43. title: Some(format!("{} {}", &repo_name, &release.tag_name)),
  44. type_: None,
  45. description: Some(desc),
  46. url: None,
  47. timestamp: None,
  48. color: Some(0x00C800), // Colour::from_rgb(0, 200, 0)
  49. footer: Some(EmbedFooter {
  50. text: release.author.login.clone(),
  51. icon_url: Some(release.author.avatar_url.clone()),
  52. proxy_icon_url: None
  53. }),
  54. image: None,
  55. thumbnail: None,
  56. video: None,
  57. provider: None,
  58. author: Some(EmbedAuthor {
  59. name: Some(release.name.clone()),
  60. url: Some(format!("https://git.exmods.org/{}/{}", &username, &repo_name)),
  61. icon_url: None,
  62. proxy_icon_url: None
  63. }),
  64. fields: Some(vec![
  65. EmbedField {
  66. name: "Download".to_string(),
  67. value: asset_str,
  68. inline: Some(true)
  69. }
  70. ])
  71. };
  72. return InteractionResponse::ChannelMessageWithSource {
  73. data: Some(InteractionApplicationCommandCallbackData {
  74. tts: false,
  75. content: "".to_string(),
  76. embeds: Some(vec![embed]),
  77. allowed_mentions: None
  78. })
  79. }
  80. } else {
  81. return InteractionResponse::ChannelMessageWithSource {
  82. data: Some(InteractionApplicationCommandCallbackData {
  83. tts: false,
  84. content: format!("Gitea API error: `{}`", res.err().unwrap()),
  85. embeds: None,
  86. allowed_mentions: None
  87. })
  88. }
  89. }
  90. }
  91. pub fn gitea_issue(interaction: &Interaction) -> InteractionResponse {
  92. let cmd = interaction.cmd().unwrap();
  93. // these should always be populated, but Rust doesn't know that
  94. let mut username = String::new();
  95. let mut repo_name = String::new();
  96. let mut index = 0;
  97. for opt in &cmd.data.options.unwrap() {
  98. match &opt.name as &str {
  99. "username" => {
  100. if let CommandValue::StrVal(v) = opt.value.clone().unwrap() {
  101. username = v;
  102. }
  103. },
  104. "repo" => {
  105. if let CommandValue::StrVal(v) = opt.value.clone().unwrap() {
  106. repo_name = v;
  107. }
  108. },
  109. "issue" => {
  110. if let CommandValue::IntVal(v) = opt.value.clone().unwrap() {
  111. index = v;
  112. }
  113. }
  114. _ => {}
  115. }
  116. }
  117. let res = get_issue_by_index(&username, &repo_name, index);
  118. if let Ok(resp) = res {
  119. // limit description to 2000 characters
  120. let mut desc = resp.body.clone();
  121. if desc.len() > 2000 {
  122. desc = desc[..2000].to_string() + "...";
  123. }
  124. let embed = Embed {
  125. title: Some(format!("{} #{}", &repo_name, index)),
  126. type_: None,
  127. description: Some(desc),
  128. url: None,
  129. timestamp: None,
  130. color: Some(0x00C800), // Colour::from_rgb(0, 200, 0)
  131. footer: Some(EmbedFooter {
  132. text: resp.user.login.clone(),
  133. icon_url: Some(resp.user.avatar_url.clone()),
  134. proxy_icon_url: None
  135. }),
  136. image: None,
  137. thumbnail: None,
  138. video: None,
  139. provider: None,
  140. author: Some(EmbedAuthor {
  141. name: Some(resp.title.clone()),
  142. url: Some(format!("https://git.exmods.org/{}/{}/issues/{}", &username, &repo_name, index)),
  143. icon_url: None,
  144. proxy_icon_url: None
  145. }),
  146. fields: None,
  147. /*fields: Some(vec![
  148. EmbedField {
  149. name: "Download".to_string(),
  150. value: asset_str,
  151. inline: Some(true)
  152. }
  153. ])*/
  154. };
  155. return InteractionResponse::ChannelMessageWithSource {
  156. data: Some(InteractionApplicationCommandCallbackData {
  157. tts: false,
  158. content: "".to_string(),
  159. embeds: Some(vec![embed]),
  160. allowed_mentions: None
  161. })
  162. }
  163. } else {
  164. return InteractionResponse::ChannelMessageWithSource {
  165. data: Some(InteractionApplicationCommandCallbackData {
  166. tts: false,
  167. content: format!("Gitea API error: `{}`", res.err().unwrap()),
  168. embeds: None,
  169. allowed_mentions: None
  170. })
  171. }
  172. }
  173. }