uls 0.2.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.
- checksums.yaml +7 -0
- data/.gitignore +56 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +55 -0
- data/LICENSE.txt +21 -0
- data/README.md +117 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/uls/codes/applicant_type.rb +22 -0
- data/lib/uls/codes/base.rb +43 -0
- data/lib/uls/codes/entity_type.rb +15 -0
- data/lib/uls/codes/license_status.rb +13 -0
- data/lib/uls/codes/status.rb +11 -0
- data/lib/uls/configuration.rb +11 -0
- data/lib/uls/dat_file.rb +43 -0
- data/lib/uls/database.rb +72 -0
- data/lib/uls/records/base.rb +80 -0
- data/lib/uls/records/entity.rb +32 -0
- data/lib/uls/records/form_primary.rb +56 -0
- data/lib/uls/records/form_secondary.rb +36 -0
- data/lib/uls/retriever.rb +89 -0
- data/lib/uls/version.rb +3 -0
- data/lib/uls.rb +34 -0
- data/uls.gemspec +43 -0
- metadata +169 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e4c602c4bd5b7ceb3ee7b0378a7a0d66ec59e31e6bb82f29d8f334b7ea86c269
|
|
4
|
+
data.tar.gz: e7529e3a187621009257ef3b5a623103f8183233bf53d76c62115a538ae9155f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 329af07c3c6b4aa5636a4d68b9f27b35e2626547be4e666df10b2e2c04cd04791ba0af137d51371209ec75d4bdb16471b51d77a7f9aa859958bdccc195023e20
|
|
7
|
+
data.tar.gz: 35bcd041e58ad4a0caa83978298152858b558814b8c57dcb46591e9a738cf05189e19edd78995953f9ca6396022e244abc6e6da4666b499b6fb598eb1c5ebe85
|
data/.gitignore
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
/.config
|
|
4
|
+
/coverage/
|
|
5
|
+
/InstalledFiles
|
|
6
|
+
/pkg/
|
|
7
|
+
/spec/reports/
|
|
8
|
+
/spec/examples.txt
|
|
9
|
+
/test/tmp/
|
|
10
|
+
/test/version_tmp/
|
|
11
|
+
/tmp/
|
|
12
|
+
.rspec_status
|
|
13
|
+
.idea
|
|
14
|
+
|
|
15
|
+
# Used by dotenv library to load environment variables.
|
|
16
|
+
# .env
|
|
17
|
+
|
|
18
|
+
## Specific to RubyMotion:
|
|
19
|
+
.dat*
|
|
20
|
+
.repl_history
|
|
21
|
+
build/
|
|
22
|
+
*.bridgesupport
|
|
23
|
+
build-iPhoneOS/
|
|
24
|
+
build-iPhoneSimulator/
|
|
25
|
+
|
|
26
|
+
## Specific to RubyMotion (use of CocoaPods):
|
|
27
|
+
#
|
|
28
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
|
29
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
|
30
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
|
31
|
+
#
|
|
32
|
+
# vendor/Pods/
|
|
33
|
+
|
|
34
|
+
## Documentation cache and generated files:
|
|
35
|
+
/.yardoc/
|
|
36
|
+
/_yardoc/
|
|
37
|
+
/doc/
|
|
38
|
+
/rdoc/
|
|
39
|
+
|
|
40
|
+
## Environment normalization:
|
|
41
|
+
/.bundle/
|
|
42
|
+
/vendor/bundle
|
|
43
|
+
/lib/bundler/man/
|
|
44
|
+
|
|
45
|
+
# for a library or gem, you might want to ignore these files since the code is
|
|
46
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
47
|
+
# Gemfile.lock
|
|
48
|
+
# .ruby-version
|
|
49
|
+
# .ruby-gemset
|
|
50
|
+
|
|
51
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
52
|
+
.rvmrc
|
|
53
|
+
|
|
54
|
+
# Editor files
|
|
55
|
+
*.swp
|
|
56
|
+
.DS_Store
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
+
orientation.
|
|
11
|
+
|
|
12
|
+
## Our Standards
|
|
13
|
+
|
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
|
15
|
+
include:
|
|
16
|
+
|
|
17
|
+
* Using welcoming and inclusive language
|
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
|
19
|
+
* Gracefully accepting constructive criticism
|
|
20
|
+
* Focusing on what is best for the community
|
|
21
|
+
* Showing empathy towards other community members
|
|
22
|
+
|
|
23
|
+
Examples of unacceptable behavior by participants include:
|
|
24
|
+
|
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
26
|
+
advances
|
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
28
|
+
* Public or private harassment
|
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
|
30
|
+
address, without explicit permission
|
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
+
professional setting
|
|
33
|
+
|
|
34
|
+
## Our Responsibilities
|
|
35
|
+
|
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
|
38
|
+
response to any instances of unacceptable behavior.
|
|
39
|
+
|
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
|
44
|
+
threatening, offensive, or harmful.
|
|
45
|
+
|
|
46
|
+
## Scope
|
|
47
|
+
|
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
|
49
|
+
when an individual is representing the project or its community. Examples of
|
|
50
|
+
representing a project or community include using an official project e-mail
|
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
|
53
|
+
further defined and clarified by project maintainers.
|
|
54
|
+
|
|
55
|
+
## Enforcement
|
|
56
|
+
|
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
+
reported by contacting the project team at garth@codejunkie.org. All
|
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
|
63
|
+
|
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
|
66
|
+
members of the project's leadership.
|
|
67
|
+
|
|
68
|
+
## Attribution
|
|
69
|
+
|
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
|
72
|
+
|
|
73
|
+
[homepage]: http://contributor-covenant.org
|
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
uls (0.2.0)
|
|
5
|
+
rubyzip (~> 2.3.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
codecov (0.6.0)
|
|
11
|
+
simplecov (>= 0.15, < 0.22)
|
|
12
|
+
coderay (1.1.2)
|
|
13
|
+
diff-lcs (1.3)
|
|
14
|
+
docile (1.4.0)
|
|
15
|
+
method_source (0.9.2)
|
|
16
|
+
pry (0.12.2)
|
|
17
|
+
coderay (~> 1.1.0)
|
|
18
|
+
method_source (~> 0.9.0)
|
|
19
|
+
rake (12.3.3)
|
|
20
|
+
rspec (3.8.0)
|
|
21
|
+
rspec-core (~> 3.8.0)
|
|
22
|
+
rspec-expectations (~> 3.8.0)
|
|
23
|
+
rspec-mocks (~> 3.8.0)
|
|
24
|
+
rspec-core (3.8.0)
|
|
25
|
+
rspec-support (~> 3.8.0)
|
|
26
|
+
rspec-expectations (3.8.3)
|
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
28
|
+
rspec-support (~> 3.8.0)
|
|
29
|
+
rspec-mocks (3.8.0)
|
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
31
|
+
rspec-support (~> 3.8.0)
|
|
32
|
+
rspec-support (3.8.0)
|
|
33
|
+
rubyzip (2.3.0)
|
|
34
|
+
simplecov (0.21.2)
|
|
35
|
+
docile (~> 1.1)
|
|
36
|
+
simplecov-html (~> 0.11)
|
|
37
|
+
simplecov_json_formatter (~> 0.1)
|
|
38
|
+
simplecov-html (0.12.3)
|
|
39
|
+
simplecov_json_formatter (0.1.4)
|
|
40
|
+
timecop (0.9.5)
|
|
41
|
+
|
|
42
|
+
PLATFORMS
|
|
43
|
+
ruby
|
|
44
|
+
|
|
45
|
+
DEPENDENCIES
|
|
46
|
+
bundler (>= 2.2.33)
|
|
47
|
+
codecov (~> 0.6.0)
|
|
48
|
+
pry (~> 0.12.2)
|
|
49
|
+
rake (~> 12.3.3)
|
|
50
|
+
rspec (~> 3.0)
|
|
51
|
+
timecop (~> 0.9.5)
|
|
52
|
+
uls!
|
|
53
|
+
|
|
54
|
+
BUNDLED WITH
|
|
55
|
+
2.3.16
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 Garth Dubin
|
|
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,117 @@
|
|
|
1
|
+
[](https://travis-ci.com/gdubin/uls) [](https://codecov.io/gh/gdubin/uls)
|
|
2
|
+
|
|
3
|
+
# ULS
|
|
4
|
+
|
|
5
|
+
This gem is used for parsing the database/files from the FCC Universal Licensing System. These files are often relevant to amateur radio enthusiasts.
|
|
6
|
+
|
|
7
|
+
You may download the source files from the FCC by visiting the [Universal Licensing System Databases](http://wireless.fcc.gov/uls/index.htm?job=transaction&page=weekly) page.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem 'uls'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
And then execute:
|
|
18
|
+
|
|
19
|
+
$ bundle install
|
|
20
|
+
|
|
21
|
+
Or install it yourself as:
|
|
22
|
+
|
|
23
|
+
$ gem install uls
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
##### Configuration
|
|
28
|
+
|
|
29
|
+
Configuration of various options are available via the base ULS module. To configure ULS related settings:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
ULS.configure do |config|
|
|
33
|
+
config.tmpdir = '/your/tmpdir/here'
|
|
34
|
+
end
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The options currently available are as follows:
|
|
38
|
+
|
|
39
|
+
|option|default|description|
|
|
40
|
+
|------|-------|-----------|
|
|
41
|
+
|tmpdir|Dir.tmpdir|A location for ULS database files to be downloaded to and unpacked. Defaults to whatever the [Dir#tmpdir](https://ruby-doc.org/stdlib-2.5.3/libdoc/tmpdir/rdoc/Dir.html#method-c-tmpdir) is set to for your system.|
|
|
42
|
+
|
|
43
|
+
##### Retrieving Databases
|
|
44
|
+
|
|
45
|
+
The FCC splits their data into several categories. Each category is represented as a class method on `ULS::Retriever`. From there, you may select either the daily or weekly file for a specific types. Types are driven by the category but for most categories the types are `applications` or `licenses`.
|
|
46
|
+
|
|
47
|
+
For example, to download the entire license database for amateur radio:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
database = ULS::Retriever.amateur_radio.weekly(:licenses)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The weekly database contains all of the data and is republished weekly. Daily database updates are also provided that are much smaller and only contain the specified day's data:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
database = ULS::Retriever.amateur_radio.daily(:licenses)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The above line will download the previous day's updates. It also takes a second parameter which corresponds to the [Date#wday](https://apidock.com/ruby/Date/wday) value. So if you wanted to download last Tuesday's daily license file:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
database = ULS::Retriever.amateur_radio.daily(:licenses, 2)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
##### Parsing Databases
|
|
66
|
+
|
|
67
|
+
After you have an available database to work with, you may start interacting with the records within it:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
database.name_and_addresses.each_record do |record|
|
|
71
|
+
# do something
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
When you're done with a database, you can clean up the extracted files using:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
database.clean
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If you're completely done with this version of the database then this command will remove the zip file:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
database.delete
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
If you want to do both:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
database.delete!
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The above will not only remove all the extracted files but also delete the compressed file.
|
|
94
|
+
|
|
95
|
+
There may be instances where you want to keep the source files around. A database can be reconstructed from the filesystem by calling:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
ULS::Database.new('/path/to/zip/or/extracted/directory')
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
You may pass the path to the zip file, or the already extracted directory, to interact with the records within.
|
|
102
|
+
|
|
103
|
+
## Development
|
|
104
|
+
|
|
105
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
106
|
+
|
|
107
|
+
## Contributing
|
|
108
|
+
|
|
109
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/gdubin/uls. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
114
|
+
|
|
115
|
+
## Code of Conduct
|
|
116
|
+
|
|
117
|
+
Everyone interacting in the ULS project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/uls/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "uls"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
module Codes
|
|
3
|
+
class ApplicantType < Base
|
|
4
|
+
define_uls_code 'B', description: 'Amateur Club'
|
|
5
|
+
define_uls_code 'C', description: 'Corporation'
|
|
6
|
+
define_uls_code 'D', description: 'General Partnership'
|
|
7
|
+
define_uls_code 'E', description: 'Limited Partnership'
|
|
8
|
+
define_uls_code 'F', description: 'Limited Liability Partnership'
|
|
9
|
+
define_uls_code 'G', description: 'Government Entity'
|
|
10
|
+
define_uls_code 'H', description: 'Other'
|
|
11
|
+
define_uls_code 'I', description: 'Individual'
|
|
12
|
+
define_uls_code 'J', description: 'Joint Venture'
|
|
13
|
+
define_uls_code 'L', description: 'Limited Liability Company'
|
|
14
|
+
define_uls_code 'M', description: 'Military Recreation'
|
|
15
|
+
define_uls_code 'O', description: 'Consortium'
|
|
16
|
+
define_uls_code 'P', description: 'Partnership'
|
|
17
|
+
define_uls_code 'R', description: 'RACES'
|
|
18
|
+
define_uls_code 'T', description: 'Trust'
|
|
19
|
+
define_uls_code 'U', description: 'Unincorporated Association'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
module Codes
|
|
3
|
+
# A base class to handle the various codes/descriptions that the ULS database
|
|
4
|
+
# uses throughout their records.
|
|
5
|
+
class Base
|
|
6
|
+
attr_accessor :code
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def define_uls_code(code, description:)
|
|
10
|
+
possible_codes[code] = description
|
|
11
|
+
|
|
12
|
+
# Takes the description and turns it into a question mark
|
|
13
|
+
# method for quick testing. For example:
|
|
14
|
+
#
|
|
15
|
+
# 'Active' -> :active?
|
|
16
|
+
# 'Pending Legal Status' -> :pending_legal_status?
|
|
17
|
+
question_method = description.downcase
|
|
18
|
+
question_method.tr!(' ', '_')
|
|
19
|
+
question_method += '?'
|
|
20
|
+
define_method question_method.to_sym do
|
|
21
|
+
self.code.eql?(code)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def possible_codes
|
|
26
|
+
@possible_codes ||= {}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def initialize(code = nil)
|
|
31
|
+
return if code.nil?
|
|
32
|
+
|
|
33
|
+
raise ArgumentError, "'#{code}' is an invalid code." unless self.class.possible_codes.include?(code)
|
|
34
|
+
|
|
35
|
+
self.code = code
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def description
|
|
39
|
+
self.class.possible_codes[code] unless code.nil?
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
module Codes
|
|
3
|
+
class EntityType < Base
|
|
4
|
+
define_uls_code 'CE', description: 'Transferee Contact'
|
|
5
|
+
define_uls_code 'CL', description: 'Licensee Contact'
|
|
6
|
+
define_uls_code 'CR', description: 'Assignor or Transferor Contact'
|
|
7
|
+
define_uls_code 'CS', description: 'Lessee Contact'
|
|
8
|
+
define_uls_code 'E', description: 'Transferee'
|
|
9
|
+
define_uls_code 'L', description: 'Licensee or Assignee'
|
|
10
|
+
define_uls_code 'O', description: 'Owner'
|
|
11
|
+
define_uls_code 'R', description: 'Assignor or Transferor'
|
|
12
|
+
define_uls_code 'S', description: 'Lessee'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
module Codes
|
|
3
|
+
class LicenseStatus < Base
|
|
4
|
+
define_uls_code 'A', description: 'Active'
|
|
5
|
+
define_uls_code 'C', description: 'Canceled'
|
|
6
|
+
define_uls_code 'E', description: 'Expired'
|
|
7
|
+
define_uls_code 'L', description: 'Pending Legal Status'
|
|
8
|
+
define_uls_code 'P', description: 'Parent Station Canceled'
|
|
9
|
+
define_uls_code 'T', description: 'Terminated'
|
|
10
|
+
define_uls_code 'X', description: 'Term Pending'
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
module Codes
|
|
3
|
+
class Status < Base
|
|
4
|
+
# Code value is intentionally blank. That's how the FCC represents
|
|
5
|
+
# an active status: blank or null.
|
|
6
|
+
define_uls_code '', description: 'Active'
|
|
7
|
+
define_uls_code 'X', description: 'Termination Pending'
|
|
8
|
+
define_uls_code 'T', description: 'Terminated'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
data/lib/uls/dat_file.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
# Used to interact with the FCC DAT file.
|
|
3
|
+
class DatFile
|
|
4
|
+
attr_accessor :path
|
|
5
|
+
|
|
6
|
+
def initialize(path)
|
|
7
|
+
self.path = path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def each_line(&_block)
|
|
11
|
+
return unless File.exist?(path)
|
|
12
|
+
|
|
13
|
+
File.foreach(path) { |line| yield(line) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def each_record(&_block)
|
|
17
|
+
return unless File.exist?(path)
|
|
18
|
+
|
|
19
|
+
File.foreach(path) do |line|
|
|
20
|
+
record = line_to_record(line)
|
|
21
|
+
yield(record)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def record_class(record_type)
|
|
28
|
+
case record_type
|
|
29
|
+
when 'EN'
|
|
30
|
+
Records::Entity
|
|
31
|
+
when 'HD'
|
|
32
|
+
Records::FormPrimary
|
|
33
|
+
when 'AD'
|
|
34
|
+
Records::FormSecondary
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def line_to_record(line)
|
|
39
|
+
klass = record_class(line[0..1])
|
|
40
|
+
klass.new(line) unless klass.nil?
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/uls/database.rb
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'zip'
|
|
2
|
+
|
|
3
|
+
module ULS
|
|
4
|
+
# Used to interact with the FCC 'database' files. These files are compressed
|
|
5
|
+
# files containing several individual pipe-delimited data files.
|
|
6
|
+
class Database
|
|
7
|
+
attr_accessor :compressed_file
|
|
8
|
+
|
|
9
|
+
# Use to construct an interface to the Database zipfile/directory
|
|
10
|
+
# retrieved from the FCC. The filename may either be a zip file,
|
|
11
|
+
# in which case it will be extracted to the temporary directory, or
|
|
12
|
+
# may be an already extract directory containing the various 'database'
|
|
13
|
+
# files.
|
|
14
|
+
def initialize(filename)
|
|
15
|
+
path = Pathname.new(filename)
|
|
16
|
+
if path.directory?
|
|
17
|
+
@extracted_path = filename
|
|
18
|
+
else
|
|
19
|
+
@compressed_file = filename
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def name_and_addresses
|
|
24
|
+
extract unless extracted?
|
|
25
|
+
|
|
26
|
+
DatFile.new("#{extracted_path}/EN.dat")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def form_primary
|
|
30
|
+
extract unless extracted?
|
|
31
|
+
|
|
32
|
+
DatFile.new("#{extracted_path}/HD.dat")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def form_secondary
|
|
36
|
+
extract unless extracted?
|
|
37
|
+
|
|
38
|
+
DatFile.new("#{extracted_path}/AD.dat")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def extracted_path
|
|
42
|
+
@extracted_path ||= "#{ULS.configuration.tmpdir}/uls_#{Time.now.to_i}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def extracted?
|
|
46
|
+
Dir.exist?(extracted_path)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def extract
|
|
50
|
+
FileUtils.mkdir_p(extracted_path)
|
|
51
|
+
Zip::File.open(compressed_file) do |opened_file|
|
|
52
|
+
opened_file.each do |entry|
|
|
53
|
+
entry.extract("#{extracted_path}/#{entry.name}")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def clean
|
|
59
|
+
File.rmdir(extracted_path)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def delete
|
|
63
|
+
File.delete(compressed_file)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def delete!
|
|
67
|
+
clean if extracted?
|
|
68
|
+
|
|
69
|
+
delete
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
|
|
3
|
+
module ULS
|
|
4
|
+
module Records
|
|
5
|
+
# The base class for all ULS records we'll be parsing. This handles some
|
|
6
|
+
# of the helper methods for defining attributes and actually performing
|
|
7
|
+
# the parsing after the record is defined.
|
|
8
|
+
class Base
|
|
9
|
+
DEFAULT_ATTRIBUTE_OPTIONS = { type: :string }.freeze
|
|
10
|
+
FIELD_SEPARATOR = '|'.freeze
|
|
11
|
+
BLANK_RE = /\A[[:space:]]*\z/ # h/t Rails .blank? implementation
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def uls_field_accessor(symbol, options = {})
|
|
15
|
+
field = { attribute: symbol }
|
|
16
|
+
field.merge!(options)
|
|
17
|
+
field = DEFAULT_ATTRIBUTE_OPTIONS.merge(field)
|
|
18
|
+
|
|
19
|
+
fields << field
|
|
20
|
+
|
|
21
|
+
attr_accessor symbol
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def fields
|
|
25
|
+
@fields ||= []
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def initialize(line = nil)
|
|
30
|
+
return if line.nil?
|
|
31
|
+
|
|
32
|
+
from_row(line)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def from_row(line)
|
|
36
|
+
values = line.split(FIELD_SEPARATOR)
|
|
37
|
+
values.shift
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
values.each_with_index do |value, index|
|
|
41
|
+
break if index >= self.class.fields.size
|
|
42
|
+
|
|
43
|
+
field = self.class.fields[index]
|
|
44
|
+
setter = "#{field[:attribute]}="
|
|
45
|
+
value = convert(value, field[:type])
|
|
46
|
+
|
|
47
|
+
send(setter, value)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
protected
|
|
52
|
+
|
|
53
|
+
def convert(value, type)
|
|
54
|
+
begin
|
|
55
|
+
return type.new(value) if type.respond_to?(:ancestors) && type.ancestors.include?(ULS::Codes::Base)
|
|
56
|
+
rescue ArgumentError => e
|
|
57
|
+
return nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# The FCC uses blank values to represent certain codes so this check is after
|
|
61
|
+
# any code conversion that may occur. Beyond the codes, we want to set blanks
|
|
62
|
+
# to nil since that's what they represent normally.
|
|
63
|
+
return nil if blank?(value)
|
|
64
|
+
|
|
65
|
+
case type
|
|
66
|
+
when :numeric
|
|
67
|
+
value.to_i
|
|
68
|
+
when :date
|
|
69
|
+
Date.strptime(value, '%m/%d/%Y')
|
|
70
|
+
else
|
|
71
|
+
value
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def blank?(value)
|
|
76
|
+
return true if value.nil? || BLANK_RE.match?(value)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
module Records
|
|
3
|
+
class Entity < Base
|
|
4
|
+
uls_field_accessor :unique_system_identifier, type: :numeric
|
|
5
|
+
uls_field_accessor :file_number
|
|
6
|
+
uls_field_accessor :ebf_number
|
|
7
|
+
uls_field_accessor :call_sign
|
|
8
|
+
uls_field_accessor :entity_type, type: ULS::Codes::EntityType
|
|
9
|
+
uls_field_accessor :licensee_id
|
|
10
|
+
uls_field_accessor :entity_name
|
|
11
|
+
uls_field_accessor :first_name
|
|
12
|
+
uls_field_accessor :middle_name
|
|
13
|
+
uls_field_accessor :last_name
|
|
14
|
+
uls_field_accessor :suffix
|
|
15
|
+
uls_field_accessor :phone
|
|
16
|
+
uls_field_accessor :fax
|
|
17
|
+
uls_field_accessor :email
|
|
18
|
+
uls_field_accessor :street_address
|
|
19
|
+
uls_field_accessor :city
|
|
20
|
+
uls_field_accessor :state
|
|
21
|
+
uls_field_accessor :zipcode
|
|
22
|
+
uls_field_accessor :po_box
|
|
23
|
+
uls_field_accessor :attention_line
|
|
24
|
+
uls_field_accessor :sgin
|
|
25
|
+
uls_field_accessor :frn
|
|
26
|
+
uls_field_accessor :applicant_type, type: ULS::Codes::ApplicantType
|
|
27
|
+
uls_field_accessor :applicant_type_other
|
|
28
|
+
uls_field_accessor :status, type: ULS::Codes::Status
|
|
29
|
+
uls_field_accessor :status_date, type: :date
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
module Records
|
|
3
|
+
# This represents the main form 605 data that carries over to the license.
|
|
4
|
+
class FormPrimary < Base
|
|
5
|
+
uls_field_accessor :unique_system_identifier, type: :numeric
|
|
6
|
+
uls_field_accessor :uls_file_number
|
|
7
|
+
uls_field_accessor :ebf_number
|
|
8
|
+
uls_field_accessor :call_sign
|
|
9
|
+
uls_field_accessor :license_status, type: ULS::Codes::LicenseStatus
|
|
10
|
+
uls_field_accessor :radio_service_code
|
|
11
|
+
uls_field_accessor :grant_date, type: :date
|
|
12
|
+
uls_field_accessor :expired_date, type: :date
|
|
13
|
+
uls_field_accessor :cancellation_date, type: :date
|
|
14
|
+
uls_field_accessor :eligibility_rule_num
|
|
15
|
+
uls_field_accessor :applicant_type_code_reserved
|
|
16
|
+
uls_field_accessor :alien
|
|
17
|
+
uls_field_accessor :alien_government
|
|
18
|
+
uls_field_accessor :alien_corporation
|
|
19
|
+
uls_field_accessor :alien_officer
|
|
20
|
+
uls_field_accessor :alien_control
|
|
21
|
+
uls_field_accessor :revoked
|
|
22
|
+
uls_field_accessor :convicted
|
|
23
|
+
uls_field_accessor :adjudged
|
|
24
|
+
uls_field_accessor :involved_reserved
|
|
25
|
+
uls_field_accessor :common_carrier
|
|
26
|
+
uls_field_accessor :non_common_carrier
|
|
27
|
+
uls_field_accessor :private_comm
|
|
28
|
+
uls_field_accessor :fixed
|
|
29
|
+
uls_field_accessor :mobile
|
|
30
|
+
uls_field_accessor :radiolocation
|
|
31
|
+
uls_field_accessor :satellite
|
|
32
|
+
uls_field_accessor :developmental_or_sta
|
|
33
|
+
uls_field_accessor :interconnected_service
|
|
34
|
+
uls_field_accessor :certifier_first_name
|
|
35
|
+
uls_field_accessor :certifier_mi
|
|
36
|
+
uls_field_accessor :certifier_last_name
|
|
37
|
+
uls_field_accessor :certifier_suffix
|
|
38
|
+
uls_field_accessor :certifier_title
|
|
39
|
+
uls_field_accessor :gender
|
|
40
|
+
uls_field_accessor :african_american
|
|
41
|
+
uls_field_accessor :native_american
|
|
42
|
+
uls_field_accessor :hawaiian
|
|
43
|
+
uls_field_accessor :asian
|
|
44
|
+
uls_field_accessor :white
|
|
45
|
+
uls_field_accessor :ethnicity
|
|
46
|
+
uls_field_accessor :effective_date
|
|
47
|
+
uls_field_accessor :last_action_date
|
|
48
|
+
uls_field_accessor :auction_id, type: :numeric
|
|
49
|
+
uls_field_accessor :reg_stat_broad_serv
|
|
50
|
+
uls_field_accessor :band_manager
|
|
51
|
+
uls_field_accessor :type_serv_broad_serv
|
|
52
|
+
uls_field_accessor :alien_ruling
|
|
53
|
+
uls_field_accessor :licensee_name_change
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module ULS
|
|
2
|
+
module Records
|
|
3
|
+
# This represents the Main Form 605 data that does not carry over to the license.
|
|
4
|
+
class FormSecondary < Base
|
|
5
|
+
uls_field_accessor :unique_system_identifier, type: :numeric
|
|
6
|
+
uls_field_accessor :uls_file_number
|
|
7
|
+
uls_field_accessor :ebf_number
|
|
8
|
+
uls_field_accessor :application_purpose
|
|
9
|
+
uls_field_accessor :application_status
|
|
10
|
+
uls_field_accessor :application_fee_exempt
|
|
11
|
+
uls_field_accessor :regulatory_fee_exempt
|
|
12
|
+
uls_field_accessor :source
|
|
13
|
+
uls_field_accessor :requested_expiration_date_mmdd
|
|
14
|
+
uls_field_accessor :receipt_date
|
|
15
|
+
uls_field_accessor :notification_code
|
|
16
|
+
uls_field_accessor :notification_date
|
|
17
|
+
uls_field_accessor :expanding_area_or_contour
|
|
18
|
+
uls_field_accessor :change_type
|
|
19
|
+
uls_field_accessor :original_application_purpose
|
|
20
|
+
uls_field_accessor :requesting_a_waiver
|
|
21
|
+
uls_field_accessor :how_many_waivers_requested, type: :numeric
|
|
22
|
+
uls_field_accessor :any_attachments
|
|
23
|
+
uls_field_accessor :number_of_requested_sids, type: :numeric
|
|
24
|
+
uls_field_accessor :fee_control_num
|
|
25
|
+
uls_field_accessor :date_entered
|
|
26
|
+
uls_field_accessor :reason
|
|
27
|
+
uls_field_accessor :frequency_coordination_indicat
|
|
28
|
+
uls_field_accessor :emergency_sta
|
|
29
|
+
uls_field_accessor :overall_change_type
|
|
30
|
+
uls_field_accessor :slow_growth_ind
|
|
31
|
+
uls_field_accessor :previous_waiver
|
|
32
|
+
uls_field_accessor :waiver_deferral_fee
|
|
33
|
+
uls_field_accessor :has_term_pending_ind
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
require 'open-uri'
|
|
3
|
+
|
|
4
|
+
module ULS
|
|
5
|
+
class Retriever
|
|
6
|
+
APPLICATION_PREFIX = 'a'.freeze
|
|
7
|
+
LICENSE_PREFIX = 'l'.freeze
|
|
8
|
+
|
|
9
|
+
SERVICES = {
|
|
10
|
+
amateur_radio: {
|
|
11
|
+
filename: {
|
|
12
|
+
daily: 'am',
|
|
13
|
+
weekly: 'amat'
|
|
14
|
+
},
|
|
15
|
+
records: {
|
|
16
|
+
applications: APPLICATION_PREFIX,
|
|
17
|
+
licenses: LICENSE_PREFIX
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
# Different base URLs whether we're looking for the daily updates or the full
|
|
23
|
+
# weekly downloads.
|
|
24
|
+
DAILY_BASE_URL = 'ftp://wirelessftp.fcc.gov/pub/uls/daily'.freeze
|
|
25
|
+
WEEKLY_BASE_URL = 'ftp://wirelessftp.fcc.gov/pub/uls/complete'.freeze
|
|
26
|
+
|
|
27
|
+
attr_accessor :service
|
|
28
|
+
|
|
29
|
+
def self.amateur_radio
|
|
30
|
+
Retriever.new(:amateur_radio)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def initialize(service)
|
|
34
|
+
raise ArgumentError, "Invalid service #{service}" unless services.include?(service)
|
|
35
|
+
|
|
36
|
+
self.service = service
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def weekly_url(type)
|
|
40
|
+
raise ArgumentError, "Invalid type #{type}" unless types.include?(type)
|
|
41
|
+
|
|
42
|
+
prefix = SERVICES[service][:records][type]
|
|
43
|
+
name = SERVICES[service][:filename][:weekly]
|
|
44
|
+
|
|
45
|
+
"#{WEEKLY_BASE_URL}/#{prefix}_#{name}.zip"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def weekly(type)
|
|
49
|
+
url = weekly_url(type)
|
|
50
|
+
download(url)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def daily_url(type, wday = Date.new.prev_day.wday)
|
|
54
|
+
raise ArgumentError, "Invalid type #{type}" unless types.include?(type)
|
|
55
|
+
|
|
56
|
+
abbreviated_day = Date::ABBR_DAYNAMES[wday].downcase
|
|
57
|
+
prefix = SERVICES[service][:records][type]
|
|
58
|
+
name = SERVICES[service][:filename][:daily]
|
|
59
|
+
|
|
60
|
+
"#{DAILY_BASE_URL}/#{prefix}_#{name}_#{abbreviated_day}.zip"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def daily(type, wday = Date.new.prev_day.wday)
|
|
64
|
+
url = daily_url(type, wday)
|
|
65
|
+
download(url)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def types
|
|
69
|
+
SERVICES[service][:records].keys
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def services
|
|
73
|
+
SERVICES.keys
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
protected
|
|
77
|
+
|
|
78
|
+
def download(url)
|
|
79
|
+
filename = url.split('/').last
|
|
80
|
+
path = "#{ULS.configuration.tmpdir}/#{filename}"
|
|
81
|
+
|
|
82
|
+
File.open(path, 'w') do |file|
|
|
83
|
+
IO.copy_stream(open(url), file)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
path
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
data/lib/uls/version.rb
ADDED
data/lib/uls.rb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'uls/version'
|
|
2
|
+
require 'uls/configuration'
|
|
3
|
+
require 'uls/database'
|
|
4
|
+
require 'uls/dat_file'
|
|
5
|
+
require 'uls/retriever'
|
|
6
|
+
require 'uls/codes/base'
|
|
7
|
+
require 'uls/codes/status'
|
|
8
|
+
require 'uls/codes/license_status'
|
|
9
|
+
require 'uls/codes/applicant_type'
|
|
10
|
+
require 'uls/codes/entity_type'
|
|
11
|
+
require 'uls/records/base'
|
|
12
|
+
require 'uls/records/form_primary'
|
|
13
|
+
require 'uls/records/form_secondary'
|
|
14
|
+
require 'uls/records/entity'
|
|
15
|
+
|
|
16
|
+
# This gem is for parsing the FCC ULS database files available from the FCC website.
|
|
17
|
+
# For additional details, visit http://github.com/gdubin/uls
|
|
18
|
+
module ULS
|
|
19
|
+
class << self
|
|
20
|
+
attr_writer :configuration
|
|
21
|
+
|
|
22
|
+
def configuration
|
|
23
|
+
@configuration ||= Configuration.new
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.reset
|
|
28
|
+
@configuration = Configuration.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.configure(&_block)
|
|
32
|
+
yield(configuration)
|
|
33
|
+
end
|
|
34
|
+
end
|
data/uls.gemspec
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require "uls/version"
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "uls"
|
|
8
|
+
spec.version = ULS::VERSION
|
|
9
|
+
spec.authors = ["Garth Dubin"]
|
|
10
|
+
spec.email = ["garth@codejunkie.org"]
|
|
11
|
+
|
|
12
|
+
spec.summary = %q{Parsing library for FCC ULS databases.}
|
|
13
|
+
spec.description = %q{Handles the parsing of the FCC ULS databases.}
|
|
14
|
+
spec.homepage = "http://github.com/gdubin/uls"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
19
|
+
if spec.respond_to?(:metadata)
|
|
20
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
21
|
+
else
|
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
|
23
|
+
"public gem pushes."
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Specify which files should be added to the gem when it is released.
|
|
27
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
28
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
29
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
30
|
+
end
|
|
31
|
+
spec.bindir = "exe"
|
|
32
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
33
|
+
spec.require_paths = ["lib"]
|
|
34
|
+
|
|
35
|
+
spec.add_development_dependency "bundler", ">= 2.2.33"
|
|
36
|
+
spec.add_development_dependency "rake", "~> 12.3.3"
|
|
37
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
|
38
|
+
spec.add_development_dependency "pry", "~> 0.12.2"
|
|
39
|
+
spec.add_development_dependency "codecov", "~> 0.6.0"
|
|
40
|
+
spec.add_development_dependency "timecop", "~> 0.9.5"
|
|
41
|
+
|
|
42
|
+
spec.add_runtime_dependency 'rubyzip', '~> 2.3.0'
|
|
43
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: uls
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Garth Dubin
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2022-06-17 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 2.2.33
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 2.2.33
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 12.3.3
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 12.3.3
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: pry
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 0.12.2
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 0.12.2
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: codecov
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 0.6.0
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 0.6.0
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: timecop
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: 0.9.5
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: 0.9.5
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rubyzip
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 2.3.0
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 2.3.0
|
|
111
|
+
description: Handles the parsing of the FCC ULS databases.
|
|
112
|
+
email:
|
|
113
|
+
- garth@codejunkie.org
|
|
114
|
+
executables: []
|
|
115
|
+
extensions: []
|
|
116
|
+
extra_rdoc_files: []
|
|
117
|
+
files:
|
|
118
|
+
- ".gitignore"
|
|
119
|
+
- ".rspec"
|
|
120
|
+
- ".travis.yml"
|
|
121
|
+
- CODE_OF_CONDUCT.md
|
|
122
|
+
- Gemfile
|
|
123
|
+
- Gemfile.lock
|
|
124
|
+
- LICENSE.txt
|
|
125
|
+
- README.md
|
|
126
|
+
- Rakefile
|
|
127
|
+
- bin/console
|
|
128
|
+
- bin/setup
|
|
129
|
+
- lib/uls.rb
|
|
130
|
+
- lib/uls/codes/applicant_type.rb
|
|
131
|
+
- lib/uls/codes/base.rb
|
|
132
|
+
- lib/uls/codes/entity_type.rb
|
|
133
|
+
- lib/uls/codes/license_status.rb
|
|
134
|
+
- lib/uls/codes/status.rb
|
|
135
|
+
- lib/uls/configuration.rb
|
|
136
|
+
- lib/uls/dat_file.rb
|
|
137
|
+
- lib/uls/database.rb
|
|
138
|
+
- lib/uls/records/base.rb
|
|
139
|
+
- lib/uls/records/entity.rb
|
|
140
|
+
- lib/uls/records/form_primary.rb
|
|
141
|
+
- lib/uls/records/form_secondary.rb
|
|
142
|
+
- lib/uls/retriever.rb
|
|
143
|
+
- lib/uls/version.rb
|
|
144
|
+
- uls.gemspec
|
|
145
|
+
homepage: http://github.com/gdubin/uls
|
|
146
|
+
licenses:
|
|
147
|
+
- MIT
|
|
148
|
+
metadata:
|
|
149
|
+
allowed_push_host: https://rubygems.org
|
|
150
|
+
post_install_message:
|
|
151
|
+
rdoc_options: []
|
|
152
|
+
require_paths:
|
|
153
|
+
- lib
|
|
154
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
|
+
requirements:
|
|
156
|
+
- - ">="
|
|
157
|
+
- !ruby/object:Gem::Version
|
|
158
|
+
version: '0'
|
|
159
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
|
+
requirements:
|
|
161
|
+
- - ">="
|
|
162
|
+
- !ruby/object:Gem::Version
|
|
163
|
+
version: '0'
|
|
164
|
+
requirements: []
|
|
165
|
+
rubygems_version: 3.3.3
|
|
166
|
+
signing_key:
|
|
167
|
+
specification_version: 4
|
|
168
|
+
summary: Parsing library for FCC ULS databases.
|
|
169
|
+
test_files: []
|