helix 0.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +24 -0
- data/README.md +169 -0
- data/lib/helix/album.rb +27 -0
- data/lib/helix/base.rb +185 -0
- data/lib/helix/config.rb +150 -0
- data/lib/helix/image.rb +19 -0
- data/lib/helix/statistics.rb +145 -0
- data/lib/helix/track.rb +17 -0
- data/lib/helix/video.rb +19 -0
- data/lib/helix.rb +9 -0
- data/spec/album_spec.rb +27 -0
- data/spec/base_spec.rb +325 -0
- data/spec/config_spec.rb +419 -0
- data/spec/image_spec.rb +21 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/statistics_spec.rb +158 -0
- data/spec/track_spec.rb +21 -0
- data/spec/video_spec.rb +21 -0
- metadata +104 -0
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2012, Twistage
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of Twistage nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL Twistage BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
http://nestacms.com/docs/creating-content/markdown-cheat-sheet
|
2
|
+
http://support.mashery.com/docs/customizing_your_portal/Markdown_Cheat_Sheet
|
3
|
+
|
4
|
+
# Helix
|
5
|
+
|
6
|
+
The Helix gem allows developers to easily connect to and manipulate the Twistage API.
|
7
|
+
|
8
|
+
Documentation
|
9
|
+
-------------
|
10
|
+
|
11
|
+
You should find the documentation for your version of helix on [Rubygems](https://rubygems.org/gems/helix).
|
12
|
+
|
13
|
+
Install
|
14
|
+
--------
|
15
|
+
|
16
|
+
```shell
|
17
|
+
gem install helix
|
18
|
+
```
|
19
|
+
or add the following line to Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'helix'
|
23
|
+
```
|
24
|
+
and run `bundle install` from your shell.
|
25
|
+
|
26
|
+
Install From Repo
|
27
|
+
-----------------
|
28
|
+
Using sudo:
|
29
|
+
```shell
|
30
|
+
git clone git@github.com:Twistage/helix.git
|
31
|
+
gem build helix.gemspec
|
32
|
+
sudo gem i helix-*.gem
|
33
|
+
```
|
34
|
+
|
35
|
+
RVM or root support:
|
36
|
+
```shell
|
37
|
+
git clone git@github.com:Twistage/helix.git
|
38
|
+
gem build helix.gemspec
|
39
|
+
gem i helix-*.gem
|
40
|
+
```
|
41
|
+
|
42
|
+
Rebuilding the gem, use the first for sudo, the second for RVM or root:
|
43
|
+
```shell
|
44
|
+
rake reinstall_helix
|
45
|
+
rake reinstall_helix_rvm
|
46
|
+
```
|
47
|
+
|
48
|
+
Using gem in a Gemfile
|
49
|
+
```shell
|
50
|
+
gem 'helix', :git => git@github.com:Twistage/helix.git
|
51
|
+
```
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
Supported Ruby versions
|
56
|
+
-----------------------
|
57
|
+
|
58
|
+
1.9.3
|
59
|
+
1.9.2
|
60
|
+
|
61
|
+
How To
|
62
|
+
------
|
63
|
+
|
64
|
+
###Setup YAML
|
65
|
+
```yaml
|
66
|
+
site: 'http://service.twistage.com'
|
67
|
+
user: 'my_account@twistage.com'
|
68
|
+
password: 'password123'
|
69
|
+
company: 'my_company'
|
70
|
+
license_key: '141a86b5c4091
|
71
|
+
```
|
72
|
+
Load the YAML file as your config.
|
73
|
+
```ruby
|
74
|
+
Helix::Config.load("path/to/yaml.yml")
|
75
|
+
```
|
76
|
+
####Current CRUD methods supported by all models
|
77
|
+
.create
|
78
|
+
.find
|
79
|
+
\#update
|
80
|
+
\#destroy
|
81
|
+
|
82
|
+
####Current models
|
83
|
+
Videos, Images, Albums, Tracks, Playlists
|
84
|
+
|
85
|
+
###Videos
|
86
|
+
#####Required fields: title, description, library, company, and source.
|
87
|
+
```ruby
|
88
|
+
video = Helix::Video.create!( title: 'New Video',
|
89
|
+
description: 'A video of new things',
|
90
|
+
source: 'http://somesource.com/source.mp4'
|
91
|
+
company: 'some_company',
|
92
|
+
library: 'some_library')
|
93
|
+
video.update({title: "New Title"})
|
94
|
+
another_video = Helix::Video.find(some_guid)
|
95
|
+
another_video.destroy
|
96
|
+
```
|
97
|
+
###Albums
|
98
|
+
#####Required fields: title, library, company.
|
99
|
+
```ruby
|
100
|
+
album = Helix::Album.create!( title: 'New Album',
|
101
|
+
description: 'A album of new things',
|
102
|
+
source: 'http://somesource.com/source.mp4'
|
103
|
+
company: 'some_company',
|
104
|
+
library: 'some_library')
|
105
|
+
#Update for album is not currently supported
|
106
|
+
another_album = Helix::Album.find(some_guid)
|
107
|
+
another_album.destroy
|
108
|
+
```
|
109
|
+
###Images
|
110
|
+
#####Required fields: title, description, library, company, and source.
|
111
|
+
```ruby
|
112
|
+
image = Helix::Image.create!( title: 'New Image',
|
113
|
+
description: 'A image of new things',
|
114
|
+
source: 'http://somesource.com/source.jpg'
|
115
|
+
company: 'some_company',
|
116
|
+
library: 'some_library')
|
117
|
+
image.update({title: "New Title"})
|
118
|
+
another_image = Helix::Image.find(some_guid)
|
119
|
+
another_image.destroy
|
120
|
+
```
|
121
|
+
###Tracks
|
122
|
+
#####Required fields: title, description, library, company, and source.
|
123
|
+
```ruby
|
124
|
+
track = Helix::Track.create!( title: 'New Track',
|
125
|
+
description: 'A track of new things',
|
126
|
+
source: 'http://somesource.com/source.mp3'
|
127
|
+
company: 'some_company',
|
128
|
+
library: 'some_library')
|
129
|
+
track.update({title: "New Title"})
|
130
|
+
another_track = Helix::Track.find(some_guid)
|
131
|
+
another_track.destroy
|
132
|
+
```
|
133
|
+
###Playlists
|
134
|
+
#####Required fields: title, library, company.
|
135
|
+
```ruby
|
136
|
+
playlist = Helix::Playlist.create!( title: 'New Playlist',
|
137
|
+
description: 'A playlist of new things',
|
138
|
+
source: 'http://somesource.com/source.mp4'
|
139
|
+
company: 'some_company',
|
140
|
+
library: 'some_library')
|
141
|
+
playlist.update({title: "New Title"})
|
142
|
+
another_playlist = Helix::Playlist.find(some_guid)
|
143
|
+
another_playlist.destroy
|
144
|
+
```
|
145
|
+
|
146
|
+
More Information
|
147
|
+
----------------
|
148
|
+
|
149
|
+
* [Rubygems](https://rubygems.org/gems/helix)
|
150
|
+
* [Issues](https://github.com/twistage/helix/issues)
|
151
|
+
|
152
|
+
Contributing
|
153
|
+
------------
|
154
|
+
|
155
|
+
How to contribute
|
156
|
+
|
157
|
+
Credits
|
158
|
+
-------
|
159
|
+
|
160
|
+
Helix was written by Kevin Baird and Michael Wood.
|
161
|
+
|
162
|
+
Helix is maintained and funded by [Twistage, inc](http://twistage.com)
|
163
|
+
|
164
|
+
The names and logos for twistage are trademarks of twistage, inc.
|
165
|
+
|
166
|
+
License
|
167
|
+
-------
|
168
|
+
|
169
|
+
Helix is Copyright © 2008-2012 Twistage, inc.
|
data/lib/helix/album.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'helix/base'
|
2
|
+
|
3
|
+
module Helix
|
4
|
+
|
5
|
+
class Album < Base
|
6
|
+
|
7
|
+
# The class name, to be used by supporting classes. Such as Config which uses
|
8
|
+
# this method as a way to build URLs.
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# Helix::Album.media_type_sym #=> :album
|
13
|
+
#
|
14
|
+
# @return [Symbol] Name of the class.
|
15
|
+
def self.media_type_sym; :album; end
|
16
|
+
|
17
|
+
# Currently update is unsupported for album.
|
18
|
+
#
|
19
|
+
# @param [Hash] opts an array can be passed in so it remains functionally similiar to other update calls.
|
20
|
+
# @return [Exception] "Albums Update is not currently supported."
|
21
|
+
def update(opts={})
|
22
|
+
raise "Albums Update is not currently supported."
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/lib/helix/base.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'json'
|
3
|
+
require 'yaml'
|
4
|
+
require 'crack'
|
5
|
+
|
6
|
+
module Helix
|
7
|
+
class Base
|
8
|
+
|
9
|
+
unless defined?(self::METHODS_DELEGATED_TO_CLASS)
|
10
|
+
METHODS_DELEGATED_TO_CLASS = [ :guid_name, :media_type_sym, :plural_media_type ]
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :attributes, :config
|
14
|
+
|
15
|
+
# Creates a new record via API and then returns an instance of that record.
|
16
|
+
#
|
17
|
+
# Example is using Video class since Video inherits from Base. This won't
|
18
|
+
# normally be called as Helix::Base.create
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# Helix::Video.create({title: "My new video"})
|
22
|
+
#
|
23
|
+
# @param [Hash] attributes a hash containing the attributes used in the create
|
24
|
+
# @return [Base] An instance of Helix::Base
|
25
|
+
def self.create(attributes={})
|
26
|
+
config = Helix::Config.instance
|
27
|
+
#xml = '<?xml version="1.0" encoding="UTF-8"?>
|
28
|
+
# <add>
|
29
|
+
# <list>
|
30
|
+
# <entry>
|
31
|
+
# <src>http://www.minhreigen.com/videos/play.mp4</src>
|
32
|
+
# <title>Summer camp dance</title>
|
33
|
+
# <description>This one is the best</description>
|
34
|
+
# </entry>
|
35
|
+
# </list>
|
36
|
+
# </add>'.gsub!(/\s{2,}|\n/, "")
|
37
|
+
url = config.build_url(media_type: plural_media_type,
|
38
|
+
format: :xml)
|
39
|
+
response = RestClient.post(url, attributes.merge(signature: config.signature(:update)))
|
40
|
+
attrs = Crack::XML.parse(response)
|
41
|
+
self.new(attributes: attrs[media_type_sym.to_s], config: config)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Finds and returns a record in instance form for a class, through
|
45
|
+
# guid lookup.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# video_guid = "8e0701c142ab1"
|
49
|
+
# video = Helix::Video.find(video_guid)
|
50
|
+
#
|
51
|
+
# @param [String] guid an id in guid form.
|
52
|
+
# @return [Base] An instance of Helix::Base
|
53
|
+
def self.find(guid)
|
54
|
+
config = Helix::Config.instance
|
55
|
+
item = self.new(attributes: { guid_name => guid }, config: config)
|
56
|
+
item.load
|
57
|
+
end
|
58
|
+
|
59
|
+
# Fetches all accessible records, places them into instances, and returns
|
60
|
+
# them as an array.
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# Helix::Video.find_all(query: 'string_to_match') #=> [video1,video2]
|
64
|
+
#
|
65
|
+
# @param [Hash] opts a hash of options for parameters passed into the HTTP GET
|
66
|
+
# @return [Array] The array of instance objects for a class.
|
67
|
+
def self.find_all(opts)
|
68
|
+
data_sets = get_data_sets(opts)
|
69
|
+
return [] if data_sets.nil?
|
70
|
+
data_sets.map { |attrs| self.new(attributes: attrs) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.get_data_sets(opts)
|
74
|
+
config = Helix::Config.instance
|
75
|
+
url = config.build_url(format: :json)
|
76
|
+
# We allow opts[:sig_type] for internal negative testing only.
|
77
|
+
raw_response = config.get_response(url, {sig_type: :view}.merge(opts))
|
78
|
+
data_sets = raw_response[plural_media_type]
|
79
|
+
end
|
80
|
+
|
81
|
+
# Creates a string that associates to the class id.
|
82
|
+
#
|
83
|
+
# @example
|
84
|
+
# Helix::Video.guid_name #=> "video_id"
|
85
|
+
#
|
86
|
+
# @return [String] The guid name for a specific class.
|
87
|
+
def self.guid_name
|
88
|
+
"#{self.media_type_sym}_id"
|
89
|
+
end
|
90
|
+
|
91
|
+
# Creates a string associated with a class name pluralized
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# Helix::Video.plural_media_type #=> "videos"
|
95
|
+
#
|
96
|
+
# @return [String] The class name pluralized
|
97
|
+
def self.plural_media_type
|
98
|
+
"#{self.media_type_sym}s"
|
99
|
+
end
|
100
|
+
|
101
|
+
METHODS_DELEGATED_TO_CLASS.each do |meth|
|
102
|
+
define_method(meth) { |*args| self.class.send(meth, *args) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def initialize(opts)
|
106
|
+
@attributes = opts[:attributes]
|
107
|
+
@config = opts[:config]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Deletes the record of the Helix::Base instance.
|
111
|
+
#
|
112
|
+
# @example
|
113
|
+
# video = Helix::Video.create({title: "Some Title"})
|
114
|
+
# video.destroy
|
115
|
+
#
|
116
|
+
# @return [String] The response from the HTTP DELETE call.
|
117
|
+
def destroy
|
118
|
+
memo_cfg = config
|
119
|
+
url = memo_cfg.build_url(format: :xml, guid: guid, media_type: plural_media_type)
|
120
|
+
RestClient.delete(url, params: {signature: memo_cfg.signature(:update)})
|
121
|
+
end
|
122
|
+
|
123
|
+
# Creates a string that associates to the class id.
|
124
|
+
#
|
125
|
+
# @example
|
126
|
+
# video = Helix::Video.create({title: "My new title"})
|
127
|
+
# video.guid #=> "9e0989v234sf4"
|
128
|
+
#
|
129
|
+
# @return [String] The guid for the class instance.
|
130
|
+
def guid
|
131
|
+
@attributes[guid_name]
|
132
|
+
end
|
133
|
+
|
134
|
+
# Loads in the record from a HTTP GET response.
|
135
|
+
#
|
136
|
+
# @param [Hash] opts a hash of attributes to update the instance with.
|
137
|
+
# @return [Base] Returns an instance of the class.
|
138
|
+
def load(opts={})
|
139
|
+
memo_cfg = config
|
140
|
+
url = memo_cfg.build_url(format: :json, guid: self.guid, media_type: plural_media_type)
|
141
|
+
# We allow opts[:sig_type] for internal negative testing only.
|
142
|
+
raw_attrs = memo_cfg.get_response(url, {sig_type: :view}.merge(opts))
|
143
|
+
@attributes = massage_raw_attrs(raw_attrs)
|
144
|
+
self
|
145
|
+
end
|
146
|
+
alias_method :reload, :load
|
147
|
+
|
148
|
+
# Raises an error for missing method calls.
|
149
|
+
#
|
150
|
+
# @param [Symbol] method_sym The method attempting to be called.
|
151
|
+
# @return [String] An error for the method attempting to be called.
|
152
|
+
def method_missing(method_sym)
|
153
|
+
begin
|
154
|
+
@attributes[method_sym.to_s]
|
155
|
+
rescue
|
156
|
+
raise NoMethodError, "#{method_sym} is not recognized within #{self.class.to_s}'s @attributes"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Updates instance and record with attributes passed in.
|
161
|
+
#
|
162
|
+
# @example
|
163
|
+
# video = Helix::Video.find(video_guid)
|
164
|
+
# video.update({title: "My new title"})
|
165
|
+
#
|
166
|
+
# @param [Hash] opts a hash of attributes to update the instance with.
|
167
|
+
# @return [Base] Returns an instance of the class after update.
|
168
|
+
def update(opts={})
|
169
|
+
memo_cfg = config
|
170
|
+
url = memo_cfg.build_url(format: :xml, guid: guid, media_type: plural_media_type)
|
171
|
+
params = {signature: memo_cfg.signature(:update)}.merge(media_type_sym => opts)
|
172
|
+
RestClient.put(url, params)
|
173
|
+
self
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def massage_raw_attrs(raw_attrs)
|
179
|
+
# FIXME: Albums JSON output is embedded as the only member of an Array.
|
180
|
+
proper_hash = raw_attrs.respond_to?(:has_key?) && raw_attrs.has_key?(guid_name)
|
181
|
+
proper_hash ? raw_attrs : raw_attrs.first
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
end
|
data/lib/helix/config.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'helix/video'
|
2
|
+
require 'helix/track'
|
3
|
+
require 'helix/album'
|
4
|
+
require 'helix/image'
|
5
|
+
require 'singleton'
|
6
|
+
|
7
|
+
module Helix
|
8
|
+
|
9
|
+
class Config
|
10
|
+
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
unless defined?(self::DEFAULT_FILENAME)
|
14
|
+
DEFAULT_FILENAME = './helix.yml'
|
15
|
+
SCOPES = %w(reseller company library)
|
16
|
+
SIG_DURATION = 1200 # in minutes
|
17
|
+
TIME_OFFSET = 1000 * 60 # 1000 minutes, lower to give some margin of error
|
18
|
+
VALID_SIG_TYPES = [ :ingest, :update, :view ]
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :credentials
|
22
|
+
|
23
|
+
# Creates a singleton of itself, setting the config
|
24
|
+
# to a specified YAML file. If no file is specified the default
|
25
|
+
# helix.yml file is used.
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# Helix::Config.load("/some/path/my_yaml.yml")
|
29
|
+
# video = Helix::Video.find("8e0701c142ab1") #Uses my_yaml.yml
|
30
|
+
#
|
31
|
+
# @param [String] yaml_file_location the yaml file used for config
|
32
|
+
# @return [Helix::Config] config returns singleton of Helix::Config
|
33
|
+
def self.load(yaml_file_location = DEFAULT_FILENAME)
|
34
|
+
config = self.instance
|
35
|
+
config.instance_variable_set(:@filename, yaml_file_location)
|
36
|
+
config.instance_variable_set(:@credentials, YAML.load(File.open(yaml_file_location)))
|
37
|
+
config
|
38
|
+
end
|
39
|
+
|
40
|
+
# Creates additional URL stubbing that can be used in conjuction
|
41
|
+
# with the base_url to create RESTful URLs
|
42
|
+
#
|
43
|
+
# @param [String] base_url the base part of the URL to be used
|
44
|
+
# @param [Hash] opts a hash of options for building URL additions
|
45
|
+
# @return [String] The full RESTful URL string object
|
46
|
+
def add_sub_urls(base_url, opts)
|
47
|
+
guid, action = [:guid, :action].map { |sub| opts[sub] }
|
48
|
+
url = "#{base_url}/#{opts[:media_type]}"
|
49
|
+
url += "/#{guid}" if guid
|
50
|
+
url += "/#{action}" if action
|
51
|
+
"#{url}.#{opts[:format]}"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Creates a full RESTful URL to be used for HTTP requests.
|
55
|
+
#
|
56
|
+
# @param [Hash] opts a hash of options for building URL
|
57
|
+
# @return [String] The full RESTful URL string object
|
58
|
+
def build_url(opts={})
|
59
|
+
opts[:format] ||= :json
|
60
|
+
opts[:media_type] ||= :videos
|
61
|
+
base_url = get_base_url(opts)
|
62
|
+
url = add_sub_urls(base_url, opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Creates the base url with information collected from credentials.
|
66
|
+
#
|
67
|
+
# @param [Hash] opts a hash of options for building URL
|
68
|
+
# @return [String] The base RESTful URL string object
|
69
|
+
def get_base_url(opts)
|
70
|
+
creds = credentials
|
71
|
+
base_url = creds['site']
|
72
|
+
reseller, company, library = SCOPES.map { |scope| creds[scope] }
|
73
|
+
base_url += "/resellers/#{reseller}" if reseller
|
74
|
+
if company
|
75
|
+
base_url += "/companies/#{company}"
|
76
|
+
base_url += "/libraries/#{library}" if library
|
77
|
+
end
|
78
|
+
base_url
|
79
|
+
end
|
80
|
+
|
81
|
+
# Creates additional URL stubbing that can be used in conjuction
|
82
|
+
# with the base_url to create RESTful URLs
|
83
|
+
#
|
84
|
+
# @param [String] url the base part of the URL to be used
|
85
|
+
# @param [Hash] opts a hash of options for building URL additions
|
86
|
+
# @return [String] The full RESTful URL string object
|
87
|
+
def get_response(url, opts={})
|
88
|
+
sig_type = opts.delete(:sig_type)
|
89
|
+
params = opts.merge(signature: signature(sig_type, opts))
|
90
|
+
response = RestClient.get(url, params: params)
|
91
|
+
JSON.parse(response)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Fetches the signature for a specific license key.
|
95
|
+
#
|
96
|
+
# @param [Symbol] sig_type The type of signature required for calls.
|
97
|
+
# @return [String] The signature needed to pass around for calls.
|
98
|
+
def signature(sig_type, opts={})
|
99
|
+
prepare_signature_memoization
|
100
|
+
memo_sig = existing_sig_for(sig_type)
|
101
|
+
return memo_sig if memo_sig
|
102
|
+
unless VALID_SIG_TYPES.include?(sig_type)
|
103
|
+
raise ArgumentError, error_message_for(sig_type)
|
104
|
+
end
|
105
|
+
|
106
|
+
lk = license_key
|
107
|
+
@signature_expiration_for[lk][sig_type] = Time.now + TIME_OFFSET
|
108
|
+
@signature_for[lk][sig_type] = RestClient.get(url_for(sig_type, opts))
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def error_message_for(sig_type)
|
114
|
+
"I don't understand '#{sig_type}'. Please give me one of :ingest, :update, or :view."
|
115
|
+
end
|
116
|
+
|
117
|
+
def existing_sig_for(sig_type)
|
118
|
+
return if sig_expired_for?(sig_type)
|
119
|
+
@signature_for[license_key][sig_type]
|
120
|
+
end
|
121
|
+
|
122
|
+
def license_key
|
123
|
+
@credentials['license_key']
|
124
|
+
end
|
125
|
+
|
126
|
+
def prepare_signature_memoization
|
127
|
+
lk = license_key
|
128
|
+
@signature_for ||= {}
|
129
|
+
@signature_expiration_for ||= {}
|
130
|
+
@signature_for[lk] ||= {}
|
131
|
+
@signature_expiration_for[lk] ||= {}
|
132
|
+
end
|
133
|
+
|
134
|
+
def sig_expired_for?(sig_type)
|
135
|
+
expires_at = @signature_expiration_for[license_key][sig_type]
|
136
|
+
return true if expires_at.nil?
|
137
|
+
expires_at <= Time.now
|
138
|
+
end
|
139
|
+
|
140
|
+
def url_for(sig_type, opts={})
|
141
|
+
contributor, library_id = [:contributor, :library_id].map { |key| opts[key] }
|
142
|
+
url = "#{credentials['site']}/api/#{sig_type}_key?licenseKey=#{credentials['license_key']}&duration=#{SIG_DURATION}"
|
143
|
+
url += "&contributor=#{contributor}" if contributor
|
144
|
+
url += "&library_id=#{library_id}" if library_id
|
145
|
+
url
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
data/lib/helix/image.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'helix/base'
|
2
|
+
|
3
|
+
module Helix
|
4
|
+
|
5
|
+
class Image < Base
|
6
|
+
|
7
|
+
# The class name, to be used by supporting classes. Such as Config which uses
|
8
|
+
# this method as a way to build URLs.
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# Helix::Image.media_type_sym #=> :image
|
13
|
+
#
|
14
|
+
# @return [Symbol] Name of the class.
|
15
|
+
def self.media_type_sym; :image; end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|