truncator 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +20 -0
- data/README.md +29 -0
- data/Rakefile +4 -0
- data/lib/truncator.rb +2 -0
- data/lib/truncator/url_parser.rb +155 -0
- data/lib/truncator/version.rb +3 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/url_parser_spec.rb +177 -0
- data/truncator.gemspec +21 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f2291c4c5706173cac9a8d622c702e15fa3d0b17
|
4
|
+
data.tar.gz: 193f48279bd97d6a4c298417c796ff42f7c78e95
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9e58e7ce29d2996fc93868c89d94d86351827a8b9a396724bb21514dd844d91b4e1bd8613cb1e996adc23f72c079d80b4cc5d6579857d57e8ff98ae06fb3b38a
|
7
|
+
data.tar.gz: e403967ea6e475503f3050939ae5e9b0e780f941e4c3c0d15fa1b34c12e422a638e18a0e539b43df70c364bf9d1f56029079eef883e5970eabfa57adf0e3c10e
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 freemanoid
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Truncator [](https://codeclimate.com/github/freemanoid/truncator)
|
2
|
+
|
3
|
+
Truncate you urls as much as possible
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'truncator'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install truncator
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/truncator.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
class UrlParser
|
2
|
+
class << self
|
3
|
+
URL_VALID_SYMBOLS = %Q{[#{Regexp.escape('!#$&-;=?-[]_~')}a-zA-Z0-9]}
|
4
|
+
SEPARATOR = '...'
|
5
|
+
|
6
|
+
def shorten_url(url, truncation_length = 42)
|
7
|
+
url = url.dup
|
8
|
+
unless ordinary_hostname?(url)
|
9
|
+
if url[-1] != '/'
|
10
|
+
# truncate all parameter except the first
|
11
|
+
url[url.index('&')..-1] = '...'
|
12
|
+
end
|
13
|
+
return url
|
14
|
+
end
|
15
|
+
|
16
|
+
url.sub!(/\Ahttp:\/\//, '') # remove http protocol
|
17
|
+
url.gsub(/\/{2,}/, '/') # replace multiple slashes by one
|
18
|
+
url.chomp!('/') # remove slash from the end
|
19
|
+
return url if valid_length?(url.length, truncation_length)
|
20
|
+
|
21
|
+
if !has_path?(url)
|
22
|
+
url = truncate(url, truncation_length)
|
23
|
+
return url
|
24
|
+
end
|
25
|
+
|
26
|
+
if params_exists?(url)
|
27
|
+
if invalid_length?(hostname(url).length, truncation_length) and last_directory(url).length > truncation_length
|
28
|
+
url = truncate_last_directory(url, truncation_length)
|
29
|
+
elsif valid_length?(url.length - last_directory(url).length, truncation_length) or !has_dirs?(url)
|
30
|
+
url = truncate(url, truncation_length)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
if valid_length?(hostname(url).length, truncation_length)
|
34
|
+
url = truncate_by_shortest(url, truncation_length)
|
35
|
+
else
|
36
|
+
url = truncate_all_directories(url)
|
37
|
+
url = truncate_last_directory(url, truncation_length)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
url
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
## FIXME: add to String#truncate
|
46
|
+
def truncate(str, length)
|
47
|
+
str = str.dup
|
48
|
+
if str.length > length
|
49
|
+
str[(length - SEPARATOR.length)..-1] = SEPARATOR
|
50
|
+
end
|
51
|
+
str
|
52
|
+
end
|
53
|
+
|
54
|
+
def ordinary_hostname?(url)
|
55
|
+
if url.start_with?('https://')
|
56
|
+
# https
|
57
|
+
false
|
58
|
+
elsif url =~ /^http[s]?:\/\/[a-zA-Z\d.]+:\d{1,5}\//
|
59
|
+
# has port
|
60
|
+
false
|
61
|
+
elsif url.start_with?('ftp://')
|
62
|
+
# ftp
|
63
|
+
false
|
64
|
+
elsif url =~ /^http:\/\/[a-zA-Z\d]+:[a-zA-Z\d]+@[a-zA-Z\d.]+\//
|
65
|
+
# with credentials
|
66
|
+
false
|
67
|
+
else
|
68
|
+
true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def hostname(url)
|
73
|
+
url[0..(url.index('/') - 1)]
|
74
|
+
end
|
75
|
+
|
76
|
+
def valid_length?(url_length, truncation_length)
|
77
|
+
url_length <= truncation_length
|
78
|
+
end
|
79
|
+
|
80
|
+
def invalid_length?(url_length, truncation_length)
|
81
|
+
!valid_length?(url_length, truncation_length)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Check if url has query parameters
|
85
|
+
def params_exists?(url)
|
86
|
+
valid_symbols_before_params = URL_VALID_SYMBOLS.dup.tap { |r| r[-1] = '.\/]' }
|
87
|
+
!!(url =~ /^#{valid_symbols_before_params}+\?(#{URL_VALID_SYMBOLS}+)/)
|
88
|
+
end
|
89
|
+
|
90
|
+
def params(url)
|
91
|
+
valid_symbols_before_params = URL_VALID_SYMBOLS.dup.tap { |r| r[-1] = '.\/]' }
|
92
|
+
url.match(/^#{valid_symbols_before_params}+\?(#{URL_VALID_SYMBOLS}+)/)[1]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get the 'directories' of the link
|
96
|
+
def directories(url)
|
97
|
+
url.to_enum(:scan, /(?<=\/)(#{URL_VALID_SYMBOLS}+)(?=\/)/).map { Regexp.last_match }
|
98
|
+
end
|
99
|
+
|
100
|
+
def truncate_all_directories(url)
|
101
|
+
first_slash = url.index('/')
|
102
|
+
last_slash = url.rindex('/')
|
103
|
+
url = url.dup
|
104
|
+
url[first_slash..last_slash] = "/#{SEPARATOR}/"
|
105
|
+
url
|
106
|
+
end
|
107
|
+
|
108
|
+
def last_directory(url)
|
109
|
+
url[(url.rindex('/') + 1)..-1]
|
110
|
+
end
|
111
|
+
|
112
|
+
def truncate_last_directory(url, truncation_length)
|
113
|
+
last_dir_begin = url.rindex('/') + 1
|
114
|
+
last_dir = last_directory(url)
|
115
|
+
url = url.dup
|
116
|
+
url[last_dir_begin..-1] = truncate(last_dir, truncation_length)
|
117
|
+
url
|
118
|
+
end
|
119
|
+
|
120
|
+
# If url has any 'dirs' this is suburls between '/'
|
121
|
+
def has_dirs?(url)
|
122
|
+
url.count('/') > 1
|
123
|
+
end
|
124
|
+
|
125
|
+
def has_path?(url)
|
126
|
+
url.count('/') > 0
|
127
|
+
end
|
128
|
+
|
129
|
+
def truncate_by_shortest(url, target_length)
|
130
|
+
url = url.dup
|
131
|
+
dirs = directories(url)
|
132
|
+
dirs_sorted = dirs.sort_by { |d| d.to_s.length }
|
133
|
+
|
134
|
+
# Get the shortest dir and try to truncate the url by this dir and nexts
|
135
|
+
dirs_sorted.each do |next_min_dir|
|
136
|
+
current_dirs_length = 0
|
137
|
+
current_dirs_count = 0
|
138
|
+
dirs[dirs.index(next_min_dir)..-1].each do |dir|
|
139
|
+
current_dirs_length += dir.to_s.length
|
140
|
+
current_dirs_count += 1
|
141
|
+
current_dirs_length_with_slashes = current_dirs_length + (current_dirs_count - 1) - SEPARATOR.length
|
142
|
+
break if url.length - current_dirs_length_with_slashes <= target_length
|
143
|
+
end
|
144
|
+
current_dirs_length_with_slashes = current_dirs_length + (current_dirs_count - 1) - SEPARATOR.length
|
145
|
+
|
146
|
+
if url.length - current_dirs_length_with_slashes <= target_length
|
147
|
+
url[next_min_dir.begin(0)..
|
148
|
+
(dirs[dirs.index(next_min_dir) + (current_dirs_count - 1)].end(0) - 1)] = SEPARATOR
|
149
|
+
break
|
150
|
+
end
|
151
|
+
end
|
152
|
+
url
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
# Run specs in random order to surface order dependencies. If you find an
|
13
|
+
# order dependency and want to debug it, you can fix the order by providing
|
14
|
+
# the seed, which is printed after each run.
|
15
|
+
# --seed 1234
|
16
|
+
# config.order = 'random'
|
17
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'truncator'
|
3
|
+
|
4
|
+
describe UrlParser do
|
5
|
+
|
6
|
+
describe ".shorten_url" do
|
7
|
+
|
8
|
+
context "when no truncation length is specified, the URL is too long, has sublevels, but no query params" do
|
9
|
+
let(:shortened) { UrlParser.shorten_url "http://www.foo.com/this/is/a/b/c/d/e/f/string.html" }
|
10
|
+
|
11
|
+
it "should default to truncate at 42 characters" do
|
12
|
+
# shortened.should == "www.foo.com/this/is/a/.../e/f/string.html"
|
13
|
+
shortened.length.should <= 42
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when URL has a large last folder level' do
|
18
|
+
let(:shortened) { UrlParser.shorten_url "http://m.whitehouse.gov/blog/2013/08/23/check-out-secretary-education-arne-duncans-google-hangout-sal-khan?utm_source=email&utm_medium=email&utm_content=email232-graphic2&utm_campaign=education" }
|
19
|
+
|
20
|
+
it "should should default to truncate at 42 characters" do
|
21
|
+
shortened.should == "m.whitehouse.gov/blog/2013/08/23/check-..."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when URL is too long, has sublevels, but no query params" do
|
26
|
+
it "should ellipse the directories and just show the file" do
|
27
|
+
UrlParser.shorten_url("http://www.foo.com/this/is/a/really/long/url/that/has/no/query/string.html", 30).should == "www.foo.com/.../string.html"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should replace path segments with ellipses to shorten the path as much as necessary" do
|
31
|
+
url_prefix = "http://www.foo.com/this/goes/on/"
|
32
|
+
url_middle = ""
|
33
|
+
url_suffix = "with/XXX.html"
|
34
|
+
0.upto(20) do |n|
|
35
|
+
url = url_prefix + url_middle + url_suffix
|
36
|
+
url_middle += "and/on/"
|
37
|
+
shorter_url = UrlParser.shorten_url(url, 30)
|
38
|
+
#TODO: rewrite this
|
39
|
+
shorter_url.should == if url[7..-1].length <= 30
|
40
|
+
url[7..-1]
|
41
|
+
else
|
42
|
+
"www.foo.com/.../with/XXX.html"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should replace path segments with ellipses to shorten the path as much as necessary (different path pattern)" do
|
48
|
+
url_prefix = "http://www.foo.com/on/"
|
49
|
+
url_middle = ""
|
50
|
+
url_suffix = "X.html"
|
51
|
+
0.upto(20) do |n|
|
52
|
+
url = url_prefix + url_middle + url_suffix
|
53
|
+
url_middle += "nd/on/"
|
54
|
+
shorter_url = UrlParser.shorten_url(url, 30)
|
55
|
+
#TODO: rewrite this
|
56
|
+
shorter_url.should == if url[7..-1].length <= 30
|
57
|
+
url[7..-1]
|
58
|
+
else
|
59
|
+
"www.foo.com/.../nd/on/X.html"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# it "should replace path segments with ellipses to shorten the path as much as necessary for various lengths", focus: true do
|
65
|
+
# url = "http://www.foo.com/this/goes/on/and/on/and/on/with/XXX.html"
|
66
|
+
# UrlParser.shorten_url(url, 24).should == "www.foo.com/.../XXX.html"
|
67
|
+
# 32.upto(33) { |n| UrlParser.shorten_url(url, n).should == "www.foo.com/.../on/with/XXX.html" }
|
68
|
+
# 35.upto(39) { |n| UrlParser.shorten_url(url, n).should == "www.foo.com/this/.../with/XXX.html" }
|
69
|
+
# 40.upto(42) { |n| UrlParser.shorten_url(url, n).should == "www.foo.com/this/goes/.../with/XXX.html" }
|
70
|
+
# 43.upto(45) { |n| UrlParser.shorten_url(url, n).should == "www.foo.com/this/goes/.../on/with/XXX.html" }
|
71
|
+
# end
|
72
|
+
end
|
73
|
+
|
74
|
+
# context "when URL is too long and has at least one sublevel specified as well as a query parameter" do
|
75
|
+
# let(:shortened) { UrlParser.shorten_url("http://www.foo.com/this/goes/on/and/on/and/on/and/on/and/ends/with/XXXX.html?q=1&a=2&b=3", 50) }
|
76
|
+
|
77
|
+
# it "should replace path segments with ellipses to shorten the path as much as necessary, and show only the first param, followed by ellipses" do
|
78
|
+
# shortened.should == "www.foo.com/this/goes/.../with/XXXX.html?q=1..."
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
|
82
|
+
context "when URL is more than 30 chars long and does not have at least one sublevel specified" do
|
83
|
+
let(:shortened) { UrlParser.shorten_url("http://www.mass.gov/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre", 30) }
|
84
|
+
|
85
|
+
it "should truncate to 30 chars with ellipses" do
|
86
|
+
shortened.should == "www.mass.gov/?pageID=trepre..."
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when the URL contains a really long host name and a long trailing filename" do
|
91
|
+
let(:shortened) { UrlParser.shorten_url("http://www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/some/path/1234567890123456789012345678901234test_of_the_mergency_broadcastingnet_work.html", 30) }
|
92
|
+
|
93
|
+
it "should not truncate the host name and truncated the last part of the path to truncation length and all dirs" do
|
94
|
+
shortened.should == "www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/.../123456789012345678901234567..."
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
#TODO: this and the next spec can be merged
|
99
|
+
context "when the URL contains a really long host name and is an http url and has an empty path" do
|
100
|
+
let(:shortened) { UrlParser.shorten_url("http://www128376218.skjdhfskdj.lqdkwjqlkwjdqlqwkjd.com/", 30) }
|
101
|
+
|
102
|
+
it "should truncate the host name and have no trailing /" do
|
103
|
+
shortened.should == "www128376218.skjdhfskdj.lqd..."
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when the URL contains a really long host name and is an http url and has an empty path and no trailing /" do
|
108
|
+
let(:shortened) { UrlParser.shorten_url("http://www128376218.skjdhfskdj.lqdkwjqlkwjdqlqwkjd.com", 30) }
|
109
|
+
|
110
|
+
it "should truncate the URL and have no trailing /" do
|
111
|
+
shortened.should == "www128376218.skjdhfskdj.lqd..."
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when the URL contains a really long host name and has a really long query parameter" do
|
116
|
+
let(:shortened) { UrlParser.shorten_url("http://www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/?cmd=1234567890123456789012345678901234&api_key=1234567890123456789012345678901234", 30) }
|
117
|
+
|
118
|
+
it "should not truncate the host name but truncate the query parameter" do
|
119
|
+
shortened.should == "www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/?cmd=1234567890123456789012..."
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when URL is really short and contains only the protocol http and hostname" do
|
124
|
+
let(:shortened) { UrlParser.shorten_url("http://bit.ly/") }
|
125
|
+
|
126
|
+
it "should omit the protocol as well as trailing slash" do
|
127
|
+
shortened.should == "bit.ly"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when URL is really short and contains only the protocol http and hostname and a long query parameter" do
|
132
|
+
let(:shortened) { UrlParser.shorten_url("http://api.bit.ly/?cmd=boom&t=now&auth_token=f886c1c02896492577e92b550cd22b3c83b062") }
|
133
|
+
|
134
|
+
it "should omit the protocol as well as trailing slash" do
|
135
|
+
shortened.should == "api.bit.ly/?cmd=boom&t=now&auth_token=f..."
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "when URL is really short and contains only the protocol http and hostname and a short query parameter" do
|
140
|
+
let(:shortened) { UrlParser.shorten_url("http://api.bit.ly/?cmd=boom&t=now") }
|
141
|
+
|
142
|
+
it "should omit the protocol as well as trailing slash" do
|
143
|
+
shortened.should == "api.bit.ly/?cmd=boom&t=now"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "when the URL starts with something other than http://hostname/" do
|
148
|
+
before do
|
149
|
+
@long_urls = [
|
150
|
+
"https://www.mass.gov/",
|
151
|
+
"http://www.mass.gov:80/",
|
152
|
+
"http://user:secret@www.mass.gov/",
|
153
|
+
"https://www.mass.gov/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre",
|
154
|
+
"http://www.mass.gov:80/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre",
|
155
|
+
"http://user:secret@www.mass.gov/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre",
|
156
|
+
"ftp://www.mass.gov/"
|
157
|
+
]
|
158
|
+
@short_urls = [
|
159
|
+
"https://www.mass.gov/",
|
160
|
+
"http://www.mass.gov:80/",
|
161
|
+
"http://user:secret@www.mass.gov/",
|
162
|
+
"https://www.mass.gov/?pageID=trepressrelease...",
|
163
|
+
"http://www.mass.gov:80/?pageID=trepressrelease...",
|
164
|
+
"http://user:secret@www.mass.gov/?pageID=trepressrelease...",
|
165
|
+
"ftp://www.mass.gov/"
|
166
|
+
]
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should truncate to 30 chars with ellipses" do
|
170
|
+
@long_urls.each_with_index do |url, x|
|
171
|
+
UrlParser.shorten_url(url, 30).should == @short_urls[x]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
data/truncator.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'truncator/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "truncator"
|
7
|
+
spec.version = Truncator::VERSION
|
8
|
+
spec.authors = ["freemanoid"]
|
9
|
+
spec.email = ["freemanoid321@gmail.com"]
|
10
|
+
spec.description = %q{url truncator}
|
11
|
+
spec.summary = %q{Truncate urls as much as possible}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.require_paths = ["lib"]
|
17
|
+
|
18
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
19
|
+
spec.add_development_dependency "rake"
|
20
|
+
spec.add_development_dependency "rspec", "~> 2.13"
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: truncator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- freemanoid
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.13'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.13'
|
55
|
+
description: url truncator
|
56
|
+
email:
|
57
|
+
- freemanoid321@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- lib/truncator.rb
|
68
|
+
- lib/truncator/url_parser.rb
|
69
|
+
- lib/truncator/version.rb
|
70
|
+
- spec/spec_helper.rb
|
71
|
+
- spec/url_parser_spec.rb
|
72
|
+
- truncator.gemspec
|
73
|
+
homepage: ''
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.0.3
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Truncate urls as much as possible
|
97
|
+
test_files: []
|