2a61cdcc |
class WsRosterController < WsController |
b27f285a |
require 'xmpp4r/roster'
require 'xmpp4r/vcard' |
ff94bdbf |
|
b27f285a |
def initialize
super |
d4872cda |
@storages_arr = [:clients, :rosters]
@storages_hash = [:link_roster_client, :presences] |
b27f285a |
end
def initialize_storage |
d4872cda |
@storages_arr.each do |storage| |
93083165 |
connection_store[storage] = [] |
b27f285a |
end |
52ef7688 |
|
d4872cda |
@storages_hash.each do |storage|
connection_store[storage] = {}
end |
ff94bdbf |
end
|
52ef7688 |
##
# Pripoj sa na jabber ucty. |
70fc03c1 |
def connect |
b27f285a |
initialize_storage()
|
a615e89f |
# TODO: Pouzit najprv:
# clients = Token.fing_user_accounts_having_to_token(session[:token])
# ale toto, az ked budem mat dokonceny multiaccount (settings a popup) |
5011e360 |
# TODO: skusit zrychlit |
f3618169 |
cookies = env['rack.request.cookie_hash'] # TODO: nahlasit bug na websocket-rails, lebo sa neda pristupit ku `cookies' |
882090fc |
cipher_key = cookies['key']
cipher_iv = cookies['iv'] |
b27f285a |
|
882090fc |
clients = session[:users].map do |jid, encrypted_pass|
decrypted_pass = Security::decrypt(encrypted_pass, cipher_key, cipher_iv)
{jid: jid, pass: decrypted_pass}
end |
b27f285a |
|
882090fc |
clients.each do |client| |
b27f285a |
begin |
882090fc |
client = Signin.try_login(client[:jid], client[:pass]) |
93083165 |
connection_store[:clients] << client |
b27f285a |
rescue Signin::LoginError |
52ef7688 |
send_message 'app.client.cannot_connect', true |
b27f285a |
end
end |
70fc03c1 |
end
|
ff94bdbf |
## |
52ef7688 |
# 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 |
b27f285a |
roster.get_roster() |
52ef7688 |
roster.wait_for_roster() |
b27f285a |
roster.items.each do |jid, contact| |
6a6ccd01 |
all_jids << {
jid: jid.to_s,
belongsTo: client.jid.strip.to_s
} |
b27f285a |
end
end
|
52ef7688 |
trigger_success contacts: all_jids |
ff94bdbf |
end
|
52ef7688 |
##
# 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| |
635339a3 |
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
|
52ef7688 |
roster.add_presence_callback do |roster_item, old_presence, new_presence|
if new_presence.type == :unavailable
result = {status: :offline, message: ''} |
5011e360 |
# mozno treba vyhodit cloveka z multichatu, ak som jeho owner |
88c1de39 |
kick_from_all_multichats(roster_item.jid.strip.to_s) |
52ef7688 |
else |
d4872cda |
status = uniform_presence(new_presence.show) |
52ef7688 |
result = { status: status, message: new_presence.status.to_s }
end
send_message 'app.roster.statusChanged',
jid: roster_item.jid.strip.to_s, status: result |
b27f285a |
end |
43ad79fa |
end
end |
52ef7688 |
|
43ad79fa |
##
# 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| |
d4872cda |
presence = Jabber::Presence.new.set_type(:available)
client.send(presence)
connection_store[:presences][client] = presence
end
end
|
635339a3 |
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
|
d4872cda |
##
# 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) |
52ef7688 |
end |
d4872cda |
trigger_success jid: jid, vcard: vcard, status: presence |
52ef7688 |
end
|
c4a1e746 |
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
|
52ef7688 |
def disconnect
connection_store[:clients] && connection_store[:clients].each do |client|
client.close() |
b27f285a |
end |
ff94bdbf |
|
4b5bb9c5 |
@storages_arr.each do |storage|
connection_store.delete(storage)
end
@storages_hash.each do |storage| |
b27f285a |
connection_store.delete(storage)
end |
ff94bdbf |
end |
70fc03c1 |
|
7a817e66 |
def ask_if_using_this_app
connection_store[:rosters].each do |roster|
client = connection_store[:link_roster_client][roster]
roster.items.each do |jid, contact|
client.send(MessageBuilder::control_question(client.jid.strip.to_s, jid))
end
end
start_polling_control_answer()
end
|
b27f285a |
##
# Pridaj noveho priatela do zoznamu
def add_friend(data) |
70fc03c1 |
|
23f7b7b2 |
end |
52ef7688 |
private
|
d4872cda |
def get_vcard(me, contact_jid = nil)
vcard = Jabber::Vcard::Helper.get(me, contact_jid) |
52ef7688 |
|
d4872cda |
{ name: pull_name_from_vcard(vcard) || contact_jid, |
f99e8d29 |
avatar: vcard['PHOTO/TYPE'] && ('data:' + vcard['PHOTO/TYPE'] + ';base64,' + vcard['PHOTO/BINVAL']) || '' |
52ef7688 |
}
end |
d4872cda |
def pull_name_from_vcard(vcard) |
f99e8d29 |
vcard && (vcard['FN'] || vcard['NICKNAME']) |
d4872cda |
end
def uniform_presence(xmpp_presence)
case xmpp_presence
when :away, :xa then :away
when :dnd then :dnd
else :online
end
end |
7a817e66 |
def start_polling_control_answer
connection_store[:clients].each do |client|
client.add_message_callback do |message|
if message.attribute('i_am_using_same_app')
send_message 'app.roster.using_this_app',
jid: message.from.node + '@' + message.from.domain
elsif message.attribute('are_you_using_my_app')
client.send(MessageBuilder::control_answer(client.jid.strip.to_s, message.from))
end
end
end
end |
ff94bdbf |
end |