bbc-programmes 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/README.md +11 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/examples/basic.rb +19 -0
- data/examples/broadcasts.rb +19 -0
- data/examples/search.rb +15 -0
- data/examples/tracklist.rb +20 -0
- data/lib/bbc/programmes/base.rb +46 -0
- data/lib/bbc/programmes/brand.rb +12 -0
- data/lib/bbc/programmes/broadcast.rb +31 -0
- data/lib/bbc/programmes/episode.rb +13 -0
- data/lib/bbc/programmes/programme.rb +33 -0
- data/lib/bbc/programmes/segment.rb +18 -0
- data/lib/bbc/programmes/series.rb +14 -0
- data/lib/bbc/programmes/service.rb +17 -0
- data/lib/bbc/programmes/time_interval.rb +16 -0
- data/lib/bbc/programmes/time_line.rb +10 -0
- data/lib/bbc/programmes/version.rb +51 -0
- data/lib/bbc/programmes.rb +110 -0
- data/lib/rdf/po.rb +17 -0
- data/lib/rdf/time_line.rb +12 -0
- data/spec/bbc-programmes.spec +71 -0
- data/spec/brand.spec +74 -0
- data/spec/broadcast.spec +65 -0
- data/spec/data/b005sv69.rdf +507 -0
- data/spec/data/b00jnwlc.rdf +51 -0
- data/spec/data/b00jnwm0.rdf +128 -0
- data/spec/data/b00jnwnv.rdf +62 -0
- data/spec/data/the_wire.rdf +41 -0
- data/spec/episode.spec +78 -0
- data/spec/series.spec +74 -0
- data/spec/service.spec +34 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/version.spec +90 -0
- metadata +151 -0
data/README.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Ruby client library for the BBC Programmes website
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bbc/programmes'
|
5
|
+
|
6
|
+
episode = BBC::Programmes::Episode.fetch('b00jnwnv')
|
7
|
+
puts "PID: #{episode.pid}"
|
8
|
+
puts "Title: #{episode.title}"
|
9
|
+
puts "Short Synopsis: #{episode.short_synopsis}"
|
10
|
+
puts "Medium Synopsis: #{episode.medium_synopsis}"
|
11
|
+
puts "Long Synopsis: #{episode.long_synopsis}"
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'yard'
|
3
|
+
|
4
|
+
begin
|
5
|
+
gem 'jeweler'
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |gemspec|
|
8
|
+
gemspec.name = "bbc-programmes"
|
9
|
+
gemspec.summary = "Ruby client library for the BBC Programmes website."
|
10
|
+
gemspec.email = "njh@aelius.com.com"
|
11
|
+
gemspec.homepage = "http://github.com/njh/bbc-programmes-ruby"
|
12
|
+
gemspec.authors = ["Nicholas J Humfrey"]
|
13
|
+
gemspec.add_dependency('rdf', '>= 0.2.2')
|
14
|
+
gemspec.add_dependency('nokogiri', '>= 1.3.3')
|
15
|
+
gemspec.add_development_dependency('rspec')
|
16
|
+
gemspec.add_development_dependency('yard')
|
17
|
+
gemspec.extra_rdoc_files = %w(README.md)
|
18
|
+
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'spec/rake/spectask'
|
25
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.pattern = 'spec/*.spec'
|
28
|
+
spec.spec_opts = ["-c"]
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Run specs through RCov"
|
32
|
+
Spec::Rake::SpecTask.new("spec:rcov") do |spec|
|
33
|
+
spec.libs << 'lib' << 'spec'
|
34
|
+
spec.pattern = 'spec/*.spec'
|
35
|
+
spec.rcov = true
|
36
|
+
spec.rcov_opts = ['-x', '/Library', '-x', '/System/Library', '-x', 'spec']
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Generate HTML report specs"
|
40
|
+
Spec::Rake::SpecTask.new("doc:spec") do |spec|
|
41
|
+
spec.libs << 'lib' << 'spec'
|
42
|
+
spec.spec_files = FileList['spec/*.spec']
|
43
|
+
spec.spec_opts = ["--format", "html:doc/spec.html"]
|
44
|
+
end
|
45
|
+
|
46
|
+
YARD::Rake::YardocTask.new do |t|
|
47
|
+
t.files = %w(lib/**/*.rb)
|
48
|
+
end
|
49
|
+
|
50
|
+
task :default => :spec
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/examples/basic.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Basic example of getting the title and synopsis for an episode
|
4
|
+
#
|
5
|
+
|
6
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bbc/programmes'
|
10
|
+
|
11
|
+
Spira.add_repository(:default, RDF::Repository)
|
12
|
+
|
13
|
+
|
14
|
+
episode = BBC::Programmes::Episode.fetch('b00jnwnv')
|
15
|
+
puts "PID: #{episode.pid}"
|
16
|
+
puts "Title: #{episode.title}"
|
17
|
+
puts "Short Synopsis: #{episode.short_synopsis}"
|
18
|
+
puts "Medium Synopsis: #{episode.medium_synopsis}"
|
19
|
+
puts "Long Synopsis: #{episode.long_synopsis}"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Example of listing all the broadcasts for episode
|
4
|
+
#
|
5
|
+
|
6
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bbc/programmes'
|
10
|
+
|
11
|
+
Spira.add_repository(:default, RDF::Repository)
|
12
|
+
|
13
|
+
episode = BBC::Programmes::Episode.fetch('b00jnwnv')
|
14
|
+
puts "#{episode.pid}: #{episode.title}"
|
15
|
+
|
16
|
+
version = episode.versions.first.fetch!
|
17
|
+
version.broadcasts.each do |broadcast|
|
18
|
+
puts "#{broadcast.start} - #{broadcast.end} #{broadcast.service}"
|
19
|
+
end
|
data/examples/search.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Example of searching for programmes by title
|
4
|
+
#
|
5
|
+
|
6
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bbc/programmes'
|
10
|
+
|
11
|
+
Spira.add_repository(:default, RDF::Repository)
|
12
|
+
|
13
|
+
programmes = BBC::Programmes.search('The Wire').each do |programme|
|
14
|
+
puts "#{programme.pid}: #{programme.title}"
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Example of listing all the broadcasts for episode
|
4
|
+
#
|
5
|
+
|
6
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bbc/programmes'
|
10
|
+
|
11
|
+
Spira.add_repository(:default, RDF::Repository)
|
12
|
+
|
13
|
+
episode = BBC::Programmes::Episode.fetch('b00sk7q2')
|
14
|
+
puts "Episode: #{episode.title}"
|
15
|
+
puts
|
16
|
+
|
17
|
+
version = episode.versions.first.fetch!
|
18
|
+
version.segments.each do |segment|
|
19
|
+
puts segment
|
20
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Base
|
6
|
+
include Spira::Resource
|
7
|
+
|
8
|
+
base_uri BBC::Programmes::BASE_URI
|
9
|
+
default_vocabulary RDF::PO
|
10
|
+
|
11
|
+
property :pid, :type => String
|
12
|
+
|
13
|
+
def self.fetch(identifier)
|
14
|
+
programme = self.for(identifier)
|
15
|
+
programme.fetch!
|
16
|
+
programme
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch!
|
20
|
+
BBC::Programmes.fetch(subject)
|
21
|
+
self.reload
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def pid
|
26
|
+
pid = attribute_get(:pid)
|
27
|
+
if pid.nil?
|
28
|
+
subject.to_s =~ /(\w+)\#(\w+)$/
|
29
|
+
pid = $1
|
30
|
+
end
|
31
|
+
pid
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.subclasses
|
35
|
+
subclasses = []
|
36
|
+
ObjectSpace.each_object(Class) do |klass|
|
37
|
+
if klass.ancestors.include?(self)
|
38
|
+
subclasses << klass
|
39
|
+
end
|
40
|
+
end
|
41
|
+
subclasses
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Brand < Programme
|
6
|
+
type RDF::PO.Brand
|
7
|
+
|
8
|
+
has_many :series, :predicate => RDF::PO.series, :type => 'BBC_Programmes_Series'
|
9
|
+
has_many :episodes, :predicate => RDF::PO.episode, :type => 'BBC_Programmes_Episode'
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Broadcast < Base
|
6
|
+
type RDF::PO.Broadcast
|
7
|
+
|
8
|
+
default_vocabulary RDF::PO
|
9
|
+
property :time, :predicate => RDF::URI('http://purl.org/NET/c4dm/event.owl#time'), :type => 'BBC_Programmes_TimeInterval'
|
10
|
+
property :schedule_date, :type => String # Date
|
11
|
+
property :broadcast_of, :type => 'BBC_Programmes_Version'
|
12
|
+
property :broadcast_on, :type => 'BBC_Programmes_Service'
|
13
|
+
|
14
|
+
def start
|
15
|
+
time.nil? ? nil : time.start
|
16
|
+
end
|
17
|
+
|
18
|
+
def end
|
19
|
+
time.nil? ? nil : time.end
|
20
|
+
end
|
21
|
+
|
22
|
+
def service
|
23
|
+
broadcast_on
|
24
|
+
end
|
25
|
+
|
26
|
+
def version
|
27
|
+
broadcast_of
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Episode < Programme
|
6
|
+
type RDF::PO.Episode
|
7
|
+
|
8
|
+
default_vocabulary RDF::PO
|
9
|
+
property :position, :type => Integer
|
10
|
+
has_many :versions, :predicate => RDF::PO.version, :type => 'BBC_Programmes_Version'
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Programme < Base
|
6
|
+
default_vocabulary RDF::PO
|
7
|
+
type RDF::PO.Programme
|
8
|
+
|
9
|
+
property :title, :predicate => DC11.title, :type => String
|
10
|
+
property :short_synopsis, :type => String
|
11
|
+
property :medium_synopsis, :type => String
|
12
|
+
property :long_synopsis, :type => String
|
13
|
+
property :image, :predicate => FOAF.depiction, :type => RDF::URI
|
14
|
+
|
15
|
+
# FIXME: this should be of type service
|
16
|
+
property :masterbrand, :type => RDF::URI
|
17
|
+
|
18
|
+
# FIXME: implement this
|
19
|
+
#has_many :genres
|
20
|
+
#has_many :formats
|
21
|
+
|
22
|
+
def self.id_for(identifier)
|
23
|
+
if identifier.is_a?(::String)
|
24
|
+
super(
|
25
|
+
RDF::URI("#{base_uri}/#{identifier}#programme")
|
26
|
+
)
|
27
|
+
else
|
28
|
+
super(identifier)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Segment < Base
|
6
|
+
type RDF::PO.Segment
|
7
|
+
|
8
|
+
default_vocabulary RDF::PO
|
9
|
+
property :label, :predicate => RDF::RDFS.label, :type => String
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
label
|
13
|
+
end
|
14
|
+
|
15
|
+
# FIXME: add support for fetching full details of a segment
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Series < Programme
|
6
|
+
type RDF::PO.Series
|
7
|
+
|
8
|
+
default_vocabulary RDF::PO
|
9
|
+
property :position, :type => Integer
|
10
|
+
has_many :series, :predicate => RDF::PO.series, :type => 'BBC_Programmes_Series'
|
11
|
+
has_many :episodes, :predicate => RDF::PO.episode, :type => 'BBC_Programmes_Episode'
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Service < Base
|
6
|
+
type RDF::PO.Service
|
7
|
+
|
8
|
+
default_vocabulary RDF::PO
|
9
|
+
property :label, :predicate => RDF::RDFS.label, :type => String
|
10
|
+
property :parent, :predicate => RDF::PO.parent_service, :type => 'BBC_Programmes_Service'
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
label.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class TimeInterval
|
6
|
+
include Spira::Resource
|
7
|
+
|
8
|
+
type RDF::TimeLine.Interval
|
9
|
+
property :start, :predicate => RDF::TimeLine.start, :type => Any
|
10
|
+
property :end, :predicate => RDF::TimeLine.end, :type => Any
|
11
|
+
property :duration, :predicate => RDF::TimeLine.end, :type => String # Duration
|
12
|
+
property :position, :predicate => RDF::PO.position, :type => Integer
|
13
|
+
property :timeline, :predicate => RDF::TimeLine.timeline, :type => 'BBC_Programmes_TimeLine'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module BBC::Programmes
|
4
|
+
|
5
|
+
class Version < Base
|
6
|
+
type RDF::PO.Version
|
7
|
+
|
8
|
+
default_vocabulary RDF::PO
|
9
|
+
property :aspect_ratio, :type => String
|
10
|
+
property :sound_format, :type => String
|
11
|
+
property :duration, :type => Integer
|
12
|
+
property :time, :predicate => RDF::PO.time, :type => 'BBC_Programmes_TimeInterval'
|
13
|
+
|
14
|
+
def self.id_for(identifier)
|
15
|
+
if identifier.is_a?(::String)
|
16
|
+
super(
|
17
|
+
RDF::URI("#{base_uri}/#{identifier}#programme")
|
18
|
+
)
|
19
|
+
else
|
20
|
+
super(identifier)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def broadcasts
|
25
|
+
# FIXME: can this be done using inverse properties?
|
26
|
+
Broadcast.repository.query([nil, RDF::PO.broadcast_of, subject]).map do |b|
|
27
|
+
b.subject.as(Broadcast)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def timeline
|
32
|
+
time.nil? ? nil : time.timeline
|
33
|
+
end
|
34
|
+
|
35
|
+
def intervals
|
36
|
+
TimeInterval.repository.query([nil, RDF::TimeLine.timeline, timeline.subject]).map do |b|
|
37
|
+
b.subject.as(TimeInterval)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def segments
|
42
|
+
intervals = self.intervals.select {|i| !i.position.nil?}
|
43
|
+
intervals.sort! {|a,b| (a.position.to_i||0) <=> (b.position.to_i||0)}
|
44
|
+
intervals.map do |interval|
|
45
|
+
segment = Segment.repository.first_subject([nil, RDF::PO.time, interval.subject])
|
46
|
+
segment.nil? ? nil : segment.as(Segment)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rdf'
|
4
|
+
require 'rdf/raptor'
|
5
|
+
require 'rdf/po'
|
6
|
+
require 'rdf/time_line'
|
7
|
+
require 'net/http'
|
8
|
+
require 'addressable/uri'
|
9
|
+
require 'spira'
|
10
|
+
|
11
|
+
|
12
|
+
module BBC
|
13
|
+
module Programmes
|
14
|
+
BASE_URI = 'http://www.bbc.co.uk/programmes'
|
15
|
+
USER_AGENT = "bbc-programmes-ruby/0.1"
|
16
|
+
|
17
|
+
require 'bbc/programmes/base'
|
18
|
+
require 'bbc/programmes/programme'
|
19
|
+
require 'bbc/programmes/brand'
|
20
|
+
require 'bbc/programmes/episode'
|
21
|
+
require 'bbc/programmes/series'
|
22
|
+
require 'bbc/programmes/version'
|
23
|
+
require 'bbc/programmes/service'
|
24
|
+
require 'bbc/programmes/broadcast'
|
25
|
+
require 'bbc/programmes/segment'
|
26
|
+
|
27
|
+
require 'bbc/programmes/time_interval'
|
28
|
+
require 'bbc/programmes/time_line'
|
29
|
+
|
30
|
+
def self.search(keywords)
|
31
|
+
encoded = Addressable::URI.encode(keywords)
|
32
|
+
graph = http_get_graph("#{BASE_URI}/a-z/by/#{encoded}/all.rdf")
|
33
|
+
|
34
|
+
# FIXME: push graph into the repository?
|
35
|
+
|
36
|
+
programmes = []
|
37
|
+
graph.query([nil, RDF.type, RDF::PO.Programme]) do |s|
|
38
|
+
programme = Programme.for(s.subject)
|
39
|
+
programme.title = graph.first_literal([s.subject, RDF::DC11.title, nil])
|
40
|
+
programmes << programme
|
41
|
+
end
|
42
|
+
programmes
|
43
|
+
end
|
44
|
+
|
45
|
+
# Fetches and returns a Graph for an identifier
|
46
|
+
def self.http_get_graph(uri)
|
47
|
+
uri = RDF::URI(uri) unless uri.is_a?(RDF::URI)
|
48
|
+
|
49
|
+
# FIXME: support other HTTP libraries too
|
50
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
51
|
+
http.get(uri.request_uri, {
|
52
|
+
'User-Agent' => USER_AGENT,
|
53
|
+
'Accept' => 'application/rdf+xml'
|
54
|
+
})
|
55
|
+
end
|
56
|
+
|
57
|
+
# Throw an exception if it failed
|
58
|
+
res.value
|
59
|
+
|
60
|
+
# Find a reader for the content type returned
|
61
|
+
reader_class = RDF::Reader.for(:content_type => res.content_type)
|
62
|
+
raise "No reader found for parsing: #{res.content_type}" if reader_class.nil?
|
63
|
+
|
64
|
+
# Parse the RDF
|
65
|
+
RDF::Graph.new(uri) do |graph|
|
66
|
+
reader_class.new(res.body, :base_uri => uri) do |reader|
|
67
|
+
reader.each_statement do |statement|
|
68
|
+
graph << statement
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Load a subject into the local repository
|
75
|
+
def self.fetch(identifier)
|
76
|
+
unless identifier.is_a?(RDF::URI)
|
77
|
+
identifier = RDF::URI("#{BASE_URI}/#{identifier}")
|
78
|
+
end
|
79
|
+
|
80
|
+
graph = self.http_get_graph(identifier)
|
81
|
+
|
82
|
+
type = graph.first_object([identifier, RDF.type, nil])
|
83
|
+
raise "No type found for #{identifier}" if type.nil?
|
84
|
+
|
85
|
+
klass = BBC::Programmes::Base.subclasses.find { |k| k.type == type }
|
86
|
+
raise "No class found for #{identifier} of type #{type}" if klass.nil?
|
87
|
+
|
88
|
+
# Add the graph to the repository of the type
|
89
|
+
graph.each_statement do |s|
|
90
|
+
klass.repository << s
|
91
|
+
end
|
92
|
+
|
93
|
+
klass.for(identifier)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# FIXME: hack for Spira not supporting namespaced resources
|
101
|
+
BBC_Programmes_Programme = BBC::Programmes::Programme
|
102
|
+
BBC_Programmes_Brand = BBC::Programmes::Brand
|
103
|
+
BBC_Programmes_Episode = BBC::Programmes::Episode
|
104
|
+
BBC_Programmes_Series = BBC::Programmes::Series
|
105
|
+
BBC_Programmes_Version = BBC::Programmes::Version
|
106
|
+
BBC_Programmes_Service = BBC::Programmes::Service
|
107
|
+
BBC_Programmes_Broadcast = BBC::Programmes::Broadcast
|
108
|
+
BBC_Programmes_Segment = BBC::Programmes::Segment
|
109
|
+
BBC_Programmes_TimeInterval = BBC::Programmes::TimeInterval
|
110
|
+
BBC_Programmes_TimeLine = BBC::Programmes::TimeLine
|
data/lib/rdf/po.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module RDF
|
4
|
+
|
5
|
+
##
|
6
|
+
# Programmes Ontology vocabulary.
|
7
|
+
#
|
8
|
+
# @see http://purl.org/ontology/po/
|
9
|
+
class PO < RDF::Vocabulary('http://purl.org/ontology/po/')
|
10
|
+
property :Brand
|
11
|
+
property :Series
|
12
|
+
property :Episode
|
13
|
+
property :Programme
|
14
|
+
property :Version
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper.rb"
|
2
|
+
|
3
|
+
describe BBC::Programmes do
|
4
|
+
before :each do
|
5
|
+
@repo = RDF::Repository.new
|
6
|
+
Spira.add_repository(:default, @repo)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "performing an HTTP get for a URI" do
|
10
|
+
before :each do
|
11
|
+
mock_http('www.bbc.co.uk', 'b00jnwlc.rdf')
|
12
|
+
@uri = RDF::URI('http://www.bbc.co.uk/programmes/b00jnwlc#programme')
|
13
|
+
@graph = BBC::Programmes.http_get_graph(@uri)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return an object of type RDF::Graph" do
|
17
|
+
@graph.should be_a RDF::Graph
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return a graph with more than 10 statements" do
|
21
|
+
@graph.size.should > 10
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return multiple statements about the URI looked up" do
|
25
|
+
@graph.query([@uri, nil, nil]).count.should > 2
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return a triple stating that the programme is of type Brand" do
|
29
|
+
@graph.should have_triple([@uri, RDF.type, RDF::PO.Brand])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "searching for a keyword" do
|
34
|
+
before :each do
|
35
|
+
mock_http('www.bbc.co.uk', 'the_wire.rdf')
|
36
|
+
@programmes = BBC::Programmes.search("The Wire")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return an array" do
|
40
|
+
@programmes.should be_a Array
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have three items in the array" do
|
44
|
+
@programmes.size.should == 3
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have items of type Programme in the array" do
|
48
|
+
@programmes.first.should be_a BBC::Programmes::Programme
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "fetching an episode" do
|
53
|
+
before :each do
|
54
|
+
mock_http('www.bbc.co.uk', 'b00jnwnv.rdf')
|
55
|
+
@episode = BBC::Programmes.fetch('b00jnwnv#programme')
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have a type URI defined" do
|
59
|
+
@episode.type.should == RDF::URI('http://purl.org/ontology/po/Episode')
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have a correct URI" do
|
63
|
+
@episode.subject.should == RDF::URI('http://www.bbc.co.uk/programmes/b00jnwnv#programme')
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have the title 'The Target'" do
|
67
|
+
@episode.title.should == 'The Target'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|