summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 07cf4d6f73638420487e401aac724e46e89cdba8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
extern crate rusqlite;

use blake2::{Blake2b, Digest};
use rusqlite::{params, Connection, Result};
use std::io;
use std::path::Path;

/// Return a hex-encoded string representing the contents of `hash`.
fn hexlify(hash: &[u8]) -> String {
    hash.iter()
        .map(|b| format!("{:x}", b))
        .collect::<Vec<String>>()
        .join("")
}

#[derive(Debug)]
struct TagBase {
    conn: Connection,
}

impl TagBase {
    /// Instantiate a new `TagBase` whose backing database is at `path`.
    fn new(path: &str) -> Result<Self> {
        let conn = Connection::open(path)?;
        conn.execute(
            "CREATE TABLE IF NOT EXISTS images (
                 id       INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
                 blake2   TEXT NOT NULL,
                 filename TEXT NOT NULL,
                 orig_dir TEXT NOT NULL
             )",
            params![],
        )?;
        conn.execute(
            "CREATE TABLE IF NOT EXISTS tags (
                 id   INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
                 name TEXT NOT NULL
             )",
            params![],
        )?;
        conn.execute(
            "CREATE TABLE IF NOT EXISTS mapping (
                 image  INTEGER NOT NULL,
                 tag    INTEGER NOT NULL
             )",
            params![],
        )?;
        Ok(TagBase { conn })
    }

    // TODO: Return a proper error.
    fn import_image(&self, path: &Path) -> Result<()> {
        if path.is_dir() {
            return Err(rusqlite::Error::InvalidQuery);
        }

        let mut file = std::fs::File::open(path).unwrap();
        let mut hasher = Blake2b::new();
        let n = io::copy(&mut file, &mut hasher).unwrap();
        let hash = hexlify(&hasher.result());

        let parsed_or_none = path.file_name().and_then(|os| os.to_str());
        if let (Some(path), Some(file_name)) = (path.to_str(), parsed_or_none) {
            let split_index = path.len() - file_name.len();
            let parent_directory = &path[0..split_index];
            self.conn.execute(
                "INSERT INTO images (sha256, filename, orig_dir) VALUES(?,?,?)",
                params![0, file_name, parent_directory],
            )?;
            Ok(())
        } else {
            Err(rusqlite::Error::InvalidQuery)
        }
    }
}

fn main() {
    let tb = TagBase::new("/tmp/test.db").unwrap();
    tb.import_image(Path::new("/home/jakob/Sync/06fc9ae71549eb4d.jpeg"))
        .unwrap();
    println!("{:?}", tb);
}