Re: [web2py] Re: Mobile detector
Hi Martin, You are right, but the previous trunk version it worked. Massimo, could you enlighten us? Thanks! 2011/9/13 Martin Weissenboeck mweis...@gmail.com: Hi, I have tried to test the user_agent_parser. At the top of default.py there is from gluon.contrib import user_agent_parser @mobilize def m(): ua = request.user_agent() if ua.is_mobile(): return dict(a='MOBILE') else: return dict(a='FIX') And I got: Traceback (most recent call last): File /home/web2py-trunk/public_html/gluon/restricted.py, line 194, in restricted exec ccode in environment File /home/web2py-trunk/public_html/applications/welcome/controllers/default.py, line 14, in module @mobilize NameError: name 'mobilize' is not defined Version 1.99.0 (2011-09-13 04:16:50) I have checked it, in the source code there is: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent and current.session._user_agent.is_mobile: items = current.response.view.split('.') items.insert(-1,'mobile') current.response.view = '.'.join(items) return self.func() Without @mobilize the program detects my Android phone - no errors. Maybe there is only a small error, but I cannot find it. Regards, Martin
Re: [web2py] Re: Mobile detector
You are right - as always :-) Now it works. I have only copied the (wrong) example from this thead. 2011/9/13 Massimo Di Pierro massimo.dipie...@gmail.com Shouldn't this be from gluon.contrib.user_agent_parser import mobilize @mobilize ... On Sep 13, 3:22 am, Martin Weissenboeck mweis...@gmail.com wrote: Hi, I have tried to test the user_agent_parser. At the top of default.py there is from gluon.contrib import user_agent_parser @mobilize def m(): ua = request.user_agent() if ua.is_mobile(): return dict(a='MOBILE') else: return dict(a='FIX') And I got: Traceback (most recent call last): File /home/web2py-trunk/public_html/gluon/restricted.py, line 194, in restricted exec ccode in environment File /home/web2py-trunk/public_html/applications/welcome/controllers/default.py https://web2py-trunk.fluxflex.com/admin/default/edit/welcome/controll.. ., line 14, in module @mobilize NameError: name 'mobilize' is not defined Version 1.99.0 (2011-09-13 04:16:50) I have checked it, in the source code there is: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent and current.session._user_agent.is_mobile: items = current.response.view.split('.') items.insert(-1,'mobile') current.response.view = '.'.join(items) return self.func() Without @mobilize the program detects my Android phone - no errors. Maybe there is only a small error, but I cannot find it. Regards, Martin
[web2py] Re: Mobile detector
Shouldn't this be from gluon.contrib.user_agent_parser import mobilize @mobilize ... On Sep 13, 3:22 am, Martin Weissenboeck mweis...@gmail.com wrote: Hi, I have tried to test the user_agent_parser. At the top of default.py there is from gluon.contrib import user_agent_parser @mobilize def m(): ua = request.user_agent() if ua.is_mobile(): return dict(a='MOBILE') else: return dict(a='FIX') And I got: Traceback (most recent call last): File /home/web2py-trunk/public_html/gluon/restricted.py, line 194, in restricted exec ccode in environment File /home/web2py-trunk/public_html/applications/welcome/controllers/default.py https://web2py-trunk.fluxflex.com/admin/default/edit/welcome/controll..., line 14, in module @mobilize NameError: name 'mobilize' is not defined Version 1.99.0 (2011-09-13 04:16:50) I have checked it, in the source code there is: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent and current.session._user_agent.is_mobile: items = current.response.view.split('.') items.insert(-1,'mobile') current.response.view = '.'.join(items) return self.func() Without @mobilize the program detects my Android phone - no errors. Maybe there is only a small error, but I cannot find it. Regards, Martin
[web2py] Re: Mobile detector
Sorry guys, the hurricane did a number on the east coast and I haven't been able to keep up with the conversations. Good work yet again Angelo! I like the @mobilize decorator.
Re: [web2py] Re: Mobile detector
On Tue, Aug 30, 2011 at 2:05 AM, Anthony abasta...@gmail.com wrote: Good point. Couldn't you also do something like index.mobi.html or index.html.mobi? I don't think these view names would necessarily have to be exposed as URLs -- they just need to be used server side to render the page appropriately. It is only a semantic issue, because the pattern for any API is terminating with the extension format. .json, .xml, .csv . it is more elegant IMO than x.json.mobi
[web2py] Re: Mobile detector
Unless there is a strong objection I will modify the code in trunk to use index.mobile.html view = '.'.join(view.split().insert(-1,'mobile')) On Aug 30, 2:13 am, Bruno Rocha rochacbr...@gmail.com wrote: On Tue, Aug 30, 2011 at 2:05 AM, Anthony abasta...@gmail.com wrote: Good point. Couldn't you also do something like index.mobi.html or index.html.mobi? I don't think these view names would necessarily have to be exposed as URLs -- they just need to be used server side to render the page appropriately. It is only a semantic issue, because the pattern for any API is terminating with the extension format. .json, .xml, .csv . it is more elegant IMO than x.json.mobi
Re: [web2py] Re: Mobile detector
I think that the extension should match the content, it's more clear. For a json object I'm expecting a .json, an xml should have an xml extension and so on. So for the mobile view I think the best is to have a .mobi extension, but this is IMHO. Also using the .mobile.html could be viable, because a mobile view is substantially an html file. For me it's ok to have .mobile.html extension 2011/8/30 Massimo Di Pierro massimo.dipie...@gmail.com: Unless there is a strong objection I will modify the code in trunk to use index.mobile.html view = '.'.join(view.split().insert(-1,'mobile')) On Aug 30, 2:13 am, Bruno Rocha rochacbr...@gmail.com wrote: On Tue, Aug 30, 2011 at 2:05 AM, Anthony abasta...@gmail.com wrote: Good point. Couldn't you also do something like index.mobi.html or index.html.mobi? I don't think these view names would necessarily have to be exposed as URLs -- they just need to be used server side to render the page appropriately. It is only a semantic issue, because the pattern for any API is terminating with the extension format. .json, .xml, .csv . it is more elegant IMO than x.json.mobi
[web2py] Re: Mobile detector
index.mobile.html is in trunk On Aug 30, 8:19 am, Angelo Compagnucci angelo.compagnu...@gmail.com wrote: I think that the extension should match the content, it's more clear. For a json object I'm expecting a .json, an xml should have an xml extension and so on. So for the mobile view I think the best is to have a .mobi extension, but this is IMHO. Also using the .mobile.html could be viable, because a mobile view is substantially an html file. For me it's ok to have .mobile.html extension 2011/8/30 Massimo Di Pierro massimo.dipie...@gmail.com: Unless there is a strong objection I will modify the code in trunk to use index.mobile.html view = '.'.join(view.split().insert(-1,'mobile')) On Aug 30, 2:13 am, Bruno Rocha rochacbr...@gmail.com wrote: On Tue, Aug 30, 2011 at 2:05 AM, Anthony abasta...@gmail.com wrote: Good point. Couldn't you also do something like index.mobi.html or index.html.mobi? I don't think these view names would necessarily have to be exposed as URLs -- they just need to be used server side to render the page appropriately. It is only a semantic issue, because the pattern for any API is terminating with the extension format. .json, .xml, .csv . it is more elegant IMO than x.json.mobi
Re: [web2py] Re: Mobile detector
I tried: def mobile(): from gluon.contrib import user_agent_parser ua = user_agent_parser.detect(request.env.http_user_agent) if ua.dist.is_mobile: and i got: AttributeError: 'NoneType' object has no attribute 'is_mobile' Browsers: Opera 11.50, Safari 3.1.2 (1) What is wrong? (2) There have been a lot of proposals how to change every view from .html to .m.html if is_mobile is true. Now I am a little bit confused: what would be the best code following if ua.dist.is_mobile...? Regards, Martin 2011/8/28 Massimo Di Pierro massimo.dipie...@gmail.com I have no objection.What do others think? On Aug 28, 10:53 am, Angelo Compagnucci angelo.compagnu...@gmail.com wrote: HI Ross, Massimo, I wrote a small decorator to use the newly added is_mobile flag: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent: if current.session._user_agent.is_mobile: current.response.view = \ current.response.view.split(.)[0] + .mobi return self.func() It should be included at the bottom of user_agent_parser.py. With this you can have automatically selected the view.html or the view.mobi depending on your browser is mobile or not, an example could be: @mobilize def index(): example action using the mobilizer decorator it is rendered by views/default/index.html or views/default/index.mobi depending if your browser is mobile or not return dict(message=response.view) Could this be added in trunk? 2011/8/27 Massimo Di Pierro massimo.dipie...@gmail.com: This is in trunk as of last night. On Aug 26, 12:13 pm, Ross Peoples ross.peop...@gmail.com wrote: I submitted this to Massimo for inclusion. Now we wait :)
Re: [web2py] Re: Mobile detector
Hi Martin, In trunk the correct syntax should be: from gluon.contrib import user_agent_parser ua = user_agent_parser.detect(request.env.http_user_agent) if ua.is_mobile: ... Or better: ua = request.user_agent() if ua.is_mobile: ... The mothod user_agent() search in session if the user_agent was already parsed, so in the end it parses the user agent only first time. 2011/8/29 Martin Weissenboeck mweis...@gmail.com: I tried: def mobile(): from gluon.contrib import user_agent_parser ua = user_agent_parser.detect(request.env.http_user_agent) if ua.dist.is_mobile: and i got: AttributeError: 'NoneType' object has no attribute 'is_mobile' Browsers: Opera 11.50, Safari 3.1.2 (1) What is wrong? (2) There have been a lot of proposals how to change every view from .html to .m.html if is_mobile is true. Now I am a little bit confused: what would be the best code following if ua.dist.is_mobile...? Regards, Martin 2011/8/28 Massimo Di Pierro massimo.dipie...@gmail.com I have no objection.What do others think? On Aug 28, 10:53 am, Angelo Compagnucci angelo.compagnu...@gmail.com wrote: HI Ross, Massimo, I wrote a small decorator to use the newly added is_mobile flag: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent: if current.session._user_agent.is_mobile: current.response.view = \ current.response.view.split(.)[0] + .mobi return self.func() It should be included at the bottom of user_agent_parser.py. With this you can have automatically selected the view.html or the view.mobi depending on your browser is mobile or not, an example could be: @mobilize def index(): example action using the mobilizer decorator it is rendered by views/default/index.html or views/default/index.mobi depending if your browser is mobile or not return dict(message=response.view) Could this be added in trunk? 2011/8/27 Massimo Di Pierro massimo.dipie...@gmail.com: This is in trunk as of last night. On Aug 26, 12:13 pm, Ross Peoples ross.peop...@gmail.com wrote: I submitted this to Massimo for inclusion. Now we wait :)
Re: [web2py] Re: Mobile detector
Hi Angelo, it works now, thanks! Any ideas about the second question? There have been a lot of proposals how to change every view from .html to .m.html if is_mobile is true. Now I am a little bit confused: what would be the best code following if ua.is_mobile...? 2011/8/29 Angelo Compagnucci angelo.compagnu...@gmail.com Hi Martin, In trunk the correct syntax should be: from gluon.contrib import user_agent_parser ua = user_agent_parser.detect(request.env.http_user_agent) if ua.is_mobile: ... Or better: ua = request.user_agent() if ua.is_mobile: ... The mothod user_agent() search in session if the user_agent was already parsed, so in the end it parses the user agent only first time. 2011/8/29 Martin Weissenboeck mweis...@gmail.com: I tried: def mobile(): from gluon.contrib import user_agent_parser ua = user_agent_parser.detect(request.env.http_user_agent) if ua.dist.is_mobile: and i got: AttributeError: 'NoneType' object has no attribute 'is_mobile' Browsers: Opera 11.50, Safari 3.1.2 (1) What is wrong? (2) There have been a lot of proposals how to change every view from .html to .m.html if is_mobile is true. Now I am a little bit confused: what would be the best code following if ua.dist.is_mobile...? Regards, Martin 2011/8/28 Massimo Di Pierro massimo.dipie...@gmail.com I have no objection.What do others think? On Aug 28, 10:53 am, Angelo Compagnucci angelo.compagnu...@gmail.com wrote: HI Ross, Massimo, I wrote a small decorator to use the newly added is_mobile flag: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent: if current.session._user_agent.is_mobile: current.response.view = \ current.response.view.split(.)[0] + .mobi return self.func() It should be included at the bottom of user_agent_parser.py. With this you can have automatically selected the view.html or the view.mobi depending on your browser is mobile or not, an example could be: @mobilize def index(): example action using the mobilizer decorator it is rendered by views/default/index.html or views/default/index.mobi depending if your browser is mobile or not return dict(message=response.view) Could this be added in trunk? 2011/8/27 Massimo Di Pierro massimo.dipie...@gmail.com: This is in trunk as of last night. On Aug 26, 12:13 pm, Ross Peoples ross.peop...@gmail.com wrote: I submitted this to Massimo for inclusion. Now we wait :)
Re: [web2py] Re: Mobile detector
Hi Maritn, In trunk you can now do: #only at the top of you controller from gluon.contrib import user_agent_parser @mobilize def index(): example action using the mobilizer decorator it is rendered by views/default/index.html or views/default/index.mobi depending if your browser is mobile or not return dict(message=response.view) With this decorator, the index page is rendered by index.html if you are on a desktop browser and index.mobi if you are on a mobile browser. So to implement a sort of responsive design simply using the @mobilize decorator and writing your mobile custom views. The decorator is totally optional, so you can implement only the mobile version of pages you care. Angelo 2011/8/29 Martin Weissenboeck mweis...@gmail.com: Hi Angelo, it works now, thanks! Any ideas about the second question? There have been a lot of proposals how to change every view from .html to .m.html if is_mobile is true. Now I am a little bit confused: what would be the best code following if ua.is_mobile...? 2011/8/29 Angelo Compagnucci angelo.compagnu...@gmail.com Hi Martin, In trunk the correct syntax should be: from gluon.contrib import user_agent_parser ua = user_agent_parser.detect(request.env.http_user_agent) if ua.is_mobile: ... Or better: ua = request.user_agent() if ua.is_mobile: ... The mothod user_agent() search in session if the user_agent was already parsed, so in the end it parses the user agent only first time. 2011/8/29 Martin Weissenboeck mweis...@gmail.com: I tried: def mobile(): from gluon.contrib import user_agent_parser ua = user_agent_parser.detect(request.env.http_user_agent) if ua.dist.is_mobile: and i got: AttributeError: 'NoneType' object has no attribute 'is_mobile' Browsers: Opera 11.50, Safari 3.1.2 (1) What is wrong? (2) There have been a lot of proposals how to change every view from .html to .m.html if is_mobile is true. Now I am a little bit confused: what would be the best code following if ua.dist.is_mobile...? Regards, Martin 2011/8/28 Massimo Di Pierro massimo.dipie...@gmail.com I have no objection.What do others think? On Aug 28, 10:53 am, Angelo Compagnucci angelo.compagnu...@gmail.com wrote: HI Ross, Massimo, I wrote a small decorator to use the newly added is_mobile flag: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent: if current.session._user_agent.is_mobile: current.response.view = \ current.response.view.split(.)[0] + .mobi return self.func() It should be included at the bottom of user_agent_parser.py. With this you can have automatically selected the view.html or the view.mobi depending on your browser is mobile or not, an example could be: @mobilize def index(): example action using the mobilizer decorator it is rendered by views/default/index.html or views/default/index.mobi depending if your browser is mobile or not return dict(message=response.view) Could this be added in trunk? 2011/8/27 Massimo Di Pierro massimo.dipie...@gmail.com: This is in trunk as of last night. On Aug 26, 12:13 pm, Ross Peoples ross.peop...@gmail.com wrote: I submitted this to Massimo for inclusion. Now we wait :)
Re: [web2py] Re: Mobile detector
I commented in Anthony notes, but I will replicate it here. --- I created my own mechanism for mobile detection, which I am using for a long time. So there is one thing I decided. It is better to prefix instead of suffix. so I named my views as mobile.index.html instead of index.mobi. why? just because I can have .html, .load, .json, .xml for specific mobile scope too. and it is better to have mobile.index.html for mobile while index.html to browsers, same for mobile.index.json for index.json, and .load etc. --- http://code.google.com/p/web2py/source/detail?r=93578e588a1b22fd0c971932aed9823fb10df476
Re: [web2py] Re: Mobile detector
Good point. Couldn't you also do something like index.mobi.html or index.html.mobi? I don't think these view names would necessarily have to be exposed as URLs -- they just need to be used server side to render the page appropriately. Anthony On Tuesday, August 30, 2011 12:01:53 AM UTC-4, rochacbruno wrote: I commented in Anthony notes, but I will replicate it here. --- I created my own mechanism for mobile detection, which I am using for a long time. So there is one thing I decided. It is better to prefix instead of suffix. so I named my views as mobile.index.html instead of index.mobi. why? just because I can have .html, .load, .json, .xml for specific mobile scope too. and it is better to have mobile.index.html for mobile while index.html to browsers, same for mobile.index.json for index.json, and .load etc. --- http://code.google.com/p/web2py/source/detail?r=93578e588a1b22fd0c971932aed9823fb10df476
Re: [web2py] Re: Mobile detector
HI Ross, Massimo, I wrote a small decorator to use the newly added is_mobile flag: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent: if current.session._user_agent.is_mobile: current.response.view = \ current.response.view.split(.)[0] + .mobi return self.func() It should be included at the bottom of user_agent_parser.py. With this you can have automatically selected the view.html or the view.mobi depending on your browser is mobile or not, an example could be: @mobilize def index(): example action using the mobilizer decorator it is rendered by views/default/index.html or views/default/index.mobi depending if your browser is mobile or not return dict(message=response.view) Could this be added in trunk? 2011/8/27 Massimo Di Pierro massimo.dipie...@gmail.com: This is in trunk as of last night. On Aug 26, 12:13 pm, Ross Peoples ross.peop...@gmail.com wrote: I submitted this to Massimo for inclusion. Now we wait :)
[web2py] Re: Mobile detector
I have no objection.What do others think? On Aug 28, 10:53 am, Angelo Compagnucci angelo.compagnu...@gmail.com wrote: HI Ross, Massimo, I wrote a small decorator to use the newly added is_mobile flag: class mobilize(object): def __init__(self, func): self.func = func def __call__(self): from gluon import current if current.session._user_agent: if current.session._user_agent.is_mobile: current.response.view = \ current.response.view.split(.)[0] + .mobi return self.func() It should be included at the bottom of user_agent_parser.py. With this you can have automatically selected the view.html or the view.mobi depending on your browser is mobile or not, an example could be: @mobilize def index(): example action using the mobilizer decorator it is rendered by views/default/index.html or views/default/index.mobi depending if your browser is mobile or not return dict(message=response.view) Could this be added in trunk? 2011/8/27 Massimo Di Pierro massimo.dipie...@gmail.com: This is in trunk as of last night. On Aug 26, 12:13 pm, Ross Peoples ross.peop...@gmail.com wrote: I submitted this to Massimo for inclusion. Now we wait :)
Re: [web2py] Re: Mobile detector
Hi Ross, I have explained myself too convoluted! You are right on is_mobile and polymorphism, I read too approximatively the code. You are right also on attch always the is_mobile True/False to the result object, is more simple to test for true false than that if exists or not. I hope it will be included as soon as possible! Thank you! 2011/8/24 Ross Peoples ross.peop...@gmail.com: Well, the reason is_mobile is in the base object is for polymorphism to work. If we later did do a WindowsMobile(Dist): class, we can easily set is_mobile = True in it, since Dist is a subclass of the DetectorBase. I just left is_mobile attached to the response even if it's not mobile because it makes it easier to test. Someone may test by trying if ua.is_mobile == False. So if is_mobile doesn't exist, it equals None and the test will fail. The routine runs pretty quickly. The thing that takes the longest is string searching.
Re: [web2py] Re: Mobile detector
I submitted this to Massimo for inclusion. Now we wait :)
Re: [web2py] Re: Mobile detector
Nice work on that Angelo, I did have to change a few things, since 'dist' will not always exist (like when a non-Linux desktop machine visits). So this is what I did: When any 'dist' or 'os' returns is_mobile=True, then the result will have is_mobile at the root. So you can test for mobile like this: ua = request.user_agent() if ua.is_mobile: ... else: ... This should simplify things a bit. I also modified the simple_detect() method (in case anyone uses it) to return a third item in the tuple which is either True or False for is_mobile. I have attached the new user_agent_parser.py file so that you can test and confirm it works for you. If so, let me know and I will submit this for inclusion into the trunk. Nice job!
Re: [web2py] Re: Mobile detector
Forgot to attach, sorry Extract client information from http user agent The module does not try to detect all capabilities of browser in current form (it can easily be extended though). 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 class DetectorsHub(dict): _known_types = ['os', 'dist', 'flavor', 'browser'] def __init__(self, *args, **kw): dict.__init__(self, *args, **kw) for typ in self._known_types: self.setdefault(typ, []) self.registerDetectors() def register(self, detector): if detector.info_type not in self._known_types: self[detector.info_type] = [detector] self._known_types.insert(detector.order, detector.info_type) else: self[detector.info_type].append(detector) def reorderByPrefs(self, detectors, prefs): if prefs is None: return [] elif prefs == []: return detectors else: prefs.insert(0, '') def key_name(d): return d.name in prefs and prefs.index(d.name) or sys.maxint return sorted(detectors, key=key_name) def __iter__(self): return iter(self._known_types) def registerDetectors(self): detectors = [v() for v in globals().values() \ if DetectorBase in getattr(v, '__mro__', [])] for d in detectors: if d.can_register: self.register(d) class DetectorBase(object): name = # to perform match in DetectorsHub object info_type = override me 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): if not self.name: self.name = self.__class__.__name__ 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 in agent: return True return False def getVersion(self, agent): # - version string /None vs = self.version_splitters return agent.split(self.look_for + vs[0])[-1].split(vs[1])[0].strip() class OS(DetectorBase): info_type = os can_register = False version_splitters = [;, ] class Dist(DetectorBase): info_type = dist can_register = False class Flavor(DetectorBase): info_type = flavor can_register = False class Browser(DetectorBase): info_type = browser can_register = False class Macintosh(OS): look_for = 'Macintosh' prefs = Storage(dist=None) def getVersion(self, agent): pass class Firefox(Browser): look_for = Firefox class Konqueror(Browser): look_for = Konqueror version_splitters = [/, ;] class Opera(Browser): look_for = Opera def getVersion(self, agent): return agent.split(self.look_for)[1][1:].split(' ')[0] class Netscape(Browser): look_for = Netscape class MSIE(Browser): look_for = MSIE skip_if_found = [Opera] name = Microsoft Internet Explorer version_splitters = [ , ;] class Galeon(Browser): look_for = Galeon class Safari(Browser): look_for = Safari def checkWords(self, agent): unless_list = [Chrome, OmniWeb] if self.look_for in agent: for word in unless_list: if word in agent: return False return True 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() class Linux(OS): look_for = 'Linux' prefs = Storage(browser=[Firefox], dist=[Ubuntu, Android], flavor=None) def getVersion(self, agent): pass class Macintosh(OS): look_for = 'Macintosh' prefs =
Re: [web2py] Re: Mobile detector
Hi Ross, I thought deeply on the implication on using the dist object. There are many points in favour: 1) Only dist object could be mobile ones from the code, Android - Iphone - Ipad are all dist objects. 2) If you want to detect Windows Mobile in a near future, you'll create a new dist object right? Then you can add the is_mobile flag there. 3) I think that is_mobile flag should be in dist object, because a Linux could have a dist like ubuntu whithout is_mobile or a dist like android whit is_mobile = True. I agree whit you that the is_mobile flag should be on root of the result object and not on a leaf object as dist, we could copy the flag if found at the end of detect phase. Furthermore I think that is a waste copying everey time the is_mobile flag to the root of result also when the useragent is not mobile. I think that the detect method should be like this: def detect(self, agent, result): if agent and self.checkWords(agent): result[self.info_type] = Storage(name=self.name) is_mobile = getattr(self, 'is_mobile', False) if version: result[self.info_type].version = version if is_mobile: result.is_mobile = \ result[self.info_type].is_mobile = is_mobile return True return False The getattr is really a speedy python operation and the if is_mobile is evaluated to True only one time, the one it founds a dist whit is_mobile = True. What do you think? 2011/8/24 Ross Peoples ross.peop...@gmail.com: Forgot to attach, sorry
Re: [web2py] Re: Mobile detector
This works like a charm! def detect(self, agent, result): if agent and self.checkWords(agent): result[self.info_type] = Storage(name=self.name) version = self.getVersion(agent) if version: result[self.info_type].version = version if self.is_mobile: result.is_mobile = \ result[self.info_type].is_mobile = self.is_mobile return True return False 2011/8/24 Angelo Compagnucci angelo.compagnu...@gmail.com: Hi Ross, I thought deeply on the implication on using the dist object. There are many points in favour: 1) Only dist object could be mobile ones from the code, Android - Iphone - Ipad are all dist objects. 2) If you want to detect Windows Mobile in a near future, you'll create a new dist object right? Then you can add the is_mobile flag there. 3) I think that is_mobile flag should be in dist object, because a Linux could have a dist like ubuntu whithout is_mobile or a dist like android whit is_mobile = True. I agree whit you that the is_mobile flag should be on root of the result object and not on a leaf object as dist, we could copy the flag if found at the end of detect phase. Furthermore I think that is a waste copying everey time the is_mobile flag to the root of result also when the useragent is not mobile. I think that the detect method should be like this: def detect(self, agent, result): if agent and self.checkWords(agent): result[self.info_type] = Storage(name=self.name) is_mobile = getattr(self, 'is_mobile', False) if version: result[self.info_type].version = version if is_mobile: result.is_mobile = \ result[self.info_type].is_mobile = is_mobile return True return False The getattr is really a speedy python operation and the if is_mobile is evaluated to True only one time, the one it founds a dist whit is_mobile = True. What do you think? 2011/8/24 Ross Peoples ross.peop...@gmail.com: Forgot to attach, sorry
Re: [web2py] Re: Mobile detector
Well, the reason is_mobile is in the base object is for polymorphism to work. If we later did do a WindowsMobile(Dist): class, we can easily set is_mobile = True in it, since Dist is a subclass of the DetectorBase. I just left is_mobile attached to the response even if it's not mobile because it makes it easier to test. Someone may test by trying if ua.is_mobile == False. So if is_mobile doesn't exist, it equals None and the test will fail. The routine runs pretty quickly. The thing that takes the longest is string searching.
Re: [web2py] Re: Mobile detector
Hi Ross, I'm looking into your user_agent_parser.py but I cannot find something like the mobile detector. I'll explain better. With user_agent_parser.py you can look for browser version and os version, but there isn't an easy way to dectect if a browser is mobile or not, or I'm missing something? I think that a decorator for mobile versions or a global variable that tells me a mobile browser wants mobile view is really necessary. I think it could be a really great and appreciated addition to the framework! If you have somthing in mind, please share with us, I can contribute to code and help testing. Thank you! 2011/8/18 Ross Peoples ross.peop...@gmail.com: We already have a user_agent_parser.py in contrib. Isn't that the same thing? Usage: import contrib.user_agent_parser user_agent_parser.simple_detect(request.env.http_user_agent) By the way, didn't you add something to the Google Issues page for the proposal saying you were getting an error from that? If so can you give me the user agent string that caused it? I asked for it on the issue, but I figured you didn't have notifications turned on and never got the message.
Re: [web2py] Re: Mobile detector
We could always modify the simple_detect() method to include a third item in the returned tuple that is a string (i.e. 'desktop', ,'mobile', etc) based on the outcome of the detect. That shouldn't be too difficult to do if you want to give it a try.
Re: [web2py] Re: Mobile detector
Hi Ross, Thank you for the info, it's really a good suggestion. I'll try to add a variable like is_mobile, becase all informations about browser and versions are already present in your code. I think however that the Bruno's approach is really awesome. It's really simple using the decorator, and really conveniente to have a globale switch for .mobile views. I think the Bruno's code should be included because it doesn't conflict with user_agent_parser.py and it really complements it from a mobile perspective. Thank you! 2011/8/23 Ross Peoples ross.peop...@gmail.com: We could always modify the simple_detect() method to include a third item in the returned tuple that is a string (i.e. 'desktop', ,'mobile', etc) based on the outcome of the detect. That shouldn't be too difficult to do if you want to give it a try.
Re: [web2py] Re: Mobile detector
Also, note that you can access user_agent_parser.py by calling request.user_agent(). The nice thing about the latter is that it will store the result in the session (as session._user_agent), so it only needs to parse the user agent once per session. Anthony On Tuesday, August 23, 2011 1:30:36 PM UTC-4, AngeloC wrote: Hi Ross, I'm looking into your user_agent_parser.py but I cannot find something like the mobile detector. I'll explain better. With user_agent_parser.py you can look for browser version and os version, but there isn't an easy way to dectect if a browser is mobile or not, or I'm missing something? I think that a decorator for mobile versions or a global variable that tells me a mobile browser wants mobile view is really necessary. I think it could be a really great and appreciated addition to the framework! If you have somthing in mind, please share with us, I can contribute to code and help testing. Thank you! 2011/8/18 Ross Peoples ross.p...@gmail.com: We already have a user_agent_parser.py in contrib. Isn't that the same thing? Usage: import contrib.user_agent_parser user_agent_parser.simple_detect(request.env.http_user_agent) By the way, didn't you add something to the Google Issues page for the proposal saying you were getting an error from that? If so can you give me the user agent string that caused it? I asked for it on the issue, but I figured you didn't have notifications turned on and never got the message.
Re: [web2py] Re: Mobile detector
Hi Ross, I produced a patch that adds the is_mobile boolean flag to a dist if the useragent belongs to a mobile device. Ptch is made on the last dev revision pulled from mercurial. It's actually a simple patch that modifies no more than ten lines of code, hope this helps! Now you could make: from gluon.contrib import user_agent_parser ua = user_agent_parser.detect(request.env.http_user_agent) if ua.dist.is_mobile: ... else: ... 2011/8/23 Anthony abasta...@gmail.com: Also, note that you can access user_agent_parser.py by calling request.user_agent(). The nice thing about the latter is that it will store the result in the session (as session._user_agent), so it only needs to parse the user agent once per session. Anthony On Tuesday, August 23, 2011 1:30:36 PM UTC-4, AngeloC wrote: Hi Ross, I'm looking into your user_agent_parser.py but I cannot find something like the mobile detector. I'll explain better. With user_agent_parser.py you can look for browser version and os version, but there isn't an easy way to dectect if a browser is mobile or not, or I'm missing something? I think that a decorator for mobile versions or a global variable that tells me a mobile browser wants mobile view is really necessary. I think it could be a really great and appreciated addition to the framework! If you have somthing in mind, please share with us, I can contribute to code and help testing. Thank you! 2011/8/18 Ross Peoples ross.p...@gmail.com: We already have a user_agent_parser.py in contrib. Isn't that the same thing? Usage: import contrib.user_agent_parser user_agent_parser.simple_detect(request.env.http_user_agent) By the way, didn't you add something to the Google Issues page for the proposal saying you were getting an error from that? If so can you give me the user agent string that caused it? I asked for it on the issue, but I figured you didn't have notifications turned on and never got the message. # HG changeset patch # User Angelo Compagnucci angelo.compagnu...@gmail.com # Date 1314136920 -7200 # Node ID eb6774c91adac9a064e8d361f2cc3f1ea0dfe955 # Parent 2c1f4c7f4f8e7e286d561688a16b08d139d5ea62 Added is_mobile flag in each dist that is actually a mobile device. If a device is a mobile one, the resulting Storage has the attribute is_mobile in dist set to True. diff -r 2c1f4c7f4f8e -r eb6774c91ada gluon/contrib/user_agent_parser.py --- a/gluon/contrib/user_agent_parser.py Mon Aug 22 22:58:57 2011 -0500 +++ b/gluon/contrib/user_agent_parser.py Wed Aug 24 00:02:00 2011 +0200 @@ -72,8 +72,11 @@ if agent and self.checkWords(agent): result[self.info_type] = Storage(name=self.name) version = self.getVersion(agent) +is_mobile = getattr(self, 'is_mobile', False) if version: result[self.info_type].version = version +if is_mobile: +result[self.info_type].is_mobile = is_mobile return True return False @@ -81,7 +84,7 @@ 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 @@ -234,6 +237,7 @@ class Android(Dist): look_for = 'Android' +is_mobile = True def getVersion(self, agent): return agent.split('Android')[-1].split(';')[0].strip() @@ -241,6 +245,7 @@ class iPhone(Dist): look_for = 'iPhone' +is_mobile = True def getVersion(self, agent): version_end_chars = ['like', ';', ')'] @@ -253,6 +258,7 @@ class iPad(Dist): look_for = 'iPad' +is_mobile = True def getVersion(self, agent): version_end_chars = ['like', ';', ')']
[web2py] Re: Mobile detector
We already have a user_agent_parser.py in contrib. Isn't that the same thing? Usage: import contrib.user_agent_parser user_agent_parser.simple_detect(request.env.http_user_agent) By the way, didn't you add something to the Google Issues page for the proposal saying you were getting an error from that? If so can you give me the user agent string that caused it? I asked for it on the issue, but I figured you didn't have notifications turned on and never got the message.