stupeflixclient 0.0.1

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.
@@ -0,0 +1,123 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module Stupeflixclient
5
+
6
+ class Connection
7
+ def initialize(server, base_url)
8
+ @server = server
9
+ @base_url = base_url
10
+ @MAX_NETWORK_RETRY = 1
11
+ @debuglevel = 0
12
+ end
13
+
14
+ def request_get( resource, args = nil, headers={})
15
+ return request(resource, "get", args, body = nil, filename = nil, headers=headers)
16
+ end
17
+
18
+ def request_delete( resource, args = nil, headers={})
19
+ return request(resource, "delete", args, headers=headers)
20
+ end
21
+
22
+ def request_head( resource, args = nil, headers={})
23
+ return request(resource, "head", args, headers=headers)
24
+ end
25
+
26
+ def request_post( resource, args = nil, body = nil, filename=nil, headers={})
27
+ return request(resource, "post", args , body = body, filename=filename, headers=headers)
28
+ end
29
+
30
+ def request_put(resource, args = nil, body = nil, filename=nil, headers={}, sendcallback = nil)
31
+ dump("In request_put in connection", resource, "PUT")
32
+ resp = request(resource, "put", args , body = body, filename=filename, headers=headers, sendcallback = sendcallback)
33
+ return resp
34
+ end
35
+
36
+ def dump( message, request_uri, method)
37
+ if @debuglevel > 0
38
+ print message, " " , time.asctime, " " , request_uri, "\n"
39
+ end
40
+ end
41
+
42
+ def request_method(verb)
43
+ Net::HTTP.const_get(verb.to_s.capitalize)
44
+ end
45
+
46
+ def fetch(uri_str, limit = 10)
47
+ # You should choose better exception.
48
+ raise ArgumentError, 'HTTP redirect too deep' if limit == 0
49
+
50
+ response = Net::HTTP.get_response(URI.parse(uri_str))
51
+ case response
52
+ when Net::HTTPSuccess then response
53
+ when Net::HTTPRedirection then fetch(response['location'], limit - 1)
54
+ else
55
+ response.error!
56
+ end
57
+
58
+ end
59
+
60
+ def request( resource, method = "get", args = nil, body = nil, filename=nil, headers={}, sendcallback = nil)
61
+ params = nil
62
+ path = resource
63
+
64
+ if headers == nil
65
+ headers = {}
66
+ end
67
+
68
+ headers['User-Agent'] = 'Basic Agent'
69
+
70
+ # TEMPORARY : add support for streaming
71
+ if method != "get"
72
+ if not body and filename
73
+ bodystream = File.open(filename, 'r')
74
+ end
75
+ end
76
+
77
+ if args
78
+ path += "?" + urllib.urlencode(args)
79
+ end
80
+
81
+ url = 'http://' + @server + @base_url + path
82
+
83
+ dump("Connection Request starting", path, method.upcase)
84
+
85
+ for i in 0..@MAX_NETWORK_RETRY
86
+ begin
87
+ # http.set_debug_output $stdout
88
+ # headers['Expect'] = '100-Continue'
89
+
90
+ response = nil
91
+ while true
92
+ url = URI.parse(url)
93
+ request = request_method(method).new(url.path + "?" + url.query, headers)
94
+ if bodystream
95
+ request.body_stream = bodystream
96
+ elsif body
97
+ request.body = body
98
+ end
99
+ http = Net::HTTP.new(url.host, url.port)
100
+ result = http.start {|http|
101
+ response = http.request(request)
102
+ }
103
+ case response
104
+ when Net::HTTPRedirection
105
+ then
106
+ url = response['location']
107
+ else
108
+ break
109
+ end
110
+ end
111
+ break
112
+ rescue StandardError => e
113
+ if i == (@MAX_NETWORK_RETRY - 1)
114
+ raise
115
+ end
116
+ end
117
+ end
118
+ response["status"] = response.code.to_s
119
+ return {'headers' => response, 'body' => response.body}
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,4 @@
1
+ module Stupeflixclient::Constants
2
+ SERVER_NAME = "http://services.stupeflix.com"
3
+ BASE_ENDPOINT = 'stupeflix-1.0'
4
+ end
@@ -0,0 +1,4 @@
1
+ module Stupeflixclient::Settings
2
+ ACCESS_KEY = ENV['stupeflix_access_key']
3
+ ACCESS_SECRET = ENV['stupeflix_access_secret']
4
+ end
@@ -0,0 +1,273 @@
1
+ require 'openssl'
2
+ require 'digest'
3
+ require 'base64'
4
+ require 'stupeflixclient/connection'
5
+ require 'digest/md5'
6
+ module Stupeflixclient
7
+ class StupeflixBase
8
+ def initialize( accessKey, privateKey, host = "http://services.stupeflix.com", service = 'stupeflix-1.0', debug = false)
9
+ @accessKey = accessKey
10
+ @privateKey = privateKey
11
+ len = host.length - 7
12
+ if host[host.length - 1, 1] == "/"
13
+ host = host[0, host.length - 1]
14
+ end
15
+
16
+ @host = host[7,len]
17
+ @base_url = service
18
+ @debug = debug
19
+ @service = service
20
+ @TEXT_XML_CONTENT_TYPE = "text/xml"
21
+ @APPLICATION_ZIP_CONTENT_TYPE = "application/zip"
22
+ @APPLICATION_JSON_CONTENT_TYPE = "application/json"
23
+ @APPLICATION_URLENCODED_CONTENT_TYPE = "application/x-www-form-urlencoded"
24
+ @PROFILES_PARAMETER = "Profiles"
25
+ @XML_PARAMETER = "ProfilesXML"
26
+ @MARKER_PARAMETER = "Marker"
27
+ @MAXKEYS_PARAMETER = "MaxKeys"
28
+ # Currently there is only the Marker parameter (used for partial enumeration)
29
+ @parametersToAdd = [@MARKER_PARAMETER, @MAXKEYS_PARAMETER]
30
+ @sleepTime = 1.0
31
+ @maxRetry = 4
32
+ @base = true
33
+ end
34
+
35
+ def connectionGet
36
+ return Connection.new(@host, "/" + @base_url)
37
+ end
38
+
39
+ def paramString( parameters)
40
+ paramStr = ""
41
+ if parameters != nil
42
+ for p in @parametersToAdd
43
+ if parameters.include?(p)
44
+ paramStr += sprintf( "%s\n%s\n", p, parameters[p])
45
+ end
46
+ end
47
+ end
48
+ return paramStr
49
+ end
50
+
51
+ def strToSign( method, resource, md5, mime, datestr, parameters)
52
+ paramStr = paramString(parameters)
53
+ stringToSign = sprintf( "%s\n%s\n%s\n%s\n%s\n%s", method, md5, mime, datestr, '/' + @service + resource, paramStr)
54
+ return stringToSign
55
+ end
56
+
57
+ def sign( strToSign, secretKey)
58
+ digest = OpenSSL::Digest::Digest.new('sha1')
59
+ return OpenSSL::HMAC.hexdigest(digest, secretKey, strToSign)
60
+ end
61
+
62
+ def signUrl( url, method, md5, mime, parameters = {})
63
+ now =Time.now.to_i
64
+ strToSign = strToSign(method, url, md5, mime, now, parameters)
65
+ signature = sign(strToSign, @privateKey)
66
+ url += sprintf( "?Date=%s&AccessKey=%s&Signature=%s", now, @accessKey,signature)
67
+ if parameters
68
+ parameters.each_pair do |k,v|
69
+ url += sprintf("&%s=%s", k,v)
70
+ end
71
+ end
72
+ return url
73
+ end
74
+
75
+ def md5FileOrBody( filename, body = nil)
76
+ md5 = Digest::MD5.new()
77
+
78
+ if body != nil
79
+ md5.update(body)
80
+ else
81
+ chunksize=1024
82
+ f = File.open(filename, 'r')
83
+
84
+ while true
85
+ chunk = f.read(chunksize)
86
+ if not chunk
87
+ break
88
+ end
89
+ md5.update(chunk)
90
+ end
91
+ f.close
92
+ end
93
+
94
+ digest = md5.digest
95
+
96
+ return [digest, md5.hexdigest, Base64.encode64(digest).strip]
97
+ end
98
+
99
+ def isZip( filename)
100
+ f = File.open(filename, 'r')
101
+ header = f.read(4)
102
+ return header == 'PK'+3.chr+4.chr
103
+ end
104
+
105
+ def logdebug( s)
106
+ if @debug
107
+ print s.to_s
108
+ end
109
+ end
110
+
111
+ def error( message)
112
+ logdebug(message)
113
+ raise StandardError, message
114
+ end
115
+
116
+ def answer_error( answer, message)
117
+ raise StandardError, sprintf( "%s\n%s", message, answer['body'])
118
+ end
119
+
120
+ # sendcallback is an object with
121
+ # - a 'sendCallBack' member function that accept a unique int argument (=number of bytes written so far)
122
+ # - a 'sendBlockSize' member function with no argument which return the size of block to be sent
123
+ def sendContent( method, url, contentType, filename = nil, body = nil, parameters = nil, sendcallback = nil)
124
+
125
+ # SEND DATA
126
+ conn = connectionGet()
127
+
128
+ md5, md5hex, md5base64 = md5FileOrBody(filename, body)
129
+
130
+ if filename
131
+ size = File.stat(filename).size
132
+ else
133
+ size = body.length
134
+ end
135
+
136
+ headers = {'Content-MD5' => md5base64.to_s,
137
+ 'Content-Length' => size.to_s,
138
+ 'Content-Type' => contentType}
139
+
140
+ url = signUrl(url, method, md5base64, contentType, parameters)
141
+
142
+ # LAUNCH THE REQUEST : TODO : pass filename instead of body
143
+ if method == "PUT"
144
+ answer = conn.request_put(url, args = nil, body = body, filename = filename, headers = headers, sendcallback = sendcallback)
145
+ elsif method == "POST"
146
+ answer = conn.request_post(url, args = nil, body = body, filename = filename, headers = headers)
147
+ elsif method == "DELETE"
148
+ answer = conn.request_delete(url, headers = headers)
149
+ end
150
+
151
+ headers = answer['headers']
152
+
153
+ logdebug(headers)
154
+ logdebug(answer['body'])
155
+
156
+ # NOW CHECK THAT EVERYTHING IS OK
157
+ status = headers['status']
158
+ if status != '200'
159
+ msg = sprintf( "sendContent : bad STATUS %s", status )
160
+ answer_error(answer, msg)
161
+ end
162
+
163
+ if headers['etag'] == nil
164
+ msg = "corrupted answer: no etag in headers. Response body is " + answer['body']
165
+ error(msg)
166
+ end
167
+
168
+ obtainedMD5 = headers['etag']
169
+
170
+ if obtainedMD5 != md5hex
171
+ msg = sprintf( "sendContent : bad returned etags %s =! %s (ref)", obtainedMD5, md5hex)
172
+ error(msg)
173
+ end
174
+
175
+ return answer
176
+ end
177
+
178
+ def getContentUrl( url, method, parameters)
179
+ return signUrl(url, method, "", "", parameters)
180
+ end
181
+
182
+ def getContent( url, filename = nil, parameters = nil)
183
+ sleepTime = @sleepTime
184
+
185
+ for i in 0..@maxRetry
186
+ raiseExceptionOn404 = (i + 1) == @maxRetry
187
+ ret = getContent_(url, filename, parameters, raiseExceptionOn404)
188
+ if ret["status"] != 404
189
+ return ret
190
+ end
191
+ # Wait for amazon S3 ...
192
+ sleep(1)
193
+ end
194
+ end
195
+
196
+ def getContent_( url, filename = nil, parameters = nil, raiseExceptionOn404 = true)
197
+ method = "GET"
198
+ url = getContentUrl(url, method, parameters)
199
+
200
+ # GET DATA
201
+ conn = connectionGet()
202
+ answer = conn.request_get(url)
203
+ body = answer['body']
204
+
205
+ headers = answer['headers']
206
+ status = headers['status'].to_i
207
+
208
+ if status == 204
209
+ # there was no content
210
+ obtainedSize = 0
211
+ if body.length != 0
212
+ error("204 status with non empty body.")
213
+ end
214
+ elsif status == 200
215
+ obtainedSize =headers['content-length'].to_i
216
+ elsif status == 404 and not raiseExceptionOn404
217
+ return {"url" => headers['content-location'], "status" => 404}
218
+ else
219
+ msg = sprintf( "getContent : bad STATUS %s", status )
220
+ answer_error(answer, msg)
221
+ end
222
+
223
+ if body.length != obtainedSize
224
+ error("Non matching body length and content-length")
225
+ end
226
+
227
+ if filename != nil
228
+ f = File.open(filename, 'w')
229
+ f.write(body)
230
+ f.close
231
+
232
+ if obtainedSize == 0
233
+ File.unlink(filename)
234
+ else
235
+ filesize = File.stat(filename).size
236
+ if obtainedSize != filesize
237
+ File.unlink(filename)
238
+ error(sprintf( "file size is incorrect : file size = %d, body size = %d", filesize, obtainedSize))
239
+ end
240
+ end
241
+ end
242
+
243
+ # NOW CHECK EVERYTHING IS OK
244
+ md5, md5hex, md5base64 = md5FileOrBody(filename, body)
245
+
246
+ if status != 204
247
+ obtainedMD5 = headers['etag'].gsub(/"/,"")
248
+ if obtainedMD5 != md5hex
249
+ if filename
250
+ File.unlink(filename)
251
+ end
252
+ error(sprintf( "getDefinition : bad returned etag %s =! %s (ref)", md5hex, obtainedMD5))
253
+ end
254
+ end
255
+
256
+ if status == 200
257
+ logdebug(sprintf( "headers = %s", headers) )
258
+ url = headers['content-location']
259
+ ret = {'size' => obtainedSize, 'url' => url, 'headers' => headers}
260
+ else
261
+ ret = {'size' => obtainedSize, 'url' => url}
262
+ end
263
+
264
+ if not filename
265
+ ret['body'] = body
266
+ end
267
+
268
+ ret["status"] = status
269
+
270
+ return ret
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,354 @@
1
+ require 'stupeflixclient/stupeflix_base'
2
+ require 'stupeflixclient/connection'
3
+ require 'cgi'
4
+ require 'json.rb'
5
+ module Stupeflixclient
6
+ class StupeflixClient < StupeflixBase
7
+ def initialize(accessKey, privateKey, host = "http://services.stupeflix.com", service = 'stupeflix-1.0', debug = false)
8
+ super(accessKey, privateKey, host, service, debug)
9
+ @batch = false
10
+ @batchData = ""
11
+ end
12
+
13
+ # Start a batch, used for speeduping video definition upload
14
+ # Operation that can be batched : sendDefinition and createProfiles
15
+ # Operation
16
+ # Only works for xml definition, not zip, and xml must be in UTF8
17
+ def batchStart( maxSize = 1000000)
18
+ @batch = true
19
+ @batchData = "<batch>"
20
+ @batchMaxSize = maxSize
21
+ end
22
+
23
+ # End a batch: actually send data
24
+ def batchEnd
25
+ @batchData += "</batch>"
26
+ sendDefinitionBatch(body = @batchData)
27
+ @batchData = ""
28
+ @batch = false
29
+ end
30
+
31
+ # Send a definition file to the API
32
+ def sendDefinition( user, resource, filename = nil, body = nil)
33
+ url = definitionUrl(user, resource)
34
+ if body
35
+ contentType = @TEXT_XML_CONTENT_TYPE;
36
+ elsif isZip(filename)
37
+ contentType = @APPLICATION_ZIP_CONTENT_TYPE
38
+ else
39
+ contentType = @TEXT_XML_CONTENT_TYPE
40
+ end
41
+ if @batch and contentType == @TEXT_XML_CONTENT_TYPE
42
+ @batchData += sprintf("<task user=\"%s\" resource=\"%s\">", user, resource)
43
+ if body
44
+ @batchData += body
45
+ else
46
+ @batchData += File.open(filename).read
47
+ end
48
+ else
49
+
50
+ return sendContent("PUT", url, contentType, filename, body)
51
+ end
52
+ end
53
+
54
+ # Send a definition file to the API
55
+ def sendDefinitionBatch( filename = nil, body = nil)
56
+ url = @definitionBatchUrl
57
+ contentType = @TEXT_XML_CONTENT_TYPE;
58
+ return sendContent("PUT", url, contentType, filename, body)
59
+ end
60
+
61
+ def getDefinition( user, resource, filename)
62
+ url = definitionUrl(user, resource)
63
+ return getContent(url, filename)['size']
64
+ end
65
+
66
+ def _getAbsoluteUrl( url, followRedirect = false)
67
+ urlPart = getContentUrl(url, 'GET', nil)
68
+ if followRedirect
69
+ conn = connection.Connection(@base_url, followRedirect = false)
70
+ response = conn.request_get(urlPart)
71
+ return response["headers"]["location"]
72
+ else
73
+ return @base_url + urlPart
74
+ end
75
+ end
76
+
77
+ def getProfileUrl( user, resource, profile, followRedirect = false)
78
+ url = profileUrl(user, resource, profile)
79
+ return _getAbsoluteUrl(url, followRedirect)
80
+ end
81
+
82
+ def getProfile( user, resource, profile, filename)
83
+ url = profileUrl(user, resource, profile)
84
+ getContent(url, filename)
85
+ end
86
+
87
+ def getProfileThumbUrl( user, resource, profile, followRedirect = false)
88
+ url = profileThumbUrl(user, resource, profile, "thumb.jpg")
89
+ return _getAbsoluteUrl(url, followRedirect)
90
+ end
91
+
92
+ def getProfileThumb( user, resource, profile, filename)
93
+ url = profileThumbUrl(user, resource, profile, "thumb.jpg")
94
+ getContent(url, filename)
95
+ end
96
+
97
+ def getProfileReportUrl( user, resource, profile, followRedirect = false)
98
+ url = profileReportUrl(user, resource, profile)
99
+ return _getAbsoluteUrl(url, followRedirect)
100
+ end
101
+
102
+ def getProfileReport( user, resource, profile, filename)
103
+ url = profileReportUrl(user, resource, profile)
104
+ getContent(url, filename)
105
+ end
106
+
107
+ def createProfiles( user, resource, profiles)
108
+ profileData = profiles.xmlGet
109
+ if @batch
110
+ @batchData += profileData
111
+ @batchData += "</task>"
112
+ if @batchData.length >= @batchMaxSize
113
+ begin
114
+ @batchEnd
115
+ finally
116
+ batchStart(@batchMaxSize)
117
+ end
118
+ end
119
+ else
120
+ url, parameters = profileCreateUrl(user, resource, profileData)
121
+ contentType = @APPLICATION_URLENCODED_CONTENT_TYPE
122
+ body = ""
123
+ parameters.each_pair do |k,v|
124
+ body += CGI::escape(k) + "=" + CGI::escape(v)
125
+ end
126
+ return sendContent("POST", url, contentType, filename = nil, body = body)
127
+ end
128
+ end
129
+
130
+ def getStatus( user = nil, resource = nil, profile = nil, marker = nil, maxKeys = nil)
131
+ url, parameters = statusUrl(user, resource, profile, marker, maxKeys)
132
+ ret = getContent(url, filename = nil, parameters = parameters)
133
+ status = JSON.parse(ret['body'])
134
+ return status
135
+ end
136
+
137
+ def getMarker( status)
138
+ if status.length == 0
139
+ return nil
140
+ end
141
+ lastStatus = status[-1]
142
+ #return map(lambda x: lastStatus[x], ["user", "resource", "profile"])
143
+ return []
144
+ end
145
+
146
+ # helper functions : build non signed urls for each kind of action
147
+ def definitionUrl( user, resource)
148
+ return sprintf( "/%s/%s/definition/", user, resource)
149
+ end
150
+
151
+ # helper functions : build non signed urls for each kind of action
152
+ def definitionBatchUrl
153
+ return "/batch/"
154
+ end
155
+
156
+ def profileUrl( user, resource, profile)
157
+ return sprintf( "/%s/%s/%s/", user, resource, profile)
158
+ end
159
+
160
+ def profileThumbUrl( user, resource, profile, thumbname)
161
+ return sprintf( "/%s/%s/%s/%s/", user, resource, profile, thumbname)
162
+ end
163
+
164
+ def profileReportUrl( user, resource, profile)
165
+ return sprintf( "/%s/%s/%s/%s/", user, resource, profile, "report.xml")
166
+ end
167
+
168
+ def profileCreateUrl( user, resource, profiles)
169
+ s = sprintf( "/%s/%s/", user, resource)
170
+ parameters = {@XML_PARAMETER => profiles}
171
+ return s, parameters
172
+ end
173
+
174
+ def actionUrl( user, resource, profile, action)
175
+ path = [user, resource, profile]
176
+ s = ""
177
+ path.each do |p|
178
+ if p == nil
179
+ break
180
+ end
181
+ s += sprintf( "/%s", p )
182
+ end
183
+ s += sprintf( "/%s/", action )
184
+ return s
185
+ end
186
+
187
+ def statusUrl( user, resource, profile, marker = nil, maxKeys = nil)
188
+ params = {}
189
+ if marker != nil
190
+ params[@MARKER_PARAMETER] = marker.join('/')
191
+ end
192
+ if maxKeys != nil
193
+ params[@MAXKEYS_PARAMETER] = maxKeys
194
+ end
195
+
196
+ return [actionUrl(user, resource, profile, "status"), params]
197
+ end
198
+ end
199
+
200
+ class StupeflixXMLNode
201
+ def initialize( nodeName, attributes = nil, children = nil, text = nil)
202
+ @children = children
203
+ @attributes = attributes
204
+ @nodeName = nodeName
205
+ @text = text
206
+ end
207
+
208
+ def xmlGet
209
+ docXML = '<' + @nodeName
210
+ if @attributes and @attributes.length != 0
211
+
212
+ @attributes.each_pair do |k, v|
213
+ docXML += " "
214
+ if v == nil
215
+ v = ""
216
+ end
217
+ k = k.to_s
218
+ v = v.to_s
219
+ docXML += k + '="' + CGI.escapeHTML(v) + '"'
220
+ end
221
+ end
222
+ docXML += '>'
223
+ if @children
224
+ for c in @children
225
+ docXML += c.xmlGet
226
+ end
227
+ end
228
+ if @text
229
+ docXML += @text
230
+ end
231
+ docXML += '</' + @nodeName + '>'
232
+
233
+ return docXML
234
+ end
235
+
236
+ def metaChildrenAppend( meta = nil, notify = nil, children = nil)
237
+ childrenArray = []
238
+ if meta
239
+ childrenArray += [meta]
240
+ end
241
+ if notify
242
+ childrenArray += [notify]
243
+ end
244
+ if children
245
+ childrenArray += children
246
+ end
247
+ return childrenArray
248
+ end
249
+ end
250
+
251
+ class StupeflixMeta < StupeflixXMLNode
252
+ def initialize(dict)
253
+ children = []
254
+
255
+ dict.all? {|k, v|
256
+ children += [StupeflixXMLNode.new(k, nil, nil, v)]
257
+ }
258
+ super("meta", {}, children)
259
+ end
260
+ end
261
+
262
+ class StupeflixProfileSet < StupeflixXMLNode
263
+ def initialize( profiles, meta = nil, notify = nil)
264
+ children = metaChildrenAppend(meta, notify, profiles)
265
+ super("profiles", {}, children)
266
+ end
267
+
268
+ def deflt(profiles)
269
+ profSet = []
270
+ for p in profiles
271
+ upload = StupeflixDefaultUpload
272
+ profSet += [StupeflixProfile(p, [upload])]
273
+ end
274
+
275
+ return StupeflixProfileSet.new(profSet)
276
+ end
277
+ end
278
+
279
+ class StupeflixProfile < StupeflixXMLNode
280
+ def initialize( profileName, uploads = nil, meta = nil, notify = nil)
281
+ children = metaChildrenAppend(meta, notify, uploads)
282
+ super("profile", {"name" => profileName}, children)
283
+ end
284
+ end
285
+
286
+ class StupeflixNotify < StupeflixXMLNode
287
+ def initialize( url, statusRegexp)
288
+ super("notify", {"url" => url, "statusRegexp" => statusRegexp})
289
+ end
290
+ end
291
+
292
+ class StupeflixHttpHeader < StupeflixXMLNode
293
+ def initialize(key, value)
294
+ super("header", {"key" => key, "value" => value})
295
+ end
296
+ end
297
+
298
+ class StupeflixUpload < StupeflixXMLNode
299
+ def initialize( name, parameters, meta = nil, notify = nil, children = nil)
300
+ children = metaChildrenAppend(meta, notify, children)
301
+ super(name, parameters, children)
302
+ end
303
+ end
304
+
305
+ class StupeflixHttpPOSTUpload < StupeflixUpload
306
+ def initialize( url, meta = nil, notify = nil)
307
+ super("httpPOST", {"url" => url}, meta, notify)
308
+ end
309
+ end
310
+
311
+ class StupeflixHttpPUTUpload < StupeflixUpload
312
+ def initialize( url, meta = nil, notify = nil, headers = nil)
313
+ super("httpPUT", {"url" => url}, meta, notify, headers)
314
+ end
315
+ end
316
+
317
+ class StupeflixYoutubeUpload < StupeflixUpload
318
+ def initialize(login, password, meta = nil, notify = nil)
319
+ super("youtube", {"login" => login, "password" => password}, meta, notify)
320
+ end
321
+ end
322
+
323
+ class StupeflixBrightcoveUpload < StupeflixUpload
324
+ def initialize(token, reference_id = nil, meta = nil, notify = nil)
325
+ parameters = {"sid" => token}
326
+ if reference_id != nil
327
+ parameters["reference_id"] = reference_id
328
+ end
329
+ super("brightcove", parameters, meta, notify)
330
+ end
331
+ end
332
+
333
+ class StupeflixDefaultUpload < StupeflixUpload
334
+ def initialize( meta = nil, notify = nil)
335
+ children = metaChildrenAppend(meta)
336
+ super("stupeflixStore", {}, meta, notify)
337
+ end
338
+ end
339
+
340
+ class StupeflixS3Upload < StupeflixUpload
341
+ def initialize(bucket, resourcePrefix, accesskey = nil, secretkey = nil, meta = nil, notify = nil)
342
+ children = metaChildrenAppend(meta)
343
+ parameters = {"bucket" => bucket, "resourcePrefix" => resourcePrefix}
344
+ if accesskey != nil
345
+ parameters["accesskey"] = accesskey
346
+ end
347
+ if secretkey != nil
348
+ parameters["secretkey"] = secretkey
349
+ end
350
+ super("s3", parameters, meta, notify)
351
+ end
352
+ end
353
+
354
+ end