@@ -4,11 +4,11 @@ Aim is * fast * very easy to extend * reliable enough for practical purposes * and assist python web apps to detect clients. - + Taken from http://pypi.python.org/pypi/httpagentparser (MIT license) Modified my Ross Peoples for web2py to better support iPhone and iPad. """ import sys from storage import Storage @@ -57,10 +57,11 @@ result_key = "override me" order = 10 # 0 is highest look_for = "string to look for" skip_if_found = [] # strings if present stop processin can_register = False + is_mobile = False prefs = Storage() # dict(info_type = [name1, name2], ..) version_splitters = ["/", " "] _suggested_detectors = None def __init__(self): @@ -69,21 +70,26 @@ self.can_register = (self.__class__.__dict__.get('can_register', True)) def detect(self, agent, result): if agent and self.checkWords(agent): result[self.info_type] = Storage(name=self.name) + result[self.info_type].is_mobile = self.is_mobile + if not result.is_mobile: + result.is_mobile = result[self.info_type].is_mobile + version = self.getVersion(agent) if version: result[self.info_type].version = version + return True return False def checkWords(self, agent): for w in self.skip_if_found: if w in agent: return False - if self.look_for: + if self.look_for in agent: return True return False def getVersion(self, agent): # -> version string /None @@ -161,16 +167,16 @@ def getVersion(self, agent): if "Version/" in agent: return agent.split('Version/')[-1].split(' ')[0].strip() else: # Mobile Safari - return agent.split('Safari ')[-1].split(' ')[0].strip() + return agent.split('Safari ')[-1].split(' ')[0].strip() class Linux(OS): look_for = 'Linux' - prefs = Storage(browser=["Firefox"], + prefs = Storage(browser=["Firefox"], dist=["Ubuntu", "Android"], flavor=None) def getVersion(self, agent): pass @@ -232,29 +238,32 @@ vs = self.version_splitters return agent.split(self.look_for+vs[0])[-1].split(vs[1])[1].strip()[:-1] class Android(Dist): look_for = 'Android' + is_mobile = True def getVersion(self, agent): return agent.split('Android')[-1].split(';')[0].strip() class iPhone(Dist): look_for = 'iPhone' + is_mobile = True def getVersion(self, agent): version_end_chars = ['like', ';', ')'] part = agent.split('CPU OS')[-1].strip() for c in version_end_chars: if c in part: version = 'iOS ' + part.split(c)[0].strip() break return version.replace('_', '.') - + class iPad(Dist): look_for = 'iPad' + is_mobile = True def getVersion(self, agent): version_end_chars = ['like', ';', ')'] part = agent.split('CPU OS')[-1].strip() for c in version_end_chars: @@ -277,11 +286,11 @@ if "detector" in locals(): detector._suggested_detectors = detectors else: detectors = _suggested_detectors for detector in detectors: - print "detector name: ", detector.name + # print "detector name: ", detector.name if detector.detect(agent, result): prefs = detector.prefs _suggested_detectors = detector._suggested_detectors break return result @@ -289,10 +298,12 @@ class Result(Storage): def __missing__(self, k): return "" +""" +THIS VERSION OF DETECT CAUSES IndexErrors. def detect(agent): result = Result() _suggested_detectors = [] for info_type in detectorshub: @@ -303,35 +314,36 @@ _suggested_detectors = detectorshub.reorderByPrefs( detectors, detector.prefs.get(info_type)) detector._suggested_detectors = _suggested_detectors break return result - +""" def simple_detect(agent): """ - -> (os, browser) # tuple of strings + -> (os, browser, is_mobile) # tuple of strings """ result = detect(agent) os_list = [] if 'flavor' in result: os_list.append(result['flavor']['name']) if 'dist' in result: os_list.append(result['dist']['name']) if 'os' in result: os_list.append(result['os']['name']) os = os_list and " ".join(os_list) or "Unknown OS" - os_version = os_list and (result['flavor'] and result['flavor'].get( - 'version')) or (result['dist'] and result['dist'].get('version')) \ - or (result['os'] and result['os'].get('version')) or "" + os_version = os_list and ('flavor' in result and result['flavor'] and result['flavor'].get( + 'version')) or ('dist' in result and result['dist'] and result['dist'].get('version')) \ + or ('os' in result and result['os'] and result['os'].get('version')) or "" browser = 'browser' in result and result['browser']['name'] \ or 'Unknown Browser' browser_version = 'browser' in result \ and result['browser'].get('version') or "" if browser_version: browser = " ".join((browser, browser_version)) if os_version: os = " ".join((os, os_version)) - return os, browser + #is_mobile = ('dist' in result and result.dist.is_mobile) or ('os' in result and result.os.is_mobile) or False + return os, browser, result.is_mobile if __name__ == '__main__': import time import unittest @@ -363,11 +375,11 @@ {"os": {"name": "Linux"}, "browser": {"name": "Opera", "version": "9.80"}},), ("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20060127 Netscape/8.1", ("Windows NT 5.1", "Netscape 8.1"), {'os': {'name': 'Windows', 'version': 'NT 5.1'}, 'browser': {'name': 'Netscape', 'version': '8.1'}},), ) - + class TestHAP(unittest.TestCase): def setUp(self): self.harass_repeat = 1000 self.data = data @@ -390,5 +402,19 @@ print "Time taken for single detecttion: ", \ time_taken / (len(self.data) * self.harass_repeat) unittest.main() + +class mobilize(object): + + def __init__(self, func): + self.func = func + + def __call__(self): + from gluon import current + user_agent = current.request.user_agent() + if user_agent.is_mobile: + items = current.response.view.split('.') + items.insert(-1,'mobile') + current.response.view = '.'.join(items) + return self.func()