short 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/bin/short CHANGED
@@ -105,6 +105,39 @@ def usage
105
105
  EOU
106
106
  end
107
107
 
108
+ def write_configuration
109
+ store = ARGV.shift(2)
110
+ puts "the Short command line tool works best with a config file, ~/.shortener."
111
+ puts "We didn't find on, if you'd like we can write one now. (y|n)"
112
+ if gets.chomp == 'y'
113
+ opts = Hash.new
114
+ puts "sweet. What is the URL for your shortener server?"
115
+ opts[:SHORTENER_URL] = gets.chomp
116
+ puts "for your shortener server, what would you like the default redirect to be? (defaults to /index)"
117
+ opts[:DEFAULT_URL] = gets.chomp
118
+ puts "are you going to be running the server on this computer? (y|n)"
119
+ if gets.chomp == 'y'
120
+ puts "what url would you like to use for redis? (ex. redis://localhost:6379)"
121
+ opts[:REDISTOGO_URL] = gets.chomp
122
+ puts "would you like to enabled S3 uploads? (y|n)"
123
+ if gets.chomp == 'y'
124
+ opts[:S3_ENABLED] = true
125
+ puts "You will want to set the following options, either in your ENV of edit this config:"
126
+ puts "S3_KEY_PREFIX, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_DEFAULT_ACL, S3_BUCKET\n\n"
127
+ end
128
+ end
129
+ puts "nice. for now, that's all we need. writing file...\n\n"
130
+ File.open(@conf_file, 'w') {|f| f.puts opts.to_yaml}
131
+ else
132
+ puts "fine, but any errors aren't my fault.\n\n"
133
+ end
134
+ ARGV.concat(store)
135
+ end
136
+
137
+ @conf_file = ENV['DOTFILE_PATH'] || File.join(ENV['HOME'], ".shortener")
138
+
139
+ write_configuration unless File.exists?(@conf_file)
140
+
108
141
  case ARGV[0]
109
142
  when 'shorten'
110
143
  do_action(:shorten, ARGV[1])
@@ -7,7 +7,7 @@ class Shortener
7
7
 
8
8
  OPTIONS = [:SHORTENER_URL, :DEFAULT_URL, :REDISTOGO_URL, :S3_KEY_PREFIX,
9
9
  :S3_ACCESS_KEY_ID, :S3_SECRET_ACCESS_KEY, :S3_DEFAULT_ACL, :S3_BUCKET,
10
- :DOTFILE_PATH]
10
+ :DOTFILE_PATH, :S3_ENABLED]
11
11
 
12
12
  HEROKU_IGNORE = [:DOTFILE_PATH, :SHORTENER_URL, :REDISTOGO_URL]
13
13
 
@@ -21,6 +21,7 @@ class Shortener
21
21
  check_dotfile
22
22
  check_env
23
23
  @options = @options.merge!(opts)
24
+ @options[:DEFAULT_URL] ||= '/index'
24
25
  end
25
26
 
26
27
  def uri_for(end_point, opts = nil)
@@ -39,12 +40,50 @@ class Shortener
39
40
  end
40
41
 
41
42
  OPTIONS.each do |opt|
43
+ next if [:REDISTOGO_URL, :S3_ENABLED].include?(opt)
42
44
  method_name = opt.to_s.downcase.to_sym
43
45
  define_method "#{method_name}" do
44
46
  @options[opt]
45
47
  end
46
48
  end
47
49
 
50
+ def redistogo_url
51
+ begin
52
+ URI.parse(@options[:REDISTOGO_URL])
53
+ rescue Exception => boom
54
+ puts "Error parsing redistogo_url: #{@options[:REDISTOGO_URL]}"
55
+ puts "should probably be something like: redis://localhost:6379 if run locally"
56
+ puts "if you're on Heroku, make sure you have the RedisToGo addon installed.\n\n"
57
+ raise boom
58
+ end
59
+ end
60
+
61
+ def s3_enabled
62
+ @options[:S3_ENABLED].to_s == 'true'
63
+ end
64
+
65
+ def s3_policy
66
+ expiration_date = (Time.now + 36000).utc.strftime('%Y-%m-%dT%H:%M:%S.000Z') # 10.hours.from_now
67
+ max_filesize = 2147483648 # 2.gigabyte
68
+ policy = Base64.encode64(
69
+ "{'expiration': '#{expiration_date}',
70
+ 'conditions': [
71
+ {'bucket': '#{s3_bucket}'},
72
+ ['starts-with', '$key', '#{s3_key_prefix}'],
73
+ {'acl': '#{s3_default_acl}'},
74
+ {'success_action_status': '201'},
75
+ ['starts-with', '$Filename', ''],
76
+ ['content-length-range', 0, #{max_filesize}]
77
+ ]
78
+ }"
79
+ ).gsub(/\n|\r/, '')
80
+ end
81
+
82
+ def s3_signature(policy)
83
+ signature = Base64.encode64(OpenSSL::HMAC.digest(
84
+ OpenSSL::Digest::Digest.new('sha1'), s3_secret_access_key, policy)).gsub("\n","")
85
+ end
86
+
48
87
  private
49
88
 
50
89
  def check_dotfile
@@ -16,6 +16,9 @@
16
16
  %a{href: '/index'} Index
17
17
  %li
18
18
  %a{href: '/add'} Add
19
+ - if $conf.s3_enabled
20
+ %li
21
+ %a{href: '/upload'} Upload
19
22
 
20
23
  #main.container(style="margin-top: 40px;")
21
24
  = yield
@@ -62,7 +62,7 @@
62
62
  // data: "name=" + file.name,
63
63
  // async: false,
64
64
  // });
65
- $.post('/upload', values, function(data){
65
+ $.post('/upload.json', values, function(data){
66
66
  $('#shortener-display').text(data.url)
67
67
  .removeClass('hide');
68
68
  });
@@ -5,6 +5,7 @@ require 'json'
5
5
  require 'haml'
6
6
  require 'digest/sha1'
7
7
  require 'base64'
8
+ require File.join(File.dirname(__FILE__), 'configuration')
8
9
 
9
10
 
10
11
 
@@ -15,19 +16,14 @@ class Shortener
15
16
  set :public_folder, File.join(dir, 'server', 'public')
16
17
 
17
18
  configure do
18
- uri = URI.parse(ENV["REDISTOGO_URL"])
19
+ $conf = Shortener::Configuration.new
20
+ uri = $conf.redistogo_url
19
21
  _redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
20
22
  $redis = Redis::Namespace.new(:shortener, redis: _redis)
21
- $default_url = ENV['DEFAULT_URL'] || '/index'
22
- $s3_config = {
23
- bucket: ENV['S3_BUCKET'],
24
- key_prefix: ENV['S3_KEY_PREFIX'],
25
- default_acl: ENV['S3_DEFAULT_ACL'],
26
- access_key_id: ENV['S3_ACCESS_KEY_ID'],
27
- secret_access_key: ENV['S3_SECRET_ACCESS_KEY']
28
- }
29
23
  end
30
24
 
25
+ set(:s3_enabled) {|v| condition {$conf.s3_enabled == v}}
26
+
31
27
  helpers do
32
28
 
33
29
  def bad! message
@@ -92,7 +88,7 @@ class Shortener
92
88
  fname = params['file_name'].gsub(' ', '+')
93
89
  sha = Digest::SHA1.hexdigest(fname)
94
90
  hash_key = "data:#{sha}:#{key}"
95
- url = "https://s3.amazonaws.com/#{$s3_config[:bucket]}/#{$s3_config[:key_prefix]}/#{fname}"
91
+ url = "https://s3.amazonaws.com/#{$conf.s3_bucket}/#{$conf.s3_key_prefix}/#{fname}"
96
92
  ext = File.extname(fname)[1..-1]
97
93
  extras = ['url', url, 's3', true, 'shortened', key, 'extension', ext, 'set-count', 1]
98
94
  data = params.keys.map {|k| [k, params[k]] }.flatten.concat(extras)
@@ -198,30 +194,6 @@ class Shortener
198
194
  ret
199
195
  end
200
196
 
201
- def s3_policy
202
- expiration_date = (Time.now + 36000).utc.strftime('%Y-%m-%dT%H:%M:%S.000Z') # 10.hours.from_now
203
- max_filesize = 2147483648 # 2.gigabyte
204
- policy = Base64.encode64(
205
- "{'expiration': '#{expiration_date}',
206
- 'conditions': [
207
- {'bucket': '#{$s3_config[:bucket]}'},
208
- ['starts-with', '$key', '#{$s3_config[:key_prefix]}'],
209
- {'acl': '#{$s3_config[:default_acl]}'},
210
- {'success_action_status': '201'},
211
- ['starts-with', '$Filename', ''],
212
- ['content-length-range', 0, #{max_filesize}]
213
- ]
214
- }"
215
- ).gsub(/\n|\r/, '')
216
- end
217
-
218
- def s3_signature(policy)
219
- signature = Base64.encode64(OpenSSL::HMAC.digest(
220
- OpenSSL::Digest::Digest.new('sha1'),
221
- $s3_config[:secret_access_key], policy)
222
- ).gsub("\n","")
223
- end
224
-
225
197
  end
226
198
 
227
199
  before do
@@ -229,7 +201,7 @@ class Shortener
229
201
  end
230
202
 
231
203
  get '/' do
232
- redirect $default_url
204
+ redirect $conf.default_url
233
205
  end
234
206
 
235
207
  get '/add' do
@@ -262,20 +234,20 @@ class Shortener
262
234
  end
263
235
  end
264
236
 
265
- get '/upload' do
266
- policy = s3_policy
267
- signature = s3_signature(policy)
237
+ get '/upload', s3_enabled: true do
238
+ policy = $conf.s3_policy
239
+ signature = $conf.s3_signature(policy)
268
240
 
269
241
  @post = {
270
- "key" => "#{$s3_config[:key_prefix]}/${filename}",
271
- "AWSAccessKeyId" => "#{$s3_config[:access_key_id]}",
272
- "acl" => "#{$s3_config[:default_acl]}",
242
+ "key" => "#{$conf.s3_key_prefix}/${filename}",
243
+ "AWSAccessKeyId" => "#{$conf.s3_access_key_id}",
244
+ "acl" => "#{$conf.s3_default_acl}",
273
245
  "policy" => "#{policy}",
274
246
  "signature" => "#{signature}",
275
247
  "success_action_status" => "201"
276
248
  }
277
249
 
278
- @upload_url = "http://#{$s3_config[:bucket]}.s3.amazonaws.com/"
250
+ @upload_url = "http://#{$conf.s3_bucket}.s3.amazonaws.com/"
279
251
  haml :upload
280
252
  end
281
253
 
@@ -286,10 +258,10 @@ class Shortener
286
258
  if sha.nil?
287
259
  if (params[:captures].last == '.json')
288
260
  content_type :json
289
- {success: false, message: 'Short not found'}.to_json
261
+ return {success: false, message: 'Short not found'}.to_json
290
262
  else
291
263
  puts "redirecting to default url"
292
- redirect $default_url
264
+ redirect $conf.default_url
293
265
  end
294
266
  else
295
267
  key = "data:#{sha}:#{id}"
@@ -317,13 +289,15 @@ class Shortener
317
289
  end # => expired check
318
290
  end # => format
319
291
  end
292
+ puts "redirecting to default url"
293
+ redirect $conf.default_url
320
294
  end
321
295
 
322
296
  post '/upload.?:format?' do |format|
323
- content_type :json
324
297
  short = set_upload_short(params['shortener'])
325
298
  puts "set #{short} to #{params['shortener']['file_name']}"
326
299
  if format == 'json'
300
+ content_type :json
327
301
  {url: short}.to_json
328
302
  else
329
303
  redirect :index
@@ -1,6 +1,6 @@
1
1
 
2
2
  class Shortener
3
3
 
4
- VERSION = '0.3.2'
4
+ VERSION = '0.3.3'
5
5
 
6
6
  end
data/tasks/heroku.rake CHANGED
@@ -10,6 +10,7 @@ namespace :heroku do
10
10
  cmd += " && mkdir heroku/server"
11
11
  cmd += " && cp -r #{gem_file("lib/shortener/server/*")} ./heroku/server/"
12
12
  cmd += " && cp #{gem_file('lib/shortener/server.rb')} ./heroku/main.rb"
13
+ cmd += " && cp #{gem_file('lib/shortener/configuration.rb')} ./heroku/configuration.rb"
13
14
  cmd += " && mv ./heroku/server/config.ru.template ./heroku/config.ru"
14
15
  cmd += " && mv ./heroku/server/Gemfile ./heroku/server/Gemfile.lock ./heroku"
15
16
  cmd += " && git init heroku && cd heroku && git add . && git commit -m initial"
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.3.2
4
+ version: 0.3.3
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: 2011-12-25 00:00:00.000000000 Z
12
+ date: 2011-12-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
16
- requirement: &70253057029640 !ruby/object:Gem::Requirement
16
+ requirement: &70233398587560 !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: *70253057029640
24
+ version_requirements: *70233398587560
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: redis-namespace
27
- requirement: &70253057028820 !ruby/object:Gem::Requirement
27
+ requirement: &70233398586580 !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: *70253057028820
35
+ version_requirements: *70233398586580
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: haml
38
- requirement: &70253057027960 !ruby/object:Gem::Requirement
38
+ requirement: &70233398584580 !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: *70253057027960
46
+ version_requirements: *70233398584580
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: turn
49
- requirement: &70253057023180 !ruby/object:Gem::Requirement
49
+ requirement: &70233398580400 !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: *70253057023180
57
+ version_requirements: *70233398580400
58
58
  description: A (hopefully) easy and handy deployable APIable way to shorten links.
59
59
  email:
60
60
  - jake@jakewilkins.com