murlsh 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/README.textile +25 -2
- data/Rakefile +37 -5
- data/VERSION +1 -1
- data/bin/murlsh +3 -3
- data/config.ru +10 -4
- data/config.yaml +14 -10
- data/lib/murlsh/atom_feed.rb +5 -4
- data/lib/murlsh/auth.rb +6 -7
- data/lib/murlsh/dispatch.rb +25 -23
- data/lib/murlsh/doc.rb +14 -6
- data/lib/murlsh/etag_add_encoding.rb +27 -0
- data/lib/murlsh/flickr_server.rb +54 -0
- data/lib/murlsh/markup.rb +18 -1
- data/lib/murlsh/plugin.rb +2 -0
- data/lib/murlsh/sqlite3_adapter.rb +3 -1
- data/lib/murlsh/time_ago.rb +27 -0
- data/lib/murlsh/uri.rb +3 -1
- data/lib/murlsh/uri_ask.rb +13 -10
- data/lib/murlsh/url.rb +11 -4
- data/lib/murlsh/url_body.rb +21 -31
- data/lib/murlsh/url_server.rb +1 -2
- data/lib/murlsh/yaml_ordered_hash.rb +22 -0
- data/lib/murlsh.rb +4 -18
- data/murlsh.gemspec +22 -5
- data/plugins/add_post_50_update_feed.rb +4 -2
- data/plugins/add_post_50_update_rss.rb +37 -0
- data/plugins/add_post_60_notify_hubs.rb +3 -2
- data/plugins/add_pre_50_lookup_content_type_title.rb +3 -1
- data/plugins/time_50_ago.rb +16 -0
- data/plugins/via_50_domain.rb +36 -0
- data/public/css/screen.css +5 -6
- data/public/js/js.js +142 -94
- data/spec/atom_feed_spec.rb +21 -20
- data/spec/auth_spec.rb +8 -6
- data/spec/dispatch_spec.rb +26 -0
- data/spec/doc_spec.rb +27 -0
- data/spec/markup_spec.rb +3 -1
- data/spec/uri_ask_spec.rb +5 -3
- data/spec/uri_spec.rb +3 -1
- data/spec/url_spec.rb +52 -0
- data/spec/xhtml_response_spec.rb +3 -1
- data/spec/yaml_ordered_hash_spec.rb +28 -0
- metadata +37 -9
- data/lib/murlsh/time.rb +0 -20
data/public/js/js.js
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
var Murlsh = {};
|
6
6
|
|
7
|
-
Murlsh.img = function
|
7
|
+
Murlsh.img = function(src, text) {
|
8
8
|
text = text || '';
|
9
9
|
return $('<img />', {
|
10
10
|
src : src,
|
@@ -13,18 +13,19 @@ Murlsh.img = function (src, text) {
|
|
13
13
|
});
|
14
14
|
};
|
15
15
|
|
16
|
-
Murlsh.
|
17
|
-
var
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
Murlsh.makeFit = function(e, maxWidth, maxHeight) {
|
17
|
+
var height = e.height();
|
18
|
+
var scale;
|
19
|
+
var width = e.width();
|
20
|
+
|
21
|
+
if (width > maxWidth || height > maxHeight) {
|
22
|
+
scale = Math.min(maxWidth / width, maxHeight / height);
|
22
23
|
e.width(Math.round(width * scale));
|
23
24
|
e.height(Math.round(height * scale));
|
24
25
|
}
|
25
|
-
}
|
26
|
+
};
|
26
27
|
|
27
|
-
Murlsh.
|
28
|
+
Murlsh.closerAdd = function(x, header) {
|
28
29
|
var html = (typeof x === 'object') ? $('<div />').append(x).html() : x;
|
29
30
|
|
30
31
|
$.jGrowl(html, {
|
@@ -32,9 +33,9 @@ Murlsh.closer_add = function (x, header) {
|
|
32
33
|
glue : 'before',
|
33
34
|
header : header,
|
34
35
|
sticky : true,
|
35
|
-
beforeOpen : function
|
36
|
-
e.find('.message img').load(function
|
37
|
-
Murlsh.
|
36
|
+
beforeOpen : function(e) {
|
37
|
+
e.find('.message img').load(function() {
|
38
|
+
Murlsh.makeFit($(this),
|
38
39
|
Math.round($(window).width() / 2),
|
39
40
|
Math.round($(window).height() - 100));
|
40
41
|
});
|
@@ -42,20 +43,20 @@ Murlsh.closer_add = function (x, header) {
|
|
42
43
|
});
|
43
44
|
};
|
44
45
|
|
45
|
-
Murlsh.
|
46
|
+
Murlsh.escapeXml = function(s) {
|
46
47
|
return s.replace(/&/g, '&');
|
47
48
|
};
|
48
49
|
|
49
|
-
Murlsh.
|
50
|
+
Murlsh.objectTag = function(data, height, width, params) {
|
50
51
|
// this does not use jQuery to build tags because building object
|
51
52
|
// tags is broken in IE
|
52
|
-
var result = '<object data="' + Murlsh.
|
53
|
+
var result = '<object data="' + Murlsh.escapeXml(data) +
|
53
54
|
'" height="' + height +
|
54
55
|
'" type="application/x-shockwave-flash" width="' + width + '">';
|
55
56
|
|
56
|
-
$.each(params, function
|
57
|
+
$.each(params, function(i, v) {
|
57
58
|
result += '<param name="' + v.name + '" value="' +
|
58
|
-
Murlsh.
|
59
|
+
Murlsh.escapeXml(v.value) + '" />';
|
59
60
|
});
|
60
61
|
|
61
62
|
result += '</object>';
|
@@ -63,11 +64,12 @@ Murlsh.object_tag = function (data, height, width, params) {
|
|
63
64
|
return result;
|
64
65
|
};
|
65
66
|
|
66
|
-
Murlsh.
|
67
|
-
var
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
Murlsh.flickrThumb = function(d) {
|
68
|
+
var base;
|
69
|
+
var owner;
|
70
|
+
var photo = d.photo;
|
71
|
+
var zoom;
|
72
|
+
|
71
73
|
if (d.stat === 'ok') {
|
72
74
|
base = 'http://farm' + photo.farm + '.static.flickr.com/' +
|
73
75
|
photo.server + '/' + photo.id + '_';
|
@@ -85,36 +87,46 @@ Murlsh.flickr_thumb = function (d) {
|
|
85
87
|
}
|
86
88
|
};
|
87
89
|
|
88
|
-
Murlsh.
|
89
|
-
Murlsh.
|
90
|
+
Murlsh.flickrClick = function() {
|
91
|
+
Murlsh.closerAdd(Murlsh.img($(this).data('zoom')));
|
90
92
|
};
|
91
93
|
|
92
|
-
Murlsh.
|
93
|
-
|
94
|
-
|
94
|
+
Murlsh.imgThumb = function() {
|
95
|
+
var lastIndex;
|
96
|
+
var urlParts = [];
|
97
|
+
|
98
|
+
for (var i = 0; i < arguments.length; i += 1) {
|
99
|
+
urlParts.push(arguments[i]);
|
100
|
+
}
|
101
|
+
|
102
|
+
lastIndex = urlParts.length - 1;
|
103
|
+
|
104
|
+
// if pdf the thumbnail will be .png
|
105
|
+
if (urlParts[lastIndex].match(/^pdf$/i)) {
|
106
|
+
urlParts.lastIndex = 'png';
|
107
|
+
}
|
108
|
+
|
109
|
+
return Murlsh.img(urlParts.join('')).addClass('thumb');
|
95
110
|
};
|
96
111
|
|
97
|
-
Murlsh.
|
98
|
-
Murlsh.
|
112
|
+
Murlsh.imgClick = function() {
|
113
|
+
Murlsh.closerAdd(Murlsh.img($(this).data('href')));
|
99
114
|
};
|
100
115
|
|
101
|
-
Murlsh.
|
102
|
-
return Murlsh.img(d.
|
103
|
-
height : d.thumbnail_height,
|
104
|
-
width : d.thumbnail_width
|
105
|
-
});
|
116
|
+
Murlsh.vimeoThumb = function(d) {
|
117
|
+
return Murlsh.img(d.thumbnail_medium, d.title).addClass('thumb vimeo');
|
106
118
|
};
|
107
119
|
|
108
|
-
Murlsh.
|
109
|
-
Murlsh.
|
120
|
+
Murlsh.vimeoClick = function() {
|
121
|
+
Murlsh.closerAdd($(this).data('embedHtml'));
|
110
122
|
};
|
111
123
|
|
112
|
-
Murlsh.
|
124
|
+
Murlsh.youtubeThumb = function(id) {
|
113
125
|
return Murlsh.img('http://img.youtube.com/vi/' + id + '/default.jpg',
|
114
126
|
'click to watch').addClass('thumb youtube').data('id', id);
|
115
127
|
};
|
116
128
|
|
117
|
-
Murlsh.
|
129
|
+
Murlsh.youtubeClick = function() {
|
118
130
|
var movie = 'http://www.youtube.com/v/' + $(this).data('id') + '?' +
|
119
131
|
$.param({
|
120
132
|
fs : 1,
|
@@ -124,115 +136,155 @@ Murlsh.youtube_click = function () {
|
|
124
136
|
showinfo : 0,
|
125
137
|
showsearch : 0
|
126
138
|
});
|
127
|
-
|
139
|
+
|
140
|
+
Murlsh.closerAdd(Murlsh.objectTag(movie, 505, 640,
|
128
141
|
[{ name : 'movie', value : movie }]));
|
129
142
|
};
|
130
143
|
|
131
|
-
Murlsh.
|
144
|
+
Murlsh.thumbInsert = function(img, clickFunction, a) {
|
132
145
|
if (img) {
|
133
|
-
if (Murlsh.
|
146
|
+
if (Murlsh.isIphone()) {
|
134
147
|
a.prepend(img);
|
135
148
|
} else {
|
136
|
-
|
149
|
+
if (clickFunction) {
|
150
|
+
img.click(clickFunction);
|
151
|
+
}
|
152
|
+
a.before(img);
|
137
153
|
}
|
138
154
|
}
|
139
155
|
};
|
140
156
|
|
141
|
-
Murlsh.
|
157
|
+
Murlsh.isIphone = function() {
|
142
158
|
return navigator.userAgent.match(/i(phone|pod)/i);
|
143
159
|
};
|
144
160
|
|
145
|
-
Murlsh.
|
161
|
+
Murlsh.hrefRes = {
|
146
162
|
flickr :
|
147
163
|
/^http:\/\/(?:www\.)?flickr\.com\/photos\/[@\w\-]+?\/([\d]+)/i,
|
148
164
|
imageshack :
|
149
165
|
/^(http:\/\/img\d+\.imageshack\.us\/img\d+\/\d+\/\w+\.)(jpe?g|gif|png)$/i,
|
166
|
+
imgur :
|
167
|
+
/^(http:\/\/(?:i\.)?imgur\.com\/[a-z\d]+)(\.(?:jpe?g|gif|png))$/i,
|
150
168
|
mp3 :
|
151
169
|
/\.mp3$/i,
|
152
170
|
s3 :
|
153
|
-
/^(http:\/\/static\.mmb\.s3\.amazonaws\.com\/[\w
|
171
|
+
/^(http:\/\/static\.mmb\.s3\.amazonaws\.com\/[\w\-]+\.)(jpe?g|gif|pdf|png)$/i,
|
172
|
+
twitter :
|
173
|
+
/^http:\/\/twitter\.com\/\w+\/statuses\/(\d+)$/i,
|
154
174
|
vimeo :
|
155
175
|
/^http:\/\/(?:www\.)?vimeo\.com\/(\d+)$/i,
|
156
176
|
youtube :
|
157
177
|
/^http:\/\/(?:(?:www|uk)\.)?youtube\.com\/watch\?v=([\w\-]+)(?:&|$)/i
|
158
178
|
};
|
159
179
|
|
160
|
-
Murlsh.
|
161
|
-
var href = $(this).attr('href')
|
162
|
-
|
163
|
-
|
164
|
-
|
180
|
+
Murlsh.addExtra = function() {
|
181
|
+
var href = $(this).attr('href');
|
182
|
+
var match = {};
|
183
|
+
var swf = 'swf/player_mp3_mini.swf';
|
184
|
+
var thumb;
|
165
185
|
|
166
|
-
$.each(Murlsh.
|
186
|
+
$.each(Murlsh.hrefRes, function(x, re) {
|
167
187
|
return !(match[x] = re.exec(href));
|
168
188
|
});
|
169
189
|
|
170
190
|
if (match.flickr) {
|
171
191
|
$.ajax({
|
172
|
-
url : 'http://api.flickr.com/services/rest/',
|
192
|
+
// url : 'http://api.flickr.com/services/rest/',
|
193
|
+
url : 'flickr',
|
173
194
|
data : {
|
174
|
-
api_key : 'd04e574aaf11bf2e1c03cba4ee7e5725',
|
175
195
|
format : 'json',
|
176
196
|
method : 'flickr.photos.getinfo',
|
177
197
|
photo_id : match.flickr[1]
|
178
198
|
},
|
179
199
|
dataType : 'jsonp',
|
180
200
|
jsonp : 'jsoncallback',
|
181
|
-
success : function
|
182
|
-
Murlsh.
|
183
|
-
Murlsh.
|
201
|
+
success : function(d) {
|
202
|
+
Murlsh.thumbInsert(Murlsh.flickrThumb(d),
|
203
|
+
Murlsh.flickrClick, $(this));
|
184
204
|
},
|
185
|
-
context : $(this)
|
205
|
+
context : $(this),
|
206
|
+
jsonpCallback : 'flickrCallback' + match.flickr[1]
|
186
207
|
});
|
187
208
|
} else if (match.imageshack) {
|
188
|
-
Murlsh.
|
189
|
-
Murlsh.
|
209
|
+
Murlsh.thumbInsert(
|
210
|
+
Murlsh.imgThumb(match.imageshack[1], 'th.', match.imageshack[2]).data(
|
190
211
|
'href', match.imageshack[0]),
|
191
|
-
|
212
|
+
Murlsh.imgClick, $(this).html('imageshack.us'));
|
213
|
+
} else if (match.imgur) {
|
214
|
+
Murlsh.thumbInsert(
|
215
|
+
Murlsh.imgThumb(match.imgur[1], 's', match.imgur[2]).data('href', match.imgur[0]),
|
216
|
+
Murlsh.imgClick, $(this).html('imgur.com'));
|
192
217
|
} else if (match.mp3) {
|
193
|
-
$(this).before(Murlsh.
|
218
|
+
$(this).before(Murlsh.objectTag(swf, 20, 200, [
|
194
219
|
{ name : 'bgcolor', value : '#000000' },
|
195
220
|
{ name : 'FlashVars', value : 'mp3=' + href },
|
196
221
|
{ name : 'movie', value : swf }
|
197
222
|
]));
|
198
223
|
} else if (match.s3) {
|
199
|
-
thumb = Murlsh.
|
224
|
+
thumb = Murlsh.imgThumb(match.s3[1], 'th.', match.s3[2]);
|
200
225
|
|
201
226
|
if (match.s3[2].match(/^pdf$/i)) {
|
202
227
|
$(this).before(thumb).html('pdf');
|
203
228
|
} else {
|
204
|
-
if (Murlsh.
|
229
|
+
if (Murlsh.isIphone()) {
|
205
230
|
$(this).html(thumb);
|
206
231
|
} else {
|
207
232
|
$(this).html('link');
|
208
233
|
$(this).before(thumb.data('href', match.s3[0]).click(
|
209
|
-
Murlsh.
|
234
|
+
Murlsh.imgClick));
|
210
235
|
}
|
211
236
|
}
|
212
|
-
} else if (match.
|
237
|
+
} else if (match.twitter) {
|
213
238
|
$.ajax({
|
214
|
-
url : 'http://
|
215
|
-
|
239
|
+
url : 'http://api.twitter.com/1/statuses/show/' + match.twitter[1] +
|
240
|
+
'.json',
|
216
241
|
dataType : 'jsonp',
|
217
|
-
success : function
|
218
|
-
|
219
|
-
|
220
|
-
|
242
|
+
success : function(d) {
|
243
|
+
var nameLink = $('<a />', {
|
244
|
+
href: 'http://twitter.com/' + d.user.screen_name,
|
245
|
+
text: d.user.screen_name
|
246
|
+
});
|
247
|
+
|
248
|
+
$(this).html(d.text).before(nameLink).before(
|
249
|
+
document.createTextNode(': '));
|
250
|
+
|
251
|
+
Murlsh.thumbInsert(
|
252
|
+
Murlsh.imgThumb(d.user.profile_image_url).attr({
|
253
|
+
height : '48',
|
254
|
+
width : '48'
|
255
|
+
}), null, nameLink);
|
221
256
|
},
|
222
257
|
context : $(this)
|
223
258
|
});
|
259
|
+
} else if (match.vimeo) {
|
260
|
+
$.ajax({
|
261
|
+
url : 'http://vimeo.com/api/v2/video/' + match.vimeo[1] + '.json',
|
262
|
+
dataType : 'jsonp',
|
263
|
+
success : function(d) {
|
264
|
+
var video = d[0];
|
265
|
+
var movie = 'http://vimeo.com/moogaloop.swf?clip_id=' + video.id;
|
266
|
+
|
267
|
+
Murlsh.thumbInsert(Murlsh.vimeoThumb(video).data(
|
268
|
+
'embedHtml',
|
269
|
+
Murlsh.objectTag(movie, video.height, video.width, [
|
270
|
+
{ name : 'movie', value : movie }
|
271
|
+
])), Murlsh.vimeoClick, $(this));
|
272
|
+
},
|
273
|
+
context : $(this),
|
274
|
+
jsonpCallback : 'vimeoCallback' + match.vimeo[1]
|
275
|
+
});
|
224
276
|
} else if (match.youtube) {
|
225
|
-
Murlsh.
|
226
|
-
Murlsh.
|
277
|
+
Murlsh.thumbInsert(Murlsh.youtubeThumb(match.youtube[1]),
|
278
|
+
Murlsh.youtubeClick, $(this));
|
227
279
|
}
|
228
280
|
};
|
229
281
|
|
230
|
-
Murlsh.
|
282
|
+
Murlsh.formatLi = function(d) {
|
283
|
+
var iconSize = 32;
|
231
284
|
var li = $('<li />').append($('<a />', {
|
232
285
|
href : d.url,
|
233
286
|
text : d.title
|
234
|
-
}))
|
235
|
-
icon_size = 32;
|
287
|
+
}));
|
236
288
|
|
237
289
|
if (d.name) {
|
238
290
|
li.prepend($('<div />', { text : d.name }).addClass('name'));
|
@@ -241,18 +293,18 @@ Murlsh.format_li = function (d) {
|
|
241
293
|
if (d.email) {
|
242
294
|
li.prepend($('<div />').addClass('icon').append(
|
243
295
|
Murlsh.img(
|
244
|
-
'http://www.gravatar.com/avatar/' + d.email + '?s=' +
|
296
|
+
'http://www.gravatar.com/avatar/' + d.email + '?s=' + iconSize,
|
245
297
|
d.name).attr({
|
246
|
-
width :
|
247
|
-
height :
|
298
|
+
width : iconSize,
|
299
|
+
height : iconSize
|
248
300
|
})));
|
249
301
|
}
|
250
302
|
|
251
303
|
return li;
|
252
304
|
};
|
253
305
|
|
254
|
-
Murlsh.
|
255
|
-
window.onorientationchange = function
|
306
|
+
Murlsh.iphoneInit = function() {
|
307
|
+
window.onorientationchange = function() {
|
256
308
|
var width = 450;
|
257
309
|
if (window.orientation === 0 || window.orientation === 180) {
|
258
310
|
width = 290;
|
@@ -262,32 +314,28 @@ Murlsh.iphone_init = function () {
|
|
262
314
|
|
263
315
|
window.onorientationchange();
|
264
316
|
|
265
|
-
$('
|
317
|
+
$('a.feed').replaceWith($('<a />', {
|
266
318
|
href : '#bottom',
|
267
319
|
text : 'bottom'
|
268
320
|
}));
|
269
|
-
$('#urls li:last').append($('<a />', {
|
270
|
-
href : '#urls',
|
271
|
-
text : 'top'
|
272
|
-
}));
|
273
321
|
};
|
274
322
|
|
275
|
-
$(document).ready(function
|
276
|
-
if (Murlsh.
|
277
|
-
Murlsh.
|
323
|
+
$(document).ready(function() {
|
324
|
+
if (Murlsh.isIphone()) {
|
325
|
+
Murlsh.iphoneInit();
|
278
326
|
}
|
279
|
-
$('
|
327
|
+
$('a.m').map(Murlsh.addExtra);
|
280
328
|
|
281
|
-
$('#submit').click(function
|
329
|
+
$('#submit').click(function() {
|
282
330
|
$.post('url', {
|
283
331
|
url : $('#url').val(),
|
284
332
|
via : $('#via').val(),
|
285
333
|
auth : $('#auth').val()
|
286
334
|
}, function (d) {
|
287
|
-
$.each(d, function
|
288
|
-
var li = Murlsh.
|
335
|
+
$.each(d, function(i, v) {
|
336
|
+
var li = Murlsh.formatLi(v);
|
289
337
|
$('#urls > li:first').after(li);
|
290
|
-
$(li).children('a:first').map(Murlsh.
|
338
|
+
$(li).children('a:first').map(Murlsh.addExtra);
|
291
339
|
});
|
292
340
|
$('#url').val('');
|
293
341
|
$('#via').val('');
|
data/spec/atom_feed_spec.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
%w{
|
4
|
+
tempfile
|
5
|
+
time
|
5
6
|
|
6
|
-
|
7
|
+
murlsh
|
8
|
+
}.each { |m| require m }
|
7
9
|
|
8
10
|
describe Murlsh::AtomFeed do
|
9
11
|
|
@@ -30,11 +32,11 @@ describe Murlsh::AtomFeed do
|
|
30
32
|
|
31
33
|
@feed = Murlsh::AtomFeed.new('http://test.com/test/', :title => 'test')
|
32
34
|
|
33
|
-
@expected = <<EOS
|
34
|
-
|
35
|
-
<feed xmlns="http://www
|
36
|
-
<id>http://test
|
37
|
-
<link href="http://test
|
35
|
+
@expected = Regexp.new(<<EOS, Regexp::MULTILINE)
|
36
|
+
<\\?xml version="1\.0" encoding="UTF-8"\\?>
|
37
|
+
<feed xmlns="http://www\\.w3\\.org/2005/Atom">
|
38
|
+
<id>http://test\\.com/test/</id>
|
39
|
+
<link href="http://test\\.com/test/atom\\.xml" rel="self"/>
|
38
40
|
<title>test</title>
|
39
41
|
<updated>2009-12-20T15:10:10Z</updated>
|
40
42
|
<entry>
|
@@ -42,38 +44,37 @@ describe Murlsh::AtomFeed do
|
|
42
44
|
<name>test 1</name>
|
43
45
|
</author>
|
44
46
|
<title>test title</title>
|
45
|
-
<id>tag:test
|
47
|
+
<id>tag:test\\.com,2009-12-19:test\\.com/test/1</id>
|
46
48
|
<summary>test title</summary>
|
47
49
|
<updated>2009-12-19T17:34:56Z</updated>
|
48
|
-
<link href="http://matthewm
|
49
|
-
<link type="
|
50
|
+
<link href="http://matthewm\\.boedicker\\.org/"/>
|
51
|
+
<link type=".*"/>
|
50
52
|
</entry>
|
51
53
|
<entry>
|
52
54
|
<author>
|
53
55
|
<name>test 2</name>
|
54
56
|
</author>
|
55
57
|
<title>image test</title>
|
56
|
-
<id>tag:test
|
58
|
+
<id>tag:test\\.com,2009-12-20:test\\.com/test/2</id>
|
57
59
|
<summary>image test</summary>
|
58
60
|
<updated>2009-12-20T15:10:10Z</updated>
|
59
|
-
<link href="http://matthewm
|
60
|
-
<link type="
|
61
|
+
<link href="http://matthewm\\.boedicker\\.org/test\\.jpg"/>
|
62
|
+
<link type=".*"/>
|
61
63
|
</entry>
|
62
64
|
</feed>
|
63
65
|
EOS
|
66
|
+
|
64
67
|
end
|
65
68
|
|
66
69
|
it 'should generate the correct atom feed' do
|
67
|
-
@feed.make([@url1, @url2], :indent => 2).should
|
70
|
+
@feed.make([@url1, @url2], :indent => 2).should match @expected
|
68
71
|
end
|
69
72
|
|
70
73
|
it 'should write the correct atom feed to a file' do
|
71
|
-
|
72
|
-
@feed.make([@url1, @url2], :indent => 2, :target =>
|
74
|
+
tempfile = Tempfile.open('test_atom_feed')
|
75
|
+
@feed.make([@url1, @url2], :indent => 2, :target => tempfile)
|
73
76
|
|
74
|
-
f.
|
75
|
-
f.read.should == @expected
|
76
|
-
f.close
|
77
|
+
open(tempfile) { |f| f.read.should match @expected }
|
77
78
|
end
|
78
79
|
|
79
80
|
end
|
data/spec/auth_spec.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
|
3
|
-
|
3
|
+
%w{
|
4
|
+
tempfile
|
5
|
+
|
6
|
+
murlsh
|
7
|
+
}.each { |m| require m }
|
4
8
|
|
5
9
|
describe Murlsh::Auth do
|
6
10
|
|
7
11
|
before do
|
8
|
-
@f = '
|
12
|
+
@f = Tempfile.new('murlsh_users_test')
|
9
13
|
|
10
|
-
@a = Murlsh::Auth.new(@f)
|
14
|
+
@a = Murlsh::Auth.new(@f.path)
|
11
15
|
|
12
16
|
@a.add_user('test1', 'test1@test.com', 'secret1')
|
13
17
|
@a.add_user('test2', 'test2@test.com', 'secret2')
|
14
18
|
end
|
15
19
|
|
16
|
-
after do
|
17
|
-
File.delete(@f)
|
18
|
-
end
|
20
|
+
after do; @f.close!; end
|
19
21
|
|
20
22
|
it 'should authorize valid credentials' do
|
21
23
|
@a.auth('secret1').should == {
|
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
|
3
|
+
%w{
|
4
|
+
rack/test
|
5
|
+
|
6
|
+
murlsh
|
7
|
+
}.each { |m| require m }
|
8
|
+
|
9
|
+
describe Murlsh::Dispatch do
|
10
|
+
include Rack::Test::Methods
|
11
|
+
|
12
|
+
def app
|
13
|
+
config = YAML.load_file('config.yaml')
|
14
|
+
Murlsh::Dispatch.new(config)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should return ok for GET /' do
|
18
|
+
get '/'
|
19
|
+
last_response.should be_ok
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should return 404 for an invalid request' do
|
23
|
+
get '/foo'
|
24
|
+
last_response.should_not be_ok
|
25
|
+
end
|
26
|
+
end
|
data/spec/doc_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
|
3
|
+
%w{
|
4
|
+
hpricot
|
5
|
+
|
6
|
+
murlsh
|
7
|
+
}.each { |m| require m }
|
8
|
+
|
9
|
+
describe Murlsh::Doc do
|
10
|
+
|
11
|
+
it 'should get the right title from an HTML page that has one' do
|
12
|
+
html = <<eos
|
13
|
+
<html>
|
14
|
+
<head>
|
15
|
+
<title>the title</title>
|
16
|
+
</head>
|
17
|
+
<body>
|
18
|
+
<h1>hi</h1>
|
19
|
+
</body>
|
20
|
+
</html>
|
21
|
+
eos
|
22
|
+
|
23
|
+
doc = Hpricot(html).extend(Murlsh::Doc)
|
24
|
+
doc.title.should == 'the title'
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/spec/markup_spec.rb
CHANGED
data/spec/uri_ask_spec.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
|
3
|
-
|
3
|
+
%w{
|
4
|
+
uri
|
4
5
|
|
5
|
-
|
6
|
+
murlsh
|
7
|
+
}.each { |m| require m }
|
6
8
|
|
7
9
|
describe Murlsh::UriAsk do
|
8
10
|
|
@@ -24,7 +26,7 @@ describe Murlsh::UriAsk do
|
|
24
26
|
content_type('http://a.b/test/').should be_empty
|
25
27
|
end
|
26
28
|
|
27
|
-
it 'should return an empty string for the content type of a URI with a
|
29
|
+
it 'should return an empty string for the content type of a URI with a nonexistent path' do
|
28
30
|
content_type(
|
29
31
|
'http://matthewm.boedicker.org/does_not_exist/').should be_empty
|
30
32
|
end
|
data/spec/uri_spec.rb
CHANGED
data/spec/url_spec.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
|
3
|
+
%w{
|
4
|
+
tempfile
|
5
|
+
|
6
|
+
sqlite3
|
7
|
+
|
8
|
+
murlsh
|
9
|
+
}.each { |m| require m }
|
10
|
+
|
11
|
+
describe Murlsh::Url do
|
12
|
+
|
13
|
+
before do
|
14
|
+
@db_file = Tempfile.open('murlsh_test_db')
|
15
|
+
|
16
|
+
db = SQLite3::Database.new(@db_file.path)
|
17
|
+
db.execute("CREATE TABLE urls (
|
18
|
+
id INTEGER PRIMARY KEY,
|
19
|
+
time TIMESTAMP,
|
20
|
+
url TEXT,
|
21
|
+
email TEXT,
|
22
|
+
name TEXT,
|
23
|
+
title TEXT,
|
24
|
+
content_type TEXT,
|
25
|
+
via TEXT);
|
26
|
+
")
|
27
|
+
|
28
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3',
|
29
|
+
:database => @db_file.path)
|
30
|
+
|
31
|
+
@url = Murlsh::Url.new
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
@db_file.close
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should return the url for the title if the title is nil' do
|
39
|
+
@url.url = 'http://matthewm.boedicker.org/'
|
40
|
+
@url.title = nil
|
41
|
+
|
42
|
+
@url.title.should == @url.url
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should return the url for the title if the title is empty' do
|
46
|
+
@url.url = 'http://matthewm.boedicker.org/'
|
47
|
+
@url.title = ''
|
48
|
+
|
49
|
+
@url.title.should == @url.url
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|