murlsh 0.11.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.htaccess +2 -0
  2. data/README.textile +3 -33
  3. data/Rakefile +12 -5
  4. data/VERSION +1 -1
  5. data/config.ru +10 -4
  6. data/config.yaml +6 -12
  7. data/lib/murlsh/dispatch.rb +0 -6
  8. data/lib/murlsh/img_store.rb +36 -0
  9. data/lib/murlsh/markup.rb +0 -1
  10. data/lib/murlsh/plugin.rb +2 -6
  11. data/lib/murlsh/uri_ask.rb +66 -22
  12. data/lib/murlsh/url.rb +0 -18
  13. data/lib/murlsh/url_body.rb +15 -23
  14. data/lib/murlsh/url_server.rb +5 -5
  15. data/murlsh.gemspec +44 -19
  16. data/plugins/add_post_50_update_feed.rb +17 -3
  17. data/plugins/add_post_50_update_podcast.rb +46 -0
  18. data/plugins/add_post_50_update_rss.rb +18 -2
  19. data/plugins/add_post_60_notify_hubs.rb +3 -1
  20. data/plugins/add_pre_40_convert_mobile.rb +30 -0
  21. data/plugins/add_pre_50_lookup_content_type_title.rb +11 -4
  22. data/plugins/add_pre_60_flickr.rb +38 -0
  23. data/plugins/add_pre_60_github_title.rb +5 -1
  24. data/plugins/add_pre_60_google_code_title.rb +5 -2
  25. data/plugins/add_pre_60_imageshack.rb +31 -0
  26. data/plugins/add_pre_60_imgur.rb +32 -0
  27. data/plugins/add_pre_60_s3_image.rb +34 -0
  28. data/plugins/add_pre_60_twitter.rb +35 -0
  29. data/plugins/add_pre_60_vimeo.rb +35 -0
  30. data/plugins/add_pre_60_youtube.rb +31 -0
  31. data/plugins/html_parse_50_hpricot.rb +2 -0
  32. data/plugins/url_display_add_45_mp3.rb +30 -0
  33. data/plugins/url_display_add_50_hostrec.rb +38 -0
  34. data/plugins/url_display_add_55_content_type.rb +27 -0
  35. data/plugins/url_display_add_60_via.rb +52 -0
  36. data/plugins/url_display_add_65_time.rb +22 -0
  37. data/public/css/jquery.jgrowl.css +0 -3
  38. data/public/css/screen.css +0 -18
  39. data/public/img/thumb/README +0 -0
  40. data/public/js/jquery-1.4.3.min.js +166 -0
  41. data/public/js/js.js +62 -234
  42. data/public/js/twitter-text-1.0.3.js +538 -0
  43. data/spec/img_store_spec.rb +53 -0
  44. data/spec/uri_ask_spec.rb +14 -4
  45. metadata +139 -37
  46. data/lib/murlsh/flickr_server.rb +0 -55
  47. data/lib/murlsh/twitter_server.rb +0 -45
  48. data/lib/murlsh/unwrap_jsonp.rb +0 -15
  49. data/lib/murlsh/xhtml_response.rb +0 -20
  50. data/plugins/hostrec_50_redundant.rb +0 -14
  51. data/plugins/hostrec_60_skip.rb +0 -24
  52. data/plugins/time_50_ago.rb +0 -16
  53. data/plugins/via_50_domain.rb +0 -36
  54. data/public/js/jquery-1.4.2.min.js +0 -154
  55. data/spec/unwrap_json_spec.rb +0 -21
  56. data/spec/xhtml_response_spec.rb +0 -112
data/murlsh.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{murlsh}
8
- s.version = "0.11.0"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Matthew M. Boedicker"]
12
- s.date = %q{2010-09-21}
12
+ s.date = %q{2010-11-03}
13
13
  s.default_executable = %q{murlsh}
14
14
  s.description = %q{url sharing site framework with easy adding, title lookup, atom feed, thumbnails and embedding}
15
15
  s.email = %q{matthewm@boedicker.org}
@@ -35,51 +35,59 @@ Gem::Specification.new do |s|
35
35
  "lib/murlsh/etag_add_encoding.rb",
36
36
  "lib/murlsh/failproof.rb",
37
37
  "lib/murlsh/far_future_expires.rb",
38
- "lib/murlsh/flickr_server.rb",
39
38
  "lib/murlsh/head_from_get.rb",
39
+ "lib/murlsh/img_store.rb",
40
40
  "lib/murlsh/markup.rb",
41
41
  "lib/murlsh/must_revalidate.rb",
42
42
  "lib/murlsh/openlock.rb",
43
43
  "lib/murlsh/plugin.rb",
44
44
  "lib/murlsh/sqlite3_adapter.rb",
45
45
  "lib/murlsh/time_ago.rb",
46
- "lib/murlsh/twitter_server.rb",
47
- "lib/murlsh/unwrap_jsonp.rb",
48
46
  "lib/murlsh/uri.rb",
49
47
  "lib/murlsh/uri_ask.rb",
50
48
  "lib/murlsh/url.rb",
51
49
  "lib/murlsh/url_body.rb",
52
50
  "lib/murlsh/url_server.rb",
53
- "lib/murlsh/xhtml_response.rb",
54
51
  "lib/murlsh/yaml_ordered_hash.rb",
55
52
  "murlsh.gemspec",
56
53
  "plugins/add_post_50_update_feed.rb",
54
+ "plugins/add_post_50_update_podcast.rb",
57
55
  "plugins/add_post_50_update_rss.rb",
58
56
  "plugins/add_post_60_notify_hubs.rb",
57
+ "plugins/add_pre_40_convert_mobile.rb",
59
58
  "plugins/add_pre_50_lookup_content_type_title.rb",
59
+ "plugins/add_pre_60_flickr.rb",
60
60
  "plugins/add_pre_60_github_title.rb",
61
61
  "plugins/add_pre_60_google_code_title.rb",
62
- "plugins/hostrec_50_redundant.rb",
63
- "plugins/hostrec_60_skip.rb",
62
+ "plugins/add_pre_60_imageshack.rb",
63
+ "plugins/add_pre_60_imgur.rb",
64
+ "plugins/add_pre_60_s3_image.rb",
65
+ "plugins/add_pre_60_twitter.rb",
66
+ "plugins/add_pre_60_vimeo.rb",
67
+ "plugins/add_pre_60_youtube.rb",
64
68
  "plugins/html_parse_50_hpricot.rb",
65
- "plugins/time_50_ago.rb",
66
- "plugins/via_50_domain.rb",
69
+ "plugins/url_display_add_45_mp3.rb",
70
+ "plugins/url_display_add_50_hostrec.rb",
71
+ "plugins/url_display_add_55_content_type.rb",
72
+ "plugins/url_display_add_60_via.rb",
73
+ "plugins/url_display_add_65_time.rb",
67
74
  "public/css/jquery.jgrowl.css",
68
75
  "public/css/screen.css",
76
+ "public/img/thumb/README",
69
77
  "public/js/comments.json",
70
- "public/js/jquery-1.4.2.min.js",
78
+ "public/js/jquery-1.4.3.min.js",
71
79
  "public/js/jquery.jgrowl_compressed.js",
72
80
  "public/js/js.js",
81
+ "public/js/twitter-text-1.0.3.js",
73
82
  "public/swf/player_mp3_mini.swf",
74
83
  "spec/auth_spec.rb",
75
84
  "spec/dispatch_spec.rb",
76
85
  "spec/doc_spec.rb",
86
+ "spec/img_store_spec.rb",
77
87
  "spec/markup_spec.rb",
78
- "spec/unwrap_json_spec.rb",
79
88
  "spec/uri_ask_spec.rb",
80
89
  "spec/uri_spec.rb",
81
90
  "spec/url_spec.rb",
82
- "spec/xhtml_response_spec.rb",
83
91
  "spec/yaml_ordered_hash_spec.rb"
84
92
  ]
85
93
  s.homepage = %q{http://github.com/mmb/murlsh}
@@ -88,11 +96,10 @@ Gem::Specification.new do |s|
88
96
  s.rubygems_version = %q{1.3.7}
89
97
  s.summary = %q{url sharing site framework}
90
98
  s.test_files = [
91
- "spec/xhtml_response_spec.rb",
92
- "spec/auth_spec.rb",
99
+ "spec/auth_spec.rb",
93
100
  "spec/yaml_ordered_hash_spec.rb",
94
- "spec/unwrap_json_spec.rb",
95
101
  "spec/uri_ask_spec.rb",
102
+ "spec/img_store_spec.rb",
96
103
  "spec/dispatch_spec.rb",
97
104
  "spec/markup_spec.rb",
98
105
  "spec/url_spec.rb",
@@ -108,42 +115,60 @@ Gem::Specification.new do |s|
108
115
  s.add_runtime_dependency(%q<activerecord>, [">= 2.3.4"])
109
116
  s.add_runtime_dependency(%q<bcrypt-ruby>, [">= 2.1.2"])
110
117
  s.add_runtime_dependency(%q<builder>, [">= 2.1.2"])
118
+ s.add_runtime_dependency(%q<flickraw>, [">= 0.8.3"])
119
+ s.add_runtime_dependency(%q<flog>, [">= 2.5.0"])
111
120
  s.add_runtime_dependency(%q<hpricot>, [">= 0.8.1"])
112
121
  s.add_runtime_dependency(%q<htmlentities>, [">= 4.2.0"])
113
122
  s.add_runtime_dependency(%q<json>, [">= 1.2.3"])
114
123
  s.add_runtime_dependency(%q<push-notify>, [">= 0.1.0"])
115
124
  s.add_runtime_dependency(%q<rack>, [">= 1.0.0"])
116
125
  s.add_runtime_dependency(%q<rack-cache>, [">= 0.5.2"])
126
+ s.add_runtime_dependency(%q<rack-rewrite>, [">= 1.0.2"])
117
127
  s.add_runtime_dependency(%q<rack-throttle>, [">= 0.3.0"])
118
128
  s.add_runtime_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
119
- s.add_runtime_dependency(%q<tinyatom>, [">= 0.1.1"])
129
+ s.add_runtime_dependency(%q<tinyatom>, [">= 0.2.0"])
130
+ s.add_runtime_dependency(%q<twitter>, [">= 0.9.12"])
131
+ s.add_runtime_dependency(%q<vimeo>, [">= 1.2.2"])
132
+ s.add_runtime_dependency(%q<rspec>, ["~> 1.3"])
120
133
  else
121
134
  s.add_dependency(%q<activerecord>, [">= 2.3.4"])
122
135
  s.add_dependency(%q<bcrypt-ruby>, [">= 2.1.2"])
123
136
  s.add_dependency(%q<builder>, [">= 2.1.2"])
137
+ s.add_dependency(%q<flickraw>, [">= 0.8.3"])
138
+ s.add_dependency(%q<flog>, [">= 2.5.0"])
124
139
  s.add_dependency(%q<hpricot>, [">= 0.8.1"])
125
140
  s.add_dependency(%q<htmlentities>, [">= 4.2.0"])
126
141
  s.add_dependency(%q<json>, [">= 1.2.3"])
127
142
  s.add_dependency(%q<push-notify>, [">= 0.1.0"])
128
143
  s.add_dependency(%q<rack>, [">= 1.0.0"])
129
144
  s.add_dependency(%q<rack-cache>, [">= 0.5.2"])
145
+ s.add_dependency(%q<rack-rewrite>, [">= 1.0.2"])
130
146
  s.add_dependency(%q<rack-throttle>, [">= 0.3.0"])
131
147
  s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
132
- s.add_dependency(%q<tinyatom>, [">= 0.1.1"])
148
+ s.add_dependency(%q<tinyatom>, [">= 0.2.0"])
149
+ s.add_dependency(%q<twitter>, [">= 0.9.12"])
150
+ s.add_dependency(%q<vimeo>, [">= 1.2.2"])
151
+ s.add_dependency(%q<rspec>, ["~> 1.3"])
133
152
  end
134
153
  else
135
154
  s.add_dependency(%q<activerecord>, [">= 2.3.4"])
136
155
  s.add_dependency(%q<bcrypt-ruby>, [">= 2.1.2"])
137
156
  s.add_dependency(%q<builder>, [">= 2.1.2"])
157
+ s.add_dependency(%q<flickraw>, [">= 0.8.3"])
158
+ s.add_dependency(%q<flog>, [">= 2.5.0"])
138
159
  s.add_dependency(%q<hpricot>, [">= 0.8.1"])
139
160
  s.add_dependency(%q<htmlentities>, [">= 4.2.0"])
140
161
  s.add_dependency(%q<json>, [">= 1.2.3"])
141
162
  s.add_dependency(%q<push-notify>, [">= 0.1.0"])
142
163
  s.add_dependency(%q<rack>, [">= 1.0.0"])
143
164
  s.add_dependency(%q<rack-cache>, [">= 0.5.2"])
165
+ s.add_dependency(%q<rack-rewrite>, [">= 1.0.2"])
144
166
  s.add_dependency(%q<rack-throttle>, [">= 0.3.0"])
145
167
  s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
146
- s.add_dependency(%q<tinyatom>, [">= 0.1.1"])
168
+ s.add_dependency(%q<tinyatom>, [">= 0.2.0"])
169
+ s.add_dependency(%q<twitter>, [">= 0.9.12"])
170
+ s.add_dependency(%q<vimeo>, [">= 1.2.2"])
171
+ s.add_dependency(%q<rspec>, ["~> 1.3"])
147
172
  end
148
173
  end
149
174
 
@@ -1,4 +1,6 @@
1
1
  %w{
2
+ uri
3
+
2
4
  tinyatom
3
5
 
4
6
  murlsh
@@ -11,7 +13,16 @@ module Murlsh
11
13
 
12
14
  @hook = 'add_post'
13
15
 
14
- def self.run(config)
16
+ # content types to add an enclosure for
17
+ EnclosureContentTypes = %w{
18
+ application/pdf
19
+ audio/mpeg
20
+ image/gif
21
+ image/jpeg
22
+ image/png
23
+ }
24
+
25
+ def self.run(url, config)
15
26
  feed = TinyAtom::Feed.new(config['root_url'], config.fetch('page_title'),
16
27
  URI.join(config['root_url'], config['feed_file']),
17
28
  :hubs => config.fetch('pubsubhubbub_hubs', []).
@@ -26,12 +37,15 @@ module Murlsh
26
37
  :summary => mu.title_stripped
27
38
  }
28
39
 
29
- if mu.is_image?
40
+ if EnclosureContentTypes.include?(mu.content_type)
30
41
  options.merge!(
31
42
  :enclosure_type => mu.content_type,
32
43
  :enclosure_href => mu.url,
33
- :enclosure_title => 'Full-size'
44
+ :enclosure_title => mu.title
34
45
  )
46
+ if mu.content_length
47
+ options.merge!(:enclosure_length => mu.content_length)
48
+ end
35
49
  end
36
50
 
37
51
  Murlsh::failproof do
@@ -0,0 +1,46 @@
1
+ %w{
2
+ rss/maker
3
+ uri
4
+
5
+ murlsh
6
+ }.each { |m| require m }
7
+
8
+ module Murlsh
9
+
10
+ # Regenerate podcast RSS feed after a new audio/mpeg url has been added.
11
+ class AddPost50UpdatePodcast < Plugin
12
+
13
+ @hook = 'add_post'
14
+
15
+ def self.run(url, config)
16
+ if url.content_type == 'audio/mpeg'
17
+ output_file = 'podcast.rss'
18
+
19
+ feed = RSS::Maker.make('2.0') do |f|
20
+ f.channel.title = f.channel.description = config.fetch(
21
+ 'page_title', '')
22
+ f.channel.link = URI.join(config.fetch('root_url'), output_file)
23
+ f.items.do_sort = true
24
+
25
+ Murlsh::Url.all(:conditions => { :content_type => 'audio/mpeg' },
26
+ :order => 'id DESC',
27
+ :limit => config.fetch('num_posts_feed', 25)).each do |mu|
28
+ i = f.items.new_item
29
+ i.title = mu.title_stripped
30
+ i.link = mu.url
31
+ i.date = mu.time
32
+
33
+ i.enclosure.url = mu.url
34
+ i.enclosure.type = mu.content_type
35
+ i.enclosure.length = mu.content_length
36
+ end
37
+
38
+ end
39
+
40
+ Murlsh::openlock(output_file, 'w') { |f| f.write(feed) }
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -1,5 +1,6 @@
1
1
  %w{
2
2
  rss/maker
3
+ uri
3
4
 
4
5
  murlsh
5
6
  }.each { |m| require m }
@@ -11,8 +12,17 @@ module Murlsh
11
12
 
12
13
  @hook = 'add_post'
13
14
 
14
- def self.run(config)
15
- output_file = 'rss.xml'
15
+ # content types to add an enclosure for
16
+ EnclosureContentTypes = %w{
17
+ application/pdf
18
+ audio/mpeg
19
+ image/gif
20
+ image/jpeg
21
+ image/png
22
+ }
23
+
24
+ def self.run(url, config)
25
+ output_file = 'rss.rss'
16
26
 
17
27
  feed = RSS::Maker.make('2.0') do |f|
18
28
  f.channel.title = f.channel.description = config.fetch('page_title', '')
@@ -25,6 +35,12 @@ module Murlsh
25
35
  i.title = mu.title_stripped
26
36
  i.link = mu.url
27
37
  i.date = mu.time
38
+
39
+ if EnclosureContentTypes.include?(mu.content_type)
40
+ i.enclosure.url = mu.url
41
+ i.enclosure.type = mu.content_type
42
+ i.enclosure.length = mu.content_length
43
+ end
28
44
  end
29
45
 
30
46
  end
@@ -1,4 +1,6 @@
1
1
  %w{
2
+ uri
3
+
2
4
  murlsh
3
5
  }.each { |m| require m }
4
6
 
@@ -9,7 +11,7 @@ module Murlsh
9
11
 
10
12
  @hook = 'add_post'
11
13
 
12
- def self.run(config)
14
+ def self.run(url, config)
13
15
  hubs = config.fetch('pubsubhubbub_hubs', [])
14
16
 
15
17
  unless hubs.empty?
@@ -0,0 +1,30 @@
1
+ %w{
2
+ murlsh
3
+ }.each { |m| require m }
4
+
5
+ module Murlsh
6
+
7
+
8
+ # Convert urls specifically for use on mobile devices into their non-mobile
9
+ # equivalents.
10
+ class AddPre40ConvertMobile < Plugin
11
+
12
+ @hook = 'add_pre'
13
+
14
+ TwitterRe = %r{^(http://)mobile\.(twitter\.com/.*)$}i
15
+ WikipediaRe = %r{^(http://[a-z]+\.)m\.(wikipedia\.org/.*)$}i
16
+
17
+ def self.run(url, config)
18
+ url.url = case
19
+ when match = TwitterRe.match(url.url)
20
+ "#{match[1]}#{match[2]}"
21
+ when match = WikipediaRe.match(url.url)
22
+ "#{match[1]}#{match[2]}"
23
+ else
24
+ url.url
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -1,19 +1,26 @@
1
1
  %w{
2
+ uri
3
+
2
4
  murlsh
3
5
  }.each { |m| require m }
4
6
 
5
7
  module Murlsh
6
8
 
7
- # try to fetch the content type and title of a url
9
+ # try to fetch the content length, content type and title of a url
8
10
  class AddPre50LookupContentTypeTitle < Plugin
9
11
 
10
12
  @hook = 'add_pre'
11
13
 
12
14
  def self.run(url, config)
13
15
  ask = URI(url.url).extend(Murlsh::UriAsk)
14
- headers = {
15
- 'User-Agent' => 'murlsh (http://github.com/mmb/murlsh)'
16
- }
16
+ headers = {}
17
+ headers['User-Agent'] = config['user_agent'] if config['user_agent']
18
+
19
+ content_length = ask.content_length(:headers => headers)
20
+ if content_length and not content_length.empty?
21
+ url.content_length = content_length
22
+ end
23
+
17
24
  url.content_type = ask.content_type(:headers => headers)
18
25
  url.title = ask.title(:headers => headers)
19
26
  end
@@ -0,0 +1,38 @@
1
+ %w{
2
+ cgi
3
+
4
+ flickraw
5
+
6
+ murlsh
7
+ }.each { |m| require m }
8
+
9
+ module Murlsh
10
+
11
+ # Set the title and thumbnail url of Flickr photos.
12
+ class AddPre60Flickr < Plugin
13
+
14
+ @hook = 'add_pre'
15
+
16
+ FlickrRe = %r{^http://(?:www\.)?flickr\.com/photos/[@\w\-]+?/([\d]+)}i
17
+ StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
18
+ 'thumb')
19
+
20
+ def self.run(url, config)
21
+ if config['flickr_api_key'] and not config['flickr_api_key'].empty?
22
+ if photo_id = url.url[FlickrRe, 1]
23
+ FlickRaw.api_key = config['flickr_api_key']
24
+ info = flickr.photos.getInfo(:photo_id => photo_id)
25
+
26
+ url.title = "#{info.title} by #{info.owner.username}"
27
+
28
+ thumb_storage = Murlsh::ImgStore.new(StorageDir,
29
+ :user_agent => config['user_agent'])
30
+ stored_filename = thumb_storage.store(FlickRaw.url_s(info))
31
+ url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
32
+ end
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -1,4 +1,6 @@
1
1
  %w{
2
+ uri
3
+
2
4
  murlsh
3
5
  }.each { |m| require m }
4
6
 
@@ -10,8 +12,10 @@ module Murlsh
10
12
 
11
13
  @hook = 'add_pre'
12
14
 
15
+ GithubRe = %r{^http://github\.com/\w+/[\w.-]+$}i
16
+
13
17
  def self.run(url, config)
14
- if url.url[%r{^http://github\.com/\w+/[\w.-]+$}]
18
+ if url.url[GithubRe]
15
19
  ask = URI(url.url).extend(Murlsh::UriAsk)
16
20
  url.title << " - #{ask.description}" unless ask.description.empty?
17
21
  end
@@ -1,4 +1,6 @@
1
1
  %w{
2
+ uri
3
+
2
4
  murlsh
3
5
  }.each { |m| require m }
4
6
 
@@ -10,9 +12,10 @@ module Murlsh
10
12
 
11
13
  @hook = 'add_pre'
12
14
 
15
+ GoogleCodeRe = %r{^http://code\.google\.com/p/[\w-]+/$}i
16
+
13
17
  def self.run(url, config)
14
- if url.url[%r{^http://code\.google\.com/p/[\w-]+/$}]
15
- puts 'xxx'
18
+ if url.url[GoogleCodeRe]
16
19
  ask = URI(url.url).extend(Murlsh::UriAsk)
17
20
  ask.doc.xpath_search("//a[@id='project_summary_link']") do |node|
18
21
  summary = node ? node.inner_html : nil
@@ -0,0 +1,31 @@
1
+ %w{
2
+ cgi
3
+
4
+ murlsh
5
+ }.each { |m| require m }
6
+
7
+ module Murlsh
8
+
9
+ # Set the thumbnail of imageshack images.
10
+ class AddPre60Imageshack < Plugin
11
+
12
+ @hook = 'add_pre'
13
+
14
+ ImageshackRe =
15
+ %r{^(http://img\d+\.imageshack\.us/img\d+/\d+/)(\w+)\.(jpe?g|gif|png)$}i
16
+ StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
17
+ 'thumb')
18
+
19
+ def self.run(url, config)
20
+ if match = ImageshackRe.match(url.url)
21
+ thumb_storage = Murlsh::ImgStore.new(StorageDir,
22
+ :user_agent => config['user_agent'])
23
+ stored_filename = thumb_storage.store(
24
+ "#{match[1]}#{match[2]}.th.#{match[3]}")
25
+ url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,32 @@
1
+ %w{
2
+ cgi
3
+
4
+ murlsh
5
+ }.each { |m| require m }
6
+
7
+ module Murlsh
8
+
9
+ # Add YouTube thumbnail.
10
+ class AddPre60Imgur < Plugin
11
+
12
+ @hook = 'add_pre'
13
+
14
+ ImgurRe = %r{^(http://(?:i\.)?imgur\.com/)([a-z\d]+)(\.(?:jpe?g|gif|png))$}i
15
+ StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
16
+ 'thumb')
17
+
18
+ def self.run(url, config)
19
+ if match = ImgurRe.match(url.url)
20
+ url.title = "imgur/#{match[2]}s#{match[3]}"
21
+
22
+ thumb_storage = Murlsh::ImgStore.new(StorageDir,
23
+ :user_agent => config['user_agent'])
24
+ stored_filename = thumb_storage.store(
25
+ "#{match[1]}#{match[2]}s#{match[3]}")
26
+ url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,34 @@
1
+ %w{
2
+ cgi
3
+
4
+ murlsh
5
+ }.each { |m| require m }
6
+
7
+ module Murlsh
8
+
9
+ # Set the thumbnail of s3 hosted images.
10
+ class AddPre60S3Image < Plugin
11
+
12
+ @hook = 'add_pre'
13
+
14
+ S3ImageRe = %r{^(http://static\.mmb\.s3\.amazonaws\.com/)([\w\-]+)\.(jpe?g|gif|pdf|png)$}i
15
+ StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
16
+ 'thumb')
17
+
18
+ def self.run(url, config)
19
+ if match = S3ImageRe.match(url.url)
20
+ extension = match[3].downcase == 'pdf' ? 'png' : match[3]
21
+
22
+ thumb_storage = Murlsh::ImgStore.new(StorageDir,
23
+ :user_agent => config['user_agent'])
24
+ stored_filename = thumb_storage.store(
25
+ "#{match[1]}#{match[2]}.th.#{extension}")
26
+
27
+ url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
28
+ url.title = match[2]
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,35 @@
1
+ %w{
2
+ cgi
3
+
4
+ twitter
5
+
6
+ murlsh
7
+ }.each { |m| require m }
8
+
9
+ module Murlsh
10
+
11
+ # Set title to entire tweet and set thumbnail url.
12
+ class AddPre60Twitter < Plugin
13
+
14
+ @hook = 'add_pre'
15
+
16
+ TwitterRe = %r{^https?://twitter\.com/\w+/status(?:es)?/(\d+)$}i
17
+ StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
18
+ 'thumb')
19
+
20
+ def self.run(url, config)
21
+ if tweet_id = url.url[TwitterRe, 1]
22
+ tweet = Twitter.status(tweet_id)
23
+
24
+ url.title = "@#{tweet.user.screen_name}: #{tweet.text}"
25
+
26
+ thumb_storage = Murlsh::ImgStore.new(StorageDir,
27
+ :user_agent => config['user_agent'])
28
+ stored_filename = thumb_storage.store(tweet.user.profile_image_url)
29
+ url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,35 @@
1
+ %w{
2
+ cgi
3
+
4
+ vimeo
5
+
6
+ murlsh
7
+ }.each { |m| require m }
8
+
9
+ module Murlsh
10
+
11
+ # Set title and thumbnail url for Vimeo urls.
12
+ class AddPre60Vimeo < Plugin
13
+
14
+ @hook = 'add_pre'
15
+
16
+ VimeoRe = %r{^http://(?:www\.)?vimeo\.com/(\d+)$}i
17
+ StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
18
+ 'thumb')
19
+
20
+ def self.run(url, config)
21
+ if id = url.url[VimeoRe, 1]
22
+ info = Vimeo::Simple::Video.info(id)[0]
23
+
24
+ url.title = "#{info['title']} by #{info['user_name']}"
25
+
26
+ thumb_storage = Murlsh::ImgStore.new(StorageDir,
27
+ :user_agent => config['user_agent'])
28
+ stored_filename = thumb_storage.store(info['thumbnail_small'])
29
+ url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,31 @@
1
+ %w{
2
+ cgi
3
+
4
+ murlsh
5
+ }.each { |m| require m }
6
+
7
+ module Murlsh
8
+
9
+ # Add YouTube thumbnail.
10
+ class AddPre60Youtube < Plugin
11
+
12
+ @hook = 'add_pre'
13
+
14
+ YoutubeRe =
15
+ %r{^http://(?:(?:www|uk)\.)?youtube\.com/watch\?v=([\w\-]+)(?:&|$)}i
16
+ StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
17
+ 'thumb')
18
+
19
+ def self.run(url, config)
20
+ if youtube_id = url.url[YoutubeRe, 1]
21
+ thumb_storage = Murlsh::ImgStore.new(StorageDir,
22
+ :user_agent => config['user_agent'])
23
+ stored_filename = thumb_storage.store(
24
+ "http://img.youtube.com/vi/#{youtube_id}/default.jpg")
25
+ url.thumbnail_url = "img/thumb/#{CGI.escape(stored_filename)}"
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -1,5 +1,7 @@
1
1
  %w{
2
2
  hpricot
3
+
4
+ murlsh
3
5
  }.each { |m| require m }
4
6
 
5
7
  module Murlsh