oso 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create ree-1.8.7-2011.01@audiosocket-oso
@@ -1,3 +1,8 @@
1
+ === 1.0.1 / 2011-03-28
2
+
3
+ * Support Bundler for development/deployment.
4
+ * Support Ruby 1.8.7.
5
+
1
6
  === 1.0.0 / 2011-02-15
2
7
 
3
8
  * Birthday!
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source :rubygems
2
+
3
+ gem "new_base_60", "1.0.3"
4
+ gem "rack", "1.2.1"
5
+ gem "redis-namespace", "0.10.0"
6
+ gem "sinatra", "1.1.2"
7
+
8
+ group :development do
9
+ gem "heroku"
10
+ gem "hoe"
11
+ gem "hoe-doofus"
12
+ gem "hoe-git"
13
+ end
14
+
15
+ group :test do
16
+ gem "fakeweb", "1.3.0"
17
+ gem "minitest", "2.0.2"
18
+ gem "mocha", "0.9.12"
19
+ end
@@ -0,0 +1,49 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.0.5)
5
+ configuration (1.2.0)
6
+ fakeweb (1.3.0)
7
+ heroku (1.19.1)
8
+ activesupport (>= 2.1.0)
9
+ launchy (~> 0.3.2)
10
+ rest-client (>= 1.4.0, < 1.7.0)
11
+ hoe (2.8.0)
12
+ rake (>= 0.8.7)
13
+ hoe-doofus (1.0.0)
14
+ hoe-git (1.3.0)
15
+ hoe (>= 2.2.0)
16
+ launchy (0.3.7)
17
+ configuration (>= 0.0.5)
18
+ rake (>= 0.8.1)
19
+ mime-types (1.16)
20
+ minitest (2.0.2)
21
+ mocha (0.9.12)
22
+ new_base_60 (1.0.3)
23
+ rack (1.2.1)
24
+ rake (0.8.7)
25
+ redis (2.1.1)
26
+ redis-namespace (0.10.0)
27
+ redis (< 3.0.0)
28
+ rest-client (1.6.1)
29
+ mime-types (>= 1.16)
30
+ sinatra (1.1.2)
31
+ rack (~> 1.1)
32
+ tilt (~> 1.2)
33
+ tilt (1.2.2)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ fakeweb (= 1.3.0)
40
+ heroku
41
+ hoe
42
+ hoe-doofus
43
+ hoe-git
44
+ minitest (= 2.0.2)
45
+ mocha (= 0.9.12)
46
+ new_base_60 (= 1.0.3)
47
+ rack (= 1.2.1)
48
+ redis-namespace (= 0.10.0)
49
+ sinatra (= 1.1.2)
@@ -1,5 +1,7 @@
1
- .gems
1
+ .rvmrc
2
2
  CHANGELOG.rdoc
3
+ Gemfile
4
+ Gemfile.lock
3
5
  Manifest.txt
4
6
  README.rdoc
5
7
  Rakefile
@@ -9,9 +11,11 @@ lib/oso/public/audiosocket.png
9
11
  lib/oso/public/favicon.ico
10
12
  lib/oso/public/index.css
11
13
  lib/oso/public/index.html
14
+ lib/oso/public/jquery.ago.js
12
15
  lib/oso/public/robots.txt
13
16
  lib/oso/public/style.css
14
17
  lib/oso/server.rb
15
18
  lib/oso/views/layout.rhtml
19
+ lib/oso/views/stat.rhtml
16
20
  lib/oso/views/stats.rhtml
17
21
  test/test_oso.rb
@@ -9,11 +9,11 @@ three letters look a bit like our logo.
9
9
 
10
10
  == Configuring
11
11
 
12
- We deploy 1.9.2, so Oso expects it. It shouldn't be too hard to port
13
- to 1.8 if you feel the need.
12
+ Oso has a <tt>.rvmrc</tt> because it's useful in our dev process. We
13
+ know it's annoying for you.
14
14
 
15
- If you install the deps in the <tt>.gems</tt> file you can run
16
- <tt>rackup</tt> by itself.
15
+ If you run <tt>bundle install</tt> you can launch <tt>rackup</tt> by
16
+ itself.
17
17
 
18
18
  Oso needs Redis. Set the <tt>OSO_REDIS_URL</tt> environment variable,
19
19
  which defaults to <tt>redis://localhost:6379</tt>. All keys are
@@ -29,8 +29,8 @@ to <tt>/</tt> with a <tt>url</tt> parameter. It'll return a
29
29
  You can optionally pass a <tt>life</tt> parameter, which is the
30
30
  lifetime of the shortened URL in seconds.
31
31
 
32
- You can optionally pass a <tt>limit</tt> parameter, which is the number
33
- of times you want the shortened URL to work. After the limit is
32
+ You can optionally pass a <tt>limit</tt> parameter, which is the
33
+ number of times you want the shortened URL to work. After the limit is
34
34
  reached <tt>404</tt>'s are returned.
35
35
 
36
36
  You can optionally pass a <tt>name</tt> parameter, which will be used
@@ -43,8 +43,8 @@ If you install the <tt>oso</tt> RubyGem:
43
43
 
44
44
  require "oso"
45
45
 
46
- Oso.shorten "github.com" # => "http://oso.local/Acf"
47
- Oso.shorten "github.com", life: 30 # => "http://oso.local/Ad0"
46
+ Oso.shorten "github.com" # => "http://oso.local/Acf"
47
+ Oso.shorten "github.com", :life => 30 # => "http://oso.local/Ad0"
48
48
 
49
49
  Set the <tt>OSO_URL</tt> environment variable to control where the
50
50
  client looks for the server, or see the RDocs for information on
@@ -53,8 +53,10 @@ creating multiple instances.
53
53
  == Deploying
54
54
 
55
55
  If you fork it, Oso is already prepped for Heroku. It has an
56
- up-to-date <tt>.gems</tt> manifest, and it'll use the
57
- <tt>REDISTOGO_URL</tt> env var if it exists.
56
+ up-to-date <tt>Gemfile.lock</tt>, and it'll use the
57
+ <tt>REDISTOGO_URL</tt> env var if it exists. You'll probably want to
58
+ set the <tt>BUNDLE_WITHOUT</tt> env var to exclude the
59
+ <tt>development</tt> and <tt>test</tt> groups.
58
60
 
59
61
  If you'd like to use it in your own <tt>config.ru</tt> file via the
60
62
  gem, you'll need to provide the server's dependencies yourself. The
@@ -62,7 +64,7 @@ gem doesn't express any runtime dependencies since it's primarily used
62
64
  as a client.
63
65
 
64
66
  Assuming you've provided the server dependencies (see the
65
- <tt>.gems</tt> file), using the gem from Rack is simple:
67
+ <tt>Gemfile</tt>), using the gem from Rack is simple:
66
68
 
67
69
  require "oso/server"
68
70
  run Sinatra::Application
data/lib/oso.rb CHANGED
@@ -13,7 +13,7 @@ class Oso
13
13
 
14
14
  # Duh.
15
15
 
16
- VERSION = "1.0.0"
16
+ VERSION = "1.0.1"
17
17
 
18
18
  # :nodoc:
19
19
 
@@ -58,7 +58,7 @@ class Oso
58
58
  # conditions keep +url+ from being shortened in one second.
59
59
 
60
60
  def shorten url, options = {}
61
- params = options.merge url: url
61
+ params = options.merge :url => url
62
62
 
63
63
  params[:life] &&= params[:life].to_i
64
64
  params[:limit] &&= params[:limit].to_i
@@ -0,0 +1,31 @@
1
+ (function($) {
2
+ $.fn.ago = function() {
3
+ var now = parseInt((new Date()).getTime() / 1000)
4
+
5
+ return this.each(function() {
6
+ var then = parseInt($(this).attr("data-at"), 10)
7
+ var delta = now - then
8
+ var message = "" + delta + " seconds ago"
9
+
10
+ if (delta < 30)
11
+ message = "just now"
12
+
13
+ else if (delta >= 60 && delta < 120)
14
+ message = "a minute ago"
15
+
16
+ else if (delta >= 120 && delta < 3300)
17
+ message = "" + parseInt(delta / 60) + " minutes ago"
18
+
19
+ else if (delta >= 3300 && delta < 3600)
20
+ message = "almost an hour ago"
21
+
22
+ else if (delta >= 3600) {
23
+ var hours = parseInt(delta / 3600)
24
+ var unit = hours > 1 ? "hours" : "hour"
25
+ message = "" + hours + " " + unit + " ago"
26
+ }
27
+
28
+ $(this).html(message)
29
+ })
30
+ }
31
+ })(jQuery)
@@ -6,8 +6,10 @@ require "uri"
6
6
  url = ENV.values_at("OSO_REDIS_URL", "REDISTOGO_URL").compact.first
7
7
  url = URI.parse url || "redis://localhost:6379"
8
8
 
9
- $redis = Redis::Namespace.new :oso,
10
- redis: Redis.new(host: url.host, password: url.password, port: url.port)
9
+ $redis = Redis::Namespace.new(:oso,
10
+ :redis => Redis.new(:host => url.host,
11
+ :password => url.password,
12
+ :port => url.port))
11
13
 
12
14
  helpers do
13
15
  def bad! message
@@ -36,6 +38,11 @@ helpers do
36
38
  end
37
39
  end
38
40
 
41
+ def shorten str
42
+ return str unless str.length > 40
43
+ str[0, 37] + "..."
44
+ end
45
+
39
46
  def shorturl short
40
47
  request.path_info = "/#{short}"
41
48
  request.url
@@ -54,7 +61,8 @@ get "/stats" do
54
61
  @bytimes = Hash[*$redis.zrevrange("by:time", 0, 10, :with_scores => true)]
55
62
 
56
63
  [@byhits, @bytimes].each do |h|
57
- h.each { |k, v| h[k] = { long: $redis.get("short:#{k}"), score: v } }
64
+ h.select! { |k, v| $redis.exists "short:#{k}" }
65
+ h.each { |k, v| h[k] = { :long => $redis.get("short:#{k}"), :score => v } }
58
66
  end
59
67
 
60
68
  @title = "Stats"
@@ -105,3 +113,15 @@ get "/:short" do |short|
105
113
 
106
114
  redirect long
107
115
  end
116
+
117
+ get "/:short/stats" do |short|
118
+ nope! unless @long = $redis.get("short:#{short}")
119
+
120
+ @short = short
121
+ @hits = $redis.zscore("by:hits", short).to_i
122
+ @limit = $redis.get("short:#{short}:limit").to_i
123
+ @time = $redis.zscore("by:time", short).to_i
124
+
125
+ @title = "Stats :: #@short"
126
+ erb :stat
127
+ end
@@ -18,5 +18,11 @@
18
18
 
19
19
  <script type="text/javascript"
20
20
  src="http://code.jquery.com/jquery-1.5.min.js"></script>
21
+
22
+ <script type="text/javascript" src="/jquery.ago.js"></script>
23
+
24
+ <script type="text/javascript">
25
+ $(function() { $("[data-at]").ago() })
26
+ </script>
21
27
  </body>
22
28
  </html>
@@ -0,0 +1,14 @@
1
+ <p>
2
+ <a href="<%= shorturl @short %>"><%= @short %></a> points at
3
+ <a href="<%= @long %>"><%= shorten @long %></a>.
4
+
5
+ <% if @hits > 0 %>
6
+ It's been hit <b><%= @hits %></b> time<%= "s" if @hits != 1 %>,
7
+ most recently <b data-at="<%= @time %>">timestamp</b>.
8
+ <% end %>
9
+
10
+ <% if @limit > 0 %>
11
+ It can be hit <b><%= @limit %> more time<%= "s" if @limit != 1 %></b>
12
+ before it disappears.
13
+ <% end %>
14
+ </p>
@@ -30,18 +30,17 @@
30
30
  <tbody>
31
31
  <% @bytimes.each do |short, data| %>
32
32
  <tr>
33
- <td><%= data[:score] %></td>
34
- <td><a href="<%= data[:long] %>"><%= data[:long] %></a></td>
33
+ <td data-at="<%= data[:score] %>">time</td>
34
+ <td><a href="<%= data[:long] %>"><%= shorten data[:long] %></a></td>
35
35
  <td><a href="<%= shorturl(short) %>"><%= shorturl(short) %></a></td>
36
36
  </tr>
37
37
  <% end %>
38
38
  </tbody>
39
- </table>
40
-
41
- <h2>Most Hits</h2>
42
-
43
- <table cellspacing="0">
44
39
  <thead>
40
+ <tr colspan="3">
41
+ <td><h2>Most Hits</h2></td>
42
+ </tr>
43
+
45
44
  <tr>
46
45
  <th>Hits</th>
47
46
  <th>URL</th>
@@ -53,7 +52,7 @@
53
52
  <% @byhits.each do |short, data| %>
54
53
  <tr>
55
54
  <td><%= data[:score] %></td>
56
- <td><a href="<%= data[:long] %>"><%= data[:long] %></a></td>
55
+ <td><a href="<%= data[:long] %>"><%= shorten data[:long] %></a></td>
57
56
  <td><a href="<%= shorturl(short) %>"><%= shorturl(short) %></a></td>
58
57
  </tr>
59
58
  <% end %>
@@ -34,7 +34,7 @@ class TestOso < MiniTest::Unit::TestCase
34
34
 
35
35
  def test_shorten
36
36
  FakeWeb.register_uri :post, "http://example.org/",
37
- body: "http://example.org/1", status: 201
37
+ :body => "http://example.org/1", :status => 201
38
38
 
39
39
  oso = Oso.new "example.org"
40
40
 
@@ -43,7 +43,7 @@ class TestOso < MiniTest::Unit::TestCase
43
43
 
44
44
  def test_shorten_bad
45
45
  FakeWeb.register_uri :post, "http://example.org/",
46
- body: "No luck.", status: 404
46
+ :body => "No luck.", :status => 404
47
47
 
48
48
  oso = Oso.new "example.org"
49
49
 
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oso
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 1.0.0
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 1
10
+ version: 1.0.1
6
11
  platform: ruby
7
12
  authors:
8
13
  - Audiosocket
@@ -10,7 +15,7 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2011-02-17 00:00:00 -06:00
18
+ date: 2011-03-28 00:00:00 -05:00
14
19
  default_executable:
15
20
  dependencies:
16
21
  - !ruby/object:Gem::Dependency
@@ -21,6 +26,11 @@ dependencies:
21
26
  requirements:
22
27
  - - "="
23
28
  - !ruby/object:Gem::Version
29
+ hash: 27
30
+ segments:
31
+ - 1
32
+ - 3
33
+ - 0
24
34
  version: 1.3.0
25
35
  type: :development
26
36
  version_requirements: *id001
@@ -32,6 +42,11 @@ dependencies:
32
42
  requirements:
33
43
  - - "="
34
44
  - !ruby/object:Gem::Version
45
+ hash: 11
46
+ segments:
47
+ - 2
48
+ - 0
49
+ - 2
35
50
  version: 2.0.2
36
51
  type: :development
37
52
  version_requirements: *id002
@@ -43,6 +58,11 @@ dependencies:
43
58
  requirements:
44
59
  - - "="
45
60
  - !ruby/object:Gem::Version
61
+ hash: 35
62
+ segments:
63
+ - 0
64
+ - 9
65
+ - 12
46
66
  version: 0.9.12
47
67
  type: :development
48
68
  version_requirements: *id003
@@ -54,7 +74,12 @@ dependencies:
54
74
  requirements:
55
75
  - - ">="
56
76
  - !ruby/object:Gem::Version
57
- version: 2.9.1
77
+ hash: 47
78
+ segments:
79
+ - 2
80
+ - 8
81
+ - 0
82
+ version: 2.8.0
58
83
  type: :development
59
84
  version_requirements: *id004
60
85
  description: |-
@@ -72,8 +97,10 @@ extra_rdoc_files:
72
97
  - CHANGELOG.rdoc
73
98
  - README.rdoc
74
99
  files:
75
- - .gems
100
+ - .rvmrc
76
101
  - CHANGELOG.rdoc
102
+ - Gemfile
103
+ - Gemfile.lock
77
104
  - Manifest.txt
78
105
  - README.rdoc
79
106
  - Rakefile
@@ -83,13 +110,14 @@ files:
83
110
  - lib/oso/public/favicon.ico
84
111
  - lib/oso/public/index.css
85
112
  - lib/oso/public/index.html
113
+ - lib/oso/public/jquery.ago.js
86
114
  - lib/oso/public/robots.txt
87
115
  - lib/oso/public/style.css
88
116
  - lib/oso/server.rb
89
117
  - lib/oso/views/layout.rhtml
118
+ - lib/oso/views/stat.rhtml
90
119
  - lib/oso/views/stats.rhtml
91
120
  - test/test_oso.rb
92
- - .gemtest
93
121
  has_rdoc: true
94
122
  homepage: http://github.com/audiosocket/oso
95
123
  licenses: []
@@ -105,17 +133,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
133
  requirements:
106
134
  - - ">="
107
135
  - !ruby/object:Gem::Version
136
+ hash: 3
137
+ segments:
138
+ - 0
108
139
  version: "0"
109
140
  required_rubygems_version: !ruby/object:Gem::Requirement
110
141
  none: false
111
142
  requirements:
112
143
  - - ">="
113
144
  - !ruby/object:Gem::Version
145
+ hash: 3
146
+ segments:
147
+ - 0
114
148
  version: "0"
115
149
  requirements: []
116
150
 
117
151
  rubyforge_project: oso
118
- rubygems_version: 1.5.2
152
+ rubygems_version: 1.3.7
119
153
  signing_key:
120
154
  specification_version: 3
121
155
  summary: Audiosocket's minimal URL shortener
data/.gems DELETED
@@ -1,4 +0,0 @@
1
- new_base_60 --version '= 1.0.3'
2
- rack --version '= 1.2.1'
3
- redis-namespace --version '= 0.10.0'
4
- sinatra --version '= 1.1.2'
data/.gemtest DELETED
File without changes