jorgenmodin.net
2010-03-06
Archetypes.schemaextender does not create getters and setters for fields
So if you want to access a field's value you have to do it through the content item's schema:
obj.Schema()['fieldname'].get(obj)
In templates (or more actually, views), this means doing it from the python file in a Zope view.
Nein, ich habe gesagt, dass man mit der """ "get" Methode des fields """ an die Daten kommt -> obj.Schema()['fieldname'].get(obj)
Läs mer: [dzug-zope] Probleme mit archetypes.schemaextender und ReferenceField
2010-03-01
Plone training in London May 4-6
We've been doing Plone Training in London since 2005, but last autumn we were so swamped with consulting work back home that we could not make it. However we now have scheduled a course for May in London. There is going to be more about buildout, subversion and a preview of Plone 4, otherwise steady as she goes.
How to use Edge Side Includes (ESI) with Varnish in Plone
With ESI it is possible to cache the more or less static parts of Plone's pages in Varnish, and "fold in" the dynamic stuff per request. This can in some use cases increase performance massively.
Putting Varnish in front of Plone is a common way to speed up things, and can lead to insane speed increases. However, Plone and Zope are dynamic and tighly coupled frameworks, and it is a bit of a shame to have it serve out essentially static pages. Even if you use something intelligent like CacheSetup (Cache fu), if you make a change that affects a portlet, e.g. "recent comments", you will need to invalidate all pages where that portlet is shown.
Varnish however has support for caching only parts of pages and then fetch the dynamic parts and combine with the static stuff, before serving it out to the visitor. Can Plone be used with it? Yes it can, with some hoop jumping.
The technology of combing pages on the fly is called Edge Side Includes (ESI) and Varnish supports part of the standard. Here is how it works in Varnish:
If you put in a special xml fragment (stanza) like this in your html output:
<esi:include src="/site/@@left_column"/>
...Varnish will fetch the contents of that url (http://yoursite/site/@@left_column), and include it, and replace the stanza with what it finds at that url.
The 123-567.net hobby project
My current hobby project is a salsa dancing web site called 123-567.net. It allows visitors to put together their own salsa dancing routine from short fragments ("Moves"). Moves are connected through positions. It is currently running on our hobby server on the office ADSL connection.
In the right hand column there is a portlet that keeps track of each visitor's routine as it is being built up. No login is required but a captcha tries to keep the salsa dancing away from robots (who suck at dancing anyway, currently, although this may change).
There is one big honking page that lists all moves, and traverses a lot of archetypes references to compute and display all possible moves from each move (and how many moves in its turn can follow each such move). This page basically manages to wake up and excercise every single content object on the site, sometimes multiple times, and the page takes 3-5 seconds to render on a small server. The page cannot be made static, since the contents of the routine portlet will be different for each visitor that uses it.
There are multiple ways of optimizing this page while keeping the portlet dynamic, from RAM-caching with memoize (which brings down the render time of the page to 0.2 s), to using KSS, to using the catalog exclusively for calculating moves.
Memoize seemed like a good solution, but since there are also videos on the site, and I did not want to tie up a Plone process serving each one, I still needed some extra oomph. Varnish should be able to cache the videos and offload Zope's precious processes.
Making the portlet render with ESI
It should be enough to instead of showing the portlet on the page, just show a placeholder for it:
<esi:include src="/site/@@left_column"/>
..and then construct a view by the name "@@left_column" and show the portlet in that view.
Varnish's behavior is controlled by a configuration file, normally called varnish.vcl. The configuration file basically deals with:
- What it should do with requests coming in
- What to do with responses going out
The part of the vcl file that deals with responses is a subroutine called vcl_fetch. Here is a simplified part of that code for 123-567.net, with esi enabled:
sub vcl_fetch {
if (req.url == "/site/@@left_column") {
pass;
}
if (obj.http.Content-Type ~ "html") {
esi; /* Do ESI processing */
unset obj.http.set-cookie;
set obj.ttl = 24 h;
}
The esi directive as framed above enables esi parsing and caching of all html pages, but first the preceding if clause sees to that the @@left_column is passed through without caching ("pass").
The @@left_column view needs to be constructed, and since the portlet is a proper portlet, I could register its page template file also as a viewlet, but a quicker and dirtier way (the "customer" of this project, i.e. me, is very tolerant of whims and shortcuts :-) is to just put in a the entire portlet renderer into the view.
<metal:block use-macro="here/global_defines/macros/defines"/>
<tal:block replace="structure provider:plone.leftcolumn" />
Come to think of it, that may not be quicker... Anyway, now the site renders the page statically but puts in the portlet in varnish. We are down to 50 ms rendering time from 5s rendering time, according to Apache's ab tool (with an empty portlet).
The portlet is context free, it renders the same on all pages. It uses the Zope (not Plone) session machinery and is essentialy independent of Plone, and should render very quickly, if put directly in the view instead of with the above provider stanza. For portlets that need context, one could just put in a cgi parameter in the esi stanza, with the path from the calling page, and then use that to recreate the context on the receiving end.
But now the site is broken without Varnish...
However if we view the site without Varnish the portlet will never materialize on the pages. There will just be stupid esi directive sitting there. I believe it is important that the site can be used without Varnish.
The obvious solution would be this:
<esi:include src="/site/@@left_column">
<--portlet goes here-->
</esi>
One would hope that Varnish would replace the entire esi element. However Varnish is not zpt, and if you put in the above code, Varnish will replace the start tag of the esi element with the portlet, and happily let the rest of the code stay on the page. Viewed through Varnish you would now have two portlets on the page (of which one portlet is stale).
So we need a way for the portlet to "know":
- If it is behind Vanish
- If Varnish has any intentions of caching it
It seems you can find this out from the Plone side! Analyzing the contents of the request variable shows that there is an HTTP_X_VARNISH environment variable which will only be present if varnish is in front. That takes care of displaying the portlet when you are directly accessing Zope. But when behind Varnish, how do we now if we are on the page (ouput ESI tag) or on the specially crafted view (output portlet)? One way is to check for path. The specially crafted view has in its id the string "left_column". Quickly and dirtily we can do it in the page template:
<tal:varnish define= "behind_varnish
python:context.REQUEST.get('HTTP_X_VARNISH',False);
not_cached_in_varnish python: 'left_column' in context.REQUEST['URL0']">
<esi:include src="/site/@@left_column"
tal:condition=
"python:behind_varnish and not not_cached_in_varnish"/>
<tal:portlet condition=
"python: not behind_varnish or not_cached_in_varnish">
[...]
Installing varnish
You can do it with a buildout recipe.
Monitoring varnish
You can use varnishtop and varnishhist, which probably comes if you install Varnish centrally on your machine. However for monitoring the buildout based Varnish we need to specify its name. The buildout recipe does not allow this and I do not think it would work even if it were possible. Instead of the name we supply the path to the name parameter ("-n"), giving the path to to where the buildout's Varnish .vsh directory is.
varnishttop -n absolutepath/to/buildout/parts/varnish-build/var/varnish/
..and then tab complete to the lonely dir in there.
2010-02-27
Making money and helping by investing in Africa
The world economy is shifting away a bit from the "first world", towards countries like China and Brazil, but poorer places in Africa south of Sahara are also starting to get more attention and are deemed to have more potential for growth.
At the same time there is a rather painful insight among many idealists in the developed world that development aid hasn't worked and that in may cases foreign aid has possibly destroyed more than it has helped. For liberals (freedom of the individual, free market) the obvious solution is free trade and strong institutions, and a number of liberals have taken it on themselves to pressure EU and other trading blocks to work in that direction. The results of this work proceeds at a glacial pace.
For socialists these trend towards deregulation and free trade smacks of oppression. I have lost count of the number of debates with socialists I have had about this.
However, if you subscribe to the more liberal (and more correct dare I say) world view of freedom to work and freedom to trade, what can you do as an individual?
The blogger behind Hotel Ivory has taken upon himself (according the blog the blogger wishes to remain anonymous) to in a small way reach the goals of:
- Living the good life
- Do business in a country in west Africa with a violent history and somewhat problematic institutional and legal circumstances.
These goals are hardly unique to the blogger, but it is interesting to follow the analysis and decisions that are taken from a business sense but also liberal perspective. So far the blog has dealt with:
- Whom can you trust?
- Should you invest in the finer areas or more middle-of-the-road areas?
- Analysis of the rental situation in Abidjan
I believe that if thousands (if not millions) of people started doing stuff like this, we should see some pretty strong devlopment all over the world. Problem being of course that these enterprises are fraught with risk. In the nineties, the currency used in the Ivory Coast was devalued by 50%. However as soon as a middle class starts to entrench itself, the virtues of good governance tend to make it into the seats of power. There is just a need to reach that tipping point.
2010-02-18
Switcha över en fil till branch i subversion
1) Skapa en branch, t ex genom att skapa ett bibliotek någonstans på hårddisken och sedan importera det:
jorgen@computer:~$ mkdir jm20091111
jorgen@computer:~$ svn import jm20091111 https://svn.someserver/some.project/branches/
Committed revision 2683.
2) Gå till det bibliotek någonstans din utcheckade trunk, där filen som man vill jobba på i en branch ligger, Och kopiera över filen till branchen:
svn cp trickyModule.py https://svn.someserver/some.
3) Filen på disken på din dator är nu fortfarande i trunk, men man kan switcha över till kopian. Normalt jobbar switch på ett helt bibliotek, men man kan lägga på ett optional andra argument om man bara vill switcha en fil:
svn switch https://svn.someserver/some.
4) Kolla status:
svn st
S trickyModule.py
S betyder väl "switched" får man gissa. Alla ändringar i denna fil blir nu på commit skickade till den nya branchen (har kollat)
2010-02-13
Länk - Eurotopics - nyhetsbevakning av vad som skrivs i europeiska tidningar i kompakt format
Recension: Musik av Ricardo Lemvo
Beväpnad endast med ett Spotify-konto och med skraltig kunskap om salsamusikvärldens artister, var det dags att sätta ihop en kollektion med dansant salsamusik. Efter mer eller mindre kreativa sökningar och ett antal genomlyssningar hade dammet lagt sig och av de 40 eller så låtar jag hade valt ut var hälften av Ricardo Lemvo och hans band Makina Loca.
Lemvo gör salsamusik som det är omöjligt att inte bli glad av. Musiken är välproducerad och hela bandet har ett sinne för rytm som gör att en gedigen, närmast muskulös, rytm flödar genom låtarna. Lemvos röst har en tröghet som om hela kroppen måste röra sig i position för att frambringa fraseringen; det är så uppenbart musik att dansa till. När blåssektion kommer in är den snyggt mutad, vilket förutom att det är väldigt vackert gör att man slipper få så hårda ljudstötar från högtalarna på dansgolvet, när blåset kommer in.
Den första låt jag hörde var Africa Havana Paris, som fortfarande efter några dagar är en favorit. Lemvos musik är afrikainfluerad (Lemvo är från DR Kongo med Angolansk bakgrund och bor i Los Angeles i USA), men hans passion är uppenbart kubansk musik.
En ännu mer uptempo-låt är Kasongo Boogaloo, och en lugnare är Serenata Angolano. Lemvo sjunger på en måängd språk. Spanska naturligtvis, men även portugisiska, kikongo och på senaste skivan tydligen även på turkiska.
A long-time fan of Cuban music and traditional salsa as embodied by Johnny Pacheco, Lemvo moved to the USA at age 15 to pursue his studies[1]. His mixture of languages (Spanish, Lingala, Kikongo, French, Portuguese and English) and his keen sense of rhythm made him a favorite of dancers throughout North America, Europe, Latin America, and Africa.
Läs mer: Ricardo Lemvo - Wikipedia, the free encyclopedia
Salsarytm förklarad med hjälp av Java
En sida där man kan examinera och slå av och på clave, conga osv, och lyssna på rersultatet
Salsa music has a complex rhythm. Understanding the rhythm can help you to find the 1 beat or find the 2 beat so that you know when to start dancing. On this page I introduce the most important salsa percussion instruments and explain their common rhythms. You can listen to each instrument as you read about it or combine them in the interactive rhythm player at the end. Each rhythm is "counted in" by six beats to give you the speed.
Läs mer: Salsa Rhythm
2010-02-11
Man-in-the-middle-attack mot alla kortläsare med PIN
Forskare vid universitet i Cambridge har lyckats med att auktorisera köp med 6 olika kreditkort genom att interceptera kommunikationen mellan kort och terminal på ett sådant sätt att terminalen tror att transaktionen autentiserats med korrekt PIN-kod, fast slumpmässig PIN-kod använts.
Felet tycks bero på att man inte särkiljer mellan olika autentiseringssätt, och en man in the middle kan därför blanda så att terminalen tror att en högre autentiseringsgrad (PIN) har använts.
In particular, the terminal can record that a PIN verification has taken place, while the card itself receives a verification message that does not specify that a PIN has been used. The resultant authorisation by the terminal is acc
Läs mer: Chip and PIN is broken, say researchers - ZDNet.co.uk
Bra förklaring här: How the Cambridge chip and PIN attack works - at ZDNet.co.uk
2010-02-09
Run a plone zexp imported into a fresh Data.fs
Summary: You can't. The server will give an error. The trick is to create a bogus site in the new Zope server. This somehow modifies Zope, from what I have read on the Internet, the acl_users folder in the Zope root.
One of my hobby projects was not on our backup bandwagon, so when I accidentally corrupted Data.fs by overwriting it (the tar command is very picky it turns out about not mixing up source and destination file names) I was out of remedies. But luckily enough I had made a "site.zexp" a few days ago by exporting the site from within the Zope ZMI.
So, just delete the old Data.fs completely, start up the server and import the zexp. That works, but you cannot view any pages, you get AttributeError: getGroups . Googling I found a posting by Andreas Jung. Jung doesn't explicitly say it but writes:
Problem solved. The behavior is caused by the stupid expectation of Plone
that the root acl_users folder having been replaced with its own
implementation while creating a new site
...and from there it was possible to deduce that creating a new bogus site from within the ZMI should do the trick. And this can be done after the import.
Recent Comments
2010-03-06 16:18:37
2010-03-06 00:28:40
2010-03-01 15:57:16
2010-03-01 13:12:02
2010-02-27 12:50:44
2010-02-22 17:20:36
2010-02-10 11:39:30
2010-02-10 07:58:00
2010-01-29 22:24:35
2010-01-29 22:17:04