murlsh 0.3.0 → 0.4.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/.gitignore CHANGED
@@ -1 +1,3 @@
1
1
  *~
2
+ public/css/*.gen.css
3
+ public/js/*.gen.js
data/.htaccess CHANGED
@@ -5,3 +5,7 @@ AddOutputFilterByType DEFLATE application/xhtml+xml
5
5
  AddOutputFilterByType DEFLATE application/xml
6
6
  AddOutputFilterByType DEFLATE text/css
7
7
  AddOutputFilterByType DEFLATE text/html
8
+
9
+ <FilesMatch "\.gen\.(css|js)$">
10
+ Header add Expires "Wed, 22 Jun 2019 20:07:00 GMT"
11
+ </FilesMatch>
data/README.textile CHANGED
@@ -30,3 +30,5 @@ edit config.yaml
30
30
  rake db:init user:add
31
31
  </code>
32
32
  </pre>
33
+
34
+ Questions and comments: "matthewm@boedicker.org":mailto:matthewm@boedicker.org
data/Rakefile CHANGED
@@ -1,21 +1,27 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
2
 
3
- require 'rubygems'
3
+ %w{
4
+ cgi
5
+ digest/md5
6
+ net/http
7
+ pp
8
+ uri
9
+ yaml
4
10
 
5
- require 'murlsh'
11
+ rubygems
6
12
 
7
- require 'flog'
8
- require 'rake/testtask'
9
- require 'sqlite3'
13
+ flog
14
+ rake/testtask
15
+ sqlite3
10
16
 
11
- require 'pp'
12
- require 'yaml'
17
+ murlsh
18
+ }.each { |d| require d }
13
19
 
14
20
  config = YAML.load_file('config.yaml')
15
21
 
16
22
  desc "Test remote content type fetch for a URL and show errors."
17
23
  task :content_type, :url do |t, args|
18
- puts Murlsh.get_content_type(args.url, :failproof => false)
24
+ puts Murlsh.get_content_type(args.url, :failproof => false, :debug => STDOUT)
19
25
  end
20
26
 
21
27
  namespace :db do
@@ -56,7 +62,8 @@ namespace :db do
56
62
  email TEXT,
57
63
  name TEXT,
58
64
  title TEXT,
59
- content_type TEXT);
65
+ content_type TEXT,
66
+ via TEXT);
60
67
  ")
61
68
  end
62
69
 
@@ -67,10 +74,12 @@ namespace :db do
67
74
 
68
75
  end
69
76
 
70
- namespace :dreamhost do
77
+ directory 'tmp'
71
78
 
72
- desc "Restart Passenger."
73
- task :restart do
79
+ namespace :passenger do
80
+
81
+ desc 'Restart Passenger.'
82
+ task :restart => ['tmp'] do
74
83
  open('tmp/restart.txt', 'w') { |f| }
75
84
  end
76
85
 
@@ -92,7 +101,7 @@ end
92
101
 
93
102
  desc "Test remote title fetch for a URL and show errors."
94
103
  task :title, :url do |t, args|
95
- puts Murlsh.get_title(args.url, :failproof => false)
104
+ puts Murlsh.get_title(args.url, :failproof => false, :debug => STDOUT)
96
105
  end
97
106
 
98
107
  desc 'Try to fetch the title for a url and update it in the database.'
@@ -124,9 +133,6 @@ end
124
133
 
125
134
  desc "Validate XHTML."
126
135
  task :validate do
127
- require 'cgi'
128
- require 'net/http'
129
-
130
136
  net_http = Net::HTTP.new('validator.w3.org', 80)
131
137
  #net_http.set_debug_output(STDOUT)
132
138
 
@@ -152,15 +158,93 @@ task :post_sh do
152
158
  #!/bin/sh
153
159
 
154
160
  URL="$1"
155
- AUTH="$2" # password can be passed as second parameter or hardcoded here
161
+ VIA="$2"
162
+ AUTH="$3" # password can be passed as second parameter or hardcoded here
156
163
 
157
164
  curl \\
158
165
  --data-urlencode "url=${URL}" \\
159
166
  --data-urlencode "auth=${AUTH}" \\
167
+ --data-urlencode "via=${VIA}" \\
160
168
  #{config.fetch('root_url')}
161
169
  EOS
162
170
  end
163
171
 
172
+ # Concatenate some files and return the result as a string.
173
+ def cat(in_files, sep=nil)
174
+ result = ''
175
+ in_files.each do |fname|
176
+ open(fname) do |h|
177
+ while (line = h.gets) do; result << line; end
178
+ result << sep if sep
179
+ end
180
+ end
181
+ result
182
+ end
183
+
184
+ directory 'public/css'
185
+
186
+ namespace :css do
187
+
188
+ desc 'Combine and compress css.'
189
+ task :compress => ['public/css'] do
190
+ combined = cat(config['css_files'].collect { |x| "public/#{x}" }, "\n")
191
+
192
+ md5sum = Digest::MD5.hexdigest(combined)
193
+
194
+ filename = "#{md5sum}.gen.css"
195
+
196
+ out = "public/css/#{filename}"
197
+
198
+ open(out, 'w') { |f| f.write(combined) }
199
+ puts "generated #{out}"
200
+
201
+ compressed_url = "css/#{filename}"
202
+
203
+ unless config['css_compressed'] == compressed_url
204
+ config['css_compressed'] = compressed_url
205
+ open('config.yaml', 'w') { |f| YAML.dump(config, f) }
206
+ puts "updated config with css_compressed = #{compressed_url}"
207
+ end
208
+ end
209
+
210
+ end
211
+
212
+ directory 'public/js'
213
+
214
+ namespace :js do
215
+
216
+ desc 'Combine and compress javascript.'
217
+ task :compress => ['public/js'] do
218
+ combined = cat(config['js_files'].collect { |x| "public/#{x}" } )
219
+
220
+ compressed = Net::HTTP.post_form(
221
+ URI.parse('http://closure-compiler.appspot.com/compile'), {
222
+ 'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
223
+ 'js_code' => combined,
224
+ 'output_format' => 'text',
225
+ 'output_info' => 'compiled_code',
226
+ }).body
227
+
228
+ md5sum = Digest::MD5.hexdigest(compressed)
229
+
230
+ filename = "#{md5sum}.gen.js"
231
+
232
+ out = "public/js/#{filename}"
233
+
234
+ open(out, 'w') { |f| f.write(compressed) }
235
+ puts "generated #{out}"
236
+
237
+ compressed_url = "js/#{filename}"
238
+
239
+ unless config['js_compressed'] == compressed_url
240
+ config['js_compressed'] = compressed_url
241
+ open('config.yaml', 'w') { |f| YAML.dump(config, f) }
242
+ puts "updated config with js_compressed = #{compressed_url}"
243
+ end
244
+ end
245
+
246
+ end
247
+
164
248
  def ask(prompt, sep=':')
165
249
  print "#{prompt}#{sep} "
166
250
  return STDIN.gets.chomp
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
data/config.yaml CHANGED
@@ -9,10 +9,11 @@ num_posts_feed: 25
9
9
  num_posts_page: 100
10
10
  page_title: mmb url share
11
11
  root_url: http://urls.matthewm.boedicker.org/
12
- css_prefix: css/
13
- img_prefix: img/
14
- js_prefix: js/
15
- swf_prefix: swf/
16
12
  css_files:
17
- - jquery.jgrowl.css
18
- - screen.css
13
+ - css/jquery.jgrowl.css
14
+ - css/screen.css
15
+ js_files:
16
+ - js/jquery-1.3.2.min.js
17
+ - js/jquery.cookie.js
18
+ - js/jquery.jgrowl_compressed.js
19
+ - js/js.js
@@ -37,20 +37,14 @@ module Murlsh
37
37
 
38
38
  # Generate the feed and write it to the filesystem with locking.
39
39
  def write(entries, path)
40
- open(path, 'w') do |f|
41
- f.flock(File::LOCK_EX)
42
-
43
- make(entries, :target => f)
44
-
45
- f.flock(File::LOCK_UN)
46
- end
40
+ Murlsh::openlock(path, 'w') { |f| make(entries, :target => f) }
47
41
  end
48
42
 
49
43
  # Build the feed using XML builder. Options are passed to
50
44
  # Builder::XmlMarkup.new.
51
45
  def make(entries, options={})
52
46
  xm = Builder::XmlMarkup.new(options)
53
- xm.instruct! :xml
47
+ xm.instruct!(:xml)
54
48
 
55
49
  xm.feed(:xmlns => 'http://www.w3.org/2005/Atom') {
56
50
  xm.id(@root_url)
data/lib/murlsh/auth.rb CHANGED
@@ -30,11 +30,9 @@ module Murlsh
30
30
 
31
31
  # Add a user to the authentication file.
32
32
  def add_user(username, email, password)
33
- open(@file, 'a') do |f|
34
- f.flock(File::LOCK_EX)
33
+ Murlsh::openlock(@file, 'a') do |f|
35
34
  f.write("#{[username, Digest::MD5.hexdigest(email),
36
35
  BCrypt::Password.create(password)].join(',')}\n")
37
- f.flock(File::LOCK_UN)
38
36
  end
39
37
  end
40
38
 
@@ -0,0 +1,12 @@
1
+ module Murlsh
2
+
3
+ module_function
4
+
5
+ # Open a file with an exclusive lock.
6
+ def openlock(*args)
7
+ open(*args) do |f|
8
+ f.flock(File::LOCK_EX) ; yield f ; f.flock(File::LOCK_UN)
9
+ end
10
+ end
11
+
12
+ end
@@ -38,7 +38,7 @@ module Murlsh
38
38
 
39
39
  # Regex host match to name of query string parameter.
40
40
  Qmap = {
41
- /^www\.google\.(bs|ca|com|cz|dk|es|fi|nl)(\/m)?\/search$/ => 'q',
41
+ /^www\.google\.(bs|ca|com|cz|dk|es|fi|it|nl|no)(\/m)?\/search$/ => 'q',
42
42
  /^www\.bing\.com\/search$/ => 'q',
43
43
  }
44
44
 
data/lib/murlsh/url.rb CHANGED
@@ -3,6 +3,10 @@ require 'active_record'
3
3
 
4
4
  require 'uri'
5
5
 
6
+ module URI
7
+ def domain; host[/[a-z\d-]+\.[a-z]{2,}(\.[a-z]{2})?$/].downcase; end
8
+ end
9
+
6
10
  module Murlsh
7
11
 
8
12
  # URL ActiveRecord.
@@ -21,11 +25,7 @@ module Murlsh
21
25
 
22
26
  # Return text showing what domain a link goes to.
23
27
  def hostrec
24
- begin
25
- domain = URI(url).host[/[a-z\d-]+\.[a-z]{2,}(\.[a-z]{2})?$/].downcase
26
- rescue Exception => e
27
- domain = nil
28
- end
28
+ domain = begin; URI(url).domain; rescue Exception; end
29
29
 
30
30
  domain = Murlsh::Plugin.hooks('hostrec').inject(domain) {
31
31
  |result,plugin| plugin.run(result, url, title) }
@@ -33,6 +33,16 @@ module Murlsh
33
33
  yield domain if domain
34
34
  end
35
35
 
36
+ # Yield the url that the url came from.
37
+ def viarec
38
+ if via
39
+ begin
40
+ yield URI(via)
41
+ rescue Exception
42
+ end
43
+ end
44
+ end
45
+
36
46
  # Return true if this url is an image.
37
47
  def is_image?
38
48
  %w{image/gif image/jpeg image/png}.include?(content_type)
@@ -6,7 +6,7 @@ module Murlsh
6
6
 
7
7
  def initialize(config, db, req)
8
8
  @config, @db, @req, @q = config, db, req, req.params['q']
9
- super(:indent => 2)
9
+ super(:indent => @config['xhtml_indent'] || 0)
10
10
  end
11
11
 
12
12
  # Fetch urls base on query string parameters.
@@ -56,7 +56,15 @@ module Murlsh
56
56
 
57
57
  a(mu.title.strip.gsub(/\s+/, ' '), :href => mu.url)
58
58
 
59
- mu.hostrec { |hostrec| span(hostrec, :class => 'host') }
59
+ mu.hostrec do |hostrec|
60
+ text!(' ')
61
+ span(hostrec, :class => 'host')
62
+ end
63
+ mu.viarec do |via|
64
+ span(:class => 'via') {
65
+ text!(' (via '); a(via.domain, :href => via); text!(')')
66
+ }
67
+ end
60
68
  span(", #{mu.time.fuzzy}", :class => 'date') if
61
69
  @config.fetch('show_dates', true) and mu.time
62
70
  last = mu
@@ -82,10 +90,7 @@ module Murlsh
82
90
  :viewport =>
83
91
  'width=device-width,minimum-scale=1.0,maximum-scale=1.0')
84
92
  google_verify
85
- css(@config.fetch('css_files', []),
86
- :prefix => @config.fetch('css_prefix', ''))
87
- css('phone.css', :media => 'only screen and (max-device-width: 480px)',
88
- :prefix => @config.fetch('css_prefix', ''))
93
+ css(@config['css_compressed'] || @config['css_files'])
89
94
  atom(@config.fetch('feed_file'))
90
95
  }
91
96
  end
@@ -128,6 +133,7 @@ module Murlsh
128
133
  form(:action => '', :method => 'post') {
129
134
  fieldset(:id => 'add') {
130
135
  self.p { add_form_input('Add URL:', 'url', 32) }
136
+ self.p { add_form_input('Via:', 'via', 32) }
131
137
  self.p {
132
138
  add_form_input('Password:', 'auth', 16, 'password')
133
139
  input(:type => 'button', :id => 'submit', :value => 'Add')
@@ -156,14 +162,7 @@ module Murlsh
156
162
  end
157
163
 
158
164
  # Required javascript builder.
159
- def js
160
- javascript(%w{
161
- jquery-1.3.2.min.js
162
- jquery.cookie.js
163
- jquery.jgrowl_compressed.js
164
- js.js
165
- }, :prefix => @config.fetch('js_prefix', ''))
166
- end
165
+ def js; javascript(@config['js_compressed'] || @config['js_files']); end
167
166
 
168
167
  end
169
168
 
@@ -10,8 +10,7 @@ module Murlsh
10
10
  class UrlServer
11
11
 
12
12
  def initialize(config, db)
13
- @config = config
14
- @db = db
13
+ @config, @db = config, db
15
14
  ActiveRecord::Base.default_timezone = :utc
16
15
 
17
16
  Dir['plugins/*.rb'].each { |p| load p }
@@ -35,11 +34,7 @@ module Murlsh
35
34
 
36
35
  # Respond to a POST request. Add the new url and return json.
37
36
  def post(req)
38
- resp = Rack::Response.new
39
-
40
- url = req.params['url']
41
-
42
- unless url.empty?
37
+ unless req.params['url'].empty?
43
38
  auth = req.params['auth']
44
39
  if user = auth.empty? ? nil : Murlsh::Auth.new(
45
40
  @config.fetch('auth_file')).auth(auth)
@@ -48,9 +43,10 @@ module Murlsh
48
43
 
49
44
  mu = Murlsh::Url.new do |u|
50
45
  u.time = Time.now.gmtime
51
- u.url = url
46
+ u.url = req.params['url']
52
47
  u.email = user[:email]
53
48
  u.name = user[:name]
49
+ u.via = req.params['via'] unless (req.params['via'] || []).empty?
54
50
  end
55
51
 
56
52
  Murlsh::Plugin.hooks('add_pre') { |p| p.run(mu, @config) }
@@ -59,25 +55,22 @@ module Murlsh
59
55
 
60
56
  Murlsh::Plugin.hooks('add_post') { |p| p.run(@config) }
61
57
 
62
- resp['Content-Type'] = 'application/json'
58
+ resp = Rack::Response.new([mu].to_json, 200, {
59
+ 'Content-Type' => 'application/json' })
63
60
 
64
61
  resp.set_cookie('auth',
65
62
  :expires => Time.mktime(2015, 6, 22),
66
63
  :path => '/',
67
64
  :value => auth)
68
65
 
69
- resp.body = [mu].to_json
66
+ resp
70
67
  else
71
- resp.status = 403
72
- resp['Content-Type'] = 'text/plain'
73
- resp.write('Permission denied')
68
+ Rack::Response.new('Permission denied', 403, {
69
+ 'Content-Type' => 'text/plain' })
74
70
  end
75
71
  else
76
- resp.status = 500
77
- resp['Content-Type'] = 'text/plain'
78
- resp.write('No url')
72
+ Rack::Response.new('No url', 500, { 'Content-Type' => 'text/plain' })
79
73
  end
80
- resp
81
74
  end
82
75
 
83
76
  end
data/lib/murlsh.rb CHANGED
@@ -2,6 +2,7 @@ require 'murlsh/auth'
2
2
  require 'murlsh/dispatch'
3
3
  require 'murlsh/get_content_type'
4
4
  require 'murlsh/get_title'
5
+ require 'murlsh/openlock'
5
6
  require 'murlsh/plugin'
6
7
  require 'murlsh/referrer'
7
8
  require 'murlsh/sqlite3_adapter'
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.3.0"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Matthew M. Boedicker"]
12
- s.date = %q{2009-11-05}
12
+ s.date = %q{2009-12-13}
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,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  "lib/murlsh/get_content_type.rb",
35
35
  "lib/murlsh/get_title.rb",
36
36
  "lib/murlsh/markup.rb",
37
+ "lib/murlsh/openlock.rb",
37
38
  "lib/murlsh/plugin.rb",
38
39
  "lib/murlsh/referrer.rb",
39
40
  "lib/murlsh/sqlite3_adapter.rb",
@@ -48,7 +49,6 @@ Gem::Specification.new do |s|
48
49
  "plugins/lookup_content_type_title.rb",
49
50
  "plugins/update_feed.rb",
50
51
  "public/css/jquery.jgrowl.css",
51
- "public/css/phone.css",
52
52
  "public/css/screen.css",
53
53
  "public/js/jquery-1.3.2.min.js",
54
54
  "public/js/jquery.cookie.js",
@@ -1,5 +1,6 @@
1
1
  body {
2
- font-family : sans-serif;
2
+ font-size : 1em;
3
+ line-height : 1.5em;
3
4
  }
4
5
 
5
6
  img {
@@ -8,7 +9,7 @@ img {
8
9
 
9
10
  #urls {
10
11
  list-style-type : none;
11
- width : 480px;
12
+ width : 600px;
12
13
  }
13
14
 
14
15
  li {
@@ -16,13 +17,6 @@ li {
16
17
  float : left;
17
18
  padding : 10px 20px 10px 10px;
18
19
  width : 100%;
19
- border-bottom : 1px solid #f6f6f6;
20
- }
21
-
22
- li.even {
23
- background-color : #eee;
24
- border-right : 1px solid #ddd;
25
- border-bottom : 1px solid #ccc;
26
20
  }
27
21
 
28
22
  div.icon {
@@ -30,10 +24,12 @@ div.icon {
30
24
  margin : 0 0.5em 0 0;
31
25
  }
32
26
 
33
- div.name {
34
- float : left;
35
- font-style : italic;
36
- margin-right : 0.5em;
27
+ a:link {
28
+ color : #000;
29
+ }
30
+
31
+ a:visited {
32
+ color : #808080;
37
33
  }
38
34
 
39
35
  a:link, a:visited, a:active {
@@ -44,6 +40,12 @@ a:hover {
44
40
  text-decoration : underline;
45
41
  }
46
42
 
43
+ div.name {
44
+ float : left;
45
+ font-style : italic;
46
+ margin-right : 0.5em;
47
+ }
48
+
47
49
  img.thumb, li object {
48
50
  float : left;
49
51
  margin-right : 10px;
@@ -92,3 +94,35 @@ div.jGrowl div.jGrowl-closer {
92
94
  float : right;
93
95
  width : auto;
94
96
  }
97
+
98
+ /* iphone */
99
+ @media screen and (max-device-width : 480px) {
100
+
101
+ a.feed {
102
+ display : none;
103
+ }
104
+
105
+ body {
106
+ margin : 0;
107
+ padding : 0;
108
+ }
109
+
110
+ #urls {
111
+ margin : 0;
112
+ padding-left : 0;
113
+ width : 290px;
114
+ }
115
+
116
+ #urls li {
117
+ overflow : hidden;
118
+ }
119
+
120
+ input#q {
121
+ width : 130px;
122
+ }
123
+
124
+ input#url {
125
+ width : 160px;
126
+ }
127
+
128
+ }
data/public/js/js.js CHANGED
@@ -1,23 +1,46 @@
1
+ "use strict";
2
+
1
3
  var Murlsh = {};
2
4
 
3
- Murlsh.new_img = function(src, text) {
4
- return $('<img />').attr({
5
+ Murlsh.tag = function(name, attr, text) {
6
+ var klass;
7
+ var result = $('<' + name + ' />');
8
+
9
+ if (attr) {
10
+ if (attr.klass) {
11
+ klass = attr.klass;
12
+ delete attr.klass;
13
+ }
14
+ result.attr(attr);
15
+ }
16
+
17
+ if (text) {
18
+ result.text(text);
19
+ }
20
+
21
+ if (klass) {
22
+ result.addClass(klass);
23
+ }
24
+
25
+ return result;
26
+ };
27
+
28
+ Murlsh.img = function(src, text) {
29
+ text = text || '';
30
+ return Murlsh.tag('img', {
5
31
  src : src,
6
32
  alt : text,
7
33
  title : text
8
34
  });
9
35
  };
10
36
 
11
- Murlsh.close = function() {
12
- $(this).parent().remove();
13
- };
14
-
15
- Murlsh.closer_add = function(x) {
16
- var html = (typeof x == 'object') ? $('<div />').append(x).html() : x;
37
+ Murlsh.closer_add = function(x, header) {
38
+ var html = (typeof x == 'object') ? Murlsh.tag('div').append(x).html() : x;
17
39
 
18
40
  $.jGrowl(html, {
19
41
  closeTemplate : 'X',
20
42
  glue :'before',
43
+ header : header,
21
44
  sticky : true
22
45
  });
23
46
  };
@@ -33,34 +56,40 @@ Murlsh.object_tag = function(data, height, width, params) {
33
56
  };
34
57
 
35
58
  Murlsh.flickr_thumb = function(d) {
36
- var base = 'http://farm' + d.photo.farm + '.static.flickr.com/' +
37
- d.photo.server + '/' + d.photo.id + '_';
38
- var zoom;
39
- if (d.photo.originalsecret) {
40
- zoom = base + d.photo.originalsecret + '_o.' + d.photo.originalformat;
41
- } else {
42
- zoom = base + d.photo.secret + '_m.jpg';
43
- }
59
+ var photo = d.photo;
60
+ if (d.stat == 'ok') {
61
+ var base = 'http://farm' + photo.farm + '.static.flickr.com/' +
62
+ photo.server + '/' + photo.id + '_';
63
+ var zoom;
64
+ if (photo.originalsecret) {
65
+ zoom = base + photo.originalsecret + '_o.' + photo.originalformat;
66
+ } else {
67
+ zoom = base + photo.secret + '_m.jpg';
68
+ }
44
69
 
45
- return Murlsh.new_img(base + d.photo.secret + '_s.jpg',
46
- d.photo.title._content).addClass(
47
- 'thumb flickr').data('zoom', zoom);
70
+ var owner = photo.owner;
71
+ return Murlsh.img(base + photo.secret + '_s.jpg',
72
+ photo.title._content +
73
+ (owner && owner.username ? ' by ' + owner.username : '')
74
+ ).addClass('thumb flickr').data('zoom', zoom);
75
+ }
48
76
  };
49
77
 
50
78
  Murlsh.flickr_click = function() {
51
- Murlsh.closer_add(Murlsh.new_img($(this).data('zoom'), ''));
79
+ Murlsh.closer_add(Murlsh.img($(this).data('zoom')));
52
80
  };
53
81
 
54
- Murlsh.imageshack_thumb = function(prefix, ext) {
55
- return Murlsh.new_img(prefix + 'th.' + ext, '').addClass('thumb imgshack');
82
+ Murlsh.img_thumb = function(prefix, ext) {
83
+ return Murlsh.img(prefix + 'th.' +
84
+ (ext.match(/^pdf$/i) ? 'png' : ext)).addClass('thumb');
56
85
  };
57
86
 
58
- Murlsh.imageshack_click = function() {
59
- Murlsh.closer_add(Murlsh.new_img($(this).data('href'), ''));
87
+ Murlsh.img_click = function() {
88
+ Murlsh.closer_add(Murlsh.img($(this).data('href')));
60
89
  };
61
90
 
62
91
  Murlsh.vimeo_thumb = function(d) {
63
- return Murlsh.new_img(d.thumbnail_url, d.title).addClass('thumb vimeo').attr({
92
+ return Murlsh.img(d.thumbnail_url, d.title).addClass('thumb vimeo').attr({
64
93
  height : d.thumbnail_height,
65
94
  width : d.thumbnail_width
66
95
  });
@@ -71,7 +100,7 @@ Murlsh.vimeo_click = function() {
71
100
  };
72
101
 
73
102
  Murlsh.youtube_thumb = function(id) {
74
- return Murlsh.new_img('http://img.youtube.com/vi/' + id + '/1.jpg',
103
+ return Murlsh.img('http://img.youtube.com/vi/' + id + '/1.jpg',
75
104
  'click to watch').addClass('thumb youtube').data('id', id);
76
105
  };
77
106
 
@@ -81,109 +110,99 @@ Murlsh.youtube_click = function() {
81
110
  Murlsh.closer_add(Murlsh.object_tag(movie, 344, 425, [{ name : 'movie', value : movie }]));
82
111
  };
83
112
 
113
+ Murlsh.thumb_insert = function(img, click_function, a) {
114
+ if (img) {
115
+ if (Murlsh.is_iphone()) {
116
+ a.prepend(img);
117
+ } else {
118
+ a.before(img.click(click_function));
119
+ }
120
+ }
121
+ };
122
+
84
123
  Murlsh.is_iphone = function() {
85
124
  return navigator.userAgent.match(/i(phone|pod)/i);
86
125
  };
87
126
 
127
+ Murlsh.href_res = {
128
+ flickr :
129
+ /^http:\/\/(?:www\.)?flickr\.com\/photos\/[^\/]+?\/([0-9]+)/i,
130
+ imageshack :
131
+ /^(http:\/\/img\d+\.imageshack\.us\/img\d+\/\d+\/\w+\.)(jpe?g|gif|png)$/i,
132
+ mp3 :
133
+ /.*\.mp3$/i,
134
+ s3 :
135
+ /^(http:\/\/static\.mmb\.s3\.amazonaws.com\/.*\.)(jpe?g|gif|pdf|png)$/i,
136
+ vimeo :
137
+ /^http:\/\/(?:www\.)?vimeo\.com\/([0-9]+)$/i,
138
+ youtube :
139
+ /^http:\/\/(?:(?:www|uk)\.)?youtube\.com\/watch\?v=(.+?)(?:&|$)/i
140
+ };
141
+
88
142
  Murlsh.add_extra = function() {
89
143
  var this_a = $(this);
90
144
 
91
145
  var href = $(this).attr('href');
92
146
 
93
- var flickr_match =
94
- /^http:\/\/(?:www\.)?flickr\.com\/photos\/[^\/]+?\/([0-9]+)/i.exec(
95
- href);
96
-
97
- var imageshack_match =
98
- /^(http:\/\/img\d+\.imageshack\.us\/img\d+\/\d+\/\w+\.)(jpg|gif|png)$/i.exec(
99
- href);
100
-
101
- var mp3_match = /.*\.mp3$/i.exec(href);
102
-
103
- var s3_match =
104
- /^(http:\/\/static\.mmb\.s3\.amazonaws.com\/.*\.)(jpg|gif|png)$/i.exec(
105
- href);
106
-
107
- var vimeo_match = /^http:\/\/(?:www\.)?vimeo\.com\/([0-9]+)$/i.exec(href);
108
-
109
- var youtube_match =
110
- /^http:\/\/(?:(?:www|uk)\.)?youtube\.com\/watch\?v=(.+?)(?:&|$)/i.exec(
111
- href);
147
+ var match = {};
148
+ $.each(Murlsh.href_res, function(x, re) { return !(match[x] = re.exec(href)); });
112
149
 
113
150
  var thumb;
114
- var thumb_insert_func;
115
151
 
116
- if (flickr_match) {
117
- thumb_insert_func = function flickr_thumb_insert(d) {
118
- var img = Murlsh.flickr_thumb(d);
119
- if (Murlsh.is_iphone()) {
120
- this_a.prepend(img);
121
- } else {
122
- this_a.before(img.click(Murlsh.flickr_click));
123
- }
152
+ if (match.flickr) {
153
+ var callback = function(d) {
154
+ Murlsh.thumb_insert(Murlsh.flickr_thumb(d), Murlsh.flickr_click, this_a);
124
155
  };
125
156
  $.getJSON('http://api.flickr.com/services/rest/?api_key=d04e574aaf11bf2e1c03cba4ee7e5725&method=flickr.photos.getinfo&format=json&photo_id=' +
126
- flickr_match[1] + '&jsoncallback=?', thumb_insert_func);
127
- } else if (imageshack_match) {
128
- thumb = Murlsh.imageshack_thumb(imageshack_match[1], imageshack_match[2]);
129
- this_a.html('imageshack.us');
130
- if (Murlsh.is_iphone()) {
131
- this_a.prepend(thumb);
132
- } else {
133
- this_a.before(thumb.data('href', imageshack_match[0]).click(
134
- Murlsh.imageshack_click));
135
- }
136
- } else if (mp3_match) {
157
+ match.flickr[1] + '&jsoncallback=?', callback);
158
+ } else if (match.imageshack) {
159
+ thumb = Murlsh.img_thumb(match.imageshack[1], match.imageshack[2]).data(
160
+ 'href', match.imageshack[0]);
161
+ Murlsh.thumb_insert(thumb, Murlsh.img_click, this_a.html('imageshack.us'));
162
+ } else if (match.mp3) {
137
163
  var swf = 'swf/player_mp3_mini.swf';
138
164
  $(this).before(Murlsh.object_tag(swf, 20, 200, [
139
165
  { name : 'bgcolor', value : '#000000' },
140
- { name : 'FlashVars', value : 'mp3=' + mp3_match[0] },
166
+ { name : 'FlashVars', value : 'mp3=' + match.mp3[0] },
141
167
  { name : 'movie', value : swf }
142
168
  ]));
143
- } else if (s3_match) {
144
- thumb = Murlsh.imageshack_thumb(s3_match[1], s3_match[2]);
145
- if (Murlsh.is_iphone()) {
146
- this_a.html(thumb);
169
+ } else if (match.s3) {
170
+ thumb = Murlsh.img_thumb(match.s3[1], match.s3[2]);
171
+ if (match.s3[2].match(/^pdf$/i)) {
172
+ this_a.before(thumb).html('pdf');
147
173
  } else {
148
- this_a.html('link');
149
- this_a.before(thumb.data('href', s3_match[0]).click(
150
- Murlsh.imageshack_click));
151
- }
152
- } else if (vimeo_match) {
153
- thumb_insert_func = function vimeo_thumb_insert(d) {
154
- var img = Murlsh.vimeo_thumb(d);
155
174
  if (Murlsh.is_iphone()) {
156
- this_a.prepend(img);
175
+ this_a.html(thumb);
157
176
  } else {
158
- this_a.before(img.data('embed_html', d.html).click(
159
- Murlsh.vimeo_click));
177
+ this_a.html('link');
178
+ this_a.before(thumb.data('href', match.s3[0]).click(Murlsh.img_click));
160
179
  }
180
+ }
181
+ } else if (match.vimeo) {
182
+ var callback = function(d) {
183
+ var thumb = Murlsh.vimeo_thumb(d).data('embed_html', d.html);
184
+ Murlsh.thumb_insert(thumb, Murlsh.vimeo_click, this_a);
161
185
  };
162
186
  $.getJSON('http://vimeo.com/api/oembed.json?url=http%3A//vimeo.com/' +
163
- vimeo_match[1] + '&callback=?', thumb_insert_func);
164
- } else if (youtube_match) {
165
- var img = Murlsh.youtube_thumb(youtube_match[1]);
166
- if (Murlsh.is_iphone()) {
167
- $(this).prepend(img);
168
- } else {
169
- $(this).before(img.click(Murlsh.youtube_click));
170
- }
187
+ match.vimeo[1] + '&callback=?', callback);
188
+ } else if (match.youtube) {
189
+ thumb = Murlsh.youtube_thumb(match.youtube[1]);
190
+ Murlsh.thumb_insert(thumb, Murlsh.youtube_click, this_a);
171
191
  }
172
192
  };
173
193
 
174
194
  Murlsh.format_li = function(d) {
175
- var li = $('<li />').append($('<a />').attr('href', d.url).text(
176
- d.title));
195
+ var li = Murlsh.tag('li').append(Murlsh.tag('a', { href : d.url }, d.title));
177
196
 
178
197
  if (d.name) {
179
- li.prepend($('<div />').addClass('name').text(d.name));
198
+ li.prepend(Murlsh.tag('div', { klass : 'name' }, d.name));
180
199
  }
181
200
 
182
201
  var icon_size = 32;
183
202
 
184
203
  if (d.email) {
185
- li.prepend($('<div />').addClass('icon').append(
186
- Murlsh.new_img(
204
+ li.prepend(Murlsh.tag('div', { klass : 'icon' }).append(
205
+ Murlsh.img(
187
206
  'http://www.gravatar.com/avatar/' + d.email + '?s=' + icon_size,
188
207
  d.name).attr({
189
208
  width : icon_size,
@@ -194,29 +213,31 @@ Murlsh.format_li = function(d) {
194
213
  return li;
195
214
  };
196
215
 
197
- Murlsh.orientation_changed = function() {
198
- if (window.orientation === 0 || window.orientation == 180) {
199
- $('#urls').width(290);
200
- } else {
201
- $('#urls').width(450);
202
- }
203
- };
216
+ Murlsh.iphone_init = function() {
217
+ window.onorientationchange = function() {
218
+ if (window.orientation === 0 || window.orientation == 180) {
219
+ $('#urls').width(290);
220
+ } else {
221
+ $('#urls').width(450);
222
+ }
223
+ };
224
+
225
+ window.onorientationchange();
204
226
 
205
- window.onorientationchange = Murlsh.orientation_changed;
227
+ $('#urls li:first').prepend(Murlsh.tag('a', { href : '#bottom' }, 'bottom'));
228
+ $('#urls li:last').append(Murlsh.tag('a', { href : '#urls' }, 'top'));
229
+ };
206
230
 
207
231
  $(document).ready(function() {
208
232
  if (Murlsh.is_iphone()) {
209
- Murlsh.orientation_changed();
210
- $('#urls li:first').prepend($('<a />').attr('href', '#bottom').text(
211
- 'bottom'));
212
- $('#urls li:last').append($('<a />').attr('href', '#urls').text('top'));
233
+ Murlsh.iphone_init();
213
234
  }
214
- $('a').map(Murlsh.add_extra);
215
- $('#urls li:even').addClass('even');
235
+ $('#urls a').map(Murlsh.add_extra);
216
236
 
217
237
  $('#submit').click(function() {
218
238
  $.post('url', {
219
239
  url : $('#url').val(),
240
+ via : $('#via').val(),
220
241
  auth : $('#auth').val()
221
242
  }, function(d) {
222
243
  $.each(d, function(i, v) {
@@ -225,6 +246,7 @@ $(document).ready(function() {
225
246
  $(li).children('a:first').map(Murlsh.add_extra);
226
247
  });
227
248
  $('#url').val('');
249
+ $('#via').val('');
228
250
  }, 'json');
229
251
  });
230
252
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: murlsh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew M. Boedicker
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-05 00:00:00 -05:00
12
+ date: 2009-12-13 00:00:00 -05:00
13
13
  default_executable: murlsh
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -107,6 +107,7 @@ files:
107
107
  - lib/murlsh/get_content_type.rb
108
108
  - lib/murlsh/get_title.rb
109
109
  - lib/murlsh/markup.rb
110
+ - lib/murlsh/openlock.rb
110
111
  - lib/murlsh/plugin.rb
111
112
  - lib/murlsh/referrer.rb
112
113
  - lib/murlsh/sqlite3_adapter.rb
@@ -121,7 +122,6 @@ files:
121
122
  - plugins/lookup_content_type_title.rb
122
123
  - plugins/update_feed.rb
123
124
  - public/css/jquery.jgrowl.css
124
- - public/css/phone.css
125
125
  - public/css/screen.css
126
126
  - public/js/jquery-1.3.2.min.js
127
127
  - public/js/jquery.cookie.js
data/public/css/phone.css DELETED
@@ -1,26 +0,0 @@
1
- a.feed {
2
- display : none;
3
- }
4
-
5
- body {
6
- margin : 0;
7
- padding : 0;
8
- }
9
-
10
- #urls {
11
- margin : 0;
12
- padding-left : 0;
13
- width : 290px;
14
- }
15
-
16
- #urls li {
17
- overflow : hidden;
18
- }
19
-
20
- input#q {
21
- width : 130px;
22
- }
23
-
24
- input#url {
25
- width : 160px;
26
- }