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