murlsh 0.2.1

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/public/js/js.js ADDED
@@ -0,0 +1,229 @@
1
+ var Murlsh = {};
2
+
3
+ Murlsh.new_img = function(src, text) {
4
+ return $('<img />').attr({
5
+ src : src,
6
+ alt : text,
7
+ title : text
8
+ });
9
+ };
10
+
11
+ Murlsh.close = function() {
12
+ $(this).parent().remove();
13
+ };
14
+
15
+ Murlsh.closer_add = function(x) {
16
+ var html = (typeof x == 'object') ? $('<div />').append(x).html() : x;
17
+
18
+ $.jGrowl(html, {
19
+ closeTemplate : 'X',
20
+ glue :'before',
21
+ sticky : true
22
+ });
23
+ };
24
+
25
+ Murlsh.object_tag = function(data, height, width, params) {
26
+ var result = '<object data="' + data + '" height="' + height +
27
+ '" type="application/x-shockwave-flash" width="' + width + '">';
28
+ $.each(params, function(i, v) {
29
+ result += '<param name="' + v.name + '" value="' + v.value + '" />';
30
+ });
31
+ result += '</object>';
32
+ return result;
33
+ };
34
+
35
+ Murlsh.flickr_thumb = function(d) {
36
+ var base = 'http://farm' + d.photo.farm + '.static.flickr.com/' +
37
+ d.photo.server + '/' + d.photo.id + '_';
38
+ var zoom;
39
+ if (d.photo.originalsecret) {
40
+ zoom = base + d.photo.originalsecret + '_o.' + d.photo.originalformat;
41
+ } else {
42
+ zoom = base + d.photo.secret + '_m.jpg';
43
+ }
44
+
45
+ return Murlsh.new_img(base + d.photo.secret + '_s.jpg',
46
+ d.photo.title._content).addClass(
47
+ 'thumb flickr').data('zoom', zoom);
48
+ };
49
+
50
+ Murlsh.flickr_click = function() {
51
+ Murlsh.closer_add(Murlsh.new_img($(this).data('zoom'), ''));
52
+ };
53
+
54
+ Murlsh.imageshack_thumb = function(prefix, ext) {
55
+ return Murlsh.new_img(prefix + 'th.' + ext, '').addClass('thumb imgshack');
56
+ };
57
+
58
+ Murlsh.imageshack_click = function() {
59
+ Murlsh.closer_add(Murlsh.new_img($(this).data('href'), ''));
60
+ };
61
+
62
+ Murlsh.vimeo_thumb = function(d) {
63
+ return Murlsh.new_img(d.thumbnail_url, d.title).addClass('thumb vimeo').attr({
64
+ height : d.thumbnail_height,
65
+ width : d.thumbnail_width
66
+ });
67
+ };
68
+
69
+ Murlsh.vimeo_click = function() {
70
+ Murlsh.closer_add($(this).data('embed_html'));
71
+ };
72
+
73
+ Murlsh.youtube_thumb = function(id) {
74
+ return Murlsh.new_img('http://img.youtube.com/vi/' + id + '/1.jpg',
75
+ 'click to watch').addClass('thumb youtube').data('id', id);
76
+ };
77
+
78
+ Murlsh.youtube_click = function() {
79
+ var movie = 'http://www.youtube.com/v/' + $(this).data('id') +
80
+ '?hd=1&amp;hl=en&amp;fs=1&amp;showinfo=0&amp;showsearch=0';
81
+ Murlsh.closer_add(Murlsh.object_tag(movie, 344, 425, [{ name : 'movie', value : movie }]));
82
+ };
83
+
84
+ Murlsh.is_iphone = function() {
85
+ return navigator.userAgent.match(/i(phone|pod)/i);
86
+ };
87
+
88
+ Murlsh.add_extra = function() {
89
+ var this_a = $(this);
90
+
91
+ var href = $(this).attr('href');
92
+
93
+ var flickr_match =
94
+ /^http:\/\/(?:www\.)?flickr\.com\/photos\/[^\/]+?\/([0-9]+)/i.exec(
95
+ href);
96
+
97
+ var imageshack_match =
98
+ /^(http:\/\/img\d+\.imageshack\.us\/img\d+\/\d+\/\w+\.)(jpg|gif|png)$/i.exec(
99
+ href);
100
+
101
+ var mp3_match = /.*\.mp3$/i.exec(href);
102
+
103
+ var s3_match =
104
+ /^(http:\/\/static\.mmb\.s3\.amazonaws.com\/.*\.)(jpg|gif|png)$/i.exec(
105
+ href);
106
+
107
+ var vimeo_match = /^http:\/\/(?:www\.)?vimeo\.com\/([0-9]+)$/i.exec(href);
108
+
109
+ var youtube_match =
110
+ /^http:\/\/(?:(?:www|uk)\.)?youtube\.com\/watch\?v=(.+?)(?:&|$)/i.exec(
111
+ href);
112
+
113
+ var thumb;
114
+ var thumb_insert_func;
115
+
116
+ if (flickr_match) {
117
+ thumb_insert_func = function flickr_thumb_insert(d) {
118
+ var img = Murlsh.flickr_thumb(d);
119
+ if (Murlsh.is_iphone()) {
120
+ this_a.prepend(img);
121
+ } else {
122
+ this_a.before(img.click(Murlsh.flickr_click));
123
+ }
124
+ };
125
+ $.getJSON('http://api.flickr.com/services/rest/?api_key=d04e574aaf11bf2e1c03cba4ee7e5725&method=flickr.photos.getinfo&format=json&photo_id=' +
126
+ flickr_match[1] + '&jsoncallback=?', thumb_insert_func);
127
+ } else if (imageshack_match) {
128
+ thumb = Murlsh.imageshack_thumb(imageshack_match[1], imageshack_match[2]);
129
+ this_a.html('imageshack.us');
130
+ if (Murlsh.is_iphone()) {
131
+ this_a.prepend(thumb);
132
+ } else {
133
+ this_a.before(thumb.data('href', imageshack_match[0]).click(
134
+ Murlsh.imageshack_click));
135
+ }
136
+ } else if (mp3_match) {
137
+ var swf = 'swf/player_mp3_mini.swf';
138
+ $(this).before(Murlsh.object_tag(swf, 20, 200, [
139
+ { name : 'bgcolor', value : '#000000' },
140
+ { name : 'FlashVars', value : 'mp3=' + mp3_match[0] },
141
+ { name : 'movie', value : swf }
142
+ ]));
143
+ } else if (s3_match) {
144
+ thumb = Murlsh.imageshack_thumb(s3_match[1], s3_match[2]);
145
+ if (Murlsh.is_iphone()) {
146
+ this_a.html(thumb);
147
+ } else {
148
+ this_a.html('link');
149
+ this_a.before(thumb.data('href', s3_match[0]).click(
150
+ Murlsh.imageshack_click));
151
+ }
152
+ } else if (vimeo_match) {
153
+ thumb_insert_func = function vimeo_thumb_insert(d) {
154
+ var img = Murlsh.vimeo_thumb(d);
155
+ if (Murlsh.is_iphone()) {
156
+ this_a.prepend(img);
157
+ } else {
158
+ this_a.before(img.data('embed_html', d.html).click(
159
+ Murlsh.vimeo_click));
160
+ }
161
+ };
162
+ $.getJSON('http://vimeo.com/api/oembed.json?url=http%3A//vimeo.com/' +
163
+ vimeo_match[1] + '&callback=?', thumb_insert_func);
164
+ } else if (youtube_match) {
165
+ var img = Murlsh.youtube_thumb(youtube_match[1]);
166
+ if (Murlsh.is_iphone()) {
167
+ $(this).prepend(img);
168
+ } else {
169
+ $(this).before(img.click(Murlsh.youtube_click));
170
+ }
171
+ }
172
+ };
173
+
174
+ Murlsh.format_li = function(d) {
175
+ var li = $('<li />').append($('<a />').attr('href', d.url).text(
176
+ d.title));
177
+
178
+ if (d.name) {
179
+ li.prepend($('<div />').addClass('name').text(d.name));
180
+ }
181
+
182
+ var icon_size = 32;
183
+
184
+ if (d.email) {
185
+ li.prepend($('<div />').addClass('icon').append(
186
+ Murlsh.new_img(
187
+ 'http://www.gravatar.com/avatar/' + d.email + '?s=' + icon_size,
188
+ d.name).attr({
189
+ width : icon_size,
190
+ height : icon_size
191
+ })));
192
+ }
193
+
194
+ return li;
195
+ };
196
+
197
+ Murlsh.orientation_changed = function() {
198
+ if (window.orientation === 0 || window.orientation == 180) {
199
+ $('#urls').width(290);
200
+ } else {
201
+ $('#urls').width(450);
202
+ }
203
+ };
204
+
205
+ window.onorientationchange = Murlsh.orientation_changed;
206
+
207
+ $(document).ready(function() {
208
+ Murlsh.orientation_changed();
209
+ $('a').map(Murlsh.add_extra);
210
+ $('#urls li:even').addClass('even');
211
+
212
+ $('#submit').click(function() {
213
+ $.post('url', {
214
+ url : $('#url').val(),
215
+ auth : $('#auth').val()
216
+ }, function(d) {
217
+ $.each(d, function(i, v) {
218
+ var li = Murlsh.format_li(v);
219
+ $('#urls > li:first').after(li);
220
+ $(li).children('a:first').map(Murlsh.add_extra);
221
+ });
222
+ $('#url').val('');
223
+ }, 'json');
224
+ });
225
+
226
+ if ($.cookie('auth')) {
227
+ $('#auth').val($.cookie('auth'));
228
+ }
229
+ });
Binary file
data/test/auth_test.rb ADDED
@@ -0,0 +1,34 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'murlsh'
4
+
5
+ require 'test/unit'
6
+
7
+ class AuthTest < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @f = '/tmp/murlsh_users_test'
11
+
12
+ @a = Murlsh::Auth.new(@f)
13
+
14
+ @a.add_user('test1', 'test1@test.com', 'secert1')
15
+ @a.add_user('test2', 'test2@test.com', 'secert2')
16
+ @a.add_user('test3', 'test3@test.com', 'secert3')
17
+ end
18
+
19
+ def teardown
20
+ File.delete(@f)
21
+ end
22
+
23
+ def test_auth_good
24
+ assert_equal({
25
+ :name => 'test1',
26
+ :email => Digest::MD5.hexdigest('test1@test.com') },
27
+ @a.auth('secert1'))
28
+ end
29
+
30
+ def test_bad
31
+ assert_equal(nil, @a.auth('not there'))
32
+ end
33
+
34
+ end
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'murlsh'
4
+
5
+ require 'rubygems'
6
+ require 'hpricot'
7
+
8
+ require 'test/unit'
9
+
10
+ class GetCharsetTest < Test::Unit::TestCase
11
+
12
+ def test_no_charset
13
+ doc = Hpricot(<<eos
14
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
15
+ "http://www.w3.org/TR/html4/strict.dtd">
16
+ <html>
17
+ <head></head>
18
+ <body></body>
19
+ </html>
20
+ eos
21
+ )
22
+ assert_nil(Murlsh.get_charset(doc))
23
+ end
24
+
25
+ end
@@ -0,0 +1,63 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'murlsh'
4
+
5
+ require 'test/unit'
6
+ require 'uri'
7
+
8
+ class GetContentTypeTest < Test::Unit::TestCase
9
+
10
+ def test_nil
11
+ assert_equal('', Murlsh.get_content_type(nil))
12
+ end
13
+
14
+ def test_empty
15
+ assert_equal('', Murlsh.get_content_type(''))
16
+ end
17
+
18
+ def test_bad_url
19
+ assert_equal('', Murlsh.get_content_type('not a url'))
20
+ end
21
+
22
+ def test_bad_host
23
+ assert_equal('', Murlsh.get_content_type('http://a.b/test/'))
24
+ end
25
+
26
+ def test_bad_path
27
+ assert_equal('', Murlsh.get_content_type(
28
+ 'http://matthewm.boedicker.org/does_not_exist/'))
29
+ end
30
+
31
+ def test_good
32
+ assert_match(/^text\/html/, Murlsh.get_content_type(
33
+ 'http://www.google.com/'))
34
+ end
35
+
36
+ def test_already_parsed
37
+ assert_match(/^text\/html/, Murlsh.get_content_type(
38
+ URI('http://www.google.com/')))
39
+ end
40
+
41
+ def test_already_parsed_https
42
+ assert_match(/^text\/html/, Murlsh.get_content_type(
43
+ URI('https://msp.f-secure.com/web-test/common/test.html')))
44
+ end
45
+
46
+ def test_303
47
+ # youtube returns a 303
48
+ assert_match(/^text\/html/, Murlsh.get_content_type(
49
+ 'http://www.youtube.com/watch?v=vfxCnZ4Dp3c'))
50
+ end
51
+
52
+ def test_failproof_true
53
+ assert_equal('', Murlsh.get_content_type('http://x.boedicker.org/',
54
+ :failproof => true))
55
+ end
56
+
57
+ def test_failproof_false
58
+ assert_raise SocketError do
59
+ Murlsh.get_content_type('http://x.boedicker.org/', :failproof => false)
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,43 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'murlsh'
4
+
5
+ require 'test/unit'
6
+
7
+ class GetTitleTest < Test::Unit::TestCase
8
+
9
+ def noop(url)
10
+ assert_equal(url, Murlsh.get_title(url))
11
+ end
12
+
13
+ def test_nil
14
+ noop(nil)
15
+ end
16
+
17
+ def test_empty
18
+ noop('')
19
+ end
20
+
21
+ def test_invalid_url
22
+ noop('foo')
23
+ end
24
+
25
+ def test_invalid_host
26
+ noop('http://28fac7a1ac51976c90016509d97c89ba.edu/')
27
+ end
28
+
29
+ def test_good
30
+ assert_equal('Google', Murlsh.get_title('http://www.google.com/'))
31
+ end
32
+
33
+ def test_failproof_true
34
+ noop(Murlsh.get_title('http://x.boedicker.org/', :failproof => true))
35
+ end
36
+
37
+ def test_failproof_false
38
+ assert_raise SocketError do
39
+ Murlsh.get_title('http://x.boedicker.org/', :failproof => false)
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,144 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'murlsh'
4
+
5
+ require 'test/unit'
6
+
7
+ class MarkupMixer < Builder::XmlMarkup
8
+ include Murlsh::Markup
9
+ end
10
+
11
+ class MarkupTest < Test::Unit::TestCase
12
+
13
+ def setup
14
+ @m = MarkupMixer.new()
15
+ end
16
+
17
+ def attr_check(name, value, s)
18
+ assert_match(/#{name}="#{value}"/, s)
19
+ end
20
+
21
+ def test_javascript_single
22
+ @m.javascript('test.js')
23
+ assert_equal(
24
+ '<script type="text/javascript" src="test.js"></script>', @m.target!)
25
+ end
26
+
27
+ def test_javascript_multiple
28
+ @m.javascript(['test1.js', 'test2.js'])
29
+ assert_equal(
30
+ '<script type="text/javascript" src="test1.js"></script><script type="text/javascript" src="test2.js"></script>',
31
+ @m.target!)
32
+ end
33
+
34
+ def test_javascript_single_prefix
35
+ @m.javascript('test.js', :prefix => 'http://static.com/js/')
36
+ assert_equal(
37
+ '<script type="text/javascript" src="http://static.com/js/test.js"></script>',
38
+ @m.target!)
39
+ end
40
+
41
+ def test_javascript_multiple_prefix
42
+ @m.javascript(['test1.js', 'test2.js'], :prefix => 'js/')
43
+ assert_equal(
44
+ '<script type="text/javascript" src="js/test1.js"></script><script type="text/javascript" src="js/test2.js"></script>',
45
+ @m.target!)
46
+ end
47
+
48
+ def test_murlsh_img_prefix
49
+ @m.murlsh_img(:src => 'foo.png', :prefix => 'http://static.com/img/')
50
+ assert_equal('<img src="http://static.com/img/foo.png"/>', @m.target!)
51
+ end
52
+
53
+ def test_murlsh_img_size_one
54
+ @m.murlsh_img(:src => 'foo.png', :size => 32)
55
+ [
56
+ %w{height 32},
57
+ %w{src foo.png},
58
+ %w{width 32},
59
+ ].each { |t| attr_check(*t.push(@m.target!)) }
60
+ end
61
+
62
+ def test_murlsh_img_size_two
63
+ @m.murlsh_img(:src => 'foo.png', :size => [100, 200])
64
+ [
65
+ %w{height 200},
66
+ %w{src foo.png},
67
+ %w{width 100},
68
+ ].each { |t| attr_check(*t.push(@m.target!)) }
69
+ end
70
+
71
+ def test_murlsh_img_size_text
72
+ @m.murlsh_img(:src => 'foo.png', :text => 'test')
73
+ [
74
+ %w{alt test},
75
+ %w{src foo.png},
76
+ %w{title test},
77
+ ].each { |t| attr_check(*t.push(@m.target!)) }
78
+ end
79
+
80
+ def test_murlsh_img_href
81
+ @m.murlsh_img(:href => '/test/', :src => 'foo.png')
82
+ assert_equal('<a href="/test/"><img src="foo.png"/></a>', @m.target!)
83
+ end
84
+
85
+ def test_metas
86
+ @m.metas(:a => '1', :b => '2', :c => '3')
87
+ [
88
+ '<meta (name="a" content="1"|content="1" name="a")/>',
89
+ '<meta (name="b" content="2"|content="2" name="b")/>',
90
+ '<meta (name="c" content="3"|content="3" name="c")/>',
91
+ ].each { |r| assert_match(/#{r}/, @m.target!) }
92
+ end
93
+
94
+ def test_gravatar_none
95
+ @m.gravatar('xxx')
96
+ assert_equal('<img src="http://www.gravatar.com/avatar/xxx"/>', @m.target!)
97
+ end
98
+
99
+ def test_gravatar_valid_d
100
+ @m.gravatar('xxx', 'd' => 'identicon')
101
+ assert_equal('<img src="http://www.gravatar.com/avatar/xxx?d=identicon"/>',
102
+ @m.target!)
103
+ end
104
+
105
+ def test_gravatar_invalid_d
106
+ @m.gravatar('xxx', 'd' => 'bad')
107
+ assert_equal('<img src="http://www.gravatar.com/avatar/xxx"/>', @m.target!)
108
+ end
109
+
110
+ def test_gravatar_valid_r
111
+ @m.gravatar('xxx', 'r' => 'x')
112
+ assert_equal('<img src="http://www.gravatar.com/avatar/xxx?r=x"/>',
113
+ @m.target!)
114
+ end
115
+
116
+ def test_gravatar_invalid_r
117
+ @m.gravatar('xxx', 'r' => 'foo')
118
+ assert_equal('<img src="http://www.gravatar.com/avatar/xxx"/>', @m.target!)
119
+ end
120
+
121
+ def test_gravatar_valid_s
122
+ @m.gravatar('xxx', 's' => 100)
123
+ assert_equal('<img src="http://www.gravatar.com/avatar/xxx?s=100"/>',
124
+ @m.target!)
125
+ end
126
+
127
+ def test_gravatar_invalid_s
128
+ @m.gravatar('xxx', 's' => 1000)
129
+ assert_equal('<img src="http://www.gravatar.com/avatar/xxx"/>', @m.target!)
130
+ end
131
+
132
+ def test_gravatar_s_0
133
+ @m.gravatar('xxx', 's' => 0)
134
+ assert_equal('', @m.target!)
135
+ end
136
+
137
+ def test_gravatar_href
138
+ @m.gravatar('xxx', :href => '/test/')
139
+ assert_equal(
140
+ '<a href="/test/"><img src="http://www.gravatar.com/avatar/xxx"/></a>',
141
+ @m.target!)
142
+ end
143
+
144
+ end
@@ -0,0 +1,71 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'murlsh'
4
+
5
+ require 'test/unit'
6
+
7
+ class ReferrerTest < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @qmap = {
11
+ /www\.foo\.com\/search/ => 'q',
12
+ }
13
+ end
14
+
15
+ def instantiate(url)
16
+ Murlsh::Referrer.new(url)
17
+ end
18
+
19
+ def test_url_nil
20
+ r = instantiate(nil)
21
+ assert_equal('', r.hostpath)
22
+ assert_equal({}, r.query_string)
23
+ end
24
+
25
+ def test_url_nil_block
26
+ r = instantiate(nil)
27
+ r.search_query(@qmap) { |x| flunk }
28
+ end
29
+
30
+ def test_url_empty
31
+ r = instantiate('')
32
+ assert_equal('', r.hostpath)
33
+ assert_equal({}, r.query_string)
34
+ end
35
+
36
+ def test_url_empty_block
37
+ r = instantiate('')
38
+ r.search_query(@qmap) { |x| flunk }
39
+ end
40
+
41
+ def test_hostpath_not_found
42
+ r = instantiate('http://www.bar.com/search?q=test&a=1&b=2&c=3')
43
+ assert_equal(nil, r.search_query(@qmap))
44
+ end
45
+
46
+ def test_hostpath_not_found_block
47
+ r = instantiate('http://www.bar.com/search?q=test&a=1&b=2&c=3')
48
+ r.search_query(@qmap) { |x| flunk }
49
+ end
50
+
51
+ def test_query_not_found
52
+ r = instantiate('http://www.foo.com/search?a=1&b=2&c=3')
53
+ assert_equal(nil, r.search_query(@qmap))
54
+ end
55
+
56
+ def test_query_not_found_block
57
+ r = instantiate('http://www.foo.com/search?a=1&b=2&c=3')
58
+ r.search_query(@qmap) { |x| flunk }
59
+ end
60
+
61
+ def test_good
62
+ r = instantiate('http://www.foo.com/search?q=test&a=1&b=2&c=3')
63
+ assert_equal('test', r.search_query(@qmap))
64
+ end
65
+
66
+ def test_good_block
67
+ r = instantiate('http://www.foo.com/search?q=test&a=1&b=2&c=3')
68
+ r.search_query(@qmap) { |x| assert_equal('test', x) }
69
+ end
70
+
71
+ end