firefly 1.4.1 → 1.5.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.
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/Gemfile.lock +25 -7
- data/HISTORY +7 -0
- data/README.md +12 -13
- data/Rakefile +4 -13
- data/config.ru.example +1 -1
- data/firefly.gemspec +8 -5
- data/lib/firefly.rb +4 -0
- data/lib/firefly/config.rb +7 -5
- data/lib/firefly/server.rb +27 -72
- data/lib/firefly/version.rb +1 -1
- data/spec/firefly/api_spec.rb +1 -22
- data/spec/firefly/sharing_facebook_spec.rb +67 -0
- data/spec/firefly/sharing_hyves_spec.rb +100 -0
- data/spec/firefly/{sharing_spec.rb → sharing_twitter_spec.rb} +14 -4
- data/spec/spec_helper.rb +16 -21
- data/views/layout.haml +1 -1
- metadata +71 -25
- data/VERSION +0 -1
- data/firefly_test.sqlite3-journal +0 -0
- data/spec/files/export.csv +0 -3
- data/spec/files/export.xml +0 -16
- data/spec/files/export.yml +0 -13
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--format progress --colour
|
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
@@ -1,21 +1,24 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
firefly (1.4.
|
4
|
+
firefly (1.4.1)
|
5
5
|
dm-aggregates (~> 1.0.2)
|
6
6
|
dm-core (~> 1.0.2)
|
7
7
|
dm-migrations (~> 1.0.2)
|
8
8
|
dm-mysql-adapter (~> 1.0.2)
|
9
9
|
dm-transactions (~> 1.0.2)
|
10
|
+
escape_utils (~> 0.2.3)
|
10
11
|
haml (~> 3.0.18)
|
11
12
|
sinatra (~> 1.0)
|
12
13
|
|
13
14
|
GEM
|
14
15
|
remote: http://rubygems.org/
|
15
16
|
specs:
|
16
|
-
addressable (2.2.
|
17
|
+
addressable (2.2.5)
|
17
18
|
data_objects (0.10.3)
|
18
19
|
addressable (~> 2.1)
|
20
|
+
database_cleaner (0.6.6)
|
21
|
+
diff-lcs (1.1.2)
|
19
22
|
dm-aggregates (1.0.2)
|
20
23
|
dm-core (~> 1.0.2)
|
21
24
|
dm-core (1.0.2)
|
@@ -29,25 +32,40 @@ GEM
|
|
29
32
|
dm-mysql-adapter (1.0.2)
|
30
33
|
dm-do-adapter (~> 1.0.2)
|
31
34
|
do_mysql (~> 0.10.2)
|
35
|
+
dm-sqlite-adapter (1.0.2)
|
36
|
+
dm-do-adapter (~> 1.0.2)
|
37
|
+
do_sqlite3 (~> 0.10.2)
|
32
38
|
dm-transactions (1.0.2)
|
33
39
|
dm-core (~> 1.0.2)
|
34
40
|
do_mysql (0.10.3)
|
35
41
|
data_objects (= 0.10.3)
|
42
|
+
do_sqlite3 (0.10.3)
|
43
|
+
data_objects (= 0.10.3)
|
44
|
+
escape_utils (0.2.3)
|
36
45
|
extlib (0.9.15)
|
37
46
|
haml (3.0.25)
|
38
|
-
rack (1.2.
|
47
|
+
rack (1.2.2)
|
39
48
|
rack-test (0.5.7)
|
40
49
|
rack (>= 1.0)
|
41
|
-
rspec (
|
42
|
-
|
50
|
+
rspec (2.5.0)
|
51
|
+
rspec-core (~> 2.5.0)
|
52
|
+
rspec-expectations (~> 2.5.0)
|
53
|
+
rspec-mocks (~> 2.5.0)
|
54
|
+
rspec-core (2.5.1)
|
55
|
+
rspec-expectations (2.5.0)
|
56
|
+
diff-lcs (~> 1.1.2)
|
57
|
+
rspec-mocks (2.5.0)
|
58
|
+
sinatra (1.2.3)
|
43
59
|
rack (~> 1.1)
|
44
|
-
tilt (
|
60
|
+
tilt (>= 1.2.2, < 2.0)
|
45
61
|
tilt (1.2.2)
|
46
62
|
|
47
63
|
PLATFORMS
|
48
64
|
ruby
|
49
65
|
|
50
66
|
DEPENDENCIES
|
67
|
+
database_cleaner (~> 0.6.6)
|
68
|
+
dm-sqlite-adapter (~> 1.0.2)
|
51
69
|
firefly!
|
52
70
|
rack-test (~> 0.5.4)
|
53
|
-
rspec (~>
|
71
|
+
rspec (~> 2.5.0)
|
data/HISTORY
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
= 1.5.0 - 2011-04-21
|
2
|
+
|
3
|
+
* 2011-04-21 Firefly is now compatible with ruby 1.8.7, 1.9.2 and ree-1.8 [ariejan]
|
4
|
+
* 2011-04-21 Added support for sharing to hyves [stalkert]
|
5
|
+
* 2011-04-21 Added support for sharing to facebook [stalkert]
|
6
|
+
* 2011-04-21 Removed exports because they add to much overhead [ariejan]
|
7
|
+
|
1
8
|
= 1.4.1 - 2011-02-11
|
2
9
|
|
3
10
|
* 2011-02-11 Strip leading and trailing whitespace from titles when sharing [ariejan]
|
data/README.md
CHANGED
@@ -41,13 +41,13 @@ After you have installed the Firefly gem you should create a `config.ru` file th
|
|
41
41
|
# Default: Check this out: %short_url%
|
42
42
|
# set :tweet, "I loved this: %short_url% - Go check it out now!"
|
43
43
|
|
44
|
-
# If you want to enable 'share to
|
44
|
+
# If you want to enable 'share to sharing targets'
|
45
45
|
|
46
|
-
# A secure key to be used with 'share to
|
46
|
+
# A secure key to be used with 'share to sharing targets'
|
47
47
|
# set :sharing_key, "set-a-long-secure-key-here"
|
48
48
|
|
49
|
-
# Currently only twitter
|
50
|
-
# set :sharing_targets, [:twitter]
|
49
|
+
# Currently only twitter, hyves and facebook are supported
|
50
|
+
# set :sharing_targets, [:twitter, :hyves, :facebook]
|
51
51
|
|
52
52
|
# Set the TLDs (in URLs) that are allowed to be shortened
|
53
53
|
# set :sharing_domains, ["example.com", "mydomain.com"]
|
@@ -79,9 +79,9 @@ All configuration is done in `config.ru`.
|
|
79
79
|
* `:recent_urls` sets the number of URLs to show in the overview. Default: 25.
|
80
80
|
* `:tweet` set the template to use for tweets. Default: `"Check this out: %short_url%"`
|
81
81
|
* `:sharing_key` set this to something long and secure, used for
|
82
|
-
creating 'share to
|
83
|
-
* `:sharing_targets` set to `[:twitter]` if you want to enable sharing
|
84
|
-
to twitter
|
82
|
+
creating 'share to sharing targets' links.
|
83
|
+
* `:sharing_targets` set to `[:twitter, :hyves, :facebook]` if you want to enable sharing
|
84
|
+
to twitter, hyves or facebook
|
85
85
|
* `:sharing_domains` set to an array of TLDs. Only urls shared in those
|
86
86
|
domains will be allowed. Set to an empty array (`[]`) if you want to
|
87
87
|
accept all domains.
|
@@ -92,9 +92,7 @@ It's possible to use all kinds of backends with DataMapper. Sqlite3 and MySQL ha
|
|
92
92
|
|
93
93
|
Simply visit `http://:hostname/` and enter your `:api_key`. You can now shorten URLs.
|
94
94
|
|
95
|
-
##
|
96
|
-
|
97
|
-
### Using the API
|
95
|
+
## Using the API
|
98
96
|
|
99
97
|
You may also use the API to automate URL shortening. Here's how.
|
100
98
|
|
@@ -119,9 +117,9 @@ After you restart Terminal.app (or at least reload the `.profile` file) you can
|
|
119
117
|
-- http://ariejan.net => http://aj.gs/1
|
120
118
|
Short URL copied to clipboard.
|
121
119
|
|
122
|
-
|
120
|
+
## Using the social features (Twitter, Facebook, etc.)
|
123
121
|
|
124
|
-
The share to
|
122
|
+
The share to sharing targets feature allows you to create custom links on your
|
125
123
|
site. When clicked, the specified URL will be shortened and the user
|
126
124
|
will be redirect to Twitter to share the new short URL.
|
127
125
|
|
@@ -131,7 +129,7 @@ will be redirect to Twitter to share the new short URL.
|
|
131
129
|
Parameters:
|
132
130
|
url - Long URL to share (required)
|
133
131
|
key - The sharing key, specified in `config.ru` (required)
|
134
|
-
target - Target to share to
|
132
|
+
target - Target to share to. E.g. `twitter` or `facebook` (required)
|
135
133
|
title - Title of text to use in the tweet (optional)
|
136
134
|
|
137
135
|
# Bugs, Feature Requests, etc.
|
@@ -161,6 +159,7 @@ Feel free to fork Firefly and create patches for it. Here are some basic instruc
|
|
161
159
|
|
162
160
|
* Ariejan de Vroom - Original author
|
163
161
|
* Matthew Boeh - Contributor
|
162
|
+
* Joost Saanen - Contributor
|
164
163
|
|
165
164
|
# License
|
166
165
|
|
data/Rakefile
CHANGED
@@ -1,18 +1,9 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
|
-
|
5
|
-
Spec::Rake::SpecTask.new(:spec) do |spec|
|
6
|
-
spec.libs << 'lib' << 'spec'
|
7
|
-
spec.spec_files = FileList['spec/**/*_spec.rb']
|
8
|
-
end
|
4
|
+
task :default => :spec
|
9
5
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
spec.rcov = true
|
6
|
+
desc "Run all specs"
|
7
|
+
task "spec" do
|
8
|
+
exec "bundle exec rspec spec"
|
14
9
|
end
|
15
|
-
|
16
|
-
task :spec
|
17
|
-
|
18
|
-
task :default => :spec
|
data/config.ru.example
CHANGED
@@ -25,7 +25,7 @@ app = Firefly::Server.new do
|
|
25
25
|
set :sharing_key, ""
|
26
26
|
|
27
27
|
# Currently only twitter is supported
|
28
|
-
# set :sharing_targets, [:twitter]
|
28
|
+
# set :sharing_targets, [:twitter, :hyves, :facebook]
|
29
29
|
set :sharing_targets, []
|
30
30
|
|
31
31
|
# Set the TLDs (in URLs) that are allowed to be shortened
|
data/firefly.gemspec
CHANGED
@@ -8,9 +8,9 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Ariejan de Vroom"]
|
10
10
|
s.email = ["ariejan@ariejan.net"]
|
11
|
-
s.homepage = "http://
|
12
|
-
s.summary = %q{
|
13
|
-
s.description = %q{
|
11
|
+
s.homepage = "http://fireflyrb.com"
|
12
|
+
s.summary = %q{Firefly is your own personal URL shortener for your own domain.}
|
13
|
+
s.description = %q{Firefly is your own personal URL shortener for your own domain. It's written in Ruby and powered by Sinatra. You can run it with any Rack-capable web server.}
|
14
14
|
|
15
15
|
s.rubyforge_project = "firefly"
|
16
16
|
|
@@ -26,7 +26,10 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_runtime_dependency("dm-aggregates", ["~> 1.0.2"])
|
27
27
|
s.add_runtime_dependency("dm-mysql-adapter", ["~> 1.0.2"])
|
28
28
|
s.add_runtime_dependency("haml", ["~> 3.0.18"])
|
29
|
+
s.add_runtime_dependency("escape_utils", ["~> 0.2.3"])
|
29
30
|
|
30
|
-
s.add_development_dependency("rspec",
|
31
|
-
s.add_development_dependency("rack-test",
|
31
|
+
s.add_development_dependency("rspec", ["~> 2.5.0"])
|
32
|
+
s.add_development_dependency("rack-test", ["~> 0.5.4"])
|
33
|
+
s.add_development_dependency("dm-sqlite-adapter", ["~> 1.0.2"])
|
34
|
+
s.add_development_dependency("database_cleaner", ["~> 0.6.6"])
|
32
35
|
end
|
data/lib/firefly.rb
CHANGED
data/lib/firefly/config.rb
CHANGED
@@ -2,11 +2,13 @@ module Firefly
|
|
2
2
|
class Config < Hash
|
3
3
|
|
4
4
|
DEFAULTS = {
|
5
|
-
:hostname
|
6
|
-
:api_key
|
7
|
-
:database
|
8
|
-
:recent_urls
|
9
|
-
:tweet
|
5
|
+
:hostname => "localhost:3000",
|
6
|
+
:api_key => "test",
|
7
|
+
:database => "sqlite3://#{Dir.pwd}/firefly_#{ENV['RACK_ENV']}.sqlite3",
|
8
|
+
:recent_urls => 25,
|
9
|
+
:tweet => "Check this out: %short_url%",
|
10
|
+
:hyves_title => "Check this out",
|
11
|
+
:hyves_body => "Check this out: %short_url%"
|
10
12
|
}
|
11
13
|
|
12
14
|
def initialize obj
|
data/lib/firefly/server.rb
CHANGED
@@ -71,7 +71,7 @@ module Firefly
|
|
71
71
|
def validate_api_permission
|
72
72
|
if !has_valid_api_cookie? && params[:api_key] != config[:api_key]
|
73
73
|
status 401
|
74
|
-
return false
|
74
|
+
return false
|
75
75
|
else
|
76
76
|
return true
|
77
77
|
end
|
@@ -104,6 +104,8 @@ module Firefly
|
|
104
104
|
end
|
105
105
|
|
106
106
|
# Format a tweet
|
107
|
+
#
|
108
|
+
# redirect(URI.escape("http://twitter.com/home?status=#{tweet("http://#{config[:hostname]}/#{@code}", params[:title])}"))
|
107
109
|
def tweet(url, message = nil)
|
108
110
|
if message.nil? || message == ""
|
109
111
|
config[:tweet].gsub('%short_url%', url)
|
@@ -113,6 +115,20 @@ module Firefly
|
|
113
115
|
end
|
114
116
|
end
|
115
117
|
|
118
|
+
# Format a hyves post
|
119
|
+
# {"http://www.hyves.nl/profielbeheer/toevoegen/tips/?name=#{name_of_titel}&text=#{tekst_met_url)}&type=12&rating=5"
|
120
|
+
def hyves_post(url, title = nil, body = nil)
|
121
|
+
if title.nil? || title == ""
|
122
|
+
title = config[:hyves_title]
|
123
|
+
end
|
124
|
+
|
125
|
+
if body.nil? || body == ""
|
126
|
+
body = config[:hyves_body].gsub('%short_url%', url)
|
127
|
+
end
|
128
|
+
|
129
|
+
return "name=#{title.strip}&text=#{body.strip}&type=12&rating=5"
|
130
|
+
end
|
131
|
+
|
116
132
|
def store_api_key(key)
|
117
133
|
if key == config[:api_key]
|
118
134
|
set_api_cookie(config[:api_key])
|
@@ -175,9 +191,14 @@ module Firefly
|
|
175
191
|
@code, @result = generate_short_url(@url, nil)
|
176
192
|
invalid = @code.nil?
|
177
193
|
|
178
|
-
|
179
|
-
|
180
|
-
|
194
|
+
case (params[:target].downcase.to_sym)
|
195
|
+
when :twitter
|
196
|
+
redirect(URI.escape("http://twitter.com/home?status=#{tweet("http://#{config[:hostname]}/#{@code}", params[:title])}"))
|
197
|
+
when :hyves
|
198
|
+
redirect(URI.escape("http://www.hyves.nl/profielbeheer/toevoegen/tips/?#{hyves_post("http://#{config[:hostname]}/#{@code}", params[:title])}"))
|
199
|
+
when :facebook
|
200
|
+
redirect(URI.escape("http://www.facebook.com/share.php?u=http://#{config[:hostname]}/#{@code}"))
|
201
|
+
end
|
181
202
|
}
|
182
203
|
|
183
204
|
get '/api/share', &api_share
|
@@ -200,72 +221,6 @@ module Firefly
|
|
200
221
|
end
|
201
222
|
end
|
202
223
|
|
203
|
-
# GET /api/export.csv
|
204
|
-
#
|
205
|
-
# Download a CSV file with all shortened URLs
|
206
|
-
get '/api/export.csv' do
|
207
|
-
validate_api_permission or return "Permission denied: Invalid API key"
|
208
|
-
|
209
|
-
@urls = Firefly::Url.all(:order => [ :created_at.asc ])
|
210
|
-
|
211
|
-
output = "\"Code\",\"Short URL\",\"Long URL\",\"Clicks\",\"Created at\"\n"
|
212
|
-
@urls.each do |url|
|
213
|
-
output += "\"#{url.code}\",\"#{short_url(url)}\",\"#{url.url}\",\"#{url.clicks}\",\"#{url.created_at.strftime('%Y-%m-%d %H:%M:%S')}\"\n"
|
214
|
-
end
|
215
|
-
|
216
|
-
attachment "firefly-export.csv"
|
217
|
-
content_type "text/csv"
|
218
|
-
output
|
219
|
-
end
|
220
|
-
|
221
|
-
# GET /api/export.xml
|
222
|
-
#
|
223
|
-
# Download a XML file with all shortened URLs
|
224
|
-
get '/api/export.xml' do
|
225
|
-
validate_api_permission or return "Permission denied: Invalid API key"
|
226
|
-
|
227
|
-
@urls = Firefly::Url.all(:order => [ :created_at.asc ])
|
228
|
-
|
229
|
-
# I know, manual XML creation is ugly, at least you don't need nokogiri
|
230
|
-
output = "<urls>\n"
|
231
|
-
@urls.each do |url|
|
232
|
-
output += " <url>\n"
|
233
|
-
output += " <code>#{url.code}</code>\n"
|
234
|
-
output += " <short_url>#{short_url(url)}</short_url>\n"
|
235
|
-
output += " <long_url>#{url.url}</long_url>\n"
|
236
|
-
output += " <clicks>#{url.clicks}</clicks>\n"
|
237
|
-
output += " <created_at>#{url.created_at.strftime('%Y-%m-%d %H:%M:%S')}</created_at>\n"
|
238
|
-
output += " </url>\n"
|
239
|
-
end
|
240
|
-
output += "</urls>\n"
|
241
|
-
|
242
|
-
attachment "firefly-export.xml"
|
243
|
-
content_type "text/xml"
|
244
|
-
output
|
245
|
-
end
|
246
|
-
|
247
|
-
# GET /api/export.yml
|
248
|
-
#
|
249
|
-
# Download a YAML file with all shortened URLs
|
250
|
-
get '/api/export.yml' do
|
251
|
-
validate_api_permission or return "Permission denied: Invalid API key"
|
252
|
-
|
253
|
-
@urls = Firefly::Url.all(:order => [ :created_at.asc ])
|
254
|
-
|
255
|
-
output = {}
|
256
|
-
@urls.each do |url|
|
257
|
-
output[url.code] = { 'code' => url.code,
|
258
|
-
'short_url' => short_url(url),
|
259
|
-
'long_url' => url.url,
|
260
|
-
'clicks' => url.clicks,
|
261
|
-
'created_at' => url.created_at.strftime('%Y-%m-%d %H:%M:%S') }
|
262
|
-
end
|
263
|
-
|
264
|
-
attachment "firefly-export.yml"
|
265
|
-
content_type "text/yaml"
|
266
|
-
YAML::dump(output)
|
267
|
-
end
|
268
|
-
|
269
224
|
if defined? Barby
|
270
225
|
# GET /b3d.png
|
271
226
|
#
|
@@ -325,7 +280,7 @@ module Firefly
|
|
325
280
|
|
326
281
|
def check_mysql_collation(first_try = true)
|
327
282
|
# Make sure the 'code' column is case-sensitive. This hack is for
|
328
|
-
# MySQL only, other database systems don't have this problem.
|
283
|
+
# MySQL only, other database systems don't have this problem.
|
329
284
|
if DataMapper.repository(:default).adapter =~ "DataMapper::Adapters::MysqlAdapter"
|
330
285
|
query = "SHOW FULL COLUMNS FROM firefly_urls WHERE Field='code';"
|
331
286
|
collation = DataMapper.repository(:default).adapter.select(query)[0][:collation]
|
@@ -334,7 +289,7 @@ module Firefly
|
|
334
289
|
if first_try
|
335
290
|
puts " ~ Your MySQL database is not using the 'utf8-bin' collation. Trying to fix..."
|
336
291
|
DataMapper.repository(:default).adapter.execute("ALTER TABLE firefly_urls MODIFY `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;")
|
337
|
-
return check_mysql_collation(false)
|
292
|
+
return check_mysql_collation(false)
|
338
293
|
else
|
339
294
|
puts " ~ Failed to set the collation for `code` in `firefly_urls`. Please see http://wiki.github.com/ariejan/firefly/faq for details."
|
340
295
|
return false
|
data/lib/firefly/version.rb
CHANGED
data/spec/firefly/api_spec.rb
CHANGED
@@ -149,33 +149,12 @@ describe "API" do
|
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
-
describe "exports" do
|
153
|
-
before(:each) do
|
154
|
-
load_fixtures
|
155
|
-
end
|
156
|
-
|
157
|
-
it "should export in CSV" do
|
158
|
-
get '/api/export.csv', :api_key => "test"
|
159
|
-
last_response.body.should eql(spec_file('export.csv'))
|
160
|
-
end
|
161
|
-
|
162
|
-
it "should export in XML" do
|
163
|
-
get '/api/export.xml', :api_key => "test"
|
164
|
-
last_response.body.should eql(spec_file('export.xml'))
|
165
|
-
end
|
166
|
-
|
167
|
-
it "should export in YAML" do
|
168
|
-
get '/api/export.yml', :api_key => "test"
|
169
|
-
last_response.body.should eql(spec_file('export.yml'))
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
152
|
describe "api key" do
|
174
153
|
def app
|
175
154
|
Firefly::Server.new do
|
176
155
|
set :hostname, "test.host"
|
177
156
|
set :api_key, "test#!"
|
178
|
-
set :database, "
|
157
|
+
set :database, "sqlite3://firefly_test_alt.sqlite3"
|
179
158
|
end
|
180
159
|
end
|
181
160
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
3
|
+
|
4
|
+
describe "Sharing" do
|
5
|
+
include Rack::Test::Methods
|
6
|
+
|
7
|
+
def app
|
8
|
+
@@app
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@params = {
|
13
|
+
:url => 'http://example.com/test',
|
14
|
+
:key => 'asdfasdf',
|
15
|
+
:target => 'facebook',
|
16
|
+
:title => 'Test post'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
[:post, :get].each do |verb|
|
21
|
+
describe "facebook" do
|
22
|
+
it "should create a shortened URL" do
|
23
|
+
lambda {
|
24
|
+
self.send verb, '/api/share', @params
|
25
|
+
}.should change(Firefly::Url, :count).by(1)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should redirect to facebook with status" do
|
29
|
+
self.send verb, '/api/share', @params
|
30
|
+
last_response.should be_redirect
|
31
|
+
last_response['Location'].should match(/facebook.com/i)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should post the short url to facebook" do
|
35
|
+
self.send verb, '/api/share', @params
|
36
|
+
url = Firefly::Url.first(:url => @params[:url])
|
37
|
+
|
38
|
+
last_response['Location'].should include(URI.escape("http://test.host/#{url.code}"))
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not allow sharing of example.org URL" do
|
42
|
+
self.send verb, '/api/share', @params.merge(:url => 'http://example.org/test123')
|
43
|
+
last_response.status.should eql(401)
|
44
|
+
last_response.body.should match(/cannot share that URL/i)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not create a short URL for example.org URL" do
|
48
|
+
lambda {
|
49
|
+
self.send verb, '/api/share', @params.merge(:url => 'http://example.org/test123')
|
50
|
+
}.should_not change(Firefly::Url, :count)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should not share to unknown target" do
|
54
|
+
self.send verb, '/api/share', @params.merge(:target => 'twitterbook')
|
55
|
+
last_response.status.should eql(401)
|
56
|
+
last_response.body.should match(/cannot share that URL/i)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not create a short URL for unknown target" do
|
60
|
+
lambda {
|
61
|
+
self.send verb, '/api/share', @params.merge(:target => 'twitterbook')
|
62
|
+
}.should_not change(Firefly::Url, :count)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# encoding: UTF-8
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
4
|
+
|
5
|
+
describe "Sharing" do
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
def app
|
9
|
+
@@app
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@params = {
|
14
|
+
:url => 'http://example.com/test',
|
15
|
+
:key => 'asdfasdf',
|
16
|
+
:target => 'hyves',
|
17
|
+
:title => 'Test post'
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
[:post, :get].each do |verb|
|
22
|
+
describe "hyves" do
|
23
|
+
it "should create a shortened URL" do
|
24
|
+
lambda {
|
25
|
+
self.send verb, '/api/share', @params
|
26
|
+
}.should change(Firefly::Url, :count).by(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should redirect to hyves with status" do
|
30
|
+
self.send verb, '/api/share', @params
|
31
|
+
last_response.should be_redirect
|
32
|
+
last_response['Location'].should match(/hyves.nl/i)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should post the title to hyves" do
|
36
|
+
self.send verb, '/api/share', @params
|
37
|
+
url = Firefly::Url.first(:url => @params[:url])
|
38
|
+
last_response['Location'].should include(URI.escape("#{@params[:title]}"))
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should post the title and short url to hyves" do
|
42
|
+
self.send verb, '/api/share', @params
|
43
|
+
url = Firefly::Url.first(:url => @params[:url])
|
44
|
+
last_response['Location'].should include(URI.escape("http://test.host/#{url.code}"))
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not allow sharing of example.org URL" do
|
48
|
+
self.send verb, '/api/share', @params.merge(:url => 'http://example.org/test123')
|
49
|
+
last_response.status.should eql(401)
|
50
|
+
last_response.body.should match(/cannot share that URL/i)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should not create a short URL for example.org URL" do
|
54
|
+
lambda {
|
55
|
+
self.send verb, '/api/share', @params.merge(:url => 'http://example.org/test123')
|
56
|
+
}.should_not change(Firefly::Url, :count)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not share to unknown target" do
|
60
|
+
self.send verb, '/api/share', @params.merge(:target => 'twitterbook')
|
61
|
+
last_response.status.should eql(401)
|
62
|
+
last_response.body.should match(/cannot share that URL/i)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not create a short URL for unknown target" do
|
66
|
+
lambda {
|
67
|
+
self.send verb, '/api/share', @params.merge(:target => 'twitterbook')
|
68
|
+
}.should_not change(Firefly::Url, :count)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should strip the title to remove any unnecessary white space" do
|
72
|
+
title = " Test post "
|
73
|
+
self.send verb, '/api/share', @params.merge(:title => title)
|
74
|
+
url = Firefly::Url.first(:url => @params[:url])
|
75
|
+
|
76
|
+
last_response['Location'].should include(URI.escape("Test post"))
|
77
|
+
last_response['Location'].should_not include(URI.escape(title))
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should strip the body to remove any unnecessary white space" do
|
81
|
+
title = " This is the test body "
|
82
|
+
self.send verb, '/api/share', @params.merge(:title => title)
|
83
|
+
url = Firefly::Url.first(:url => @params[:url])
|
84
|
+
|
85
|
+
last_response['Location'].should include(URI.escape("http://test.host/#{url.code}"))
|
86
|
+
last_response['Location'].should_not include(URI.escape(title))
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
it "should escape UTF-8 correctly" do
|
91
|
+
title = "Chávez"
|
92
|
+
self.send verb, '/api/share', @params.merge(:title => title)
|
93
|
+
url = Firefly::Url.first(:url => @params[:url])
|
94
|
+
|
95
|
+
last_response['Location'].should include("Ch%C3%A1vez")
|
96
|
+
last_response['Location'].should_not include("Ch%E1vez")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
3
|
|
3
4
|
describe "Sharing" do
|
@@ -49,15 +50,15 @@ describe "Sharing" do
|
|
49
50
|
}.should_not change(Firefly::Url, :count)
|
50
51
|
end
|
51
52
|
|
52
|
-
it "should not share to
|
53
|
-
self.send verb, '/api/share', @params.merge(:target => '
|
53
|
+
it "should not share to unknown target" do
|
54
|
+
self.send verb, '/api/share', @params.merge(:target => 'twitterbook')
|
54
55
|
last_response.status.should eql(401)
|
55
56
|
last_response.body.should match(/cannot share that URL/i)
|
56
57
|
end
|
57
58
|
|
58
|
-
it "should not create a short URL for
|
59
|
+
it "should not create a short URL for unknown target" do
|
59
60
|
lambda {
|
60
|
-
self.send verb, '/api/share', @params.merge(:target => '
|
61
|
+
self.send verb, '/api/share', @params.merge(:target => 'twitterbook')
|
61
62
|
}.should_not change(Firefly::Url, :count)
|
62
63
|
end
|
63
64
|
|
@@ -80,6 +81,15 @@ describe "Sharing" do
|
|
80
81
|
last_response['Location'].should include(URI.escape("Test post http://test.host/#{url.code}"))
|
81
82
|
last_response['Location'].should_not include(URI.escape(title))
|
82
83
|
end
|
84
|
+
|
85
|
+
it "should escape UTF-8 correctly" do
|
86
|
+
title = "Chávez"
|
87
|
+
self.send verb, '/api/share', @params.merge(:title => title)
|
88
|
+
url = Firefly::Url.first(:url => @params[:url])
|
89
|
+
|
90
|
+
last_response['Location'].should include("Ch%C3%A1vez")
|
91
|
+
last_response['Location'].should_not include("Ch%E1vez")
|
92
|
+
end
|
83
93
|
end
|
84
94
|
end
|
85
95
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,10 +5,8 @@ require "bundler/setup"
|
|
5
5
|
|
6
6
|
require 'sinatra'
|
7
7
|
require 'rack/test'
|
8
|
-
require 'spec'
|
9
|
-
require 'spec/autorun'
|
10
|
-
require 'spec/interop/test'
|
11
8
|
require 'yaml'
|
9
|
+
require 'database_cleaner'
|
12
10
|
|
13
11
|
# set test environment
|
14
12
|
set :environment, :test
|
@@ -19,31 +17,28 @@ set :logging, false
|
|
19
17
|
@@app = Firefly::Server.new do
|
20
18
|
set :hostname, "test.host"
|
21
19
|
set :api_key, "test"
|
22
|
-
set :database, "
|
20
|
+
set :database, "sqlite3::memory:"
|
23
21
|
|
24
22
|
set :sharing_key, "asdfasdf"
|
25
|
-
set :sharing_targets, [:twitter]
|
23
|
+
set :sharing_targets, [:twitter, :hyves, :facebook]
|
26
24
|
set :sharing_domains, ["example.com", "example.net"]
|
27
25
|
end
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
adapter.pop_transaction
|
36
|
-
end
|
37
|
-
end
|
27
|
+
RSpec.configure do |config|
|
28
|
+
|
29
|
+
config.before(:suite) do
|
30
|
+
DatabaseCleaner.strategy = :truncation
|
31
|
+
DatabaseCleaner.clean_with(:truncation)
|
32
|
+
Firefly::CodeFactory.create(:count => 0)
|
38
33
|
end
|
39
34
|
|
40
|
-
config.before(:each)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
35
|
+
config.before(:each) do
|
36
|
+
DatabaseCleaner.start
|
37
|
+
end
|
38
|
+
|
39
|
+
config.after(:each) do
|
40
|
+
DatabaseCleaner.clean
|
41
|
+
Firefly::CodeFactory.create(:count => 0)
|
47
42
|
end
|
48
43
|
|
49
44
|
# Loads the urls.yml fixtures.
|
data/views/layout.haml
CHANGED
@@ -15,4 +15,4 @@
|
|
15
15
|
|
16
16
|
#footer
|
17
17
|
%p
|
18
|
-
Powered by <a href="http://github.com/ariejan/firefly">Firefly</a> v#{Firefly::VERSION} | <a href="http://github.com/ariejan/firefly/tree/v#{Firefly::VERSION}">Source</a> | <a href="http://github.com/ariejan/firefly/issues">Issues</a>
|
18
|
+
Powered by <a href="http://github.com/ariejan/firefly">Firefly</a> v#{Firefly::VERSION} | <a href="http://github.com/ariejan/firefly/tree/v#{Firefly::VERSION}">Source</a> | <a href="http://github.com/ariejan/firefly/issues">Issues</a>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: firefly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 1.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ariejan de Vroom
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-04-21 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -130,25 +130,41 @@ dependencies:
|
|
130
130
|
type: :runtime
|
131
131
|
version_requirements: *id007
|
132
132
|
- !ruby/object:Gem::Dependency
|
133
|
-
name:
|
133
|
+
name: escape_utils
|
134
134
|
prerelease: false
|
135
135
|
requirement: &id008 !ruby/object:Gem::Requirement
|
136
136
|
none: false
|
137
137
|
requirements:
|
138
138
|
- - ~>
|
139
139
|
- !ruby/object:Gem::Version
|
140
|
-
hash:
|
140
|
+
hash: 17
|
141
141
|
segments:
|
142
|
-
-
|
142
|
+
- 0
|
143
|
+
- 2
|
143
144
|
- 3
|
145
|
+
version: 0.2.3
|
146
|
+
type: :runtime
|
147
|
+
version_requirements: *id008
|
148
|
+
- !ruby/object:Gem::Dependency
|
149
|
+
name: rspec
|
150
|
+
prerelease: false
|
151
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ~>
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
hash: 27
|
157
|
+
segments:
|
158
|
+
- 2
|
159
|
+
- 5
|
144
160
|
- 0
|
145
|
-
version:
|
161
|
+
version: 2.5.0
|
146
162
|
type: :development
|
147
|
-
version_requirements: *
|
163
|
+
version_requirements: *id009
|
148
164
|
- !ruby/object:Gem::Dependency
|
149
165
|
name: rack-test
|
150
166
|
prerelease: false
|
151
|
-
requirement: &
|
167
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
152
168
|
none: false
|
153
169
|
requirements:
|
154
170
|
- - ~>
|
@@ -160,8 +176,40 @@ dependencies:
|
|
160
176
|
- 4
|
161
177
|
version: 0.5.4
|
162
178
|
type: :development
|
163
|
-
version_requirements: *
|
164
|
-
|
179
|
+
version_requirements: *id010
|
180
|
+
- !ruby/object:Gem::Dependency
|
181
|
+
name: dm-sqlite-adapter
|
182
|
+
prerelease: false
|
183
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
184
|
+
none: false
|
185
|
+
requirements:
|
186
|
+
- - ~>
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
hash: 19
|
189
|
+
segments:
|
190
|
+
- 1
|
191
|
+
- 0
|
192
|
+
- 2
|
193
|
+
version: 1.0.2
|
194
|
+
type: :development
|
195
|
+
version_requirements: *id011
|
196
|
+
- !ruby/object:Gem::Dependency
|
197
|
+
name: database_cleaner
|
198
|
+
prerelease: false
|
199
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
200
|
+
none: false
|
201
|
+
requirements:
|
202
|
+
- - ~>
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
hash: 11
|
205
|
+
segments:
|
206
|
+
- 0
|
207
|
+
- 6
|
208
|
+
- 6
|
209
|
+
version: 0.6.6
|
210
|
+
type: :development
|
211
|
+
version_requirements: *id012
|
212
|
+
description: Firefly is your own personal URL shortener for your own domain. It's written in Ruby and powered by Sinatra. You can run it with any Rack-capable web server.
|
165
213
|
email:
|
166
214
|
- ariejan@ariejan.net
|
167
215
|
executables: []
|
@@ -172,16 +220,16 @@ extra_rdoc_files: []
|
|
172
220
|
|
173
221
|
files:
|
174
222
|
- .gitignore
|
223
|
+
- .rspec
|
224
|
+
- .travis.yml
|
175
225
|
- Gemfile
|
176
226
|
- Gemfile.lock
|
177
227
|
- HISTORY
|
178
228
|
- LICENSE
|
179
229
|
- README.md
|
180
230
|
- Rakefile
|
181
|
-
- VERSION
|
182
231
|
- config.ru.example
|
183
232
|
- firefly.gemspec
|
184
|
-
- firefly_test.sqlite3-journal
|
185
233
|
- lib/firefly.rb
|
186
234
|
- lib/firefly/base62.rb
|
187
235
|
- lib/firefly/code_factory.rb
|
@@ -194,14 +242,13 @@ files:
|
|
194
242
|
- public/jquery-1.4.2.min.js
|
195
243
|
- public/reset.css
|
196
244
|
- public/style.css
|
197
|
-
- spec/files/export.csv
|
198
|
-
- spec/files/export.xml
|
199
|
-
- spec/files/export.yml
|
200
245
|
- spec/firefly/api_spec.rb
|
201
246
|
- spec/firefly/base62_spec.rb
|
202
247
|
- spec/firefly/code_factory_spec.rb
|
203
248
|
- spec/firefly/server_spec.rb
|
204
|
-
- spec/firefly/
|
249
|
+
- spec/firefly/sharing_facebook_spec.rb
|
250
|
+
- spec/firefly/sharing_hyves_spec.rb
|
251
|
+
- spec/firefly/sharing_twitter_spec.rb
|
205
252
|
- spec/firefly/url_spec.rb
|
206
253
|
- spec/fixtures/urls.yml
|
207
254
|
- spec/spec.opts
|
@@ -211,7 +258,7 @@ files:
|
|
211
258
|
- views/info.haml
|
212
259
|
- views/layout.haml
|
213
260
|
has_rdoc: true
|
214
|
-
homepage: http://
|
261
|
+
homepage: http://fireflyrb.com
|
215
262
|
licenses: []
|
216
263
|
|
217
264
|
post_install_message:
|
@@ -243,16 +290,15 @@ rubyforge_project: firefly
|
|
243
290
|
rubygems_version: 1.5.0
|
244
291
|
signing_key:
|
245
292
|
specification_version: 3
|
246
|
-
summary:
|
293
|
+
summary: Firefly is your own personal URL shortener for your own domain.
|
247
294
|
test_files:
|
248
|
-
- spec/files/export.csv
|
249
|
-
- spec/files/export.xml
|
250
|
-
- spec/files/export.yml
|
251
295
|
- spec/firefly/api_spec.rb
|
252
296
|
- spec/firefly/base62_spec.rb
|
253
297
|
- spec/firefly/code_factory_spec.rb
|
254
298
|
- spec/firefly/server_spec.rb
|
255
|
-
- spec/firefly/
|
299
|
+
- spec/firefly/sharing_facebook_spec.rb
|
300
|
+
- spec/firefly/sharing_hyves_spec.rb
|
301
|
+
- spec/firefly/sharing_twitter_spec.rb
|
256
302
|
- spec/firefly/url_spec.rb
|
257
303
|
- spec/fixtures/urls.yml
|
258
304
|
- spec/spec.opts
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
1.2.2
|
Binary file
|
data/spec/files/export.csv
DELETED
data/spec/files/export.xml
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
<urls>
|
2
|
-
<url>
|
3
|
-
<code>def</code>
|
4
|
-
<short_url>http://test.host/def</short_url>
|
5
|
-
<long_url>http://example.org/</long_url>
|
6
|
-
<clicks>456</clicks>
|
7
|
-
<created_at>2010-02-24 14:55:00</created_at>
|
8
|
-
</url>
|
9
|
-
<url>
|
10
|
-
<code>abc</code>
|
11
|
-
<short_url>http://test.host/abc</short_url>
|
12
|
-
<long_url>http://example.com/</long_url>
|
13
|
-
<clicks>123</clicks>
|
14
|
-
<created_at>2010-04-01 12:00:00</created_at>
|
15
|
-
</url>
|
16
|
-
</urls>
|
data/spec/files/export.yml
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
---
|
2
|
-
abc:
|
3
|
-
created_at: 2010-04-01 12:00:00
|
4
|
-
long_url: http://example.com/
|
5
|
-
short_url: http://test.host/abc
|
6
|
-
code: abc
|
7
|
-
clicks: 123
|
8
|
-
def:
|
9
|
-
created_at: 2010-02-24 14:55:00
|
10
|
-
long_url: http://example.org/
|
11
|
-
short_url: http://test.host/def
|
12
|
-
code: def
|
13
|
-
clicks: 456
|