class WsRosterController < WebsocketRails::BaseController
require 'xmpp4r/roster'
require 'xmpp4r/vcard'
def initialize
super
@storages_arr = [:clients, :rosters]
@storages_hash = [:link_roster_client, :presences]
end
def initialize_storage
@storages_arr.each do |storage|
connection_store[storage] = []
end
@storages_hash.each do |storage|
connection_store[storage] = {}
end
end
##
# Pripoj sa na jabber ucty.
def connect
initialize_storage()
clients = Token.fing_user_accounts_having_to_token(session[:token])
clients.each do |credentials|
begin
client = Signin.try_login(credentials['jid'], credentials['pass'])
connection_store[:clients] << client
rescue Signin::LoginError
send_message 'app.client.cannot_connect', true
end
end
end
##
# Inicializuj roster so zoznamom ludi v nom.
# Vrat zoznam ludi (ich JID).
def init_roster
all_jids = []
connection_store[:clients].each do |client|
roster = Jabber::Roster::Helper.new(client)
connection_store[:rosters] << roster
connection_store[:link_roster_client][roster] = client
roster.get_roster()
roster.wait_for_roster()
roster.items.each do |jid, contact|
all_jids << {
jid: jid.to_s,
belongsTo: client.jid.strip.to_s
}
end
end
trigger_success contacts: all_jids
end
##
# Stiahni vcard ludi v rosteri
def start_fetching_vcards
connection_store[:rosters].each do |roster|
client = connection_store[:link_roster_client][roster]
roster.items.each do |jid, contact|
Thread.new do
vcard = get_vcard(client, jid.to_s)
send_message 'app.roster.vcard', jid: jid.to_s, vcard: vcard
end
end
end
end
##
# Zacni pocuvat zmeny stavov v rosteri
def start_polling_contacts_state
connection_store[:rosters].each do |roster|
roster.add_subscription_callback do |roster_item, stanza|
# stan unsubscribe = niekto uz ma nesubscribuje
# stan unsubscribed = niekto ma uz nesubscribuje a aj si ma vymazal
# stan subscribed = niekto moze vidiet moj stav
client = connection_store[:link_roster_client][roster]
send_message 'app.roster.subscriptionChanged',
action: stanza.type,
jid: roster_item.jid.strip.to_s,
belongsTo: client.jid.strip.to_s
end
roster.add_presence_callback do |roster_item, old_presence, new_presence|
if new_presence.type == :unavailable
result = {status: :offline, message: ''}
else
status = uniform_presence(new_presence.show)
result = { status: status, message: new_presence.status.to_s }
end
send_message 'app.roster.statusChanged',
jid: roster_item.jid.strip.to_s, status: result
end
end
end
##
# Nastav ma ako online
#
# Musi sa zavolat az po start_polling_contacts_state, inak sa nemusia
# zachytit stavy ostatnych v rosteri.
def set_presence
connection_store[:clients].each do |client|
presence = Jabber::Presence.new.set_type(:available)
client.send(presence)
connection_store[:presences][client] = presence
end
end
def remove_contact
jid = message[:jid]
client_jid = message[:client]
found_roster_item = nil
connection_store[:rosters].each do |roster|
roster_item = roster.find(jid)
if roster_item.first[1] && connection_store[:link_roster_client][roster].jid.strip.to_s == client_jid
found_roster_item = roster_item.first[1]
break
end
end
found_roster_item && found_roster_item.remove()
end
##
# Ziskaj informacie o mne (meno, stav, status...)
def myself
# TODO: v pripade viacerych uctov zjednotit meno a stav
vcard = {}
jid = presence = ''
connection_store[:clients].each do |client|
vcard = get_vcard(client)
jid = client.jid.strip.to_s
presence = uniform_presence(connection_store[:presences][client].show)
end
trigger_success jid: jid, vcard: vcard, status: presence
end
def me_update_status
status_message = message[:message]
state = message[:state]
xmpp_state = case state
when 'away' then :away
when 'dnd' then :dnd
else nil
end
presence = Jabber::Presence.new
presence.show = xmpp_state
presence.status = status_message
connection_store[:clients].each do |client|
client.send(presence)
end
end
def me_update_vcard
end
def disconnect
connection_store[:clients] && connection_store[:clients].each do |client|
client.close()
end
@storages_arr.each do |storage|
connection_store.delete(storage)
end
@storages_hash.each do |storage|
connection_store.delete(storage)
end
end
##
# Pridaj noveho priatela do zoznamu
def add_friend(data)
end
private
def get_vcard(me, contact_jid = nil)
vcard = Jabber::Vcard::Helper.get(me, contact_jid)
{ name: pull_name_from_vcard(vcard) || contact_jid,
avatar: vcard['PHOTO/TYPE'] && ('data:' + vcard['PHOTO/TYPE'] + ';base64,' + vcard['PHOTO/BINVAL']) || ''
}
end
def pull_name_from_vcard(vcard)
vcard && (vcard['FN'] || vcard['NICKNAME'])
end
def uniform_presence(xmpp_presence)
case xmpp_presence
when :away, :xa then :away
when :dnd then :dnd
else :online
end
end
end