dircat 0.1.12 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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