Search Results: "ag"

7 November 2009

Romain Francoise: Zeya: your music, anywhere


The 0.3 release of Zeya is now available in unstable. If you haven't heard of it, Zeya is a web music player that brings your music to any <audio>-capable browser like Iceweasel/Firefox or Google Chrome, turning your collection into a personal online streaming service, using only Free Software (Zeya is licensed under the Affero GPLv3).

Phil has more details about this release, as you can see I contributed a few new features like a search function (100% client-side) and some performance improvements. It's been great fun hacking on Zeya in this cycle and there's plenty of interesting new stuff to add in the near future; feel free to join the team if you want to contribute!

Bastian Venthur: Bundesverdienstkreuz for Matthias Ettrich

Matthias Ettrich, the founder of KDE earned the Bundesverdienstkreuz (Federal Cross of Merit) last Friday for his engagement in open source. How cool is that? Congratulations Matthias and thank you (and all the others) for the K Desktop Environment!

Stefano Zacchiroli: RC bugs of the week - week 9

RCBW - week #9 Here is this week squashes, by yours truly: This week NMUs have been mostly dominated by Haskell's "ambiguous type variable e" squashing.

Bastian Venthur: Python2.6 Blockers

Today s work: 5 lazy NMUs (thanks again Kumar). Leaves us with only five open python2.6 blockers to fix and a whopping 62 of closed ones.

Sha Liu: Chrome on Debian


I just installed google chrome on Debian. It s really awesome that I can t believe my eyes at first! I found that most sites I visited usually are well displayed in the layout. And the fonts in it are much better than in my iceweasel. From the screenshots down below, I can say that no one could tell I m using Debian instead of Windows xp! Although the linux version of Chrome has been released for a while, I told myself that iceweasel is good enough with my collection of add-ons and Chrome is just another beautiful and fancy browser which doesn t have much more practical value in everyday use. Now I found I m WRONG! Except the "speed boom" on openning and loading web page, the fine layout and its simplicity is really fascinating! I really recommend it to others who still have doubt in Chrome. At least, it offers another good choice of browser to you. If you re interested, you can download it here and installed it with "dpkg -i google-chrome-unstable_current_i386.deb". And voila, you can now enjoy it!
my chrome screenshot 1
chrome my chrome screenshot 2
chrome2 my firefox screenshot
firefox

Daniel Leidert: Good bye Warren,

A tragic loss has hit the open source software community. Warren Lyford DeLano, among other things, open source advocate, scientist and the author of the famous PyMOL molecular visualization system, suddenly passed away at the age of 37. I remember you as a genial, pleasent intelligent guy and software author. It has been a pleasure to work with you. Good bye.

Andrew Pollock: [life] Whirlwind visit to Brisbane

Sarah's Mum is flying her back for the scattering of her grandmother's ashes, and I figured that as this will be her third trip back this year, and she's seen my family more than I have in the last 12 months, I should come as well. So I'm getting my first opportunity to sample V Australia's service. I must say that flying Virgin America to LAX and then transferring to V Australia to fly direct to Brisbane seems like a fairly civilised way to do it. Anything that involves Virgin America is always a delight. My only complaints so far are that the SFO-LAX flight left late, and the check in line for V Australia in LAX was ridiculously slow given it was so short. The time of the flight is pretty good - it leaves LAX at 10:30pm, so hopefully we'll get a semi-decent amount of sleep. It gets into Brisbane at 6:30am on Sunday, so we'll have to try and imitate the living dead for the day. I'm heading back again on Saturday, as I have to be in Dallas next week for the Ubuntu Developer Summit.

6 November 2009

Neil Williams: Successful start . . .

gPDFText was only released yesterday and it's being downloaded three times faster than my next most popular upstream project: drivel. Even nicer, it only took under a month to get to this point - and that includes a string freeze to get four translations for the program output and three for the User Manual (which uses yelp, as usual).

gPDFText is a text editor for GTK+ that opens PDF documents for ebook readers, converts the text contents into plain ASCII text, restores the original paragraphs and removes unwanted line breaks to allow easier zooming on the reader.

Many downloaded PDF files for ebook readers still use the A4 paper type (or letter which is similar in size) and when the PDF is displayed on the ebook reader, the zoom required to display the entire page makes the text too small. Simply exporting the PDF into text causes problems with line wrapping and the various ways that ebook PDFs indicate page headers and footers make it hard to automate the conversion.

gPDFText loads the PDF, extracts the text, reformats the paragraphs into single long lines and then puts the text into a standard GTK+ editor where you can make other adjustments.

On the ebook reader, the plain text file then has no unwanted line breaks and can be zoomed to whatever text size you prefer.

Each reformatting option can be turned off using the gPDFText preferences window.

Spelling support also helps identify areas where the text has not been fully reconstructed.

Debian & Ubuntu - it's waiting in NEW but it should build fine on Squeeze and Jaunty or Karmic. Any feedback, use the wiki. Any bugs, use the Trac tickets. All links available via the SF pages.

Hopefully, the extra interest will produce some more people will join the work to improve it. It's a fairly simple codebase, lots of TODO and FIXME items for new contributors to work on and it's all up to date with GtkBuilder and ready for GTK+3.0. If you are looking for an upstream project, take a look at the SVN and give it a go.

Matt Brubeck: Android 2.0 ships with V8 JavaScript engine

Google has not yet released most of the Android 2.0 source code, but they did publish source for a very small number of components, including a WebKit snapshot. I was very excited to see that the snapshot includes Google's V8 virtual machine! (Previous Android releases used Safari's JavaScriptCore/"SquirrelFish Extreme" VM.) But without the rest of the source tree, there was no way to build and run this on a real Android phone. The SDK includes a binary image that runs only in the qemu-based emulator. Today I got to try out a Motorola Droid. Here is how its browser compares to Android 1.6 on my HTC Dream (Android Dev Phone / T-Mobile G1) in the V8 Benchmark Suite (version 5):
Test Dream Droid Change
Richards 13.5 15.6 16%
DeltaBlue 5.23 12.9 147%
Crypto 13.2 10.9 -17%
RayTrace 10.9 80.1 635%
EarleyBoyer 23.5 74.7 218%
RegExp did not complete 16.5
Splay did not complete did not complete
Some tests (Richards, Crypto) see little or no improvement, while others (DeltaBlue, RayTrace, EarleyBoyer) are dramatically faster. Just for comparison, let's run the same benchmark on Safari 4 (JavaScriptCore) and a Chromium 4 nightly build (V8) on a Mac Pro:
Test Safari Chromium Change
Richards 4103 4640 13%
DeltaBlue 3171 4418 39%
Crypto 3331 3643 9%
RayTrace 3509 6662 90%
EarleyBoyer 4737 7643 61%
RegExp 1268 1187 -6%
Splay 1198 7290 509%
The precise ratios are different, but the same tests that showed the most improvement from Android 1.6 to 2.0 also show the most improvement from Safari to Chrome. Based on this plus the source code snapshot, I'm pretty sure that Android 2.0 is indeed using V8. This is exciting news. It makes Droid the first shipping product I know that uses V8 on an ARM processor, although V8 has included an ARM JIT compiler for some time now. For mobile web developers (like me), it means we're one step closer to having desktop-quality rich web applications on low-power handheld devices. Final thought: Although the Motorola Droid is still 100 times slower than Chromium on a Mac Pro, it's actually faster at some benchmarks than IE8 on a low-end Windows machine, or Firefox 2 on hardware from just a few years ago.

Joachim Breitner: Releasing zpub as Free Software

Earlier this year, my brother and I developed a documentation management server for a small software developing company. They were sick of creating their documentation by sending around Word documents, having to manually merge them, losing changes and not getting a clean, consistent layout.So we created zpub for them: It is based on DocBook and Subversion, and adds a fairly nice web interface to it. Now their work flow is
  1. The editor checks out the DocBook source document via Subversion. With a client like TortoiseSVN, this is possible even for the less tech-savvy editor.
  2. He works on the document using the editor of his choice. We recommended an editor with a proper DocBook mode such as the XMLMind XML Editor or Serna Free, which was recently published as Free Software, to our customer.
  3. When satisfied, he commits his changes via Subversion, adding a comment describing his modifications.
  4. On the server, zpub renders the document in the various output formats (.html, .pdf, .chm), and makes the result available via the web interface. The commit messages are put there, and all previous revisions of the document can still be accessed.
  5. Optionally, an e-mail about the change is sent out to a per-document configurable list of recipients.
  6. Optionally, the documents are rendered with a DRAFT -Watermark on the pages, to avoid leaking wrong revisions to the outside. Only users with extended rights are allowed to release a document, thus causing a version without that watermark to be rendered.
For more details on the feature and usage of zpub, check out the documentation that you can find on the demo instance.We are actually quite satisfied by zpub, and it would be a petty if that was just it. Of course, there are quite a view programs out that that can provide these features plus many more, much more than a company the size of our customer would want to have (or even to worry about). So there is a niche between sending Word documents by mail and buying a very expensive, complicated product where zpub fits in.Being a fan of Free Software myself, and since zpub is based on Free Software, we decided that we want to release zpub itself under a Free License. We chose the EUPL, which is a GPL compatible license created by the European Commission, since our customer comes from a municipal environment. The code is hosted on gitorious now, so if you have a need for zpub, just give it a try.Also, if you run a Free Software project, manage your documentation in DocBook (or want to start to do so) and think that zpub might be a neat idea to allow more documentation writers to contribute, talk to me. I might well offer free hosting in that case. If you are a commercial user, I m still offering hosting (and support or feature development), just not for free any more. Note that the zpub user interface and documentation is currently only available in German.

Steve Kemp: What would you have me do, Stephen?

Things which should exist, but don't yet:
Transparent SQL Cache
Imagine a proxy listening on 127.0.0.1:3306, receiving SQL Queries. Any query that was "SELECT .." could return the result from a local cache for the appropriate table. Any query of the form "UPDATE" or "INSERT" would flush all caches for the table. Should be near-trivial: Hash the incoming query & parameters via SHA1sum to get a unique key then store/lookup results in Memcached. Would it be useful? I think so, but of course it depends on the application and the effort involved.
"Global status"
A single site that would rebroadcast a posted (short) status message to facebook/twitter/your chat client/etc/etc. Hard part would be receiving comments from the sites it re-served to. Scraping statuses from facebook is hard, not sure about twitter.
This concludes my Friday wishlist. ObFilm: Master and Commander

Stefano Zacchiroli: DPKG source v3 stats

graphing DPKG source v3 adoption Given that now we can upload DPKG source v3 packages to the archive, prodded by Lucas and Martin, I've added yet another page to my Debian graph/stats collection: namely stats about DPKG source v3 usage in the archive. This time, I've done even less work than the other pages: Lucas was already providing the actual data via a UDD CGI. So thank him, I'm basically just aggregating/mirroring the graphs for bandwidth reasons. Of course, I've also added the new page to the stats index on wiki.d.o.

Jaldhar Vyas: The Road to Wigan Dpen

3.0 format source packages can now be uploaded to the Debian archive. (Note: despite the title of this post, this is not the "Wig and Pen" format which is 2.0. See dpkg-source(1) for a detailed description of all the source package formats.) I tried converting my libcgi-application-basic-plugin-bundle-perl package with mostly good results. l-a-b-p-b-p is an aggregation of perl modules (in .tar.gz format) from CPAN. There is no upstream, this is a Debian only package. Currently the source looks something like this:
   
build-area/
    libcgi-application-basic-plugin-bundle-perl-0.5/
        debian/
            [all the standard stuff: control, rules, etc.]
        tarballs/
            CGI-Application-Dispatch-2.16.tar.gz
            CGI-Application-Plugin-AutoRunmode-0.16.tar.gz
            CGI-Application-Plugin-ConfigAuto-1.31.tar.gz
            ...
            [rest of modules]
The files in the tarballs directory are unpacked at build time to create the binary package. This works but has all the disadvantages of "tarballs in tarballs." By adding a file called debian/source format with the single line:
   
3.0 (quilt)
...dpkg-source is directed to use that format. Now I can rename each upstream tarball to
   
<package name>_<package version>.orig-<upstream tarball name with .'s replaced by -'s>.tar.gz
...and organize the source like this:
   
build-area/
    libcgi-application-basic-plugin-bundle-perl-0.5/
        debian/
            [all the standard stuff: control, rules, etc.]
    libcgi-application-basic-plugin-bundle-perl_0.5.orig-CGI-Application-Dispatch-2-16.tar.gz
    libcgi-application-basic-plugin-bundle-perl_0.5.orig-CGI-Application-Plugin-AutoRunmode-0-16.tar.gz
    libcgi-application-basic-plugin-bundle-perl_0.5.orig-CGI-Application-Plugin-ConfigAuto-1-31.tar.gz
    ...
    [rest of modules]
    libcgi-application-basic-plugin-bundle-perl.orig.tar.gz
Each module is now a seperate file in the debianized source with MD5sum etc. The only problem I am having is with the last file. libcgi-application-basic-plugin-bundle-perl.orig.tar.gz makes no sense for me because there is no upstream yet dpkg-source insists on it. I can make a dummy easily enough but this is an unnecessary annoyance so I filed bug #554488. Raphael Hertzog responded quickly. He is considering adding a --create-empty-orig option to dpkg-source which would solve the problem nicely.

5 November 2009

Chris Lamb: Confusing bugs

I love bugs that are just confusing and/or break your mental model of how you think the software works. Here is a good example: Given the following HTML in Gecko, what happens when a user clicks the button?
<form method="POST" action="/form-action">
  <a href="/anchor-target">
    <input type="button" value="harro">
  </a>
</form>
GET /anchor-target HTTP/1.1
GET /anchor-target HTTP/1.1
2 GET requests? Okay, perhaps some sort of event bubbling problem; it's relatively common in GUI internals. But what about:
<form method="POST" action="/form-action">
  <a href="/anchor-target">
    <input type="image" src="http://upload.wikimedia.org/wikipedia/en/7/75/LHC5.jpg">
  </a>
</form>
POST /form-action HTTP/1.1
GET /anchor-target HTTP/1.1
GET /anchor-target HTTP/1.1
Wait, this time it POSTs the form and makes 2 GET requests? Answers in a Bugzilla report, thanks.

Martin F. Krafft: This space intentionally left blank

Your favourite pretend-do-no-evil information monopolist appears to have discovered wit: Google leaves space intentionally blank This is part of ongoing design experiments. What should happen is that the message fades out and gives way to the content that used to be there. Some of us continue to oppose JavaScript bling, or use text-mode browsers. In those, it just looks like Google inserted space between the search box and the money-making/legalese stuff at the bottom to be able to declare it intentionally blank. How witty! Apart from that, you cannot fade something else into the space you previously declared intentionally blank . Go Google. Be good!

Tollef Fog Heen: Package workflow

As 3.0 format packages are now allowed into the archive, I am thinking about what I would like the workflow to look like and hoping one of them fits me. For new upstream releases, I am imaginging something like:
  1. New upstream version is released.
  2. git fetch + merge into upstream branch.
  3. Import tarballs, preferably in their original format (bz2/gzip), using pristine-tar.
  4. Merge upstream to debian branch. Do necessary fixups and adjustments. At this point, the upstream..debian branch delta is what I want to apply to the upstream release. The reason I need to apply this delta is so I get all generated files into the package that's built and uploaded.
  5. The source package has two functions at this point: Be a starting point for further hacking; and be the source that buildds use to build the binary Debian packages. For the former, I need the git repository itself. It is increasingly my preferred form of modification and so I consider it part of the source. For the latter, it might be easiest just to ship the orig.tar. gz,bz2 and the upstream..debian delta. This does require the upstream..debian delta not to change any generated files, which I think is a fair requirement.
I'm not actually sure which source format can give me this. I think maybe the 3.0 (git) format can, but I haven't played around with it enough to see. I also don't know if any tools actually support this workflow.

Eddy Petri&#537;or: Know your rights!

It is only a few days since my last post about the referendum which is due to happen on the same day as the Presidential elections, but I am forced to make another post because there are lots of incorrect views on the subject.

So let's try take the issues one by one and see what is the problem with every one of them, using reason and the information we have available from more mature democracies than Romania's.

What's the referendum about

The referendum, in this case, is about two issues:

Information on the subject

For an election such as the referendum (basically asking the population on a subject of national importance) every citizen has the right to be correctly informed about the options of the referendum, what each implies, what are the pros and cons for every option, what problems does the referendum tries to resolve.

There is no information on the subject, no videos, no spots, no fliers, nothing, just biased posters (I'll explain later).

Debate on the subject

In order to have a correct information, a clear public debate which should happen, without the pressure of a presidential campaign at the same time as the debate.


Well, we have no debate, so I guess there is no problem of overlapping (sad, but true), but on the other hand, there is no information on the subject.

Analysis of the options

Now let's analyse the two proposed measures in opposition to the current situation.

  1. reducing the number of representatives
    • pros
      • reducing costs
      • minorities have a bigger influence (they can defend their rights - see comments for explanations)
    • cons
      • easier to corrupt (obtaining a corrupt 5% in a 300 seats parliament is easier than in a 500 seats parliament)
      • minorities have a bigger influence (they are disproportionally powerful, in regard to the population they represent - see comments)
      • absence of a representative with a big vote power could allow passing an abusive law (to pass a regular law there is a need of a majority relative to the number of present representatives, not the total number), but, in a numerous parliament, the absence of a person isn't that risky (other colleagues would be present to stop the abusive initiative)
  2. one chamber instead of two
    • pros
      • faster processing of decisions
      • less bureaucratic
    • cons
      • in the current system there can be a passive vote (law passes silently if not discussed) which has just one occasion to be caught, while in the current system silent passing is allowed only in one of the chambers, but needs to be discussed in the other
      • there is a chance that one chamber might amend/catch abusive initiatives with "two chambers", but with "one chamber" there is one chance only
      • more prone to power abuse

So, there are pros and cons for all solutions, but now we can make an informed decision and know the risks for each option.

This shouldn't have been taken in haste without any public debate.


I don't want to influence anyone's vote, so I'll abstain from telling my options.

The president has the right to associate his image with one of the options.

OK, let's analyse that.

The law doesn't explicitly forbids this, but there are some recommendations from Venice on fair elections (sorry, I couldn't find the link) which say that in a vote such as the presidential elections there shouldn't be an unfair advantage for one of the candidates. Why is that relevant? Because the current president actually uses the referendum as his campaign and he's speculating people's innate hatred for political figures.

His election material is only comprised of virulent attacks at the representatives or calls to the population to vote in favour of both questions.


Why is that unfair? Because the current president is using his current position (president) as launch ramp for his campaign as a candidate.

OTOH, if the seal of the presidency was used instead his face, the problem wouldn't have been that bad.


Organisational issues

There were various rumours about how the voting will take place. Here is a list of things I heard:
  1. there will be a single list for both presidential elections and referendum and there will be a single column for signature to confirm your presence at vote
  2. there will be one paper, but two columns for signatures
  3. no matter what the list looks like, you'll be given both sets of ballots, but you can annul the one you don't want to vote on
All the variants above are incorrect from a democratic pov, but to different degrees:

  1. a single signature covering for either of the vaiants "presidential vote only", "refrendum only", "both" asks for trouble because unused ballots in "only" variants might be added later to the valid votes as if they were expressed by voters; since there is no distinct count for each of the ballots to confront that with signatures, before the counting period one could use unused ballots and vote for you on the issue you didn't want to express an opinion on
  2. informing on what to do in some cases such as "only" vote is essential to prevent fraud; e.g.: strike through the cell corresponding to the the election you don't want to express a vote on, instead of signing
  3. giving the ballot unconditionally to everybody, leaving you to decide to annul it or not is abusive, because vote is not compulsory in Romania; more than that, this artificial presence burst (even with void votes) could end up validating the referendum since a 50%+1 presence is needed to pass Constitution modification, as we have here
So, recap:
  1. favours fraud by allowing inside people to obtain untraceable/unaccounted ballots
  2. preventing fraud isn't of any concern, it seems (and could be achieved)
  3. forced voting might lead to validation of the referendum because the voting presence is sufficient, even if there are many annuled ballots
Vote validation and artificial voter presence

Since validation of a referendum on the changes on the constitution depends on sufficient voter presence (there is some mandatory threshold, but I can't find references now), it is in the interest of people wanting to promote the changes to mobilize people to vote.

By different measures the vote presence at the referendum is artificially increased raising the risk of validation, when people, in fact, wouldn't want to validate it and would, to express neutrality, will be be forced to annul the ballot.

Also, a high presence in the referendum might increase the number of voters for presidency, and the people mobilized this way may have a high chance to be biased in favour of the current president because he associates himself with the violent message against the representatives.

What does it take to implement, if referendum passes

If the referendum passes, the changes aren't immediate. The proposed changes are discussed in the Parliament and a final proposal for the constitution changes is made; after approval of the proposals by the Parliament, the ball goes back to population for final approval.

This means it will take a while to see a changed parliament.

Conclusions

Romania is not a true democracy yet and there are areas where individuals should know what their rights are and not let authorities fool them into buying any argument uncritically.

Romanians must learn their rights so they can't be manipulated whenever somebody wants to trick them into some scheme by knowingly omitting issues and creating insane situations.


Romanians, wake up, learn you have rights, form your own oppinion, as distinct individuals, then we might see a change.

4 November 2009

Eugene V. Lyubimkin: cupt-standalone

Some people worried that cupt has a lot of dependencies, so it's uninstallable on very limited systems. I probably have good news for them:


$ dpkg -l grep perl
ii liblocale-gettext-perl 1.05-4 Using libc functions for internationalizatio
ii perl-base 5.10.1-6 minimal Perl system

$ ./cupt-compiled-i386 -s full-upgrade
Building the package cache... [done]
Initializing package resolver and worker... [done]
Scheduling requested actions... [done]
Resolving possible unmet dependencies...
The following 15 packages will be INSTALLED:

dash gnupg-curl insserv install-info libc-bin libc6-i686 libdb4.7 [...]

The following 118 packages will be UPGRADED:

apt apt-utils base-files base-passwd bash bsdmainutils coreutils cpio [...]

Need to get 48.5MiB/56.0MiB of archives. After unpacking 46.7MiB will be used.
Do you want to continue? [y/N/q] q

$ wc -c ./cupt-compiled-i386
3584686 ./cupt-compiled-i386


This is a part of the log from my i386 chroot.

The only extra dependency for the binary is 'libcurl3-gnutls' for downloading from http/https/ftp. It does not need even perl-base to work, but I can't remove perl-base from the system as it's essential.

PAR rocks.

Kartik Mistry: Kavin@School


* This really deserve more than twit , so I am putting it here as NEWS. We selected nearby no-nonsense, no-hype, no-big-fees kind of school running in somewhat 4 BHK kind of bungalow in residential area. He is in Playgroup where primary motive is to interact with others, to learn by monkey business and to learn some good (hopefully) stuffs. I was glad that he did not cried while going to school, but we had to drag him to home and he cried a lot :P Current school timings are 9.30 AM to 11.30 AM, so I must help K and need to wake up early in the morning and probably stop (or reduce) useless hacking till late night. However, I m kind of down due to RCT, Stomach issues and now some pain in shoulder but still alive to write this.

Enrico Zini: Custom function decorators with TurboGears 2

Custom function decorators with TurboGears 2 I am exposing some library functions using a TurboGears2 controller (see web-api-with-turbogears2). It turns out that some functions return a dict, some a list, some a string, and TurboGears 2 only allows JSON serialisation for dicts. A simple work-around for this is to wrap the function result into a dict, something like this:
@expose("json")
@validate(validator_dispatcher, error_handler=api_validation_error)
def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
    # Call API
    res = self.engine.list_colours(filter, productID, maxResults)
    # Return result
    return dict(r=res)
It would be nice, however, to have an @webapi() decorator that automatically wraps the function result with the dict:
def webapi(func):
    def dict_wrap(*args, **kw):
        return dict(r=func(*args, **kw))
    return dict_wrap
# ...in the controller...
    @expose("json")
    @validate(validator_dispatcher, error_handler=api_validation_error)
    @webapi
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)
        # Return result
        return res
This works, as long as @webapi appears last in the list of decorators. This is because if it appears last it will be the first to wrap the function, and so it will not interfere with the tg.decorators machinery. Would it be possible to create a decorator that can be put anywhere among the decorator list? Yes, it is possible but tricky, and it gives me the feeling that it may break in any future version of TurboGears:
class webapi(object):
    def __call__(self, func):
        def dict_wrap(*args, **kw):
            return dict(r=func(*args, **kw))
        # Migrate the decoration attribute to our new function
        if hasattr(func, 'decoration'):
            dict_wrap.decoration = func.decoration
            dict_wrap.decoration.controller = dict_wrap
            delattr(func, 'decoration')
        return dict_wrap
# ...in the controller...
    @expose("json")
    @validate(validator_dispatcher, error_handler=api_validation_error)
    @webapi
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)
        # Return result
        return res
As a convenience, TurboGears 2 offers, in the decorators module, a way to build decorator "hooks":
class before_validate(_hook_decorator):
    '''A list of callables to be run before validation is performed'''
    hook_name = 'before_validate'
class before_call(_hook_decorator):
    '''A list of callables to be run before the controller method is called'''
    hook_name = 'before_call'
class before_render(_hook_decorator):
    '''A list of callables to be run before the template is rendered'''
    hook_name = 'before_render'
class after_render(_hook_decorator):
    '''A list of callables to be run after the template is rendered.

    Will be run before it is returned returned up the WSGI stack'''
    hook_name = 'after_render'
The way these are invoked can be found in the _perform_call function in tg/controllers.py. To show an example use of those hooks, let's add a some polygen wisdom to every data structure we return:
class wisdom(decorators.before_render):
    def __init__(self, grammar):
        super(wisdom, self).__init__(self.add_wisdom)
        self.grammar = grammar
    def add_wisdom(self, remainder, params, output):
        from subprocess import Popen, PIPE
        output["wisdom"] = Popen(["polyrun", self.grammar], stdout=PIPE).communicate()[0]
# ...in the controller...
    @wisdom("genius")
    @expose("json")
    @validate(validator_dispatcher, error_handler=api_validation_error)
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)
        # Return result
        return res
These hooks cannot however be used for what I need, that is, to wrap the result inside a dict. The reason is because they are called in this way:
        controller.decoration.run_hooks(
                'before_render', remainder, params, output)
and not in this way:
        output = controller.decoration.run_hooks(
                'before_render', remainder, params, output)
So it is possible to modify the output (if it is a mutable structure) but not to exchange it with something else. Can we do even better? Sure we can. We can assimilate @expose and @validate inside @webapi to avoid repeating those same many decorator lines over and over again:
class webapi(object):
    def __init__(self, error_handler = None):
        self.error_handler = error_handler
    def __call__(self, func):
        def dict_wrap(*args, **kw):
            return dict(r=func(*args, **kw))
        res = expose("json")(dict_wrap)
        res = validate(validator_dispatcher, error_handler=self.error_handler)(res)
        return res
# ...in the controller...
    @expose("json")
    def api_validation_error(self, **kw):
        pylons.response.status = "400 Error"
        return dict(e="validation error on input fields", form_errors=pylons.c.form_errors)
    @webapi(error_handler=api_validation_error)
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)
        # Return result
        return res
This got rid of @expose and @validate, and provides almost all the default values that I need. Unfortunately I could not find out how to access api_validation_error from the decorator so that I can pass it to the validator, therefore I remain with the inconvenience of having to explicitly pass it every time.

Next.

Previous.