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_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 ## # 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 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