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
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+ module SimpleCataloger
3
+
4
+ class Tagging
5
+ include DataMapper::Resource
6
+ property :id, Serial
7
+ belongs_to :item
8
+ belongs_to :tag
9
+ end
10
+
11
+ end # module
@@ -0,0 +1,60 @@
1
+ # -*- coding: utf-8 -*-
2
+ module SimpleCataloger
3
+ module Helpers
4
+
5
+ def partial(template, *args)
6
+ options = args.extract_options!
7
+ options.merge!(:layout => false)
8
+ if collection = options.delete(:collection) then
9
+ collection.inject([]) do |buffer, member|
10
+ buffer << haml(template, options.merge(
11
+ :layout => false,
12
+ :locals => {template.to_sym => member}
13
+ )
14
+ )
15
+ end.join("\n")
16
+ else
17
+ haml(template, options)
18
+ end
19
+ end
20
+
21
+ def partial_erb(template)
22
+ erb template
23
+ end
24
+
25
+ def base_url
26
+ if Sinatra::Application.port == 80
27
+ "http://#{Sinatra::Application.host}/"
28
+ else
29
+ "http://#{Sinatra::Application.host}:#{Sinatra::Application.port}/"
30
+ end
31
+ end
32
+
33
+ def when_updated(time)
34
+ days = (Time.now - time) / (60 * 60 * 24)
35
+ case days.to_i
36
+ when 0
37
+ "today"
38
+ when 1
39
+ "yesterday"
40
+ else
41
+ "#{sprintf("%i", days) } days ago"
42
+ end
43
+ end
44
+
45
+ def gen_url(field, visible_field = nil)
46
+ visible_field ||= field
47
+ pos = request.env['REQUEST_URI'].index "?"
48
+ url = if pos
49
+ request.env['REQUEST_URI'][0...pos]
50
+ else
51
+ request.env['REQUEST_URI']
52
+ end
53
+ "<a href='#{url}?order=#{field}'>#{visible_field}</a>"
54
+ end
55
+
56
+ def rfc_3339(timestamp)
57
+ timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,40 @@
1
+ module Rack
2
+
3
+ # The Rack::Static middleware intercepts requests for static files
4
+ # (javascript files, images, stylesheets, etc) based on the url prefixes
5
+ # passed in the options, and serves them using a Rack::File object. This
6
+ # allows a Rack stack to serve both static and dynamic content.
7
+ #
8
+ # Examples:
9
+ # use Rack::Static, :urls => ["/media"]
10
+ # will serve all requests beginning with /media from the "media" folder
11
+ # located in the current directory (ie media/*).
12
+ #
13
+ # use Rack::Static, :urls => ["/css", "/images"], :root => "public"
14
+ # will serve all requests beginning with /css or /images from the folder
15
+ # "public" in the current directory (ie public/css/* and public/images/*)
16
+
17
+ class MyStatic
18
+
19
+ def initialize(app, options={})
20
+ @app = app
21
+ @urls = options[:urls] || ["/favicon.ico"]
22
+ root = options[:root] || Dir.pwd
23
+ @file_server = Rack::File.new(root)
24
+ end
25
+
26
+ def call(env)
27
+ path = env["PATH_INFO"]
28
+ puts "mystatic #{path} #{URI.decode(path)}"
29
+ path = URI.decode(path)
30
+ can_serve = @urls.any? { |url| path.index(url) == 0 }
31
+
32
+ if can_serve
33
+ @file_server.call(env)
34
+ else
35
+ @app.call(env)
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,171 @@
1
+ # -*- coding: utf-8 -*-
2
+ module SimpleCataloger
3
+
4
+ class WebServer < Sinatra::Base
5
+
6
+ def self.run!(*args)
7
+ options = args.last.is_a?(::Hash) ? args.last : {}
8
+ catalog = options[:catalog]
9
+
10
+ catalog.roots.each do |root|
11
+ use Rack::MyStatic,
12
+ :urls => ["/#{File.basename(root)}"],
13
+ :root => File.dirname(root)
14
+ puts "mount #{File.basename(root)} -> #{File.dirname(root)}"
15
+ end
16
+
17
+ define_method :catalog do
18
+ catalog
19
+ end
20
+ super(*args)
21
+ end
22
+
23
+ # turns on static file serving for Sinatra::Base apps
24
+ enable :static
25
+
26
+ server_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'web'))
27
+ set :public, File.join(server_dir, 'public')
28
+ set :views, File.join(server_dir, 'views')
29
+
30
+ helpers do
31
+ include Rack::Utils
32
+ alias_method :h, :escape_html
33
+ end
34
+
35
+ helpers Sinatra::GroupItems
36
+ helpers Helpers
37
+
38
+ get '/app.css' do
39
+ content_type 'text/css', :charset => 'utf-8'
40
+ sass :app
41
+ end
42
+
43
+ get "/js/tooltips/tooltips.css" do
44
+ content_type 'text/css', :charset => 'utf-8'
45
+ sass "/js/tooltips/tooltips".to_sym
46
+ end
47
+
48
+ get '/' do
49
+ @catalog = catalog
50
+ @items = Item.all
51
+ order = params[:o] || "alpha"
52
+
53
+ @render = proc { |item|
54
+ "<a href=\"/item/#{item.id}\" rel=\"#{item.id}\">#{item.name}</a>" +
55
+ if item.rating then
56
+ " (r:#{item.rating})"
57
+ else
58
+ " (r:unrated)"
59
+ end
60
+ }
61
+
62
+ case order
63
+ when "alpha"
64
+ @grouped_items = group_items(@items, :group_size => 5)
65
+ @title = "Films in alphabetical order (c:#{@items.length})"
66
+ when "time"
67
+ @grouped_items = group_items(@items, :group_size => 1, :header => proc { |film| film.added_at })
68
+ @title = "Films in time added order (c:#{@items.length})"
69
+ end
70
+ haml :items
71
+ end
72
+
73
+ get '/item/:id' do
74
+ @catalog = catalog
75
+ @item = Item.get(params[:id])
76
+ @grouped_items = group_items(@item.tags, :group_size => 1, :header => proc { |tag| tag.category.name })
77
+ haml :item
78
+ end
79
+
80
+ get '/categories' do
81
+ @catalog = catalog
82
+ @categories = Category.all
83
+ haml :categories
84
+ end
85
+
86
+ get "/category/:id" do
87
+ @catalog = catalog
88
+ @category = Category.get(params[:id])
89
+ haml :category
90
+ end
91
+
92
+ get "/tag/:id" do
93
+ @catalog = catalog
94
+ @tag = Tag.get(params[:id])
95
+ haml :tag
96
+ end
97
+
98
+ get "/random" do
99
+ max_peso = Item.inject.each do |f|
100
+ f.peso
101
+ end
102
+ Random.new.rand(0..maxpeso)
103
+ end
104
+
105
+ #######################################################################################
106
+ # Ajax
107
+
108
+ get '/ajax/ajax_item/:id' do
109
+ @item = Item.get(params[:id])
110
+ haml 'ajax/ajax_item'.to_sym, :layout => false
111
+ end
112
+
113
+ post '/ajax/open_folder' do
114
+ dir = params[:dir] || "/"
115
+ system("nautilus", dir)
116
+ "ok"
117
+ end
118
+
119
+ post "/ajax/set-category" do
120
+ id = params[:tag_id]
121
+ category_name = params[:category_name]
122
+ tag = Tag.get(id.to_i)
123
+ category = Category.first_or_create(:name => category_name)
124
+ tag.category = category
125
+ tag.save
126
+ catalog.update_categories
127
+ catalog.write_config
128
+ "ok"
129
+ end
130
+
131
+ get '/ajax/ajax_set_flag/:id' do
132
+ @film = Item.get(params[:id])
133
+ if (params[:checked] == "true")
134
+ @film.flagged_at = Time.new
135
+ else
136
+ @film.flagged_at = nil
137
+ end
138
+ @film.save
139
+ "ok"
140
+ end
141
+
142
+ #######################################################################################
143
+ # Tests
144
+
145
+ get "/test/resize" do
146
+ @catalog = catalog
147
+ haml "/test/resize".to_sym
148
+ end
149
+
150
+ get "/test/jquery" do
151
+ @catalog = catalog
152
+ haml "/test/jquery".to_sym
153
+ end
154
+
155
+ get "/test/lightbox" do
156
+ @catalog = catalog
157
+ haml "/test/lightbox".to_sym
158
+ end
159
+
160
+ get "/test/select" do
161
+ @catalog = catalog
162
+ haml "/test/select".to_sym
163
+ end
164
+
165
+ get "/test/protovis" do
166
+ @catalog = catalog
167
+ haml "/test/protovis".to_sym
168
+ end
169
+ end
170
+
171
+ end
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
3
+ include SimpleCataloger
4
+
5
+ describe CatOnSqlite do
6
+ it "should write and read catalog" do
7
+
8
+ TestCatalogHelper.create_test_catalog
9
+ filename = File.join(TMP_DIR, "test_ar")
10
+ CatOnSqlite.new(filename).open
11
+
12
+ Category.all.map(&:name).should == %w(Actor Director)
13
+
14
+
15
+ Category.find_by_name("Actor").tags.map(&:name).should == ["Diane Keaton", "Mia Farrow"]
16
+ Category.find_by_name("Director").tags.map(&:name).should == ["Fellini", "Kurosawa", "Woody Allen"]
17
+ Tag.all.map(&:name).should == ["Mia Farrow", "Diane Keaton", "Woody Allen", "Fellini", "Kurosawa"]
18
+
19
+
20
+ Tag.find_by_name("Woody Allen").category.name == "Director"
21
+ Tag.find_by_name("Mia Farrow").category.name == "Actor"
22
+ Tag.find_by_name("Woody Allen").items.map(&:name).should == ["Annie Hall", "Play It Again, Sam"]
23
+
24
+ Item.find_by_name("Annie Hall").images.map(&:path).should == ['path']
25
+ Item.find_by_name("Annie Hall").images.first.to_json.should == "{\"item\":\"Annie Hall\",\"tag\":null,\"src\":\"path from root\"}"
26
+ end
27
+
28
+ it "should extract tag from directory name" do
29
+
30
+ TestCatalogHelper.create_test_catalog
31
+ filename = File.join(TMP_DIR, "test_ar")
32
+ CatOnSqlite.new(filename).open
33
+
34
+ dir_name = "Broadway Danny Rose [Woody Allen][Mia Farrow][1984]"
35
+ Tag.extract_tags(dir_name).should == ['Woody Allen', 'Mia Farrow', '1984']
36
+ Tag.extract_name(dir_name).should == "Broadway Danny Rose"
37
+ Tag.match_category("1984").name.should == "year"
38
+ Tag.match_category("1985").name.should == "year"
39
+ end
40
+
41
+ end
@@ -0,0 +1,30 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
3
+
4
+ module SimpleCataloger
5
+ describe WebServer do
6
+
7
+ include Rack::Test::Methods
8
+
9
+ def app
10
+ @app ||= WebServer
11
+ end
12
+
13
+ it "should respond to /" do
14
+ pending "need integrate all code"
15
+ get '/'
16
+ # pp last_response
17
+ last_response.should be_ok
18
+ end
19
+
20
+
21
+ # before(:each) do
22
+ # @web_server = WebServer.new
23
+ # end
24
+ #
25
+ # it "should desc" do
26
+ # # TODO
27
+ # end
28
+ end
29
+
30
+ end
@@ -1,6 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
-
3
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
4
3
 
5
4
  #
6
5
  # dir1 contains 2 files
@@ -9,35 +8,35 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
9
8
  #
10
9
  # dir3 contains two duplicated files
11
10
 
12
- describe Cat do
11
+ describe CatOnYaml do
13
12
 
14
13
  before do
15
14
  @data_dir = TEST_DIR
16
15
  end
17
16
 
18
17
  it "should build catalog from dir1" do
19
- cat1 = Cat.from_dir(File.join(@data_dir, "dir1"))
18
+ cat1 = CatOnYaml.from_dir(File.join(@data_dir, "dir1"))
20
19
  cat1.size.should == 2
21
20
  cat1.bytes.should == 4
22
21
  end
23
22
 
24
23
  it "should load catalog from dir2" do
25
- cat2 = Cat.from_dir(File.join(@data_dir, "dir2"))
24
+ cat2 = CatOnYaml.from_dir(File.join(@data_dir, "dir2"))
26
25
  cat2.size.should == 3
27
26
  cat2.bytes.should == 6
28
27
  end
29
28
 
30
29
  it "(dir1 - dir2): the difference from dir1 and dir2 is empty" do
31
- cat1 = Cat.from_dir(File.join(@data_dir, "dir1"))
32
- cat2 = Cat.from_dir(File.join(@data_dir, "dir2"))
30
+ cat1 = CatOnYaml.from_dir(File.join(@data_dir, "dir1"))
31
+ cat2 = CatOnYaml.from_dir(File.join(@data_dir, "dir2"))
33
32
  # dir1 contains all the files in dir2
34
33
  cat_diff = cat1 - cat2
35
34
  cat_diff.size.should == 0
36
35
  end
37
36
 
38
37
  it "(dir2 - dir1): the difference from dir2 and dir1 is a file" do
39
- cat1 = Cat.from_dir(File.join(@data_dir, "dir1"))
40
- cat2 = Cat.from_dir(File.join(@data_dir, "dir2"))
38
+ cat1 = CatOnYaml.from_dir(File.join(@data_dir, "dir1"))
39
+ cat2 = CatOnYaml.from_dir(File.join(@data_dir, "dir2"))
41
40
 
42
41
  # dir2 contains one file more than dir1
43
42
  cat_diff = cat2 - cat1
@@ -45,10 +44,17 @@ describe Cat do
45
44
  end
46
45
 
47
46
  it "should detect duplicates" do
48
- cat1 = Cat.from_dir(File.join(@data_dir, "dir3"))
47
+ cat1 = CatOnYaml.from_dir(File.join(@data_dir, "dir3"))
49
48
  cat1.duplicates.should have(1).files
50
49
  end
51
50
 
51
+ # dir4 has an broken symlink, otherwise is identical to dir1
52
+ it "should build catalog from dir4" do
53
+ cat1 = CatOnYaml.from_dir(File.join(@data_dir, "dir4"))
54
+ cat1.size.should == 3
55
+ cat1.bytes.should == 20
56
+ end
57
+
52
58
  context "save to a file" do
53
59
  before do
54
60
  @tmp_file = File.join(Dir.tmpdir, "dircat1.yaml")
@@ -59,23 +65,23 @@ describe Cat do
59
65
  end
60
66
 
61
67
  it "saving to a file" do
62
- cat1 = Cat.from_dir(File.join(@data_dir, "dir1"))
68
+ cat1 = CatOnYaml.from_dir(File.join(@data_dir, "dir1"))
63
69
  cat1.save_to(@tmp_file)
64
70
 
65
- dircat1_bis = Cat.from_file(@tmp_file)
71
+ dircat1_bis = CatOnYaml.from_file(@tmp_file)
66
72
  (cat1 - dircat1_bis).size.should == 0
67
73
  (dircat1_bis - cat1).size.should == 0
68
74
  end
69
75
 
70
76
  it "saving to an non-existent file should raise an exception" do
71
- cat1 = Cat.from_dir(File.join(@data_dir, "dir1"))
77
+ cat1 = CatOnYaml.from_dir(File.join(@data_dir, "dir1"))
72
78
  not_existent_file = File.join(Dir.tmpdir, "not_existent", "dircat1.yaml")
73
79
  lambda { cat1.save_to(not_existent_file) }.should raise_exception(DirCatException)
74
80
  end
75
81
  end
76
82
 
77
83
  it "should print a report" do
78
- cat1 = Cat.from_dir(File.join(@data_dir, "dir1"))
84
+ cat1 = CatOnYaml.from_dir(File.join(@data_dir, "dir1"))
79
85
  cat1.size.should == 2
80
86
  cat1.bytes.should == 4
81
87