short 0.3.2 → 0.3.3
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/bin/short +33 -0
- data/lib/shortener/configuration.rb +40 -1
- data/lib/shortener/server/views/layout.haml +3 -0
- data/lib/shortener/server/views/upload.haml +1 -1
- data/lib/shortener/server.rb +19 -45
- data/lib/shortener/version.rb +1 -1
- data/tasks/heroku.rake +1 -0
- metadata +10 -10
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
|
data/lib/shortener/server.rb
CHANGED
@@ -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
|
-
|
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/#{$
|
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" => "#{$
|
271
|
-
"AWSAccessKeyId" => "#{$
|
272
|
-
"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://#{$
|
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
|
data/lib/shortener/version.rb
CHANGED
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.
|
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-
|
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: &
|
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: *
|
24
|
+
version_requirements: *70233398587560
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: redis-namespace
|
27
|
-
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: *
|
35
|
+
version_requirements: *70233398586580
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: haml
|
38
|
-
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: *
|
46
|
+
version_requirements: *70233398584580
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: turn
|
49
|
-
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: *
|
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
|