vidispine 1.4.0

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.
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
+