minisky 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|