easyfaa 0.20.0 → 0.90.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.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -549
  3. data/MIT-LICENSE +1 -3
  4. data/README.md +17 -234
  5. data/exe/faa +4 -0
  6. data/lib/easyfaa/cli.rb +65 -0
  7. data/lib/easyfaa/version.rb +2 -2
  8. data/lib/easyfaa.rb +6 -36
  9. metadata +15 -227
  10. data/app/views/layouts/easyfaa.html.erb +0 -24
  11. data/app/views/recourses/_head.html.erb +0 -3
  12. data/art/autopilot.svg +0 -9
  13. data/art/cube.svg +0 -9
  14. data/art/design.svg +0 -8
  15. data/art/down.html.erb +0 -95
  16. data/art/easyfaa.svg +0 -7
  17. data/art/fountain.svg +0 -9
  18. data/art/goldrush.svg +0 -7
  19. data/art/houston.svg +0 -8
  20. data/art/icons.txt +0 -185
  21. data/art/index.html.erb +0 -157
  22. data/config/locales/easyfaa.en.yml +0 -7
  23. data/lib/easyfaa/copy.rb +0 -5
  24. data/lib/easyfaa/down.rb +0 -19
  25. data/lib/easyfaa/engine.rb +0 -53
  26. data/lib/easyfaa/helpers/flows.rb +0 -53
  27. data/lib/easyfaa/helpers/heads.rb +0 -60
  28. data/lib/easyfaa/helpers/logos.rb +0 -43
  29. data/lib/easyfaa/helpers.rb +0 -11
  30. data/lib/easyfaa/marks.rb +0 -16
  31. data/public/404.html +0 -118
  32. data/public/_headers +0 -28
  33. data/public/bh/css/bh.css +0 -1
  34. data/public/bh/js/bh.js +0 -152
  35. data/public/bh/theme/bootstrap.css +0 -10
  36. data/public/bh/theme/dawn.css +0 -189
  37. data/public/bh/theme/dracula.css +0 -189
  38. data/public/bh/theme/gruvbox.css +0 -189
  39. data/public/bh/theme/monokai.css +0 -190
  40. data/public/bh/theme/nord.css +0 -189
  41. data/public/bh/theme/one_dark.css +0 -189
  42. data/public/bh/theme/solarized.css +0 -188
  43. data/public/bh/theme/tokyo_night.css +0 -189
  44. data/public/css/easyfaa.css +0 -1
  45. data/public/down/autopilot.html +0 -87
  46. data/public/down/cube.html +0 -87
  47. data/public/down/design.html +0 -87
  48. data/public/down/easyfaa.html +0 -84
  49. data/public/down/fountain.html +0 -87
  50. data/public/down/goldrush.html +0 -87
  51. data/public/down/houston.html +0 -87
  52. data/public/favicon/autopilot-180.png +0 -0
  53. data/public/favicon/autopilot-192.png +0 -0
  54. data/public/favicon/autopilot-512.png +0 -0
  55. data/public/favicon/autopilot-96.png +0 -0
  56. data/public/favicon/autopilot-dev.svg +0 -9
  57. data/public/favicon/autopilot.ico +0 -0
  58. data/public/favicon/autopilot.svg +0 -9
  59. data/public/favicon/autopilot.webmanifest +0 -12
  60. data/public/favicon/cube-180.png +0 -0
  61. data/public/favicon/cube-192.png +0 -0
  62. data/public/favicon/cube-512.png +0 -0
  63. data/public/favicon/cube-96.png +0 -0
  64. data/public/favicon/cube-dev.svg +0 -9
  65. data/public/favicon/cube.ico +0 -0
  66. data/public/favicon/cube.svg +0 -9
  67. data/public/favicon/cube.webmanifest +0 -12
  68. data/public/favicon/design-180.png +0 -0
  69. data/public/favicon/design-192.png +0 -0
  70. data/public/favicon/design-512.png +0 -0
  71. data/public/favicon/design-96.png +0 -0
  72. data/public/favicon/design-dev.svg +0 -8
  73. data/public/favicon/design.ico +0 -0
  74. data/public/favicon/design.svg +0 -8
  75. data/public/favicon/design.webmanifest +0 -12
  76. data/public/favicon/easyfaa-180.png +0 -0
  77. data/public/favicon/easyfaa-192.png +0 -0
  78. data/public/favicon/easyfaa-512.png +0 -0
  79. data/public/favicon/easyfaa-96.png +0 -0
  80. data/public/favicon/easyfaa-dev.svg +0 -7
  81. data/public/favicon/easyfaa.ico +0 -0
  82. data/public/favicon/easyfaa.svg +0 -7
  83. data/public/favicon/easyfaa.webmanifest +0 -12
  84. data/public/favicon/fountain-180.png +0 -0
  85. data/public/favicon/fountain-192.png +0 -0
  86. data/public/favicon/fountain-512.png +0 -0
  87. data/public/favicon/fountain-96.png +0 -0
  88. data/public/favicon/fountain-dev.svg +0 -9
  89. data/public/favicon/fountain.ico +0 -0
  90. data/public/favicon/fountain.svg +0 -9
  91. data/public/favicon/fountain.webmanifest +0 -12
  92. data/public/favicon/goldrush-180.png +0 -0
  93. data/public/favicon/goldrush-192.png +0 -0
  94. data/public/favicon/goldrush-512.png +0 -0
  95. data/public/favicon/goldrush-96.png +0 -0
  96. data/public/favicon/goldrush-dev.svg +0 -7
  97. data/public/favicon/goldrush.ico +0 -0
  98. data/public/favicon/goldrush.svg +0 -7
  99. data/public/favicon/goldrush.webmanifest +0 -12
  100. data/public/favicon/houston-180.png +0 -0
  101. data/public/favicon/houston-192.png +0 -0
  102. data/public/favicon/houston-512.png +0 -0
  103. data/public/favicon/houston-96.png +0 -0
  104. data/public/favicon/houston-dev.svg +0 -8
  105. data/public/favicon/houston.ico +0 -0
  106. data/public/favicon/houston.svg +0 -8
  107. data/public/favicon/houston.webmanifest +0 -12
  108. data/public/favicon.ico +0 -0
  109. data/public/font/bootstrap-icons-6LILWPE2.woff2 +0 -0
  110. data/public/font/bootstrap-icons-FRBPO3H7.woff2 +0 -0
  111. data/public/font/ibm-plex-sans-500-latin-LA7QXWWL.woff2 +0 -0
  112. data/public/font/ibm-plex-sans-500-latin-ext-X4QHZICY.woff2 +0 -0
  113. data/public/font/ibm-plex-sans-500-latin-ext.woff2 +0 -0
  114. data/public/font/ibm-plex-sans-500-latin.woff2 +0 -0
  115. data/public/font/ibm-plex-sans-500-vietnamese-24B6BSND.woff2 +0 -0
  116. data/public/font/ibm-plex-sans-500-vietnamese.woff2 +0 -0
  117. data/public/index.html +0 -165
  118. data/public/js/easyfaa.js +0 -1
  119. data/public/logo/autopilot.png +0 -0
  120. data/public/logo/autopilot.svg +0 -9
  121. data/public/logo/cube.png +0 -0
  122. data/public/logo/cube.svg +0 -9
  123. data/public/logo/design.png +0 -0
  124. data/public/logo/design.svg +0 -8
  125. data/public/logo/easyfaa.png +0 -0
  126. data/public/logo/easyfaa.svg +0 -7
  127. data/public/logo/fountain.png +0 -0
  128. data/public/logo/fountain.svg +0 -9
  129. data/public/logo/goldrush.png +0 -0
  130. data/public/logo/goldrush.svg +0 -7
  131. data/public/logo/houston.png +0 -0
  132. data/public/logo/houston.svg +0 -8
  133. data/public/page/400.html +0 -118
  134. data/public/page/404.html +0 -118
  135. data/public/page/406-unsupported-browser.html +0 -118
  136. data/public/page/422.html +0 -118
  137. data/public/page/500.html +0 -118
  138. data/public/site.webmanifest +0 -12
  139. data/public/theme/bootstrap.css +0 -10
  140. data/public/theme/dawn.css +0 -189
  141. data/public/theme/dracula.css +0 -189
  142. data/public/theme/gruvbox.css +0 -189
  143. data/public/theme/monokai.css +0 -190
  144. data/public/theme/nord.css +0 -189
  145. data/public/theme/one_dark.css +0 -189
  146. data/public/theme/solarized.css +0 -188
  147. data/public/theme/tokyo_night.css +0 -189
  148. data/public/v0.20.0/bh/css/bh.css +0 -1
  149. data/public/v0.20.0/bh/js/bh.js +0 -152
  150. data/public/v0.20.0/bh/theme/bootstrap.css +0 -10
  151. data/public/v0.20.0/bh/theme/dawn.css +0 -189
  152. data/public/v0.20.0/bh/theme/dracula.css +0 -189
  153. data/public/v0.20.0/bh/theme/gruvbox.css +0 -189
  154. data/public/v0.20.0/bh/theme/monokai.css +0 -190
  155. data/public/v0.20.0/bh/theme/nord.css +0 -189
  156. data/public/v0.20.0/bh/theme/one_dark.css +0 -189
  157. data/public/v0.20.0/bh/theme/solarized.css +0 -188
  158. data/public/v0.20.0/bh/theme/tokyo_night.css +0 -189
  159. data/public/v0.20.0/css/easyfaa.css +0 -1
  160. data/public/v0.20.0/font/bootstrap-icons-FRBPO3H7.woff2 +0 -0
  161. data/public/v0.20.0/font/ibm-plex-sans-500-latin-LA7QXWWL.woff2 +0 -0
  162. data/public/v0.20.0/font/ibm-plex-sans-500-latin-ext-X4QHZICY.woff2 +0 -0
  163. data/public/v0.20.0/font/ibm-plex-sans-500-latin-ext.woff2 +0 -0
  164. data/public/v0.20.0/font/ibm-plex-sans-500-latin.woff2 +0 -0
  165. data/public/v0.20.0/font/ibm-plex-sans-500-vietnamese-24B6BSND.woff2 +0 -0
  166. data/public/v0.20.0/font/ibm-plex-sans-500-vietnamese.woff2 +0 -0
  167. data/public/v0.20.0/js/easyfaa.js +0 -1
data/README.md CHANGED
@@ -1,256 +1,39 @@
1
- # easyfaa design
1
+ # easyfaa
2
2
 
3
- What makes a page look like easyfaa's: the marks every app is known by, the lockup they
4
- sit in, the wall a signup flow stands on, the palettes, the pages an app shows when it is down
5
- or lost, and the one stylesheet and one script that carry all of it.
3
+ The `faa` command: what the FAA publishes about an aircraft or an Airworthiness Directive, read
4
+ in a terminal.
6
5
 
7
- The Bootstrap 6 underneath is [`bh`](https://claudiob.github.io/bh/), which this gem depends on
8
- and draws on top of rather than bundling: a page links bh's stylesheet and script first and this
9
- one's after, so the house rules win and Bootstrap ships once. **The components are documented
10
- there, not here** — the form builder, the combobox, the 6-digit code, the phone field, the
11
- dialog, the toasts, the thread of messages and the twenty-two Stimulus controllers are Bootstrap
12
- with the markup written once, and are worth the same to any Rails app. This gem is only what is
13
- the house's.
14
-
15
- Published three ways from this repo:
6
+ ```bash
7
+ faa -n 170ad # what the FAA registry keeps about N170AD
8
+ faa -ad 2020-12-12 # what the FAA published about AD 2020-12-12, every version of it
9
+ faa -n 170ad --json # the same, as JSON
10
+ ```
16
11
 
17
- | Surface | Where | What it is for |
18
- | --- | --- | --- |
19
- | Site | https://design.easyfaa.com (staging: https://design.houseparty.dev) | A stable URL for every asset, and a showcase of them |
20
- | Gem | `easyfaa` on RubyGems | A Rails engine: serves the same tree from the gem, and the helpers |
21
- | npm | `easyfaa` | The same built stylesheet and script, for any CDN that carries it |
12
+ The answers come from a copy of the FAA's data refreshed every night, at https://data.easyfaa.com.
13
+ `EASYFAA_URL` names another one. Each address may ask 20 times a minute and 200 times a day.
22
14
 
23
15
  ## How to install
24
16
 
25
- ### From RubyGems
26
-
27
17
  ```bash
28
18
  gem install easyfaa
29
19
  ```
30
20
 
31
21
  ```ruby
32
22
  # Gemfile
33
- gem 'easyfaa', '~> 0.15.0'
34
- ```
35
-
36
- bh comes with it; nothing else has to be named.
37
-
38
- `~> 0.15.0` stops short of `0.16`, since below 1.0 a minor release may break whatever it likes.
39
- Rails 8.1 and Ruby 3.2 are the minimum.
40
-
41
- A page takes the gem's layout, and wears the same head:
42
-
43
- ```ruby
44
- class Unauthenticated::AgentsController < ApplicationController
45
- layout 'easyfaa'
46
- end
47
- ```
48
-
49
- ```erb
50
- <% content_for :title, 'Authenticating as admin' %>
51
- <% content_for :head, tag.meta(name: 'robots', content: 'noindex') %>
52
- <h1>Authenticating as admin</h1>
53
- ```
54
-
55
- <p>
56
- <img src='screenshot/layout-light.png' width='49%' alt='The page in light mode'>
57
- <img src='screenshot/layout-dark.png' width='49%' alt='The page in dark mode'>
58
- </p>
59
-
60
- The layout is the charset, the title, the CSRF and CSP metas, `easyfaa_head_tags`,
61
- `yield :head`, then `yield` inside a `main.container-fluid` in the `<body>`, and `notices`
62
- after it, and nothing else. A host wanting more copies
63
- it into its own `app/views/layouts/`, which wins on being earlier in the view paths.
64
-
65
- Which of the family an app is, the gem reads off the Rails application's own name: the
66
- `Goldrush` of `Goldrush::Application`. That is what its tab wears, what `easyfaa_head_tags`
67
- links without an argument, and whose page the engine answers `/down.html` with — the app's
68
- mark in the middle and the house's at the foot. An app the family has no mark for wears the
69
- horizon. The same page stands at `https://design.easyfaa.com/down/fountain` for Heroku's
70
- `MAINTENANCE_PAGE_URL`, which has to be somewhere the app is not — without the `.html`,
71
- which Pages redirects away from.
72
-
73
- With the gem in the bundle an app serves `/css/easyfaa.css`, `/js/easyfaa.js`,
74
- `/theme/*`, `/font/*`, `/logo/*` and `/favicon/*` itself — and its own version's copy under
75
- `/v0.15.0/`, which is what the head helper links, cached for a year — answers a 400, 404, 406,
76
- 422 or 500 with the house's own page, and answers `/down.html` with this app's.
77
-
78
- ## Which app this is
79
-
80
- Read off the Rails application's own name, the `Goldrush` of `Goldrush::Application`. That is
81
- what its tab wears, what `easyfaa_head_tags` links without an argument, and whose page the
82
- engine answers `/down.html` with — the app's mark in the middle and the house's at the foot. An
83
- app the family has no mark for wears the horizon.
84
-
85
- ## The helpers
86
-
87
- ```erb
88
- <%# In the <head>: the viewport, color-scheme and Turbo refresh metas, the stylesheet, the
89
- script, and the icons a tab, a phone and a manifest ask for — this app's, by its name. %>
90
- <%= easyfaa_head_tags %>
91
-
92
- <%# The icons alone, for a head of the host's own: this app's unless another of the family is
93
- named, the way a page for customers wears the house's horizon rather than the app's. A host of
94
- recourse needs no call at all — the gem answers recourse's `recourses/head` with them. %>
95
- <%= easyfaa_icons :easyfaa %>
96
-
97
- <%# A mark beside its name, as one word and one link. Each drawing fills its 512 grid
98
- differently, so equal sizes never align: every mark is rendered at a box of its own and
99
- pushed down by its own nudge, and its ink then stands on the baseline. %>
100
- <%= easyfaa_logo %>
101
- <%= easyfaa_logo app: :fountain, href: root_path, class: 'fs-3' %>
102
-
103
- <%# An asset on the design site, for a page this app does not serve — a mail, say. %>
104
- <%= image_tag easyfaa_url('logo/fountain.png') %>
23
+ gem 'easyfaa', '~> 0.90'
105
24
  ```
106
25
 
107
- ## The layout
108
-
109
- A page takes the gem's layout and wears the same head:
110
-
111
- ```ruby
112
- class Unauthenticated::AgentsController < ApplicationController
113
- layout 'easyfaa'
114
- end
115
- ```
116
-
117
- ```erb
118
- <% content_for :title, 'Authenticating as admin' %>
119
- <% content_for :head, tag.meta(name: 'robots', content: 'noindex') %>
120
- <h1>Authenticating as admin</h1>
121
- ```
122
-
123
- <p>
124
- <img src='screenshot/layout-light.png' width='49%' alt='The page in light mode'>
125
- <img src='screenshot/layout-dark.png' width='49%' alt='The page in dark mode'>
126
- </p>
127
-
128
- It is the charset, the title, the CSRF and CSP metas, `easyfaa_head_tags`, `yield :head`,
129
- then `yield` inside a `main.container-fluid`, and `notices` after it — and nothing else. A host
130
- wanting more copies it into its own `app/views/layouts/`, which wins on being earlier in the
131
- view paths.
26
+ `~> 0.90` takes every 0.x from 0.90 on and never 1.0: until 1.0, a minor version may change what the command prints.
132
27
 
133
- ## The flow, and the wall it stands on
134
-
135
- `flow` is the page a signup flow lives on: the lockup over the cyanotype, a title, a line, one
136
- card, and the way out under it. A layout of the app's own calls it and nests on the gem's:
137
-
138
- ```erb
139
- <% content_for :logo, 'easyfaa' %>
140
-
141
- <% content_for :content do %>
142
- <%= flow href: root_path, links: [button_to('Sign out', session_path, method: :delete, class: 'btn btn-link')] do %>
143
- <%= yield %>
144
- <% end %>
145
- <% end %>
146
-
147
- <%= render template: 'layouts/easyfaa' %>
148
- ```
149
-
150
- `href:` is where the mark links, the house's front door unless said; `links:` the pieces of the
151
- foot, joined by a middot, none drawing no foot. The mark and the wall are not asked for, being
152
- what a house flow is. What the page says about itself — `content_for :title`, `:subtitle` and
153
- `:width` — it says in its own view, and `content_for :logo` is which of the family's marks the
154
- tab wears, for a page a customer reads rather than the app's own people.
155
-
156
- The wall alone is one attribute, `data-controller='wall'`, on any element that should stand on
157
- it: fourteen trade tools and the family's five marks drifting up in seven columns, on blueprint
158
- blues of its own so it reads the same whatever the primary is. Under `prefers-reduced-motion`
159
- the columns stand still.
160
-
161
- ## A code sent to a phone
162
-
163
- The same words from every app, in each voice they are said in. `written` is the sentence a
164
- person reads and, under it, the `@host #code` line that offers the code above the keyboard on
165
- the phone it arrived on; `spoken` is the sentence alone, its digits one at a time so a listener
166
- can write them down.
167
-
168
- ```ruby
169
- Easyfaa.one_time_code(contact.pin).written
170
- # => "Enter this 6-digit code to proceed: 482913\n\n@easyfaa.com #482913"
171
- Easyfaa.one_time_code(contact.pin).spoken
172
- # => "Enter this 6-digit code to proceed: 4, 8, 2, 9, 1, 3"
173
- ```
174
-
175
- ## Off the gem
176
-
177
- A page not on the gem links the two files from the site, and nothing else:
178
-
179
- ```html
180
- <link rel='stylesheet' href='https://design.easyfaa.com/css/easyfaa.css'>
181
- <script type='module' src='https://design.easyfaa.com/js/easyfaa.js'></script>
182
- ```
183
-
184
- Those follow the latest release. Every release is also kept whole under its own version,
185
- forever and cached for a year, for a page that would rather move on its own terms:
186
-
187
- ```html
188
- <link rel='stylesheet' href='https://design.easyfaa.com/v0.20.0/css/easyfaa.css'>
189
- <script type='module' src='https://design.easyfaa.com/v0.20.0/js/easyfaa.js'></script>
190
- ```
191
-
192
- bh's layer goes under the house's, from the same place, since the house is drawn on top of it
193
- and neither stands alone:
194
-
195
- ```html
196
- <link rel='stylesheet' href='https://design.easyfaa.com/v0.20.0/bh/css/bh.css'>
197
- <link rel='stylesheet' href='https://design.easyfaa.com/v0.20.0/css/easyfaa.css'>
198
- ```
199
-
200
- The palettes are beside it, at `bh/theme/nord.css` and the rest — bh's nine, copied out of the
201
- gem at build time. A version under `v` is never written again, so that URL is owed its bytes.
202
-
203
- A host with a Content Security Policy allows whichever origin it names for `style-src`,
204
- `script-src` and `font-src`.
205
-
206
- ## What is in the bundle
207
-
208
- `css/easyfaa.css` is the house's layer alone: the rules this gem writes over bh's,
209
- followed by Bootstrap Icons cut down to the glyphs `art/icons.txt` names (the ones `unicon`
210
- maps and the few written out by name) and the house's three — the page, the lockup and the
211
- wall. IBM Plex Sans, the lockup's face, is served from `/font` too; nothing on a page reaches
212
- another origin. `js/easyfaa.js` is the house's script alone: `wall`, the one controller
213
- that is its own, registered with the Stimulus application bh's script starts. bh's two files
214
- are copied beside these at `bh/`, and a page links bh's first. Everything is drawn for light and dark alike: every color is a Bootstrap
215
- token or a `light-dark()` pair, and `data-bs-theme` on `<html>` forces either. A phone is
216
- formatted in the browser: the server hands over ten digits and
217
- `data-controller='phone'`, and the controller decides `555-555-5555`.
28
+ For accidents, see the `ntsb` command (`gem install ntsb`).
218
29
 
219
30
  ## Development
220
31
 
221
32
  ```bash
222
- bin/setup # bundle and npm install
223
- bundle exec rake # build, test at 100% coverage, RuboCop, the file-length ceiling
224
- ./build-icons.sh # after editing a drawing under art/
225
- rake icons # after editing art/icons.txt, the glyphs the icon font keeps
226
- cd test/dummy && bin/rails server
33
+ bin/setup # the bundle
34
+ bundle exec rake # the suite at 100% line coverage, and RuboCop
227
35
  ```
228
36
 
229
- The build reads bh's sources out of the gem — `bundle info bh --path` — rather than out of
230
- `node_modules`, so the Gemfile is the one place bh's version is pinned. An edit to bh shows in
231
- this bundle on the next `rake assets`.
232
-
233
- The built `public/css`, `public/js`, `public/font` and `public/theme` are committed: the gem
234
- serves them, and `spec.files` is `git ls-files`. `rake assets` rebuilds and fails until the
235
- result is committed, so a source edit cannot ship without its build.
236
-
237
- While the gem is read from a path, an app in development serves every file `no-cache`, so a
238
- rebuild shows on the next reload; only a production app keeps the versioned copy for a year.
239
-
240
- Every build also writes `public/v<version>/`, whole, with every URL inside pointing under
241
- that prefix, until the tag `v<version>` exists; from then on the folder is never written
242
- again, and a page that pinned it is owed the same bytes for good.
243
-
244
- A release, in order: `CHANGELOG.md`, the version in `lib/easyfaa/version.rb` and
245
- `package.json`, `bundle exec rake` so the versioned copy is the release's, then commit, tag
246
- `v<version>`, `gem build` and `gem push`, and fast-forward `production` to `main` so the
247
- site carries both the latest and the versioned copy.
248
-
249
- ## Cloudflare
37
+ ## License
250
38
 
251
- The site is a Cloudflare Pages project named `design` on this repo: production branch
252
- `production`, no build command, output directory `public`, custom domain
253
- `design.easyfaa.com`. `main` deploys as the branch alias `main.design.pages.dev`, which
254
- `design.houseparty.dev` is a CNAME to. `public/_headers` adds the CORS header a cross-origin
255
- module script and font need, and marks the hashed fonts immutable; everything else keeps
256
- Pages' default of revalidating on every load, so a URL never has to change between versions.
39
+ [MIT](MIT-LICENSE).
data/exe/faa ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'easyfaa'
3
+
4
+ exit Easyfaa::CLI.new(ARGV).run
@@ -0,0 +1,65 @@
1
+ require 'net/http'
2
+
3
+ module Easyfaa
4
+ # The `faa` command: what the FAA publishes about an N-number (`faa -n 170ad`) or an AD
5
+ # (`faa -ad 2020-12-12`), as text, or as JSON with `--json`.
6
+ class CLI
7
+ # Each option, and the page it asks for.
8
+ PAGES = { '-n' => 'N', '-ad' => 'AD' }.freeze
9
+
10
+ # What `faa --help` prints.
11
+ USAGE = <<~TEXT.freeze
12
+ Usage: faa -n N-NUMBER [--json] what the FAA registry keeps about an aircraft
13
+ faa -ad AD-NUMBER [--json] what the FAA published about an Airworthiness Directive
14
+ faa --version
15
+
16
+ Reads EASYFAA_URL, where the data is served (#{URL} unless set).
17
+ TEXT
18
+
19
+ # @param args [Array<String>] command-line arguments.
20
+ # @param out [IO] where the answer is printed.
21
+ # @param err [IO] where a problem is printed.
22
+ def initialize(args, out: $stdout, err: $stderr)
23
+ @args = args
24
+ @out = out
25
+ @err = err
26
+ end
27
+
28
+ # Prints what was asked for.
29
+ # @return [Integer] exit status: 0 when it was found, 1 otherwise.
30
+ def run
31
+ option, number, format = @args
32
+ if %w[-v --version].include?(option) then answer "faa #{VERSION}"
33
+ elsif PAGES.key?(option) && number then fetch PAGES[option], number, format
34
+ else answer USAGE, status: option.nil? || %w[-h --help].include?(option) ? 0 : 1
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def fetch(page, number, format)
41
+ extension = format == '--json' ? 'json' : 'txt'
42
+ response = Net::HTTP.get_response URI("#{url}/#{page}/#{escape number}.#{extension}")
43
+ case response
44
+ when Net::HTTPSuccess then answer response.body
45
+ when Net::HTTPNotFound then problem "The FAA publishes nothing under #{number}."
46
+ when Net::HTTPTooManyRequests then problem 'Too many requests: try again in a minute.'
47
+ else problem "#{url} answered #{response.code}."
48
+ end
49
+ end
50
+
51
+ def escape(number) = URI.encode_www_form_component(number)
52
+
53
+ def url = ENV.fetch('EASYFAA_URL', URL).chomp('/')
54
+
55
+ def answer(text, status: 0)
56
+ @out.puts text
57
+ status
58
+ end
59
+
60
+ def problem(text)
61
+ @err.puts text
62
+ 1
63
+ end
64
+ end
65
+ end
@@ -1,4 +1,4 @@
1
1
  module Easyfaa
2
- # Version of the gem, read by the gemspec and by hosts checking compatibility.
3
- VERSION = '0.20.0'
2
+ # Version of the gem, read by the gemspec and printed by `faa --version`.
3
+ VERSION = '0.90.0'.freeze
4
4
  end
data/lib/easyfaa.rb CHANGED
@@ -1,39 +1,9 @@
1
- require 'bh'
2
- require_relative 'easyfaa/version'
3
- require_relative 'easyfaa/marks'
4
- require_relative 'easyfaa/copy'
5
- require_relative 'easyfaa/down'
6
- require_relative 'easyfaa/helpers'
7
- require_relative 'easyfaa/engine'
1
+ require 'easyfaa/version'
8
2
 
9
- # easyfaa's front end: the stylesheet and script every page loads — bh's Bootstrap 6
10
- # with the house's own layer over it — the marks every app is known by, and the helpers that
11
- # draw a head, a logo or a signup page the same way everywhere.
3
+ # What the FAA publishes about an aircraft or an Airworthiness Directive, read in a terminal.
12
4
  module Easyfaa
13
- # The form every easyfaa page is written with, which is bh's: the house dresses no
14
- # field differently, so this name and `Bh::FormBuilder` are one builder.
15
- FormBuilder = Bh::FormBuilder
16
-
17
- # One message of a chat, which is bh's too. Named here for a host that reached for it by
18
- # the house's name before the components moved.
19
- Message = Bh::Message
20
-
21
- # Which of the family this host is, read off the Rails application's own name — the
22
- # `Goldrush` of `Goldrush::Application` — and the house itself for any app not in `MARKS`.
23
- # What a tab wears, what a logo says and whose page answers `/down.html`.
24
- def self.app
25
- name = Rails.application.class.module_parent_name.downcase.to_sym
26
- MARKS.key?(name) ? name : :easyfaa
27
- end
28
-
29
- # The words that carry a 6-digit code to a phone, in both voices. `written` is the sentence
30
- # a person reads and, under it, the line Safari matches against the page about to be filled,
31
- # `@host #code`, which offers the code above the keyboard so nobody leaves for Messages to
32
- # copy it. `spoken` is the sentence alone, its digits one at a time so a listener can write
33
- # them down, and without a line meant for a phone rather than a person. Every app of the
34
- # house that sends a code sends these, from `config/locales`.
35
- def self.one_time_code(pin, host: Rails.application.default_url_options[:host])
36
- Copy.new written: I18n.t('easyfaa.one_time_code', pin:, host:),
37
- spoken: I18n.t('easyfaa.spoken_one_time_code', pin: pin.chars.join(', '))
38
- end
5
+ # Where the FAA's data is served, unless EASYFAA_URL says otherwise.
6
+ URL = 'https://data.easyfaa.com'.freeze
39
7
  end
8
+
9
+ require 'easyfaa/cli'
metadata CHANGED
@@ -1,248 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easyfaa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.90.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - claudiob
8
- bindir: bin
8
+ bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: actionpack
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - ">="
17
- - !ruby/object:Gem::Version
18
- version: '8.1'
19
- type: :runtime
20
- prerelease: false
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - ">="
24
- - !ruby/object:Gem::Version
25
- version: '8.1'
26
- - !ruby/object:Gem::Dependency
27
- name: actionview
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: '8.1'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '8.1'
40
- - !ruby/object:Gem::Dependency
41
- name: bh
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 6.7.0
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: 6.7.0
54
- - !ruby/object:Gem::Dependency
55
- name: railties
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: '8.1'
61
- type: :runtime
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: '8.1'
68
- description: One stylesheet and one script, served by the engine or from design.easyfaa.com,
69
- the marks every app is known by, the pages shown when an app is not, and helpers
70
- that draw a head, a lockup or a chat the same way everywhere.
11
+ dependencies: []
12
+ description: "`faa -n 170ad` prints what the FAA registry keeps about an N-number,
13
+ and `faa -ad 2020-12-12` what the FAA published about an Airworthiness Directive."
71
14
  email:
72
- - info@easyfaa.com
73
- executables: []
15
+ - claudiob@users.noreply.github.com
16
+ executables:
17
+ - faa
74
18
  extensions: []
75
19
  extra_rdoc_files: []
76
20
  files:
77
21
  - CHANGELOG.md
78
22
  - MIT-LICENSE
79
23
  - README.md
80
- - app/views/layouts/easyfaa.html.erb
81
- - app/views/recourses/_head.html.erb
82
- - art/autopilot.svg
83
- - art/cube.svg
84
- - art/design.svg
85
- - art/down.html.erb
86
- - art/easyfaa.svg
87
- - art/fountain.svg
88
- - art/goldrush.svg
89
- - art/houston.svg
90
- - art/icons.txt
91
- - art/index.html.erb
92
- - config/locales/easyfaa.en.yml
24
+ - exe/faa
93
25
  - lib/easyfaa.rb
94
- - lib/easyfaa/copy.rb
95
- - lib/easyfaa/down.rb
96
- - lib/easyfaa/engine.rb
97
- - lib/easyfaa/helpers.rb
98
- - lib/easyfaa/helpers/flows.rb
99
- - lib/easyfaa/helpers/heads.rb
100
- - lib/easyfaa/helpers/logos.rb
101
- - lib/easyfaa/marks.rb
26
+ - lib/easyfaa/cli.rb
102
27
  - lib/easyfaa/version.rb
103
- - public/404.html
104
- - public/_headers
105
- - public/bh/css/bh.css
106
- - public/bh/js/bh.js
107
- - public/bh/theme/bootstrap.css
108
- - public/bh/theme/dawn.css
109
- - public/bh/theme/dracula.css
110
- - public/bh/theme/gruvbox.css
111
- - public/bh/theme/monokai.css
112
- - public/bh/theme/nord.css
113
- - public/bh/theme/one_dark.css
114
- - public/bh/theme/solarized.css
115
- - public/bh/theme/tokyo_night.css
116
- - public/css/easyfaa.css
117
- - public/down/autopilot.html
118
- - public/down/cube.html
119
- - public/down/design.html
120
- - public/down/easyfaa.html
121
- - public/down/fountain.html
122
- - public/down/goldrush.html
123
- - public/down/houston.html
124
- - public/favicon.ico
125
- - public/favicon/autopilot-180.png
126
- - public/favicon/autopilot-192.png
127
- - public/favicon/autopilot-512.png
128
- - public/favicon/autopilot-96.png
129
- - public/favicon/autopilot-dev.svg
130
- - public/favicon/autopilot.ico
131
- - public/favicon/autopilot.svg
132
- - public/favicon/autopilot.webmanifest
133
- - public/favicon/cube-180.png
134
- - public/favicon/cube-192.png
135
- - public/favicon/cube-512.png
136
- - public/favicon/cube-96.png
137
- - public/favicon/cube-dev.svg
138
- - public/favicon/cube.ico
139
- - public/favicon/cube.svg
140
- - public/favicon/cube.webmanifest
141
- - public/favicon/design-180.png
142
- - public/favicon/design-192.png
143
- - public/favicon/design-512.png
144
- - public/favicon/design-96.png
145
- - public/favicon/design-dev.svg
146
- - public/favicon/design.ico
147
- - public/favicon/design.svg
148
- - public/favicon/design.webmanifest
149
- - public/favicon/easyfaa-180.png
150
- - public/favicon/easyfaa-192.png
151
- - public/favicon/easyfaa-512.png
152
- - public/favicon/easyfaa-96.png
153
- - public/favicon/easyfaa-dev.svg
154
- - public/favicon/easyfaa.ico
155
- - public/favicon/easyfaa.svg
156
- - public/favicon/easyfaa.webmanifest
157
- - public/favicon/fountain-180.png
158
- - public/favicon/fountain-192.png
159
- - public/favicon/fountain-512.png
160
- - public/favicon/fountain-96.png
161
- - public/favicon/fountain-dev.svg
162
- - public/favicon/fountain.ico
163
- - public/favicon/fountain.svg
164
- - public/favicon/fountain.webmanifest
165
- - public/favicon/goldrush-180.png
166
- - public/favicon/goldrush-192.png
167
- - public/favicon/goldrush-512.png
168
- - public/favicon/goldrush-96.png
169
- - public/favicon/goldrush-dev.svg
170
- - public/favicon/goldrush.ico
171
- - public/favicon/goldrush.svg
172
- - public/favicon/goldrush.webmanifest
173
- - public/favicon/houston-180.png
174
- - public/favicon/houston-192.png
175
- - public/favicon/houston-512.png
176
- - public/favicon/houston-96.png
177
- - public/favicon/houston-dev.svg
178
- - public/favicon/houston.ico
179
- - public/favicon/houston.svg
180
- - public/favicon/houston.webmanifest
181
- - public/font/bootstrap-icons-6LILWPE2.woff2
182
- - public/font/bootstrap-icons-FRBPO3H7.woff2
183
- - public/font/ibm-plex-sans-500-latin-LA7QXWWL.woff2
184
- - public/font/ibm-plex-sans-500-latin-ext-X4QHZICY.woff2
185
- - public/font/ibm-plex-sans-500-latin-ext.woff2
186
- - public/font/ibm-plex-sans-500-latin.woff2
187
- - public/font/ibm-plex-sans-500-vietnamese-24B6BSND.woff2
188
- - public/font/ibm-plex-sans-500-vietnamese.woff2
189
- - public/index.html
190
- - public/js/easyfaa.js
191
- - public/logo/autopilot.png
192
- - public/logo/autopilot.svg
193
- - public/logo/cube.png
194
- - public/logo/cube.svg
195
- - public/logo/design.png
196
- - public/logo/design.svg
197
- - public/logo/easyfaa.png
198
- - public/logo/easyfaa.svg
199
- - public/logo/fountain.png
200
- - public/logo/fountain.svg
201
- - public/logo/goldrush.png
202
- - public/logo/goldrush.svg
203
- - public/logo/houston.png
204
- - public/logo/houston.svg
205
- - public/page/400.html
206
- - public/page/404.html
207
- - public/page/406-unsupported-browser.html
208
- - public/page/422.html
209
- - public/page/500.html
210
- - public/site.webmanifest
211
- - public/theme/bootstrap.css
212
- - public/theme/dawn.css
213
- - public/theme/dracula.css
214
- - public/theme/gruvbox.css
215
- - public/theme/monokai.css
216
- - public/theme/nord.css
217
- - public/theme/one_dark.css
218
- - public/theme/solarized.css
219
- - public/theme/tokyo_night.css
220
- - public/v0.20.0/bh/css/bh.css
221
- - public/v0.20.0/bh/js/bh.js
222
- - public/v0.20.0/bh/theme/bootstrap.css
223
- - public/v0.20.0/bh/theme/dawn.css
224
- - public/v0.20.0/bh/theme/dracula.css
225
- - public/v0.20.0/bh/theme/gruvbox.css
226
- - public/v0.20.0/bh/theme/monokai.css
227
- - public/v0.20.0/bh/theme/nord.css
228
- - public/v0.20.0/bh/theme/one_dark.css
229
- - public/v0.20.0/bh/theme/solarized.css
230
- - public/v0.20.0/bh/theme/tokyo_night.css
231
- - public/v0.20.0/css/easyfaa.css
232
- - public/v0.20.0/font/bootstrap-icons-FRBPO3H7.woff2
233
- - public/v0.20.0/font/ibm-plex-sans-500-latin-LA7QXWWL.woff2
234
- - public/v0.20.0/font/ibm-plex-sans-500-latin-ext-X4QHZICY.woff2
235
- - public/v0.20.0/font/ibm-plex-sans-500-latin-ext.woff2
236
- - public/v0.20.0/font/ibm-plex-sans-500-latin.woff2
237
- - public/v0.20.0/font/ibm-plex-sans-500-vietnamese-24B6BSND.woff2
238
- - public/v0.20.0/font/ibm-plex-sans-500-vietnamese.woff2
239
- - public/v0.20.0/js/easyfaa.js
240
- homepage: https://design.easyfaa.com
28
+ homepage: https://github.com/easyfaa/faa
241
29
  licenses:
242
30
  - MIT
243
31
  metadata:
244
- source_code_uri: https://github.com/easyfaa/design
245
- changelog_uri: https://github.com/easyfaa/design/blob/main/CHANGELOG.md
32
+ source_code_uri: https://github.com/easyfaa/faa
33
+ changelog_uri: https://github.com/easyfaa/faa/blob/main/CHANGELOG.md
246
34
  documentation_uri: https://rubydoc.info/gems/easyfaa
247
35
  rdoc_options: []
248
36
  require_paths:
@@ -251,7 +39,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
251
39
  requirements:
252
40
  - - ">="
253
41
  - !ruby/object:Gem::Version
254
- version: 3.2.0
42
+ version: '3.1'
255
43
  required_rubygems_version: !ruby/object:Gem::Requirement
256
44
  requirements:
257
45
  - - ">="
@@ -260,5 +48,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
260
48
  requirements: []
261
49
  rubygems_version: 4.0.3
262
50
  specification_version: 4
263
- summary: The front end every easyfaa app shares.
51
+ summary: 'The faa command: what the FAA publishes about an aircraft or an AD.'
264
52
  test_files: []