~misterio/sistemer-bot

2ea8486e00347e74568d481597755ef183761420 — Gabriel Fontes 3 years ago 20bdaab
finalizado  comando de disciplina
7 files changed, 129 insertions(+), 8 deletions(-)

M .gitignore
M Cargo.lock
M Cargo.toml
M flake.nix
A src/disciplina.rs
A src/lib.rs
M src/main.rs
M .gitignore => .gitignore +1 -0
@@ 1,1 1,2 @@
/target
.env

M Cargo.lock => Cargo.lock +16 -0
@@ 18,6 18,12 @@ dependencies = [
]

[[package]]
name = "anyhow"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"

[[package]]
name = "async-trait"
version = "0.1.51"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 206,6 212,12 @@ dependencies = [
]

[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"

[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1125,8 1137,12 @@ dependencies = [
name = "sistemer-bot"
version = "0.1.0"
dependencies = [
 "anyhow",
 "dotenv",
 "log",
 "pretty_env_logger",
 "regex",
 "reqwest",
 "teloxide",
 "tokio",
]

M Cargo.toml => Cargo.toml +4 -0
@@ 10,3 10,7 @@ teloxide = { version = "0.5", features = ["auto-send", "macros"] }
log = "0.4"
pretty_env_logger = "0.4.0"
tokio = { version =  "1.8", features = ["rt-multi-thread", "macros"] }
dotenv = "0.15"
reqwest = "0.11"
anyhow = "1.0"
regex = "1.5"

M flake.nix => flake.nix +10 -6
@@ 12,19 12,21 @@
  outputs = { self, nixpkgs, flake-utils, naersk }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        name = "sistemer-bot";
        pkgs = nixpkgs.legacyPackages.${system};
        naersk-lib = naersk.lib."${system}";
      in rec {
        packages.backend-uget = naersk-lib.buildPackage {
          pname = "sistemerb-bot";
        packages.${name} = naersk-lib.buildPackage {
          pname = name;
          buildInputs = with pkgs; [ openssl pkg-config ];
          root = ./.;
        };
        defaultPackage = packages.sistemer-bot;
        defaultPackage = packages.${name};

        apps.backend-uget = flake-utils.lib.mkApp {
          drv = packages.sistemer-bot;
        apps.${name} = flake-utils.lib.mkApp {
          drv = packages.${name};
        };
        defaultApp = apps.sistemer-bot;
        defaultApp = apps.${name};

        devShell = pkgs.mkShell {
          buildInputs = with pkgs;


@@ 34,6 36,8 @@
              rust-analyzer
              rustfmt
              clippy
              pkgconfig
              openssl
            ];
        };
      });

A src/disciplina.rs => src/disciplina.rs +53 -0
@@ 0,0 1,53 @@
use anyhow::Result;
use regex::Regex;

fn sanitize_line(line: &str) -> Result<String> {
    log::info!("Transformando {:?}", line);

    let line = format!("{}\n", line);
    // Replace headers with <b>
    let line = Regex::new("h\\d")?.replace_all(&line, "b");
    // Remove <ul> entire lines
    let line = Regex::new("^ *</?ul>\n")?.replace_all(&line, "");
    let line = Regex::new("</?ul>")?.replace_all(&line, "");
    // Remove <li>
    let line = Regex::new("^ *</?li>\n")?.replace_all(&line, "");
    let line = Regex::new("</?li>")?.replace_all(&line, "");
    // Remove <p>
    let line = Regex::new("</?p>")?.replace_all(&line, "");
    // Remove email links
    let line = Regex::new("<a href=\"mailto:.*>(.*)</a>")?.replace(&line, "$1");

    log::info!("Em: {:?}", line);

    Ok(line.into())
}

pub async fn get_disciplina(disciplina: &str) -> Result<String> {
    let fulltext = reqwest::get("https://misterio.me/notes/bsi/disciplinas-2021-2.html")
        .await?
        .text()
        .await?;

    let start_pattern = Regex::new(&format!("<h2.*>.*{}.*</h2>", disciplina))?;
    let stop_pattern = Regex::new("<hr />")?;

    let mut output: String = "".into();
    let mut adding = false;
    for line in fulltext.lines() {
        if start_pattern.is_match(line) {
            log::info!("Iniciando escrita");
            output.push_str(&sanitize_line(line)?);
            adding = true;
        } else if adding {
            if stop_pattern.is_match(line) {
                log::info!("Finalizando escrita:\n{}", output);
                return Ok(output);
            } else {
                output.push_str(&sanitize_line(line)?);
            }
        }
    }

    Ok("Disciplina não encontrada!".into())
}

A src/lib.rs => src/lib.rs +1 -0
@@ 0,0 1,1 @@
pub mod disciplina;

M src/main.rs => src/main.rs +44 -2
@@ 1,3 1,45 @@
fn main() {
    println!("Hello, world!");
use teloxide::prelude::*;
use teloxide::types::ParseMode::Html;
use teloxide::utils::command::BotCommand;

use anyhow::Result;
use dotenv::dotenv;

use sistemer_bot::disciplina;

#[derive(BotCommand)]
#[command(rename = "lowercase", description = "These commands are supported:")]
enum Command {
    #[command(description = "exibe essa ajuda.")]
    Help,
    #[command(description = "mostra info de uma disciplina.")]
    Disciplina(String),
}

async fn answer(cx: UpdateWithCx<AutoSend<Bot>, Message>, command: Command) -> Result<()> {
    match command {
        Command::Help => cx.answer(Command::descriptions()).await?,
        Command::Disciplina(disciplina) => {
            cx.answer(disciplina::get_disciplina(&disciplina).await?)
                .parse_mode(Html)
                .await?
        }
    };

    Ok(())
}

async fn run() {
    teloxide::enable_logging!();

    let bot = Bot::from_env().auto_send();
    let bot_name: String = "Sistemer Bot".into();

    teloxide::commands_repl(bot, bot_name, answer).await;
}

#[tokio::main]
async fn main() {
    dotenv().ok();
    run().await;
}