social_stream-presence 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/Rakefile +7 -0
  2. data/app/assets/audio/chat/onMessageAudio.mp3 +0 -0
  3. data/app/assets/audio/chat/onMessageAudio.wav +0 -0
  4. data/app/assets/images/black_arrow3.png +0 -0
  5. data/app/assets/images/status/available.png +0 -0
  6. data/app/assets/images/status/away.png +0 -0
  7. data/app/assets/images/status/dnd.png +0 -0
  8. data/app/assets/javascripts/jquery-ui-1.8.14.custom.min.js +789 -0
  9. data/app/assets/javascripts/jquery.tools.min.js +17 -0
  10. data/app/assets/javascripts/jquery.tools.tooltip.js +11 -0
  11. data/app/assets/javascripts/jquery.ui.chatbox.js +260 -0
  12. data/app/assets/javascripts/social_stream-presence.js +2 -0
  13. data/app/assets/javascripts/store.js +20 -0
  14. data/app/assets/javascripts/strophe.js +3612 -0
  15. data/app/assets/javascripts/xmpp_client.js +494 -0
  16. data/app/assets/stylesheets/chat.css +239 -0
  17. data/app/assets/stylesheets/jquery.ui.chatbox.css +54 -0
  18. data/app/assets/stylesheets/social_stream-presence.css +3 -0
  19. data/app/controllers/xmpp_controller.rb +223 -0
  20. data/app/helpers/xmpp_helper.rb +20 -0
  21. data/app/views/xmpp/_chat.html.erb +63 -0
  22. data/app/views/xmpp/_chat_connecting.html.erb +8 -0
  23. data/app/views/xmpp/_chat_contacts.html.erb +46 -0
  24. data/app/views/xmpp/_chat_off.html.erb +35 -0
  25. data/app/views/xmpp/active_users.html.erb +33 -0
  26. data/app/views/xmpp/chat.html.erb +13 -0
  27. data/app/views/xmpp/index.html +19 -0
  28. data/app/views/xmpp/test.html.erb +11 -0
  29. data/config/routes.rb +15 -0
  30. data/db/migrate/20110711111408_add_connected_column_to_user.rb +9 -0
  31. data/db/migrate/20110928135031_add_status_column_to_user.rb +9 -0
  32. data/ejabberd/conf/ejabberd.cfg +625 -0
  33. data/ejabberd/conf/ejabberdctl.cfg +154 -0
  34. data/ejabberd/conf/inetrc +3 -0
  35. data/ejabberd/conf/server.pem +37 -0
  36. data/ejabberd/conf/ssconfig.cfg +32 -0
  37. data/ejabberd/ejabberd_scripts/authentication_script +117 -0
  38. data/ejabberd/ejabberd_scripts/authentication_script_org +114 -0
  39. data/ejabberd/ejabberd_scripts/compile_module +34 -0
  40. data/ejabberd/ejabberd_scripts/emanagement +245 -0
  41. data/ejabberd/ejabberd_scripts/generate_random_password +18 -0
  42. data/ejabberd/ejabberd_scripts/kill_authentication_script.sh +13 -0
  43. data/ejabberd/ejabberd_scripts/reset_connection_script +55 -0
  44. data/ejabberd/ejabberd_scripts/reset_logs.sh +23 -0
  45. data/ejabberd/ejabberd_scripts/set_connection_script +48 -0
  46. data/ejabberd/ejabberd_scripts/set_presence_script +48 -0
  47. data/ejabberd/ejabberd_scripts/show_config.sh +30 -0
  48. data/ejabberd/ejabberd_scripts/start_ejabberd.sh +68 -0
  49. data/ejabberd/ejabberd_scripts/stop_ejabberd.sh +12 -0
  50. data/ejabberd/ejabberd_scripts/synchronize_presence_script +57 -0
  51. data/ejabberd/ejabberd_scripts/unset_connection_script +48 -0
  52. data/ejabberd/mod_admin_extra/mod_admin_extra.beam +0 -0
  53. data/ejabberd/mod_admin_extra/mod_admin_extra.erl +1560 -0
  54. data/ejabberd/mod_sspresence/mod_sspresence.beam +0 -0
  55. data/ejabberd/mod_sspresence/mod_sspresence.erl +257 -0
  56. data/lib/social_stream-presence.rb +19 -2
  57. data/lib/social_stream/migrations/presence.rb +9 -0
  58. data/lib/social_stream/presence/engine.rb +62 -0
  59. data/lib/social_stream/presence/models/buddy_manager.rb +76 -0
  60. data/lib/social_stream/presence/version.rb +5 -0
  61. data/lib/tasks/presence/synchronize.rake +63 -0
  62. data/social_stream-presence.gemspec +4 -4
  63. metadata +69 -11
  64. data/.project +0 -17
@@ -0,0 +1,257 @@
1
+ -module(mod_sspresence).
2
+
3
+ -behavior(gen_mod).
4
+
5
+ -include("ejabberd.hrl").
6
+
7
+ -export([start/2, stop/1, on_register_connection/3, on_remove_connection/3, on_presence/4, on_unset_presence/4, isConnected/1, on_packet_send/3]).
8
+
9
+ start(Host, _Opts) ->
10
+ ?INFO_MSG("mod_sspresence starting", []),
11
+ ejabberd_hooks:add(sm_register_connection_hook, Host, ?MODULE, on_register_connection, 50),
12
+ ejabberd_hooks:add(sm_remove_connection_hook, Host, ?MODULE, on_remove_connection, 50),
13
+ ejabberd_hooks:add(set_presence_hook, Host, ?MODULE, on_presence, 50),
14
+ ejabberd_hooks:add(unset_presence_hook, Host, ?MODULE, on_unset_presence, 50),
15
+ ejabberd_hooks:add(user_send_packet, Host, ?MODULE, on_packet_send, 50),
16
+ %Uncomment to reset connected users directly when module sspresence starts.
17
+ %reset_connections(),
18
+ ok.
19
+
20
+ stop(Host) ->
21
+ ?INFO_MSG("mod_sspresence stopping", []),
22
+ ejabberd_hooks:delete(sm_register_connection_hook, Host, ?MODULE, on_register_connection, 50),
23
+ ejabberd_hooks:delete(sm_remove_connection_hook, Host, ?MODULE, on_remove_connection, 50),
24
+ ejabberd_hooks:delete(set_presence_hook, Host, ?MODULE, on_presence, 50),
25
+ ejabberd_hooks:delete(unset_presence_hook, Host, ?MODULE, on_unset_presence, 50),
26
+ ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, on_packet_send, 50),
27
+ ok.
28
+
29
+
30
+
31
+ on_register_connection(_SID, _JID, _Info) ->
32
+ {_A,User,_B,_C,_D,_E,_F} = _JID,
33
+ ?INFO_MSG("mod_sspresence: on_register_connection (~p)", [User]),
34
+ Login_path = string:concat(getOptionValue("scripts_path="), "/set_connection_script "),
35
+ os:cmd(string:join([Login_path, User ], " ")),
36
+ ok.
37
+
38
+ on_remove_connection(_SID, _JID, _SessionInfo) ->
39
+ {_A,User,_B,_C,_D,_E,_F} = _JID,
40
+ ?INFO_MSG("mod_sspresence: on_remove_connection (~p)", [User]),
41
+ Connected = isConnected(User),
42
+ case Connected of
43
+ true -> ok;
44
+ _ -> Logout_path = string:concat(getOptionValue("scripts_path="), "/unset_connection_script "),
45
+ os:cmd(string:join([Logout_path, User ], " "))
46
+ end,
47
+ ok.
48
+
49
+ on_presence(User, _Server, _Resource, Packet) ->
50
+ ?INFO_MSG("mod_sspresence: on_presence (~p)", [User]),
51
+ {_xmlelement, Type, _Attr, Subel} = Packet,
52
+
53
+ case Type of
54
+ "presence" -> Status = getStatusFromSubel(Subel),
55
+ Login_path = string:concat(getOptionValue("scripts_path="), "/set_presence_script "),
56
+ ?INFO_MSG("mod_sspresence: set_presence_script call with user (~p) and status (~p)", [User,Status]),
57
+ os:cmd(string:join([Login_path, User , Status], " "));
58
+ _ -> ok
59
+ end,
60
+ ok.
61
+
62
+ on_unset_presence(User, _Server, _Resource, _Status) ->
63
+ ?INFO_MSG("mod_sspresence: on_unset_presence (~p)", [User]),
64
+ ok.
65
+
66
+ on_packet_send(From, _To, {xmlelement, Type, _Attr, Subel} = _Packet) ->
67
+ case Type of
68
+ "message" ->
69
+ {_SenderJID,Sender,_SenderDomain,_A,_B,_C,_D} = From,
70
+
71
+ SSlogin = getOptionValue("ss_login="),
72
+
73
+ case Sender of
74
+ SSlogin ->
75
+ Message = getMessageFromSubel(Subel),
76
+ execute(Message);
77
+ _ -> ok
78
+ end;
79
+ _ -> ok
80
+ end.
81
+
82
+
83
+ getStatusFromSubel(Subel) ->
84
+ try
85
+ %Strophe tuples
86
+ [{_A,"status",[],[{_B,_StatusStrophe}]},{_C,"show",[],[{_D,ShowStrophe}]}|_R1] = Subel,
87
+ parseXmlCdata(ShowStrophe)
88
+ catch
89
+ _:Reason ->
90
+ try
91
+ %Pidgin tuples
92
+ [{_E,"show",[],[{_F,ShowPidgin}]}|_R2] = Subel,
93
+ parseXmlCdata(ShowPidgin)
94
+ catch
95
+ _:Reason -> "chat" %Status when parsed failed
96
+ after
97
+ noop
98
+ end
99
+ after
100
+ noop
101
+ end.
102
+
103
+
104
+ getMessageFromSubel(Subel) ->
105
+ [{_I,_J,_K,[{_L,MessageData}]}] = Subel,
106
+ parseXmlCdata(MessageData).
107
+
108
+
109
+ parseXmlCdata(Msg) ->
110
+ MessageString = binary_to_list(list_to_binary(io_lib:format("~p", [Msg]))),
111
+ lists:sublist(MessageString, 4, string:len(MessageString)-6).
112
+
113
+
114
+ execute(Message) ->
115
+ %?INFO_MSG("Message vale: ~p", [Message]),
116
+ %?INFO_MSG("Order vale: ~p", [Order]),
117
+ [Order|Params] = string:tokens(Message, "&"),
118
+ case Order of
119
+ "AddItemToRoster" ->
120
+ case length(Params) of
121
+ 4 -> [UserSID,BuddySID,BuddyName,Subscription_type] = Params,
122
+ ?INFO_MSG("Execute: ~p with params ~p", [Order,Params]),
123
+ [ContactName|_R] = string:tokens(BuddyName, " "),
124
+ [UserSlug,UserDomain] = string:tokens(UserSID, "@"),
125
+ [BuddySlug,BuddyDomain] = string:tokens(BuddySID, "@"),
126
+ addItemToRoster(UserSlug,UserDomain,BuddySlug,BuddyDomain,ContactName,"SocialStream",Subscription_type),
127
+ ok;
128
+ _ -> ?INFO_MSG("Incorrect parameters in order ~p", [Order]),
129
+ ok
130
+ end,
131
+ ok;
132
+
133
+ "SetRosterForBidirectionalTie" ->
134
+ case length(Params) of
135
+ 4 -> [UserASID,UserBSID,UserAName,UserBName] = Params,
136
+ ?INFO_MSG("Executing: ~p with params ~p", [Order,Params]),
137
+ [UserASlug,UserADomain] = string:tokens(UserASID, "@"),
138
+ [UserBSlug,UserBDomain] = string:tokens(UserBSID, "@"),
139
+ addItemToRoster(UserASlug,UserADomain,UserBSlug,UserBDomain,UserBName,"SocialStream","both"),
140
+ addItemToRoster(UserBSlug,UserBDomain,UserASlug,UserADomain,UserAName,"SocialStream","both"),
141
+ ok;
142
+ _ -> ?INFO_MSG("Incorrect parameters in order ~p", [Order]),
143
+ ok
144
+ end,
145
+ ok;
146
+
147
+ "Synchronize" ->
148
+ synchronizePresence(),
149
+ ok;
150
+
151
+ "SynchronizeRosters" ->
152
+ synchronizeRosters(),
153
+ ok;
154
+
155
+ _ -> ?INFO_MSG("Command not found", []),
156
+ ok
157
+ end.
158
+
159
+
160
+
161
+ %%Call ejabberdctl command add_rosteritem
162
+ %Command Name: add_rosteritem
163
+ %Needs mod_admin_extra (http://www.ejabberd.im/ejabberd-modules)
164
+ %ejabberdctl add_rosteritem localuser localserver buddy buddyserver nick group subs
165
+ %subs= none, from, to or both,
166
+
167
+ %Example
168
+ %ejabberdctl add_rosteritem frank-williamson trapo demo trapo NickName SocialStream from
169
+ %frank-williamson@trapo adds demo@trapo to its roster with subscription from, in the group SocialStream with the name Nickname
170
+ %%
171
+ addItemToRoster(UserSlug,UserDomain,BuddySlug,BuddyDomain,ContactName,Group,Subscription_type) ->
172
+ Command = lists:concat(["ejabberdctl add_rosteritem ", UserSlug , " ", UserDomain, " ", BuddySlug, " ", BuddyDomain , " \\'", ContactName , "\\' ", Group , " ", Subscription_type]),
173
+ os:cmd(Command),
174
+ ?INFO_MSG("Execute command: ~p", [Command]),
175
+ ok.
176
+
177
+ %%GETTERS CONFIG VALUES
178
+ %%CONFIG FILE: /etc/ejabberd/ssconfig.cfg
179
+
180
+ getOptionValue(Option) ->
181
+ {_, In} = file:open("/etc/ejabberd/ssconfig.cfg", read),
182
+ parser(In,Option).
183
+
184
+
185
+ parser(In,Option) ->
186
+ L = io:get_line(In, ''),
187
+
188
+ case L of
189
+ eof -> "Undefined";
190
+ _ -> {_,S,_} = regexp:gsub(L, "\\n", ""),
191
+
192
+
193
+ %%IGNORE COMMENTS
194
+ case string:str(S, "#") of
195
+ 0 ->
196
+ case string:str(S, Option) of
197
+ 0 -> ok,
198
+ %% Continue with next line
199
+ parser(In,Option);
200
+
201
+ %% return path
202
+ _ -> lists:sublist(S, string:len(Option)+1, string:len(S))
203
+ end;
204
+
205
+ _ -> %% Comment: Continue with next line
206
+ parser(In,Option)
207
+ end
208
+ end.
209
+
210
+
211
+ %%Check if a user is connected (any active session with Ejabberd server)
212
+ isConnected(User) ->
213
+
214
+ Command = string:concat("ejabberdctl connected-users | grep ", User),
215
+ Output = os:cmd(Command),
216
+
217
+ case Output of
218
+ [] -> false;
219
+ _ -> Sessions = string:tokens(Output, "\n"),
220
+
221
+ catch lists:foreach(
222
+ fun(S) ->
223
+ [Slug|_R] = string:tokens(S, "@"),
224
+ %User.slug connected = Slug
225
+
226
+ case Slug of
227
+ User -> throw(true);
228
+ _ -> false
229
+ end
230
+
231
+ end,
232
+ Sessions)
233
+ end.
234
+
235
+
236
+ %%Send all connected users to Social Stream Rails Application
237
+ synchronizePresence() ->
238
+ Synchronize_path = string:concat(getOptionValue("scripts_path="), "/synchronize_presence_script "),
239
+ os:cmd(Synchronize_path),
240
+ ok.
241
+
242
+
243
+ %%Reset all rosters and wait to received data from Social Stream Rails Application
244
+ synchronizeRosters() ->
245
+ SynchronizeRosters_path = string:concat(getOptionValue("scripts_path="), "/emanagement removeAllRosters"),
246
+ os:cmd(SynchronizeRosters_path),
247
+ ok.
248
+
249
+
250
+ %Reset all connections
251
+ %reset_connections() ->
252
+ % Reset_path = string:concat(getOptionValue("scripts_path="), "/reset_connection_script "),
253
+ % os:cmd(Reset_path),
254
+ %ok.
255
+
256
+
257
+
@@ -1,7 +1,24 @@
1
1
  require 'social_stream-base'
2
2
 
3
- module Socialstream
4
- module Presence
3
+ module SocialStream
4
+ module Presence
5
+
6
+ module Models
7
+ autoload :BuddyManager, 'social_stream/presence/models/buddy_manager'
8
+ end
9
+
10
+ mattr_accessor :domain
11
+ mattr_accessor :bosh_service
12
+ mattr_accessor :password
13
+ mattr_accessor :xmpp_server_password
14
+ mattr_accessor :social_stream_presence_username
15
+
16
+ class << self
17
+ def setup
18
+ yield self
19
+ end
20
+ end
21
+
5
22
  end
6
23
  end
7
24
 
@@ -0,0 +1,9 @@
1
+ require 'social_stream/migrations/components'
2
+
3
+ module SocialStream
4
+ module Migrations
5
+ # Migrate Documents
6
+ class Presence < Components
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,62 @@
1
+ require 'xmpp4r'
2
+ require 'xmpp4r/muc'
3
+ require 'xmpp4r/roster'
4
+ require 'xmpp4r/client'
5
+ require 'xmpp4r/message'
6
+
7
+ module SocialStream
8
+ module Presence
9
+ class Engine < Rails::Engine
10
+ config.to_prepare do
11
+
12
+ #Patching Tie
13
+ Tie.class_eval do
14
+ include SocialStream::Presence::Models::BuddyManager
15
+ end
16
+
17
+ end
18
+
19
+ initializer "social_stream-presence.synchronize" do
20
+ #Synchronize User Presence
21
+ #Reset connected users when XMMP Server Down
22
+ Thread.start {
23
+ begin
24
+ #XMPP DOMAIN
25
+ domain = SocialStream::Presence.domain
26
+ #PASSWORD
27
+ password= SocialStream::Presence.password
28
+ #SS Username
29
+ ss_name = SocialStream::Presence.social_stream_presence_username
30
+
31
+ ss_sid = ss_name + "@" + domain
32
+ client = Jabber::Client.new(Jabber::JID.new(ss_sid))
33
+ client.connect
34
+ client.auth(password)
35
+
36
+ msg = Jabber::Message::new(ss_sid, "Synchronize")
37
+ msg.type=:chat
38
+ client.send(msg)
39
+ client.close()
40
+
41
+ rescue Exception => e
42
+ case e
43
+ when Errno::ECONNREFUSED
44
+ begin
45
+ users = User.find_all_by_connected(true)
46
+ users.each do |user|
47
+ user.connected = false
48
+ user.save!
49
+ end
50
+ puts "Connection to XMPP Server refused: Reset Connected Users"
51
+ rescue
52
+ end
53
+ else
54
+ puts "Unknown exception: #{e.to_s}"
55
+ end
56
+ end
57
+ }
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,76 @@
1
+ require 'xmpp4r'
2
+ require 'xmpp4r/muc'
3
+ require 'xmpp4r/roster'
4
+ require 'xmpp4r/client'
5
+ require 'xmpp4r/message'
6
+
7
+ module SocialStream
8
+ module Presence
9
+ module Models
10
+ module BuddyManager
11
+ extend ActiveSupport::Concern
12
+
13
+ included do
14
+ after_create :save_buddy
15
+ end
16
+
17
+ module InstanceMethods
18
+
19
+ def save_buddy
20
+
21
+ unless self.receiver.subject_type == "User" and self.sender.subject_type == "User"
22
+ return
23
+ end
24
+
25
+ #XMPP DOMAIN
26
+ domain = SocialStream::Presence.domain
27
+ #PASSWORD
28
+ password= SocialStream::Presence.password
29
+ #SS Username
30
+ ss_name = SocialStream::Presence.social_stream_presence_username
31
+ ss_sid = ss_name + "@" + domain
32
+
33
+ user_sid = self.sender.slug + "@" + domain
34
+ user_name = self.sender.name
35
+ buddy_sid = self.receiver.slug + "@" + domain
36
+ buddy_name = self.receiver.name
37
+
38
+
39
+ begin
40
+ client = Jabber::Client.new(Jabber::JID.new(ss_sid))
41
+ client.connect
42
+ client.auth(password)
43
+
44
+ #Check if is a positive and replied tie
45
+ if self.bidirectional?
46
+ #SetRosterForBidirectionalTie[UserASID,UserBSID,UserAName,UserBName]
47
+ msg = Jabber::Message::new(ss_sid, "SetRosterForBidirectionalTie&" + user_sid + "&" + buddy_sid + "&" + buddy_name + "&" + user_name)
48
+ elsif self.positive?
49
+ #Case: Possitive tie unidirectional
50
+ sType = "from"
51
+ #AddItemToRoster[UserSID,BuddySID,BuddyName,Subscription_type]
52
+ msg = Jabber::Message::new(ss_sid, "AddItemToRoster&" + user_sid + "&" + buddy_sid + "&" + buddy_name + "&" + sType)
53
+ else
54
+ return
55
+ end
56
+
57
+ msg.type=:chat
58
+ client.send(msg)
59
+ client.close()
60
+
61
+ rescue Exception => e
62
+ case e
63
+ when Errno::ECONNREFUSED
64
+ puts "Connection to XMPP Server refused"
65
+ else
66
+ puts "Unknown exception: #{e.to_s}"
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,5 @@
1
+ module Socialstream
2
+ module Presence
3
+ VERSION = "0.0.4"
4
+ end
5
+ end
@@ -0,0 +1,63 @@
1
+ namespace :presence do
2
+ desc 'Synchronize the Xmpp Server database with the Social Stream database'
3
+ task :synchronize => [ 'presence:synchronize:connections', 'presence:synchronize:rosters' ]
4
+
5
+ namespace :synchronize do
6
+
7
+
8
+ desc "Synchronize user presence."
9
+ task :connections => :environment do
10
+ puts "Starting presence:synchronize:connections"
11
+ puts "Synchronization complete"
12
+ end
13
+
14
+ desc "Remove all rosters and populate rosters from Social Stream data."
15
+ task :rosters => :environment do
16
+ puts "Starting presence:synchronize:rosters"
17
+
18
+ #XMPP DOMAIN
19
+ domain = SocialStream::Presence.domain
20
+ #PASSWORD
21
+ password= SocialStream::Presence.password
22
+ #SS Username
23
+ ss_name = SocialStream::Presence.social_stream_presence_username
24
+ ss_sid = ss_name + "@" + domain
25
+
26
+ puts "Connecting to Xmpp Server"
27
+ client = Jabber::Client.new(Jabber::JID.new(ss_sid))
28
+ client.connect
29
+ client.auth(password)
30
+ puts "Connected to Xmpp Server"
31
+
32
+ puts "Remove all rosters"
33
+ msg = Jabber::Message::new(ss_sid, "SynchronizeRosters")
34
+ msg.type=:chat
35
+ client.send(msg)
36
+
37
+
38
+ puts "Populate rosters"
39
+ users = User.all
40
+ checkedUsers = []
41
+
42
+ users.each do |user|
43
+ checkedUsers << user.slug
44
+ contacts = user.contact_actors(:type=>:user)
45
+ contacts.each do |contact|
46
+ unless checkedUsers.include?(contact.slug)
47
+ user_sid = user.slug + "@" + domain
48
+ buddy_sid = contact.slug + "@" + domain
49
+ msg = Jabber::Message::new(ss_sid, "SetRosterForBidirectionalTie&" + user_sid + "&" + buddy_sid + "&" + user.name + "&" + contact.name)
50
+ msg.type=:chat
51
+ client.send(msg)
52
+ end
53
+ end
54
+ end
55
+
56
+ puts "Synchronization complete"
57
+ puts "Closing connection"
58
+ client.close()
59
+ puts "Connection closing"
60
+
61
+ end
62
+ end
63
+ end