short 0.5.4 → 0.6.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.
Files changed (35) hide show
  1. data/README.md +14 -0
  2. data/bin/short +3 -0
  3. data/lib/shortener/configuration.rb +38 -6
  4. data/lib/shortener/server/Gemfile +2 -0
  5. data/lib/shortener/server/Gemfile.lock +5 -0
  6. data/lib/shortener/server/api/v1.rb +76 -0
  7. data/lib/shortener/server/auth.rb +117 -0
  8. data/lib/shortener/server/brief.rb +189 -0
  9. data/lib/shortener/server/config.ru.template +44 -2
  10. data/lib/shortener/server/helpers.rb +84 -0
  11. data/lib/shortener/server/pbkdf2.rb +192 -0
  12. data/lib/shortener/server/public/css/bootstrap-responsive.min.css +9 -3
  13. data/lib/shortener/server/public/css/bootstrap.min.css +9 -610
  14. data/lib/shortener/server/public/css/controls.png +0 -0
  15. data/lib/shortener/server/public/css/loading.gif +0 -0
  16. data/lib/shortener/server/public/css/shortener.css +23 -2
  17. data/lib/shortener/server/public/js/bootstrap.min.js +6 -1
  18. data/lib/shortener/server/public/js/site.js +2 -2
  19. data/lib/shortener/server/user.rb +131 -0
  20. data/lib/shortener/server/views.rb +55 -0
  21. data/lib/shortener/server/views/add.haml +8 -8
  22. data/lib/shortener/server/views/display.haml +1 -1
  23. data/lib/shortener/server/views/index.haml +28 -12
  24. data/lib/shortener/server/views/layout.haml +38 -12
  25. data/lib/shortener/server/views/s3/layout.haml +1 -1
  26. data/lib/shortener/server/views/u/edit.haml +40 -0
  27. data/lib/shortener/server/views/u/login.haml +13 -0
  28. data/lib/shortener/server/views/upload.haml +9 -9
  29. data/lib/shortener/server/warden.rb +29 -0
  30. data/lib/shortener/short.rb +2 -2
  31. data/lib/shortener/tasks/heroku.rb +16 -10
  32. data/lib/shortener/version.rb +1 -1
  33. metadata +22 -12
  34. data/lib/shortener/server.rb +0 -350
  35. data/lib/shortener/server/public/flash/clippy.swf +0 -0
@@ -0,0 +1,13 @@
1
+
2
+ .row
3
+ %form{action: '/api/v1/u/login', method: 'post'}
4
+ .control-group
5
+ %label.control-label{for: 'user[username]'} Username:
6
+ .controls
7
+ %input{type: 'text', name: 'user[username]', class: 'text'}
8
+ .control-group
9
+ %label.control-label{for: 'user[password]'} Password:
10
+ .controls
11
+ %input{type: 'password', name: 'user[password]', class: 'password'}
12
+
13
+ %input{type: 'submit', value: 'Login', class: 'btn primary'}
@@ -1,7 +1,7 @@
1
- %script{src: "js/swfupload.js"}
2
- %script{src: "js/jquery-swfupload-min.js"}
1
+ %script{src: "/js/swfupload.js"}
2
+ %script{src: "/js/jquery-swfupload-min.js"}
3
3
  .row
4
- %form.form-horizontal.span6{id: 'upload-form', action: '/upload', method: 'post'}
4
+ %form.form-horizontal.span6{id: 'upload-form', action: '/api/v1/upload', method: 'post'}
5
5
  .control-group
6
6
  %label.control-label Select File:
7
7
  .controls
@@ -13,16 +13,16 @@
13
13
  %label.control-label Display Type:
14
14
  .controls
15
15
  %label.radio.inline
16
- %input{name: 'shortener[type]', type: 'radio', value: 'video'}
16
+ %input{name: 'shortener[type]', type: 'radio', value: 'video'}
17
17
  Video
18
18
  %label.radio.inline
19
- %input{name: 'shortener[type]', type: 'radio', value: 'audio'}
19
+ %input{name: 'shortener[type]', type: 'radio', value: 'audio'}
20
20
  Audio
21
21
  %label.radio.inline
22
- %input{name: 'shortener[type]', type: 'radio', value: 'image'}
22
+ %input{name: 'shortener[type]', type: 'radio', value: 'image'}
23
23
  Image
24
24
  %label.radio.inline
25
- %input{name: 'shortener[type]', type: 'radio', value: 'download'}
25
+ %input{name: 'shortener[type]', type: 'radio', value: 'download'}
26
26
  Download
27
27
  .control-group.hideable
28
28
  %label.control-label{for: 'shorterner[name]'} Name
@@ -45,7 +45,7 @@
45
45
  $(function(){
46
46
  $('#swfupload-control').swfupload({
47
47
  // Backend Settings
48
- upload_url: "#{@upload_url}",
48
+ upload_url: "#{@upload_url}",
49
49
  http_success : [ 200, 201, 204 ], // FOR AWS
50
50
 
51
51
  // File Upload Settings
@@ -84,7 +84,7 @@
84
84
  .bind('uploadSuccess', function(event, file, serverData){
85
85
  var values = $('#upload-form').serialize();
86
86
  values += '&shortener%5bfile_name%5d=' + file.name;
87
- $.post('/upload.json', values, function(data){
87
+ $.post('/api/v1/upload', values, function(data){
88
88
  $('#display-up-new-shorts').append(data.html)
89
89
  });
90
90
 
@@ -0,0 +1,29 @@
1
+
2
+ Warden::Manager.serialize_into_session{|user| user.token }
3
+ Warden::Manager.serialize_from_session{|token| User.get_by_token(token) }
4
+
5
+ Warden::Manager.before_failure do |env,opts|
6
+ env['REQUEST_METHOD'] = "POST"
7
+ end
8
+
9
+ Warden::Strategies.add(:password) do
10
+ def valid?
11
+ params['user']["username"] || params['user']["password"]
12
+ end
13
+
14
+ def authenticate!
15
+ u = User.authenticate!(params['user']["username"], params['user']["password"])
16
+ u ? success!(u) : fail!('Could not log in')
17
+ end
18
+ end
19
+
20
+ Warden::Strategies.add(:token) do
21
+ def valid?
22
+ params.has_key?('token')
23
+ end
24
+
25
+ def authenticate!
26
+ u = User.get_by_token(params['token'])
27
+ u ? success!(u) : fail!('Could not log in')
28
+ end
29
+ end
@@ -11,7 +11,7 @@ class Shortener
11
11
 
12
12
  # set a shortened url
13
13
  def shorten(url, conf = nil)
14
- opts = {'shortener' => {'url' => url}.to_json}
14
+ opts = {"shortener[url]" => "#{url}"}
15
15
  response = request(:post, :add, conf, opts)
16
16
  if response.is_a?(Net::HTTPOK)
17
17
  return Short.new(response.body, conf)
@@ -40,7 +40,7 @@ class Shortener
40
40
 
41
41
  # delete a short
42
42
  def delete(short, conf = nil)
43
- response = request(:get, :delete, conf, short)
43
+ response = request(:post, :delete, conf, {id: short})
44
44
  Short.new(response.body, conf)
45
45
  end
46
46
 
@@ -64,10 +64,10 @@ namespace :short do
64
64
  desc "Build a Heroku Ready Git repo"
65
65
  task :build do
66
66
  FileUtils.mkdir(File.join(Dir.pwd, 'shortener-heroku')) unless $existing_repo
67
- [:'server', :'server/public', :'server/views', :'server/views/s3',
67
+ [:'server', :'server/public', :'server/views', :'server/views/s3',
68
68
  :'server/public/flash', :'server/public/js', :'server/public/css',
69
- :'server/public/skin', :'server/public/images',
70
- :'server/public/skin/blue.monday'].each do |f|
69
+ :'server/public/skin', :'server/public/images', :'server/views/u',
70
+ :'server/public/skin/blue.monday', 'server/api'].each do |f|
71
71
  unless File.exist?(_file(f))
72
72
  puts "creating #{_file(f)}" if ENV['VERBOSE']
73
73
  FileUtils.mkdir(_file(f))
@@ -76,8 +76,8 @@ namespace :short do
76
76
 
77
77
  ['server', 'server/public', 'server/views', :'server/views/s3',
78
78
  :'server/public/flash', :'server/public/images', :'server/public/skin',
79
- :'server/public/skin/blue.monday', :'server/public/js',
80
- :'server/public/css'].each do |end_point|
79
+ :'server/public/skin/blue.monday', :'server/public/js', :'server/views/u',
80
+ :'server/public/css', 'server/api'].each do |end_point|
81
81
  Dir["#{$gem_dir}/#{end_point}/**"].each do |f|
82
82
  next if File.directory?(f)
83
83
  end_point = _file(:"#{_ep(f)}")
@@ -85,9 +85,9 @@ namespace :short do
85
85
  FileUtils.cp(f, end_point)
86
86
  end
87
87
  end
88
- _s, _e = gem_file('server.rb'), _file(:'main.rb')
89
- _l(:copying, _s, _e)
90
- FileUtils.cp(_s, _e)
88
+ #_s, _e = gem_file('server.rb'), _file(:'main.rb')
89
+ #_l(:copying, _s, _e)
90
+ #FileUtils.cp(_s, _e)
91
91
  _s, _e = gem_file('configuration.rb'), _file(:'configuration.rb')
92
92
  _l(:copying, _s, _e)
93
93
  FileUtils.cp(_s, _e)
@@ -117,6 +117,7 @@ namespace :short do
117
117
  recursively_remove_files(Dir.pwd)
118
118
  else
119
119
  puts "working directory not clean, stash or commit your changes"
120
+ exit
120
121
  end
121
122
  $existing_repo = true
122
123
  Rake::Task[:'short:heroku:build'].execute
@@ -124,16 +125,21 @@ namespace :short do
124
125
 
125
126
  desc "config a Heroku app the way we need it. Optionally set APPNAME to set heroku app name"
126
127
  task :config do
127
- require 'shortener'
128
128
  $name = ENV['APPNAME'] || "shner-#{`whoami`.chomp}"
129
129
  cmd = Dir.pwd =~ /heroku$/ ? "" : "cd heroku && "
130
130
  cmd += "heroku create #{$name}"
131
131
  cmd += " && heroku addons:add redistogo:nano"
132
- cmd += " && heroku config:add #{Shortener::Configuration.new.to_params}"
133
132
  cmd += " && heroku addons:add custom_domains:basic"
133
+ Rake::Task[:update_config].execute
134
134
  sh cmd
135
135
  end
136
136
 
137
+ desc "Update Heroku env vars with Shortener::Config dump"
138
+ task :update_config do
139
+ require 'shortener'
140
+ sh "heroku config:add #{Shortener::Configuration.new.to_params}"
141
+ end
142
+
137
143
  desc "Push to Heroku"
138
144
  task :push do
139
145
  cmd = Dir.pwd =~ /heroku$/ ? "" : "cd heroku && "
@@ -1,6 +1,6 @@
1
1
 
2
2
  class Shortener
3
3
 
4
- VERSION = '0.5.4'
4
+ VERSION = '0.6.0'
5
5
 
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: short
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-13 00:00:00.000000000 Z
12
+ date: 2012-06-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
16
- requirement: &70158657395380 !ruby/object:Gem::Requirement
16
+ requirement: &70284680213020 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70158657395380
24
+ version_requirements: *70284680213020
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: redis-namespace
27
- requirement: &70158657394620 !ruby/object:Gem::Requirement
27
+ requirement: &70284680212600 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70158657394620
35
+ version_requirements: *70284680212600
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: haml
38
- requirement: &70158657393920 !ruby/object:Gem::Requirement
38
+ requirement: &70284680212140 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70158657393920
46
+ version_requirements: *70284680212140
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: turn
49
- requirement: &70158657393160 !ruby/object:Gem::Requirement
49
+ requirement: &70284680211720 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70158657393160
57
+ version_requirements: *70284680211720
58
58
  description: A (hopefully) easy and handy deployable APIable way to shorten links.
59
59
  email:
60
60
  - jake@jakewilkins.com
@@ -71,16 +71,21 @@ files:
71
71
  - config.ru
72
72
  - lib/shortener.rb
73
73
  - lib/shortener/configuration.rb
74
- - lib/shortener/server.rb
75
74
  - lib/shortener/server/Gemfile
76
75
  - lib/shortener/server/Gemfile.lock
76
+ - lib/shortener/server/api/v1.rb
77
+ - lib/shortener/server/auth.rb
78
+ - lib/shortener/server/brief.rb
77
79
  - lib/shortener/server/config.ru.template
80
+ - lib/shortener/server/helpers.rb
81
+ - lib/shortener/server/pbkdf2.rb
78
82
  - lib/shortener/server/public/css/bootstrap-responsive.min.css
79
83
  - lib/shortener/server/public/css/bootstrap.min.css
80
84
  - lib/shortener/server/public/css/colorbox.css
85
+ - lib/shortener/server/public/css/controls.png
86
+ - lib/shortener/server/public/css/loading.gif
81
87
  - lib/shortener/server/public/css/shortener.css
82
88
  - lib/shortener/server/public/flash/Jplayer.swf
83
- - lib/shortener/server/public/flash/clippy.swf
84
89
  - lib/shortener/server/public/flash/swfupload.swf
85
90
  - lib/shortener/server/public/images/XPButtonUploadText_61x22.png
86
91
  - lib/shortener/server/public/images/delete-icon.png
@@ -98,6 +103,8 @@ files:
98
103
  - lib/shortener/server/public/skin/blue.monday/jplayer.blue.monday.jpg
99
104
  - lib/shortener/server/public/skin/blue.monday/jplayer.blue.monday.seeking.gif
100
105
  - lib/shortener/server/public/skin/blue.monday/jplayer.blue.monday.video.play.png
106
+ - lib/shortener/server/user.rb
107
+ - lib/shortener/server/views.rb
101
108
  - lib/shortener/server/views/add.haml
102
109
  - lib/shortener/server/views/display.haml
103
110
  - lib/shortener/server/views/index.haml
@@ -106,7 +113,10 @@ files:
106
113
  - lib/shortener/server/views/s3/image.haml
107
114
  - lib/shortener/server/views/s3/layout.haml
108
115
  - lib/shortener/server/views/s3/video.haml
116
+ - lib/shortener/server/views/u/edit.haml
117
+ - lib/shortener/server/views/u/login.haml
109
118
  - lib/shortener/server/views/upload.haml
119
+ - lib/shortener/server/warden.rb
110
120
  - lib/shortener/short.rb
111
121
  - lib/shortener/tasks/heroku.rb
112
122
  - lib/shortener/version.rb
@@ -1,350 +0,0 @@
1
- require 'sinatra'
2
- require 'redis-namespace'
3
- require 'uri'
4
- require 'json'
5
- require 'haml'
6
- require 'digest/sha1'
7
- require 'base64'
8
- require File.join(File.dirname(__FILE__), 'configuration')
9
-
10
-
11
-
12
- class Shortener
13
- class Server < Sinatra::Base
14
- dir = File.expand_path(File.dirname(__FILE__))
15
- set :root, File.join(dir, 'server')
16
- set :public_folder, File.join(dir, 'server', 'public')
17
-
18
- configure do
19
- $conf = Shortener::Configuration.new
20
- uri = $conf.redistogo_url
21
- _redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
22
- $redis = Redis::Namespace.new(:shortener, redis: _redis)
23
- end
24
-
25
- set(:s3_available) {|v| condition {$conf.s3_available == v}}
26
-
27
- helpers do
28
-
29
- def bad! message
30
- halt 412, {}, message
31
- end
32
-
33
- def nope!(message = 'No luck.')
34
- halt 404, {}, message
35
- end
36
-
37
- def base_url
38
- @base_url ||= "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}"
39
- end
40
-
41
- def clippy(text, bgcolor='#FFFFFF')
42
- html = <<-EOF
43
- <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
44
- width="110"
45
- height="25"
46
- id="clippy" >
47
- <param name="movie" value="/flash/clippy.swf"/>
48
- <param name="allowScriptAccess" value="always" />
49
- <param name="quality" value="high" />
50
- <param name="scale" value="noscale" />
51
- <param NAME="FlashVars" value="text=#{text}">
52
- <param name="bgcolor" value="#{bgcolor}">
53
- <embed src="/flash/clippy.swf"
54
- width="110"
55
- height="14"
56
- name="clippy"
57
- quality="high"
58
- allowScriptAccess="always"
59
- type="application/x-shockwave-flash"
60
- pluginspage="http://www.macromedia.com/go/getflashplayer"
61
- FlashVars="text=#{text}"
62
- bgcolor="#{bgcolor}"
63
- />
64
- </object>
65
- EOF
66
- end
67
-
68
- def set_or_fetch_url(params)
69
- bad! 'Missing url.' unless url = params['url']
70
- bad! 'Bad URL' unless params['url'] =~ /(^http|^www)/
71
- url = "http://#{url}" unless /^http/i =~ url
72
- bad! 'Bad URL' unless (url = URI.parse(url)) && /^http/ =~ url.scheme
73
-
74
- %w(max-clicks expire desired-short allow-override).each do |k|
75
- params[k] = false if params[k].nil? || params[k].empty?
76
- end
77
-
78
- unless params['max-clicks'] || params['expire'] || params['desired-short']
79
- data = check_cache(url)
80
- end
81
- data ||= shorten(url, params)
82
-
83
- data
84
- end
85
-
86
- def set_upload_short(params)
87
- bad! 'Missing content type.' unless type = params['type']
88
- key = generate_short
89
- fname = params['file_name'].gsub(' ', '+')
90
- sha = Digest::SHA1.hexdigest(fname)
91
- hash_key = "data:#{sha}:#{key}"
92
- url = "https://s3.amazonaws.com/#{$conf.s3_bucket}/#{$conf.s3_key_prefix}/#{fname}"
93
- ext = File.extname(fname)[1..-1]
94
- data = {'url' => url, 's3' => true, 'shortened' => key,
95
- 'extension' => ext, 'set_count' => 1}
96
- data = params.merge(data)
97
-
98
- $redis.set(key, sha)
99
- $redis.hmset(hash_key, *arrayify_hash(data))
100
-
101
- data
102
- end
103
-
104
- def shorten(url, options = {})
105
-
106
- unless options['desired-short']
107
- key = generate_short
108
- else
109
- check = $redis.get(options['desired-short'])
110
- if check # it's already taken
111
- check_key = "data:#{check}:#{options['desired-short']}"
112
- prev_set = $redis.hgetall(check_key)
113
-
114
- # if we don't expire or have max clicks and previously set key
115
- # doesn't expire or have max clicks we can go ahead and use it
116
- # without any further setup.
117
- unless options['expire'] || options['max-clicks']
118
- if (!prev_set['max-clicks'] && !prev_set['expire'] &&
119
- (prev_set['url'] == url.to_s))
120
- $redis.hincrby(check_key, 'set_count', 1)
121
- return prev_set
122
- end
123
- end
124
-
125
- if prev_set['max-clicks'].to_i < prev_set['clicks'].to_i
126
- # previous key is no longer valid, we can assign to it
127
- key = options['desired-short']
128
- else
129
- bad! 'Name is already taken. Use Allow override' unless options['allow-override'] == 'true'
130
- key = generate_short
131
- end
132
-
133
- else
134
- key = options['desired-short']
135
- end
136
- end
137
-
138
- sha = Digest::SHA1.hexdigest(url.to_s)
139
- $redis.set(key, sha)
140
-
141
- hsh_data = {'shortened' => key, 'url' => url, 'set_count' => 1}
142
- hsh_data['max-clicks'] = options['max-clicks'].to_i if options['max-clicks']
143
-
144
- if options['expire'] # set expire time if specified
145
- ttl = options['expire'].to_i
146
- ttl_key = "expire:#{sha}:#{key}"
147
- $redis.set(ttl_key, "#{sha}:#{key}")
148
- $redis.expire(ttl_key, ttl)
149
- hsh_data[:expire] = ttl_key
150
- end
151
- $redis.hmset("data:#{sha}:#{key}", *arrayify_hash(hsh_data))
152
-
153
- hsh_data
154
- end
155
-
156
- def check_cache(url)
157
- sha = Digest::SHA1.hexdigest(url.to_s)
158
-
159
- $redis.keys("data:#{sha}:*").each do |key|
160
- short = $redis.hgetall(key)
161
- unless short == {} || short['expire'] || short['max-clicks']
162
- $redis.hincrby(key, 'set_count', 1)
163
- return short
164
- end
165
- end
166
- nil
167
- end
168
-
169
- def delete_short(id)
170
- puts "deleting #{id}"
171
- puts sha = $redis.get(id)
172
- unless sha.nil?
173
- $redis.multi do
174
- $redis.del "data:#{sha}:#{id}"
175
- $redis.del "expire:#{sha}:#{id}"
176
- $redis.del id
177
- end
178
- true
179
- else
180
- false
181
- end
182
- end
183
-
184
- def generate_short
185
- begin
186
- o = [('a'..'z'),('A'..'Z'),(0..9)].map{|i| i.to_a}.flatten;
187
- key = (0..4).map{ o[rand(o.length)] }.join;
188
- puts "testing #{key}"
189
- end while !$redis.get(key).nil?
190
- key
191
- end
192
-
193
- def ttl_display(ttl)
194
- if ttl == -1
195
- ret = 'expired'
196
- elsif ttl == nil
197
- ret = '&infin;'
198
- else
199
- ret = ttl
200
- end
201
- ret
202
- end
203
-
204
- def arrayify_hash(hsh)
205
- hsh.keys.map {|k| [k, hsh[k]] }.flatten
206
- end
207
-
208
- def boxify_class(int, boxify_classes = '', nonbox_classes = '', other_classes = '')
209
- str = if @boxify
210
- "#{other_classes} #{boxify_classes}"
211
- else
212
- "#{other_classes} #{nonbox_classes}"
213
- end
214
- str = str + " offset#{int}" unless !int.nil? && @boxify
215
- str
216
- end
217
-
218
- end
219
-
220
- before do
221
- params
222
- end
223
-
224
- get '/' do
225
- redirect $conf.default_url
226
- end
227
-
228
- get '/add' do
229
- @boxify = !params['boxify'].nil?
230
- haml :add, layout: !@boxify
231
- end
232
-
233
- get '/index.?:format?' do
234
- @shortens = Array.new
235
- $redis.keys('data:*').each do |key|
236
- short = $redis.hgetall(key)
237
- short['expire'] = $redis.ttl(short['expire']) if short.has_key?('expire')
238
- @shortens << short
239
- puts " url for #{key[-5..-1]} => #{short['url']}"
240
- end
241
- if params[:format] == 'json'
242
- content_type :json
243
- return @shortens.to_json
244
- end
245
- haml :index
246
- end
247
-
248
- get '/delete/:id.:format' do |id, format|
249
- status = delete_short(id)
250
- if format == 'json'
251
- nope! "Short not found: #{id}" if status == false
252
- content_type :json
253
- {success: status, shortened: id}.to_json
254
- else
255
- redirect :index
256
- end
257
- end
258
-
259
- get '/upload', s3_available: true do
260
- policy = $conf.s3_policy
261
- signature = $conf.s3_signature(policy)
262
-
263
- @post = {
264
- "key" => "#{$conf.s3_key_prefix}/${filename}",
265
- "AWSAccessKeyId" => "#{$conf.s3_access_key_id}",
266
- "acl" => "#{$conf.s3_default_acl}",
267
- "policy" => "#{policy}",
268
- "signature" => "#{signature}",
269
- "success_action_status" => "201"
270
- }
271
-
272
- @upload_url = "http://#{$conf.s3_bucket}.s3.amazonaws.com/"
273
- @boxify = !params['boxify'].nil?
274
- haml :upload, layout: !@boxify
275
- end
276
-
277
- #get '/:id.?:format?' do
278
- get %r{\/([a-z0-9]{3,})(\.[a-z]{3,}){0,1}}i do
279
- id = params[:captures].first
280
- sha = $redis.get(id)
281
- if sha.nil?
282
- if (params[:captures].last == '.json')
283
- nope! "Short not found: #{id}"
284
- else
285
- puts "redirecting to default url"
286
- redirect $conf.default_url
287
- end
288
- else
289
- key = "data:#{sha}:#{id}"
290
- short = $redis.hgetall(key)
291
- not_expired = short.has_key?('expire') ? $redis.get(short['expire']) : true
292
- not_maxed = !(short['click_count'].to_i >= short['max-clicks'].to_i)
293
- short.has_key?('max-clicks') ? not_maxed : not_maxed = true
294
- if params[:captures].last == '.json'
295
- ret = short.merge({expired: not_expired.nil? , maxed: !not_maxed})
296
- content_type :json
297
- return ret.to_json
298
- else
299
- $redis.hincrby(key, 'click_count', 1) if not_expired && not_maxed
300
- if not_expired
301
- unless short['s3'] == 'true' && !(short['type'] == 'download')
302
- if not_maxed
303
- puts "redirecting #{id} to #{url}"
304
- redirect short['url']
305
- end # => max clicks check
306
- else
307
- @short = short
308
- puts "rendering view for s3 content. #{id} => #{short['url']}"
309
- return haml(:"s3/#{short['type']}", layout: :'s3/layout')
310
- end # => it's S3 and needs displaying.
311
- end # => expired check
312
- end # => format
313
- end
314
- puts "redirecting to default url"
315
- redirect $conf.default_url
316
- end
317
-
318
- post '/upload.?:format?' do |format|
319
- @data = set_upload_short(params['shortener'])
320
- puts "set #{@data['shortened']} to #{params['shortener']['file_name']}"
321
- @url = "#{base_url}/#{@data['shortened']}"
322
- if format == 'json'
323
- content_type :json
324
- @data.merge({html: haml(:display, layout: false)}).to_json
325
- else
326
- redirect :index
327
- end
328
- end
329
-
330
- post '/add.?:format?' do |format|
331
- begin
332
- # TODO figure out why the fuck these are parsing from Net::HTTP
333
- params['shortener'] = JSON.parse(params['shortener']) if params['shortener'].is_a?(String)
334
- rescue Exception => boom
335
- # essentally, params = params
336
- end
337
-
338
- @data = set_or_fetch_url(params["shortener"])
339
- @url = "#{base_url}/#{@data['shortened']}"
340
- puts "set #{@url} to #{params['shortener']['url']}"
341
- if format == 'json'
342
- content_type :json
343
- @data.merge({success: true, html: haml(:display, :layout => false)}).to_json
344
- else
345
- haml :display
346
- end
347
- end
348
-
349
- end # => Server
350
- end # => Shortener