Entries For: September 2006
2006-09-23
Kde applications vs Gnome applications
I'm switching a bunch of Gnome daily used apps to their KDE counterparts. Namely I've switched from *Liferea to Akregate, from **GnoCHM to KchmViewer and from ***GIMP to Krita (Gimp sucks too much for me in terms of workflow, while Krita is more conventional and less awkward from some points of view). I'm using already using Konversation for IRC (much better then XChat, I'd use Chatzilla but it doesn't go to the systray), Tellico to keep a database of PS2 games and K3b for burning dvds. Next switch is for the full desktop, Gnome > KDE, but I'm waiting for some free time and Edgy, to give the new Gnome a proper review first. I've been looking at some screenshots on KDELook (thanks to Akregate came with some feeds preinstalled) and I think I wouldn't have a problem, especially if I install some compiz goodness.
* Liferea was really really slow in marking feeds as read
** Although I can't copy & paste easily inside Gnome from this kde application, it is a far better chm viewer then its gnome counterpart.
*** Come on GIMP, fixed brush sizes? Windows all over the desktop and taskbar? Plus, Krita has layer groups, which is a step away (I imagine) from having layer effects just like Photoshop. I hate GIMP so much that I'm willing to use ImageReady under wine just to avoid it.
UPDATE: gnome-mag (magnifier) doesn't even give me the opportunity to test it (just maxes the CPU), while kmag works great as a screen magnifier. Koppete is really nice, even compared to the new GAIM 2.0 beta.
2006-09-22
Best Plone quote ever
[18:43] <julesa> newbie39: To paraphrase Jon Ribbens "PHP is a minor evil perpetrated and created by incompetent amateurs, whereas Plone s a great and insidious evil, perpetrated by skilled but perverted professionals."
I admit I love being evil! :-)
Online tools to check DNS
Every now and then I need to check the dns settings for some servers that I look after. Not being an expert, I use these two sites frequently to check that I'm not doing anything stupid:
My preferate is dnsreport.com, but I always forget its name and its pagerank on google is not too high. So I'm doing my really really tiny bit in lifting up its page rank by linking to it on this page.
2006-09-21
Datetime output for an RSS2 feed
To display properly, an RSS 2 feed needs to have the date entered in something resembling this format:
<pubDate>Thu, 21 Sep 2006 15:15:26 GMT</pubDate>
This is needed to get a date to display in this format:
<pubDate tal:content="python: DateTime(res.Date).rfc822()"> </pubDate>
2006-09-20
Short recipe for adaptation with Five
>>> from zope.interface import Interface, Attribute, implements
Let's say we have an object type "Person". This person can introduce himself with the name.
class IPerson(Interface):
name = Attribute('Name of the person')
def say_name():
"""The name of the person"""
class Person(object):
implements(IPerson)
def __init__(self, name):
self.name = name
def say_name():
return 'My name is ' + self.name
Next, we have another object type, let's say "Worker", with an interface of IWorker.
class IWorker(Interface):
job = Attribute('Name of the job')
def set_job():
"""sets the job"""
def say_job():
"""the job"""
Now we want to adapt the Person so that a person is also a Worker.
class PersonJob(object):
implements(IWorker)
def __init__(self, context):
self.context = context
def set_job(self, job):
self.job = job
def say_job(self):
return "My name is %s and I work at %s" % (self.context.name, self.job)
Now let's register the factory that implements the Worker for a Person.
#### >>> registry.register(IPerson, [IWorker,], '', PersonJob)
<configure xmlns="http://namespaces.zope.org/zope">
<adapter
for=".IPerson"
provides=".IWorker"
factory=".PersonJob" />
</configure>
Now let's see how this works
>>> Tom = Person('Tom Sawyer')
>>> print Tom.say_name()
'My name is Tom Sawyer'
>>> tomjob = IWorker(Tom)
>>> tomjob.set_job('DisneyLand')
>>> tomjob.say_job()
'My name is Tom Sawyer and I work at DisneyLand'
Further reference:
- http://plone.org/documentation/tutorial/five-zope3-walkthrough/adapters
- http://codespeak.net/z3/five/manual.html
- http://www.serverzen.net/weblog/archive/2006/09/17/keeping-client-concerns-separate
- http://www.plope.com/Members/chrism/adaptation_for_busy_people
- http://plone.org/documentation/manual/plone-developer-reference/patterns/adapters
- http://svn.zope.org/Zope3/branches/3.3/src/zope/component/README.txt?view=markup
Basic recipe for a Five view
This recipe is addressed more to the zope2/plone developer with a bit of knowledge of the zope3 universe, but not much experience in implementing the new practices.
Simply put, Five views are just like TTW python scripts, except without the limited forced security, and with the possibility to integrate them in unit testing and adapt them to other protocols then just http.
First, things should be done the newly recommended "Zope3 ways". That means creating a new package under the Products folder, or, if pythonproducts is used, anywhere in the python packages path.
Let's name this package "views_test". Make it a python package by placing an empty __init__.py file inside. We'll place the views under a 'browser' package, so we need to create a new folder called 'browser' with an empty __init__.py file as well.
Inside the browser package, we'll create a 'testing' module, with the following content:
from zope.interface import Interface, implements
from Products.CMFPlone import utils
class ITesting(Interface):
def drink():
"""Drinks the cool aid"""
class Testing(utils.BrowserView):
implements(ITesting)
def drink(self):
context=utils.context(self)
portal_url = context.portal_url()
return "We drank the cool aid at %s" % portal_url
The interface declaration is not needed, and it's not necesary for the view to implement a certain interface, but it makes documenting, configuring and possibly future extending the software easier.
Configuring zope to load the view
Best practices is to place configuration files (configure.zcml) in the closest package to which they belong, so we'll have to configure zope to look in the 'browser' package for zcmls as well. To do this, edit the views_test/configure.zcml file and place a simple directive to load the browser package.
<include package=".browser" />The configure.zcml file for the browser package will contain
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:five="http://namespaces.zope.org/five">
<browser:page
for="*"
name="testing_view"
class=".testing.Testing"
permission="zope.Public"
template="testview"
allowed_interface=".testing.ITesting"
allowed_attributes="drink"
/>
</configure>
The TAL template, testview.pt is like this:
<html>
<head>
<title tal:content="template/title">The title</title>
</head>
<body tal:define="view context/@@testing_view">
<span tal:content="view/drink" />
</body>
</html>
It doesn't use the standard main_template macros, but this can be easily integrated.
2006-09-16
Short checklist for Postfix + MySQL + Dovecot + SASL authentication on Fedora
1. Postfix needs to be rebuilt with Mysql enabled
Follow this tutorial: http://postfix.wiki.xs4all.nl/index.php?title=Virtual_Users_and_Domains_with_Courier-IMAP_and_MySQL
This one also helps: Virtual Users And Domains With Postfix, Courier And MySQL (Fedora Core 5) | HowtoForge - Linux Howtos and Tutorials
2. Instal cyrus-sasl and cyrus-sasl-sql.
Configure /etc/sysconfig/saslauthd to run with the rimap mechanism
3. Start saslauthd
2006-09-10
Adaptation explained
It seems that there's a proposal to introduce adaptation in Python 3000, which sparked a discussion and a nice introduction to adaptation on the python-dev list. Another explanation here.
2006-09-06
Printing frameworks and wxPython
As hard as I have tried to find, there's no good printing framework for wxPython. wxEasyPrinting sucks so much for anything more then simple text (for example, the table cells don't support specifying a height). Generating PDF files with a toolkit such as ReportLab (even with Platypus) is harder then it should be, especially when there's no ready made higher level framework. This page explores some of the common printing solutions on Windows.
My own solution to all these is a single-platform hack. Based on my previous experience of creating a "zope based desktop application" using an embeded Internet Explorer, I'm using Internet Explorer through ActiveX as a rendering and print preview engine. Building a new "form" is easy with any HTML GUI builder such as NVU or Dreamweaver and SimpleTAL bridges the gap between the application data and the presentation for printing. The trick is to display only the Print Preview dialog, which can't be done without going through Internet Explorer's back door.
In my generated HTML files I have the following snippet, which automatically calls the Print Preview dialog from Internet Explorer when the file is loaded.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function printpr()
{
var OLECMDID = 7;
/* OLECMDID values:
* 6 - print
* 7 - print preview
* 1 - open window
* 4 - Save As
*/
var PROMPT = 1; // 2 DONTPROMPTUSER
var WebBrowser = "<OBJECT ID='WebBrowser1' WIDTH=0 HEIGHT=0 CLASSID='CLSID:8856F961-340A-11D0-A96B-00C04FD705A2' />";
document.body.insertAdjacentHTML('beforeEnd', WebBrowser);
WebBrowser1.ExecWB(OLECMDID, PROMPT);
WebBrowser1.outerHTML = "";
}
</script>
</head>
<body onload="printpr(); return false;">
</body>
</html>
Next, I have a frame with the IE ActiveX control embeded.
# -*- coding: ISO-8859-1 -*-To display the printing dialog I'm just dumping the generated HTML file to a temporary file and loading it into the IE control.
# generated by wxGlade 0.4.1 on Sun Apr 30 20:43:52 2006
import wx
import wx.lib.iewin as iewin
# begin wxGlade: dependencies
# end wxGlade
def ieWidget(parent, id):
ie = iewin.IEHtmlWindow(parent, -1)
return ie
class dlgIEFrame(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: dlgIEFrame.__init__
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.window_4 = ieWidget(self, -1)
self.__set_properties()
self.__do_layout()
# end wxGlade
self.ie = self.window_4
self.ie.SetClientSizeWH(300, 400)
def __set_properties(self):
# begin wxGlade: dlgIEFrame.__set_properties
self.SetTitle("frame_1")
self.SetSize((792, 755))
# end wxGlade
def __do_layout(self):
# begin wxGlade: dlgIEFrame.__do_layout
sizer_59 = wx.BoxSizer(wx.VERTICAL)
sizer_59.Add(self.window_4, 1, wx.EXPAND, 0)
self.SetAutoLayout(True)
self.SetSizer(sizer_59)
self.Layout()
self.Centre()
# end wxGlade
# end of class dlgIEFrame
2006-09-05
Override the default actions for an ArchGenXML based Archetype
To specify the default view for an AT archetype the "view" action needs to be overriden. Adding a default_actions=True tagged value in the model will generate a view action that will use the base_view template. To be able to change the view action, default_actions should be deleted from the model and replaced with a base_actions=my_actions.
The my_actions statement could look like this:
my_actions = (
{'action': 'string:${object_url}/base_edit',
'category': 'object',
'id': 'edit',
'name': 'Edit',
'permissions': ('Modify portal content',),
},
{'action': 'string:${object_url}/confirmationpage_view',
'category': 'object',
'id': 'view',
'name': 'View',
'permissions': ('View',),
},
)
Inside the class declaration, this will result in the following code:
actions = my_actions + (
)
Replacing the 'view' action is the corect solution to replace the default view. If the content type is derived from ATCT or uses TemplateMixin, a 'default_view' tagged value should also be added
2006-09-04
Customized Archetypes edit form with only one of the fields
I recently had a need for an "administration screen" for an AT-based content that would give the administrators just one field to edit and following that edit, change the workflow state of that piece of content.
Usually, to limit the fields visible in the edit form, I would give those fields different write permissions. Obviously, in this case this was not possible, so I had to take another path. Easiest way to achieve my goal was something like this:
- Make a copy of the base_edit.cpt and its .metadata file and rename them to something like "workorder_schedule_edit.cpt"
- Edit the new cpt file and change its edit body macro to something like:
<metal:body use-macro="body_macro" >
<metal:block fill-slot="widgets">
<metal:fieldMacro use-macro="python:here.widget('end_date', mode='edit')" />
</metal:block>
</metal:body>
- This would use the body defined in the edit_macros (follow the metal statements for details) and only show the 'end_date' field in the edit form.
- Next, I've changed the metadata file to insert my cpy file there
[actions]
action.success = traverse_to:string:workorder_schedule_content_edit
action.success..form_add = traverse_to:string:add_reference
action.success..cancel = traverse_to:string:go_back
action.failure = traverse_to:string:workorder_schedule_edit
From here onward things are easy. Add workorder_schedule_content_edit.cpy form controler script, and its metadata file to point back to the content_edit file.
2006-09-02
Trying KDE as the main work desktop
Until a year ago, when I had my first hands-on experience with Ubuntu, I was a KDE fan. I still admire the desktop and follow closely the development, but I was so impressed at that time by the uniformity and visual appeal that Gnome, under Ubuntu, offered, that I switched. Recently I found the Gnome desktop to be a bit on the slow on my laptop, so I've tried several lighter window managers. First, my trusted WindowMaker. I totally dig wmaker. But I became too used to a full desktop, and I don't feel that I can waste too much productive time configuring the window menu to be the way I like it, so I gave up on it. Next, I've tried blackbox & fluxbox, which I found to be ugly and quickly abandoned. I've played a bit with e16, as it was one of my old time favourites, but I didn't have the patience to configure it to my liking. So I've installed kde 3.5 and now I'm testing it (one note: I still haven't installed the kubuntu-desktop package, just the kde-desktop).
Impressions so far: first, I had some serious problems with the sound. It worked perfectly in Gnome, but I couldn't get anything from KDE. After I've played several times with various mixers and killed several applications, I got it to work. BUT... there's no support (as far as I could see) for the volume control buttons that my HP Compax NX6125 has. I don't know how to configure kmilo, so that's it. Luckily, I can configure some keyboard shortcuts in amarok's global shortcuts, so it's not all lost.
Amarok seems better in handling online radio streams. Rhythmbox became very unresponsive when the network choked. I still like the simplicity of the Rhythmbox interface better.
Although I spent some time trying to get KDE to look a bit better, it still feels ugly, compared to Gnome. There are a myriad of little things that make Gnome to feel "better integrated" and friendlier to me. On the plus side, KDE seems to be trying harder at integration: Firefox and all the other Gnome applications follow the KDE theme and KControl has several checkboxes to control this. I'm still giving KDE a chance, at least to prove that it works faster and better then Gnome. Also, I'm still using the "heavyweights": Poseidon, Firefox & jEdit, so it all comes down to the desktop environment to improve my workflow. I'll see what the results are in a few days.
2006-09-01
Running Microsoft Word as a Windows service
Apparently, this is not recommended by Microsoft, but they have some pointers on how to achieve this on their website.
- How to configure Office applications to run under the interactive user account
- Considerations for server-side Automation of Office