ducklink 0.0.2

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,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ducklink.gemspec
4
+ gemspec
@@ -0,0 +1,96 @@
1
+ # Ducklink #
2
+
3
+ Ducklink is a super-simple way of centrally managing the format of URLs which should be used for links to other sites. Quack.
4
+
5
+ ## Why ##
6
+
7
+ * Maybe you have an affiliate deal with a site which requires redirecting through a third-party platform
8
+ * Maybe you need to add parameters to URLs for campaign management
9
+ * Er..
10
+ * Hmm.
11
+
12
+ ## How ##
13
+
14
+ Given a URL, Ducklink will extract the host and try to match against one of its configured formats.
15
+
16
+ If nothing matches, the URL is returned untouched. If a match is found, then the URL returned will be based on the format together with any run-time parameters you passed in.
17
+
18
+ ### Add parameters ###
19
+
20
+
21
+ Ducklink::Decorator.configure do
22
+ host 'www.example.com' do
23
+ format '{{url}}?extra=params&added=here'
24
+ end
25
+ end
26
+
27
+ Ducklink.decorate 'http://www.example.com/some/path'
28
+ => http://www.example.com/some/path?extra=params&added=here
29
+
30
+ ### Redirects ###
31
+
32
+ Ducklink::Decorator.configure do
33
+ host 'www.example.com' do
34
+ format 'http://affiliate.example.com?clickref=42&url={{url}}'
35
+ end
36
+ end
37
+
38
+ Ducklink.decorate 'http://www.example.com/some/path'
39
+ => http://affiliate.example.com?clickref=42&url=http://www.example.com/some/path
40
+
41
+ If you need to, you can URLEncode the target URL explicitly:
42
+
43
+ Ducklink::Decorator.configure do
44
+ host 'www.example.com' do
45
+ format 'http://affiliate.example.com?clickref=42&url={{url}}'
46
+ set :url, CGI::escape(self[:url])
47
+ end
48
+ end
49
+
50
+ Ducklink.decorate 'http://www.example.com/some/path'
51
+ => http://affiliate.example.com?clickref=42&url=http%3A%2F%2Fwww.example.com%2Fsome%2Fpath
52
+
53
+ ### Run-time parameters ###
54
+
55
+ Ducklink::Decorator.configure do
56
+ host 'www.example.com' do |context|
57
+ format 'http://affiliate.example.com?clickref={{reference}}&url={{url}}'
58
+ set :reference, context[:reference]
59
+ end
60
+ end
61
+
62
+ Ducklink.decorate 'http://www.example.com/some/path', :reference => 100
63
+ => http://affiliate.example.com?clickref=100&url=http://www.example.com/some/path
64
+
65
+ ### Specify format of groups ###
66
+
67
+ Ducklink::Decorator.configure do
68
+ group do
69
+ format 'http://affiliate.example.com?clickref={{reference}}&url={{url}}#campaign={{campaign}}'
70
+ host 'buy.example.com', 'shop.example.com' do |context|
71
+ set :campaign, 'campaign1'
72
+ set :reference, context[:reference]
73
+ end
74
+ host 'another.com' do |context|
75
+ set :campaign, 'campaign2'
76
+ set :reference, context[:reference]
77
+ end
78
+ end
79
+ end
80
+
81
+ Ducklink.decorate 'http://shop.example.com/goodies', :reference => 100
82
+ => http://affiliate.example.com?clickref=100&url=http://shop.example.com/goodies#campaign=campaign1
83
+
84
+ ## TODO ##
85
+
86
+ 1. Tests!
87
+ 2. URL validity checks
88
+ 3. Merge parameters if url already has them
89
+ 4. Intelligently URL encode parameters
90
+ 5. Support introspection of keys expected in context so calling code knows what to provide
91
+
92
+ ## Licence ##
93
+
94
+ Ducklink is released under the MIT Licence.
95
+
96
+ Copyright © 2011 Henry Garner
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ducklink/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ducklink"
7
+ s.version = Ducklink::VERSION
8
+ s.authors = ["Henry Garner"]
9
+ s.email = ["henry.garner@mac.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Decorates URLs according to a format specification}
12
+ s.description = %q{}
13
+
14
+ s.rubyforge_project = "ducklink"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,70 @@
1
+ require "ducklink/version"
2
+ require 'uri'
3
+ require 'cgi'
4
+
5
+ module Ducklink
6
+ def self.decorate(url)
7
+ Decorator.decorate(url)
8
+ end
9
+
10
+ class Decorator
11
+ class << self
12
+ @@hosts = {}
13
+
14
+ def configure(&block)
15
+ Params.new.instance_exec &block
16
+ end
17
+
18
+ def hosts
19
+ @@hosts
20
+ end
21
+
22
+ def host(domain, params, &block)
23
+ @@hosts[domain] = [params, block]
24
+ end
25
+
26
+ def decorate(url, context = {})
27
+ params, block = hosts[URI.parse(url).host]
28
+ return url unless params
29
+
30
+ params.set :url, url
31
+ params.instance_exec context, &block
32
+
33
+ format = params[:format]
34
+ format.scan(/\{\{([a-z_]+?)\}\}/i).inject(format) do |result, matches|
35
+ params[matches.first] ? result.gsub("{{#{matches.first}}}", params[matches.first]) : result
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ class Params
42
+ attr_reader :settings
43
+
44
+ def initialize(settings = {})
45
+ @settings = settings
46
+ end
47
+
48
+ def format(format)
49
+ set :format, format
50
+ end
51
+
52
+ def group(&block)
53
+ Params.new(settings.clone).instance_exec &block
54
+ end
55
+
56
+ def set(key, value)
57
+ @settings[key.to_s] = value.to_s
58
+ end
59
+
60
+ def [](key)
61
+ @settings[key.to_s]
62
+ end
63
+
64
+ def host(*domains, &block)
65
+ domains.each do |domain|
66
+ Ducklink::Decorator.host domain, Params.new(settings.clone), &block
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ module Ducklink
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ducklink
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - Henry Garner
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-23 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: ""
18
+ email:
19
+ - henry.garner@mac.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - .gitignore
28
+ - Gemfile
29
+ - README.markdown
30
+ - Rakefile
31
+ - ducklink.gemspec
32
+ - lib/ducklink.rb
33
+ - lib/ducklink/version.rb
34
+ has_rdoc: true
35
+ homepage: ""
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ requirements: []
56
+
57
+ rubyforge_project: ducklink
58
+ rubygems_version: 1.6.2
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Decorates URLs according to a format specification
62
+ test_files: []
63
+