minisky 0.3.1 → 0.4.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 +4 -4
- data/CHANGELOG.md +9 -0
- data/example/ask_password.rb +76 -0
- data/lib/minisky/minisky.rb +7 -1
- data/lib/minisky/requests.rb +24 -16
- data/lib/minisky/version.rb +1 -1
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b22e3b707a428f0381e5c194ce6b5bd4118f6b6dfb7f2d249140c8025e3b1dd7
|
4
|
+
data.tar.gz: 2a6370ea6cb538c680252836295c411ff4c6df93b8c5aab9d8b73b843753febb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f86def9480e86d2989a52f143eacee8e5b78fede45bd6ba49ea7ad54f1da88a55555421d3fdfdddad025bed21a708c830e5e9b2c351ba57e016234e200b9f74
|
7
|
+
data.tar.gz: f8f7faa8d7e5df7807d6e9bb7ee1b87d1d5ab5503c0193fd031190be6e6346004618c66efdba96970fc93117d4f587c53ff5f17585a2ffa3ddafb503abc5a3cc
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## [0.4.0] - 2024-03-31 🐣
|
2
|
+
|
3
|
+
* allow passing non-JSON body to requests (e.g. when uploading blobs)
|
4
|
+
* allow passing custom headers to requests, including overriding `Content-Type`
|
5
|
+
* fixed error when the response is success but not JSON (e.g. an empty body like in deleteRecord)
|
6
|
+
* allow passing options to the client in the initializer
|
7
|
+
* aliased `default_progress` setting as `progress`
|
8
|
+
* added `base64` dependency explicitly to the gemspec - fixes a warning in Ruby 3.3, since it will be extracted as an optional gem in 3.4
|
9
|
+
|
1
10
|
## [0.3.1] - 2023-10-10
|
2
11
|
|
3
12
|
* fixed Minisky not working on Ruby 2.x
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Example: print 10 latest posts from the user's home feed.
|
4
|
+
#
|
5
|
+
# Instead of using a config file to read & store authentication info, this example uses a customized client class
|
6
|
+
# which reads the password from the console and creates a throwaway access token.
|
7
|
+
#
|
8
|
+
# This approach makes sense for one-off scripts, but it shouldn't be used for things that need to be done repeatedly
|
9
|
+
# and often (the authentication-related endpoints have lower rate limits than others).
|
10
|
+
|
11
|
+
# load minisky from a local folder - you normally won't need this
|
12
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
13
|
+
|
14
|
+
require 'io/console'
|
15
|
+
require 'minisky'
|
16
|
+
|
17
|
+
class TransientClient
|
18
|
+
include Minisky::Requests
|
19
|
+
|
20
|
+
attr_reader :config, :host
|
21
|
+
|
22
|
+
def initialize(host, user)
|
23
|
+
@host = host
|
24
|
+
@config = { 'id' => user.gsub(/^@/, '') }
|
25
|
+
end
|
26
|
+
|
27
|
+
def ask_for_password
|
28
|
+
print "Enter password for @#{config['id']}: "
|
29
|
+
@config['pass'] = STDIN.noecho(&:gets).chomp
|
30
|
+
puts
|
31
|
+
end
|
32
|
+
|
33
|
+
def save_config
|
34
|
+
# ignore
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
host, handle = ARGV
|
39
|
+
|
40
|
+
unless host && handle
|
41
|
+
puts "Usage: #{$PROGRAM_NAME} <pds_hostname> <handle>"
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
|
45
|
+
# create a client instance & read password
|
46
|
+
bsky = TransientClient.new(host, handle)
|
47
|
+
bsky.ask_for_password
|
48
|
+
|
49
|
+
# fetch 10 posts from the user's home feed
|
50
|
+
result = bsky.get_request('app.bsky.feed.getTimeline', { limit: 10 })
|
51
|
+
|
52
|
+
result['feed'].each do |r|
|
53
|
+
reason = r['reason']
|
54
|
+
reply = r['reply']
|
55
|
+
post = r['post']
|
56
|
+
|
57
|
+
if reason && reason['$type'] == 'app.bsky.feed.defs#reasonRepost'
|
58
|
+
puts "[Reposted by @#{reason['by']['handle']}]"
|
59
|
+
end
|
60
|
+
|
61
|
+
handle = post['author']['handle']
|
62
|
+
timestamp = Time.parse(post['record']['createdAt']).getlocal
|
63
|
+
|
64
|
+
puts "@#{handle} • #{timestamp}"
|
65
|
+
puts
|
66
|
+
|
67
|
+
if reply
|
68
|
+
puts "[in reply to @#{reply['parent']['author']['handle']}]"
|
69
|
+
puts
|
70
|
+
end
|
71
|
+
|
72
|
+
puts post['record']['text']
|
73
|
+
puts
|
74
|
+
puts "=" * 120
|
75
|
+
puts
|
76
|
+
end
|
data/lib/minisky/minisky.rb
CHANGED
@@ -3,7 +3,7 @@ require 'yaml'
|
|
3
3
|
class Minisky
|
4
4
|
attr_reader :host, :config
|
5
5
|
|
6
|
-
def initialize(host, config_file)
|
6
|
+
def initialize(host, config_file, options = {})
|
7
7
|
@host = host
|
8
8
|
@config_file = config_file
|
9
9
|
|
@@ -18,6 +18,12 @@ class Minisky
|
|
18
18
|
@send_auth_headers = false
|
19
19
|
@auto_manage_tokens = false
|
20
20
|
end
|
21
|
+
|
22
|
+
if options
|
23
|
+
options.each do |k, v|
|
24
|
+
self.send("#{k}=", v)
|
25
|
+
end
|
26
|
+
end
|
21
27
|
end
|
22
28
|
|
23
29
|
def save_config
|
data/lib/minisky/requests.rb
CHANGED
@@ -39,6 +39,9 @@ class Minisky
|
|
39
39
|
instance_variable_defined?('@auto_manage_tokens') ? @auto_manage_tokens : true
|
40
40
|
end
|
41
41
|
|
42
|
+
alias progress default_progress
|
43
|
+
alias progress= default_progress=
|
44
|
+
|
42
45
|
def base_url
|
43
46
|
@base_url ||= "https://#{host}/xrpc"
|
44
47
|
end
|
@@ -47,10 +50,10 @@ class Minisky
|
|
47
50
|
@user ||= User.new(config)
|
48
51
|
end
|
49
52
|
|
50
|
-
def get_request(method, params = nil, auth: default_auth_mode)
|
53
|
+
def get_request(method, params = nil, auth: default_auth_mode, headers: nil)
|
51
54
|
check_access if auto_manage_tokens && auth == true
|
52
55
|
|
53
|
-
headers = authentication_header(auth)
|
56
|
+
headers = authentication_header(auth).merge(headers || {})
|
54
57
|
url = URI("#{base_url}/#{method}")
|
55
58
|
|
56
59
|
if params && !params.empty?
|
@@ -63,18 +66,24 @@ class Minisky
|
|
63
66
|
handle_response(response)
|
64
67
|
end
|
65
68
|
|
66
|
-
def post_request(method, params = nil, auth: default_auth_mode)
|
69
|
+
def post_request(method, params = nil, auth: default_auth_mode, headers: nil)
|
67
70
|
check_access if auto_manage_tokens && auth == true
|
68
71
|
|
69
|
-
headers = authentication_header(auth).merge(
|
70
|
-
|
72
|
+
headers = authentication_header(auth).merge(headers || {})
|
73
|
+
headers["Content-Type"] = "application/json" unless headers.keys.any? { |k| k.to_s.downcase == 'content-type' }
|
74
|
+
|
75
|
+
body = if params.is_a?(String) || params.nil?
|
76
|
+
params.to_s
|
77
|
+
else
|
78
|
+
params.to_json
|
79
|
+
end
|
71
80
|
|
72
81
|
response = Net::HTTP.post(URI("#{base_url}/#{method}"), body, headers)
|
73
82
|
handle_response(response)
|
74
83
|
end
|
75
84
|
|
76
85
|
def fetch_all(method, params = nil, field:,
|
77
|
-
auth: default_auth_mode, break_when: nil, max_pages: nil, progress: @default_progress)
|
86
|
+
auth: default_auth_mode, break_when: nil, max_pages: nil, headers: nil, progress: @default_progress)
|
78
87
|
data = []
|
79
88
|
params = {} if params.nil?
|
80
89
|
pages = 0
|
@@ -82,7 +91,7 @@ class Minisky
|
|
82
91
|
loop do
|
83
92
|
print(progress) if progress
|
84
93
|
|
85
|
-
response = get_request(method, params, auth: auth)
|
94
|
+
response = get_request(method, params, auth: auth, headers: headers)
|
86
95
|
records = response[field]
|
87
96
|
cursor = response['cursor']
|
88
97
|
|
@@ -152,14 +161,14 @@ class Minisky
|
|
152
161
|
alias_method :do_post_request, :post_request
|
153
162
|
private :do_get_request, :do_post_request
|
154
163
|
|
155
|
-
def get_request(method, params = nil, auth: default_auth_mode, **kwargs)
|
164
|
+
def get_request(method, params = nil, auth: default_auth_mode, headers: nil, **kwargs)
|
156
165
|
params ||= kwargs unless kwargs.empty?
|
157
|
-
do_get_request(method, params, auth: auth)
|
166
|
+
do_get_request(method, params, auth: auth, headers: headers)
|
158
167
|
end
|
159
168
|
|
160
|
-
def post_request(method, params = nil, auth: default_auth_mode, **kwargs)
|
169
|
+
def post_request(method, params = nil, auth: default_auth_mode, headers: nil, **kwargs)
|
161
170
|
params ||= kwargs unless kwargs.empty?
|
162
|
-
do_post_request(method, params, auth: auth)
|
171
|
+
do_post_request(method, params, auth: auth, headers: headers)
|
163
172
|
end
|
164
173
|
end
|
165
174
|
|
@@ -210,16 +219,15 @@ class Minisky
|
|
210
219
|
def handle_response(response)
|
211
220
|
status = response.code.to_i
|
212
221
|
message = response.message
|
222
|
+
response_body = (response.content_type == 'application/json') ? JSON.parse(response.body) : response.body
|
213
223
|
|
214
224
|
case response
|
215
225
|
when Net::HTTPSuccess
|
216
|
-
|
226
|
+
response_body
|
217
227
|
when Net::HTTPRedirection
|
218
228
|
raise UnexpectedRedirect.new(status, message, response['location'])
|
219
229
|
else
|
220
|
-
|
221
|
-
|
222
|
-
error_class = if data.is_a?(Hash) && data['error'] == 'ExpiredToken'
|
230
|
+
error_class = if response_body.is_a?(Hash) && response_body['error'] == 'ExpiredToken'
|
223
231
|
ExpiredTokenError
|
224
232
|
elsif response.is_a?(Net::HTTPClientError)
|
225
233
|
ClientErrorResponse
|
@@ -229,7 +237,7 @@ class Minisky
|
|
229
237
|
BadResponse
|
230
238
|
end
|
231
239
|
|
232
|
-
raise error_class.new(status, message,
|
240
|
+
raise error_class.new(status, message, response_body)
|
233
241
|
end
|
234
242
|
end
|
235
243
|
end
|
data/lib/minisky/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minisky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kuba Suder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2024-03-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: base64
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.1'
|
13
27
|
description: A very simple client class that lets you log in to the Bluesky API and
|
14
28
|
make any requests there.
|
15
29
|
email:
|
@@ -21,6 +35,7 @@ files:
|
|
21
35
|
- CHANGELOG.md
|
22
36
|
- LICENSE.txt
|
23
37
|
- README.md
|
38
|
+
- example/ask_password.rb
|
24
39
|
- example/fetch_my_posts.rb
|
25
40
|
- example/fetch_profile.rb
|
26
41
|
- example/post_skeet.rb
|