fm 0.0.1.rc1 → 0.0.1.rc2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7d0f4d34c704b38b5d784fe3997b9091baf88a98
4
- data.tar.gz: 29584d1d119fb84b545ffbcdaef0b0cd8889e519
3
+ metadata.gz: 79737935b4d50e7abb22c6bb7dfb5eb7763c71c0
4
+ data.tar.gz: f46f80372be4fabd3d187954737f7fbcc9117e85
5
5
  SHA512:
6
- metadata.gz: cfa1ff8a82c72590c3107be92a483ac155478afe26a6d87ba3b6e99da42466faec71bd6f20e94e1fe4ba4c47eaae2207e9afc125242fb5d3c5468ce732e6471f
7
- data.tar.gz: c600dc7a08dcb26ace4c6f0886689e19fa35ea09b0e93116fb402bb924051f158bf1730ea80f02422d04ed0ef4c3497134dc8a857b5b079b7bb0bb56a93cc0dc
6
+ metadata.gz: 544af8ebb7d73431aa7bbd8b70c8c14e2705ccb5bc2815afeacb5a774b3f7bbf5e0f1e4dba94ab20984364d0f8fa4a37ba418c124e8eb06c6fa522cdc83b4eba
7
+ data.tar.gz: f10e15da4f1567374950598ad291c60d9f5a0c5dc78ed570ee9570fa037c81fa2195b64a50a90105af97a007c209d28d589973f6114321b99f5f78ea692d6b09
data/bin/fm CHANGED
@@ -6,9 +6,25 @@ require 'fm'
6
6
  def usage
7
7
  <<EOS
8
8
  fm #{FM::VERSION}
9
- EOS
10
9
 
10
+ usage: fm <command> [args]
11
+
12
+ Available fm commands:
13
+ index Update index of the storage.
14
+ EOS
11
15
  end
12
16
 
13
17
 
14
- puts usage
18
+ if ARGV.size == 0
19
+ $stderr << usage
20
+ exit
21
+ end
22
+
23
+ cmd = ARGV.shift
24
+ case cmd
25
+ when "index"
26
+ FM.cmd_index(ARGV.clone)
27
+ else
28
+ $stderr << "fm: '#{cmd}' is not a fm command.\n"
29
+ exit
30
+ end
data/lib/fm.rb CHANGED
@@ -1 +1,2 @@
1
1
  require 'fm/version'
2
+ require 'fm/index'
data/lib/fm/file.rb ADDED
@@ -0,0 +1,15 @@
1
+ module FM
2
+
3
+ class FMFile
4
+ attr_reader :fsize
5
+ attr_reader :digest
6
+ attr_reader :path
7
+
8
+ def initialize(fsize, path, digest)
9
+ @fsize = fsize
10
+ @digest = digest
11
+ @path = path
12
+ end
13
+ end
14
+
15
+ end
data/lib/fm/index.rb ADDED
@@ -0,0 +1,131 @@
1
+ require 'digest/md5'
2
+ require 'fileutils'
3
+ require 'optparse'
4
+ require 'yaml'
5
+
6
+ require 'fm/file'
7
+ require 'fm/match'
8
+
9
+
10
+ DBFILE = ENV['HOME'] + '/.fm/fdata.db'
11
+
12
+
13
+ module FM
14
+
15
+ def cmd_index(argv)
16
+
17
+ banner = "usage: fm index [options] <PATH>"
18
+ options = {
19
+ dbfile: DBFILE,
20
+ }
21
+ OptionParser.new do |opts|
22
+ opts.banner = banner
23
+
24
+ opts.on "-h", "--help", "Show this message." do
25
+ puts opts
26
+ exit
27
+ end
28
+ end.parse!(argv)
29
+
30
+ if argv.size != 1
31
+ $stderr << "#{banner}\n"
32
+ exit
33
+ end
34
+
35
+
36
+ puts "Loading DB #{options[:dbfile]} ..."
37
+ t0 = Time.now
38
+ h = {}
39
+ needupdate = true
40
+ if File.exists?(options[:dbfile])
41
+ obj = YAML::load(File.read(options[:dbfile]))
42
+ if obj.is_a?(Hash)
43
+ h = obj
44
+ needupdate = false
45
+ end
46
+ end
47
+ t1 = Time.now
48
+ puts "Loaded DB in #{(t1-t0).round(2)}s."
49
+
50
+ indexpath = argv[0]
51
+ nnewfiles = 0
52
+ nskipfiles = 0
53
+ ndupfiles = 0
54
+ nfailfiles = 0
55
+ puts "Indexing #{indexpath} ..."
56
+ t0 = Time.now
57
+
58
+ for fpath in Dir.glob("#{indexpath}/**/*", File::FNM_DOTMATCH).select { |e| e.force_encoding("binary"); File.ftype(e) == "file" && has_folder?(".git", e) == false && has_folder?(".hg", e) == false }
59
+ begin
60
+ fpath = File.realpath(fpath).force_encoding("binary")
61
+ fsize = File.size(fpath)
62
+
63
+ if fsize == 0
64
+ nskipfiles += 1
65
+ puts "[SKIP]: #{fpath}"
66
+ next
67
+ end
68
+
69
+ # Lazy index the file.
70
+ if h[fsize].nil?
71
+ h[fsize] = fpath
72
+ needupdate = true
73
+ nnewfiles += 1
74
+ puts "[NEW]: #{fpath} nil"
75
+ else
76
+ if h[fsize].is_a?(String)
77
+ p = h[fsize]
78
+ if p == fpath
79
+ ndupfiles += 1
80
+ puts "[DUP]: #{fpath}"
81
+ puts " #{p}"
82
+ next
83
+ end
84
+
85
+ d = Digest::MD5.hexdigest(File.read(p))
86
+ h[fsize] = { d => FMFile.new(fsize, p, d) }
87
+ needupdate = true
88
+ end
89
+ digest = Digest::MD5.hexdigest(File.read(fpath))
90
+ if h[fsize][digest].nil?
91
+ h[fsize][digest] = FMFile.new(fsize, fpath, digest)
92
+ needupdate = true
93
+ nnewfiles += 1
94
+ puts "[NEW]: #{fpath} #{digest}"
95
+ else
96
+ ndupfiles += 1
97
+ puts "[DUP]: #{fpath}"
98
+ puts " #{h[fsize][digest].path}"
99
+ end
100
+ end
101
+ rescue StandardError => e
102
+ nfailfiles += 1
103
+ puts "[FAIL]: file=\"#{fpath}\" #{e.message}"
104
+ end
105
+ end
106
+ t1 = Time.now
107
+ puts "Indexing completed in #{(t1-t0).round(2)}s."
108
+
109
+ puts "Indexed:"
110
+ puts " NEW: #{nnewfiles}"
111
+ puts " DUP: #{ndupfiles}"
112
+ puts " SKIP: #{nskipfiles}"
113
+ puts " FAIL: #{nfailfiles}"
114
+
115
+ if needupdate
116
+ puts "Updating DB #{options[:dbfile]} ..."
117
+ t0 = Time.now
118
+ FileUtils.mkdir_p(File.dirname(options[:dbfile]))
119
+ File.write(options[:dbfile], YAML::dump(h))
120
+ t1 = Time.now
121
+ puts "Updated DB in #{(t1-t0).round(2)}s."
122
+ else
123
+ puts "Skip updating DB."
124
+ end
125
+
126
+ end
127
+
128
+
129
+ module_function :cmd_index
130
+
131
+ end
data/lib/fm/match.rb ADDED
@@ -0,0 +1,11 @@
1
+ module FM
2
+
3
+ def has_folder?(folder, path)
4
+ pos = (path =~ /^#{folder}\/|^#{folder}$|\/#{folder}\/|\/#{folder}$/)
5
+ pos != nil
6
+ end
7
+
8
+
9
+ module_function :has_folder?
10
+
11
+ end
data/lib/fm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module FM
2
- VERSION = '0.0.1.rc1'
2
+ VERSION = '0.0.1.rc2'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.rc1
4
+ version: 0.0.1.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ShinYee
@@ -53,6 +53,9 @@ files:
53
53
  - bin/fm
54
54
  - fm.gemspec
55
55
  - lib/fm.rb
56
+ - lib/fm/file.rb
57
+ - lib/fm/index.rb
58
+ - lib/fm/match.rb
56
59
  - lib/fm/version.rb
57
60
  homepage: http://github.com/xman/ruby-fm
58
61
  licenses: