short 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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