+5
app/bluesky_account.rb
+5
app/bluesky_account.rb
···
40
40
@sky.get_request('com.atproto.repo.getRecord', { repo: repo, collection: collection, rkey: rkey })
41
41
end
42
42
43
+
def fetch_blob(cid)
44
+
# todo
45
+
@sky.get_blob('com.atproto.sync.getBlob', { did: @sky.user.did, cid: cid })
46
+
end
47
+
43
48
def delete_record_at(uri)
44
49
repo, collection, rkey = uri.split('/')[2..4]
45
50
+21
app/bluesky_client.rb
+21
app/bluesky_client.rb
···
24
24
def save_config
25
25
File.write(CONFIG_FILE, YAML.dump(@config))
26
26
end
27
+
28
+
def get_blob(method, params = nil)
29
+
check_access
30
+
31
+
headers = authentication_header(true)
32
+
url = URI("#{base_url}/#{method}")
33
+
34
+
if params && !params.empty?
35
+
url.query = URI.encode_www_form(params)
36
+
end
37
+
38
+
request = Net::HTTP::Get.new(url, headers)
39
+
response = make_request(request)
40
+
41
+
case response
42
+
when Net::HTTPSuccess
43
+
response.body
44
+
else
45
+
handle_response(response)
46
+
end
47
+
end
27
48
end
+8
-2
app/mastodon_account.rb
+8
-2
app/mastodon_account.rb
···
42
42
client.create_app(APP_NAME, 'urn:ietf:wg:oauth:2.0:oob', scopes)
43
43
end
44
44
45
-
def post_status(text)
45
+
def post_status(text, media_ids = nil)
46
46
instance = @config['handle'].split('@').last
47
47
api = MastodonAPI.new(instance, @config['access_token'])
48
-
api.post_status(text)
48
+
api.post_status(text, media_ids)
49
+
end
50
+
51
+
def upload_media(data, filename, content_type, alt = nil)
52
+
instance = @config['handle'].split('@').last
53
+
api = MastodonAPI.new(instance, @config['access_token'])
54
+
api.upload_media(data, filename, content_type, alt)
49
55
end
50
56
end
+28
-4
app/mastodon_api.rb
+28
-4
app/mastodon_api.rb
···
58
58
get_json("/accounts/#{user_id}/statuses", params)
59
59
end
60
60
61
-
def post_status(text)
62
-
post_json("/statuses", {
63
-
status: text
64
-
})
61
+
def post_status(text, media_ids = nil)
62
+
params = { status: text }
63
+
params['media_ids[]'] = media_ids if media_ids
64
+
65
+
post_json("/statuses", params)
66
+
end
67
+
68
+
def upload_media(data, filename, content_type, alt = nil)
69
+
url = URI("https://#{@host}/api/v2/media")
70
+
headers = { 'Authorization' => "Bearer #{@access_token}" }
71
+
72
+
form_data = [
73
+
['file', data, { :filename => filename, :content_type => content_type }],
74
+
['description', alt.to_s]
75
+
]
76
+
77
+
request = Net::HTTP::Post.new(url, headers)
78
+
request.set_form(form_data, 'multipart/form-data')
79
+
80
+
response = Net::HTTP.start(url.hostname, url.port, :use_ssl => true) do |http|
81
+
http.request(request)
82
+
end
83
+
84
+
if response.code.to_i / 100 == 2
85
+
JSON.parse(response.body)
86
+
else
87
+
raise APIError.new(response)
88
+
end
65
89
end
66
90
67
91
def get_json(path, params = {})
+29
-1
app/tootify.rb
+29
-1
app/tootify.rb
···
82
82
end
83
83
end
84
84
85
-
p @mastodon.post_status(text)
85
+
if images = attached_images(record)
86
+
media_ids = []
87
+
88
+
images.each do |image|
89
+
alt = image['alt']
90
+
cid = image['image']['ref']['$link']
91
+
mime = image['image']['mimeType']
92
+
93
+
data = @bluesky.fetch_blob(cid)
94
+
95
+
uploaded_media = @mastodon.upload_media(data, cid, mime, alt)
96
+
media_ids << uploaded_media['id']
97
+
end
98
+
end
99
+
100
+
p @mastodon.post_status(text, media_ids)
86
101
end
87
102
88
103
def expand_facets(record)
···
125
140
embed['record']['uri']
126
141
when 'app.bsky.embed.recordWithMedia'
127
142
embed['record']['record']['uri']
143
+
else
144
+
nil
145
+
end
146
+
end
147
+
end
148
+
149
+
def attached_images(record)
150
+
if embed = record['embed']
151
+
case embed['$type']
152
+
when 'app.bsky.embed.images'
153
+
embed['images']
154
+
when 'app.bsky.embed.recordWithMedia'
155
+
embed['media']['images']
128
156
else
129
157
nil
130
158
end