nolij_web 1.0.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.
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +50 -0
- data/Rakefile +9 -0
- data/lib/nolij_web/attribute_missing_error.rb +4 -0
- data/lib/nolij_web/authentication_error.rb +4 -0
- data/lib/nolij_web/connection.rb +179 -0
- data/lib/nolij_web/connection_configuration_error.rb +4 -0
- data/lib/nolij_web/handler.rb +208 -0
- data/lib/nolij_web/version.rb +5 -0
- data/lib/nolij_web.rb +13 -0
- data/nolij_web.gemspec +33 -0
- data/test/nolij_web/attribute_missing_error_test.rb +7 -0
- data/test/nolij_web/authentication_error_test.rb +7 -0
- data/test/nolij_web/connection_configuration_error_test.rb +7 -0
- data/test/nolij_web/connection_test.rb +404 -0
- data/test/nolij_web/handler_test.rb +210 -0
- data/test/nolij_web/test_stubs/bad_nolij_config.yml +3 -0
- data/test/nolij_web/test_stubs/document_submitted_success.xml +3 -0
- data/test/nolij_web/test_stubs/folder_info.xml +27 -0
- data/test/nolij_web/test_stubs/nolij_config.yml +3 -0
- data/test/nolij_web/test_stubs/text_file.txt +1 -0
- data/test/nolij_web/test_stubs/version_info.xml +2 -0
- data/test/nolij_web/version_test.rb +7 -0
- data/test/test_helper.rb +11 -0
- metadata +187 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Shannon Henderson
|
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.rdoc
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
= NolijWeb
|
2
|
+
|
3
|
+
Talk to the Nolij Web API. The first version of this gem contains a small subset of available API methods. Document submission/printing(retrieval) are the main focus. Methods for folder listings, work flow request, and generated urls for the viewer are provided.
|
4
|
+
|
5
|
+
The raw connection can be used to execute other types of requests.
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'nolij_web'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install nolij_web
|
20
|
+
|
21
|
+
== Basic Usage
|
22
|
+
|
23
|
+
You should be able to use the handler for basic requests.
|
24
|
+
require 'nolij_web'
|
25
|
+
|
26
|
+
handler = NolijWeb::Handler.new(config_hash_or_path_to_config_yaml)
|
27
|
+
|
28
|
+
handler.folder_info({:folder_id => 1111111})
|
29
|
+
|
30
|
+
Configuration can be passed as an assigned hash or read from a YAML file.
|
31
|
+
config = {
|
32
|
+
:username => 'username',
|
33
|
+
:password => 'password',
|
34
|
+
:base_url => 'https://somedomain.com/NolijWeb'
|
35
|
+
}
|
36
|
+
|
37
|
+
== Passing a block to NolijWeb::Handler methods
|
38
|
+
You may pass a custom block to handler methods. Please note that your block should return the response for successful request. Some of the methods rely on parsing XML responses from the server.
|
39
|
+
|
40
|
+
== Using the Connection Directly
|
41
|
+
|
42
|
+
You can use the handler's connection directly. See NolijWeb::Connection for info.
|
43
|
+
|
44
|
+
== Contributing
|
45
|
+
|
46
|
+
1. Fork it
|
47
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
48
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
49
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
50
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
|
2
|
+
require 'rest_client'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module NolijWeb
|
6
|
+
=begin rdoc
|
7
|
+
Nolijweb::Connection is the class that handles actual Nolijweb api sessions and requests.
|
8
|
+
|
9
|
+
===Basic Usage
|
10
|
+
|
11
|
+
#get, #post, #delete will automatically wrap your request in open and close connection. Arguments are passed through to RestClient, so see RestClient docs for more options.
|
12
|
+
|
13
|
+
conn = NolijWeb::Connection.new(config_hash_or_yaml_path)
|
14
|
+
conn.get('/print', :query_params => { :document_id => 1})
|
15
|
+
|
16
|
+
===Manual Usage
|
17
|
+
You can manually establish a connection and use the _custom_connection methods to execute multiple requests in series.
|
18
|
+
|
19
|
+
Be sure the close the connection when you are finished.
|
20
|
+
|
21
|
+
conn = NolijWeb::Connection.new(config_hash_or_yaml_path)
|
22
|
+
conn.establish_connection
|
23
|
+
# do some stuff using get, post, etc. (_custom_connection methods)
|
24
|
+
close_connection
|
25
|
+
=end
|
26
|
+
class Connection
|
27
|
+
attr_reader :base_url
|
28
|
+
attr_reader :username
|
29
|
+
attr_reader :cookies
|
30
|
+
attr_reader :connection
|
31
|
+
|
32
|
+
@@valid_config_keys = [:username, :password, :base_url]
|
33
|
+
|
34
|
+
def initialize(config)
|
35
|
+
if config.is_a?(String)
|
36
|
+
configure_with(config)
|
37
|
+
elsif config.is_a?(Hash)
|
38
|
+
configure(config)
|
39
|
+
else
|
40
|
+
raise ConnectionConfigurationError, 'Invalid configuration options supplied.'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Configure using hash
|
45
|
+
def configure(opts = {})
|
46
|
+
@config = clean_config_hash(opts)
|
47
|
+
|
48
|
+
raise ConnectionConfigurationError, 'Nolij Web Connection configuration failed.' unless @config
|
49
|
+
|
50
|
+
@base_url = @config[:base_url] || ''
|
51
|
+
@username = @config[:username] || ''
|
52
|
+
@password = @config[:password] || ''
|
53
|
+
@connection = nil
|
54
|
+
@cookies = nil
|
55
|
+
@headers = {}
|
56
|
+
end
|
57
|
+
|
58
|
+
# Configure with yaml
|
59
|
+
def configure_with(path_to_yaml_file)
|
60
|
+
raise ConnectionConfigurationError, "Invalid request. #configure_with requires string" unless path_to_yaml_file.is_a?(String)
|
61
|
+
begin
|
62
|
+
@config = YAML::load(IO.read(path_to_yaml_file))
|
63
|
+
rescue Errno::ENOENT
|
64
|
+
raise ConnectionConfigurationError, "YAML configuration file was not found."
|
65
|
+
return
|
66
|
+
rescue Psych::SyntaxError
|
67
|
+
raise ConnectionConfigurationError, "YAML configuration file contains invalid syntax."
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
configure(@config)
|
72
|
+
end
|
73
|
+
|
74
|
+
def establish_connection
|
75
|
+
@connection = RestClient.post("#{@base_url}/j_spring_security_check", {:j_username => @username, :j_password => @password}) { |response, request, result, &block|
|
76
|
+
if [301, 302, 307].include? response.code
|
77
|
+
response
|
78
|
+
else
|
79
|
+
response.return!(request, result, &block)
|
80
|
+
end
|
81
|
+
}
|
82
|
+
@cookies = @connection.cookies if @connection
|
83
|
+
@headers = {:cookies => @cookies}
|
84
|
+
return true if @connection
|
85
|
+
end
|
86
|
+
|
87
|
+
def close_connection
|
88
|
+
RestClient.get("#{@base_url}/j_spring_security_logout", :cookies => @cookies) if @connection
|
89
|
+
@connection = nil
|
90
|
+
@cookies = nil
|
91
|
+
@headers = {}
|
92
|
+
return true
|
93
|
+
end
|
94
|
+
|
95
|
+
def get(path, headers = {}, &block)
|
96
|
+
execute(headers) do
|
97
|
+
get_custom_connection(path, @headers, &block)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def delete(path, headers = {}, &block)
|
102
|
+
execute(headers) do
|
103
|
+
delete_custom_connection(path, @headers, &block)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def post(path, payload, headers = {}, &block)
|
108
|
+
execute(headers) do
|
109
|
+
post_custom_connection(path, payload, @headers, &block)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def execute(headers = {}, &block)
|
114
|
+
establish_connection
|
115
|
+
if @connection
|
116
|
+
merge_headers(headers)
|
117
|
+
yield(block)
|
118
|
+
end
|
119
|
+
ensure
|
120
|
+
close_connection
|
121
|
+
end
|
122
|
+
|
123
|
+
# Use this inside an execute block to make mulitiple calls in the same request
|
124
|
+
def get_custom_connection(path, headers = {}, &block)
|
125
|
+
block ||= default_response_handler
|
126
|
+
url = URI.join(@base_url, URI.parse(@base_url).path + '/', path.to_s).to_s
|
127
|
+
RestClient.get(url, headers, &block)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Use this inside an execute block to make mulitiple calls in the same request
|
131
|
+
def delete_custom_connection(path, headers = {}, &block)
|
132
|
+
block ||= default_response_handler
|
133
|
+
url = URI.join(@base_url, URI.parse(@base_url).path + '/', path.to_s).to_s
|
134
|
+
RestClient.delete(url, headers, &block)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Use this inside an execute block to make mulitiple calls in the same request
|
138
|
+
def post_custom_connection(path, payload, headers = {}, &block)
|
139
|
+
block ||= default_response_handler
|
140
|
+
url = URI.join(@base_url, URI.parse(@base_url).path + '/', path.to_s).to_s
|
141
|
+
RestClient.post(url, payload, headers, &block)
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def clean_config_hash(config)
|
147
|
+
clean_config = {}
|
148
|
+
config = config.each {|k,v| config[k.to_sym] = v}
|
149
|
+
@@valid_config_keys.each{|k| clean_config[k] = config[k]}
|
150
|
+
|
151
|
+
return clean_config
|
152
|
+
end
|
153
|
+
|
154
|
+
def merge_headers(headers = {})
|
155
|
+
instance_cookies = @headers.delete(:cookies) || {}
|
156
|
+
local_cookies = headers.delete(:cookies) || {}
|
157
|
+
@headers = @headers.merge(headers)
|
158
|
+
@headers[:cookies] = instance_cookies.merge(local_cookies)
|
159
|
+
return @headers
|
160
|
+
end
|
161
|
+
|
162
|
+
def default_response_handler
|
163
|
+
@default_response_handler ||= lambda{ |response, request, result, &block|
|
164
|
+
case response.code
|
165
|
+
when 200
|
166
|
+
#Success!
|
167
|
+
return response
|
168
|
+
when 302
|
169
|
+
raise AuthenticationError, 'User is not logged in.'
|
170
|
+
when 401
|
171
|
+
raise AuthenticationError, 'Request requires authentication'
|
172
|
+
else
|
173
|
+
# Some other error. Let it bubble up.
|
174
|
+
response.return!(request, result, &block)
|
175
|
+
end
|
176
|
+
}
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'uri'
|
3
|
+
module NolijWeb
|
4
|
+
class Handler
|
5
|
+
@@doc_handler_path = 'handler/api/docs'
|
6
|
+
@@doc_viewer_path = ''
|
7
|
+
@@workflow_path = 'handler/api/workflow/workcomplete'
|
8
|
+
@@api_path = 'handler/api'
|
9
|
+
|
10
|
+
attr_reader :connection
|
11
|
+
|
12
|
+
def initialize(connection_config)
|
13
|
+
@config = connection_config
|
14
|
+
@connection = Connection.new(@config)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Folder contents
|
18
|
+
# required options: :folder_id
|
19
|
+
# additional options: :user_code, :user_id, :sort, :offset, :limit, :wfma_code
|
20
|
+
def folder_info(options = {}, &block)
|
21
|
+
folder_id = options[:folder_id]
|
22
|
+
raise AttributeMissingError, 'Folder ID is required.' unless folder_id.is_a?(String) && !folder_id.empty?
|
23
|
+
|
24
|
+
allowed_query_params_keys = [:user_code, :user_id, :sort, :offset, :limit, :wfma_code]
|
25
|
+
query_params = format_query_params(options, allowed_query_params_keys)
|
26
|
+
headers = options[:headers] || {}
|
27
|
+
relative_path = [@@doc_handler_path, options[:folder_id]].join('/')
|
28
|
+
|
29
|
+
response = @connection.get relative_path, headers.merge(:params => query_params), &block
|
30
|
+
|
31
|
+
folder = Nokogiri.XML(response)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns an array of hashes with the file info for each file in the folder
|
35
|
+
# See #folder_info for options
|
36
|
+
def folder_contents(options = {}, &block)
|
37
|
+
folder = folder_info(options, &block)
|
38
|
+
files = folder.xpath('//folderobjects//folderobject')
|
39
|
+
|
40
|
+
file_attrs = files.collect(&:attributes)
|
41
|
+
file_attrs = file_attrs.collect {|attr|
|
42
|
+
attr.inject({}){|n, (k,v)| n[k] = v.value; n}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
# Submit a file.
|
47
|
+
# A local file path is required.
|
48
|
+
# required options: :folder_id
|
49
|
+
# additional options: :user_code, :wfma_code, :index_code, :dept_code, :custom_name, :folder_name
|
50
|
+
def submit_document(local_file, options = {}, &block)
|
51
|
+
folder_id = options[:folder_id]
|
52
|
+
folder_id = if folder_id.kind_of?(Numeric) || folder_id.kind_of?(String)
|
53
|
+
folder_id.to_s
|
54
|
+
else
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
raise AttributeMissingError, 'Folder ID is required to submit a document.' unless folder_id.is_a?(String) && !folder_id.empty?
|
58
|
+
|
59
|
+
local_file ||= ''
|
60
|
+
file = begin
|
61
|
+
File.new(local_file)
|
62
|
+
rescue Errno::ENOENT
|
63
|
+
end
|
64
|
+
|
65
|
+
raise AttributeMissingError, 'Valid file or local filepath is required to submit a document.' unless file.is_a?(File)
|
66
|
+
options[:file_name] = File.basename(file.path)
|
67
|
+
allowed_query_params_keys = [:user_code, :wfma_code, :index_code, :dept_code, :custom_name, :file_name]
|
68
|
+
formatted_query = query_str(:allowed_query_params_keys => allowed_query_params_keys , :query_params => options)
|
69
|
+
relative_path = [@@doc_handler_path, folder_id].join('/') + formatted_query
|
70
|
+
|
71
|
+
# TODO custom attributes?
|
72
|
+
form_params = {}
|
73
|
+
form_params[:ocrwords] = options[:ocr_words] if options.has_key?(:oci_words)
|
74
|
+
form_params[:my_file] = file
|
75
|
+
|
76
|
+
#upload file to nolijweb
|
77
|
+
response = @connection.post relative_path, form_params, (options[:headers] || {}), &block
|
78
|
+
|
79
|
+
# return Nolij file id
|
80
|
+
doc_metadata = Nokogiri.XML(response)
|
81
|
+
document_id = doc_metadata.xpath('//documentmeta/@documentid').first
|
82
|
+
return document_id.value if document_id
|
83
|
+
end
|
84
|
+
|
85
|
+
# Print one or more documents to a single pdf
|
86
|
+
# required options: document_ids - can be a numer or an array of numbers
|
87
|
+
# additional options: :user_code, :document_id, :user_id
|
88
|
+
def print_document(options = {}, &block)
|
89
|
+
doc_ids = options.delete(:document_id)
|
90
|
+
raise AttributeMissingError, 'At least one document ID is required to print a document.' unless doc_ids
|
91
|
+
options[:document_id] = [doc_ids].flatten.compact.collect(&:to_i).join('-')
|
92
|
+
|
93
|
+
allowed_query_params_keys = [:user_code, :wfma_code, :user_id, :document_id]
|
94
|
+
query_params = format_query_params(options, allowed_query_params_keys)
|
95
|
+
headers = options[:headers] || {}
|
96
|
+
relative_path = [@@doc_handler_path, 'print'].join('/')
|
97
|
+
|
98
|
+
@connection.get relative_path, headers.merge(:params => query_params), &block
|
99
|
+
end
|
100
|
+
|
101
|
+
# Delete a document
|
102
|
+
# required options: :document_id, :folder_id
|
103
|
+
# additional options: :user_code, :user_id, :wfma_code
|
104
|
+
def delete_document(options = {}, &block)
|
105
|
+
folder_id = options[:folder_id]
|
106
|
+
document_id = options[:document_id]
|
107
|
+
raise AttributeMissingError, 'Folder ID is required to delete a document.' unless folder_id.is_a?(String) && ! folder_id.empty?
|
108
|
+
raise AttributeMissingError, 'Document ID is required to delete a document.' unless document_id.is_a?(String) && ! document_id.empty?
|
109
|
+
|
110
|
+
allowed_query_params_keys = [:user_code, :user_id, :wfma_code]
|
111
|
+
query_params = format_query_params(options, allowed_query_params_keys)
|
112
|
+
headers = options[:headers] || {}
|
113
|
+
relative_path = [@@doc_handler_path, 'delete', folder_id, document_id].join('/') + formatted_query
|
114
|
+
|
115
|
+
@connection.delete relative_path, headers.merge(:params => query_params), &block
|
116
|
+
end
|
117
|
+
|
118
|
+
# URL or path to verify that user is authenticated to Nolijweb in their browser.
|
119
|
+
# If the user is logged in redirect them to :redir path.
|
120
|
+
# If not, redirect to login and return them to the URL provided once they've authenticated.
|
121
|
+
# Redirect path must be relative to /public
|
122
|
+
# :redir is required. A path is returned unless :full_url => true
|
123
|
+
def login_check(options = {})
|
124
|
+
raise AttributeMissingError, 'Redirect path is required to check login' unless options[:redir].is_a?(String) && !options[:redir].empty?
|
125
|
+
|
126
|
+
full_url = options.delete(:full_url) || false
|
127
|
+
allowed_query_params_keys = [:redir]
|
128
|
+
formatted_query = query_str(:allowed_query_params_keys => allowed_query_params_keys , :query_params => options)
|
129
|
+
|
130
|
+
relative_path = ['public', 'apiLoginCheck.jsp'].join('/') + formatted_query
|
131
|
+
path = relative_path
|
132
|
+
url = full_url ? [@connection.base_url, path].join('/') : path
|
133
|
+
return url
|
134
|
+
end
|
135
|
+
|
136
|
+
# URL or path to open the standalone document viewer utility.
|
137
|
+
# required options: :document_id is required
|
138
|
+
# additional options: :user_code, :wfma_code
|
139
|
+
# use option :full_url => true for a full url, otherwise a relative path is returned.
|
140
|
+
def viewer_url(options = {})
|
141
|
+
raise AttributeMissingError, 'Document ID is required to launch viewer' unless (options[:document_id].is_a?(String) && !options[:document_id].empty?) || options[:document_id].is_a?(Integer)
|
142
|
+
full_url = options.delete(:full_url) || false
|
143
|
+
url_opts = {}
|
144
|
+
allowed_query_params_keys = [:document_id, :user_code, :wfma_code]
|
145
|
+
formatted_query = query_str(:allowed_query_params_keys => allowed_query_params_keys , :query_params => options)
|
146
|
+
relative_path = [@@doc_viewer_path, 'documentviewer'].join('/') + formatted_query
|
147
|
+
path = relative_path
|
148
|
+
url = full_url ? [@connection.base_url, path].join('/') : path
|
149
|
+
return url
|
150
|
+
end
|
151
|
+
|
152
|
+
# Issue work complete to push item along in work flow
|
153
|
+
# required options: :wfma_code, :folder_name
|
154
|
+
# additional options: :user_id, :user_code
|
155
|
+
def work_complete(options = {}, &block)
|
156
|
+
raise AttributeMissingError, 'Workflow master code is required for workflow requests.' unless options[:wfma_code]
|
157
|
+
folder_id = options[:folder_id]
|
158
|
+
raise AttributeMissingError, 'Folder ID is required.' unless folder_id
|
159
|
+
|
160
|
+
raise AttributeMissingError, 'Folder name is required.' unless options[:folder_name]
|
161
|
+
|
162
|
+
allowed_query_params_keys = [:wfma_code, :user_id, :user_code, :folder_name]
|
163
|
+
formatted_query = query_str(:allowed_query_params_keys => allowed_query_params_keys , :query_params => options)
|
164
|
+
relative_path = [@@workflow_path, folder_id, formatted_query].join('/')
|
165
|
+
|
166
|
+
@connection.post relative_path, {}, options[:headers] || {}, &block
|
167
|
+
end
|
168
|
+
|
169
|
+
# Nolij Web server version information
|
170
|
+
def version(&block)
|
171
|
+
relative_path = [@@api_path, 'version'].join('/')
|
172
|
+
response = @connection.get relative_path, &block
|
173
|
+
|
174
|
+
info = Nokogiri.XML(response).xpath('//version').collect(&:attributes)
|
175
|
+
info= info.collect {|attr|
|
176
|
+
attr.inject({}){|n, (k,v)| n[k] = v.value; n}
|
177
|
+
}.first
|
178
|
+
end
|
179
|
+
|
180
|
+
# TODO Add query and query results methods
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def query_str(options = {})
|
185
|
+
keys = options[:allowed_query_params_keys] || []
|
186
|
+
query_params = options[:query_params] || {}
|
187
|
+
query_str = if query_params.empty?
|
188
|
+
''
|
189
|
+
else
|
190
|
+
format_query_params(query_params, keys).collect{|k,v| "#{k}=#{URI.escape v}"}.join('&')
|
191
|
+
end
|
192
|
+
return query_str.empty? ? '' : "?#{query_str}"
|
193
|
+
end
|
194
|
+
|
195
|
+
# format param names and return the query hash
|
196
|
+
def format_query_params(params = {}, keys = [])
|
197
|
+
keys.inject([]){|m, v| v.to_sym; m}
|
198
|
+
query_params = params.select{|k,v| keys.include?(k.to_sym)}
|
199
|
+
cleaned = query_params.inject({}) do |p,(k,v)|
|
200
|
+
key = k.to_s.gsub('_', '').to_sym
|
201
|
+
value = v.to_s
|
202
|
+
p[key] = value
|
203
|
+
p
|
204
|
+
end
|
205
|
+
return cleaned.reject{|k,v| v.empty?}
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
data/lib/nolij_web.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'uri'
|
3
|
+
require 'nolij_web/connection'
|
4
|
+
require 'nolij_web/handler'
|
5
|
+
require "nolij_web/version"
|
6
|
+
require 'nolij_web/authentication_error'
|
7
|
+
require 'nolij_web/attribute_missing_error'
|
8
|
+
require 'nolij_web/connection_configuration_error'
|
9
|
+
|
10
|
+
# See README for installation and usage instructions
|
11
|
+
module NolijWeb
|
12
|
+
# Nothing to see here
|
13
|
+
end
|
data/nolij_web.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'nolij_web/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "nolij_web"
|
8
|
+
spec.version = NolijWeb::Version::VERSION
|
9
|
+
spec.authors = ["Shannon Henderson"]
|
10
|
+
spec.email = ["shenders@reed.edu"]
|
11
|
+
spec.description = %q{A Ruby wrapper for the Nolijweb API}
|
12
|
+
spec.summary = %q{Interact with Nolijweb's REST API}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.extra_rdoc_files = spec.files.select { |p| p =~ /^README/ } << 'LICENSE.txt'
|
22
|
+
spec.rdoc_options = %w[--line-numbers --inline-source --main README.rdoc]
|
23
|
+
|
24
|
+
spec.add_runtime_dependency 'rest-client', '~> 1.6'
|
25
|
+
spec.add_runtime_dependency 'nokogiri', '~> 1.6'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'minitest', '~> 5.0.0'
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
29
|
+
spec.add_development_dependency 'rake'
|
30
|
+
spec.add_development_dependency 'webmock', '~>1.13'
|
31
|
+
|
32
|
+
spec.required_ruby_version = '>= 1.9.3'
|
33
|
+
end
|