nolij_web 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|