<commit_before>extern crate chrono;
extern crate hyper;
extern crate iron;
extern crate mount;
extern crate router;
extern crate rustc_serialize;
extern crate staticfile;
extern crate urlencoded;

use self::chrono::UTC;
use self::hyper::header::ContentType;
use self::hyper::mime::{Mime, TopLevel, SubLevel};
use self::iron::prelude::*;
use self::iron::status;
use self::mount::Mount;
use self::router::Router;
use self::rustc_serialize::json;
use self::rustc_serialize::json::{ToJson, Json};
use self::staticfile::Static;
use self::urlencoded::UrlEncodedBody;
use record_backend::{RecordRepository, RecordRepositoryError};
use config;
use std::any::Any;
use std::collections::BTreeMap;
use std::path::Path;
use worker::Record;

#[derive(Debug, Clone, RustcDecodable, RustcEncodable)]
pub struct Config {
  address: String,
  webapp_path: String,
  websockets: bool,
  password: String
}

pub struct HttpServer<R> {
  config: Config,
  backend: R,
  started_at: chrono::DateTime<UTC>
}

#[derive(Debug, Clone, RustcDecodable, RustcEncodable)]
struct ServerResponse {
  ip: String,
  hostname: String,
  version: String,
  started_at: String,
  websockets: bool
}

struct JobsResponse {
  job: Vec<Record>
}

impl ToJson for JobsResponse {

  fn to_json(&self) -> Json {
    let mut data = BTreeMap::new();
    data.insert("job".to_string(), self.job.to_json());
    Json::Object(data)
  }

}

impl <R: RecordRepository + Clone + Send + Sync + Any> HttpServer<R> {

  pub fn new (config: Config, backend: R) -> HttpServer <R> {
    HttpServer { config: config, backend: backend, started_at: UTC::now() }
  }

  pub fn listen (&mut self) {
    let mut router = Router::new();
    let mut mount = Mount::new();

    {
      let hostname = self.config.address.clone();
      let version = String::from(config::VERSION);
      let started_at = self.started_at.to_rfc3339().clone();
      let websockets = self.config.websockets;

      router.get("/api/server", move |req: &mut Request| {
        let ip = format!("{}", req.local_addr).to_string();
        let server = ServerResponse {
          ip: ip, hostname: hostname.clone(), version: version.clone(), started_at: started_at.clone(), websockets: websockets
        };
        let response_data : String = json::encode(&server).unwrap();
        let mut response = Response::with((status::Ok, response_data));
        response.headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));
        Ok(response)
      });
    }

    {
      let password = <PASSWORD>;
      router.post("/api/auth", move |req: &mut Request| {
        match req.get_ref::<UrlEncodedBody>() {
          Ok(ref body) => {
            if !body.contains_key("password") {
              return Ok(Response::with((status::BadRequest, "")))
            }
            if body.get("password").unwrap()[0] != password {
              return Ok(Response::with((status::Unauthorized, "")))
            }
            Ok(Response::with((status::Ok, "")))
          },
          Err(ref e) => {
            Ok(Response::with((status::BadRequest, "")))
          }
        };
      });
    }

    {
      let backend = self.backend.clone();
      router.get("/api/jobs", move |req: &mut Request| {
        match backend.fetch_limit(30, 0) {
          Err(RecordRepositoryError::CannotDenormalizeRecord) => {
            let json = "{\"message\": \"Cannot denormalize records from database\"}";
            let mut response = Response::with((status::InternalServerError, json));
            response.headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));
            Ok(response)
          },
          Err(_) => {
            let mut response = Response::with((status::InternalServerError, "{\"message\": \"Unknown error\" }"));
            response.headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));
            Ok(response)<commit_msg>try auth<commit_after>extern crate chrono;
extern crate hyper;
extern crate iron;
extern crate mount;
extern crate router;
extern crate rustc_serialize;
extern crate staticfile;
extern crate urlencoded;

use self::chrono::UTC;
use self::hyper::header::ContentType;
use self::hyper::mime::{Mime, TopLevel, SubLevel};
use self::iron::prelude::*;
use self::iron::status;
use self::mount::Mount;
use self::router::Router;
use self::rustc_serialize::json;
use self::rustc_serialize::json::{ToJson, Json};
use self::staticfile::Static;
use self::urlencoded::UrlEncodedBody;
use record_backend::{RecordRepository, RecordRepositoryError};
use config;
use std::any::Any;
use std::collections::BTreeMap;
use std::path::Path;
use worker::Record;

#[derive(Debug, Clone, RustcDecodable, RustcEncodable)]
pub struct Config {
  address: String,
  webapp_path: String,
  websockets: bool,
  password: <PASSWORD>
}

pub struct HttpServer<R> {
  config: Config,
  backend: R,
  started_at: chrono::DateTime<UTC>
}

#[derive(Debug, Clone, RustcDecodable, RustcEncodable)]
struct ServerResponse {
  ip: String,
  hostname: String,
  version: String,
  started_at: String,
  websockets: bool
}

struct JobsResponse {
  job: Vec<Record>
}

impl ToJson for JobsResponse {

  fn to_json(&self) -> Json {
    let mut data = BTreeMap::new();
    data.insert("job".to_string(), self.job.to_json());
    Json::Object(data)
  }

}

impl <R: RecordRepository + Clone + Send + Sync + Any> HttpServer<R> {

  pub fn new (config: Config, backend: R) -> HttpServer <R> {
    HttpServer { config: config, backend: backend, started_at: UTC::now() }
  }

  pub fn listen (&mut self) {
    let mut router = Router::new();
    let mut mount = Mount::new();

    {
      let hostname = self.config.address.clone();
      let version = String::from(config::VERSION);
      let started_at = self.started_at.to_rfc3339().clone();
      let websockets = self.config.websockets;

      router.get("/api/server", move |req: &mut Request| {
        let ip = format!("{}", req.local_addr).to_string();
        let server = ServerResponse {
          ip: ip, hostname: hostname.clone(), version: version.clone(), started_at: started_at.clone(), websockets: websockets
        };
        let response_data : String = json::encode(&server).unwrap();
        let mut response = Response::with((status::Ok, response_data));
        response.headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));
        Ok(response)
      });
    }

    {
      let password = <PASSWORD>;
      router.post("/api/auth", move |req: &mut Request| {
        match req.get_ref::<UrlEncodedBody>() {
          Ok(ref body) => {
            if !body.contains_key("password") {
              return Ok(Response::with((status::BadRequest, "")))
            }
            if body.get("password").unwrap()[0] != password {
              return Ok(Response::with((status::Unauthorized, "")))
            }
            Ok(Response::with((status::Ok, "")))
          },
          Err(_) => {
            Ok(Response::with((status::BadRequest, "")))
          }
        };
      });
    }

    {
      let backend = self.backend.clone();
      router.get("/api/jobs", move |req: &mut Request| {
        match backend.fetch_limit(30, 0) {
          Err(RecordRepositoryError::CannotDenormalizeRecord) => {
            let json = "{\"message\": \"Cannot denormalize records from database\"}";
            let mut response = Response::with((status::InternalServerError, json));
            response.headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));
            Ok(response)
          },
          Err(_) => {
            let mut response = Response::with((status::InternalServerError, "{\"message\": \"Unknown error\" }"));
            response.headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));
            Ok(response)
{'fraction_non_alphanumeric': 0.1561822125813449, 'fraction_numerical': 0.0020415975500829397, 'mean_word_length': 3.3471991125901277, 'pattern_counts': {'":': 4, '<': 20, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4187546', 'n_tokens_mistral': 2409, 'n_tokens_neox': 2363, 'n_words': 541}