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
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2010 tokiro.oyama@gmail.com
1
+ Copyright (c) 2009-2012 tokiro.oyama@gmail.com
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,8 +1,18 @@
1
- # DIRCAT
1
+ # DIRCAT & Simple Cataloger (merging Simple Cataloger in progress)
2
2
 
3
- Dircat build, starting from a directory, a catalog with files meta information (path, timestamp, md5. ...), so it
4
- is possible to compare this catalog with another directory to detect duplicate, file change, and so.
5
- This utilities could be utilized as help to backup a directory or to find duplicates
3
+ ## DIRCAT
4
+
5
+ Dircat build, starting from a directory, a catalog with files
6
+ meta information (path, timestamp, md5. ...), so it is possible to compare
7
+ this catalog with another directory to detect duplicate, file change, and so.
8
+ This utilities could be utilized as help to backup a directory
9
+ or to find duplicates
10
+
11
+ ## Simple Cataloger
12
+
13
+ An extremely simple cataloging tool. You can use it to index files stored on
14
+ hard disks and create searchable catalogs that can be used without
15
+ having access to original media.
6
16
 
7
17
  ### dircat build
8
18
 
@@ -38,6 +48,21 @@ or
38
48
 
39
49
  sudo gem install gf-dircat -s gems.github.com
40
50
 
41
- ### Copyright
51
+ ## Note on Patches/Pull Requests
52
+
53
+ * Fork the project.
54
+ * Make your feature addition or bug fix.
55
+ * Add tests for it. This is important so I don't break it in a
56
+ future version unintentionally.
57
+ * Commit, do not mess with rakefile, version, or history.
58
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
59
+ * Send me a pull request. Bonus points for topic branches.
60
+
61
+
62
+ ## Contributor
63
+
64
+ 2012-08: merging with mstrauss branch (not following symlinks)
65
+
66
+ ## Copyright
42
67
 
43
- Copyright (c) 2009-2010 tokiro.oyama@gmail.com See LICENSE for details.
68
+ Copyright (c) 2009-2012 Tokyro (tokyro.oyama@gmail.com). See LICENSE for details.
data/bin/dircat CHANGED
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ require 'rubygems'
2
4
  cwd = File.expand_path(File.join(File.dirname(__FILE__), %w{ .. lib}))
3
5
  $:.unshift(cwd) unless $:.include?(cwd)
4
6
 
5
7
  require 'dircat'
6
- DirCat::CliDirCat.run!
8
+ include DirCat
9
+ exit DirCat::CliDirCat.run!
10
+
data/bin/scat ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ require 'rubygems'
4
+ cwd = File.expand_path(File.join(File.dirname(__FILE__), %w{.. lib}))
5
+ $:.unshift(cwd) unless $:.include?(cwd)
6
+
7
+ require 'simple_cataloger_cli'
8
+ # TODO: we need exit befor run?
9
+ CliCat.run!
data/dircat.gemspec CHANGED
@@ -4,14 +4,26 @@ require "dircat/version"
4
4
 
5
5
  Gem::Specification.new do |gem|
6
6
 
7
- gem.name = "dircat"
7
+ gem.name = DirCat::NAME
8
8
  gem.version = DirCat::VERSION
9
9
  gem.platform = Gem::Platform::RUBY
10
- gem.summary = "command line utilities to manage catalogs of directory"
11
- gem.description = %Q{
10
+
11
+ gem.summary = %Q{
12
12
  command line utilities to manage catalogs of directory
13
+ and damn simple cataloger using directory convention
13
14
  }
14
- gem.authors = ["Tokiro"]
15
+
16
+ gem.description = <<-EOS
17
+ command line utilities to manage catalogs of directory
18
+
19
+ damn simple catalog based on tagging file name.
20
+ The tag are between bracket.
21
+ For example the filename 'photo [sea][2010][summer]', associate
22
+ with the name photo the tag sea,2010,summer.
23
+ EOS
24
+
25
+
26
+ gem.authors = %w{ Tokiro }
15
27
  gem.email = "tokiro.oyama@gmail.com"
16
28
  gem.homepage = "http://github.com/tokiro/dircat"
17
29
 
@@ -19,39 +31,60 @@ Gem::Specification.new do |gem|
19
31
  #
20
32
  # dependencies
21
33
  #
22
- gem.add_runtime_dependency(%q<treevisitor>, ["= 0.2.2"])
23
- gem.add_runtime_dependency(%q<optparse-command>, ["= 0.1.6"])
34
+
35
+ gem.add_runtime_dependency(%q<tree.rb>)
36
+ gem.add_runtime_dependency(%q<optparse-command>)
37
+ gem.add_runtime_dependency(%q<sinatra-group-items>)
38
+
39
+ gem.add_runtime_dependency(%q<ansi>, [">= 0"])
40
+
41
+ # gem.add_runtime_dependency(%q<data_mapper>, [">= 0"])
42
+ # gem.add_runtime_dependency(%q<dm-sqlite-adapter>, [">= 0"])
43
+
44
+ gem.add_runtime_dependency(%q<activerecord>, [">= 0"])
45
+ # gem.add_runtime_dependency(%q<mysql2>, ["<= 0.2"])
46
+ gem.add_runtime_dependency(%q<sqlite3>, [">= 0"])
47
+
48
+ gem.add_runtime_dependency(%q<sinatra>, [">= 0"])
49
+ gem.add_runtime_dependency(%q<haml>, [">= 0"])
50
+ gem.add_runtime_dependency(%q<sass>, [">= 0"])
51
+ gem.add_runtime_dependency(%q<json>, [">= 0"])
52
+
24
53
 
25
54
  gem.add_development_dependency(%q<rake>, [">= 0"])
26
55
  gem.add_development_dependency(%q<yard>, [">= 0"])
27
56
  gem.add_development_dependency(%q<bundler>, [">= 0"])
28
57
  gem.add_development_dependency(%q<rspec>, [">= 0"])
58
+ gem.add_development_dependency(%q<webrat>, [">= 0"])
59
+ gem.add_development_dependency(%q<sinatra>, [">= 0"])
60
+ gem.add_development_dependency(%q<rmagick>, [">= 0"])
29
61
 
30
62
  #
31
63
  # bin
32
64
  #
33
- gem.require_paths = ["lib"]
34
- gem.executables = %w{ dircat }
35
65
  # s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
66
+ gem.require_paths = %w{ lib }
67
+ gem.executables = %w{ dircat scat }
36
68
 
37
69
  #
38
70
  # files
39
71
  #
40
- gem.files = %w{LICENSE.txt README.md Rakefile dircat.gemspec .gemtest}
41
- gem.extra_rdoc_files = [
42
- "LICENSE.txt",
43
- "README.md"
44
- ]
72
+ # s.files = `git ls-files`.split("\n")
73
+ gem.files = %w{LICENSE.txt README.md Rakefile dircat.gemspec}
74
+ gem.extra_rdoc_files = %w{
75
+ LICENSE.txt
76
+ README.md
77
+ }
45
78
  gem.files.concat Dir['lib/**/*.rb']
46
79
  gem.files.concat Dir['examples/*.rb']
80
+ gem.files.concat Dir['web/**/*']
47
81
  gem.files.concat Dir['tasks/*.rake']
48
- # s.files = `git ls-files`.split("\n")
49
82
 
50
83
  #
51
84
  # test files
52
85
  #
86
+ # s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
53
87
  gem.test_files = Dir['spec/**/*.rb']
54
88
  gem.test_files.concat Dir['spec/fixtures/**/*']
55
- # s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
56
89
 
57
90
  end
data/examples/example.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
3
 
3
4
  require 'dircat'
@@ -5,6 +6,6 @@ include DirCat
5
6
 
6
7
  dir = File.join( File.dirname(__FILE__), "..")
7
8
 
8
- cat = Cat.from_dir( dir )
9
+ cat = CatOnYaml.from_dir( dir )
9
10
  cat.fmt_report
10
11
 
data/lib/dircat.rb CHANGED
@@ -1,34 +1,29 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # std lib
4
- #
5
- require 'fileutils'
6
- require 'tmpdir'
7
- require 'yaml'
8
- require 'ostruct'
9
- require 'optparse'
10
- require 'pp'
11
-
12
- #
13
- # rubygems
14
- #
15
- gem "optparse-command", "0.1.6"
16
- require 'optparse-command'
17
-
18
- gem "treevisitor", "0.2.2"
19
- require 'treevisitor'
20
-
21
- #
22
- # dircat
23
- #
24
- require 'dircat/version'
25
- require 'dircat/extension_md5'
26
- require 'dircat/extension_numeric'
27
-
28
- require 'dircat/cat'
29
- require 'dircat/entry'
30
-
31
- require 'dircat/cli/cli_dircat'
32
- require 'dircat/cli/command_build'
33
- require 'dircat/cli/command_diff'
34
- require 'dircat/cli/command_query'
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # std lib
4
+ #
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require 'yaml'
8
+ require 'ostruct'
9
+ require 'optparse'
10
+ require 'pp'
11
+
12
+ #
13
+ # rubygems
14
+ #
15
+ require 'optparse-command'
16
+ require 'tree_rb'
17
+
18
+ #
19
+ # dircat
20
+ #
21
+ require 'dircat/version'
22
+
23
+ require 'dircat/cat_on_yaml/cat_on_yaml'
24
+ require 'dircat/cat_on_yaml/entry'
25
+
26
+ require 'dircat/cat_on_yaml_cli/cli_dircat'
27
+ require 'dircat/cat_on_yaml_cli/command_build'
28
+ require 'dircat/cat_on_yaml_cli/command_diff'
29
+ require 'dircat/cat_on_yaml_cli/command_query'
@@ -0,0 +1,177 @@
1
+ # -*- coding: utf-8 -*-
2
+ module SimpleCataloger
3
+
4
+ class CatOnSqlite
5
+
6
+ attr_reader :name
7
+
8
+ # @param [Object] path
9
+ def initialize(path, options = {})
10
+ @verbose ||= options[:verbose]
11
+ @path = File.expand_path(path)
12
+ @name = File.basename(path)
13
+ catalogs_dir = File.dirname(path)
14
+
15
+ #
16
+ # path db, config, etc...
17
+ #
18
+ @db_filepath = File.join(catalogs_dir, "#{name}.sqlite3")
19
+ @db_log_filepath = File.join(catalogs_dir, "#{name}.log")
20
+ @config_filepath = File.join(catalogs_dir, "#{name}.yml")
21
+
22
+ #TODO: logger usabile per loggare altri eventi oltre a quelli del db
23
+
24
+ database_filename = File.join(File.dirname(__FILE__), %w{default_database_config.yml})
25
+ @active_record_config = YAML.load(File.open(database_filename))
26
+ # pp config
27
+ # ActiveRecord::Base.connection.create_database(catalog_dbname)
28
+ # ActiveRecord::Base.establish_connection(config['films_mysql'])
29
+ @active_record_config['films_sqlite']['database'] = @db_filepath
30
+ @active_record_config = @active_record_config['films_sqlite']
31
+
32
+ puts "database in '#{@db_filepath}'" if @verbose
33
+ end
34
+
35
+ def open
36
+ ActiveRecord::Base.establish_connection(@active_record_config)
37
+ require_models
38
+ self
39
+ end
40
+
41
+ #
42
+ # Create a new catalog
43
+ # @param array of directories
44
+ #
45
+ def create(*catalog_roots)
46
+ fs = [@db_filepath, @db_log_filepath, @config_filepath]
47
+ fs.each do |f|
48
+ FileUtils.rm(f) if File.exist?(f)
49
+ end
50
+
51
+ if File.exist? @config_filepath
52
+ raise SimpleCatalogerError, "cannot create already existent catalog '#{@name}'"
53
+ end
54
+ @config = {
55
+ :roots => catalog_roots,
56
+ :ignore => %w{sub subtitles images},
57
+ :version => DirCat::VERSION
58
+ }
59
+ write_config
60
+
61
+ #
62
+ # migrate db
63
+ #
64
+ # TODO: drop tables!
65
+ ActiveRecord::Base.establish_connection(@active_record_config)
66
+ ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : false
67
+ migration_dir = File.join(File.dirname(__FILE__), %w{migration})
68
+ unless Dir.exist? migration_dir
69
+ raise "migration dir '#{migration_dir}' not exists"
70
+ end
71
+ ActiveRecord::Migrator.migrate(migration_dir, ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
72
+ require_models
73
+ end
74
+
75
+ #
76
+ # Rebuild catalog
77
+ #
78
+ def update
79
+ unless File.exist? @config_filepath
80
+ raise "cannot update catalog #{@name}"
81
+ end
82
+ open
83
+ read_config
84
+
85
+ #
86
+ # Initialize tag and categories from config
87
+ #
88
+ if @config[:categories]
89
+ # pp @config[:categories]
90
+ @config[:categories].each_pair do |category, tags|
91
+ # puts category
92
+ cat = Category.find_or_create_by_name(category)
93
+ tags.each do |name|
94
+ tag = Tag.find_or_create_by_name(name)
95
+ tag.category = cat
96
+ tag.save
97
+ end
98
+ end
99
+ end
100
+
101
+ #
102
+ # read catalog root
103
+ #
104
+ @config[:roots].each do |root|
105
+ dtw = TreeRb::DirTreeWalker.new(root)
106
+ dtw.ignore /^\./
107
+ @config[:ignore].each do |i|
108
+ dtw.ignore i
109
+ end
110
+ dtw.visit_file=true
111
+ dtw.run(DirectoryVisitor.new(root))
112
+ end
113
+
114
+ #
115
+ # cache rating tag
116
+ #
117
+ rating = Category.find_by_name("rating")
118
+ if rating
119
+ Item.all.each do |item|
120
+ t = item.tags.find_by_category_id(rating.id)
121
+ if t
122
+ item.rating = t.name.to_i
123
+ item.save
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ #
130
+ # array of roots
131
+ #
132
+ def roots
133
+ read_config unless @config
134
+ @config[:roots]
135
+ end
136
+
137
+ #
138
+ # update config file with tag category list and association from category to tag name,
139
+ # so to not lose the association next time the catalog is rebuilt (updated)
140
+ #
141
+ def load_categories_in_config
142
+ h = { }
143
+ Category.all.each do |category|
144
+ next if %w{rating year unknown}.include?(category.name)
145
+ h[category.name] = category.tags.collect { |tag| tag.name }
146
+ end
147
+ @config[:categories] = h
148
+ end
149
+
150
+ def write_config
151
+ File.open(@config_filepath, "w") { |f| f.write @config.to_yaml }
152
+ end
153
+
154
+ private
155
+
156
+ def read_config
157
+ #noinspection RubyResolve
158
+ @config = YAML.load(File.open(@config_filepath))
159
+ end
160
+
161
+ #
162
+ # model must be loaded after the connection is established
163
+ #
164
+ def require_models
165
+ model_dir = File.join(File.dirname(__FILE__), %w{ model })
166
+ unless Dir.exist? model_dir
167
+ raise "model directory '#{model_dir}' not exists"
168
+ end
169
+ Dir[File.join(model_dir, '*.rb')].each do |f|
170
+ # puts f
171
+ require f
172
+ end
173
+ end
174
+
175
+ end # class
176
+
177
+ end # module SimpleCatalog
@@ -0,0 +1,106 @@
1
+ module SimpleCataloger
2
+
3
+ #
4
+ # Find directory without subdirectories
5
+ #
6
+ class DirectoryVisitor
7
+
8
+ def initialize(catalog_root)
9
+ @stack = []
10
+ @files = []
11
+ @nr = 0
12
+ @catalog_root = catalog_root
13
+ end
14
+
15
+ def enter_node(pathname)
16
+ # each directory is associated to a number,
17
+ # so when exit_tree_node is called and the number @nr is not increased
18
+ # the directory doesn't have subdirectories
19
+ @nr += 1
20
+
21
+ dirname = File.basename(pathname)
22
+ tags = Tag.extract_tags(dirname)
23
+ tags = tags.concat(@stack.last.tags).uniq unless @stack.empty?
24
+ info = OpenStruct.new(:nr => @nr, :pathname => pathname, :tags => tags, :name => Tag.extract_name(dirname))
25
+
26
+ @files = []
27
+ @stack.push(info)
28
+ end
29
+
30
+ def exit_node(pathname)
31
+ info = @stack.pop
32
+
33
+ if info.nr == @nr
34
+ # this directory doesn't have subdirectories
35
+ name = info.name
36
+ tag_names = info.tags
37
+ puts name
38
+ # pp tags
39
+
40
+ # every name must be unique, two films cannot have the some name
41
+ if Item.find_by_name(name)
42
+ raise "item #{name} is not unique path #{pathname}"
43
+ end
44
+
45
+ item = Item.create(
46
+ :name => name,
47
+ :added_at => File.lstat(pathname).ctime,
48
+ :path => pathname,
49
+ :path_from_catalog_root => pathname[File.dirname(@catalog_root).length..-1]
50
+ )
51
+
52
+ #
53
+ # Associate item and tags
54
+ #
55
+ unknown = Category.find_or_create_by_name("unknown")
56
+ tag_names.each do |tag_name|
57
+ tag = Tag.find_by_name(tag_name)
58
+ unless tag
59
+ tag = Tag.match_category(tag_name)
60
+ unless tag
61
+ tag = Tag.find_by_name_and_category_id(tag_name, unknown.id)
62
+ unless tag
63
+ tag = Tag.create(:name => tag_name, :category => unknown)
64
+ end
65
+ end
66
+ end
67
+ Tagging.find_or_create_by_item_id_and_tag_id(item.id, tag.id)
68
+ end
69
+
70
+ #
71
+ # Searches images
72
+ #
73
+ @files.each do |pathname|
74
+ next unless pathname.match /(jpg|jpeg)$/
75
+
76
+ image = Image.find_or_create_by_path_and_path_from_catalog_root(
77
+ pathname,
78
+ pathname[File.dirname(@catalog_root).length..-1]
79
+ )
80
+ item.images << image
81
+
82
+ filename = File.basename(pathname)
83
+ tag_names = Tag.extract_tags(filename)
84
+ tag_names.each do |tag_name|
85
+ tag = Tag.first(:name => tag_name)
86
+ if tag
87
+ tag.images << image
88
+ tag.save
89
+ else
90
+ puts "WARNING: tag '#{tag_name}' not found"
91
+ end
92
+ end
93
+ end
94
+ item.save
95
+ end
96
+ end
97
+
98
+
99
+ #
100
+ # called when visit leaf node
101
+ #
102
+ def visit_leaf(pathname)
103
+ @files << pathname
104
+ end
105
+ end # class
106
+ end # module SimpleCataloger