-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.rb
136 lines (117 loc) · 4.62 KB
/
app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
require 'rubygems'
require 'sinatra'
require 'sinatra/reloader' if development?
require 'sinatra/config_file'
require 'rest-client'
require 'yaml'
# Load config file.
config_file 'config.yml'
# Reuse the same user credentials for all the requests.
# See comment on `get '/register'`.
USER_ID = '555556'
USER_KEY = '000102030405060708090a0b0c0d0124'
get '/' do
set_ce_html_content_type!
erb :content_list, :locals => {:contents => all_contents}
end
get '/download/:content_id' do |content_id|
set_ce_html_content_type!
erb :download, :locals => content_info(content_id)
end
get '/stream/:content_id' do |content_id|
set_ce_html_content_type!
erb :stream, :locals => content_info(content_id)
end
# Serve a DCF file directly.
get '/contents/:content_id.dcf' do |content_id|
path = settings.root + '/contents/' + content_id + '.dcf'
send_file(path)
end
# Acquires a Marlin Broadband Registration action token and serves it directly.
get '/register', :provides => :xml do
# Here you should use your real user credentials, so this request should be
# authenticated. The user key should be a 128-bit hex key associated with the
# user ID. For the purpose of this example, we are using the same credentials
# for all the requests.
user_id = USER_ID
user_key = USER_KEY
# Make the actual API call to the Hosted Marlin Service.
RestClient.get hms_api_url, :params => {
:actionTokenType => '0', # 0 -> Marlin Broadband Registration Token.
:errorFormat => 'json',
:customerAuthenticator => settings.customer_authenticator,
:userId => user_id,
:userKey => user_key
}
end
# Acquires a User-Bound Marlin Broadband License transaction token, like a boss.
get '/license/:content_id', :provides => :xml do |content_id|
content = content_info(content_id)
RestClient.get hms_api_url, :params => {
:actionTokenType => '1', # 1 -> Marlin Broadband License Token.
:errorFormat => 'json',
:customerAuthenticator => settings.customer_authenticator,
:userId => USER_ID, # See comment about user id above.
:userKey => USER_KEY,
:contentId => content[:id],
:contentKey => content[:key],
:rightsType => 'Rental',
:'rental.periodEndTime' => '+9999', # Use appropriate values here.
:'rental.playDuration' => '9999'
}
end
# Returns a Content Access Descriptor (CAD).
# Notice that the CAD file is only rendered with useful title, synopsis and
# rights-URL fields, which is quite the minimum to get this working, all the
# other field are filled with garbage (e.g. the artwork URL points to a Nyan Cat
# image). As this file should be generated by you (the content provider), you
# should fill it with useful content information, like its actual duration,
# size, MD5 hash, etc.
get '/cad/:content_id', :provides => :xml do |content_id|
erb :cad, :locals => content_info(content_id), :layout => false
end
helpers do
# Sets the content type of the response to either CE-HTML or XML.
def set_ce_html_content_type!
if request.user_agent =~ /Opera\//
# Opera and NetTV devices recognize CE-HTML mime type.
content_type 'application/ce-html+xml;charset="UTF-8"'
else
# Other browsers don't, but they can render XHTML.
content_type 'application/xhtml+xml;charset="UTF-8"'
end
end
# Hosted Marlin Service API base URL.
def hms_api_url
'https://' + settings.hms_hostname + '/hms/bb/token'
end
# Returns a list of all the videos under /contents directory.
def all_contents
yml_filenames = Dir.glob(settings.root + '/contents/*.yml')
yml_filenames.map { |filename|
id = filename.match(/\/contents\/(.*)\.yml/)[1]
content_info(id)
}
end
# Returns a hash with the information for a given content ID. The information
# is taken from the corresponding YAML file under /contents directory.
def content_info(id)
filename = settings.root + '/contents/' + id + '.yml'
content = YAML.load(File.read(filename))
raise 'Content has not key' unless content[:key]
# Complete HMS information with default values.
content[:id] ||= "urn:marlin:organization:example:#{id}"
content[:title] ||= id
content[:synopsis] ||= content[:title]
content[:url] ||= url("/contents/#{id}.dcf")
# Other useful URLs.
content[:rights_url] = url('/license/' + id)
content[:download_url] = url('/download/' + id)
content[:stream_url] = url('/stream/' + id)
content[:cad_url] = url('/cad/' + id)
content
rescue Errno::ENOENT
# .yml file does not exist. Show a 404 Not Found.
not_found
end
end