<commit_before>use std::fs;
use std::env;
use std::fs::File;
use std::io::Read;
use std::hash::Hasher;
use std::path::PathBuf;
use std::collections::HashMap;
use std::os::unix::fs::MetadataExt;
use std::collections::hash_map::DefaultHasher;

#[macro_use]
extern crate log;
extern crate env_logger;

struct FileEntry {
    inode: u64,
    dev:  u64,
    path : String,
}

fn collect_files(dir: &String, h: &mut HashMap<u64, Vec<FileEntry>>) {

    let entries = match fs::read_dir(dir) {
        Ok(x) => x,
        _ => {
            warn!("{}: invalid directory", dir);
            return
        },
    };

    for path in  entries.filter( |x| x.is_ok() ).map( |x| x.unwrap().path() )
                .collect::<Vec<PathBuf>>() {
        if let (Some(path_str), Ok(metadata)) =
                (path.to_str(), path.symlink_metadata()) {
            let ft = metadata.file_type();
            if ft.is_symlink() {
                continue;
            } else if ft.is_file() {
                match metadata.len() {
                    0 => continue,
                    i => h.entry(i).or_insert_with(Vec::new)
                          .push(
                           FileEntry{
                               inode : metadata.ino(),
                               dev   : metadata.dev(),
                               path  : String::from(path_str),
                           }),
                };
            } else if ft.is_dir() {
                collect_files(&(String::from(path_str)), h);
            }
        }
    }
}

fn find_duplicates(duplicates: &mut HashMap<u64, Vec<FileEntry>>,
                   vec: &Vec<FileEntry>, thorough: bool ) {
    for file_entry in vec {
        if let Ok(mut file) = File::open(&file_entry.path) {
            let mut contents: Vec<u8> = Vec::new();
            let mut buf: [u8; 1024] = [0; 1024];
            let mut hash: u64 = 0;
            let mut hasher = DefaultHasher::new();
            if thorough {
                if let Ok(_) = file.read_to_end(&mut contents) {
                    hasher.write(&contents[..]);
                    hash = hasher.finish();
                }
            } else {
                if let Ok(nbytes) = file.read(&mut buf) {
                    hasher.write(&buf[..nbytes as usize]);
                    hash = hasher.finish();
                }
            }
            if hash != 0 {
                duplicates.entry(hash).or_insert_with(Vec::new)
                    .push(
                        FileEntry{
                            inode : file_entry.inode,
                            dev   : file_entry.dev,
                            path  : file_entry.path.to_string(),
                        });
            }
        }
    }
}

fn main() {
    env_logger::init().unwrap();

    let args: Vec<String> = env::args().collect();

    // Print out usage if no directories are given.
    if args.len() == 1 || ( args.len() == 2 && args[1] == "--thorough" ) {
        println!("Usage: {} [--thorough] <dir1> [dir2 [dir3 ...]]", args[0]);
        ::std::process::exit(0);
    }

    let mut hmap: HashMap<u64, Vec<FileEntry> > = HashMap::new();

    let mut thorough = false;
    for dir in &args[1..] {
        if dir == "--thorough" {
            thorough = true;
            continue;
        }
        collect_files(dir, &mut hmap);
    }

    // Get rid of all the single entries.
    hmap.retain(|_, v| v.len() >= 2);

    let mut cluster = 1;

    for (key, val) in hmap.iter() {
        let mut duplicates: HashMap<u64, Vec<FileEntry> > = HashMap::new();
        find_duplicates(&mut duplicates, &val, thorough);

        for (hash, vec) in duplicates {
            if vec.len() >= 2 {
                println!("{} files in cluster {} (size: {}, digest: {})",
                         vec.len(), cluster, key, hash);
                // for_each becomes stable v1.22.0 onwards. Should uncomment then.
                //vec.iter().for_each(|f| println!("{}", f.path));
                for file_entry in vec {
                    println!("{}", file_entry.path);
                }
                cluster += 1;
            }
        }
    }
}
<commit_msg>Fix declarations<commit_after>use std::fs;
use std::env;
use std::fs::File;
use std::io::Read;
use std::hash::Hasher;
use std::path::PathBuf;
use std::collections::HashMap;
use std::os::unix::fs::MetadataExt;
use std::collections::hash_map::DefaultHasher;

#[macro_use]
extern crate log;
extern crate env_logger;

struct FileEntry {
    inode: u64,
    dev:  u64,
    path : String,
}

fn collect_files(dir: &String, h: &mut HashMap<u64, Vec<FileEntry>>) {

    let entries = match fs::read_dir(dir) {
        Ok(x) => x,
        _ => {
            warn!("{}: invalid directory", dir);
            return
        },
    };

    for path in  entries.filter( |x| x.is_ok() ).map( |x| x.unwrap().path() )
                .collect::<Vec<PathBuf>>() {
        if let (Some(path_str), Ok(metadata)) =
                (path.to_str(), path.symlink_metadata()) {
            let ft = metadata.file_type();
            if ft.is_symlink() {
                continue;
            } else if ft.is_file() {
                match metadata.len() {
                    0 => continue,
                    i => h.entry(i).or_insert_with(Vec::new)
                          .push(
                           FileEntry{
                               inode : metadata.ino(),
                               dev   : metadata.dev(),
                               path  : String::from(path_str),
                           }),
                };
            } else if ft.is_dir() {
                collect_files(&(String::from(path_str)), h);
            }
        }
    }
}

fn find_duplicates(duplicates: &mut HashMap<u64, Vec<FileEntry>>,
                   vec: &Vec<FileEntry>, thorough: bool ) {
    for file_entry in vec {
        if let Ok(mut file) = File::open(&file_entry.path) {
            let mut hash: u64 = 0;
            let mut hasher = DefaultHasher::new();
            if thorough {
                let mut contents: Vec<u8> = Vec::new();
                if let Ok(_) = file.read_to_end(&mut contents) {
                    hasher.write(&contents[..]);
                    hash = hasher.finish();
                }
            } else {
                let mut buf: [u8; 1024] = [0; 1024];
                if let Ok(nbytes) = file.read(&mut buf) {
                    hasher.write(&buf[..nbytes as usize]);
                    hash = hasher.finish();
                }
            }
            if hash != 0 {
                duplicates.entry(hash).or_insert_with(Vec::new)
                    .push(
                        FileEntry{
                            inode : file_entry.inode,
                            dev   : file_entry.dev,
                            path  : file_entry.path.to_string(),
                        });
            }
        }
    }
}

fn main() {
    env_logger::init().unwrap();

    let args: Vec<String> = env::args().collect();

    // Print out usage if no directories are given.
    if args.len() == 1 || ( args.len() == 2 && args[1] == "--thorough" ) {
        println!("Usage: {} [--thorough] <dir1> [dir2 [dir3 ...]]", args[0]);
        ::std::process::exit(0);
    }

    let mut hmap: HashMap<u64, Vec<FileEntry> > = HashMap::new();

    let mut thorough = false;
    for dir in &args[1..] {
        if dir == "--thorough" {
            thorough = true;
            continue;
        }
        collect_files(dir, &mut hmap);
    }

    // Get rid of all the single entries.
    hmap.retain(|_, v| v.len() >= 2);

    let mut cluster = 1;

    for (key, val) in hmap.iter() {
        let mut duplicates: HashMap<u64, Vec<FileEntry> > = HashMap::new();
        find_duplicates(&mut duplicates, &val, thorough);

        for (hash, vec) in duplicates {
            if vec.len() >= 2 {
                println!("{} files in cluster {} (size: {}, digest: {})",
                         vec.len(), cluster, key, hash);
                // for_each becomes stable v1.22.0 onwards. Should uncomment then.
                //vec.iter().for_each(|f| println!("{}", f.path));
                for file_entry in vec {
                    println!("{}", file_entry.path);
                }
                cluster += 1;
            }
        }
    }
}
<|endoftext|>


<commit_before>/// Rosten track Bring packages in Rust
/// For testing use "TESTPACKAGE-AT-PICKUPPOINT" as tracking number
/// https://www.mybring.com/tracking/api

/// Request parameters
/// Query param     Type        Description
/// q               string      Reference, package number, shipment num to query
/// callback        string      Optional JSONP callback function name
///
/// Endpoints for Base URL
///
/// Method      Endpoint                        Usage
/// GET         /tracking{mediaTypeExtension}   Get information about a shipment
///
/// Request string for JSON would look like tracking.bring.com/tracking.json?q=trackingnumber

extern crate curl;
extern crate clap;
extern crate serde_json;

use std::env;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use curl::easy::Easy;
use std::fmt::Display;
use serde_json::Value;

// Define contents of JSON. Would an enum be better here?

struct Data {
    Firstname: String,
    Lastname: String,
    Age: u32,
    Address: Address,
    PhoneNumber: Vec<String>
}
// Do we need to define everything in tracking.json?
struct Address {
    Street: String,
    City: String,
    Country: String
}

pub fn main() {

    let path = Path::new("/home/stian/projects/rosten/test.json");
    let display = path.display();

    let mut file = match File::open(&path) {
        Err(e) => panic!("unable to open {}: {}", display, e.description()),
        Ok(file) => file,
    };
    let mut buffer = String::new();
    file.read_to_string(&mut buffer).unwrap();
    let data: Value = serde_json::from_str(&buffer).unwrap();
    println!("data: {}", data);

    let obj = data.as_object().unwrap();
    let foo = obj.get("foo").unwrap();
    println!("array? {:?}", foo.as_array());
    println!("u64? {:?}", foo.as_u64());

    for (key, value) in obj.iter() {
        println!("{}: {}", key, match *value {
            Value::String(ref v) => format!("{} (string)", v),
            Value::U64(v) => format!("{} (u64)", v),
            _ => format!("other match")
        });
    }
}

    // TODO Implement match on wanted output instead of .unwrap()
    // println!("{}", json.find_path(&["consignmentSet", "packageSet"]).unwrap());
    // println!("{}", json.find_path(&{"consignmentSet", ["PhoneNumbers"] }).unwrap());

// TODO Handle external GET
//    let mut easy = Easy::new();
//    easy.url(&json_file).unwrap();
//    easy.get("TESTPACKAGE-AT-PICKUPPOINT");

// get_http_body from url
//    let http_body = std::str::from_utf8(http_response.get_http_body()).unwrap_or_else(|err| {
//    panic!("Failed to get response {}; error is {}", url, err); // TODO Error handling
//    });

// import io, os, filecmp // assert_eq!()
// import json, requests
// import argparse

// parser = argparse.ArgumentParser()
// parser.add_argument("sid")
// args = parser.parse_args()

// sid = args.sid // tracking ID

// params = dict(
//             q=sid
//         )
//
// resp = requests.get(url=url, params=params)
// data = json.loads(resp.text)
//
// path = '/home/ix/src/posten/data'
// first = True
// f_i = 0
// f_new = f_old = path + '/' + 'posten-{0}-{1}'.format(sid, f_i) + '.json'
// if os.path.exists(f_new):
//     first = False
//     while os.path.exists(f_new):
//             f_old = path + '/' + 'posten-{0}-{1}'.format(sid, f_i) + '.json'
//             f_i += 1
//             f_new = path + '/' + 'posten-{0}-{1}'.format(sid, f_i) + '.json'
// #print 'f_old: ' + f_old
// #print 'f_new: ' + f_new
//
// # print status for i3
// if not os.path.exists('/tmp/posten'):
//     os.mkdir('/tmp/posten')
//
// e_i = 0
// events = []
// for i in range(0, len(data['consignmentSet'][0]['packageSet'][0]['eventSet'])):
//     events.append(data['consignmentSet'][0]['packageSet'][0]['eventSet'][i]['status'])
// e_i = 0
// while events[e_i] == u'NOTIFICATION_SENT':
//     e_i = e_i + 1
//
// with open('/tmp/posten/' + sid, 'w') as status_file:
//     status_file.write(events[e_i])
//
// with open(f_new, 'w') as outfile:
//      json.dump(data, outfile, sort_keys = True, indent = 4, ensure_ascii=False)
//
// if not first:
//     if filecmp.cmp(f_old, f_new):
//         print 'no change'
//         os.remove(f_new)
//     else:
//         print 'new entry'
<commit_msg>attempt to iterate<commit_after>/// Rosten track Bring packages in Rust
/// For testing use "TESTPACKAGE-AT-PICKUPPOINT" as tracking number
/// https://www.mybring.com/tracking/api

/// Request parameters
/// Query param     Type        Description
/// q               string      Reference, package number, shipment num to query
/// callback        string      Optional JSONP callback function name
///
/// Endpoints for Base URL
///
/// Method      Endpoint                        Usage
/// GET         /tracking{mediaTypeExtension}   Get information about a shipment
///
/// Request string for JSON would look like tracking.bring.com/tracking.json?q=trackingnumber

extern crate curl;
extern crate clap;
extern crate serde_json;

use std::env;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use curl::easy::Easy;
use std::fmt::Display;
use serde_json::Value;

// Define contents of JSON. Would an enum be better here?

struct Data {
    Firstname: String,
    Lastname: String,
    Age: u32,
    Address: Address,
    PhoneNumber: Vec<String>
}
// Do we need to define everything in tracking.json?
struct Address {
    Street: String,
    City: String,
    Country: String
}

pub fn main() {

    let path = Path::new("/home/stian/projects/rosten/tracking.json");
    let display = path.display();
    let mut file = match File::open(&path) {
        Err(e) => panic!("unable to open {}: {}", display, e.description()),
        Ok(file) => file,
    };

    let mut buffer = String::new();
    file.read_to_string(&mut buffer).unwrap();

   let data: Value = serde_json::from_str(&buffer).unwrap();
   let values = data.as_object()
       .and_then(|object| object.get("[consignmentSet]"))
       .and_then(|values| values.as_object())
       .unwrap_or_else(|| {
           panic!("Failed to get obj value from JSON");
       });

    for (key, value) in values.iter() {
        let results = value.find("consignmentId")
            .and_then(|value| value.as_object())
            .unwrap_or_else(|| {
                panic!("Failed to get value");
            });
        println!("{} -> {:?}", key, results);
    }
}

// TODO Handle external GET
//    let mut easy = Easy::new();
//    easy.url(&json_file).unwrap();
//    easy.get("TESTPACKAGE-AT-PICKUPPOINT");

// get_http_body from url
//    let http_body = std::str::from_utf8(http_response.get_http_body()).unwrap_or_else(|err| {
//    panic!("Failed to get response {}; error is {}", url, err); // TODO Error handling
//    });

// import io, os, filecmp // assert_eq!()
// import json, requests
// import argparse

// parser = argparse.ArgumentParser()
// parser.add_argument("sid")
// args = parser.parse_args()

// sid = args.sid // tracking ID

// params = dict(
//             q=sid
//         )
//
// resp = requests.get(url=url, params=params)
// data = json.loads(resp.text)
//
// path = '/home/ix/src/posten/data'
// first = True
// f_i = 0
// f_new = f_old = path + '/' + 'posten-{0}-{1}'.format(sid, f_i) + '.json'
// if os.path.exists(f_new):
//     first = False
//     while os.path.exists(f_new):
//             f_old = path + '/' + 'posten-{0}-{1}'.format(sid, f_i) + '.json'
//             f_i += 1
//             f_new = path + '/' + 'posten-{0}-{1}'.format(sid, f_i) + '.json'
// #print 'f_old: ' + f_old
// #print 'f_new: ' + f_new
//
// # print status for i3
// if not os.path.exists('/tmp/posten'):
//     os.mkdir('/tmp/posten')
//
// e_i = 0
// events = []
// for i in range(0, len(data['consignmentSet'][0]['packageSet'][0]['eventSet'])):
//     events.append(data['consignmentSet'][0]['packageSet'][0]['eventSet'][i]['status'])
// e_i = 0
// while events[e_i] == u'NOTIFICATION_SENT':
//     e_i = e_i + 1
//
// with open('/tmp/posten/' + sid, 'w') as status_file:
//     status_file.write(events[e_i])
//
// with open(f_new, 'w') as outfile:
//      json.dump(data, outfile, sort_keys = True, indent = 4, ensure_ascii=False)
//
// if not first:
//     if filecmp.cmp(f_old, f_new):
//         print 'no change'
//         os.remove(f_new)
//     else:
//         print 'new entry'
<|endoftext|>


<commit_before>use docopt::Docopt;
use liquid::Template;
use std::env;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::path::PathBuf;
use std::process::exit;
use walkdir::WalkDir;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

const USAGE: &'static str = "
Usage: limpet [options] <source> <dest>
       limpet [options] --recursive <dir>
       limpet (--help | --version)

Options:
    -h, --help              Show this message.
    -v, --version           Show the version of limpet.
    -r, --recursive         Scan for files with extension from given directory.  Outputs to same directory.
    -e, --extension=EXT     Override the default extention for recursive scans [default: liquid].
";

#[derive(RustcDecodable)]
struct Args {
    arg_source: String,
    arg_dest: String,
    flag_extension: String,
    flag_recursive: bool,
    arg_dir: String,
    // flag_help: bool,  Don't need this - it's automatically processed by docopt
    flag_version: bool,
}

fn process_single_file(
    source: &PathBuf,
    destination: &PathBuf,
    context: &mut liquid::Object,
) -> Result<(), String> {
    // Read in full template as string
    match File::open(source.as_path()) {
        Ok(mut f) => {
            // Double check that the source isn't a directory
            if let Ok(metadata) = source.metadata() {
                if metadata.is_dir() {
                    return Err(format!("Source file {:?} can't be a directory.  Did you mean to use the --recursive option?", &source));
                }

            // TODO: save permissions to set file with later?
            // let permissions = metadata.permissions();
            } else {
                return Err(format!(
                    "Problem reading source file metadata <{:?}>: Could be permissions.",
                    &source
                ));
            }

            // Read template and process
            let mut contents: Vec<u8> = Vec::new();
            let _ = f
                .read_to_end(&mut contents)
                .expect("Couldn't read whole file");
            // println!("Read {} bytes", size);
            let template_string = String::from_utf8(contents).unwrap();
            let template: Template = liquid::ParserBuilder::with_stdlib()
                .build()
                .unwrap()
                .parse(&template_string)
                .unwrap();
            if let Ok(output_string) = template.render(context) {
                // println!("rendered file is {:?}", &output_string);
                match File::create(&destination) {
                    Ok(mut output_file) => {
                        if let Err(e) = output_file.write_all(&output_string.into_bytes()) {
                            return Err(format!(
                                "Error writing file {}: {}",
                                destination.to_str().unwrap(),
                                &e
                            ));
                        }
                        // I don't think we need to flush/close in rust.
                        // output_file.flush();
                        return Ok(());
                    }
                    Err(e) => {
                        return Err(format!(
                            "Destination file <{}>: {}",
                            destination.to_str().unwrap(),
                            &e
                        ));
                    }
                }
            } else {
                return Err(format!(
                    "Unknown error while rendering the template for {}",
                    source.to_str().unwrap()
                ));
            }
        }
        Err(e) => {
            return Err(format!("{:?}", e));
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    // Build a data context for the liquid templates
    let mut data = liquid::Object::new();
    for (key, value) in env::vars() {
        // println!("key: {} value: {}", &key, &value);
        data.insert(key.into(), liquid::model::Value::scalar(value));
    }

    if args.flag_version {
        println!("limpet v{}", VERSION);
        exit(0);
    }

    if args.flag_recursive {
        // Do recursive scan starting at <dir>
        println!("Scanning directory {}...", &args.arg_dir);
        for entry in WalkDir::new(&args.arg_dir) {
            match entry {
                Ok(ref e) => {
                    // println!("Scanning directory {} ", e.path().display());
                    if e.file_type().is_file() {
                        let p = e.path();
                        // println!("{} is a file", p.display());
                        if let Some(ext) = p.extension() {
                            if ext.to_str() == Some(&args.flag_extension) {
                                if let Some(parent) = p.parent() {
                                    let mut dest = PathBuf::from(parent);
                                    if let Some(file_stem) = p.file_stem() {
                                        dest.push(file_stem);
                                        // println!("Processing file {} into {}", p.display(), dest.display());
                                        match process_single_file(
                                            &p.to_path_buf(),
                                            &dest,
                                            &mut data,
                                        ) {
                                            Ok(_) => {
                                                println!(
                                                    "Processed: {} => {}",
                                                    p.to_path_buf().display(),
                                                    dest.display()
                                                );
                                            }
                                            Err(e) => {
                                                println!(
                                                    "ERROR processing file {}: {:?}",
                                                    p.display(),
                                                    e
                                                );
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                Err(ref e) => {
                    println!("ERROR processing directory entry {:?}: {:?}", entry, e);
                }
            }
        }
    } else {
        // Do single file
        let source = PathBuf::from(&args.arg_source);
        let dest = PathBuf::from(&args.arg_dest);
        match process_single_file(&source.to_path_buf(), &dest, &mut data) {
            Ok(_) => {
                println!("Processed: {} => {}", source.display(), dest.display());
                exit(0);
            }
            Err(e) => {
                println!("ERROR processing file {}: {:?}", source.display(), e);
                exit(1);
            }
        }
    }
}
<commit_msg>Print error output from the semver library when it has errors<commit_after>use docopt::Docopt;
use liquid::Template;
use std::env;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::path::PathBuf;
use std::process::exit;
use walkdir::WalkDir;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

const USAGE: &'static str = "
Usage: limpet [options] <source> <dest>
       limpet [options] --recursive <dir>
       limpet (--help | --version)

Options:
    -h, --help              Show this message.
    -v, --version           Show the version of limpet.
    -r, --recursive         Scan for files with extension from given directory.  Outputs to same directory.
    -e, --extension=EXT     Override the default extention for recursive scans [default: liquid].
";

#[derive(RustcDecodable)]
struct Args {
    arg_source: String,
    arg_dest: String,
    flag_extension: String,
    flag_recursive: bool,
    arg_dir: String,
    // flag_help: bool,  Don't need this - it's automatically processed by docopt
    flag_version: bool,
}

fn process_single_file(
    source: &PathBuf,
    destination: &PathBuf,
    context: &mut liquid::Object,
) -> Result<(), String> {
    // Read in full template as string
    match File::open(source.as_path()) {
        Ok(mut f) => {
            // Double check that the source isn't a directory
            if let Ok(metadata) = source.metadata() {
                if metadata.is_dir() {
                    return Err(format!("Source file {:?} can't be a directory.  Did you mean to use the --recursive option?", &source));
                }

            // TODO: save permissions to set file with later?
            // let permissions = metadata.permissions();
            } else {
                return Err(format!(
                    "Problem reading source file metadata <{:?}>: Could be permissions.",
                    &source
                ));
            }

            // Read template and process
            let mut contents: Vec<u8> = Vec::new();
            let _ = f
                .read_to_end(&mut contents)
                .expect("Couldn't read whole file");
            // println!("Read {} bytes", size);
            let template_string = String::from_utf8(contents).unwrap();
            let template_result = liquid::ParserBuilder::with_stdlib()
                .build()
                .unwrap()
                .parse(&template_string);

            let template: Template = match template_result {
                Ok(t) => t,
                Err(e) => return Err(e.to_string()),
            };

            match template.render(context) {
                Ok(output_string) => {
                    match File::create(&destination) {
                        Ok(mut output_file) => {
                            if let Err(e) = output_file.write_all(&output_string.into_bytes()) {
                                return Err(format!(
                                    "Error writing file {}: {}",
                                    destination.to_str().unwrap(),
                                    &e
                                ));
                            }
                            // I don't think we need to flush/close in rust.
                            // output_file.flush();
                            return Ok(());
                        }
                        Err(e) => {
                            return Err(format!(
                                "Destination file <{}>: {}",
                                destination.to_str().unwrap(),
                                &e
                            ));
                        }
                    }
                }
                Err(e) => {
                    return Err(format!(
                        "Unknown error while rendering the template for {}: {}",
                        source.to_str().unwrap(),
                        e.to_string(),
                    ));
                }
            }
        }
        Err(e) => {
            return Err(format!("{:?}", e));
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    // Build a data context for the liquid templates
    let mut data = liquid::Object::new();
    for (key, value) in env::vars() {
        // println!("key: {} value: {}", &key, &value);
        data.insert(key.into(), liquid::model::Value::scalar(value));
    }

    if args.flag_version {
        println!("limpet v{}", VERSION);
        exit(0);
    }

    if args.flag_recursive {
        // Do recursive scan starting at <dir>
        println!("Scanning directory {}...", &args.arg_dir);
        for entry in WalkDir::new(&args.arg_dir) {
            match entry {
                Ok(ref e) => {
                    // println!("Scanning directory {} ", e.path().display());
                    if e.file_type().is_file() {
                        let p = e.path();
                        // println!("{} is a file", p.display());
                        if let Some(ext) = p.extension() {
                            if ext.to_str() == Some(&args.flag_extension) {
                                if let Some(parent) = p.parent() {
                                    let mut dest = PathBuf::from(parent);
                                    if let Some(file_stem) = p.file_stem() {
                                        dest.push(file_stem);
                                        // println!("Processing file {} into {}", p.display(), dest.display());
                                        match process_single_file(
                                            &p.to_path_buf(),
                                            &dest,
                                            &mut data,
                                        ) {
                                            Ok(_) => {
                                                println!(
                                                    "Processed: {} => {}",
                                                    p.to_path_buf().display(),
                                                    dest.display()
                                                );
                                            }
                                            Err(e) => {
                                                println!(
                                                    "ERROR processing file {}: {:?}",
                                                    p.display(),
                                                    e
                                                );
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                Err(ref e) => {
                    println!("ERROR processing directory entry {:?}: {:?}", entry, e);
                }
            }
        }
    } else {
        // Do single file
        let source = PathBuf::from(&args.arg_source);
        let dest = PathBuf::from(&args.arg_dest);
        match process_single_file(&source.to_path_buf(), &dest, &mut data) {
            Ok(_) => {
                println!("Processed: {} => {}", source.display(), dest.display());
                exit(0);
            }
            Err(e) => {
                println!("ERROR processing file {}: {:}", source.display(), e);
                exit(1);
            }
        }
    }
}
<|endoftext|>


<commit_before>use casile::{cli::*, i18n};
use clap::{FromArgMatches, IntoApp};
use std::error;

fn main() -> Result<(), Box<dyn error::Error>> {
    let app = Cli::into_app().version(env!("VERGEN_SEMVER"));
    let matches = app.get_matches();
    let args = Cli::from_arg_matches(&matches);
    let config = casile::Config {
        verbose: args.verbose,
        debug: args.debug,
        locale: i18n::Locale::negotiate(args.language),
    };
    match args.subcommand {
        Subcommand::Make { target } => casile::make::run(&config, target),
        Subcommand::Setup { path } => casile::setup::run(&config, path),
        Subcommand::Other(input) => casile::shell::run(&config, input),
    }
}
<commit_msg>chore(cli): Set version relative to lightweight git tags<commit_after>use casile::{cli::*, i18n};
use clap::{FromArgMatches, IntoApp};
use std::error;

fn main() -> Result<(), Box<dyn error::Error>> {
    let app = Cli::into_app().version(env!("VERGEN_SEMVER_LIGHTWEIGHT"));
    let matches = app.get_matches();
    let args = Cli::from_arg_matches(&matches);
    let config = casile::Config {
        verbose: args.verbose,
        debug: args.debug,
        locale: i18n::Locale::negotiate(args.language),
    };
    match args.subcommand {
        Subcommand::Make { target } => casile::make::run(&config, target),
        Subcommand::Setup { path } => casile::setup::run(&config, path),
        Subcommand::Other(input) => casile::shell::run(&config, input),
    }
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate git2;

use git2::{Repository, Remote, Error};
use clap::{Arg, App};

const E_NO_GIT_REPO : i32 = 1;

fn main() {
    let options = App::new("git-submerge")
                          .version("0.1")
                          .author("Alexander Batischev <eual.jp@gmail.com>")
                          .about("Merges git submodule into the repo as if it was that way from the start")
                          .arg(Arg::with_name("SUBMODULE_DIR")
                               .help("The submodule to merge")
                               .required(true)
                               .index(1))
                          .get_matches();
    // We can safely use unwrap() here because if the option is empty, Clap would've already shown
    // the error message and aborted.
    let submodule_dir = options.value_of("SUBMODULE_DIR").unwrap();
    println!("Merging {}...", submodule_dir);

    let repo = match Repository::open(".") {
        Ok(repo) => repo,
        Err(e) => {
            eprintln!("Couldn't find Git repo in the current directory: {}", e.message());
            std::process::exit(E_NO_GIT_REPO);
        },
    };

    // 1. Add submodule as a remote
    let mut remote = add_remote(&repo, submodule_dir).unwrap();
    // 2. Fetch submodule's history
    remote.fetch(&[], None, None);
    // 3. Check out submodule's branch under some unique name (UUID?)
    // 4. Rewrite submodule branch's history, moving everything under a single directory named
    //    after the submodule
    // 5. Run through main branch's history and note down commit IDs where submodule was touched,
    //    along with submodule's commit ID
    // 6. Run through old and new submodule's history (in lockstep) and note down new commit IDs of
    //    the commits that were referenced in the main repo
    // 7. Remove submodule's remote
    // 8. Run through master's history, doing two things:
    //      8.1 updating the tree to contain the relevant tree from submodule
    //      8.2 in commits that used to update the submodule, add a parent pointing to appropriate
    //          commit in new submodule history
}

fn add_remote<'a>(repo : &'a Repository, submodule_name : &str) -> Result<Remote<'a>, Error> {
    // TODO: randomize remote's name or at least check that it doesn't exist already
    let url = String::from("./") + submodule_name;
    repo.remote(submodule_name, &url)
}
<commit_msg>unwrap() → expect(…)<commit_after>extern crate clap;
extern crate git2;

use git2::{Repository, Remote, Error};
use clap::{Arg, App};

const E_NO_GIT_REPO : i32 = 1;

fn main() {
    let options = App::new("git-submerge")
                          .version("0.1")
                          .author("Alexander Batischev <eual.jp@gmail.com>")
                          .about("Merges git submodule into the repo as if it was that way from the start")
                          .arg(Arg::with_name("SUBMODULE_DIR")
                               .help("The submodule to merge")
                               .required(true)
                               .index(1))
                          .get_matches();
    // We can safely use unwrap() here because if the option is empty, Clap would've already shown
    // the error message and aborted.
    let submodule_dir = options.value_of("SUBMODULE_DIR").unwrap();
    println!("Merging {}...", submodule_dir);

    let repo = match Repository::open(".") {
        Ok(repo) => repo,
        Err(e) => {
            eprintln!("Couldn't find Git repo in the current directory: {}", e.message());
            std::process::exit(E_NO_GIT_REPO);
        },
    };

    // 1. Add submodule as a remote
    let mut remote = add_remote(&repo, submodule_dir).expect("Couldn't add a remote");
    // 2. Fetch submodule's history
    remote.fetch(&[], None, None);
    // 3. Check out submodule's branch under some unique name (UUID?)
    // 4. Rewrite submodule branch's history, moving everything under a single directory named
    //    after the submodule
    // 5. Run through main branch's history and note down commit IDs where submodule was touched,
    //    along with submodule's commit ID
    // 6. Run through old and new submodule's history (in lockstep) and note down new commit IDs of
    //    the commits that were referenced in the main repo
    // 7. Remove submodule's remote
    // 8. Run through master's history, doing two things:
    //      8.1 updating the tree to contain the relevant tree from submodule
    //      8.2 in commits that used to update the submodule, add a parent pointing to appropriate
    //          commit in new submodule history
}

fn add_remote<'a>(repo : &'a Repository, submodule_name : &str) -> Result<Remote<'a>, Error> {
    // TODO: randomize remote's name or at least check that it doesn't exist already
    let url = String::from("./") + submodule_name;
    repo.remote(submodule_name, &url)
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate cobalt;
extern crate getopts;
extern crate env_logger;
extern crate notify;
extern crate ghp;

#[macro_use]
extern crate nickel;

#[macro_use]
extern crate log;

use getopts::Options;
use std::env;
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use nickel::{Nickel, Options as NickelOptions, StaticFilesHandler};
use ghp::import_dir;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;

fn print_version() {
    println!("0.2.0");
}

fn print_usage(opts: Options) {
    let usage = concat!("\n\tbuild -- build the cobalt project at the source dir, -i --import will import the site to the gh-pages branch",
                        "\n\tserve -- build and serve the cobalt project at the source dir",
                        "\n\twatch -- build, serve, and watch the project at the source dir",
                        "\n\timport -- moves the contents of the dest folder to the gh-pages branch");
    println!("{}", opts.usage(usage));
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();

    opts.optopt("s", "source", "Source folder, Default: ./", "");
    opts.optopt("d", "destination", "Destination folder, Default: ./", "");
    opts.optopt("c",
                "config",
                "Config file to use, Default: .cobalt.yml",
                "");
    opts.optopt("l",
                "layouts",
                "\tLayout templates folder, Default: _layouts/",
                "");
    opts.optopt("p", "posts", "Posts folder, Default: _posts/", "");
    opts.optopt("P", "port", "Port to serve from, Default: 3000", "");
    opts.optopt("b", "branch", "Branch that will be used to import the site to, Default: gh-pages", "");
    opts.optopt("m", "message", "Commit message that will be used on import, Default: cobalt site import", "");

    opts.optflag("", "debug", "Log verbose (debug level) information");
    opts.optflag("", "trace", "Log ultra-verbose (trace level) information");
    opts.optflag("", "silent", "Suppress all output");
    opts.optflag("i", "import", "Import after build to gh-pages branch");
    opts.optflag("h", "help", "Print this help menu");
    opts.optflag("v", "version", "Display version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return;
    }

    if matches.opt_present("version") {
        print_version();
        return;
    }

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);
    builder.filter(None, LogLevelFilter::Info);

    if matches.opt_present("debug") {
        builder.filter(None, LogLevelFilter::Debug);
    }

    if matches.opt_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.opt_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = match matches.opt_str("config") {
        Some(config) => config,
        None => "./.cobalt.yml".to_owned(),
    };

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        Default::default()
    };

    if let Some(source) = matches.opt_str("s") {
        config.source = source;
    };

    if let Some(dest) = matches.opt_str("d") {
        config.dest = dest;
    };

    if let Some(layouts) = matches.opt_str("layouts") {
        config.layouts = layouts;
    };

    if let Some(posts) = matches.opt_str("posts") {
        config.posts = posts;
    };

    let command = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(opts);
        return;
    };

    // Check for port and set port variable to it
    let port = matches.opt_str("port").unwrap_or("3000".to_owned());
    let branch = matches.opt_str("branch").unwrap_or("gh-pages".to_owned());
    let message = matches.opt_str("message").unwrap_or("cobalt site import".to_owned());
    let should_import = matches.opt_present("import");

    match command.as_ref() {
        "build" => {
            build(&config);
            if should_import {
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                info!("Rebuilding cobalt site...");
                                build(&config);
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            import(&config, &branch, &message);
        }

        _ => {
            print_usage(opts);
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);
    let mut server = Nickel::new();
    server.options = NickelOptions::default().output_on_listen(false);

    server.utilize(StaticFilesHandler::new(dest));

    let ip = "127.0.0.1:".to_owned() + port;
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");
    server.listen(&*ip);
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<commit_msg>removed extra documentation of import flag<commit_after>#![deny(warnings)]

extern crate cobalt;
extern crate getopts;
extern crate env_logger;
extern crate notify;
extern crate ghp;

#[macro_use]
extern crate nickel;

#[macro_use]
extern crate log;

use getopts::Options;
use std::env;
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use nickel::{Nickel, Options as NickelOptions, StaticFilesHandler};
use ghp::import_dir;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;

fn print_version() {
    println!("0.2.0");
}

fn print_usage(opts: Options) {
    let usage = concat!("\n\tbuild -- build the cobalt project at the source dir",
                        "\n\tserve -- build and serve the cobalt project at the source dir",
                        "\n\twatch -- build, serve, and watch the project at the source dir",
                        "\n\timport -- moves the contents of the dest folder to the gh-pages branch");
    println!("{}", opts.usage(usage));
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();

    opts.optopt("s", "source", "Source folder, Default: ./", "");
    opts.optopt("d", "destination", "Destination folder, Default: ./", "");
    opts.optopt("c",
                "config",
                "Config file to use, Default: .cobalt.yml",
                "");
    opts.optopt("l",
                "layouts",
                "\tLayout templates folder, Default: _layouts/",
                "");
    opts.optopt("p", "posts", "Posts folder, Default: _posts/", "");
    opts.optopt("P", "port", "Port to serve from, Default: 3000", "");
    opts.optopt("b", "branch", "Branch that will be used to import the site to, Default: gh-pages", "");
    opts.optopt("m", "message", "Commit message that will be used on import, Default: cobalt site import", "");

    opts.optflag("", "debug", "Log verbose (debug level) information");
    opts.optflag("", "trace", "Log ultra-verbose (trace level) information");
    opts.optflag("", "silent", "Suppress all output");
    opts.optflag("i", "import", "Import after build to gh-pages branch");
    opts.optflag("h", "help", "Print this help menu");
    opts.optflag("v", "version", "Display version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return;
    }

    if matches.opt_present("version") {
        print_version();
        return;
    }

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);
    builder.filter(None, LogLevelFilter::Info);

    if matches.opt_present("debug") {
        builder.filter(None, LogLevelFilter::Debug);
    }

    if matches.opt_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.opt_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = match matches.opt_str("config") {
        Some(config) => config,
        None => "./.cobalt.yml".to_owned(),
    };

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        Default::default()
    };

    if let Some(source) = matches.opt_str("s") {
        config.source = source;
    };

    if let Some(dest) = matches.opt_str("d") {
        config.dest = dest;
    };

    if let Some(layouts) = matches.opt_str("layouts") {
        config.layouts = layouts;
    };

    if let Some(posts) = matches.opt_str("posts") {
        config.posts = posts;
    };

    let command = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(opts);
        return;
    };

    // Check for port and set port variable to it
    let port = matches.opt_str("port").unwrap_or("3000".to_owned());
    let branch = matches.opt_str("branch").unwrap_or("gh-pages".to_owned());
    let message = matches.opt_str("message").unwrap_or("cobalt site import".to_owned());
    let should_import = matches.opt_present("import");

    match command.as_ref() {
        "build" => {
            build(&config);
            if should_import {
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                info!("Rebuilding cobalt site...");
                                build(&config);
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            import(&config, &branch, &message);
        }

        _ => {
            print_usage(opts);
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);
    let mut server = Nickel::new();
    server.options = NickelOptions::default().output_on_listen(false);

    server.utilize(StaticFilesHandler::new(dest));

    let ip = "127.0.0.1:".to_owned() + port;
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");
    server.listen(&*ip);
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![feature(static_in_const)]

#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use std::path::PathBuf;
use std::process::Command;
use syntax::ast;

use clippy_lints::utils::cargo;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(&mut self,
                      matches: &getopts::Matches,
                      sopts: &config::Options,
                      cfg: &ast::CrateConfig,
                      descriptions: &rustc_errors::registry::Registry,
                      output: ErrorOutputType)
                      -> Compilation {
        self.default.early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(&mut self,
                matches: &getopts::Matches,
                sopts: &config::Options,
                cfg: &ast::CrateConfig,
                odir: &Option<PathBuf>,
                ofile: &Option<PathBuf>,
                descriptions: &rustc_errors::registry::Registry)
                -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(&mut self,
                     matches: &getopts::Matches,
                     sess: &Session,
                     input: &Input,
                     odir: &Option<PathBuf>,
                     ofile: &Option<PathBuf>)
                     -> Compilation {
        self.default.late_callback(matches, sess, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(state.session, state.krate.as_ref().expect("at this compilation stage the krate must be parsed").span);
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry { early_lint_passes,
                                                           late_lint_passes,
                                                           lint_groups,
                                                           llvm_passes,
                                                           attributes,
                                                           mir_passes,
                                                           .. } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.mir_passes.borrow_mut().extend(mir_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    --features               Features to compile for the package
    -V, --version            Print version info and exit

Other options are the same as `cargo rustc`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

#[allow(print_stdout)]
fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }
    if std::env::args().any(|a| a == "--version" || a == "-V") {
        println!("{}", env!("CARGO_PKG_VERSION"));
        return;
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`

        let manifest_path_arg = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));

        let mut metadata = cargo::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)).expect("could not obtain cargo metadata");

        assert_eq!(metadata.version, 1);

        let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));

        let current_dir = std::env::current_dir();

        let package_index = metadata.packages.iter()
            .position(|package| {
                let package_manifest_path = Path::new(&package.manifest_path);
                if let Some(ref manifest_path) = manifest_path {
                    package_manifest_path == manifest_path
                } else {
                    let current_dir = current_dir.as_ref().expect("could not read current directory");
                    let package_manifest_directory = package_manifest_path.parent().expect("could not find parent directory of package manifest");
                    package_manifest_directory == current_dir
                }
            })
            .expect("could not find matching package");
        let package = metadata.packages.remove(package_index);
        for target in package.targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path) {
                        std::process::exit(code);
                    }
                } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                    if let Err(code) = process(vec![format!("--{}", first), target.name].into_iter().chain(args), &dep_path) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself

        let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
        let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
        let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
            format!("{}/toolchains/{}", home, toolchain)
        } else {
            option_env!("SYSROOT")
                .map(|s| s.to_owned())
                .or(Command::new("rustc")
                    .arg("--print")
                    .arg("sysroot")
                    .output()
                    .ok()
                    .and_then(|out| String::from_utf8(out.stdout).ok())
                    .map(|s| s.trim().to_owned()))
                .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust")
        };

        // this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
        // without having to pass --sysroot or anything
        let mut args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
            env::args().collect()
        } else {
            env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
        };

        // this check ensures that dependencies are built but not linted and the final crate is
        // linted but not built
        args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);

        let mut ccc = ClippyCompilerCalls::new(env::args().any(|s| s == "-Zno-trans"));
        let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);

        if let Err(err_count) = result {
            if err_count > 0 {
                std::process::exit(1);
            }
        }
    }
}

fn process<P, I>(old_args: I, dep_path: P) -> Result<(), i32>
    where P: AsRef<Path>,
          I: Iterator<Item = String>
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push("-Zno-trans".to_owned());
    args.push("--cfg".to_owned());
    args.push(r#"feature="cargo-clippy""#.to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn().expect("could not run cargo")
        .wait().expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<commit_msg>Add '--version' flag and use version and help flags when called as 'cargo-clippy'<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![feature(static_in_const)]

#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use std::path::PathBuf;
use std::process::{self, Command};
use syntax::ast;
use std::io::{self, Write};

use clippy_lints::utils::cargo;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(&mut self,
                      matches: &getopts::Matches,
                      sopts: &config::Options,
                      cfg: &ast::CrateConfig,
                      descriptions: &rustc_errors::registry::Registry,
                      output: ErrorOutputType)
                      -> Compilation {
        self.default.early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(&mut self,
                matches: &getopts::Matches,
                sopts: &config::Options,
                cfg: &ast::CrateConfig,
                odir: &Option<PathBuf>,
                ofile: &Option<PathBuf>,
                descriptions: &rustc_errors::registry::Registry)
                -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(&mut self,
                     matches: &getopts::Matches,
                     sess: &Session,
                     input: &Input,
                     odir: &Option<PathBuf>,
                     ofile: &Option<PathBuf>)
                     -> Compilation {
        self.default.late_callback(matches, sess, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(state.session, state.krate.as_ref().expect("at this compilation stage the krate must be parsed").span);
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry { early_lint_passes,
                                                           late_lint_passes,
                                                           lint_groups,
                                                           llvm_passes,
                                                           attributes,
                                                           mir_passes,
                                                           .. } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.mir_passes.borrow_mut().extend(mir_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    --features               Features to compile for the package
    -V, --version            Print version info and exit

Other options are the same as `cargo rustc`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

#[allow(print_stdout)]
fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

#[allow(print_stdout)]
fn show_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}

#[cfg_attr(feature = "cargo-clippy", allow(print_stdout))]
pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }
    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`

        let manifest_path_arg = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));

        let mut metadata = if let Ok(metadata) = cargo::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)) {
            metadata
        } else {
            let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata."));
            process::exit(101);
        };

        assert_eq!(metadata.version, 1);

        let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));

        let current_dir = std::env::current_dir();

        let package_index = metadata.packages.iter()
            .position(|package| {
                let package_manifest_path = Path::new(&package.manifest_path);
                if let Some(ref manifest_path) = manifest_path {
                    package_manifest_path == manifest_path
                } else {
                    let current_dir = current_dir.as_ref().expect("could not read current directory");
                    let package_manifest_directory = package_manifest_path.parent().expect("could not find parent directory of package manifest");
                    package_manifest_directory == current_dir
                }
            })
            .expect("could not find matching package");
        let package = metadata.packages.remove(package_index);
        for target in package.targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path) {
                        std::process::exit(code);
                    }
                } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                    if let Err(code) = process(vec![format!("--{}", first), target.name].into_iter().chain(args), &dep_path) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself

        let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
        let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
        let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
            format!("{}/toolchains/{}", home, toolchain)
        } else {
            option_env!("SYSROOT")
                .map(|s| s.to_owned())
                .or(Command::new("rustc")
                    .arg("--print")
                    .arg("sysroot")
                    .output()
                    .ok()
                    .and_then(|out| String::from_utf8(out.stdout).ok())
                    .map(|s| s.trim().to_owned()))
                .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust")
        };

        // this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
        // without having to pass --sysroot or anything
        let mut args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
            env::args().collect()
        } else {
            env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
        };

        // this check ensures that dependencies are built but not linted and the final crate is
        // linted but not built
        args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);

        let mut ccc = ClippyCompilerCalls::new(env::args().any(|s| s == "-Zno-trans"));
        let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);

        if let Err(err_count) = result {
            if err_count > 0 {
                std::process::exit(1);
            }
        }
    }
}

fn process<P, I>(old_args: I, dep_path: P) -> Result<(), i32>
    where P: AsRef<Path>,
          I: Iterator<Item = String>
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push("-Zno-trans".to_owned());
    args.push("--cfg".to_owned());
    args.push(r#"feature="cargo-clippy""#.to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn().expect("could not run cargo")
        .wait().expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<|endoftext|>


<commit_before>extern crate image;

use std::fs::File;
use std::path::Path;
use std::env;
use image::GenericImage;

//should be a trait.  I am not sure how to impliment one for only Vec <Vec <bool>> and not Vec <T>
fn boundless_insert(y: i64, x: i64, value: bool, img: &mut Vec<Vec <bool>>) {
	let mut tx = x;
	let mut ty = y;
	for i in 0..img.len(){
		let mut ttx = x;
		while ttx < 0 {
			img[i].insert(0, false);
			ttx += 1;
		}
		assert!(((x < 0) && (ttx == 0)) || (x == ttx), "Expected ttx = zero or ttx = x.  Found {}", ttx);
		while img[i].len() <= ttx as usize {
			img[i].push(false);
		}
		tx = ttx
	}
	let mut row:Vec <bool> = Vec::new();
	for i in 0..img[0].len() {
		row.push(false);
	}
	while ty < 0 {
		img.insert(0, row.clone());
		ty += 1;
	}
	assert!(((y < 0) && (ty == 0)) || (y == ty), "Expected ty = zero or ty = y.  Found {}", ty);
	while img.len() <= ty as usize {
		img.push(row.clone())
	}
	img[ty as usize][tx as usize] = value;
}

struct ImgBlob {
	blob_type: u8, //0: object, 1: line
	top_right: [usize; 2],
	middle: [usize; 2],
	text: String,
	bitmap: Vec <Vec <bool>>
}

impl ImgBlob {
	fn from_top_right(x: usize, y: usize, claim: &mut Vec <Vec <bool>>, img: &Vec <Vec <bool>>) -> Option<ImgBlob>{
		let mut right = x;
		let mut top = y; //pretty sure that this is not supposed to change and can be eliminated
		let mut bitmap: Vec <Vec <bool>> = Vec::new();
		let mut queue: Vec <[usize; 2]> = Vec::new();
		claim[y][x] = true;
		queue.push([y+1, x]);
		queue.push([y, x+1]);
		bitmap.push(vec![true]);
		while queue.len() > 0 {
			let tempx = queue[0][1];
			let tempy = queue[0][0];
			if (tempy < img.len()) && (tempx < img[0].len()) && (tempy > 0) && (tempx > 0) {
				if img[tempy][tempx] && !(claim[tempy][tempx]){
					boundless_insert(((tempy as i64)-(top as i64)), ((tempx as i64)-(right as i64)), true, &mut bitmap);
					if tempx < right {
						right = tempx;
					}
					if tempy < top {
						top = tempy;
					}
					claim[tempy][tempx] = true;
					if queue[0][1] > top {
						queue.push([tempy-1, tempx]);
					}
					queue.push([tempy, tempx-1]);
					queue.push([tempy+1, tempx]);
					queue.push([tempy, tempx+1]);
				}
			}
			queue.remove(0);
		}
		if (bitmap[0].len() + bitmap.len() > 6) && (bitmap.len() > 3) && (bitmap[0].len() > 3) {
			println!("Found: {} x {}", bitmap[0].len(), bitmap.len());
			Some(ImgBlob {
				blob_type: if (bitmap[0].len() / bitmap.len()) > 10 {1} else {0},
				top_right: [right, top],
				middle: [right+(bitmap[0].len()/2), top+(bitmap.len()/2)],
				text: String::from(""),
				bitmap: bitmap
			})
		} else {
			None
		}
	}
}

struct Section {
	Heading: ImgBlob,
	blobs: Vec <ImgBlob>
}

struct Chapter {
	heading: ImgBlob,
	blobs: Vec <ImgBlob>,
	Sections: Vec <Section>
}

fn main() {
	let mut claimed: Vec <Vec <bool>> = Vec::new();
	let mut thresh: Vec <Vec <bool>> = Vec::new();
	let mut rblobs: Vec <ImgBlob> = Vec::new();
	let mut gblobs: Vec <ImgBlob> = Vec::new();
	let mut bblobs: Vec <ImgBlob> = Vec::new();
	let img = image::open(&Path::new("target.jpg")).unwrap();
	let mut row:Vec <bool> = Vec::new();
	for x in 0..img.width() {
		row.push(false);
	}
	for y in 0..img.height() {
		claimed.push(row.clone());
		thresh.push(row.clone());
	}
	let rgbimg = img.to_rgb();
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[0] > 140) && (pixel[1] <= 170) && (pixel[2] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => rblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished R");
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[1] > 140) && (pixel[0] <= 170) && (pixel[2] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => gblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished G");
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[2] > 140) && (pixel[1] <= 170) && (pixel[0] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => bblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished B");
}
<commit_msg>Removed extra structs and attributes also style fixes<commit_after>extern crate image;

use std::fs::File;
use std::path::Path;
use std::env;
use image::GenericImage;

//should be a trait.  I am not sure how to impliment one for only Vec <Vec <bool>> and not Vec <T>
fn boundless_insert(y: i64, x: i64, value: bool, img: &mut Vec<Vec <bool>>) {
	let mut tx = x;
	let mut ty = y;
	for i in 0..img.len(){
		let mut ttx = x;
		while ttx < 0 {
			img[i].insert(0, false);
			ttx += 1;
		}
		assert!(((x < 0) && (ttx == 0)) || (x == ttx), "Expected ttx = zero or ttx = x.  Found {}", ttx);
		while img[i].len() <= ttx as usize {
			img[i].push(false);
		}
		tx = ttx
	}
	let mut row:Vec <bool> = Vec::new();
	for i in 0..img[0].len() {
		row.push(false);
	}
	while ty < 0 {
		img.insert(0, row.clone());
		ty += 1;
	}
	assert!(((y < 0) && (ty == 0)) || (y == ty), "Expected ty = zero or ty = y.  Found {}", ty);
	while img.len() <= ty as usize {
		img.push(row.clone())
	}
	img[ty as usize][tx as usize] = value;
}

struct ImgBlob {
	blob_type: u8, //0: object, 1: line
	top_right: [usize; 2],
	middle: [usize; 2],
	bitmap: Vec <Vec <bool>>
}

impl ImgBlob {
	fn from_top_right(x: usize, y: usize, claim: &mut Vec <Vec <bool>>, img: &Vec <Vec <bool>>) -> Option<ImgBlob>{
		let mut right = x;
		let mut top = y; //pretty sure that this is not supposed to change and can be eliminated
		let mut bitmap: Vec <Vec <bool>> = Vec::new();
		let mut queue: Vec <[usize; 2]> = Vec::new();
		claim[y][x] = true;
		queue.push([y+1, x]);
		queue.push([y, x+1]);
		bitmap.push(vec![true]);
		while queue.len() > 0 {
			let tempx = queue[0][1];
			let tempy = queue[0][0];
			if (tempy < img.len()) && (tempx < img[0].len()) && (tempy > 0) && (tempx > 0) {
				if img[tempy][tempx] && !(claim[tempy][tempx]){
					boundless_insert(((tempy as i64)-(top as i64)), ((tempx as i64)-(right as i64)), true, &mut bitmap);
					if tempx < right {
						right = tempx;
					}
					if tempy < top {
						top = tempy;
					}
					claim[tempy][tempx] = true;
					if queue[0][1] > top {
						queue.push([tempy-1, tempx]);
					}
					queue.push([tempy, tempx-1]);
					queue.push([tempy+1, tempx]);
					queue.push([tempy, tempx+1]);
				}
			}
			queue.remove(0);
		}
		if (bitmap[0].len() + bitmap.len() > 6) && (bitmap.len() > 3) && (bitmap[0].len() > 3) {
			println!("Found: {} x {}", bitmap[0].len(), bitmap.len());
			Some(ImgBlob {
				blob_type: if (bitmap[0].len() / bitmap.len()) > 10 {1} else {0},
				top_right: [right, top],
				middle: [right+(bitmap[0].len()/2), top+(bitmap.len()/2)],
				bitmap: bitmap
			})
		} else {
			None
		}
	}
}

struct Chapter {
	heading: ImgBlob,
	blobs: Vec <ImgBlob>,
	subchapters: Vec <Chapter>
}

fn main() {
	let mut claimed: Vec <Vec <bool>> = Vec::new();
	let mut thresh: Vec <Vec <bool>> = Vec::new();
	let mut rblobs: Vec <ImgBlob> = Vec::new();
	let mut gblobs: Vec <ImgBlob> = Vec::new();
	let mut bblobs: Vec <ImgBlob> = Vec::new();
	let img = image::open(&Path::new("target.jpg")).unwrap();
	let mut row:Vec <bool> = Vec::new();
	for x in 0..img.width() {
		row.push(false);
	}
	for y in 0..img.height() {
		claimed.push(row.clone());
		thresh.push(row.clone());
	}
	let rgbimg = img.to_rgb();
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[0] > 140) && (pixel[1] <= 170) && (pixel[2] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => rblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished R");
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[1] > 140) && (pixel[0] <= 170) && (pixel[2] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => gblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished G");
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[2] > 140) && (pixel[1] <= 170) && (pixel[0] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => bblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished B");
}
<|endoftext|>


<commit_before>// fs.rs
use std::env; // env::home_dir()
use std::fs; // fs::read_dir()
//use std::path::Path;
use std::path::PathBuf;

fn main() {
   //let mut idg_dir_path = PathBuf::from("~/Files/Doom/idgames");
   // create an empty PathBuf
   let mut idg_dir = PathBuf::new();
   // call `home_dir()` and act on what it returns
   match env::home_dir() {
      //Some(idg_dir) => println!("{}", idg_dir.display()),
      // home_dir() returned something
      Some(home_dir) => idg_dir = home_dir,
      // home_dir() returned nothing
      None => println!("Can't obtain home directory path!"),
   }

   // append more directories on to idg_dir
   idg_dir.push("Files");
   idg_dir.push("Doom");
   idg_dir.push("idgames");

   // try and read the contents of idg_dir/
   match fs::read_dir(idg_dir) {
      // nope, can't read for some reason
      Err(why) => println!("! {:?}", why.kind()),
      // yep, can read contents of idg_dir, see what items are there
      Ok(items) => for item in items {
         // Result<Metadata>
         match item.unwrap().metadata() {
            Err(why) => println!("! {:?}", why.kind()),
            //Ok(metadata) => println!("- {:?}", metadata.file_type()),
            //Ok(metadata) => println!("- {:?}", metadata.permissions()),
            // is this a file, directory, or ???
            Ok(metadata) => {
               println!("- {:?}", metadata.is_dir());
            }
         }
      }
   }
}
<commit_msg>src/main.rs: added ItemType enum and FoundItem struct<commit_after>// fs.rs
use std::env; // env::home_dir()
use std::fs; // fs::read_dir()
//use std::path::Path;
use std::path::PathBuf;

enum ItemType {
   Dir,
   File,
   Other,
}

struct FoundItem {
   item_type: ItemType,
   item_path: PathBuf,
}

fn main() {
   //let mut idg_dir_path = PathBuf::from("~/Files/Doom/idgames");
   // create an empty PathBuf
   let mut idg_dir = PathBuf::new();
   // call `home_dir()` and act on what it returns
   match env::home_dir() {
      //Some(idg_dir) => println!("{}", idg_dir.display()),
      // home_dir() returned something
      Some(home_dir) => idg_dir = home_dir,
      // home_dir() returned nothing
      None => println!("Can't obtain home directory path!"),
   }

   // append more directories on to idg_dir
   idg_dir.push("Files");
   idg_dir.push("Doom");
   idg_dir.push("idgames");

   // try and read the contents of idg_dir/
   match fs::read_dir(idg_dir) {
      // nope, can't read for some reason
      Err(why) => println!("! {:?}", why.kind()),
      // yep, can read contents of idg_dir, see what items are there
      Ok(items) => for item in items {
         // Result<Metadata>
         match item.unwrap().metadata() {
            Err(why) => println!("! {:?}", why.kind()),
            //Ok(metadata) => println!("- {:?}", metadata.file_type()),
            //Ok(metadata) => println!("- {:?}", metadata.permissions()),
            // is this a file, directory, or ???
            Ok(metadata) => {
               println!("- {:?}", metadata.is_dir());
            }
         }
      }
   }
}
<|endoftext|>


<commit_before>extern crate bip_metainfo;
extern crate chrono;
#[macro_use]
extern crate log;
extern crate pretty_env_logger;
extern crate rustyline;
extern crate hyper;
extern crate url;

use bip_metainfo::MetainfoFile;
use chrono::{TimeZone, UTC};
use rustyline::Editor;
use rustyline::error::ReadlineError;
use hyper::Client;
use url::Url;

use std::io::prelude::*;
use std::fs::File;
use std::str;
use std::string::String;

const HISTORY_FILE: &'static str = ".rustyline.history";

/// Print general information about the torrent.
fn print_metainfo_overview(bytes: &[u8]) {
    let metainfo = MetainfoFile::from_bytes(bytes).unwrap();
    let info = metainfo.info();
    let info_hash_hex = metainfo.info_hash()
        .as_ref()
        .iter()
        .map(|b| format!("{:02X}", b))
        .fold(String::new(), |mut acc, nex| {
            acc.push_str(&nex);
            acc
        });
    let utc_creation_date = metainfo.creation_date().map(|c| UTC.timestamp(c, 0));

    println!("\n\n-----------------------------Metainfo File Overview-----------------------------");

    println!("InfoHash: {}", info_hash_hex);
    println!("Main Tracker: {:?}", metainfo.main_tracker());
    println!("Comment: {:?}", metainfo.comment());
    println!("Creator: {:?}", metainfo.created_by());
    println!("Creation Date: {:?}", utc_creation_date);

    println!("Directory: {:?}", info.directory());
    println!("Piece Length: {:?}", info.piece_length());
    println!("Number Of Pieces: {}", info.pieces().count());
    println!("Number Of Files: {}", info.files().count());
    println!("Total File Size: {}",
             info.files().fold(0, |acc, nex| acc + nex.length()));
}

fn connect_to_tracker(metainfo_file: MetainfoFile, peer_id: &str, port: u16) -> Result<(), String> {
    debug!("connecting to tracker: {:?}", metainfo_file.main_tracker());
    let client = Client::new();
    let mut url = Url::parse(metainfo_file.main_tracker().unwrap()).unwrap();
    let info_hash = metainfo_file.info_hash();
    let info_hash_str = unsafe { str::from_utf8_unchecked(info_hash.as_ref()) };
    url.query_pairs_mut().append_pair("info_hash", &info_hash_str);
    // metainfo_file.info_hash(),
    // "&peer_id=",
    // peer_id,
    // "&port=",
    // port,
    // "&uploaded=0",
    // "&downloaded=0",
    // "&left=",
    // metainfo_file.info().files().fold(0, |acc, nex| acc + nex.length()),
    // "&compact=0",
    // "&event=started");
    debug!("URL {:?}", url);
    // let res = client.get(url);
    //    debug!("Tracker resp {:?}", res);
    Ok(())
}

fn main() {
    pretty_env_logger::init();

    let mut rl = Editor::<()>::new();
    if rl.load_history(HISTORY_FILE).is_err() {
        info!("No previous history!");
    }
    loop {
        let readline = rl.readline("> ");
        match readline {
            Ok(cmd) => {
                rl.add_history_entry(&cmd);

                let cmd = cmd.trim().split(' ').collect::<Vec<&str>>();

                match cmd[0] {
                    "parse" => {
                        if cmd.len() != 2 {
                            error!("usage: parse <torrent file>");
                        } else {
                            let path = cmd[1];
                            debug!("MetainfoFile: {:?}", path);

                            match File::open(path) {
                                Ok(mut f) => {
                                    let mut bytes: Vec<u8> = Vec::new();
                                    f.read_to_end(&mut bytes).unwrap();
                                    print_metainfo_overview(&bytes);
                                    connect_to_tracker(MetainfoFile::from_bytes(&bytes).unwrap(),
                                                       "myid",
                                                       6882 /* .unwrap()
                                                             * .main_tracker() */);
                                }
                                Err(e) => error!("{:?}", e),
                            }
                        }
                    }
                    _ => {}
                }
            }
            Err(ReadlineError::Interrupted) => {
                break;
            }
            Err(ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                error!("Error: {:?}", err);
                break;
            }
        }
    }
    rl.save_history(HISTORY_FILE).unwrap();
}
<commit_msg>handshake returning 200 OK<commit_after>extern crate bip_metainfo;
extern crate chrono;
#[macro_use]
extern crate log;
extern crate pretty_env_logger;
extern crate rustyline;
extern crate hyper;
extern crate url;

use bip_metainfo::MetainfoFile;
use chrono::{TimeZone, UTC};
use rustyline::Editor;
use rustyline::error::ReadlineError;
use hyper::Client;
use url::Url;
use hyper::header::Connection;

use std::io::prelude::*;
use std::fs::File;
use std::str;
use std::string::String;

const HISTORY_FILE: &'static str = ".rustyline.history";

/// Print general information about the torrent.
fn print_metainfo_overview(bytes: &[u8]) {
    let metainfo = MetainfoFile::from_bytes(bytes).unwrap();
    let info = metainfo.info();
    let info_hash_hex = metainfo.info_hash()
        .as_ref()
        .iter()
        .map(|b| format!("{:02X}", b))
        .fold(String::new(), |mut acc, nex| {
            acc.push_str(&nex);
            acc
        });
    let utc_creation_date = metainfo.creation_date().map(|c| UTC.timestamp(c, 0));

    println!("\n\n-----------------------------Metainfo File Overview-----------------------------");

    println!("InfoHash: {}", info_hash_hex);
    println!("Main Tracker: {:?}", metainfo.main_tracker());
    println!("Comment: {:?}", metainfo.comment());
    println!("Creator: {:?}", metainfo.created_by());
    println!("Creation Date: {:?}", utc_creation_date);

    println!("Directory: {:?}", info.directory());
    println!("Piece Length: {:?}", info.piece_length());
    println!("Number Of Pieces: {}", info.pieces().count());
    println!("Number Of Files: {}", info.files().count());
    println!("Total File Size: {}",
             info.files().fold(0, |acc, nex| acc + nex.length()));
}

fn connect_to_tracker(metainfo_file: MetainfoFile, peer_id: &str, port: u16) -> Result<(), String> {
    debug!("connecting to tracker: {:?}", metainfo_file.main_tracker());
    let client = Client::new();
    let mut url = Url::parse(metainfo_file.main_tracker().unwrap()).unwrap();
    let info_hash = metainfo_file.info_hash();
    let info_hash_str = unsafe { str::from_utf8_unchecked(info_hash.as_ref()) };
    url.query_pairs_mut().append_pair("info_hash", &info_hash_str);
    url.query_pairs_mut().append_pair("peer_id", "-TR2920-utffmgat89lc");
    url.query_pairs_mut().append_pair("port", &(port.to_string()));
    url.query_pairs_mut().append_pair("uploaded", "0");
    url.query_pairs_mut().append_pair("downloaded", "0");
    let total_len = metainfo_file.info().files().fold(0, |acc, nex| acc + nex.length());
    url.query_pairs_mut().append_pair("left", &(total_len.to_string()));
    url.query_pairs_mut().append_pair("compact", "1");
    url.query_pairs_mut().append_pair("event", "started");
    debug!("URL {:?}", url);
    let res = client.get(url).header(Connection::close()).send().unwrap();
    debug!("Resp {:?}", res);
    Ok(())
}

fn main() {
    pretty_env_logger::init();

    let mut rl = Editor::<()>::new();
    if rl.load_history(HISTORY_FILE).is_err() {
        info!("No previous history!");
    }
    loop {
        let readline = rl.readline("> ");
        match readline {
            Ok(cmd) => {
                rl.add_history_entry(&cmd);

                let cmd = cmd.trim().split(' ').collect::<Vec<&str>>();

                match cmd[0] {
                    "parse" => {
                        if cmd.len() != 2 {
                            error!("usage: parse <torrent file>");
                        } else {
                            let path = cmd[1];
                            debug!("MetainfoFile: {:?}", path);

                            match File::open(path) {
                                Ok(mut f) => {
                                    let mut bytes: Vec<u8> = Vec::new();
                                    f.read_to_end(&mut bytes).unwrap();
                                    print_metainfo_overview(&bytes);
                                    connect_to_tracker(MetainfoFile::from_bytes(&bytes).unwrap(),
                                                       "myid",
                                                       6882 /* .unwrap()
                                                             * .main_tracker() */);
                                }
                                Err(e) => error!("{:?}", e),
                            }
                        }
                    }
                    _ => {}
                }
            }
            Err(ReadlineError::Interrupted) => {
                break;
            }
            Err(ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                error!("Error: {:?}", err);
                break;
            }
        }
    }
    rl.save_history(HISTORY_FILE).unwrap();
}
<|endoftext|>