Before starting
Get ready for this 8 minutes tutorial that will take you from the download to a running web application. This sample case will be an application of video catalog, with web interface and a simplesqlite database.
Framework installation and GenroHome
When you install GenroPy-framework, a new directory tree is been created at your /usr/local/ path. The path /usr/local/genro is called GenroHome, we suggest to set /usr/local/genro/bin in your profile PATH to use easily the following bin commands.
Here's how GenroHome is structured:
- bin
- data: will contain application instances and sites
- lib: contains jasvascript libraries
- packages: contains some ready packages. You can put yours here.
External requirements
Now you need something else to make GenroApplication work.
- Apache2
- mod_python
- sqlite
- pysqlite
- Dojo
Rename the Dojo directory as dojo and move it at path /usr/local/genro/lib.
Creating a sample package
Since we said that an application is a collection of one or more packages, we have to start from the package itself. As first step let's make a sample package for a video-catalog management, called video. In order to do this, we use the command gnrmkpackage that creates an empty package into the current directory.
With the following instruction we are going to create the video package into the /usr/local/genro/packages directory.
gnrmkpackage video
Describing the database model
The directories lib, model, webpages are empty, and here is the main.py code:
#!/usr/bin/env python
# encoding: utf-8
class Package(object):
def config_attributes(self):
return dict(comment='video package',
name_short='video',
name_long='video',
name_full='video')
def config_db(self, pkg):
testtbl = pkg.table('test')
testtbl.stringColumn('id', len_max='22').isPkey()
Now we have to implement the methods config_attributes and config_db for our purposes.
The first sets metadata on the package:
def config_attributes(self):
return dict(comment='A package for video catalog management',
name_short='video',
name_long='Video Catalog',
name_full='Video Catalog')
The method config_db defines the database model source, composed as follows:
- director
- id (pkey)
- name
- year
- nationality
- movie
- id (pkey)
- title
- genre
- director (related with director.id)
- year
- nationality
- description
- dvd
- code (pkey)
- movieid (related with movie.id)
- purchasedate
- available
def config_db(self,pkg):
director = pkg.table('director', name_short='Dir', name_long='Director',
pcol='name,year:%s (%s)')
dir_id = director.intColumn('id')
director.pkey('id')
director.column('name', name_short='N.', name_long='Name')
director.intColumn('year', name_short='Yr', name_long='Birth Year')
director.column('nationality', name_short='Ntl',name_long='Nationality')
movie = pkg.table('movie', name_short='Mv',name_long='Movie', pcol='title')
movie_id = movie.intColumn('id')
movie.pkey('id')
movie.column('title', name_short='Ttl.',name_long='Title',
validate_case='capitalize', validate_len='3,40')
movie.column('genre', name_short='Gnr',name_long='Genre',
validate_case='upper', validate_len='3,10')
movie.column('director', name_short='Dir',name_long='Director').relate(dir_id)
movie.intColumn('year', name_short='Yr',name_long='Year')
movie.column('nationality', name_short='Ntl', name_long='Nationality')
movie.column('description', name_short='Dsc', name_long='Movie description')
dvd = pkg.table('dvd', name_short='Dvd', name_long='Dvd')
dvd_id = dvd.intColumn('code')
dvd.pkey('code')
dvd.column('movieid', name_short='Mid', name_long='Movie id').relate(movie_id)
dvd.dateColumn('purchasedate', name_short='Pdt', name_long='Purchase date')
dvd.column('available', name_short='Avl', name_long='Available')
Creating the page
Now the database model is ready, let's prepare the first package's webpage. movieinfo.py The page structure is very simple and composed by:
- Page layout container
- Title header
- Left column
- Select widget
- Client pane
- Box with movie informations
We use just one complex widget called dbSelect. It is a field that makes realt-time queries on a database table and displays in a popup menu all results that starts with the typed substring. When the user choose one result rom the menu it auto-fills the field and load from server the selected record in the page's data bag. This widget must be configured passing the db table (dbtable), the column to show (dbfield) and the path of page's data bag where the record must be saved into (recordpath).
Here's the GnrWebPage implementation.
class GnrCustomWebPage(GnrWebPage):
# ----- Page description -----
def main(self, root, **kwargs):
# ----- page layout -----
layout = root.layoutContainer(height='100%',background_color='silver')
# ----- title header ------
header = layout.contentPane(layoutAlign='top',
background_color='maroon')
title = header.div('Movies', color='white', text_align='center', font_size='18pt')
#------dbSelect --------------
left = layout.contentPane(layoutAlign='left', width='30em', padding='1em')
left.span('Select a movie', margin_right='10px')
movie_selector = left.dbSelect(gnrId='film_selector',
dbtable='video.movie',
dbfield="title",
recordpath='film.record',
_class='linkerselect')
# ----- client pane with information box -----
client= layout.contentPane(layoutAlign='client')
movie_info=client.div(datasource='film.record',
border='inset 1px', height='5em', width='20em',
padding='1em', margin='1em',
background_color='#CCCCFF')
movie_info.span(datasource=':title', font_weight='bold', font_size='12pt')
movie_info.br()
movie_info.span(datasource=':genre', mask='%s ')
movie_info.span(datasource=':nationality', mask='(%s ')
movie_info.span(datasource=':year', mask='-%s)')
movie_info.br()
movie_info.span(datasource=':@director.name', mask=' directed by %s ')
# ------------ Standard Rpc Call ------------
def rpc_serverCall(req,**kwargs):
return GnrCustomWebPage(req, **kwargs).serverCall()
Creating a sample application instance
We want to create an instance of an application composed only by one package, video. From the console in any directory the build command is gnrmakeinstance followed by the instance name and then by all the packages included by the instance:
sudo gnrmkinstance videoapp video
Now the directory videoapp /usr/local/genro/data/instances has been created. At the moment it only contains the file instanceconfig.xml and the empty folder data.
First of all, we need to configure the database line within the instanceconfig.xml:
You can use Postgres as DB:
<db implementation="postgres" host="localhost" password="mypassword" user="foo" dbname="videodb"/>
and Sqlite DB too:
<db implementation="sqlite" password="foo" user="bar" filename='data/videodb' dbname='videodb'/>
For this tutorial use the Sqlite implementation. Then we have to update the instance's database structure or, if empty, to create it by the execution, from the instance's directory (e.g.: /usr/local/genro/data/instances/videoapp), of the command:
sudo gnrdbsetup
In this example let's populate the database importing data from a proper xml file:
gnrdbsetup import /foo/bar/videodata.xml
Now the application instance is ready and can be eventually customized.
Creating a sample site
Now we want to create a site, starting from our brand-new application instance. To do this we use the command gnrmksite from the instance directory. The correct syntax for gnrmksite is:
gnrmksite sitepath [instancepath]
In this example we write:
sudo gnrmksite /usr/local/genro/data/sites/myvideosite
The second argument, instancepath is optional, if it isn't passed the command adds to the site the current directory. This bin command prepares an empty site structure that contains all the instance's pages divided by packages.
Since a site can be multi-instance, if you apply the command gnrmksite to the same site but from a different instance, the instance is added to the site.
In the end, here is what we made
- the package video
- the application instance videoapp
- the site myvideosite
Set your Server configuration
Now, before seeing what we have done, we have to place a symbolic link of the site folder into the htdocs. So from your htdocs you have to write in your console something like this:
ln -s /usr/local/genro/data/sites/myvideosite myvideosite
Let's set the file httpd.conf in the dir /usr/local/apache2/conf adding this line at the end of the file:
<Directory /usr/local/apache2/htdocs/myvideosite/pages> SetHandler mod_python PythonHandler mod_python.publisher PythonDebug On </Directory>
Now start your apache2 server:
sudo /usr/local/apache2/bin/apachectl start
Go to your localhost address
http://localhost:8001/myvideosite/pages/video/movieinfo.py
Genro bin commands that we have used
| command | arg 1 | arg 2 | description |
| gnrmkpackage | packagename | Creates an empty package in the current directory | |
| gnrmkinstance | instance name | included packages | Creates in genro/data/instances an empty instance that includes the passed packages |
| gnrdbsetup | mode [check, import] | if mode import [path of xml dump] | Check if database structure corresponds to the model and if doesn't it updates the db structure. If mode is import it loads data from an xml dump |
| gnrmksite | sitepath | [instancepath] | If the site doesn't exists yet, it creates the site, containing the current instance's pages else it adds the instance to the site |
Attachments
- videoapp.png (12.5 kB) - added by anonymous 20 months ago.
- videodata.xml (2.9 kB) - added by etorrente 20 months ago.
- sitefolder.jpg (55.3 kB) - added by etorrente 20 months ago.
- packg_video.tiff (111.7 kB) - added by etorrente 20 months ago.
- packg_video.png (78.5 kB) - added by etorrente 20 months ago.
- database_video.jpg (163.5 kB) - added by etorrente 20 months ago.
- videoapp.jpg (74.8 kB) - added by etorrente 20 months ago.
- tutorial.png (26.3 kB) - added by anonymous 19 months ago.
- scshot.png (19.8 kB) - added by sporcari 19 months ago.




