murlsh 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +2 -0
- data/README.textile +28 -0
- data/Rakefile +11 -3
- data/config/README +2 -0
- data/config.ru +10 -1
- data/config.yaml +1 -1
- data/lib/murlsh/atom_server.rb +3 -9
- data/lib/murlsh/dispatch.rb +1 -0
- data/lib/murlsh/doc.rb +1 -1
- data/lib/murlsh/install.rb +1 -0
- data/lib/murlsh/json_server.rb +6 -19
- data/lib/murlsh/m3u_server.rb +5 -17
- data/lib/murlsh/markup.rb +12 -7
- data/lib/murlsh/must_revalidate.rb +1 -1
- data/lib/murlsh/podcast_server.rb +4 -15
- data/lib/murlsh/pop_server.rb +1 -5
- data/lib/murlsh/random_server.rb +7 -17
- data/lib/murlsh/rss_server.rb +3 -9
- data/lib/murlsh/search_conditions.rb +1 -1
- data/lib/murlsh/server.rb +11 -0
- data/lib/murlsh/uri_ask.rb +2 -2
- data/lib/murlsh/url_body.rb +9 -2
- data/lib/murlsh/url_result_set.rb +28 -3
- data/lib/murlsh/url_server.rb +2 -7
- data/lib/murlsh/version.rb +1 -1
- data/lib/murlsh.rb +1 -1
- data/murlsh.gemspec +1 -1
- data/plugins/add_pre_50_link_rel_image_src.rb +31 -0
- data/plugins/add_pre_50_media_thumbnail.rb +1 -1
- data/plugins/add_pre_50_open_graph_image.rb +1 -1
- data/plugins/add_pre_65_content_type_warn.rb +22 -0
- data/public/css/screen.css +9 -1
- data/public/js/jquery-1.5.1.min.js +16 -0
- data/public/js/js.js +26 -13
- data/spec/search_conditions_spec.rb +41 -0
- data/spec/search_grammar_spec.rb +33 -0
- data/spec/uri_ask_spec.rb +47 -18
- metadata +23 -17
- data/lib/murlsh/jsonp_body.rb +0 -17
- data/plugins/add_pre_60_google_code_title.rb +0 -28
- data/plugins/url_display_add_55_content_type.rb +0 -25
- data/public/js/jquery-1.5.min.js +0 -16
data/AUTHORS
ADDED
data/README.textile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
Host your bookmarks or maintain a link blog.
|
2
2
|
|
3
|
+
* post from a command-line, a bookmarklet, or directly from your murlsh
|
3
4
|
* fetches url titles and generates thumbnails from page
|
4
5
|
* jGrowls embedded versions of Imageshack, Imgur, Vimeo and YouTube urls
|
5
6
|
* converts Twitter status urls to their full text and adds user thumbnail
|
@@ -15,6 +16,7 @@ Host your bookmarks or maintain a link blog.
|
|
15
16
|
* Gravatar support
|
16
17
|
* generates import scripts from delicious api exports
|
17
18
|
* optionally store thumbnails in S3
|
19
|
+
* experimental support for posting by email via POP
|
18
20
|
|
19
21
|
See "http://urls.matthewm.boedicker.org/":http://urls.matthewm.boedicker.org/ for example.
|
20
22
|
|
@@ -94,6 +96,32 @@ the murlsh command again from your web directory to update plugins, javascript
|
|
94
96
|
and css. It will prompt before overwriting anything in case you have made
|
95
97
|
modifications.
|
96
98
|
|
99
|
+
h1. Posting
|
100
|
+
|
101
|
+
h2. Bookmarklet
|
102
|
+
|
103
|
+
<pre>
|
104
|
+
rake post_bookmarklet
|
105
|
+
</pre>
|
106
|
+
|
107
|
+
This will produce a bookmarklet link customized with your murlsh's URL
|
108
|
+
and your password. Create a link in your bookmarks toolbar with the
|
109
|
+
output; the resulting bookmarklet will let you post to your murlsh
|
110
|
+
from whatever page you're currently viewing.
|
111
|
+
|
112
|
+
If you select text on the page before hitting the bookmarklet, your
|
113
|
+
selection will be used as the title; otherwise, the page's title will
|
114
|
+
be used.
|
115
|
+
|
116
|
+
h2. Shell script
|
117
|
+
|
118
|
+
<pre>
|
119
|
+
rake post_sh
|
120
|
+
</pre>
|
121
|
+
|
122
|
+
will produce a customized shell script that will take command-line
|
123
|
+
arguments for URL, etc, and post to your murlsh using curl.
|
124
|
+
|
97
125
|
h1. API
|
98
126
|
|
99
127
|
h2. Recent urls
|
data/Rakefile
CHANGED
@@ -176,14 +176,22 @@ namespace :user do
|
|
176
176
|
|
177
177
|
end
|
178
178
|
|
179
|
-
desc 'Generate a
|
180
|
-
task :
|
179
|
+
desc 'Generate code for a bookmarklet that will post a new url.'
|
180
|
+
task :post_bookmarklet do
|
181
|
+
password = Murlsh.ask('Password:')
|
182
|
+
puts <<EOS
|
183
|
+
javascript:var%20d=document,dgs=d.getSelection,enc=encodeURIComponent,w=window,wgs=w.getSelection,s=''+(wgs?wgs():dgs?dgs():d.selection.createRange().text),t=s===''?d.title:s;void(window.open('#{config.fetch('root_url')}bookmarklet?title='+enc(t)+'&url='+enc(location.href)+'&auth=#{password}'));
|
184
|
+
EOS
|
185
|
+
end
|
186
|
+
|
187
|
+
desc 'Generate a shell script that will post a new url (saved password optional).'
|
188
|
+
task :post_sh, :password do |t,args|
|
181
189
|
puts <<EOS
|
182
190
|
#!/bin/sh
|
183
191
|
|
184
192
|
URL="$1"
|
185
193
|
VIA="$2"
|
186
|
-
AUTH="
|
194
|
+
AUTH="#{args.password || '$3'}"
|
187
195
|
|
188
196
|
curl \\
|
189
197
|
--data-urlencode "url=${URL}" \\
|
data/config/README
ADDED
data/config.ru
CHANGED
@@ -5,6 +5,7 @@ require 'yaml'
|
|
5
5
|
|
6
6
|
require 'rack'
|
7
7
|
require 'rack/cache'
|
8
|
+
require 'rack/contrib/jsonp'
|
8
9
|
require 'rack/rewrite'
|
9
10
|
require 'rack/throttle'
|
10
11
|
|
@@ -41,8 +42,16 @@ use Murlsh::FarFutureExpires, :patterns => [
|
|
41
42
|
]
|
42
43
|
|
43
44
|
feed_url = URI.join(config.fetch('root_url'), config.fetch('feed_file'))
|
44
|
-
use Murlsh::MustRevalidate, :patterns =>
|
45
|
+
use Murlsh::MustRevalidate, :patterns => [
|
46
|
+
%r{^#{Regexp.escape(feed_url.path)}$},
|
47
|
+
%r{^/(url)?$},
|
48
|
+
%r{^/json\.json$},
|
49
|
+
%r{^/m3u\.m3u$},
|
50
|
+
%r{^/podcast\.rss$},
|
51
|
+
%r{^/rss\.rss$},
|
52
|
+
]
|
45
53
|
|
54
|
+
use Rack::JSONP
|
46
55
|
use Rack::Static, :urls => %w{/css/ /img/ /js/}, :root => 'public'
|
47
56
|
|
48
57
|
use Rack::Rewrite do
|
data/config.yaml
CHANGED
data/lib/murlsh/atom_server.rb
CHANGED
@@ -7,24 +7,19 @@ require 'murlsh'
|
|
7
7
|
module Murlsh
|
8
8
|
|
9
9
|
# Serve Atom feed.
|
10
|
-
class AtomServer
|
11
|
-
|
12
|
-
def initialize(config); @config = config; end
|
10
|
+
class AtomServer < Server
|
13
11
|
|
14
12
|
# Respond to a GET request for Atom feed.
|
15
13
|
def get(req)
|
16
|
-
conditions = Murlsh::SearchConditions.new(req['q']).conditions
|
17
14
|
page = 1
|
18
15
|
per_page = config.fetch('num_posts_feed', 25)
|
19
16
|
|
20
|
-
result_set = Murlsh::UrlResultSet.new(
|
21
|
-
urls = result_set.results
|
17
|
+
result_set = Murlsh::UrlResultSet.new(req['q'], page, per_page)
|
22
18
|
|
23
19
|
feed_url = URI.join(config.fetch('root_url'), config.fetch('feed_file'))
|
24
|
-
body = Murlsh::AtomBody.new(config, req, feed_url,
|
20
|
+
body = Murlsh::AtomBody.new(config, req, feed_url, result_set.results)
|
25
21
|
|
26
22
|
resp = Rack::Response.new(body, 200,
|
27
|
-
'Cache-Control' => 'must-revalidate, max-age=0',
|
28
23
|
'Content-Type' => 'application/atom+xml')
|
29
24
|
if u = body.updated
|
30
25
|
resp['Last-Modified'] = u.httpdate
|
@@ -32,7 +27,6 @@ module Murlsh
|
|
32
27
|
resp
|
33
28
|
end
|
34
29
|
|
35
|
-
attr_reader :config
|
36
30
|
end
|
37
31
|
|
38
32
|
end
|
data/lib/murlsh/dispatch.rb
CHANGED
@@ -34,6 +34,7 @@ module Murlsh
|
|
34
34
|
[%r{^(?:HEAD|GET) #{root_path}random$}, random_server.method(:get)],
|
35
35
|
[%r{^(?:HEAD|GET) #{root_path}rss\.rss$}, rss_server.method(:get)],
|
36
36
|
[%r{^(?:HEAD|GET) #{root_path}(url)?$}, url_server.method(:get)],
|
37
|
+
[%r{^GET #{root_path}bookmarklet$}, url_server.method(:post)],
|
37
38
|
[%r{^POST #{root_path}(url)?$}, url_server.method(:post)],
|
38
39
|
]
|
39
40
|
|
data/lib/murlsh/doc.rb
CHANGED
@@ -6,7 +6,7 @@ module Murlsh
|
|
6
6
|
# Check a list of xpaths in order and yield and return the node matching
|
7
7
|
# the first one that is not nil
|
8
8
|
def xpath_search(xpaths)
|
9
|
-
|
9
|
+
Array(xpaths).each do |xpath|
|
10
10
|
selection = (self/xpath).first
|
11
11
|
if selection; return (yield selection); end
|
12
12
|
end
|
data/lib/murlsh/install.rb
CHANGED
data/lib/murlsh/json_server.rb
CHANGED
@@ -2,34 +2,21 @@ require 'rack'
|
|
2
2
|
|
3
3
|
module Murlsh
|
4
4
|
|
5
|
-
# Serve most recent urls in json
|
6
|
-
class JsonServer
|
5
|
+
# Serve most recent urls in json.
|
6
|
+
class JsonServer < Server
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
# Respond to a GET request. Return json of recent urls or jsonp if
|
11
|
-
# if callback parameter is sent.
|
8
|
+
# Respond to a GET request with json of recent urls.
|
12
9
|
def get(req)
|
13
|
-
conditions = Murlsh::SearchConditions.new(req['q']).conditions
|
14
10
|
page = 1
|
15
11
|
per_page = config.fetch('num_posts_feed', 25)
|
16
12
|
|
17
|
-
result_set = Murlsh::UrlResultSet.new(
|
13
|
+
result_set = Murlsh::UrlResultSet.new(req['q'], page, per_page)
|
18
14
|
|
19
|
-
|
20
|
-
content_type = 'application/javascript'
|
21
|
-
body = Murlsh::JsonpBody.new(config, req, result_set)
|
22
|
-
else
|
23
|
-
content_type = 'application/json'
|
24
|
-
body = Murlsh::JsonBody.new(config, req, result_set)
|
25
|
-
end
|
15
|
+
body = Murlsh::JsonBody.new(config, req, result_set)
|
26
16
|
|
27
|
-
Rack::Response.new body, 200,
|
28
|
-
'Cache-Control' => 'must-revalidate, max-age=0',
|
29
|
-
'Content-Type' => content_type
|
17
|
+
Rack::Response.new body, 200, 'Content-Type' => 'application/json'
|
30
18
|
end
|
31
19
|
|
32
|
-
attr_reader :config
|
33
20
|
end
|
34
21
|
|
35
22
|
end
|
data/lib/murlsh/m3u_server.rb
CHANGED
@@ -7,7 +7,7 @@ require 'murlsh'
|
|
7
7
|
module Murlsh
|
8
8
|
|
9
9
|
# Serve m3u file of audio urls.
|
10
|
-
class M3uServer
|
10
|
+
class M3uServer < Server
|
11
11
|
|
12
12
|
AudioContentTypes = %w{
|
13
13
|
application/ogg
|
@@ -15,36 +15,24 @@ module Murlsh
|
|
15
15
|
audio/ogg
|
16
16
|
}
|
17
17
|
|
18
|
-
def initialize(config); @config = config; end
|
19
|
-
|
20
18
|
# Respond to a GET request for m3u file.
|
21
19
|
def get(req)
|
22
|
-
conditions = ['content_type IN (?)', AudioContentTypes]
|
23
|
-
search_conditions = Murlsh::SearchConditions.new(req['q']).conditions
|
24
|
-
unless search_conditions.empty?
|
25
|
-
conditions[0] << " AND (#{search_conditions[0]})"
|
26
|
-
conditions.push(*search_conditions[1..-1])
|
27
|
-
end
|
28
|
-
|
29
20
|
page = 1
|
30
21
|
per_page = config.fetch('num_posts_feed', 25)
|
31
22
|
|
32
|
-
result_set = Murlsh::UrlResultSet.new(
|
33
|
-
|
23
|
+
result_set = Murlsh::UrlResultSet.new(req['q'], page, per_page,
|
24
|
+
:content_type => AudioContentTypes)
|
34
25
|
|
35
26
|
feed_url = URI.join(config.fetch('root_url'), 'm3u.m3u')
|
36
|
-
body = Murlsh::M3uBody.new(config, req, feed_url,
|
27
|
+
body = Murlsh::M3uBody.new(config, req, feed_url, result_set.results)
|
37
28
|
|
38
|
-
resp = Rack::Response.new(body, 200,
|
39
|
-
'Cache-Control' => 'must-revalidate, max-age=0',
|
40
|
-
'Content-Type' => 'audio/x-mpegurl')
|
29
|
+
resp = Rack::Response.new(body, 200, 'Content-Type' => 'audio/x-mpegurl')
|
41
30
|
if u = body.updated
|
42
31
|
resp['Last-Modified'] = u.httpdate
|
43
32
|
end
|
44
33
|
resp
|
45
34
|
end
|
46
35
|
|
47
|
-
attr_reader :config
|
48
36
|
end
|
49
37
|
|
50
38
|
end
|
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
|
-
|
11
|
+
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
|
-
|
53
|
+
Array(hrefs).each do |href|
|
54
54
|
attrs = {
|
55
55
|
:href => "#{options[:prefix]}#{href}",
|
56
56
|
:rel => 'stylesheet',
|
@@ -69,17 +69,22 @@ module Murlsh
|
|
69
69
|
def form_input(options)
|
70
70
|
if options[:id]
|
71
71
|
if options[:label]
|
72
|
-
|
73
|
-
label
|
72
|
+
label_class = options[:optional] ? 'optional' : 'required'
|
73
|
+
label options[:label], :for => options[:id], :class => label_class
|
74
74
|
end
|
75
75
|
options[:name] ||= options[:id]
|
76
76
|
end
|
77
77
|
|
78
78
|
options.delete :label
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
options[:type] ||= 'text'
|
81
|
+
|
82
|
+
if %w{text password}.include?(options[:type]) and @req and
|
83
|
+
not @req[options[:name]].to_s.empty?
|
84
|
+
options[:value] = @req[options[:name]]
|
85
|
+
end
|
86
|
+
|
87
|
+
input options
|
83
88
|
end
|
84
89
|
|
85
90
|
private
|
@@ -7,30 +7,20 @@ require 'murlsh'
|
|
7
7
|
module Murlsh
|
8
8
|
|
9
9
|
# Serve podcast RSS feed.
|
10
|
-
class PodcastServer
|
11
|
-
|
12
|
-
def initialize(config); @config = config; end
|
10
|
+
class PodcastServer < Server
|
13
11
|
|
14
12
|
# Respond to a GET request for podcast RSS feed.
|
15
13
|
def get(req)
|
16
|
-
conditions = ['content_type = ?', 'audio/mpeg']
|
17
|
-
search_conditions = Murlsh::SearchConditions.new(req['q']).conditions
|
18
|
-
unless search_conditions.empty?
|
19
|
-
conditions[0] << " AND (#{search_conditions[0]})"
|
20
|
-
conditions.push(*search_conditions[1..-1])
|
21
|
-
end
|
22
|
-
|
23
14
|
page = 1
|
24
15
|
per_page = config.fetch('num_posts_feed', 25)
|
25
16
|
|
26
|
-
result_set = Murlsh::UrlResultSet.new(
|
27
|
-
|
17
|
+
result_set = Murlsh::UrlResultSet.new(req['q'], page, per_page,
|
18
|
+
:content_type => 'audio/mpeg')
|
28
19
|
|
29
20
|
feed_url = URI.join(config.fetch('root_url'), 'podcast.rss')
|
30
|
-
body = Murlsh::RssBody.new(config, req, feed_url,
|
21
|
+
body = Murlsh::RssBody.new(config, req, feed_url, result_set.results)
|
31
22
|
|
32
23
|
resp = Rack::Response.new(body, 200,
|
33
|
-
'Cache-Control' => 'must-revalidate, max-age=0',
|
34
24
|
'Content-Type' => 'application/rss+xml')
|
35
25
|
if u = body.updated
|
36
26
|
resp['Last-Modified'] = u.httpdate
|
@@ -38,7 +28,6 @@ module Murlsh
|
|
38
28
|
resp
|
39
29
|
end
|
40
30
|
|
41
|
-
attr_reader :config
|
42
31
|
end
|
43
32
|
|
44
33
|
end
|
data/lib/murlsh/pop_server.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'net/pop'
|
2
2
|
|
3
3
|
require 'active_record'
|
4
|
-
require 'json'
|
5
4
|
require 'postrank-uri'
|
6
5
|
require 'rack'
|
7
6
|
require 'rmail'
|
@@ -9,9 +8,7 @@ require 'rmail'
|
|
9
8
|
module Murlsh
|
10
9
|
|
11
10
|
# Pop mail from a pop3 server and add all urls in messages from murlsh users.
|
12
|
-
class PopServer
|
13
|
-
|
14
|
-
def initialize(config); @config = config; end
|
11
|
+
class PopServer < Server
|
15
12
|
|
16
13
|
def post(req)
|
17
14
|
response_body = []
|
@@ -72,7 +69,6 @@ module Murlsh
|
|
72
69
|
}
|
73
70
|
end
|
74
71
|
|
75
|
-
attr_reader :config
|
76
72
|
end
|
77
73
|
|
78
74
|
end
|
data/lib/murlsh/random_server.rb
CHANGED
@@ -5,18 +5,19 @@ require 'murlsh'
|
|
5
5
|
module Murlsh
|
6
6
|
|
7
7
|
# Redirect to a random url from the database.
|
8
|
-
class RandomServer
|
9
|
-
|
10
|
-
def initialize(config); @config = config; end
|
8
|
+
class RandomServer < Server
|
11
9
|
|
12
10
|
# Redirect to a random url from the database optionally matching a query.
|
13
11
|
#
|
14
12
|
# Redirect to root url if no urls match.
|
15
13
|
def get(req)
|
16
|
-
|
17
|
-
|
14
|
+
all_results = Murlsh::UrlResultSet.new(req['q'], 1, 1)
|
15
|
+
|
16
|
+
url = if all_results.total_entries > 0
|
17
|
+
Murlsh::UrlResultSet.new(req['q'],
|
18
|
+
rand(all_results.total_entries) + 1, 1).results[0].url
|
18
19
|
else
|
19
|
-
|
20
|
+
config.fetch('root_url')
|
20
21
|
end
|
21
22
|
|
22
23
|
resp = Rack::Response.new("<a href=\"#{url}\">#{url}</a>")
|
@@ -25,17 +26,6 @@ module Murlsh
|
|
25
26
|
resp
|
26
27
|
end
|
27
28
|
|
28
|
-
# Select a random url from the database optionally matching a query.
|
29
|
-
#
|
30
|
-
# Return nil if no urls match.
|
31
|
-
def random_url(conditions=[])
|
32
|
-
count = Murlsh::Url.count(:conditions => conditions)
|
33
|
-
if count > 0
|
34
|
-
Murlsh::Url.first(:conditions => conditions, :offset => rand(count))
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
attr_reader :config
|
39
29
|
end
|
40
30
|
|
41
31
|
end
|
data/lib/murlsh/rss_server.rb
CHANGED
@@ -7,24 +7,19 @@ require 'murlsh'
|
|
7
7
|
module Murlsh
|
8
8
|
|
9
9
|
# Serve RSS feed.
|
10
|
-
class RssServer
|
11
|
-
|
12
|
-
def initialize(config); @config = config; end
|
10
|
+
class RssServer < Server
|
13
11
|
|
14
12
|
# Respond to a GET request for RSS feed.
|
15
13
|
def get(req)
|
16
|
-
conditions = Murlsh::SearchConditions.new(req['q']).conditions
|
17
14
|
page = 1
|
18
15
|
per_page = config.fetch('num_posts_feed', 25)
|
19
16
|
|
20
|
-
result_set = Murlsh::UrlResultSet.new(
|
21
|
-
urls = result_set.results
|
17
|
+
result_set = Murlsh::UrlResultSet.new(req['q'], page, per_page)
|
22
18
|
|
23
19
|
feed_url = URI.join(config.fetch('root_url'), 'rss.rss')
|
24
|
-
body = Murlsh::RssBody.new(config, req, feed_url,
|
20
|
+
body = Murlsh::RssBody.new(config, req, feed_url, result_set.results)
|
25
21
|
|
26
22
|
resp = Rack::Response.new(body, 200,
|
27
|
-
'Cache-Control' => 'must-revalidate, max-age=0',
|
28
23
|
'Content-Type' => 'application/rss+xml')
|
29
24
|
if u = body.updated
|
30
25
|
resp['Last-Modified'] = u.httpdate
|
@@ -32,7 +27,6 @@ module Murlsh
|
|
32
27
|
resp
|
33
28
|
end
|
34
29
|
|
35
|
-
attr_reader :config
|
36
30
|
end
|
37
31
|
|
38
32
|
end
|
data/lib/murlsh/uri_ask.rb
CHANGED
@@ -119,8 +119,8 @@ module Murlsh
|
|
119
119
|
# * :failproof - if true hide all exceptions and return empty string on failure
|
120
120
|
# * :headers - hash of headers to send in request
|
121
121
|
def header(header_name, options={})
|
122
|
-
result =
|
123
|
-
result = get_headers(options)[header_name] if
|
122
|
+
result = Array(head_headers(options)[header_name]).first
|
123
|
+
result = get_headers(options)[header_name] if result.to_s.empty?
|
124
124
|
result.to_s
|
125
125
|
end
|
126
126
|
|
data/lib/murlsh/url_body.rb
CHANGED
@@ -165,7 +165,7 @@ module Murlsh
|
|
165
165
|
def search_form
|
166
166
|
form(:action => @config.fetch('root_url'), :method => 'get') {
|
167
167
|
fieldset {
|
168
|
-
form_input :id => 'q', :size => 32
|
168
|
+
form_input :id => 'q', :size => 32
|
169
169
|
form_input :type => 'submit', :value => 'Search'
|
170
170
|
}
|
171
171
|
}
|
@@ -189,7 +189,14 @@ module Murlsh
|
|
189
189
|
form(:action => 'url', :method => 'post') {
|
190
190
|
fieldset(:id => 'add') {
|
191
191
|
self.p { form_input :id => 'url', :label => 'Add URL', :size => 32 }
|
192
|
-
self.p {
|
192
|
+
self.p {
|
193
|
+
form_input :id => 'title', :label => 'Title', :size => 32,
|
194
|
+
:optional => true
|
195
|
+
}
|
196
|
+
self.p {
|
197
|
+
form_input :id => 'via', :label => 'Via', :size => 32,
|
198
|
+
:optional => true
|
199
|
+
}
|
193
200
|
self.p {
|
194
201
|
form_input :type => 'password', :id => 'auth', :label => 'Password',
|
195
202
|
:size => 16
|
@@ -1,12 +1,36 @@
|
|
1
|
+
require 'murlsh'
|
2
|
+
|
1
3
|
module Murlsh
|
2
4
|
|
3
5
|
class UrlResultSet
|
4
6
|
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
+
def initialize(query, page, per_page, filters={})
|
8
|
+
@query, @page, @per_page, @filters = query, page, per_page, filters
|
7
9
|
@order = 'time DESC'
|
8
10
|
end
|
9
11
|
|
12
|
+
def search_conditions
|
13
|
+
@search_conditions ||= Murlsh::SearchConditions.new(query).conditions
|
14
|
+
end
|
15
|
+
|
16
|
+
def conditions
|
17
|
+
@conditions ||= if filters[:content_type]
|
18
|
+
result = if filters[:content_type].is_a?(String)
|
19
|
+
['content_type = ?', filters[:content_type]]
|
20
|
+
else
|
21
|
+
['content_type IN (?)', filters[:content_type]]
|
22
|
+
end
|
23
|
+
|
24
|
+
unless search_conditions.empty?
|
25
|
+
result[0] << " AND (#{search_conditions[0]})"
|
26
|
+
result.push(*search_conditions[1..-1])
|
27
|
+
end
|
28
|
+
result
|
29
|
+
else
|
30
|
+
search_conditions
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
10
34
|
def total_entries
|
11
35
|
@total_entries ||= Murlsh::Url.count(:conditions => conditions)
|
12
36
|
end
|
@@ -36,9 +60,10 @@ module Murlsh
|
|
36
60
|
@next_page
|
37
61
|
end
|
38
62
|
|
39
|
-
attr_reader :
|
63
|
+
attr_reader :query
|
40
64
|
attr_reader :page
|
41
65
|
attr_reader :per_page
|
66
|
+
attr_reader :filters
|
42
67
|
attr_reader :order
|
43
68
|
end
|
44
69
|
|
data/lib/murlsh/url_server.rb
CHANGED
@@ -4,26 +4,22 @@ require 'rack'
|
|
4
4
|
module Murlsh
|
5
5
|
|
6
6
|
# Build responses for HTTP requests.
|
7
|
-
class UrlServer
|
8
|
-
|
9
|
-
def initialize(config); @config = config; end
|
7
|
+
class UrlServer < Server
|
10
8
|
|
11
9
|
# Respond to a GET request. Return a page of urls based on the query
|
12
10
|
# string parameters.
|
13
11
|
def get(req)
|
14
|
-
conditions = Murlsh::SearchConditions.new(req['q']).conditions
|
15
12
|
page = [req['p'].to_i, 1].max
|
16
13
|
per_page = req['pp'] ? req['pp'].to_i :
|
17
14
|
config.fetch('num_posts_page', 25)
|
18
15
|
|
19
16
|
content_type = 'text/html; charset=utf-8'
|
20
|
-
result_set = Murlsh::UrlResultSet.new(
|
17
|
+
result_set = Murlsh::UrlResultSet.new(req['q'], page, per_page)
|
21
18
|
|
22
19
|
body = Murlsh::UrlBody.new(config, req, result_set, content_type)
|
23
20
|
|
24
21
|
resp = Rack::Response.new
|
25
22
|
resp.write(body.build)
|
26
|
-
resp['Cache-Control'] = 'must-revalidate, max-age=0'
|
27
23
|
resp['Content-Type'] = content_type
|
28
24
|
|
29
25
|
resp
|
@@ -86,7 +82,6 @@ module Murlsh
|
|
86
82
|
config.fetch('auth_file')).auth(secret)
|
87
83
|
end
|
88
84
|
|
89
|
-
attr_reader :config
|
90
85
|
end
|
91
86
|
|
92
87
|
end
|
data/lib/murlsh/version.rb
CHANGED
data/lib/murlsh.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'murlsh/search_conditions'
|
2
|
+
require 'murlsh/server'
|
2
3
|
|
3
4
|
require 'murlsh/atom_server'
|
4
5
|
require 'murlsh/ask'
|
@@ -18,7 +19,6 @@ require 'murlsh/img_store'
|
|
18
19
|
require 'murlsh/install'
|
19
20
|
require 'murlsh/json_body'
|
20
21
|
require 'murlsh/json_server'
|
21
|
-
require 'murlsh/jsonp_body'
|
22
22
|
require 'murlsh/m3u_body'
|
23
23
|
require 'murlsh/m3u_server'
|
24
24
|
require 'murlsh/markup'
|
data/murlsh.gemspec
CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |s|
|
|
21
21
|
bcrypt-ruby
|
22
22
|
builder
|
23
23
|
htmlentities
|
24
|
-
json
|
25
24
|
nokogiri
|
26
25
|
plumnailer
|
27
26
|
postrank-uri
|
@@ -29,6 +28,7 @@ Gem::Specification.new do |s|
|
|
29
28
|
push-notify
|
30
29
|
rack
|
31
30
|
rack-cache
|
31
|
+
rack-contrib
|
32
32
|
rack-rewrite
|
33
33
|
rack-throttle
|
34
34
|
rmagick
|