murlsh 1.0.0 → 1.1.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/.htaccess +5 -0
- data/COPYING +27 -0
- data/README.textile +2 -2
- data/Rakefile +133 -66
- data/VERSION +1 -1
- data/config.ru +9 -8
- data/config.yaml +3 -2
- data/lib/murlsh/auth.rb +6 -8
- data/lib/murlsh/config_server.rb +4 -6
- data/lib/murlsh/dispatch.rb +5 -7
- data/lib/murlsh/doc.rb +1 -1
- data/lib/murlsh/etag_add_encoding.rb +1 -3
- data/lib/murlsh/failproof.rb +0 -1
- data/lib/murlsh/far_future_expires.rb +2 -4
- data/lib/murlsh/head_from_get.rb +2 -2
- data/lib/murlsh/image_list.rb +32 -0
- data/lib/murlsh/img_store.rb +47 -9
- data/lib/murlsh/markup.rb +53 -20
- data/lib/murlsh/must_revalidate.rb +2 -4
- data/lib/murlsh/plugin.rb +1 -1
- data/lib/murlsh/sqlite3_adapter.rb +2 -4
- data/lib/murlsh/time_ago.rb +6 -8
- data/lib/murlsh/uri.rb +1 -3
- data/lib/murlsh/uri_ask.rb +23 -25
- data/lib/murlsh/url.rb +4 -6
- data/lib/murlsh/url_body.rb +19 -21
- data/lib/murlsh/url_server.rb +8 -10
- data/lib/murlsh/yaml_ordered_hash.rb +2 -4
- data/lib/murlsh.rb +21 -4
- data/murlsh.gemspec +95 -90
- data/plugins/add_post_50_update_feed.rb +22 -10
- data/plugins/add_post_50_update_podcast.rb +3 -5
- data/plugins/add_post_50_update_rss.rb +4 -6
- data/plugins/add_post_60_notify_hubs.rb +3 -5
- data/plugins/add_pre_40_convert_mobile.rb +4 -10
- data/plugins/add_pre_50_lookup_content_type_title.rb +4 -6
- data/plugins/add_pre_60_flickr.rb +3 -14
- data/plugins/add_pre_60_github_title.rb +4 -6
- data/plugins/add_pre_60_google_code_title.rb +4 -6
- data/plugins/add_pre_60_imgur.rb +4 -16
- data/plugins/add_pre_60_s3_image.rb +7 -6
- data/plugins/add_pre_60_twitter.rb +3 -14
- data/plugins/add_pre_60_vimeo.rb +7 -6
- data/plugins/add_pre_60_youtube.rb +8 -7
- data/plugins/add_pre_65_html_thumb.rb +41 -0
- data/plugins/add_pre_65_img_thumb.rb +39 -0
- data/plugins/html_parse_50_hpricot.rb +2 -4
- data/plugins/url_display_add_45_audio.rb +28 -0
- data/plugins/url_display_add_50_hostrec.rb +15 -18
- data/plugins/url_display_add_55_content_type.rb +6 -8
- data/plugins/url_display_add_60_via.rb +12 -19
- data/plugins/url_display_add_65_time.rb +4 -6
- data/public/css/screen.css +2 -3
- data/public/img/thumb/.gitignore +3 -0
- data/public/js/jquery-1.4.4.min.js +167 -0
- data/public/js/js.js +6 -5
- data/public/js/{twitter-text-1.0.3.js → twitter-text-1.0.4.js} +3 -1
- data/spec/auth_spec.rb +4 -6
- data/spec/dispatch_spec.rb +3 -5
- data/spec/doc_spec.rb +2 -4
- data/spec/img_store_spec.rb +46 -20
- data/spec/markup_spec.rb +22 -24
- data/spec/uri_ask_spec.rb +5 -7
- data/spec/uri_spec.rb +2 -4
- data/spec/url_spec.rb +5 -9
- data/spec/yaml_ordered_hash_spec.rb +1 -3
- metadata +85 -53
- data/.gitignore +0 -6
- data/plugins/add_pre_60_imageshack.rb +0 -31
- data/plugins/url_display_add_45_mp3.rb +0 -30
- data/public/img/thumb/README +0 -0
- data/public/js/jquery-1.4.3.min.js +0 -166
- data/public/swf/player_mp3_mini.swf +0 -0
@@ -1,12 +1,10 @@
|
|
1
|
-
|
2
|
-
cgi
|
1
|
+
require 'cgi'
|
3
2
|
|
4
|
-
murlsh
|
5
|
-
}.each { |m| require m }
|
3
|
+
require 'murlsh'
|
6
4
|
|
7
5
|
module Murlsh
|
8
6
|
|
9
|
-
#
|
7
|
+
# Set the thumbnail url for youtube urls.
|
10
8
|
class AddPre60Youtube < Plugin
|
11
9
|
|
12
10
|
@hook = 'add_pre'
|
@@ -20,8 +18,11 @@ module Murlsh
|
|
20
18
|
if youtube_id = url.url[YoutubeRe, 1]
|
21
19
|
thumb_storage = Murlsh::ImgStore.new(StorageDir,
|
22
20
|
:user_agent => config['user_agent'])
|
23
|
-
stored_filename = thumb_storage.
|
24
|
-
"http://img.youtube.com/vi/#{youtube_id}/default.jpg")
|
21
|
+
stored_filename = thumb_storage.store_url(
|
22
|
+
"http://img.youtube.com/vi/#{youtube_id}/default.jpg") do |i|
|
23
|
+
max_side = config.fetch('thumbnail_max_side', 90)
|
24
|
+
i.extend(Murlsh::ImageList).resize_down!(max_side)
|
25
|
+
end
|
25
26
|
url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
|
26
27
|
end
|
27
28
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
require 'plumnailer'
|
4
|
+
|
5
|
+
require 'murlsh'
|
6
|
+
|
7
|
+
module Murlsh
|
8
|
+
|
9
|
+
# Get thumbnail for HTML page urls with plumnailer if not already set.
|
10
|
+
class AddPre65HtmlThumb < Plugin
|
11
|
+
|
12
|
+
@hook = 'add_pre'
|
13
|
+
|
14
|
+
StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
|
15
|
+
'thumb')
|
16
|
+
|
17
|
+
MarkupContentTypeRe = %r{^text/html|application/xhtml\+xml}
|
18
|
+
|
19
|
+
def self.run(url, config)
|
20
|
+
if not url.thumbnail_url and url.content_type and
|
21
|
+
url.content_type[MarkupContentTypeRe]
|
22
|
+
Murlsh::failproof do
|
23
|
+
chooser = Plumnailer::Chooser.new
|
24
|
+
choice = chooser.choose(url.url)
|
25
|
+
|
26
|
+
if choice
|
27
|
+
max_side = config.fetch('thumbnail_max_side', 90)
|
28
|
+
choice.extend(Murlsh::ImageList).resize_down!(max_side)
|
29
|
+
|
30
|
+
thumb_storage = Murlsh::ImgStore.new(StorageDir)
|
31
|
+
|
32
|
+
stored_filename = thumb_storage.store_img(choice)
|
33
|
+
url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
require 'murlsh'
|
4
|
+
|
5
|
+
module Murlsh
|
6
|
+
|
7
|
+
# Get thumbnail for image urls if not already set.
|
8
|
+
class AddPre65ImgThumb < Plugin
|
9
|
+
|
10
|
+
@hook = 'add_pre'
|
11
|
+
|
12
|
+
StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
|
13
|
+
'thumb')
|
14
|
+
|
15
|
+
ImageContentType = %w{
|
16
|
+
image/gif
|
17
|
+
image/jpeg
|
18
|
+
image/png
|
19
|
+
}
|
20
|
+
|
21
|
+
def self.run(url, config)
|
22
|
+
if not url.thumbnail_url and url.content_type and
|
23
|
+
ImageContentType.include?(url.content_type)
|
24
|
+
Murlsh::failproof do
|
25
|
+
thumb_storage = Murlsh::ImgStore.new(StorageDir,
|
26
|
+
:user_agent => config['user_agent'])
|
27
|
+
|
28
|
+
stored_filename = thumb_storage.store_url(url.url) do |i|
|
29
|
+
max_side = config.fetch('thumbnail_max_side', 90)
|
30
|
+
i.extend(Murlsh::ImageList).resize_down!(max_side)
|
31
|
+
end
|
32
|
+
url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'murlsh'
|
2
|
+
|
3
|
+
module Murlsh
|
4
|
+
|
5
|
+
# Add HTML5 audio tag to audio urls.
|
6
|
+
class UrlDisplayAdd45Audio < Plugin
|
7
|
+
|
8
|
+
@hook = 'url_display_add'
|
9
|
+
|
10
|
+
AudioContentTypes = %w{
|
11
|
+
application/ogg
|
12
|
+
audio/mpeg
|
13
|
+
audio/ogg
|
14
|
+
}
|
15
|
+
|
16
|
+
def self.run(markup, url, config)
|
17
|
+
if AudioContentTypes.include?(url.content_type)
|
18
|
+
markup.text! ' '
|
19
|
+
markup.audio(
|
20
|
+
:controls => 'controls',
|
21
|
+
:preload => 'none',
|
22
|
+
:src => url.url) { }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -1,28 +1,15 @@
|
|
1
|
-
|
2
|
-
uri
|
1
|
+
require 'uri'
|
3
2
|
|
4
|
-
murlsh
|
5
|
-
}.each { |m| require m }
|
3
|
+
require 'murlsh'
|
6
4
|
|
7
5
|
module Murlsh
|
8
6
|
|
9
|
-
#
|
7
|
+
# Show the domain of the url.
|
10
8
|
class UrlDisplayAdd50HostRec < Plugin
|
11
9
|
|
12
10
|
@hook = 'url_display_add'
|
13
11
|
|
14
|
-
|
15
|
-
def self.run(markup, url, config)
|
16
|
-
if domain = Murlsh::failproof { URI(url.url).domain }
|
17
|
-
# show domain if not already contained in title and not on skip list
|
18
|
-
unless (url.title and url.title.downcase.index(domain)) or
|
19
|
-
skips.include?(domain)
|
20
|
-
markup.span(" [#{domain}]", :class => 'host')
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
@skips = %w{
|
12
|
+
SkipDomains = %w{
|
26
13
|
wikipedia.org
|
27
14
|
flickr.com
|
28
15
|
github.com
|
@@ -31,7 +18,17 @@ module Murlsh
|
|
31
18
|
vimeo.com
|
32
19
|
youtube.com
|
33
20
|
}
|
34
|
-
|
21
|
+
|
22
|
+
# Show the domain of the url.
|
23
|
+
def self.run(markup, url, config)
|
24
|
+
if domain = Murlsh::failproof { URI(url.url).domain }
|
25
|
+
# show domain if not already contained in title and not on skip list
|
26
|
+
unless (url.title and url.title.downcase.index(domain)) or
|
27
|
+
SkipDomains.include?(domain)
|
28
|
+
markup.span " [#{domain}]", :class => 'host'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
35
32
|
|
36
33
|
end
|
37
34
|
|
@@ -1,24 +1,22 @@
|
|
1
|
-
|
2
|
-
murlsh
|
3
|
-
}.each { |m| require m }
|
1
|
+
require 'murlsh'
|
4
2
|
|
5
3
|
module Murlsh
|
6
4
|
|
7
|
-
#
|
5
|
+
# Warn of content types that launch external apps.
|
8
6
|
class UrlDisplayAdd55ContentType < Plugin
|
9
7
|
|
10
8
|
@hook = 'url_display_add'
|
11
9
|
|
12
|
-
#
|
10
|
+
# Warn of content types that launch external apps.
|
13
11
|
def self.run(markup, url, config)
|
14
12
|
content_type_display = case url.content_type
|
15
|
-
when 'application/pdf'
|
16
|
-
when 'audio/mpeg'
|
13
|
+
when 'application/pdf'; 'pdf'
|
14
|
+
when 'audio/mpeg'; 'mp3'
|
17
15
|
else ''
|
18
16
|
end
|
19
17
|
|
20
18
|
unless content_type_display.empty?
|
21
|
-
markup.span
|
19
|
+
markup.span " (#{content_type_display})", :class => 'content-type'
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
@@ -1,12 +1,10 @@
|
|
1
|
-
|
2
|
-
uri
|
1
|
+
require 'uri'
|
3
2
|
|
4
|
-
murlsh
|
5
|
-
}.each { |m| require m }
|
3
|
+
require 'murlsh'
|
6
4
|
|
7
5
|
module Murlsh
|
8
6
|
|
9
|
-
#
|
7
|
+
# Show a via link for the url.
|
10
8
|
class UrlDisplayAdd60Via < Plugin
|
11
9
|
|
12
10
|
@hook = 'url_display_add'
|
@@ -18,7 +16,7 @@ module Murlsh
|
|
18
16
|
TwitterRe = %r{^twitter\.com/(\w+)}i
|
19
17
|
TumblrRe = %r{^([a-z\d][a-z\d-]{0,61}[a-z\d])\.tumblr\.com/}i
|
20
18
|
|
21
|
-
#
|
19
|
+
# Show a via link for the url.
|
22
20
|
def self.run(markup, url, config)
|
23
21
|
if url.via
|
24
22
|
if via_uri = Murlsh::failproof { URI(url.via) }
|
@@ -26,22 +24,17 @@ module Murlsh
|
|
26
24
|
search = via_uri_s.gsub(HttpRe, '')
|
27
25
|
|
28
26
|
display_via = case
|
29
|
-
when
|
30
|
-
|
31
|
-
when m = search.match(
|
32
|
-
|
33
|
-
when m = search.match(
|
34
|
-
|
35
|
-
when m = search.match(TwitterRe)
|
36
|
-
"twitter/#{m[1]}"
|
37
|
-
when m = search.match(TumblrRe)
|
38
|
-
"#{m[1]}.tumblr"
|
39
|
-
else
|
40
|
-
via_uri.domain || via_uri_s
|
27
|
+
when search.match(HackerNewsRe); 'hacker news'
|
28
|
+
when m = search.match(RedditRe); "#{m[1]}.reddit"
|
29
|
+
when m = search.match(DeliciousRe); "delicious/#{m[1]}"
|
30
|
+
when m = search.match(TwitterRe); "twitter/#{m[1]}"
|
31
|
+
when m = search.match(TumblrRe); "#{m[1]}.tumblr"
|
32
|
+
else via_uri.domain || via_uri_s
|
41
33
|
end
|
42
34
|
|
43
35
|
markup.span(:class => 'via') do
|
44
|
-
markup.text!
|
36
|
+
markup.text! ' via '
|
37
|
+
markup.a display_via, :href => via_uri_s
|
45
38
|
end
|
46
39
|
end
|
47
40
|
end
|
@@ -1,19 +1,17 @@
|
|
1
|
-
|
2
|
-
murlsh
|
3
|
-
}.each { |m| require m }
|
1
|
+
require 'murlsh'
|
4
2
|
|
5
3
|
module Murlsh
|
6
4
|
|
7
|
-
#
|
5
|
+
# Show the time the url was posted.
|
8
6
|
class UrlDisplayAdd65Time < Plugin
|
9
7
|
|
10
8
|
@hook = 'url_display_add'
|
11
9
|
|
12
|
-
#
|
10
|
+
# Show the time the url was posted.
|
13
11
|
def self.run(markup, url, config)
|
14
12
|
if url.time
|
15
13
|
display_time = url.time.extend(Murlsh::TimeAgo).ago
|
16
|
-
markup.span
|
14
|
+
markup.span ", #{display_time}", :class => 'date'
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
data/public/css/screen.css
CHANGED