vines 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/LICENSE +1 -1
  2. data/Rakefile +33 -53
  3. data/conf/certs/README +10 -3
  4. data/conf/certs/ca-bundle.crt +55 -410
  5. data/lib/vines/cluster/connection.rb +1 -1
  6. data/lib/vines/command/ldap.rb +1 -1
  7. data/lib/vines/command/schema.rb +1 -1
  8. data/lib/vines/config.rb +11 -5
  9. data/lib/vines/jid.rb +3 -3
  10. data/lib/vines/stanza/iq/disco_items.rb +1 -1
  11. data/lib/vines/storage/local.rb +1 -0
  12. data/lib/vines/store.rb +50 -9
  13. data/lib/vines/stream.rb +5 -9
  14. data/lib/vines/stream/client/session.rb +1 -1
  15. data/lib/vines/stream/http.rb +3 -1
  16. data/lib/vines/stream/http/ready.rb +5 -1
  17. data/lib/vines/stream/http/request.rb +22 -0
  18. data/lib/vines/version.rb +1 -1
  19. data/test/config/host_test.rb +9 -9
  20. data/test/config/pubsub_test.rb +2 -2
  21. data/test/config_test.rb +5 -3
  22. data/test/jid_test.rb +9 -0
  23. data/test/rake_test_loader.rb +1 -1
  24. data/test/router_test.rb +7 -7
  25. data/test/stanza/iq/disco_info_test.rb +2 -2
  26. data/test/stanza/iq/private_storage_test.rb +1 -1
  27. data/test/stanza/iq_test.rb +1 -1
  28. data/test/stanza/presence/subscribe_test.rb +1 -1
  29. data/test/stanza/pubsub/subscribe_test.rb +3 -3
  30. data/test/stanza/pubsub/unsubscribe_test.rb +3 -3
  31. data/test/storage_test.rb +15 -8
  32. data/test/store_test.rb +131 -0
  33. data/test/stream/client/ready_test.rb +6 -6
  34. data/test/stream/component/ready_test.rb +1 -1
  35. data/test/stream/http/ready_test.rb +46 -11
  36. data/test/stream/http/request_test.rb +83 -11
  37. data/test/stream/http/sessions_test.rb +2 -2
  38. data/web/chat/coffeescripts/chat.coffee +1 -1
  39. data/web/chat/index.html +9 -10
  40. data/web/chat/javascripts/app.js +1 -1
  41. data/web/lib/coffeescripts/button.coffee +1 -1
  42. data/web/lib/coffeescripts/contact.coffee +2 -2
  43. data/web/lib/coffeescripts/filter.coffee +1 -1
  44. data/web/lib/coffeescripts/layout.coffee +2 -2
  45. data/web/lib/coffeescripts/login.coffee +1 -1
  46. data/web/lib/coffeescripts/logout.coffee +2 -2
  47. data/web/lib/coffeescripts/navbar.coffee +1 -1
  48. data/web/lib/coffeescripts/notification.coffee +1 -1
  49. data/web/lib/coffeescripts/router.coffee +1 -1
  50. data/web/lib/coffeescripts/session.coffee +1 -1
  51. data/web/lib/coffeescripts/transfer.coffee +1 -1
  52. data/web/lib/javascripts/base.js +10 -9
  53. metadata +65 -43
  54. data/web/chat/javascripts/chat.js +0 -390
  55. data/web/chat/javascripts/init.js +0 -21
  56. data/web/lib/javascripts/button.js +0 -39
  57. data/web/lib/javascripts/contact.js +0 -94
  58. data/web/lib/javascripts/filter.js +0 -88
  59. data/web/lib/javascripts/layout.js +0 -48
  60. data/web/lib/javascripts/login.js +0 -88
  61. data/web/lib/javascripts/logout.js +0 -11
  62. data/web/lib/javascripts/navbar.js +0 -69
  63. data/web/lib/javascripts/notification.js +0 -26
  64. data/web/lib/javascripts/router.js +0 -105
  65. data/web/lib/javascripts/session.js +0 -291
  66. data/web/lib/javascripts/transfer.js +0 -124
@@ -1,390 +0,0 @@
1
- var ChatPage;
2
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3
- ChatPage = (function() {
4
- function ChatPage(session) {
5
- this.session = session;
6
- this.session.onRoster(__bind(function() {
7
- return this.roster();
8
- }, this));
9
- this.session.onCard(__bind(function(c) {
10
- return this.card(c);
11
- }, this));
12
- this.session.onMessage(__bind(function(m) {
13
- return this.message(m);
14
- }, this));
15
- this.session.onPresence(__bind(function(p) {
16
- return this.presence(p);
17
- }, this));
18
- this.chats = {};
19
- this.currentContact = null;
20
- this.layout = null;
21
- }
22
- ChatPage.prototype.datef = function(millis) {
23
- var d, hour, meridian, minutes;
24
- d = new Date(millis);
25
- meridian = d.getHours() >= 12 ? ' pm' : ' am';
26
- hour = d.getHours() > 12 ? d.getHours() - 12 : d.getHours();
27
- if (hour === 0) {
28
- hour = 12;
29
- }
30
- minutes = d.getMinutes() + '';
31
- if (minutes.length === 1) {
32
- minutes = '0' + minutes;
33
- }
34
- return hour + ':' + minutes + meridian;
35
- };
36
- ChatPage.prototype.card = function(card) {
37
- return this.eachContact(card.jid, __bind(function(node) {
38
- return $('.vcard-img', node).attr('src', this.session.avatar(card.jid));
39
- }, this));
40
- };
41
- ChatPage.prototype.roster = function() {
42
- var contact, found, jid, node, roster, setName, _ref, _results;
43
- roster = $('#roster');
44
- $('li', roster).each(__bind(function(ix, node) {
45
- var jid;
46
- jid = $(node).attr('data-jid');
47
- if (!this.session.roster[jid]) {
48
- return $(node).remove();
49
- }
50
- }, this));
51
- setName = function(node, contact) {
52
- $('.text', node).text(contact.name || contact.jid);
53
- return node.attr('data-name', contact.name || '');
54
- };
55
- _ref = this.session.roster;
56
- _results = [];
57
- for (jid in _ref) {
58
- contact = _ref[jid];
59
- found = $("#roster li[data-jid='" + jid + "']");
60
- setName(found, contact);
61
- _results.push(found.length === 0 ? (node = $("<li data-jid=\"" + jid + "\" data-name=\"\" class=\"offline\">\n <span class=\"text\"></span>\n <span class=\"status-msg\">Offline</span>\n <span class=\"unread\" style=\"display:none;\"></span>\n <img class=\"vcard-img\" alt=\"" + jid + "\" src=\"" + (this.session.avatar(jid)) + "\"/>\n</li>").appendTo(roster), setName(node, contact), node.click(__bind(function(event) {
62
- return this.selectContact(event);
63
- }, this))) : void 0);
64
- }
65
- return _results;
66
- };
67
- ChatPage.prototype.message = function(message) {
68
- var bottom, chat, from, me;
69
- if (!(message.type === 'chat' && message.text)) {
70
- return;
71
- }
72
- this.queueMessage(message);
73
- me = message.from === this.session.jid();
74
- from = message.from.split('/')[0];
75
- if (me || from === this.currentContact) {
76
- bottom = this.atBottom();
77
- this.appendMessage(message);
78
- if (bottom) {
79
- return this.scroll();
80
- }
81
- } else {
82
- chat = this.chat(message.from);
83
- chat.unread++;
84
- return this.eachContact(from, function(node) {
85
- return $('.unread', node).text(chat.unread).show();
86
- });
87
- }
88
- };
89
- ChatPage.prototype.eachContact = function(jid, callback) {
90
- var node, _i, _len, _ref, _results;
91
- _ref = $("#roster li[data-jid='" + jid + "']").get();
92
- _results = [];
93
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
94
- node = _ref[_i];
95
- _results.push(callback($(node)));
96
- }
97
- return _results;
98
- };
99
- ChatPage.prototype.appendMessage = function(message) {
100
- var contact, from, name, node;
101
- from = message.from.split('/')[0];
102
- contact = this.session.roster[from];
103
- name = contact ? contact.name || from : from;
104
- if (message.from === this.session.jid()) {
105
- name = 'Me';
106
- }
107
- node = $("<li data-jid=\"" + from + "\" style=\"display:none;\">\n <p></p>\n <img alt=\"" + from + "\" src=\"" + (this.session.avatar(from)) + "\"/>\n <footer>\n <span class=\"author\"></span>\n <span class=\"time\">" + (this.datef(message.received)) + "</span>\n </footer>\n</li>").appendTo('#messages');
108
- $('p', node).text(message.text);
109
- $('.author', node).text(name);
110
- return node.fadeIn(200);
111
- };
112
- ChatPage.prototype.queueMessage = function(message) {
113
- var chat, full, me;
114
- me = message.from === this.session.jid();
115
- full = message[me ? 'to' : 'from'];
116
- chat = this.chat(full);
117
- chat.jid = full;
118
- return chat.messages.push(message);
119
- };
120
- ChatPage.prototype.chat = function(jid) {
121
- var bare, chat;
122
- bare = jid.split('/')[0];
123
- chat = this.chats[bare];
124
- if (!chat) {
125
- chat = {
126
- jid: jid,
127
- messages: [],
128
- unread: 0
129
- };
130
- this.chats[bare] = chat;
131
- }
132
- return chat;
133
- };
134
- ChatPage.prototype.presence = function(presence) {
135
- var contact, from, node;
136
- from = presence.from.split('/')[0];
137
- if (from === this.session.bareJid()) {
138
- return;
139
- }
140
- if (!presence.type || presence.offline) {
141
- contact = this.session.roster[from];
142
- this.eachContact(from, function(node) {
143
- $('.status-msg', node).text(contact.status());
144
- if (contact.offline()) {
145
- return node.addClass('offline');
146
- } else {
147
- return node.removeClass('offline');
148
- }
149
- });
150
- }
151
- if (presence.offline) {
152
- this.chat(from).jid = from;
153
- }
154
- if (presence.type === 'subscribe') {
155
- node = $("<li data-jid=\"" + presence.from + "\" style=\"display:none;\">\n <form class=\"inset\">\n <h2>Buddy Approval</h2>\n <p>" + presence.from + " wants to add you as a buddy.</p>\n <fieldset class=\"buttons\">\n <input type=\"button\" value=\"Decline\"/>\n <input type=\"submit\" value=\"Accept\"/>\n </fieldset>\n </form>\n</li>").appendTo('#notifications');
156
- node.fadeIn(200);
157
- $('form', node).submit(__bind(function() {
158
- return this.acceptContact(node, presence.from);
159
- }, this));
160
- return $('input[type="button"]', node).click(__bind(function() {
161
- return this.rejectContact(node, presence.from);
162
- }, this));
163
- }
164
- };
165
- ChatPage.prototype.acceptContact = function(node, jid) {
166
- node.fadeOut(200, function() {
167
- return node.remove();
168
- });
169
- this.session.sendSubscribed(jid);
170
- this.session.sendSubscribe(jid);
171
- return false;
172
- };
173
- ChatPage.prototype.rejectContact = function(node, jid) {
174
- node.fadeOut(200, function() {
175
- return node.remove();
176
- });
177
- return this.session.sendUnsubscribed(jid);
178
- };
179
- ChatPage.prototype.selectContact = function(event) {
180
- var chat, contact, jid, messages, msg, _i, _len;
181
- jid = $(event.currentTarget).attr('data-jid');
182
- contact = this.session.roster[jid];
183
- if (this.currentContact === jid) {
184
- return;
185
- }
186
- this.currentContact = jid;
187
- $('#roster li').removeClass('selected');
188
- $(event.currentTarget).addClass('selected');
189
- $('#chat-title').text('Chat with ' + (contact.name || contact.jid));
190
- $('#messages').empty();
191
- chat = this.chats[jid];
192
- messages = [];
193
- if (chat) {
194
- messages = chat.messages;
195
- chat.unread = 0;
196
- this.eachContact(jid, function(node) {
197
- return $('.unread', node).text('').hide();
198
- });
199
- }
200
- for (_i = 0, _len = messages.length; _i < _len; _i++) {
201
- msg = messages[_i];
202
- this.appendMessage(msg);
203
- }
204
- this.scroll();
205
- $('#remove-contact-msg').html("Are you sure you want to remove " + ("<strong>" + this.currentContact + "</strong> from your buddy list?"));
206
- $('#remove-contact-form .buttons').fadeIn(200);
207
- $('#edit-contact-jid').text(this.currentContact);
208
- $('#edit-contact-name').val(this.session.roster[this.currentContact].name);
209
- $('#edit-contact-form input').fadeIn(200);
210
- return $('#edit-contact-form .buttons').fadeIn(200);
211
- };
212
- ChatPage.prototype.scroll = function() {
213
- var msgs;
214
- msgs = $('#messages');
215
- return msgs.animate({
216
- scrollTop: msgs.prop('scrollHeight')
217
- }, 400);
218
- };
219
- ChatPage.prototype.atBottom = function() {
220
- var bottom, msgs;
221
- msgs = $('#messages');
222
- bottom = msgs.prop('scrollHeight') - msgs.outerHeight();
223
- return msgs.scrollTop() >= bottom;
224
- };
225
- ChatPage.prototype.send = function() {
226
- var chat, input, jid, text;
227
- if (!this.currentContact) {
228
- return false;
229
- }
230
- input = $('#message');
231
- text = input.val().trim();
232
- if (text) {
233
- chat = this.chats[this.currentContact];
234
- jid = chat ? chat.jid : this.currentContact;
235
- this.message({
236
- from: this.session.jid(),
237
- text: text,
238
- to: jid,
239
- type: 'chat',
240
- received: new Date()
241
- });
242
- this.session.sendMessage(jid, text);
243
- }
244
- input.val('');
245
- return false;
246
- };
247
- ChatPage.prototype.addContact = function() {
248
- var contact;
249
- this.toggleForm('#add-contact-form');
250
- contact = {
251
- jid: $('#add-contact-jid').val(),
252
- name: $('#add-contact-name').val(),
253
- groups: ['Buddies']
254
- };
255
- if (contact.jid) {
256
- this.session.updateContact(contact, true);
257
- }
258
- return false;
259
- };
260
- ChatPage.prototype.removeContact = function() {
261
- this.toggleForm('#remove-contact-form');
262
- this.session.removeContact(this.currentContact);
263
- this.currentContact = null;
264
- $('#chat-title').text('Select a buddy to chat');
265
- $('#messages').empty();
266
- $('#remove-contact-msg').html("Select a buddy in the list above to remove.");
267
- $('#remove-contact-form .buttons').hide();
268
- $('#edit-contact-jid').text("Select a buddy in the list above to update.");
269
- $('#edit-contact-name').val('');
270
- $('#edit-contact-form input').hide();
271
- $('#edit-contact-form .buttons').hide();
272
- return false;
273
- };
274
- ChatPage.prototype.updateContact = function() {
275
- var contact;
276
- this.toggleForm('#edit-contact-form');
277
- contact = {
278
- jid: this.currentContact,
279
- name: $('#edit-contact-name').val(),
280
- groups: this.session.roster[this.currentContact].groups
281
- };
282
- this.session.updateContact(contact);
283
- return false;
284
- };
285
- ChatPage.prototype.toggleForm = function(form, fn) {
286
- form = $(form);
287
- $('form.overlay').each(function() {
288
- if (this.id !== form.attr('id')) {
289
- return $(this).hide();
290
- }
291
- });
292
- if (form.is(':hidden')) {
293
- if (fn) {
294
- fn();
295
- }
296
- return form.fadeIn(100);
297
- } else {
298
- return form.fadeOut(100, __bind(function() {
299
- form[0].reset();
300
- this.layout.resize();
301
- if (fn) {
302
- return fn();
303
- }
304
- }, this));
305
- }
306
- };
307
- ChatPage.prototype.draw = function() {
308
- var fn;
309
- if (!this.session.connected()) {
310
- window.location.hash = '';
311
- return;
312
- }
313
- $('body').attr('id', 'chat-page');
314
- $('#container').hide().empty();
315
- $("<div id=\"alpha\" class=\"sidebar column y-fill\">\n <h2>Buddies <div id=\"search-roster-icon\"></div></h2>\n <div id=\"search-roster-form\"></div>\n <ul id=\"roster\" class=\"selectable scroll y-fill\"></ul>\n <div id=\"alpha-controls\" class=\"controls\">\n <div id=\"add-contact\"></div>\n <div id=\"remove-contact\"></div>\n <div id=\"edit-contact\"></div>\n </div>\n <form id=\"add-contact-form\" class=\"overlay\" style=\"display:none;\">\n <h2>Add Buddy</h2>\n <input id=\"add-contact-jid\" type=\"email\" maxlength=\"1024\" placeholder=\"Account name\"/>\n <input id=\"add-contact-name\" type=\"text\" maxlength=\"1024\" placeholder=\"Real name\"/>\n <fieldset class=\"buttons\">\n <input id=\"add-contact-cancel\" type=\"button\" value=\"Cancel\"/>\n <input id=\"add-contact-ok\" type=\"submit\" value=\"Add\"/>\n </fieldset>\n </form>\n <form id=\"remove-contact-form\" class=\"overlay\" style=\"display:none;\">\n <h2>Remove Buddy</h2>\n <p id=\"remove-contact-msg\">Select a buddy in the list above to remove.</p>\n <fieldset class=\"buttons\" style=\"display:none;\">\n <input id=\"remove-contact-cancel\" type=\"button\" value=\"Cancel\"/>\n <input id=\"remove-contact-ok\" type=\"submit\" value=\"Remove\"/>\n </fieldset>\n </form>\n <form id=\"edit-contact-form\" class=\"overlay\" style=\"display:none;\">\n <h2>Update Profile</h2>\n <p id=\"edit-contact-jid\">Select a buddy in the list above to update.</p>\n <input id=\"edit-contact-name\" type=\"text\" maxlength=\"1024\" placeholder=\"Real name\" style=\"display:none;\"/>\n <fieldset class=\"buttons\" style=\"display:none;\">\n <input id=\"edit-contact-cancel\" type=\"button\" value=\"Cancel\"/>\n <input id=\"edit-contact-ok\" type=\"submit\" value=\"Save\"/>\n </fieldset>\n </form>\n</div>\n<div id=\"beta\" class=\"primary column x-fill y-fill\">\n <h2 id=\"chat-title\">Select a buddy to chat</h2>\n <ul id=\"messages\" class=\"scroll y-fill\"></ul>\n <form id=\"message-form\">\n <input id=\"message\" name=\"message\" type=\"text\" maxlength=\"1024\" placeholder=\"Type a message and press enter to send\"/>\n </form>\n</div>\n<div id=\"charlie\" class=\"sidebar column y-fill\">\n <h2>Notifications</h2>\n <ul id=\"notifications\" class=\"scroll y-fill\"></ul>\n <div id=\"charlie-controls\" class=\"controls\">\n <div id=\"clear-notices\"></div>\n </div>\n</div>").appendTo('#container');
316
- this.roster();
317
- new Button('#clear-notices', ICONS.no);
318
- new Button('#add-contact', ICONS.plus);
319
- new Button('#remove-contact', ICONS.minus);
320
- new Button('#edit-contact', ICONS.user);
321
- $('#message').focus(function() {
322
- return $('form.overlay').fadeOut();
323
- });
324
- $('#message-form').submit(__bind(function() {
325
- return this.send();
326
- }, this));
327
- $('#clear-notices').click(function() {
328
- return $('#notifications li').fadeOut(200);
329
- });
330
- $('#add-contact').click(__bind(function() {
331
- return this.toggleForm('#add-contact-form');
332
- }, this));
333
- $('#remove-contact').click(__bind(function() {
334
- return this.toggleForm('#remove-contact-form');
335
- }, this));
336
- $('#edit-contact').click(__bind(function() {
337
- return this.toggleForm('#edit-contact-form', __bind(function() {
338
- if (this.currentContact) {
339
- $('#edit-contact-jid').text(this.currentContact);
340
- return $('#edit-contact-name').val(this.session.roster[this.currentContact].name);
341
- }
342
- }, this));
343
- }, this));
344
- $('#add-contact-cancel').click(__bind(function() {
345
- return this.toggleForm('#add-contact-form');
346
- }, this));
347
- $('#remove-contact-cancel').click(__bind(function() {
348
- return this.toggleForm('#remove-contact-form');
349
- }, this));
350
- $('#edit-contact-cancel').click(__bind(function() {
351
- return this.toggleForm('#edit-contact-form');
352
- }, this));
353
- $('#add-contact-form').submit(__bind(function() {
354
- return this.addContact();
355
- }, this));
356
- $('#remove-contact-form').submit(__bind(function() {
357
- return this.removeContact();
358
- }, this));
359
- $('#edit-contact-form').submit(__bind(function() {
360
- return this.updateContact();
361
- }, this));
362
- $('#container').fadeIn(200);
363
- this.layout = this.resize();
364
- fn = __bind(function() {
365
- this.layout.resize();
366
- return this.layout.resize();
367
- }, this);
368
- return new Filter({
369
- list: '#roster',
370
- icon: '#search-roster-icon',
371
- form: '#search-roster-form',
372
- attrs: ['data-jid', 'data-name'],
373
- open: fn,
374
- close: fn
375
- });
376
- };
377
- ChatPage.prototype.resize = function() {
378
- var a, b, c, form, msg;
379
- a = $('#alpha');
380
- b = $('#beta');
381
- c = $('#charlie');
382
- msg = $('#message');
383
- form = $('#message-form');
384
- return new Layout(function() {
385
- c.css('left', a.width() + b.width());
386
- return msg.width(form.width() - 32);
387
- });
388
- };
389
- return ChatPage;
390
- })();
@@ -1,21 +0,0 @@
1
- $(function() {
2
- var buttons, icon, label, nav, pages, session;
3
- session = new Session();
4
- nav = new NavBar(session);
5
- nav.draw();
6
- buttons = {
7
- Messages: ICONS.chat,
8
- Logout: ICONS.power
9
- };
10
- for (label in buttons) {
11
- icon = buttons[label];
12
- nav.addButton(label, icon);
13
- }
14
- pages = {
15
- '/messages': new ChatPage(session),
16
- '/logout': new LogoutPage(session),
17
- 'default': new LoginPage(session, '/messages/')
18
- };
19
- new Router(pages).draw();
20
- return nav.select($('#nav-link-messages').parent());
21
- });
@@ -1,39 +0,0 @@
1
- var Button;
2
- Button = (function() {
3
- function Button(node, path, options) {
4
- this.node = $(node);
5
- this.path = path;
6
- this.options = options || {};
7
- if (this.options.animate == null) {
8
- this.options.animate = true;
9
- }
10
- this.draw();
11
- }
12
- Button.prototype.draw = function() {
13
- var icon, paper, transform;
14
- paper = Raphael(this.node.get(0));
15
- transform = "s" + (this.options.scale || 0.85);
16
- if (this.options.translation) {
17
- transform += ",t" + this.options.translation;
18
- }
19
- icon = paper.path(this.path).attr({
20
- fill: this.options.fill || '#000',
21
- stroke: this.options.stroke || '#fff',
22
- 'stroke-width': this.options['stroke-width'] || 0.3,
23
- opacity: this.options.opacity || 0.6,
24
- transform: transform
25
- });
26
- if (this.options.animate) {
27
- return this.node.hover(function() {
28
- return icon.animate({
29
- opacity: 1.0
30
- }, 200);
31
- }, function() {
32
- return icon.animate({
33
- opacity: 0.6
34
- }, 200);
35
- });
36
- }
37
- };
38
- return Button;
39
- })();