vidispine 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/Gemfile +11 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +296 -0
  6. data/Rakefile +2 -0
  7. data/bin/vidispine +7 -0
  8. data/bin/vidispine-notification-handler +339 -0
  9. data/bin/vidispine-utilities-http-server +13 -0
  10. data/dist/vidispine-1.4.0.gem +0 -0
  11. data/lib/vidispine.rb +5 -0
  12. data/lib/vidispine/api/client.rb +981 -0
  13. data/lib/vidispine/api/client/http_client.rb +291 -0
  14. data/lib/vidispine/api/client/requests.rb +27 -0
  15. data/lib/vidispine/api/client/requests/base_request.rb +234 -0
  16. data/lib/vidispine/api/client/requests/collection_access_add.rb +30 -0
  17. data/lib/vidispine/api/client/requests/collection_access_delete.rb +26 -0
  18. data/lib/vidispine/api/client/requests/collection_metadata_set.rb +24 -0
  19. data/lib/vidispine/api/client/requests/import_placeholder.rb +36 -0
  20. data/lib/vidispine/api/client/requests/import_placeholder_item.rb +38 -0
  21. data/lib/vidispine/api/client/requests/import_sidecar_file.rb +28 -0
  22. data/lib/vidispine/api/client/requests/import_using_uri.rb +44 -0
  23. data/lib/vidispine/api/client/requests/item_access_add.rb +30 -0
  24. data/lib/vidispine/api/client/requests/item_access_delete.rb +26 -0
  25. data/lib/vidispine/api/client/requests/item_delete.rb +17 -0
  26. data/lib/vidispine/api/client/requests/item_export.rb +44 -0
  27. data/lib/vidispine/api/client/requests/item_metadata_get.rb +37 -0
  28. data/lib/vidispine/api/client/requests/item_metadata_set.rb +29 -0
  29. data/lib/vidispine/api/client/requests/item_search.rb +0 -0
  30. data/lib/vidispine/api/client/requests/item_transcode.rb +23 -0
  31. data/lib/vidispine/api/client/requests/items_search.rb +40 -0
  32. data/lib/vidispine/api/client/requests/search.rb +59 -0
  33. data/lib/vidispine/api/client/requests/storage_file_create.rb +23 -0
  34. data/lib/vidispine/api/client/requests/storage_file_get.rb +40 -0
  35. data/lib/vidispine/api/client/requests/storage_files_get.rb +42 -0
  36. data/lib/vidispine/api/utilities.rb +1608 -0
  37. data/lib/vidispine/api/utilities/cli.rb +168 -0
  38. data/lib/vidispine/api/utilities/http_server.rb +230 -0
  39. data/lib/vidispine/api/utilities/http_server/cli.rb +77 -0
  40. data/lib/vidispine/cli.rb +174 -0
  41. data/lib/vidispine/version.rb +3 -0
  42. data/resources/postman/Vidispine API (From WADL v4.11).postman_collection.json +47437 -0
  43. data/vidispine.gemspec +26 -0
  44. metadata +117 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4d9919ba4f728d001342ea3e8c254eed8ecd59ae29a4fbf759b8faefac79fcfd
4
+ data.tar.gz: 1b4f5580669b0ed5edc15692f2d7deb19e6616ab1c8b98e2e52802e9e256b001
5
+ SHA512:
6
+ metadata.gz: b7359a1382a8edeb9b33ec53178c4f9588a70b363378bc292cfe0f12a41260771b1b3b5e77603c86a7eae34bf1b5d6458fd1e361cd660771dfbeb023b8a0eea9
7
+ data.tar.gz: f97825f0cb2874fe8445dc98b8766b47750f41bf89f6b64586f974838970e8a334fd9fc58e235edbf45771824c19141f0fd2d3ef945bd846f2163522b8bfd644
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /dev/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'aws-sdk-s3', '~> 1'
4
+
5
+ gem 'json', '~> 1.8', :platforms => :mri_18
6
+ # gem 'mini_portile', '~> 0.5.0', :platforms => :mri_18
7
+ # gem 'mime-types', '~> 1.25.1', :platforms => :mri_18
8
+ # gem 'nokogiri', '<= 1.5.11', :platforms => :mri_18
9
+ # gem 'fog', '~> 1.22.0', :platforms => :mri_18
10
+ # Specify your gem's dependencies in vidispine.gemspec
11
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 John Whitson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,296 @@
1
+ # Vidispine
2
+
3
+ ## Installation
4
+
5
+ ### Pre-requisites
6
+
7
+ - [git](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
8
+ - [ruby](https://www.ruby-lang.org/en/documentation/installation/)
9
+ - rubygems
10
+ - [bundler](http://bundler.io/#getting-started)
11
+
12
+ #### Install Pre-requisites on CentOS
13
+
14
+ Execute the following:
15
+
16
+ $ yum install -y git ruby ruby-devel rubygems
17
+ $ gem install bundler
18
+
19
+ ### Install Using Git
20
+
21
+ Execute the following:
22
+
23
+ $ git clone https://github.com/XPlatform-Consulting/vidispine.git
24
+ $ cd vidispine
25
+ $ bundle update
26
+
27
+ Or install it yourself using the specific_install gem:
28
+
29
+ $ gem install specific_install
30
+ $ gem specific_install https://github.com/XPlatform-Consulting/vidispine.git
31
+
32
+ ## Vidispine API Executable [bin/vidispine](../bin/vidispine)
33
+
34
+ ### Usage
35
+
36
+ Usage:
37
+ vidispine -h | --help
38
+
39
+ Options:
40
+ --host-address HOSTADDRESS The address of the server to communicate with.
41
+ default: localhost
42
+ --host-port HOSTPORT The port to use when communicating with the server.
43
+ default: 8080
44
+ --username USERNAME The account username to authenticate with.
45
+ --password PASSWORD The account password to authenticate with.
46
+ --accept-header VALUE The value for the Accept header sent in each request.
47
+ default: application/json
48
+ --content-type VALUE The value for the Content-Type header sent in each request.
49
+ default: application/json; charset=utf-8
50
+ --method-name METHODNAME The name of the method to call.
51
+ --method-arguments JSON The arguments to pass when calling the method.
52
+ --storage-map JSON A map of file paths to storage ids to use in utility methods.
53
+ --metadata-map JSON A map of field aliases to field names to use in utility methods.
54
+ --pretty-print Will format the output to be more human readable.
55
+ --log-to FILENAME Log file location.
56
+ default: STDERR
57
+ --log-level LEVEL Logging level. Available Options: debug, info, warn, error, fatal
58
+ default: error
59
+ --[no-]options-file [FILENAME]
60
+ Path to a file which contains default command line arguments.
61
+ default: /Users/jw/.options/vidispine
62
+ -h, --help Display this message.
63
+
64
+ ### Available API Methods
65
+
66
+ #### [collection_create](http://apidoc.vidispine.com/4.2/ref/collection.html#create-a-collection)
67
+
68
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_create --method-arguments '{"collection_name":"SomeName"}'
69
+
70
+ #### [collection_delete](http://apidoc.vidispine.com/4.2/ref/collection.html#delete--collection-\(collection-id\))
71
+
72
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_delete --method-arguments '{"collection_id":"VX-1"}'
73
+
74
+ #### [collection_get](http://apidoc.vidispine.com/4.2/ref/collection.html#retrieve-a-list-of-all-collections)
75
+
76
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_get --method-arguments '{"collection_id":"VX-1"}'
77
+
78
+ #### [collection_items_get](http://apidoc.vidispine.com/4.2/ref/collection.html#retrieve-the-items-of-a-collection)
79
+
80
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_items_get --method-arguments '{"collection_id":"VX-1"}'
81
+
82
+ #### [collection_metadata_get](http://apidoc.vidispine.com/4.2/ref/collection.html#retrieve-collection-metadata)
83
+
84
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_metadata_get --method-arguments '{"collection_id":"VX-1"}'
85
+
86
+ #### [collection_object_add](http://apidoc.vidispine.com/4.2/ref/collection.html#add-an-item-library-or-collection-to-a-collection)
87
+
88
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_object_add --method-arguments '{"collection_id":"VX-1","object_id":"VX-2","type":'item"}'
89
+
90
+ #### [collection_object_remove](http://apidoc.vidispine.com/4.2/ref/collection.html#remove-an-item-library-or-collection-from-a-collection)
91
+
92
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_object_remove --method-arguments '{"collection_id":"VX-1","object_id":"VX-2","type":"item"}'
93
+
94
+ #### [collection_rename](http://apidoc.vidispine.com/4.2/ref/collection.html#rename-a-collection)
95
+
96
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_rename --method-arguments '{"collection_id":"VX-1","name":"NewName"}'
97
+
98
+ #### [collections_get](http://apidoc.vidispine.com/latest/ref/collection.html#retrieve-a-list-of-all-collections)
99
+
100
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collections_get
101
+
102
+ #### [import_placeholder](http://apidoc.vidispine.com/latest/ref/item/import.html#create-a-placeholder-item)
103
+
104
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name import_placeholder --method-arguments '{"video":1}'
105
+
106
+ #### [import_placeholder_item](http://apidoc.vidispine.com/latest/ref/item/import.html#import-to-a-placeholder-item)
107
+
108
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name import_placeholder_item --method-arguments '{"item_id":"VX-1","item_type":"video","uri":"file://srv/media1/test.mov"}'
109
+
110
+ #### [import_using_uri](http://apidoc.vidispine.com/4.2/ref/item/import.html#import-using-a-uri)
111
+
112
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name import_using_uri --method-arguments '{"uri":"file://srv/media1/test.mov"}'
113
+
114
+ #### [item_collections_get](http://apidoc.vidispine.com/4.2/ref/item/item.html#list-collections-that-contain-an-item)
115
+
116
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_collections_get --method-arguments '{"item_id":"VX-1"}'
117
+
118
+ #### [item_delete](http://apidoc.vidispine.com/latest/ref/item/item.html#delete-a-single-item)
119
+
120
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_delete --method-arguments '{"item_id":"VX-117"}'
121
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_delete --method-arguments '{"item_id":"VX-117","keepShapeTagMedia":"lowres,webm,original","keepShapeTagStorage":"VX-2,VX-3"}'
122
+
123
+ #### [item_get](http://apidoc.vidispine.com/latest/ref/item/item.html#get-information-about-a-single-item)
124
+
125
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_get --method-arguments '{"item_id":"VX-1"}'
126
+
127
+ #### [item_metadata_get](http://apidoc.vidispine.com/4.2/ref/metadata/metadata.html#get--item-\(id\)-metadata)
128
+
129
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_metadata_get --method-arguments '{"item_id":"VX-1"}'
130
+
131
+ #### [item_metadata_set](http://apidoc.vidispine.com/4.2/ref/metadata/metadata.html#add-a-metadata-change-set)
132
+
133
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_metadata_set --method-arguments '{"item_id":"VX-1","metadata_document":{ }}'
134
+
135
+ #### [item_shape_files_get](http://apidoc.vidispine.com/4.2/ref/item/shape.html#get-files-for-shape)
136
+
137
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_shape_files_get --method-arguments '{"item_id":"VX-1","shape_id":"VX-2"}'
138
+
139
+ #### [item_shape_import](http://apidoc.vidispine.com/4.2/ref/item/shape.html#import-a-shape-using-a-uri-or-an-existing-file)
140
+
141
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_shape_import --method-arguments '{"item_id":"VX-1","uri":"file:///srv/media1/test.mov","tag":"original"}'
142
+
143
+ #### [item_thumbnail](http://apidoc.vidispine.com/latest/ref/item/thumbnail.html#start-a-thumbnail-job)
144
+
145
+ TODO: ADD EXAMPLE
146
+
147
+ #### [item_transcode](http://apidoc.vidispine.com/4.2/ref/item/transcode.html#start-an-item-transcode-job)
148
+
149
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_transcode --method-arguments '{"item_id":"VX-116", "tag":"original"}'
150
+
151
+ #### [item_uris_get](http://apidoc.vidispine.com/4.2/ref/item-content.html#get--item-\(item-id\)-uri)
152
+
153
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_uris_get --method-arguments '{"item_id":"VX-1"}'
154
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_uris_get --method-arguments '{"item_id":"VX-1","tag":"lowres"}'
155
+
156
+ #### [items_get](http://apidoc.vidispine.com/latest/ref/item/item.html#retrieve-a-list-of-all-items)
157
+
158
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name items_get
159
+
160
+ #### [items_search](http://apidoc.vidispine.com/latest/ref/item/item.html#search-items)
161
+
162
+ TODO: ADD EXAMPLE
163
+
164
+ #### [job_abort](http://apidoc.vidispine.com/4.2/ref/job.html#abort-job)
165
+
166
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name job_abort --method-arguments '{"job_id":"VX-1"}'
167
+
168
+ #### [job_get](http://apidoc.vidispine.com/4.2/ref/job.html#get-job-information)
169
+
170
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name job_get --method-arguments '{"job_id":"VX-1"}'
171
+
172
+ #### [jobs_get](http://apidoc.vidispine.com/4.2/ref/job.html#get--job)
173
+
174
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name jobs_get
175
+
176
+ #### [storage_delete](http://apidoc.vidispine.com/4.2/ref/storage/storage.html#delete--storage-\(storage-id\))
177
+
178
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name storage_delete --method-arguments '{"storage_id":"VX-1"}'
179
+
180
+ #### [storage_file_create](http://apidoc.vidispine.com/4.2/ref/storage/file.html)
181
+
182
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name storage_file_create --method-arguments '{"storage_id":"VX-1", "path":"filename.ext", "state":"closed"}'
183
+
184
+ #### [storage_file_get](http://apidoc.vidispine.com/4.2/ref/storage/file.html)
185
+
186
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name storage_file_get --method-arguments '{"storage_id":"VX-1"}'
187
+
188
+ #### [storage_get](http://apidoc.vidispine.com/4.2/ref/storage/storage.html#get--storage-\(storage-id\))
189
+
190
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name storage_get --method-arguments '{"storage_id":"VX-1"}'
191
+
192
+ #### [storage_method_get](http://apidoc.vidispine.com/4.2/ref/storage/storage.html#storage-methods)
193
+
194
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name storage_method_get --method-arguments '{"storage_id":"VX-1"}'
195
+
196
+ #### [storages_get](http://apidoc.vidispine.com/4.2/ref/storage/storage.html#retrieve-list-of-storages)
197
+
198
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name storages_get
199
+
200
+ ### Utility Methods
201
+
202
+ #### collection_file_add_using_path
203
+
204
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_file_add_using_path --method-arguments '{"storage_path_map":{"/Volumes/storages/media1":"VX-1"},"relative_file_path_collection_name_position":0,"metadata_file_path_field_id":"portal_mf48881","file_path":"/Volumes/storages/media1/MyCollectionName/test12_original.mp4"}'
205
+
206
+ #### collection_get_by_name
207
+
208
+ Get First Match
209
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_get_by_name --method-arguments '{"collection_name":"SomeName"}'
210
+
211
+ Get All Matches
212
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name collection_get_by_name --method-arguments '[{"collection_name":"SomeName"},{"return_first_match":false}]'
213
+
214
+ #### item_add_using_file_path
215
+
216
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_add_using_file_path --method-arguments '{"storage_path_map":{"/Volumes/storages/media1":"VX-1"},"file_path":"someDirectory/someFile.mov"}'
217
+
218
+ #### item_add_using_file_path_metadata
219
+
220
+ Find/Create Item
221
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_add_using_file_path_metadata --method-arguments '{"storage_path_map":{"/Volumes/storages/media1":"VX-1"},"metadata_file_path_field_id":"portal_mf48881","file_path":"/Volumes/storages/media1/MyCollectionName/test12_original.mp4"}'
222
+
223
+ Find/Create Item and Add Item to Collection
224
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_add_using_file_path_metadata --method-arguments '{"storage_path_map":{"/Volumes/storages/media1":"VX-1"},"metadata_file_path_field_id":"portal_mf48881","file_path":"/Volumes/storages/media1/MyCollectionName/test12_original.mp4","add_item_to_collection":true,"file_path_collection_name_position":4}'
225
+
226
+ #### item_create_with_proxy_using_storage_file_paths
227
+
228
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_create_with_proxy_using_storage_file_paths --method-arguments '{"storage_id":"VX-1","original_file_path":"test_original.mp4","lowres_file_path":"test_lowres.mp4"}'
229
+
230
+ #### item_annotation_create
231
+
232
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_annotation_create --method-arguments '{"item_id":"VX-1","inpoint":"00:00:00:00","outpoint":"00:00:00:01","title":"SomeTitle"}'
233
+
234
+ #### item_annotation_get
235
+
236
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name item_annotation_get --method-arguments '{"item_id":"VX-1"}'
237
+
238
+ #### storage_file_create_extended
239
+ Uses [Ruby Dir Glob Patterns](http://ruby-doc.org/core-1.8.7/Dir.html#method-c-glob) for the dir argument
240
+
241
+ vidispine --host-address 127.0.0.1 --host-port 8080 --method-name storage_file_create_extended --method-arguments '{"storage_map":{"/srv/media1":"VX-1"}, "dir":"/srv/media1/SomeCollection", "state":"closed"}'
242
+
243
+
244
+ ## Vidispine API Utilities HTTP Server Executable [bin/vidispine-utilities-http-server](../bin/vidispine-utilities-http-server)
245
+
246
+ ### Configuration
247
+ Create a Vidispine HTTP Server options files
248
+ vi /homefolderofuser/.options/vidispine-utilities-http-server
249
+
250
+ ### Usage
251
+
252
+ Usage:
253
+ vidispine-utilities-http-server -h | --help
254
+ vidispine-utilities-http-server [start stop restart status]
255
+
256
+ Options:
257
+ --vidispine-http-host-address HOSTADDRESS
258
+ The address of the server to communicate with.
259
+ default: localhost
260
+ --vidispine-http-host-port HOSTPORT
261
+ The port to use when communicating with the server.
262
+ default: 8080
263
+ --vidispine-username USERNAME
264
+ The account username to authenticate with.
265
+ default: admin
266
+ --vidispine-password PASSWORD
267
+ The account password to authenticate with.
268
+ default: password
269
+ --storage-path-map MAP A path=>storage-id mapping to match incoming file paths to storages.
270
+ --relative-file-path-collection-name-position NUM
271
+ The relative position from the storage base path in which to select the collection name.
272
+ default: 0
273
+ --metadata-file-path-field-id ID
274
+ The Id of the metadata field where the file path is to be stored.
275
+ --port PORT The port to bind to.
276
+ default: 4567
277
+ --log-to FILENAME Log file location.
278
+ default: STDERR
279
+ --log-level LEVEL Logging level. Available Options: info, fatal, error, warn, debug
280
+ default: error
281
+ --[no-]options-file [FILENAME]
282
+ Path to a file which contains default command line arguments.
283
+ default: /homefolderofuser/.options/vidispine-utilities-http-server
284
+ -h, --help Display this message.
285
+
286
+ #### SOME EXAMPLE
287
+
288
+ vidispine-utilities-http-server --storage-path-map '{"/Volumes/storages/media1":"VX-1"}' --metadata-file-path-field-id 'portal_mf48881'
289
+
290
+ ## Contributing
291
+
292
+ 1. Fork it ( https://github.com/XPlatform-Consulting/vidispine.git )
293
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
294
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
295
+ 4. Push to the branch (`git push origin my-new-feature`)
296
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+
data/bin/vidispine ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ lib_path = File.expand_path('../../lib', __FILE__)
3
+ $:.unshift(lib_path) unless $:.include?(lib_path) or !File.exists?(lib_path)
4
+
5
+ require 'rubygems'
6
+ require 'vidispine/api/utilities/cli'
7
+ cli.run
@@ -0,0 +1,339 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'logger'
4
+ require 'optparse'
5
+ require 'pp'
6
+
7
+ ARGV << '--uri'
8
+ ARGV << 'https://o6h5m0r0ih.execute-api.us-east-1.amazonaws.com/latest/vidispine/notification'
9
+ ARGV << '{changeSetId=[VX-460], userName=[admin], itemId=[VX-90], portal_mf201890=[3], sequenceNumber=[0]}'
10
+ puts 'Arguments:'
11
+ pp ARGV
12
+
13
+
14
+ module Vidispine
15
+
16
+ class HTTPClient
17
+
18
+ class HTTPAuthorizationError < RuntimeError; end
19
+
20
+ attr_accessor :logger, :http, :http_host_address, :http_host_port, :base_uri, :default_base_path
21
+ attr_accessor :username, :password
22
+
23
+ attr_accessor :default_request_headers,
24
+ :authorization_header_key, :authorization_header_value
25
+
26
+ attr_accessor :log_request_body, :log_response_body, :log_pretty_print_body
27
+
28
+ attr_accessor :request, :response, :use_exceptions
29
+
30
+ DEFAULT_HTTP_HOST_ADDRESS = 'localhost'
31
+ DEFAULT_HTTP_HOST_PORT = 80
32
+
33
+ DEFAULT_USERNAME = ''
34
+ DEFAULT_PASSWORD = ''
35
+ DEFAULT_BASE_PATH = '/'
36
+
37
+ DEFAULT_HEADER_CONTENT_TYPE = 'application/json; charset=utf-8'
38
+ DEFAULT_HEADER_ACCEPTS = 'application/json'
39
+
40
+ def initialize(args = { })
41
+ args = args.dup
42
+
43
+ @use_exceptions = args.fetch(:use_exceptions, true)
44
+
45
+ initialize_logger(args)
46
+ initialize_http(args)
47
+
48
+ logger.debug { "#{self.class.name}::#{__method__} Arguments: #{args.inspect}" }
49
+
50
+ @username = args[:username] || DEFAULT_USERNAME
51
+ @password = args[:password] || DEFAULT_PASSWORD
52
+ @authorization_header_value = args[:authorization_header_value]
53
+
54
+ @base_uri = "http#{http.use_ssl? ? 's' : ''}://#{http.address}:#{http.port}"
55
+ @default_base_path = args[:default_base_path] || DEFAULT_BASE_PATH
56
+
57
+ content_type = args[:content_type_header] ||= DEFAULT_HEADER_CONTENT_TYPE
58
+ accepts = args[:accepts_header] ||= args[:accept_header] || DEFAULT_HEADER_ACCEPTS
59
+
60
+ @default_request_headers = {
61
+ 'Content-Type' => content_type,
62
+ 'Accept' => accepts,
63
+ }
64
+
65
+ if !username.empty? && !password.empty?
66
+ @authorization_header_key ||= 'Authorization' #CaseSensitiveHeaderKey.new('Authorization')
67
+ @authorization_header_value ||= %(Basic #{["#{username}:#{password}"].pack('m').delete("\r\n")})
68
+ @default_request_headers[authorization_header_key] = authorization_header_value
69
+ end
70
+
71
+ @log_request_body = args.fetch(:log_request_body, true)
72
+ @log_response_body = args.fetch(:log_response_body, true)
73
+ @log_pretty_print_body = args.fetch(:log_pretty_print_body, true)
74
+
75
+ @parse_response = args.fetch(:parse_response, true)
76
+ end
77
+
78
+ def initialize_logger(args = { })
79
+ @logger = args[:logger] ||= Logger.new(args[:log_to] || STDOUT)
80
+ log_level = args[:log_level]
81
+ if log_level
82
+ @logger.level = log_level
83
+ args[:logger] = @logger
84
+ end
85
+ @logger
86
+ end
87
+
88
+ def initialize_http(args = { })
89
+ @http_host_address = args[:http_host_address] ||= DEFAULT_HTTP_HOST_ADDRESS
90
+ @http_host_port = args[:http_host_port] ||= DEFAULT_HTTP_HOST_PORT
91
+ @http = Net::HTTP.new(http_host_address, http_host_port)
92
+
93
+ use_ssl = args[:http_host_use_ssl]
94
+ if use_ssl
95
+ # @TODO Add SSL Support
96
+ http.use_ssl = true
97
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
98
+ end
99
+
100
+ http
101
+ end
102
+
103
+ # Formats a HTTPRequest or HTTPResponse body for log output.
104
+ # @param [HTTPRequest|HTTPResponse] obj
105
+ # @return [String]
106
+ def format_body_for_log_output(obj)
107
+ if obj.content_type == 'application/json'
108
+ if @log_pretty_print_body
109
+ _body = obj.body
110
+ output = JSON.pretty_generate(JSON.parse(_body)) rescue _body
111
+ return output
112
+ else
113
+ return obj.body
114
+ end
115
+ elsif obj.content_type == 'application/xml'
116
+ return obj.body
117
+ else
118
+ return obj.body.inspect
119
+ end
120
+ end
121
+
122
+ # @param [HTTPRequest] request
123
+ def send_request(request)
124
+ @response_parsed = nil
125
+ @request = request
126
+ logger.debug { %(REQUEST: #{request.method} http#{http.use_ssl? ? 's' : ''}://#{http.address}:#{http.port}#{request.path} HEADERS: #{request.to_hash.inspect} #{log_request_body and request.request_body_permitted? ? "\n-- BODY BEGIN --\n#{format_body_for_log_output(request)}\n-- BODY END --" : ''}) }
127
+
128
+ @request_time_start = Time.now
129
+ @response = http.request(request)
130
+ @request_time_end = Time.now
131
+ logger.debug { %(RESPONSE: #{response.inspect} HEADERS: #{response.to_hash.inspect} #{log_response_body and response.respond_to?(:body) ? "\n-- BODY BEGIN --\n#{format_body_for_log_output(response)}\n-- BODY END--" : ''}\nTook: #{@request_time_end - @request_time_start} seconds) }
132
+ #logger.debug { "Parse Response? #{@parse_response}" }
133
+
134
+ raise HTTPAuthorizationError if @use_exceptions && @response.code == '401'
135
+
136
+ @parse_response ? response_parsed : response.body
137
+ end
138
+
139
+ def response_parsed
140
+ @response_parsed ||= begin
141
+ response_body = response.respond_to?(:body) ? response.body : ''
142
+ logger.debug { "Parsing Response. #{response_body.inspect}" }
143
+
144
+ case response.content_type
145
+ when 'application/json'
146
+ response_body.empty? ? response_body : JSON.parse(response_body) # rescue response
147
+ else
148
+ response_body
149
+ end
150
+ end
151
+ end
152
+
153
+ # @param [String] path
154
+ # @param [Hash|String|Nil] query
155
+ # @return [URI]
156
+ def build_uri(path = '', query = nil)
157
+ _query = query.is_a?(Hash) ? query.map { |k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.respond_to?(:to_s) ? v.to_s : v)}" }.join('&') : query
158
+ _path = "#{path}#{_query and _query.respond_to?(:empty?) and !_query.empty? ? "?#{_query}" : ''}"
159
+ URI.parse(File.join(base_uri, _path))
160
+ end
161
+
162
+ if RUBY_VERSION.start_with? '1.8.'
163
+ def request_method_name_to_class_name(method_name)
164
+ method_name.to_s.capitalize
165
+ end
166
+ else
167
+ def request_method_name_to_class_name(method_name)
168
+ method_name.to_s.capitalize.to_sym
169
+ end
170
+ end
171
+
172
+ # @param [Symbol] method_name (:get)
173
+ # @param [Hash] args
174
+ # @option args [Hash] :headers ({})
175
+ # @option args [String] :path ('')
176
+ # @option args [Hash] :query ({})
177
+ # @option args [Any] :body (nil)
178
+ # @param [Hash] options
179
+ # @option options [Hash] :default_request_headers (@default_request_headers)
180
+ def call_method(method_name = :get, args = { }, options = { })
181
+ headers = args[:headers] || options[:headers] || { }
182
+ path = args[:path] || ''
183
+ query = args[:query] || { }
184
+ body = args[:body]
185
+
186
+ # Allow the default request headers to be overridden
187
+ _default_request_headers = options.fetch(:default_request_headers, default_request_headers)
188
+ _default_request_headers ||= { }
189
+ _headers = _default_request_headers.merge(headers)
190
+
191
+ @uri = build_uri(path, query)
192
+ klass_name = request_method_name_to_class_name(method_name)
193
+ klass = Net::HTTP.const_get(klass_name)
194
+
195
+ request = klass.new(@uri.request_uri, _headers)
196
+
197
+ if request.request_body_permitted?
198
+ _body = (body and !body.is_a?(String)) ? JSON.generate(body) : body
199
+ logger.debug { "Processing Body: '#{_body}'" }
200
+ request.body = _body if _body
201
+ end
202
+
203
+ send_request(request)
204
+ end
205
+
206
+ def delete(path, options = { })
207
+ call_method(:delete, { :path => path }, options)
208
+ end
209
+
210
+ def get(path, options = { })
211
+ call_method(:get, { :path => path }, options)
212
+ end
213
+
214
+ def head(path, options = { })
215
+ call_method(:head, { :path => path }, options)
216
+ end
217
+
218
+ def options(path, options = { })
219
+ call_method(:options, { :path => path }, options)
220
+ end
221
+
222
+ def put(path, body, options = { })
223
+ call_method(:put, { :path => path, :body => body }, options)
224
+ end
225
+
226
+ def post(path, body, options = { })
227
+ call_method(:post, { :path => path, :body => body }, options)
228
+ end
229
+
230
+ # HTTPClient
231
+ end
232
+
233
+ class NotificationHandler
234
+
235
+ attr_accessor :logger
236
+
237
+ def initialize(args = { })
238
+ initialize_logger(args)
239
+ initialize_http(args)
240
+ end
241
+
242
+ def initialize_logger(args = { })
243
+ @logger = args[:logger] ||= begin
244
+ _logger = Logger.new(args[:log_to] || STDERR)
245
+ _logger.level = args[:log_level] || Logger::DEBUG
246
+ _logger
247
+ end
248
+ end
249
+
250
+ def initialize_http(args = { })
251
+ uri_as_str = args[:uri]
252
+
253
+ uri = URI(uri_as_str)
254
+
255
+ args[:http_host_address] = uri.host
256
+ args[:http_host_port] = uri.port
257
+ args[:http_host_use_ssl] = uri.scheme == 'https'
258
+ args[:username] = uri.user
259
+ args[:password] = uri.password
260
+ args[:default_base_path] = uri.request_uri
261
+
262
+ @http_client = HTTPClient.new(args)
263
+ end
264
+
265
+ def forward_notification(notification)
266
+ @http_client.call_method(:post, :body => notification)
267
+ end
268
+
269
+ end
270
+
271
+ end
272
+
273
+ LOGGING_LEVELS = {
274
+ :debug => Logger::DEBUG,
275
+ :info => Logger::INFO,
276
+ :warn => Logger::WARN,
277
+ :error => Logger::ERROR,
278
+ :fatal => Logger::FATAL
279
+ }
280
+
281
+ DEFAULT_HEADER_CONTENT_TYPE = 'application/json; charset=utf-8'
282
+
283
+ def log_to_as_string
284
+ _log_to = arguments[:log_to]
285
+ case _log_to
286
+ when STDERR; 'STDERR'
287
+ when STDOUT; 'STDOUT'
288
+ else _log_to
289
+ end
290
+ end
291
+
292
+
293
+ default_arguments = {
294
+ :log_to => "/tmp/#{File.basename($0)}.log",
295
+ :log_level => Logger::DEBUG,
296
+ :options_file_path => File.expand_path(File.basename($0, '.*'), '~/.options'),
297
+ :http_method => :post
298
+ }
299
+ @arguments = default_arguments.dup
300
+ def arguments; @arguments end
301
+
302
+ argument_parser = OptionParser.new
303
+ argument_parser.on('--uri URI', 'The address of the server to communicate with.') { |v| arguments[:uri] = v }
304
+
305
+ argument_parser.on('--content-type VALUE', 'The value for the Content-Type header sent in each request.', "\tdefault: #{DEFAULT_HEADER_CONTENT_TYPE}") { |v| arguments[:content_type] = v }
306
+ argument_parser.on('--method METHOD', 'The HTTP method to use when submitting the notification.', "\tdefault: #{arguments[:http_method]}") { |v| arguments[:http_method] = v.to_sym }
307
+ argument_parser.on('--pretty-print', 'Will format the output to be more human readable.') { |v| arguments[:pretty_print] = v }
308
+
309
+ argument_parser.on('--log-to FILENAME', 'Log file location.', "\tdefault: #{log_to_as_string}") { |v| arguments[:log_to] = v }
310
+ argument_parser.on('--log-level LEVEL', LOGGING_LEVELS.keys, "Logging level. Available Options: #{LOGGING_LEVELS.keys.join(', ')}",
311
+ "\tdefault: #{LOGGING_LEVELS.invert[arguments[:log_level]]}") { |v| arguments[:log_level] = LOGGING_LEVELS[v] }
312
+
313
+ argument_parser.on('--[no-]options-file [FILENAME]', 'Path to a file which contains default command line arguments.', "\tdefault: #{arguments[:options_file_path]}" ) { |v| arguments[:options_file_path] = v}
314
+ argument_parser.on_tail('-h', '--help', 'Display this message.') { puts help; exit }
315
+
316
+ arguments.clear
317
+ original_argv_args = ARGV.dup
318
+ argument_parser.parse!(ARGV)
319
+ remaining_argv_args = ARGV.dup
320
+ arguments_from_command_line = arguments.dup
321
+
322
+ options_file_path = arguments_from_command_line[:options_file_path] || default_arguments[:options_file_path]
323
+
324
+ arguments.clear
325
+ argument_parser.load(options_file_path)
326
+ arguments_from_options_file = arguments.dup
327
+
328
+ arguments = default_arguments.merge(arguments_from_options_file).merge(arguments_from_command_line)
329
+
330
+ pp arguments
331
+ # @handler = Vidispine::NotificationHandler.new(arguments)
332
+ # def logger; @handler.logger end
333
+ # logger.debug { "ARGUMENTS: #{remaining_argv_args.inspect}" }
334
+
335
+
336
+
337
+ # @handler.forward_notification(remaining_argv_args)
338
+
339
+