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,291 +0,0 @@
1
- var Session;
2
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3
- Session = (function() {
4
- function Session() {
5
- this.xmpp = new Strophe.Connection('/xmpp');
6
- this.roster = {};
7
- this.listeners = {
8
- card: [],
9
- message: [],
10
- presence: [],
11
- roster: []
12
- };
13
- }
14
- Session.prototype.connect = function(jid, password, callback) {
15
- return this.xmpp.connect(jid, password, __bind(function(status) {
16
- switch (status) {
17
- case Strophe.Status.AUTHFAIL:
18
- case Strophe.Status.CONNFAIL:
19
- return callback(false);
20
- case Strophe.Status.CONNECTED:
21
- this.xmpp.addHandler((__bind(function(el) {
22
- return this.handleIq(el);
23
- }, this)), null, 'iq');
24
- this.xmpp.addHandler((__bind(function(el) {
25
- return this.handleMessage(el);
26
- }, this)), null, 'message');
27
- this.xmpp.addHandler((__bind(function(el) {
28
- return this.handlePresence(el);
29
- }, this)), null, 'presence');
30
- callback(true);
31
- return this.findRoster(__bind(function() {
32
- this.notify('roster');
33
- this.xmpp.send(this.xml('<presence/>'));
34
- return this.findCards();
35
- }, this));
36
- }
37
- }, this));
38
- };
39
- Session.prototype.disconnect = function() {
40
- return this.xmpp.disconnect();
41
- };
42
- Session.prototype.onCard = function(callback) {
43
- return this.listeners['card'].push(callback);
44
- };
45
- Session.prototype.onRoster = function(callback) {
46
- return this.listeners['roster'].push(callback);
47
- };
48
- Session.prototype.onMessage = function(callback) {
49
- return this.listeners['message'].push(callback);
50
- };
51
- Session.prototype.onPresence = function(callback) {
52
- return this.listeners['presence'].push(callback);
53
- };
54
- Session.prototype.connected = function() {
55
- return this.xmpp.jid && this.xmpp.jid.length > 0;
56
- };
57
- Session.prototype.jid = function() {
58
- return this.xmpp.jid;
59
- };
60
- Session.prototype.bareJid = function() {
61
- return this.xmpp.jid.split('/')[0];
62
- };
63
- Session.prototype.uniqueId = function() {
64
- return this.xmpp.getUniqueId();
65
- };
66
- Session.prototype.avatar = function(jid) {
67
- var card;
68
- card = this.loadCard(jid);
69
- if (card && card.photo) {
70
- return "data:" + card.photo.type + ";base64," + card.photo.binval;
71
- } else {
72
- return '/lib/images/default-user.png';
73
- }
74
- };
75
- Session.prototype.loadCard = function(jid) {
76
- var found;
77
- jid = jid.split('/')[0];
78
- found = localStorage['vcard:' + jid];
79
- if (found) {
80
- return JSON.parse(found);
81
- }
82
- };
83
- Session.prototype.storeCard = function(card) {
84
- return localStorage['vcard:' + card.jid] = JSON.stringify(card);
85
- };
86
- Session.prototype.findCards = function() {
87
- var contacts, jid, jids, success;
88
- jids = (function() {
89
- var _ref, _results;
90
- _ref = this.roster;
91
- _results = [];
92
- for (jid in _ref) {
93
- contacts = _ref[jid];
94
- if (!this.loadCard(jid)) {
95
- _results.push(jid);
96
- }
97
- }
98
- return _results;
99
- }).call(this);
100
- if (!this.loadCard(this.bareJid())) {
101
- jids.push(this.bareJid());
102
- }
103
- success = __bind(function(card) {
104
- this.findCard(jids.shift(), success);
105
- if (card) {
106
- this.storeCard(card);
107
- return this.notify('card', card);
108
- }
109
- }, this);
110
- return this.findCard(jids.shift(), success);
111
- };
112
- Session.prototype.findCard = function(jid, callback) {
113
- var node;
114
- if (!jid) {
115
- return;
116
- }
117
- node = this.xml("<iq id=\"" + (this.uniqueId()) + "\" to=\"" + jid + "\" type=\"get\">\n <vCard xmlns=\"vcard-temp\"/>\n</iq>");
118
- return this.sendIQ(node, function(result) {
119
- var bin, card, photo, type, vcard;
120
- card = $('vCard', result);
121
- photo = $('PHOTO', card);
122
- type = $('TYPE', photo).text();
123
- bin = $('BINVAL', photo).text();
124
- photo = type && bin ? {
125
- type: type,
126
- binval: bin.replace(/\n/g, '')
127
- } : null;
128
- vcard = {
129
- jid: jid,
130
- photo: photo,
131
- retrieved: new Date()
132
- };
133
- return callback(card.size() > 0 ? vcard : null);
134
- });
135
- };
136
- Session.prototype.parseRoster = function(node) {
137
- return $('item', node).map(function() {
138
- return new Contact(this);
139
- }).get();
140
- };
141
- Session.prototype.findRoster = function(callback) {
142
- var node;
143
- node = this.xml("<iq id='" + (this.uniqueId()) + "' type=\"get\">\n <query xmlns=\"jabber:iq:roster\"/>\n</iq>");
144
- return this.sendIQ(node, __bind(function(result) {
145
- var contact, contacts, _i, _len;
146
- contacts = this.parseRoster(result);
147
- for (_i = 0, _len = contacts.length; _i < _len; _i++) {
148
- contact = contacts[_i];
149
- this.roster[contact.jid] = contact;
150
- }
151
- return callback();
152
- }, this));
153
- };
154
- Session.prototype.sendMessage = function(jid, message) {
155
- var node;
156
- node = this.xml("<message id=\"" + (this.uniqueId()) + "\" to=\"" + jid + "\" type=\"chat\">\n <body></body>\n</message>");
157
- $('body', node).text(message);
158
- return this.xmpp.send(node);
159
- };
160
- Session.prototype.sendPresence = function(away, status) {
161
- var node;
162
- node = $(this.xml('<presence/>'));
163
- if (away) {
164
- node.append($(this.xml('<show>xa</show>')));
165
- if (status !== 'Away') {
166
- node.append($(this.xml('<status/>')).text(status));
167
- }
168
- } else {
169
- if (status !== 'Available') {
170
- node.append($(this.xml('<status/>')).text(status));
171
- }
172
- }
173
- return this.xmpp.send(node);
174
- };
175
- Session.prototype.sendIQ = function(node, callback) {
176
- return this.xmpp.sendIQ(node, callback, callback, 5000);
177
- };
178
- Session.prototype.updateContact = function(contact, add) {
179
- var group, node, _i, _len, _ref;
180
- node = this.xml("<iq id=\"" + (this.uniqueId()) + "\" type=\"set\">\n <query xmlns=\"jabber:iq:roster\">\n <item name=\"\" jid=\"" + contact.jid + "\"/>\n </query>\n</iq>");
181
- $('item', node).attr('name', contact.name);
182
- _ref = contact.groups;
183
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
184
- group = _ref[_i];
185
- $('item', node).append($(this.xml('<group></group>')).text(group));
186
- }
187
- this.xmpp.send(node);
188
- if (add) {
189
- return this.sendSubscribe(contact.jid);
190
- }
191
- };
192
- Session.prototype.removeContact = function(jid) {
193
- var node;
194
- node = this.xml("<iq id=\"" + (this.uniqueId()) + "\" type=\"set\">\n <query xmlns=\"jabber:iq:roster\">\n <item jid=\"" + jid + "\" subscription=\"remove\"/>\n </query>\n</iq>");
195
- return this.xmpp.send(node);
196
- };
197
- Session.prototype.sendSubscribe = function(jid) {
198
- return this.xmpp.send(this.presence(jid, 'subscribe'));
199
- };
200
- Session.prototype.sendSubscribed = function(jid) {
201
- return this.xmpp.send(this.presence(jid, 'subscribed'));
202
- };
203
- Session.prototype.sendUnsubscribed = function(jid) {
204
- return this.xmpp.send(this.presence(jid, 'unsubscribed'));
205
- };
206
- Session.prototype.presence = function(to, type) {
207
- return this.xml("<presence\n id=\"" + (this.uniqueId()) + "\"\n to=\"" + to + "\"\n type=\"" + type + "\"/>");
208
- };
209
- Session.prototype.handleIq = function(node) {
210
- var contact, contacts, ns, old, type, _i, _len;
211
- node = $(node);
212
- type = node.attr('type');
213
- ns = node.find('query').attr('xmlns');
214
- if (type === 'set' && ns === 'jabber:iq:roster') {
215
- contacts = this.parseRoster(node);
216
- for (_i = 0, _len = contacts.length; _i < _len; _i++) {
217
- contact = contacts[_i];
218
- if (contact.subscription === 'remove') {
219
- delete this.roster[contact.jid];
220
- } else {
221
- old = this.roster[contact.jid];
222
- if (old) {
223
- contact.presence = old.presence;
224
- }
225
- this.roster[contact.jid] = contact;
226
- }
227
- }
228
- this.notify('roster');
229
- }
230
- return true;
231
- };
232
- Session.prototype.handleMessage = function(node) {
233
- var body, from, thread, to, type;
234
- node = $(node);
235
- to = node.attr('to');
236
- from = node.attr('from');
237
- type = node.attr('type');
238
- thread = node.find('thread').first();
239
- body = node.find('body').first();
240
- this.notify('message', {
241
- to: to,
242
- from: from,
243
- type: type,
244
- thread: thread.text(),
245
- text: body.text(),
246
- received: new Date(),
247
- node: node
248
- });
249
- return true;
250
- };
251
- Session.prototype.handlePresence = function(node) {
252
- var contact, from, presence, show, status, to, type;
253
- node = $(node);
254
- to = node.attr('to');
255
- from = node.attr('from');
256
- type = node.attr('type');
257
- show = node.find('show').first();
258
- status = node.find('status').first();
259
- presence = {
260
- to: to,
261
- from: from,
262
- status: status.text(),
263
- show: show.text(),
264
- type: type,
265
- offline: type === 'unavailable' || type === 'error',
266
- away: show.text() === 'away' || show.text() === 'xa',
267
- dnd: show.text() === 'dnd',
268
- node: node
269
- };
270
- contact = this.roster[from.split('/')[0]];
271
- if (contact) {
272
- contact.update(presence);
273
- }
274
- this.notify('presence', presence);
275
- return true;
276
- };
277
- Session.prototype.notify = function(type, obj) {
278
- var callback, _i, _len, _ref, _results;
279
- _ref = this.listeners[type] || [];
280
- _results = [];
281
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
282
- callback = _ref[_i];
283
- _results.push(callback(obj));
284
- }
285
- return _results;
286
- };
287
- Session.prototype.xml = function(xml) {
288
- return $.parseXML(xml).documentElement;
289
- };
290
- return Session;
291
- })();
@@ -1,124 +0,0 @@
1
- var Transfer;
2
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3
- Transfer = (function() {
4
- var Chunks;
5
- function Transfer(options) {
6
- this.session = options.session;
7
- this.file = options.file;
8
- this.to = options.to;
9
- this.progress = options.progress;
10
- this.complete = options.complete;
11
- this.chunks = new Chunks(this.file);
12
- this.opened = false;
13
- this.closed = false;
14
- this.sid = this.session.uniqueId();
15
- this.seq = 0;
16
- this.sent = 0;
17
- }
18
- Transfer.prototype.start = function() {
19
- var node;
20
- node = $("<iq id=\"" + (this.session.uniqueId()) + "\" to=\"" + this.to + "\" type=\"set\">\n <si xmlns=\"http://jabber.org/protocol/si\" id=\"" + (this.session.uniqueId()) + "\" profile=\"http://jabber.org/protocol/si/profile/file-transfer\">\n <file xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\" name=\"\" size=\"" + this.file.size + "\"/>\n <feature xmlns=\"http://jabber.org/protocol/feature-neg\">\n <x xmlns=\"jabber:x:data\" type=\"form\">\n <field var=\"stream-method\" type=\"list-single\">\n <option><value>http://jabber.org/protocol/ibb</value></option>\n </field>\n </x>\n </feature>\n </si>\n</iq>");
21
- $('file', node).attr('name', this.file.name);
22
- return this.session.sendIQ(node.get(0), __bind(function(result) {
23
- var m, methods, ok;
24
- methods = $('si feature x field[var="stream-method"] value', result);
25
- ok = ((function() {
26
- var _i, _len, _results;
27
- _results = [];
28
- for (_i = 0, _len = methods.length; _i < _len; _i++) {
29
- m = methods[_i];
30
- if ($(m).text() === 'http://jabber.org/protocol/ibb') {
31
- _results.push(true);
32
- }
33
- }
34
- return _results;
35
- })()).length > 0;
36
- if (ok) {
37
- return this.open();
38
- }
39
- }, this));
40
- };
41
- Transfer.prototype.open = function() {
42
- var node;
43
- node = $("<iq id=\"" + (this.session.uniqueId()) + "\" to=\"" + this.to + "\" type=\"set\">\n <open xmlns=\"http://jabber.org/protocol/ibb\" sid=\"" + this.sid + "\" block-size=\"4096\"/>\n</iq>");
44
- return this.session.sendIQ(node.get(0), __bind(function(result) {
45
- if (this.ok(result)) {
46
- this.opened = true;
47
- return this.sendChunk();
48
- }
49
- }, this));
50
- };
51
- Transfer.prototype.sendChunk = function() {
52
- if (this.closed) {
53
- return;
54
- }
55
- return this.chunks.chunk(__bind(function(chunk) {
56
- var node;
57
- if (!chunk) {
58
- this.close();
59
- return;
60
- }
61
- node = $("<iq id=\"" + (this.session.uniqueId()) + "\" to=\"" + this.to + "\" type=\"set\">\n <data xmlns=\"http://jabber.org/protocol/ibb\" sid=\"" + this.sid + "\" seq=\"" + (this.seq++) + "\">" + chunk + "</data>\n</iq>");
62
- if (this.seq > 65535) {
63
- this.seq = 0;
64
- }
65
- return this.session.sendIQ(node.get(0), __bind(function(result) {
66
- var pct;
67
- if (!this.ok(result)) {
68
- return;
69
- }
70
- pct = Math.ceil(++this.sent / this.chunks.total * 100);
71
- this.progress(pct);
72
- return this.sendChunk();
73
- }, this));
74
- }, this));
75
- };
76
- Transfer.prototype.close = function() {
77
- var node;
78
- if (this.closed) {
79
- return;
80
- }
81
- this.closed = true;
82
- node = $("<iq id=\"" + (this.session.uniqueId()) + "\" to=\"" + this.to + "\" type=\"set\">\n <close xmlns=\"http://jabber.org/protocol/ibb\" sid=\"" + this.sid + "\"/>\n</iq>");
83
- this.session.sendIQ(node.get(0), function() {});
84
- return this.complete();
85
- };
86
- Transfer.prototype.stop = function() {
87
- if (this.opened) {
88
- return this.close();
89
- } else {
90
- return this.complete();
91
- }
92
- };
93
- Transfer.prototype.ok = function(result) {
94
- return $(result).attr('type') === 'result';
95
- };
96
- Chunks = (function() {
97
- var CHUNK_SIZE;
98
- CHUNK_SIZE = 3 / 4 * 4096;
99
- function Chunks(file) {
100
- this.file = file;
101
- this.total = Math.ceil(this.file.size / CHUNK_SIZE);
102
- this.slice = this.file.slice || this.file.webkitSlice || this.file.mozSlice;
103
- this.pos = 0;
104
- }
105
- Chunks.prototype.chunk = function(callback) {
106
- var chunk, end, reader, start;
107
- start = this.pos;
108
- end = this.pos + CHUNK_SIZE;
109
- this.pos = end;
110
- if (start > this.file.size) {
111
- return callback(null);
112
- } else {
113
- chunk = this.slice.call(this.file, start, end);
114
- reader = new FileReader();
115
- reader.onload = function(event) {
116
- return callback(btoa(event.target.result));
117
- };
118
- return reader.readAsBinaryString(chunk);
119
- }
120
- };
121
- return Chunks;
122
- })();
123
- return Transfer;
124
- })();