Last active
December 7, 2016 17:37
-
-
Save paulohrpinheiro/888b35913d4a491ec77dffa53f84c568 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! Crawler — My own crawler in Rust! | |
extern crate hyper; // biblioteca (crate) não padrão | |
use std::env; // argumentos env::args | |
use std::io::{Read, Write}; // para IO de arquivos | |
use std::fs::File; // para criar arquivos | |
use std::path::Path; // configurar nome de arquivo | |
use std::thread; // concorrência | |
const ROBOT_NAME: &'static str = "paulohrpinheiro-crawler"; | |
const BUFFER_SIZE: usize = 512; | |
fn download_content(url: &str) -> Result<String, String> { | |
// Somos um respeitável e conhecido bot | |
let mut headers = hyper::header::Headers::new(); | |
headers.set(hyper::header::UserAgent(ROBOT_NAME.to_string())); | |
// Pega cabeçalhos (e possivelmente algum dado já) | |
let client = hyper::Client::new(); | |
let mut response; | |
match client.get(url).headers(headers).send() { | |
Err(error) => return Err(format!("{:?}", error)), | |
Ok(res) => response = res, | |
} | |
// Cria arquivo para salvar conteúdo | |
let filename = Path::new(&url).file_name().unwrap(); | |
let mut localfile; | |
match File::create(filename) { | |
Err(error) => return Err(format!("{:?}", error)), | |
Ok(filehandle) => localfile = filehandle, | |
} | |
// pega conteúdo e salva em arquivo | |
loop { | |
let mut buffer = [0; BUFFER_SIZE]; | |
match response.read(&mut buffer) { | |
Err(read_error) => return Err(format!("{:?}", read_error)), | |
Ok(bytes_read) => { | |
if bytes_read == 0 { | |
// não tem mais o que ler | |
break; | |
} | |
// vamos tentar escrever o que pegamos | |
match localfile.write(&buffer[0..bytes_read]) { | |
Err(write_error) => return Err(format!("{:?}", write_error)), | |
Ok(bytes_write) => { | |
if bytes_write != bytes_read { | |
return Err("Error in write.".to_string()); | |
} | |
}, | |
} | |
}, | |
} | |
} | |
return Ok(String::from(filename.to_str().unwrap())); | |
} | |
fn main() { | |
// Pega os argumentos, mas ignorando o primeiro | |
// que é o nome do programa. | |
let mut args = env::args(); | |
args.next(); | |
// vetor para as threads que serão criadas | |
let mut workers = vec![]; | |
// Pega o conteúdo de cada URL | |
for url in args { | |
workers.push(thread::spawn(move || { | |
print!("{} - ", url); | |
match download_content(&url) { | |
Err(error) => println!("{:?}", error), | |
Ok(filename) => println!("{:?}", filename), | |
} | |
print!("\n\n"); | |
})); | |
} | |
// espera cada thread acabar | |
for worker in workers { | |
let _ = worker.join(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment