Re: [web2py] Re: Mobile detector

2011-09-13 Thread Martin Weissenboeck
You are right - as always  :-) Now it works.
I have only copied the (wrong) example from this thead.

2011/9/13 Massimo Di Pierro 

> Shouldn't this be
>
> from gluon.contrib.user_agent_parser  import mobilize
> @mobilize
> ...
>
> On Sep 13, 3:22 am, Martin Weissenboeck  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
> "
> >  .>,
> > line 14, in 
> >
> > @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

2011-09-13 Thread Angelo Compagnucci
Hi Martin,

You are right, but the previous trunk version it worked.

Massimo, could you enlighten us?

Thanks!

2011/9/13 Martin Weissenboeck :
> 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 
>
>
> @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

2011-09-13 Thread Martin Weissenboeck
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 

@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

2011-08-30 Thread Angelo Compagnucci
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 :
> 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  wrote:
>> On Tue, Aug 30, 2011 at 2:05 AM, Anthony  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

2011-08-30 Thread Bruno Rocha
On Tue, Aug 30, 2011 at 2:05 AM, Anthony  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

2011-08-29 Thread Anthony
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

2011-08-29 Thread Bruno Rocha
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

2011-08-29 Thread Angelo Compagnucci
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 :
> 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 
>>
>> 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 :
>> > 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 
>> >>
>> >> I have no objection.What do others think?
>> >>
>> >> On Aug 28, 10:53 am, Angelo Compagnucci 
>> >> 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 :
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> > > This is in trunk as of last night.
>> >> >
>> >> > > On Aug 26, 12:13 pm, Ross Peoples  wrote:
>> >> > >> I submitted this to Massimo for inclusion. Now we wait :)
>> >
>> >
>
>


Re: [web2py] Re: Mobile detector

2011-08-29 Thread Martin Weissenboeck
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 

> 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 :
> > 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 
> >>
> >> I have no objection.What do others think?
> >>
> >> On Aug 28, 10:53 am, Angelo Compagnucci 
> >> 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 :
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> > > This is in trunk as of last night.
> >> >
> >> > > On Aug 26, 12:13 pm, Ross Peoples  wrote:
> >> > >> I submitted this to Massimo for inclusion. Now we wait :)
> >
> >
>


Re: [web2py] Re: Mobile detector

2011-08-29 Thread Angelo Compagnucci
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 :
> 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 
>>
>> I have no objection.What do others think?
>>
>> On Aug 28, 10:53 am, Angelo Compagnucci 
>> 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 :
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > > This is in trunk as of last night.
>> >
>> > > On Aug 26, 12:13 pm, Ross Peoples  wrote:
>> > >> I submitted this to Massimo for inclusion. Now we wait :)
>
>


Re: [web2py] Re: Mobile detector

2011-08-29 Thread Martin Weissenboeck
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 

> I have no objection.What do others think?
>
> On Aug 28, 10:53 am, Angelo Compagnucci 
> 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 :
> >
> >
> >
> >
> >
> >
> >
> > > This is in trunk as of last night.
> >
> > > On Aug 26, 12:13 pm, Ross Peoples  wrote:
> > >> I submitted this to Massimo for inclusion. Now we wait :)
>


Re: [web2py] Re: Mobile detector

2011-08-28 Thread Angelo Compagnucci
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 :
> This is in trunk as of last night.
>
> On Aug 26, 12:13 pm, Ross Peoples  wrote:
>> I submitted this to Massimo for inclusion. Now we wait :)


Re: [web2py] Re: Mobile detector

2011-08-26 Thread Ross Peoples
I submitted this to Massimo for inclusion. Now we wait :)

Re: [web2py] Re: Mobile detector

2011-08-26 Thread Angelo Compagnucci
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 :
> 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

2011-08-24 Thread Ross Peoples
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

2011-08-24 Thread Angelo Compagnucci
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 :
> 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 :
>> Forgot to attach, sorry
>>
>>
>


Re: [web2py] Re: Mobile detector

2011-08-24 Thread Angelo Compagnucci
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 :
> Forgot to attach, sorry
>
>


Re: [web2py] Re: Mobile detector

2011-08-24 Thread Ross Peoples
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):
pas

Re: [web2py] Re: Mobile detector

2011-08-24 Thread Ross Peoples
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

2011-08-23 Thread Angelo Compagnucci
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 :
> 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 :
>>
>> > 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 
# 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', ';', ')']


Re: [web2py] Re: Mobile detector

2011-08-23 Thread Anthony
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 :
> > 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

2011-08-23 Thread Angelo Compagnucci
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 :
> 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

2011-08-23 Thread Ross Peoples
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

2011-08-23 Thread Angelo Compagnucci
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 :
> 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.