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.
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