murlsh 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.htaccess +5 -0
  2. data/COPYING +27 -0
  3. data/README.textile +2 -2
  4. data/Rakefile +133 -66
  5. data/VERSION +1 -1
  6. data/config.ru +9 -8
  7. data/config.yaml +3 -2
  8. data/lib/murlsh/auth.rb +6 -8
  9. data/lib/murlsh/config_server.rb +4 -6
  10. data/lib/murlsh/dispatch.rb +5 -7
  11. data/lib/murlsh/doc.rb +1 -1
  12. data/lib/murlsh/etag_add_encoding.rb +1 -3
  13. data/lib/murlsh/failproof.rb +0 -1
  14. data/lib/murlsh/far_future_expires.rb +2 -4
  15. data/lib/murlsh/head_from_get.rb +2 -2
  16. data/lib/murlsh/image_list.rb +32 -0
  17. data/lib/murlsh/img_store.rb +47 -9
  18. data/lib/murlsh/markup.rb +53 -20
  19. data/lib/murlsh/must_revalidate.rb +2 -4
  20. data/lib/murlsh/plugin.rb +1 -1
  21. data/lib/murlsh/sqlite3_adapter.rb +2 -4
  22. data/lib/murlsh/time_ago.rb +6 -8
  23. data/lib/murlsh/uri.rb +1 -3
  24. data/lib/murlsh/uri_ask.rb +23 -25
  25. data/lib/murlsh/url.rb +4 -6
  26. data/lib/murlsh/url_body.rb +19 -21
  27. data/lib/murlsh/url_server.rb +8 -10
  28. data/lib/murlsh/yaml_ordered_hash.rb +2 -4
  29. data/lib/murlsh.rb +21 -4
  30. data/murlsh.gemspec +95 -90
  31. data/plugins/add_post_50_update_feed.rb +22 -10
  32. data/plugins/add_post_50_update_podcast.rb +3 -5
  33. data/plugins/add_post_50_update_rss.rb +4 -6
  34. data/plugins/add_post_60_notify_hubs.rb +3 -5
  35. data/plugins/add_pre_40_convert_mobile.rb +4 -10
  36. data/plugins/add_pre_50_lookup_content_type_title.rb +4 -6
  37. data/plugins/add_pre_60_flickr.rb +3 -14
  38. data/plugins/add_pre_60_github_title.rb +4 -6
  39. data/plugins/add_pre_60_google_code_title.rb +4 -6
  40. data/plugins/add_pre_60_imgur.rb +4 -16
  41. data/plugins/add_pre_60_s3_image.rb +7 -6
  42. data/plugins/add_pre_60_twitter.rb +3 -14
  43. data/plugins/add_pre_60_vimeo.rb +7 -6
  44. data/plugins/add_pre_60_youtube.rb +8 -7
  45. data/plugins/add_pre_65_html_thumb.rb +41 -0
  46. data/plugins/add_pre_65_img_thumb.rb +39 -0
  47. data/plugins/html_parse_50_hpricot.rb +2 -4
  48. data/plugins/url_display_add_45_audio.rb +28 -0
  49. data/plugins/url_display_add_50_hostrec.rb +15 -18
  50. data/plugins/url_display_add_55_content_type.rb +6 -8
  51. data/plugins/url_display_add_60_via.rb +12 -19
  52. data/plugins/url_display_add_65_time.rb +4 -6
  53. data/public/css/screen.css +2 -3
  54. data/public/img/thumb/.gitignore +3 -0
  55. data/public/js/jquery-1.4.4.min.js +167 -0
  56. data/public/js/js.js +6 -5
  57. data/public/js/{twitter-text-1.0.3.js → twitter-text-1.0.4.js} +3 -1
  58. data/spec/auth_spec.rb +4 -6
  59. data/spec/dispatch_spec.rb +3 -5
  60. data/spec/doc_spec.rb +2 -4
  61. data/spec/img_store_spec.rb +46 -20
  62. data/spec/markup_spec.rb +22 -24
  63. data/spec/uri_ask_spec.rb +5 -7
  64. data/spec/uri_spec.rb +2 -4
  65. data/spec/url_spec.rb +5 -9
  66. data/spec/yaml_ordered_hash_spec.rb +1 -3
  67. metadata +85 -53
  68. data/.gitignore +0 -6
  69. data/plugins/add_pre_60_imageshack.rb +0 -31
  70. data/plugins/url_display_add_45_mp3.rb +0 -30
  71. data/public/img/thumb/README +0 -0
  72. data/public/js/jquery-1.4.3.min.js +0 -166
  73. data/public/swf/player_mp3_mini.swf +0 -0
@@ -1,12 +1,10 @@
1
- %w{
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
- # Add YouTube thumbnail.
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.store(
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
@@ -1,8 +1,6 @@
1
- %w{
2
- hpricot
1
+ require 'hpricot'
3
2
 
4
- murlsh
5
- }.each { |m| require m }
3
+ require 'murlsh'
6
4
 
7
5
  module Murlsh
8
6
 
@@ -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
- %w{
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
- # show the domain of the url
7
+ # Show the domain of the url.
10
8
  class UrlDisplayAdd50HostRec < Plugin
11
9
 
12
10
  @hook = 'url_display_add'
13
11
 
14
- # show the domain of the url
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
- class << self; attr_reader :skips; end
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
- %w{
2
- murlsh
3
- }.each { |m| require m }
1
+ require 'murlsh'
4
2
 
5
3
  module Murlsh
6
4
 
7
- # warn of content types that launch external apps
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
- # warn of content types that launch external apps
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' then 'pdf'
16
- when 'audio/mpeg' then 'mp3'
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(" (#{content_type_display})", :class => 'content-type')
19
+ markup.span " (#{content_type_display})", :class => 'content-type'
22
20
  end
23
21
  end
24
22
 
@@ -1,12 +1,10 @@
1
- %w{
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
- # show a via link for the url
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
- # show a via link for the url
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 m = search.match(HackerNewsRe)
30
- 'hacker news'
31
- when m = search.match(RedditRe)
32
- "#{m[1]}.reddit"
33
- when m = search.match(DeliciousRe)
34
- "delicious/#{m[1]}"
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!(' via '); markup.a(display_via, :href => via_uri_s)
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
- %w{
2
- murlsh
3
- }.each { |m| require m }
1
+ require 'murlsh'
4
2
 
5
3
  module Murlsh
6
4
 
7
- # show the time the url was posted
5
+ # Show the time the url was posted.
8
6
  class UrlDisplayAdd65Time < Plugin
9
7
 
10
8
  @hook = 'url_display_add'
11
9
 
12
- # show the time the url was posted
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(", #{display_time}", :class => 'date')
14
+ markup.span ", #{display_time}", :class => 'date'
17
15
  end
18
16
  end
19
17
 
@@ -55,9 +55,8 @@ img.thumb, li object {
55
55
  margin-right : 10px;
56
56
  }
57
57
 
58
- img.thumb.twitter {
59
- height : 48px;
60
- width : 48px;
58
+ .clickable {
59
+ border-right : 4px solid green;
61
60
  }
62
61
 
63
62
  span.host {
@@ -0,0 +1,3 @@
1
+ *.gif
2
+ *.jpg
3
+ *.png