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 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

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 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

2011-09-13 Thread Massimo Di Pierro
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

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

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

2011-08-30 Thread 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 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

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 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

2011-08-30 Thread Massimo Di Pierro
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

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 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

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 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

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 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

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 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

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 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-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 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

2011-08-28 Thread Massimo Di Pierro
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

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 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

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

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-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):
pass


class Macintosh(OS):
look_for = 'Macintosh'
prefs = 

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 ross.peop...@gmail.com:
 Forgot to attach, sorry




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 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

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-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 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

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,

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

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 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

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 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

2011-08-18 Thread 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.