dircat 0.1.12 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +1 -1
- data/README.md +31 -6
- data/bin/dircat +5 -1
- data/bin/scat +9 -0
- data/dircat.gemspec +48 -15
- data/examples/example.rb +2 -1
- data/lib/dircat.rb +29 -34
- data/lib/dircat/cat_on_sqlite/cat_on_sqlite.rb +177 -0
- data/lib/dircat/cat_on_sqlite/directory_visitor.rb +106 -0
- data/lib/dircat/cat_on_sqlite/migration/00_create_dircat_properties.rb +13 -0
- data/lib/dircat/cat_on_sqlite/migration/01_create_categories.rb +12 -0
- data/lib/dircat/cat_on_sqlite/migration/02_create_images.rb +16 -0
- data/lib/dircat/cat_on_sqlite/migration/03_create_items.rb +23 -0
- data/lib/dircat/cat_on_sqlite/migration/04_create_taggings.rb +13 -0
- data/lib/dircat/cat_on_sqlite/migration/05_create_tags.rb +13 -0
- data/lib/dircat/cat_on_sqlite/model/category.rb +16 -0
- data/lib/dircat/cat_on_sqlite/model/image.rb +24 -0
- data/lib/dircat/cat_on_sqlite/model/item.rb +19 -0
- data/lib/dircat/cat_on_sqlite/model/tag.rb +58 -0
- data/lib/dircat/cat_on_sqlite/model/tagging.rb +9 -0
- data/lib/dircat/cat_on_sqlite/simple_cataloger_error.rb +9 -0
- data/lib/dircat/cat_on_sqlite_cli/cli_cat.rb +25 -0
- data/lib/dircat/cat_on_sqlite_cli/cli_server.rb +65 -0
- data/lib/dircat/cat_on_sqlite_cli/cmd_create.rb +56 -0
- data/lib/dircat/cat_on_sqlite_cli/cmd_list.rb +72 -0
- data/lib/dircat/cat_on_sqlite_cli/cmd_server.rb +62 -0
- data/lib/dircat/cat_on_sqlite_cli/cmd_update.rb +49 -0
- data/lib/dircat/{cat.rb → cat_on_yaml/cat_on_yaml.rb} +22 -10
- data/lib/dircat/cat_on_yaml/entry.rb +64 -0
- data/lib/dircat/{cli → cat_on_yaml_cli}/cli_dircat.rb +0 -0
- data/lib/dircat/{cli → cat_on_yaml_cli}/command_build.rb +53 -12
- data/lib/dircat/{cli → cat_on_yaml_cli}/command_diff.rb +4 -4
- data/lib/dircat/{cli → cat_on_yaml_cli}/command_query.rb +16 -2
- data/lib/dircat/config.rb +25 -0
- data/lib/dircat/extensions.rb +26 -0
- data/lib/dircat/server/helpers.rb +60 -0
- data/lib/dircat/server/my_static.rb +40 -0
- data/lib/dircat/server/web_server.rb +176 -0
- data/lib/dircat/version.rb +2 -1
- data/lib/dircat_on_sqlite.rb +31 -0
- data/lib/dircat_on_sqlite_cli.rb +37 -0
- data/lib/simple_cataloger_dm/cli.rb +32 -0
- data/lib/simple_cataloger_dm/core.rb +43 -0
- data/lib/simple_cataloger_dm/core/catalog.rb +141 -0
- data/lib/simple_cataloger_dm/core/directory_visitor.rb +107 -0
- data/lib/simple_cataloger_dm/core/extensions.rb +26 -0
- data/lib/simple_cataloger_dm/core/simple_cataloger_error.rb +9 -0
- data/lib/simple_cataloger_dm/models/category.rb +21 -0
- data/lib/simple_cataloger_dm/models/image.rb +30 -0
- data/lib/simple_cataloger_dm/models/item.rb +24 -0
- data/lib/simple_cataloger_dm/models/tag.rb +62 -0
- data/lib/simple_cataloger_dm/models/tagging.rb +11 -0
- data/lib/simple_cataloger_dm/server/helpers.rb +60 -0
- data/lib/simple_cataloger_dm/server/my_static.rb +40 -0
- data/lib/simple_cataloger_dm/server/web_server.rb +171 -0
- data/spec/dircat/cat_on_sqlite/cat_on_sqlite_spec.rb +41 -0
- data/spec/dircat/cat_on_sqlite_web/web_server_spec.rb +30 -0
- data/spec/dircat/{cat_spec.rb → cat_on_yaml/cat_on_yaml_spec.rb} +20 -14
- data/spec/dircat/{cli → cat_on_yaml_cli}/cli_dircat_spec.rb +0 -0
- data/spec/dircat/{cli → cat_on_yaml_cli}/command_build_spec.rb +4 -4
- data/spec/dircat/{cli → cat_on_yaml_cli}/command_diff_spec.rb +0 -0
- data/spec/dircat/{cli → cat_on_yaml_cli}/command_query_spec.rb +1 -1
- data/spec/fixtures/certified_output/cat_dir1_20120811.yaml +25 -0
- data/spec/fixtures/certified_output/cat_dir2_20120811.yaml +34 -0
- data/spec/fixtures/certified_output/{dircat1.yaml → dircat1_version_0.1.yaml} +0 -0
- data/spec/fixtures/certified_output/{dircat2.yaml → dircat2_version_0.1.yaml} +0 -0
- data/spec/fixtures/dir4/file1.txt +1 -0
- data/spec/fixtures/dir4/file2.txt +1 -0
- data/spec/fixtures/dir4/subdir/file3.txt +1 -0
- data/spec/fixtures/films/A-Z/A/Arancia meccanica [Stanley Kubrick][1971]/folder.jpg +0 -0
- data/spec/fixtures/films/A-Z/P/Plan 9 [Edward Wood][1959]/folder.jpg +0 -0
- data/spec/fixtures/films/Directors/[Akira Kurosawa]/[1940] Dersu Uzala [5]/folder.jpg +0 -0
- data/spec/fixtures/films/Directors/[Akira Kurosawa]/[1965] Barbarossa [Toshiro Mifune][4]/folder.jpg +0 -0
- data/spec/fixtures/films/Directors/[Federico Fellini]/[1963] 8 e mezzo [Marcello Mastroianni][Claudia Cardinale][5]/folder.jpg +0 -0
- data/spec/fixtures/films/Directors/[Woody Allen]/[1977] Annie Hall [Diane Keaton][5]/folder.jpg +0 -0
- data/{.gemtest → spec/fixtures/readme.txt} +0 -0
- data/spec/fixtures/tmp/test_ar.sqlite3 +0 -0
- data/spec/fixtures/tmp/test_ar.yml +7 -0
- data/spec/generate_directories_to_catalog.rb +80 -0
- data/spec/generate_mysql_catalog.rb +124 -0
- data/spec/spec_helper.rb +29 -0
- data/tasks/rspec.rake +0 -2
- metadata +390 -112
- data/lib/dircat/entry.rb +0 -61
- data/lib/dircat/extension_md5.rb +0 -25
- data/lib/dircat/extension_numeric.rb +0 -15
- data/spec/dircat/md5_spec.rb +0 -8
- data/spec/dircat/numeric_spec.rb +0 -13
@@ -0,0 +1,13 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class CreateDircatProperties < ActiveRecord::Migration
|
3
|
+
def self.up
|
4
|
+
create_table :dircat_properties do |t|
|
5
|
+
t.string :name, :null => false
|
6
|
+
t.string :value, :null => false
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
drop_table :dircat_properties
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class CreateImages < ActiveRecord::Migration
|
3
|
+
def self.up
|
4
|
+
create_table :images do |t|
|
5
|
+
t.string :path, :null => false
|
6
|
+
t.string :path_from_catalog_root, :null => false
|
7
|
+
|
8
|
+
t.integer :tag_id
|
9
|
+
t.integer :item_id
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :images
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class CreateItems < ActiveRecord::Migration
|
3
|
+
def self.up
|
4
|
+
create_table :items do |t|
|
5
|
+
|
6
|
+
t.string :md5
|
7
|
+
|
8
|
+
t.string :name, :null => false
|
9
|
+
t.string :path, :null => false
|
10
|
+
t.string :path_from_catalog_root, :null => false
|
11
|
+
t.integer :size, :null => false
|
12
|
+
|
13
|
+
t.date :added_at, :null => false
|
14
|
+
|
15
|
+
t.integer :rating
|
16
|
+
t.date :flagged_at
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.down
|
21
|
+
drop_table :items
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SimpleCataloger
|
3
|
+
|
4
|
+
class Category < ActiveRecord::Base
|
5
|
+
scope :order_by_name, order("name")
|
6
|
+
has_many :tags, :order => "name"
|
7
|
+
|
8
|
+
# tried following but it didn't work
|
9
|
+
# has_many :items, :through => :tags
|
10
|
+
#
|
11
|
+
def items
|
12
|
+
tags.collect { |t| t.items }.flatten
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SimpleCataloger
|
3
|
+
|
4
|
+
class Image < ActiveRecord::Base
|
5
|
+
belongs_to :item # :required => false
|
6
|
+
belongs_to :tag # :required => false
|
7
|
+
|
8
|
+
def to_json(*a)
|
9
|
+
{ :item => if item then
|
10
|
+
item.name
|
11
|
+
else
|
12
|
+
nil
|
13
|
+
end,
|
14
|
+
:tag => if tag then
|
15
|
+
tag.name
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end,
|
19
|
+
:src => path_from_catalog_root }.to_json(*a)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SimpleCataloger
|
3
|
+
|
4
|
+
class Tag < ActiveRecord::Base
|
5
|
+
belongs_to :category
|
6
|
+
|
7
|
+
has_many :taggings
|
8
|
+
has_many :items, :through => :taggings, :order => "name"
|
9
|
+
has_many :images
|
10
|
+
|
11
|
+
##################################################
|
12
|
+
#
|
13
|
+
|
14
|
+
RE_TAG = /\[([^\]]+)\]/
|
15
|
+
|
16
|
+
# extracts tags from directory or file name
|
17
|
+
def self.extract_tags(dir_or_file_name)
|
18
|
+
tags = []
|
19
|
+
match_data = dir_or_file_name.match(RE_TAG)
|
20
|
+
while match_data
|
21
|
+
tags << match_data[1]
|
22
|
+
match_data = dir_or_file_name.match(RE_TAG, match_data.end(0))
|
23
|
+
end
|
24
|
+
tags
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.extract_name(dir_or_file_name)
|
28
|
+
dir_or_file_name.gsub(Tag::RE_TAG, '').strip
|
29
|
+
end
|
30
|
+
|
31
|
+
RE_RATING = /^\d$/
|
32
|
+
RE_YEAR = /^\d\d\d\d$/
|
33
|
+
|
34
|
+
MATCHES = [
|
35
|
+
[RE_RATING, "rating", proc { |tag_name| tag_name.to_i }],
|
36
|
+
[RE_YEAR, "year", proc { |tag_name| tag_name.to_i }]
|
37
|
+
]
|
38
|
+
|
39
|
+
#
|
40
|
+
# decode standard tags
|
41
|
+
#
|
42
|
+
def self.match_category(tag_name)
|
43
|
+
MATCHES.each do |re, category_name, convert|
|
44
|
+
if re.match tag_name
|
45
|
+
category = Category.find_or_create_by_name(category_name)
|
46
|
+
tag = Tag.find_or_create_by_name_and_category_id(
|
47
|
+
convert.call(tag_name),
|
48
|
+
category.id
|
49
|
+
)
|
50
|
+
return category
|
51
|
+
end
|
52
|
+
end
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
end # class Tag
|
57
|
+
|
58
|
+
end # module SimpleCatalog
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class CliCat < OptParseCommand::CliMain
|
3
|
+
|
4
|
+
def self.command
|
5
|
+
"simple_cataloger"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.description
|
9
|
+
"description"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.version
|
13
|
+
SimpleCataloger::VERSION
|
14
|
+
end
|
15
|
+
|
16
|
+
# def defaults(options)
|
17
|
+
# OpenStruct.new(
|
18
|
+
# )
|
19
|
+
# end
|
20
|
+
|
21
|
+
# def option_parser(options)
|
22
|
+
# super(options)
|
23
|
+
# end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SimpleCataloger
|
3
|
+
#
|
4
|
+
# Build a catalogue starting from a directory
|
5
|
+
#
|
6
|
+
class CliServer
|
7
|
+
|
8
|
+
def self.run
|
9
|
+
return self.new.parse_args( ARGV )
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_args( argv )
|
13
|
+
options = { :verbose => true, :force => false }
|
14
|
+
opts = OptionParser.new
|
15
|
+
opts.banner << " <catalog name>\n"
|
16
|
+
opts.banner << "launch a webs server to browse the content of <catalog name>\n";
|
17
|
+
opts.banner << "\n"
|
18
|
+
|
19
|
+
opts.on("-h", "--help", "Print this message") do
|
20
|
+
puts opts
|
21
|
+
return 0
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("--version", "show the simple catalog version") do
|
25
|
+
puts "simple catalog version #{SimpleCatalog::version}"
|
26
|
+
return 0
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
30
|
+
options[:verbose] = v
|
31
|
+
end
|
32
|
+
|
33
|
+
rest = opts.parse(argv)
|
34
|
+
|
35
|
+
if rest.length < 1
|
36
|
+
puts "too few arguments"
|
37
|
+
puts "-h to print help"
|
38
|
+
return 0
|
39
|
+
end
|
40
|
+
|
41
|
+
catalog_name = rest[0]
|
42
|
+
cat_opts = {}
|
43
|
+
|
44
|
+
#
|
45
|
+
# option verbose
|
46
|
+
#
|
47
|
+
|
48
|
+
if options.has_key?(:verbose)
|
49
|
+
if options[:verbose]
|
50
|
+
cat_opts[:verbose_level] = 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# main
|
56
|
+
#
|
57
|
+
|
58
|
+
catalog = CatOnSqlite.new(catalog_name)
|
59
|
+
WebServer.run! :host => 'localhost', :port => 9091, :catalog => catalog
|
60
|
+
|
61
|
+
0
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SimpleCataloger
|
3
|
+
class CmdCreate < OptParseCommand::Command
|
4
|
+
|
5
|
+
CliCat.register_command(self)
|
6
|
+
|
7
|
+
def self.command
|
8
|
+
"create"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.description
|
12
|
+
"create a catalog"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.usage
|
16
|
+
"#{command} <catalog name> <directory>\n" +
|
17
|
+
"Create a catalog with name <catalog name> starting from structure of <directory>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def defaults(options)
|
21
|
+
options.force = false
|
22
|
+
options
|
23
|
+
end
|
24
|
+
|
25
|
+
def option_parser(options)
|
26
|
+
parser = super(options)
|
27
|
+
parser
|
28
|
+
end
|
29
|
+
|
30
|
+
def exec(main, options, rest)
|
31
|
+
if rest.length < 2
|
32
|
+
puts "too few arguments"
|
33
|
+
puts "-h to print help"
|
34
|
+
return 0
|
35
|
+
end
|
36
|
+
catalog_name = rest[0]
|
37
|
+
catalog_dirname = rest[1]
|
38
|
+
catalog_dirname = File.expand_path(catalog_dirname)
|
39
|
+
|
40
|
+
if not FileTest.directory?(catalog_dirname)
|
41
|
+
puts "'#{catalog_dirname}' not exists or is not a directory"
|
42
|
+
return 0
|
43
|
+
end
|
44
|
+
|
45
|
+
begin
|
46
|
+
catalog = SimpleCataloger::CatOnSqlite.new(catalog_name)
|
47
|
+
catalog.create(catalog_dirname)
|
48
|
+
catalog.update
|
49
|
+
rescue SimpleCataloger::SimpleCatalogerError => e
|
50
|
+
puts e.message
|
51
|
+
end
|
52
|
+
0
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SimpleCataloger
|
3
|
+
class CmdList < OptParseCommand::Command
|
4
|
+
|
5
|
+
CliCat.register_command(self)
|
6
|
+
|
7
|
+
def self.command
|
8
|
+
"list"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.description
|
12
|
+
"list items in catalog"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.usage
|
16
|
+
"#{command} <catalog name> <directory>\n" +
|
17
|
+
"Create a catalog with name <catalog name> starting from structure of <directory>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def defaults(options)
|
21
|
+
options.force = false
|
22
|
+
options
|
23
|
+
end
|
24
|
+
|
25
|
+
def option_parser(options)
|
26
|
+
parser = super(options)
|
27
|
+
parser
|
28
|
+
end
|
29
|
+
|
30
|
+
def exec(main, options, rest)
|
31
|
+
if rest.length < 1
|
32
|
+
puts "too few arguments"
|
33
|
+
puts "-h to print help"
|
34
|
+
return 0
|
35
|
+
end
|
36
|
+
|
37
|
+
catalog_name = rest[0]
|
38
|
+
cat_opts = {}
|
39
|
+
|
40
|
+
# begin
|
41
|
+
catalog = CatOnSqlite.new(catalog_name).open
|
42
|
+
puts "contains of '#{catalog.name}'"
|
43
|
+
puts "categories"
|
44
|
+
Category.all.each do |c|
|
45
|
+
puts "\t #{c.name}"
|
46
|
+
end
|
47
|
+
|
48
|
+
# Category.find_by_name("Actor").items.each do |i|
|
49
|
+
# pp i
|
50
|
+
# end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Tags
|
54
|
+
#
|
55
|
+
puts "tags"
|
56
|
+
Tag.all.each do |t|
|
57
|
+
puts "\t #{t.name} (category: #{t.category.name})"
|
58
|
+
end
|
59
|
+
|
60
|
+
puts "items"
|
61
|
+
Item.all.each do |f|
|
62
|
+
puts "\t #{f.name}"
|
63
|
+
end
|
64
|
+
# rescue e
|
65
|
+
# puts e.message
|
66
|
+
# end
|
67
|
+
|
68
|
+
0
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|