jobs-referer-parser 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/.DS_Store +0 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE-2.0.txt +202 -0
- data/README.md +98 -0
- data/Rakefile +10 -0
- data/data/referers.json +4090 -0
- data/data/referers.yml +3621 -0
- data/lib/.DS_Store +0 -0
- data/lib/referer-parser/errors.rb +29 -0
- data/lib/referer-parser/parser.rb +215 -0
- data/lib/referer-parser/version.rb +19 -0
- data/lib/referer-parser.rb +21 -0
- data/referer-parser.gemspec +38 -0
- data/spec/fixtures/internal.json +9 -0
- data/spec/fixtures/invalid.json +1 -0
- data/spec/fixtures/invalid.yml +2 -0
- data/spec/fixtures/referer-tests.json +234 -0
- data/spec/parser_spec.rb +181 -0
- data/spec/spec_helper.rb +35 -0
- metadata +103 -0
data/lib/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Author:: Yali Sassoon (mailto:support@snowplowanalytics.com)
|
13
|
+
# Copyright:: Copyright (c) 2012-2013 Snowplow Analytics Ltd
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
module RefererParser
|
17
|
+
|
18
|
+
class RefererParserError < StandardError
|
19
|
+
attr_reader :original
|
20
|
+
def initialize(msg, original=nil);
|
21
|
+
super(msg);
|
22
|
+
@original = original;
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class UnsupportedFormatError < RefererParserError; end
|
27
|
+
class InvalidUriError < RefererParserError; end
|
28
|
+
class CorruptReferersError < RefererParserError; end
|
29
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# Copyright (c) 2014 Inside Systems, Inc All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Author:: Kelley Reynolds (mailto:kelley@insidesystems.net)
|
13
|
+
# Copyright:: Copyright (c) 2014 Inside Systems Inc
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
require 'uri'
|
17
|
+
require 'cgi'
|
18
|
+
|
19
|
+
module RefererParser
|
20
|
+
class Parser
|
21
|
+
DefaultFile = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'referers.json'))
|
22
|
+
|
23
|
+
# Create a new parser from one or more filenames/uris, defaults to ../data/referers.json
|
24
|
+
def initialize(uris=DefaultFile)
|
25
|
+
@domain_index ||= {}
|
26
|
+
@name_hash ||= {}
|
27
|
+
|
28
|
+
update(uris)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Update the referer database with one or more uris
|
32
|
+
def update(uris)
|
33
|
+
[uris].flatten.each do |uri|
|
34
|
+
deserialize_referer_data(read_referer_data(uri), File.extname(uri).downcase)
|
35
|
+
end
|
36
|
+
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
# Clean out the database
|
41
|
+
def clear!
|
42
|
+
@domain_index, @name_hash = {}, {}
|
43
|
+
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
# Add a referer to the database with medium, name, domain or array of domains, and a parameter or array of parameters
|
48
|
+
# If called manually and a domain is added to an existing entry with a path, you may need to call optimize_index! afterwards.
|
49
|
+
def add_referer(medium, name, domains, parameters=nil)
|
50
|
+
# The same name can be used with multiple mediums so we make a key here
|
51
|
+
name_key = "#{name}-#{medium}"
|
52
|
+
|
53
|
+
# Update the name has with the parameter and medium data
|
54
|
+
@name_hash[name_key] = {:source => name, :medium => medium, :parameters => [parameters].flatten }
|
55
|
+
|
56
|
+
# Update the domain to name index
|
57
|
+
[domains].flatten.each do |domain_url|
|
58
|
+
domain, *path = domain_url.split('/')
|
59
|
+
if domain =~ /\Awww\.(.*)\z/i
|
60
|
+
domain = $1
|
61
|
+
end
|
62
|
+
|
63
|
+
domain.downcase!
|
64
|
+
|
65
|
+
@domain_index[domain] ||= []
|
66
|
+
if !path.empty?
|
67
|
+
@domain_index[domain] << ['/' + path.join('/'), name_key]
|
68
|
+
else
|
69
|
+
@domain_index[domain] << ['/', name_key]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Prune duplicate entries and sort with the most specific path first if there is more than one entry
|
75
|
+
# In this case, sorting by the longest string works fine
|
76
|
+
def optimize_index!
|
77
|
+
@domain_index.each do |key, val|
|
78
|
+
# Sort each path/name_key pair by the longest path
|
79
|
+
@domain_index[key].sort! { |a, b|
|
80
|
+
b[0].size <=> a[0].size
|
81
|
+
}.uniq!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Given a string or URI, return a hash of data
|
86
|
+
def parse(obj)
|
87
|
+
url = obj.is_a?(URI) ? obj : URI.parse(obj.to_s)
|
88
|
+
|
89
|
+
if !['http', 'https'].include?(url.scheme)
|
90
|
+
raise InvalidUriError.new("Only HTTP and HTTPS schemes are supported -- #{url.scheme}")
|
91
|
+
end
|
92
|
+
|
93
|
+
data = { :known => false, :uri => url.to_s }
|
94
|
+
|
95
|
+
domain, name_key = domain_and_name_key_for(url)
|
96
|
+
if domain and name_key
|
97
|
+
referer_data = @name_hash[name_key]
|
98
|
+
data[:known] = true
|
99
|
+
data[:source] = referer_data[:source]
|
100
|
+
data[:medium] = referer_data[:medium]
|
101
|
+
data[:domain] = domain
|
102
|
+
|
103
|
+
# Parse parameters if the referer uses them
|
104
|
+
if url.query and referer_data[:parameters]
|
105
|
+
query_params = CGI.parse(url.query)
|
106
|
+
referer_data[:parameters].each do |param|
|
107
|
+
# If there is a matching parameter, get the first non-blank value
|
108
|
+
if !(values = query_params[param]).empty?
|
109
|
+
data[:term] = values.select { |v| v.strip != "" }.first
|
110
|
+
break if data[:term]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
data
|
117
|
+
rescue URI::InvalidURIError
|
118
|
+
raise InvalidUriError.new("Unable to parse URI, not a URI? -- #{obj.inspect}", $!)
|
119
|
+
end
|
120
|
+
|
121
|
+
protected
|
122
|
+
|
123
|
+
# Determine the correct name_key for this host and path
|
124
|
+
def domain_and_name_key_for(uri)
|
125
|
+
# Create a proc that will return immediately
|
126
|
+
check = Proc.new do |domain|
|
127
|
+
domain.downcase!
|
128
|
+
if paths = @domain_index[domain]
|
129
|
+
paths.each do |path, name_key|
|
130
|
+
return [domain, name_key] if uri.path.include?(path)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# First check hosts with and without the www prefix with the path
|
136
|
+
if uri.host =~ /\Awww\.(.+)\z/i
|
137
|
+
check.call $1
|
138
|
+
else
|
139
|
+
check.call uri.host
|
140
|
+
end
|
141
|
+
|
142
|
+
# Remove subdomains until only three are left (probably good enough)
|
143
|
+
host_arr = uri.host.split(".")
|
144
|
+
while host_arr.size > 2 do
|
145
|
+
host_arr.shift
|
146
|
+
check.call host_arr.join(".")
|
147
|
+
end
|
148
|
+
|
149
|
+
nil
|
150
|
+
end
|
151
|
+
|
152
|
+
def deserialize_referer_data(data, ext)
|
153
|
+
# Parse the loaded data with the correct parser
|
154
|
+
deserialized_data = if ['.yml', '.yaml'].include?(ext)
|
155
|
+
deserialize_yaml(data)
|
156
|
+
elsif ext == '.json'
|
157
|
+
deserialize_json(data)
|
158
|
+
else
|
159
|
+
raise UnsupportedFormatError.new("Only yaml and json file formats are currently supported -- #{@msg}")
|
160
|
+
end
|
161
|
+
|
162
|
+
begin
|
163
|
+
parse_referer_data deserialized_data
|
164
|
+
rescue
|
165
|
+
raise CorruptReferersError.new("Unable to parse data file -- #{$!.class} #{$!.to_s}", $!)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def deserialize_yaml(data)
|
170
|
+
require 'yaml'
|
171
|
+
YAML.load(data)
|
172
|
+
rescue Exception => e
|
173
|
+
raise CorruptReferersError.new("Unable to YAML file -- #{e.to_s}", e)
|
174
|
+
end
|
175
|
+
|
176
|
+
def deserialize_json(data)
|
177
|
+
require 'json'
|
178
|
+
JSON.parse(data)
|
179
|
+
rescue JSON::ParserError
|
180
|
+
raise CorruptReferersError.new("Unable to JSON file -- #{$!.to_s}", $!)
|
181
|
+
end
|
182
|
+
|
183
|
+
def read_referer_data(uri)
|
184
|
+
# Attempt to read the data from the network if application, or the file on the local system
|
185
|
+
if uri =~ /\A(?:ht|f)tps?:\/\//
|
186
|
+
require 'open-uri'
|
187
|
+
begin
|
188
|
+
open(uri).read
|
189
|
+
rescue OpenURI::HTTPError
|
190
|
+
raise InvalidUriError.new("Cannot load referer data from URI #{uri} -- #{$!.to_s}", $!)
|
191
|
+
end
|
192
|
+
else
|
193
|
+
File.read(uri)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Create an index that maps domains/paths to their name/medium and a hash that contains their metadata
|
198
|
+
# The index strips leading www in order to keep the index smaller
|
199
|
+
# Format of the domain_index:
|
200
|
+
# { domain => [[path1, name_key], [path2, name_key], ... ] }
|
201
|
+
# Format of the name_hash:
|
202
|
+
# { name_key => {:source, :medium, :parameters} }
|
203
|
+
def parse_referer_data(data)
|
204
|
+
data.each do |medium, name_hash|
|
205
|
+
name_hash.each do |name, name_data|
|
206
|
+
add_referer(medium, name, name_data['domains'], name_data['parameters'])
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
optimize_index!
|
211
|
+
rescue
|
212
|
+
raise CorruptReferersError.new("Unable to parse referer data", $!)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Original Author:: Yali Sassoon (mailto:support@snowplowanalytics.com)
|
13
|
+
# Copyright:: Copyright (c) 2012-2013 Snowplow Analytics Ltd
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
module RefererParser
|
17
|
+
NAME = "jobs-referer-parser"
|
18
|
+
VERSION = "0.0.1"
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Author:: Yali Sassoon (mailto:support@snowplowanalytics.com)
|
13
|
+
# Copyright:: Copyright (c) 2012-2013 Snowplow Analytics Ltd
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
require "referer-parser/version"
|
17
|
+
require "referer-parser/errors"
|
18
|
+
require "referer-parser/parser"
|
19
|
+
|
20
|
+
module RefererParser
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Author:: Yali Sassoon (mailto:support@snowplowanalytics.com)
|
13
|
+
# Copyright:: Copyright (c) 2012-2013 Snowplow Analytics Ltd
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
# -*- encoding: utf-8 -*-
|
17
|
+
lib = File.expand_path('../lib', __FILE__)
|
18
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
19
|
+
require 'referer-parser/version'
|
20
|
+
|
21
|
+
Gem::Specification.new do |gem|
|
22
|
+
gem.authors = ["Yali Sassoon", "Martin Loy", "Alex Dean", "Kelley Reynolds", "Shiv Bharthur"]
|
23
|
+
gem.email = ["shiv@recroup.com"]
|
24
|
+
gem.description = %q{Library for extracting marketing attribution data from referer URLs}
|
25
|
+
gem.summary = %q{Library for extracting marketing attribution data (e.g. search terms) from referer (sic) URLs. This is used by Recroup (http://github.com/bharthur/jobs-referer-parser). Originally developed by Snowplow (http://github.com/snowplow/snowplow).}
|
26
|
+
gem.homepage = "http://github.com/bharthur/jobs-referer-parser"
|
27
|
+
|
28
|
+
gem.files = `git ls-files`.split($/)
|
29
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
30
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
31
|
+
gem.name = RefererParser::NAME
|
32
|
+
gem.version = RefererParser::VERSION
|
33
|
+
gem.platform = Gem::Platform::RUBY
|
34
|
+
gem.require_paths = ["lib"]
|
35
|
+
|
36
|
+
gem.add_development_dependency "rspec", "~> 2.6"
|
37
|
+
gem.add_development_dependency "rake", ">= 0.9.2"
|
38
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This has the right extension but is unparsable gibberish to json:{}}}}
|
@@ -0,0 +1,234 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"spec": "Google Images search",
|
4
|
+
"uri": "http://www.google.fr/imgres?q=Ogham+the+celtic+oracle&hl=fr&safe=off&client=firefox-a&hs=ZDu&sa=X&rls=org.mozilla:fr-FR:unofficial&tbm=isch&prmd=imvnsa&tbnid=HUVaj-o88ZRdYM:&imgrefurl=http://www.psychicbazaar.com/oracles/101-ogham-the-celtic-oracle-set.html&docid=DY5_pPFMliYUQM&imgurl=http://mdm.pbzstatic.com/oracles/ogham-the-celtic-oracle-set/montage.png&w=734&h=250&ei=GPdWUIePCOqK0AWp3oCQBA&zoom=1&iact=hc&vpx=129&vpy=276&dur=827&hovh=131&hovw=385&tx=204&ty=71&sig=104115776612919232039&page=1&tbnh=69&tbnw=202&start=0&ndsp=26&ved=1t:429,r:13,s:0,i:114&biw=1272&bih=826",
|
5
|
+
"medium": "search",
|
6
|
+
"source": "Google Images",
|
7
|
+
"term": "Ogham the celtic oracle",
|
8
|
+
"known": true
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"spec": "Yahoo! Images search",
|
12
|
+
"uri": "http://it.images.search.yahoo.com/images/view;_ylt=A0PDodgQmGBQpn4AWQgdDQx.;_ylu=X3oDMTBlMTQ4cGxyBHNlYwNzcgRzbGsDaW1n?back=http%3A%2F%2Fit.images.search.yahoo.com%2Fsearch%2Fimages%3Fp%3DEarth%2BMagic%2BOracle%2BCards%26fr%3Dmcafee%26fr2%3Dpiv-web%26tab%3Dorganic%26ri%3D5&w=1064&h=1551&imgurl=mdm.pbzstatic.com%2Foracles%2Fearth-magic-oracle-cards%2Fcard-1.png&rurl=http%3A%2F%2Fwww.psychicbazaar.com%2Foracles%2F143-earth-magic-oracle-cards.html&size=2.8+KB&name=Earth+Magic+Oracle+Cards+-+Psychic+Bazaar&p=Earth+Magic+Oracle+Cards&oid=f0a5ad5c4211efe1c07515f56cf5a78e&fr2=piv-web&fr=mcafee&tt=Earth%2BMagic%2BOracle%2BCards%2B-%2BPsychic%2BBazaar&b=0&ni=90&no=5&ts=&tab=organic&sigr=126n355ib&sigb=13hbudmkc&sigi=11ta8f0gd&.crumb=IZBOU1c0UHU",
|
13
|
+
"medium": "search",
|
14
|
+
"source": "Yahoo! Images",
|
15
|
+
"term": "Earth Magic Oracle Cards",
|
16
|
+
"known": true
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"spec": "Powered by Google",
|
20
|
+
"uri": "http://isearch.avg.com/pages/images.aspx?q=tarot+card+change&sap=dsp&lang=en&mid=209215200c4147d1a9d6d1565005540b-b0d4f81a8999f5981f04537c5ec8468fd5234593&cid=%7B50F9298B-C111-4C7E-9740-363BF0015949%7D&v=12.1.0.21&ds=AVG&d=7%2F23%2F2012+10%3A31%3A08+PM&pr=fr&sba=06oENya4ZG1YS6vOLJwpLiFdjG91ICt2YE59W2p5ENc2c4w8KvJb5xbvjkj3ceMjnyTSpZq-e6pj7GQUylIQtuK4psJU60wZuI-8PbjX-OqtdX3eIcxbMoxg3qnIasP0ww2fuID1B-p2qJln8vBHxWztkpxeixjZPSppHnrb9fEcx62a9DOR0pZ-V-Kjhd-85bIL0QG5qi1OuA4M1eOP4i_NzJQVRXPQDmXb-CpIcruc2h5FE92Tc8QMUtNiTEWBbX-QiCoXlgbHLpJo5Jlq-zcOisOHNWU2RSHYJnK7IUe_SH6iQ.%2CYT0zO2s9MTA7aD1mNjZmZDBjMjVmZDAxMGU4&snd=hdr&tc=test1",
|
21
|
+
"medium": "search",
|
22
|
+
"source": "Google",
|
23
|
+
"term": "tarot card change",
|
24
|
+
"known": true
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"spec": "Google search #1",
|
28
|
+
"uri": "http://www.google.com/search",
|
29
|
+
"medium": "search",
|
30
|
+
"source": "Google",
|
31
|
+
"term": null,
|
32
|
+
"known": true
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"spec": "Google search #2",
|
36
|
+
"uri": "http://www.google.com/search?q=gateway+oracle+cards+denise+linn&hl=en&client=safari",
|
37
|
+
"medium": "search",
|
38
|
+
"source": "Google",
|
39
|
+
"term": "gateway oracle cards denise linn",
|
40
|
+
"known": true
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"spec": "Yahoo! search",
|
44
|
+
"uri": "http://es.search.yahoo.com/search;_ylt=A7x9QbwbZXxQ9EMAPCKT.Qt.?p=BIEDERMEIER+FORTUNE+TELLING+CARDS&ei=utf-8&type=685749&fr=chr-greentree_gc&xargs=0&pstart=1&b=11",
|
45
|
+
"medium": "search",
|
46
|
+
"source": "Yahoo!",
|
47
|
+
"term": "BIEDERMEIER FORTUNE TELLING CARDS",
|
48
|
+
"known": true
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"spec": "PriceRunner search",
|
52
|
+
"uri": "http://www.pricerunner.co.uk/search?displayNoHitsMessage=1&q=wild+wisdom+of+the+faery+oracle",
|
53
|
+
"medium": "search",
|
54
|
+
"source": "PriceRunner",
|
55
|
+
"term": "wild wisdom of the faery oracle",
|
56
|
+
"known": true
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"spec": "Bing Images search",
|
60
|
+
"uri": "http://www.bing.com/images/search?q=psychic+oracle+cards&view=detail&id=D268EDDEA8D3BF20AF887E62AF41E8518FE96F08",
|
61
|
+
"medium": "search",
|
62
|
+
"source": "Bing Images",
|
63
|
+
"term": "psychic oracle cards",
|
64
|
+
"known": true
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"spec": "IXquick search",
|
68
|
+
"uri": "https://s3-us3.ixquick.com/do/search",
|
69
|
+
"medium": "search",
|
70
|
+
"source": "IXquick",
|
71
|
+
"term": null,
|
72
|
+
"known": true
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"spec": "AOL search",
|
76
|
+
"uri": "http://aolsearch.aol.co.uk/aol/search?s_chn=hp&enabled_terms=&s_it=aoluk-homePage50&q=pendulums",
|
77
|
+
"medium": "search",
|
78
|
+
"source": "AOL",
|
79
|
+
"term": "pendulums",
|
80
|
+
"known": true
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"spec": "AOL search.com",
|
84
|
+
"uri": "http://www.aolsearch.com/search?s_pt=hp&s_gl=NL&query=voorbeeld+cv+competenties&invocationType=tb50hpcnnbie7-nl-nl",
|
85
|
+
"medium": "search",
|
86
|
+
"source": "AOL",
|
87
|
+
"term": "voorbeeld cv competenties",
|
88
|
+
"known": true
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"spec": "Ask search",
|
92
|
+
"uri": "http://uk.search-results.com/web?qsrc=1&o=1921&l=dis&q=pendulums&dm=ctry&atb=sysid%3D406%3Aappid%3D113%3Auid%3D8f40f651e7b608b5%3Auc%3D1346336505%3Aqu%3Dpendulums%3Asrc%3Dcrt%3Ao%3D1921&locale=en_GB",
|
93
|
+
"medium": "search",
|
94
|
+
"source": "Ask",
|
95
|
+
"term": "pendulums",
|
96
|
+
"known": true
|
97
|
+
},
|
98
|
+
{
|
99
|
+
"spec": "Mail.ru search",
|
100
|
+
"uri": "http://go.mail.ru/search?q=Gothic%20Tarot%20Cards&where=any&num=10&rch=e&sf=20",
|
101
|
+
"medium": "search",
|
102
|
+
"source": "Mail.ru",
|
103
|
+
"term": "Gothic Tarot Cards",
|
104
|
+
"known": true
|
105
|
+
},
|
106
|
+
{
|
107
|
+
"spec": "Yandex search",
|
108
|
+
"uri": "http://images.yandex.ru/yandsearch?text=Blue%20Angel%20Oracle%20Blue%20Angel%20Oracle&noreask=1&pos=16&rpt=simage&lr=45&img_url=http%3A%2F%2Fmdm.pbzstatic.com%2Foracles%2Fblue-angel-oracle%2Fbox-small.png",
|
109
|
+
"medium": "search",
|
110
|
+
"source": "Yandex Images",
|
111
|
+
"term": "Blue Angel Oracle Blue Angel Oracle",
|
112
|
+
"known": true
|
113
|
+
},
|
114
|
+
{
|
115
|
+
"spec": "Ask toolbar search",
|
116
|
+
"uri": "http://search.tb.ask.com/search/GGmain.jhtml?cb=AYY&pg=GGmain&p2=%5EAYY%5Exdm071%5EYYA%5Eid&n=77fdaa55&qid=c2678d9147654034bb8b16daa7bfb48c&ss=sub&st=hp&ptb=F9FC6C22-EAE6-4D1E-8126-A70119B6E02F&si=flvrunner&tpr=hst&searchfor=CARA+MEMASAK+CUMI+CUMI&ots=1219016089614",
|
117
|
+
"medium": "search",
|
118
|
+
"source": "Ask Toolbar",
|
119
|
+
"term": "CARA MEMASAK CUMI CUMI",
|
120
|
+
"known": true
|
121
|
+
},
|
122
|
+
{
|
123
|
+
"spec": "Ask toolbar search #2",
|
124
|
+
"uri": "http://search.tb.ask.com/search/GGmain.jhtml?&st=hp&p2=%5EZU%5Exdm458%5EYYA%5Eus&n=77fda1bd&ptb=F0B68CA5-4791-4376-BFCC-5F0100329FB6&si=CMKg9-nX07oCFSjZQgodcikACQ&tpr=hpsbsug&searchfor=test",
|
125
|
+
"medium": "search",
|
126
|
+
"source": "Ask Toolbar",
|
127
|
+
"term": "test",
|
128
|
+
"known": true
|
129
|
+
},
|
130
|
+
{
|
131
|
+
"spec": "Voila search",
|
132
|
+
"uri": "http://search.ke.voila.fr/?module=voila&bhv=web_fr&kw=test",
|
133
|
+
"medium": "search",
|
134
|
+
"source": "Voila",
|
135
|
+
"term": "test",
|
136
|
+
"known": true
|
137
|
+
},
|
138
|
+
{
|
139
|
+
"spec": "Dale search",
|
140
|
+
"uri": "http://www.dalesearch.com/?q=+lego.nl+%2Fclub&s=web&as=0&rlz=0&babsrc=HP_ss",
|
141
|
+
"medium": "search",
|
142
|
+
"source": "Dalesearch",
|
143
|
+
"term": " lego.nl /club",
|
144
|
+
"known": true
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"spec": "Twitter redirect",
|
148
|
+
"uri": "http://t.co/chrgFZDb",
|
149
|
+
"medium": "social",
|
150
|
+
"source": "Twitter",
|
151
|
+
"term": null,
|
152
|
+
"known": true
|
153
|
+
},
|
154
|
+
{
|
155
|
+
"spec": "Facebook social",
|
156
|
+
"uri": "http://www.facebook.com/l.php?u=http%3A%2F%2Fwww.psychicbazaar.com&h=yAQHZtXxS&s=1",
|
157
|
+
"medium": "social",
|
158
|
+
"source": "Facebook",
|
159
|
+
"term": null,
|
160
|
+
"known": true
|
161
|
+
},
|
162
|
+
{
|
163
|
+
"spec": "Facebook mobile",
|
164
|
+
"uri": "http://m.facebook.com/l.php?u=http%3A%2F%2Fwww.psychicbazaar.com%2Fblog%2F2012%2F09%2Fpsychic-bazaar-reviews-tarot-foundations-31-days-to-read-tarot-with-confidence%2F&h=kAQGXKbf9&s=1",
|
165
|
+
"medium": "social",
|
166
|
+
"source": "Facebook",
|
167
|
+
"term": null,
|
168
|
+
"known": true
|
169
|
+
},
|
170
|
+
{
|
171
|
+
"spec": "Odnoklassniki",
|
172
|
+
"uri": "http://www.odnoklassniki.ru/dk?cmd=logExternal&st._aid=Conversations_Openlink&st.name=externalLinkRedirect&st.link=http%3A%2F%2Fwww.psychicbazaar.com%2Foracles%2F187-blue-angel-oracle.html",
|
173
|
+
"medium": "social",
|
174
|
+
"source": "Odnoklassniki",
|
175
|
+
"term": null,
|
176
|
+
"known": true
|
177
|
+
},
|
178
|
+
{
|
179
|
+
"spec": "Tumblr social #1",
|
180
|
+
"uri": "http://www.tumblr.com/dashboard",
|
181
|
+
"medium": "social",
|
182
|
+
"source": "Tumblr",
|
183
|
+
"term": null,
|
184
|
+
"known": true
|
185
|
+
},
|
186
|
+
{
|
187
|
+
"spec": "Tumblr w subdomain",
|
188
|
+
"uri": "http://psychicbazaar.tumblr.com/",
|
189
|
+
"medium": "social",
|
190
|
+
"source": "Tumblr",
|
191
|
+
"term": null,
|
192
|
+
"known": true
|
193
|
+
},
|
194
|
+
{
|
195
|
+
"spec": "Yahoo! Mail",
|
196
|
+
"uri": "http://36ohk6dgmcd1n-c.c.yom.mail.yahoo.net/om/api/1.0/openmail.app.invoke/36ohk6dgmcd1n/11/1.0.35/us/en-US/view.html/0",
|
197
|
+
"medium": "email",
|
198
|
+
"source": "Yahoo! Mail",
|
199
|
+
"term": null,
|
200
|
+
"known": true
|
201
|
+
},
|
202
|
+
{
|
203
|
+
"spec": "Outlook.com mail",
|
204
|
+
"uri": "http://co106w.col106.mail.live.com/default.aspx?rru=inbox",
|
205
|
+
"medium": "email",
|
206
|
+
"source": "Outlook.com",
|
207
|
+
"term": null,
|
208
|
+
"known": true
|
209
|
+
},
|
210
|
+
{
|
211
|
+
"spec": "Orange Webmail",
|
212
|
+
"uri": "http://webmail1m.orange.fr/webmail/fr_FR/read.html?FOLDER=SF_INBOX&IDMSG=8594&check=&SORTBY=31",
|
213
|
+
"medium": "email",
|
214
|
+
"source": "Orange Webmail",
|
215
|
+
"term": null,
|
216
|
+
"known": true
|
217
|
+
},
|
218
|
+
{
|
219
|
+
"spec": "Internal HTTP",
|
220
|
+
"uri": "http://www.snowplowanalytics.com/about/team",
|
221
|
+
"medium": "internal",
|
222
|
+
"source": "SnowPlow",
|
223
|
+
"term": null,
|
224
|
+
"known": true
|
225
|
+
},
|
226
|
+
{
|
227
|
+
"spec": "Internal HTTPS",
|
228
|
+
"uri": "https://www.snowplowanalytics.com/account/profile",
|
229
|
+
"medium": "internal",
|
230
|
+
"source": "SnowPlow",
|
231
|
+
"term": null,
|
232
|
+
"known": true
|
233
|
+
}
|
234
|
+
]
|