rivendell-import 0.9 → 0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +84 -73
- data/Guardfile +2 -5
- data/lib/rivendell/import/base.rb +1 -1
- data/lib/rivendell/import/cart.rb +84 -27
- data/lib/rivendell/import/context.rb +4 -0
- data/lib/rivendell/import/file.rb +36 -0
- data/lib/rivendell/import/task.rb +7 -1
- data/lib/rivendell/import/tasking/file.rb +4 -0
- data/lib/rivendell/import/tasks.rb +13 -2
- data/lib/rivendell/import/version.rb +1 -1
- data/lib/rivendell/import/views/index.erb +1 -1
- data/lib/rivendell/import/worker.rb +12 -9
- data/lib/rivendell/import.rb +1 -0
- data/rivendell-import.gemspec +2 -1
- data/spec/fixtures/audio.ogg +0 -0
- data/spec/rivendell/import/base_spec.rb +1 -1
- data/spec/rivendell/import/cart_spec.rb +208 -23
- data/spec/rivendell/import/context_spec.rb +12 -1
- data/spec/rivendell/import/file_spec.rb +45 -7
- data/spec/rivendell/import/task_spec.rb +26 -0
- data/spec/support/fixtures.rb +5 -1
- metadata +24 -6
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rivendell-import (0.
|
4
|
+
rivendell-import (0.10)
|
5
5
|
SyslogLogger (~> 2.0)
|
6
6
|
activerecord (~> 3.2.8)
|
7
7
|
activesupport (~> 3.2.8)
|
@@ -11,9 +11,10 @@ PATH
|
|
11
11
|
listen (~> 1.3.1)
|
12
12
|
mail
|
13
13
|
rivendell-api (~> 0.0.5)
|
14
|
-
rivendell-db (~> 0.
|
14
|
+
rivendell-db (~> 0.3)
|
15
15
|
sinatra
|
16
16
|
sqlite3
|
17
|
+
taglib-ruby
|
17
18
|
trollop
|
18
19
|
will_paginate (~> 3.0.0)
|
19
20
|
|
@@ -21,38 +22,40 @@ GEM
|
|
21
22
|
remote: https://rubygems.org/
|
22
23
|
specs:
|
23
24
|
SyslogLogger (2.0)
|
24
|
-
activemodel (3.2.
|
25
|
-
activesupport (= 3.2.
|
25
|
+
activemodel (3.2.19)
|
26
|
+
activesupport (= 3.2.19)
|
26
27
|
builder (~> 3.0.0)
|
27
|
-
activerecord (3.2.
|
28
|
-
activemodel (= 3.2.
|
29
|
-
activesupport (= 3.2.
|
28
|
+
activerecord (3.2.19)
|
29
|
+
activemodel (= 3.2.19)
|
30
|
+
activesupport (= 3.2.19)
|
30
31
|
arel (~> 3.0.2)
|
31
32
|
tzinfo (~> 0.3.29)
|
32
|
-
activesupport (3.2.
|
33
|
+
activesupport (3.2.19)
|
33
34
|
i18n (~> 0.6, >= 0.6.4)
|
34
35
|
multi_json (~> 1.0)
|
35
|
-
addressable (2.3.
|
36
|
+
addressable (2.3.6)
|
36
37
|
arel (3.0.3)
|
37
|
-
bcrypt
|
38
|
+
bcrypt (3.1.7)
|
39
|
+
bcrypt-ruby (3.1.5)
|
40
|
+
bcrypt (>= 3.1.3)
|
38
41
|
builder (3.0.4)
|
39
|
-
capistrano (2.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
cucumber (1.3.
|
42
|
+
capistrano (3.2.1)
|
43
|
+
i18n
|
44
|
+
rake (>= 10.0.0)
|
45
|
+
sshkit (~> 1.3)
|
46
|
+
coderay (1.1.0)
|
47
|
+
colorize (0.7.3)
|
48
|
+
cucumber (1.3.17)
|
46
49
|
builder (>= 2.1.2)
|
47
50
|
diff-lcs (>= 1.1.3)
|
48
51
|
gherkin (~> 2.12)
|
49
52
|
multi_json (>= 1.7.5, < 2.0)
|
50
|
-
multi_test (>= 0.
|
53
|
+
multi_test (>= 0.1.1)
|
51
54
|
daemons (1.1.9)
|
52
|
-
data_objects (0.10.
|
55
|
+
data_objects (0.10.14)
|
53
56
|
addressable (~> 2.1)
|
54
|
-
database_cleaner (
|
55
|
-
diff-lcs (1.
|
57
|
+
database_cleaner (1.3.0)
|
58
|
+
diff-lcs (1.2.5)
|
56
59
|
dm-core (1.2.1)
|
57
60
|
addressable (~> 2.3)
|
58
61
|
dm-do-adapter (1.2.0)
|
@@ -77,106 +80,114 @@ GEM
|
|
77
80
|
uuidtools (~> 2.1)
|
78
81
|
dm-validations (1.2.0)
|
79
82
|
dm-core (~> 1.2.0)
|
80
|
-
do_mysql (0.10.
|
81
|
-
data_objects (= 0.10.
|
83
|
+
do_mysql (0.10.14)
|
84
|
+
data_objects (= 0.10.14)
|
85
|
+
docile (1.1.5)
|
82
86
|
fastercsv (1.5.5)
|
83
|
-
ffi (1.9.
|
87
|
+
ffi (1.9.5)
|
88
|
+
formatador (0.2.5)
|
84
89
|
gherkin (2.12.2)
|
85
90
|
multi_json (~> 1.3)
|
86
|
-
guard (1.
|
87
|
-
|
91
|
+
guard (1.8.3)
|
92
|
+
formatador (>= 0.2.4)
|
93
|
+
listen (~> 1.3)
|
94
|
+
lumberjack (>= 1.0.2)
|
95
|
+
pry (>= 0.9.10)
|
88
96
|
thor (>= 0.14.6)
|
89
|
-
guard-cucumber (1.
|
97
|
+
guard-cucumber (1.4.1)
|
90
98
|
cucumber (>= 1.2.0)
|
91
99
|
guard (>= 1.1.0)
|
92
|
-
guard-rspec (
|
93
|
-
guard (>= 1.
|
94
|
-
rspec (~> 2.
|
95
|
-
|
96
|
-
httmultiparty (0.3.14)
|
100
|
+
guard-rspec (3.1.0)
|
101
|
+
guard (>= 1.8)
|
102
|
+
rspec (~> 2.13)
|
103
|
+
httmultiparty (0.3.15)
|
97
104
|
httparty (>= 0.7.3)
|
98
105
|
mimemagic
|
99
106
|
multipart-post
|
100
107
|
httparty (0.11.0)
|
101
108
|
multi_json (~> 1.0)
|
102
109
|
multi_xml (>= 0.5.2)
|
103
|
-
i18n (0.6.
|
110
|
+
i18n (0.6.11)
|
104
111
|
json (1.8.1)
|
105
112
|
json_pure (1.8.1)
|
106
|
-
libnotify (0.8.
|
113
|
+
libnotify (0.8.3)
|
107
114
|
ffi (>= 1.0.11)
|
108
115
|
listen (1.3.1)
|
109
116
|
rb-fsevent (>= 0.9.3)
|
110
117
|
rb-inotify (>= 0.9)
|
111
118
|
rb-kqueue (>= 0.2)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
119
|
+
lumberjack (1.0.9)
|
120
|
+
mail (2.6.1)
|
121
|
+
mime-types (>= 1.16, < 3)
|
122
|
+
method_source (0.8.2)
|
123
|
+
mime-types (2.3)
|
116
124
|
mimemagic (0.2.1)
|
117
|
-
multi_json (1.
|
118
|
-
multi_test (0.
|
125
|
+
multi_json (1.10.1)
|
126
|
+
multi_test (0.1.1)
|
119
127
|
multi_xml (0.5.5)
|
120
128
|
multipart-post (2.0.0)
|
121
|
-
net-scp (1.1
|
122
|
-
net-ssh (>= 2.6.5)
|
123
|
-
net-sftp (2.1.1)
|
124
|
-
net-ssh (>= 2.6.5)
|
125
|
-
net-ssh (2.6.6)
|
126
|
-
net-ssh-gateway (1.2.0)
|
129
|
+
net-scp (1.2.1)
|
127
130
|
net-ssh (>= 2.6.5)
|
131
|
+
net-ssh (2.9.1)
|
128
132
|
null_logger (0.0.1)
|
129
|
-
|
133
|
+
pry (0.10.1)
|
134
|
+
coderay (~> 1.1.0)
|
135
|
+
method_source (~> 0.8.1)
|
136
|
+
slop (~> 3.4)
|
130
137
|
rack (1.5.2)
|
131
|
-
rack-protection (1.5.
|
138
|
+
rack-protection (1.5.3)
|
132
139
|
rack
|
133
|
-
rake (
|
134
|
-
rb-fsevent (0.9.
|
135
|
-
rb-inotify (0.9.
|
140
|
+
rake (10.3.2)
|
141
|
+
rb-fsevent (0.9.4)
|
142
|
+
rb-inotify (0.9.5)
|
136
143
|
ffi (>= 0.5.0)
|
137
|
-
rb-kqueue (0.2.
|
144
|
+
rb-kqueue (0.2.3)
|
138
145
|
ffi (>= 0.5.0)
|
139
|
-
rdoc (
|
146
|
+
rdoc (4.1.2)
|
140
147
|
json (~> 1.4)
|
141
148
|
rivendell-api (0.0.5)
|
142
149
|
activesupport
|
143
150
|
httmultiparty
|
144
151
|
null_logger
|
145
|
-
rivendell-db (0.
|
152
|
+
rivendell-db (0.3)
|
146
153
|
dm-core
|
147
154
|
dm-mysql-adapter
|
148
155
|
dm-serializer
|
149
156
|
dm-types
|
150
157
|
dm-validations
|
151
|
-
rspec (2.
|
152
|
-
rspec-core (~> 2.
|
153
|
-
rspec-expectations (~> 2.
|
154
|
-
rspec-mocks (~> 2.
|
155
|
-
rspec-core (2.
|
156
|
-
rspec-expectations (2.
|
157
|
-
diff-lcs (
|
158
|
-
rspec-mocks (2.
|
159
|
-
simplecov (0.
|
158
|
+
rspec (2.99.0)
|
159
|
+
rspec-core (~> 2.99.0)
|
160
|
+
rspec-expectations (~> 2.99.0)
|
161
|
+
rspec-mocks (~> 2.99.0)
|
162
|
+
rspec-core (2.99.2)
|
163
|
+
rspec-expectations (2.99.2)
|
164
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
165
|
+
rspec-mocks (2.99.2)
|
166
|
+
simplecov (0.9.1)
|
167
|
+
docile (~> 1.1.0)
|
160
168
|
multi_json (~> 1.0)
|
161
|
-
simplecov-html (~> 0.
|
162
|
-
simplecov-html (0.
|
169
|
+
simplecov-html (~> 0.8.0)
|
170
|
+
simplecov-html (0.8.0)
|
163
171
|
simplecov-rcov (0.2.3)
|
164
172
|
simplecov (>= 0.4.1)
|
165
|
-
sinatra (1.4.
|
173
|
+
sinatra (1.4.5)
|
166
174
|
rack (~> 1.4)
|
167
175
|
rack-protection (~> 1.4)
|
168
176
|
tilt (~> 1.3, >= 1.3.4)
|
177
|
+
slop (3.6.0)
|
169
178
|
sqlite3 (1.3.9)
|
179
|
+
sshkit (1.5.1)
|
180
|
+
colorize
|
181
|
+
net-scp (>= 1.1.2)
|
182
|
+
net-ssh (>= 2.8.0)
|
170
183
|
stringex (1.5.1)
|
171
|
-
|
184
|
+
taglib-ruby (0.7.0)
|
185
|
+
thor (0.19.1)
|
172
186
|
tilt (1.4.1)
|
173
|
-
treetop (1.4.15)
|
174
|
-
polyglot
|
175
|
-
polyglot (>= 0.3.1)
|
176
187
|
trollop (2.0)
|
177
|
-
tzinfo (0.3.
|
178
|
-
uuidtools (2.1.
|
179
|
-
will_paginate (3.0.
|
188
|
+
tzinfo (0.3.41)
|
189
|
+
uuidtools (2.1.5)
|
190
|
+
will_paginate (3.0.7)
|
180
191
|
|
181
192
|
PLATFORMS
|
182
193
|
ruby
|
data/Guardfile
CHANGED
@@ -1,9 +1,6 @@
|
|
1
|
-
|
2
|
-
# More info at https://github.com/guard/guard#readme
|
3
|
-
|
4
|
-
guard 'rspec' do
|
1
|
+
guard :rspec do
|
5
2
|
watch(%r{^spec/.+_spec\.rb$})
|
6
|
-
watch(%r{^lib/(.+)\.rb$}) { |m| "spec
|
3
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
4
|
watch('spec/spec_helper.rb') { "spec" }
|
8
5
|
end
|
9
6
|
|
@@ -10,7 +10,7 @@ module Rivendell::Import
|
|
10
10
|
|
11
11
|
def attributes
|
12
12
|
attributes = {}
|
13
|
-
%w{number group clear_cuts title default_title import_options}.each do |attribute|
|
13
|
+
%w{number group clear_cuts title default_title scheduler_codes import_options}.each do |attribute|
|
14
14
|
value = send attribute
|
15
15
|
attributes[attribute] = value if value.present?
|
16
16
|
end
|
@@ -32,13 +32,17 @@ module Rivendell::Import
|
|
32
32
|
|
33
33
|
delegate :blank?, :to => :attributes
|
34
34
|
|
35
|
-
attr_accessor :number, :group, :title, :default_title
|
35
|
+
attr_accessor :number, :group, :title, :default_title, :scheduler_codes
|
36
36
|
attr_reader :task
|
37
37
|
|
38
38
|
def initialize(task = nil)
|
39
39
|
@task = task
|
40
40
|
end
|
41
41
|
|
42
|
+
def scheduler_codes
|
43
|
+
@scheduler_codes ||= []
|
44
|
+
end
|
45
|
+
|
42
46
|
def xport
|
43
47
|
task.xport
|
44
48
|
end
|
@@ -51,44 +55,97 @@ module Rivendell::Import
|
|
51
55
|
end
|
52
56
|
|
53
57
|
def update
|
54
|
-
|
55
|
-
|
56
|
-
rescue => e
|
57
|
-
Rivendell::Import.logger.debug "Update by API failed : #{e}"
|
58
|
-
update_by_db if Database.enabled?
|
58
|
+
updaters.any? do |updater|
|
59
|
+
updater.new(self).update
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
62
|
-
def
|
63
|
-
[
|
63
|
+
def updaters
|
64
|
+
[].tap do |updaters|
|
65
|
+
updaters << ApiUpdater if scheduler_codes.empty?
|
66
|
+
updaters << DbUpdater if Database.enabled?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Updater
|
71
|
+
|
72
|
+
attr_accessor :cart
|
73
|
+
|
74
|
+
def initialize(cart)
|
75
|
+
@cart = cart
|
76
|
+
end
|
77
|
+
delegate :number, :title, :default_title, :scheduler_codes, :to => :cart
|
78
|
+
|
79
|
+
def empty_title?(title)
|
80
|
+
[ nil, "", "[new cart]" ].include? title
|
81
|
+
end
|
82
|
+
|
83
|
+
def title_with_default
|
84
|
+
@title_with_default ||=
|
85
|
+
if title
|
86
|
+
title
|
87
|
+
else
|
88
|
+
default_title if default_title && empty_title?(current_title)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def update
|
93
|
+
begin
|
94
|
+
update!
|
95
|
+
rescue => e
|
96
|
+
Rivendell::Import.logger.debug "#{self.class.name} failed : #{e}"
|
97
|
+
false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
64
101
|
end
|
65
102
|
|
66
|
-
|
67
|
-
update_attributes = {}
|
103
|
+
class ApiUpdater < Updater
|
68
104
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
105
|
+
def update!
|
106
|
+
unless attributes.empty?
|
107
|
+
Rivendell::Import.logger.debug "Update Cart by API : #{attributes}"
|
108
|
+
xport.edit_cart number, attributes
|
109
|
+
else
|
110
|
+
true
|
111
|
+
end
|
73
112
|
end
|
74
113
|
|
75
|
-
|
76
|
-
|
77
|
-
|
114
|
+
delegate :xport, :to => :cart
|
115
|
+
|
116
|
+
def current_title
|
117
|
+
xport.list_cart(number).title
|
78
118
|
end
|
119
|
+
|
120
|
+
def attributes
|
121
|
+
{}.tap do |attributes|
|
122
|
+
attributes[:title] = title_with_default if title_with_default
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
79
126
|
end
|
80
127
|
|
81
|
-
|
82
|
-
Database.init
|
128
|
+
class DbUpdater < Updater
|
83
129
|
|
84
|
-
|
85
|
-
|
86
|
-
if title
|
87
|
-
current_cart.title = title
|
88
|
-
else
|
89
|
-
current_cart.title = default_title if default_title && empty_title?(current_cart.title)
|
130
|
+
def current_cart
|
131
|
+
@current_cart ||= Rivendell::DB::Cart.get(number)
|
90
132
|
end
|
91
|
-
|
133
|
+
|
134
|
+
def current_title
|
135
|
+
current_cart.title
|
136
|
+
end
|
137
|
+
|
138
|
+
def update!
|
139
|
+
Database.init
|
140
|
+
|
141
|
+
if title_with_default or not scheduler_codes.empty?
|
142
|
+
Rivendell::Import.logger.debug "Update Cart by DB"
|
143
|
+
current_cart.title = title_with_default
|
144
|
+
current_cart.scheduler_codes = scheduler_codes
|
145
|
+
current_cart.save
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
92
149
|
end
|
93
150
|
|
94
151
|
def cut
|
@@ -31,6 +31,16 @@ module Rivendell::Import
|
|
31
31
|
::File.extname(name).gsub(/^\./,'')
|
32
32
|
end
|
33
33
|
|
34
|
+
def directories
|
35
|
+
filename = path
|
36
|
+
[].tap do |directories|
|
37
|
+
while (parent = ::File.dirname(filename)) != ::File::SEPARATOR
|
38
|
+
directories << ::File.basename(parent)
|
39
|
+
filename = parent
|
40
|
+
end
|
41
|
+
end.reverse
|
42
|
+
end
|
43
|
+
|
34
44
|
def ==(other)
|
35
45
|
other and path == other.path
|
36
46
|
end
|
@@ -65,6 +75,32 @@ module Rivendell::Import
|
|
65
75
|
::File.exists? path
|
66
76
|
end
|
67
77
|
|
78
|
+
def file_ref
|
79
|
+
@file_ref ||=
|
80
|
+
if exists? and not (file_ref = TagLib::FileRef.new(path)).null?
|
81
|
+
file_ref
|
82
|
+
else
|
83
|
+
:null
|
84
|
+
end
|
85
|
+
|
86
|
+
@file_ref unless :null == @file_ref
|
87
|
+
end
|
88
|
+
|
89
|
+
def close
|
90
|
+
if @file_ref.respond_to?(:close)
|
91
|
+
@file_ref.close
|
92
|
+
@file_ref = nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def tag
|
97
|
+
file_ref.tag if file_ref
|
98
|
+
end
|
99
|
+
|
100
|
+
def audio_properties
|
101
|
+
file_ref.audio_properties if file_ref
|
102
|
+
end
|
103
|
+
|
68
104
|
def destroy!
|
69
105
|
Rivendell::Import.logger.debug "Delete file #{path}"
|
70
106
|
::File.delete(path) if exists?
|
@@ -17,7 +17,11 @@ module Rivendell::Import
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.ready
|
20
|
-
|
20
|
+
pending.by_priority.select(&:ready?)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.by_priority
|
24
|
+
order(["priority desc", "created_at"])
|
21
25
|
end
|
22
26
|
|
23
27
|
RAN_STATUSES = %w{completed failed canceled}.freeze
|
@@ -128,6 +132,8 @@ module Rivendell::Import
|
|
128
132
|
logger.error "Task failed : #{e}"
|
129
133
|
logger.debug e.backtrace.join("\n")
|
130
134
|
ensure
|
135
|
+
close_file
|
136
|
+
|
131
137
|
unless ran?
|
132
138
|
change_status! :failed
|
133
139
|
end
|
@@ -14,8 +14,19 @@ module Rivendell::Import
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def create(file, &block)
|
17
|
-
|
18
|
-
|
17
|
+
retry_count = 3
|
18
|
+
begin
|
19
|
+
Rivendell::Import::Task.create({:file => file}, {}, &block).tap do |task|
|
20
|
+
Rivendell::Import.logger.debug "Created task #{task.inspect}"
|
21
|
+
end
|
22
|
+
rescue Exception => e
|
23
|
+
Rivendell::Import.logger.error "Can't create Task: #{e}"
|
24
|
+
retry_count -= 1
|
25
|
+
if retry_count > 0
|
26
|
+
Rivendell::Import.logger.error "Retry in 5s"
|
27
|
+
sleep 5
|
28
|
+
retry
|
29
|
+
end
|
19
30
|
end
|
20
31
|
end
|
21
32
|
|
@@ -8,9 +8,9 @@ module Rivendell::Import
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def start
|
11
|
-
Thread.new do
|
11
|
+
Thread.new do
|
12
12
|
Rivendell::Import.logger.debug "Start Worker"
|
13
|
-
run
|
13
|
+
run
|
14
14
|
end
|
15
15
|
|
16
16
|
self
|
@@ -18,16 +18,19 @@ module Rivendell::Import
|
|
18
18
|
|
19
19
|
def run
|
20
20
|
loop do
|
21
|
-
|
22
|
-
|
23
|
-
task
|
24
|
-
|
25
|
-
|
21
|
+
begin
|
22
|
+
task = import.tasks.pop
|
23
|
+
if task
|
24
|
+
task.run
|
25
|
+
else
|
26
|
+
# Rivendell::Import.logger.debug "No pending task, sleep 10s"
|
27
|
+
sleep 10
|
28
|
+
end
|
29
|
+
rescue Exception => e
|
30
|
+
Rivendell::Import.logger.error "Worker failed : #{e}"
|
26
31
|
sleep 10
|
27
32
|
end
|
28
33
|
end
|
29
|
-
rescue => e
|
30
|
-
Rivendell::Import.logger.error "Worker failed : #{e}"
|
31
34
|
end
|
32
35
|
|
33
36
|
end
|
data/lib/rivendell/import.rb
CHANGED
data/rivendell-import.gemspec
CHANGED
@@ -27,13 +27,14 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_runtime_dependency 'mail'
|
28
28
|
gem.add_runtime_dependency 'sqlite3'
|
29
29
|
gem.add_runtime_dependency 'SyslogLogger', '~> 2.0'
|
30
|
+
gem.add_runtime_dependency 'taglib-ruby'
|
30
31
|
|
31
32
|
gem.add_runtime_dependency 'sinatra'
|
32
33
|
gem.add_runtime_dependency 'will_paginate', '~> 3.0.0'
|
33
34
|
|
34
35
|
gem.add_runtime_dependency 'daemons'
|
35
36
|
|
36
|
-
gem.add_runtime_dependency 'rivendell-db', '~> 0.
|
37
|
+
gem.add_runtime_dependency 'rivendell-db', '~> 0.3'
|
37
38
|
|
38
39
|
gem.add_development_dependency "simplecov"
|
39
40
|
gem.add_development_dependency "rspec"
|
Binary file
|
@@ -188,6 +188,11 @@ describe Rivendell::Import::Cart do
|
|
188
188
|
subject.attributes["cut"].should == { "days" => %{mon} }
|
189
189
|
end
|
190
190
|
|
191
|
+
it "should include scheduler codes" do
|
192
|
+
subject.scheduler_codes << "dummy"
|
193
|
+
subject.attributes["scheduler_codes"].should == ["dummy"]
|
194
|
+
end
|
195
|
+
|
191
196
|
end
|
192
197
|
|
193
198
|
describe "#to_json" do
|
@@ -208,6 +213,60 @@ describe Rivendell::Import::Cart do
|
|
208
213
|
|
209
214
|
end
|
210
215
|
|
216
|
+
describe "#updaters" do
|
217
|
+
|
218
|
+
it "should contain ApiUpdater" do
|
219
|
+
subject.updaters.should include(Rivendell::Import::Cart::ApiUpdater)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should not contain ApiUpdater if scheduler codes is defined" do
|
223
|
+
subject.scheduler_codes << "dummy"
|
224
|
+
subject.updaters.should_not include(Rivendell::Import::Cart::ApiUpdater)
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should contain DbUpdater if Database is enabled" do
|
228
|
+
Rivendell::Import::Database.stub :enabled? => true
|
229
|
+
subject.updaters.should include(Rivendell::Import::Cart::DbUpdater)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should not contain DbUpdater if Database isn't enabled" do
|
233
|
+
Rivendell::Import::Database.stub :enabled? => false
|
234
|
+
subject.updaters.should_not include(Rivendell::Import::Cart::DbUpdater)
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
describe "#update" do
|
240
|
+
|
241
|
+
def updater(success = true)
|
242
|
+
double(:new => mock(:update => success))
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should return true if an Updater is successful" do
|
246
|
+
subject.stub :updaters => [updater(false), updater(true)]
|
247
|
+
subject.update.should be_true
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should return true if all Updaters are not successful" do
|
251
|
+
subject.stub :updaters => [updater(false)]
|
252
|
+
subject.update.should be_false
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should return false when no Updater is available" do
|
256
|
+
subject.stub :updaters => []
|
257
|
+
subject.update.should be_false
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
|
264
|
+
describe Rivendell::Import::Cart::Updater do
|
265
|
+
|
266
|
+
let(:task) { mock }
|
267
|
+
let(:cart) { Rivendell::Import::Cart.new task }
|
268
|
+
subject { Rivendell::Import::Cart::Updater.new cart }
|
269
|
+
|
211
270
|
describe "#empty_title?" do
|
212
271
|
|
213
272
|
it "should true when title is nil" do
|
@@ -224,44 +283,170 @@ describe Rivendell::Import::Cart do
|
|
224
283
|
|
225
284
|
end
|
226
285
|
|
227
|
-
describe "update" do
|
286
|
+
describe "#update" do
|
228
287
|
|
229
|
-
it "should
|
230
|
-
subject.
|
231
|
-
subject.update
|
288
|
+
it "should return false if update! raises an error" do
|
289
|
+
subject.stub(:update!).and_raise("fail")
|
290
|
+
subject.update.should be_false
|
232
291
|
end
|
233
292
|
|
234
|
-
|
293
|
+
it "should return true if update! returns true" do
|
294
|
+
subject.stub :update! => true
|
295
|
+
subject.update.should be_true
|
296
|
+
end
|
235
297
|
|
236
|
-
|
237
|
-
|
298
|
+
it "should return false if update! returns false" do
|
299
|
+
subject.stub :update! => false
|
300
|
+
subject.update.should be_false
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
describe "#title_with_default" do
|
306
|
+
|
307
|
+
context "when Cart title is defined" do
|
308
|
+
|
309
|
+
before { cart.title = "dummy" }
|
310
|
+
|
311
|
+
it "should use this Cart title" do
|
312
|
+
subject.title_with_default.should == cart.title
|
238
313
|
end
|
239
314
|
|
240
|
-
|
315
|
+
end
|
241
316
|
|
242
|
-
|
243
|
-
Rivendell::Import::Database.stub :enabled? => true
|
244
|
-
end
|
317
|
+
context "when default title is defined" do
|
245
318
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
319
|
+
before { cart.default_title = "dummy" }
|
320
|
+
|
321
|
+
it "should default title if current title is empty" do
|
322
|
+
subject.stub current_title: "[new cart]"
|
323
|
+
subject.title_with_default.should == cart.default_title
|
324
|
+
end
|
250
325
|
|
326
|
+
it "should not use default title if current title is not empty" do
|
327
|
+
subject.stub current_title: "Dummy"
|
328
|
+
subject.title_with_default.should be_nil
|
251
329
|
end
|
252
330
|
|
253
|
-
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
describe Rivendell::Import::Cart::ApiUpdater do
|
338
|
+
|
339
|
+
let(:task) { mock }
|
340
|
+
let(:cart) { Rivendell::Import::Cart.new task }
|
341
|
+
subject { Rivendell::Import::Cart::ApiUpdater.new cart }
|
342
|
+
|
343
|
+
let(:xport) { mock }
|
254
344
|
|
255
|
-
|
256
|
-
|
257
|
-
|
345
|
+
before do
|
346
|
+
subject.stub xport: xport
|
347
|
+
end
|
348
|
+
|
349
|
+
describe "#current_title" do
|
350
|
+
|
351
|
+
it "should retrive the current title via the API" do
|
352
|
+
xport_cart = mock(title: "dummy")
|
353
|
+
xport.should_receive(:list_cart).with(cart.number).and_return(xport_cart)
|
354
|
+
subject.current_title.should == xport_cart.title
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
358
|
+
|
359
|
+
describe "#attributes" do
|
360
|
+
|
361
|
+
it "should use title with default" do
|
362
|
+
subject.stub title_with_default: "dummy"
|
363
|
+
subject.attributes.should == { title: subject.title_with_default }
|
364
|
+
end
|
365
|
+
|
366
|
+
it "should not contain title when title_with_default is nil" do
|
367
|
+
subject.stub title_with_default: nil
|
368
|
+
subject.attributes.should == {}
|
369
|
+
end
|
370
|
+
|
371
|
+
end
|
372
|
+
|
373
|
+
describe "#update!" do
|
374
|
+
|
375
|
+
context "when attributes is not empty" do
|
376
|
+
|
377
|
+
it "should invoke xport edit_cart with attributes" do
|
378
|
+
subject.stub attributes: { title: "dummy" }
|
379
|
+
xport.should_receive(:edit_cart).with(cart.number, subject.attributes)
|
380
|
+
subject.update!
|
381
|
+
end
|
382
|
+
|
383
|
+
end
|
258
384
|
|
259
|
-
|
260
|
-
subject.should_not_receive :update_by_db
|
261
|
-
subject.update
|
262
|
-
end
|
385
|
+
context "when attributes is empty" do
|
263
386
|
|
387
|
+
it "should not invoke xport edit_cart" do
|
388
|
+
subject.stub attributes: {}
|
389
|
+
xport.should_not_receive(:edit_cart)
|
390
|
+
subject.update!.should be_true
|
264
391
|
end
|
392
|
+
|
393
|
+
end
|
394
|
+
|
395
|
+
end
|
396
|
+
|
397
|
+
end
|
398
|
+
|
399
|
+
describe Rivendell::Import::Cart::DbUpdater do
|
400
|
+
|
401
|
+
let(:task) { mock }
|
402
|
+
let(:cart) { Rivendell::Import::Cart.new task }
|
403
|
+
subject { Rivendell::Import::Cart::DbUpdater.new cart }
|
404
|
+
|
405
|
+
let(:db_cart) { Rivendell::DB::Cart.new }
|
406
|
+
|
407
|
+
before do
|
408
|
+
Rivendell::Import::Database.stub init: true
|
409
|
+
db_cart.stub save: true
|
410
|
+
Rivendell::DB::Cart.stub get: db_cart
|
411
|
+
end
|
412
|
+
|
413
|
+
describe "#current_cart" do
|
414
|
+
|
415
|
+
it "should get cart with its number" do
|
416
|
+
Rivendell::DB::Cart.should_receive(:get).with(cart.number).and_return(db_cart)
|
417
|
+
subject.current_cart.should == db_cart
|
418
|
+
end
|
419
|
+
|
420
|
+
end
|
421
|
+
|
422
|
+
describe "#current_title" do
|
423
|
+
|
424
|
+
it "should return current_cart title" do
|
425
|
+
db_cart.stub title: "dummy"
|
426
|
+
subject.current_title.should == db_cart.title
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|
430
|
+
|
431
|
+
describe "#update!" do
|
432
|
+
|
433
|
+
it "should init database" do
|
434
|
+
Rivendell::Import::Database.should_receive :init
|
435
|
+
subject.update!
|
436
|
+
end
|
437
|
+
|
438
|
+
it "should use title_with_default as Cart title" do
|
439
|
+
subject.stub title_with_default: "dummy"
|
440
|
+
subject.update!
|
441
|
+
db_cart.title.should == subject.title_with_default
|
442
|
+
end
|
443
|
+
|
444
|
+
it "should define scheduler_codes" do
|
445
|
+
subject.stub scheduler_codes: ["dummy"]
|
446
|
+
subject.update!
|
447
|
+
db_cart.scheduler_codes.should == subject.scheduler_codes
|
265
448
|
end
|
449
|
+
|
266
450
|
end
|
451
|
+
|
267
452
|
end
|
@@ -8,7 +8,7 @@ describe Rivendell::Import::Context do
|
|
8
8
|
subject { Rivendell::Import::Context.new task }
|
9
9
|
|
10
10
|
describe "#notify" do
|
11
|
-
|
11
|
+
|
12
12
|
it "should add the specified notifier to the task" do
|
13
13
|
subject.notify 'recipient@domain', :by => :email
|
14
14
|
subject.task.notifiers.first.to.should == 'recipient@domain'
|
@@ -16,4 +16,15 @@ describe Rivendell::Import::Context do
|
|
16
16
|
|
17
17
|
end
|
18
18
|
|
19
|
+
describe "#log" do
|
20
|
+
|
21
|
+
let(:message) { "dummy" }
|
22
|
+
|
23
|
+
it "should log the given message with info level" do
|
24
|
+
subject.logger.should_receive(:info).with(message)
|
25
|
+
subject.log message
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
19
30
|
end
|
@@ -2,10 +2,14 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Rivendell::Import::File do
|
4
4
|
|
5
|
-
subject { Rivendell::Import::File.new "
|
5
|
+
subject { Rivendell::Import::File.new fixture_file("audio.ogg"), :base_directory => fixture_directory }
|
6
|
+
|
7
|
+
after do
|
8
|
+
subject.close
|
9
|
+
end
|
6
10
|
|
7
11
|
describe "initialization" do
|
8
|
-
|
12
|
+
|
9
13
|
it "should use given base_directory to compute relative name" do
|
10
14
|
Rivendell::Import::File.new("/path/to/dummy.wav", :base_directory => "/path/to").name.should == "dummy.wav"
|
11
15
|
end
|
@@ -13,7 +17,7 @@ describe Rivendell::Import::File do
|
|
13
17
|
end
|
14
18
|
|
15
19
|
describe "#to_s" do
|
16
|
-
|
20
|
+
|
17
21
|
it "should use name" do
|
18
22
|
subject.to_s.should == subject.name
|
19
23
|
end
|
@@ -21,7 +25,7 @@ describe Rivendell::Import::File do
|
|
21
25
|
end
|
22
26
|
|
23
27
|
describe ".relative_filename" do
|
24
|
-
|
28
|
+
|
25
29
|
it "should return '/subdirectory/file' from '/base/subdirectory/file'" do
|
26
30
|
Rivendell::Import::File.relative_filename('/base/subdirectory/file', '/base').should == 'subdirectory/file'
|
27
31
|
end
|
@@ -29,7 +33,7 @@ describe Rivendell::Import::File do
|
|
29
33
|
end
|
30
34
|
|
31
35
|
describe "match" do
|
32
|
-
|
36
|
+
|
33
37
|
it "should match a given regexp" do
|
34
38
|
subject.stub :name => "dummy"
|
35
39
|
subject.should match(/^dum/)
|
@@ -43,7 +47,7 @@ describe Rivendell::Import::File do
|
|
43
47
|
end
|
44
48
|
|
45
49
|
describe "#basename" do
|
46
|
-
|
50
|
+
|
47
51
|
it "should return 'dummy' for 'path/to/dummy.wav'" do
|
48
52
|
subject.stub :name => "path/to/dummy.wav"
|
49
53
|
subject.basename.should == "dummy"
|
@@ -52,7 +56,7 @@ describe Rivendell::Import::File do
|
|
52
56
|
end
|
53
57
|
|
54
58
|
describe "#extension" do
|
55
|
-
|
59
|
+
|
56
60
|
it "should 'wav' for 'path/to/dummy.wav'" do
|
57
61
|
subject.stub :name => "path/to/dummy.wav"
|
58
62
|
subject.extension.should == "wav"
|
@@ -60,4 +64,38 @@ describe Rivendell::Import::File do
|
|
60
64
|
|
61
65
|
end
|
62
66
|
|
67
|
+
describe "#directories" do
|
68
|
+
|
69
|
+
it "should return 'path' and 'to' for 'path/to/dummy.wav'" do
|
70
|
+
subject.stub :path => "/path/to/dummy.wav"
|
71
|
+
subject.directories.should == %w{path to}
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#tag" do
|
77
|
+
|
78
|
+
it "should return tags contained by file metadata" do
|
79
|
+
subject.tag.title.should == "Audio Test Content"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#audio_properties" do
|
85
|
+
|
86
|
+
it "should file audio properties" do
|
87
|
+
subject.audio_properties.length.should == 60
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#close" do
|
93
|
+
|
94
|
+
it "should close TaLib file_ref" do
|
95
|
+
subject.file_ref.should_receive :close
|
96
|
+
subject.close
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
63
101
|
end
|
@@ -108,6 +108,11 @@ describe Rivendell::Import::Task do
|
|
108
108
|
subject.status.should be_completed
|
109
109
|
end
|
110
110
|
|
111
|
+
it "should close the used file" do
|
112
|
+
subject.file.should_receive :close
|
113
|
+
subject.run
|
114
|
+
end
|
115
|
+
|
111
116
|
it "should change the status to failed if an error is raised" do
|
112
117
|
subject.cart.stub(:create).and_raise("dummy")
|
113
118
|
subject.run
|
@@ -364,4 +369,25 @@ describe Rivendell::Import::Task do
|
|
364
369
|
|
365
370
|
end
|
366
371
|
|
372
|
+
describe "#ready" do
|
373
|
+
|
374
|
+
def task(attributes = {})
|
375
|
+
attributes = { :file => file }.merge(attributes)
|
376
|
+
Rivendell::Import::Task.create attributes
|
377
|
+
end
|
378
|
+
|
379
|
+
it "should return Task order by priority" do
|
380
|
+
lower_priority_task = task priority: 1, created_at: 5.minutes.ago
|
381
|
+
higher_priority_task = task priority: 2
|
382
|
+
Rivendell::Import::Task.ready.should == [ higher_priority_task, lower_priority_task ]
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should return Task order by creation date" do
|
386
|
+
new_task = task
|
387
|
+
old_task = task created_at: 5.minutes.ago
|
388
|
+
Rivendell::Import::Task.ready.should == [ old_task, new_task ]
|
389
|
+
end
|
390
|
+
|
391
|
+
end
|
392
|
+
|
367
393
|
end
|
data/spec/support/fixtures.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rivendell-import
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.10'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-10-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: listen
|
@@ -171,6 +171,22 @@ dependencies:
|
|
171
171
|
- - ~>
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '2.0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: taglib-ruby
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :runtime
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
174
190
|
- !ruby/object:Gem::Dependency
|
175
191
|
name: sinatra
|
176
192
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,7 +242,7 @@ dependencies:
|
|
226
242
|
requirements:
|
227
243
|
- - ~>
|
228
244
|
- !ruby/object:Gem::Version
|
229
|
-
version: '0.
|
245
|
+
version: '0.3'
|
230
246
|
type: :runtime
|
231
247
|
prerelease: false
|
232
248
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -234,7 +250,7 @@ dependencies:
|
|
234
250
|
requirements:
|
235
251
|
- - ~>
|
236
252
|
- !ruby/object:Gem::Version
|
237
|
-
version: '0.
|
253
|
+
version: '0.3'
|
238
254
|
- !ruby/object:Gem::Dependency
|
239
255
|
name: simplecov
|
240
256
|
requirement: !ruby/object:Gem::Requirement
|
@@ -441,6 +457,7 @@ files:
|
|
441
457
|
- lib/rivendell/import/worker.rb
|
442
458
|
- log/.gitkeep
|
443
459
|
- rivendell-import.gemspec
|
460
|
+
- spec/fixtures/audio.ogg
|
444
461
|
- spec/fixtures/mail-body.erb
|
445
462
|
- spec/rivendell/import/base_spec.rb
|
446
463
|
- spec/rivendell/import/cart_finder_spec.rb
|
@@ -482,7 +499,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
482
499
|
version: '0'
|
483
500
|
segments:
|
484
501
|
- 0
|
485
|
-
hash:
|
502
|
+
hash: 3604849735216139138
|
486
503
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
487
504
|
none: false
|
488
505
|
requirements:
|
@@ -491,7 +508,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
491
508
|
version: '0'
|
492
509
|
segments:
|
493
510
|
- 0
|
494
|
-
hash:
|
511
|
+
hash: 3604849735216139138
|
495
512
|
requirements: []
|
496
513
|
rubyforge_project:
|
497
514
|
rubygems_version: 1.8.23
|
@@ -504,6 +521,7 @@ test_files:
|
|
504
521
|
- features/step_definitions/import_steps.rb
|
505
522
|
- features/support/env.rb
|
506
523
|
- features/support/mock_xport.rb
|
524
|
+
- spec/fixtures/audio.ogg
|
507
525
|
- spec/fixtures/mail-body.erb
|
508
526
|
- spec/rivendell/import/base_spec.rb
|
509
527
|
- spec/rivendell/import/cart_finder_spec.rb
|