ecfr 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +11 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rspec_parallel +4 -0
- data/.rubocop.yml +28 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +6 -0
- data/Dockerfile +6 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +138 -0
- data/LICENSE.txt +21 -0
- data/README.md +133 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ecfr.gemspec +74 -0
- data/lib/ecfr/admin_service/agency/hierarchy.rb +27 -0
- data/lib/ecfr/admin_service/agency.rb +34 -0
- data/lib/ecfr/admin_service/api_documentation.rb +7 -0
- data/lib/ecfr/admin_service/base.rb +26 -0
- data/lib/ecfr/admin_service/build.rb +38 -0
- data/lib/ecfr/admin_service/ecfr_correction/cfr_reference.rb +17 -0
- data/lib/ecfr/admin_service/ecfr_correction.rb +78 -0
- data/lib/ecfr/admin_service/editorial_note/hierarchy.rb +19 -0
- data/lib/ecfr/admin_service/editorial_note.rb +40 -0
- data/lib/ecfr/admin_service/ibr_cfr_range/address.rb +17 -0
- data/lib/ecfr/admin_service/ibr_cfr_range/organization.rb +28 -0
- data/lib/ecfr/admin_service/ibr_cfr_range.rb +67 -0
- data/lib/ecfr/admin_service/issue/change.rb +19 -0
- data/lib/ecfr/admin_service/issue.rb +86 -0
- data/lib/ecfr/admin_service/site_notification.rb +34 -0
- data/lib/ecfr/admin_service/status.rb +7 -0
- data/lib/ecfr/attribute_caster.rb +72 -0
- data/lib/ecfr/attribute_method_definition.rb +92 -0
- data/lib/ecfr/base.rb +71 -0
- data/lib/ecfr/client.rb +318 -0
- data/lib/ecfr/common/hierarchy.rb +35 -0
- data/lib/ecfr/configuration.rb +58 -0
- data/lib/ecfr/constants.rb +21 -0
- data/lib/ecfr/default_documentation_setup.rb +39 -0
- data/lib/ecfr/default_status_setup.rb +46 -0
- data/lib/ecfr/diff_service/base.rb +17 -0
- data/lib/ecfr/diff_service/status.rb +34 -0
- data/lib/ecfr/extensible.rb +45 -0
- data/lib/ecfr/facet_attribute_method_definition.rb +47 -0
- data/lib/ecfr/faraday/user_agent/middleware.rb +14 -0
- data/lib/ecfr/ofr_profile_service/base.rb +20 -0
- data/lib/ecfr/ofr_profile_service/status.rb +7 -0
- data/lib/ecfr/parallel_client.rb +33 -0
- data/lib/ecfr/prince_xml_service/base.rb +17 -0
- data/lib/ecfr/prince_xml_service/pdf.rb +31 -0
- data/lib/ecfr/renderer_service/base.rb +31 -0
- data/lib/ecfr/renderer_service/content.rb +34 -0
- data/lib/ecfr/renderer_service/diff.rb +31 -0
- data/lib/ecfr/renderer_service/origin.rb +56 -0
- data/lib/ecfr/renderer_service/status.rb +7 -0
- data/lib/ecfr/request_representation.rb +12 -0
- data/lib/ecfr/search_service/api_documentation.rb +7 -0
- data/lib/ecfr/search_service/base.rb +23 -0
- data/lib/ecfr/search_service/content_version/count.rb +33 -0
- data/lib/ecfr/search_service/content_version/hierarchical_count.rb +17 -0
- data/lib/ecfr/search_service/content_version/hierarchical_count_node.rb +30 -0
- data/lib/ecfr/search_service/content_version/hierarchichal_result.rb +42 -0
- data/lib/ecfr/search_service/content_version/result.rb +110 -0
- data/lib/ecfr/search_service/content_version/suggestion.rb +76 -0
- data/lib/ecfr/search_service/content_version/summary.rb +27 -0
- data/lib/ecfr/search_service/content_version.rb +85 -0
- data/lib/ecfr/search_service/date_facet.rb +19 -0
- data/lib/ecfr/search_service/facet_base.rb +55 -0
- data/lib/ecfr/search_service/status.rb +7 -0
- data/lib/ecfr/search_service/title_facet.rb +18 -0
- data/lib/ecfr/subscriptions_service/base.rb +19 -0
- data/lib/ecfr/subscriptions_service/status.rb +7 -0
- data/lib/ecfr/subscriptions_service/subscription.rb +97 -0
- data/lib/ecfr/testing/extensions/admin_service/ecfr_correction_extensions.rb +13 -0
- data/lib/ecfr/testing/extensions/admin_service/issue_extensions.rb +13 -0
- data/lib/ecfr/testing/extensions/renderer_service/origin_extensions.rb +13 -0
- data/lib/ecfr/testing/extensions/search_service/content_version_result_extensions.rb +16 -0
- data/lib/ecfr/testing/extensions/search_service/date_facet_extensions.rb +13 -0
- data/lib/ecfr/testing/extensions/versioner_service/ancestors_extensions.rb +20 -0
- data/lib/ecfr/testing/extensions/versioner_service/title_extenstions.rb +16 -0
- data/lib/ecfr/testing/factories/admin_service/cfr_reference_factory.rb +14 -0
- data/lib/ecfr/testing/factories/admin_service/ecfr_correction_factory.rb +31 -0
- data/lib/ecfr/testing/factories/admin_service/issue_change_factory.rb +12 -0
- data/lib/ecfr/testing/factories/admin_service/issue_factory.rb +21 -0
- data/lib/ecfr/testing/factories/common/hierarchy_factory.rb +36 -0
- data/lib/ecfr/testing/factories/renderer_service/origin_factory.rb +32 -0
- data/lib/ecfr/testing/factories/search_service/content_version_count_factory.rb +20 -0
- data/lib/ecfr/testing/factories/search_service/content_version_result_factory.rb +76 -0
- data/lib/ecfr/testing/factories/search_service/date_facet_factory.rb +12 -0
- data/lib/ecfr/testing/factories/versioner_service/ancestors_factory.rb +26 -0
- data/lib/ecfr/testing/factories/versioner_service/metadata_node_info_factory.rb +15 -0
- data/lib/ecfr/testing/factories/versioner_service/node_summary_factory.rb +16 -0
- data/lib/ecfr/testing/factories/versioner_service/structure_factory.rb +57 -0
- data/lib/ecfr/testing/factories/versioner_service/title_factory.rb +36 -0
- data/lib/ecfr/testing/factory_bot_helpers/content_version.rb +38 -0
- data/lib/ecfr/testing/factory_bot_helpers/ecfr_gem_initialize_helpers.rb +51 -0
- data/lib/ecfr/testing/helpers/response_helper.rb +5 -0
- data/lib/ecfr/testing/strategies/ecfr_attribute_hash_strategy.rb +37 -0
- data/lib/ecfr/testing.rb +28 -0
- data/lib/ecfr/version.rb +5 -0
- data/lib/ecfr/versioner_service/ancestors/metadata_node_info.rb +22 -0
- data/lib/ecfr/versioner_service/ancestors/node_summary.rb +54 -0
- data/lib/ecfr/versioner_service/ancestors.rb +152 -0
- data/lib/ecfr/versioner_service/api_documentation.rb +7 -0
- data/lib/ecfr/versioner_service/base.rb +24 -0
- data/lib/ecfr/versioner_service/status.rb +7 -0
- data/lib/ecfr/versioner_service/structure.rb +120 -0
- data/lib/ecfr/versioner_service/title.rb +78 -0
- data/lib/ecfr/versioner_service/xml_content.rb +59 -0
- data/lib/ecfr.rb +90 -0
- data/lib/yard/attribute_handler.rb +87 -0
- data/lib/yard/metadata_handler.rb +87 -0
- metadata +389 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e01bffb47225f9d31bd9a6d862f8b6e967586b4ac296ec25814e04dd254dacbe
|
4
|
+
data.tar.gz: 0b1f9d5b015063e167a27fc98036299ceb8b10d486a8a3d188044da99ad4c903
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a294244d1e845f3ea9d3b6a128c557f85f9bc5b5c9eebea84ea507437b0101b27a9c87528c26e6dfb0ebb9d7c3888963569698b366b653399e2bf79eb37d579b
|
7
|
+
data.tar.gz: dc588b8531cb89e27a69a53c6a47deb8648c493d4fdc176e17bf51018ef88fd884876ebf69a875d44c30421be6735775555038cd4c6d19f3d7a8b3c6da399633
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rspec_parallel
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- bin/*
|
4
|
+
- lib/yard/*
|
5
|
+
TargetRubyVersion: 3.1
|
6
|
+
|
7
|
+
Layout/EmptyLineBetweenDefs:
|
8
|
+
AllowAdjacentOneLineDefs: true
|
9
|
+
|
10
|
+
Lint/ConstantDefinitionInBlock:
|
11
|
+
Exclude:
|
12
|
+
- spec/ecfr/extensible_spec.rb
|
13
|
+
|
14
|
+
# We want Exclude directives from different
|
15
|
+
# config files to get merged, not overwritten
|
16
|
+
inherit_mode:
|
17
|
+
merge:
|
18
|
+
- Exclude
|
19
|
+
|
20
|
+
require:
|
21
|
+
# Performance cops are bundled with Standard
|
22
|
+
- rubocop-performance
|
23
|
+
# Standard's config uses this custom cop,
|
24
|
+
# so it must be loaded
|
25
|
+
- standard/cop/block_single_line_braces
|
26
|
+
|
27
|
+
inherit_gem:
|
28
|
+
standard: config/base.yml
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/Dockerfile
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ecfr (1.0.0)
|
5
|
+
activemodel (~> 6.0)
|
6
|
+
activesupport (~> 6.0)
|
7
|
+
faraday (~> 2.0)
|
8
|
+
faraday-net_http_persistent (~> 2.0)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activemodel (6.1.4)
|
14
|
+
activesupport (= 6.1.4)
|
15
|
+
activesupport (6.1.4)
|
16
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
|
+
i18n (>= 1.6, < 2)
|
18
|
+
minitest (>= 5.1)
|
19
|
+
tzinfo (~> 2.0)
|
20
|
+
zeitwerk (~> 2.3)
|
21
|
+
ast (2.4.2)
|
22
|
+
coderay (1.1.3)
|
23
|
+
concurrent-ruby (1.1.9)
|
24
|
+
connection_pool (2.4.0)
|
25
|
+
diff-lcs (1.4.4)
|
26
|
+
ethon (0.16.0)
|
27
|
+
ffi (>= 1.15.0)
|
28
|
+
factory_bot (6.2.1)
|
29
|
+
activesupport (>= 5.0.0)
|
30
|
+
faraday (2.5.2)
|
31
|
+
faraday-net_http (>= 2.0, < 3.1)
|
32
|
+
ruby2_keywords (>= 0.0.4)
|
33
|
+
faraday-net_http (3.0.0)
|
34
|
+
faraday-net_http_persistent (2.1.0)
|
35
|
+
faraday (~> 2.5)
|
36
|
+
net-http-persistent (~> 4.0)
|
37
|
+
faraday-typhoeus (1.0.0)
|
38
|
+
faraday (~> 2.0)
|
39
|
+
typhoeus (~> 1.4)
|
40
|
+
ffi (1.15.5)
|
41
|
+
i18n (1.8.10)
|
42
|
+
concurrent-ruby (~> 1.0)
|
43
|
+
json (2.6.3)
|
44
|
+
language_server-protocol (3.17.0.3)
|
45
|
+
method_source (1.0.0)
|
46
|
+
mini_portile2 (2.8.1)
|
47
|
+
minitest (5.14.4)
|
48
|
+
net-http-persistent (4.0.2)
|
49
|
+
connection_pool (~> 2.2)
|
50
|
+
nokogiri (1.14.0)
|
51
|
+
mini_portile2 (~> 2.8.0)
|
52
|
+
racc (~> 1.4)
|
53
|
+
optparse (0.3.1)
|
54
|
+
parallel (1.22.1)
|
55
|
+
parallel_tests (4.2.0)
|
56
|
+
parallel
|
57
|
+
parser (3.2.2.0)
|
58
|
+
ast (~> 2.4.1)
|
59
|
+
pry (0.14.1)
|
60
|
+
coderay (~> 1.1)
|
61
|
+
method_source (~> 1.0)
|
62
|
+
racc (1.6.2)
|
63
|
+
rack (3.0.4.1)
|
64
|
+
rainbow (3.1.1)
|
65
|
+
regexp_parser (2.7.0)
|
66
|
+
request_store (1.5.1)
|
67
|
+
rack (>= 1.4)
|
68
|
+
rexml (3.2.5)
|
69
|
+
rspec (3.10.0)
|
70
|
+
rspec-core (~> 3.10.0)
|
71
|
+
rspec-expectations (~> 3.10.0)
|
72
|
+
rspec-mocks (~> 3.10.0)
|
73
|
+
rspec-core (3.10.1)
|
74
|
+
rspec-support (~> 3.10.0)
|
75
|
+
rspec-expectations (3.10.1)
|
76
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
77
|
+
rspec-support (~> 3.10.0)
|
78
|
+
rspec-mocks (3.10.2)
|
79
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
80
|
+
rspec-support (~> 3.10.0)
|
81
|
+
rspec-support (3.10.2)
|
82
|
+
rspec_junit_formatter (0.6.0)
|
83
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
84
|
+
rubocop (1.48.1)
|
85
|
+
json (~> 2.3)
|
86
|
+
parallel (~> 1.10)
|
87
|
+
parser (>= 3.2.0.0)
|
88
|
+
rainbow (>= 2.2.2, < 4.0)
|
89
|
+
regexp_parser (>= 1.8, < 3.0)
|
90
|
+
rexml (>= 3.2.5, < 4.0)
|
91
|
+
rubocop-ast (>= 1.26.0, < 2.0)
|
92
|
+
ruby-progressbar (~> 1.7)
|
93
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
94
|
+
rubocop-ast (1.28.0)
|
95
|
+
parser (>= 3.2.1.0)
|
96
|
+
rubocop-performance (1.16.0)
|
97
|
+
rubocop (>= 1.7.0, < 2.0)
|
98
|
+
rubocop-ast (>= 0.4.0)
|
99
|
+
ruby-progressbar (1.13.0)
|
100
|
+
ruby2_keywords (0.0.5)
|
101
|
+
standard (1.26.0)
|
102
|
+
language_server-protocol (~> 3.17.0.2)
|
103
|
+
rubocop (~> 1.48.1)
|
104
|
+
rubocop-performance (~> 1.16.0)
|
105
|
+
turbo_tests (1.0.0)
|
106
|
+
optparse
|
107
|
+
parallel_tests
|
108
|
+
rspec
|
109
|
+
typhoeus (1.4.0)
|
110
|
+
ethon (>= 0.9.0)
|
111
|
+
tzinfo (2.0.4)
|
112
|
+
concurrent-ruby (~> 1.0)
|
113
|
+
unicode-display_width (2.4.2)
|
114
|
+
webrick (1.7.0)
|
115
|
+
yard (0.9.28)
|
116
|
+
webrick (~> 1.7.0)
|
117
|
+
zeitwerk (2.4.2)
|
118
|
+
|
119
|
+
PLATFORMS
|
120
|
+
ruby
|
121
|
+
|
122
|
+
DEPENDENCIES
|
123
|
+
ecfr!
|
124
|
+
factory_bot
|
125
|
+
faraday-typhoeus
|
126
|
+
nokogiri
|
127
|
+
parallel_tests
|
128
|
+
pry
|
129
|
+
request_store
|
130
|
+
rspec (~> 3.0)
|
131
|
+
rspec_junit_formatter
|
132
|
+
rubocop
|
133
|
+
standard (~> 1.0)
|
134
|
+
turbo_tests
|
135
|
+
yard
|
136
|
+
|
137
|
+
BUNDLED WITH
|
138
|
+
2.2.33
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2023 Critical Juncture, LLC
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
# Ecfr
|
2
|
+
|
3
|
+
Provides a Ruby API client for the eCFR.gov APIs.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'ecfr'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install ecfr
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Configuration is supported via a configuration block. Only `user_agent` is required to be configured. See `lib/ecfr/configuration.rb` for options.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
Ecfr.configure do |config|
|
27
|
+
config.user_agent = "MyProject(me@myproject.com)"
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
### XML parsing
|
32
|
+
|
33
|
+
Some endpoints return XML (like the Structure) and will be automatically parsed using Nokogiri. However we do not bundle this as a gem dependency since it may not always be used. To use this you will need to add the Nokogiri gem to your code.
|
34
|
+
|
35
|
+
### Response caching
|
36
|
+
|
37
|
+
Response caching can be enabled via a configuration option. This is a performance feature that allows the calling code to not worry about performance when different parts of the application call the same endpoints at different times in the same request. Responses are cached my HTTP method, api endpoint and requested parameters. You will need to install the [request_store](https://github.com/steveklabnik/request_store) gem when enabling this option.
|
38
|
+
|
39
|
+
If you are using request store outside of a Rails project or in a background process (eg Sidekiq) check the RequestStore documentation for how to use the required middleware.
|
40
|
+
|
41
|
+
### Parallel client
|
42
|
+
|
43
|
+
A basic parallel client is provided to support some use cases (we use it internally for our status page). This requires the use of [faraday-typhoeus](https://github.com/dleavitt/faraday-typhoeus) adapter. However we do not bundle this as a gem dependency since it may not always be used. To use the parallel client you will need to add the typhoeus faraday adapter gem to your code.
|
44
|
+
|
45
|
+
## Development
|
46
|
+
|
47
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
48
|
+
|
49
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
50
|
+
|
51
|
+
### Simple endpoints that return an array of data under a single key
|
52
|
+
|
53
|
+
For endpoints that return results like:
|
54
|
+
|
55
|
+
```
|
56
|
+
{
|
57
|
+
items: [
|
58
|
+
{name: "Item 1", active: true},
|
59
|
+
{name: "Item 2", active: true},
|
60
|
+
{name: "Item 3", active: false}
|
61
|
+
]
|
62
|
+
}
|
63
|
+
```
|
64
|
+
|
65
|
+
We support a `result_key` in the definition. In this example `result_key: :items`. This will cause each item in the items array to be instantiated as an instance of the class and delegate enumerable methods such as `.each`, `.first`, `.last`.
|
66
|
+
|
67
|
+
So the following definition:
|
68
|
+
```
|
69
|
+
class Items < Base
|
70
|
+
result_key: :items
|
71
|
+
|
72
|
+
attribute :name
|
73
|
+
attribute :active, type: boolean
|
74
|
+
|
75
|
+
def self.all
|
76
|
+
new(
|
77
|
+
get(...)
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
could be used `Items.all.each` which would iterate through an array of `Item` instances with `name` and `active` (and `active?`) methods.
|
84
|
+
|
85
|
+
|
86
|
+
### More complex endpoints
|
87
|
+
|
88
|
+
If however the endpoint returns data more like:
|
89
|
+
|
90
|
+
```
|
91
|
+
{
|
92
|
+
items: [
|
93
|
+
{name: "Item 1", active: true},
|
94
|
+
{name: "Item 2", active: true},
|
95
|
+
{name: "Item 3", active: false}
|
96
|
+
],
|
97
|
+
warehouse: "Warehouse 32",
|
98
|
+
dock: "Dock A"
|
99
|
+
}
|
100
|
+
```
|
101
|
+
|
102
|
+
then we support the following definition:
|
103
|
+
|
104
|
+
```
|
105
|
+
class Items < Base
|
106
|
+
class Item
|
107
|
+
include AttributeMethodDefinition
|
108
|
+
|
109
|
+
attribute :name
|
110
|
+
attribute :active, type: boolean
|
111
|
+
end
|
112
|
+
|
113
|
+
attribute: :items, type: Array(Item)
|
114
|
+
attribute: :dock, :warehouse
|
115
|
+
|
116
|
+
def self.all
|
117
|
+
new(
|
118
|
+
get(...)
|
119
|
+
)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
which can then be used like `result = Items.all; result.items.each...; result.warehouse`.
|
125
|
+
|
126
|
+
|
127
|
+
## Contributing
|
128
|
+
|
129
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/criticaljuncture/ecfr.
|
130
|
+
|
131
|
+
## License
|
132
|
+
|
133
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "ecfr"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/ecfr.gemspec
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/ecfr/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "ecfr"
|
7
|
+
spec.version = Ecfr::VERSION
|
8
|
+
spec.authors = ["Peregrinator"]
|
9
|
+
spec.email = ["bob.burbach@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "ecfr.federalregister.gov API client"
|
12
|
+
spec.description = "Ruby client for APIs provided by ecfr.federalregister.gov"
|
13
|
+
spec.homepage = "https://github.com/criticaljuncture/ecfr"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 2.6.0"
|
16
|
+
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
|
+
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/criticaljuncture/ecfr"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/criticaljuncture/ecfr"
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_dependency "activemodel", "~> 6.0"
|
33
|
+
spec.add_dependency "activesupport", "~> 6.0"
|
34
|
+
spec.add_dependency "faraday", "~> 2.0"
|
35
|
+
spec.add_dependency "faraday-net_http_persistent", "~> 2.0"
|
36
|
+
|
37
|
+
spec.add_development_dependency "factory_bot"
|
38
|
+
spec.add_development_dependency "parallel_tests"
|
39
|
+
spec.add_development_dependency "pry"
|
40
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
41
|
+
spec.add_development_dependency "rspec_junit_formatter"
|
42
|
+
spec.add_development_dependency "rubocop"
|
43
|
+
spec.add_development_dependency "standard", "~> 1.0"
|
44
|
+
spec.add_development_dependency "turbo_tests"
|
45
|
+
spec.add_development_dependency "yard"
|
46
|
+
|
47
|
+
# A parallel client is made available when the faraday-typhoeus adapter
|
48
|
+
# is installed. However we don't bundle this as a dependency. If you want
|
49
|
+
# to use the parallel client make sure to require it in your code.
|
50
|
+
spec.add_development_dependency "faraday-typhoeus"
|
51
|
+
|
52
|
+
# Some features of the gem support parsing XML responses
|
53
|
+
# with Nokogiri.
|
54
|
+
# However we don't bundle this as a dependency. If you want
|
55
|
+
# to use such features make sure to require it in your code.
|
56
|
+
spec.add_development_dependency "nokogiri"
|
57
|
+
|
58
|
+
# Caching of responses can be enabled and require the
|
59
|
+
# request store gem. However we don't bundle this as a
|
60
|
+
# dependency - it will need to be installed in your code.
|
61
|
+
spec.add_development_dependency "request_store"
|
62
|
+
|
63
|
+
spec.post_install_message = '
|
64
|
+
Some features of the eCFR gem support parsing XML responses, response
|
65
|
+
caching, and parallel requests.
|
66
|
+
|
67
|
+
To use these features you will beed to install the appropriate gems
|
68
|
+
(nokogiri, request_store, and faraday-typhoeus respectively) in your
|
69
|
+
application. In order to minimize depedencies and code that is loaded these
|
70
|
+
are not a default dependencies of the eCFR gem.
|
71
|
+
|
72
|
+
See the README for details of these features.
|
73
|
+
'
|
74
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module AdminService
|
3
|
+
class Agency
|
4
|
+
class Hierarchy
|
5
|
+
include AttributeMethodDefinition
|
6
|
+
extend Extensible
|
7
|
+
|
8
|
+
attribute :title,
|
9
|
+
desc: "Title number"
|
10
|
+
attribute :subtitle,
|
11
|
+
desc: "Subtitle identifier"
|
12
|
+
attribute :chapter,
|
13
|
+
desc: "Chapter identifier"
|
14
|
+
attribute :subchapter,
|
15
|
+
desc: "Subchapter identifier"
|
16
|
+
attribute :part,
|
17
|
+
desc: "Part identifier"
|
18
|
+
|
19
|
+
def to_hash
|
20
|
+
@attributes.each_with_object({}) { |attr, hsh|
|
21
|
+
hsh[attr[0]] = attr[1]
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module AdminService
|
3
|
+
class Agency < Base
|
4
|
+
require_relative "agency/hierarchy"
|
5
|
+
|
6
|
+
result_key :agencies
|
7
|
+
|
8
|
+
attribute :name, desc: "name of agency"
|
9
|
+
|
10
|
+
attribute :cfr_references, type: Array(Ecfr::Common::Hierarchy),
|
11
|
+
desc: "portions of the CFR this agency is responsible for,
|
12
|
+
expected keys are only :title, :subtitle, :chapter,
|
13
|
+
:subchapter, and :part"
|
14
|
+
|
15
|
+
attribute :children, type: Array(Agency),
|
16
|
+
desc: "sub-agencies of the current agency"
|
17
|
+
|
18
|
+
AGENCIES_PATH = "v1/agencies.json"
|
19
|
+
|
20
|
+
#
|
21
|
+
# Retrieve the list of all agencies, their subagencies
|
22
|
+
# and the portions of the CFR they are responsible for
|
23
|
+
#
|
24
|
+
# @return [[<Agency>]] an array of agency records
|
25
|
+
#
|
26
|
+
def self.all
|
27
|
+
perform(
|
28
|
+
:get,
|
29
|
+
AGENCIES_PATH
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module AdminService
|
3
|
+
class Base < Ecfr::Base
|
4
|
+
require_relative "api_documentation"
|
5
|
+
require_relative "status"
|
6
|
+
|
7
|
+
require_relative "agency"
|
8
|
+
require_relative "build"
|
9
|
+
require_relative "ecfr_correction"
|
10
|
+
require_relative "editorial_note"
|
11
|
+
require_relative "ibr_cfr_range"
|
12
|
+
require_relative "issue"
|
13
|
+
require_relative "site_notification"
|
14
|
+
|
15
|
+
SERVICE_PATH = "/admin/api/admin"
|
16
|
+
|
17
|
+
def self.base_url
|
18
|
+
Ecfr.config.admin_service_url || Ecfr.config.base_url
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.service_name
|
22
|
+
"Admin Service"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module AdminService
|
3
|
+
class Build < Base
|
4
|
+
result_key :builds
|
5
|
+
|
6
|
+
attribute :id,
|
7
|
+
desc: "build id"
|
8
|
+
attribute :status,
|
9
|
+
desc: "build status - either *Success* or *Failure*"
|
10
|
+
|
11
|
+
attribute :expired,
|
12
|
+
type: :boolean
|
13
|
+
attribute :previewable,
|
14
|
+
type: :boolean
|
15
|
+
|
16
|
+
BUILDS_PATH = "v1/builds"
|
17
|
+
|
18
|
+
#
|
19
|
+
# Retrieve a Build by id
|
20
|
+
#
|
21
|
+
# @param [<String>] build_id - id of the desired build
|
22
|
+
#
|
23
|
+
# @return [<Build>] data for a single build
|
24
|
+
#
|
25
|
+
def self.find(build_id)
|
26
|
+
perform(
|
27
|
+
:get,
|
28
|
+
build_path(build_id)
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.build_path(build_id)
|
33
|
+
"#{BUILDS_PATH}/#{build_id}"
|
34
|
+
end
|
35
|
+
private_class_method :build_path
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module AdminService
|
3
|
+
class EcfrCorrection
|
4
|
+
class CfrReference
|
5
|
+
include AttributeMethodDefinition
|
6
|
+
extend Extensible
|
7
|
+
|
8
|
+
attribute :cfr_reference,
|
9
|
+
desc: "CFR reference in the form '40 CFR 100'"
|
10
|
+
|
11
|
+
attribute :hierarchy,
|
12
|
+
type: Ecfr::Common::Hierarchy,
|
13
|
+
desc: "hash of CFR hierarchy attributes"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|