dogo 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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Nando Vieira
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,51 @@
1
+ # Dogo
2
+
3
+ A simple URL shortener service backed by Redis.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application"s Gemfile:
8
+
9
+ gem "dogo"
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install dogo
18
+
19
+ ## Usage
20
+
21
+ Set some options, like your API key and the host that will be used to compose the url.
22
+
23
+ ``` ruby
24
+ Dogo.api_key = "abc"
25
+ Dogo.default_url = "http://hellobits.com"
26
+ Dogo.host = "http://fnando.me"
27
+ ```
28
+
29
+ You can create shortened urls by using `Dogo::Url.new`.
30
+
31
+ ```ruby
32
+ shortened = Dogo::Url.new("http://hellobits.com")
33
+ shortened.id #=> return some an integer
34
+ shortened.url #=> return the long url
35
+ shortened.full #=> return full shortened url
36
+ ```
37
+
38
+ Starting the server:
39
+
40
+ ``` ruby
41
+ require "dogo"
42
+ run Dogo::Server.new
43
+ ```
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am "Add some feature"`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "./lib/dogo/version"
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "dogo"
6
+ gem.version = Dogo::VERSION
7
+ gem.authors = ["Nando Vieira"]
8
+ gem.email = ["fnando.vieira@gmail.com"]
9
+ gem.description = "A Redis-backed shortener url service."
10
+ gem.summary = gem.description
11
+
12
+ gem.files = `git ls-files`.split($/)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.require_paths = ["lib"]
16
+
17
+ gem.add_dependency "redis"
18
+ gem.add_dependency "sinatra"
19
+
20
+ gem.add_development_dependency "pry"
21
+ gem.add_development_dependency "awesome_print"
22
+ end
@@ -0,0 +1,8 @@
1
+ $:.unshift File.expand_path("../../lib", __FILE__)
2
+
3
+ require "dogo"
4
+
5
+ Dogo.api_key = "abc"
6
+ Dogo.default_url = "http://hellobits.com"
7
+
8
+ run Dogo::Server.new
@@ -0,0 +1,36 @@
1
+ require "redis"
2
+ require "uri"
3
+ require "digest/md5"
4
+ require "sinatra/base"
5
+
6
+ require "dogo/server"
7
+ require "dogo/url"
8
+ require "dogo/version"
9
+
10
+ module Dogo
11
+ # Return the Redis connection.
12
+ # If no connection has been set, connects
13
+ # to localhost.
14
+ def self.redis
15
+ @redis ||= Redis.new
16
+ end
17
+
18
+ # Set the Redis connection.
19
+ def self.redis=(redis)
20
+ @redis = redis
21
+ end
22
+
23
+ class << self
24
+ # Set the API Key that will be used to create new
25
+ # URLs.
26
+ attr_accessor :api_key
27
+
28
+ # Set the default URL.
29
+ # The `GET /` route will redirect to it.
30
+ attr_accessor :default_url
31
+
32
+ # Set the default host that will be
33
+ # used to construct the shortened url.
34
+ attr_accessor :host
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ module Dogo
2
+ class Server < Sinatra::Application
3
+ set :views, File.expand_path("../server/views", __FILE__)
4
+ set :public_dir, File.expand_path("../server/assets", __FILE__)
5
+ set :static, true
6
+
7
+ helpers do
8
+ def find_or_pass(id)
9
+ url = Dogo::Url.find(id)
10
+ pass unless url
11
+ url
12
+ end
13
+ end
14
+
15
+ get "/" do
16
+ redirect Dogo.default_url
17
+ end
18
+
19
+ get "/shorten" do
20
+ require "pry"; binding.pry
21
+ halt 401, erb(:"401") unless Dogo.api_key == params[:api_key]
22
+
23
+ if Dogo::Url.valid?(params[:url])
24
+ shortened = Dogo::Url.new(params[:url])
25
+ "#{request.scheme}://#{request.host_with_port}/#{shortened.id}"
26
+ else
27
+ status 422
28
+ erb(:"422")
29
+ end
30
+ end
31
+
32
+ get "/:id" do
33
+ url = find_or_pass(params[:id])
34
+
35
+ url.click!
36
+ redirect url.url
37
+ end
38
+
39
+ not_found do
40
+ erb(:"404")
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" dir="ltr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6
+ <title>Unauthorized!</title>
7
+ </head>
8
+
9
+ <body>
10
+ <h1>Unauthorized!</h1>
11
+ <p>
12
+ Sorry! You don't have permission to do this.
13
+ </p>
14
+ </body>
15
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" dir="ltr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6
+ <title>Page not found!</title>
7
+ </head>
8
+
9
+ <body>
10
+ <h1>Page not found!</h1>
11
+ <p>
12
+ Sorry! Page you're trying to access doesn't exist.
13
+ </p>
14
+ </body>
15
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" dir="ltr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6
+ <title>Invalid URL!</title>
7
+ </head>
8
+
9
+ <body>
10
+ <h1>Invalid URL!</h1>
11
+ <p>
12
+ Sorry! The URL you're trying to add is invalid!
13
+ </p>
14
+ </body>
15
+ </html>
@@ -0,0 +1,59 @@
1
+ module Dogo
2
+ class Url
3
+ attr_reader :url, :id
4
+
5
+ # Check if the given URL is valid, according the the
6
+ # +URI+ regular expression.
7
+ def self.valid?(url)
8
+ URI::DEFAULT_PARSER.regexp[:ABS_URI] =~ url.to_s
9
+ end
10
+
11
+ #
12
+ #
13
+ def self.find(id)
14
+ key = Dogo.redis.keys("urls:*:#{id}").first
15
+ return unless key
16
+
17
+ new Dogo.redis.get(key)
18
+ end
19
+
20
+ def initialize(url)
21
+ @url = url
22
+ load_or_create
23
+ end
24
+
25
+ # Increment the click counter for this URL.
26
+ def click!
27
+ Dogo.redis.incr(click_key)
28
+ end
29
+
30
+ # Return the clicks for the current URL.
31
+ def clicks
32
+ Dogo.redis.get(click_key).to_i
33
+ end
34
+
35
+ private
36
+ def click_key
37
+ "clicks:#{id}"
38
+ end
39
+
40
+ def next_id
41
+ Dogo.redis.incr("urls._id")
42
+ end
43
+
44
+ def load_or_create
45
+ key = Dogo.redis.keys("urls:#{hash}:*").first
46
+
47
+ if key
48
+ @id = key.split(":").last
49
+ else
50
+ @id = next_id.to_s(36)
51
+ Dogo.redis.set("urls:#{hash}:#{id}", url)
52
+ end
53
+ end
54
+
55
+ def hash
56
+ @hash ||= Digest::MD5.hexdigest(url)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module Dogo
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dogo
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Nando Vieira
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ type: :runtime
16
+ name: redis
17
+ prerelease: false
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ none: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ! '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ none: false
30
+ - !ruby/object:Gem::Dependency
31
+ type: :runtime
32
+ name: sinatra
33
+ prerelease: false
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ none: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ none: false
46
+ - !ruby/object:Gem::Dependency
47
+ type: :development
48
+ name: pry
49
+ prerelease: false
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ none: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ none: false
62
+ - !ruby/object:Gem::Dependency
63
+ type: :development
64
+ name: awesome_print
65
+ prerelease: false
66
+ requirement: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ none: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ none: false
78
+ description: A Redis-backed shortener url service.
79
+ email:
80
+ - fnando.vieira@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - LICENSE.txt
88
+ - README.md
89
+ - Rakefile
90
+ - dogo.gemspec
91
+ - examples/config.ru
92
+ - lib/dogo.rb
93
+ - lib/dogo/server.rb
94
+ - lib/dogo/server/views/401.erb
95
+ - lib/dogo/server/views/404.erb
96
+ - lib/dogo/server/views/422.erb
97
+ - lib/dogo/url.rb
98
+ - lib/dogo/version.rb
99
+ homepage:
100
+ licenses: []
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ none: false
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ none: false
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 1.8.23
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: A Redis-backed shortener url service.
123
+ test_files: []