81 lines
2.1 KiB
Ruby
81 lines
2.1 KiB
Ruby
require 'digest'
|
|
require "image_processing/vips"
|
|
|
|
module EjabberdManager
|
|
class SetAvatar < EjabberdManagerService
|
|
def initialize(user:, overwrite: false)
|
|
@user = user
|
|
@overwrite = overwrite
|
|
end
|
|
|
|
def call
|
|
unless @overwrite
|
|
current_avatar = EjabberdManager::GetAvatar.call(user: @user)
|
|
Rails.logger.info { "User #{@user.cn} already has an avatar set" }
|
|
return if current_avatar.present?
|
|
end
|
|
|
|
Rails.logger.debug { "Setting XMPP avatar for user #{@user.cn}" }
|
|
|
|
stanzas = build_xep0084_stanzas
|
|
|
|
stanzas.each do |stanza|
|
|
payload = { from: @user.address, to: @user.address, stanza: stanza }
|
|
res = send_stanza payload
|
|
raise res.inspect if res.status != 200
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def process_avatar
|
|
@user.avatar.blob.open do |file|
|
|
processed = ImageProcessing::Vips
|
|
.source(file)
|
|
.resize_to_fill(256, 256)
|
|
.convert("png")
|
|
.call
|
|
processed.read
|
|
end
|
|
end
|
|
|
|
# See https://xmpp.org/extensions/xep-0084.html
|
|
def build_xep0084_stanzas
|
|
img_data = process_avatar
|
|
sha1_hash = Digest::SHA1.hexdigest(img_data)
|
|
base64_data = Base64.strict_encode64(img_data)
|
|
|
|
[
|
|
"""
|
|
<iq type='set' from='#{@user.address}' id='avatar-data-#{rand(101)}'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<publish node='urn:xmpp:avatar:data'>
|
|
<item id='#{sha1_hash}'>
|
|
<data xmlns='urn:xmpp:avatar:data'>#{base64_data}</data>
|
|
</item>
|
|
</publish>
|
|
</pubsub>
|
|
</iq>
|
|
""".strip,
|
|
"""
|
|
<iq type='set' from='#{@user.address}' id='avatar-metadata-#{rand(101)}'>
|
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
|
<publish node='urn:xmpp:avatar:metadata'>
|
|
<item id='#{sha1_hash}'>
|
|
<metadata xmlns='urn:xmpp:avatar:metadata'>
|
|
<info bytes='#{img_data.size}'
|
|
id='#{sha1_hash}'
|
|
height='256'
|
|
type='image/png'
|
|
width='256'/>
|
|
</metadata>
|
|
</item>
|
|
</publish>
|
|
</pubsub>
|
|
</iq>
|
|
""".strip,
|
|
]
|
|
end
|
|
end
|