Derniers billets de blog
Grok 1.0 released !
[Ce post est une traduction partielle et adaptée de l'annonce officielle de la publication de Grok 1.0]
Introduction
Puisque Grok est extensible, de nombreuses et puissantes fonctionnalités ont été développées par la communauté et sont disponibles en tant qu'extensions. L'équipe de développement de Grok travaille déjà sur toute une série de nouvelles fonctionnalités et améliorations pour les futures versions de Grok. Citons par exemple le support de Python 2.6, l'intégration du ZTK (Zope Toolkit) ou encore l'intégration de z3c.hashedresource et hurry.resource pour une meilleure gestion des ressources statiques, sans oublier biensûr l'amélioration de la documentation !
À propos de Grok
Un framework construit sur Python
Grok est un framework moderne construit sur Python. Les développeurs expert trouveront dans Grok un outil très puissant qui excelle dans les domaines de la réutilisablité et de l'extensibilité grâce à l'utilisation du modèle de développement par composant. En parallèle, Grok a également pour objectif de permettre aux développeurs moins expérimentés d'être immédiatement productif en leur offrant une courbe d'apprentissage assez douce.
Compatible avec la ZODB et les bases de données relationnelles
Grok permet de stocker tous les objets Python d'une application au sein de la célèbre base de données object ZODB. Les adeptes des bases de données SQL trouveront également leur bonheur puisque Grok supporte également les bases de données relationnelles grâce à l'extension megrok.rdb et l'excellent ORM (Object Relational Mapper) SQLAlchemy.
Grok est construit sur les technologies Zope
Grok est développé au sein de la communauté Zope et est construit sur les technologies Zope. Grok s'appuit en particulier sur le Zope Toolkit qui offre une collection de librairies réutilisables basées sur le modèle de développement par composant, le "Zope Component Architecture". La communauté Zope a plus de dix ans d'expérience dans le développement d'applications web en Python, et le Zope Toolkit en est le remarquable résultat.
Grok est compatible WSGI
Grok est compatible WSGI et peut par conséquent être intégré avec toutes les autres applications Python WSGI-compatibles.
La réutilisabilité des technologies Grok font qu'elles s'exportent pour être réutilisées dans d'autres applications. Le CMS Plone (contruit sur le serveur d'applications Zope 2) et Silva ont fait ce pari.
chameleon.zpt versus standard Zope page templates
The default expression type is Python
With zope.pagetemplate
<div tal:content="python:2+2" />
With chameleon.zpt
<div tal:content="2+2" />
Tuple unpacking is allowed when defining variables
With zope.pagetemplate
<tal:vars define="a python:1; b python:2; c python:3"> ... </tal:vars>
With chameleon.zpt
<tal:vars define="(a, b, c) [1, 2, 3]"> ... </tal:vars>
Generators are allowed in tal:repeat statements
With chameleon.zpt
<div tal:repeat="i <some generator>"> ... </some>
Attribute-access to dictionary entries is allowed in Python-expressions
With zope.pagetemplate
<span tal:define="mydict python:{'e1': 'one', 'e2': 'two'}" tal:context="python:mydict['e1']"> using dictionary['key'] </span>
With chameleon.zpt
<span tal:define="mydict {'e1': 'one', 'e2': 'two'}" tal:content="mydict.e1"> using dictionary.key </span>
Genshi expression interpolation syntax is supported outside tags and inside static attributes
With zope.pagetemplate
<span tal:define="world string:'css'" class="" tal:attributes="class string:hello-$world" tal:content="string:Hello, $world!"> Hello, css! </span>
With chameleon.zpt
<span tal:define="world 'css'" class="hello-${'world'}"> Hello, ${'world'}! </span>
Using Chameleon in debug mode
$ export CHAMELEON_CACHE=False
Installez Google Chrome sur Ubuntu, ça rocks !
Ajouter les dépôts Launchpad de Chromium, ici pour Jaunty
$ sudo vi /etc/apt/sources.list + deb http://ppa.launchpad.net/chromium-daily/ppa/ubuntu jaunty main + deb-src http://ppa.launchpad.net/chromium-daily/ppa/ubuntu jaunty main
Installer la clée GPG
$ sudo apt-get update ... W: GPG error: http://ppa.launchpad.net jaunty Release: Les signatures suivantes n'ont pas pu être vérifiées car la clé publique n'est pas disponible : NO_PUBKEY 5A9BF3BB4E5E17B5
$ gpg --keyserver subkeys.pgp.net --recv 5A9BF3BB4E5E17B5 $ gpg --export --armor 5A9BF3BB4E5E17B5 | sudo apt-key add -
Installer Google Chrome
$ sudo apt-get update $ sudo apt-get install chromium-browser
$ sudo apt-get install chromium-codecs-ffmpeg-nonfree $ sudo apt-get install chromium-browser-inspector
Liens
Python Agility: be careful ;)
silvio@serv:~$ python Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> tmp = True >>> True = False >>> False = tmp >>> True False >>> False True >>> >>> file <type 'file'> >>> file = 'Hi!' >>> file 'Hi!' >>>
Create an archetype content type with Paster and ZopeSkel
1. Install ZopeSkel
$ easy_install -U ZopeSkel
2. Create the archetype Plone egg
$ paster create --list-template Available templates: [...] archetype: A Plone project that uses Archetypes [...] $ paster create -t archetype [...] Enter project name: myproject.contenttypes [...]
3. Create the content-type
$ cd myproject.contenttypes $ paster addcontent --list Available templates: [...] contenttype: A content type skeleton [...] $ paster addcontent contenttype [...] Enter contenttype_name (Content type name ) ['Example Type']: MyContentType [...]
4. Add an archetype field to the new content-type
$ paster addcontent --list Available templates: [...] atschema: A handy AT schema builder [...] $ paster addcontent atschema [...] Enter content_class_filename (What is the module (file)name of your content class?) ['exampletype']: mycontenttype Enter field_name (What would you like to name this field?) ['newfield']: myfield Enter field_type (What kind of field should I make for you? Some examples: [computed,cmfobject,reference,text,image,float,lines,datetime,boolean, file,integer,fixedpoint,string]) ['string']: Enter widget_type (What kind of widget do you want to use (example: Password)?) ['default']: [...]
5. Links
6. Thanks
Thank you to Jean-Michel François aka toutpt who introduced me to this very handy tool, and of course to the authors of PasteScript and ZopeSkel!
1) after cd to my product, I had to run paster with "..\paster"
2) I could install the product by doing this from the product folder: "..\..\python.exe setup.py install"
3) The message about Cheetah can apparently be ignored.
Thanks for a great write-up.
Using timezones in your Python scripts
pytz - World Timezone Definitions for Python
1. Create an utility which provides a getCurrentTimes fonction (file utils.py)
# Python imports from datetime import datetime import pytz # Zope imports from zope.interface import Interface, implements from zope.component import provideUtility class ITimezoneUtils(Interface): """ Utilities for timezone calculations """ def getCurrentTimes(timezones, fmt=None): """ Return current time for a list of timezones. >>> getCurrentTimes(['Europe/London', 'Asia/Tokyo']) {'Europe/London': datetime.datetime(2009, 7, 9, 20, 29, 26, 603590, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>), 'Asia/Tokyo': datetime.datetime(2009, 7, 10, 4, 29, 26, 603590, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)} >>> getCurrentTimes(['Europe/London', 'Asia/Tokyo'], fmt='%Y-%m-%d %H:%M') {'Europe/London': '2009-07-09 20:31', 'Asia/Tokyo': '2009-07-10 04:31'} """ class TimezoneUtils(object): implements(ITimezoneUtils) def getCurrentTimes(self, timezones, fmt=None): # Get UTC current time now_utc = datetime.now(pytz.timezone('UTC')) # Compute current time for each timezone result = {} for tz in timezones: now_tz = now_utc.astimezone(pytz.timezone(tz)) if fmt is not None: now_tz = now_tz.strftime(fmt) result[tz] = now_tz return result provideUtility(TimezoneUtils(), ITimezoneUtils)
2. Use this utility to compute date and time for multiple timezones
>>> # Zope imports >>> from zope.component import getUtility >>> from utils import ITimezoneUtils >>> tz_utils = getUtility(ITimezoneUtils) >>> timezones = ['Europe/London', 'Asia/Tokyo', 'America/New_York'] >>> tz_utils.getCurrentTimes(timezones) {'America/New_York': datetime.datetime(2009, 7, 9, 15, 32, 18, 910813, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>), 'Europe/London': datetime.datetime(2009, 7, 9, 20, 32, 18, 910813, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>), 'Asia/Tokyo': datetime.datetime(2009, 7, 10, 4, 32, 18, 910813, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>)} >>> tz_utils.getCurrentTimes(timezones, fmt='%Y-%m-%d %H:%M') {'America/New_York': '2009-07-09 15:32', 'Europe/London': '2009-07-09 20:32', 'Asia/Tokyo': '2009-07-10 04:32'}
Notes
Chameleon templates and macros/slots for Grok Views
<html metal:define-macro="mypage">
<head></head>
<body>
The content:
<div metal:define-slot="mycontent">
Put your content here...
</div>
</body>
</html>
Use the "mypage" in a new template: mypage.cpt:
<html metal:use-macro="path:context/@@mymacros/template/macros/mypage">
<!-- slot 'mycontent' was defined in the macro above -->
<div metal:fill-slot="mycontent">
...
</div>
</html>