murlsh 0.9.0 → 0.10.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/README.textile +33 -8
- data/Rakefile +43 -15
- data/VERSION +1 -1
- data/config.yaml +4 -0
- data/lib/murlsh/config_server.rb +32 -0
- data/lib/murlsh/dispatch.rb +4 -2
- data/murlsh.gemspec +7 -2
- data/plugins/add_post_60_notify_hubs.rb +4 -13
- data/public/css/screen.css +11 -5
- data/public/js/comments.json +12 -0
- data/public/js/js.js +376 -289
- data/spec/auth_spec.rb +0 -2
- data/spec/dispatch_spec.rb +0 -2
- data/spec/doc_spec.rb +0 -2
- data/spec/markup_spec.rb +0 -2
- data/spec/unwrap_json_spec.rb +0 -2
- data/spec/uri_ask_spec.rb +0 -2
- data/spec/uri_spec.rb +0 -2
- data/spec/xhtml_response_spec.rb +0 -2
- data/spec/yaml_ordered_hash_spec.rb +0 -2
- metadata +32 -14
data/README.textile
CHANGED
@@ -8,7 +8,7 @@ Site for sharing and archiving links.
|
|
8
8
|
* embeds Flash mp3 player for mp3 urls
|
9
9
|
* looks good on iPhone
|
10
10
|
* PubSubHubbub notification
|
11
|
-
*
|
11
|
+
* plugin interface
|
12
12
|
* rack interface
|
13
13
|
* Gravatar support
|
14
14
|
|
@@ -22,6 +22,8 @@ h1. Installation
|
|
22
22
|
|
23
23
|
h2. Phusion Passenger
|
24
24
|
|
25
|
+
DESTINATION_DIRECTORY is the web directory to install the murlsh site to.
|
26
|
+
|
25
27
|
<pre>
|
26
28
|
<code>
|
27
29
|
gem sources -a http://gemcutter.org/
|
@@ -33,6 +35,36 @@ rake init
|
|
33
35
|
</code>
|
34
36
|
</pre>
|
35
37
|
|
38
|
+
h1. Updating
|
39
|
+
|
40
|
+
If you are using the gem and it gets updated to a new version you should run
|
41
|
+
the murlsh command again from your web directory to update plugins, javascript
|
42
|
+
and css. It will prompt before overwriting anything in case you have made
|
43
|
+
modifications.
|
44
|
+
|
45
|
+
h1. Plugins
|
46
|
+
|
47
|
+
Classes in the plugins directory can be used to change behavior at certain
|
48
|
+
points. Each class that extends Murlsh::Plugin and sets an instance variable
|
49
|
+
called @hook will be called for that hook. Each plugin has a run() method that
|
50
|
+
accepts arguments and returns something. These methods will be called in the
|
51
|
+
order of their class names sorted lexically. Some hooks pass the output of their
|
52
|
+
run() method to the next plugin for that hook so that the data can be passed
|
53
|
+
through a chain of methods that each do something to it.
|
54
|
+
|
55
|
+
A lot of the standard behavior is implemented as plugins. See the plugins
|
56
|
+
directory for examples.
|
57
|
+
|
58
|
+
Plugin hooks
|
59
|
+
|
60
|
+
|Hook|Description|run() arguments|Returns|
|
61
|
+
|add_pre|called before a new url is saved|url, config hash|undefined|
|
62
|
+
|add_post|called after a new url is saved|config hash|undefined|
|
63
|
+
|hostrec|post process the domain that is shown after links|domain, url, title|text to display|
|
64
|
+
|html_parse|parse HTML using something like Hpricot or Nokogiri|parseable|parsed HTML, only first plugin is run (cannot be chained)|
|
65
|
+
|time|convert the time of a post into a string for display|time|time display text|
|
66
|
+
|via|convert a via url into a string for display|via url|via url display text|
|
67
|
+
|
36
68
|
h1. PubSubHubbub
|
37
69
|
|
38
70
|
Murlsh can notify "PubSubHubbub":http://code.google.com/p/pubsubhubbub/ hubs
|
@@ -52,11 +84,4 @@ subscribe_url is what gets put in the feed as link rel="hub"
|
|
52
84
|
|
53
85
|
This will make updates to your feed show up in Google Reader instantly.
|
54
86
|
|
55
|
-
h1. Updating
|
56
|
-
|
57
|
-
If you are using the gem and it gets updated to a new version you should run
|
58
|
-
the murlsh command again from your web directory to update plugins, javascript
|
59
|
-
and css. It will prompt before overwriting anything in case you have made
|
60
|
-
modifications.
|
61
|
-
|
62
87
|
Questions and comments: "matthewm@boedicker.org":mailto:matthewm@boedicker.org
|
data/Rakefile
CHANGED
@@ -154,23 +154,47 @@ namespace :user do
|
|
154
154
|
|
155
155
|
end
|
156
156
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
157
|
+
# Validate a document with the W3C validation service.
|
158
|
+
def validate(check_url, options={})
|
159
|
+
opts = {
|
160
|
+
:validator_host => 'validator.w3.org',
|
161
|
+
:validator_port => 80,
|
162
|
+
:validator_path =>
|
163
|
+
"/check?uri=#{CGI::escape(check_url)}&charset=(detect+automatically)&doctype=Inline&group=0",
|
164
|
+
}.merge(options)
|
165
|
+
|
166
|
+
net_http = Net::HTTP.new(opts[:validator_host], opts[:validator_port])
|
167
|
+
# net_http.set_debug_output(STDOUT)
|
165
168
|
|
166
169
|
net_http.start do |http|
|
167
|
-
resp = http.request_head(
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
170
|
+
resp = http.request_head(opts[:validator_path])
|
171
|
+
result = {
|
172
|
+
:response => resp
|
173
|
+
}
|
174
|
+
if Net::HTTPSuccess === resp
|
175
|
+
result.merge!(
|
176
|
+
:status => resp['X-W3C-Validator-Status'],
|
177
|
+
:errors => resp['X-W3C-Validator-Errors'],
|
178
|
+
:warnings => resp['X-W3C-Validator-Warnings']
|
179
|
+
)
|
180
|
+
end
|
181
|
+
result
|
182
|
+
end
|
172
183
|
|
173
|
-
|
184
|
+
end
|
185
|
+
|
186
|
+
namespace :validate do
|
187
|
+
|
188
|
+
desc 'Validate XHTML.'
|
189
|
+
task :xhtml do
|
190
|
+
check_url = config['root_url']
|
191
|
+
print "validating #{check_url} : "
|
192
|
+
result = validate(check_url)
|
193
|
+
if Net::HTTPSuccess === result[:response]
|
194
|
+
puts "#{result[:status]} (#{result[:errors]} errors, #{result[:warnings]} warnings)"
|
195
|
+
else
|
196
|
+
puts result[:response]
|
197
|
+
end
|
174
198
|
end
|
175
199
|
|
176
200
|
end
|
@@ -294,6 +318,9 @@ begin
|
|
294
318
|
gemspec.authors = ['Matthew M. Boedicker']
|
295
319
|
gemspec.executables = %w{murlsh}
|
296
320
|
|
321
|
+
# gemspec.signing_key = '/home/mmb/src/keys/gem-private_key.pem'
|
322
|
+
# gemspec.cert_chain = %w{/home/mmb/src/keys/gem-public_cert.pem}
|
323
|
+
|
297
324
|
%w{
|
298
325
|
activerecord 2.3.4
|
299
326
|
bcrypt-ruby 2.1.2
|
@@ -301,6 +328,7 @@ begin
|
|
301
328
|
hpricot 0.8.1
|
302
329
|
htmlentities 4.2.0
|
303
330
|
json 1.2.3
|
331
|
+
push-notify 0.1.0
|
304
332
|
rack 1.0.0
|
305
333
|
rack-cache 0.5.2
|
306
334
|
rack-throttle 0.3.0
|
@@ -310,5 +338,5 @@ begin
|
|
310
338
|
|
311
339
|
end
|
312
340
|
rescue LoadError
|
313
|
-
puts
|
341
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
314
342
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.10.0
|
data/config.yaml
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
%w{
|
2
|
+
digest/sha1
|
3
|
+
|
4
|
+
json
|
5
|
+
rack
|
6
|
+
}.each { |m| require m }
|
7
|
+
|
8
|
+
module Murlsh
|
9
|
+
|
10
|
+
# Serve a JSON subset of the configuration.
|
11
|
+
#
|
12
|
+
# Will include all config keys contained in the config key named config_js.
|
13
|
+
class ConfigServer
|
14
|
+
|
15
|
+
def initialize(config)
|
16
|
+
@config_json =
|
17
|
+
config.reject { |k,v| !config.fetch('config_js', []).
|
18
|
+
include?(k) }.to_json
|
19
|
+
|
20
|
+
@headers = {
|
21
|
+
'Content-Type' => 'application/json',
|
22
|
+
'ETag' => "\"#{Digest::SHA1.hexdigest(@config_json)}\"",
|
23
|
+
'Last-Modified' => Time.now.httpdate
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Serve a JSON subset of the configuration.
|
28
|
+
def get(req); Rack::Response.new(@config_json, 200, @headers); end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/lib/murlsh/dispatch.rb
CHANGED
@@ -20,6 +20,7 @@ module Murlsh
|
|
20
20
|
db = ActiveRecord::Base.connection.instance_variable_get(:@connection)
|
21
21
|
|
22
22
|
url_server = Murlsh::UrlServer.new(@config, db)
|
23
|
+
config_server = Murlsh::ConfigServer.new(@config)
|
23
24
|
flickr_server = Murlsh::FlickrServer.new(@config)
|
24
25
|
twitter_server = Murlsh::TwitterServer.new
|
25
26
|
|
@@ -28,8 +29,9 @@ module Murlsh
|
|
28
29
|
@dispatch = [
|
29
30
|
[%r{^GET #{root_path}(url)?$}, url_server.method(:get)],
|
30
31
|
[%r{^POST #{root_path}(url)?$}, url_server.method(:post)],
|
31
|
-
[%r{^GET
|
32
|
-
[%r{^GET
|
32
|
+
[%r{^GET #{root_path}config$}, config_server.method(:get)],
|
33
|
+
[%r{^GET #{root_path}flickr$}, flickr_server.method(:get)],
|
34
|
+
[%r{^GET #{root_path}twitter/.+$}, twitter_server.method(:get)],
|
33
35
|
]
|
34
36
|
end
|
35
37
|
|
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.
|
8
|
+
s.version = "0.10.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-
|
12
|
+
s.date = %q{2010-08-05}
|
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}
|
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
"config.yaml",
|
30
30
|
"lib/murlsh.rb",
|
31
31
|
"lib/murlsh/auth.rb",
|
32
|
+
"lib/murlsh/config_server.rb",
|
32
33
|
"lib/murlsh/dispatch.rb",
|
33
34
|
"lib/murlsh/doc.rb",
|
34
35
|
"lib/murlsh/etag_add_encoding.rb",
|
@@ -63,6 +64,7 @@ Gem::Specification.new do |s|
|
|
63
64
|
"plugins/via_50_domain.rb",
|
64
65
|
"public/css/jquery.jgrowl.css",
|
65
66
|
"public/css/screen.css",
|
67
|
+
"public/js/comments.json",
|
66
68
|
"public/js/jquery-1.4.2.min.js",
|
67
69
|
"public/js/jquery.jgrowl_compressed.js",
|
68
70
|
"public/js/js.js",
|
@@ -107,6 +109,7 @@ Gem::Specification.new do |s|
|
|
107
109
|
s.add_runtime_dependency(%q<hpricot>, [">= 0.8.1"])
|
108
110
|
s.add_runtime_dependency(%q<htmlentities>, [">= 4.2.0"])
|
109
111
|
s.add_runtime_dependency(%q<json>, [">= 1.2.3"])
|
112
|
+
s.add_runtime_dependency(%q<push-notify>, [">= 0.1.0"])
|
110
113
|
s.add_runtime_dependency(%q<rack>, [">= 1.0.0"])
|
111
114
|
s.add_runtime_dependency(%q<rack-cache>, [">= 0.5.2"])
|
112
115
|
s.add_runtime_dependency(%q<rack-throttle>, [">= 0.3.0"])
|
@@ -119,6 +122,7 @@ Gem::Specification.new do |s|
|
|
119
122
|
s.add_dependency(%q<hpricot>, [">= 0.8.1"])
|
120
123
|
s.add_dependency(%q<htmlentities>, [">= 4.2.0"])
|
121
124
|
s.add_dependency(%q<json>, [">= 1.2.3"])
|
125
|
+
s.add_dependency(%q<push-notify>, [">= 0.1.0"])
|
122
126
|
s.add_dependency(%q<rack>, [">= 1.0.0"])
|
123
127
|
s.add_dependency(%q<rack-cache>, [">= 0.5.2"])
|
124
128
|
s.add_dependency(%q<rack-throttle>, [">= 0.3.0"])
|
@@ -132,6 +136,7 @@ Gem::Specification.new do |s|
|
|
132
136
|
s.add_dependency(%q<hpricot>, [">= 0.8.1"])
|
133
137
|
s.add_dependency(%q<htmlentities>, [">= 4.2.0"])
|
134
138
|
s.add_dependency(%q<json>, [">= 1.2.3"])
|
139
|
+
s.add_dependency(%q<push-notify>, [">= 0.1.0"])
|
135
140
|
s.add_dependency(%q<rack>, [">= 1.0.0"])
|
136
141
|
s.add_dependency(%q<rack-cache>, [">= 0.5.2"])
|
137
142
|
s.add_dependency(%q<rack-throttle>, [">= 0.3.0"])
|
@@ -13,23 +13,14 @@ module Murlsh
|
|
13
13
|
hubs = config.fetch('pubsubhubbub_hubs', [])
|
14
14
|
|
15
15
|
unless hubs.empty?
|
16
|
-
require '
|
17
|
-
require 'pubsubhubbub'
|
16
|
+
require 'push-notify'
|
18
17
|
|
19
18
|
feed_url = URI.join(config['root_url'], config['feed_file'])
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
pub = EventMachine::PubSubHubbub.new(hub['publish_url']).publish(
|
24
|
-
feed_url)
|
25
|
-
|
26
|
-
pub.callback { EventMachine.stop }
|
27
|
-
pub.errback { EventMachine.stop }
|
28
|
-
}
|
19
|
+
begin
|
20
|
+
PushNotify::Content.new(feed_url).tell(*hubs.map { |h| h['publish_url'] })
|
21
|
+
rescue Exception
|
29
22
|
end
|
30
|
-
|
31
23
|
end
|
32
|
-
|
33
24
|
end
|
34
25
|
|
35
26
|
end
|
data/public/css/screen.css
CHANGED
@@ -12,6 +12,10 @@ img {
|
|
12
12
|
width : 600px;
|
13
13
|
}
|
14
14
|
|
15
|
+
ul.comments {
|
16
|
+
list-style-type : none;
|
17
|
+
}
|
18
|
+
|
15
19
|
li {
|
16
20
|
clear : both;
|
17
21
|
float : left;
|
@@ -49,9 +53,6 @@ div.name {
|
|
49
53
|
img.thumb, li object {
|
50
54
|
float : left;
|
51
55
|
margin-right : 10px;
|
52
|
-
border : 1px solid #808080;
|
53
|
-
-moz-border-radius : 5px;
|
54
|
-
-webkit-border-radius : 5px;
|
55
56
|
}
|
56
57
|
|
57
58
|
img.thumb.twitter {
|
@@ -59,6 +60,11 @@ img.thumb.twitter {
|
|
59
60
|
width : 48px;
|
60
61
|
}
|
61
62
|
|
63
|
+
img.thumb.apple {
|
64
|
+
height : 48px;
|
65
|
+
width : 48px;
|
66
|
+
}
|
67
|
+
|
62
68
|
span.host {
|
63
69
|
color : #808080;
|
64
70
|
font-family : monospace;
|
@@ -88,7 +94,7 @@ fieldset#add label {
|
|
88
94
|
}
|
89
95
|
|
90
96
|
a.feed {
|
91
|
-
background
|
97
|
+
background : #fb9e3a;
|
92
98
|
border-top : 1px solid #fba141;
|
93
99
|
border-right : 1px solid #bc4d04;
|
94
100
|
border-bottom : 1px solid #bc4d04;
|
@@ -129,7 +135,7 @@ div.jGrowl div.jGrowl-closer {
|
|
129
135
|
width : 290px;
|
130
136
|
}
|
131
137
|
|
132
|
-
#urls
|
138
|
+
#urls>li {
|
133
139
|
overflow : hidden;
|
134
140
|
border-bottom : 1px solid #ccc;
|
135
141
|
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"http://url/being/commented/on": [
|
3
|
+
{
|
4
|
+
"authorAvatar": "http://url/of/your/avatar/image",
|
5
|
+
"authorName": "yourname",
|
6
|
+
"authorUrl": "http://url/of/your/site",
|
7
|
+
"comment": "your comment",
|
8
|
+
"createdTime": 1275005075,
|
9
|
+
"updatedTime": 1275005075
|
10
|
+
},
|
11
|
+
],
|
12
|
+
}
|
data/public/js/js.js
CHANGED
@@ -1,347 +1,434 @@
|
|
1
|
-
/*global $, window*/
|
1
|
+
/*global $, document, navigator, window*/
|
2
2
|
|
3
3
|
"use strict";
|
4
4
|
|
5
|
-
var Murlsh = {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
var Murlsh = function (config, $, navigator, window) {
|
6
|
+
var my = {},
|
7
|
+
hrefRes = {
|
8
|
+
flickr :
|
9
|
+
/^http:\/\/(?:www\.)?flickr\.com\/photos\/[@\w\-]+?\/([\d]+)/i,
|
10
|
+
imageshack :
|
11
|
+
/^(http:\/\/img\d+\.imageshack\.us\/img\d+\/\d+\/\w+\.)(jpe?g|gif|png)$/i,
|
12
|
+
imgur :
|
13
|
+
/^(http:\/\/(?:i\.)?imgur\.com\/[a-z\d]+)(\.(?:jpe?g|gif|png))$/i,
|
14
|
+
mp3 :
|
15
|
+
/\.mp3$/i,
|
16
|
+
s3 :
|
17
|
+
/^(http:\/\/static\.mmb\.s3\.amazonaws\.com\/[\w\-]+\.)(jpe?g|gif|pdf|png)$/i,
|
18
|
+
twitter :
|
19
|
+
/^https?:\/\/twitter\.com\/\w+\/status(?:es)?\/(\d+)$/i,
|
20
|
+
vimeo :
|
21
|
+
/^http:\/\/(?:www\.)?vimeo\.com\/(\d+)$/i,
|
22
|
+
youtube :
|
23
|
+
/^http:\/\/(?:(?:www|uk)\.)?youtube\.com\/watch\?v=([\w\-]+)(?:&|$)/i
|
24
|
+
},
|
25
|
+
hostRe = /^http:\/\/([a-z\d\.\-]+(?::\d+)?)\//i;
|
26
|
+
|
27
|
+
function autoLink(s) {
|
28
|
+
// turn urls into links
|
29
|
+
var result = s.replace(
|
30
|
+
/https?:\/\/(?:[0-9a-z](?:[0-9a-z\-]{0,61}[0-9a-z])?\.)+[a-z]+\/[0-9a-z$_.+!*'(),\/?#\-]*/gi,
|
31
|
+
'<a href="$&">$&</a>');
|
32
|
+
|
33
|
+
return result;
|
34
|
+
}
|
15
35
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
var width = e.width();
|
36
|
+
function escapeXml(s) {
|
37
|
+
return s.replace(/&/g, '&');
|
38
|
+
}
|
20
39
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
40
|
+
function img(src, text) {
|
41
|
+
text = text || '';
|
42
|
+
return $('<img />', {
|
43
|
+
src : src,
|
44
|
+
alt : text,
|
45
|
+
title : text
|
46
|
+
});
|
25
47
|
}
|
26
|
-
};
|
27
48
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
e.find('.message img').load(function() {
|
38
|
-
Murlsh.makeFit($(this),
|
39
|
-
Math.round($(window).width() / 2),
|
40
|
-
Math.round($(window).height() - 100));
|
41
|
-
});
|
49
|
+
function makeFit(e, maxWidth, maxHeight) {
|
50
|
+
var height = e.height(),
|
51
|
+
scale,
|
52
|
+
width = e.width();
|
53
|
+
|
54
|
+
if (width > maxWidth || height > maxHeight) {
|
55
|
+
scale = Math.min(maxWidth / width, maxHeight / height);
|
56
|
+
e.width(Math.round(width * scale));
|
57
|
+
e.height(Math.round(height * scale));
|
42
58
|
}
|
43
|
-
}
|
44
|
-
};
|
59
|
+
}
|
45
60
|
|
46
|
-
|
47
|
-
|
48
|
-
|
61
|
+
function objectTag(data, height, width, params) {
|
62
|
+
// this does not use jQuery to build tags because building object
|
63
|
+
// tags is broken in IE
|
64
|
+
var result = '<object data="' + escapeXml(data) +
|
65
|
+
'" height="' + height +
|
66
|
+
'" type="application/x-shockwave-flash" width="' + width + '">';
|
49
67
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
'" height="' + height +
|
55
|
-
'" type="application/x-shockwave-flash" width="' + width + '">';
|
68
|
+
$.each(params, function (i, v) {
|
69
|
+
result += '<param name="' + v.name + '" value="' +
|
70
|
+
escapeXml(v.value) + '" />';
|
71
|
+
});
|
56
72
|
|
57
|
-
|
58
|
-
result += '<param name="' + v.name + '" value="' +
|
59
|
-
Murlsh.escapeXml(v.value) + '" />';
|
60
|
-
});
|
73
|
+
result += '</object>';
|
61
74
|
|
62
|
-
|
75
|
+
return result;
|
76
|
+
}
|
63
77
|
|
64
|
-
|
65
|
-
|
78
|
+
function appleThumb(host) {
|
79
|
+
return img('http://' + host + '/apple-touch-icon.png', '').addClass(
|
80
|
+
'thumb apple');
|
81
|
+
}
|
66
82
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
83
|
+
function closerAdd(x, header) {
|
84
|
+
var html = (typeof x === 'object') ? $('<div />').append(x).html() : x;
|
85
|
+
|
86
|
+
$.jGrowl(html, {
|
87
|
+
closeTemplate : 'X',
|
88
|
+
glue : 'before',
|
89
|
+
header : header,
|
90
|
+
sticky : true,
|
91
|
+
beforeOpen : function (e) {
|
92
|
+
e.find('.message img').load(function () {
|
93
|
+
makeFit($(this), Math.round($(window).width() / 2),
|
94
|
+
Math.round($(window).height() - 100));
|
95
|
+
});
|
96
|
+
}
|
97
|
+
});
|
98
|
+
}
|
99
|
+
|
100
|
+
function flickrClick() {
|
101
|
+
closerAdd(img($(this).data('zoom')));
|
102
|
+
}
|
72
103
|
|
73
|
-
|
74
|
-
base
|
75
|
-
|
76
|
-
|
104
|
+
function flickrThumb(d) {
|
105
|
+
var base,
|
106
|
+
owner,
|
107
|
+
photo = d.photo,
|
108
|
+
zoom;
|
77
109
|
|
78
|
-
if (
|
79
|
-
|
110
|
+
if (d.stat === 'ok') {
|
111
|
+
base = 'http://farm' + photo.farm + '.static.flickr.com/' +
|
112
|
+
photo.server + '/' + photo.id + '_';
|
113
|
+
zoom = base + photo.secret + '_m.jpg';
|
114
|
+
|
115
|
+
if (photo.originalsecret) {
|
116
|
+
zoom = base + photo.originalsecret + '_o.' +
|
117
|
+
photo.originalformat;
|
118
|
+
}
|
119
|
+
|
120
|
+
owner = photo.owner;
|
121
|
+
return img(base + photo.secret + '_s.jpg', photo.title._content +
|
122
|
+
(owner && owner.username ? ' by ' + owner.username : '')
|
123
|
+
).addClass('thumb flickr').data('zoom', zoom);
|
80
124
|
}
|
125
|
+
}
|
81
126
|
|
82
|
-
|
83
|
-
|
84
|
-
photo.title._content +
|
85
|
-
(owner && owner.username ? ' by ' + owner.username : '')
|
86
|
-
).addClass('thumb flickr').data('zoom', zoom);
|
127
|
+
function imgClick() {
|
128
|
+
closerAdd(img($(this).data('href')));
|
87
129
|
}
|
88
|
-
};
|
89
130
|
|
90
|
-
|
91
|
-
|
92
|
-
|
131
|
+
function imgThumb() {
|
132
|
+
var i,
|
133
|
+
lastIndex,
|
134
|
+
urlParts = [];
|
93
135
|
|
94
|
-
|
95
|
-
|
96
|
-
|
136
|
+
for (i = 0; i < arguments.length; i += 1) {
|
137
|
+
urlParts.push(arguments[i]);
|
138
|
+
}
|
97
139
|
|
98
|
-
|
99
|
-
urlParts.push(arguments[i]);
|
100
|
-
}
|
140
|
+
lastIndex = urlParts.length - 1;
|
101
141
|
|
102
|
-
|
142
|
+
// if pdf the thumbnail will be .png
|
143
|
+
if (urlParts[lastIndex].match(/^pdf$/i)) {
|
144
|
+
urlParts.splice(lastIndex, 1, 'png');
|
145
|
+
}
|
103
146
|
|
104
|
-
|
105
|
-
if (urlParts[lastIndex].match(/^pdf$/i)) {
|
106
|
-
urlParts.splice(lastIndex, 1, 'png');
|
147
|
+
return img(urlParts.join('')).addClass('thumb');
|
107
148
|
}
|
108
149
|
|
109
|
-
|
110
|
-
|
150
|
+
function thumbInsert(img, clickFunction, a) {
|
151
|
+
if (img) {
|
152
|
+
if (my.isIphone()) {
|
153
|
+
a.prepend(img);
|
154
|
+
} else {
|
155
|
+
if (clickFunction) {
|
156
|
+
img.click(clickFunction);
|
157
|
+
}
|
158
|
+
a.before(img);
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
111
162
|
|
112
|
-
|
113
|
-
|
114
|
-
|
163
|
+
function twitterAddLinks(s) {
|
164
|
+
// turn urls into links and Twitter usernames into links to Twitter
|
165
|
+
var result = autoLink(s);
|
115
166
|
|
116
|
-
|
117
|
-
|
118
|
-
|
167
|
+
result = result.replace(
|
168
|
+
/(^|[\s,(])@([0-9a-z_]+)($|[\s,.)])/gi,
|
169
|
+
'$1<a href="http://twitter.com/$2">@$2</a>$3');
|
119
170
|
|
120
|
-
|
121
|
-
|
122
|
-
};
|
171
|
+
return result;
|
172
|
+
}
|
123
173
|
|
124
|
-
|
125
|
-
|
126
|
-
}
|
174
|
+
function twitterThumb(d) {
|
175
|
+
return img(d.user.profile_image_url).addClass('thumb twitter');
|
176
|
+
}
|
127
177
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
};
|
178
|
+
function vimeoClick() {
|
179
|
+
closerAdd($(this).data('embedHtml'));
|
180
|
+
}
|
132
181
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
fs : 1,
|
137
|
-
hd : 1,
|
138
|
-
hl : 'en',
|
139
|
-
iv_load_policy : 3,
|
140
|
-
showinfo : 0,
|
141
|
-
showsearch : 0
|
142
|
-
});
|
182
|
+
function vimeoThumb(d) {
|
183
|
+
return img(d.thumbnail_medium, d.title).addClass('thumb vimeo');
|
184
|
+
}
|
143
185
|
|
144
|
-
|
145
|
-
|
146
|
-
|
186
|
+
function youtubeClick() {
|
187
|
+
var movie = 'http://www.youtube.com/v/' + $(this).data('id') + '?' +
|
188
|
+
$.param({
|
189
|
+
fs : 1,
|
190
|
+
hd : 1,
|
191
|
+
hl : 'en',
|
192
|
+
iv_load_policy : 3,
|
193
|
+
showinfo : 0,
|
194
|
+
showsearch : 0
|
195
|
+
});
|
147
196
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
} else {
|
153
|
-
if (clickFunction) {
|
154
|
-
img.click(clickFunction);
|
155
|
-
}
|
156
|
-
a.before(img);
|
157
|
-
}
|
197
|
+
closerAdd(objectTag(movie, 505, 640, [{
|
198
|
+
name : 'movie',
|
199
|
+
value : movie
|
200
|
+
}]));
|
158
201
|
}
|
159
|
-
};
|
160
202
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
Murlsh.hrefRes = {
|
166
|
-
flickr :
|
167
|
-
/^http:\/\/(?:www\.)?flickr\.com\/photos\/[@\w\-]+?\/([\d]+)/i,
|
168
|
-
imageshack :
|
169
|
-
/^(http:\/\/img\d+\.imageshack\.us\/img\d+\/\d+\/\w+\.)(jpe?g|gif|png)$/i,
|
170
|
-
imgur :
|
171
|
-
/^(http:\/\/(?:i\.)?imgur\.com\/[a-z\d]+)(\.(?:jpe?g|gif|png))$/i,
|
172
|
-
mp3 :
|
173
|
-
/\.mp3$/i,
|
174
|
-
s3 :
|
175
|
-
/^(http:\/\/static\.mmb\.s3\.amazonaws\.com\/[\w\-]+\.)(jpe?g|gif|pdf|png)$/i,
|
176
|
-
twitter :
|
177
|
-
/^https?:\/\/twitter\.com\/\w+\/status(?:es)?\/(\d+)$/i,
|
178
|
-
vimeo :
|
179
|
-
/^http:\/\/(?:www\.)?vimeo\.com\/(\d+)$/i,
|
180
|
-
youtube :
|
181
|
-
/^http:\/\/(?:(?:www|uk)\.)?youtube\.com\/watch\?v=([\w\-]+)(?:&|$)/i
|
182
|
-
};
|
203
|
+
function youtubeThumb(id) {
|
204
|
+
return img('http://img.youtube.com/vi/' + id + '/default.jpg',
|
205
|
+
'click to watch').addClass('thumb youtube').data('id', id);
|
206
|
+
}
|
183
207
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
208
|
+
my.addComments = function (link, comments) {
|
209
|
+
var avatar,
|
210
|
+
comment,
|
211
|
+
commentElement,
|
212
|
+
i,
|
213
|
+
ul = $('<ul />').addClass('comments').appendTo(link.parent());
|
214
|
+
|
215
|
+
for (i = 0; i < comments.length; i += 1) {
|
216
|
+
comment = comments[i];
|
217
|
+
commentElement = $('<li />');
|
218
|
+
if (comment.authorAvatar.length > 0) {
|
219
|
+
avatar = img(comment.authorAvatar).appendTo(commentElement);
|
220
|
+
if (comment.authorUrl.length > 0) {
|
221
|
+
avatar.wrapAll($('<a />').attr('href', comment.authorUrl));
|
222
|
+
}
|
223
|
+
commentElement.append(' ');
|
224
|
+
}
|
225
|
+
commentElement
|
226
|
+
.append($('<span />').append(comment.authorName).addClass(
|
227
|
+
'comment-name'))
|
228
|
+
.append(' : ')
|
229
|
+
.append($('<span />').append(autoLink(comment.comment)).
|
230
|
+
addClass('comment-comment'))
|
231
|
+
.appendTo(ul);
|
232
|
+
}
|
233
|
+
};
|
189
234
|
|
190
|
-
|
191
|
-
|
192
|
-
|
235
|
+
my.addExtra = function () {
|
236
|
+
var host,
|
237
|
+
hostMatch,
|
238
|
+
href = $(this).attr('href'),
|
239
|
+
match = {},
|
240
|
+
swf = 'swf/player_mp3_mini.swf',
|
241
|
+
thumb;
|
193
242
|
|
194
|
-
|
195
|
-
|
196
|
-
// url : 'http://api.flickr.com/services/rest/',
|
197
|
-
url : 'flickr',
|
198
|
-
data : {
|
199
|
-
format : 'json',
|
200
|
-
method : 'flickr.photos.getinfo',
|
201
|
-
photo_id : match.flickr[1]
|
202
|
-
},
|
203
|
-
dataType : 'jsonp',
|
204
|
-
jsonp : 'jsoncallback',
|
205
|
-
success : function(d) {
|
206
|
-
Murlsh.thumbInsert(Murlsh.flickrThumb(d),
|
207
|
-
Murlsh.flickrClick, $(this));
|
208
|
-
},
|
209
|
-
context : $(this),
|
210
|
-
jsonpCallback : 'flickrCallback' + match.flickr[1]
|
243
|
+
$.each(hrefRes, function (x, re) {
|
244
|
+
return !(match[x] = re.exec(href));
|
211
245
|
});
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
'
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
if (match.
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
246
|
+
|
247
|
+
if (match.flickr) {
|
248
|
+
$.ajax({
|
249
|
+
// url : 'http://api.flickr.com/services/rest/',
|
250
|
+
url : 'flickr',
|
251
|
+
data : {
|
252
|
+
format : 'json',
|
253
|
+
method : 'flickr.photos.getinfo',
|
254
|
+
photo_id : match.flickr[1]
|
255
|
+
},
|
256
|
+
dataType : 'jsonp',
|
257
|
+
jsonp : 'jsoncallback',
|
258
|
+
success : function (d) {
|
259
|
+
thumbInsert(flickrThumb(d), flickrClick, $(this));
|
260
|
+
},
|
261
|
+
context : $(this),
|
262
|
+
jsonpCallback : 'flickrCallback' + match.flickr[1]
|
263
|
+
});
|
264
|
+
} else if (match.imageshack) {
|
265
|
+
thumbInsert(imgThumb(match.imageshack[1], 'th.',
|
266
|
+
match.imageshack[2]).data('href', match.imageshack[0]),
|
267
|
+
imgClick, $(this).html('imageshack.us'));
|
268
|
+
} else if (match.imgur) {
|
269
|
+
thumbInsert(imgThumb(match.imgur[1], 's', match.imgur[2]).data(
|
270
|
+
'href', match.imgur[0]), imgClick, $(this).html('imgur.com'));
|
271
|
+
} else if (match.mp3) {
|
272
|
+
$(this).before(objectTag(swf, 20, 200, [
|
273
|
+
{ name : 'bgcolor', value : '#000000' },
|
274
|
+
{ name : 'FlashVars', value : 'mp3=' + href },
|
275
|
+
{ name : 'movie', value : swf }
|
276
|
+
]));
|
277
|
+
} else if (match.s3) {
|
278
|
+
thumb = imgThumb(match.s3[1], 'th.', match.s3[2]);
|
279
|
+
|
280
|
+
if (match.s3[2].match(/^pdf$/i)) {
|
281
|
+
$(this).before(thumb).html('pdf');
|
235
282
|
} else {
|
236
|
-
|
237
|
-
|
238
|
-
|
283
|
+
if (my.isIphone()) {
|
284
|
+
$(this).html(thumb);
|
285
|
+
} else {
|
286
|
+
$(this).html('link');
|
287
|
+
$(this).before(thumb.data('href', match.s3[0]).click(
|
288
|
+
imgClick));
|
289
|
+
}
|
290
|
+
}
|
291
|
+
} else if (match.twitter) {
|
292
|
+
$.ajax({
|
293
|
+
// url : 'http://api.twitter.com/1/statuses/show/' +
|
294
|
+
url : '/twitter/1/statuses/show/' +
|
295
|
+
match.twitter[1] + '.json',
|
296
|
+
dataType : 'jsonp',
|
297
|
+
success : function (d) {
|
298
|
+
var nameLink = $('<a />', {
|
299
|
+
href: 'http://twitter.com/' + d.user.screen_name +
|
300
|
+
'/status/' + d.id,
|
301
|
+
text: '@' + d.user.screen_name
|
302
|
+
}),
|
303
|
+
tweet = $('<span />').addClass('tweet').append(
|
304
|
+
nameLink).append(': ').append(twitterAddLinks(
|
305
|
+
d.text));
|
306
|
+
|
307
|
+
thumbInsert(twitterThumb(d), null, nameLink);
|
308
|
+
|
309
|
+
$(this).replaceWith(tweet);
|
310
|
+
},
|
311
|
+
context : $(this),
|
312
|
+
jsonpCallback : 'twitterCallback' + match.twitter[1]
|
313
|
+
});
|
314
|
+
} else if (match.vimeo) {
|
315
|
+
$.ajax({
|
316
|
+
url : 'http://vimeo.com/api/v2/video/' + match.vimeo[1] +
|
317
|
+
'.json',
|
318
|
+
dataType : 'jsonp',
|
319
|
+
success : function (d) {
|
320
|
+
var video = d[0],
|
321
|
+
movie = 'http://vimeo.com/moogaloop.swf?clip_id=' +
|
322
|
+
video.id;
|
323
|
+
|
324
|
+
thumbInsert(vimeoThumb(video).data('embedHtml',
|
325
|
+
objectTag(movie, video.height, video.width, [
|
326
|
+
{ name : 'movie', value : movie }
|
327
|
+
])), vimeoClick, $(this));
|
328
|
+
},
|
329
|
+
context : $(this),
|
330
|
+
jsonpCallback : 'vimeoCallback' + match.vimeo[1]
|
331
|
+
});
|
332
|
+
} else if (match.youtube) {
|
333
|
+
thumbInsert(youtubeThumb(match.youtube[1]), youtubeClick, $(this));
|
334
|
+
} else {
|
335
|
+
// Apple touch icon if available
|
336
|
+
hostMatch = hostRe.exec(href);
|
337
|
+
if (hostMatch) {
|
338
|
+
host = hostMatch[1];
|
339
|
+
if ($.inArray(host, config.apple_icon_hosts) > -1) {
|
340
|
+
thumbInsert(appleThumb(host), null, $(this));
|
341
|
+
}
|
239
342
|
}
|
240
343
|
}
|
241
|
-
}
|
242
|
-
$.ajax({
|
243
|
-
// url : 'http://api.twitter.com/1/statuses/show/' +
|
244
|
-
url : '/twitter/1/statuses/show/' +
|
245
|
-
match.twitter[1] + '.json',
|
246
|
-
dataType : 'jsonp',
|
247
|
-
success : function(d) {
|
248
|
-
var nameLink = $('<a />', {
|
249
|
-
href: 'http://twitter.com/' + d.user.screen_name,
|
250
|
-
text: d.user.screen_name
|
251
|
-
});
|
344
|
+
};
|
252
345
|
|
253
|
-
|
254
|
-
|
346
|
+
my.formatLi = function (d) {
|
347
|
+
var iconSize = 32,
|
348
|
+
li = $('<li />').append($('<a />', {
|
349
|
+
href : d.url,
|
350
|
+
text : d.title
|
351
|
+
}));
|
255
352
|
|
256
|
-
|
257
|
-
}
|
258
|
-
|
259
|
-
jsonpCallback : 'twitterCallback' + match.twitter[1]
|
260
|
-
});
|
261
|
-
} else if (match.vimeo) {
|
262
|
-
$.ajax({
|
263
|
-
url : 'http://vimeo.com/api/v2/video/' + match.vimeo[1] + '.json',
|
264
|
-
dataType : 'jsonp',
|
265
|
-
success : function(d) {
|
266
|
-
var video = d[0];
|
267
|
-
var movie = 'http://vimeo.com/moogaloop.swf?clip_id=' + video.id;
|
268
|
-
|
269
|
-
Murlsh.thumbInsert(Murlsh.vimeoThumb(video).data(
|
270
|
-
'embedHtml',
|
271
|
-
Murlsh.objectTag(movie, video.height, video.width, [
|
272
|
-
{ name : 'movie', value : movie }
|
273
|
-
])), Murlsh.vimeoClick, $(this));
|
274
|
-
},
|
275
|
-
context : $(this),
|
276
|
-
jsonpCallback : 'vimeoCallback' + match.vimeo[1]
|
277
|
-
});
|
278
|
-
} else if (match.youtube) {
|
279
|
-
Murlsh.thumbInsert(Murlsh.youtubeThumb(match.youtube[1]),
|
280
|
-
Murlsh.youtubeClick, $(this));
|
281
|
-
}
|
282
|
-
};
|
353
|
+
if (d.name) {
|
354
|
+
li.prepend($('<div />', { text : d.name }).addClass('name'));
|
355
|
+
}
|
283
356
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
357
|
+
if (d.email) {
|
358
|
+
li.prepend($('<div />').addClass('icon').append(
|
359
|
+
img('http://www.gravatar.com/avatar/' + d.email + '?s=' +
|
360
|
+
iconSize, d.name).attr({
|
361
|
+
width : iconSize,
|
362
|
+
height : iconSize
|
363
|
+
})));
|
364
|
+
}
|
290
365
|
|
291
|
-
|
292
|
-
|
293
|
-
}
|
366
|
+
return li;
|
367
|
+
};
|
294
368
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
}
|
303
|
-
}
|
369
|
+
my.iphoneInit = function () {
|
370
|
+
window.onorientationchange = function () {
|
371
|
+
var width = 450;
|
372
|
+
if (window.orientation === 0 || window.orientation === 180) {
|
373
|
+
width = 290;
|
374
|
+
}
|
375
|
+
$('#urls').width(width);
|
376
|
+
};
|
304
377
|
|
305
|
-
|
306
|
-
};
|
378
|
+
window.onorientationchange();
|
307
379
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
width = 290;
|
313
|
-
}
|
314
|
-
$('#urls').width(width);
|
380
|
+
$('a.feed').replaceWith($('<a />', {
|
381
|
+
href : '#bottom',
|
382
|
+
text : 'bottom'
|
383
|
+
}));
|
315
384
|
};
|
316
385
|
|
317
|
-
|
386
|
+
my.isIphone = function () {
|
387
|
+
return navigator.userAgent.match(/i(phone|pod)/i);
|
388
|
+
};
|
318
389
|
|
319
|
-
|
320
|
-
href : '#bottom',
|
321
|
-
text : 'bottom'
|
322
|
-
}));
|
390
|
+
return my;
|
323
391
|
};
|
324
392
|
|
325
|
-
$(document).ready(function() {
|
326
|
-
|
327
|
-
Murlsh
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
393
|
+
$(document).ready(function () {
|
394
|
+
$.getJSON('config', function (config) {
|
395
|
+
var murlsh = new Murlsh(config, $, navigator, window),
|
396
|
+
urls;
|
397
|
+
|
398
|
+
if (murlsh.isIphone()) {
|
399
|
+
murlsh.iphoneInit();
|
400
|
+
}
|
401
|
+
|
402
|
+
$('#submit').click(function () {
|
403
|
+
$.post('url', {
|
404
|
+
url : $('#url').val(),
|
405
|
+
via : $('#via').val(),
|
406
|
+
auth : $('#auth').val()
|
407
|
+
}, function (d) {
|
408
|
+
$.each(d, function (i, v) {
|
409
|
+
var li = murlsh.formatLi(v);
|
410
|
+
$('#urls > li:first').after(li);
|
411
|
+
$(li).children('a:first').each(murlsh.addExtra);
|
412
|
+
});
|
413
|
+
$('#url').val('');
|
414
|
+
$('#via').val('');
|
415
|
+
}, 'json');
|
416
|
+
});
|
417
|
+
|
418
|
+
urls = $('a.m');
|
419
|
+
|
420
|
+
urls.each(murlsh.addExtra);
|
421
|
+
|
422
|
+
/*
|
423
|
+
// experimental comment support, to enable uncomment and edit comments.json
|
424
|
+
$.getJSON('/js/comments.json', function (data) {
|
425
|
+
urls.each(function () {
|
426
|
+
var href = $(this).attr('href');
|
427
|
+
if (href in data) {
|
428
|
+
murlsh.addComments($(this), data[href]);
|
429
|
+
}
|
341
430
|
});
|
342
|
-
|
343
|
-
|
344
|
-
}, 'json');
|
431
|
+
});
|
432
|
+
*/
|
345
433
|
});
|
346
|
-
|
347
434
|
});
|
data/spec/auth_spec.rb
CHANGED
data/spec/dispatch_spec.rb
CHANGED
data/spec/doc_spec.rb
CHANGED
data/spec/markup_spec.rb
CHANGED
data/spec/unwrap_json_spec.rb
CHANGED
data/spec/uri_ask_spec.rb
CHANGED
data/spec/uri_spec.rb
CHANGED
data/spec/xhtml_response_spec.rb
CHANGED
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: 55
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 10
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.10.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: 2010-
|
18
|
+
date: 2010-08-05 00:00:00 -04:00
|
19
19
|
default_executable: murlsh
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -115,9 +115,25 @@ dependencies:
|
|
115
115
|
type: :runtime
|
116
116
|
version_requirements: *id006
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
118
|
+
name: push-notify
|
119
119
|
prerelease: false
|
120
120
|
requirement: &id007 !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
hash: 27
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
- 1
|
129
|
+
- 0
|
130
|
+
version: 0.1.0
|
131
|
+
type: :runtime
|
132
|
+
version_requirements: *id007
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: rack
|
135
|
+
prerelease: false
|
136
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
121
137
|
none: false
|
122
138
|
requirements:
|
123
139
|
- - ">="
|
@@ -129,11 +145,11 @@ dependencies:
|
|
129
145
|
- 0
|
130
146
|
version: 1.0.0
|
131
147
|
type: :runtime
|
132
|
-
version_requirements: *
|
148
|
+
version_requirements: *id008
|
133
149
|
- !ruby/object:Gem::Dependency
|
134
150
|
name: rack-cache
|
135
151
|
prerelease: false
|
136
|
-
requirement: &
|
152
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
137
153
|
none: false
|
138
154
|
requirements:
|
139
155
|
- - ">="
|
@@ -145,11 +161,11 @@ dependencies:
|
|
145
161
|
- 2
|
146
162
|
version: 0.5.2
|
147
163
|
type: :runtime
|
148
|
-
version_requirements: *
|
164
|
+
version_requirements: *id009
|
149
165
|
- !ruby/object:Gem::Dependency
|
150
166
|
name: rack-throttle
|
151
167
|
prerelease: false
|
152
|
-
requirement: &
|
168
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
153
169
|
none: false
|
154
170
|
requirements:
|
155
171
|
- - ">="
|
@@ -161,11 +177,11 @@ dependencies:
|
|
161
177
|
- 0
|
162
178
|
version: 0.3.0
|
163
179
|
type: :runtime
|
164
|
-
version_requirements: *
|
180
|
+
version_requirements: *id010
|
165
181
|
- !ruby/object:Gem::Dependency
|
166
182
|
name: sqlite3-ruby
|
167
183
|
prerelease: false
|
168
|
-
requirement: &
|
184
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
169
185
|
none: false
|
170
186
|
requirements:
|
171
187
|
- - ">="
|
@@ -177,11 +193,11 @@ dependencies:
|
|
177
193
|
- 1
|
178
194
|
version: 1.2.1
|
179
195
|
type: :runtime
|
180
|
-
version_requirements: *
|
196
|
+
version_requirements: *id011
|
181
197
|
- !ruby/object:Gem::Dependency
|
182
198
|
name: tinyatom
|
183
199
|
prerelease: false
|
184
|
-
requirement: &
|
200
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
185
201
|
none: false
|
186
202
|
requirements:
|
187
203
|
- - ">="
|
@@ -193,7 +209,7 @@ dependencies:
|
|
193
209
|
- 1
|
194
210
|
version: 0.1.1
|
195
211
|
type: :runtime
|
196
|
-
version_requirements: *
|
212
|
+
version_requirements: *id012
|
197
213
|
description: url sharing site framework with easy adding, title lookup, atom feed, thumbnails and embedding
|
198
214
|
email: matthewm@boedicker.org
|
199
215
|
executables:
|
@@ -214,6 +230,7 @@ files:
|
|
214
230
|
- config.yaml
|
215
231
|
- lib/murlsh.rb
|
216
232
|
- lib/murlsh/auth.rb
|
233
|
+
- lib/murlsh/config_server.rb
|
217
234
|
- lib/murlsh/dispatch.rb
|
218
235
|
- lib/murlsh/doc.rb
|
219
236
|
- lib/murlsh/etag_add_encoding.rb
|
@@ -248,6 +265,7 @@ files:
|
|
248
265
|
- plugins/via_50_domain.rb
|
249
266
|
- public/css/jquery.jgrowl.css
|
250
267
|
- public/css/screen.css
|
268
|
+
- public/js/comments.json
|
251
269
|
- public/js/jquery-1.4.2.min.js
|
252
270
|
- public/js/jquery.jgrowl_compressed.js
|
253
271
|
- public/js/js.js
|