sferik 0.0.1

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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +5 -0
  3. data/CHANGELOG.md +72 -0
  4. data/LICENSE.md +16 -0
  5. data/README.md +517 -0
  6. data/exe/sferik +6 -0
  7. data/lib/sferik/api/code_endpoints.rb +37 -0
  8. data/lib/sferik/api/profile_endpoints.rb +113 -0
  9. data/lib/sferik/api/resume_endpoints.rb +41 -0
  10. data/lib/sferik/api/site_endpoints.rb +247 -0
  11. data/lib/sferik/api/talk_endpoints.rb +45 -0
  12. data/lib/sferik/api.rb +23 -0
  13. data/lib/sferik/block.rb +25 -0
  14. data/lib/sferik/body.rb +54 -0
  15. data/lib/sferik/cache.rb +361 -0
  16. data/lib/sferik/cli.rb +369 -0
  17. data/lib/sferik/client.rb +453 -0
  18. data/lib/sferik/collection.rb +82 -0
  19. data/lib/sferik/configuration.rb +129 -0
  20. data/lib/sferik/connections.rb +151 -0
  21. data/lib/sferik/contributions.rb +86 -0
  22. data/lib/sferik/day.rb +35 -0
  23. data/lib/sferik/dependency.rb +26 -0
  24. data/lib/sferik/deployment.rb +36 -0
  25. data/lib/sferik/errors.rb +234 -0
  26. data/lib/sferik/figure.rb +83 -0
  27. data/lib/sferik/finger.rb +74 -0
  28. data/lib/sferik/freshness.rb +54 -0
  29. data/lib/sferik/home/pages.rb +27 -0
  30. data/lib/sferik/home/profile.rb +51 -0
  31. data/lib/sferik/home/section.rb +27 -0
  32. data/lib/sferik/home.rb +38 -0
  33. data/lib/sferik/json_parsing.rb +28 -0
  34. data/lib/sferik/name_change.rb +49 -0
  35. data/lib/sferik/place.rb +33 -0
  36. data/lib/sferik/podcast.rb +41 -0
  37. data/lib/sferik/project.rb +49 -0
  38. data/lib/sferik/projects.rb +138 -0
  39. data/lib/sferik/push.rb +33 -0
  40. data/lib/sferik/resource.rb +373 -0
  41. data/lib/sferik/resume/award.rb +43 -0
  42. data/lib/sferik/resume/basics.rb +77 -0
  43. data/lib/sferik/resume/education.rb +59 -0
  44. data/lib/sferik/resume/location.rb +35 -0
  45. data/lib/sferik/resume/meta.rb +35 -0
  46. data/lib/sferik/resume/patent.rb +43 -0
  47. data/lib/sferik/resume/profile.rb +35 -0
  48. data/lib/sferik/resume/project.rb +27 -0
  49. data/lib/sferik/resume/skill.rb +27 -0
  50. data/lib/sferik/resume/speaking.rb +19 -0
  51. data/lib/sferik/resume/volunteer.rb +59 -0
  52. data/lib/sferik/resume/work.rb +51 -0
  53. data/lib/sferik/resume.rb +125 -0
  54. data/lib/sferik/session.rb +41 -0
  55. data/lib/sferik/social_profile.rb +49 -0
  56. data/lib/sferik/status/github.rb +38 -0
  57. data/lib/sferik/status/loaded.rb +48 -0
  58. data/lib/sferik/status.rb +33 -0
  59. data/lib/sferik/talk.rb +73 -0
  60. data/lib/sferik/talks.rb +79 -0
  61. data/lib/sferik/validation.rb +119 -0
  62. data/lib/sferik/version.rb +7 -0
  63. data/lib/sferik/web_finger/link.rb +46 -0
  64. data/lib/sferik/web_finger.rb +43 -0
  65. data/lib/sferik/who.rb +53 -0
  66. data/lib/sferik/whoami.rb +36 -0
  67. data/lib/sferik/wrapping.rb +114 -0
  68. data/lib/sferik.rb +246 -0
  69. data/sig/manifest.yaml +13 -0
  70. data/sig/sferik.rbs +825 -0
  71. metadata +118 -0
data/lib/sferik.rb ADDED
@@ -0,0 +1,246 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+ require_relative "sferik/client"
5
+ require_relative "sferik/configuration"
6
+ require_relative "sferik/version"
7
+
8
+ # A Ruby wrapper for the sferik.net API
9
+ #
10
+ # Every public method of {API} is a method of this module too, delegated to {.client}: {API::ProfileEndpoints#whoami}
11
+ # is `Sferik.whoami`, {API::ResumeEndpoints#resume} is `Sferik.resume`, and so on for every endpoint. {API} groups them
12
+ # into one mixin per topic, and each is documented there.
13
+ #
14
+ # @api public
15
+ # @see API The endpoints, grouped into one mixin per topic
16
+ module Sferik
17
+ # The sferik command, loaded when it's first used: a program that only calls the API doesn't load it, or optparse
18
+ autoload :CLI, "#{__dir__}/sferik/cli"
19
+
20
+ extend Configuration
21
+ extend SingleForwardable
22
+
23
+ # The mutex that guards the client the API methods of the module delegate to
24
+ CLIENT_MUTEX = Mutex.new
25
+ private_constant :CLIENT_MUTEX
26
+
27
+ # @!method self.new(**options)
28
+ # Alias for Sferik::Client.new
29
+ # @api public
30
+ # @param options [Hash] options passed to {Sferik::Client#initialize}
31
+ # @return [Sferik::Client] a new client
32
+ # @example Create a client for a local copy of the site
33
+ # Sferik.new(host: "http://localhost:3745")
34
+ def_delegator "Sferik::Client", :new
35
+
36
+ # The endpoints of {API}, each delegated to the client the module has, and documented here so that each is found
37
+ # under the name it's called by
38
+ #
39
+ # @!method self.home
40
+ # Returns the profile and the home page's modules
41
+ # @api public
42
+ # @return [Home]
43
+ # @example
44
+ # Sferik.home.profile.tagline
45
+ # @see API::ProfileEndpoints#home What it raises, and more about it
46
+ # @!method self.whoami
47
+ # Returns the bio: paragraphs of HTML
48
+ # @api public
49
+ # @return [Whoami]
50
+ # @example
51
+ # Sferik.whoami.blocks.map(&:html)
52
+ # @see API::ProfileEndpoints#whoami What it raises, and more about it
53
+ # @!method self.dependency
54
+ # Returns the xkcd comic on the home page: xkcd 2347, adapted
55
+ # @api public
56
+ # @return [Dependency]
57
+ # @example
58
+ # Sferik.dependency.figure.alt
59
+ # @see API::ProfileEndpoints#dependency What it raises, and more about it
60
+ # @!method self.finger
61
+ # Returns contact details and profiles elsewhere
62
+ # @api public
63
+ # @return [Finger]
64
+ # @example
65
+ # Sferik.finger.profiles.map(&:url)
66
+ # @see API::ProfileEndpoints#finger What it raises, and more about it
67
+ # @!method self.finger_vcard
68
+ # Returns contact details and profiles as a contact card (a vCard)
69
+ # @api public
70
+ # @return [String] the vCard
71
+ # @example
72
+ # File.write("erik-berlin.vcf", Sferik.finger_vcard)
73
+ # @see API::ProfileEndpoints#finger_vcard What it raises, and more about it
74
+ # @!method self.name_change
75
+ # Returns the name change, from Erik Michaels-Ober to Erik Berlin, as a git commit
76
+ # @api public
77
+ # @return [NameChange]
78
+ # @example
79
+ # Sferik.name_change.year # => 2017
80
+ # @see API::ProfileEndpoints#name_change What it raises, and more about it
81
+ # @!method self.signature
82
+ # Returns the motto: ~/.signature, which the home page shows as cat .signature
83
+ # @api public
84
+ # @return [String] the motto, without the newline the site ends it with
85
+ # @example
86
+ # Sferik.signature # => "I build libraries and tools software engineers depend on."
87
+ # @see API::ProfileEndpoints#signature What it raises, and more about it
88
+ # @!method self.webfinger(resource = "acct:sferik@sferik.net")
89
+ # Returns where an account at sferik.net points to, as WebFinger answers
90
+ # @api public
91
+ # @param resource [String] the account, as an acct: URI
92
+ # @return [WebFinger]
93
+ # @example
94
+ # Sferik.webfinger.subject # => "acct:sferik@mastodon.social"
95
+ # @see API::ProfileEndpoints#webfinger What it raises, and more about it
96
+ # @!method self.contributions
97
+ # Returns a year of GitHub contributions, the longest streak, and the latest push
98
+ # @api public
99
+ # @return [Contributions]
100
+ # @example
101
+ # Sferik.contributions.days.max_by(&:count).date
102
+ # @see API::CodeEndpoints#contributions What it raises, and more about it
103
+ # @!method self.projects
104
+ # Returns projects with their RubyGems downloads and GitHub stars
105
+ # @api public
106
+ # @return [Projects]
107
+ # @example
108
+ # Sferik.projects.total_downloads # => 5_460_234_129
109
+ # @see API::CodeEndpoints#projects What it raises, and more about it
110
+ # @!method self.talks
111
+ # Returns conference talks, newest first, and podcast appearances
112
+ # @api public
113
+ # @return [Talks]
114
+ # @example
115
+ # Sferik.talks.select(&:video).map(&:title)
116
+ # @see API::TalkEndpoints#talks What it raises, and more about it
117
+ # @!method self.talks_feed
118
+ # Returns the talks as an Atom feed, newest first
119
+ # @api public
120
+ # @return [String] the feed, as XML
121
+ # @example
122
+ # File.write("talks.atom", Sferik.talks_feed)
123
+ # @see API::TalkEndpoints#talks_feed What it raises, and more about it
124
+ # @!method self.podcasts
125
+ # Returns podcast appearances
126
+ # @api public
127
+ # @return [Array<Podcast>]
128
+ # @example
129
+ # Sferik.podcasts.first.show # => "Ruby Rogues, episode 248"
130
+ # @see API::TalkEndpoints#podcasts What it raises, and more about it
131
+ # @!method self.resume
132
+ # Returns the resume as a JSON Resume document
133
+ # @api public
134
+ # @return [Resume]
135
+ # @example
136
+ # Sferik.resume.work.first.position
137
+ # @see API::ResumeEndpoints#resume What it raises, and more about it
138
+ # @!method self.resume_latex
139
+ # Returns the resume as a LaTeX document, ready for pdflatex or tectonic
140
+ # @api public
141
+ # @return [String] the LaTeX source
142
+ # @example
143
+ # File.write("resume.tex", Sferik.resume_latex)
144
+ # @see API::ResumeEndpoints#resume_latex What it raises, and more about it
145
+ # @!method self.resume_pdf
146
+ # Returns the resume as a two-page PDF
147
+ # @api public
148
+ # @return [String] the PDF, as binary
149
+ # @example
150
+ # File.binwrite("resume.pdf", Sferik.resume_pdf)
151
+ # @see API::ResumeEndpoints#resume_pdf What it raises, and more about it
152
+ # @!method self.who
153
+ # Returns everyone reading the site right now
154
+ # @api public
155
+ # @return [Who]
156
+ # @example
157
+ # Sferik.who.map(&:page) # => ["/", "/talks"]
158
+ # @see API::SiteEndpoints#who What it raises, and more about it
159
+ # @!method self.check_in(token, page: "/", &block)
160
+ # Checks in a terminal, or keeps one logged in while a block runs
161
+ # @api public
162
+ # @param token [String] a random token, one per terminal, of 16 to 64 letters, digits, underscores, and hyphens
163
+ # @param page [String] the page the terminal is on: "/", "/talks", or "/resume"
164
+ # @yield [who] what to do while the terminal is logged in: it's checked in again every minute until the block ends
165
+ # @yieldparam who [Who] everyone reading the site when the terminal checked in, with the terminal as {Who#you}
166
+ # @return [Who, Object] everyone reading the site, with the terminal that checked in as {Who#you}, or what the
167
+ # block returns, if there is one
168
+ # @example
169
+ # Sferik.check_in(SecureRandom.uuid).you # => "ttys001"
170
+ # @example Stay logged in for as long as it takes to write a message
171
+ # Sferik.check_in(SecureRandom.uuid) { |who| Sferik.write(gets, tty: who.you) }
172
+ # @see API::SiteEndpoints#check_in What it raises, and more about it
173
+ # @!method self.write(message, tty: nil, key: SecureRandom.uuid)
174
+ # Sends Erik a message, as the shell's write sferik does
175
+ # @api public
176
+ # @param message [String] the message, as plain text: 5,000 bytes at most, sent as UTF-8
177
+ # @param tty [String, nil] the sender's terminal, for the subject line: {Who#you}, from {.check_in}
178
+ # @param key [String] a random key, one per message: the server doesn't email a message twice whose key it has taken
179
+ # @return [String] what the server says: "message sent to sferik"
180
+ # @example
181
+ # Sferik.write("Hello from Ruby. Reply to me@example.com")
182
+ # @see API::SiteEndpoints#write What it raises, and more about it
183
+ # @!method self.text(path = "")
184
+ # Returns a resource as terminal output, wrapped to 80 columns
185
+ # @api public
186
+ # @param path [String] the resource's path: "/whoami", "/resume" (as a man page), etc. (defaults to the home page)
187
+ # @return [String] the text
188
+ # @example
189
+ # puts Sferik.text("/resume")
190
+ # @see API::SiteEndpoints#text What it raises, and more about it
191
+ # @!method self.openapi
192
+ # Returns the API's OpenAPI 3.1 description
193
+ # @api public
194
+ # @return [Hash{String => Object}] the parsed document, deep-frozen
195
+ # @example
196
+ # Sferik.openapi["paths"].keys
197
+ # @see API::SiteEndpoints#openapi What it raises, and more about it
198
+ # @!method self.deployment
199
+ # Returns which commit of the site is deployed, and when it was
200
+ # @api public
201
+ # @return [Deployment]
202
+ # @example
203
+ # Sferik.deployment.commit # => "6a34226a3f351a78339b75430055a018ac30c964"
204
+ # @see API::SiteEndpoints#deployment What it raises, and more about it
205
+ # @!method self.status
206
+ # Returns whether the site's live numbers come as they should
207
+ # @api public
208
+ # @return [Status]
209
+ # @example
210
+ # Sferik.status.github.error # => nil
211
+ # @see API::SiteEndpoints#status What it raises, and more about it
212
+ def_delegators :client, *API.public_instance_methods
213
+
214
+ # The methods of SingleForwardable, which the module delegates with rather than offers (one at a time: YARD can't
215
+ # read the names of a splat)
216
+ SingleForwardable.instance_methods.each { |name| private_class_method name }
217
+
218
+ # The client the API methods of the module delegate to
219
+ #
220
+ # The client is built from the global configuration, and built again whenever that configuration changes.
221
+ #
222
+ # @api public
223
+ # @return [Client] the client
224
+ # @example Perform a raw request with the module's client
225
+ # Sferik.client.get("/whoami", accept: "text/plain")
226
+ def self.client
227
+ CLIENT_MUTEX.synchronize do
228
+ @client = nil unless options.eql?(@client_options)
229
+ @client_options = options
230
+ @client ||= new
231
+ end
232
+ end
233
+
234
+ # Reset the global configuration and forget the client
235
+ #
236
+ # @api public
237
+ # @return [self]
238
+ # @example Reset the configuration
239
+ # Sferik.reset
240
+ def self.reset
241
+ CLIENT_MUTEX.synchronize do
242
+ @client = @client_options = nil
243
+ super
244
+ end
245
+ end
246
+ end
data/sig/manifest.yaml ADDED
@@ -0,0 +1,13 @@
1
+ # The standard libraries the signatures of sferik refer to, which rbs collection loads for code that depends on it
2
+ dependencies:
3
+ - name: date
4
+ - name: forwardable
5
+ - name: json
6
+ - name: net-http
7
+ - name: openssl
8
+ - name: optparse
9
+ - name: securerandom
10
+ - name: time
11
+ - name: timeout
12
+ - name: uri
13
+ - name: zlib