murlsh 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.htaccess +1 -0
  2. data/README.textile +6 -12
  3. data/Rakefile +19 -17
  4. data/VERSION +1 -1
  5. data/bin/murlsh +2 -35
  6. data/config.ru +1 -1
  7. data/config.yaml +9 -9
  8. data/lib/murlsh/ask.rb +15 -0
  9. data/lib/murlsh/cp_r_safe.rb +33 -0
  10. data/lib/murlsh/doc.rb +1 -16
  11. data/lib/murlsh/install.rb +28 -0
  12. data/lib/murlsh/plugin.rb +0 -2
  13. data/lib/murlsh/search_conditions.rb +12 -2
  14. data/lib/murlsh/search_grammar.rb +225 -0
  15. data/lib/murlsh/search_grammar.treetop +34 -0
  16. data/lib/murlsh/uri_ask.rb +10 -14
  17. data/lib/murlsh/url_body.rb +33 -19
  18. data/lib/murlsh/url_result_set.rb +12 -2
  19. data/lib/murlsh.rb +4 -1
  20. data/murlsh.gemspec +26 -21
  21. data/plugins/add_post_50_update_m3u.rb +35 -0
  22. data/plugins/{add_pre_41_unajax_twitter.rb → add_pre_30_unajax_twitter.rb} +1 -1
  23. data/plugins/add_pre_35_url_clean.rb +21 -0
  24. data/plugins/add_pre_50_media_thumbnail.rb +6 -3
  25. data/plugins/add_pre_65_html_thumb.rb +1 -3
  26. data/plugins/url_display_add_60_via.rb +4 -1
  27. data/public/css/jquery.jgrowl.css +11 -7
  28. data/public/css/screen.css +3 -2
  29. data/public/js/jquery-1.5.min.js +16 -0
  30. data/public/js/jquery.jgrowl_compressed.js +40 -32
  31. data/public/js/js.js +3 -43
  32. data/public/js/{twitter-text-1.0.4.js → twitter-text-1.3.1.js} +25 -22
  33. data/spec/doc_spec.rb +10 -4
  34. metadata +75 -61
  35. data/lib/murlsh/sqlite3_adapter.rb +0 -13
  36. data/plugins/add_pre_60_flickr.rb +0 -27
  37. data/plugins/add_pre_60_vimeo.rb +0 -38
  38. data/plugins/html_parse_50_nokogiri.rb +0 -16
  39. data/public/js/comments.json +0 -1
  40. data/public/js/jquery-1.4.4.min.js +0 -167
@@ -62,10 +62,7 @@ module Murlsh
62
62
  @description
63
63
  end
64
64
 
65
- # Get the parsed doc at this url.
66
- #
67
- # Doc can be an Hpricot or Nokogiri doc or anything that supports the
68
- # methods in Murlsh::Doc.
65
+ # Get the parsed Nokogiri doc at this url.
69
66
  #
70
67
  # Options:
71
68
  # * :failproof - if true hide all exceptions and return empty string on failure
@@ -78,14 +75,13 @@ module Murlsh
78
75
  if html?(options)
79
76
  Murlsh::failproof(options) do
80
77
  self.open(options[:headers]) do |f|
81
- html_parse_plugins = Murlsh::Plugin.hooks('html_parse')
82
- @doc = if html_parse_plugins.empty?
83
- Nokogiri(f).extend(Murlsh::Doc)
84
- else
85
- html_parse_plugins.first.run(f).extend(Murlsh::Doc)
78
+ data = f.read
79
+ @doc = Nokogiri(data, to_s)
80
+ # encoding unknown, reparse with f.charset, default to utf-8
81
+ unless @doc.encoding
82
+ @doc = Nokogiri(data, to_s, f.charset || 'utf-8')
86
83
  end
87
-
88
- @charset = @doc.charset || f.charset
84
+ @doc.extend(Murlsh::Doc)
89
85
  end
90
86
  end
91
87
  end
@@ -106,15 +102,15 @@ module Murlsh
106
102
  result
107
103
  end
108
104
 
109
- HtmlContentTypePattern = %r{^text/html}i
105
+ HtmlContentTypeRe = %r{^text/html|application/xhtml\+xml}
110
106
 
111
107
  # Return true if the content type is HTML.
112
- def html?(options={}); content_type(options)[HtmlContentTypePattern]; end
108
+ def html?(options={}); content_type(options)[HtmlContentTypeRe]; end
113
109
 
114
110
  # Convert from the character set of this url to utf-8 and decode HTML
115
111
  # entities.
116
112
  def decode(s)
117
- HTMLEntities.new.decode(Iconv.conv('utf-8', @charset, s))
113
+ HTMLEntities.new.decode(Iconv.conv('utf-8', doc.encoding, s))
118
114
  end
119
115
 
120
116
  # Get the value of a response header.
@@ -44,11 +44,9 @@ module Murlsh
44
44
  @body = html(:lang => 'en') {
45
45
  headd
46
46
  body {
47
+ self.p(:id => 'menu') { home_link ; text! ' | ' ; feed_link }
47
48
  search_form
48
- self.p {
49
- predefined_searches
50
- feed_link
51
- }
49
+ quick_search
52
50
  ul(:id => 'urls') {
53
51
  last = nil
54
52
 
@@ -105,21 +103,15 @@ module Murlsh
105
103
  css(@config['css_compressed'] || @config['css_files'])
106
104
  atom @config.fetch('feed_file')
107
105
  link :rel => 'first', :href => page_href(1)
108
- link :rel => 'prev', :href => @prev_href if @prev_href
109
- link :rel => 'next', :href => @next_href if @next_href
106
+ if p_href = prev_href
107
+ link :rel => 'prev', :href => p_href
108
+ end
109
+ if n_href = next_href
110
+ link :rel => 'next', :href => n_href
111
+ end
110
112
  }
111
113
  end
112
114
 
113
- # Predefined search list builder.
114
- def predefined_searches
115
- if @config['predefined_searches']
116
- text! 'search: '
117
- @config['predefined_searches'].each do |k,v|
118
- a "/#{k}", :href => "?q=#{URI.escape(v)}" ; text! ' '
119
- end
120
- text! '| '
121
- end
122
- end
123
115
 
124
116
  # Title builder.
125
117
  def titlee
@@ -127,9 +119,31 @@ module Murlsh
127
119
  (@req['q'] ? " /#{@req['q']}" : ''))
128
120
  end
129
121
 
122
+ # Home link builder.
123
+ def home_link; a 'Home', :href => @config.fetch('root_url'); end
124
+
130
125
  # Feed link builder.
131
126
  def feed_link
132
- a('feed', :href => @config.fetch('feed_file'), :class => 'feed')
127
+ a 'Feed', :href => @config.fetch('feed_file'), :class => 'feed'
128
+ end
129
+
130
+ # Quick search list builder.
131
+ def quick_search
132
+ if @config['quick_search']
133
+ self.p {
134
+ text! 'Quick search: '
135
+ # can specify keys to be sorted first in quick_search_order config
136
+ # key, those keys will be first in given order, any keys not there
137
+ # will follow in natural sorted order
138
+ order = @config['quick_search_order'] || []
139
+ order += (@config['quick_search'].keys - order).sort
140
+ order.each do |k|
141
+ if v = @config['quick_search'][k]
142
+ a "/#{k}", :href => "?q=#{URI.escape(v)}" ; text! ' '
143
+ end
144
+ end
145
+ }
146
+ end
133
147
  end
134
148
 
135
149
  # Search form builder.
@@ -137,7 +151,7 @@ module Murlsh
137
151
  form(:action => '', :method => 'get') {
138
152
  fieldset {
139
153
  form_input :id => 'q', :size => 32, :value => @req['q']
140
- form_input :type => 'submit', :value => 'Regex Search'
154
+ form_input :type => 'submit', :value => 'Search'
141
155
  }
142
156
  }
143
157
  end
@@ -176,7 +190,7 @@ module Murlsh
176
190
  # Powered by builder.
177
191
  def powered_by
178
192
  self.p {
179
- text! 'powered by '
193
+ text! 'Powered by '
180
194
  a 'murlsh', :href => 'http://github.com/mmb/murlsh/'
181
195
  }
182
196
  end
@@ -22,9 +22,19 @@ module Murlsh
22
22
  :limit => per_page, :offset => offset)
23
23
  end
24
24
 
25
- def prev_page; @prev_page ||= page - 1 if (2..total_pages) === page; end
25
+ def prev_page
26
+ unless instance_variable_defined? :@prev_page
27
+ @prev_page = page - 1 if (2..total_pages) === page
28
+ end
29
+ @prev_page
30
+ end
26
31
 
27
- def next_page; @next_page ||= page + 1 if page < total_pages; end
32
+ def next_page
33
+ unless instance_variable_defined? :@next_page
34
+ @next_page = page + 1 if page < total_pages
35
+ end
36
+ @next_page
37
+ end
28
38
 
29
39
  attr_reader :conditions
30
40
  attr_reader :page
data/lib/murlsh.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  require 'murlsh/head_from_get'
2
2
  require 'murlsh/search_conditions'
3
3
 
4
+ require 'murlsh/ask'
4
5
  require 'murlsh/auth'
5
6
  require 'murlsh/build_md5'
6
7
  require 'murlsh/build_query'
8
+ require 'murlsh/cp_r_safe'
7
9
  require 'murlsh/delicious_parse'
8
10
  require 'murlsh/dispatch'
9
11
  require 'murlsh/doc'
@@ -12,6 +14,7 @@ require 'murlsh/failproof'
12
14
  require 'murlsh/far_future_expires'
13
15
  require 'murlsh/image_list'
14
16
  require 'murlsh/img_store'
17
+ require 'murlsh/install'
15
18
  require 'murlsh/json_body'
16
19
  require 'murlsh/json_server'
17
20
  require 'murlsh/jsonp_body'
@@ -19,7 +22,7 @@ require 'murlsh/markup'
19
22
  require 'murlsh/must_revalidate'
20
23
  require 'murlsh/openlock'
21
24
  require 'murlsh/plugin'
22
- require 'murlsh/sqlite3_adapter'
25
+ require 'murlsh/search_grammar'
23
26
  require 'murlsh/time_ago'
24
27
  require 'murlsh/uri_ask'
25
28
  require 'murlsh/uri_domain'
data/murlsh.gemspec CHANGED
@@ -5,13 +5,13 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{murlsh}
8
- s.version = "1.3.1"
8
+ s.version = "1.4.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{2011-01-15}
12
+ s.date = %q{2011-01-31}
13
13
  s.default_executable = %q{murlsh}
14
- s.description = %q{url sharing site framework with easy adding, title lookup, atom feed, thumbnails and embedding}
14
+ s.description = %q{Host your bookmarks or maintain a link blog}
15
15
  s.email = %q{matthewm@boedicker.org}
16
16
  s.executables = ["murlsh"]
17
17
  s.extra_rdoc_files = [
@@ -27,9 +27,11 @@ Gem::Specification.new do |s|
27
27
  "config.ru",
28
28
  "config.yaml",
29
29
  "lib/murlsh.rb",
30
+ "lib/murlsh/ask.rb",
30
31
  "lib/murlsh/auth.rb",
31
32
  "lib/murlsh/build_md5.rb",
32
33
  "lib/murlsh/build_query.rb",
34
+ "lib/murlsh/cp_r_safe.rb",
33
35
  "lib/murlsh/delicious_parse.rb",
34
36
  "lib/murlsh/dispatch.rb",
35
37
  "lib/murlsh/doc.rb",
@@ -39,6 +41,7 @@ Gem::Specification.new do |s|
39
41
  "lib/murlsh/head_from_get.rb",
40
42
  "lib/murlsh/image_list.rb",
41
43
  "lib/murlsh/img_store.rb",
44
+ "lib/murlsh/install.rb",
42
45
  "lib/murlsh/json_body.rb",
43
46
  "lib/murlsh/json_server.rb",
44
47
  "lib/murlsh/jsonp_body.rb",
@@ -47,7 +50,8 @@ Gem::Specification.new do |s|
47
50
  "lib/murlsh/openlock.rb",
48
51
  "lib/murlsh/plugin.rb",
49
52
  "lib/murlsh/search_conditions.rb",
50
- "lib/murlsh/sqlite3_adapter.rb",
53
+ "lib/murlsh/search_grammar.rb",
54
+ "lib/murlsh/search_grammar.treetop",
51
55
  "lib/murlsh/time_ago.rb",
52
56
  "lib/murlsh/uri_ask.rb",
53
57
  "lib/murlsh/uri_domain.rb",
@@ -59,26 +63,25 @@ Gem::Specification.new do |s|
59
63
  "lib/murlsh/yaml_ordered_hash.rb",
60
64
  "murlsh.gemspec",
61
65
  "plugins/add_post_50_update_feed.rb",
66
+ "plugins/add_post_50_update_m3u.rb",
62
67
  "plugins/add_post_50_update_podcast.rb",
63
68
  "plugins/add_post_50_update_rss.rb",
64
69
  "plugins/add_post_60_notify_hubs.rb",
70
+ "plugins/add_pre_30_unajax_twitter.rb",
71
+ "plugins/add_pre_35_url_clean.rb",
65
72
  "plugins/add_pre_40_convert_mobile.rb",
66
- "plugins/add_pre_41_unajax_twitter.rb",
67
73
  "plugins/add_pre_45_supplied_thumbnail.rb",
68
74
  "plugins/add_pre_50_lookup_content_type_title.rb",
69
75
  "plugins/add_pre_50_media_thumbnail.rb",
70
76
  "plugins/add_pre_50_open_graph_image.rb",
71
- "plugins/add_pre_60_flickr.rb",
72
77
  "plugins/add_pre_60_github_title.rb",
73
78
  "plugins/add_pre_60_google_code_title.rb",
74
79
  "plugins/add_pre_60_imgur.rb",
75
80
  "plugins/add_pre_60_s3_image.rb",
76
81
  "plugins/add_pre_60_twitter.rb",
77
- "plugins/add_pre_60_vimeo.rb",
78
82
  "plugins/add_pre_65_html_thumb.rb",
79
83
  "plugins/add_pre_65_img_thumb.rb",
80
84
  "plugins/avatar_50_gravatar.rb",
81
- "plugins/html_parse_50_nokogiri.rb",
82
85
  "plugins/url_display_add_45_audio.rb",
83
86
  "plugins/url_display_add_50_hostrec.rb",
84
87
  "plugins/url_display_add_55_content_type.rb",
@@ -87,11 +90,10 @@ Gem::Specification.new do |s|
87
90
  "public/css/jquery.jgrowl.css",
88
91
  "public/css/screen.css",
89
92
  "public/img/thumb/.gitignore",
90
- "public/js/comments.json",
91
- "public/js/jquery-1.4.4.min.js",
93
+ "public/js/jquery-1.5.min.js",
92
94
  "public/js/jquery.jgrowl_compressed.js",
93
95
  "public/js/js.js",
94
- "public/js/twitter-text-1.0.4.js",
96
+ "public/js/twitter-text-1.3.1.js",
95
97
  "spec/auth_spec.rb",
96
98
  "spec/dispatch_spec.rb",
97
99
  "spec/doc_spec.rb",
@@ -105,7 +107,7 @@ Gem::Specification.new do |s|
105
107
  s.homepage = %q{http://github.com/mmb/murlsh}
106
108
  s.require_paths = ["lib"]
107
109
  s.rubygems_version = %q{1.4.2}
108
- s.summary = %q{url sharing site framework}
110
+ s.summary = %q{Host your bookmarks or maintain a link blog}
109
111
  s.test_files = [
110
112
  "spec/auth_spec.rb",
111
113
  "spec/dispatch_spec.rb",
@@ -125,11 +127,11 @@ Gem::Specification.new do |s|
125
127
  s.add_runtime_dependency(%q<activerecord>, [">= 2.3.4"])
126
128
  s.add_runtime_dependency(%q<bcrypt-ruby>, [">= 2.1.2"])
127
129
  s.add_runtime_dependency(%q<builder>, [">= 2.1.2"])
128
- s.add_runtime_dependency(%q<flickraw>, [">= 0.8.3"])
129
130
  s.add_runtime_dependency(%q<htmlentities>, [">= 4.2.0"])
130
131
  s.add_runtime_dependency(%q<json>, [">= 1.2.3"])
131
132
  s.add_runtime_dependency(%q<nokogiri>, ["~> 1.0"])
132
133
  s.add_runtime_dependency(%q<plumnailer>, [">= 0.1.0"])
134
+ s.add_runtime_dependency(%q<postrank-uri>, ["~> 1.0"])
133
135
  s.add_runtime_dependency(%q<public_suffix_service>, ["~> 0.0"])
134
136
  s.add_runtime_dependency(%q<push-notify>, [">= 0.1.0"])
135
137
  s.add_runtime_dependency(%q<rack>, [">= 1.0.0"])
@@ -137,10 +139,11 @@ Gem::Specification.new do |s|
137
139
  s.add_runtime_dependency(%q<rack-rewrite>, [">= 1.0.2"])
138
140
  s.add_runtime_dependency(%q<rack-throttle>, [">= 0.3.0"])
139
141
  s.add_runtime_dependency(%q<rmagick>, [">= 1.15.14"])
140
- s.add_runtime_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
142
+ s.add_runtime_dependency(%q<sqlite3>, ["~> 1.3"])
141
143
  s.add_runtime_dependency(%q<tinyatom>, [">= 0.3.3"])
144
+ s.add_runtime_dependency(%q<treetop>, ["~> 1.4"])
142
145
  s.add_runtime_dependency(%q<twitter>, [">= 0.9.12"])
143
- s.add_runtime_dependency(%q<vimeo>, [">= 1.2.2"])
146
+ s.add_development_dependency(%q<fakeweb>, ["~> 1.3"])
144
147
  s.add_development_dependency(%q<flog>, [">= 2.5.0"])
145
148
  s.add_development_dependency(%q<rack-test>, ["~> 0.5"])
146
149
  s.add_development_dependency(%q<rspec>, ["~> 2.0"])
@@ -148,11 +151,11 @@ Gem::Specification.new do |s|
148
151
  s.add_dependency(%q<activerecord>, [">= 2.3.4"])
149
152
  s.add_dependency(%q<bcrypt-ruby>, [">= 2.1.2"])
150
153
  s.add_dependency(%q<builder>, [">= 2.1.2"])
151
- s.add_dependency(%q<flickraw>, [">= 0.8.3"])
152
154
  s.add_dependency(%q<htmlentities>, [">= 4.2.0"])
153
155
  s.add_dependency(%q<json>, [">= 1.2.3"])
154
156
  s.add_dependency(%q<nokogiri>, ["~> 1.0"])
155
157
  s.add_dependency(%q<plumnailer>, [">= 0.1.0"])
158
+ s.add_dependency(%q<postrank-uri>, ["~> 1.0"])
156
159
  s.add_dependency(%q<public_suffix_service>, ["~> 0.0"])
157
160
  s.add_dependency(%q<push-notify>, [">= 0.1.0"])
158
161
  s.add_dependency(%q<rack>, [">= 1.0.0"])
@@ -160,10 +163,11 @@ Gem::Specification.new do |s|
160
163
  s.add_dependency(%q<rack-rewrite>, [">= 1.0.2"])
161
164
  s.add_dependency(%q<rack-throttle>, [">= 0.3.0"])
162
165
  s.add_dependency(%q<rmagick>, [">= 1.15.14"])
163
- s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
166
+ s.add_dependency(%q<sqlite3>, ["~> 1.3"])
164
167
  s.add_dependency(%q<tinyatom>, [">= 0.3.3"])
168
+ s.add_dependency(%q<treetop>, ["~> 1.4"])
165
169
  s.add_dependency(%q<twitter>, [">= 0.9.12"])
166
- s.add_dependency(%q<vimeo>, [">= 1.2.2"])
170
+ s.add_dependency(%q<fakeweb>, ["~> 1.3"])
167
171
  s.add_dependency(%q<flog>, [">= 2.5.0"])
168
172
  s.add_dependency(%q<rack-test>, ["~> 0.5"])
169
173
  s.add_dependency(%q<rspec>, ["~> 2.0"])
@@ -172,11 +176,11 @@ Gem::Specification.new do |s|
172
176
  s.add_dependency(%q<activerecord>, [">= 2.3.4"])
173
177
  s.add_dependency(%q<bcrypt-ruby>, [">= 2.1.2"])
174
178
  s.add_dependency(%q<builder>, [">= 2.1.2"])
175
- s.add_dependency(%q<flickraw>, [">= 0.8.3"])
176
179
  s.add_dependency(%q<htmlentities>, [">= 4.2.0"])
177
180
  s.add_dependency(%q<json>, [">= 1.2.3"])
178
181
  s.add_dependency(%q<nokogiri>, ["~> 1.0"])
179
182
  s.add_dependency(%q<plumnailer>, [">= 0.1.0"])
183
+ s.add_dependency(%q<postrank-uri>, ["~> 1.0"])
180
184
  s.add_dependency(%q<public_suffix_service>, ["~> 0.0"])
181
185
  s.add_dependency(%q<push-notify>, [">= 0.1.0"])
182
186
  s.add_dependency(%q<rack>, [">= 1.0.0"])
@@ -184,10 +188,11 @@ Gem::Specification.new do |s|
184
188
  s.add_dependency(%q<rack-rewrite>, [">= 1.0.2"])
185
189
  s.add_dependency(%q<rack-throttle>, [">= 0.3.0"])
186
190
  s.add_dependency(%q<rmagick>, [">= 1.15.14"])
187
- s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
191
+ s.add_dependency(%q<sqlite3>, ["~> 1.3"])
188
192
  s.add_dependency(%q<tinyatom>, [">= 0.3.3"])
193
+ s.add_dependency(%q<treetop>, ["~> 1.4"])
189
194
  s.add_dependency(%q<twitter>, [">= 0.9.12"])
190
- s.add_dependency(%q<vimeo>, [">= 1.2.2"])
195
+ s.add_dependency(%q<fakeweb>, ["~> 1.3"])
191
196
  s.add_dependency(%q<flog>, [">= 2.5.0"])
192
197
  s.add_dependency(%q<rack-test>, ["~> 0.5"])
193
198
  s.add_dependency(%q<rspec>, ["~> 2.0"])
@@ -0,0 +1,35 @@
1
+ require 'murlsh'
2
+
3
+ module Murlsh
4
+
5
+ # Regenerate m3u file after a new audio url has been added.
6
+ class AddPost50UpdateM3u < Plugin
7
+
8
+ @hook = 'add_post'
9
+
10
+ AudioContentTypes = %w{
11
+ application/ogg
12
+ audio/mpeg
13
+ audio/ogg
14
+ }
15
+
16
+ OutputFile = 'm3u.m3u'
17
+
18
+ def self.run(url, config)
19
+ if AudioContentTypes.include?(url.content_type) or
20
+ not File.exists?(OutputFile)
21
+
22
+ Murlsh::openlock(OutputFile, 'w') do |f|
23
+ f.write "# #{config['root_url']}\r\n\r\n"
24
+ Murlsh::Url.all(:conditions =>
25
+ ["content_type IN (?)", AudioContentTypes],
26
+ :order => 'time DESC').each do |mu|
27
+ f.write "#{mu.url}\r\n"
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -3,7 +3,7 @@ require 'murlsh'
3
3
  module Murlsh
4
4
 
5
5
  # Convert Ajax friendly Twitter urls (with #!) into usable urls.
6
- class AddPre41UnajaxTwitter < Plugin
6
+ class AddPre30UnajaxTwitter < Plugin
7
7
 
8
8
  @hook = 'add_pre'
9
9
 
@@ -0,0 +1,21 @@
1
+ require 'postrank-uri'
2
+
3
+ require 'murlsh'
4
+
5
+ module Murlsh
6
+
7
+ # Canonicalize and clean urls with postrank-uri.
8
+ #
9
+ # See https://github.com/postrank-labs/postrank-uri
10
+ class AddPre35UrlClean < Plugin
11
+
12
+ @hook = 'add_pre'
13
+
14
+ def self.run(url, config)
15
+ url.url = PostRank::URI.clean(url.url)
16
+ url.via = PostRank::URI.clean(url.via) if url.via
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -4,7 +4,7 @@ require 'murlsh'
4
4
 
5
5
  module Murlsh
6
6
 
7
- # If document has <meta rel="media:thumbnail"> use it as the thumbnail.
7
+ # If document has meta or link media:thumbnail use it as the thumbnail.
8
8
  class AddPre50MediaThumbnail < Plugin
9
9
 
10
10
  @hook = 'add_pre'
@@ -14,8 +14,11 @@ module Murlsh
14
14
 
15
15
  def self.run(url, config)
16
16
  if not url.thumbnail_url and url.ask.doc
17
- url.ask.doc.xpath_search("//meta[@rel='media:thumbnail']") do |node|
18
- if node and node['href'] and not node['href'].empty?
17
+ url.ask.doc.xpath_search(%w{
18
+ //meta[@rel='media:thumbnail']
19
+ //link[@rel='media:thumbnail']
20
+ }) do |node|
21
+ if node and not node['href'].to_s.empty?
19
22
  Murlsh::failproof do
20
23
  thumb_storage = Murlsh::ImgStore.new(StorageDir,
21
24
  :user_agent => config['user_agent'])
@@ -14,11 +14,9 @@ module Murlsh
14
14
  StorageDir = File.join(File.dirname(__FILE__), '..', 'public', 'img',
15
15
  'thumb')
16
16
 
17
- MarkupContentTypeRe = %r{^text/html|application/xhtml\+xml}
18
-
19
17
  def self.run(url, config)
20
18
  if not url.thumbnail_url and url.content_type and
21
- url.content_type[MarkupContentTypeRe]
19
+ url.content_type[Murlsh::UriAsk::HtmlContentTypeRe]
22
20
  Murlsh::failproof do
23
21
  chooser = Plumnailer::Chooser.new
24
22
  choice = chooser.choose(url.url)
@@ -9,12 +9,13 @@ module Murlsh
9
9
 
10
10
  @hook = 'url_display_add'
11
11
 
12
- HttpRe = %r{^http://}i
12
+ HttpRe = %r{^https?://}i
13
13
  HackerNewsRe = %r{^news\.ycombinator\.com}i
14
14
  RedditRe = %r{^www\.reddit\.com/r/([a-z\d]+?)/}i
15
15
  DeliciousRe = %r{^(?:www\.)?delicious\.com/(\w+)}i
16
16
  TwitterRe = %r{^twitter\.com/(\w+)}i
17
17
  TumblrRe = %r{^([a-z\d][a-z\d-]{0,61}[a-z\d])\.tumblr\.com/}i
18
+ PinboardRe = %r{^pinboard\.in/(popular|[tu]:[^/]+(?:/t:[^/]+)?)/?$}i
18
19
 
19
20
  # Show a via link for the url.
20
21
  def self.run(markup, url, config)
@@ -29,6 +30,7 @@ module Murlsh
29
30
  when m = search.match(DeliciousRe); "delicious/#{m[1]}"
30
31
  when m = search.match(TwitterRe); "twitter/#{m[1]}"
31
32
  when m = search.match(TumblrRe); "#{m[1]}.tumblr"
33
+ when m = search.match(PinboardRe); "pinboard/#{m[1]}"
32
34
  else via_uri.extend(Murlsh::URIDomain).domain || via_uri_s
33
35
  end
34
36
 
@@ -43,3 +45,4 @@ module Murlsh
43
45
  end
44
46
 
45
47
  end
48
+
@@ -40,31 +40,35 @@ div.ie6.center {
40
40
  }
41
41
 
42
42
  /** Normal Style Positions **/
43
+ div.jGrowl {
44
+ position: absolute;
45
+ }
46
+
43
47
  body > div.jGrowl {
44
48
  position: fixed;
45
49
  }
46
50
 
47
- body > div.jGrowl.top-left {
51
+ div.jGrowl.top-left {
48
52
  left: 0px;
49
53
  top: 0px;
50
54
  }
51
55
 
52
- body > div.jGrowl.top-right {
56
+ div.jGrowl.top-right {
53
57
  right: 0px;
54
58
  top: 0px;
55
59
  }
56
60
 
57
- body > div.jGrowl.bottom-left {
61
+ div.jGrowl.bottom-left {
58
62
  left: 0px;
59
63
  bottom: 0px;
60
64
  }
61
65
 
62
- body > div.jGrowl.bottom-right {
66
+ div.jGrowl.bottom-right {
63
67
  right: 0px;
64
68
  bottom: 0px;
65
69
  }
66
70
 
67
- body > div.jGrowl.center {
71
+ div.jGrowl.center {
68
72
  top: 0px;
69
73
  width: 50%;
70
74
  left: 25%;
@@ -95,12 +99,12 @@ div.jGrowl div.jGrowl-notification {
95
99
  min-height: 40px;
96
100
  }
97
101
 
98
- div.jGrowl div.jGrowl-notification div.header {
102
+ div.jGrowl div.jGrowl-notification div.jGrowl-header {
99
103
  font-weight: bold;
100
104
  font-size: .85em;
101
105
  }
102
106
 
103
- div.jGrowl div.jGrowl-notification div.close {
107
+ div.jGrowl div.jGrowl-notification div.jGrowl-close {
104
108
  z-index: 99;
105
109
  float: right;
106
110
  font-weight: bold;
@@ -1,4 +1,5 @@
1
1
  body {
2
+ color : #333;
2
3
  font-size : 1em;
3
4
  line-height : 1.5em;
4
5
  }
@@ -9,7 +10,7 @@ img {
9
10
 
10
11
  #urls {
11
12
  list-style-type : none;
12
- width : 600px;
13
+ width : 50%;
13
14
  }
14
15
 
15
16
  ul.comments {
@@ -29,7 +30,7 @@ div.icon {
29
30
  }
30
31
 
31
32
  a:link {
32
- color : #000;
33
+ color : #333;
33
34
  }
34
35
 
35
36
  a:visited {