Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
module LogfileAnalyser class UserAgentStringParser def parse(user_agent_string) user_agent_name = nil user_agent_version = nil case user_agent_string # Parse Opera # e.g. Opera/9.63 (Windows NT 5.1; U; en) Presto/2.1.1 # e.g. Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.10 when /^Opera\/(.+)\..+? \(.*?\)/ user_agent_name = :opera user_agent_version = $1.to_i when /^Mozilla\/4\.0 \(compatible; MSIE ([^.]+)\.([^;]+); .+?\) (.*? )*?Opera ((.+)\..+?)/ user_agent_name = :opera user_agent_version = $4.to_i # Parse Internet Explorer # e.g. Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0) when /^Mozilla\/4\.0 \(compatible; +MSIE ([^.]+)\.([^;]+);/ user_agent_name = :msie user_agent_version = $1.to_i # Parse Firefox # e.g. Mozilla/5.0 (Windows; U; Windows NT 6.0; it; rv:1.9.1b2) Gecko/2008092313 Ubuntu/8.04 (hardy) Firefox/3.1.6 # FIXME e.g. Mozilla/5.0 Gecko/20070713 Firefox/2.0.0.0 when /^Mozilla\/.\.. \(.*?; .*?; .*?; .*?; rv:.*?\) Gecko\/\d+ (.*? )*?(Firefox|Shiretoko|Iceweasel|Iceweasel not firefox)\/(.+)\..+/ user_agent_name = :firefox user_agent_version = $3.to_i # Parse SeaMonkey # e.g. Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.19) Gecko/20081204 SeaMonkey/1.1.14 when /^Mozilla\/.\.. \(.*?; .*?; .*?; .*?; rv:.*?\) Gecko\/\d+ (.*? )*SeaMonkey\/(.+)\..+?/ user_agent_name = :seamonkey user_agent_version = $2.to_i # Parse Safari # e.g. Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1 when /^Mozilla\/5\.0 \(.*?; .*?; .*?; .*?\) AppleWebKit\/\S+ \(KHTML, like Gecko\) Version\/(.)\S+ Safari\/\S+/ user_agent_name = :safari user_agent_version = $1.to_i # Parse Chrome # e.g. Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.43 Safari/525.19 when /^Mozilla\/5\.0 \(.*?; .*?; .*?; .*?\) AppleWebKit\/\S+ \(KHTML, like Gecko\) Chrome\/(.)\S+ Safari\/\S+/ user_agent_name = :chrome user_agent_version = $1.to_i # Parse Konqueror # e.g. Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.10 (like Gecko) (Kubuntu) when /^Mozilla\/5\.0 \(compatible; Konqueror\/(.+)\..+?(;|\)) / user_agent_name = :konqueror user_agent_version = $1.to_i # Parse WordPress when /^WordPress\/(.+)\..+?$/ user_agent_name = :wordpress user_agent_version = $1.to_i # Parse mobile Safari # e.g. Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_2 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5G77 Safari/525.20 when /^Mozilla\/5\.0 \(.*?; .*?; .*?; .*?\) AppleWebKit\/\S+ \(KHTML, like Gecko\) Version\/(.)\S+ Mobile\/\S+ Safari\/\S+/ user_agent_name = :mobile_safari user_agent_version = $1.to_i # Parse generic Gecko-based user_agent # e.g. Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b3pre) Gecko/20090112 Shiretoko/3.1b3pre when /^Mozilla\/.\.. \(.*?; .*?; .*?; .*?; rv:.*?\) Gecko\/\d+/ user_agent_name = :generic_gecko user_agent_version = 1 # Parse generic WebKit-based user_agent # e.g. Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/528.9+ (KHTML, like Gecko) Stainless/0.4.5 Safari/525.20.1 when /^Mozilla\/5\.0 \(.*?; .*?; .*?; .*?\) AppleWebKit\/\S+/ user_agent_name = :generic_webkit user_agent_version = 1 # Parse bots # e.g. Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp) # e.g. Googlebot-Image/1.0 # e.g. msnbot-media/1.1 (+http://search.msn.com/msnbot.htm) when /Mozilla\/5.0 \(compatible; Yahoo! Slurp\// || user_agent_string =~ /^Googlebot-Image\// || user_agent_string =~ /^msnbot-media\// user_agent_name = :generic_spider user_agent_version = 1 else $stderr.puts "Unknown UA: #{user_agent_string}" end # Done { :user_agent_name => user_agent_name, :user_agent_version => user_agent_version } end end end
This paste will be private.
From the Design Piracy series on my blog: