imgSeek code
<nieder|at|mail.ru>
Time-stamp: <03/08/26 21:19:06 rnc>
UI code
All dialogs are created with QT's designer and resulting .ui files are fed to pyuic, which generates *Form.py. This step is done by imgSeekLib/generate-ui.sh.
MainForm (mainform.ui - the main dialog) requires a few custom widgets found on imgSeekLib/customWidgets.py, So once code is generated by pyuic, the script imgSeekLib/update-ui.sh will apply a patch that replaces original widgets used on mainform.ui by the custom ones. This patch, which is called imgSeekLib/customDiff will also fix some menu issues with old PyQt versions.
QT's designer does support custom widgets, and pyuic will generate code correctly, but in order to use this feature (and thus stop using the customDiff hack) i'd have to define each custom widget inside "designer", and by "define" i mean: add each property (and it's type) that we modified from the original (inherited) widget, and then remove the original widgets from the form (from the places where they are used, that means having to break and rebuild all those layout constrains) and place the custom ones, and then set those properties again.
Coding standards
They are based on Twisted Matrix Coding Standards, but i'll mention the important ones here.
Whitespace
Indentation is 4 spaces per indent. Tabs are not allowed. It is preferred that every block appear on a new line, so that control structure indentation is always visible.
Modules
UI implementation logic for forms and dialogs should be named FooWnd.py and form classes generated by pyuic should be named FooForm.py. Also, FooWnd.py should subclass the main class in FooForm.py, implementing callback methods/events/slot connections.
All modules must be listed on imgSeekLib/__init__.py. That's also where the version number is. This number is used by distutils to generate distribution tarballs and rpm's. You can get the current version by bringing it to the current namespace with:
from imgSeekLib import __version__
Almost all application code is on imgSeekLib/imgSeekApp.py
CVS
SourceForge anonymous cvs seems to be lagged by 24 hours. In order to checkout the cvs code, see instructions here.
On a fresh cvs checkout, before running imgSeek, you should build the c++ module and place it on imgSeekLib, so you can start it from your cvs work dir, without having to install it after every change:
~/work/imgseek/ $ python setup.py build ~/work/imgseek/ $ cp build/lib.linux-i686-2.2/imgSeekLib/imgdb.so imgSeekLib/ ~/work/imgseek/ $ rm -fr build/ ~/work/imgseek/ $ ./imgSeek
Releases and packaging
Source tarballs for distribution are built using distutils' sdist command. A script for generating tgz and bz2 files is on imgseek/mksdist.sh. Generated tarballs can be found on the dist/ dir.
Before each release, the version number must be changed at imgseek/imgSeekLib/__init__.py. This version number is used by distutils when naming dist tarballs.
Please refer to this FAQ entry on how to build RPM's.
Development tools/environment
I use xemacs 21.4, so the ChangeLog file will have the format generated by M-x add-changelog-entry & friends.
Current versions used on development:
- python 2.2.3
- PyQt 3.7
- Qt 3.1.2
- ImageMagick 5.5.6
- gcc 3.2.3
- swig 1.3.10
- pychecker 0.8.12
Misc notes
EXIF/IPTC write support
If you want to reinvent the wheel, then take an existing app or lib with EXIF/IPTC write support and port it to Python.
The other solution would be to make calls like:
commands.getoutput("jhead usersimage -etc -etc")
jhead seems to have an easy CLI, so it shouldn't be much trouble. So all we should do is make such calls on the code for a "Export metadata to image file EXIF section" option on the Metadata editor dialog.
In order to check if jhead or another cli app is available on the user's system, check the code related to jpegtran on imgSeekLib/Settings.py:150 and adapt it to jhead.
Misc Diagrams
Click here for a simple diagram showing the connection and dataflow between imgSeek components.