Posts tagged ‘python’

 

  • Install the packages:
% pip install FormAlchemy fa.query GeoFormAlchemy
1
% pip install FormAlchemy fa.query GeoFormAlchemy
  • You have now more templates available:
% paster create --list-templates
  basic_package:   A basic setuptools-enabled package
  geo_fa:          Pylons application template with GeoFormAlchemy support
  mapfish:         MapFish application template
  mapfish_client:  MapFish client plugin template
  paste_deploy:    A web application deployed through paste.deploy
  pylons:          Pylons application template
  pylons_fa:       Pylons application template with formalchemy support
  pylons_minimal:  Pylons minimal application template
1
2
3
4
5
6
7
8
9
% paster create --list-templates
  basic_package:   A basic setuptools-enabled package
  geo_fa:          Pylons application template with GeoFormAlchemy support
  mapfish:         MapFish application template
  mapfish_client:  MapFish client plugin template
  paste_deploy:    A web application deployed through paste.deploy
  pylons:          Pylons application template
  pylons_fa:       Pylons application template with formalchemy support
  pylons_minimal:  Pylons minimal application template
  • You can run the command to add some of the GeoFormAlchemy or the formalchemy support to your project:
% paster create -t geo_fa
1
% paster create -t geo_fa

Keep the default values except for the first one

Enter admin_controller (Add formalchemy's admin controller) [False]: True 
1
Enter admin_controller (Add formalchemy's admin controller) [False]: True

And answer no unless  you want to overrite a file:

Overwrite ./MyApp/myapp/config/environment.py [y/n/d/B/?] n
[etc ...]
1
2
Overwrite ./MyApp/myapp/config/environment.py [y/n/d/B/?] n
[etc ...]
  • If you do not run the paster create command, you’ll have to add those files directly:
    • Add the file
      myapp/controllers/admin.py
    • Add the file
      myapp/forms/__init__.py
    • Add the template files in (on githhub-FormAlchemy and github-GeoFormAlchemy)
      myapp/templates/forms/ fieldset.mako,
      fieldset_readonly.mako, grid.mako, grid_readonly.mako, map.mako, map_js.mako,
      restfieldset.mako
    • Modify
      myapp/config/routing.py
  • Add the admin controller
    myapp/controllers/admin.py
### myapp/controllers/admin.py
import logging
from formalchemy.ext.pylons.controller import ModelsController
from webhelpers.paginate import Page
from myapp.lib.base import BaseController, render
from myapp import model
from myapp import forms
from myapp.model import meta

log = logging.getLogger(__name__)

class AdminControllerBase(BaseController):
    model = model # where your SQLAlchemy mappers are
    forms = forms # module containing FormAlchemy fieldsets definitions
    def Session(self): # Session factory
        return meta.Session

    ## customize the query for a model listing
    # def get_page(self):
    #     if self.model_name == 'Foo':
    #         return Page(meta.Session.query(model.Foo).order_by(model.Foo.bar)
    #     return super(AdminControllerBase, self).get_page()

AdminController = ModelsController(AdminControllerBase,
                                   prefix_name='admin',
                                   member_name='model',
                                   collection_name='models',
                                  )
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
### myapp/controllers/admin.py
import logging
from formalchemy.ext.pylons.controller import ModelsController
from webhelpers.paginate import Page
from myapp.lib.base import BaseController, render
from myapp import model
from myapp import forms
from myapp.model import meta

log = logging.getLogger(__name__)

class AdminControllerBase(BaseController):
    model = model # where your SQLAlchemy mappers are
    forms = forms # module containing FormAlchemy fieldsets definitions
    def Session(self): # Session factory
        return meta.Session

    ## customize the query for a model listing
    # def get_page(self):
    #     if self.model_name == 'Foo':
    #         return Page(meta.Session.query(model.Foo).order_by(model.Foo.bar)
    #     return super(AdminControllerBase, self).get_page()

AdminController = ModelsController(AdminControllerBase,
                                   prefix_name='admin',
                                   member_name='model',
                                   collection_name='models',
                                  )
  • Modify
    myapp/config/routing.py
### In myapp/config/routing.py
    # Map the /admin url to FA's AdminController
    # Map static files
    map.connect('fa_static', '/admin/_static/{path_info:.*}', controller='admin', action='static')
    # Index page
    map.connect('admin', '/admin', controller='admin', action='models')
    map.connect('formatted_admin', '/admin.json', controller='admin', action='models', format='json')
    # Models
    map.resource('model', 'models', path_prefix='/admin/{model_name}', controller='admin')
1
2
3
4
5
6
7
8
9
### In myapp/config/routing.py
    # Map the /admin url to FA's AdminController
    # Map static files
    map.connect('fa_static', '/admin/_static/{path_info:.*}', controller='admin', action='static')
    # Index page
    map.connect('admin', '/admin', controller='admin', action='models')
    map.connect('formatted_admin', '/admin.json', controller='admin', action='models', format='json')
    # Models
    map.resource('model', 'models', path_prefix='/admin/{model_name}', controller='admin')
  • myapp/forms/__init__.py
### myapp/forms/__init__.py
from pylons import config
from myapp.model import my_app_points
from myapp.lib.base import render
from formalchemy import config as fa_config
from formalchemy import templates
from formalchemy import validators
from formalchemy import fields
from formalchemy import forms
from formalchemy import tables
from formalchemy.ext.fsblob import FileFieldRenderer
from formalchemy.ext.fsblob import ImageFieldRenderer

from geoformalchemy.base import GeometryFieldRenderer
from geoalchemy import geometry
forms.FieldSet.default_renderers[geometry.Geometry] = GeometryFieldRenderer

fa_config.encoding = 'utf-8'
class TemplateEngine(templates.TemplateEngine):
    def render(self, name, **kwargs):
        return render('/forms/%s.mako' % name, extra_vars=kwargs)
fa_config.engine = TemplateEngine()
class FieldSet(forms.FieldSet):
    pass
class Grid(tables.Grid):
    pass
## Initialize fieldsets
#Foo = FieldSet(model.Foo)
#Reflected = FieldSet(Reflected)
## Initialize grids
#FooGrid = Grid(model.Foo)
#ReflectedGrid = Grid(Reflected)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
### myapp/forms/__init__.py
from pylons import config
from myapp.model import my_app_points
from myapp.lib.base import render
from formalchemy import config as fa_config
from formalchemy import templates
from formalchemy import validators
from formalchemy import fields
from formalchemy import forms
from formalchemy import tables
from formalchemy.ext.fsblob import FileFieldRenderer
from formalchemy.ext.fsblob import ImageFieldRenderer

from geoformalchemy.base import GeometryFieldRenderer
from geoalchemy import geometry
forms.FieldSet.default_renderers[geometry.Geometry] = GeometryFieldRenderer

fa_config.encoding = 'utf-8'
class TemplateEngine(templates.TemplateEngine):
    def render(self, name, **kwargs):
        return render('/forms/%s.mako' % name, extra_vars=kwargs)
fa_config.engine = TemplateEngine()
class FieldSet(forms.FieldSet):
    pass
class Grid(tables.Grid):
    pass
## Initialize fieldsets
#Foo = FieldSet(model.Foo)
#Reflected = FieldSet(Reflected)
## Initialize grids
#FooGrid = Grid(model.Foo)
#ReflectedGrid = Grid(Reflected)
  • To test, restart you server, and open and refresh
    /admin

    . Unless you’ve added models in your

    myapp/models/__init__.py

    , you won’t see any link to the models.

Adding a model to the Admin view

One of my models
myapp/model/my_app_points.py

was defined as such

###myapp/model/my_app_points.py
from sqlalchemy import Column, types
from geoalchemy import GeometryColumn, Point
from mapfish.sqlalchemygeom import GeometryTableMixIn
from mapfishapp.model.meta import Session, Base

class MyAppPoint(Base, GeometryTableMixIn):
    autoload_with = Session.bind
    __tablename__ = 'my_app_point'
    __table_args__ = {
        "autoload_with": Session.bind,
        "autoload": True,
    }
    way = GeometryColumn(Point(srid=900913))
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
###myapp/model/my_app_points.py 
from sqlalchemy import Column, types
from geoalchemy import GeometryColumn, Point
from mapfish.sqlalchemygeom import GeometryTableMixIn
from mapfishapp.model.meta import Session, Base

class MyAppPoint(Base, GeometryTableMixIn):
    autoload_with = Session.bind
    __tablename__ = 'my_app_point'
    __table_args__ = {
        "autoload_with": Session.bind,
        "autoload": True,
    }
    way = GeometryColumn(Point(srid=900913))

I’d get an error by importing that class in

myapp/model/__init__.py
from myapp.models.my_app_points import MyAppPoint
1
from myapp.models.my_app_points import MyAppPoint

would lead to that error:

sqlalchemy.exc.UnboundExecutionError: No engine is bound to this Table's MetaData.
Pass an engine to the Table via autoload_with=<someengine>, or associate the MetaData
with an engine via metadata.bind=<someengine>
1
2
3
sqlalchemy.exc.UnboundExecutionError: No engine is bound to this Table's MetaData.
Pass an engine to the Table via autoload_with=<someengine>, or associate the MetaData
with an engine via metadata.bind=<someengine>

Modifying myapp/model/__init__.py by adding Base.metadata.bind = engine at the end of init_model(engine) did not work.

The solution I found after checking the formalchemy code was to modify the myapp/controllers/admin.py and pass a list of the model classes to list in the web admin view.

###Modify in myapp/controllers/admin.py
from myapp.model.my_app_points import MyAppPoint

list_models = [MyAppPoint,]
class AdminControllerBase(BaseController):
    model = list_models # where your SQLAlchemy mappers are
    forms = forms # module containing FormAlchemy fieldsets definitions
1
2
3
4
5
6
7
###Modify in myapp/controllers/admin.py
from myapp.model.my_app_points import MyAppPoint

list_models = [MyAppPoint,]
class AdminControllerBase(BaseController):
    model = list_models # where your SQLAlchemy mappers are
    forms = forms # module containing FormAlchemy fieldsets definitions

And finally you can add something like that at the end of your

myapp/forms/__init__.py
MyAppPoint = FieldSet(my_app_points.MyAppPoint)
MyAppPoint.configure(options=[MyAppPoint.way.label('Geometry').required()])
MyAppPoint.way.set(options=[
        ('map_srid', 900913),
        ('base_layer', 'new OpenLayers.Layer.OSM("OSM")'),
        ('openlayers_lib', '/lib/openlayers/lib/OpenLayers.js'),
        ('zoom', 14)
    ])
1
2
3
4
5
6
7
8
MyAppPoint = FieldSet(my_app_points.MyAppPoint)
MyAppPoint.configure(options=[MyAppPoint.way.label('Geometry').required()])
MyAppPoint.way.set(options=[
        ('map_srid', 900913),
        ('base_layer', 'new OpenLayers.Layer.OSM("OSM")'),
        ('openlayers_lib', '/lib/openlayers/lib/OpenLayers.js'),
        ('zoom', 14)
    ])

 

Sources: mapfish-geoformalchemy,

I attended TEI’10 conference in Boston and presented there our work and demo of SensorComix (Pdf) , a research project at NRC I did with my colleagues Vidya Setlur, Tim Sohn, and Hiroshi Horii.

In SensorComix, we leverage and build upon a previous project called Nokia Mashups where SMS conversations are displayed with rich graphics representative of who’s having the conversation, the place where the communicants are located, and what they’re talking about.

The idea in SensorComix is twofold: add another dimension of expressiveness to SMS conversations, and add playfulness.

I personally have tons of stories about SMS mishaps and miscommunication, and from what I’ve seen in our projects and user trials, I’m surely not the only one. For example, a girl sends an SMS to her boyfriend asking him about something, he replies ‘yes’. The girl sends quickly another message telling him how rude he is. The boyfriend sends back that he’s in class and has no time to elaborate. Another example with yet another couple communicating, the boyfriend asks his girlfriend if she went to an evening work event, then quickly in another SMS, asks her if he’s going to see her in the evening. He gets a reply of ‘No too tired’ and assumes it’s the answer to the second message.

SMS messages are a strange way of communicating. They’re short, and because the input methods are limited to small physical keyboards, or tiny keypads, or onscreen keyboards, people are limited in how much they can write, and how clearly they can convey all the nuances in their message. SMS are sent from mobile phones, and have become a preferred way people communicate whenever and wherever they are. But often people are busy, they’re going places, they’re in meetings or in class, with other people, and they may not have time to write clear and unambiguous messages. SMS are asynchronous but nonetheless there is some expectation that the other person is going to reply, sometimes quickly, especially when SMS are between people in a close relationship or when the persons are suppose to meet or plan something together.

In SensorComix, the user writes the SMS and can use one of four different gestures that add different graphical elements to convey an emotion associated to that gesture. For example, rubbing the phone will make little hearts pop up. Shaking the phone will make a fire and flames appear. The four gestures we’ve included are those:

  • Rubbing, to convey affection
  • Shaking, to convey impatience or anger
  • Tapping, to poke
  • Knocking, to get attention

With SensorComix, one can write the message, and quickly add an emotion to it with a simple gesture.

It’s best seen on the video:

Details on the demo implementation

We used Nokia tablet devices N810, a SHAKE SK6 sensor and a MAC laptop to create the prototype. The demo does not send SMS or MMS, but is hacked together to let the user takes an N810, see a comic with preloaded images (that one can change), write a message, enter gestures on the sensor which will display animated graphical elements on the comic, and send the message. The other N810 will receive the message and display the message with the comic, message and animated elements, and one can then reply to the message.

The messaging application showing the comic and the input text for the message is actually an HTML web page, which is served by the MAC laptop. But the actual comic and the animation that appear when entering a gesture are done with a Flash/Flex component embedded in the Web page. The laptop runs a custom Python HTTP server which does 3 things:

  • Serve Web pages to the clients. There are 2 types of web pages, one for sending a message, one for receiving a message. The server also provides all the images displayed in the comic.
  • Connect to the SK6 sensor via Bluetooth. The server reads the data from the sensor and performs the gesture recognition.
  • Communicate via permanent sockets with the Flash/Flex component embedded in the Web pages. When the Web page for sending a message is displayed, the Flash/Flex component opens a socket with the server, registers as ‘sender’ and will receive the information to update the comic: the message being typed in the HTML input textarea, and which animated elements to display which should correspond to the gesture recognized by the server from the sensor data.

To run the demo, I create a ‘Network’ on the laptop. The server runs on port 80 on the laptop and I open the browser on the N810 to the URL http://[IP address of the laptop]. This configuration is somewhat stable but not highly robust. I could demo it without too much trouble for a couple of hours at TEI. During the development, there were few hiccups to circumvent with the Flash/Flex – Python socket communication. The advantage is of course that you don’t need the N810 to develop the code, you can just run the Flash/Flex in your laptop browser all the same.

For the gesture recognition, I wrote some custom simple code to identify the 4 gestures. Only 2 different sensors out of the several provided on the SK6 are used: the touch sensor (rubbing and tapping) and accelerometer (knocking and shaking). The recognition is robust enough that I don’t recalibrate the SK6 at all, but the knocking gesture was the one that was not recognized well. I should just rewrite the code. We did the project before this SHAKE  Drivers Google project started and haven’t had a chance to look into it.

There is tons of work going on at Nokia Design on gestures. See Gesture Design and the video here.

A priori, mes résolutions pour cette année n’incluent pas de bloguer plus. Alors voyons voir, depuis Novembre dernier… Et bien, si plusieurs petites choses:

Je suis allée début Décembre en Belgique pour donner un tutoriel sur Python For S60. J’ai passé les 3-4 jours juste avant à créer le-dit tutoriel. De toute façon il pleuvait, j’avais pas besoin de voir plus que la fenêtre de la chambre d’hotel. J’ai aussi mis le tutorial sur un site web, histoire de. Tout est ici, en Anglais par contre: http://www.girlcoder.com. J’avais un nom de domaine qui trainait – résultat d’une de ces nuits où, ne dormant pas et rêvant d’un site, je me lève et me dis qu’il faut que je prenne le nom de domaine. Donc, ca s’appelle girlcoder.com, mais c’est pas que pour les filles.

Juste après le tutoriel, j’ai pu faire une petite visite à Orléans et visiter toute ou presque la famille. J’ai aussi appris une bonne chose: Si vous voulez récupérer un billet de TGV d’un pays autre que la France, ne réservez pas le billet sur la SNCF.

Mi-décembre, mon ami A. arrivait à San Francisco pour 2 semaines. On est descendu en voiture jusqu’à San Diego pour 2 jours (où on a visité le zoo entre autres choses), puis pris l’avion le 25 Déc de SD pour Cancún, au Mexique. Retour le 1er Janvier.
Ah les vancances de fin d’année au soleil, au Mexique. C’est assez extraordinaire. J’étais d’abord surprise des types de touristes là-bas. Cancùn, c’est connu ici pour être la destination des étudiants pendant leur Spring-break. Ils vont là-bas, se dechainent et font la fête pendant une semaine. En Décembre, qui est la haute saison touristique, c’est plutôt beaucoup de familles, des couples, et des groupes d’amis. Aussi, il y a beaucoup d’hispanophones, et c’est une destination touristique importante pour les Méxicains. Beaucoup d’Américains, normal aussi.

Chichen Itza pyramide

On avait un package qui incluait une voiture de location. Arrivés là-bas, Hertz n’avait pas de voitures en réserve. On s’en est tiré en louant 2 jours une voiture à une agence de location locale, et on a ainsi pu visiter Valladolid, Chichen-Itza, et Playa-Del-Carmen et Tulum. On a visité Isla Mujeres, le centre de Cancún et plusieurs des plages de la zone des hotels. On est bien entendu sortis pas mal. Notre hotel -Le Flamenco- est pas très loin du centre ville de la zone des hotels, bien pourvue en restos, bars, clubs. On a passé le réveillon dans un resto mexicain, Le Perico. Excellentes vacances, et reposantes – on en avait besoin.

Comme je retourne bientôt au Mexique, à Orizaba, je me suis mise sérieusement à l’espagnol. Ce sera ma première résolution de l’année. Feliz año nuevo!