rack-campaign 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +24 -0
- data/README.textile +1 -0
- data/Rakefile +53 -0
- data/lib/rack/zetetic/campaign_link.rb +53 -0
- metadata +77 -0
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2010, ZETETIC LLC
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the ZETETIC LLC nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
|
16
|
+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.textile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
More to come soon...
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rubygems/specification'
|
4
|
+
require 'date'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
|
7
|
+
GEM = "rack-campaign"
|
8
|
+
GEM_VERSION = "0.0.2"
|
9
|
+
AUTHOR = "Billy Gray"
|
10
|
+
EMAIL = "wgray@zetetic.net"
|
11
|
+
HOMEPAGE = "http://github.com/billymeltdown/rack-campaign"
|
12
|
+
SUMMARY = "A Rack middleware/app for re-writing a simple URL into a Google analytics-tracked URL for ad campaigns"
|
13
|
+
DESCRIPTION = "Allows you to route URLs like /c/get-widgets to http://widgets.com/promo?utm_campaign=fallwidgets, etc."
|
14
|
+
|
15
|
+
spec = Gem::Specification.new do |s|
|
16
|
+
s.name = GEM
|
17
|
+
s.version = GEM_VERSION
|
18
|
+
s.platform = Gem::Platform::RUBY
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.extra_rdoc_files = ["README.textile", "LICENSE"]
|
21
|
+
s.summary = SUMMARY
|
22
|
+
s.description = s.summary
|
23
|
+
s.author = AUTHOR
|
24
|
+
s.email = EMAIL
|
25
|
+
s.homepage = HOMEPAGE
|
26
|
+
s.add_dependency "rack"
|
27
|
+
s.require_path = 'lib'
|
28
|
+
s.files = %w(LICENSE README.textile Rakefile) + Dir.glob("{lib}/**/*")
|
29
|
+
end
|
30
|
+
|
31
|
+
task :default => :spec
|
32
|
+
|
33
|
+
desc "Run specs"
|
34
|
+
Spec::Rake::SpecTask.new do |t|
|
35
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
36
|
+
t.spec_opts = %w(-fs --color)
|
37
|
+
end
|
38
|
+
|
39
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
40
|
+
pkg.gem_spec = spec
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "install the gem locally"
|
44
|
+
task :install => [:package] do
|
45
|
+
sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "create a gemspec file"
|
49
|
+
task :make_spec do
|
50
|
+
File.open("#{GEM}.gemspec", "w") do |file|
|
51
|
+
file.puts spec.to_ruby
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rack'
|
3
|
+
require 'rack/request'
|
4
|
+
require 'rack/utils'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module Rack
|
8
|
+
module Zetetic
|
9
|
+
class CampaignLink
|
10
|
+
|
11
|
+
UTM_VARS = {
|
12
|
+
'campaign' => 'utm_campaign',
|
13
|
+
'source' => 'utm_source',
|
14
|
+
'medium' => 'utm_medium',
|
15
|
+
'term' => 'utm_term',
|
16
|
+
'content' => 'utm_content'
|
17
|
+
}
|
18
|
+
|
19
|
+
attr_accessor :campaign_file
|
20
|
+
attr_accessor :campaigns
|
21
|
+
def campaigns
|
22
|
+
@campaigns ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize *args
|
26
|
+
@app = args.shift if args.first.respond_to? :call
|
27
|
+
@campaign_file = args.shift
|
28
|
+
@campaigns = open( @campaign_file ){ |yf| YAML::load( yf ) }
|
29
|
+
yield self if block_given?
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(env)
|
33
|
+
# get a convenient request wrapper from Rack
|
34
|
+
req = Rack::Request.new(env)
|
35
|
+
id = req.path.split('/').last # take the last path piece as the campaign id
|
36
|
+
if campaign = @campaigns[id]
|
37
|
+
# we've got a match!
|
38
|
+
destination = campaign['url'] + '?'
|
39
|
+
UTM_VARS.each do |key, utm_name|
|
40
|
+
destination << "#{utm_name}=#{Rack::Utils.escape(campaign['tokens'][key])}&"
|
41
|
+
end
|
42
|
+
|
43
|
+
[ 302, { 'Location' => destination, "Content-Type" => "text/plain" }, ['Redirecting...'] ]
|
44
|
+
else
|
45
|
+
# drop a 404 on the head!
|
46
|
+
[ 404, {'Content-Type' => 'text/html'}, ["Page not found"] ]
|
47
|
+
end # if
|
48
|
+
end # call
|
49
|
+
end # CampaignLink
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Rack::Handler::Mongrel.run Rack::Zetetic::CampaignLink.new, :Port => 9292
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-campaign
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Billy Gray
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-06-10 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rack
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description: A Rack middleware/app for re-writing a simple URL into a Google analytics-tracked URL for ad campaigns
|
33
|
+
email: wgray@zetetic.net
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files:
|
39
|
+
- README.textile
|
40
|
+
- LICENSE
|
41
|
+
files:
|
42
|
+
- LICENSE
|
43
|
+
- README.textile
|
44
|
+
- Rakefile
|
45
|
+
- lib/rack/zetetic/campaign_link.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: http://github.com/billymeltdown/rack-campaign
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.3.6
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: A Rack middleware/app for re-writing a simple URL into a Google analytics-tracked URL for ad campaigns
|
76
|
+
test_files: []
|
77
|
+
|