rivendell-import 0.9 → 0.10

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.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rivendell-import (0.9)
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.2)
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.17)
25
- activesupport (= 3.2.17)
25
+ activemodel (3.2.19)
26
+ activesupport (= 3.2.19)
26
27
  builder (~> 3.0.0)
27
- activerecord (3.2.17)
28
- activemodel (= 3.2.17)
29
- activesupport (= 3.2.17)
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.17)
33
+ activesupport (3.2.19)
33
34
  i18n (~> 0.6, >= 0.6.4)
34
35
  multi_json (~> 1.0)
35
- addressable (2.3.5)
36
+ addressable (2.3.6)
36
37
  arel (3.0.3)
37
- bcrypt-ruby (3.1.2)
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.14.2)
40
- highline
41
- net-scp (>= 1.0.0)
42
- net-sftp (>= 2.0.0)
43
- net-ssh (>= 2.0.14)
44
- net-ssh-gateway (>= 1.1.0)
45
- cucumber (1.3.10)
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.0.2)
53
+ multi_test (>= 0.1.1)
51
54
  daemons (1.1.9)
52
- data_objects (0.10.13)
55
+ data_objects (0.10.14)
53
56
  addressable (~> 2.1)
54
- database_cleaner (0.8.0)
55
- diff-lcs (1.1.3)
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.13)
81
- data_objects (= 0.10.13)
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.3)
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.4.0)
87
- listen (>= 0.4.2)
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.2.0)
97
+ guard-cucumber (1.4.1)
90
98
  cucumber (>= 1.2.0)
91
99
  guard (>= 1.1.0)
92
- guard-rspec (2.0.0)
93
- guard (>= 1.1)
94
- rspec (~> 2.11)
95
- highline (1.6.16)
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.9)
110
+ i18n (0.6.11)
104
111
  json (1.8.1)
105
112
  json_pure (1.8.1)
106
- libnotify (0.8.2)
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
- mail (2.5.4)
113
- mime-types (~> 1.16)
114
- treetop (~> 1.4.8)
115
- mime-types (1.25.1)
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.8.2)
118
- multi_test (0.0.3)
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.0)
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
- polyglot (0.3.5)
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.1)
138
+ rack-protection (1.5.3)
132
139
  rack
133
- rake (0.9.2.2)
134
- rb-fsevent (0.9.3)
135
- rb-inotify (0.9.2)
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.0)
144
+ rb-kqueue (0.2.3)
138
145
  ffi (>= 0.5.0)
139
- rdoc (3.12.2)
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.2)
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.11.0)
152
- rspec-core (~> 2.11.0)
153
- rspec-expectations (~> 2.11.0)
154
- rspec-mocks (~> 2.11.0)
155
- rspec-core (2.11.1)
156
- rspec-expectations (2.11.3)
157
- diff-lcs (~> 1.1.3)
158
- rspec-mocks (2.11.3)
159
- simplecov (0.6.4)
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.5.3)
162
- simplecov-html (0.5.3)
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.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
- thor (0.16.0)
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.39)
178
- uuidtools (2.1.4)
179
- will_paginate (3.0.5)
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
- # A sample Guardfile
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/lib/#{m[1]}_spec.rb" }
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
4
  watch('spec/spec_helper.rb') { "spec" }
8
5
  end
9
6
 
@@ -35,7 +35,7 @@ module Rivendell::Import
35
35
  end
36
36
  end
37
37
 
38
- Listen.to(directory).change(&callback).start!
38
+ Listen.to(directory, latency: 1, wait_for_delay: 5).change(&callback).start!
39
39
  end
40
40
 
41
41
  def process(*paths)
@@ -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
- begin
55
- update_by_api
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 empty_title?(title)
63
- [ nil, "", "[new cart]" ].include? title
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
- def update_by_api
67
- update_attributes = {}
103
+ class ApiUpdater < Updater
68
104
 
69
- if title
70
- update_attributes[:title] = title
71
- else
72
- update_attributes[:title] = default_title if default_title && empty_title?(xport.list_cart(number).title)
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
- unless update_attributes.empty?
76
- Rivendell::Import.logger.debug "Update Cart by API : #{update_attributes}"
77
- xport.edit_cart number, update_attributes
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
- def update_by_db
82
- Database.init
128
+ class DbUpdater < Updater
83
129
 
84
- Rivendell::Import.logger.debug "Update Cart by DB"
85
- current_cart = Rivendell::DB::Cart.get(number)
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
- current_cart.save
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
@@ -20,6 +20,10 @@ module Rivendell::Import
20
20
  end
21
21
  end
22
22
 
23
+ def log(message)
24
+ logger.info message if message
25
+ end
26
+
23
27
  def run(&block)
24
28
  instance_exec file, &block if block_given?
25
29
  end
@@ -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
- self.pending.select(&:ready?)
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
@@ -22,5 +22,9 @@ module Rivendell::Import::Tasking
22
22
  self.delete_file = true
23
23
  end
24
24
 
25
+ def close_file
26
+ @file.close if @file
27
+ end
28
+
25
29
  end
26
30
  end
@@ -14,8 +14,19 @@ module Rivendell::Import
14
14
  end
15
15
 
16
16
  def create(file, &block)
17
- Rivendell::Import::Task.create({:file => file}, {}, &block).tap do |task|
18
- Rivendell::Import.logger.debug "Created task #{task.inspect}"
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
 
@@ -1,5 +1,5 @@
1
1
  module Rivendell
2
2
  module Import
3
- VERSION = "0.9"
3
+ VERSION = "0.10"
4
4
  end
5
5
  end
@@ -45,7 +45,7 @@
45
45
  <td><%= distance_of_time_in_words_from_now(task.updated_at) %></td>
46
46
  <td><%= truncate_filename(task.file, 60) %></td>
47
47
  <td><%= task.destination %></td>
48
- <td>default</td>
48
+ <td><%= task.priority or "default" %></td>
49
49
  </tr>
50
50
  <% end %>
51
51
  </table>
@@ -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
- task = import.tasks.pop
22
- if task
23
- task.run
24
- else
25
- # Rivendell::Import.logger.debug "No pending task, sleep 10s"
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
@@ -4,6 +4,7 @@ require "null_logger"
4
4
  require "active_support/core_ext/module/attribute_accessors"
5
5
  require "active_support/core_ext/module/delegation"
6
6
  require "active_support/core_ext/enumerable"
7
+ require 'taglib'
7
8
 
8
9
  require "rivendell/import/config"
9
10
 
@@ -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.2'
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
@@ -120,7 +120,7 @@ describe Rivendell::Import::Base do
120
120
  end
121
121
 
122
122
  it "should invoke Listen.to with given directory" do
123
- Listen.should_receive(:to).with(directory)
123
+ Listen.should_receive(:to).with(directory, anything)
124
124
  subject.listen directory
125
125
  end
126
126
 
@@ -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 invoke update_by_api" do
230
- subject.should_receive :update_by_api
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
- context "when when update_by_api fails" do
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
- before do
237
- subject.stub(:update_by_api).and_raise("#fail")
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
- context "when database is enabled" do
315
+ end
241
316
 
242
- before do
243
- Rivendell::Import::Database.stub :enabled? => true
244
- end
317
+ context "when default title is defined" do
245
318
 
246
- it "should invoke update_by_db " do
247
- subject.should_receive :update_by_db
248
- subject.update
249
- end
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
- context "when database is disabled" do
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
- before do
256
- Rivendell::Import::Database.stub :enabled? => false
257
- end
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
- it "should not invoke update_by_db " do
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 "/path/to/dummy.wav", :base_directory => "/path/to" }
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
@@ -1,3 +1,7 @@
1
+ def fixture_directory
2
+ File.expand_path "../../fixtures", __FILE__
3
+ end
4
+
1
5
  def fixture_file(name)
2
- File.expand_path "../../fixtures/#{name}", __FILE__
6
+ File.join fixture_directory, name
3
7
  end
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.9'
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-06-11 00:00:00.000000000 Z
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.2'
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.2'
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: 1053952433249090038
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: 1053952433249090038
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