bbc_redux 0.4.7.pre → 0.4.8.pre

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,5 +1,3 @@
1
- # THIS IS PRE RELEASE, DON'T USE IT AS IT PROBABLY WON'T WORK!
2
-
3
1
  # Redux
4
2
 
5
3
  A gem to help navigate the Redux API's and to screen scrape where an API does
data/bbc_redux.gemspec CHANGED
@@ -29,6 +29,8 @@ Gem::Specification.new do |gem|
29
29
 
30
30
  # Files / paths
31
31
 
32
+ gem.executables << 'bbc-redux'
33
+
32
34
  gem.files = FileList[
33
35
  'AUTHORS',
34
36
  'COPYING',
@@ -36,6 +38,7 @@ Gem::Specification.new do |gem|
36
38
  'README.md',
37
39
  'Rakefile',
38
40
  'bbc_redux.gemspec',
41
+ 'bin/*',
39
42
  'lib/**/*'
40
43
  ]
41
44
 
@@ -54,6 +57,7 @@ Gem::Specification.new do |gem|
54
57
 
55
58
  gem.add_dependency 'nokogiri'
56
59
  gem.add_dependency 'representable'
60
+ gem.add_dependency 'terminal-table'
57
61
  gem.add_dependency 'typhoeus', '>= 0.6.8'
58
62
  gem.add_dependency 'virtus', '>= 0.5.0'
59
63
 
data/bin/bbc-redux ADDED
@@ -0,0 +1,325 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # vim: set filetype=ruby:
4
+
5
+ $LOAD_PATH << File.join( File.dirname(__FILE__), '..', 'lib' )
6
+
7
+ require 'fileutils'
8
+ require 'logger'
9
+ require 'optparse'
10
+
11
+ require 'bbc/redux'
12
+ require 'terminal-table'
13
+
14
+ ################################################################################
15
+ # OPTIONS PARSER
16
+
17
+ def parse_options( input )
18
+
19
+ options = { :command => :assets }
20
+
21
+ parser = OptionParser.new do |opts|
22
+
23
+ opts.banner = 'usage: ' + File.basename(__FILE__) + ' [options]'
24
+
25
+ opts.separator ''
26
+ opts.separator 'asset download options:'
27
+
28
+ opts.on( '-a', '--after DATE', 'Filter by after date' ) do |d|
29
+ options[:after] = DateTime.parse( d )
30
+ end
31
+
32
+ opts.on( '-b', '--before DATE', 'Filter by before date' ) do |d|
33
+ options[:before] = DateTime.parse( d )
34
+ end
35
+
36
+ opts.on( '-c', '--channels CHANNEL,...', 'Filter by channel name' ) do |c|
37
+ options[:channel] = c.split(',')
38
+ end
39
+
40
+ opts.on( '-i', '--id ID', 'Filter by asset id' ) do |i|
41
+ options[:id] = i
42
+ end
43
+
44
+ opts.on( '-m', '--metadata', 'Download json metadata' ) do |metadata|
45
+ options[:metadata] = metadata
46
+ end
47
+
48
+ opts.on( '-o', '--output-directory DIR', 'Save to directory' ) do |d|
49
+ options[:output_directory] = d
50
+ end
51
+
52
+ opts.on( '-p', '--profiles PROFILE,...', 'Fetch asset with profile' ) do |p|
53
+ options[:profiles] = p.split(',')
54
+ end
55
+
56
+ opts.on( '-q', '--query QUERY', 'Filter by query' ) do |q|
57
+ options[:q] = q
58
+ end
59
+
60
+ opts.on( '--[no]-repeats', 'Include / exclude repeats' ) do |repeats|
61
+ options[:repeats] = repeats
62
+ end
63
+
64
+ opts.separator ''
65
+ opts.separator 'channel info commands:'
66
+
67
+ opts.on( '--list-channels', 'List available channels' ) do
68
+ options[:command] = :list_channels
69
+ end
70
+
71
+ opts.on( '--list-categories', 'List available channel categories' ) do
72
+ options[:command] = :list_categories
73
+ end
74
+
75
+ opts.separator ''
76
+ opts.separator 'common options:'
77
+
78
+ opts.on_tail( '-h', '--help', 'Show this message' ) do
79
+ puts opts
80
+ puts DATA.read
81
+ exit
82
+ end
83
+
84
+ opts.on_tail( '-v', '--verbose', 'Enable verbose logging' ) do
85
+ options[:verbose] = true
86
+ end
87
+
88
+ opts.on_tail( '-V', '--version', 'Show version' ) do
89
+ puts BBC::Redux::VERSION
90
+ exit
91
+ end
92
+
93
+ end
94
+
95
+ parser.parse!( input )
96
+
97
+ return options
98
+
99
+ rescue ArgumentError,
100
+ OptionParser::InvalidOption,
101
+ OptionParser::MissingArgument => e
102
+ $stderr.puts e.message
103
+ exit 1
104
+ end
105
+
106
+ ################################################################################
107
+ # APPLICATION
108
+
109
+ class BBC::Redux::CLI
110
+
111
+ attr_reader :options
112
+
113
+ def initialize( options )
114
+ @options = options
115
+ end
116
+
117
+ def run
118
+
119
+ valid_commands = [ :assets, :list_channels, :list_categories ]
120
+
121
+ if valid_commands.include? options[:command]
122
+ self.send( options[:command] )
123
+ else
124
+ fail "Unrecognized command #{options[:command]}, see --help"
125
+ end
126
+
127
+ if options[:token].nil?
128
+ logger.debug 'Logging out of redux'
129
+ redux_client.logout
130
+ end
131
+
132
+ end
133
+
134
+ def logger
135
+ if @logger.nil?
136
+ @logger = Logger.new( $stderr )
137
+
138
+ if options[:verbose]
139
+ @logger.level = Logger::DEBUG
140
+ else
141
+ @logger.level = Logger::INFO
142
+ end
143
+ end
144
+
145
+ @logger
146
+ end
147
+
148
+ def redux_client
149
+ if @redux_client.nil?
150
+ if options[:token]
151
+ credentials = { :token => options[:token] }
152
+ elsif options[:username] && options[:password]
153
+ credentials = {
154
+ :username => options[:username],
155
+ :password => options[:password],
156
+ }
157
+ else
158
+ $stderr.puts 'You need to set either the REDUX_TOKEN or REDUX_USERNAME'
159
+ $stderr.puts 'and REDUX_PASSWORD environment variables'
160
+ fail
161
+ end
162
+
163
+ @redux_client = BBC::Redux::Client.new( credentials )
164
+ end
165
+
166
+ @redux_client
167
+ end
168
+
169
+ def fail( message = '' )
170
+ $stderr.puts message
171
+ exit 1
172
+ end
173
+
174
+ def print_table( headings, rows )
175
+ puts Terminal::Table.new :headings => headings, :rows => rows
176
+ end
177
+
178
+ def assets
179
+
180
+ disk_references = [ ]
181
+ output_directory = options[:output_directory] || '.'
182
+
183
+ FileUtils.mkdir_p output_directory
184
+
185
+ if options[:id]
186
+ disk_references << options[:id]
187
+ else
188
+
189
+ search_params = options.select do |key,_|
190
+ [ :after, :before, :channel, :q ].include? key
191
+ end
192
+
193
+ unless options[:repeats] == false
194
+ search_params[:repeats] = true
195
+ end
196
+
197
+ search_params = search_params.merge({
198
+ :offset => 0,
199
+ :sort_by =>'time',
200
+ :sort_order => 'ascending'
201
+ })
202
+
203
+ logger.info 'Searching for references'
204
+
205
+ results = redux_client.search( search_params )
206
+
207
+ while true do
208
+ results.assets.each { |a| disk_references << a.disk_reference }
209
+
210
+ if results.has_more?
211
+ next_query = results.query.merge({
212
+ :offset => results.query[:offset] + 10
213
+ })
214
+
215
+ logger.debug "Searching for references, offset #{next_query[:offset]}"
216
+
217
+ results = redux_client.search(next_query)
218
+ else
219
+ break
220
+ end
221
+ end
222
+ end
223
+
224
+ disk_references.each do |disk_reference|
225
+
226
+ logger.info 'Fetching data for asset ' + disk_reference
227
+
228
+ asset = redux_client.asset( disk_reference )
229
+
230
+ if options[:metadata]
231
+ logger.debug 'Saving metadata for asset ' + disk_reference
232
+
233
+ serializer = BBC::Redux::Serializers::Asset.new( asset )
234
+ file_path = File.join( output_directory, disk_reference + '.json' )
235
+
236
+ File.open( file_path, 'w' ) { |f| f << serializer.to_json }
237
+ end
238
+
239
+ if options[:profiles]
240
+ options[:profiles].each do |profile|
241
+
242
+ logger.debug "Saving profile #{profile} for asset #{disk_reference}"
243
+
244
+ url = asset.send( profile + '_url' ).end_point
245
+ fname = File.basename( url )
246
+ file_path = File.join( output_directory, fname )
247
+
248
+ `wget --quiet -O "#{file_path}" "#{url}"`
249
+
250
+ end
251
+ end
252
+
253
+ end
254
+
255
+ end
256
+
257
+ def list_categories
258
+ logger.debug 'Listing categories'
259
+
260
+ headings = %w{ id description priority }
261
+
262
+ rows = redux_client.channel_categories.map do |category|
263
+ [ category.id, category.description, category.priority ]
264
+ end
265
+
266
+ print_table headings, rows
267
+ end
268
+
269
+ def list_channels
270
+ logger.debug 'Listing channels'
271
+
272
+ headings = %w{ category_id longname name sortorder }
273
+
274
+ rows = redux_client.channels.map do |channel|
275
+ [
276
+ channel.category_id,
277
+ channel.longname,
278
+ channel.name,
279
+ channel.sortorder
280
+ ]
281
+ end
282
+
283
+ print_table headings, rows
284
+ end
285
+
286
+ end
287
+
288
+ ################################################################################
289
+ # FIRE UP THE QUATTRO
290
+
291
+ options = parse_options( ARGV )
292
+
293
+ runner = BBC::Redux::CLI.new( options.merge({
294
+ :token => ENV['REDUX_TOKEN'],
295
+ :username => ENV['REDUX_USERNAME'],
296
+ :password => ENV['REDUX_PASSWORD'],
297
+ }))
298
+
299
+ runner.run
300
+
301
+ ################################################################################
302
+ # EXTENDED USAGE INFO
303
+
304
+ __END__
305
+
306
+ examples:
307
+
308
+ To use the client you must have set one of these environment variables:
309
+
310
+ REDUX_TOKEN # A valid session token
311
+ REDUX_USERNAME & REDUX_PASSWORD # Your credentials
312
+
313
+ You may then us the client, some examples below:
314
+
315
+ # Listing channels
316
+ $: bbc-redux --list-channels
317
+
318
+ # Downloading json metadata for an asset
319
+ $: bbc-redux --metadata --id 6008591816398520492
320
+
321
+ # Downloading MP3 files for a week of The Archers
322
+ $: bbc-redux -p mp3 -q 'The Archers' -a 2014-W01 -b 2014-W02
323
+
324
+ # Downloading TS files for a day of BBC One
325
+ $: bbc-redux -p ts -c bbcone -a 2014-01-01 -b 2014-01-02
@@ -33,6 +33,8 @@ module BBC
33
33
  # @return [String] channel short name, e.g. 'bbcone'
34
34
  attribute :name, String
35
35
 
36
+ alias :to_s :name
37
+
36
38
  # @!attribute [r] sortorder
37
39
  # @return [Integer] channel's suggested sort order in list views
38
40
  attribute :sortorder, Integer
@@ -42,6 +42,11 @@ module BBC
42
42
 
43
43
  end
44
44
 
45
+ class Assets < Representable::Decorator
46
+ include Representable::JSON::Collection
47
+ items extend: Asset, class: BBC::Redux::Asset
48
+ end
49
+
45
50
  class Channel < Representable::Decorator
46
51
  include Representable::JSON
47
52
  property :category_id, :as => :category
@@ -2,7 +2,7 @@ module BBC
2
2
  module Redux
3
3
 
4
4
  # Library version
5
- VERSION = '0.4.7.pre'
5
+ VERSION = '0.4.8.pre'
6
6
 
7
7
  end
8
8
  end
data/lib/bbc/redux.rb CHANGED
@@ -10,3 +10,4 @@ require_relative 'redux/media_url'
10
10
  require_relative 'redux/search_results'
11
11
  require_relative 'redux/serializers'
12
12
  require_relative 'redux/user'
13
+ require_relative 'redux/version'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bbc_redux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7.pre
4
+ version: 0.4.8.pre
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-03-03 00:00:00.000000000 Z
14
+ date: 2015-03-13 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
@@ -109,6 +109,22 @@ dependencies:
109
109
  - - ! '>='
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: terminal-table
114
+ requirement: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :runtime
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
112
128
  - !ruby/object:Gem::Dependency
113
129
  name: typhoeus
114
130
  requirement: !ruby/object:Gem::Requirement
@@ -145,7 +161,8 @@ description: A gem to help navigate the BBC Redux API
145
161
  email:
146
162
  - james.harrison@bbc.co.uk
147
163
  - matt.haynes@bbc.co.uk
148
- executables: []
164
+ executables:
165
+ - bbc-redux
149
166
  extensions: []
150
167
  extra_rdoc_files: []
151
168
  files:
@@ -155,6 +172,7 @@ files:
155
172
  - README.md
156
173
  - Rakefile
157
174
  - bbc_redux.gemspec
175
+ - bin/bbc-redux
158
176
  - lib/bbc/redux/asset.rb
159
177
  - lib/bbc/redux/channel.rb
160
178
  - lib/bbc/redux/channel_category.rb
@@ -200,7 +218,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
200
218
  version: '0'
201
219
  segments:
202
220
  - 0
203
- hash: 1837997505390490635
221
+ hash: 2647790705023314369
204
222
  required_rubygems_version: !ruby/object:Gem::Requirement
205
223
  none: false
206
224
  requirements: