/
main.rb
176 lines (157 loc) · 5.89 KB
/
main.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
require "bundler"
Bundler.setup :default, :api
require "sinatra"
require "xmlsimple"
require "lib/media_queue"
require "timeout"
require "pstore"
require "yaml"
require "logger"
require "addressable/uri"
class MediaprocessorApi < Sinatra::Application
def self.config
@@config ||= YAML.load_file(File.join(File.dirname(__FILE__),
'config', 'main.yml'))
end
configure do
LOGGER = Logger.new(File.join(config["logger_path"], "media_api.log"))
end
helpers do
def logger
LOGGER
end
def validate_uri uri, type
begin
parsed_uri = Addressable::URI.parse uri
logger.debug "#{type}-#{parsed_uri.scheme}"
if parsed_uri.scheme.nil? or not File.exists?(File.join type, "#{parsed_uri.scheme}.rb")
logger.debug "invalid uri #{uri}"
return false
end
rescue Addressable::URI::InvalidURIError => e
logger.debug "invalid uri #{uri} - exception: #{e}"
return false
end
return true
end
end
def media_queue
@@media_queue ||= MediaQueue::Queue.new MediaprocessorApi.config["media_queue_file"]
end
def synchronize_codes
if RUBY_VERSION < "1.9"
@@synchronize_codes ||= PStore.new MediaprocessorApi.config["notifier-synchronize"]["sync_state_file"]
else
@@synchronize_codes ||= PStore.new MediaprocessorApi.config["notifier-synchronize"]["sync_state_file"], true
end
end
get "/" do
"it works"
end
put "/media/create" do
source_uri_is_valid = true
destination_uri_is_valid = true
XmlSimple.xml_in(request.env["rack.input"].read, 'ForceArray' => false).each do |media_type, media_spec|
logger.debug "media/create request: #{media_spec.inspect}"
source_uri_is_valid = validate_uri media_spec["source"], "downloaders"
destination_uri_is_valid = validate_uri media_spec["destination"], "uploaders"
if source_uri_is_valid and destination_uri_is_valid
media_queue << media_spec.merge({"type" => media_type})
end
end
if source_uri_is_valid and destination_uri_is_valid
XmlSimple.xml_out({"type" => ["ok"]},
"RootName" => ["response"])
else
unless source_uri_is_valid or destination_uri_is_valid
XmlSimple.xml_out({"type" => ["error"],
"description" => ["invalid source and destination uri"]},
"RootName" => "response")
else
unless source_uri_is_valid
logger.debug "invalid source uri"
XmlSimple.xml_out({"type" => ["error"],
"description" => ["invalid source uri"]},
"RootName" => "response")
else
logger.debug "invalid destination uri"
XmlSimple.xml_out({"type" => ["error"],
"description" => ["invalid destination uri"]},
"RootName" => "response")
end
end
end
end
put "/media/fetch" do
code = nil
if RUBY_VERSION < "1.9"
code = (('a'..'z').to_a + 0.upto(10).to_a).shuffle.first(20).join
else
code = (('a'..'z').to_a + 0.upto(10).to_a).sample(20).join
end
source_uri_is_valid = true
destination_uri_is_valid = true
XmlSimple.xml_in(request.env["rack.input"].read, 'ForceArray' => false).each do |media_type, media_spec|
logger.debug "media/fetch request #{media_spec.inspect}"
source_uri_is_valid = validate_uri media_spec["source"], "downloaders"
destination_uri_is_valid = validate_uri media_spec["destination"], "uploaders"
if source_uri_is_valid and destination_uri_is_valid
synchronize_codes.transaction do
synchronize_codes[code] = :processing
end
media_queue << media_spec.merge({"type" => media_type, :notifier => :synchronize, :code => code})
end
end
if source_uri_is_valid and destination_uri_is_valid
begin
t = nil
Timeout::timeout(60) do
t = Time.now
finished = false
result = nil
until finished do
synchronize_codes.transaction do
result = synchronize_codes[code]
finished = synchronize_codes[code] != :processing
end
sleep 0.1
end
if result == :ready
logger.debug "fetch (media ready) time: #{Time.now - t}s"
XmlSimple.xml_out({"type" => ["ok"]},
"RootName" => ["response"])
elsif result.instance_of?(Array) and result.first == :error
logger.debug "fetch (media error) time: #{Time.now - t}s"
XmlSimple.xml_out({"type" => ["error"],
"description" => [result.last]},
"RootName" => "response")
end
end
rescue Timeout::Error
logger.warn "timeout!"
XmlSimple.xml_out({"type" => ["error"],
"description" => ["timeout error"]},
"RootName" => "response")
end
else
unless source_uri_is_valid or destination_uri_is_valid
logger.debug "sending error (invalid both uri)"
XmlSimple.xml_out({"type" => ["error"],
"description" => ["invalid source and destination uri"]},
"RootName" => "response")
else
unless source_uri_is_valid
logger.debug "sending error (invalid source uri)"
XmlSimple.xml_out({"type" => ["error"],
"description" => ["invalid source uri"]},
"RootName" => "response")
else
logger.debug "sending error (description source uri)"
XmlSimple.xml_out({"type" => ["error"],
"description" => ["invalid destination uri"]},
"RootName" => "response")
end
end
end
end
end