oso 1.0.0 → 1.0.1

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/.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