Skip to content

Commit

Permalink
Leer enlaces de github (#35)
Browse files Browse the repository at this point in the history
* feat: event

* fix: imports

* Update read_github_links.rs

Allow to show entire files without `#L` in url

---------

Co-authored-by: Apika Luca <bjqf0724@gmail.com>
  • Loading branch information
stifskere and Brayan-724 authored Jul 24, 2024
1 parent f1c94b1 commit 65dd1e7
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/config/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use crate::config::songbird_config::SoundStore;

use super::general_command_loader::GENERAL_GROUP;

use crate::events::read_github_links::ReadGithubLinkHandler;

use super::slash_command_loader::Handler;

pub async fn setup(secret_store: SecretStore, _: PathBuf) -> Result<Client, anyhow::Error> {
Expand Down Expand Up @@ -51,6 +53,7 @@ pub async fn setup(secret_store: SecretStore, _: PathBuf) -> Result<Client, anyh

let client = Client::builder(token, intents)
.event_handler(handler)
.event_handler(ReadGithubLinkHandler)
.framework(framework)
.register_songbird()
.await
Expand Down
1 change: 1 addition & 0 deletions src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod anti_spam;
pub mod daily_challenge;
pub mod join;
pub mod send_message;
pub mod read_github_links;
144 changes: 144 additions & 0 deletions src/events/read_github_links.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use regex::{Captures, Regex};
use reqwest::get;
use serenity::all::{Context, EventHandler, Message};
use serenity::async_trait;
use std::option::Option;

pub struct ReadGithubLinkHandler;

pub enum RangeOrIndex {
Language(String),
Index(String, i32),
Range(String, i32, i32)
}

pub fn parse_url(url: &str) -> Option<RangeOrIndex> {
let extension_regex = Regex::new(r"\.([^./?#]+)(#|$)").unwrap();

let range_regex
= Regex::new(r"(?:\.(?<language>[^#]+))?(?:#L(?<start>\d+)?(?:-L(?<end>\d+))?)?$")
.unwrap();

let language = extension_regex
.captures(url)
.and_then(|caps| caps.get(1))
.map(|m| m.as_str().to_string())
.unwrap_or_default();

if let Some(caps) = range_regex.captures(url) {
let start = caps.name("start").and_then(|m| m.as_str().parse::<i32>().ok());
let end = caps.name("end").and_then(|m| m.as_str().parse::<i32>().ok());

if end < start {
return None;
}

match (start, end) {
(Some(start), Some(end)) => Some(RangeOrIndex::Range(
language,
start - 1,
end
)),
(Some(start), None) => Some(RangeOrIndex::Index(
language,
start - 1
)),
(None, None) => {
Some(RangeOrIndex::Language(language))
}
_ => None
}
} else {
None
}
}


async fn read_message(link: String) -> Option<String> {
if let Ok(result) = get(&link).await {
if result.status() == 200 {
if let Ok(text) = result.text().await {
let parsed = parse_url(&link)?;

let subtext: Vec<&str> = text.split('\n').collect();

return match parsed {
RangeOrIndex::Language(language)
=> Some(format!(
"Mostrando <{link}>\n```{language}\n{text}\n```"
)),
RangeOrIndex::Index(language, index)
=> {
if index < subtext.len() as i32 {
Some(format!(
"Mostrando linea {} de <{link}>\n```{language}\n{}\n```",
index + 1,
subtext[index as usize].to_string())
)
} else {
None
}
}
RangeOrIndex::Range(language, start, end)
=> {
if start < subtext.len() as i32 && end <= subtext.len() as i32 {
Some(format!(
"Mostrando desde la linea {} hasta la linea {end} de <{link}>\n```{language}\n{}\n```",
start + 1,
subtext[start as usize..end as usize].join("\n")
))
} else {
None
}
}
};
}
}
}
None
}

#[async_trait]
impl EventHandler for ReadGithubLinkHandler {
async fn message(&self, ctx: Context, msg: Message) {
let repo_regex
= Regex::new(r"(https://github\.com/(?:[^/]+/){2})blob/(.*)")
.unwrap();
let hidden_link_regex
= Regex::new(r"[<>]")
.unwrap();
let split_message_regex
= Regex::new(r"[\n ]")
.unwrap();

let replaced = if repo_regex.is_match(&msg.content) {
repo_regex.replace_all(&msg.content, |captures: &Captures| {
captures[1].to_string() + &captures[2]
})
} else {
return;
}.replace("https://github.com/", "https://raw.githubusercontent.com/");

let without_hidden = hidden_link_regex
.replace_all(&replaced, "");

let without_spaces = split_message_regex
.split(&without_hidden);

let links = without_spaces
.filter(|s| s.starts_with("https://raw.githubusercontent.com/"));

let mut dup: Vec<&str> = Vec::new();
for link in links {
if dup.contains(&link) {
continue;
}

if let Some(content) = read_message(link.to_string()).await {
msg.reply(&ctx, content).await.unwrap();
}

dup.push(link);
}
}
}

0 comments on commit 65dd1e7

Please sign in to comment.