Skip to content

Instantly share code, notes, and snippets.

View rippinrobr's full-sized avatar

Rob Rowe rippinrobr

View GitHub Profile
@rippinrobr
rippinrobr / main.rs
Last active June 14, 2018 12:23
Starting the actix system
let sys = actix::System::new("conspiracies-api");
// Start 3 parallel db executors
let addr = SyncArbiter::start(3, || {
DbExecutor(SqliteConnection::establish("database/conspiracies.sqlite3").unwrap())
});
..... Route definitions here .....
let _ = sys.run();
@rippinrobr
rippinrobr / main.rs
Created May 27, 2018 13:28
A reminder of what the chained function calls look like that process the returned value from the actor
// Send message to `DbExecutor` actor
req.state().db.send(GetConspiracy{page_id: page_id.to_owned()})
.from_err()
.and_then(|res| {
match res {
Ok(conspiracy) => Ok(HttpResponse::Ok().json(conspiracy)),
Err(_) => Ok(HttpResponse::NotFound().into())
}
})
.responder()
@rippinrobr
rippinrobr / actors.rs
Last active June 6, 2018 22:32
The code for the retrieving a particular conspiracy
/// The DbExecutor is contains the database connection which will be used by all of the
/// message handlers
pub struct DbExecutor(pub SqliteConnection);
impl Actor for DbExecutor {
type Context = SyncContext<Self>;
}
/// Sent to the DbExecutor to fetch the conspiracy with the given page_id
pub struct GetConspiracy {
@rippinrobr
rippinrobr / main.rs
Last active May 24, 2018 23:07
The updated resource mapping with the default settings
App::with_state(State{db: addr.clone()})
// the default_resource call here uses a closure
// to return 405 Method Not Allowed error for
// all routes
.default_resource(|r| {
r.route().filter(pred::Not(pred::Get()))
.f(|req| HttpResponse::MethodNotAllowed());
})
.resource("/", |r| r.method(http::Method::GET).f(index))
.resource("/conspiracies/{page_id}", |r| r.method(http::Method::GET).a(get_conspiracies_by_id))
@rippinrobr
rippinrobr / main.rs
Created May 24, 2018 22:38
the handler for /conspiracies/{page_id}
/// returns the conspiracy by the given id
fn get_conspiracies_by_id(req: HttpRequest<State>) -> impl Future<Item=HttpResponse, Error=Error> {
let page_id = &req.match_info()["page_id"];
// Send message to `DbExecutor` actor
req.state().db.send(GetConspiracy{page_id: page_id.to_owned()})
.from_err()
.and_then(|res| {
match res {
Ok(conspiracy) => Ok(HttpResponse::Ok().json(conspiracy)),
@rippinrobr
rippinrobr / main.rs
Created May 24, 2018 22:25
Making the calls to Wikipedia to fetch the pages
let links = db::get_links_to_process(&conn, batch_size);
WikiRepo::get_conspiracies(&c, links, title.to_string(), |p2, categories| {
match db::add_conspiracy(&conn, &p2) {
Err(e) => println!("SAVE ERROR: {} {} {}", e ,p2.title, p2.page_id),
Ok(_) => {
let title = &p2.title;
db::add_categories(&conn, categories).unwrap();
db::mark_link_as_processed(&conn, title).expect(&format!("A problem occurred when marking the link '{}' as processed",title));
println!("Added: {} {}", title, p2.page_id)
}
@rippinrobr
rippinrobr / main.rs
Created May 24, 2018 22:23
Adding links to the table to track the fetching of the pages
let page = client.page_from_title(title.to_string());
let links_iter = page.get_links().expect("unable to get the links");
for (i, l) in links_iter.enumerate() {
let lp = LinkProcessed {
title: l.title,
processed: 0,
};
save_action(lp);
}
@rippinrobr
rippinrobr / wiki.rs
Last active May 24, 2018 22:22
discussion of what the function signrature looks like
pub fn get_page_links<'a, F>(client: &'a wikipedia::Wikipedia::<wikipedia::http::default::Client>,
title: String,
save_action: F)
where F: Fn(LinkProcessed) {
@rippinrobr
rippinrobr / main.rs
Last active May 24, 2018 22:20
Getting all of the links from the 'seed' page
if _matches.is_present("get-links") {
WikiRepo::get_page_links(&c, title.to_string(), |link| {
match db::add_link_process(&conn, &link) {
Err(e) => println!("SAVE ERROR: {} {}", e ,link.title),
Ok(_) => println!("Added: {}", link.title)
};
});
}
@rippinrobr
rippinrobr / db.rs
Last active May 24, 2018 22:18
Updates the link record to indicate that it has been processed
pub fn mark_link_as_processed(conn: &SqliteConnection, link_title: &str) ->Result<usize, diesel::result::Error> {
let u_stmt = format!("UPDATE links_processed SET processed=1 WHERE title='{}';", link_title.replace("'", "''"));
let update = sql::<Bool>(&u_stmt);
update.execute(conn)
}