dircat 0.1.12 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. data/LICENSE.txt +1 -1
  2. data/README.md +31 -6
  3. data/bin/dircat +5 -1
  4. data/bin/scat +9 -0
  5. data/dircat.gemspec +48 -15
  6. data/examples/example.rb +2 -1
  7. data/lib/dircat.rb +29 -34
  8. data/lib/dircat/cat_on_sqlite/cat_on_sqlite.rb +177 -0
  9. data/lib/dircat/cat_on_sqlite/directory_visitor.rb +106 -0
  10. data/lib/dircat/cat_on_sqlite/migration/00_create_dircat_properties.rb +13 -0
  11. data/lib/dircat/cat_on_sqlite/migration/01_create_categories.rb +12 -0
  12. data/lib/dircat/cat_on_sqlite/migration/02_create_images.rb +16 -0
  13. data/lib/dircat/cat_on_sqlite/migration/03_create_items.rb +23 -0
  14. data/lib/dircat/cat_on_sqlite/migration/04_create_taggings.rb +13 -0
  15. data/lib/dircat/cat_on_sqlite/migration/05_create_tags.rb +13 -0
  16. data/lib/dircat/cat_on_sqlite/model/category.rb +16 -0
  17. data/lib/dircat/cat_on_sqlite/model/image.rb +24 -0
  18. data/lib/dircat/cat_on_sqlite/model/item.rb +19 -0
  19. data/lib/dircat/cat_on_sqlite/model/tag.rb +58 -0
  20. data/lib/dircat/cat_on_sqlite/model/tagging.rb +9 -0
  21. data/lib/dircat/cat_on_sqlite/simple_cataloger_error.rb +9 -0
  22. data/lib/dircat/cat_on_sqlite_cli/cli_cat.rb +25 -0
  23. data/lib/dircat/cat_on_sqlite_cli/cli_server.rb +65 -0
  24. data/lib/dircat/cat_on_sqlite_cli/cmd_create.rb +56 -0
  25. data/lib/dircat/cat_on_sqlite_cli/cmd_list.rb +72 -0
  26. data/lib/dircat/cat_on_sqlite_cli/cmd_server.rb +62 -0
  27. data/lib/dircat/cat_on_sqlite_cli/cmd_update.rb +49 -0
  28. data/lib/dircat/{cat.rb → cat_on_yaml/cat_on_yaml.rb} +22 -10
  29. data/lib/dircat/cat_on_yaml/entry.rb +64 -0
  30. data/lib/dircat/{cli → cat_on_yaml_cli}/cli_dircat.rb +0 -0
  31. data/lib/dircat/{cli → cat_on_yaml_cli}/command_build.rb +53 -12
  32. data/lib/dircat/{cli → cat_on_yaml_cli}/command_diff.rb +4 -4
  33. data/lib/dircat/{cli → cat_on_yaml_cli}/command_query.rb +16 -2
  34. data/lib/dircat/config.rb +25 -0
  35. data/lib/dircat/extensions.rb +26 -0
  36. data/lib/dircat/server/helpers.rb +60 -0
  37. data/lib/dircat/server/my_static.rb +40 -0
  38. data/lib/dircat/server/web_server.rb +176 -0
  39. data/lib/dircat/version.rb +2 -1
  40. data/lib/dircat_on_sqlite.rb +31 -0
  41. data/lib/dircat_on_sqlite_cli.rb +37 -0
  42. data/lib/simple_cataloger_dm/cli.rb +32 -0
  43. data/lib/simple_cataloger_dm/core.rb +43 -0
  44. data/lib/simple_cataloger_dm/core/catalog.rb +141 -0
  45. data/lib/simple_cataloger_dm/core/directory_visitor.rb +107 -0
  46. data/lib/simple_cataloger_dm/core/extensions.rb +26 -0
  47. data/lib/simple_cataloger_dm/core/simple_cataloger_error.rb +9 -0
  48. data/lib/simple_cataloger_dm/models/category.rb +21 -0
  49. data/lib/simple_cataloger_dm/models/image.rb +30 -0
  50. data/lib/simple_cataloger_dm/models/item.rb +24 -0
  51. data/lib/simple_cataloger_dm/models/tag.rb +62 -0
  52. data/lib/simple_cataloger_dm/models/tagging.rb +11 -0
  53. data/lib/simple_cataloger_dm/server/helpers.rb +60 -0
  54. data/lib/simple_cataloger_dm/server/my_static.rb +40 -0
  55. data/lib/simple_cataloger_dm/server/web_server.rb +171 -0
  56. data/spec/dircat/cat_on_sqlite/cat_on_sqlite_spec.rb +41 -0
  57. data/spec/dircat/cat_on_sqlite_web/web_server_spec.rb +30 -0
  58. data/spec/dircat/{cat_spec.rb → cat_on_yaml/cat_on_yaml_spec.rb} +20 -14
  59. data/spec/dircat/{cli → cat_on_yaml_cli}/cli_dircat_spec.rb +0 -0
  60. data/spec/dircat/{cli → cat_on_yaml_cli}/command_build_spec.rb +4 -4
  61. data/spec/dircat/{cli → cat_on_yaml_cli}/command_diff_spec.rb +0 -0
  62. data/spec/dircat/{cli → cat_on_yaml_cli}/command_query_spec.rb +1 -1
  63. data/spec/fixtures/certified_output/cat_dir1_20120811.yaml +25 -0
  64. data/spec/fixtures/certified_output/cat_dir2_20120811.yaml +34 -0
  65. data/spec/fixtures/certified_output/{dircat1.yaml → dircat1_version_0.1.yaml} +0 -0
  66. data/spec/fixtures/certified_output/{dircat2.yaml → dircat2_version_0.1.yaml} +0 -0
  67. data/spec/fixtures/dir4/file1.txt +1 -0
  68. data/spec/fixtures/dir4/file2.txt +1 -0
  69. data/spec/fixtures/dir4/subdir/file3.txt +1 -0
  70. data/spec/fixtures/films/A-Z/A/Arancia meccanica [Stanley Kubrick][1971]/folder.jpg +0 -0
  71. data/spec/fixtures/films/A-Z/P/Plan 9 [Edward Wood][1959]/folder.jpg +0 -0
  72. data/spec/fixtures/films/Directors/[Akira Kurosawa]/[1940] Dersu Uzala [5]/folder.jpg +0 -0
  73. data/spec/fixtures/films/Directors/[Akira Kurosawa]/[1965] Barbarossa [Toshiro Mifune][4]/folder.jpg +0 -0
  74. data/spec/fixtures/films/Directors/[Federico Fellini]/[1963] 8 e mezzo [Marcello Mastroianni][Claudia Cardinale][5]/folder.jpg +0 -0
  75. data/spec/fixtures/films/Directors/[Woody Allen]/[1977] Annie Hall [Diane Keaton][5]/folder.jpg +0 -0
  76. data/{.gemtest → spec/fixtures/readme.txt} +0 -0
  77. data/spec/fixtures/tmp/test_ar.sqlite3 +0 -0
  78. data/spec/fixtures/tmp/test_ar.yml +7 -0
  79. data/spec/generate_directories_to_catalog.rb +80 -0
  80. data/spec/generate_mysql_catalog.rb +124 -0
  81. data/spec/spec_helper.rb +29 -0
  82. data/tasks/rspec.rake +0 -2
  83. metadata +390 -112
  84. data/lib/dircat/entry.rb +0 -61
  85. data/lib/dircat/extension_md5.rb +0 -25
  86. data/lib/dircat/extension_numeric.rb +0 -15
  87. data/spec/dircat/md5_spec.rb +0 -8
  88. data/spec/dircat/numeric_spec.rb +0 -13
@@ -0,0 +1,62 @@
1
+ # -*- coding: utf-8 -*-
2
+ module SimpleCataloger
3
+
4
+ class CmdServer < OptParseCommand::Command
5
+
6
+ CliCat.register_command(self)
7
+
8
+ def self.command
9
+ "server"
10
+ end
11
+
12
+ def self.description
13
+ "start server"
14
+ end
15
+
16
+ def self.usage
17
+ "#{command} <catalog name> <directory>"
18
+ "Create a catalog with name <catalog name> starting from structure of <directory>"
19
+ end
20
+
21
+ def defaults(options)
22
+ options.force = false
23
+ options
24
+ end
25
+
26
+ def option_parser(options)
27
+ parser = super(options)
28
+ parser
29
+ end
30
+
31
+ def exec(main, options, rest)
32
+ if rest.length < 1
33
+ puts "too few arguments"
34
+ puts "-h to print help"
35
+ return 0
36
+ end
37
+
38
+ catalog_name = rest[0]
39
+ cat_opts = { }
40
+
41
+ #
42
+ # option verbose
43
+ #
44
+
45
+ # if options.has_key?(:verbose)
46
+ # if options[:verbose]
47
+ # cat_opts[:verbose_level] = 1
48
+ # end
49
+ # end
50
+
51
+ #
52
+ # main
53
+ #
54
+
55
+ catalog = SimpleCataloger::CatOnSqlite.new(catalog_name).open
56
+ SimpleCataloger::WebServer.run! :host => 'localhost', :port => 9091, :catalog => catalog
57
+
58
+ 0
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,49 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ include SimpleCataloger
4
+
5
+ module SimpleCataloger
6
+ class CmdUpdate < OptParseCommand::Command
7
+
8
+ CliCat.register_command(self)
9
+
10
+ def self.command
11
+ "update"
12
+ end
13
+
14
+ def self.description
15
+ "update the content of catalog"
16
+ end
17
+
18
+ def self.usage
19
+ "#{command} <catalog name> <directory>"
20
+ "Create a catalog with name <catalog name> starting from structure of <directory>"
21
+ end
22
+
23
+ def defaults(options)
24
+ options.force = false
25
+ options
26
+ end
27
+
28
+ def option_parser(options)
29
+ parser = super(options)
30
+ parser
31
+ end
32
+
33
+ def exec(main, options, rest)
34
+ if rest.length < 1
35
+ puts "too few arguments"
36
+ puts "-h to print help"
37
+ return 0
38
+ end
39
+
40
+ catalog_name = rest[0]
41
+
42
+ catalog = CatOnSqlite.new(catalog_name)
43
+ catalog.update
44
+
45
+ 0
46
+ end
47
+
48
+ end
49
+ end
@@ -4,7 +4,7 @@ module DirCat
4
4
  #
5
5
  # Catalog of files (contained into directory :-))
6
6
  #
7
- class Cat
7
+ class CatOnYaml
8
8
 
9
9
  #
10
10
  # Directory name
@@ -20,11 +20,13 @@ module DirCat
20
20
  # verbose level used to print message on $stdout
21
21
  #
22
22
  attr_reader :verbose_level
23
+ attr_reader :show_progress
23
24
 
24
25
  # @param [Hash] options
25
26
  # @option options [Number] :verbose list of ignore pattern
26
27
  def initialize(options = {})
27
28
  @verbose_level = options.delete(:verbose) || 0
29
+ @show_progress = options.delete(:show_progress)
28
30
  @dirname = ""
29
31
  @ctime = DateTime.now
30
32
  @entries = Array.new
@@ -55,7 +57,7 @@ module DirCat
55
57
 
56
58
  # Build a catalog from a directory
57
59
  def from_dir(dirname)
58
- if not File.directory?(dirname)
60
+ unless File.directory?(dirname)
59
61
  raise "'#{dirname}' is not a directory or doesn't exists"
60
62
  end
61
63
  @dirname = File.expand_path dirname
@@ -66,14 +68,14 @@ module DirCat
66
68
 
67
69
  # Load catalog from a file
68
70
  def from_file(filename)
69
- if not File.exist?(filename)
71
+ unless File.exist?(filename)
70
72
  raise DirCatException.new, "'#{filename}' not exists"
71
73
  end
72
74
  dircat_ser = File.open(filename) { |f| YAML::load(f) }
73
75
  @dirname = dircat_ser.dirname
74
76
  @ctime = dircat_ser.ctime
75
77
  dircat_ser.entries.each do |entry_ser|
76
- add_entry(Entry.new.from_ser(entry_ser))
78
+ add_entry(Entry.from_ser(entry_ser))
77
79
  end
78
80
  self
79
81
  end
@@ -92,7 +94,7 @@ module DirCat
92
94
  # @return [DirCatSer] serialized catalog
93
95
  def to_ser
94
96
  dircat_ser = DirCatSer.new
95
- dircat_ser.version = 0.1
97
+ dircat_ser.dircat_version = DirCat::VERSION
96
98
  dircat_ser.dirname = @dirname
97
99
  dircat_ser.ctime = @ctime
98
100
  dircat_ser.entries = []
@@ -109,14 +111,24 @@ module DirCat
109
111
  # @private
110
112
  #
111
113
  def _load_from_dir
114
+ start = Time.now
112
115
  me = self
113
- TreeVisitor::DirTreeWalker.new.run @dirname do
116
+ bytes = 0
117
+ TreeRb::DirTreeWalker.new.run @dirname do
118
+
114
119
  on_leaf do |filename|
115
- me.add_entry(Entry.new.from_filename(filename))
120
+ entry = Entry.from_filename(filename)
121
+ me.add_entry(entry)
122
+ bytes += entry.size
116
123
  if me.verbose_level > 0
117
124
  print "#{CR}#{filename}#{CLEAR}"
118
125
  end
126
+ if me.show_progress
127
+ sec = Time.now - start
128
+ print "#{CR}bytes: #{bytes.to_human} time: #{sec} bytes/sec #{bytes/sec} #{CLEAR}"
129
+ end
119
130
  end
131
+
120
132
  end
121
133
  self
122
134
  end
@@ -192,9 +204,9 @@ module DirCat
192
204
  #
193
205
  # return differences from this catalog and right catalog
194
206
  # param [Cat] right
195
- # @return [Cat]
207
+ # @return [CatOnYaml]
196
208
  def -(right)
197
- result = Cat.new
209
+ result = CatOnYaml.new
198
210
  @entries.each do |e|
199
211
  result.add_entry(e) unless right.contains(e)
200
212
  end
@@ -214,7 +226,7 @@ module DirCat
214
226
  # print a complex report on stdout
215
227
  #
216
228
  def fmt_report(*columns)
217
- columns = [:md5, :name, :path, :size] unless columns
229
+ columns = [:md5, :name, :path, :size] if columns.empty?
218
230
  OptParseCommand::report(@entries, *columns)
219
231
  end
220
232
 
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+ module DirCat
3
+
4
+ class EntrySer < OpenStruct
5
+ end
6
+
7
+ class DirCatSer < OpenStruct
8
+ end
9
+
10
+ class DirCatException < RuntimeError
11
+ end
12
+
13
+ #
14
+ # Entry
15
+ #
16
+ class Entry
17
+
18
+ # TODO: must be attr_reader
19
+ attr_accessor :md5
20
+ attr_accessor :name
21
+ attr_accessor :path
22
+ attr_accessor :size
23
+ attr_accessor :mtime
24
+
25
+ def self.from_filename( filename )
26
+ entry = new
27
+ entry.name = File.basename(filename)
28
+ entry.path = File.dirname(filename)
29
+ stat = File.lstat(filename)
30
+ entry.size = stat.size
31
+ entry.mtime = stat.mtime
32
+ # self.md5 = Digest::MD5.hexdigest(File.read( f ))
33
+ entry.md5 = MD5.file( filename ).hexdigest unless stat.symlink?
34
+ entry
35
+ end
36
+
37
+ def self.from_ser( entry_ser )
38
+ entry = new
39
+ entry.md5 = entry_ser.md5
40
+ entry.name = entry_ser.name
41
+ entry.path = entry_ser.path
42
+ entry.size = entry_ser.size
43
+ entry.mtime = entry_ser.mtime
44
+ entry
45
+ end
46
+
47
+ def to_ser
48
+ entry_ser = EntrySer.new
49
+ entry_ser.md5 = @md5
50
+ entry_ser.name = @name
51
+ entry_ser.path = @path
52
+ entry_ser.size = @size
53
+ entry_ser.mtime = @mtime
54
+ entry_ser
55
+ end
56
+
57
+ def to_s
58
+ @md5 + " " + @name + "\t " + @path + "\n"
59
+ end
60
+
61
+ end
62
+
63
+
64
+ end
File without changes
@@ -1,9 +1,9 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module DirCat
4
- #
5
- # Build a catalogue starting from a directory
6
- #
4
+ #
5
+ # Build a catalogue starting from a directory
6
+ #
7
7
  class CommandBuild < OptParseCommand::Command
8
8
 
9
9
  CliDirCat.register_command(self)
@@ -38,33 +38,66 @@ module DirCat
38
38
  options.output = v
39
39
  end
40
40
 
41
+ # TODO: progress is true for default
42
+ options.show_progress = true
43
+ parser.on("-p", "--show-progress", "show progress during catalog building") do
44
+ options.show_progress = true
45
+ end
46
+
47
+ parser.on("--find", "try to find a catalog from this directory to path") do
48
+ options.find = true
49
+ end
50
+
41
51
  parser
42
52
  end
43
53
 
44
54
  def exec(main, options, rest)
55
+
45
56
  if rest.length < 1
46
57
  $stderr.puts "directory (from which build catalog) is missing"
47
58
  $stderr.puts "-h to print help"
48
59
  return false
49
60
  end
50
61
 
51
- dirname = rest[0]
52
- dirname = File.expand_path(dirname)
53
- cat_opts = {}
62
+ dirname = rest[0]
63
+ dirname = File.expand_path(dirname)
54
64
 
55
- if not FileTest.directory?(dirname)
65
+ #
66
+ # experimental find
67
+ #
68
+ if options.find
69
+ f = File.join(dirname, ".dircat.yml")
70
+ until File.exist?(f) or dirname == "/"
71
+ dirname = File.split(dirname)[0]
72
+ end
73
+ if File.exist?(f)
74
+ puts "file exists!!"
75
+ else
76
+ puts "don't exists"
77
+ end
78
+ exit
79
+ end
80
+ #
81
+ # end experimental find
82
+ #
83
+
84
+ unless FileTest.directory?(dirname)
56
85
  $stderr.puts "'#{dirname}' not exists or is not a directory"
57
86
  return 0
58
87
  end
59
88
 
89
+ cat_opts = { }
90
+
60
91
  #
61
- # option verbose
92
+ # option verbose, progress
62
93
  #
63
-
94
+ cat_opts[:verbose_level] = 0
64
95
  if options.verbose
65
96
  cat_opts[:verbose_level] = 1
66
97
  end
67
98
 
99
+ cat_opts[:show_progress] = options.show_progress
100
+
68
101
  #
69
102
  # option: output, force
70
103
  #
@@ -79,16 +112,24 @@ module DirCat
79
112
  return 0
80
113
  end
81
114
 
115
+ #
116
+ # go!
117
+ #
118
+
119
+ Signal.trap('INT') { puts "intercepted ctr+c"; exit }
120
+
121
+ $stderr.puts "Writing file '#{filename}'"
122
+
82
123
  output = File.open(filename, "w")
83
124
  start_time = Time.now
84
- s = Cat.from_dir(dirname)
125
+ cat = CatOnYaml.from_dir(dirname, cat_opts)
85
126
  end_time = Time.now
86
- s.save_to(output)
127
+ cat.save_to(output)
87
128
 
88
129
  if output != $stdout
89
130
  output.close
90
131
  end
91
- $stderr.puts s.report
132
+ $stderr.puts cat.report
92
133
  $stderr.puts "elapsed: #{end_time - start_time}"
93
134
  $stderr.puts "written to #{filename}" if output != $stdout
94
135
 
@@ -43,10 +43,10 @@ and then print the difference with the format specified on output
43
43
  #
44
44
  if File.directory?(cat_filename1)
45
45
  puts "build first set from directory #{cat_filename1}"
46
- s1 = Cat.from_dir(cat_filename1)
46
+ s1 = CatOnYaml.from_dir(cat_filename1)
47
47
  elsif File.exists?(cat_filename1)
48
48
  puts "load catalog #{cat_filename1}"
49
- s1 = Cat.from_file(cat_filename1)
49
+ s1 = CatOnYaml.from_file(cat_filename1)
50
50
  else
51
51
  puts "#{cat_filename1} is not a catalog file or directory"
52
52
  return 1
@@ -57,10 +57,10 @@ and then print the difference with the format specified on output
57
57
  #
58
58
  if File.directory?(cat_filename2)
59
59
  puts "build first set from directory #{cat_filename2}"
60
- s2 = Cat.from_dir(cat_filename2)
60
+ s2 = CatOnYaml.from_dir(cat_filename2)
61
61
  elsif File.exists?(cat_filename2)
62
62
  puts "load catalog #{cat_filename2}"
63
- s2 = Cat.from_file(cat_filename2)
63
+ s2 = CatOnYaml.from_file(cat_filename2)
64
64
  else
65
65
  puts "#{cat_filename2} is not a catalog file or directory"
66
66
  return 1
@@ -13,7 +13,16 @@ module DirCat
13
13
  end
14
14
 
15
15
  def self.usage
16
- "Usage: query [options] <catalog> [<method>]"
16
+ <<-EOS
17
+ Usage: query [options] <catalog> [<method>]
18
+ where method can be:
19
+ report: show info on catalog
20
+ duplicates: list duplicates into catalog
21
+ list_dup
22
+ script_dup
23
+ fmt_simple
24
+
25
+ EOS
17
26
  end
18
27
 
19
28
  def exec(main, options, rest)
@@ -43,7 +52,12 @@ module DirCat
43
52
  cat_opts[:verbose_level] = 1
44
53
  end
45
54
 
46
- s = Cat.from_file(cat_filename, cat_opts)
55
+ begin
56
+ s = CatOnYaml.from_file(cat_filename, cat_opts)
57
+ rescue Exception => e
58
+ $stderr.put "cannot read catalog '#{cat_filename}' maybe it is an old version?"
59
+ return false
60
+ end
47
61
 
48
62
  if s.respond_to? command.to_sym
49
63
  puts s.send(command.to_sym)