Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

hash.rs 1.9 KB

You have to be logged in to leave a comment. Sign In
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
83
84
85
86
  1. use structopt::StructOpt;
  2. use std::io;
  3. use std::fs::File;
  4. use std::path::PathBuf;
  5. use std::mem::drop;
  6. use log::*;
  7. use indicatif::{ProgressBar, ProgressStyle};
  8. use postgres::Connection;
  9. use sha1::Sha1;
  10. use anyhow::Result;
  11. use super::Command;
  12. use crate::db;
  13. const PB_STYLE: &'static str = "{prefix}: {elapsed_precise} {bar} {percent}% {bytes}/{total_bytes} (eta: {eta})";
  14. /// Concatenate one or more files with a progress bar
  15. #[derive(StructOpt, Debug)]
  16. #[structopt(name="hash")]
  17. pub struct Hash {
  18. #[structopt(flatten)]
  19. db: db::DbOpts,
  20. /// Input file
  21. #[structopt(name = "FILE", parse(from_os_str))]
  22. infiles: Vec<PathBuf>
  23. }
  24. trait Hasher: io::Write {
  25. fn finish(self) -> String;
  26. }
  27. struct H {
  28. sha: Sha1
  29. }
  30. impl Hasher for H {
  31. fn finish(self) -> String {
  32. self.sha.hexdigest()
  33. }
  34. }
  35. impl io::Write for H {
  36. fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  37. self.sha.update(buf);
  38. Ok(buf.len())
  39. }
  40. fn flush(&mut self) -> io::Result<()> {
  41. Ok(())
  42. }
  43. }
  44. fn save_hash(db: &mut Connection, file: &str, hash: &str) -> Result<()> {
  45. info!("saving {}: {}", file, hash);
  46. let tx = db.transaction()?;
  47. tx.execute("DELETE FROM source_file WHERE filename = $1", &[&file])?;
  48. tx.execute("INSERT INTO source_file (filename, checksum) VALUES ($1, $2)", &[&file, &hash])?;
  49. tx.commit()?;
  50. Ok(())
  51. }
  52. impl Command for Hash {
  53. fn exec(self) -> Result<()> {
  54. let mut db = self.db.open()?;
  55. for inf in self.infiles {
  56. let inf = inf.as_path();
  57. let fstr = inf.to_str().unwrap();
  58. info!("opening file {}", fstr);
  59. let fs = File::open(inf)?;
  60. let pb = ProgressBar::new(fs.metadata().unwrap().len());
  61. pb.set_style(ProgressStyle::default_bar().template(PB_STYLE));
  62. pb.set_prefix(fstr);
  63. let mut pbr = pb.wrap_read(fs);
  64. let mut hash = H { sha: Sha1::new() };
  65. io::copy(&mut pbr, &mut hash)?;
  66. drop(pbr);
  67. let hash = hash.finish();
  68. save_hash(&mut db, &fstr, &hash)?;
  69. }
  70. Ok(())
  71. }
  72. }
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...