-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathtest.rb
More file actions
77 lines (61 loc) · 1.67 KB
/
Copy pathtest.rb
File metadata and controls
77 lines (61 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# frozen_string_literal: true
module VoightKampff
# Test User-Agent against Voight-Kampff
class Test
CRAWLERS_FILENAME = 'crawler-user-agents.json'
class << self
def crawlers
@crawlers ||= JSON.parse File.read preferred_path
end
def crawler_regexp
@crawler_regexp ||= begin
# NOTE: This is admittedly a bit convoluted
# but the performance gains make it worthwhile
crawler_patterns =
crawlers.map.with_index do |crawler, index|
"(?<match#{index}>#{crawler['pattern']})"
end.join('|')
crawler_patterns = "(#{crawler_patterns})"
Regexp.new(crawler_patterns, Regexp::IGNORECASE)
end
end
private
def lookup_paths
# These paths should be orderd by priority
[
(Rails.root if defined? Rails),
Dir.pwd,
VoightKampff::ROOT
]
end
def preferred_path
lookup_paths.find do |base_path|
next unless base_path
path = File.join base_path, 'tmp', CRAWLERS_FILENAME
break path if File.exist? path
end
end
end
attr_accessor :user_agent_string
def initialize(user_agent_string)
@user_agent_string = user_agent_string
end
def agent
@agent ||= matching_crawler || {}
end
def human?
agent.empty?
end
def bot?
!human?
end
alias replicant? bot?
private
def matching_crawler
match = self.class.crawler_regexp.match(@user_agent_string)
return unless match
index = match.names.first.sub(/match/, '').to_i
self.class.crawlers[index]
end
end
end