murlsh 1.8.0 → 1.9.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/ChangeLog +17 -0
- data/db/migrate/20110906003222_create_enclosures.rb +32 -0
- data/lib/murlsh/atom_body.rb +11 -9
- data/lib/murlsh/enclosure.rb +14 -0
- data/lib/murlsh/feed_body.rb +0 -9
- data/lib/murlsh/json_body.rb +6 -0
- data/lib/murlsh/markup.rb +3 -3
- data/lib/murlsh/rss_body.rb +5 -4
- data/lib/murlsh/uri_ask.rb +1 -1
- data/lib/murlsh/url.rb +2 -1
- data/lib/murlsh/url_body.rb +11 -14
- data/lib/murlsh/version.rb +1 -1
- data/lib/murlsh.rb +1 -0
- data/plugins/add_pre_35_url_clean.rb +33 -10
- data/plugins/add_pre_55_enclosure_self.rb +31 -0
- data/plugins/add_pre_55_enclosure_vimeo.rb +24 -0
- data/plugins/add_pre_55_enclosure_youtube.rb +24 -0
- metadata +9 -4
data/ChangeLog
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
1.9.0
|
|
2
|
+
2011-09-25
|
|
3
|
+
|
|
4
|
+
Do not strip trailing slashes from urls during normalization.
|
|
5
|
+
|
|
6
|
+
Add enclosures to JSON.
|
|
7
|
+
|
|
8
|
+
Support multiple enclosures per url that can be set by plugins.
|
|
9
|
+
|
|
10
|
+
Plugins for adding enclosures for YouTube and Vimeo urls.
|
|
11
|
+
|
|
12
|
+
Support builder version 3.
|
|
13
|
+
|
|
14
|
+
Update user agent sent when asking about urls to more recent browser.
|
|
15
|
+
|
|
16
|
+
Use "required" instead of "optional" attribute for form inputs.
|
|
17
|
+
|
|
1
18
|
1.8.0
|
|
2
19
|
2011-06-22
|
|
3
20
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'murlsh'
|
|
2
|
+
|
|
3
|
+
class CreateEnclosures < ActiveRecord::Migration
|
|
4
|
+
|
|
5
|
+
def self.up
|
|
6
|
+
create_table :enclosures do |t|
|
|
7
|
+
t.integer :content_length
|
|
8
|
+
t.string :content_type
|
|
9
|
+
t.string :title
|
|
10
|
+
t.string :enclosure_url
|
|
11
|
+
|
|
12
|
+
t.references :url
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
add_index :enclosures, :url_id
|
|
16
|
+
|
|
17
|
+
# populate
|
|
18
|
+
require './plugins/add_pre_55_enclosure_self.rb'
|
|
19
|
+
require './plugins/add_pre_55_enclosure_vimeo.rb'
|
|
20
|
+
require './plugins/add_pre_55_enclosure_youtube.rb'
|
|
21
|
+
|
|
22
|
+
Murlsh::Url.find(:all).each do |u|
|
|
23
|
+
Murlsh::Plugin.hooks('add_pre') { |p| p.run u, {} }
|
|
24
|
+
u.save!
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.down
|
|
29
|
+
drop_table :enclosures
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
data/lib/murlsh/atom_body.rb
CHANGED
|
@@ -29,15 +29,17 @@ module Murlsh
|
|
|
29
29
|
:summary => mu.title_stripped
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
:enclosure_href =>
|
|
36
|
-
:enclosure_title =>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
options[:enclosures] = []
|
|
33
|
+
mu.enclosures.each do |e|
|
|
34
|
+
new_e = {
|
|
35
|
+
:enclosure_href => e.enclosure_url,
|
|
36
|
+
:enclosure_title => e.title_stripped,
|
|
37
|
+
:enclosure_type => e.content_type
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
new_e[:enclosure_length] = e.content_length if e.content_length
|
|
41
|
+
|
|
42
|
+
options[:enclosures] << new_e
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
if mu.thumbnail_url
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
|
|
3
|
+
module Murlsh
|
|
4
|
+
|
|
5
|
+
# Enclosure ActiveRecord.
|
|
6
|
+
class Enclosure < ActiveRecord::Base
|
|
7
|
+
belongs_to :url
|
|
8
|
+
|
|
9
|
+
# Title with whitespace compressed and leading and trailing whitespace
|
|
10
|
+
# stripped.
|
|
11
|
+
def title_stripped; title.to_s.strip.gsub(/\s+/, ' '); end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
data/lib/murlsh/feed_body.rb
CHANGED
|
@@ -3,15 +3,6 @@ module Murlsh
|
|
|
3
3
|
# Feed body mixin.
|
|
4
4
|
module FeedBody
|
|
5
5
|
|
|
6
|
-
# Content types to add an enclosure for.
|
|
7
|
-
EnclosureContentTypes = %w{
|
|
8
|
-
application/pdf
|
|
9
|
-
audio/mpeg
|
|
10
|
-
image/gif
|
|
11
|
-
image/jpeg
|
|
12
|
-
image/png
|
|
13
|
-
}
|
|
14
|
-
|
|
15
6
|
def initialize(config, req, feed_url, urls)
|
|
16
7
|
@config, @req, @feed_url, @urls = config, req, feed_url, urls
|
|
17
8
|
@updated = nil
|
data/lib/murlsh/json_body.rb
CHANGED
data/lib/murlsh/markup.rb
CHANGED
|
@@ -8,7 +8,7 @@ module Murlsh
|
|
|
8
8
|
# Options:
|
|
9
9
|
# * :prefix - prefix to append to all script urls
|
|
10
10
|
def javascript(sources, options={})
|
|
11
|
-
Array(sources).each do |src|
|
|
11
|
+
::Kernel::Array(sources).each do |src|
|
|
12
12
|
script '', :type => 'text/javascript',
|
|
13
13
|
:src => "#{options[:prefix]}#{src}"
|
|
14
14
|
end
|
|
@@ -50,7 +50,7 @@ module Murlsh
|
|
|
50
50
|
# * :media - optional media attribute
|
|
51
51
|
# * :prefix - prepended to all CSS urls
|
|
52
52
|
def css(hrefs, options={})
|
|
53
|
-
Array(hrefs).each do |href|
|
|
53
|
+
::Kernel::Array(hrefs).each do |href|
|
|
54
54
|
attrs = {
|
|
55
55
|
:href => "#{options[:prefix]}#{href}",
|
|
56
56
|
:rel => 'stylesheet',
|
|
@@ -69,7 +69,7 @@ module Murlsh
|
|
|
69
69
|
def form_input(options)
|
|
70
70
|
if options[:id]
|
|
71
71
|
if options[:label]
|
|
72
|
-
label_class = options[:
|
|
72
|
+
label_class = options[:required] ? 'required' : 'optional'
|
|
73
73
|
label options[:label], :for => options[:id], :class => label_class
|
|
74
74
|
end
|
|
75
75
|
options[:name] ||= options[:id]
|
data/lib/murlsh/rss_body.rb
CHANGED
|
@@ -29,11 +29,12 @@ module Murlsh
|
|
|
29
29
|
i.link = mu.url
|
|
30
30
|
i.date = mu.time
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
i.enclosure.url =
|
|
34
|
-
i.enclosure.type =
|
|
35
|
-
i.enclosure.length =
|
|
32
|
+
mu.enclosures.first(1).each do |e|
|
|
33
|
+
i.enclosure.url = e.enclosure_url
|
|
34
|
+
i.enclosure.type = e.content_type
|
|
35
|
+
i.enclosure.length = e.content_length
|
|
36
36
|
end
|
|
37
|
+
|
|
37
38
|
end
|
|
38
39
|
end
|
|
39
40
|
|
data/lib/murlsh/uri_ask.rb
CHANGED
|
@@ -93,7 +93,7 @@ module Murlsh
|
|
|
93
93
|
def default_headers
|
|
94
94
|
result = {
|
|
95
95
|
'User-Agent' =>
|
|
96
|
-
'Mozilla/5.0 (X11;
|
|
96
|
+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.126 Safari/535.1',
|
|
97
97
|
}
|
|
98
98
|
if host.to_s[/^www\.nytimes\.com/]
|
|
99
99
|
result['Referer'] = 'http://news.google.com/'
|
data/lib/murlsh/url.rb
CHANGED
|
@@ -6,6 +6,7 @@ module Murlsh
|
|
|
6
6
|
|
|
7
7
|
# URL ActiveRecord.
|
|
8
8
|
class Url < ActiveRecord::Base
|
|
9
|
+
has_many :enclosures
|
|
9
10
|
validates_format_of :url, :with => URI.regexp
|
|
10
11
|
|
|
11
12
|
# Get the title of this url.
|
|
@@ -21,7 +22,7 @@ module Murlsh
|
|
|
21
22
|
|
|
22
23
|
# Title with whitespace compressed and leading and trailing whitespace
|
|
23
24
|
# stripped.
|
|
24
|
-
def title_stripped; title.strip.gsub(/\s+/, ' '); end
|
|
25
|
+
def title_stripped; title.to_s.strip.gsub(/\s+/, ' '); end
|
|
25
26
|
|
|
26
27
|
# Return true if this url has the same author as another url.
|
|
27
28
|
def same_author?(other)
|
data/lib/murlsh/url_body.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Murlsh
|
|
|
5
5
|
|
|
6
6
|
# Url list page builder.
|
|
7
7
|
class UrlBody < Builder::XmlMarkup
|
|
8
|
-
include Murlsh::Markup
|
|
8
|
+
include ::Murlsh::Markup
|
|
9
9
|
|
|
10
10
|
def initialize(config, req, result_set, content_type='text/html')
|
|
11
11
|
@config, @req, @result_set, @content_type = config, req, result_set,
|
|
@@ -20,7 +20,7 @@ module Murlsh
|
|
|
20
20
|
if page.to_i >= 1
|
|
21
21
|
query = @req.params.dup
|
|
22
22
|
query['p'] = page
|
|
23
|
-
Murlsh.build_query(query)
|
|
23
|
+
::Murlsh.build_query(query)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -50,13 +50,13 @@ module Murlsh
|
|
|
50
50
|
last = nil
|
|
51
51
|
|
|
52
52
|
@result_set.results.each do |mu|
|
|
53
|
-
Murlsh::Plugin.hooks('url_display_pre') do |p|
|
|
53
|
+
::Murlsh::Plugin.hooks('url_display_pre') do |p|
|
|
54
54
|
p.run mu, @req, @config
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
li(:id => "liu#{mu.id}") {
|
|
58
58
|
unless mu.same_author?(last)
|
|
59
|
-
avatar_url = Murlsh::Plugin.hooks('avatar').inject(
|
|
59
|
+
avatar_url = ::Murlsh::Plugin.hooks('avatar').inject(
|
|
60
60
|
nil) do |url_so_far,plugin|
|
|
61
61
|
plugin.run url_so_far, mu, @config
|
|
62
62
|
end
|
|
@@ -74,7 +74,7 @@ module Murlsh
|
|
|
74
74
|
|
|
75
75
|
a mu.title_stripped, :href => mu.url, :class => 'm'
|
|
76
76
|
|
|
77
|
-
Murlsh::Plugin.hooks('url_display_add') do |p|
|
|
77
|
+
::Murlsh::Plugin.hooks('url_display_add') do |p|
|
|
78
78
|
p.run self, mu, @config
|
|
79
79
|
end
|
|
80
80
|
|
|
@@ -154,7 +154,7 @@ module Murlsh
|
|
|
154
154
|
order += (@config['quick_search'].keys - order).sort
|
|
155
155
|
order.each do |k|
|
|
156
156
|
if v = @config['quick_search'][k]
|
|
157
|
-
a "/#{k}", :href => "?q=#{URI.escape(v)}" ; text! ' '
|
|
157
|
+
a "/#{k}", :href => "?q=#{::URI.escape(v)}" ; text! ' '
|
|
158
158
|
end
|
|
159
159
|
end
|
|
160
160
|
}
|
|
@@ -188,18 +188,15 @@ module Murlsh
|
|
|
188
188
|
def add_form
|
|
189
189
|
form(:action => 'url', :method => 'post') {
|
|
190
190
|
fieldset(:id => 'add') {
|
|
191
|
-
self.p { form_input :id => 'url', :label => 'Add URL', :size => 32 }
|
|
192
191
|
self.p {
|
|
193
|
-
form_input :id => '
|
|
194
|
-
:
|
|
195
|
-
}
|
|
196
|
-
self.p {
|
|
197
|
-
form_input :id => 'via', :label => 'Via', :size => 32,
|
|
198
|
-
:optional => true
|
|
192
|
+
form_input :id => 'url', :label => 'Add URL', :size => 32,
|
|
193
|
+
:required => ''
|
|
199
194
|
}
|
|
195
|
+
self.p { form_input :id => 'title', :label => 'Title', :size => 32 }
|
|
196
|
+
self.p { form_input :id => 'via', :label => 'Via', :size => 32 }
|
|
200
197
|
self.p {
|
|
201
198
|
form_input :type => 'password', :id => 'auth', :label => 'Password',
|
|
202
|
-
:size => 16
|
|
199
|
+
:size => 16, :required => ''
|
|
203
200
|
form_input :id => 'submit', :type => 'button', :value => 'Add'
|
|
204
201
|
}
|
|
205
202
|
}
|
data/lib/murlsh/version.rb
CHANGED
data/lib/murlsh.rb
CHANGED
|
@@ -4,26 +4,49 @@ require 'postrank-uri'
|
|
|
4
4
|
|
|
5
5
|
require 'murlsh'
|
|
6
6
|
|
|
7
|
+
# Patch PostRank::URI.normalize to not strip trailing slashes from the path.
|
|
8
|
+
module PostRank
|
|
9
|
+
|
|
10
|
+
module URI
|
|
11
|
+
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
def normalize(uri, opts = {})
|
|
15
|
+
u = parse(uri, opts)
|
|
16
|
+
u.path = u.path.squeeze('/')
|
|
17
|
+
# u.path = u.path.chomp('/') if u.path.size != 1
|
|
18
|
+
u.query = nil if u.query && u.query.empty?
|
|
19
|
+
u.fragment = nil
|
|
20
|
+
u
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
7
27
|
module Murlsh
|
|
8
28
|
|
|
9
|
-
# Canonicalize and clean urls
|
|
10
|
-
|
|
11
|
-
# See https://github.com/postrank-labs/postrank-uri
|
|
29
|
+
# Canonicalize and clean urls.
|
|
30
|
+
|
|
12
31
|
class AddPre35UrlClean < Plugin
|
|
13
32
|
|
|
14
33
|
@hook = 'add_pre'
|
|
15
34
|
|
|
16
35
|
def self.run(url, config)
|
|
17
|
-
url.url =
|
|
18
|
-
url.via =
|
|
36
|
+
Murlsh::failproof { url.url = clean(url.url) if cleanable?(url.url) }
|
|
37
|
+
Murlsh::failproof { url.via = clean(url.via) if cleanable?(url.via) }
|
|
19
38
|
end
|
|
20
39
|
|
|
21
|
-
#
|
|
40
|
+
# Canonicalize and clean a url using PostRank::URI.clean.
|
|
22
41
|
#
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
# PostRank::URI.normalize is patched to not strip trailing slashes from
|
|
43
|
+
# the path (see above).
|
|
44
|
+
#
|
|
45
|
+
# See https://github.com/postrank-labs/postrank-uri
|
|
46
|
+
def self.clean(url); PostRank::URI.clean(url); end
|
|
47
|
+
|
|
48
|
+
# Return true if the url can be cleaned (is http or https).
|
|
49
|
+
def self.cleanable?(url); URI(url).scheme.to_s.match(/^https?$/i); end
|
|
27
50
|
|
|
28
51
|
end
|
|
29
52
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'murlsh'
|
|
2
|
+
|
|
3
|
+
module Murlsh
|
|
4
|
+
|
|
5
|
+
# Create enclosures for content types that can directly become enclosures.
|
|
6
|
+
class AddPre55EnclosureSelf < Plugin
|
|
7
|
+
|
|
8
|
+
@hook = 'add_pre'
|
|
9
|
+
|
|
10
|
+
# Content types that can be enclosures.
|
|
11
|
+
ContentTypes = %w{
|
|
12
|
+
application/pdf
|
|
13
|
+
audio/mpeg
|
|
14
|
+
image/gif
|
|
15
|
+
image/jpeg
|
|
16
|
+
image/png
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def self.run(url, config)
|
|
20
|
+
if ContentTypes.include?(url.content_type)
|
|
21
|
+
url.enclosures.build(
|
|
22
|
+
:content_length => url.content_length,
|
|
23
|
+
:title => url.title,
|
|
24
|
+
:content_type => url.content_type,
|
|
25
|
+
:enclosure_url => url.url)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'murlsh'
|
|
2
|
+
|
|
3
|
+
module Murlsh
|
|
4
|
+
|
|
5
|
+
# Create video enclosures for Vimeo urls.
|
|
6
|
+
class AddPre55EnclosureVimeo < Plugin
|
|
7
|
+
|
|
8
|
+
@hook = 'add_pre'
|
|
9
|
+
|
|
10
|
+
VimeoRe = %r{^http://(?:www\.)?vimeo\.com/(\d+)$}i
|
|
11
|
+
|
|
12
|
+
def self.run(url, config)
|
|
13
|
+
if match = VimeoRe.match(url.url)
|
|
14
|
+
url.enclosures.build(
|
|
15
|
+
:title => url.title,
|
|
16
|
+
:content_type => 'application/x-shockwave-flash',
|
|
17
|
+
:enclosure_url =>
|
|
18
|
+
"http://vimeo.com/moogaloop.swf?clip_id=#{match[1]}")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'murlsh'
|
|
2
|
+
|
|
3
|
+
module Murlsh
|
|
4
|
+
|
|
5
|
+
# Create video enclosures for YouTube urls.
|
|
6
|
+
class AddPre55EnclosureYoutube < Plugin
|
|
7
|
+
|
|
8
|
+
@hook = 'add_pre'
|
|
9
|
+
|
|
10
|
+
YoutubeRe =
|
|
11
|
+
%r{^http://(?:(?:www|uk)\.)?youtube\.com/watch\?v=([\w\-]+)(?:&|$)}i
|
|
12
|
+
|
|
13
|
+
def self.run(url, config)
|
|
14
|
+
if match = YoutubeRe.match(url.url)
|
|
15
|
+
url.enclosures.build(
|
|
16
|
+
:title => url.title,
|
|
17
|
+
:content_type => 'application/x-shockwave-flash',
|
|
18
|
+
:enclosure_url => "http://www.youtube.com/v/#{match[1]}.swf")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: murlsh
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 51
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 1
|
|
8
|
-
-
|
|
8
|
+
- 9
|
|
9
9
|
- 0
|
|
10
|
-
version: 1.
|
|
10
|
+
version: 1.9.0
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Matthew M. Boedicker
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2011-
|
|
18
|
+
date: 2011-09-25 00:00:00 -04:00
|
|
19
19
|
default_executable:
|
|
20
20
|
dependencies:
|
|
21
21
|
- !ruby/object:Gem::Dependency
|
|
@@ -377,6 +377,7 @@ files:
|
|
|
377
377
|
- config.yaml
|
|
378
378
|
- config/README
|
|
379
379
|
- db/migrate/20110213023123_init.rb
|
|
380
|
+
- db/migrate/20110906003222_create_enclosures.rb
|
|
380
381
|
- lib/murlsh.rb
|
|
381
382
|
- lib/murlsh/ask.rb
|
|
382
383
|
- lib/murlsh/atom_body.rb
|
|
@@ -388,6 +389,7 @@ files:
|
|
|
388
389
|
- lib/murlsh/delicious_parse.rb
|
|
389
390
|
- lib/murlsh/dispatch.rb
|
|
390
391
|
- lib/murlsh/doc.rb
|
|
392
|
+
- lib/murlsh/enclosure.rb
|
|
391
393
|
- lib/murlsh/etag_add_encoding.rb
|
|
392
394
|
- lib/murlsh/failproof.rb
|
|
393
395
|
- lib/murlsh/far_future_expires.rb
|
|
@@ -433,6 +435,9 @@ files:
|
|
|
433
435
|
- plugins/add_pre_50_lookup_content_type_title.rb
|
|
434
436
|
- plugins/add_pre_50_media_thumbnail.rb
|
|
435
437
|
- plugins/add_pre_50_open_graph_image.rb
|
|
438
|
+
- plugins/add_pre_55_enclosure_self.rb
|
|
439
|
+
- plugins/add_pre_55_enclosure_vimeo.rb
|
|
440
|
+
- plugins/add_pre_55_enclosure_youtube.rb
|
|
436
441
|
- plugins/add_pre_55_open_graph_title.rb
|
|
437
442
|
- plugins/add_pre_60_github_title.rb
|
|
438
443
|
- plugins/add_pre_60_imgur.rb
|