murlsh 0.7.0 → 0.8.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/Rakefile CHANGED
@@ -302,6 +302,7 @@ begin
302
302
  htmlentities 4.2.0
303
303
  json 1.2.3
304
304
  rack 1.0.0
305
+ rack-cache 0.5.2
305
306
  sqlite3-ruby 1.2.1
306
307
  }.each_slice(2) { |g,v| gemspec.add_dependency(g, ">= #{v}") }
307
308
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.0
1
+ 0.8.0
data/config.ru CHANGED
@@ -3,16 +3,29 @@ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
3
3
  %w{
4
4
  yaml
5
5
 
6
+ rack/cache
7
+
6
8
  murlsh
7
9
  }.each { |m| require m }
8
10
 
11
+ config = YAML.load_file('config.yaml')
12
+
9
13
  # use Rack::ShowExceptions
14
+ use Rack::Cache,
15
+ :verbose => true,
16
+ :metastore => 'file:tmp/cache/rack/meta',
17
+ :entitystore => 'file:tmp/cache/rack/body'
10
18
  use Rack::ConditionalGet
11
19
  use Murlsh::EtagAddEncoding
12
20
  use Rack::Deflater
21
+ use Murlsh::FarFutureExpires, :patterns => %r{\.gen\.(css|js)$}
22
+
23
+ feed_path = URI.join(config.fetch('root_url'), config.fetch('feed_file')).path
24
+ use Murlsh::MustRevalidate, :patterns => %r{^#{Regexp.escape(feed_path)}$}
25
+
13
26
  use Rack::Static, :urls => %w{/css /js /swf}, :root => 'public'
14
27
  use Rack::Static, :urls => %w{/atom.xml /rss.xml}
15
28
 
16
- config = YAML.load_file('config.yaml')
29
+ # use Rack::Lint
17
30
 
18
31
  run Murlsh::Dispatch.new(config)
data/config.yaml CHANGED
@@ -9,7 +9,6 @@ flickr_api_key:
9
9
  gravatar_size: 32
10
10
  js_files:
11
11
  - js/jquery-1.4.2.min.js
12
- - js/jquery.cookie.js
13
12
  - js/jquery.jgrowl_compressed.js
14
13
  - js/js.js
15
14
  meta_tag_description: URLs found interesting by Matthew M. Boedicker
@@ -21,13 +21,15 @@ module Murlsh
21
21
 
22
22
  url_server = Murlsh::UrlServer.new(@config, db)
23
23
  flickr_server = Murlsh::FlickrServer.new(@config)
24
+ twitter_server = Murlsh::TwitterServer.new
24
25
 
25
26
  root_path = URI(@config.fetch('root_url')).path
26
27
 
27
28
  @dispatch = [
28
- [/^GET #{root_path}(url)?$/, url_server.method(:get)],
29
- [/^POST #{root_path}(url)?$/, url_server.method(:post)],
30
- [/^GET \/flickr$/, flickr_server.method(:get)],
29
+ [%r{^GET #{root_path}(url)?$}, url_server.method(:get)],
30
+ [%r{^POST #{root_path}(url)?$}, url_server.method(:post)],
31
+ [%r{^GET /flickr$}, flickr_server.method(:get)],
32
+ [%r{^GET /twitter/.+$}, twitter_server.method(:get)],
31
33
  ]
32
34
  end
33
35
 
data/lib/murlsh/doc.rb CHANGED
@@ -25,16 +25,28 @@ module Murlsh
25
25
  # Check a list of xpaths in order and return the inner html of the first
26
26
  # one that is not nil.
27
27
  def xpath_search(xpaths)
28
- xpaths.each do |xpath|
28
+ [*xpaths].each do |xpath|
29
29
  selection = (self/xpath).first
30
- return selection.inner_html unless selection.nil?
30
+ if selection; return (yield selection); end
31
31
  end
32
32
  nil
33
33
  end
34
34
 
35
35
  # Get the title of the document.
36
36
  def title
37
- xpath_search(%w{//html/head/title //head/title //html/title //title})
37
+ xpath_search(%w{
38
+ //html/head/title
39
+ //head/title
40
+ //html/title
41
+ //title
42
+ }) { |node| node.inner_html }
43
+ end
44
+
45
+ # Get the meta description of the document.
46
+ def description
47
+ xpath_search(
48
+ "//html/head/meta[@name='description']"
49
+ ) { |node| node['content'] }
38
50
  end
39
51
 
40
52
  end
@@ -0,0 +1,37 @@
1
+ %w{
2
+ rack
3
+ rack/utils
4
+ }.each { |m| require m }
5
+
6
+ module Murlsh
7
+
8
+ # Rack middleware to set a far future expires header for urls that match
9
+ # patterns.
10
+ class FarFutureExpires
11
+
12
+ def initialize(app, options={})
13
+ @app = app
14
+ @patterns = options[:patterns] ? [*options[:patterns]] : []
15
+ @future = options[:future] || 'Wed, 22 Jun 2019 20:07:00 GMT'
16
+ end
17
+
18
+ def call(env)
19
+ status, headers, body = @app.call(env)
20
+
21
+ req = Rack::Request.new(env)
22
+
23
+ headers = Rack::Utils::HeaderHash.new(headers)
24
+
25
+ @patterns.each do |pattern|
26
+ if pattern.match(req.path)
27
+ headers['Expires'] = @future
28
+ break
29
+ end
30
+ end
31
+
32
+ [status, headers, body]
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -1,4 +1,5 @@
1
1
  %w{
2
+ digest/sha1
2
3
  open-uri
3
4
 
4
5
  json
@@ -7,16 +8,15 @@ rack
7
8
 
8
9
  module Murlsh
9
10
 
10
- # Proxy for Flickr rest API flickr.photos.getinfo call to support conditional
11
- # get.
11
+ # Proxy for Flickr rest API to support conditional get and caching.
12
12
  #
13
13
  # Passes along query string with api key added, returns result from Flickr
14
- # with content type set to application/json and last modified header set.
14
+ # with cache-control, etag and last-modified headers set.
15
15
  class FlickrServer
16
16
 
17
17
  def initialize(config); @config = config; end
18
18
 
19
- # Proxy a flickr.photos.getinfo request to the Flickr rest API.
19
+ # Proxy a request to the Flickr API.
20
20
  def get(req)
21
21
  resp = Rack::Response.new
22
22
 
@@ -26,9 +26,6 @@ module Murlsh
26
26
  q = params.map { |k,v| "#{URI.encode(k)}=#{URI.encode(v)}" }.join('&')
27
27
 
28
28
  json_wrapped = open("http://api.flickr.com/services/rest/?#{q}") do |f|
29
- # for some reason Firefox will not cache if it's text/plain, which is
30
- # what Flickr returns
31
- resp['Content-Type'] = 'application/json'
32
29
  f.read
33
30
  end
34
31
 
@@ -36,6 +33,9 @@ module Murlsh
36
33
 
37
34
  json_parsed = JSON.parse(json)
38
35
 
36
+ resp['Cache-Control'] = 'max-age=86400'
37
+ resp['Content-Type'] = 'application/json'
38
+ resp['ETag'] = "\"#{Digest::SHA1.hexdigest(json_wrapped)}\""
39
39
  resp['Last-Modified'] = Time.at(
40
40
  json_parsed['photo']['dates']['lastupdate'].to_i).httpdate
41
41
 
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
- sources.to_a.each do |src|
11
+ [*sources].each do |src|
12
12
  script('', :type => 'text/javascript',
13
13
  :src => "#{options[:prefix]}#{src}")
14
14
  end
@@ -49,7 +49,7 @@ module Murlsh
49
49
  # * :media - optional media attribute
50
50
  # * :prefix - prepended to all CSS urls
51
51
  def css(hrefs, options={})
52
- hrefs.to_a.each do |href|
52
+ [*hrefs].each do |href|
53
53
  attrs = {
54
54
  :href => "#{options[:prefix]}#{href}",
55
55
  :rel => 'stylesheet',
@@ -0,0 +1,36 @@
1
+ %w{
2
+ rack
3
+ rack/utils
4
+ }.each { |m| require m }
5
+
6
+ module Murlsh
7
+
8
+ # Rack middleware to force caches to always revalidate for urls that match
9
+ # patterns.
10
+ class MustRevalidate
11
+
12
+ def initialize(app, options={})
13
+ @app = app
14
+ @patterns = options[:patterns] ? [*options[:patterns]] : []
15
+ end
16
+
17
+ def call(env)
18
+ status, headers, body = @app.call(env)
19
+
20
+ req = Rack::Request.new(env)
21
+
22
+ headers = Rack::Utils::HeaderHash.new(headers)
23
+
24
+ @patterns.each do |pattern|
25
+ if pattern.match(req.path)
26
+ headers['Cache-Control'] = 'must-revalidate, max-age=0'
27
+ break
28
+ end
29
+ end
30
+
31
+ [status, headers, body]
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,44 @@
1
+ %w{
2
+ digest/sha1
3
+ open-uri
4
+
5
+ json
6
+ rack
7
+ }.each { |m| require m }
8
+
9
+ module Murlsh
10
+
11
+ # Proxy for Twitter rest API to support conditional get and caching.
12
+ #
13
+ # Passes along path and query string, returns result from Twitter with
14
+ # cache-control, etag and last-modified headers set.
15
+ class TwitterServer
16
+
17
+ # Proxy a request to the Twitter API.
18
+ def get(req)
19
+ resp = Rack::Response.new
20
+
21
+ twitter_url = URI.join('http://api.twitter.com',
22
+ req.fullpath[/twitter\/(.+)/, 1])
23
+
24
+ json_wrapped = open(twitter_url) do |f|
25
+ resp['Content-Type'] = f.content_type
26
+ f.read
27
+ end
28
+
29
+ json = /.+?\((.+)\)/.match(json_wrapped)[1]
30
+
31
+ json_parsed = JSON.parse(json)
32
+
33
+ resp['Cache-Control'] = 'max-age=86400'
34
+ resp['ETag'] = "\"#{Digest::SHA1.hexdigest(json_wrapped)}\""
35
+ resp['Last-Modified'] = Time.parse(json_parsed['created_at']).httpdate
36
+
37
+ resp.body = json_wrapped
38
+
39
+ resp
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -41,26 +41,61 @@ module Murlsh
41
41
  # Get the HTML title.
42
42
  #
43
43
  # Options:
44
- # * :failproof - if true hide all exceptions and return empty string on failure
44
+ # * :failproof - if true hide all exceptions and return url on failure
45
45
  # * :headers - hash of headers to send in request
46
46
  def title(options={})
47
47
  return @title if defined?(@title)
48
- options[:headers] = default_headers.merge(options.fetch(:headers, {}))
49
48
 
50
49
  @title = to_s
51
- if might_have_title?(options)
50
+
51
+ d = doc(options)
52
+
53
+ if d and d.title and !d.title.empty?
54
+ @title = decode(d.title)
55
+ end
56
+
57
+ @title
58
+ end
59
+
60
+ # Get the HTML meta description.
61
+ #
62
+ # Options:
63
+ # * :failproof - if true hide all exceptions and return empty string on failure
64
+ # * :headers - hash of headers to send in request
65
+ def description(options={})
66
+ return @description if defined?(@description)
67
+
68
+ @description = ''
69
+
70
+ d = doc(options)
71
+
72
+ if d and d.description and !d.description.empty?
73
+ @description = decode(d.description)
74
+ end
75
+
76
+ @description
77
+ end
78
+
79
+ # Get the parsed Hpricot doc at this url.
80
+ #
81
+ # Options:
82
+ # * :failproof - if true hide all exceptions and return empty string on failure
83
+ # * :headers - hash of headers to send in request
84
+ def doc(options={})
85
+ return @doc if defined?(@doc)
86
+ options[:headers] = default_headers.merge(options.fetch(:headers, {}))
87
+
88
+ @doc = nil
89
+ if html?(options)
52
90
  Murlsh::failproof(options) do
53
91
  self.open(options[:headers]) do |f|
54
- doc = Hpricot(f).extend(Murlsh::Doc)
92
+ @doc = Hpricot(f).extend(Murlsh::Doc)
55
93
 
56
- if doc.title and !doc.title.empty?
57
- @title = HTMLEntities.new.decode(Iconv.conv('utf-8',
58
- doc.charset || f.charset, doc.title))
59
- end
94
+ @charset = @doc.charset || f.charset
60
95
  end
61
96
  end
62
97
  end
63
- @title
98
+ @doc
64
99
  end
65
100
 
66
101
  # Default headers sent with the request.
@@ -76,12 +111,17 @@ module Murlsh
76
111
  result
77
112
  end
78
113
 
79
- # Return true if the content type is likely to have a title that can be
80
- # parsed.
81
- def might_have_title?(options={})
114
+ # Return true if the content type is HTML.
115
+ def html?(options={})
82
116
  content_type(options)[/^text\/html/]
83
117
  end
84
118
 
119
+ # Convert from the character set of this url to utf-8 and decode HTML
120
+ # entities.
121
+ def decode(s)
122
+ HTMLEntities.new.decode(Iconv.conv('utf-8', @charset, s))
123
+ end
124
+
85
125
  end
86
126
 
87
127
  end
@@ -23,8 +23,9 @@ module Murlsh
23
23
  resp.set_content_type(req.env['HTTP_ACCEPT'], req.env['HTTP_USER_AGENT'])
24
24
 
25
25
  last_db_update = File::Stat.new(@config['db_file']).mtime
26
- resp['Last-Modified'] = last_db_update.httpdate
26
+ resp['Cache-Control'] = 'must-revalidate, max-age=0'
27
27
  resp['ETag'] = "W/\"#{last_db_update.to_i}#{req.params.sort}\""
28
+ resp['Last-Modified'] = last_db_update.httpdate
28
29
 
29
30
  resp.body = Murlsh::UrlBody.new(@config, @db, req)
30
31
 
@@ -57,11 +58,6 @@ module Murlsh
57
58
  resp = Rack::Response.new([mu].to_json, 200, {
58
59
  'Content-Type' => 'application/json' })
59
60
 
60
- resp.set_cookie('auth',
61
- :expires => Time.mktime(2015, 6, 22),
62
- :path => '/',
63
- :value => auth)
64
-
65
61
  resp
66
62
  else
67
63
  Rack::Response.new('Permission denied', 403, {
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.7.0"
8
+ s.version = "0.8.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-04-10}
12
+ s.date = %q{2010-04-25}
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}
@@ -34,12 +34,15 @@ Gem::Specification.new do |s|
34
34
  "lib/murlsh/doc.rb",
35
35
  "lib/murlsh/etag_add_encoding.rb",
36
36
  "lib/murlsh/failproof.rb",
37
+ "lib/murlsh/far_future_expires.rb",
37
38
  "lib/murlsh/flickr_server.rb",
38
39
  "lib/murlsh/markup.rb",
40
+ "lib/murlsh/must_revalidate.rb",
39
41
  "lib/murlsh/openlock.rb",
40
42
  "lib/murlsh/plugin.rb",
41
43
  "lib/murlsh/sqlite3_adapter.rb",
42
44
  "lib/murlsh/time_ago.rb",
45
+ "lib/murlsh/twitter_server.rb",
43
46
  "lib/murlsh/uri.rb",
44
47
  "lib/murlsh/uri_ask.rb",
45
48
  "lib/murlsh/url.rb",
@@ -52,6 +55,7 @@ Gem::Specification.new do |s|
52
55
  "plugins/add_post_50_update_rss.rb",
53
56
  "plugins/add_post_60_notify_hubs.rb",
54
57
  "plugins/add_pre_50_lookup_content_type_title.rb",
58
+ "plugins/add_pre_60_github_title.rb",
55
59
  "plugins/hostrec_50_redundant.rb",
56
60
  "plugins/hostrec_60_skip.rb",
57
61
  "plugins/time_50_ago.rb",
@@ -59,7 +63,6 @@ Gem::Specification.new do |s|
59
63
  "public/css/jquery.jgrowl.css",
60
64
  "public/css/screen.css",
61
65
  "public/js/jquery-1.4.2.min.js",
62
- "public/js/jquery.cookie.js",
63
66
  "public/js/jquery.jgrowl_compressed.js",
64
67
  "public/js/js.js",
65
68
  "public/swf/player_mp3_mini.swf",
@@ -104,6 +107,7 @@ Gem::Specification.new do |s|
104
107
  s.add_runtime_dependency(%q<htmlentities>, [">= 4.2.0"])
105
108
  s.add_runtime_dependency(%q<json>, [">= 1.2.3"])
106
109
  s.add_runtime_dependency(%q<rack>, [">= 1.0.0"])
110
+ s.add_runtime_dependency(%q<rack-cache>, [">= 0.5.2"])
107
111
  s.add_runtime_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
108
112
  else
109
113
  s.add_dependency(%q<activerecord>, [">= 2.3.4"])
@@ -113,6 +117,7 @@ Gem::Specification.new do |s|
113
117
  s.add_dependency(%q<htmlentities>, [">= 4.2.0"])
114
118
  s.add_dependency(%q<json>, [">= 1.2.3"])
115
119
  s.add_dependency(%q<rack>, [">= 1.0.0"])
120
+ s.add_dependency(%q<rack-cache>, [">= 0.5.2"])
116
121
  s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
117
122
  end
118
123
  else
@@ -123,6 +128,7 @@ Gem::Specification.new do |s|
123
128
  s.add_dependency(%q<htmlentities>, [">= 4.2.0"])
124
129
  s.add_dependency(%q<json>, [">= 1.2.3"])
125
130
  s.add_dependency(%q<rack>, [">= 1.0.0"])
131
+ s.add_dependency(%q<rack-cache>, [">= 0.5.2"])
126
132
  s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.1"])
127
133
  end
128
134
  end
@@ -0,0 +1,22 @@
1
+ %w{
2
+ murlsh
3
+ }.each { |m| require m }
4
+
5
+ module Murlsh
6
+
7
+ # Github project page titles are not very descriptive so add meta description
8
+ # to title.
9
+ class AddPre60GithubTitle < Plugin
10
+
11
+ Hook = 'add_pre'
12
+
13
+ def self.run(url, config)
14
+ if url.url[%r{http://github.com/\w+/\w+}]
15
+ ask = URI(url.url).extend(Murlsh::UriAsk)
16
+ url.title << " - #{ask.description}" unless ask.description.empty?
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
data/public/js/js.js CHANGED
@@ -170,7 +170,7 @@ Murlsh.hrefRes = {
170
170
  s3 :
171
171
  /^(http:\/\/static\.mmb\.s3\.amazonaws\.com\/[\w\-]+\.)(jpe?g|gif|pdf|png)$/i,
172
172
  twitter :
173
- /^http:\/\/twitter\.com\/\w+\/statuses\/(\d+)$/i,
173
+ /^http:\/\/twitter\.com\/\w+\/status(?:es)?\/(\d+)$/i,
174
174
  vimeo :
175
175
  /^http:\/\/(?:www\.)?vimeo\.com\/(\d+)$/i,
176
176
  youtube :
@@ -236,8 +236,9 @@ Murlsh.addExtra = function() {
236
236
  }
237
237
  } else if (match.twitter) {
238
238
  $.ajax({
239
- url : 'http://api.twitter.com/1/statuses/show/' + match.twitter[1] +
240
- '.json',
239
+ // url : 'http://api.twitter.com/1/statuses/show/' +
240
+ url : '/twitter/1/statuses/show/' +
241
+ match.twitter[1] + '.json',
241
242
  dataType : 'jsonp',
242
243
  success : function(d) {
243
244
  var nameLink = $('<a />', {
@@ -254,7 +255,8 @@ Murlsh.addExtra = function() {
254
255
  width : '48'
255
256
  }), null, nameLink);
256
257
  },
257
- context : $(this)
258
+ context : $(this),
259
+ jsonpCallback : 'twitterCallback' + match.twitter[1]
258
260
  });
259
261
  } else if (match.vimeo) {
260
262
  $.ajax({
@@ -318,6 +320,10 @@ Murlsh.iphoneInit = function() {
318
320
  href : '#bottom',
319
321
  text : 'bottom'
320
322
  }));
323
+
324
+ // change input types to html5 to make typing easier
325
+ $('#q').attr('type', 'search');
326
+ $('#url,#via').attr('type', 'url');
321
327
  };
322
328
 
323
329
  $(document).ready(function() {
@@ -342,7 +348,4 @@ $(document).ready(function() {
342
348
  }, 'json');
343
349
  });
344
350
 
345
- if ($.cookie('auth')) {
346
- $('#auth').val($.cookie('auth'));
347
- }
348
351
  });
data/spec/doc_spec.rb CHANGED
@@ -8,10 +8,13 @@ murlsh
8
8
 
9
9
  describe Murlsh::Doc do
10
10
 
11
- it 'should get the right title from an HTML page that has one' do
12
- html = <<eos
11
+ context 'when html has everything' do
12
+ subject do
13
+ html = <<eos
13
14
  <html>
14
15
  <head>
16
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
17
+ <meta name="description" content="the description" />
15
18
  <title>the title</title>
16
19
  </head>
17
20
  <body>
@@ -19,9 +22,31 @@ describe Murlsh::Doc do
19
22
  </body>
20
23
  </html>
21
24
  eos
25
+ Hpricot(html).extend(Murlsh::Doc)
26
+ end
22
27
 
23
- doc = Hpricot(html).extend(Murlsh::Doc)
24
- doc.title.should == 'the title'
28
+ its(:charset) { should == 'utf-8' }
29
+ its(:title) { should == 'the title' }
30
+ its(:description) { should == 'the description' }
31
+ end
32
+
33
+ context 'when html has nothing' do
34
+ subject do
35
+ html = <<eos
36
+ <html>
37
+ <head>
38
+ </head>
39
+ <body>
40
+ <h1>hi</h1>
41
+ </body>
42
+ </html>
43
+ eos
44
+ Hpricot(html).extend(Murlsh::Doc)
45
+ end
46
+
47
+ its(:charset) { should be_nil }
48
+ its(:title) { should be_nil }
49
+ its(:description) { should be_nil }
25
50
  end
26
51
 
27
52
  end
@@ -6,7 +6,7 @@ murlsh
6
6
 
7
7
  describe Murlsh::YamlOrderedHash do
8
8
 
9
- it 'should generate yaml with hash keys in sorted order' do
9
+ subject do
10
10
  h = {
11
11
  'd' => 4,
12
12
  'a' => 1,
@@ -15,14 +15,15 @@ describe Murlsh::YamlOrderedHash do
15
15
  }
16
16
 
17
17
  h.extend(Murlsh::YamlOrderedHash)
18
-
19
- h.to_yaml.should == <<EOS
18
+ end
19
+
20
+ its(:to_yaml) { should == <<EOS
20
21
  ---
21
22
  a: 1
22
23
  b: 2
23
24
  c: 3
24
25
  d: 4
25
26
  EOS
26
- end
27
+ }
27
28
 
28
29
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 7
7
+ - 8
8
8
  - 0
9
- version: 0.7.0
9
+ version: 0.8.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Matthew M. Boedicker
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-10 00:00:00 -04:00
17
+ date: 2010-04-25 00:00:00 -04:00
18
18
  default_executable: murlsh
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -116,9 +116,23 @@ dependencies:
116
116
  type: :runtime
117
117
  version_requirements: *id007
118
118
  - !ruby/object:Gem::Dependency
119
- name: sqlite3-ruby
119
+ name: rack-cache
120
120
  prerelease: false
121
121
  requirement: &id008 !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ segments:
126
+ - 0
127
+ - 5
128
+ - 2
129
+ version: 0.5.2
130
+ type: :runtime
131
+ version_requirements: *id008
132
+ - !ruby/object:Gem::Dependency
133
+ name: sqlite3-ruby
134
+ prerelease: false
135
+ requirement: &id009 !ruby/object:Gem::Requirement
122
136
  requirements:
123
137
  - - ">="
124
138
  - !ruby/object:Gem::Version
@@ -128,7 +142,7 @@ dependencies:
128
142
  - 1
129
143
  version: 1.2.1
130
144
  type: :runtime
131
- version_requirements: *id008
145
+ version_requirements: *id009
132
146
  description: url sharing site framework with easy adding, title lookup, atom feed, thumbnails and embedding
133
147
  email: matthewm@boedicker.org
134
148
  executables:
@@ -154,12 +168,15 @@ files:
154
168
  - lib/murlsh/doc.rb
155
169
  - lib/murlsh/etag_add_encoding.rb
156
170
  - lib/murlsh/failproof.rb
171
+ - lib/murlsh/far_future_expires.rb
157
172
  - lib/murlsh/flickr_server.rb
158
173
  - lib/murlsh/markup.rb
174
+ - lib/murlsh/must_revalidate.rb
159
175
  - lib/murlsh/openlock.rb
160
176
  - lib/murlsh/plugin.rb
161
177
  - lib/murlsh/sqlite3_adapter.rb
162
178
  - lib/murlsh/time_ago.rb
179
+ - lib/murlsh/twitter_server.rb
163
180
  - lib/murlsh/uri.rb
164
181
  - lib/murlsh/uri_ask.rb
165
182
  - lib/murlsh/url.rb
@@ -172,6 +189,7 @@ files:
172
189
  - plugins/add_post_50_update_rss.rb
173
190
  - plugins/add_post_60_notify_hubs.rb
174
191
  - plugins/add_pre_50_lookup_content_type_title.rb
192
+ - plugins/add_pre_60_github_title.rb
175
193
  - plugins/hostrec_50_redundant.rb
176
194
  - plugins/hostrec_60_skip.rb
177
195
  - plugins/time_50_ago.rb
@@ -179,7 +197,6 @@ files:
179
197
  - public/css/jquery.jgrowl.css
180
198
  - public/css/screen.css
181
199
  - public/js/jquery-1.4.2.min.js
182
- - public/js/jquery.cookie.js
183
200
  - public/js/jquery.jgrowl_compressed.js
184
201
  - public/js/js.js
185
202
  - public/swf/player_mp3_mini.swf
@@ -1,96 +0,0 @@
1
- /**
2
- * Cookie plugin
3
- *
4
- * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
5
- * Dual licensed under the MIT and GPL licenses:
6
- * http://www.opensource.org/licenses/mit-license.php
7
- * http://www.gnu.org/licenses/gpl.html
8
- *
9
- */
10
-
11
- /**
12
- * Create a cookie with the given name and value and other optional parameters.
13
- *
14
- * @example $.cookie('the_cookie', 'the_value');
15
- * @desc Set the value of a cookie.
16
- * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
17
- * @desc Create a cookie with all available options.
18
- * @example $.cookie('the_cookie', 'the_value');
19
- * @desc Create a session cookie.
20
- * @example $.cookie('the_cookie', null);
21
- * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
22
- * used when the cookie was set.
23
- *
24
- * @param String name The name of the cookie.
25
- * @param String value The value of the cookie.
26
- * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
27
- * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
28
- * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
29
- * If set to null or omitted, the cookie will be a session cookie and will not be retained
30
- * when the the browser exits.
31
- * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
32
- * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
33
- * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
34
- * require a secure protocol (like HTTPS).
35
- * @type undefined
36
- *
37
- * @name $.cookie
38
- * @cat Plugins/Cookie
39
- * @author Klaus Hartl/klaus.hartl@stilbuero.de
40
- */
41
-
42
- /**
43
- * Get the value of a cookie with the given name.
44
- *
45
- * @example $.cookie('the_cookie');
46
- * @desc Get the value of a cookie.
47
- *
48
- * @param String name The name of the cookie.
49
- * @return The value of the cookie.
50
- * @type String
51
- *
52
- * @name $.cookie
53
- * @cat Plugins/Cookie
54
- * @author Klaus Hartl/klaus.hartl@stilbuero.de
55
- */
56
- jQuery.cookie = function(name, value, options) {
57
- if (typeof value != 'undefined') { // name and value given, set cookie
58
- options = options || {};
59
- if (value === null) {
60
- value = '';
61
- options.expires = -1;
62
- }
63
- var expires = '';
64
- if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
65
- var date;
66
- if (typeof options.expires == 'number') {
67
- date = new Date();
68
- date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
69
- } else {
70
- date = options.expires;
71
- }
72
- expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
73
- }
74
- // CAUTION: Needed to parenthesize options.path and options.domain
75
- // in the following expressions, otherwise they evaluate to undefined
76
- // in the packed version for some reason...
77
- var path = options.path ? '; path=' + (options.path) : '';
78
- var domain = options.domain ? '; domain=' + (options.domain) : '';
79
- var secure = options.secure ? '; secure' : '';
80
- document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
81
- } else { // only name given, get cookie
82
- var cookieValue = null;
83
- if (document.cookie && document.cookie != '') {
84
- var cookies = document.cookie.split(';');
85
- for (var i = 0; i < cookies.length; i++) {
86
- var cookie = jQuery.trim(cookies[i]);
87
- // Does this cookie string begin with the name we want?
88
- if (cookie.substring(0, name.length + 1) == (name + '=')) {
89
- cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
90
- break;
91
- }
92
- }
93
- }
94
- return cookieValue;
95
- }
96
- };