Sunday, October 31, 2010

Web2py, Eclipse, Pydev - Recipe

Web2py Integration with Google Code and Eclipse 200-10-31

In this blog, I'm going to give you a recipe to integrate Web2py applications with Google Code (GC) issue tracking and code version using Mercurial with Pydev in Eclipse.

We are going to integrate the following stuff:
  • GC issue tracking with Mylyn;
  • GC versioning using Mercurial and the MercurialEclipse plug-in;
  • Pydev with code completion and code checking;
  • Aptana Studio plug-in for Eclipse for the edition of HTML and CSS files.
Mylyn is a task manager. It will enable us to create queries to get tickets from QC, edit the tickets and track the views associated with them. With MercurialEclipse, we can do all the usual Mercurial operations we normally do on the command line, see incoming and outgoing changes and the status of files. Pydev is of course our main tool for editing Python files. Finally, the Aptana plug-in offers a much better editor for HTML and CSS files than the Web Tools Platform of Eclipse (this my subjective point of view).

Maybe we don't need all this stuff. But I guess this blog will be useful to anyone who wants to do web development in Python with Eclipse.

I am writing the recipe in the context of my development environment: Linux OpenSuse 11.3. If you are using another operating system, you may have to do some adaptations (especially for Windows).

I assume that you are able to use the command line terminal (moving around, deleting or copying files, etc.). Otherwise, you may start with this tutorial (http://linuxreviews.org/beginner/) and comeback later. I also assume that Mercurial is already installed on your machine (http://mercurial.selenic.com/wiki/Download).

The text in italic needs to be adapted to your application context. Command names or directory names are written with the courrier font.

I hope the links on this page are going to stay valid for a while but you may have to do a little search as this page gets older.

Creating a new Web2py application

This is easy:
  1. Start the Web2Py server;

  2. Go to the site section of Web2py admin;

  3. In the right side of the page, type the name of the new application and click create (don't use name with hyphens “-” Web2py doesn't like them).

Push the code on Google Code (manually)

Use this recipe when you don't want to use the MercurialEclipse plug-in. I suppose that you have already installed Mercurial (http://mercurial.selenic.com/) and that Mercurial is in your path.
  1. Create your new project on GC with Mercurial as control versioning system (http://code.google.com/hosting/) if needed;

  2. Open your terminal and move to the “applications” directory of your Web2py installation;

  3. Under the “Source” tab of the web site your GC project you will find the Mercurial clone needed to clone your project. Use this command to clone project but change the destination (it is the last parameter) if a directory with that name already exist (we cannot clone to an existing directory).
We cannot clone to our application directory because files are already there and Mercurial wants a new brand directory for the destination. So we are going to copy the files to the new directory, delete the old directory and finally we will rename the destination directory of Mercurial to match the name of our application.

  1. Copy the files of your Web2Py application into the new directory created my Mercurial:

    cp -r nameofweb2pyapp/* nameofmercurialdirectory/
  2. You can after that delete the source directory:

    rm -r nameofweb2pyapp

  3. And finally, rename the Mercurial directory with the name of your application:

    mv nameofmercurialdirectory nameofweb2pyapp

  4. We can now move inside our application directory:

    cd nameofweb2pyapp

  5. Add all the files of the directory for the next commit:

    hg add

Now we would like to specify that we don't want some temporary directories to be tracked by Mercurial:

  1. Create the directories if they are not already there:

    mkdir cache databases errors sessions
  2. Tell Mercurial not to track them:

    hg forget cache databases errors sessions

We are now ready to create the first change set:

  • hg commit -m 'commit message'

Now that our local repository is up to date, we can push the changes on GC:

  • hg push

    Mercurial will ask for your username and password. This is not your usual Google account password but a specific password for GC. To see the GC password, click the “google.com password” link under the 'Source' tab of GC. Use the password shown for Mercurial.

    After the Mercurial upload, click the browse link on the GC web page to see your changes (You should see your files).

Everyday Mercurial (manually)

This is mostly the everyday process with Mercurial. You can work with the command line or you can use the MercurialEclipse plug-in with the Eclipse contextual menu:

  1. When you want to add a Mercurial file under tracking, use:

    hg add
    filename

  2. To create a new change set, use:

    hg commit or hg commit -m '
    message'

    This will create a new change set in the local repository. If you don't supply a message, Mercurial will start a text editor for you to type the message. If you save the file and quit the editor, Mercurial will commit with the message in the file. Otherwise, the commit will be canceled.

  3. To push the changes on GC, use:

    hg push

    This will push the changes on GC.

  4. To obtain the changes from the other developers, use hg pull then hg update to update the working directory.

OK, this was a very short introduction of Mercurial.

To know more about Mercurial, I recommend “Mercurial: The Definitive Guide” by Bryan O'Sullivan. This book is available free of charge at (http://hgbook.red-bean.com/).

Install Java

Before installing Eclipse, you may need to install Java. While Java OpenJDK has made a lot of progress, I highly recommend the Sun (Oracle) Java version. Use the following command to verify the Java version you are using:

java -version

It will print something like:

java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)

Download and install the Sun Java version if needed: http://java.sun.com/javase/downloads/index.jsp. Use the JDK in favor of the JRE. To make it the default Java version on your machine, you may use 'update-alternatives' (https://help.ubuntu.com/community/Java).

Install Eclipse

Now that we have Java, we can install Eclipse. You can probably install from your distribution's packages but personally I prefer to install from the source to have the latest version available to have the latest bug fixes.

  1. Go to http://www.eclipse.org/downloads/ to find the latest Eclipse version available;

  2. There are no dedicated version for Python developers. All the Eclipse distributions include Eclipse Marketplace with the exception of Eclipse Classic. Eclipse Marketplace is an easy to use interface to find and install plug-ins directly from the IDE. It is a very valuable tool that I highly recommend. Because the Eclipse IDE is used a lot by Java developers and because sometimes Eclipse plug-in developers create unwanted dependencies with Java tools, I recommend Eclipse IDE for Java Developers or Eclipse IDE for Java EE Developers even for Python developers;

  3. Download an Eclipse distribution suitable for your system and unpack the tar ball in the installation directory of your choice. Make sure the directory is writable. Eclipse needs a writable directory to work properly.

    tar xvfz
    eclipse-...tar.gz

Install the Eclipse plug-ins

The easiest to install all the plug-ins listed at the beginning of this blog is using the Eclipse Marketplace. The Eclipse Marketplace is located in the Help menu. This is what I discovered after I wrote this blog. Since the manual method to install plug-ins from the IDE was already written, I am publishing it anyway in this section. I won't give explicit instructions for the Marketplace feature because it is mostly self evident. Beware that while installing plug-ins in Eclipse is easy, there is no easy way to uninstall them. So it might be a good idea to backup your Eclipse install before installing new stuff especially if your are installing plug-ins still in incubation. So here is the manual install anyway...

  1. Start Eclipse. We are going to install our plug-ins. Open the 'Help' menu and choose 'Install New Software...':



    You are going to see the install dialog:

  2. Click the 'Add...' button. We are going to add the update sites. I hope the URLs I have are going to be still valid at the time you'll use them. If some of them are not working, we'll have to google a bit to find the right one. So add the following sites (you can give them other names if you like):

    Name

    Location

    Aptana Studio

    http://download.aptana.org/tools/studio/plugin/install/studio

    MercurialEclipse

    http://cbes.javaforge.com/update

    MyLyn for Eclipse 3.4 and 3.5

    http://download.eclipse.org/tools/mylyn/update/e3.4/

    Mylyn-GoogleCodeConnector

    http://knittig.de/googlecode-mylyn-connector/update/

    Pydev

    http://pydev.org/updates

  3. Choose 'Aptana Studio' in the 'Work with menu';

  4. Check Aptana Studio;

    Start the installation:

  5. Click 'Next';

  6. Click 'Next' in Install Details;

  7. Click 'I accept the terms of the license agreements' in Review Licenses;

  8. Click 'Finish' to start the installation;

    T
    he install process will start and run for a while. We have to wait...

  9. Click 'OK' when you see the 'Security Warning';

  10. Click the 'Eclipse.org...' certificate and 'OK';

  11. Click 'No' at the 'Software Updates' dialog. We are going to continue our install process;

    O
    K, let's continue with the installation of Mylyn:

  12. Help > Install New Software;

  13. Choose 'MyLyn for Eclipse 3.4 and 3.5';

  14. Check 'Mylyn Features' and 'Mylyn Integration' (you probably don't need the plug-in stuff). The entry you need for GC is named 'Mylyn Connector: Web Templates (Advanced)' so make sure it is checked;

  15. Start the install process by clicking the 'Next' button;

  16. Follow the process you did for the Aptana plug-in studio;

  17. Click 'No' when asked for a restart;

    N
    ow we have Mylyn but we also need the connector for GC:

  18. Help > Install New Software;

  19. Choose 'Mylyn-GoogleCodeConnector';

  20. Check 'Nightly Builds', yes it still a work in progress;

  21. ...Follow the usual process;

  22. Don't forget to click 'No' when asked to restart;

    I
    t is now Pydev's turn:

  23. Help > Install New Software;

  24. Choose 'Pydev';

  25. Check both 'Pydev' and 'Pydev Mylyn Integration';

  26. ...Follow the usual process;

  27. Don't forget to click 'No' when asked to restart;

    L
    ast but not least: Mercurial:

  28. Help > Install New Software;

  29. Choose 'MercurialEclipse';

  30. Check everything except 'Obsolete';

  31. Open MercurialEclipse and uncheck 'Windows Binaries for Mercurial' if you are not on Windows ;

  32. ...Follow the usual process;

  33. Finally we can click 'Yes' to restart.

We have installed a lot of software. In the next section, we are going to configure all this.

Configuring Eclipse

While we have installed a lot of software, we don't have to do a lot of configuration in Eclipse. The default configuration should be OK. The configuration we need is more related to the project itself. I have dedicated sections on this blog for Mylyn and MercurialEclipse. One exception is Pydev. Pydev needs its own configuration. Go to http://pydev.org/manual_101_root.html. You need to set the different Python locations you want to use so Pydev can find them.

Creating the Eclipse Pydev project with Maven

To automate the process of creating EclipseWeb2py Pydev projects, I created a Python script that uses Apache Maven (http://maven.apache.org/). So to use the script, you first need to install Maven. Make sure Maven is your path so the script can find it. If you don't want to do this installation and the Python script that I created, you can do it manually. It is not a very complicated process.

To use the script, it is very easy:

  1. Download the last version of the script on GoogleCode;

  2. Rename the file 'create_eclipse_project';
  3. Copy the file in the directory of your Web2py application or, even better, in your path to make the script available everywhere;

  4. Run the script (you may have to set the file as executable);

  5. The script will ask the name of Pydev Python interpreter to use with the project. You may see this name in Eclipse (Window > Preferences Pydev > Interpreter – Python). Type the name to use;

  6. Maven may takes a while to load all its dependencies. If everything goes well, a new Eclipse project is created. Import the project in Eclipse (File > Import... > General > Existing Projects into Workspace) select the directory of your Web2py application as the new project. Don't check 'Copy projects into workspace';

You may now switch to the Pydev perspective to see your project. If you did the manual configuration of Mercurial, your project is already under source control. Don't worry if it is not the case, I am going to tell how to do it from Eclipse.

You may see Pydev reporting a lot of errors for the new project. It is because the static code analyzer of Pydev does not know about the 'magic' imports of web2py. I explain how to get around this problem in the 'Avoiding warning and errors with Pydev' section bellow. Before that, you can use the '#@PydevCodeAnalysisIgnore' comment in your files to deactivate the code analyzer.

You may want to look at the next section to understand what the script has done for you.

Creating the Eclipse Pydev project manually

If you don't want to use the previous method and prefer to do things manually, here is how to proceed:

  1. File New > Pydev Project This command will bring the following dialog:

  2. Give your project a name (I use the same name as the application folder);

  3. Unckeck 'Use default';

  4. Click 'Browse' and select the application directory;

  5. The project type should be set to 'Python' to use CPython (or may want to use another implementation);

  6. Web2py is made to run on Python 2.5 and later. So I prefer to choose 2.5 as the grammar version but it is up to you;

  7. Choose the Python interpreter you want to use for your project

  8. Unckek 'Create default 'src' forlder and add it to the pythonpath?' Web2py does not use this folder.

  9. Click 'Finish' to create the new project.

We have now created the new project. We are now ready to set the source folders and the external libraries.

  1. If needed switch to the Pydev perspective: Window > Open Perspective > Other... > Pydev > OK;

  2. Bring the contextual menu on the application project and choose 'Properties'.

    This will bring the following dialog:



  3. Choose 'PyDev – PYTHONPATH.

  4. For the 'Source Folders' tab, add the following source folders ('Add source folder' button): 'controllers', 'languages', models', 'modules' and the application folder itself. We need the 'modules' folder for the static code analyzer of Pydev but you'll probably use the 'local_import' of Web2Py to use the code in 'modules' in your application (http://web2py.com/book/default/section/4/18);

  5. Next we have to add the external libraries. Move the 'External Libraries' tab. Add the source folders ('Add source folder' button) of Web2py itself (the directory of the web2py installation) and the 'site-packages' folder inside it. The paths are absolute for these folders.
The Pydev project is now configured.

Configuring MercurialEclipse

MercurialEclipse is easy to configure. What I like about this plug-in is the fact that I can see the status of a file just by looking at its icon. It can also remember the password for your repository.

Here are the steps:
  1. Move to the 'Team Synchronizing' perspective (Window > Open Perspective > Other...);

  2. The 'Synchronize' wizard that appears when the 'Synchronize...' icon is clicked but it does not work with Mercurial (at least with my version of Eclipse). So instead, open the 'Mercurial Repositories' view (Window > Show View Others... > Mercurial Repositories);

  3. Click the 'Create Repository...' icon ;

  4. Find the url for your Mercurial project. You see the url under the “Source” tab of your GC web page. You will see a command in the form hg clone url projectname. Copy the url without the project name (the url and the project name are separated by a space) for the URL of the 'Repository location' in the dialog:



  5. Type your user name and the password for the Mercurial repository on GC. To see the password, it is not your usual Google account password but a specific password for the repository, click the 'google.com password' link under the 'Source' tab to see it;

  6. Click 'Finish';

  7. I don't know how to create a Mercurial repository from Eclipse so you'll have to create it from the command line. Use hg init from your application directory;

  8. Close the perspective to return to the Pydev perspective (Window > Close Perspective). We may have to do it more than one time;

  9. Bring the contextual menu on the project and choose Team > Add...;

  10. Select the files to add. Uncheck the files only needed by the Eclipse IDE;

  11. Use Team > Ignore... to tell Mercurial for forget the unnecessary files for the repository (cache databases errors sessions);

  12. Commit the project (Team > Commit...). Enter the commit message and click 'OK'. This saves the files in your local repository as a new change set;

  13. Use (Team > Ignore...) to tell Mercurial the files and folders that you want it to forget. These are the temporary folders created by Web2py (cache databases errors sessions), the files defining the Eclipse project. Do not select the '.hgignore' file (this a file to keep in the repository). The files to ignore are all beginning by a dot (.). Use the 'Navigator' view to see them (Window > Show View > Navigator);

  14. Push the changes on GC (Team > Push...). Select the URL of GC using the menu and click 'Finish' (the 'Next' button is for selecting a revision but we are using the last one so we don't need to be more specific).
Your code is now on GC. You may go back to 'Every day Mercurial (manually)' if you never worked with Mercurial to have a better idea of every day versioning management process. With the plug-in it is pretty easy: the menu gives you a good idea of the commands available.

I won't dive too deep into MercurialEclipse. I invite to explore on your own. But there are two features that I like a lot. Using the contextual menu on a file or a directory you can see the changes (Team > Show History (or Show Local History)). Try also the 'Compare With' command also available in the contextual menu.

Configuring Eclipse Mylyn


Mylyn gives access to all the tickets related to your code. Let's access the ticket created on GC:

  1. Open the Task Repositories view: Window > Show View > Other... Tasks Repositories;
  2. Click the 'Add Task Repository...' icon ;

  3. Select 'Web Template (Advanced)'. You should have that choice available if you have installed 'Mylyn-GoogleCodeConnector' at the Install the Eclipse plug-ins step;

  4. Click the 'Next' button;

  5. In the 'Server' field, choose 'Eclipse Outliner (Google Code)'. This will show a generic template that we can customize;

  6. Change the URL in the 'Server' field with the URL for your GC project. It should be something like
    http://code.google.com/p/projectname/issues';

  7. You may type a label in 'Label'. (But I don't know what this mean);

  8. Uncheck the 'Ananymous' check box;

  9. Type your GC user name in 'User ID';

  10. Type your Google password. This is not the same password that you used for source control with Mercurial under the 'Source' tab of the web page for your project;

  11. Check the 'Save Password' check box if you want to Eclipse remembers your password;

  12. Unfold 'Additional Settings' and then 'Advanced Configuration';

  13. Change 'Query Request URL' for (without the quote):
    '${serverUrl}/csv?can=1&colspec=ID+Status+Type+Owner+Summary';

  14. Change 'Query Pattern' for:
    '"({Id}[0-9]+?)","({Status}.+?)","({Type}.+?)","({Owner}.+?)","({Description}.+?)"\s';

    This is all on a single line without the starting and ending simple quotes but with all the double quotes.

  15. If you are behind a proxy, set the proxy configuration appropriately;

  16. Click the 'Validate Settings' button to make sure everything is fine;

  17. Click 'Finish'.
To view your GC tickets, open the 'Task List' view (Window > Show View > Others... > Taks > Task List). This is not like the general 'Tasks' view of Eclipse that helps track the task tags in your code (Window > Preferences > Pydev > Taks Tags).

I won't go very far with Mylyn on this blog. My goal was to help you with the GC configuration. To know more Mylyn, I suggest that you visit the Mylyn web site (http://www.eclipse.org/mylyn/).

Thanks for Alex's blog at http://eclipse.dzone.com/articles/using-mylyn-with-google-code-u.

Configuring Aptana plug-ins

Since you have installed it, Aptana is now the default editor for the .html files. Personally, I like the default configuration so I won't comment that much. The only thing that I dislike is seeing the 'Aptana Intro' each time I start Eclipse. To remove it, choose:

  1. Window > Preference > General > Startup and Shutdown;

  2. Uncheck 'Aptana Intro'.

I invite you to experiment on your own.

Avoiding warning and errors with Pydev

Web2py dynamically imports a lot of things for your models and controllers. This is way Pydev is reporting a lot of errors as 'Undefined variable'. The fix I created to get rid of these errors is two little pieces of code. One that I put in my models and the other that I put in my controllers:

(for the models)

# Static analyzer import helpers:
if 0:
None
# import gluon
# from gluon.contrib.gql import GQLDB
# from gluon.html import A
# from gluon.html import B
# from gluon.html import BEAUTIFY
# from gluon.html import BODY
# from gluon.html import BR
# from gluon.html import CENTER
# from gluon.html import CLEANUP
# from gluon.html import CODE
# from gluon.html import CRYPT
# from gluon.html import DIV
# from gluon.html import FORM
# from gluon.html import I
# from gluon.html import IFRAME
# from gluon.html import IMG
# from gluon.html import INPUT
# from gluon.html import IS_ALPHANUMERIC
# from gluon.html import IS_DATE
# from gluon.html import IS_DATETIME
# from gluon.html import IS_DATETIME_IN_RANGE
# from gluon.html import IS_DATE_IN_RANGE
# from gluon.html import IS_DECIMAL_IN_RANGE
# from gluon.html import IS_EMAIL
# from gluon.html import IS_EMPTY_OR
# from gluon.html import IS_EQUAL_TO
# from gluon.html import IS_EXPR
# from gluon.html import IS_FLOAT_IN_RANGE
# from gluon.html import IS_IMAGE
# from gluon.html import IS_INT_IN_RANGE
# from gluon.html import IS_IN_DB
# from gluon.html import IS_IN_SET
# from gluon.html import IS_IPV4
# from gluon.html import IS_LENGTH
# from gluon.html import IS_LIST_OF
# from gluon.html import IS_LOWER
# from gluon.html import IS_MATCH
# from gluon.html import IS_NOT_EMPTY
# from gluon.html import IS_NOT_IN_DB
# from gluon.html import IS_NULL_OR
# from gluon.html import IS_SLUG
# from gluon.html import IS_STRONG
# from gluon.html import IS_TIME
# from gluon.html import IS_UPLOAD_FILENAME
# from gluon.html import IS_UPPER
# from gluon.html import IS_URL
# from gluon.html import LABEL
# from gluon.html import LEGEND
# from gluon.html import LI
# from gluon.html import LINK
# from gluon.html import MARKMIN
# from gluon.html import MENU
# from gluon.html import META
# from gluon.html import OBJECT
# from gluon.html import OL
# from gluon.html import ON
# from gluon.html import OPTGROUP
# from gluon.html import OPTION
# from gluon.html import P
# from gluon.html import PRE
# from gluon.html import SCRIPT
# from gluon.html import SELECT
# from gluon.html import SPAN
# from gluon.html import TABLE
# from gluon.html import TAG
# from gluon.html import TBODY
# from gluon.html import TD
# from gluon.html import TEXTAREA
# from gluon.html import TFOOT
# from gluon.html import TH
# from gluon.html import THEAD
# from gluon.html import TITLE
# from gluon.html import TR
# from gluon.html import TT
# from gluon.html import UL
# from gluon.html import URL
# from gluon.html import XHTML
# from gluon.html import XML
# from gluon.html import embed64
# from gluon.html import xmlescape
# from gluon.sql import SQLDB
# from gluon.sqlhtml import SQLFORM
# from gluon.sql import SQLField

# from gluon.sqlhtml import SQLTABLE
# from gluon.html import STYLE
# from gluon.http import redirect
# import gluon.languages.translator as T
# global cache; cache = gluon.cache.Cache()
# import gluon.compileapp.local_import_aux as local_import
# global request; request = gluon.globals.Request()
# global response; response = gluon.globals.Response()
# global session; session = gluon.globals.Session()
# global DAL; DAL = gluon.dal()
# global HTTP; HTTP = gluon.http()
# global LOAD; LOAD = gluon.compileapp.LoadFactory()

(for the controllers)

# Static analyzer import helpers:
if 0:
None
# import gluon
# from gluon.contrib.gql import GQLDB
# from gluon.html import A
# from gluon.html import B
# from gluon.html import BEAUTIFY
# from gluon.html import BODY
# from gluon.html import BR
# from gluon.html import CENTER
# from gluon.html import CLEANUP
# from gluon.html import CODE
# from gluon.html import CRYPT
# from gluon.html import DIV
# from gluon.html import FORM
# from gluon.html import I
# from gluon.html import IFRAME
# from gluon.html import IMG
# from gluon.html import INPUT
# from gluon.html import IS_ALPHANUMERIC
# from gluon.html import IS_DATE
# from gluon.html import IS_DATETIME
# from gluon.html import IS_DATETIME_IN_RANGE
# from gluon.html import IS_DATE_IN_RANGE
# from gluon.html import IS_DECIMAL_IN_RANGE
# from gluon.html import IS_EMAIL
# from gluon.html import IS_EMPTY_OR
# from gluon.html import IS_EQUAL_TO
# from gluon.html import IS_EXPR
# from gluon.html import IS_FLOAT_IN_RANGE
# from gluon.html import IS_IMAGE
# from gluon.html import IS_INT_IN_RANGE
# from gluon.html import IS_IN_DB
# from gluon.html import IS_IN_SET
# from gluon.html import IS_IPV4
# from gluon.html import IS_LENGTH
# from gluon.html import IS_LIST_OF
# from gluon.html import IS_LOWER
# from gluon.html import IS_MATCH
# from gluon.html import IS_NOT_EMPTY
# from gluon.html import IS_NOT_IN_DB
# from gluon.html import IS_NULL_OR
# from gluon.html import IS_SLUG
# from gluon.html import IS_STRONG
# from gluon.html import IS_TIME
# from gluon.html import IS_UPLOAD_FILENAME
# from gluon.html import IS_UPPER
# from gluon.html import IS_URL
# from gluon.html import LABEL
# from gluon.html import LEGEND
# from gluon.html import LI
# from gluon.html import LINK
# from gluon.html import MARKMIN
# from gluon.html import MENU
# from gluon.html import META
# from gluon.html import OBJECT
# from gluon.html import OL
# from gluon.html import ON
# from gluon.html import OPTGROUP
# from gluon.html import OPTION
# from gluon.html import P
# from gluon.html import PRE
# from gluon.html import SCRIPT
# from gluon.html import SELECT
# from gluon.html import SPAN
# from gluon.html import TABLE
# from gluon.html import TAG
# from gluon.html import TBODY
# from gluon.html import TD
# from gluon.html import TEXTAREA
# from gluon.html import TFOOT
# from gluon.html import TH
# from gluon.html import THEAD
# from gluon.html import TITLE
# from gluon.html import TR
# from gluon.html import TT
# from gluon.html import UL
# from gluon.html import URL
# from gluon.html import XHTML
# from gluon.html import XML
# from gluon.html import embed64
# from gluon.html import xmlescape
# from gluon.sql import SQLDB
# from gluon.sqlhtml import SQLFORM
# from gluon.sql import SQLField
# from gluon.sqlhtml import SQLTABLE
# from gluon.html import STYLE
# from gluon.http import redirect
# import gluon.languages.translator as T
# from gluon.tools import Auth
# from gluon.tools import Service
# global auth; auth = gluon.tools.Auth()
# global cache; cache = gluon.cache.Cache()
# global crud; crud = gluon.tools.Crud()
# global db; db = gluon.sql.DAL()
# import gluon.compileapp.local_import_aux as local_import
# global request; request = gluon.globals.Request()
# global response; response = gluon.globals.Response()
# global service; service = gluon.tools.Service()
# global session; session = gluon.globals.Session()
# global DAL; DAL = gluon.dal()
# global HTTP; HTTP = gluon.http()
# global LOAD; LOAD = gluon.compileapp.LoadFactory()

This code is never executed but the static code analyzer sees the missing variables so it removes the errors we talked about. But instead of having errors, you may see warnings. These warnings appear because some imports are not used. To finalize the solution, comment the 'import *' statements and add only the specific imports needed. It is not a very nice solution but it is best one I found yet.

Since you'll probably be using this piece of code a lot, it is good idea to create a template to avoid copying and pasting all the time.

To do so:

Go to Window > Preferences > Pydev > Editor > Templates

Define the template with the name you like. Once defined, templates can be expended using Control+Space in the text editor (if the default shortcut has not been changed).

Create the launch configuration to start the application

To start the Web2py application, we need access to the web2py.py file that is not inside the application project. To have access to the file, we need to create a link in Eclipse. If you used the Python script create_eclipse_project to create the Eclipse project, the link is already created and you can go directly to step 7. Otherwise, start at step 1 to create the link first:

  1. Click in the application folder.

  2. Bring the menu contextual and choose New > File

  3. Click the 'Advanced >>' button.

  4. Check the 'Link to file in the file system' check box.

  5. Click the 'Browse...' button select the web2py.py file in the file selector as the file to link.

  6. Click 'Finish' to validate the dialog.

    Mercurial will complain that the file is outside the application folder but just ignore the message. Do not try to create a symbolic link on your file system. I've tried and it does not work well.

    Now that we have created the link, we can create the launch configuration:

  7. Click in the application folder.

  8. Bring the menu contextual and choose 'Properties'.

  9. Choose 'Run/Debug Settings' in the property dialog.

  10. Click the 'New..' button to create a new configuration.

  11. Select 'Python Run' as the type of configuration to create and click 'OK'.

  12. In the 'Name:' filed, give a name to the configuration. I simply use the name of the project.

  13. Click the 'Browse...' button and choose the project related to your application.

  14. Click the second 'Browse' button and choose the linked 'web2py.py' file we just created at the last step.

  15. Click the 'Common' tab and check the 'Debug' and 'Run' check boxes in 'Display in favorites menu' so the configuration appears in the favorites menu.

  16. Click 'OK' to confirm everything.

  17. Click 'OK' again to dismiss the property dialog.

You can now run and debug the application using the play and the debug button menu by choose the configuration from the tool bar.

Useful things to know about Eclipse

To use Eclipse well, some concepts are very important to understand. If you are new to Eclipse, look for help in Help > Welcome > Workbench basics. I'll find the 'Workbench User Guide' that is worth reading. The most important concepts to understand, I believe, are workbench, workspace, view and perspective. This is a must to use Eclipse properly. I also suggest that you take some time to customize the perspectives you are using (Window > Customize Perspective...). By doing so, you can choose the menu commands, buttons in the tool bar, view and other perspectives that are relevant to your working environment. You'll move the noise way and put the useful stuff at your finger tip.

If this can help, here are the views I use the most for Python development:
  • Bookmarks : Using the Edit menu, you can create bookmarks for your project in your workspace. Useful for temporary bookmarks you don't want to share with others;

  • Console : Where you can the result output;

  • Error Log : Shows the problems related to the IDE environment;

  • Internal Web Browser : Use this one to preview HTML code. The Aptana editor can also preview code;

  • Navigator : Shows the files using a more file system centric point of view than the Project Explorer view;

  • Markers: This view list a lot of things: warnings, errors, bookmarks and tasks. You can use this view if you prefer and it will replace all these other views: Bookrmarks, Problems and Tasks;

  • Outline : Shows the outline of both the Python code and the HTML code;

  • Problems : Shows the warnings and errors of the Python code;

  • Progress: Shows the background activities of the IDE;

  • Project Explorer : Show the files like the Navigator view but with a more project centric point of view;

  • Properties : Shows the properties of the files (name, path, status, ...);

  • Pydev Package Explorer : I prefer to use the Navigator and the Project Explorer.

  • Search : Search results on files;

  • Snippets : Apatana view of html snippets and macros. It seems gone are not yet available with the version 3;

  • Task List : List the tickets of GC or from other repositories;
  • Tasks : Task marks in the code (Window > Preferences > Pydev > Task Tags).
I also suggest to read Effective Eclipse: Shortcut keys | Eclipse Zone at http://eclipse.dzone.com/news/effective-eclipse-shortcut-key fromTomas Kramar. Some shortcuts are more Java related by most of them are very useful to know.

To maximize comfort, I suggest to customize the colors of the Pydev editor:

(Window > Preferences > Pydev > Editor

You can also change the font:

Window > Preferences > General > Appearance > Color and Fonts > Basic > Text font

Personally, I like Droid Sans Mono (http://damieng.com/blog/2007/11/14/droid-sans-mono-great-coding-font). The font is probably also available in your distribution's packages.

6 comments:

Ramjee Ganti said...

Excellent piece. very detailed. It would have saved me lot of time if it was there a few months back.

Thanks for posting this.

weheh said...

What about the undefined variable: db?

Pachi said...

Thank you very much for this great post. It's very clear and to the point. It did help me a lot.

Fefe said...

Why are you stop? Keeping BlogIN

Pierre Thibault said...

I moved my blog on the Posterous platform. Please follow my blog there because I don't maintain this one anymore.
http://pierrethibault.posterous.com/2010/10/web2py-eclipse-pydev-recipe.html

Pierre Thibault said...

weheh said...

What about the undefined variable: db?

You have to add manually some stuff. The web2py magic imports are importing everything you add at the global level of your models. This of course varies from project to project. I know my solution is a bit clunky but it the less worse I think of for the moment.