bbc_redux 0.4.7.pre → 0.4.8.pre

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/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: