berkeley_library-tind 0.4.1 → 0.4.2
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.
- checksums.yaml +4 -4
- data/.idea/tind.iml +12 -16
- data/CHANGES.md +4 -0
- data/berkeley_library-tind.gemspec +1 -0
- data/lib/berkeley_library/tind/api/api.rb +17 -11
- data/lib/berkeley_library/tind/api/collection.rb +1 -1
- data/lib/berkeley_library/tind/api/search.rb +1 -1
- data/lib/berkeley_library/tind/export/exporter.rb +1 -1
- data/lib/berkeley_library/tind/export/table.rb +1 -1
- data/lib/berkeley_library/tind/export/table_metrics.rb +1 -1
- data/lib/berkeley_library/tind/module_info.rb +1 -1
- data/lib/berkeley_library/util/ods/spreadsheet.rb +1 -1
- data/lib/berkeley_library/util/ods/xml/element_node.rb +1 -1
- metadata +16 -25
- data/lib/berkeley_library/util/arrays.rb +0 -178
- data/lib/berkeley_library/util/logging.rb +0 -1
- data/lib/berkeley_library/util/paths.rb +0 -111
- data/lib/berkeley_library/util/stringios.rb +0 -30
- data/lib/berkeley_library/util/strings.rb +0 -42
- data/lib/berkeley_library/util/sys_exits.rb +0 -15
- data/lib/berkeley_library/util/times.rb +0 -22
- data/lib/berkeley_library/util/uris/appender.rb +0 -162
- data/lib/berkeley_library/util/uris/requester.rb +0 -62
- data/lib/berkeley_library/util/uris/validator.rb +0 -32
- data/lib/berkeley_library/util/uris.rb +0 -44
- data/spec/berkeley_library/util/arrays_spec.rb +0 -340
- data/spec/berkeley_library/util/paths_spec.rb +0 -90
- data/spec/berkeley_library/util/stringios_spec.rb +0 -34
- data/spec/berkeley_library/util/strings_spec.rb +0 -27
- data/spec/berkeley_library/util/times_spec.rb +0 -39
- data/spec/berkeley_library/util/uris_spec.rb +0 -118
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
module BerkeleyLibrary
|
4
|
-
module Util
|
5
|
-
module StringIOs
|
6
|
-
class << self
|
7
|
-
include StringIOs
|
8
|
-
end
|
9
|
-
|
10
|
-
# Returns the byte (**not** character) at the specified byte index
|
11
|
-
# in the specified `StringIO`.
|
12
|
-
#
|
13
|
-
# @param s [StringIO] the StringIO to search in
|
14
|
-
# @param i [Integer] the byte index
|
15
|
-
# @return [Integer, nil] the byte, or nil if the byte index is invalid.
|
16
|
-
def getbyte(s, i)
|
17
|
-
return if i >= s.size
|
18
|
-
return if s.size + i < 0
|
19
|
-
|
20
|
-
pos_orig = s.pos
|
21
|
-
begin
|
22
|
-
s.seek(i >= 0 ? i : s.size + i)
|
23
|
-
s.getbyte
|
24
|
-
ensure
|
25
|
-
s.seek(pos_orig)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module BerkeleyLibrary
|
2
|
-
module Util
|
3
|
-
module Strings
|
4
|
-
|
5
|
-
ASCII_0 = '0'.ord
|
6
|
-
ASCII_9 = '9'.ord
|
7
|
-
|
8
|
-
def ascii_numeric?(s)
|
9
|
-
s.chars.all? do |c|
|
10
|
-
ord = c.ord
|
11
|
-
ord >= ASCII_0 && ord <= ASCII_9
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# Locates the point at which two strings differ
|
16
|
-
#
|
17
|
-
# @return [Integer, nil] the index of the first character in either string
|
18
|
-
# that differs from the other, or `nil` if the strings are identical,
|
19
|
-
# or are not strings
|
20
|
-
def diff_index(s1, s2)
|
21
|
-
return unless string_like?(s1, s2)
|
22
|
-
|
23
|
-
shorter, longer = s1.size > s2.size ? [s2, s1] : [s1, s2]
|
24
|
-
shorter.chars.each_with_index do |c, i|
|
25
|
-
return i if c != longer[i]
|
26
|
-
end
|
27
|
-
shorter.length if shorter.length < longer.length # otherwise they're equal
|
28
|
-
end
|
29
|
-
|
30
|
-
class << self
|
31
|
-
include Strings
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def string_like?(*strs)
|
37
|
-
strs.all? { |s| s.respond_to?(:chars) && s.respond_to?(:size) }
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module BerkeleyLibrary
|
2
|
-
module Util
|
3
|
-
# cf. BSD sysexits.h https://cgit.freebsd.org/src/tree/include/sysexits.h?h=releng/2.0
|
4
|
-
module SysExits
|
5
|
-
# successful termination
|
6
|
-
EX_OK = 0
|
7
|
-
|
8
|
-
# command line usage error
|
9
|
-
EX_USAGE = 64
|
10
|
-
|
11
|
-
# internal software error
|
12
|
-
EX_SOFTWARE = 70 # command line usage error
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'time'
|
2
|
-
|
3
|
-
module BerkeleyLibrary
|
4
|
-
module Util
|
5
|
-
module Times
|
6
|
-
class << self
|
7
|
-
include Times
|
8
|
-
end
|
9
|
-
|
10
|
-
# @param time [Time, Date] the time
|
11
|
-
# @return the UTC time corresponding to `time`
|
12
|
-
def ensure_utc(time)
|
13
|
-
return unless time
|
14
|
-
return time if time.respond_to?(:utc?) && time.utc?
|
15
|
-
return time.getutc if time.respond_to?(:getutc)
|
16
|
-
return time.to_time.getutc if time.respond_to?(:to_time)
|
17
|
-
|
18
|
-
raise ArgumentError, "Not a date or time: #{time.inspect}"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,162 +0,0 @@
|
|
1
|
-
require 'berkeley_library/util/paths'
|
2
|
-
require 'uri'
|
3
|
-
require 'typesafe_enum'
|
4
|
-
|
5
|
-
module BerkeleyLibrary
|
6
|
-
module Util
|
7
|
-
module URIs
|
8
|
-
|
9
|
-
# Appends the specified paths to the path of the specified URI, removing any extraneous slashes,
|
10
|
-
# and builds a new URI with that path and the same scheme, host, query, fragment, etc.
|
11
|
-
# as the original.
|
12
|
-
class Appender
|
13
|
-
attr_reader :original_uri, :elements
|
14
|
-
|
15
|
-
# Creates and invokes a new {Appender}.
|
16
|
-
#
|
17
|
-
# @param uri [URI, String] the original URI
|
18
|
-
# @param elements [Array<String, Symbol>] the URI elements to join.
|
19
|
-
# @raise URI::InvalidComponentError if appending the specified elements would create an invalid URI
|
20
|
-
def initialize(uri, *elements)
|
21
|
-
raise ArgumentError, 'uri cannot be nil' unless (@original_uri = URIs.uri_or_nil(uri))
|
22
|
-
|
23
|
-
@elements = elements.map(&:to_s)
|
24
|
-
@elements.each_with_index do |element, elem_index|
|
25
|
-
next start_query_at(elem_index) if element.include?('?')
|
26
|
-
next start_fragment_at(elem_index) if element.include?('#')
|
27
|
-
|
28
|
-
add_element(element)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns the new URI.
|
33
|
-
#
|
34
|
-
# @return [URI] a new URI appending the joined path elements.
|
35
|
-
# @raise URI::InvalidComponentError if appending the specified elements would create an invalid URI
|
36
|
-
def to_uri
|
37
|
-
original_uri.dup.tap do |new_uri|
|
38
|
-
new_uri.path = Paths.join(original_uri.path, *path_elements)
|
39
|
-
new_uri.query = query unless query_elements.empty?
|
40
|
-
new_uri.fragment = fragment unless fragment_elements.empty?
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def state
|
47
|
-
@state ||= :path
|
48
|
-
end
|
49
|
-
|
50
|
-
def in_query?
|
51
|
-
state == :query
|
52
|
-
end
|
53
|
-
|
54
|
-
def in_fragment?
|
55
|
-
state == :fragment
|
56
|
-
end
|
57
|
-
|
58
|
-
def query
|
59
|
-
query_elements.join
|
60
|
-
end
|
61
|
-
|
62
|
-
def fragment
|
63
|
-
fragment_elements.join
|
64
|
-
end
|
65
|
-
|
66
|
-
def path_elements
|
67
|
-
@path_elements ||= []
|
68
|
-
end
|
69
|
-
|
70
|
-
def query_elements
|
71
|
-
@query_elements ||= [].tap { |e| e << original_uri.query if original_uri.query }
|
72
|
-
end
|
73
|
-
|
74
|
-
def fragment_elements
|
75
|
-
@fragment_elements ||= [].tap { |e| e << original_uri.fragment if original_uri.fragment }
|
76
|
-
end
|
77
|
-
|
78
|
-
def start_query_at(elem_index)
|
79
|
-
raise URI::InvalidComponentError, err_query_after_fragment(elem_index) if in_fragment?
|
80
|
-
raise URI::InvalidComponentError, err_too_many_queries(elem_index) unless query_elements.empty?
|
81
|
-
|
82
|
-
handle_query_start(elem_index)
|
83
|
-
@state = :query
|
84
|
-
end
|
85
|
-
|
86
|
-
def start_fragment_at(elem_index)
|
87
|
-
raise URI::InvalidComponentError, err_too_many_fragments(elem_index) unless fragment_elements.empty?
|
88
|
-
raise URI::InvalidComponentError, err_query_after_fragment(elem_index) if query_after_fragment?(elem_index)
|
89
|
-
|
90
|
-
handle_fragment_start(elem_index)
|
91
|
-
@state = :fragment
|
92
|
-
end
|
93
|
-
|
94
|
-
def query_after_fragment?(elem_index)
|
95
|
-
e = elements[elem_index]
|
96
|
-
e.index('?', e.index('#'))
|
97
|
-
end
|
98
|
-
|
99
|
-
def add_element(e)
|
100
|
-
return fragment_elements << e if in_fragment?
|
101
|
-
return query_elements << e if in_query? || (e.include?('&') && !query_elements.empty?)
|
102
|
-
|
103
|
-
path_elements << e
|
104
|
-
end
|
105
|
-
|
106
|
-
def handle_query_start(elem_index)
|
107
|
-
element = elements[elem_index]
|
108
|
-
|
109
|
-
# if there's anything before the '?', we treat that excess as a path element
|
110
|
-
excess, q_start = split_around(element, element.index('?'))
|
111
|
-
q_start = push_fragment_start(elem_index, q_start)
|
112
|
-
|
113
|
-
query_elements << q_start
|
114
|
-
path_elements << excess
|
115
|
-
end
|
116
|
-
|
117
|
-
# if the fragment starts in the middle of this element, we keep the part before
|
118
|
-
# the fragment delimiter '#', and push the rest (w/'#') back onto the next element
|
119
|
-
# to be parsed in the next iteration
|
120
|
-
def push_fragment_start(elem_index, q_start)
|
121
|
-
return q_start unless (f_index = q_start.index('#'))
|
122
|
-
|
123
|
-
next_index = elem_index + 1
|
124
|
-
q_start, q_next = split_around(q_start, f_index) # NOTE: this doesn't return the '#'
|
125
|
-
elements[next_index] = "##{q_next}#{elements[next_index]}" # so we prepend one here
|
126
|
-
q_start
|
127
|
-
end
|
128
|
-
|
129
|
-
def handle_fragment_start(elem_index)
|
130
|
-
element = elements[elem_index]
|
131
|
-
|
132
|
-
# if there's anything before the '#', we treat that excess as a path element,
|
133
|
-
# or as a query element if there's a query
|
134
|
-
excess, f_start = split_around(element, element.index('#'))
|
135
|
-
|
136
|
-
fragment_elements << f_start
|
137
|
-
if in_query?
|
138
|
-
query_elements << excess
|
139
|
-
else
|
140
|
-
path_elements << excess
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def split_around(s, i)
|
145
|
-
[s[0...i], s[(i + 1)..]]
|
146
|
-
end
|
147
|
-
|
148
|
-
def err_too_many_queries(elem_index)
|
149
|
-
"#{elements[elem_index].inspect}: URI already has a query string: #{query.inspect}"
|
150
|
-
end
|
151
|
-
|
152
|
-
def err_query_after_fragment(elem_index)
|
153
|
-
"#{elements[elem_index].inspect}: Query delimiter '?' cannot follow fragment delimeter '#'"
|
154
|
-
end
|
155
|
-
|
156
|
-
def err_too_many_fragments(elem_index)
|
157
|
-
"#{elements[elem_index].inspect}: URI already has a fragment: #{fragment.inspect}"
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'berkeley_library/util/uris/appender'
|
3
|
-
require 'berkeley_library/util/uris/validator'
|
4
|
-
require 'berkeley_library/logging'
|
5
|
-
|
6
|
-
module BerkeleyLibrary
|
7
|
-
module Util
|
8
|
-
module URIs
|
9
|
-
module Requester
|
10
|
-
class << self
|
11
|
-
include BerkeleyLibrary::Logging
|
12
|
-
|
13
|
-
# Performs a GET request.
|
14
|
-
#
|
15
|
-
# @param uri [URI, String] the URI to GET
|
16
|
-
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
17
|
-
# @param headers [Hash] the request headers.
|
18
|
-
# @return [String] the body as a string.
|
19
|
-
# @raise [RestClient::Exception] in the event of an error.
|
20
|
-
def get(uri, params = {}, headers = {})
|
21
|
-
url_str = url_str_with_params(uri, params)
|
22
|
-
resp = get_or_raise(url_str, headers)
|
23
|
-
resp.body
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def url_str_with_params(uri, params)
|
29
|
-
raise ArgumentError, 'uri cannot be nil' unless (url_str = Validator.url_str_or_nil(uri))
|
30
|
-
|
31
|
-
elements = [].tap do |ee|
|
32
|
-
ee << url_str
|
33
|
-
ee << '?' unless url_str.include?('?')
|
34
|
-
ee << URI.encode_www_form(params)
|
35
|
-
end
|
36
|
-
|
37
|
-
uri = Appender.new(*elements).to_uri
|
38
|
-
uri.to_s
|
39
|
-
end
|
40
|
-
|
41
|
-
def get_or_raise(url_str, headers)
|
42
|
-
resp = RestClient.get(url_str, headers)
|
43
|
-
begin
|
44
|
-
return resp if (status = resp.code) == 200
|
45
|
-
|
46
|
-
raise(exception_for(resp, status))
|
47
|
-
ensure
|
48
|
-
logger.info("GET #{url_str} returned #{status}")
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def exception_for(resp, status)
|
53
|
-
RestClient::RequestFailed.new(resp, status).tap do |ex|
|
54
|
-
status_message = RestClient::STATUSES[status] || '(Unknown)'
|
55
|
-
ex.message = "#{status} #{status_message}"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
|
3
|
-
module BerkeleyLibrary
|
4
|
-
module Util
|
5
|
-
module URIs
|
6
|
-
module Validator
|
7
|
-
class << self
|
8
|
-
|
9
|
-
# Returns the specified URL as a URI.
|
10
|
-
# @param url [String, URI] the URL.
|
11
|
-
# @return [URI] the URI.
|
12
|
-
# @raise [URI::InvalidURIError] if `url` cannot be parsed as a URI.
|
13
|
-
def uri_or_nil(url)
|
14
|
-
return unless url
|
15
|
-
|
16
|
-
# noinspection RubyYardReturnMatch
|
17
|
-
url.is_a?(URI) ? url : URI.parse(url.to_s)
|
18
|
-
end
|
19
|
-
|
20
|
-
# Returns the specified URL as a string.
|
21
|
-
# @param url [String, URI] the URL.
|
22
|
-
# @return [String] the URL.
|
23
|
-
# @raise [URI::InvalidURIError] if `url` cannot be parsed as a URI.
|
24
|
-
def url_str_or_nil(url)
|
25
|
-
uri = Validator.uri_or_nil(url)
|
26
|
-
uri.to_s if uri
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'berkeley_library/util/uris/appender'
|
2
|
-
require 'berkeley_library/util/uris/requester'
|
3
|
-
require 'berkeley_library/util/uris/validator'
|
4
|
-
|
5
|
-
module BerkeleyLibrary
|
6
|
-
module Util
|
7
|
-
module URIs
|
8
|
-
class << self
|
9
|
-
include URIs
|
10
|
-
end
|
11
|
-
|
12
|
-
# Appends the specified paths to the path of the specified URI, removing any extraneous slashes
|
13
|
-
# and merging additional query parameters, and returns a new URI with that path and the same scheme,
|
14
|
-
# host, query, fragment, etc. as the original.
|
15
|
-
#
|
16
|
-
# @param uri [URI, String] the original URI
|
17
|
-
# @param elements [Array<String, Symbol>] the URI elements to join.
|
18
|
-
# @return [URI] a new URI appending the joined path elements.
|
19
|
-
# @raise URI::InvalidComponentError if appending the specified elements would create an invalid URI
|
20
|
-
def append(uri, *elements)
|
21
|
-
Appender.new(uri, *elements).to_uri
|
22
|
-
end
|
23
|
-
|
24
|
-
# Performs a GET request.
|
25
|
-
#
|
26
|
-
# @param uri [URI, String] the URI to GET
|
27
|
-
# @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
|
28
|
-
# @param headers [Hash] the request headers.
|
29
|
-
# @return [String] the body as a string.
|
30
|
-
# @raise [RestClient::Exception] in the event of an error.
|
31
|
-
def get(uri, params = {}, headers = {})
|
32
|
-
Requester.get(uri, params, headers)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Returns the specified URL as a URI.
|
36
|
-
# @param url [String, URI] the URL.
|
37
|
-
# @return [URI] the URI.
|
38
|
-
# @raise [URI::InvalidURIError] if `url` cannot be parsed as a URI.
|
39
|
-
def uri_or_nil(url)
|
40
|
-
Validator.uri_or_nil(url)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|