Lucumr CogitationsArmin Ronacher thinkingtag:localhost,2008-02-18/zxa_export:fullZineXA Export2008-02-18T10:06:17Zvessel_theme::blue.cssFalse/adminsqlite://zine.dbvessel_theme300Lucumr CogitationsTruezeml25TrueUTCvesselTrueTrue/tags/authors1/categoriesArmin Ronacher thinkingFalse10localhost1098503af9d94df0a1774a4bac5e3cf3TruedebugcacheFalseennullentrytextzine_sessionTruehttp://localhost:4000/g#YpbBKk9`y<TPD#jB#J>;.b^R9j$j>=^;x:|5F>@_hOw]`n@wzgxaxyrk0qYA$Izine.logFalseHow not to do XMLhttp://lucumr.pocoo.org/cogitations/2008/02/18/how-not-to-do-xml/2008-02-18T10:06:17Z2008-02-18T10:06:17ZArmin Ronacherhow-not-to-do-xmlyesyes2Imagine for the moment there <a href="http://wordpress.org/">was a PHP blog software</a> that has the ability to dump the blog posts into some sort of extended RSS 2 feed and import from there later and probably from a different installation. That's nice, XML is a flexible format and RSS allows extensions via namespaces. Even better, there are XML parsers for all major programming languages and from python working with XML is especially cool because of lxml and element tree. But there is a problem with that...
...that XML, is not XML. It's called WordPress eXtended RSS (WXR) but it's not XML? And why in god's name did nobody notice so far? I mean, WordPress must have an importer for that.
Why it's not XML? It has XML syntax, XML namespace declarations but what doesn't it have? A doctype. What's the problem? It's referencing HTML entities! So step one for parsing: inject an inline DTD that defines those entities. Great fun isn't it? Then it parses. I was happy and finished my work. That XML doesn't have HTML entities is something PHP developers probably don't know and their parser isn't resolving any entities during the parsing process. Or worse, their XML parser expands HTML entites.
But it's worse! I loaded another dump that happened to have some broken HTML in comments (could happen, does happen, thanks broken trackback support). What happens next? THE XML DOESN'T PARSE ANY MORE! Why? Because comments are neither escaped nor marked as CDATA. I wonder why, especially because it's so much easier to handle embedded HTML/XHTML for dumping as cdata and not XML, especially if you are working with PHP.
But WordPress was able to import that.... so I looked at their parser.... <a href="http://trac.wordpress.org/browser/trunk/wp-admin/import/wordpress.php?rev=6870">WORDPRESS PARSES THAT WXR FILE</a> USING REGULAR EXPRESSIONS!!! Argharhgarhghargh. That's not XML what you are doing there, that's nothing. WordPress can't even parse it's own file if you bind the WordPress exporter namespace to a different prefix! WordPress can't handle it's own file if you replace their CDATA foobar against properly escaped stuff. Dammit!
I can't even write a proper exporter using XML tools because what my XML tools generate is not compatible to WordPress. And what tops it all?
Reading that in the #wordpress channel:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="nt"><nickname_deleted> </span>why does it matter what wp's xml format has flaws?
adapt your importer to the flaws
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(irc)><nickname_deleted> why does it matter what wp's xml format has flaws?
adapt your importer to the flaws<PYGMENTS_RAW -->
ARGHARGHARGHARGH. and then the webpage says:
<blockquote>WordPress is a state-of-the-art semantic personal publishing platform with a focus on aesthetics, web standards, and usability.</blockquote>
Without further comments... I lost my faith into standards that moment. Wait a second, I lost it earlier. Still sad.Imagine for the moment there <a href="http://wordpress.org/">was a PHP blog software</a> that has the ability to dump the blog posts into some sort of extended RSS 2 feed and import from there later and probably from a different installation. That's nice, XML is a flexible format and RSS allows extensions via namespaces. Even better, there are XML parsers for all major programming languages and from python working with XML is especially cool because of lxml and element tree. But there is a problem with that...
...that XML, is not XML. It's called WordPress eXtended RSS (WXR) but it's not XML? And why in god's name did nobody notice so far? I mean, WordPress must have an importer for that.
Why it's not XML? It has XML syntax, XML namespace declarations but what doesn't it have? A doctype. What's the problem? It's referencing HTML entities! So step one for parsing: inject an inline DTD that defines those entities. Great fun isn't it? Then it parses. I was happy and finished my work. That XML doesn't have HTML entities is something PHP developers probably don't know and their parser isn't resolving any entities during the parsing process. Or worse, their XML parser expands HTML entites.
But it's worse! I loaded another dump that happened to have some broken HTML in comments (could happen, does happen, thanks broken trackback support). What happens next? THE XML DOESN'T PARSE ANY MORE! Why? Because comments are neither escaped nor marked as CDATA. I wonder why, especially because it's so much easier to handle embedded HTML/XHTML for dumping as cdata and not XML, especially if you are working with PHP.
But WordPress was able to import that.... so I looked at their parser.... <a href="http://trac.wordpress.org/browser/trunk/wp-admin/import/wordpress.php?rev=6870">WORDPRESS PARSES THAT WXR FILE</a> USING REGULAR EXPRESSIONS!!! Argharhgarhghargh. That's not XML what you are doing there, that's nothing. WordPress can't even parse it's own file if you bind the WordPress exporter namespace to a different prefix! WordPress can't handle it's own file if you replace their CDATA foobar against properly escaped stuff. Dammit!
I can't even write a proper exporter using XML tools because what my XML tools generate is not compatible to WordPress. And what tops it all?
Reading that in the #wordpress channel:
ARGHARGHARGHARGH. and then the webpage says:
<blockquote>WordPress is a state-of-the-art semantic personal publishing platform with a focus on aesthetics, web standards, and usability.</blockquote>
Without further comments... I lost my faith into standards that moment. Wait a second, I lost it earlier. Still sad.SQAAAANTAAAABGJvZHlSUwAAAB1JbWFnaW5lIGZvciB0aGUgbW9tZW50IHRoZXJlIEwAA0VTAAAA
AWFMAABNAAFTAAAABGhyZWZTAAAAFWh0dHA6Ly93b3JkcHJlc3Mub3JnL1MAAAAXd2FzIGEgUEhQ
IGJsb2cgc29mdHdhcmVTAAAGTyB0aGF0IGhhcyB0aGUgYWJpbGl0eSB0byBkdW1wIHRoZSBibG9n
IHBvc3RzIGludG8gc29tZSBzb3J0IG9mIGV4dGVuZGVkIFJTUyAyIGZlZWQgYW5kIGltcG9ydCBm
cm9tIHRoZXJlIGxhdGVyIGFuZCBwcm9iYWJseSBmcm9tIGEgZGlmZmVyZW50IGluc3RhbGxhdGlv
bi4gVGhhdCdzIG5pY2UsIFhNTCBpcyBhIGZsZXhpYmxlIGZvcm1hdCBhbmQgUlNTIGFsbG93cyBl
eHRlbnNpb25zIHZpYSBuYW1lc3BhY2VzLiBFdmVuIGJldHRlciwgdGhlcmUgYXJlIFhNTCBwYXJz
ZXJzIGZvciBhbGwgbWFqb3IgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzIGFuZCBmcm9tIHB5dGhvbiB3
b3JraW5nIHdpdGggWE1MIGlzIGVzcGVjaWFsbHkgY29vbCBiZWNhdXNlIG9mIGx4bWwgYW5kIGVs
ZW1lbnQgdHJlZS4gQnV0IHRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoYXQuLi4KCi4uLnRoYXQg
WE1MLCBpcyBub3QgWE1MLiBJdCdzIGNhbGxlZCBXb3JkUHJlc3MgZVh0ZW5kZWQgUlNTIChXWFIp
IGJ1dCBpdCdzIG5vdCBYTUw/IEFuZCB3aHkgaW4gZ29kJ3MgbmFtZSBkaWQgbm9ib2R5IG5vdGlj
ZSBzbyBmYXI/IEkgbWVhbiwgV29yZFByZXNzIG11c3QgaGF2ZSBhbiBpbXBvcnRlciBmb3IgdGhh
dC4KCldoeSBpdCdzIG5vdCBYTUw/IEl0IGhhcyBYTUwgc3ludGF4LCBYTUwgbmFtZXNwYWNlIGRl
Y2xhcmF0aW9ucyBidXQgd2hhdCBkb2Vzbid0IGl0IGhhdmU/IEEgZG9jdHlwZS4gV2hhdCdzIHRo
ZSBwcm9ibGVtPyBJdCdzIHJlZmVyZW5jaW5nIEhUTUwgZW50aXRpZXMhIFNvIHN0ZXAgb25lIGZv
ciBwYXJzaW5nOiBpbmplY3QgYW4gaW5saW5lIERURCB0aGF0IGRlZmluZXMgdGhvc2UgZW50aXRp
ZXMuIEdyZWF0IGZ1biBpc24ndCBpdD8gVGhlbiBpdCBwYXJzZXMuIEkgd2FzIGhhcHB5IGFuZCBm
aW5pc2hlZCBteSB3b3JrLiBUaGF0IFhNTCBkb2Vzbid0IGhhdmUgSFRNTCBlbnRpdGllcyBpcyBz
b21ldGhpbmcgUEhQIGRldmVsb3BlcnMgcHJvYmFibHkgZG9uJ3Qga25vdyBhbmQgdGhlaXIgcGFy
c2VyIGlzbid0IHJlc29sdmluZyBhbnkgZW50aXRpZXMgZHVyaW5nIHRoZSBwYXJzaW5nIHByb2Nl
c3MuIE9yIHdvcnNlLCB0aGVpciBYTUwgcGFyc2VyIGV4cGFuZHMgSFRNTCBlbnRpdGVzLgoKQnV0
IGl0J3Mgd29yc2UhIEkgbG9hZGVkIGFub3RoZXIgZHVtcCB0aGF0IGhhcHBlbmVkIHRvIGhhdmUg
c29tZSBicm9rZW4gSFRNTCBpbiBjb21tZW50cyAoY291bGQgaGFwcGVuLCBkb2VzIGhhcHBlbiwg
dGhhbmtzIGJyb2tlbiB0cmFja2JhY2sgc3VwcG9ydCkuIFdoYXQgaGFwcGVucyBuZXh0PyBUSEUg
WE1MIERPRVNOJ1QgUEFSU0UgQU5ZIE1PUkUhIFdoeT8gQmVjYXVzZSBjb21tZW50cyBhcmUgbmVp
dGhlciBlc2NhcGVkIG5vciBtYXJrZWQgYXMgQ0RBVEEuIEkgd29uZGVyIHdoeSwgZXNwZWNpYWxs
eSBiZWNhdXNlIGl0J3Mgc28gbXVjaCBlYXNpZXIgdG8gaGFuZGxlIGVtYmVkZGVkIEhUTUwvWEhU
TUwgZm9yIGR1bXBpbmcgYXMgY2RhdGEgYW5kIG5vdCBYTUwsIGVzcGVjaWFsbHkgaWYgeW91IGFy
ZSB3b3JraW5nIHdpdGggUEhQLgoKQnV0IFdvcmRQcmVzcyB3YXMgYWJsZSB0byBpbXBvcnQgdGhh
dC4uLi4gc28gSSBsb29rZWQgYXQgdGhlaXIgcGFyc2VyLi4uLiBFUwAAAAFhTAAATQABUwAAAARo
cmVmUwAAAE5odHRwOi8vdHJhYy53b3JkcHJlc3Mub3JnL2Jyb3dzZXIvdHJ1bmsvd3AtYWRtaW4v
aW1wb3J0L3dvcmRwcmVzcy5waHA/cmV2PTY4NzBTAAAAHldPUkRQUkVTUyBQQVJTRVMgVEhBVCBX
WFIgRklMRVMAAAIsIFVTSU5HIFJFR1VMQVIgRVhQUkVTU0lPTlMhISEgQXJnaGFyaGdhcmhnaGFy
Z2guIFRoYXQncyBub3QgWE1MIHdoYXQgeW91IGFyZSBkb2luZyB0aGVyZSwgdGhhdCdzIG5vdGhp
bmcuIFdvcmRQcmVzcyBjYW4ndCBldmVuIHBhcnNlIGl0J3Mgb3duIGZpbGUgaWYgeW91IGJpbmQg
dGhlIFdvcmRQcmVzcyBleHBvcnRlciBuYW1lc3BhY2UgdG8gYSBkaWZmZXJlbnQgcHJlZml4ISBX
b3JkUHJlc3MgY2FuJ3QgaGFuZGxlIGl0J3Mgb3duIGZpbGUgaWYgeW91IHJlcGxhY2UgdGhlaXIg
Q0RBVEEgZm9vYmFyIGFnYWluc3QgcHJvcGVybHkgZXNjYXBlZCBzdHVmZi4gRGFtbWl0IQoKSSBj
YW4ndCBldmVuIHdyaXRlIGEgcHJvcGVyIGV4cG9ydGVyIHVzaW5nIFhNTCB0b29scyBiZWNhdXNl
IHdoYXQgbXkgWE1MIHRvb2xzIGdlbmVyYXRlIGlzIG5vdCBjb21wYXRpYmxlIHRvIFdvcmRQcmVz
cy4gQW5kIHdoYXQgdG9wcyBpdCBhbGw/CgpSZWFkaW5nIHRoYXQgaW4gdGhlICN3b3JkcHJlc3Mg
Y2hhbm5lbDoKCkFSR0hBUkdIQVJHSEFSR0guIGFuZCB0aGVuIHRoZSB3ZWJwYWdlIHNheXM6CkVT
AAAACmJsb2NrcXVvdGVMAABNAABTAAAAf1dvcmRQcmVzcyBpcyBhIHN0YXRlLW9mLXRoZS1hcnQg
c2VtYW50aWMgcGVyc29uYWwgcHVibGlzaGluZyBwbGF0Zm9ybSB3aXRoIGEgZm9jdXMgb24gYWVz
dGhldGljcywgd2ViIHN0YW5kYXJkcywgYW5kIHVzYWJpbGl0eS5TAAAAdQpXaXRob3V0IGZ1cnRo
ZXIgY29tbWVudHMuLi4gSSBsb3N0IG15IGZhaXRoIGludG8gc3RhbmRhcmRzIHRoYXQgbW9tZW50
LiBXYWl0IGEgc2Vjb25kLCBJIGxvc3QgaXQgZWFybGllci4gU3RpbGwgc2FkLlMAAAAGcGFyc2Vy
UwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Gustaf Eriksongerikson+comments@gmail.comhttp://gustaf.symbiandiaries.com/weblog/2008-02-18T12:06:28Znono0Those that do not understand XML will be forced to reimplement it badly, using regexps.
To be honest, RSS2.0 is notoriously badly specced, hence Atom. One of the issues is embedded HTML.
At least it's something that's close to XML, try looking at Movable Type's export "format" for something that will sear your soul.Those that do not understand XML will be forced to reimplement it badly, using regexps.
To be honest, RSS2.0 is notoriously badly specced, hence Atom. One of the issues is embedded HTML.
At least it's something that's close to XML, try looking at Movable Type's export "format" for something that will sear your soul.SQAAAAJTAAAABGJvZHlSUwAAAUBUaG9zZSB0aGF0IGRvIG5vdCB1bmRlcnN0YW5kIFhNTCB3aWxs
IGJlIGZvcmNlZCB0byByZWltcGxlbWVudCBpdCBiYWRseSwgdXNpbmcgcmVnZXhwcy4KClRvIGJl
IGhvbmVzdCwgUlNTMi4wIGlzIG5vdG9yaW91c2x5IGJhZGx5IHNwZWNjZWQsIGhlbmNlIEF0b20u
IE9uZSBvZiB0aGUgaXNzdWVzIGlzIGVtYmVkZGVkIEhUTUwuIAoKQXQgbGVhc3QgaXQncyBzb21l
dGhpbmcgdGhhdCdzIGNsb3NlIHRvIFhNTCwgdHJ5IGxvb2tpbmcgYXQgTW92YWJsZSBUeXBlJ3Mg
ZXhwb3J0ICJmb3JtYXQiIGZvciBzb21ldGhpbmcgdGhhdCB3aWxsIHNlYXIgeW91ciBzb3VsLkwA
AFMAAAAGcGFyc2VyUwAAAARodG1s
Mikkel KamstruErlandsenmikkel.kamstrup@gmail.comhttp://grillbar.org2008-02-18T13:35:51Znono0If you try an use a non-sloppy XML parser on something you snooped of the web you are naiive. Atleast, that's what I've learned over the past year.
Even if you pay a data provider for XML data (signed in the contract) you can not expect proper XML (also personal experience). You can yell and scream, complain, and refuse to pay - but in the end your users are waiting. You write that darn sloppy parser and get on with your life.
Sorry - but that is how it is.If you try an use a non-sloppy XML parser on something you snooped of the web you are naiive. Atleast, that's what I've learned over the past year.
Even if you pay a data provider for XML data (signed in the contract) you can not expect proper XML (also personal experience). You can yell and scream, complain, and refuse to pay - but in the end your users are waiting. You write that darn sloppy parser and get on with your life.
Sorry - but that is how it is.SQAAAAJTAAAABGJvZHlSUwAAAc9JZiB5b3UgdHJ5IGFuIHVzZSBhIG5vbi1zbG9wcHkgWE1MIHBh
cnNlciBvbiBzb21ldGhpbmcgeW91IHNub29wZWQgb2YgdGhlIHdlYiB5b3UgYXJlIG5haWl2ZS4g
QXRsZWFzdCwgdGhhdCdzIHdoYXQgSSd2ZSBsZWFybmVkIG92ZXIgdGhlIHBhc3QgeWVhci4KCkV2
ZW4gaWYgeW91IHBheSBhIGRhdGEgcHJvdmlkZXIgZm9yIFhNTCBkYXRhIChzaWduZWQgaW4gdGhl
IGNvbnRyYWN0KSB5b3UgY2FuIG5vdCBleHBlY3QgcHJvcGVyIFhNTCAoYWxzbyBwZXJzb25hbCBl
eHBlcmllbmNlKS4gWW91IGNhbiB5ZWxsIGFuZCBzY3JlYW0sIGNvbXBsYWluLCBhbmQgcmVmdXNl
IHRvIHBheSAtIGJ1dCBpbiB0aGUgZW5kIHlvdXIgdXNlcnMgYXJlIHdhaXRpbmcuIFlvdSB3cml0
ZSB0aGF0IGRhcm4gc2xvcHB5IHBhcnNlciBhbmQgZ2V0IG9uIHdpdGggeW91ciBsaWZlLgoKU29y
cnkgLSBidXQgdGhhdCBpcyBob3cgaXQgaXMuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Florianpyalot@gmail.com2008-02-18T13:53:08Znono0php software, what do you expect?php software, what do you expect?SQAAAAJTAAAABGJvZHlSUwAAACFwaHAgc29mdHdhcmUsIHdoYXQgZG8geW91IGV4cGVjdD9MAABT
AAAABnBhcnNlclMAAAAEaHRtbA==
Meneer RRalf.Nieuwenhuijsen@gmail.com2008-02-18T15:09:34Znono0The real reason for this is that XML is so difficult to map onto most programming languages. The datatypes you end up working with are usually complicated.
It seems designed without any knowledge of programming languages and the common ADT's. I tend to use json for machiene-talk (when I get to program both the client and server). It maps nicely onto most programming languages.
Ways XML is abused:
1) people treat it like XHTML (cause: the default escaping in XML sucks, example: RSS)
2) people map another structure onto XML (cause: its a syntactic not a semantic spec, it does not tell a programming language which types correspond to the parsed string, example: xml-rpc)
3) people use it as a database (cause: they follow the hype, example: rhythmbox, gconf)
People that do not understand XML are doomed to make the mistake of using it. We need a semantic interpretation. Such that a valid XML parser would turn a XML-integer into a signed integer, rather than returning only legal XML-integers as string which are then fed into some utility function of the programming language to be parsed. That utility function may accept a completely domain. Et voila, a nice, almost untraceble creepy bug introduced.
We need a new data-standard. One that also specifies the semantic interpretation of the data. We also need a database-query-language-standard (to replace SQL, another horrible standard) that uses that new data-standard as the communication language. Also it would be nice (read: extremely important) if the data-standard not only included things such as integers, floats, strings, unicode, but also anynimous functions. (off course this requires some sort of minimal programming language model)
The closest thing so far?
Data-standard: JSON,
Query-standard: CouchDB-style-queries
Language-standard: Javascript? Lambda-calculus?
Even javascript is already too complicated to easily create a parser and evaluator for. Perhaps just a lambda calculus? Just enough to communicate a piece of logic as data.
I can't wait to see XML die. It's the wrong solution to the wrong problem.The real reason for this is that XML is so difficult to map onto most programming languages. The datatypes you end up working with are usually complicated.
It seems designed without any knowledge of programming languages and the common ADT's. I tend to use json for machiene-talk (when I get to program both the client and server). It maps nicely onto most programming languages.
Ways XML is abused:
1) people treat it like XHTML (cause: the default escaping in XML sucks, example: RSS)
2) people map another structure onto XML (cause: its a syntactic not a semantic spec, it does not tell a programming language which types correspond to the parsed string, example: xml-rpc)
3) people use it as a database (cause: they follow the hype, example: rhythmbox, gconf)
People that do not understand XML are doomed to make the mistake of using it. We need a semantic interpretation. Such that a valid XML parser would turn a XML-integer into a signed integer, rather than returning only legal XML-integers as string which are then fed into some utility function of the programming language to be parsed. That utility function may accept a completely domain. Et voila, a nice, almost untraceble creepy bug introduced.
We need a new data-standard. One that also specifies the semantic interpretation of the data. We also need a database-query-language-standard (to replace SQL, another horrible standard) that uses that new data-standard as the communication language. Also it would be nice (read: extremely important) if the data-standard not only included things such as integers, floats, strings, unicode, but also anynimous functions. (off course this requires some sort of minimal programming language model)
The closest thing so far?
Data-standard: JSON,
Query-standard: CouchDB-style-queries
Language-standard: Javascript? Lambda-calculus?
Even javascript is already too complicated to easily create a parser and evaluator for. Perhaps just a lambda calculus? Just enough to communicate a piece of logic as data.
I can't wait to see XML die. It's the wrong solution to the wrong problem.SQAAAAJTAAAABGJvZHlSUwAACDtUaGUgcmVhbCByZWFzb24gZm9yIHRoaXMgaXMgdGhhdCBYTUwg
aXMgc28gZGlmZmljdWx0IHRvIG1hcCBvbnRvIG1vc3QgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzLiBU
aGUgZGF0YXR5cGVzIHlvdSBlbmQgdXAgd29ya2luZyB3aXRoIGFyZSB1c3VhbGx5IGNvbXBsaWNh
dGVkLgoKSXQgc2VlbXMgZGVzaWduZWQgd2l0aG91dCBhbnkga25vd2xlZGdlIG9mIHByb2dyYW1t
aW5nIGxhbmd1YWdlcyBhbmQgdGhlIGNvbW1vbiBBRFQncy4gIEkgdGVuZCB0byB1c2UganNvbiBm
b3IgbWFjaGllbmUtdGFsayAod2hlbiBJIGdldCB0byBwcm9ncmFtIGJvdGggdGhlIGNsaWVudCBh
bmQgc2VydmVyKS4gSXQgbWFwcyBuaWNlbHkgb250byBtb3N0IHByb2dyYW1taW5nIGxhbmd1YWdl
cy4KCldheXMgWE1MIGlzIGFidXNlZDoKICAxKSBwZW9wbGUgdHJlYXQgaXQgbGlrZSBYSFRNTCAo
Y2F1c2U6IHRoZSBkZWZhdWx0IGVzY2FwaW5nIGluIFhNTCBzdWNrcywgZXhhbXBsZTogUlNTKQog
IDIpIHBlb3BsZSBtYXAgYW5vdGhlciBzdHJ1Y3R1cmUgb250byBYTUwgKGNhdXNlOiBpdHMgYSBz
eW50YWN0aWMgbm90IGEgc2VtYW50aWMgc3BlYywgaXQgZG9lcyBub3QgdGVsbCBhIHByb2dyYW1t
aW5nIGxhbmd1YWdlIHdoaWNoIHR5cGVzIGNvcnJlc3BvbmQgdG8gdGhlIHBhcnNlZCBzdHJpbmcs
IGV4YW1wbGU6IHhtbC1ycGMpCiAgMykgcGVvcGxlIHVzZSBpdCBhcyBhIGRhdGFiYXNlIChjYXVz
ZTogdGhleSBmb2xsb3cgdGhlIGh5cGUsIGV4YW1wbGU6IHJoeXRobWJveCwgZ2NvbmYpCgpQZW9w
bGUgdGhhdCBkbyBub3QgdW5kZXJzdGFuZCBYTUwgYXJlIGRvb21lZCB0byBtYWtlIHRoZSBtaXN0
YWtlIG9mIHVzaW5nIGl0LiBXZSBuZWVkIGEgc2VtYW50aWMgaW50ZXJwcmV0YXRpb24uIFN1Y2gg
dGhhdCBhIHZhbGlkIFhNTCBwYXJzZXIgd291bGQgdHVybiBhIFhNTC1pbnRlZ2VyIGludG8gYSBz
aWduZWQgaW50ZWdlciwgcmF0aGVyIHRoYW4gcmV0dXJuaW5nIG9ubHkgbGVnYWwgWE1MLWludGVn
ZXJzIGFzIHN0cmluZyB3aGljaCBhcmUgdGhlbiBmZWQgaW50byBzb21lIHV0aWxpdHkgZnVuY3Rp
b24gb2YgdGhlIHByb2dyYW1taW5nIGxhbmd1YWdlIHRvIGJlIHBhcnNlZC4gVGhhdCB1dGlsaXR5
IGZ1bmN0aW9uIG1heSBhY2NlcHQgYSBjb21wbGV0ZWx5IGRvbWFpbi4gRXQgdm9pbGEsIGEgbmlj
ZSwgYWxtb3N0IHVudHJhY2VibGUgY3JlZXB5IGJ1ZyBpbnRyb2R1Y2VkLgoKV2UgbmVlZCBhIG5l
dyBkYXRhLXN0YW5kYXJkLiBPbmUgdGhhdCBhbHNvIHNwZWNpZmllcyB0aGUgc2VtYW50aWMgaW50
ZXJwcmV0YXRpb24gb2YgdGhlIGRhdGEuIFdlIGFsc28gbmVlZCBhIGRhdGFiYXNlLXF1ZXJ5LWxh
bmd1YWdlLXN0YW5kYXJkICh0byByZXBsYWNlIFNRTCwgYW5vdGhlciBob3JyaWJsZSBzdGFuZGFy
ZCkgdGhhdCB1c2VzIHRoYXQgbmV3IGRhdGEtc3RhbmRhcmQgYXMgdGhlIGNvbW11bmljYXRpb24g
bGFuZ3VhZ2UuIEFsc28gaXQgd291bGQgYmUgbmljZSAocmVhZDogZXh0cmVtZWx5IGltcG9ydGFu
dCkgaWYgdGhlIGRhdGEtc3RhbmRhcmQgbm90IG9ubHkgaW5jbHVkZWQgdGhpbmdzIHN1Y2ggYXMg
aW50ZWdlcnMsIGZsb2F0cywgc3RyaW5ncywgdW5pY29kZSwgYnV0IGFsc28gYW55bmltb3VzIGZ1
bmN0aW9ucy4gKG9mZiBjb3Vyc2UgdGhpcyByZXF1aXJlcyBzb21lIHNvcnQgb2YgbWluaW1hbCBw
cm9ncmFtbWluZyBsYW5ndWFnZSBtb2RlbCkKClRoZSBjbG9zZXN0IHRoaW5nIHNvIGZhcj8gCiAg
RGF0YS1zdGFuZGFyZDogSlNPTiwKICBRdWVyeS1zdGFuZGFyZDogQ291Y2hEQi1zdHlsZS1xdWVy
aWVzCiAgTGFuZ3VhZ2Utc3RhbmRhcmQ6IEphdmFzY3JpcHQ/IExhbWJkYS1jYWxjdWx1cz8KCkV2
ZW4gamF2YXNjcmlwdCBpcyBhbHJlYWR5IHRvbyBjb21wbGljYXRlZCB0byBlYXNpbHkgY3JlYXRl
IGEgcGFyc2VyIGFuZCBldmFsdWF0b3IgZm9yLiBQZXJoYXBzIGp1c3QgYSBsYW1iZGEgY2FsY3Vs
dXM/IEp1c3QgZW5vdWdoIHRvIGNvbW11bmljYXRlIGEgcGllY2Ugb2YgbG9naWMgYXMgZGF0YS4K
CkkgY2FuJ3Qgd2FpdCB0byBzZWUgWE1MIGRpZS4gSXQncyB0aGUgd3Jvbmcgc29sdXRpb24gdG8g
dGhlIHdyb25nIHByb2JsZW0uTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Shanti Brafordshantibraford@gmail.comhttp://onwebapps.com/2008-02-18T15:17:37Znono0Worse is better =)Worse is better =)SQAAAAJTAAAABGJvZHlSUwAAABJXb3JzZSBpcyBiZXR0ZXIgPSlMAABTAAAABnBhcnNlclMAAAAE
aHRtbA==
Meneer RRalf.Nieuwenhuijsen@gmail.com2008-02-18T15:18:45Znono0Typo, it should have been:
>> That utility function may accept a completely DIFFERENT domain. Et voila, a nice, almost untraceble creepy bug introduced.
I was talking about using a correct XML parser with a correct DOCTYPE that specifies legal integers. Yet the parser will return the legal integer as a STRING. This is not something easily overcome. It is an inherent aspect of the xml specification.
If anything doctypes _only_ are like a parser specification, except you can only specify a subset of all parsers. Other than saying a document is legal, it does not associate any interpretation with the data at all.Typo, it should have been:
>> That utility function may accept a completely DIFFERENT domain. Et voila, a nice, almost untraceble creepy bug introduced.
I was talking about using a correct XML parser with a correct DOCTYPE that specifies legal integers. Yet the parser will return the legal integer as a STRING. This is not something easily overcome. It is an inherent aspect of the xml specification.
If anything doctypes _only_ are like a parser specification, except you can only specify a subset of all parsers. Other than saying a document is legal, it does not associate any interpretation with the data at all.SQAAAAJTAAAABGJvZHlSUwAAAm1UeXBvLCBpdCBzaG91bGQgaGF2ZSBiZWVuOgoKPj4gVGhhdCB1
dGlsaXR5IGZ1bmN0aW9uIG1heSBhY2NlcHQgYSBjb21wbGV0ZWx5IERJRkZFUkVOVCBkb21haW4u
IEV0IHZvaWxhLCBhIG5pY2UsIGFsbW9zdCB1bnRyYWNlYmxlIGNyZWVweSBidWcgaW50cm9kdWNl
ZC4KCkkgd2FzIHRhbGtpbmcgYWJvdXQgdXNpbmcgYSBjb3JyZWN0IFhNTCBwYXJzZXIgd2l0aCBh
IGNvcnJlY3QgRE9DVFlQRSB0aGF0IHNwZWNpZmllcyBsZWdhbCBpbnRlZ2Vycy4gWWV0IHRoZSBw
YXJzZXIgd2lsbCByZXR1cm4gdGhlIGxlZ2FsIGludGVnZXIgYXMgYSBTVFJJTkcuIFRoaXMgaXMg
bm90IHNvbWV0aGluZyBlYXNpbHkgb3ZlcmNvbWUuIEl0IGlzIGFuIGluaGVyZW50IGFzcGVjdCBv
ZiB0aGUgeG1sIHNwZWNpZmljYXRpb24uIAoKSWYgYW55dGhpbmcgZG9jdHlwZXMgX29ubHlfIGFy
ZSBsaWtlIGEgcGFyc2VyIHNwZWNpZmljYXRpb24sIGV4Y2VwdCB5b3UgY2FuIG9ubHkgc3BlY2lm
eSBhIHN1YnNldCBvZiBhbGwgcGFyc2Vycy4gT3RoZXIgdGhhbiBzYXlpbmcgYSBkb2N1bWVudCBp
cyBsZWdhbCwgaXQgZG9lcyBub3QgYXNzb2NpYXRlIGFueSBpbnRlcnByZXRhdGlvbiB3aXRoIHRo
ZSBkYXRhIGF0IGFsbC5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Philluminatiprt_faber@hotmail.com2008-02-18T15:20:02Znono0Gustaf Erikson, please do not abuse or miss reference quotes. The quote originally goes "those who do not understand UNIX are condemned to reimplement it poorly".Gustaf Erikson, please do not abuse or miss reference quotes. The quote originally goes "those who do not understand UNIX are condemned to reimplement it poorly".SQAAAAJTAAAABGJvZHlSUwAAAKJHdXN0YWYgRXJpa3NvbiwgcGxlYXNlIGRvIG5vdCBhYnVzZSBv
ciBtaXNzIHJlZmVyZW5jZSBxdW90ZXMuIFRoZSBxdW90ZSBvcmlnaW5hbGx5IGdvZXMgInRob3Nl
IHdobyBkbyBub3QgdW5kZXJzdGFuZCBVTklYIGFyZSBjb25kZW1uZWQgdG8gcmVpbXBsZW1lbnQg
aXQgcG9vcmx5Ii5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Aliaafshar@gmail.comhttp://unpythonic.blogspot.com/2008-02-18T16:07:09Znono0Use the regular expressions as a cross-language library, they are a feature here!Use the regular expressions as a cross-language library, they are a feature here!SQAAAAJTAAAABGJvZHlSUwAAAFFVc2UgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYXMgYSBjcm9z
cy1sYW5ndWFnZSBsaWJyYXJ5LCB0aGV5IGFyZSBhIGZlYXR1cmUgaGVyZSFMAABTAAAABnBhcnNl
clMAAAAEaHRtbA==
Rudd-Orudd-o@rudd-o.comhttp://rudd-o.com/2008-02-18T16:07:20Znono0This type of moronic attitude favoring sloppiness over correctness is endemic in the WP developers. It explains why WP is always coming up with security vulnerabilities. It explains WP's choice of PHP as a language. It explains a lot.
Have you seen the internal WP machinery? Have you seen how slow it is? Serving a page is comparably slow to Plone, but the difference is Plone does *so much, much more* than WP.This type of moronic attitude favoring sloppiness over correctness is endemic in the WP developers. It explains why WP is always coming up with security vulnerabilities. It explains WP's choice of PHP as a language. It explains a lot.
Have you seen the internal WP machinery? Have you seen how slow it is? Serving a page is comparably slow to Plone, but the difference is Plone does *so much, much more* than WP.SQAAAAJTAAAABGJvZHlSUwAAAaJUaGlzIHR5cGUgb2YgbW9yb25pYyBhdHRpdHVkZSBmYXZvcmlu
ZyBzbG9wcGluZXNzIG92ZXIgY29ycmVjdG5lc3MgaXMgZW5kZW1pYyBpbiB0aGUgV1AgZGV2ZWxv
cGVycy4gIEl0IGV4cGxhaW5zIHdoeSBXUCBpcyBhbHdheXMgY29taW5nIHVwIHdpdGggc2VjdXJp
dHkgdnVsbmVyYWJpbGl0aWVzLiAgSXQgZXhwbGFpbnMgV1AncyBjaG9pY2Ugb2YgUEhQIGFzIGEg
bGFuZ3VhZ2UuICBJdCBleHBsYWlucyBhIGxvdC4KCkhhdmUgeW91IHNlZW4gdGhlIGludGVybmFs
IFdQIG1hY2hpbmVyeT8gIEhhdmUgeW91IHNlZW4gaG93IHNsb3cgaXQgaXM/ICBTZXJ2aW5nIGEg
cGFnZSBpcyBjb21wYXJhYmx5IHNsb3cgdG8gUGxvbmUsIGJ1dCB0aGUgZGlmZmVyZW5jZSBpcyBQ
bG9uZSBkb2VzICpzbyBtdWNoLCBtdWNoIG1vcmUqIHRoYW4gV1AuTAAAUwAAAAZwYXJzZXJTAAAA
BGh0bWw=
Gustaf Eriksongerikson+comments@gmail.comhttp://gustaf.symbiandiaries.com/weblog/2008-02-18T16:22:22Znono0@Philluminati: I'm quite aware of the source and provenance of the quote you mention, I was paraphrasing it in a humorous way :)@Philluminati: I'm quite aware of the source and provenance of the quote you mention, I was paraphrasing it in a humorous way :)SQAAAAJTAAAABGJvZHlSUwAAAIBAUGhpbGx1bWluYXRpOiBJJ20gcXVpdGUgYXdhcmUgb2YgdGhl
IHNvdXJjZSBhbmQgcHJvdmVuYW5jZSBvZiB0aGUgcXVvdGUgeW91IG1lbnRpb24sIEkgd2FzIHBh
cmFwaHJhc2luZyBpdCBpbiBhIGh1bW9yb3VzIHdheSA6KUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
mridkashmrid_kash@yahoo.co.in2008-02-18T16:49:07Znono0@Meneer R
"3) people use it as a database (cause: they follow the hype, example: rhythmbox, gconf)"
I didn't get you. Please explain.
As I know XML is generally used for storage of data. And w3c website says,
"XML was designed to transport and store data." Link: http://www.w3schools.com/xml/default.asp@Meneer R
"3) people use it as a database (cause: they follow the hype, example: rhythmbox, gconf)"
I didn't get you. Please explain.
As I know XML is generally used for storage of data. And w3c website says,
"XML was designed to transport and store data." Link: http://www.w3schools.com/xml/default.aspSQAAAAJTAAAABGJvZHlSUwAAATFATWVuZWVyIFIgCiIzKSBwZW9wbGUgdXNlIGl0IGFzIGEgZGF0
YWJhc2UgKGNhdXNlOiB0aGV5IGZvbGxvdyB0aGUgaHlwZSwgZXhhbXBsZTogcmh5dGhtYm94LCBn
Y29uZikiCgpJIGRpZG4ndCBnZXQgeW91LiBQbGVhc2UgZXhwbGFpbi4KQXMgSSBrbm93IFhNTCBp
cyBnZW5lcmFsbHkgdXNlZCBmb3Igc3RvcmFnZSBvZiBkYXRhLiBBbmQgdzNjIHdlYnNpdGUgc2F5
cywKIlhNTCB3YXMgZGVzaWduZWQgdG8gdHJhbnNwb3J0IGFuZCBzdG9yZSBkYXRhLiIgTGluazog
aHR0cDovL3d3dy53M3NjaG9vbHMuY29tL3htbC9kZWZhdWx0LmFzcEwAAFMAAAAGcGFyc2VyUwAA
AARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-02-18T17:52:50Znono0Just to clarify something: I love XML, I just find it very sad that there are very popular applications which just implement it so terrible wrong that it hurts.Just to clarify something: I love XML, I just find it very sad that there are very popular applications which just implement it so terrible wrong that it hurts.SQAAAAJTAAAABGJvZHlSUwAAAKBKdXN0IHRvIGNsYXJpZnkgc29tZXRoaW5nOiBJIGxvdmUgWE1M
LCBJIGp1c3QgZmluZCBpdCB2ZXJ5IHNhZCB0aGF0IHRoZXJlIGFyZSB2ZXJ5IHBvcHVsYXIgYXBw
bGljYXRpb25zIHdoaWNoIGp1c3QgaW1wbGVtZW50IGl0IHNvIHRlcnJpYmxlIHdyb25nIHRoYXQg
aXQgaHVydHMuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Biffbiff@mailinator.com2008-02-18T18:12:35Znono0"Also it would be nice (read: extremely important) if the data-standard not only included things such as integers, floats, strings, unicode, but also anynimous functions."
XML is not, and was never meant to be, a programming language."Also it would be nice (read: extremely important) if the data-standard not only included things such as integers, floats, strings, unicode, but also anynimous functions."
XML is not, and was never meant to be, a programming language.SQAAAAJTAAAABGJvZHlSUwAAAOsiQWxzbyBpdCB3b3VsZCBiZSBuaWNlIChyZWFkOiBleHRyZW1l
bHkgaW1wb3J0YW50KSBpZiB0aGUgZGF0YS1zdGFuZGFyZCBub3Qgb25seSBpbmNsdWRlZCB0aGlu
Z3Mgc3VjaCBhcyBpbnRlZ2VycywgZmxvYXRzLCBzdHJpbmdzLCB1bmljb2RlLCBidXQgYWxzbyBh
bnluaW1vdXMgZnVuY3Rpb25zLiIKClhNTCBpcyBub3QsIGFuZCB3YXMgbmV2ZXIgbWVhbnQgdG8g
YmUsIGEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Ronny Pfannschmidtronny.pfannschmidt@gmx.de2008-02-18T18:14:08Znono0@Meneer R
if you want lambda calculus - lisp has been there since ages - its parsable darn easy, and one of the most neat languages out there (simply cause its so extensible)@Meneer R
if you want lambda calculus - lisp has been there since ages - its parsable darn easy, and one of the most neat languages out there (simply cause its so extensible)SQAAAAJTAAAABGJvZHlSUwAAAK5ATWVuZWVyIFIKaWYgeW91IHdhbnQgbGFtYmRhIGNhbGN1bHVz
IC0gbGlzcCBoYXMgYmVlbiB0aGVyZSBzaW5jZSBhZ2VzIC0gaXRzIHBhcnNhYmxlIGRhcm4gZWFz
eSwgYW5kIG9uZSBvZiB0aGUgbW9zdCBuZWF0IGxhbmd1YWdlcyBvdXQgdGhlcmUgKHNpbXBseSBj
YXVzZSBpdHMgc28gZXh0ZW5zaWJsZSlMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
TextPress Development Blog Onlinehttp://lucumr.pocoo.org/cogitations/2008/02/16/textpress-development-blog-online/2008-02-16T14:38:34Z2008-02-16T14:38:34ZArmin Ronachertextpress-development-blog-onlineyesyes2TextPress has now a dedicated <a href="http://textpress.pocoo.org/">development blog</a>. That means two things. For one development on TextPress is active again and we are looking for help on converters, missing extensions (especially ATOM publishing support) and more.
That development blog is of course running on TextPress ;-)TextPress has now a dedicated <a href="http://textpress.pocoo.org/">development blog</a>. That means two things. For one development on TextPress is active again and we are looking for help on converters, missing extensions (especially ATOM publishing support) and more.
That development blog is of course running on TextPress ;-)SQAAAANTAAAABGJvZHlSUwAAAB5UZXh0UHJlc3MgaGFzIG5vdyBhIGRlZGljYXRlZCBMAAFFUwAA
AAFhTAAATQABUwAAAARocmVmUwAAABtodHRwOi8vdGV4dHByZXNzLnBvY29vLm9yZy9TAAAAEGRl
dmVsb3BtZW50IGJsb2dTAAAA8y4gVGhhdCBtZWFucyB0d28gdGhpbmdzLiBGb3Igb25lIGRldmVs
b3BtZW50IG9uIFRleHRQcmVzcyBpcyBhY3RpdmUgYWdhaW4gYW5kIHdlIGFyZSBsb29raW5nIGZv
ciBoZWxwIG9uIGNvbnZlcnRlcnMsIG1pc3NpbmcgZXh0ZW5zaW9ucyAoZXNwZWNpYWxseSBBVE9N
IHB1Ymxpc2hpbmcgc3VwcG9ydCkgYW5kIG1vcmUuCgpUaGF0IGRldmVsb3BtZW50IGJsb2cgaXMg
b2YgY291cnNlIHJ1bm5pbmcgb24gVGV4dFByZXNzIDstKVMAAAAGcGFyc2VyUwAAAARodG1sUwAA
AAVpbnRyb1JTAAAAAEwAAA==
GHRML — Haml for Genshihttp://lucumr.pocoo.org/cogitations/2008/02/15/ghrml-haml-for-genshi/2008-02-15T22:34:03Z2008-02-15T22:34:03ZArmin Ronacherghrml-haml-for-genshiyesyes2May I introduce: GHRML, the <strong>G</strong>enshi <strong>H</strong>uman <strong>r</strong>eadable <strong>m</strong>arkup <strong>l</strong>anguage. <small>name not final of course, <a href="http://michael-prokop.at/blog/">mika</a> would kill me ^^</small>.
What's GHRML? First of all it's work in progress. But beside that it's a pretty cool clone of <a href="http://haml.hamptoncatlin.com/">Haml</a> for Python. But no, it's not another templating language, just a different representation for genshi markup templates. This way we can reuse all the genshi features like the directives or serializers. This gives you the full capabilities of the genshi templating language in a nice alternative syntax.
So how does it look like? Here a small example:
<!-- PYGMENTS_CACHE><div class="highlight"><pre>%html
%head
%title Hello World
%style{'type': 'text/css'}
body { font-family: sans-serif; }
%script{'type': 'text/javascript', 'src': 'foo.js'}
%body
#header
%h1 Hello World
%ul.navigation
%li[for item in navigation]
%a{'href': item.href} $item.caption
#contents
Hello World!
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(text)>
%html
%head
%title Hello World
%style{'type': 'text/css'}
body { font-family: sans-serif; }
%script{'type': 'text/javascript', 'src': 'foo.js'}
%body
#header
%h1 Hello World
%ul.navigation
%li[for item in navigation]
%a{'href': item.href} $item.caption
#contents
Hello World!<PYGMENTS_RAW -->
Most of the syntax is directly stolen from <a href="http://haml.hamptoncatlin.com/">Haml</a>. The only real change is that we don't need explicitly marked self closing elements because genshi knows that already in the serializer. Additionally you can use brackets for genshi directives like the for-loop above. And the parser works with variable indentation, if you want an indention level of four, just do so, the parser will recognize that.
Sourcecode in the sandbox for those of you who want to try it, some updates later ;-)May I introduce: GHRML, the <strong>G</strong>enshi <strong>H</strong>uman <strong>r</strong>eadable <strong>m</strong>arkup <strong>l</strong>anguage. <small>name not final of course, <a href="http://michael-prokop.at/blog/">mika</a> would kill me ^^</small>.
What's GHRML? First of all it's work in progress. But beside that it's a pretty cool clone of <a href="http://haml.hamptoncatlin.com/">Haml</a> for Python. But no, it's not another templating language, just a different representation for genshi markup templates. This way we can reuse all the genshi features like the directives or serializers. This gives you the full capabilities of the genshi templating language in a nice alternative syntax.
So how does it look like? Here a small example:
Most of the syntax is directly stolen from <a href="http://haml.hamptoncatlin.com/">Haml</a>. The only real change is that we don't need explicitly marked self closing elements because genshi knows that already in the serializer. Additionally you can use brackets for genshi directives like the for-loop above. And the parser works with variable indentation, if you want an indention level of four, just do so, the parser will recognize that.
Sourcecode in the sandbox for those of you who want to try it, some updates later ;-)SQAAAANTAAAABGJvZHlSUwAAABxNYXkgSSBpbnRyb2R1Y2U6IEdIUk1MLCB0aGUgTAAIRVMAAAAG
c3Ryb25nTAAATQAAUwAAAAFHUwAAAAZlbnNoaSBFUwAAAAZzdHJvbmdMAABNAABTAAAAAUhTAAAA
BXVtYW4gRVMAAAAGc3Ryb25nTAAATQAAUwAAAAFyUwAAAAhlYWRhYmxlIEVTAAAABnN0cm9uZ0wA
AE0AAFMAAAABbVMAAAAGYXJrdXAgRVMAAAAGc3Ryb25nTAAATQAAUwAAAAFsUwAAAAlhbmd1YWdl
LiBFUwAAAAVzbWFsbEwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAHmh0dHA6Ly9taWNoYWVs
LXByb2tvcC5hdC9ibG9nL1MAAAAEbWlrYVMAAAARIHdvdWxkIGtpbGwgbWUgXl5NAABTAAAAGm5h
bWUgbm90IGZpbmFsIG9mIGNvdXJzZSwgUwAAAGEuCgpXaGF0J3MgR0hSTUw/IEZpcnN0IG9mIGFs
bCBpdCdzIHdvcmsgaW4gcHJvZ3Jlc3MuIEJ1dCBiZXNpZGUgdGhhdCBpdCdzIGEgcHJldHR5IGNv
b2wgY2xvbmUgb2YgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAeaHR0cDovL2hhbWwuaGFtcHRv
bmNhdGxpbi5jb20vUwAAAARIYW1sUwAAAY4gZm9yIFB5dGhvbi4gQnV0IG5vLCBpdCdzIG5vdCBh
bm90aGVyIHRlbXBsYXRpbmcgbGFuZ3VhZ2UsIGp1c3QgYSBkaWZmZXJlbnQgcmVwcmVzZW50YXRp
b24gZm9yIGdlbnNoaSBtYXJrdXAgdGVtcGxhdGVzLiBUaGlzIHdheSB3ZSBjYW4gcmV1c2UgYWxs
IHRoZSBnZW5zaGkgZmVhdHVyZXMgbGlrZSB0aGUgZGlyZWN0aXZlcyBvciBzZXJpYWxpemVycy4g
VGhpcyBnaXZlcyB5b3UgdGhlIGZ1bGwgY2FwYWJpbGl0aWVzIG9mIHRoZSBnZW5zaGkgdGVtcGxh
dGluZyBsYW5ndWFnZSBpbiBhIG5pY2UgYWx0ZXJuYXRpdmUgc3ludGF4LgoKU28gaG93IGRvZXMg
aXQgbG9vayBsaWtlPyBIZXJlIGEgc21hbGwgZXhhbXBsZToKCgoKTW9zdCBvZiB0aGUgc3ludGF4
IGlzIGRpcmVjdGx5IHN0b2xlbiBmcm9tIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAHmh0dHA6
Ly9oYW1sLmhhbXB0b25jYXRsaW4uY29tL1MAAAAESGFtbFMAAAG1LiBUaGUgb25seSByZWFsIGNo
YW5nZSBpcyB0aGF0IHdlIGRvbid0IG5lZWQgZXhwbGljaXRseSBtYXJrZWQgc2VsZiBjbG9zaW5n
IGVsZW1lbnRzIGJlY2F1c2UgZ2Vuc2hpIGtub3dzIHRoYXQgYWxyZWFkeSBpbiB0aGUgc2VyaWFs
aXplci4gQWRkaXRpb25hbGx5IHlvdSBjYW4gdXNlIGJyYWNrZXRzIGZvciBnZW5zaGkgZGlyZWN0
aXZlcyBsaWtlIHRoZSBmb3ItbG9vcCBhYm92ZS4gQW5kIHRoZSBwYXJzZXIgd29ya3Mgd2l0aCB2
YXJpYWJsZSBpbmRlbnRhdGlvbiwgaWYgeW91IHdhbnQgYW4gaW5kZW50aW9uIGxldmVsIG9mIGZv
dXIsIGp1c3QgZG8gc28sIHRoZSBwYXJzZXIgd2lsbCByZWNvZ25pemUgdGhhdC4KClNvdXJjZWNv
ZGUgaW4gdGhlIHNhbmRib3ggZm9yIHRob3NlIG9mIHlvdSB3aG8gd2FudCB0byB0cnkgaXQsIHNv
bWUgdXBkYXRlcyBsYXRlciA7LSlTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABM
AAA=
Toothynomail@for.me2008-02-16T01:15:38Znono0Dude, why are you wasting your time with this?
It is ugly, it is inefficient and generating HTML from a silly approximated tag soup that is barely different from HTML is stupid.Dude, why are you wasting your time with this?
It is ugly, it is inefficient and generating HTML from a silly approximated tag soup that is barely different from HTML is stupid.SQAAAAJTAAAABGJvZHlSUwAAALJEdWRlLCB3aHkgYXJlIHlvdSB3YXN0aW5nIHlvdXIgdGltZSB3
aXRoIHRoaXM/CgpJdCBpcyB1Z2x5LCBpdCBpcyBpbmVmZmljaWVudCBhbmQgZ2VuZXJhdGluZyBI
VE1MIGZyb20gYSBzaWxseSBhcHByb3hpbWF0ZWQgdGFnIHNvdXAgdGhhdCBpcyBiYXJlbHkgZGlm
ZmVyZW50IGZyb20gSFRNTCBpcyBzdHVwaWQuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Ronny Pfannschmidtronny.pfannschmidt@gmx.de2008-02-16T10:18:19Znono0great work - its much more pleasant than html/xhtml and gets both correct in the output :)great work - its much more pleasant than html/xhtml and gets both correct in the output :)SQAAAAJTAAAABGJvZHlSUwAAAFpncmVhdCB3b3JrIC0gaXRzIG11Y2ggbW9yZSBwbGVhc2FudCB0
aGFuIGh0bWwveGh0bWwgYW5kIGdldHMgYm90aCBjb3JyZWN0IGluIHRoZSBvdXRwdXQgOilMAABT
AAAABnBhcnNlclMAAAAEaHRtbA==
Waldemar Kornewaldwkornewald@freenet.de2008-02-16T11:29:20Znono0Wonderful! I've been waiting for this *so* long (you know it ;). I hope that soon we can get rid of that redundant HTML markup. Django already makes the underlying Python code more compact. This is the first step towards more compact template code (apart from generic views). Thank a lot!
The next problem areas are CSS and JS (both of which need more than just syntax changes, I'd say).Wonderful! I've been waiting for this *so* long (you know it ;). I hope that soon we can get rid of that redundant HTML markup. Django already makes the underlying Python code more compact. This is the first step towards more compact template code (apart from generic views). Thank a lot!
The next problem areas are CSS and JS (both of which need more than just syntax changes, I'd say).SQAAAAJTAAAABGJvZHlSUwAAAYRXb25kZXJmdWwhIEkndmUgYmVlbiB3YWl0aW5nIGZvciB0aGlz
ICpzbyogbG9uZyAoeW91IGtub3cgaXQgOykuIEkgaG9wZSB0aGF0IHNvb24gd2UgY2FuIGdldCBy
aWQgb2YgdGhhdCByZWR1bmRhbnQgSFRNTCBtYXJrdXAuIERqYW5nbyBhbHJlYWR5IG1ha2VzIHRo
ZSB1bmRlcmx5aW5nIFB5dGhvbiBjb2RlIG1vcmUgY29tcGFjdC4gVGhpcyBpcyB0aGUgZmlyc3Qg
c3RlcCB0b3dhcmRzIG1vcmUgY29tcGFjdCB0ZW1wbGF0ZSBjb2RlIChhcGFydCBmcm9tIGdlbmVy
aWMgdmlld3MpLiBUaGFuayBhIGxvdCEKClRoZSBuZXh0IHByb2JsZW0gYXJlYXMgYXJlIENTUyBh
bmQgSlMgKGJvdGggb2Ygd2hpY2ggbmVlZCBtb3JlIHRoYW4ganVzdCBzeW50YXggY2hhbmdlcywg
SSdkIHNheSkuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Ronny Pfannschmidtronny.pfannschmidt@gmx.de2008-02-18T09:02:51Znono0take a look at clevercss - its in the pocoo sandboxtake a look at clevercss - its in the pocoo sandboxSQAAAAJTAAAABGJvZHlSUwAAADN0YWtlIGEgbG9vayBhdCBjbGV2ZXJjc3MgLSBpdHMgaW4gdGhl
IHBvY29vIHNhbmRib3hMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Meneer RRalf.Nieuwenhuijsen@gmail.com2008-02-18T15:24:18Znono0This looks like ruby.
A fragment for your imagination:
<pre> %li[for item in navigation]
%a{'href': item.href} $item.caption </pre>
woud be:
<pre> navigation.foreach |item| ->
li.do
a {href => item.href} item.caption
end
end</pre>This looks like ruby.
A fragment for your imagination:
<pre> %li[for item in navigation]
%a{'href': item.href} $item.caption </pre>
woud be:
<pre> navigation.foreach |item| ->
li.do
a {href => item.href} item.caption
end
end</pre>SQAAAAJTAAAABGJvZHlSUwAAADpUaGlzIGxvb2tzIGxpa2UgcnVieS4gCgpBIGZyYWdtZW50IGZv
ciB5b3VyIGltYWdpbmF0aW9uOgoKTAACRVMAAAADcHJlTAAATQAAUwAAAEsgICVsaVtmb3IgaXRl
bSBpbiBuYXZpZ2F0aW9uXQogICAgICAgICVheydocmVmJzogaXRlbS5ocmVmfSAkaXRlbS5jYXB0
aW9uICBTAAAADAoKd291ZCBiZToKCkVTAAAAA3ByZUwAAE0AAFMAAABiICBuYXZpZ2F0aW9uLmZv
cmVhY2ggfGl0ZW18IC0+CiAgICAgbGkuZG8KICAgICAgIGEge2hyZWYgPT4gaXRlbS5ocmVmfSBp
dGVtLmNhcHRpb24KICAgICBlbmQKICBlbmRTAAAAAFMAAAAGcGFyc2VyUwAAAARodG1s
Werkzeug 0.2 Released!http://lucumr.pocoo.org/cogitations/2008/02/13/werkzeug-02-released/2008-02-13T23:01:12Z2008-02-13T23:01:12ZArmin Ronacherwerkzeug-02-releasedyesyes2Wohoo. <a href="http://werkzeug.pocoo.org/">Werkzeug</a> 0.2 is out now. Werkzeug started as simple collection of various utilities for WSGI applications and has become one of the most advanced WSGI utility modules. It includes a powerful debugger, full featured request and response objects, HTTP utilities to handle entity tags, cache control headers, HTTP dates, cookie handling, file uploads, a powerful URL routing system and a bunch of community contributed addon modules.
So, what's new in 0.2? Countless things and too many for this small list, but here the most important ones:
<ul>
<li>The path converter limitation is gone. rejoice!</li>
<li>In the contrib package there is now a secure cookie (basically a hashed a client side session storage)</li>
<li>Exceptions can now return response objects so that you can add headers etc.</li>
<li>You can now convert a response object to a different type of response objects on the fly (for example if you have your own response object subclass with special features but the response object returned by a function is a simple BaseResponse)</li>
<li>There are a bunch of extra features for response and request objects now (available as mixin classes) for HTTP header parsing and dumping</li>
<li>All the routing exceptions are now HTTPExceptions which simplifies dispatching a lot</li>
<li>werkzeug.script has a much simpler way of specifying boolean parameters</li>
<li>lazy_property is now called cached_property, update your code!</li>
<li>many cool small helper functions that deal with python modules and packages. There is find_modules which can return a generator for all the modules below a package and import_string which allows you to simply import objects from a string. No more __import__ hackery needed.</li>
<li>the usage of the map adapter is much easier now too and a lot more rest compliant. See the new documentation</li>
<li>dozens of small fixes and additions!</li>
</ul>
There is also a <a href="http://werkzeug.pocoo.org/">new website</a> and <a href="http://werkzeug.pocoo.org/documentation/">documentation</a> and the tutorial was translated to German. For 0.3 we hopefully have some more translations for the tutorial and a better documentation for the contrib modules which are currently just documented in docstrings.
<a href="http://pypi.python.org/pypi/Werkzeug/0.2">Grab it from the cheeseshop</a> while it's hot.Wohoo. <a href="http://werkzeug.pocoo.org/">Werkzeug</a> 0.2 is out now. Werkzeug started as simple collection of various utilities for WSGI applications and has become one of the most advanced WSGI utility modules. It includes a powerful debugger, full featured request and response objects, HTTP utilities to handle entity tags, cache control headers, HTTP dates, cookie handling, file uploads, a powerful URL routing system and a bunch of community contributed addon modules.
So, what's new in 0.2? Countless things and too many for this small list, but here the most important ones:
<ul>
<li>The path converter limitation is gone. rejoice!</li>
<li>In the contrib package there is now a secure cookie (basically a hashed a client side session storage)</li>
<li>Exceptions can now return response objects so that you can add headers etc.</li>
<li>You can now convert a response object to a different type of response objects on the fly (for example if you have your own response object subclass with special features but the response object returned by a function is a simple BaseResponse)</li>
<li>There are a bunch of extra features for response and request objects now (available as mixin classes) for HTTP header parsing and dumping</li>
<li>All the routing exceptions are now HTTPExceptions which simplifies dispatching a lot</li>
<li>werkzeug.script has a much simpler way of specifying boolean parameters</li>
<li>lazy_property is now called cached_property, update your code!</li>
<li>many cool small helper functions that deal with python modules and packages. There is find_modules which can return a generator for all the modules below a package and import_string which allows you to simply import objects from a string. No more __import__ hackery needed.</li>
<li>the usage of the map adapter is much easier now too and a lot more rest compliant. See the new documentation</li>
<li>dozens of small fixes and additions!</li>
</ul>
There is also a <a href="http://werkzeug.pocoo.org/">new website</a> and <a href="http://werkzeug.pocoo.org/documentation/">documentation</a> and the tutorial was translated to German. For 0.3 we hopefully have some more translations for the tutorial and a better documentation for the contrib modules which are currently just documented in docstrings.
<a href="http://pypi.python.org/pypi/Werkzeug/0.2">Grab it from the cheeseshop</a> while it's hot.SQAAAANTAAAABGJvZHlSUwAAAAdXb2hvby4gTAAFRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAa
aHR0cDovL3dlcmt6ZXVnLnBvY29vLm9yZy9TAAAACFdlcmt6ZXVnUwAAAhQgMC4yIGlzIG91dCBu
b3cuIFdlcmt6ZXVnIHN0YXJ0ZWQgYXMgc2ltcGxlIGNvbGxlY3Rpb24gb2YgdmFyaW91cyB1dGls
aXRpZXMgZm9yIFdTR0kgYXBwbGljYXRpb25zIGFuZCBoYXMgYmVjb21lIG9uZSBvZiB0aGUgbW9z
dCBhZHZhbmNlZCBXU0dJIHV0aWxpdHkgbW9kdWxlcy4gSXQgaW5jbHVkZXMgYSBwb3dlcmZ1bCBk
ZWJ1Z2dlciwgZnVsbCBmZWF0dXJlZCByZXF1ZXN0IGFuZCByZXNwb25zZSBvYmplY3RzLCBIVFRQ
IHV0aWxpdGllcyB0byBoYW5kbGUgZW50aXR5IHRhZ3MsIGNhY2hlIGNvbnRyb2wgaGVhZGVycywg
SFRUUCBkYXRlcywgY29va2llIGhhbmRsaW5nLCBmaWxlIHVwbG9hZHMsIGEgcG93ZXJmdWwgVVJM
IHJvdXRpbmcgc3lzdGVtIGFuZCBhIGJ1bmNoIG9mIGNvbW11bml0eSBjb250cmlidXRlZCBhZGRv
biBtb2R1bGVzLgoKU28sIHdoYXQncyBuZXcgaW4gMC4yPyBDb3VudGxlc3MgdGhpbmdzIGFuZCB0
b28gbWFueSBmb3IgdGhpcyBzbWFsbCBsaXN0LCBidXQgaGVyZSB0aGUgbW9zdCBpbXBvcnRhbnQg
b25lczoKRVMAAAACdWxMAAtFUwAAAAJsaUwAAE0AAFMAAAAvVGhlIHBhdGggY29udmVydGVyIGxp
bWl0YXRpb24gaXMgZ29uZS4gcmVqb2ljZSFTAAAAAQpFUwAAAAJsaUwAAE0AAFMAAABmSW4gdGhl
IGNvbnRyaWIgcGFja2FnZSB0aGVyZSBpcyBub3cgYSBzZWN1cmUgY29va2llIChiYXNpY2FsbHkg
YSBoYXNoZWQgYSBjbGllbnQgc2lkZSBzZXNzaW9uIHN0b3JhZ2UpUwAAAAEKRVMAAAACbGlMAABN
AABTAAAAS0V4Y2VwdGlvbnMgY2FuIG5vdyByZXR1cm4gcmVzcG9uc2Ugb2JqZWN0cyBzbyB0aGF0
IHlvdSBjYW4gYWRkIGhlYWRlcnMgZXRjLlMAAAABCkVTAAAAAmxpTAAATQAAUwAAAPJZb3UgY2Fu
IG5vdyBjb252ZXJ0IGEgcmVzcG9uc2Ugb2JqZWN0IHRvIGEgZGlmZmVyZW50IHR5cGUgb2YgcmVz
cG9uc2Ugb2JqZWN0cyBvbiB0aGUgZmx5IChmb3IgZXhhbXBsZSBpZiB5b3UgaGF2ZSB5b3VyIG93
biByZXNwb25zZSBvYmplY3Qgc3ViY2xhc3Mgd2l0aCBzcGVjaWFsIGZlYXR1cmVzIGJ1dCB0aGUg
cmVzcG9uc2Ugb2JqZWN0IHJldHVybmVkIGJ5IGEgZnVuY3Rpb24gaXMgYSBzaW1wbGUgQmFzZVJl
c3BvbnNlKVMAAAABCkVTAAAAAmxpTAAATQAAUwAAAIlUaGVyZSBhcmUgYSBidW5jaCBvZiBleHRy
YSBmZWF0dXJlcyBmb3IgcmVzcG9uc2UgYW5kIHJlcXVlc3Qgb2JqZWN0cyBub3cgKGF2YWlsYWJs
ZSBhcyBtaXhpbiBjbGFzc2VzKSBmb3IgSFRUUCBoZWFkZXIgcGFyc2luZyBhbmQgZHVtcGluZ1MA
AAABCkVTAAAAAmxpTAAATQAAUwAAAFRBbGwgdGhlIHJvdXRpbmcgZXhjZXB0aW9ucyBhcmUgbm93
IEhUVFBFeGNlcHRpb25zIHdoaWNoIHNpbXBsaWZpZXMgZGlzcGF0Y2hpbmcgYSBsb3RTAAAAAQpF
UwAAAAJsaUwAAE0AAFMAAABHd2Vya3pldWcuc2NyaXB0IGhhcyBhIG11Y2ggc2ltcGxlciB3YXkg
b2Ygc3BlY2lmeWluZyBib29sZWFuIHBhcmFtZXRlcnNTAAAAAQpFUwAAAAJsaUwAAE0AAFMAAAA+
bGF6eV9wcm9wZXJ0eSBpcyBub3cgY2FsbGVkIGNhY2hlZF9wcm9wZXJ0eSwgdXBkYXRlIHlvdXIg
Y29kZSFTAAAAAQpFUwAAAAJsaUwAAE0AAFMAAAERbWFueSBjb29sIHNtYWxsIGhlbHBlciBmdW5j
dGlvbnMgdGhhdCBkZWFsIHdpdGggcHl0aG9uIG1vZHVsZXMgYW5kIHBhY2thZ2VzLiBUaGVyZSBp
cyBmaW5kX21vZHVsZXMgd2hpY2ggY2FuIHJldHVybiBhIGdlbmVyYXRvciBmb3IgYWxsIHRoZSBt
b2R1bGVzIGJlbG93IGEgcGFja2FnZSBhbmQgaW1wb3J0X3N0cmluZyB3aGljaCBhbGxvd3MgeW91
IHRvIHNpbXBseSBpbXBvcnQgb2JqZWN0cyBmcm9tIGEgc3RyaW5nLiBObyBtb3JlIF9faW1wb3J0
X18gaGFja2VyeSBuZWVkZWQuUwAAAAEKRVMAAAACbGlMAABNAABTAAAAbHRoZSB1c2FnZSBvZiB0
aGUgbWFwIGFkYXB0ZXIgaXMgbXVjaCBlYXNpZXIgbm93IHRvbyBhbmQgYSBsb3QgbW9yZSByZXN0
IGNvbXBsaWFudC4gU2VlIHRoZSBuZXcgZG9jdW1lbnRhdGlvblMAAAABCkVTAAAAAmxpTAAATQAA
UwAAACRkb3plbnMgb2Ygc21hbGwgZml4ZXMgYW5kIGFkZGl0aW9ucyFTAAAAAQpNAABTAAAAAQpT
AAAAEgoKVGhlcmUgaXMgYWxzbyBhIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAGmh0dHA6Ly93
ZXJremV1Zy5wb2Nvby5vcmcvUwAAAAtuZXcgd2Vic2l0ZVMAAAAFIGFuZCBFUwAAAAFhTAAATQAB
UwAAAARocmVmUwAAAChodHRwOi8vd2Vya3pldWcucG9jb28ub3JnL2RvY3VtZW50YXRpb24vUwAA
AA1kb2N1bWVudGF0aW9uUwAAANUgYW5kIHRoZSB0dXRvcmlhbCB3YXMgdHJhbnNsYXRlZCB0byBH
ZXJtYW4uIEZvciAwLjMgd2UgaG9wZWZ1bGx5IGhhdmUgc29tZSBtb3JlIHRyYW5zbGF0aW9ucyBm
b3IgdGhlIHR1dG9yaWFsIGFuZCBhIGJldHRlciBkb2N1bWVudGF0aW9uIGZvciB0aGUgY29udHJp
YiBtb2R1bGVzIHdoaWNoIGFyZSBjdXJyZW50bHkganVzdCBkb2N1bWVudGVkIGluIGRvY3N0cmlu
Z3MuCgpFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAChodHRwOi8vcHlwaS5weXRob24ub3JnL3B5
cGkvV2Vya3pldWcvMC4yUwAAABtHcmFiIGl0IGZyb20gdGhlIGNoZWVzZXNob3BTAAAAECB3aGls
ZSBpdCdzIGhvdC5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Ronny Pfannschmidtronny.pfannschmidt@gmx.de2008-02-13T23:07:36Znono0sweet - thanks for the good worksweet - thanks for the good workSQAAAAJTAAAABGJvZHlSUwAAACBzd2VldCAtIHRoYW5rcyBmb3IgdGhlIGdvb2Qgd29ya0wAAFMA
AAAGcGFyc2VyUwAAAARodG1s
Stuff you should buyhttp://lucumr.pocoo.org/cogitations/2008/02/13/stuff-you-should-buy/2008-02-13T17:47:03Z2008-02-13T17:47:03ZArmin Ronacherstuff-you-should-buyyesyes2The "Falco Symphonic" DVD. I know Falco is hyped currently here in Austria because that month ten years back he died (damn, I'm getting old) but the DVD is really worth it. For those of you who don't know the story behind that DVD here a small summary:
1994 Falco gave a concert with an orchestra. However the only record of that concert was a already (and bad mixed) tape from three cameras and a DAT tape directly from the mixer unit with the same quality. Because it was the only concert of that kind from Falco the band decided to record the instruments again and mix the original voice back into the new record. And the result is great. They even managed to get some records by fans so there are multiple angles for some scenes now.
Great piece of music history and a brilliant production. Small hint: the CD features a different recording thatn the DVD, the DVD has eh live recording of the voice whereas the CD has a different arrangement of the instruments and Falco's voice from the studio recordings.
Yes, it's not a real live version because the instruments are recorded in the studio afterwards but the impression is great. And in the studio the same musicians play and it's the only chance for us to get such a great recording in that quality so I think it's perfectly okay to listen to that ;-)The "Falco Symphonic" DVD. I know Falco is hyped currently here in Austria because that month ten years back he died (damn, I'm getting old) but the DVD is really worth it. For those of you who don't know the story behind that DVD here a small summary:
1994 Falco gave a concert with an orchestra. However the only record of that concert was a already (and bad mixed) tape from three cameras and a DAT tape directly from the mixer unit with the same quality. Because it was the only concert of that kind from Falco the band decided to record the instruments again and mix the original voice back into the new record. And the result is great. They even managed to get some records by fans so there are multiple angles for some scenes now.
Great piece of music history and a brilliant production. Small hint: the CD features a different recording thatn the DVD, the DVD has eh live recording of the voice whereas the CD has a different arrangement of the instruments and Falco's voice from the studio recordings.
Yes, it's not a real live version because the instruments are recorded in the studio afterwards but the impression is great. And in the studio the same musicians play and it's the only chance for us to get such a great recording in that quality so I think it's perfectly okay to listen to that ;-)SQAAAANTAAAABGJvZHlSUwAABR9UaGUgIkZhbGNvIFN5bXBob25pYyIgRFZELiBJIGtub3cgRmFs
Y28gaXMgaHlwZWQgY3VycmVudGx5IGhlcmUgaW4gQXVzdHJpYSBiZWNhdXNlIHRoYXQgbW9udGgg
dGVuIHllYXJzIGJhY2sgaGUgZGllZCAoZGFtbiwgSSdtIGdldHRpbmcgb2xkKSBidXQgdGhlIERW
RCBpcyByZWFsbHkgd29ydGggaXQuIEZvciB0aG9zZSBvZiB5b3Ugd2hvIGRvbid0IGtub3cgdGhl
IHN0b3J5IGJlaGluZCB0aGF0IERWRCBoZXJlIGEgc21hbGwgc3VtbWFyeToKCjE5OTQgRmFsY28g
Z2F2ZSBhIGNvbmNlcnQgd2l0aCBhbiBvcmNoZXN0cmEuIEhvd2V2ZXIgdGhlIG9ubHkgcmVjb3Jk
IG9mIHRoYXQgY29uY2VydCB3YXMgYSBhbHJlYWR5IChhbmQgYmFkIG1peGVkKSB0YXBlIGZyb20g
dGhyZWUgY2FtZXJhcyBhbmQgYSBEQVQgdGFwZSBkaXJlY3RseSBmcm9tIHRoZSBtaXhlciB1bml0
IHdpdGggdGhlIHNhbWUgcXVhbGl0eS4gQmVjYXVzZSBpdCB3YXMgdGhlIG9ubHkgY29uY2VydCBv
ZiB0aGF0IGtpbmQgZnJvbSBGYWxjbyB0aGUgYmFuZCBkZWNpZGVkIHRvIHJlY29yZCB0aGUgaW5z
dHJ1bWVudHMgYWdhaW4gYW5kIG1peCB0aGUgb3JpZ2luYWwgdm9pY2UgYmFjayBpbnRvIHRoZSBu
ZXcgcmVjb3JkLiBBbmQgdGhlIHJlc3VsdCBpcyBncmVhdC4gVGhleSBldmVuIG1hbmFnZWQgdG8g
Z2V0IHNvbWUgcmVjb3JkcyBieSBmYW5zIHNvIHRoZXJlIGFyZSBtdWx0aXBsZSBhbmdsZXMgZm9y
IHNvbWUgc2NlbmVzIG5vdy4KCkdyZWF0IHBpZWNlIG9mIG11c2ljIGhpc3RvcnkgYW5kIGEgYnJp
bGxpYW50IHByb2R1Y3Rpb24uIFNtYWxsIGhpbnQ6IHRoZSBDRCBmZWF0dXJlcyBhIGRpZmZlcmVu
dCByZWNvcmRpbmcgdGhhdG4gdGhlIERWRCwgdGhlIERWRCBoYXMgZWggbGl2ZSByZWNvcmRpbmcg
b2YgdGhlIHZvaWNlIHdoZXJlYXMgdGhlIENEIGhhcyBhIGRpZmZlcmVudCBhcnJhbmdlbWVudCBv
ZiB0aGUgaW5zdHJ1bWVudHMgYW5kIEZhbGNvJ3Mgdm9pY2UgZnJvbSB0aGUgc3R1ZGlvIHJlY29y
ZGluZ3MuCgpZZXMsIGl0J3Mgbm90IGEgcmVhbCBsaXZlIHZlcnNpb24gYmVjYXVzZSB0aGUgaW5z
dHJ1bWVudHMgYXJlIHJlY29yZGVkIGluIHRoZSBzdHVkaW8gYWZ0ZXJ3YXJkcyBidXQgdGhlIGlt
cHJlc3Npb24gaXMgZ3JlYXQuIEFuZCBpbiB0aGUgc3R1ZGlvIHRoZSBzYW1lIG11c2ljaWFucyBw
bGF5IGFuZCBpdCdzIHRoZSBvbmx5IGNoYW5jZSBmb3IgdXMgdG8gZ2V0IHN1Y2ggYSBncmVhdCBy
ZWNvcmRpbmcgaW4gdGhhdCBxdWFsaXR5IHNvIEkgdGhpbmsgaXQncyBwZXJmZWN0bHkgb2theSB0
byBsaXN0ZW4gdG8gdGhhdCA7LSlMAABTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAA
AABMAAA=
How To Kill a Gamehttp://lucumr.pocoo.org/cogitations/2008/02/09/how-to-kill-a-game/2008-02-09T23:49:48Z2008-02-09T23:49:48ZArmin Ronacherhow-to-kill-a-gameyesyes2<img src="http://pocoo.org/~mitsuhiko/ssw_01.jpeg" class="thumbright" alt="A Söldner Screenshot" />About four years ago I stumbled about a promising game called "<a href="http://www.secretwars.net/">Söldner --- Secret Wars</a>" in a magazine. It was an online tactical shooter and featured a fully destroyable environment, more than one hundred weapons I think, many different vehicles, aircrafts and much more. It was hyped back then in the German gaming community, probably because it was developed by a German studio called "Wings". Long before the game was released the developers updated their online dairy about recent changes in the code, about what the game will feature and a lot more. Unfortunately they decided to release their game by <a href="http://www.jowood.com/">Jowood</a>, an Austrian publisher.
Why was that bad? Back then Jowood once again had financial problems and they tried to solve it by convincing the sharedholders that their next game will be a major success. They set an totally unachievable release date and the developer team at wings had to live with that. It went that far that they had to design the box are themselves even though the game was still buggy. The game was released and was still buggy. I think GameStar even omitted the rating because they wanted to wait for the first patch.
<img src="http://pocoo.org/~mitsuhiko/ssw_02.jpeg" class="thumbleft" alt="A Söldner Screenshot" />However the game sold pretty well the first two weeks despite the bad quality of the release version and the bad reviews. It even outsold the greatest competitor at that time (Joint Operations). I was one of the early adopters and I loved to play it. Owning a bad ISDN connection at that time it was terrible lagging, especially because their netcode was a catastrophe. Still, it was great fun and the destructible environment was great. Not only that, the game was somewhat revolutionary. It was the first online game I played with an (albeit bad configured) physics engine, it used python as scripting language, it had one big map that was generated from satellite images with detailed areas where the fights took place. You could buy yourself a jet and leave the map and visit all off Siberia. Not like Battlefield Vietnam where you hit the borders of the map with a jet after roughly 15 seconds. Dammit, it would still be fun and I bet it would have been bug-less by now.
The community that appeared around that game was incredible. A wiki appeared, people tried to hack around on the code to get extra features into the game, unofficial mods appeared. There was even a project that wanted to create a mod for a medieval setting. Hell, it was great back then. But instead of fixing the bugs Jowood forced the developers to start an addon project...
<img src="http://pocoo.org/~mitsuhiko/ssw_03.jpeg" class="thumbright" alt="A Söldner Screenshot" />Shortly after the addon was finished the company developing that game was liquidated. The developers lost their job and the community continued developing the closed code. The group around "project zero" continued maintaining the game until that group broke apart and the gEasy team took over the work. The gEasy team was basically just the project zero team without the founder. They did an tremendous job but Jowood once again destroyed everything. They refused to pay their bills, then the gEasy team took down the master server and Ivan Ertlov appeared on the scene. He managed to resolve the problems between Jowood and gEasy team to some extend that the master server was up and running again.
Who's that Ivan Ertlov? Very good question indeed and I personally don't know the full story but from what I've read on the forums he is called Johann Ertl and owns a company that sells guerrilla marketing and similar services. And he worked for Jowood and apparently still does, at least he is listed as community manager in the official forums. He also brought up the topic "Open Sourcing" the code after it was clear that there will be no Söldner 2. A sequel was actually under consideration and gEasy started working on that till the day they took down the master server because there was no payment by Jowood. But since some time there was no feedback any more and an open source version is somewhat unlikely.
<img src="http://pocoo.org/~mitsuhiko/ssw_04.jpeg" class="thumbleft" alt="A Söldner Screenshot" />Frankly I don't know if Jowood payed or didn't. What Jowood did was destroying the game by forcing an early release, forcing an addon when the code was still unfinished, fired the developers. Even worse: they are telling their shareholders that everything is working perfectly and that they are releasing dozens of new games. Hell, they released Spellforce 1 and 2 which both are awesome games (just happen to have the worst copy protection ever designed), the Gothic games (the 3rd part was buggy like Söldner but probably also because Jowood forced an early release). Jowood however claims that they payed and that gEasy was lying. Who is running the portal now? Apparently Ivan's company.
So why am I blogging about all that? Mainly because I think that topic hasn't gained a lot of attraction. I stopped playing that game after Wings was liquidated. For one because I switched to ubuntu and on the other hand because my Söldner plugin (an in-game Winamp controller) disappeared when the forum was updated to reflect the new ownership. All the old topics where either deleted or made unreadable when Wings was closed down.
<img src="http://pocoo.org/~mitsuhiko/ssw_05.jpeg" class="thumbright" alt="A Söldner Screenshot" />What nobody really notices is that the game had a tremendous German community. Hell, some of them even took over the development! If Jowood would have noticed that earlier they could have made that game the freaking best online shooter available at that time. But because of their small horizon they just thought about their next quarter and decided to do what shareholders want, not what players want. But not only Jowood is to blame but the root of all evil in that case.
Krawall supported Jowood in the beginning to host their initial infrastructure needed for the game. Unfortunately the server software needed Direct X to run properly which caused a lot of trouble. One the one hand it was hard to get multiple servers running on one machine do to the way the server was designed, on the other hand you needed a windows server to host games. And because the initial code base was that buggy all the magazines flamed to game. Despite the good sales figures it magazines never wrote about the game and forced an early dead which harmed the community. A release six month later, a linux server from the beginning, no addon and good press coverage would have avoided all the problems this game was facing in the past. And it would have saved Wings, the game they were working on beside Söldner, and in the end of course Jowood which would have had a lot less bad press.
Especially the gamers hate Jowood for their buggy products now and I doubt that they will be able to continue to ignore all the user feedback and push alpha versions as release versions for much longer.
I'm especially interested what the Wings guys are doing now. I know that former Wings community manager and sound designed Marc Olbertz is working at Blizzard but that's about it. It's sad what happened there and that Austrian's only game publisher caused all that.
<small><strong>Funky fact:</strong> The communication with the master server worked via jabber, the physics engine was ODE and the scripting language was Python. All open source technologies I never saw in a commercial game before :-)</small>
<small><strong>Disclaimer:</strong> the information on this page should be accurate but it's hard to say for sure because there is few information about this topic actually available. If you are able to understand German you can find some information in this thread on the Söldner forums: <a href="http://www.secretwars.net/forum/showthread.php?t=41591">Söldner ein Abenteuer mit ungewissem Ausgang</a></small><img src="http://pocoo.org/~mitsuhiko/ssw_01.jpeg" alt="A Söldner Screenshot" class="thumbright">About four years ago I stumbled about a promising game called "<a href="http://www.secretwars.net/">Söldner --- Secret Wars</a>" in a magazine. It was an online tactical shooter and featured a fully destroyable environment, more than one hundred weapons I think, many different vehicles, aircrafts and much more. It was hyped back then in the German gaming community, probably because it was developed by a German studio called "Wings". Long before the game was released the developers updated their online dairy about recent changes in the code, about what the game will feature and a lot more. Unfortunately they decided to release their game by <a href="http://www.jowood.com/">Jowood</a>, an Austrian publisher.
Why was that bad? Back then Jowood once again had financial problems and they tried to solve it by convincing the sharedholders that their next game will be a major success. They set an totally unachievable release date and the developer team at wings had to live with that. It went that far that they had to design the box are themselves even though the game was still buggy. The game was released and was still buggy. I think GameStar even omitted the rating because they wanted to wait for the first patch.
<img src="http://pocoo.org/~mitsuhiko/ssw_02.jpeg" alt="A Söldner Screenshot" class="thumbleft">However the game sold pretty well the first two weeks despite the bad quality of the release version and the bad reviews. It even outsold the greatest competitor at that time (Joint Operations). I was one of the early adopters and I loved to play it. Owning a bad ISDN connection at that time it was terrible lagging, especially because their netcode was a catastrophe. Still, it was great fun and the destructible environment was great. Not only that, the game was somewhat revolutionary. It was the first online game I played with an (albeit bad configured) physics engine, it used python as scripting language, it had one big map that was generated from satellite images with detailed areas where the fights took place. You could buy yourself a jet and leave the map and visit all off Siberia. Not like Battlefield Vietnam where you hit the borders of the map with a jet after roughly 15 seconds. Dammit, it would still be fun and I bet it would have been bug-less by now.
The community that appeared around that game was incredible. A wiki appeared, people tried to hack around on the code to get extra features into the game, unofficial mods appeared. There was even a project that wanted to create a mod for a medieval setting. Hell, it was great back then. But instead of fixing the bugs Jowood forced the developers to start an addon project...
<img src="http://pocoo.org/~mitsuhiko/ssw_03.jpeg" alt="A Söldner Screenshot" class="thumbright">Shortly after the addon was finished the company developing that game was liquidated. The developers lost their job and the community continued developing the closed code. The group around "project zero" continued maintaining the game until that group broke apart and the gEasy team took over the work. The gEasy team was basically just the project zero team without the founder. They did an tremendous job but Jowood once again destroyed everything. They refused to pay their bills, then the gEasy team took down the master server and Ivan Ertlov appeared on the scene. He managed to resolve the problems between Jowood and gEasy team to some extend that the master server was up and running again.
Who's that Ivan Ertlov? Very good question indeed and I personally don't know the full story but from what I've read on the forums he is called Johann Ertl and owns a company that sells guerrilla marketing and similar services. And he worked for Jowood and apparently still does, at least he is listed as community manager in the official forums. He also brought up the topic "Open Sourcing" the code after it was clear that there will be no Söldner 2. A sequel was actually under consideration and gEasy started working on that till the day they took down the master server because there was no payment by Jowood. But since some time there was no feedback any more and an open source version is somewhat unlikely.
<img src="http://pocoo.org/~mitsuhiko/ssw_04.jpeg" alt="A Söldner Screenshot" class="thumbleft">Frankly I don't know if Jowood payed or didn't. What Jowood did was destroying the game by forcing an early release, forcing an addon when the code was still unfinished, fired the developers. Even worse: they are telling their shareholders that everything is working perfectly and that they are releasing dozens of new games. Hell, they released Spellforce 1 and 2 which both are awesome games (just happen to have the worst copy protection ever designed), the Gothic games (the 3rd part was buggy like Söldner but probably also because Jowood forced an early release). Jowood however claims that they payed and that gEasy was lying. Who is running the portal now? Apparently Ivan's company.
So why am I blogging about all that? Mainly because I think that topic hasn't gained a lot of attraction. I stopped playing that game after Wings was liquidated. For one because I switched to ubuntu and on the other hand because my Söldner plugin (an in-game Winamp controller) disappeared when the forum was updated to reflect the new ownership. All the old topics where either deleted or made unreadable when Wings was closed down.
<img src="http://pocoo.org/~mitsuhiko/ssw_05.jpeg" alt="A Söldner Screenshot" class="thumbright">What nobody really notices is that the game had a tremendous German community. Hell, some of them even took over the development! If Jowood would have noticed that earlier they could have made that game the freaking best online shooter available at that time. But because of their small horizon they just thought about their next quarter and decided to do what shareholders want, not what players want. But not only Jowood is to blame but the root of all evil in that case.
Krawall supported Jowood in the beginning to host their initial infrastructure needed for the game. Unfortunately the server software needed Direct X to run properly which caused a lot of trouble. One the one hand it was hard to get multiple servers running on one machine do to the way the server was designed, on the other hand you needed a windows server to host games. And because the initial code base was that buggy all the magazines flamed to game. Despite the good sales figures it magazines never wrote about the game and forced an early dead which harmed the community. A release six month later, a linux server from the beginning, no addon and good press coverage would have avoided all the problems this game was facing in the past. And it would have saved Wings, the game they were working on beside Söldner, and in the end of course Jowood which would have had a lot less bad press.
Especially the gamers hate Jowood for their buggy products now and I doubt that they will be able to continue to ignore all the user feedback and push alpha versions as release versions for much longer.
I'm especially interested what the Wings guys are doing now. I know that former Wings community manager and sound designed Marc Olbertz is working at Blizzard but that's about it. It's sad what happened there and that Austrian's only game publisher caused all that.
<small><strong>Funky fact:</strong> The communication with the master server worked via jabber, the physics engine was ODE and the scripting language was Python. All open source technologies I never saw in a commercial game before :-)</small>
<small><strong>Disclaimer:</strong> the information on this page should be accurate but it's hard to say for sure because there is few information about this topic actually available. If you are able to understand German you can find some information in this thread on the Söldner forums: <a href="http://www.secretwars.net/forum/showthread.php?t=41591">Söldner ein Abenteuer mit ungewissem Ausgang</a></small>SQAAAANTAAAABGJvZHlSUwAAAABMAAlFUwAAAANpbWdMAABNAANTAAAAA3NyY1MAAAAnaHR0cDov
L3BvY29vLm9yZy9+bWl0c3VoaWtvL3Nzd18wMS5qcGVnUwAAAANhbHRTAAAAFUEgU8O2bGRuZXIg
U2NyZWVuc2hvdFMAAAAFY2xhc3NTAAAACnRodW1icmlnaHRTAAAAAFMAAAA/QWJvdXQgZm91ciB5
ZWFycyBhZ28gSSBzdHVtYmxlZCBhYm91dCBhIHByb21pc2luZyBnYW1lIGNhbGxlZCAiRVMAAAAB
YUwAAE0AAVMAAAAEaHJlZlMAAAAaaHR0cDovL3d3dy5zZWNyZXR3YXJzLm5ldC9TAAAAGFPDtmxk
bmVyIC0tLSBTZWNyZXQgV2Fyc1MAAAIJIiBpbiBhIG1hZ2F6aW5lLiBJdCB3YXMgYW4gb25saW5l
IHRhY3RpY2FsIHNob290ZXIgYW5kIGZlYXR1cmVkIGEgZnVsbHkgZGVzdHJveWFibGUgZW52aXJv
bm1lbnQsIG1vcmUgdGhhbiBvbmUgaHVuZHJlZCB3ZWFwb25zIEkgdGhpbmssIG1hbnkgZGlmZmVy
ZW50IHZlaGljbGVzLCBhaXJjcmFmdHMgYW5kIG11Y2ggbW9yZS4gSXQgd2FzIGh5cGVkIGJhY2sg
dGhlbiBpbiB0aGUgR2VybWFuIGdhbWluZyBjb21tdW5pdHksIHByb2JhYmx5IGJlY2F1c2UgaXQg
d2FzIGRldmVsb3BlZCBieSBhIEdlcm1hbiBzdHVkaW8gY2FsbGVkICJXaW5ncyIuIExvbmcgYmVm
b3JlIHRoZSBnYW1lIHdhcyByZWxlYXNlZCB0aGUgZGV2ZWxvcGVycyB1cGRhdGVkIHRoZWlyIG9u
bGluZSBkYWlyeSBhYm91dCByZWNlbnQgY2hhbmdlcyBpbiB0aGUgY29kZSwgYWJvdXQgd2hhdCB0
aGUgZ2FtZSB3aWxsIGZlYXR1cmUgYW5kIGEgbG90IG1vcmUuIFVuZm9ydHVuYXRlbHkgdGhleSBk
ZWNpZGVkIHRvIHJlbGVhc2UgdGhlaXIgZ2FtZSBieSBFUwAAAAFhTAAATQABUwAAAARocmVmUwAA
ABZodHRwOi8vd3d3Lmpvd29vZC5jb20vUwAAAAZKb3dvb2RTAAACGSwgYW4gQXVzdHJpYW4gcHVi
bGlzaGVyLgoKV2h5IHdhcyB0aGF0IGJhZD8gQmFjayB0aGVuIEpvd29vZCBvbmNlIGFnYWluIGhh
ZCBmaW5hbmNpYWwgcHJvYmxlbXMgYW5kIHRoZXkgdHJpZWQgdG8gc29sdmUgaXQgYnkgY29udmlu
Y2luZyB0aGUgc2hhcmVkaG9sZGVycyB0aGF0IHRoZWlyIG5leHQgZ2FtZSB3aWxsIGJlIGEgbWFq
b3Igc3VjY2Vzcy4gVGhleSBzZXQgYW4gdG90YWxseSB1bmFjaGlldmFibGUgcmVsZWFzZSBkYXRl
IGFuZCB0aGUgZGV2ZWxvcGVyIHRlYW0gYXQgd2luZ3MgaGFkIHRvIGxpdmUgd2l0aCB0aGF0LiBJ
dCB3ZW50IHRoYXQgZmFyIHRoYXQgdGhleSBoYWQgdG8gZGVzaWduIHRoZSBib3ggYXJlIHRoZW1z
ZWx2ZXMgZXZlbiB0aG91Z2ggdGhlIGdhbWUgd2FzIHN0aWxsIGJ1Z2d5LiBUaGUgZ2FtZSB3YXMg
cmVsZWFzZWQgYW5kIHdhcyBzdGlsbCBidWdneS4gSSB0aGluayBHYW1lU3RhciBldmVuIG9taXR0
ZWQgdGhlIHJhdGluZyBiZWNhdXNlIHRoZXkgd2FudGVkIHRvIHdhaXQgZm9yIHRoZSBmaXJzdCBw
YXRjaC4KCkVTAAAAA2ltZ0wAAE0AA1MAAAADc3JjUwAAACdodHRwOi8vcG9jb28ub3JnL35taXRz
dWhpa28vc3N3XzAyLmpwZWdTAAAAA2FsdFMAAAAVQSBTw7ZsZG5lciBTY3JlZW5zaG90UwAAAAVj
bGFzc1MAAAAJdGh1bWJsZWZ0UwAAAABTAAAFS0hvd2V2ZXIgdGhlIGdhbWUgc29sZCBwcmV0dHkg
d2VsbCB0aGUgZmlyc3QgdHdvIHdlZWtzIGRlc3BpdGUgdGhlIGJhZCBxdWFsaXR5IG9mIHRoZSBy
ZWxlYXNlIHZlcnNpb24gYW5kIHRoZSBiYWQgcmV2aWV3cy4gSXQgZXZlbiBvdXRzb2xkIHRoZSBn
cmVhdGVzdCBjb21wZXRpdG9yIGF0IHRoYXQgdGltZSAoSm9pbnQgT3BlcmF0aW9ucykuIEkgd2Fz
IG9uZSBvZiB0aGUgZWFybHkgYWRvcHRlcnMgYW5kIEkgbG92ZWQgdG8gcGxheSBpdC4gT3duaW5n
IGEgYmFkIElTRE4gY29ubmVjdGlvbiBhdCB0aGF0IHRpbWUgaXQgd2FzIHRlcnJpYmxlIGxhZ2dp
bmcsIGVzcGVjaWFsbHkgYmVjYXVzZSB0aGVpciBuZXRjb2RlIHdhcyBhIGNhdGFzdHJvcGhlLiBT
dGlsbCwgaXQgd2FzIGdyZWF0IGZ1biBhbmQgdGhlIGRlc3RydWN0aWJsZSBlbnZpcm9ubWVudCB3
YXMgZ3JlYXQuIE5vdCBvbmx5IHRoYXQsIHRoZSBnYW1lIHdhcyBzb21ld2hhdCByZXZvbHV0aW9u
YXJ5LiBJdCB3YXMgdGhlIGZpcnN0IG9ubGluZSBnYW1lIEkgcGxheWVkIHdpdGggYW4gKGFsYmVp
dCBiYWQgY29uZmlndXJlZCkgcGh5c2ljcyBlbmdpbmUsIGl0IHVzZWQgcHl0aG9uIGFzIHNjcmlw
dGluZyBsYW5ndWFnZSwgaXQgaGFkIG9uZSBiaWcgbWFwIHRoYXQgd2FzIGdlbmVyYXRlZCBmcm9t
IHNhdGVsbGl0ZSBpbWFnZXMgd2l0aCBkZXRhaWxlZCBhcmVhcyB3aGVyZSB0aGUgZmlnaHRzIHRv
b2sgcGxhY2UuIFlvdSBjb3VsZCBidXkgeW91cnNlbGYgYSBqZXQgYW5kIGxlYXZlIHRoZSBtYXAg
YW5kIHZpc2l0IGFsbCBvZmYgU2liZXJpYS4gTm90IGxpa2UgQmF0dGxlZmllbGQgVmlldG5hbSB3
aGVyZSB5b3UgaGl0IHRoZSBib3JkZXJzIG9mIHRoZSBtYXAgd2l0aCBhIGpldCBhZnRlciByb3Vn
aGx5IDE1IHNlY29uZHMuIERhbW1pdCwgaXQgd291bGQgc3RpbGwgYmUgZnVuIGFuZCBJIGJldCBp
dCB3b3VsZCBoYXZlIGJlZW4gYnVnLWxlc3MgYnkgbm93LgoKVGhlIGNvbW11bml0eSB0aGF0IGFw
cGVhcmVkIGFyb3VuZCB0aGF0IGdhbWUgd2FzIGluY3JlZGlibGUuIEEgd2lraSBhcHBlYXJlZCwg
cGVvcGxlIHRyaWVkIHRvIGhhY2sgYXJvdW5kIG9uIHRoZSBjb2RlIHRvIGdldCBleHRyYSBmZWF0
dXJlcyBpbnRvIHRoZSBnYW1lLCB1bm9mZmljaWFsIG1vZHMgYXBwZWFyZWQuIFRoZXJlIHdhcyBl
dmVuIGEgcHJvamVjdCB0aGF0IHdhbnRlZCB0byBjcmVhdGUgYSBtb2QgZm9yIGEgbWVkaWV2YWwg
c2V0dGluZy4gSGVsbCwgaXQgd2FzIGdyZWF0IGJhY2sgdGhlbi4gQnV0IGluc3RlYWQgb2YgZml4
aW5nIHRoZSBidWdzIEpvd29vZCBmb3JjZWQgdGhlIGRldmVsb3BlcnMgdG8gc3RhcnQgYW4gYWRk
b24gcHJvamVjdC4uLgoKRVMAAAADaW1nTAAATQADUwAAAANzcmNTAAAAJ2h0dHA6Ly9wb2Nvby5v
cmcvfm1pdHN1aGlrby9zc3dfMDMuanBlZ1MAAAADYWx0UwAAABVBIFPDtmxkbmVyIFNjcmVlbnNo
b3RTAAAABWNsYXNzUwAAAAp0aHVtYnJpZ2h0UwAAAABTAAAFilNob3J0bHkgYWZ0ZXIgdGhlIGFk
ZG9uIHdhcyBmaW5pc2hlZCB0aGUgY29tcGFueSBkZXZlbG9waW5nIHRoYXQgZ2FtZSB3YXMgbGlx
dWlkYXRlZC4gVGhlIGRldmVsb3BlcnMgbG9zdCB0aGVpciBqb2IgYW5kIHRoZSBjb21tdW5pdHkg
Y29udGludWVkIGRldmVsb3BpbmcgdGhlIGNsb3NlZCBjb2RlLiBUaGUgZ3JvdXAgYXJvdW5kICJw
cm9qZWN0IHplcm8iIGNvbnRpbnVlZCBtYWludGFpbmluZyB0aGUgZ2FtZSB1bnRpbCB0aGF0IGdy
b3VwIGJyb2tlIGFwYXJ0IGFuZCB0aGUgZ0Vhc3kgdGVhbSB0b29rIG92ZXIgdGhlIHdvcmsuIFRo
ZSBnRWFzeSB0ZWFtIHdhcyBiYXNpY2FsbHkganVzdCB0aGUgcHJvamVjdCB6ZXJvIHRlYW0gd2l0
aG91dCB0aGUgZm91bmRlci4gVGhleSBkaWQgYW4gdHJlbWVuZG91cyBqb2IgYnV0IEpvd29vZCBv
bmNlIGFnYWluIGRlc3Ryb3llZCBldmVyeXRoaW5nLiBUaGV5IHJlZnVzZWQgdG8gcGF5IHRoZWly
IGJpbGxzLCB0aGVuIHRoZSBnRWFzeSB0ZWFtIHRvb2sgZG93biB0aGUgbWFzdGVyIHNlcnZlciBh
bmQgSXZhbiBFcnRsb3YgYXBwZWFyZWQgb24gdGhlIHNjZW5lLiBIZSBtYW5hZ2VkIHRvIHJlc29s
dmUgdGhlIHByb2JsZW1zIGJldHdlZW4gSm93b29kIGFuZCBnRWFzeSB0ZWFtIHRvIHNvbWUgZXh0
ZW5kIHRoYXQgdGhlIG1hc3RlciBzZXJ2ZXIgd2FzIHVwIGFuZCBydW5uaW5nIGFnYWluLgoKV2hv
J3MgdGhhdCBJdmFuIEVydGxvdj8gVmVyeSBnb29kIHF1ZXN0aW9uIGluZGVlZCBhbmQgSSBwZXJz
b25hbGx5IGRvbid0IGtub3cgdGhlIGZ1bGwgc3RvcnkgYnV0IGZyb20gd2hhdCBJJ3ZlIHJlYWQg
b24gdGhlIGZvcnVtcyBoZSBpcyBjYWxsZWQgSm9oYW5uIEVydGwgYW5kIG93bnMgYSBjb21wYW55
IHRoYXQgc2VsbHMgZ3VlcnJpbGxhIG1hcmtldGluZyBhbmQgc2ltaWxhciBzZXJ2aWNlcy4gQW5k
IGhlIHdvcmtlZCBmb3IgSm93b29kIGFuZCBhcHBhcmVudGx5IHN0aWxsIGRvZXMsIGF0IGxlYXN0
IGhlIGlzIGxpc3RlZCBhcyBjb21tdW5pdHkgbWFuYWdlciBpbiB0aGUgb2ZmaWNpYWwgZm9ydW1z
LiBIZSBhbHNvIGJyb3VnaHQgdXAgdGhlIHRvcGljICJPcGVuIFNvdXJjaW5nIiB0aGUgY29kZSBh
ZnRlciBpdCB3YXMgY2xlYXIgdGhhdCB0aGVyZSB3aWxsIGJlIG5vIFPDtmxkbmVyIDIuIEEgc2Vx
dWVsIHdhcyBhY3R1YWxseSB1bmRlciBjb25zaWRlcmF0aW9uIGFuZCBnRWFzeSBzdGFydGVkIHdv
cmtpbmcgb24gdGhhdCB0aWxsIHRoZSBkYXkgdGhleSB0b29rIGRvd24gdGhlIG1hc3RlciBzZXJ2
ZXIgYmVjYXVzZSB0aGVyZSB3YXMgbm8gcGF5bWVudCBieSBKb3dvb2QuIEJ1dCBzaW5jZSBzb21l
IHRpbWUgdGhlcmUgd2FzIG5vIGZlZWRiYWNrIGFueSBtb3JlIGFuZCBhbiBvcGVuIHNvdXJjZSB2
ZXJzaW9uIGlzIHNvbWV3aGF0IHVubGlrZWx5LgoKRVMAAAADaW1nTAAATQADUwAAAANzcmNTAAAA
J2h0dHA6Ly9wb2Nvby5vcmcvfm1pdHN1aGlrby9zc3dfMDQuanBlZ1MAAAADYWx0UwAAABVBIFPD
tmxkbmVyIFNjcmVlbnNob3RTAAAABWNsYXNzUwAAAAl0aHVtYmxlZnRTAAAAAFMAAARqRnJhbmts
eSBJIGRvbid0IGtub3cgaWYgSm93b29kIHBheWVkIG9yIGRpZG4ndC4gV2hhdCBKb3dvb2QgZGlk
IHdhcyBkZXN0cm95aW5nIHRoZSBnYW1lIGJ5IGZvcmNpbmcgYW4gZWFybHkgcmVsZWFzZSwgZm9y
Y2luZyBhbiBhZGRvbiB3aGVuIHRoZSBjb2RlIHdhcyBzdGlsbCB1bmZpbmlzaGVkLCBmaXJlZCB0
aGUgZGV2ZWxvcGVycy4gRXZlbiB3b3JzZTogdGhleSBhcmUgdGVsbGluZyB0aGVpciBzaGFyZWhv
bGRlcnMgdGhhdCBldmVyeXRoaW5nIGlzIHdvcmtpbmcgcGVyZmVjdGx5IGFuZCB0aGF0IHRoZXkg
YXJlIHJlbGVhc2luZyBkb3plbnMgb2YgbmV3IGdhbWVzLiBIZWxsLCB0aGV5IHJlbGVhc2VkIFNw
ZWxsZm9yY2UgMSBhbmQgMiB3aGljaCBib3RoIGFyZSBhd2Vzb21lIGdhbWVzIChqdXN0IGhhcHBl
biB0byBoYXZlIHRoZSB3b3JzdCBjb3B5IHByb3RlY3Rpb24gZXZlciBkZXNpZ25lZCksIHRoZSBH
b3RoaWMgZ2FtZXMgKHRoZSAzcmQgcGFydCB3YXMgYnVnZ3kgbGlrZSBTw7ZsZG5lciBidXQgcHJv
YmFibHkgYWxzbyBiZWNhdXNlIEpvd29vZCBmb3JjZWQgYW4gZWFybHkgcmVsZWFzZSkuIEpvd29v
ZCBob3dldmVyIGNsYWltcyB0aGF0IHRoZXkgcGF5ZWQgYW5kIHRoYXQgZ0Vhc3kgd2FzIGx5aW5n
LiBXaG8gaXMgcnVubmluZyB0aGUgcG9ydGFsIG5vdz8gQXBwYXJlbnRseSBJdmFuJ3MgY29tcGFu
eS4KClNvIHdoeSBhbSBJIGJsb2dnaW5nIGFib3V0IGFsbCB0aGF0PyBNYWlubHkgYmVjYXVzZSBJ
IHRoaW5rIHRoYXQgdG9waWMgaGFzbid0IGdhaW5lZCBhIGxvdCBvZiBhdHRyYWN0aW9uLiBJIHN0
b3BwZWQgcGxheWluZyB0aGF0IGdhbWUgYWZ0ZXIgV2luZ3Mgd2FzIGxpcXVpZGF0ZWQuIEZvciBv
bmUgYmVjYXVzZSBJIHN3aXRjaGVkIHRvIHVidW50dSBhbmQgb24gdGhlIG90aGVyIGhhbmQgYmVj
YXVzZSBteSBTw7ZsZG5lciBwbHVnaW4gKGFuIGluLWdhbWUgV2luYW1wIGNvbnRyb2xsZXIpIGRp
c2FwcGVhcmVkIHdoZW4gdGhlIGZvcnVtIHdhcyB1cGRhdGVkIHRvIHJlZmxlY3QgdGhlIG5ldyBv
d25lcnNoaXAuIEFsbCB0aGUgb2xkIHRvcGljcyB3aGVyZSBlaXRoZXIgZGVsZXRlZCBvciBtYWRl
IHVucmVhZGFibGUgd2hlbiBXaW5ncyB3YXMgY2xvc2VkIGRvd24uCgpFUwAAAANpbWdMAABNAANT
AAAAA3NyY1MAAAAnaHR0cDovL3BvY29vLm9yZy9+bWl0c3VoaWtvL3Nzd18wNS5qcGVnUwAAAANh
bHRTAAAAFUEgU8O2bGRuZXIgU2NyZWVuc2hvdFMAAAAFY2xhc3NTAAAACnRodW1icmlnaHRTAAAA
AFMAAAc1V2hhdCBub2JvZHkgcmVhbGx5IG5vdGljZXMgaXMgdGhhdCB0aGUgZ2FtZSBoYWQgYSB0
cmVtZW5kb3VzIEdlcm1hbiBjb21tdW5pdHkuIEhlbGwsIHNvbWUgb2YgdGhlbSBldmVuIHRvb2sg
b3ZlciB0aGUgZGV2ZWxvcG1lbnQhIElmIEpvd29vZCB3b3VsZCBoYXZlIG5vdGljZWQgdGhhdCBl
YXJsaWVyIHRoZXkgY291bGQgaGF2ZSBtYWRlIHRoYXQgZ2FtZSB0aGUgZnJlYWtpbmcgYmVzdCBv
bmxpbmUgc2hvb3RlciBhdmFpbGFibGUgYXQgdGhhdCB0aW1lLiBCdXQgYmVjYXVzZSBvZiB0aGVp
ciBzbWFsbCBob3Jpem9uIHRoZXkganVzdCB0aG91Z2h0IGFib3V0IHRoZWlyIG5leHQgcXVhcnRl
ciBhbmQgZGVjaWRlZCB0byBkbyB3aGF0IHNoYXJlaG9sZGVycyB3YW50LCBub3Qgd2hhdCBwbGF5
ZXJzIHdhbnQuIEJ1dCBub3Qgb25seSBKb3dvb2QgaXMgdG8gYmxhbWUgYnV0IHRoZSByb290IG9m
IGFsbCBldmlsIGluIHRoYXQgY2FzZS4KCktyYXdhbGwgc3VwcG9ydGVkIEpvd29vZCBpbiB0aGUg
YmVnaW5uaW5nIHRvIGhvc3QgdGhlaXIgaW5pdGlhbCBpbmZyYXN0cnVjdHVyZSBuZWVkZWQgZm9y
IHRoZSBnYW1lLiBVbmZvcnR1bmF0ZWx5IHRoZSBzZXJ2ZXIgc29mdHdhcmUgbmVlZGVkIERpcmVj
dCBYIHRvIHJ1biBwcm9wZXJseSB3aGljaCBjYXVzZWQgYSBsb3Qgb2YgdHJvdWJsZS4gT25lIHRo
ZSBvbmUgaGFuZCBpdCB3YXMgaGFyZCB0byBnZXQgbXVsdGlwbGUgc2VydmVycyBydW5uaW5nIG9u
IG9uZSBtYWNoaW5lIGRvIHRvIHRoZSB3YXkgdGhlIHNlcnZlciB3YXMgZGVzaWduZWQsIG9uIHRo
ZSBvdGhlciBoYW5kIHlvdSBuZWVkZWQgYSB3aW5kb3dzIHNlcnZlciB0byBob3N0IGdhbWVzLiBB
bmQgYmVjYXVzZSB0aGUgaW5pdGlhbCBjb2RlIGJhc2Ugd2FzIHRoYXQgYnVnZ3kgYWxsIHRoZSBt
YWdhemluZXMgZmxhbWVkIHRvIGdhbWUuIERlc3BpdGUgdGhlIGdvb2Qgc2FsZXMgZmlndXJlcyBp
dCBtYWdhemluZXMgbmV2ZXIgd3JvdGUgYWJvdXQgdGhlIGdhbWUgYW5kIGZvcmNlZCBhbiBlYXJs
eSBkZWFkIHdoaWNoIGhhcm1lZCB0aGUgY29tbXVuaXR5LiBBIHJlbGVhc2Ugc2l4IG1vbnRoIGxh
dGVyLCBhIGxpbnV4IHNlcnZlciBmcm9tIHRoZSBiZWdpbm5pbmcsIG5vIGFkZG9uIGFuZCBnb29k
IHByZXNzIGNvdmVyYWdlIHdvdWxkIGhhdmUgYXZvaWRlZCBhbGwgdGhlIHByb2JsZW1zIHRoaXMg
Z2FtZSB3YXMgZmFjaW5nIGluIHRoZSBwYXN0LiBBbmQgaXQgd291bGQgaGF2ZSBzYXZlZCBXaW5n
cywgdGhlIGdhbWUgdGhleSB3ZXJlIHdvcmtpbmcgb24gYmVzaWRlIFPDtmxkbmVyLCBhbmQgaW4g
dGhlIGVuZCBvZiBjb3Vyc2UgSm93b29kIHdoaWNoIHdvdWxkIGhhdmUgaGFkIGEgbG90IGxlc3Mg
YmFkIHByZXNzLgoKRXNwZWNpYWxseSB0aGUgZ2FtZXJzIGhhdGUgSm93b29kIGZvciB0aGVpciBi
dWdneSBwcm9kdWN0cyBub3cgYW5kIEkgZG91YnQgdGhhdCB0aGV5IHdpbGwgYmUgYWJsZSB0byBj
b250aW51ZSB0byBpZ25vcmUgYWxsIHRoZSB1c2VyIGZlZWRiYWNrIGFuZCBwdXNoIGFscGhhIHZl
cnNpb25zIGFzIHJlbGVhc2UgdmVyc2lvbnMgZm9yIG11Y2ggbG9uZ2VyLgoKSSdtIGVzcGVjaWFs
bHkgaW50ZXJlc3RlZCB3aGF0IHRoZSBXaW5ncyBndXlzIGFyZSBkb2luZyBub3cuIEkga25vdyB0
aGF0IGZvcm1lciBXaW5ncyBjb21tdW5pdHkgbWFuYWdlciBhbmQgc291bmQgZGVzaWduZWQgTWFy
YyBPbGJlcnR6IGlzIHdvcmtpbmcgYXQgQmxpenphcmQgYnV0IHRoYXQncyBhYm91dCBpdC4gSXQn
cyBzYWQgd2hhdCBoYXBwZW5lZCB0aGVyZSBhbmQgdGhhdCBBdXN0cmlhbidzIG9ubHkgZ2FtZSBw
dWJsaXNoZXIgY2F1c2VkIGFsbCB0aGF0LgoKRVMAAAAFc21hbGxMAAFFUwAAAAZzdHJvbmdMAABN
AABTAAAAC0Z1bmt5IGZhY3Q6UwAAAMcgVGhlIGNvbW11bmljYXRpb24gd2l0aCB0aGUgbWFzdGVy
IHNlcnZlciB3b3JrZWQgdmlhIGphYmJlciwgdGhlIHBoeXNpY3MgZW5naW5lIHdhcyBPREUgYW5k
IHRoZSBzY3JpcHRpbmcgbGFuZ3VhZ2Ugd2FzIFB5dGhvbi4gQWxsIG9wZW4gc291cmNlIHRlY2hu
b2xvZ2llcyBJIG5ldmVyIHNhdyBpbiBhIGNvbW1lcmNpYWwgZ2FtZSBiZWZvcmUgOi0pTQAAUwAA
AABTAAAAAgoKRVMAAAAFc21hbGxMAAJFUwAAAAZzdHJvbmdMAABNAABTAAAAC0Rpc2NsYWltZXI6
UwAAAP8gdGhlIGluZm9ybWF0aW9uIG9uIHRoaXMgcGFnZSBzaG91bGQgYmUgYWNjdXJhdGUgYnV0
IGl0J3MgaGFyZCB0byBzYXkgZm9yIHN1cmUgYmVjYXVzZSB0aGVyZSBpcyBmZXcgaW5mb3JtYXRp
b24gYWJvdXQgdGhpcyB0b3BpYyBhY3R1YWxseSBhdmFpbGFibGUuIElmIHlvdSBhcmUgYWJsZSB0
byB1bmRlcnN0YW5kIEdlcm1hbiB5b3UgY2FuIGZpbmQgc29tZSBpbmZvcm1hdGlvbiBpbiB0aGlz
IHRocmVhZCBvbiB0aGUgU8O2bGRuZXIgZm9ydW1zOiBFUwAAAAFhTAAATQABUwAAAARocmVmUwAA
ADZodHRwOi8vd3d3LnNlY3JldHdhcnMubmV0L2ZvcnVtL3Nob3d0aHJlYWQucGhwP3Q9NDE1OTFT
AAAALVPDtmxkbmVyIGVpbiBBYmVudGV1ZXIgbWl0IHVuZ2V3aXNzZW0gQXVzZ2FuZ1MAAAAATQAA
UwAAAABTAAAAAFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Schranzkoppschranzkopp@gmx.nethttp://www.ssw-channel.de.vu2008-02-10T00:35:19Znono0Well written!
And all true...
I can tell you that Udett Schaffrath, Producer of söldner now works in Hamburg as the Communitymanager of Computerbild online.
I'll ask him what happened to the other guys from Wings.Well written!
And all true...
I can tell you that Udett Schaffrath, Producer of söldner now works in Hamburg as the Communitymanager of Computerbild online.
I'll ask him what happened to the other guys from Wings.SQAAAAJTAAAABGJvZHlSUwAAANhXZWxsIHdyaXR0ZW4hCgpBbmQgYWxsIHRydWUuLi4KSSBjYW4g
dGVsbCB5b3UgdGhhdCBVZGV0dCBTY2hhZmZyYXRoLCBQcm9kdWNlciBvZiBzw7ZsZG5lciBub3cg
d29ya3MgaW4gSGFtYnVyZyBhcyB0aGUgQ29tbXVuaXR5bWFuYWdlciBvZiBDb21wdXRlcmJpbGQg
b25saW5lLgoKSSdsbCBhc2sgaGltIHdoYXQgaGFwcGVuZWQgdG8gdGhlIG90aGVyIGd1eXMgZnJv
bSBXaW5ncy5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
ryancrryan@rrdesign.cahttp://blog.rrdesign.ca2008-02-10T05:30:05Znono0I remember when I first saw some videos of this game and thought it looked great. I followed it for sometime waiting for the demo release and sure enough it was buggy. Then came all the bad reviews, and then it seemed to fade away. To bad it didn't turn into the came it could have been.I remember when I first saw some videos of this game and thought it looked great. I followed it for sometime waiting for the demo release and sure enough it was buggy. Then came all the bad reviews, and then it seemed to fade away. To bad it didn't turn into the came it could have been.SQAAAAJTAAAABGJvZHlSUwAAAR9JIHJlbWVtYmVyIHdoZW4gSSBmaXJzdCBzYXcgc29tZSB2aWRl
b3Mgb2YgdGhpcyBnYW1lIGFuZCB0aG91Z2h0IGl0IGxvb2tlZCBncmVhdC4gSSBmb2xsb3dlZCBp
dCBmb3Igc29tZXRpbWUgd2FpdGluZyBmb3IgdGhlIGRlbW8gcmVsZWFzZSBhbmQgc3VyZSBlbm91
Z2ggaXQgd2FzIGJ1Z2d5LiBUaGVuIGNhbWUgYWxsIHRoZSBiYWQgcmV2aWV3cywgYW5kIHRoZW4g
aXQgc2VlbWVkIHRvIGZhZGUgYXdheS4gVG8gYmFkIGl0IGRpZG4ndCB0dXJuIGludG8gdGhlIGNh
bWUgaXQgY291bGQgaGF2ZSBiZWVuLkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
mimimimi.vx@gmail.com2008-02-10T11:23:52Znono0ODE was in Bloodrayene 2 , Python in Civ4 and Eve Online :)ODE was in Bloodrayene 2 , Python in Civ4 and Eve Online :)SQAAAAJTAAAABGJvZHlSUwAAADtPREUgd2FzIGluIEJsb29kcmF5ZW5lIDIgLCBQeXRob24gaW4g
Q2l2NCBhbmQgRXZlIE9ubGluZSA6KUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-02-10T13:40:03Znono0BloodRayne 2 was released a year after Söldner, same for Civ4. EVE indeed was released a year earlier. But back then I didn't know about that one ^^BloodRayne 2 was released a year after Söldner, same for Civ4. EVE indeed was released a year earlier. But back then I didn't know about that one ^^SQAAAAJTAAAABGJvZHlSUwAAAJVCbG9vZFJheW5lIDIgd2FzIHJlbGVhc2VkIGEgeWVhciBhZnRl
ciBTw7ZsZG5lciwgc2FtZSBmb3IgQ2l2NC4gRVZFIGluZGVlZCB3YXMgcmVsZWFzZWQgYSB5ZWFy
IGVhcmxpZXIuIEJ1dCBiYWNrIHRoZW4gSSBkaWRuJ3Qga25vdyBhYm91dCB0aGF0IG9uZSBeXkwA
AFMAAAAGcGFyc2VyUwAAAARodG1s
Vadim P.vperetokin@gmail.com2008-02-10T15:03:29Znono0Ouch. Well, that's one publishing company to stay away from..
(and damnit, why does steam have to be windows-only?)Ouch. Well, that's one publishing company to stay away from..
(and damnit, why does steam have to be windows-only?)SQAAAAJTAAAABGJvZHlSUwAAAHRPdWNoLiBXZWxsLCB0aGF0J3Mgb25lIHB1Ymxpc2hpbmcgY29t
cGFueSB0byBzdGF5IGF3YXkgZnJvbS4uCgooYW5kIGRhbW5pdCwgd2h5IGRvZXMgc3RlYW0gaGF2
ZSB0byBiZSB3aW5kb3dzLW9ubHk/KUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
allirogallirog@gmx.net2008-02-10T18:06:54Znono0Make this puuuuuuuuublic ;) and somebody translate the german forum post into english :)Make this puuuuuuuuublic ;) and somebody translate the german forum post into english :)SQAAAAJTAAAABGJvZHlSUwAAAFhNYWtlIHRoaXMgcHV1dXV1dXV1dWJsaWMgOykgYW5kIHNvbWVi
b2R5IHRyYW5zbGF0ZSB0aGUgZ2VybWFuIGZvcnVtIHBvc3QgaW50byBlbmdsaXNoIDopTAAAUwAA
AAZwYXJzZXJTAAAABGh0bWw=
Useruser@example.com2008-02-10T20:37:30Znono0Nice post. I remember reading some previews of the game. It was exciting, even though my PC couldn't handle it. It's a shame that something with so much potential got messed up like that, but it happens all the time, it seems. Be sure to post again if you ever hear about the community getting restarted. Sounds and looks like a lot of fun.Nice post. I remember reading some previews of the game. It was exciting, even though my PC couldn't handle it. It's a shame that something with so much potential got messed up like that, but it happens all the time, it seems. Be sure to post again if you ever hear about the community getting restarted. Sounds and looks like a lot of fun.SQAAAAJTAAAABGJvZHlSUwAAAVlOaWNlIHBvc3QuICBJIHJlbWVtYmVyIHJlYWRpbmcgc29tZSBw
cmV2aWV3cyBvZiB0aGUgZ2FtZS4gIEl0IHdhcyBleGNpdGluZywgZXZlbiB0aG91Z2ggbXkgUEMg
Y291bGRuJ3QgaGFuZGxlIGl0LiAgSXQncyBhIHNoYW1lIHRoYXQgc29tZXRoaW5nIHdpdGggc28g
bXVjaCBwb3RlbnRpYWwgZ290IG1lc3NlZCB1cCBsaWtlIHRoYXQsIGJ1dCBpdCBoYXBwZW5zIGFs
bCB0aGUgdGltZSwgaXQgc2VlbXMuICBCZSBzdXJlIHRvIHBvc3QgYWdhaW4gaWYgeW91IGV2ZXIg
aGVhciBhYm91dCB0aGUgY29tbXVuaXR5IGdldHRpbmcgcmVzdGFydGVkLiAgU291bmRzIGFuZCBs
b29rcyBsaWtlIGEgbG90IG9mIGZ1bi5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
prencherprencher@prencher.dk2008-02-12T02:03:58Znono0As I recall, BF2142 also uses python extensively (I believe BF2 does too). Lots of games do these days - even more use lua.As I recall, BF2142 also uses python extensively (I believe BF2 does too). Lots of games do these days - even more use lua.SQAAAAJTAAAABGJvZHlSUwAAAHtBcyBJIHJlY2FsbCwgQkYyMTQyIGFsc28gdXNlcyBweXRob24g
ZXh0ZW5zaXZlbHkgKEkgYmVsaWV2ZSBCRjIgZG9lcyB0b28pLiBMb3RzIG9mIGdhbWVzIGRvIHRo
ZXNlIGRheXMgLSBldmVuIG1vcmUgdXNlIGx1YS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
New Werkzeug Website / Docshttp://lucumr.pocoo.org/cogitations/2008/02/06/new-werkzeug-website-docs/2008-02-06T18:27:47Z2008-02-06T18:27:47ZArmin Ronachernew-werkzeug-website-docsyesyes2Disclaimer: Yes I know the colors are too bright. Everybody who saw that webpage told me that, so I will change that soon. Anyways. Because there is an upcoming 0.2 release I deployed the documentation for the 0.2 release already because most of the users are probably already working on the hg tip (at least that's what the situation looks like in #pocoo).
<a href="http://werkzeug.pocoo.org/">The new website</a> and <a href="http://werkzeug.pocoo.org/documentation/">documentation</a>.
Additionally if everything works well there will be a Werkzeug presentation on the <a href="http://www.linuxtage.at/">Grazer Linuxtage</a> April the 19th. The Werkzeug 0.2 release will be Feb 14th hopefully, until then I have to fight with Jabber, don't ask :-)Disclaimer: Yes I know the colors are too bright. Everybody who saw that webpage told me that, so I will change that soon. Anyways. Because there is an upcoming 0.2 release I deployed the documentation for the 0.2 release already because most of the users are probably already working on the hg tip (at least that's what the situation looks like in #pocoo).
<a href="http://werkzeug.pocoo.org/">The new website</a> and <a href="http://werkzeug.pocoo.org/documentation/">documentation</a>.
Additionally if everything works well there will be a Werkzeug presentation on the <a href="http://www.linuxtage.at/">Grazer Linuxtage</a> April the 19th. The Werkzeug 0.2 release will be Feb 14th hopefully, until then I have to fight with Jabber, don't ask :-)SQAAAANTAAAABGJvZHlSUwAAAWdEaXNjbGFpbWVyOiBZZXMgSSBrbm93IHRoZSBjb2xvcnMgYXJl
IHRvbyBicmlnaHQuIEV2ZXJ5Ym9keSB3aG8gc2F3IHRoYXQgd2VicGFnZSB0b2xkIG1lIHRoYXQs
IHNvIEkgd2lsbCBjaGFuZ2UgdGhhdCBzb29uLiBBbnl3YXlzLiBCZWNhdXNlIHRoZXJlIGlzIGFu
IHVwY29taW5nIDAuMiByZWxlYXNlIEkgZGVwbG95ZWQgdGhlIGRvY3VtZW50YXRpb24gZm9yIHRo
ZSAwLjIgcmVsZWFzZSBhbHJlYWR5IGJlY2F1c2UgbW9zdCBvZiB0aGUgdXNlcnMgYXJlIHByb2Jh
Ymx5IGFscmVhZHkgd29ya2luZyBvbiB0aGUgaGcgdGlwIChhdCBsZWFzdCB0aGF0J3Mgd2hhdCB0
aGUgc2l0dWF0aW9uIGxvb2tzIGxpa2UgaW4gI3BvY29vKS4KCkwAA0VTAAAAAWFMAABNAAFTAAAA
BGhyZWZTAAAAGmh0dHA6Ly93ZXJremV1Zy5wb2Nvby5vcmcvUwAAAA9UaGUgbmV3IHdlYnNpdGVT
AAAABSBhbmQgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAoaHR0cDovL3dlcmt6ZXVnLnBvY29v
Lm9yZy9kb2N1bWVudGF0aW9uL1MAAAANZG9jdW1lbnRhdGlvblMAAABWLgoKQWRkaXRpb25hbGx5
IGlmIGV2ZXJ5dGhpbmcgd29ya3Mgd2VsbCB0aGVyZSB3aWxsIGJlIGEgV2Vya3pldWcgcHJlc2Vu
dGF0aW9uIG9uIHRoZSBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAABhodHRwOi8vd3d3LmxpbnV4
dGFnZS5hdC9TAAAAEEdyYXplciBMaW51eHRhZ2VTAAAAeyBBcHJpbCB0aGUgMTl0aC4gVGhlIFdl
cmt6ZXVnIDAuMiByZWxlYXNlIHdpbGwgYmUgRmViIDE0dGggaG9wZWZ1bGx5LCB1bnRpbCB0aGVu
IEkgaGF2ZSB0byBmaWdodCB3aXRoIEphYmJlciwgZG9uJ3QgYXNrIDotKVMAAAAGcGFyc2VyUwAA
AARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
johnjohn.w@web.de2008-02-06T21:08:08Znono0Hey, the other one wasn't bad either.
And the hammer isn't really the coolest photo I could imagine. Maybe go for a Tango like one? (or at least painted)Hey, the other one wasn't bad either.
And the hammer isn't really the coolest photo I could imagine. Maybe go for a Tango like one? (or at least painted)SQAAAAJTAAAABGJvZHlSUwAAAJpIZXksIHRoZSBvdGhlciBvbmUgd2Fzbid0IGJhZCBlaXRoZXIu
CgpBbmQgdGhlIGhhbW1lciBpc24ndCByZWFsbHkgdGhlIGNvb2xlc3QgcGhvdG8gSSBjb3VsZCBp
bWFnaW5lLiBNYXliZSBnbyBmb3IgYSBUYW5nbyBsaWtlIG9uZT8gKG9yIGF0IGxlYXN0IHBhaW50
ZWQpTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
vicent rocasaptah@gmail.com2008-02-06T21:12:33Znono0hi,
I prefer the last design :)hi,
I prefer the last design :)SQAAAAJTAAAABGJvZHlSUwAAAB9oaSwKSSBwcmVmZXIgdGhlIGxhc3QgZGVzaWduIDopTAAAUwAA
AAZwYXJzZXJTAAAABGh0bWw=
Steveskryskalla@gmail.com2008-02-09T03:59:54Znono0I have to say I like the old design too :) This looks a lot like the TurboGears site (the blue header).
That "look under the hood" link is really impressive though.I have to say I like the old design too :) This looks a lot like the TurboGears site (the blue header).
That "look under the hood" link is really impressive though.SQAAAAJTAAAABGJvZHlSUwAAAKZJIGhhdmUgdG8gc2F5IEkgbGlrZSB0aGUgb2xkIGRlc2lnbiB0
b28gOikgIFRoaXMgbG9va3MgYSBsb3QgbGlrZSB0aGUgVHVyYm9HZWFycyBzaXRlICh0aGUgYmx1
ZSBoZWFkZXIpLgoKVGhhdCAibG9vayB1bmRlciB0aGUgaG9vZCIgbGluayBpcyByZWFsbHkgaW1w
cmVzc2l2ZSB0aG91Z2guTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-02-09T10:29:55Znono0Yes indeed, they look very similar. One more reason to make the header less flashy.Yes indeed, they look very similar. One more reason to make the header less flashy.SQAAAAJTAAAABGJvZHlSUwAAAFNZZXMgaW5kZWVkLCB0aGV5IGxvb2sgdmVyeSBzaW1pbGFyLiBP
bmUgbW9yZSByZWFzb24gdG8gbWFrZSB0aGUgaGVhZGVyIGxlc3MgZmxhc2h5LkwAAFMAAAAGcGFy
c2VyUwAAAARodG1s
Until TextPress is ready…http://lucumr.pocoo.org/cogitations/2008/02/05/until-textpress-is-ready/2008-02-05T19:24:40Z2008-02-05T19:24:40ZArmin Ronacheruntil-textpress-is-readyyesyes2<pre>mitsuhiko@hammett:~$ cd lucumr/cogitations/
mitsuhiko@hammett:~/lucumr/cogitations$ rm xmlrpc.php
mitsuhiko@hammett:~/lucumr/cogitations$ </pre><pre>mitsuhiko@hammett:~$ cd lucumr/cogitations/
mitsuhiko@hammett:~/lucumr/cogitations$ rm xmlrpc.php
mitsuhiko@hammett:~/lucumr/cogitations$ </pre>SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAANwcmVMAABNAABTAAAAi21pdHN1aGlrb0BoYW1t
ZXR0On4kIGNkIGx1Y3Vtci9jb2dpdGF0aW9ucy8KbWl0c3VoaWtvQGhhbW1ldHQ6fi9sdWN1bXIv
Y29naXRhdGlvbnMkIHJtIHhtbHJwYy5waHAgCm1pdHN1aGlrb0BoYW1tZXR0On4vbHVjdW1yL2Nv
Z2l0YXRpb25zJCBTAAAAAFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
BarCamp Senza Confini 2008, Day 1http://lucumr.pocoo.org/cogitations/2008/02/02/barcamp-senza-confini-2008-day-1/2008-02-02T20:32:54Z2008-02-02T20:32:54ZArmin Ronacherbarcamp-senza-confini-2008-day-1yesyes2And unfortunately also the only day for me because I can't be there tomorrow. Which is especially stupid because I'm very interested in the talk about broadband 2.0 by <a href="https://www.xing.com/profile/Alexander_List">Alexander List</a>.
Well. It was my first barcamp so I presented a topic: mercurial. Good: There was at least one person in the audience that considers switching and I hope I whetted appetite to the others too, Bad: the talk was badly organized IMO, hope I will do better the next time. But now to the positive aspects of the day.
I think the main reason why people go to barcamps are not the talks, but the possibility to meet people with similar interests and share experiences and knowledge. I meet a couple people there I didn't know before or only from IRC/Jabber/whatever and he have a couple of great discussions, especially about the currently problematic political situation here in Austria. And despite what I noticed in the past there are several groups operating here that try to fix the situation here.
I'll hopefully blog a bit about it more soon :-)And unfortunately also the only day for me because I can't be there tomorrow. Which is especially stupid because I'm very interested in the talk about broadband 2.0 by <a href="https://www.xing.com/profile/Alexander_List">Alexander List</a>.
Well. It was my first barcamp so I presented a topic: mercurial. Good: There was at least one person in the audience that considers switching and I hope I whetted appetite to the others too, Bad: the talk was badly organized IMO, hope I will do better the next time. But now to the positive aspects of the day.
I think the main reason why people go to barcamps are not the talks, but the possibility to meet people with similar interests and share experiences and knowledge. I meet a couple people there I didn't know before or only from IRC/Jabber/whatever and he have a couple of great discussions, especially about the currently problematic political situation here in Austria. And despite what I noticed in the past there are several groups operating here that try to fix the situation here.
I'll hopefully blog a bit about it more soon :-)SQAAAANTAAAABGJvZHlSUwAAAKhBbmQgdW5mb3J0dW5hdGVseSBhbHNvIHRoZSBvbmx5IGRheSBm
b3IgbWUgYmVjYXVzZSBJIGNhbid0IGJlIHRoZXJlIHRvbW9ycm93LiBXaGljaCBpcyBlc3BlY2lh
bGx5IHN0dXBpZCBiZWNhdXNlIEknbSB2ZXJ5IGludGVyZXN0ZWQgaW4gdGhlIHRhbGsgYWJvdXQg
YnJvYWRiYW5kIDIuMCBieSBMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACtodHRwczovL3d3
dy54aW5nLmNvbS9wcm9maWxlL0FsZXhhbmRlcl9MaXN0UwAAAA5BbGV4YW5kZXIgTGlzdFMAAANR
LgoKV2VsbC4gSXQgd2FzIG15IGZpcnN0IGJhcmNhbXAgc28gSSBwcmVzZW50ZWQgYSB0b3BpYzog
bWVyY3VyaWFsLiBHb29kOiBUaGVyZSB3YXMgYXQgbGVhc3Qgb25lIHBlcnNvbiBpbiB0aGUgYXVk
aWVuY2UgdGhhdCBjb25zaWRlcnMgc3dpdGNoaW5nIGFuZCBJIGhvcGUgSSB3aGV0dGVkIGFwcGV0
aXRlIHRvIHRoZSBvdGhlcnMgdG9vLCBCYWQ6IHRoZSB0YWxrIHdhcyBiYWRseSBvcmdhbml6ZWQg
SU1PLCBob3BlIEkgd2lsbCBkbyBiZXR0ZXIgdGhlIG5leHQgdGltZS4gQnV0IG5vdyB0byB0aGUg
cG9zaXRpdmUgYXNwZWN0cyBvZiB0aGUgZGF5LgoKSSB0aGluayB0aGUgbWFpbiByZWFzb24gd2h5
IHBlb3BsZSBnbyB0byBiYXJjYW1wcyBhcmUgbm90IHRoZSB0YWxrcywgYnV0IHRoZSBwb3NzaWJp
bGl0eSB0byBtZWV0IHBlb3BsZSB3aXRoIHNpbWlsYXIgaW50ZXJlc3RzIGFuZCBzaGFyZSBleHBl
cmllbmNlcyBhbmQga25vd2xlZGdlLiBJIG1lZXQgYSBjb3VwbGUgcGVvcGxlIHRoZXJlIEkgZGlk
bid0IGtub3cgYmVmb3JlIG9yIG9ubHkgZnJvbSBJUkMvSmFiYmVyL3doYXRldmVyIGFuZCBoZSBo
YXZlIGEgY291cGxlIG9mIGdyZWF0IGRpc2N1c3Npb25zLCBlc3BlY2lhbGx5IGFib3V0IHRoZSBj
dXJyZW50bHkgcHJvYmxlbWF0aWMgcG9saXRpY2FsIHNpdHVhdGlvbiBoZXJlIGluIEF1c3RyaWEu
IEFuZCBkZXNwaXRlIHdoYXQgSSBub3RpY2VkIGluIHRoZSBwYXN0IHRoZXJlIGFyZSBzZXZlcmFs
IGdyb3VwcyBvcGVyYXRpbmcgaGVyZSB0aGF0IHRyeSB0byBmaXggdGhlIHNpdHVhdGlvbiBoZXJl
LgoKSSdsbCBob3BlZnVsbHkgYmxvZyBhIGJpdCBhYm91dCBpdCBtb3JlIHNvb24gOi0pUwAAAAZw
YXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Manuzhaimail@manuzhai.nl2008-02-03T08:43:49Znono0It would be nice if you published your slides on the Mercurial wiki. There is a Presentations page just for this purpose.It would be nice if you published your slides on the Mercurial wiki. There is a Presentations page just for this purpose.SQAAAAJTAAAABGJvZHlSUwAAAHlJdCB3b3VsZCBiZSBuaWNlIGlmIHlvdSBwdWJsaXNoZWQgeW91
ciBzbGlkZXMgb24gdGhlIE1lcmN1cmlhbCB3aWtpLiBUaGVyZSBpcyBhIFByZXNlbnRhdGlvbnMg
cGFnZSBqdXN0IGZvciB0aGlzIHB1cnBvc2UuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Mercurial for Subversion Usershttp://lucumr.pocoo.org/cogitations/2008/01/28/mercurial-for-subversion-users/2008-01-28T18:59:11Z2008-01-28T18:59:11ZArmin Ronachermercurial-for-subversion-usersyesyes2More and more projects are switching over to <a href="http://www.selenic.com/mercurial/">mercurial</a> or similar DVCS. Great as mercurial is, it's hard to get started if you are used to subversion because the concept behind Subversion (svn) and mercurial (hg) is fundamentally different. This article should help you understand how mercurial and similar systems work and how you can use it to contribute patches to the pocoo projects.
If you compare Subversion to mercurial you won't find that many similarities beside the command arguments. Subversion works like FTP whereas mercurial is bittorrent. In Subversion the server is special: it keeps all the revision log and all the operations require a connection to this server. In mercurial I can take down the central repository if there is one an all developers will still be able to exchange changes. All the revision information is available to anyone and there is absolutely no difference between server and clients.
This fundamental design decision means that there are dozens of separate branches of the code. hg makes it easy to merge and branch and it's developed exactly for that. In Subversion branching and merging is painful an often people just don't branch and don't commit there changes until the testsuite etc. passes again which of course results in huge changesets. But let's step right into it!
The first thing in Subversion you do is either creating a repository on the server or checking it out on the client. In hg there is no difference between server and client so the process of creating a repository is available to everybody. Creating a repository is just as simple as typing "hg init name_of_the_repository". If that folder does not exist yet it will create an empty folder and initialize it as root of the repository, otherwise it will create the repository in the name of that folder.
The process of checking out is a bit different from Subversion because it's effectively the same as creating a branch. Say you want to check out the current Pygments version to do some changes. The first thing you will do is looking for a way to access this repository. There are three very common ways to access it: filesystem, HTTP or SSH. Pygments is available as SSH and HTTP, but for non core developers only HTTP is available. Interestingly quite a few people have problems locating the checkout URL which is not very surprising because hgweb handles that. hgweb is the standard mercurial web interface which doesn't only provide a way to look at the changesets and tree but also handles patch exchange. In the case of Pygments this command should give you a fresh checkout in a few seconds into the new folder "pygments":
<pre>hg clone http://dev.pocoo.org/hg/pygments-main pygments</pre>
One thing you will notice is that it's incredible fast and even though the repository contains the whole history the checkout is pretty small. By the time I'm writing this blog post the pygments sourcecode including the unittests and example sourcecode without the revision history is 2.5MB. A complete mercurial checkout is only 5MB even though it includes 486 changesets.
After you got your very own repository by cloning the pygments one you will notice that all the subversion-like commands ("hg ci", "hg add", "hg up", ...) work locally only. You check into your local version of the repository and hg up won't incorporate remote changes. One of the things that happen on hg clone is that mercurial will set the path to the repository you cloned from into the hgrc of the newly created repository. This file (".hg/hgrc") is used to store per-repository configuration like the path of remote repositories, the name used for checkins, plugins that are only enabled for this repository and more. Executing "hg pull" will automatically pull changes from this remote repository and put them into the current repository as second branch. To see what "hg pull" will pull from that remote repository you can execute "hg incoming" and it will print a list of changesets that are in the remote repository but not yet in the local one. After you have pulled you have to update the repository with "hg up" so that you can actually see the changes. If there were remote changes that require merging you have to "hg merge" them and "hg ci" the merge.
Because this process is very common there are ways to simplify it. "hg pull && hg update" can be written as "hg pull -u". All the commands (pull, update, merge and checkin if required) can be handled in one go using "hg fe". This command however is part of a plugin which is disabled by default. If you want to use it you have to add the following lines into the repository hgrc or your personal one:
<pre>[extensions]
hgext.fetch=</pre>
The other important difference to subversion is how you push your changes back to the server. In open source projects usually only a small number of developers has access to the main repository and contributors create patches using "diff" or "svn diff" and mail it to one of the persons with commit rights or attach it to a ticket in the project's tracker. If you are a person with push privileges you can do "hg push" and it will push the changesets which are not yet on the server (you can look at them using "hg outgoing"). If you don't have push access you can create a bundle of changes and attach that to a ticket rather than a patch. A bundle stores multiple changesets in one file and it also preserves the correct author information and timestamps. Another way is mailing the changes to a different developer using the patchbomb extension (I won't cover that here, just google it up). Or you can let other people pull from your repository. Therefore you either have to configure your apache to server a hgweb instance or you just call "hg serve" and it will spawn a server on localhost:8000 everybody can pull from.
Once the developer has decided to put your changes into the central repository and pushed them, your changes will appear there unaltered and with the same revision hashes. What will be different is the local number the changeset is given. If the revision was called deadbeef:42 locally it could be called deadbeef:52 on the server because different changesets were applied first.
All the commands that interact with remote repositories ("hg pull", "hg push", "hg fe", ...) also take a different path than the default path from the hgrc as argument. This allows you to pull changes from repositories shared over the web.
A cool example what mercurial allows you to do is our last ubuntuusers webteam meetup. There we used my notebook to store the central repository and everybody pushed the changes every once in a while to it. Additionally some people exchanged patches to not yet working features among each other so that the code on the central repo was seldom broken. When I left everybody had all the changes locally because they pulled and I could remove my notebook and everybody continued working on their way home. When we met again on IRC I copied my repo on the server and everybody pushed their local changes to it.More and more projects are switching over to <a href="http://www.selenic.com/mercurial/">mercurial</a> or similar DVCS. Great as mercurial is, it's hard to get started if you are used to subversion because the concept behind Subversion (svn) and mercurial (hg) is fundamentally different. This article should help you understand how mercurial and similar systems work and how you can use it to contribute patches to the pocoo projects.
If you compare Subversion to mercurial you won't find that many similarities beside the command arguments. Subversion works like FTP whereas mercurial is bittorrent. In Subversion the server is special: it keeps all the revision log and all the operations require a connection to this server. In mercurial I can take down the central repository if there is one an all developers will still be able to exchange changes. All the revision information is available to anyone and there is absolutely no difference between server and clients.
This fundamental design decision means that there are dozens of separate branches of the code. hg makes it easy to merge and branch and it's developed exactly for that. In Subversion branching and merging is painful an often people just don't branch and don't commit there changes until the testsuite etc. passes again which of course results in huge changesets. But let's step right into it!
The first thing in Subversion you do is either creating a repository on the server or checking it out on the client. In hg there is no difference between server and client so the process of creating a repository is available to everybody. Creating a repository is just as simple as typing "hg init name_of_the_repository". If that folder does not exist yet it will create an empty folder and initialize it as root of the repository, otherwise it will create the repository in the name of that folder.
The process of checking out is a bit different from Subversion because it's effectively the same as creating a branch. Say you want to check out the current Pygments version to do some changes. The first thing you will do is looking for a way to access this repository. There are three very common ways to access it: filesystem, HTTP or SSH. Pygments is available as SSH and HTTP, but for non core developers only HTTP is available. Interestingly quite a few people have problems locating the checkout URL which is not very surprising because hgweb handles that. hgweb is the standard mercurial web interface which doesn't only provide a way to look at the changesets and tree but also handles patch exchange. In the case of Pygments this command should give you a fresh checkout in a few seconds into the new folder "pygments":
<pre>hg clone http://dev.pocoo.org/hg/pygments-main pygments</pre>
One thing you will notice is that it's incredible fast and even though the repository contains the whole history the checkout is pretty small. By the time I'm writing this blog post the pygments sourcecode including the unittests and example sourcecode without the revision history is 2.5MB. A complete mercurial checkout is only 5MB even though it includes 486 changesets.
After you got your very own repository by cloning the pygments one you will notice that all the subversion-like commands ("hg ci", "hg add", "hg up", ...) work locally only. You check into your local version of the repository and hg up won't incorporate remote changes. One of the things that happen on hg clone is that mercurial will set the path to the repository you cloned from into the hgrc of the newly created repository. This file (".hg/hgrc") is used to store per-repository configuration like the path of remote repositories, the name used for checkins, plugins that are only enabled for this repository and more. Executing "hg pull" will automatically pull changes from this remote repository and put them into the current repository as second branch. To see what "hg pull" will pull from that remote repository you can execute "hg incoming" and it will print a list of changesets that are in the remote repository but not yet in the local one. After you have pulled you have to update the repository with "hg up" so that you can actually see the changes. If there were remote changes that require merging you have to "hg merge" them and "hg ci" the merge.
Because this process is very common there are ways to simplify it. "hg pull && hg update" can be written as "hg pull -u". All the commands (pull, update, merge and checkin if required) can be handled in one go using "hg fe". This command however is part of a plugin which is disabled by default. If you want to use it you have to add the following lines into the repository hgrc or your personal one:
<pre>[extensions]
hgext.fetch=</pre>
The other important difference to subversion is how you push your changes back to the server. In open source projects usually only a small number of developers has access to the main repository and contributors create patches using "diff" or "svn diff" and mail it to one of the persons with commit rights or attach it to a ticket in the project's tracker. If you are a person with push privileges you can do "hg push" and it will push the changesets which are not yet on the server (you can look at them using "hg outgoing"). If you don't have push access you can create a bundle of changes and attach that to a ticket rather than a patch. A bundle stores multiple changesets in one file and it also preserves the correct author information and timestamps. Another way is mailing the changes to a different developer using the patchbomb extension (I won't cover that here, just google it up). Or you can let other people pull from your repository. Therefore you either have to configure your apache to server a hgweb instance or you just call "hg serve" and it will spawn a server on localhost:8000 everybody can pull from.
Once the developer has decided to put your changes into the central repository and pushed them, your changes will appear there unaltered and with the same revision hashes. What will be different is the local number the changeset is given. If the revision was called deadbeef:42 locally it could be called deadbeef:52 on the server because different changesets were applied first.
All the commands that interact with remote repositories ("hg pull", "hg push", "hg fe", ...) also take a different path than the default path from the hgrc as argument. This allows you to pull changes from repositories shared over the web.
A cool example what mercurial allows you to do is our last ubuntuusers webteam meetup. There we used my notebook to store the central repository and everybody pushed the changes every once in a while to it. Additionally some people exchanged patches to not yet working features among each other so that the code on the central repo was seldom broken. When I left everybody had all the changes locally because they pulled and I could remove my notebook and everybody continued working on their way home. When we met again on IRC I copied my repo on the server and everybody pushed their local changes to it.SQAAAANTAAAABGJvZHlSUwAAAC1Nb3JlIGFuZCBtb3JlIHByb2plY3RzIGFyZSBzd2l0Y2hpbmcg
b3ZlciB0byBMAANFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACFodHRwOi8vd3d3LnNlbGVuaWMu
Y29tL21lcmN1cmlhbC9TAAAACW1lcmN1cmlhbFMAAAonIG9yIHNpbWlsYXIgRFZDUy4gR3JlYXQg
YXMgbWVyY3VyaWFsIGlzLCBpdCdzIGhhcmQgdG8gZ2V0IHN0YXJ0ZWQgaWYgeW91IGFyZSB1c2Vk
IHRvIHN1YnZlcnNpb24gYmVjYXVzZSB0aGUgY29uY2VwdCBiZWhpbmQgU3VidmVyc2lvbiAoc3Zu
KSBhbmQgbWVyY3VyaWFsIChoZykgaXMgZnVuZGFtZW50YWxseSBkaWZmZXJlbnQuIFRoaXMgYXJ0
aWNsZSBzaG91bGQgaGVscCB5b3UgdW5kZXJzdGFuZCBob3cgbWVyY3VyaWFsIGFuZCBzaW1pbGFy
IHN5c3RlbXMgd29yayBhbmQgaG93IHlvdSBjYW4gdXNlIGl0IHRvIGNvbnRyaWJ1dGUgcGF0Y2hl
cyB0byB0aGUgcG9jb28gcHJvamVjdHMuCgpJZiB5b3UgY29tcGFyZSBTdWJ2ZXJzaW9uIHRvIG1l
cmN1cmlhbCB5b3Ugd29uJ3QgZmluZCB0aGF0IG1hbnkgc2ltaWxhcml0aWVzIGJlc2lkZSB0aGUg
Y29tbWFuZCBhcmd1bWVudHMuIFN1YnZlcnNpb24gd29ya3MgbGlrZSBGVFAgd2hlcmVhcyBtZXJj
dXJpYWwgaXMgYml0dG9ycmVudC4gSW4gU3VidmVyc2lvbiB0aGUgc2VydmVyIGlzIHNwZWNpYWw6
IGl0IGtlZXBzIGFsbCB0aGUgcmV2aXNpb24gbG9nIGFuZCBhbGwgdGhlIG9wZXJhdGlvbnMgcmVx
dWlyZSBhIGNvbm5lY3Rpb24gdG8gdGhpcyBzZXJ2ZXIuIEluIG1lcmN1cmlhbCBJIGNhbiB0YWtl
IGRvd24gdGhlIGNlbnRyYWwgcmVwb3NpdG9yeSBpZiB0aGVyZSBpcyBvbmUgYW4gYWxsIGRldmVs
b3BlcnMgd2lsbCBzdGlsbCBiZSBhYmxlIHRvIGV4Y2hhbmdlIGNoYW5nZXMuIEFsbCB0aGUgcmV2
aXNpb24gaW5mb3JtYXRpb24gaXMgYXZhaWxhYmxlIHRvIGFueW9uZSBhbmQgdGhlcmUgaXMgYWJz
b2x1dGVseSBubyBkaWZmZXJlbmNlIGJldHdlZW4gc2VydmVyIGFuZCBjbGllbnRzLgoKVGhpcyBm
dW5kYW1lbnRhbCBkZXNpZ24gZGVjaXNpb24gbWVhbnMgdGhhdCB0aGVyZSBhcmUgZG96ZW5zIG9m
IHNlcGFyYXRlIGJyYW5jaGVzIG9mIHRoZSBjb2RlLiBoZyBtYWtlcyBpdCBlYXN5IHRvIG1lcmdl
IGFuZCBicmFuY2ggYW5kIGl0J3MgZGV2ZWxvcGVkIGV4YWN0bHkgZm9yIHRoYXQuIEluIFN1YnZl
cnNpb24gYnJhbmNoaW5nIGFuZCBtZXJnaW5nIGlzIHBhaW5mdWwgYW4gb2Z0ZW4gcGVvcGxlIGp1
c3QgZG9uJ3QgYnJhbmNoIGFuZCBkb24ndCBjb21taXQgdGhlcmUgY2hhbmdlcyB1bnRpbCB0aGUg
dGVzdHN1aXRlIGV0Yy4gcGFzc2VzIGFnYWluIHdoaWNoIG9mIGNvdXJzZSByZXN1bHRzIGluIGh1
Z2UgY2hhbmdlc2V0cy4gQnV0IGxldCdzIHN0ZXAgcmlnaHQgaW50byBpdCEKClRoZSBmaXJzdCB0
aGluZyBpbiBTdWJ2ZXJzaW9uIHlvdSBkbyBpcyBlaXRoZXIgY3JlYXRpbmcgYSByZXBvc2l0b3J5
IG9uIHRoZSBzZXJ2ZXIgb3IgY2hlY2tpbmcgaXQgb3V0IG9uIHRoZSBjbGllbnQuIEluIGhnIHRo
ZXJlIGlzIG5vIGRpZmZlcmVuY2UgYmV0d2VlbiBzZXJ2ZXIgYW5kIGNsaWVudCBzbyB0aGUgcHJv
Y2VzcyBvZiBjcmVhdGluZyBhIHJlcG9zaXRvcnkgaXMgYXZhaWxhYmxlIHRvIGV2ZXJ5Ym9keS4g
Q3JlYXRpbmcgYSByZXBvc2l0b3J5IGlzIGp1c3QgYXMgc2ltcGxlIGFzIHR5cGluZyAiaGcgaW5p
dCBuYW1lX29mX3RoZV9yZXBvc2l0b3J5Ii4gSWYgdGhhdCBmb2xkZXIgZG9lcyBub3QgZXhpc3Qg
eWV0IGl0IHdpbGwgY3JlYXRlIGFuIGVtcHR5IGZvbGRlciBhbmQgaW5pdGlhbGl6ZSBpdCBhcyBy
b290IG9mIHRoZSByZXBvc2l0b3J5LCBvdGhlcndpc2UgaXQgd2lsbCBjcmVhdGUgdGhlIHJlcG9z
aXRvcnkgaW4gdGhlIG5hbWUgb2YgdGhhdCBmb2xkZXIuCgpUaGUgcHJvY2VzcyBvZiBjaGVja2lu
ZyBvdXQgaXMgYSBiaXQgZGlmZmVyZW50IGZyb20gU3VidmVyc2lvbiBiZWNhdXNlIGl0J3MgZWZm
ZWN0aXZlbHkgdGhlIHNhbWUgYXMgY3JlYXRpbmcgYSBicmFuY2guIFNheSB5b3Ugd2FudCB0byBj
aGVjayBvdXQgdGhlIGN1cnJlbnQgUHlnbWVudHMgdmVyc2lvbiB0byBkbyBzb21lIGNoYW5nZXMu
IFRoZSBmaXJzdCB0aGluZyB5b3Ugd2lsbCBkbyBpcyBsb29raW5nIGZvciBhIHdheSB0byBhY2Nl
c3MgdGhpcyByZXBvc2l0b3J5LiBUaGVyZSBhcmUgdGhyZWUgdmVyeSBjb21tb24gd2F5cyB0byBh
Y2Nlc3MgaXQ6IGZpbGVzeXN0ZW0sIEhUVFAgb3IgU1NILiBQeWdtZW50cyBpcyBhdmFpbGFibGUg
YXMgU1NIIGFuZCBIVFRQLCBidXQgZm9yIG5vbiBjb3JlIGRldmVsb3BlcnMgb25seSBIVFRQIGlz
IGF2YWlsYWJsZS4gSW50ZXJlc3RpbmdseSBxdWl0ZSBhIGZldyBwZW9wbGUgaGF2ZSBwcm9ibGVt
cyBsb2NhdGluZyB0aGUgY2hlY2tvdXQgVVJMIHdoaWNoIGlzIG5vdCB2ZXJ5IHN1cnByaXNpbmcg
YmVjYXVzZSBoZ3dlYiBoYW5kbGVzIHRoYXQuIGhnd2ViIGlzIHRoZSBzdGFuZGFyZCBtZXJjdXJp
YWwgd2ViIGludGVyZmFjZSB3aGljaCBkb2Vzbid0IG9ubHkgcHJvdmlkZSBhIHdheSB0byBsb29r
IGF0IHRoZSBjaGFuZ2VzZXRzIGFuZCB0cmVlIGJ1dCBhbHNvIGhhbmRsZXMgcGF0Y2ggZXhjaGFu
Z2UuIEluIHRoZSBjYXNlIG9mIFB5Z21lbnRzIHRoaXMgY29tbWFuZCBzaG91bGQgZ2l2ZSB5b3Ug
YSBmcmVzaCBjaGVja291dCBpbiBhIGZldyBzZWNvbmRzIGludG8gdGhlIG5ldyBmb2xkZXIgInB5
Z21lbnRzIjoKCkVTAAAAA3ByZUwAAE0AAFMAAAA3aGcgY2xvbmUgaHR0cDovL2Rldi5wb2Nvby5v
cmcvaGcvcHlnbWVudHMtbWFpbiBweWdtZW50c1MAAAedCgpPbmUgdGhpbmcgeW91IHdpbGwgbm90
aWNlIGlzIHRoYXQgaXQncyBpbmNyZWRpYmxlIGZhc3QgYW5kIGV2ZW4gdGhvdWdoIHRoZSByZXBv
c2l0b3J5IGNvbnRhaW5zIHRoZSB3aG9sZSBoaXN0b3J5IHRoZSBjaGVja291dCBpcyBwcmV0dHkg
c21hbGwuIEJ5IHRoZSB0aW1lIEknbSB3cml0aW5nIHRoaXMgYmxvZyBwb3N0IHRoZSBweWdtZW50
cyBzb3VyY2Vjb2RlIGluY2x1ZGluZyB0aGUgdW5pdHRlc3RzIGFuZCBleGFtcGxlIHNvdXJjZWNv
ZGUgd2l0aG91dCB0aGUgcmV2aXNpb24gaGlzdG9yeSBpcyAyLjVNQi4gQSBjb21wbGV0ZSBtZXJj
dXJpYWwgY2hlY2tvdXQgaXMgb25seSA1TUIgZXZlbiB0aG91Z2ggaXQgaW5jbHVkZXMgNDg2IGNo
YW5nZXNldHMuCgpBZnRlciB5b3UgZ290IHlvdXIgdmVyeSBvd24gcmVwb3NpdG9yeSBieSBjbG9u
aW5nIHRoZSBweWdtZW50cyBvbmUgeW91IHdpbGwgbm90aWNlIHRoYXQgYWxsIHRoZSBzdWJ2ZXJz
aW9uLWxpa2UgY29tbWFuZHMgKCJoZyBjaSIsICJoZyBhZGQiLCAiaGcgdXAiLCAuLi4pIHdvcmsg
bG9jYWxseSBvbmx5LiBZb3UgY2hlY2sgaW50byB5b3VyIGxvY2FsIHZlcnNpb24gb2YgdGhlIHJl
cG9zaXRvcnkgYW5kIGhnIHVwIHdvbid0IGluY29ycG9yYXRlIHJlbW90ZSBjaGFuZ2VzLiBPbmUg
b2YgdGhlIHRoaW5ncyB0aGF0IGhhcHBlbiBvbiBoZyBjbG9uZSBpcyB0aGF0IG1lcmN1cmlhbCB3
aWxsIHNldCB0aGUgcGF0aCB0byB0aGUgcmVwb3NpdG9yeSB5b3UgY2xvbmVkIGZyb20gaW50byB0
aGUgaGdyYyBvZiB0aGUgbmV3bHkgY3JlYXRlZCByZXBvc2l0b3J5LiBUaGlzIGZpbGUgKCIuaGcv
aGdyYyIpIGlzIHVzZWQgdG8gc3RvcmUgcGVyLXJlcG9zaXRvcnkgY29uZmlndXJhdGlvbiBsaWtl
IHRoZSBwYXRoIG9mIHJlbW90ZSByZXBvc2l0b3JpZXMsIHRoZSBuYW1lIHVzZWQgZm9yIGNoZWNr
aW5zLCBwbHVnaW5zIHRoYXQgYXJlIG9ubHkgZW5hYmxlZCBmb3IgdGhpcyByZXBvc2l0b3J5IGFu
ZCBtb3JlLiBFeGVjdXRpbmcgImhnIHB1bGwiIHdpbGwgYXV0b21hdGljYWxseSBwdWxsIGNoYW5n
ZXMgZnJvbSB0aGlzIHJlbW90ZSByZXBvc2l0b3J5IGFuZCBwdXQgdGhlbSBpbnRvIHRoZSBjdXJy
ZW50IHJlcG9zaXRvcnkgYXMgc2Vjb25kIGJyYW5jaC4gVG8gc2VlIHdoYXQgImhnIHB1bGwiIHdp
bGwgcHVsbCBmcm9tIHRoYXQgcmVtb3RlIHJlcG9zaXRvcnkgeW91IGNhbiBleGVjdXRlICJoZyBp
bmNvbWluZyIgYW5kIGl0IHdpbGwgcHJpbnQgYSBsaXN0IG9mIGNoYW5nZXNldHMgdGhhdCBhcmUg
aW4gdGhlIHJlbW90ZSByZXBvc2l0b3J5IGJ1dCBub3QgeWV0IGluIHRoZSBsb2NhbCBvbmUuIEFm
dGVyIHlvdSBoYXZlIHB1bGxlZCB5b3UgaGF2ZSB0byB1cGRhdGUgdGhlIHJlcG9zaXRvcnkgd2l0
aCAiaGcgdXAiIHNvIHRoYXQgeW91IGNhbiBhY3R1YWxseSBzZWUgdGhlIGNoYW5nZXMuIElmIHRo
ZXJlIHdlcmUgcmVtb3RlIGNoYW5nZXMgdGhhdCByZXF1aXJlIG1lcmdpbmcgeW91IGhhdmUgdG8g
ImhnIG1lcmdlIiB0aGVtIGFuZCAiaGcgY2kiIHRoZSBtZXJnZS4KCkJlY2F1c2UgdGhpcyBwcm9j
ZXNzIGlzIHZlcnkgY29tbW9uIHRoZXJlIGFyZSB3YXlzIHRvIHNpbXBsaWZ5IGl0LiAiaGcgcHVs
bCAmJiBoZyB1cGRhdGUiIGNhbiBiZSB3cml0dGVuIGFzICJoZyBwdWxsIC11Ii4gQWxsIHRoZSBj
b21tYW5kcyAocHVsbCwgdXBkYXRlLCBtZXJnZSBhbmQgY2hlY2tpbiBpZiByZXF1aXJlZCkgY2Fu
IGJlIGhhbmRsZWQgaW4gb25lIGdvIHVzaW5nICJoZyBmZSIuIFRoaXMgY29tbWFuZCBob3dldmVy
IGlzIHBhcnQgb2YgYSBwbHVnaW4gd2hpY2ggaXMgZGlzYWJsZWQgYnkgZGVmYXVsdC4gIElmIHlv
dSB3YW50IHRvIHVzZSBpdCB5b3UgaGF2ZSB0byBhZGQgdGhlIGZvbGxvd2luZyBsaW5lcyBpbnRv
IHRoZSByZXBvc2l0b3J5IGhncmMgb3IgeW91ciBwZXJzb25hbCBvbmU6CgpFUwAAAANwcmVMAABN
AABTAAAAGVtleHRlbnNpb25zXQpoZ2V4dC5mZXRjaD1TAAAJNAoKVGhlIG90aGVyIGltcG9ydGFu
dCBkaWZmZXJlbmNlIHRvIHN1YnZlcnNpb24gaXMgaG93IHlvdSBwdXNoIHlvdXIgY2hhbmdlcyBi
YWNrIHRvIHRoZSBzZXJ2ZXIuIEluIG9wZW4gc291cmNlIHByb2plY3RzIHVzdWFsbHkgb25seSBh
IHNtYWxsIG51bWJlciBvZiBkZXZlbG9wZXJzIGhhcyBhY2Nlc3MgdG8gdGhlIG1haW4gcmVwb3Np
dG9yeSBhbmQgY29udHJpYnV0b3JzIGNyZWF0ZSBwYXRjaGVzIHVzaW5nICJkaWZmIiBvciAic3Zu
IGRpZmYiIGFuZCBtYWlsIGl0IHRvIG9uZSBvZiB0aGUgcGVyc29ucyB3aXRoIGNvbW1pdCByaWdo
dHMgb3IgYXR0YWNoIGl0IHRvIGEgdGlja2V0IGluIHRoZSBwcm9qZWN0J3MgdHJhY2tlci4gSWYg
eW91IGFyZSBhIHBlcnNvbiB3aXRoIHB1c2ggcHJpdmlsZWdlcyB5b3UgY2FuIGRvICJoZyBwdXNo
IiBhbmQgaXQgd2lsbCBwdXNoIHRoZSBjaGFuZ2VzZXRzIHdoaWNoIGFyZSBub3QgeWV0IG9uIHRo
ZSBzZXJ2ZXIgKHlvdSBjYW4gbG9vayBhdCB0aGVtIHVzaW5nICJoZyBvdXRnb2luZyIpLiBJZiB5
b3UgZG9uJ3QgaGF2ZSBwdXNoIGFjY2VzcyB5b3UgY2FuIGNyZWF0ZSBhIGJ1bmRsZSBvZiBjaGFu
Z2VzIGFuZCBhdHRhY2ggdGhhdCB0byBhIHRpY2tldCByYXRoZXIgdGhhbiBhIHBhdGNoLiBBIGJ1
bmRsZSBzdG9yZXMgbXVsdGlwbGUgY2hhbmdlc2V0cyBpbiBvbmUgZmlsZSBhbmQgaXQgYWxzbyBw
cmVzZXJ2ZXMgdGhlIGNvcnJlY3QgYXV0aG9yIGluZm9ybWF0aW9uIGFuZCB0aW1lc3RhbXBzLiBB
bm90aGVyIHdheSBpcyBtYWlsaW5nIHRoZSBjaGFuZ2VzIHRvIGEgZGlmZmVyZW50IGRldmVsb3Bl
ciB1c2luZyB0aGUgcGF0Y2hib21iIGV4dGVuc2lvbiAoSSB3b24ndCBjb3ZlciB0aGF0IGhlcmUs
IGp1c3QgZ29vZ2xlIGl0IHVwKS4gT3IgeW91IGNhbiBsZXQgb3RoZXIgcGVvcGxlIHB1bGwgZnJv
bSB5b3VyIHJlcG9zaXRvcnkuIFRoZXJlZm9yZSB5b3UgZWl0aGVyIGhhdmUgdG8gY29uZmlndXJl
IHlvdXIgYXBhY2hlIHRvIHNlcnZlciBhIGhnd2ViIGluc3RhbmNlIG9yIHlvdSBqdXN0IGNhbGwg
ImhnIHNlcnZlIiBhbmQgaXQgd2lsbCBzcGF3biBhIHNlcnZlciBvbiBsb2NhbGhvc3Q6ODAwMCBl
dmVyeWJvZHkgY2FuIHB1bGwgZnJvbS4KCk9uY2UgdGhlIGRldmVsb3BlciBoYXMgZGVjaWRlZCB0
byBwdXQgeW91ciBjaGFuZ2VzIGludG8gdGhlIGNlbnRyYWwgcmVwb3NpdG9yeSBhbmQgcHVzaGVk
IHRoZW0sIHlvdXIgY2hhbmdlcyB3aWxsIGFwcGVhciB0aGVyZSB1bmFsdGVyZWQgYW5kIHdpdGgg
dGhlIHNhbWUgcmV2aXNpb24gaGFzaGVzLiBXaGF0IHdpbGwgYmUgZGlmZmVyZW50IGlzIHRoZSBs
b2NhbCBudW1iZXIgdGhlIGNoYW5nZXNldCBpcyBnaXZlbi4gSWYgdGhlIHJldmlzaW9uIHdhcyBj
YWxsZWQgZGVhZGJlZWY6NDIgbG9jYWxseSBpdCBjb3VsZCBiZSBjYWxsZWQgZGVhZGJlZWY6NTIg
b24gdGhlIHNlcnZlciBiZWNhdXNlIGRpZmZlcmVudCBjaGFuZ2VzZXRzIHdlcmUgYXBwbGllZCBm
aXJzdC4KCkFsbCB0aGUgY29tbWFuZHMgdGhhdCBpbnRlcmFjdCB3aXRoIHJlbW90ZSByZXBvc2l0
b3JpZXMgKCJoZyBwdWxsIiwgImhnIHB1c2giLCAiaGcgZmUiLCAuLi4pIGFsc28gdGFrZSBhIGRp
ZmZlcmVudCBwYXRoIHRoYW4gdGhlIGRlZmF1bHQgcGF0aCBmcm9tIHRoZSBoZ3JjIGFzIGFyZ3Vt
ZW50LiBUaGlzIGFsbG93cyB5b3UgdG8gcHVsbCBjaGFuZ2VzIGZyb20gcmVwb3NpdG9yaWVzIHNo
YXJlZCBvdmVyIHRoZSB3ZWIuCgpBIGNvb2wgZXhhbXBsZSB3aGF0IG1lcmN1cmlhbCBhbGxvd3Mg
eW91IHRvIGRvIGlzIG91ciBsYXN0IHVidW50dXVzZXJzIHdlYnRlYW0gbWVldHVwLiBUaGVyZSB3
ZSB1c2VkIG15IG5vdGVib29rIHRvIHN0b3JlIHRoZSBjZW50cmFsIHJlcG9zaXRvcnkgYW5kIGV2
ZXJ5Ym9keSBwdXNoZWQgdGhlIGNoYW5nZXMgZXZlcnkgb25jZSBpbiBhIHdoaWxlIHRvIGl0LiBB
ZGRpdGlvbmFsbHkgc29tZSBwZW9wbGUgZXhjaGFuZ2VkIHBhdGNoZXMgdG8gbm90IHlldCB3b3Jr
aW5nIGZlYXR1cmVzIGFtb25nIGVhY2ggb3RoZXIgc28gdGhhdCB0aGUgY29kZSBvbiB0aGUgY2Vu
dHJhbCByZXBvIHdhcyBzZWxkb20gYnJva2VuLiBXaGVuIEkgbGVmdCBldmVyeWJvZHkgaGFkIGFs
bCB0aGUgY2hhbmdlcyBsb2NhbGx5IGJlY2F1c2UgdGhleSBwdWxsZWQgYW5kIEkgY291bGQgcmVt
b3ZlIG15IG5vdGVib29rIGFuZCBldmVyeWJvZHkgY29udGludWVkIHdvcmtpbmcgb24gdGhlaXIg
d2F5IGhvbWUuIFdoZW4gd2UgbWV0IGFnYWluIG9uIElSQyBJIGNvcGllZCBteSByZXBvIG9uIHRo
ZSBzZXJ2ZXIgYW5kIGV2ZXJ5Ym9keSBwdXNoZWQgdGhlaXIgbG9jYWwgY2hhbmdlcyB0byBpdC5T
AAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Horst Gutmannzerok@zerokspot.comhttp://zerokspot.com2008-01-28T20:20:49Znono0Very nice primer :-) It would really be nice to see more projects using DVCS and if it's just to make it easier for outsiders to contribute whole changesets instead of just patches which they won't get the full credits.
Btw.: Are you coming the the BarCamp in Klagenfurt this weekend? Would be a really nice presentation :-)Very nice primer :-) It would really be nice to see more projects using DVCS and if it's just to make it easier for outsiders to contribute whole changesets instead of just patches which they won't get the full credits.
Btw.: Are you coming the the BarCamp in Klagenfurt this weekend? Would be a really nice presentation :-)SQAAAAJTAAAABGJvZHlSUwAAAUVWZXJ5IG5pY2UgcHJpbWVyIDotKSBJdCB3b3VsZCByZWFsbHkg
YmUgbmljZSB0byBzZWUgbW9yZSBwcm9qZWN0cyB1c2luZyBEVkNTIGFuZCBpZiBpdCdzIGp1c3Qg
dG8gbWFrZSBpdCBlYXNpZXIgZm9yIG91dHNpZGVycyB0byBjb250cmlidXRlIHdob2xlIGNoYW5n
ZXNldHMgaW5zdGVhZCBvZiBqdXN0IHBhdGNoZXMgd2hpY2ggdGhleSB3b24ndCBnZXQgdGhlIGZ1
bGwgY3JlZGl0cy4KCkJ0dy46IEFyZSB5b3UgY29taW5nIHRoZSB0aGUgQmFyQ2FtcCBpbiBLbGFn
ZW5mdXJ0IHRoaXMgd2Vla2VuZD8gV291bGQgYmUgYSByZWFsbHkgbmljZSBwcmVzZW50YXRpb24g
Oi0pTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Christoph Hackchristoph@tux21b.orghttp://www.tux21b.org/2008-01-28T20:34:56Znono0Yeah, I am very impressed by mercurial too. Additionally to the main Ubuntuusers repository I have set up another on my server and now I can develop on different hosts, without altering the main one, but everybody can push if needed.
And on our meeting (which was also really awesome *g*) there where up to 10 different branches at the same time, and we continued editing the same files simultaneously and I only had to fix a conflict once. And even then, manually merging was much nicer than in subversion, because there weren't 3 different files and mercurial asks directly while merging the the branches.
Furthermore the speed of the VCS transactions where also unfamiliarly fast, so lets stick with mercurial.
Regards
ChristophYeah, I am very impressed by mercurial too. Additionally to the main Ubuntuusers repository I have set up another on my server and now I can develop on different hosts, without altering the main one, but everybody can push if needed.
And on our meeting (which was also really awesome *g*) there where up to 10 different branches at the same time, and we continued editing the same files simultaneously and I only had to fix a conflict once. And even then, manually merging was much nicer than in subversion, because there weren't 3 different files and mercurial asks directly while merging the the branches.
Furthermore the speed of the VCS transactions where also unfamiliarly fast, so lets stick with mercurial.
Regards
ChristophSQAAAAJTAAAABGJvZHlSUwAAAt5ZZWFoLCBJIGFtIHZlcnkgaW1wcmVzc2VkIGJ5IG1lcmN1cmlh
bCB0b28uIEFkZGl0aW9uYWxseSB0byB0aGUgbWFpbiBVYnVudHV1c2VycyByZXBvc2l0b3J5IEkg
aGF2ZSBzZXQgdXAgYW5vdGhlciBvbiBteSBzZXJ2ZXIgYW5kIG5vdyBJIGNhbiBkZXZlbG9wIG9u
IGRpZmZlcmVudCBob3N0cywgd2l0aG91dCBhbHRlcmluZyB0aGUgbWFpbiBvbmUsIGJ1dCBldmVy
eWJvZHkgY2FuIHB1c2ggaWYgbmVlZGVkLgoKQW5kIG9uIG91ciBtZWV0aW5nICh3aGljaCB3YXMg
YWxzbyByZWFsbHkgYXdlc29tZSAqZyopIHRoZXJlIHdoZXJlIHVwIHRvIDEwIGRpZmZlcmVudCBi
cmFuY2hlcyBhdCB0aGUgc2FtZSB0aW1lLCBhbmQgd2UgY29udGludWVkIGVkaXRpbmcgdGhlIHNh
bWUgZmlsZXMgc2ltdWx0YW5lb3VzbHkgYW5kIEkgb25seSBoYWQgdG8gZml4IGEgY29uZmxpY3Qg
b25jZS4gQW5kIGV2ZW4gdGhlbiwgbWFudWFsbHkgbWVyZ2luZyB3YXMgbXVjaCBuaWNlciB0aGFu
IGluIHN1YnZlcnNpb24sIGJlY2F1c2UgdGhlcmUgd2VyZW4ndCAzIGRpZmZlcmVudCBmaWxlcyBh
bmQgbWVyY3VyaWFsIGFza3MgZGlyZWN0bHkgd2hpbGUgbWVyZ2luZyB0aGUgdGhlIGJyYW5jaGVz
LgoKRnVydGhlcm1vcmUgdGhlIHNwZWVkIG9mIHRoZSBWQ1MgdHJhbnNhY3Rpb25zIHdoZXJlIGFs
c28gdW5mYW1pbGlhcmx5IGZhc3QsIHNvIGxldHMgc3RpY2sgd2l0aCBtZXJjdXJpYWwuCgpSZWdh
cmRzCkNocmlzdG9waEwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Ericeric.nilsson@slaskpost.se2008-01-28T20:43:08Znono0Just one question, i think you did expect it.. :) Why not git? like the hacker you are how could you not be convinced by torvalds google talk (youtube it)!Just one question, i think you did expect it.. :) Why not git? like the hacker you are how could you not be convinced by torvalds google talk (youtube it)!SQAAAAJTAAAABGJvZHlSUwAAAJtKdXN0IG9uZSBxdWVzdGlvbiwgaSB0aGluayB5b3UgZGlkIGV4
cGVjdCBpdC4uIDopIFdoeSBub3QgZ2l0PyBsaWtlIHRoZSBoYWNrZXIgeW91IGFyZSBob3cgY291
bGQgeW91IG5vdCBiZSBjb252aW5jZWQgYnkgdG9ydmFsZHMgZ29vZ2xlIHRhbGsgKHlvdXR1YmUg
aXQpIUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-28T20:51:41Znono0@Horst Gutmann: Yes, I will be there. I would love to talk about DVCS systems, however there is already a talk about that topic on the proposal list.
@Eric: Both git and mercurial are very nice systems. The reason why I'm currently more interested in mercurial is the fact that it runs on all three systems I use (linux, os x, windows) without many hacks, and that it's written in Python :-)@Horst Gutmann: Yes, I will be there. I would love to talk about DVCS systems, however there is already a talk about that topic on the proposal list.
@Eric: Both git and mercurial are very nice systems. The reason why I'm currently more interested in mercurial is the fact that it runs on all three systems I use (linux, os x, windows) without many hacks, and that it's written in Python :-)SQAAAAJTAAAABGJvZHlSUwAAAYhASG9yc3QgR3V0bWFubjogWWVzLCBJIHdpbGwgYmUgdGhlcmUu
IEkgd291bGQgbG92ZSB0byB0YWxrIGFib3V0IERWQ1Mgc3lzdGVtcywgaG93ZXZlciB0aGVyZSBp
cyBhbHJlYWR5IGEgdGFsayBhYm91dCB0aGF0IHRvcGljIG9uIHRoZSBwcm9wb3NhbCBsaXN0LgoK
QEVyaWM6IEJvdGggZ2l0IGFuZCBtZXJjdXJpYWwgYXJlIHZlcnkgbmljZSBzeXN0ZW1zLiBUaGUg
cmVhc29uIHdoeSBJJ20gY3VycmVudGx5IG1vcmUgaW50ZXJlc3RlZCBpbiBtZXJjdXJpYWwgaXMg
dGhlIGZhY3QgdGhhdCBpdCBydW5zIG9uIGFsbCB0aHJlZSBzeXN0ZW1zIEkgdXNlIChsaW51eCwg
b3MgeCwgd2luZG93cykgd2l0aG91dCBtYW55IGhhY2tzLCBhbmQgdGhhdCBpdCdzIHdyaXR0ZW4g
aW4gUHl0aG9uIDotKUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Eric Florenzanofloguy@gmail.comhttp://www.eflorenzano.com/2008-01-28T21:30:07Znono0@Armin's Comment 4: In that case, did you check out Bazaar? I've tried both, and neither one really seemed much better than the other, but Bazaar is supposedly better at complex merges.@Armin's Comment 4: In that case, did you check out Bazaar? I've tried both, and neither one really seemed much better than the other, but Bazaar is supposedly better at complex merges.SQAAAAJTAAAABGJvZHlSUwAAALpAQXJtaW4ncyBDb21tZW50IDQ6IEluIHRoYXQgY2FzZSwgZGlk
IHlvdSBjaGVjayBvdXQgQmF6YWFyPyAgSSd2ZSB0cmllZCBib3RoLCBhbmQgbmVpdGhlciBvbmUg
cmVhbGx5IHNlZW1lZCBtdWNoIGJldHRlciB0aGFuIHRoZSBvdGhlciwgYnV0IEJhemFhciBpcyBz
dXBwb3NlZGx5IGJldHRlciBhdCBjb21wbGV4IG1lcmdlcy5MAABTAAAABnBhcnNlclMAAAAEaHRt
bA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-28T21:43:07Znono0Well, there are many DVCS, I selected mercurial ;-) Feel free to use bzr, git, darcs or whatever, they are all nice systems and have their own advantages and disadvantages. The reasons why I personally use mercurial are speed, the good community and support, the trac integration, the helpful channel and the good windows/os x support beside linux.Well, there are many DVCS, I selected mercurial ;-) Feel free to use bzr, git, darcs or whatever, they are all nice systems and have their own advantages and disadvantages. The reasons why I personally use mercurial are speed, the good community and support, the trac integration, the helpful channel and the good windows/os x support beside linux.SQAAAAJTAAAABGJvZHlSUwAAAVxXZWxsLCB0aGVyZSBhcmUgbWFueSBEVkNTLCBJIHNlbGVjdGVk
IG1lcmN1cmlhbCA7LSkgRmVlbCBmcmVlIHRvIHVzZSBienIsIGdpdCwgZGFyY3Mgb3Igd2hhdGV2
ZXIsIHRoZXkgYXJlIGFsbCBuaWNlIHN5c3RlbXMgYW5kIGhhdmUgdGhlaXIgb3duIGFkdmFudGFn
ZXMgYW5kIGRpc2FkdmFudGFnZXMuIFRoZSByZWFzb25zIHdoeSBJIHBlcnNvbmFsbHkgdXNlIG1l
cmN1cmlhbCBhcmUgc3BlZWQsIHRoZSBnb29kIGNvbW11bml0eSBhbmQgc3VwcG9ydCwgdGhlIHRy
YWMgaW50ZWdyYXRpb24sIHRoZSBoZWxwZnVsIGNoYW5uZWwgYW5kIHRoZSBnb29kIHdpbmRvd3Mv
b3MgeCBzdXBwb3J0IGJlc2lkZSBsaW51eC5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Horst Gutmannzerok@zerokspot.comhttp://zerokspot.com2008-01-28T21:47:46Znono0@Armin: That's mine and I just killed that ;-) So the slot should be free again :-) If you're interested we could also convert this in some kind of discussion to find out what other people are using to perhaps find some best practices.
@Eric: I've tried using bzr every once in a while but ever time switched back to hg simply because of the far better performance. The only downside hg currently has for me is a replication "bug" that makes mercurial store a new copy of a file whenever it is renamed which might or might not be relevant depending on the project: http://www.selenic.com/mercurial/bts/issue883@Armin: That's mine and I just killed that ;-) So the slot should be free again :-) If you're interested we could also convert this in some kind of discussion to find out what other people are using to perhaps find some best practices.
@Eric: I've tried using bzr every once in a while but ever time switched back to hg simply because of the far better performance. The only downside hg currently has for me is a replication "bug" that makes mercurial store a new copy of a file whenever it is renamed which might or might not be relevant depending on the project: http://www.selenic.com/mercurial/bts/issue883SQAAAAJTAAAABGJvZHlSUwAAAmNAQXJtaW46IFRoYXQncyBtaW5lIGFuZCBJIGp1c3Qga2lsbGVk
IHRoYXQgOy0pIFNvIHRoZSBzbG90IHNob3VsZCBiZSBmcmVlIGFnYWluIDotKSBJZiB5b3UncmUg
aW50ZXJlc3RlZCB3ZSBjb3VsZCBhbHNvIGNvbnZlcnQgdGhpcyBpbiBzb21lIGtpbmQgb2YgZGlz
Y3Vzc2lvbiB0byBmaW5kIG91dCB3aGF0IG90aGVyIHBlb3BsZSBhcmUgdXNpbmcgdG8gcGVyaGFw
cyBmaW5kIHNvbWUgYmVzdCBwcmFjdGljZXMuCgpARXJpYzogSSd2ZSB0cmllZCB1c2luZyBienIg
ZXZlcnkgb25jZSBpbiBhIHdoaWxlIGJ1dCBldmVyIHRpbWUgc3dpdGNoZWQgYmFjayB0byBoZyBz
aW1wbHkgYmVjYXVzZSBvZiB0aGUgZmFyIGJldHRlciBwZXJmb3JtYW5jZS4gVGhlIG9ubHkgZG93
bnNpZGUgaGcgY3VycmVudGx5IGhhcyBmb3IgbWUgaXMgYSByZXBsaWNhdGlvbiAiYnVnIiB0aGF0
IG1ha2VzIG1lcmN1cmlhbCBzdG9yZSBhIG5ldyBjb3B5IG9mIGEgZmlsZSB3aGVuZXZlciBpdCBp
cyByZW5hbWVkIHdoaWNoIG1pZ2h0IG9yIG1pZ2h0IG5vdCBiZSByZWxldmFudCBkZXBlbmRpbmcg
b24gdGhlIHByb2plY3Q6IGh0dHA6Ly93d3cuc2VsZW5pYy5jb20vbWVyY3VyaWFsL2J0cy9pc3N1
ZTg4M0wAAFMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-28T22:01:07Znono0@Horst: Who do I have to talk to if I want to occupy that slot? And which is it? :-)@Horst: Who do I have to talk to if I want to occupy that slot? And which is it? :-)SQAAAAJTAAAABGJvZHlSUwAAAFRASG9yc3Q6IFdobyBkbyBJIGhhdmUgdG8gdGFsayB0byBpZiBJ
IHdhbnQgdG8gb2NjdXB5IHRoYXQgc2xvdD8gQW5kIHdoaWNoIGlzIGl0PyA6LSlMAABTAAAABnBh
cnNlclMAAAAEaHRtbA==
Horst Gutmannzerok@zerokspot.comhttp://zerokspot.com2008-01-29T06:59:15Znono0No one. Just add your proposal to the proposal list and take a slot in the schedule if you want. I guess the whole "who gets what timeslot" will be decided sometime on Saturday before the first presentation ;-)No one. Just add your proposal to the proposal list and take a slot in the schedule if you want. I guess the whole "who gets what timeslot" will be decided sometime on Saturday before the first presentation ;-)SQAAAAJTAAAABGJvZHlSUwAAANJObyBvbmUuIEp1c3QgYWRkIHlvdXIgcHJvcG9zYWwgdG8gdGhl
IHByb3Bvc2FsIGxpc3QgYW5kIHRha2UgYSBzbG90IGluIHRoZSBzY2hlZHVsZSBpZiB5b3Ugd2Fu
dC4gSSBndWVzcyB0aGUgd2hvbGUgIndobyBnZXRzIHdoYXQgdGltZXNsb3QiIHdpbGwgYmUgZGVj
aWRlZCBzb21ldGltZSBvbiBTYXR1cmRheSBiZWZvcmUgdGhlIGZpcnN0IHByZXNlbnRhdGlvbiA7
LSlMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Stunosp@mplea.se2008-01-29T11:55:21Znono0I don't know why people forget linking these days. The whole blog post contains not one single link. I had to google mercurial. Sigh.I don't know why people forget linking these days. The whole blog post contains not one single link. I had to google mercurial. Sigh.SQAAAAJTAAAABGJvZHlSUwAAAIVJIGRvbid0IGtub3cgd2h5IHBlb3BsZSBmb3JnZXQgbGlua2lu
ZyB0aGVzZSBkYXlzLiBUaGUgd2hvbGUgYmxvZyBwb3N0IGNvbnRhaW5zIG5vdCBvbmUgc2luZ2xl
IGxpbmsuIEkgaGFkIHRvIGdvb2dsZSBtZXJjdXJpYWwuIFNpZ2guTAAAUwAAAAZwYXJzZXJTAAAA
BGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-29T13:56:28Znono0@10: added the Link, sorry for that ;-)@10: added the Link, sorry for that ;-)SQAAAAJTAAAABGJvZHlSUwAAACdAMTA6IGFkZGVkIHRoZSBMaW5rLCBzb3JyeSBmb3IgdGhhdCA7
LSlMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Ray Gardnerraygard@gmail.com2008-01-30T22:19:55Znono0I looked briefly at Hg a few weeks ago for a project I'm working on. For my project, it's important to maintain the timestamps on files as they are edited. It seemed to me that when I cloned, files got all new timestamps. Is there a switch or config option for Hg to make it preserve timestamps of files, so that when they're checked out they have the same time as when they were checked in (modulo the resolution that Python keeps file times at)? Am I missing something?I looked briefly at Hg a few weeks ago for a project I'm working on. For my project, it's important to maintain the timestamps on files as they are edited. It seemed to me that when I cloned, files got all new timestamps. Is there a switch or config option for Hg to make it preserve timestamps of files, so that when they're checked out they have the same time as when they were checked in (modulo the resolution that Python keeps file times at)? Am I missing something?SQAAAAJTAAAABGJvZHlSUwAAAddJIGxvb2tlZCBicmllZmx5IGF0IEhnIGEgZmV3IHdlZWtzIGFn
byBmb3IgYSBwcm9qZWN0IEknbSB3b3JraW5nIG9uLiBGb3IgbXkgcHJvamVjdCwgaXQncyBpbXBv
cnRhbnQgdG8gbWFpbnRhaW4gdGhlIHRpbWVzdGFtcHMgb24gZmlsZXMgYXMgdGhleSBhcmUgZWRp
dGVkLiBJdCBzZWVtZWQgdG8gbWUgdGhhdCB3aGVuIEkgY2xvbmVkLCBmaWxlcyBnb3QgYWxsIG5l
dyB0aW1lc3RhbXBzLiBJcyB0aGVyZSBhIHN3aXRjaCBvciBjb25maWcgb3B0aW9uIGZvciBIZyB0
byBtYWtlIGl0IHByZXNlcnZlIHRpbWVzdGFtcHMgb2YgZmlsZXMsIHNvIHRoYXQgd2hlbiB0aGV5
J3JlIGNoZWNrZWQgb3V0IHRoZXkgaGF2ZSB0aGUgc2FtZSB0aW1lIGFzIHdoZW4gdGhleSB3ZXJl
IGNoZWNrZWQgaW4gKG1vZHVsbyB0aGUgcmVzb2x1dGlvbiB0aGF0IFB5dGhvbiBrZWVwcyBmaWxl
IHRpbWVzIGF0KT8gQW0gSSBtaXNzaW5nIHNvbWV0aGluZz9MAABTAAAABnBhcnNlclMAAAAEaHRt
bA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-30T22:56:12Znono0Na, mercurial doesn't track the timestamps of the files. I don't know if there is any distributed system that allows that.Na, mercurial doesn't track the timestamps of the files. I don't know if there is any distributed system that allows that.SQAAAAJTAAAABGJvZHlSUwAAAHpOYSwgbWVyY3VyaWFsIGRvZXNuJ3QgdHJhY2sgdGhlIHRpbWVz
dGFtcHMgb2YgdGhlIGZpbGVzLiBJIGRvbid0IGtub3cgaWYgdGhlcmUgaXMgYW55IGRpc3RyaWJ1
dGVkIHN5c3RlbSB0aGF0IGFsbG93cyB0aGF0LkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-30T23:00:03Znono0Okay, I was wrong I think. Here is a FAQ entry about that issue: http://www.selenic.com/mercurial/wiki/index.cgi/FAQOkay, I was wrong I think. Here is a FAQ entry about that issue: http://www.selenic.com/mercurial/wiki/index.cgi/FAQSQAAAAJTAAAABGJvZHlSUwAAAHRPa2F5LCBJIHdhcyB3cm9uZyBJIHRoaW5rLiBIZXJlIGlzIGEg
RkFRIGVudHJ5IGFib3V0IHRoYXQgaXNzdWU6IGh0dHA6Ly93d3cuc2VsZW5pYy5jb20vbWVyY3Vy
aWFsL3dpa2kvaW5kZXguY2dpL0ZBUUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
ubuntuusers Webteam Meetinghttp://lucumr.pocoo.org/cogitations/2008/01/28/ubuntuusers-webteam-meeting/2008-01-28T15:26:03Z2008-01-28T15:26:03ZArmin Ronacherubuntuusers-webteam-meetingyesyes2The last four days I attended <a href="http://www.ubuntuusers.de/">our</a> first offline-webteam meeting and it was fun ;-) We spend a few days hacking on various parts of the ubuntuusers software and had a great time. While it's pointless to talk about what we did because hacking on broken code is not that much fun as such (unless you can laugh about PHP bugs and stuff like that) I think we can present some of the changes with the upcoming hardy release.
Don't expect too much but that shows that we are doing something even if you think development on the German portal software is stalled. That's certainly not the case.
But we are once again looking for web designers. The sourcecode is multilingual and the development takes place in both German and English for potential future translations to other languages than German, so you can participate even if you are not speaking German :-) If you are interested in participating and if you have advanced XHTML1/HTML4/CSS2 skills, we want you for ubuntuusers webteam!
If you are interested mail me at mitsuhiko you know what comes next ubuntu dot com.The last four days I attended <a href="http://www.ubuntuusers.de/">our</a> first offline-webteam meeting and it was fun ;-) We spend a few days hacking on various parts of the ubuntuusers software and had a great time. While it's pointless to talk about what we did because hacking on broken code is not that much fun as such (unless you can laugh about PHP bugs and stuff like that) I think we can present some of the changes with the upcoming hardy release.
Don't expect too much but that shows that we are doing something even if you think development on the German portal software is stalled. That's certainly not the case.
But we are once again looking for web designers. The sourcecode is multilingual and the development takes place in both German and English for potential future translations to other languages than German, so you can participate even if you are not speaking German :-) If you are interested in participating and if you have advanced XHTML1/HTML4/CSS2 skills, we want you for ubuntuusers webteam!
If you are interested mail me at mitsuhiko you know what comes next ubuntu dot com.SQAAAANTAAAABGJvZHlSUwAAAB5UaGUgbGFzdCBmb3VyIGRheXMgSSBhdHRlbmRlZCBMAAFFUwAA
AAFhTAAATQABUwAAAARocmVmUwAAABpodHRwOi8vd3d3LnVidW50dXVzZXJzLmRlL1MAAAADb3Vy
UwAABAsgZmlyc3Qgb2ZmbGluZS13ZWJ0ZWFtIG1lZXRpbmcgYW5kIGl0IHdhcyBmdW4gOy0pIFdl
IHNwZW5kIGEgZmV3IGRheXMgaGFja2luZyBvbiB2YXJpb3VzIHBhcnRzIG9mIHRoZSB1YnVudHV1
c2VycyBzb2Z0d2FyZSBhbmQgaGFkIGEgZ3JlYXQgdGltZS4gV2hpbGUgaXQncyBwb2ludGxlc3Mg
dG8gdGFsayBhYm91dCB3aGF0IHdlIGRpZCBiZWNhdXNlIGhhY2tpbmcgb24gYnJva2VuIGNvZGUg
aXMgbm90IHRoYXQgbXVjaCBmdW4gYXMgc3VjaCAodW5sZXNzIHlvdSBjYW4gbGF1Z2ggYWJvdXQg
UEhQIGJ1Z3MgYW5kIHN0dWZmIGxpa2UgdGhhdCkgSSB0aGluayB3ZSBjYW4gcHJlc2VudCBzb21l
IG9mIHRoZSBjaGFuZ2VzIHdpdGggdGhlIHVwY29taW5nIGhhcmR5IHJlbGVhc2UuCgpEb24ndCBl
eHBlY3QgdG9vIG11Y2ggYnV0IHRoYXQgc2hvd3MgdGhhdCB3ZSBhcmUgZG9pbmcgc29tZXRoaW5n
IGV2ZW4gaWYgeW91IHRoaW5rIGRldmVsb3BtZW50IG9uIHRoZSBHZXJtYW4gcG9ydGFsIHNvZnR3
YXJlIGlzIHN0YWxsZWQuIFRoYXQncyBjZXJ0YWlubHkgbm90IHRoZSBjYXNlLgoKQnV0IHdlIGFy
ZSBvbmNlIGFnYWluIGxvb2tpbmcgZm9yIHdlYiBkZXNpZ25lcnMuIFRoZSBzb3VyY2Vjb2RlIGlz
IG11bHRpbGluZ3VhbCBhbmQgdGhlIGRldmVsb3BtZW50IHRha2VzIHBsYWNlIGluIGJvdGggR2Vy
bWFuIGFuZCBFbmdsaXNoIGZvciBwb3RlbnRpYWwgZnV0dXJlIHRyYW5zbGF0aW9ucyB0byBvdGhl
ciBsYW5ndWFnZXMgdGhhbiBHZXJtYW4sIHNvIHlvdSBjYW4gcGFydGljaXBhdGUgZXZlbiBpZiB5
b3UgYXJlIG5vdCBzcGVha2luZyBHZXJtYW4gOi0pIElmIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBw
YXJ0aWNpcGF0aW5nIGFuZCBpZiB5b3UgaGF2ZSBhZHZhbmNlZCBYSFRNTDEvSFRNTDQvQ1NTMiBz
a2lsbHMsIHdlIHdhbnQgeW91IGZvciB1YnVudHV1c2VycyB3ZWJ0ZWFtIQoKSWYgeW91IGFyZSBp
bnRlcmVzdGVkIG1haWwgbWUgYXQgbWl0c3VoaWtvIHlvdSBrbm93IHdoYXQgY29tZXMgbmV4dCB1
YnVudHUgZG90IGNvbS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
No…http://lucumr.pocoo.org/cogitations/2008/01/23/no/2008-01-23T22:31:07Z2008-01-23T22:31:07ZArmin Ronachernoyesyes2<a href="http://diveintomark.org/archives/2008/01/23/microsoft-koan">I</a> <a href="http://blogs.msdn.com/ie/archive/2008/01/21/compatibility-and-ie8.aspx">will</a> <a href="http://annevankesteren.nl/2008/01/ie-lock-in">not</a> <a href="http://weblogs.mozillazine.org/roc/archives/2008/01/post_2.html">blog</a> <a href="http://weblogs.mozillazine.org/roc/archives/2008/01/slipping_the_ba.html">about</a> <a href="http://webkit.org/blog/155/versioning-compatibility-and-standards/">it</a>, <a href="http://dean.edwards.name/weblog/2008/01/quotes/">because</a> <a href="http://www.b-list.org/weblog/2008/jan/23/legacy/">it</a> <a href="http://ajaxian.com/archives/ie8-compatibility-with-x-ua-compatible">just</a> <a href="http://alistapart.com/articles/beyonddoctype">sucks</a>.<a href="http://diveintomark.org/archives/2008/01/23/microsoft-koan">I</a> <a href="http://blogs.msdn.com/ie/archive/2008/01/21/compatibility-and-ie8.aspx">will</a> <a href="http://annevankesteren.nl/2008/01/ie-lock-in">not</a> <a href="http://weblogs.mozillazine.org/roc/archives/2008/01/post_2.html">blog</a> <a href="http://weblogs.mozillazine.org/roc/archives/2008/01/slipping_the_ba.html">about</a> <a href="http://webkit.org/blog/155/versioning-compatibility-and-standards/">it</a>, <a href="http://dean.edwards.name/weblog/2008/01/quotes/">because</a> <a href="http://www.b-list.org/weblog/2008/jan/23/legacy/">it</a> <a href="http://ajaxian.com/archives/ie8-compatibility-with-x-ua-compatible">just</a> <a href="http://alistapart.com/articles/beyonddoctype">sucks</a>.SQAAAANTAAAABGJvZHlSUwAAAABMAApFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADpodHRwOi8v
ZGl2ZWludG9tYXJrLm9yZy9hcmNoaXZlcy8yMDA4LzAxLzIzL21pY3Jvc29mdC1rb2FuUwAAAAFJ
UwAAAAEgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAABGaHR0cDovL2Jsb2dzLm1zZG4uY29tL2ll
L2FyY2hpdmUvMjAwOC8wMS8yMS9jb21wYXRpYmlsaXR5LWFuZC1pZTguYXNweFMAAAAEd2lsbFMA
AAABIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAALGh0dHA6Ly9hbm5ldmFua2VzdGVyZW4ubmwv
MjAwOC8wMS9pZS1sb2NrLWluUwAAAANub3RTAAAAASBFUwAAAAFhTAAATQABUwAAAARocmVmUwAA
AD9odHRwOi8vd2VibG9ncy5tb3ppbGxhemluZS5vcmcvcm9jL2FyY2hpdmVzLzIwMDgvMDEvcG9z
dF8yLmh0bWxTAAAABGJsb2dTAAAAASBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAEhodHRwOi8v
d2VibG9ncy5tb3ppbGxhemluZS5vcmcvcm9jL2FyY2hpdmVzLzIwMDgvMDEvc2xpcHBpbmdfdGhl
X2JhLmh0bWxTAAAABWFib3V0UwAAAAEgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAABCaHR0cDov
L3dlYmtpdC5vcmcvYmxvZy8xNTUvdmVyc2lvbmluZy1jb21wYXRpYmlsaXR5LWFuZC1zdGFuZGFy
ZHMvUwAAAAJpdFMAAAACLCBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAC9odHRwOi8vZGVhbi5l
ZHdhcmRzLm5hbWUvd2VibG9nLzIwMDgvMDEvcXVvdGVzL1MAAAAHYmVjYXVzZVMAAAABIEVTAAAA
AWFMAABNAAFTAAAABGhyZWZTAAAAMGh0dHA6Ly93d3cuYi1saXN0Lm9yZy93ZWJsb2cvMjAwOC9q
YW4vMjMvbGVnYWN5L1MAAAACaXRTAAAAASBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAEJodHRw
Oi8vYWpheGlhbi5jb20vYXJjaGl2ZXMvaWU4LWNvbXBhdGliaWxpdHktd2l0aC14LXVhLWNvbXBh
dGlibGVTAAAABGp1c3RTAAAAASBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACxodHRwOi8vYWxp
c3RhcGFydC5jb20vYXJ0aWNsZXMvYmV5b25kZG9jdHlwZVMAAAAFc3Vja3NTAAAAAS5TAAAABnBh
cnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Python Code Introspectionhttp://lucumr.pocoo.org/cogitations/2008/01/21/python-code-introspection/2008-01-21T21:00:09Z2008-01-21T21:00:09ZArmin Ronacherpython-code-introspectionyesyes2<a href="http://pyside.blogspot.com/2008/01/what-do-you-look-for-in-documentation.html">Georg blogged about sphinx</a> recently and now we can all rejoice because sphinx can now be used with custom documentation (non c-python documentation) too. Unfortunately hand written documentation alone is hard to maintain.
For Werkzeug 0.2 I want to switch to a combination of hand written documentation and source documentation generated from python sourcecode, powered by sphinx of course. The main problem is getting the information out of the sourcecode. Unlike compiled languages in Python a lot is dynamic and much of the functionality is only available at runtime. Unlike PHP objects can be modified later on, and unlike Ruby there are attributes and methods on classes so it's hard to hide private/protected stuff on a class. epydoc came up with some conventions (especially for rst users) but introspection is still too hard in python and will lead to unexpected results.
A pretty common idom in python is to implement a class in one file and import it to somewhere else, where it will become importable from. One of the best example was Python's "re" module. Until 2.5 that module was a stub and the actual functions were imported from the "sre" module. This becomes difficult if not impossible to get right for automatically generated modules. Pydoc for example requires __all__ to be defined in that module, otherwise it will hide those objects like it hides every other import.
Another example which is pain in the ass to get right by automatic introspection are function decorators and descriptors. Descriptors also break in pydoc half of the time and nobody seems to know when exactly it breaks. Function decorators are impossible to get right because even if you try to traverse the closure variables of all the wrapped functions up to the original function the result could be terrible wrong because one function in the middle is indeed variadic.
Because it's that hard to get right I don't want to lose time on solving something that's unsolvable anyways. My current idea to make the documentation process a little less annoying I think about adding directives to sphinx that pull information from python objects into rst files in a semiautomatic way.
Say you have a pretty complex module that implements a couple of functions and classes and who knows what. Additionally to the documentation from the docstrings you also want to group the objects by topics and add hand written documentation for every group.
In the python code you document all your functions with nice rst docstrings with the epydoc conventions. Additionally you add group markers:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">def</span> <span class="nf">escape</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">quote</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="sd">"""This function escapes strings for HTML documents.</span>
<span class="sd"> :param s: the string to escape</span>
<span class="sd"> :param quote: set to `True` to escape the quote character too.</span>
<span class="sd"> :return: escaped string</span>
<span class="sd"> :group: html-helpers</span>
<span class="sd"> """</span><span class="s">"</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>
def escape(s, quote=False):
"""This function escapes strings for HTML documents.
:param s: the string to escape
:param quote: set to `True` to escape the quote character too.
:return: escaped string
:group: html-helpers
""""<PYGMENTS_RAW -->
You can do that with every function and object. To dump the documentation for a group to an rst document you would then use a little directive:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="gh">HTML Helpers</span>
<span class="gh">============</span>
These functions and classes help you process HTML.
<span class="p">..</span> <span class="ow">autodoc</span><span class="p">::</span> <span class="k">group html-helpers [werkzeug.utils]</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(rst)>
HTML Helpers
============
These functions and classes help you process HTML.
.. autodoc:: group html-helpers [werkzeug.utils]<PYGMENTS_RAW -->
This will dump all the objects flagged with that group in alphabetical order to the rst document. But of course this breaks for complex use cases you should be able to step back. Imagine you have a pretty complex object and you want to hide some of the methods / attributes, mark missing variables or make a member a descriptor rather than a method if the automatic discovery failed:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="gh">Request</span>
<span class="gh">=======</span>
summary for the request object goes here.
<span class="p">..</span> <span class="ow">autodoc</span><span class="p">::</span> <span class="k">object werkzeug.wrappers.Request</span>
no_docstring: yes
extra_members:
<span class="m">-</span> <span class="nv">`_get_file_stream`</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(rst)>
Request
=======
summary for the request object goes here.
.. autodoc:: object werkzeug.wrappers.Request
no_docstring: yes
extra_members:
- `_get_file_stream`<PYGMENTS_RAW -->
But how exactly that should work, I don't have a good idea yet. But I want to find it quickly because right now I'm pretty unhappy because writing docs both in the sourcecode and in hand written documentation sucks ass.
<strong>Update:</strong> Fixed Georg's name :-)<a href="http://pyside.blogspot.com/2008/01/what-do-you-look-for-in-documentation.html">Georg blogged about sphinx</a> recently and now we can all rejoice because sphinx can now be used with custom documentation (non c-python documentation) too. Unfortunately hand written documentation alone is hard to maintain.
For Werkzeug 0.2 I want to switch to a combination of hand written documentation and source documentation generated from python sourcecode, powered by sphinx of course. The main problem is getting the information out of the sourcecode. Unlike compiled languages in Python a lot is dynamic and much of the functionality is only available at runtime. Unlike PHP objects can be modified later on, and unlike Ruby there are attributes and methods on classes so it's hard to hide private/protected stuff on a class. epydoc came up with some conventions (especially for rst users) but introspection is still too hard in python and will lead to unexpected results.
A pretty common idom in python is to implement a class in one file and import it to somewhere else, where it will become importable from. One of the best example was Python's "re" module. Until 2.5 that module was a stub and the actual functions were imported from the "sre" module. This becomes difficult if not impossible to get right for automatically generated modules. Pydoc for example requires __all__ to be defined in that module, otherwise it will hide those objects like it hides every other import.
Another example which is pain in the ass to get right by automatic introspection are function decorators and descriptors. Descriptors also break in pydoc half of the time and nobody seems to know when exactly it breaks. Function decorators are impossible to get right because even if you try to traverse the closure variables of all the wrapped functions up to the original function the result could be terrible wrong because one function in the middle is indeed variadic.
Because it's that hard to get right I don't want to lose time on solving something that's unsolvable anyways. My current idea to make the documentation process a little less annoying I think about adding directives to sphinx that pull information from python objects into rst files in a semiautomatic way.
Say you have a pretty complex module that implements a couple of functions and classes and who knows what. Additionally to the documentation from the docstrings you also want to group the objects by topics and add hand written documentation for every group.
In the python code you document all your functions with nice rst docstrings with the epydoc conventions. Additionally you add group markers:
You can do that with every function and object. To dump the documentation for a group to an rst document you would then use a little directive:
This will dump all the objects flagged with that group in alphabetical order to the rst document. But of course this breaks for complex use cases you should be able to step back. Imagine you have a pretty complex object and you want to hide some of the methods / attributes, mark missing variables or make a member a descriptor rather than a method if the automatic discovery failed:
But how exactly that should work, I don't have a good idea yet. But I want to find it quickly because right now I'm pretty unhappy because writing docs both in the sourcecode and in hand written documentation sucks ass.
<strong>Update:</strong> Fixed Georg's name :-)SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAE1odHRwOi8v
cHlzaWRlLmJsb2dzcG90LmNvbS8yMDA4LzAxL3doYXQtZG8teW91LWxvb2stZm9yLWluLWRvY3Vt
ZW50YXRpb24uaHRtbFMAAAAaR2VvcmcgYmxvZ2dlZCBhYm91dCBzcGhpbnhTAAAM6iByZWNlbnRs
eSBhbmQgbm93IHdlIGNhbiBhbGwgcmVqb2ljZSBiZWNhdXNlIHNwaGlueCBjYW4gbm93IGJlIHVz
ZWQgd2l0aCBjdXN0b20gZG9jdW1lbnRhdGlvbiAobm9uIGMtcHl0aG9uIGRvY3VtZW50YXRpb24p
IHRvby4gVW5mb3J0dW5hdGVseSBoYW5kIHdyaXR0ZW4gZG9jdW1lbnRhdGlvbiBhbG9uZSBpcyBo
YXJkIHRvIG1haW50YWluLgoKRm9yIFdlcmt6ZXVnIDAuMiBJIHdhbnQgdG8gc3dpdGNoIHRvIGEg
Y29tYmluYXRpb24gb2YgaGFuZCB3cml0dGVuIGRvY3VtZW50YXRpb24gYW5kIHNvdXJjZSBkb2N1
bWVudGF0aW9uIGdlbmVyYXRlZCBmcm9tIHB5dGhvbiBzb3VyY2Vjb2RlLCBwb3dlcmVkIGJ5IHNw
aGlueCBvZiBjb3Vyc2UuIFRoZSBtYWluIHByb2JsZW0gaXMgZ2V0dGluZyB0aGUgaW5mb3JtYXRp
b24gb3V0IG9mIHRoZSBzb3VyY2Vjb2RlLiBVbmxpa2UgY29tcGlsZWQgbGFuZ3VhZ2VzIGluIFB5
dGhvbiBhIGxvdCBpcyBkeW5hbWljIGFuZCBtdWNoIG9mIHRoZSBmdW5jdGlvbmFsaXR5IGlzIG9u
bHkgYXZhaWxhYmxlIGF0IHJ1bnRpbWUuIFVubGlrZSBQSFAgb2JqZWN0cyBjYW4gYmUgbW9kaWZp
ZWQgbGF0ZXIgb24sIGFuZCB1bmxpa2UgUnVieSB0aGVyZSBhcmUgYXR0cmlidXRlcyBhbmQgbWV0
aG9kcyBvbiBjbGFzc2VzIHNvIGl0J3MgaGFyZCB0byBoaWRlIHByaXZhdGUvcHJvdGVjdGVkIHN0
dWZmIG9uIGEgY2xhc3MuIGVweWRvYyBjYW1lIHVwIHdpdGggc29tZSBjb252ZW50aW9ucyAoZXNw
ZWNpYWxseSBmb3IgcnN0IHVzZXJzKSBidXQgaW50cm9zcGVjdGlvbiBpcyBzdGlsbCB0b28gaGFy
ZCBpbiBweXRob24gYW5kIHdpbGwgbGVhZCB0byB1bmV4cGVjdGVkIHJlc3VsdHMuCgpBIHByZXR0
eSBjb21tb24gaWRvbSBpbiBweXRob24gaXMgdG8gaW1wbGVtZW50IGEgY2xhc3MgaW4gb25lIGZp
bGUgYW5kIGltcG9ydCBpdCB0byBzb21ld2hlcmUgZWxzZSwgd2hlcmUgaXQgd2lsbCBiZWNvbWUg
aW1wb3J0YWJsZSBmcm9tLiBPbmUgb2YgdGhlIGJlc3QgZXhhbXBsZSB3YXMgUHl0aG9uJ3MgInJl
IiBtb2R1bGUuIFVudGlsIDIuNSB0aGF0IG1vZHVsZSB3YXMgYSBzdHViIGFuZCB0aGUgYWN0dWFs
IGZ1bmN0aW9ucyB3ZXJlIGltcG9ydGVkIGZyb20gdGhlICJzcmUiIG1vZHVsZS4gVGhpcyBiZWNv
bWVzIGRpZmZpY3VsdCBpZiBub3QgaW1wb3NzaWJsZSB0byBnZXQgcmlnaHQgZm9yIGF1dG9tYXRp
Y2FsbHkgZ2VuZXJhdGVkIG1vZHVsZXMuIFB5ZG9jIGZvciBleGFtcGxlIHJlcXVpcmVzIF9fYWxs
X18gdG8gYmUgZGVmaW5lZCBpbiB0aGF0IG1vZHVsZSwgb3RoZXJ3aXNlIGl0IHdpbGwgaGlkZSB0
aG9zZSBvYmplY3RzIGxpa2UgaXQgaGlkZXMgZXZlcnkgb3RoZXIgaW1wb3J0LgoKQW5vdGhlciBl
eGFtcGxlIHdoaWNoIGlzIHBhaW4gaW4gdGhlIGFzcyB0byBnZXQgcmlnaHQgYnkgYXV0b21hdGlj
IGludHJvc3BlY3Rpb24gYXJlIGZ1bmN0aW9uIGRlY29yYXRvcnMgYW5kIGRlc2NyaXB0b3JzLiBE
ZXNjcmlwdG9ycyBhbHNvIGJyZWFrIGluIHB5ZG9jIGhhbGYgb2YgdGhlIHRpbWUgYW5kIG5vYm9k
eSBzZWVtcyB0byBrbm93IHdoZW4gZXhhY3RseSBpdCBicmVha3MuIEZ1bmN0aW9uIGRlY29yYXRv
cnMgYXJlIGltcG9zc2libGUgdG8gZ2V0IHJpZ2h0IGJlY2F1c2UgZXZlbiBpZiB5b3UgdHJ5IHRv
IHRyYXZlcnNlIHRoZSBjbG9zdXJlIHZhcmlhYmxlcyBvZiBhbGwgdGhlIHdyYXBwZWQgZnVuY3Rp
b25zIHVwIHRvIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiB0aGUgcmVzdWx0IGNvdWxkIGJlIHRlcnJp
YmxlIHdyb25nIGJlY2F1c2Ugb25lIGZ1bmN0aW9uIGluIHRoZSBtaWRkbGUgaXMgaW5kZWVkIHZh
cmlhZGljLgoKQmVjYXVzZSBpdCdzIHRoYXQgaGFyZCB0byBnZXQgcmlnaHQgSSBkb24ndCB3YW50
IHRvIGxvc2UgdGltZSBvbiBzb2x2aW5nIHNvbWV0aGluZyB0aGF0J3MgdW5zb2x2YWJsZSBhbnl3
YXlzLiBNeSBjdXJyZW50IGlkZWEgdG8gbWFrZSB0aGUgZG9jdW1lbnRhdGlvbiBwcm9jZXNzIGEg
bGl0dGxlIGxlc3MgYW5ub3lpbmcgSSB0aGluayBhYm91dCBhZGRpbmcgZGlyZWN0aXZlcyB0byBz
cGhpbnggdGhhdCBwdWxsIGluZm9ybWF0aW9uIGZyb20gcHl0aG9uIG9iamVjdHMgaW50byByc3Qg
ZmlsZXMgaW4gYSBzZW1pYXV0b21hdGljIHdheS4KClNheSB5b3UgaGF2ZSBhIHByZXR0eSBjb21w
bGV4IG1vZHVsZSB0aGF0IGltcGxlbWVudHMgYSBjb3VwbGUgb2YgZnVuY3Rpb25zIGFuZCBjbGFz
c2VzIGFuZCB3aG8ga25vd3Mgd2hhdC4gQWRkaXRpb25hbGx5IHRvIHRoZSBkb2N1bWVudGF0aW9u
IGZyb20gdGhlIGRvY3N0cmluZ3MgeW91IGFsc28gd2FudCB0byBncm91cCB0aGUgb2JqZWN0cyBi
eSB0b3BpY3MgYW5kIGFkZCBoYW5kIHdyaXR0ZW4gZG9jdW1lbnRhdGlvbiBmb3IgZXZlcnkgZ3Jv
dXAuCgpJbiB0aGUgcHl0aG9uIGNvZGUgeW91IGRvY3VtZW50IGFsbCB5b3VyIGZ1bmN0aW9ucyB3
aXRoIG5pY2UgcnN0IGRvY3N0cmluZ3Mgd2l0aCB0aGUgZXB5ZG9jIGNvbnZlbnRpb25zLiBBZGRp
dGlvbmFsbHkgeW91IGFkZCBncm91cCBtYXJrZXJzOgoKCgpZb3UgY2FuIGRvIHRoYXQgd2l0aCBl
dmVyeSBmdW5jdGlvbiBhbmQgb2JqZWN0LiBUbyBkdW1wIHRoZSBkb2N1bWVudGF0aW9uIGZvciBh
IGdyb3VwIHRvIGFuIHJzdCBkb2N1bWVudCB5b3Ugd291bGQgdGhlbiB1c2UgYSBsaXR0bGUgZGly
ZWN0aXZlOgoKCgpUaGlzIHdpbGwgZHVtcCBhbGwgdGhlIG9iamVjdHMgZmxhZ2dlZCB3aXRoIHRo
YXQgZ3JvdXAgaW4gYWxwaGFiZXRpY2FsIG9yZGVyIHRvIHRoZSByc3QgZG9jdW1lbnQuIEJ1dCBv
ZiBjb3Vyc2UgdGhpcyBicmVha3MgZm9yIGNvbXBsZXggdXNlIGNhc2VzIHlvdSBzaG91bGQgYmUg
YWJsZSB0byBzdGVwIGJhY2suIEltYWdpbmUgeW91IGhhdmUgYSBwcmV0dHkgY29tcGxleCBvYmpl
Y3QgYW5kIHlvdSB3YW50IHRvIGhpZGUgc29tZSBvZiB0aGUgbWV0aG9kcyAvIGF0dHJpYnV0ZXMs
IG1hcmsgbWlzc2luZyB2YXJpYWJsZXMgb3IgbWFrZSBhIG1lbWJlciBhIGRlc2NyaXB0b3IgcmF0
aGVyIHRoYW4gYSBtZXRob2QgaWYgdGhlIGF1dG9tYXRpYyBkaXNjb3ZlcnkgZmFpbGVkOgoKCgpC
dXQgaG93IGV4YWN0bHkgdGhhdCBzaG91bGQgd29yaywgSSBkb24ndCBoYXZlIGEgZ29vZCBpZGVh
IHlldC4gQnV0IEkgd2FudCB0byBmaW5kIGl0IHF1aWNrbHkgYmVjYXVzZSByaWdodCBub3cgSSdt
IHByZXR0eSB1bmhhcHB5IGJlY2F1c2Ugd3JpdGluZyBkb2NzIGJvdGggaW4gdGhlIHNvdXJjZWNv
ZGUgYW5kIGluIGhhbmQgd3JpdHRlbiBkb2N1bWVudGF0aW9uIHN1Y2tzIGFzcy4KCkVTAAAABnN0
cm9uZ0wAAE0AAFMAAAAHVXBkYXRlOlMAAAAXIEZpeGVkIEdlb3JnJ3MgbmFtZSA6LSlTAAAABnBh
cnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Georggeorg@python.org2008-01-21T22:06:30Znono0This proposal is certainly a good one. The exact syntax might be different (e.g. using directive options for "no_docstring" etc.). I hope it is easily implementable as a Sphinx extension.
The combination of hand-written docs and docstrings where they make sense is something that ensures up-to-date documentation that is nice to read, not fragmented like many API docs.This proposal is certainly a good one. The exact syntax might be different (e.g. using directive options for "no_docstring" etc.). I hope it is easily implementable as a Sphinx extension.
The combination of hand-written docs and docstrings where they make sense is something that ensures up-to-date documentation that is nice to read, not fragmented like many API docs.SQAAAAJTAAAABGJvZHlSUwAAAXJUaGlzIHByb3Bvc2FsIGlzIGNlcnRhaW5seSBhIGdvb2Qgb25l
LiBUaGUgZXhhY3Qgc3ludGF4IG1pZ2h0IGJlIGRpZmZlcmVudCAoZS5nLiB1c2luZyBkaXJlY3Rp
dmUgb3B0aW9ucyBmb3IgIm5vX2RvY3N0cmluZyIgZXRjLikuIEkgaG9wZSBpdCBpcyBlYXNpbHkg
aW1wbGVtZW50YWJsZSBhcyBhIFNwaGlueCBleHRlbnNpb24uCgpUaGUgY29tYmluYXRpb24gb2Yg
aGFuZC13cml0dGVuIGRvY3MgYW5kIGRvY3N0cmluZ3Mgd2hlcmUgdGhleSBtYWtlIHNlbnNlIGlz
IHNvbWV0aGluZyB0aGF0IGVuc3VyZXMgdXAtdG8tZGF0ZSBkb2N1bWVudGF0aW9uIHRoYXQgaXMg
bmljZSB0byByZWFkLCBub3QgZnJhZ21lbnRlZCBsaWtlIG1hbnkgQVBJIGRvY3MuTAAAUwAAAAZw
YXJzZXJTAAAABGh0bWw=
Error Reporting in WSGI Applicationshttp://lucumr.pocoo.org/cogitations/2008/01/18/error-reporting-in-wsgi-applications/2008-01-18T14:15:22Z2008-01-18T14:15:22ZArmin Ronachererror-reporting-in-wsgi-applicationsyesyes2Thanks to an google alert on "pygments" I stumbled accross gluon/web2py, some sort of "enterprise ready framework". It's definitively not a framework I would use myself for countless reasons but there is one thing on the feature list which I found interesting. Apparently gluon files tickets for tracebacks in the database. While it's a terrible idea to put that data into the very same database all your application data goes (what happens if the DB is down?) it's a different approach to Django which sends mails on errors.
Two days ago someone mentioned the paste WSGI middleware which sends emails on tracebacks, similar to the way Django does that. I'm not a fan of error reporting middlewares because I think that should go into the application. On an server error (caused by lost database connections, programmer errors etc.) you should not present the user a black-and-white error page or display an inline traceback like most PHP applications do. We can do better!
First of all there is a module in the standard library everybody seems to forget about. It's called "logging" and does exactly that --- it logs errors. I don't know why so many people miss it or just don't use it, but it's really one of the good things in the python standard library.
Why is it so good? It's extensible and configurable. The idea is that the application gets itself a logger and logs into that logger (debug messages, information messages, warnings, errors or tracebacks). Independently from the logging there are logger handlers which do something with the logged messages. For example you can tell the logger to log everything except of debug output into a rotated file and mail all errors to some mail addresses.
In the Werkzeug wiki there is a <a href="http://dev.pocoo.org/projects/werkzeug/wiki/ErrorHandlingInProduction">wiki page about error handling</a> in WSGI applications using the logger module. Total amount of code needed for a simple WSGI application with logging is about ten lines or so. And it's flexible enough to integrate in every WSGI application setup, no need to solve that in a middleware where you don't have access to your application's config or whatever.
And the best thing about it is that you can configure the way errors are handled. Like I mentioned before gluon creates entries in the database for logged errors. I wrote a small logger handler that does the same but for an external trac. Whenever an application error occours the logger checks if there is already a ticket for that error, if not it creates one. For every new occurrence of that bug it will create a comment in that ticket.
If you want to try it out yourself, I added the code to the <a href="http://dev.pocoo.org/hg/sandbox/raw-file/tip/trachandler.py">sandbox repository</a>.
<strong>Update:</strong> I also created a <a href="http://trac-hacks.org/wiki/PythonTracLogHandlerIntegration">trac hack</a> for it.Thanks to an google alert on "pygments" I stumbled accross gluon/web2py, some sort of "enterprise ready framework". It's definitively not a framework I would use myself for countless reasons but there is one thing on the feature list which I found interesting. Apparently gluon files tickets for tracebacks in the database. While it's a terrible idea to put that data into the very same database all your application data goes (what happens if the DB is down?) it's a different approach to Django which sends mails on errors.
Two days ago someone mentioned the paste WSGI middleware which sends emails on tracebacks, similar to the way Django does that. I'm not a fan of error reporting middlewares because I think that should go into the application. On an server error (caused by lost database connections, programmer errors etc.) you should not present the user a black-and-white error page or display an inline traceback like most PHP applications do. We can do better!
First of all there is a module in the standard library everybody seems to forget about. It's called "logging" and does exactly that --- it logs errors. I don't know why so many people miss it or just don't use it, but it's really one of the good things in the python standard library.
Why is it so good? It's extensible and configurable. The idea is that the application gets itself a logger and logs into that logger (debug messages, information messages, warnings, errors or tracebacks). Independently from the logging there are logger handlers which do something with the logged messages. For example you can tell the logger to log everything except of debug output into a rotated file and mail all errors to some mail addresses.
In the Werkzeug wiki there is a <a href="http://dev.pocoo.org/projects/werkzeug/wiki/ErrorHandlingInProduction">wiki page about error handling</a> in WSGI applications using the logger module. Total amount of code needed for a simple WSGI application with logging is about ten lines or so. And it's flexible enough to integrate in every WSGI application setup, no need to solve that in a middleware where you don't have access to your application's config or whatever.
And the best thing about it is that you can configure the way errors are handled. Like I mentioned before gluon creates entries in the database for logged errors. I wrote a small logger handler that does the same but for an external trac. Whenever an application error occours the logger checks if there is already a ticket for that error, if not it creates one. For every new occurrence of that bug it will create a comment in that ticket.
If you want to try it out yourself, I added the code to the <a href="http://dev.pocoo.org/hg/sandbox/raw-file/tip/trachandler.py">sandbox repository</a>.
<strong>Update:</strong> I also created a <a href="http://trac-hacks.org/wiki/PythonTracLogHandlerIntegration">trac hack</a> for it.SQAAAANTAAAABGJvZHlSUwAABttUaGFua3MgdG8gYW4gZ29vZ2xlIGFsZXJ0IG9uICJweWdtZW50
cyIgSSBzdHVtYmxlZCBhY2Nyb3NzIGdsdW9uL3dlYjJweSwgc29tZSBzb3J0IG9mICJlbnRlcnBy
aXNlIHJlYWR5IGZyYW1ld29yayIuICAgSXQncyBkZWZpbml0aXZlbHkgbm90IGEgZnJhbWV3b3Jr
IEkgd291bGQgdXNlIG15c2VsZiBmb3IgY291bnRsZXNzIHJlYXNvbnMgYnV0IHRoZXJlIGlzIG9u
ZSB0aGluZyBvbiB0aGUgZmVhdHVyZSBsaXN0IHdoaWNoIEkgZm91bmQgaW50ZXJlc3RpbmcuICBB
cHBhcmVudGx5IGdsdW9uIGZpbGVzIHRpY2tldHMgZm9yIHRyYWNlYmFja3MgaW4gdGhlIGRhdGFi
YXNlLiAgV2hpbGUgaXQncyBhIHRlcnJpYmxlIGlkZWEgdG8gcHV0IHRoYXQgZGF0YSBpbnRvIHRo
ZSB2ZXJ5IHNhbWUgZGF0YWJhc2UgYWxsIHlvdXIgYXBwbGljYXRpb24gZGF0YSBnb2VzICh3aGF0
IGhhcHBlbnMgaWYgdGhlIERCIGlzIGRvd24/KSBpdCdzIGEgZGlmZmVyZW50IGFwcHJvYWNoIHRv
IERqYW5nbyB3aGljaCBzZW5kcyBtYWlscyBvbiBlcnJvcnMuCgpUd28gZGF5cyBhZ28gc29tZW9u
ZSBtZW50aW9uZWQgdGhlIHBhc3RlIFdTR0kgbWlkZGxld2FyZSB3aGljaCBzZW5kcyBlbWFpbHMg
b24gdHJhY2ViYWNrcywgc2ltaWxhciB0byB0aGUgd2F5IERqYW5nbyBkb2VzIHRoYXQuICBJJ20g
bm90IGEgZmFuIG9mIGVycm9yIHJlcG9ydGluZyBtaWRkbGV3YXJlcyBiZWNhdXNlIEkgdGhpbmsg
dGhhdCBzaG91bGQgZ28gaW50byB0aGUgYXBwbGljYXRpb24uICBPbiBhbiBzZXJ2ZXIgZXJyb3Ig
KGNhdXNlZCBieSBsb3N0IGRhdGFiYXNlIGNvbm5lY3Rpb25zLCBwcm9ncmFtbWVyIGVycm9ycyBl
dGMuKSB5b3Ugc2hvdWxkIG5vdCBwcmVzZW50IHRoZSB1c2VyIGEgYmxhY2stYW5kLXdoaXRlIGVy
cm9yIHBhZ2Ugb3IgZGlzcGxheSBhbiBpbmxpbmUgdHJhY2ViYWNrIGxpa2UgbW9zdCBQSFAgYXBw
bGljYXRpb25zIGRvLiAgV2UgY2FuIGRvIGJldHRlciEKCkZpcnN0IG9mIGFsbCB0aGVyZSBpcyBh
IG1vZHVsZSBpbiB0aGUgc3RhbmRhcmQgbGlicmFyeSBldmVyeWJvZHkgc2VlbXMgdG8gZm9yZ2V0
IGFib3V0LiAgSXQncyBjYWxsZWQgImxvZ2dpbmciIGFuZCBkb2VzIGV4YWN0bHkgdGhhdCAtLS0g
aXQgbG9ncyBlcnJvcnMuIEkgZG9uJ3Qga25vdyB3aHkgc28gbWFueSBwZW9wbGUgbWlzcyBpdCBv
ciBqdXN0IGRvbid0IHVzZSBpdCwgYnV0IGl0J3MgcmVhbGx5IG9uZSBvZiB0aGUgZ29vZCB0aGlu
Z3MgaW4gdGhlIHB5dGhvbiBzdGFuZGFyZCBsaWJyYXJ5LgoKV2h5IGlzIGl0IHNvIGdvb2Q/ICBJ
dCdzIGV4dGVuc2libGUgYW5kIGNvbmZpZ3VyYWJsZS4gIFRoZSBpZGVhIGlzIHRoYXQgdGhlIGFw
cGxpY2F0aW9uIGdldHMgaXRzZWxmIGEgbG9nZ2VyIGFuZCBsb2dzIGludG8gdGhhdCBsb2dnZXIg
KGRlYnVnIG1lc3NhZ2VzLCBpbmZvcm1hdGlvbiBtZXNzYWdlcywgd2FybmluZ3MsIGVycm9ycyBv
ciB0cmFjZWJhY2tzKS4gIEluZGVwZW5kZW50bHkgZnJvbSB0aGUgbG9nZ2luZyB0aGVyZSBhcmUg
bG9nZ2VyIGhhbmRsZXJzIHdoaWNoIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBsb2dnZWQgbWVzc2Fn
ZXMuICBGb3IgZXhhbXBsZSB5b3UgY2FuIHRlbGwgdGhlIGxvZ2dlciB0byBsb2cgZXZlcnl0aGlu
ZyBleGNlcHQgb2YgZGVidWcgb3V0cHV0IGludG8gYSByb3RhdGVkIGZpbGUgYW5kIG1haWwgYWxs
IGVycm9ycyB0byBzb21lIG1haWwgYWRkcmVzc2VzLgoKSW4gdGhlIFdlcmt6ZXVnIHdpa2kgdGhl
cmUgaXMgYSBMAARFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAEVodHRwOi8vZGV2LnBvY29vLm9y
Zy9wcm9qZWN0cy93ZXJremV1Zy93aWtpL0Vycm9ySGFuZGxpbmdJblByb2R1Y3Rpb25TAAAAHndp
a2kgcGFnZSBhYm91dCBlcnJvciBoYW5kbGluZ1MAAANAIGluIFdTR0kgYXBwbGljYXRpb25zIHVz
aW5nIHRoZSBsb2dnZXIgbW9kdWxlLiAgVG90YWwgYW1vdW50IG9mIGNvZGUgbmVlZGVkIGZvciBh
IHNpbXBsZSBXU0dJIGFwcGxpY2F0aW9uIHdpdGggbG9nZ2luZyBpcyBhYm91dCB0ZW4gbGluZXMg
b3Igc28uICBBbmQgaXQncyBmbGV4aWJsZSBlbm91Z2ggdG8gaW50ZWdyYXRlIGluIGV2ZXJ5IFdT
R0kgYXBwbGljYXRpb24gc2V0dXAsIG5vIG5lZWQgdG8gc29sdmUgdGhhdCBpbiBhIG1pZGRsZXdh
cmUgd2hlcmUgeW91IGRvbid0IGhhdmUgYWNjZXNzIHRvIHlvdXIgYXBwbGljYXRpb24ncyBjb25m
aWcgb3Igd2hhdGV2ZXIuCgpBbmQgdGhlIGJlc3QgdGhpbmcgYWJvdXQgaXQgaXMgdGhhdCB5b3Ug
Y2FuIGNvbmZpZ3VyZSB0aGUgd2F5IGVycm9ycyBhcmUgaGFuZGxlZC4gIExpa2UgSSBtZW50aW9u
ZWQgYmVmb3JlIGdsdW9uIGNyZWF0ZXMgZW50cmllcyBpbiB0aGUgZGF0YWJhc2UgZm9yIGxvZ2dl
ZCBlcnJvcnMuICBJIHdyb3RlIGEgc21hbGwgbG9nZ2VyIGhhbmRsZXIgdGhhdCBkb2VzIHRoZSBz
YW1lIGJ1dCBmb3IgYW4gZXh0ZXJuYWwgdHJhYy4gIFdoZW5ldmVyIGFuIGFwcGxpY2F0aW9uIGVy
cm9yIG9jY291cnMgdGhlIGxvZ2dlciBjaGVja3MgaWYgdGhlcmUgaXMgYWxyZWFkeSBhIHRpY2tl
dCBmb3IgdGhhdCBlcnJvciwgaWYgbm90IGl0IGNyZWF0ZXMgb25lLiAgRm9yIGV2ZXJ5IG5ldyBv
Y2N1cnJlbmNlIG9mIHRoYXQgYnVnIGl0IHdpbGwgY3JlYXRlIGEgY29tbWVudCBpbiB0aGF0IHRp
Y2tldC4KCklmIHlvdSB3YW50IHRvIHRyeSBpdCBvdXQgeW91cnNlbGYsIEkgYWRkZWQgdGhlIGNv
ZGUgdG8gdGhlIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAO2h0dHA6Ly9kZXYucG9jb28ub3Jn
L2hnL3NhbmRib3gvcmF3LWZpbGUvdGlwL3RyYWNoYW5kbGVyLnB5UwAAABJzYW5kYm94IHJlcG9z
aXRvcnlTAAAAAy4KCkVTAAAABnN0cm9uZ0wAAE0AAFMAAAAHVXBkYXRlOlMAAAASIEkgYWxzbyBj
cmVhdGVkIGEgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAA6aHR0cDovL3RyYWMtaGFja3Mub3Jn
L3dpa2kvUHl0aG9uVHJhY0xvZ0hhbmRsZXJJbnRlZ3JhdGlvblMAAAAJdHJhYyBoYWNrUwAAAAgg
Zm9yIGl0LlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Robert Brewerfumanchu@aminus.orghttp://www.aminus.org/blogs/index.php/fumanchu2008-01-18T23:02:14Znono0> I don’t know why so many people miss it or just don’t use it...
> Why is it so good? It’s extensible and configurable.
That's also why it's so bad: it's so extensible and configurable that's it's far too slow for high-performance websites. So please, when you make the latest and greatest web framework, go ahead and add support for the logging module, go ahead and make it the default, but make it easily overridable at the same time.> I don’t know why so many people miss it or just don’t use it...
> Why is it so good? It’s extensible and configurable.
That's also why it's so bad: it's so extensible and configurable that's it's far too slow for high-performance websites. So please, when you make the latest and greatest web framework, go ahead and add support for the logging module, go ahead and make it the default, but make it easily overridable at the same time.SQAAAAJTAAAABGJvZHlSUwAAAbw+IEkgZG9u4oCZdCBrbm93IHdoeSBzbyBtYW55IHBlb3BsZSBt
aXNzIGl0IG9yIGp1c3QgZG9u4oCZdCB1c2UgaXQuLi4KPiBXaHkgaXMgaXQgc28gZ29vZD8gSXTi
gJlzIGV4dGVuc2libGUgYW5kIGNvbmZpZ3VyYWJsZS4KClRoYXQncyBhbHNvIHdoeSBpdCdzIHNv
IGJhZDogaXQncyBzbyBleHRlbnNpYmxlIGFuZCBjb25maWd1cmFibGUgdGhhdCdzIGl0J3MgZmFy
IHRvbyBzbG93IGZvciBoaWdoLXBlcmZvcm1hbmNlIHdlYnNpdGVzLiBTbyBwbGVhc2UsIHdoZW4g
eW91IG1ha2UgdGhlIGxhdGVzdCBhbmQgZ3JlYXRlc3Qgd2ViIGZyYW1ld29yaywgZ28gYWhlYWQg
YW5kIGFkZCBzdXBwb3J0IGZvciB0aGUgbG9nZ2luZyBtb2R1bGUsIGdvIGFoZWFkIGFuZCBtYWtl
IGl0IHRoZSBkZWZhdWx0LCBidXQgbWFrZSBpdCBlYXNpbHkgb3ZlcnJpZGFibGUgYXQgdGhlIHNh
bWUgdGltZS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-19T00:38:36Znono0That's very true. But in a production environment the calls to the actual logger can be reduced to the cases where you actually log an error or exception. For example you can create methods for log / info / warn or whatever and if __debug__ is False you replace them with a no-op lambda.
My point with that post was mostly to not reinvent exception reporting when the stdlib can do that. And that one logger.exception call in the very last except of your WSGI application won't harm the performance of the application at all.That's very true. But in a production environment the calls to the actual logger can be reduced to the cases where you actually log an error or exception. For example you can create methods for log / info / warn or whatever and if __debug__ is False you replace them with a no-op lambda.
My point with that post was mostly to not reinvent exception reporting when the stdlib can do that. And that one logger.exception call in the very last except of your WSGI application won't harm the performance of the application at all.SQAAAAJTAAAABGJvZHlSUwAAAg5UaGF0J3MgdmVyeSB0cnVlLiBCdXQgaW4gYSBwcm9kdWN0aW9u
IGVudmlyb25tZW50IHRoZSBjYWxscyB0byB0aGUgYWN0dWFsIGxvZ2dlciBjYW4gYmUgcmVkdWNl
ZCB0byB0aGUgY2FzZXMgd2hlcmUgeW91IGFjdHVhbGx5IGxvZyBhbiBlcnJvciBvciBleGNlcHRp
b24uIEZvciBleGFtcGxlIHlvdSBjYW4gY3JlYXRlIG1ldGhvZHMgZm9yIGxvZyAvIGluZm8gLyB3
YXJuIG9yIHdoYXRldmVyIGFuZCBpZiBfX2RlYnVnX18gaXMgRmFsc2UgeW91IHJlcGxhY2UgdGhl
bSB3aXRoIGEgbm8tb3AgbGFtYmRhLgoKTXkgcG9pbnQgd2l0aCB0aGF0IHBvc3Qgd2FzIG1vc3Rs
eSB0byBub3QgcmVpbnZlbnQgZXhjZXB0aW9uIHJlcG9ydGluZyB3aGVuIHRoZSBzdGRsaWIgY2Fu
IGRvIHRoYXQuIEFuZCB0aGF0IG9uZSBsb2dnZXIuZXhjZXB0aW9uIGNhbGwgaW4gdGhlIHZlcnkg
bGFzdCBleGNlcHQgb2YgeW91ciBXU0dJIGFwcGxpY2F0aW9uIHdvbid0IGhhcm0gdGhlIHBlcmZv
cm1hbmNlIG9mIHRoZSBhcHBsaWNhdGlvbiBhdCBhbGwuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Georggeorg@python.org2008-01-19T09:41:16Znono0BTW, the documentation for logging has recently been enhanced by a tutorial section, thanks to a GHOP student, see <a href="http://docs.python.org/dev/library/logging" rel="nofollow">http://docs.python.org/dev/library/logging</a>.BTW, the documentation for logging has recently been enhanced by a tutorial section, thanks to a GHOP student, see <a href="http://docs.python.org/dev/library/logging" rel="nofollow">http://docs.python.org/dev/library/logging</a>.SQAAAAJTAAAABGJvZHlSUwAAAHNCVFcsIHRoZSBkb2N1bWVudGF0aW9uIGZvciBsb2dnaW5nIGhh
cyByZWNlbnRseSBiZWVuIGVuaGFuY2VkIGJ5IGEgdHV0b3JpYWwgc2VjdGlvbiwgdGhhbmtzIHRv
IGEgR0hPUCBzdHVkZW50LCBzZWUgTAABRVMAAAABYUwAAE0AAlMAAAAEaHJlZlMAAAAqaHR0cDov
L2RvY3MucHl0aG9uLm9yZy9kZXYvbGlicmFyeS9sb2dnaW5nUwAAAANyZWxTAAAACG5vZm9sbG93
UwAAACpodHRwOi8vZG9jcy5weXRob24ub3JnL2Rldi9saWJyYXJ5L2xvZ2dpbmdTAAAAAS5TAAAA
BnBhcnNlclMAAAAEaHRtbA==
Massimomdipierro@cs.depaul.eduhttp://www.web2py.com2008-01-20T06:46:52Znono0I would like to make two corrections: 1) You say that web2py "files tickets for tracebacks in the database". No. web2py files tickets for any error that occurs and that is not explicitly catched by the application, including db tracebacks. 2) You also say "it’s a terrible idea to put that data into the very same database all your application data goes (what happens if the DB is down?" I agree and web2py in fact does not do that. web2py tickets are stored in files and they can be accessed even if the db is down. Every app has its own seperate ticketing system provided by web2py.
You also say that you would not use web2py for countless reasons. It would be helpful if you were to list those reasons. Perhaps some of them are consequence of misinformation and I could try convince you that, in fact, you should use web2py. ;-)
One common misconception is to assume limitations because of the GPL license. If you read the web2py license carefully, as long as you do not copy web2py code into your web2py app web2py makes no claims on your app and you can even distribute it in closed form (something that web2py builds for you) and charge for it.I would like to make two corrections: 1) You say that web2py "files tickets for tracebacks in the database". No. web2py files tickets for any error that occurs and that is not explicitly catched by the application, including db tracebacks. 2) You also say "it’s a terrible idea to put that data into the very same database all your application data goes (what happens if the DB is down?" I agree and web2py in fact does not do that. web2py tickets are stored in files and they can be accessed even if the db is down. Every app has its own seperate ticketing system provided by web2py.
You also say that you would not use web2py for countless reasons. It would be helpful if you were to list those reasons. Perhaps some of them are consequence of misinformation and I could try convince you that, in fact, you should use web2py. ;-)
One common misconception is to assume limitations because of the GPL license. If you read the web2py license carefully, as long as you do not copy web2py code into your web2py app web2py makes no claims on your app and you can even distribute it in closed form (something that web2py builds for you) and charge for it.SQAAAAJTAAAABGJvZHlSUwAABIJJIHdvdWxkIGxpa2UgdG8gbWFrZSB0d28gY29ycmVjdGlvbnM6
IDEpIFlvdSBzYXkgdGhhdCB3ZWIycHkgImZpbGVzIHRpY2tldHMgZm9yIHRyYWNlYmFja3MgaW4g
dGhlIGRhdGFiYXNlIi4gTm8uIHdlYjJweSBmaWxlcyB0aWNrZXRzIGZvciBhbnkgZXJyb3IgdGhh
dCBvY2N1cnMgYW5kIHRoYXQgaXMgbm90IGV4cGxpY2l0bHkgY2F0Y2hlZCBieSB0aGUgYXBwbGlj
YXRpb24sIGluY2x1ZGluZyBkYiB0cmFjZWJhY2tzLiAyKSBZb3UgYWxzbyBzYXkgIml04oCZcyBh
IHRlcnJpYmxlIGlkZWEgdG8gcHV0IHRoYXQgZGF0YSBpbnRvIHRoZSB2ZXJ5IHNhbWUgZGF0YWJh
c2UgYWxsIHlvdXIgYXBwbGljYXRpb24gZGF0YSBnb2VzICh3aGF0IGhhcHBlbnMgaWYgdGhlIERC
IGlzIGRvd24/IiBJIGFncmVlIGFuZCB3ZWIycHkgaW4gZmFjdCBkb2VzIG5vdCBkbyB0aGF0LiB3
ZWIycHkgdGlja2V0cyBhcmUgc3RvcmVkIGluIGZpbGVzIGFuZCB0aGV5IGNhbiBiZSBhY2Nlc3Nl
ZCBldmVuIGlmIHRoZSBkYiBpcyBkb3duLiBFdmVyeSBhcHAgaGFzIGl0cyBvd24gc2VwZXJhdGUg
dGlja2V0aW5nIHN5c3RlbSBwcm92aWRlZCBieSB3ZWIycHkuCgpZb3UgYWxzbyBzYXkgdGhhdCB5
b3Ugd291bGQgbm90IHVzZSB3ZWIycHkgZm9yIGNvdW50bGVzcyByZWFzb25zLiBJdCB3b3VsZCBi
ZSBoZWxwZnVsIGlmIHlvdSB3ZXJlIHRvIGxpc3QgdGhvc2UgcmVhc29ucy4gUGVyaGFwcyBzb21l
IG9mIHRoZW0gYXJlIGNvbnNlcXVlbmNlIG9mIG1pc2luZm9ybWF0aW9uIGFuZCBJIGNvdWxkIHRy
eSBjb252aW5jZSB5b3UgdGhhdCwgaW4gZmFjdCwgeW91IHNob3VsZCB1c2Ugd2ViMnB5LiA7LSkK
Ck9uZSBjb21tb24gbWlzY29uY2VwdGlvbiBpcyB0byBhc3N1bWUgbGltaXRhdGlvbnMgYmVjYXVz
ZSBvZiB0aGUgR1BMIGxpY2Vuc2UuIElmIHlvdSByZWFkIHRoZSB3ZWIycHkgbGljZW5zZSBjYXJl
ZnVsbHksIGFzIGxvbmcgYXMgeW91IGRvIG5vdCBjb3B5IHdlYjJweSBjb2RlIGludG8geW91ciB3
ZWIycHkgYXBwIHdlYjJweSBtYWtlcyBubyBjbGFpbXMgb24geW91ciBhcHAgYW5kIHlvdSBjYW4g
ZXZlbiBkaXN0cmlidXRlIGl0IGluIGNsb3NlZCBmb3JtIChzb21ldGhpbmcgdGhhdCB3ZWIycHkg
YnVpbGRzIGZvciB5b3UpIGFuZCBjaGFyZ2UgZm9yIGl0LkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Massimomdipierro@cs.depaul.eduhttp://www.web2py.com2008-01-20T07:09:18Znono0... another misconception about web2py is that you have to use the web interface for development and for database administration. You can but you are not forced to.... another misconception about web2py is that you have to use the web interface for development and for database administration. You can but you are not forced to.SQAAAAJTAAAABGJvZHlSUwAAAKQuLi4gYW5vdGhlciBtaXNjb25jZXB0aW9uIGFib3V0IHdlYjJw
eSBpcyB0aGF0IHlvdSBoYXZlIHRvIHVzZSB0aGUgd2ViIGludGVyZmFjZSBmb3IgZGV2ZWxvcG1l
bnQgYW5kIGZvciBkYXRhYmFzZSBhZG1pbmlzdHJhdGlvbi4gWW91IGNhbiBidXQgeW91IGFyZSBu
b3QgZm9yY2VkIHRvLkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-21T19:22:11Znono0In general I'm not a framework lover, even though I'm happy Django user. Mainly because I have a couple of use cases I can solve with Django and because the Django developers do a very good job at keeping the source clean, readable and maintained.
When I looked at the web2py sources I stopped looking at it pretty soon when I found out that it's bypassing the python import system for controllers and models, that it comes in a nonstandard distribution I can't deploy on a server that easy and that it's reinventing the wheel everywhere.
For custom applications I don't want to miss SQLAlchemy any more or all those template engines available for Python. So no, for things I have to bootstrap fast and quickly I would chose Django because of the community and the number of developers, and for custom applications I go with Werkzeug, especially because I can fix it when it breaks ;-)In general I'm not a framework lover, even though I'm happy Django user. Mainly because I have a couple of use cases I can solve with Django and because the Django developers do a very good job at keeping the source clean, readable and maintained.
When I looked at the web2py sources I stopped looking at it pretty soon when I found out that it's bypassing the python import system for controllers and models, that it comes in a nonstandard distribution I can't deploy on a server that easy and that it's reinventing the wheel everywhere.
For custom applications I don't want to miss SQLAlchemy any more or all those template engines available for Python. So no, for things I have to bootstrap fast and quickly I would chose Django because of the community and the number of developers, and for custom applications I go with Werkzeug, especially because I can fix it when it breaks ;-)SQAAAAJTAAAABGJvZHlSUwAAA3dJbiBnZW5lcmFsIEknbSBub3QgYSBmcmFtZXdvcmsgbG92ZXIs
IGV2ZW4gdGhvdWdoIEknbSBoYXBweSBEamFuZ28gdXNlci4gTWFpbmx5IGJlY2F1c2UgSSBoYXZl
IGEgY291cGxlIG9mIHVzZSBjYXNlcyBJIGNhbiBzb2x2ZSB3aXRoIERqYW5nbyBhbmQgYmVjYXVz
ZSB0aGUgRGphbmdvIGRldmVsb3BlcnMgZG8gYSB2ZXJ5IGdvb2Qgam9iIGF0IGtlZXBpbmcgdGhl
IHNvdXJjZSBjbGVhbiwgcmVhZGFibGUgYW5kIG1haW50YWluZWQuCgpXaGVuIEkgbG9va2VkIGF0
IHRoZSB3ZWIycHkgc291cmNlcyBJIHN0b3BwZWQgbG9va2luZyBhdCBpdCBwcmV0dHkgc29vbiB3
aGVuIEkgZm91bmQgb3V0IHRoYXQgaXQncyBieXBhc3NpbmcgdGhlIHB5dGhvbiBpbXBvcnQgc3lz
dGVtIGZvciBjb250cm9sbGVycyBhbmQgbW9kZWxzLCB0aGF0IGl0IGNvbWVzIGluIGEgbm9uc3Rh
bmRhcmQgZGlzdHJpYnV0aW9uIEkgY2FuJ3QgZGVwbG95IG9uIGEgc2VydmVyIHRoYXQgZWFzeSBh
bmQgdGhhdCBpdCdzIHJlaW52ZW50aW5nIHRoZSB3aGVlbCBldmVyeXdoZXJlLgoKRm9yIGN1c3Rv
bSBhcHBsaWNhdGlvbnMgSSBkb24ndCB3YW50IHRvIG1pc3MgU1FMQWxjaGVteSBhbnkgbW9yZSBv
ciBhbGwgdGhvc2UgdGVtcGxhdGUgZW5naW5lcyBhdmFpbGFibGUgZm9yIFB5dGhvbi4gU28gbm8s
IGZvciB0aGluZ3MgSSBoYXZlIHRvIGJvb3RzdHJhcCBmYXN0IGFuZCBxdWlja2x5IEkgd291bGQg
Y2hvc2UgRGphbmdvIGJlY2F1c2Ugb2YgdGhlIGNvbW11bml0eSBhbmQgdGhlIG51bWJlciBvZiBk
ZXZlbG9wZXJzLCBhbmQgZm9yIGN1c3RvbSBhcHBsaWNhdGlvbnMgSSBnbyB3aXRoIFdlcmt6ZXVn
LCBlc3BlY2lhbGx5IGJlY2F1c2UgSSBjYW4gZml4IGl0IHdoZW4gaXQgYnJlYWtzIDstKUwAAFMA
AAAGcGFyc2VyUwAAAARodG1s
Massimomdipierro@cs.depaul.eduhttp://www.web2py.com2008-01-25T15:25:16Znono0If you download the web2py source code instead of the windows/mac executables, you can deploy it as any other python framework. In fact web2py is wsgi compliant, packages the paste httserver (same as pylons) if you want to use mod_proxy, and a wsgi handler like Django if you prefer mod_wsgi. You can install any python module using easy_install and import it from models/view/controllers as you would in Django or Pylons. web2py allows you to bytecode-compile your controllers/views so that 1) no parsing of templates is done in production mode, and 2) you can distribute your apps in semi-closed source; this is why it bypasses the normal import for its own controllers. A small prize to pay for a much faster framework.If you download the web2py source code instead of the windows/mac executables, you can deploy it as any other python framework. In fact web2py is wsgi compliant, packages the paste httserver (same as pylons) if you want to use mod_proxy, and a wsgi handler like Django if you prefer mod_wsgi. You can install any python module using easy_install and import it from models/view/controllers as you would in Django or Pylons. web2py allows you to bytecode-compile your controllers/views so that 1) no parsing of templates is done in production mode, and 2) you can distribute your apps in semi-closed source; this is why it bypasses the normal import for its own controllers. A small prize to pay for a much faster framework.SQAAAAJTAAAABGJvZHlSUwAAAtJJZiB5b3UgZG93bmxvYWQgdGhlIHdlYjJweSBzb3VyY2UgY29k
ZSBpbnN0ZWFkIG9mIHRoZSB3aW5kb3dzL21hYyBleGVjdXRhYmxlcywgeW91IGNhbiBkZXBsb3kg
aXQgYXMgYW55IG90aGVyIHB5dGhvbiBmcmFtZXdvcmsuIEluIGZhY3Qgd2ViMnB5IGlzIHdzZ2kg
Y29tcGxpYW50LCBwYWNrYWdlcyB0aGUgcGFzdGUgaHR0c2VydmVyIChzYW1lIGFzIHB5bG9ucykg
aWYgeW91IHdhbnQgdG8gdXNlIG1vZF9wcm94eSwgYW5kIGEgd3NnaSBoYW5kbGVyIGxpa2UgRGph
bmdvIGlmIHlvdSBwcmVmZXIgbW9kX3dzZ2kuIFlvdSBjYW4gaW5zdGFsbCBhbnkgcHl0aG9uIG1v
ZHVsZSB1c2luZyBlYXN5X2luc3RhbGwgYW5kIGltcG9ydCBpdCBmcm9tIG1vZGVscy92aWV3L2Nv
bnRyb2xsZXJzIGFzIHlvdSB3b3VsZCBpbiBEamFuZ28gb3IgUHlsb25zLiB3ZWIycHkgYWxsb3dz
IHlvdSB0byBieXRlY29kZS1jb21waWxlIHlvdXIgY29udHJvbGxlcnMvdmlld3Mgc28gdGhhdCAx
KSBubyBwYXJzaW5nIG9mIHRlbXBsYXRlcyBpcyBkb25lIGluIHByb2R1Y3Rpb24gbW9kZSwgYW5k
IDIpIHlvdSBjYW4gZGlzdHJpYnV0ZSB5b3VyIGFwcHMgaW4gc2VtaS1jbG9zZWQgc291cmNlOyB0
aGlzIGlzIHdoeSBpdCBieXBhc3NlcyB0aGUgbm9ybWFsIGltcG9ydCBmb3IgaXRzIG93biBjb250
cm9sbGVycy4gQSBzbWFsbCBwcml6ZSB0byBwYXkgZm9yIGEgbXVjaCBmYXN0ZXIgZnJhbWV3b3Jr
LkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
New Stuff in Werkzeug (and the WSGI World)http://lucumr.pocoo.org/cogitations/2008/01/16/new-stuff-in-werkzeug-and-the-wsgi-world/2008-01-16T17:29:22Z2008-01-16T17:29:22ZArmin Ronachernew-stuff-in-werkzeug-and-the-wsgi-worldyesyes2Unfortunately I'm very busy lately so there are few updates on Werkzeug and all the other libraries I personally contributed (and there are even some patches in my Mail queue I have to apply after reviewing) but that doesn't mean that there is no progress :-)
There is actually quite a lot of new stuff between the 0.1 release and now. Werkzeug tries to implement stupid stuff you reimplement in every second application in a way that you can use it with minor modifications in your application. Because many of those features only come up if you have implemented them often in your own applications they didn't make it into 0.1. Thanks to all the early adopters we now have cool new stuff that was implemented because there was need for it.
For example Werkzeug now has RFC-compliant Etag and Cache-Control parsing. You can also generate etags automatically for responses and make them conditional for some requests. The utility module was extended with many new stuff that fix limitations in the standard library or implement long missed functions like finding modules in a package (very useful if you want to automatically register controllers), importing modules by a string (useful if your URL map endpoints are (partial) import paths), generating URLs like trac does by calling an Href object, functions to fix URLs similar to the way Firefox fixes them, dumping and parsing HTTP dates, loading and dumping cookies with a simple function call (and support for http only) and probably a lot more before the actual 0.2 release.
Another cool thing is (unrelated to Werkzeug) that more and more cool modules come up that make web development a charm. While babel is available for quite a while I haven't really used it until last weak and it's really great. Together with Werkzeug's routing system and the ability to do multiple inheritance in SQLAlchemy there are so cool ways to do web development of internationalized applications. <small>I know the last sentence doesn't make sense without the context, so I guess I have to blog about that. <small>sooo freaking cool.</small></small>
Form handling in Python is still a bit strange if you are not using django's newforms (I know that there is formencode but somehow it isn't what I'm looking for) but there is now <a href="http://pypi.python.org/pypi/WTForms/">WTForms</a> which looks promising. With some more small changes it could become a very cool form handling system (for example I'm missing some default validators at the moment and I'm not completely sure how to pass choices to a select box in a per form instance basis). WTForms was derived from an application that is already in production so it solves already many problems nicely. It's a library I want to watch closely the next weeks.
And I think that approach should become the way Werkzeug is developed in the future. Implement features a release earlier and mark them as "under consideration" if they are not yet used in production applications. If you adopt them early you can give feedback and we can improve it to the next Werkzeug release and streamline the API.
What's to do until the next Werkzeug release? Georg is currently working on making the sphinx documentation builder independent from the CPython documentation so that other projects can use it too. I then want to semi-automatically build an API documentation for Werkzeug and combine them with hand written rst pages for the Werkzeug 0.2 documentation. I got some feedback for the Werkzeug docs and looks like they are a bit too chaotic and misleading. Especially getting started with Werkzeug is still too complicated so I hope we can address this with a new documentation that combines automatically generated documentation with tutorials.
The documentation tool could probably be useful for other projects too, I guess <a href="http://pyside.blogspot.com/">Georg</a> will drop some lines in his blog once it's ready.
Updates regarding Jinja will be up shortly, there is currently a branch developed by Lakin Wecker to speed up Jinja template evaluation. And if you already know what GHRML/XAML will gonna be: I will try to get that running this weekend.
That's it for the moment ;-)Unfortunately I'm very busy lately so there are few updates on Werkzeug and all the other libraries I personally contributed (and there are even some patches in my Mail queue I have to apply after reviewing) but that doesn't mean that there is no progress :-)
There is actually quite a lot of new stuff between the 0.1 release and now. Werkzeug tries to implement stupid stuff you reimplement in every second application in a way that you can use it with minor modifications in your application. Because many of those features only come up if you have implemented them often in your own applications they didn't make it into 0.1. Thanks to all the early adopters we now have cool new stuff that was implemented because there was need for it.
For example Werkzeug now has RFC-compliant Etag and Cache-Control parsing. You can also generate etags automatically for responses and make them conditional for some requests. The utility module was extended with many new stuff that fix limitations in the standard library or implement long missed functions like finding modules in a package (very useful if you want to automatically register controllers), importing modules by a string (useful if your URL map endpoints are (partial) import paths), generating URLs like trac does by calling an Href object, functions to fix URLs similar to the way Firefox fixes them, dumping and parsing HTTP dates, loading and dumping cookies with a simple function call (and support for http only) and probably a lot more before the actual 0.2 release.
Another cool thing is (unrelated to Werkzeug) that more and more cool modules come up that make web development a charm. While babel is available for quite a while I haven't really used it until last weak and it's really great. Together with Werkzeug's routing system and the ability to do multiple inheritance in SQLAlchemy there are so cool ways to do web development of internationalized applications. <small>I know the last sentence doesn't make sense without the context, so I guess I have to blog about that. <small>sooo freaking cool.</small></small>
Form handling in Python is still a bit strange if you are not using django's newforms (I know that there is formencode but somehow it isn't what I'm looking for) but there is now <a href="http://pypi.python.org/pypi/WTForms/">WTForms</a> which looks promising. With some more small changes it could become a very cool form handling system (for example I'm missing some default validators at the moment and I'm not completely sure how to pass choices to a select box in a per form instance basis). WTForms was derived from an application that is already in production so it solves already many problems nicely. It's a library I want to watch closely the next weeks.
And I think that approach should become the way Werkzeug is developed in the future. Implement features a release earlier and mark them as "under consideration" if they are not yet used in production applications. If you adopt them early you can give feedback and we can improve it to the next Werkzeug release and streamline the API.
What's to do until the next Werkzeug release? Georg is currently working on making the sphinx documentation builder independent from the CPython documentation so that other projects can use it too. I then want to semi-automatically build an API documentation for Werkzeug and combine them with hand written rst pages for the Werkzeug 0.2 documentation. I got some feedback for the Werkzeug docs and looks like they are a bit too chaotic and misleading. Especially getting started with Werkzeug is still too complicated so I hope we can address this with a new documentation that combines automatically generated documentation with tutorials.
The documentation tool could probably be useful for other projects too, I guess <a href="http://pyside.blogspot.com/">Georg</a> will drop some lines in his blog once it's ready.
Updates regarding Jinja will be up shortly, there is currently a branch developed by Lakin Wecker to speed up Jinja template evaluation. And if you already know what GHRML/XAML will gonna be: I will try to get that running this weekend.
That's it for the moment ;-)SQAAAANTAAAABGJvZHlSUwAAB5RVbmZvcnR1bmF0ZWx5IEknbSB2ZXJ5IGJ1c3kgbGF0ZWx5IHNv
IHRoZXJlIGFyZSBmZXcgdXBkYXRlcyBvbiBXZXJremV1ZyBhbmQgYWxsIHRoZSBvdGhlciBsaWJy
YXJpZXMgSSBwZXJzb25hbGx5IGNvbnRyaWJ1dGVkIChhbmQgdGhlcmUgYXJlIGV2ZW4gc29tZSBw
YXRjaGVzIGluIG15IE1haWwgcXVldWUgSSBoYXZlIHRvIGFwcGx5IGFmdGVyIHJldmlld2luZykg
YnV0IHRoYXQgZG9lc24ndCBtZWFuIHRoYXQgdGhlcmUgaXMgbm8gcHJvZ3Jlc3MgOi0pCgpUaGVy
ZSBpcyBhY3R1YWxseSBxdWl0ZSBhIGxvdCBvZiBuZXcgc3R1ZmYgYmV0d2VlbiB0aGUgMC4xIHJl
bGVhc2UgYW5kIG5vdy4gV2Vya3pldWcgdHJpZXMgdG8gaW1wbGVtZW50IHN0dXBpZCBzdHVmZiB5
b3UgcmVpbXBsZW1lbnQgaW4gZXZlcnkgc2Vjb25kIGFwcGxpY2F0aW9uIGluIGEgd2F5IHRoYXQg
eW91IGNhbiB1c2UgaXQgd2l0aCBtaW5vciBtb2RpZmljYXRpb25zIGluIHlvdXIgYXBwbGljYXRp
b24uIEJlY2F1c2UgbWFueSBvZiB0aG9zZSBmZWF0dXJlcyBvbmx5IGNvbWUgdXAgaWYgeW91IGhh
dmUgaW1wbGVtZW50ZWQgdGhlbSBvZnRlbiBpbiB5b3VyIG93biBhcHBsaWNhdGlvbnMgdGhleSBk
aWRuJ3QgbWFrZSBpdCBpbnRvIDAuMS4gVGhhbmtzIHRvIGFsbCB0aGUgZWFybHkgYWRvcHRlcnMg
d2Ugbm93IGhhdmUgY29vbCBuZXcgc3R1ZmYgdGhhdCB3YXMgaW1wbGVtZW50ZWQgYmVjYXVzZSB0
aGVyZSB3YXMgbmVlZCBmb3IgaXQuCgpGb3IgZXhhbXBsZSBXZXJremV1ZyBub3cgaGFzIFJGQy1j
b21wbGlhbnQgRXRhZyBhbmQgQ2FjaGUtQ29udHJvbCBwYXJzaW5nLiBZb3UgY2FuIGFsc28gZ2Vu
ZXJhdGUgZXRhZ3MgYXV0b21hdGljYWxseSBmb3IgcmVzcG9uc2VzIGFuZCBtYWtlIHRoZW0gY29u
ZGl0aW9uYWwgZm9yIHNvbWUgcmVxdWVzdHMuIFRoZSB1dGlsaXR5IG1vZHVsZSB3YXMgZXh0ZW5k
ZWQgd2l0aCBtYW55IG5ldyBzdHVmZiB0aGF0IGZpeCBsaW1pdGF0aW9ucyBpbiB0aGUgc3RhbmRh
cmQgbGlicmFyeSBvciBpbXBsZW1lbnQgbG9uZyBtaXNzZWQgZnVuY3Rpb25zIGxpa2UgZmluZGlu
ZyBtb2R1bGVzIGluIGEgcGFja2FnZSAodmVyeSB1c2VmdWwgaWYgeW91IHdhbnQgdG8gYXV0b21h
dGljYWxseSByZWdpc3RlciBjb250cm9sbGVycyksIGltcG9ydGluZyBtb2R1bGVzIGJ5IGEgc3Ry
aW5nICh1c2VmdWwgaWYgeW91ciBVUkwgbWFwIGVuZHBvaW50cyBhcmUgKHBhcnRpYWwpIGltcG9y
dCBwYXRocyksIGdlbmVyYXRpbmcgVVJMcyBsaWtlIHRyYWMgZG9lcyBieSBjYWxsaW5nIGFuIEhy
ZWYgb2JqZWN0LCBmdW5jdGlvbnMgdG8gZml4IFVSTHMgc2ltaWxhciB0byB0aGUgd2F5IEZpcmVm
b3ggZml4ZXMgdGhlbSwgZHVtcGluZyBhbmQgcGFyc2luZyBIVFRQIGRhdGVzLCBsb2FkaW5nIGFu
ZCBkdW1waW5nIGNvb2tpZXMgd2l0aCBhIHNpbXBsZSBmdW5jdGlvbiBjYWxsIChhbmQgc3VwcG9y
dCBmb3IgaHR0cCBvbmx5KSBhbmQgcHJvYmFibHkgYSBsb3QgbW9yZSBiZWZvcmUgdGhlIGFjdHVh
bCAwLjIgcmVsZWFzZS4KCkFub3RoZXIgY29vbCB0aGluZyBpcyAodW5yZWxhdGVkIHRvIFdlcmt6
ZXVnKSB0aGF0IG1vcmUgYW5kIG1vcmUgY29vbCBtb2R1bGVzIGNvbWUgdXAgdGhhdCBtYWtlIHdl
YiBkZXZlbG9wbWVudCBhIGNoYXJtLiBXaGlsZSBiYWJlbCBpcyBhdmFpbGFibGUgZm9yIHF1aXRl
IGEgd2hpbGUgSSBoYXZlbid0IHJlYWxseSB1c2VkIGl0IHVudGlsIGxhc3Qgd2VhayBhbmQgaXQn
cyByZWFsbHkgZ3JlYXQuIFRvZ2V0aGVyIHdpdGggV2Vya3pldWcncyByb3V0aW5nIHN5c3RlbSBh
bmQgdGhlIGFiaWxpdHkgdG8gZG8gbXVsdGlwbGUgaW5oZXJpdGFuY2UgaW4gU1FMQWxjaGVteSB0
aGVyZSBhcmUgc28gY29vbCB3YXlzIHRvIGRvIHdlYiBkZXZlbG9wbWVudCBvZiBpbnRlcm5hdGlv
bmFsaXplZCBhcHBsaWNhdGlvbnMuIEwAA0VTAAAABXNtYWxsTAABRVMAAAAFc21hbGxMAABNAABT
AAAAE3Nvb28gZnJlYWtpbmcgY29vbC5TAAAAAE0AAFMAAABnSSBrbm93IHRoZSBsYXN0IHNlbnRl
bmNlIGRvZXNuJ3QgbWFrZSBzZW5zZSB3aXRob3V0IHRoZSBjb250ZXh0LCBzbyBJIGd1ZXNzIEkg
aGF2ZSB0byBibG9nIGFib3V0IHRoYXQuIFMAAAC1CgpGb3JtIGhhbmRsaW5nIGluIFB5dGhvbiBp
cyBzdGlsbCBhIGJpdCBzdHJhbmdlIGlmIHlvdSBhcmUgbm90IHVzaW5nIGRqYW5nbydzIG5ld2Zv
cm1zIChJIGtub3cgdGhhdCB0aGVyZSBpcyBmb3JtZW5jb2RlIGJ1dCBzb21laG93IGl0IGlzbid0
IHdoYXQgSSdtIGxvb2tpbmcgZm9yKSBidXQgdGhlcmUgaXMgbm93IEVTAAAAAWFMAABNAAFTAAAA
BGhyZWZTAAAAJGh0dHA6Ly9weXBpLnB5dGhvbi5vcmcvcHlwaS9XVEZvcm1zL1MAAAAHV1RGb3Jt
c1MAAAXQIHdoaWNoIGxvb2tzIHByb21pc2luZy4gV2l0aCBzb21lIG1vcmUgc21hbGwgY2hhbmdl
cyBpdCBjb3VsZCBiZWNvbWUgYSB2ZXJ5IGNvb2wgZm9ybSBoYW5kbGluZyBzeXN0ZW0gKGZvciBl
eGFtcGxlIEknbSBtaXNzaW5nIHNvbWUgZGVmYXVsdCB2YWxpZGF0b3JzIGF0IHRoZSBtb21lbnQg
YW5kIEknbSBub3QgY29tcGxldGVseSBzdXJlIGhvdyB0byBwYXNzIGNob2ljZXMgdG8gYSBzZWxl
Y3QgYm94IGluIGEgcGVyIGZvcm0gaW5zdGFuY2UgYmFzaXMpLiBXVEZvcm1zIHdhcyBkZXJpdmVk
IGZyb20gYW4gYXBwbGljYXRpb24gdGhhdCBpcyBhbHJlYWR5IGluIHByb2R1Y3Rpb24gc28gaXQg
c29sdmVzIGFscmVhZHkgbWFueSBwcm9ibGVtcyBuaWNlbHkuIEl0J3MgYSBsaWJyYXJ5IEkgd2Fu
dCB0byB3YXRjaCBjbG9zZWx5IHRoZSBuZXh0IHdlZWtzLgoKQW5kIEkgdGhpbmsgdGhhdCBhcHBy
b2FjaCBzaG91bGQgYmVjb21lIHRoZSB3YXkgV2Vya3pldWcgaXMgZGV2ZWxvcGVkIGluIHRoZSBm
dXR1cmUuIEltcGxlbWVudCBmZWF0dXJlcyBhIHJlbGVhc2UgZWFybGllciBhbmQgbWFyayB0aGVt
IGFzICJ1bmRlciBjb25zaWRlcmF0aW9uIiBpZiB0aGV5IGFyZSBub3QgeWV0IHVzZWQgaW4gcHJv
ZHVjdGlvbiBhcHBsaWNhdGlvbnMuIElmIHlvdSBhZG9wdCB0aGVtIGVhcmx5IHlvdSBjYW4gZ2l2
ZSBmZWVkYmFjayBhbmQgd2UgY2FuIGltcHJvdmUgaXQgdG8gdGhlIG5leHQgV2Vya3pldWcgcmVs
ZWFzZSBhbmQgc3RyZWFtbGluZSB0aGUgQVBJLgoKV2hhdCdzIHRvIGRvIHVudGlsIHRoZSBuZXh0
IFdlcmt6ZXVnIHJlbGVhc2U/IEdlb3JnIGlzIGN1cnJlbnRseSB3b3JraW5nIG9uIG1ha2luZyB0
aGUgc3BoaW54IGRvY3VtZW50YXRpb24gYnVpbGRlciBpbmRlcGVuZGVudCBmcm9tIHRoZSBDUHl0
aG9uIGRvY3VtZW50YXRpb24gc28gdGhhdCBvdGhlciBwcm9qZWN0cyBjYW4gdXNlIGl0IHRvby4g
SSB0aGVuIHdhbnQgdG8gc2VtaS1hdXRvbWF0aWNhbGx5IGJ1aWxkIGFuIEFQSSBkb2N1bWVudGF0
aW9uIGZvciBXZXJremV1ZyBhbmQgY29tYmluZSB0aGVtIHdpdGggaGFuZCB3cml0dGVuIHJzdCBw
YWdlcyBmb3IgdGhlIFdlcmt6ZXVnIDAuMiBkb2N1bWVudGF0aW9uLiBJIGdvdCBzb21lIGZlZWRi
YWNrIGZvciB0aGUgV2Vya3pldWcgZG9jcyBhbmQgbG9va3MgbGlrZSB0aGV5IGFyZSBhIGJpdCB0
b28gY2hhb3RpYyBhbmQgbWlzbGVhZGluZy4gRXNwZWNpYWxseSBnZXR0aW5nIHN0YXJ0ZWQgd2l0
aCBXZXJremV1ZyBpcyBzdGlsbCB0b28gY29tcGxpY2F0ZWQgc28gSSBob3BlIHdlIGNhbiBhZGRy
ZXNzIHRoaXMgd2l0aCBhIG5ldyBkb2N1bWVudGF0aW9uIHRoYXQgY29tYmluZXMgYXV0b21hdGlj
YWxseSBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiB3aXRoIHR1dG9yaWFscy4KClRoZSBkb2N1bWVu
dGF0aW9uIHRvb2wgY291bGQgcHJvYmFibHkgYmUgdXNlZnVsIGZvciBvdGhlciBwcm9qZWN0cyB0
b28sIEkgZ3Vlc3MgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAbaHR0cDovL3B5c2lkZS5ibG9n
c3BvdC5jb20vUwAAAAVHZW9yZ1MAAAE+IHdpbGwgZHJvcCBzb21lIGxpbmVzIGluIGhpcyBibG9n
IG9uY2UgaXQncyByZWFkeS4KClVwZGF0ZXMgcmVnYXJkaW5nIEppbmphIHdpbGwgYmUgdXAgc2hv
cnRseSwgdGhlcmUgaXMgY3VycmVudGx5IGEgYnJhbmNoIGRldmVsb3BlZCBieSBMYWtpbiBXZWNr
ZXIgdG8gc3BlZWQgdXAgSmluamEgdGVtcGxhdGUgZXZhbHVhdGlvbi4gQW5kIGlmIHlvdSBhbHJl
YWR5IGtub3cgd2hhdCBHSFJNTC9YQU1MIHdpbGwgZ29ubmEgYmU6IEkgd2lsbCB0cnkgdG8gZ2V0
IHRoYXQgcnVubmluZyB0aGlzIHdlZWtlbmQuCgpUaGF0J3MgaXQgZm9yIHRoZSBtb21lbnQgOy0p
UwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
How to fix Pythonhttp://lucumr.pocoo.org/cogitations/2008/01/10/how-to-fix-python/2008-01-10T16:23:01Z2008-01-10T16:23:01ZArmin Ronacherhow-to-fix-pythonyesyes2For a long time I thought I'm the only person disliking the stdlib, but apparently there are more :-) Not just that every library has it's own code style, it also has different names, some are implemented insanely bad (Cookie.py anyone?) or Javaish (threading, unittest) or just plain stupid (codeop). I know we can't just get rid of that stdlib, wait a moment, why can't we? Python 3 is upcoming and we all have to adapt our libraries and applications anyways.
It wouldn't be too hard actually. Python loads modules from zip files anyways. Just move all the stuff into a zip file, move it into "old" or somethign and old applications just have to alter their imports "from cgi import escape" to "from old.cgi import escape". Or the other way round, the old libraries stay where they are and the new stdlib goes into "py.*" or "std.*".
Insane or a good idea? You be the judge.For a long time I thought I'm the only person disliking the stdlib, but apparently there are more :-) Not just that every library has it's own code style, it also has different names, some are implemented insanely bad (Cookie.py anyone?) or Javaish (threading, unittest) or just plain stupid (codeop). I know we can't just get rid of that stdlib, wait a moment, why can't we? Python 3 is upcoming and we all have to adapt our libraries and applications anyways.
It wouldn't be too hard actually. Python loads modules from zip files anyways. Just move all the stuff into a zip file, move it into "old" or somethign and old applications just have to alter their imports "from cgi import escape" to "from old.cgi import escape". Or the other way round, the old libraries stay where they are and the new stdlib goes into "py.*" or "std.*".
Insane or a good idea? You be the judge.SQAAAANTAAAABGJvZHlSUwAAA25Gb3IgYSBsb25nIHRpbWUgSSB0aG91Z2h0IEknbSB0aGUgb25s
eSBwZXJzb24gZGlzbGlraW5nIHRoZSBzdGRsaWIsIGJ1dCBhcHBhcmVudGx5IHRoZXJlIGFyZSBt
b3JlIDotKSBOb3QganVzdCB0aGF0IGV2ZXJ5IGxpYnJhcnkgaGFzIGl0J3Mgb3duIGNvZGUgc3R5
bGUsIGl0IGFsc28gaGFzIGRpZmZlcmVudCBuYW1lcywgc29tZSBhcmUgaW1wbGVtZW50ZWQgaW5z
YW5lbHkgYmFkIChDb29raWUucHkgYW55b25lPykgb3IgSmF2YWlzaCAodGhyZWFkaW5nLCB1bml0
dGVzdCkgb3IganVzdCBwbGFpbiBzdHVwaWQgKGNvZGVvcCkuIEkga25vdyB3ZSBjYW4ndCBqdXN0
IGdldCByaWQgb2YgdGhhdCBzdGRsaWIsIHdhaXQgYSBtb21lbnQsIHdoeSBjYW4ndCB3ZT8gUHl0
aG9uIDMgaXMgdXBjb21pbmcgYW5kIHdlIGFsbCBoYXZlIHRvIGFkYXB0IG91ciBsaWJyYXJpZXMg
YW5kIGFwcGxpY2F0aW9ucyBhbnl3YXlzLgoKSXQgd291bGRuJ3QgYmUgdG9vIGhhcmQgYWN0dWFs
bHkuIFB5dGhvbiBsb2FkcyBtb2R1bGVzIGZyb20gemlwIGZpbGVzIGFueXdheXMuIEp1c3QgbW92
ZSBhbGwgdGhlIHN0dWZmIGludG8gYSB6aXAgZmlsZSwgbW92ZSBpdCBpbnRvICJvbGQiIG9yIHNv
bWV0aGlnbiBhbmQgb2xkIGFwcGxpY2F0aW9ucyBqdXN0IGhhdmUgdG8gYWx0ZXIgdGhlaXIgaW1w
b3J0cyAiZnJvbSBjZ2kgaW1wb3J0IGVzY2FwZSIgdG8gImZyb20gb2xkLmNnaSBpbXBvcnQgZXNj
YXBlIi4gT3IgdGhlIG90aGVyIHdheSByb3VuZCwgdGhlIG9sZCBsaWJyYXJpZXMgc3RheSB3aGVy
ZSB0aGV5IGFyZSBhbmQgdGhlIG5ldyBzdGRsaWIgZ29lcyBpbnRvICJweS4qIiBvciAic3RkLioi
LgoKSW5zYW5lIG9yIGEgZ29vZCBpZGVhPyBZb3UgYmUgdGhlIGp1ZGdlLkwAAFMAAAAGcGFyc2Vy
UwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
johnjohn.w@web.de2008-01-10T16:46:11Znono0Little bit too late for such a change, hein?Little bit too late for such a change, hein?SQAAAAJTAAAABGJvZHlSUwAAACxMaXR0bGUgYml0IHRvbyBsYXRlIGZvciBzdWNoIGEgY2hhbmdl
LCBoZWluP0wAAFMAAAAGcGFyc2VyUwAAAARodG1s
Brettbrett@python.org2008-01-11T01:46:53Znono0There is a difference between wiping out the stdlib entirely and cleaning it up. While some things definitely need removal or a re-implementation, I don't think the stdlib needs to go entirely. That would put us worse off than C where you have to hunt down various 3rd-party libraries, try to figure out which ones are good, etc.
And you don't need to wait until Python 3.0 to come up with new modules and begin getting rid of old ones. People just need to write up a better implementation and be willing to maintain it in the stdlib.There is a difference between wiping out the stdlib entirely and cleaning it up. While some things definitely need removal or a re-implementation, I don't think the stdlib needs to go entirely. That would put us worse off than C where you have to hunt down various 3rd-party libraries, try to figure out which ones are good, etc.
And you don't need to wait until Python 3.0 to come up with new modules and begin getting rid of old ones. People just need to write up a better implementation and be willing to maintain it in the stdlib.SQAAAAJTAAAABGJvZHlSUwAAAhdUaGVyZSBpcyBhIGRpZmZlcmVuY2UgYmV0d2VlbiB3aXBpbmcg
b3V0IHRoZSBzdGRsaWIgZW50aXJlbHkgYW5kIGNsZWFuaW5nIGl0IHVwLiBXaGlsZSBzb21lIHRo
aW5ncyBkZWZpbml0ZWx5IG5lZWQgcmVtb3ZhbCBvciBhIHJlLWltcGxlbWVudGF0aW9uLCBJIGRv
bid0IHRoaW5rIHRoZSBzdGRsaWIgbmVlZHMgdG8gZ28gZW50aXJlbHkuIFRoYXQgd291bGQgcHV0
IHVzIHdvcnNlIG9mZiB0aGFuIEMgd2hlcmUgeW91IGhhdmUgdG8gaHVudCBkb3duIHZhcmlvdXMg
M3JkLXBhcnR5IGxpYnJhcmllcywgdHJ5IHRvIGZpZ3VyZSBvdXQgd2hpY2ggb25lcyBhcmUgZ29v
ZCwgZXRjLgoKQW5kIHlvdSBkb24ndCBuZWVkIHRvIHdhaXQgdW50aWwgUHl0aG9uIDMuMCB0byBj
b21lIHVwIHdpdGggbmV3IG1vZHVsZXMgYW5kIGJlZ2luIGdldHRpbmcgcmlkIG9mIG9sZCBvbmVz
LiBQZW9wbGUganVzdCBuZWVkIHRvIHdyaXRlIHVwIGEgYmV0dGVyIGltcGxlbWVudGF0aW9uIGFu
ZCBiZSB3aWxsaW5nIHRvIG1haW50YWluIGl0IGluIHRoZSBzdGRsaWIuTAAAUwAAAAZwYXJzZXJT
AAAABGh0bWw=
Georggeorg@python.org2008-01-11T09:40:36Znono0Also, it's not really that bad ("every library has it’s own code style"...) -- most libraries at least follow PEP 8, and the javaNaming isn't so widespread that we couldn't fix it for Py3k.
And as Brett says, if you got a working replacement for any badly implemented module and are willing to maintain it, there's almost nothing preventing replacing it.Also, it's not really that bad ("every library has it’s own code style"...) -- most libraries at least follow PEP 8, and the javaNaming isn't so widespread that we couldn't fix it for Py3k.
And as Brett says, if you got a working replacement for any badly implemented module and are willing to maintain it, there's almost nothing preventing replacing it.SQAAAAJTAAAABGJvZHlSUwAAAWVBbHNvLCBpdCdzIG5vdCByZWFsbHkgdGhhdCBiYWQgKCJldmVy
eSBsaWJyYXJ5IGhhcyBpdOKAmXMgb3duIGNvZGUgc3R5bGUiLi4uKSAtLSBtb3N0IGxpYnJhcmll
cyBhdCBsZWFzdCBmb2xsb3cgUEVQIDgsIGFuZCB0aGUgamF2YU5hbWluZyBpc24ndCBzbyB3aWRl
c3ByZWFkIHRoYXQgd2UgY291bGRuJ3QgZml4IGl0IGZvciBQeTNrLgoKQW5kIGFzIEJyZXR0IHNh
eXMsIGlmIHlvdSBnb3QgYSB3b3JraW5nIHJlcGxhY2VtZW50IGZvciBhbnkgYmFkbHkgaW1wbGVt
ZW50ZWQgbW9kdWxlIGFuZCBhcmUgd2lsbGluZyB0byBtYWludGFpbiBpdCwgdGhlcmUncyBhbG1v
c3Qgbm90aGluZyBwcmV2ZW50aW5nIHJlcGxhY2luZyBpdC5MAABTAAAABnBhcnNlclMAAAAEaHRt
bA==
Python Template Engine Comparisonhttp://lucumr.pocoo.org/cogitations/2008/01/01/python-template-engine-comparison/2008-01-01T20:32:12Z2008-01-01T20:32:12ZArmin Ronacherpython-template-engine-comparisonyesyes2I was small-talking with <a href="http://techspot.zzzeek.org/">zzzeek</a> about some things when I told him that I'm using Jinja, Genshi and Mako depending on what I'm doing. He told me that it's unusual to switch tools like that but I don't think it's that unusual.
All three template engines are totally different but have a one thing in common: All three are the "second generation" of template engines. Genshi is the formal successor of kid, Mako somewhat replaced Mygthy and Jinja was inspired by the django templates. All three of them are framework agnostic, use unicode internally and have a cool API you can use in WSGI applications without scratching your head. But what inspired those template engines and which template engine to chose for which situation?
I often used PHP in the past to do simple header/footer inclusion. But what always drove me nuts was that I had to use mod_rewrite to get nice URLs or use a bunch of folders with index.php files or use files and folders and drop the extension in the apache config. While this is nice, this is now that portable and you can't have dynamic parts in the URL and once you want some more dynamic stuff such as RSS feeds etc. you notice that you made a mistake by choosing PHP. Some days ago I then started working on the website for TextPress (not yet online) and wanted to try something new: I wrote a tiny WSGI application (about 50 lines of code) that just uses werkzeug's routing system and uses template names as endpoints. These templates are then loaded with Mako, rendered and returned as responses. This is not possible in the same way with Jinja because you don't have python blocks and not so simple and straightforward with Genshi because you have to think about XML or use a rather limited text based template engine. Another very cool feature of Mako is that you can do dynamic inheritance which is not possible in Jinja.
Mako is a great template engine if you know Python, if you need some logic in templates (and you know: logic in templates is not bad in every situation) and if you need the best performance. Without a doubt Mako is one of the fastest template engines for Python and the fastest template engine that does not use a C extension.
Then there is Jinja which is also a text based template engine like Mako. However the focus is on a completely different level. When Mako is like PHP, Jinja is like Smarty (even though Mako is a million times better than PHP as template engine). When I stated working with Python as programming language for web applications I stumbled about django. I looked at the template engine and thought: WTF is that? The syntax seemed odd and the restrictions ridiculous. Later on I loved the syntax (and apparently others do to: the mini template engine by Ian Bicking (tempita if I recall correctly) and the Genshi text templates are using that syntax or a similar one too) but some of the restrictions seem still ridiculous. When I looked at all those Django templates I created over the time I noticed that I often moved calculations into template tags that could be function calls, that I did other calculations in in the view functions that did not belong there and even more important: that you could replace 95% of the custom template tags with function calls or function calls with an enclosed template block if the template engine had proper expressions. This lead to the development of what is now known as Jinja. The syntax, the fact that it's sandboxed and the designed friendliness is still very similar to Django, but unlike Django python like expressions are possible in Jinja.
I'm using Jinja wherever I think web designers want to work on later on. For example as template engine for TextPress or other applications that should be styled by third party web designers.
Genshi on the other hand is an XML template engine. As a result of that it's slower but also "context aware". It knows when it's processing a CDATA section, it knows when it's inside a tag or an attribute etc. This makes it possible to defend XSS in an automatic way. Per default Genshi inserts the text into the output stream as text and not as markup. That means all the HTML entities are automatically escaped for you. And because it's stream based you can rewrite streams during the rendering process. This makes it possible to fill form fields automatically, use XInclude for simple layout templates and a lot more. You can even translate your XML based templates into HTML4 on the fly. So you can use your XML tool chain internally and output HTML4 and use the best of both worlds. But because of this high flexibility Genshi also has some problems to fight: You need to have XML knowledge to use it. No problem if you are a programmer, but not that good if you are a web designer doing fancy layouts. You are also forced to use XML templates everywhere. It's true that Genshi has text templates too to fill the gaps, but they are not comparable with real text template engines and you are still operating on an XML stream, just that you don't see it. And lastly: this whole stream processing makes Genshi slow. Not so slow that you can't use it for big applications, but noticeably slower than Mako or Jinja.
If you are using XML anyways in your application, Genshi is a very good idea. Also if you don't have template designers that don't know XML or if performance is not that much of a problem. Most of the time the bottleneck is the database anyways. I never had real problems with Genshi performance so far.
I hope this post sums up why I'm using all three template engines and why I think we should be happy that we can chose between a couple of template engines :-) Why I'm not covering other template engines like Cheetah or SimpleTAL? Mostly because I looked at them, tried them out and never used them for something big. Mostly because Mako looks a lot nicer than Cheetah to me and SimpleTAL is far too much away from Python for me.I was small-talking with <a href="http://techspot.zzzeek.org/">zzzeek</a> about some things when I told him that I'm using Jinja, Genshi and Mako depending on what I'm doing. He told me that it's unusual to switch tools like that but I don't think it's that unusual.
All three template engines are totally different but have a one thing in common: All three are the "second generation" of template engines. Genshi is the formal successor of kid, Mako somewhat replaced Mygthy and Jinja was inspired by the django templates. All three of them are framework agnostic, use unicode internally and have a cool API you can use in WSGI applications without scratching your head. But what inspired those template engines and which template engine to chose for which situation?
I often used PHP in the past to do simple header/footer inclusion. But what always drove me nuts was that I had to use mod_rewrite to get nice URLs or use a bunch of folders with index.php files or use files and folders and drop the extension in the apache config. While this is nice, this is now that portable and you can't have dynamic parts in the URL and once you want some more dynamic stuff such as RSS feeds etc. you notice that you made a mistake by choosing PHP. Some days ago I then started working on the website for TextPress (not yet online) and wanted to try something new: I wrote a tiny WSGI application (about 50 lines of code) that just uses werkzeug's routing system and uses template names as endpoints. These templates are then loaded with Mako, rendered and returned as responses. This is not possible in the same way with Jinja because you don't have python blocks and not so simple and straightforward with Genshi because you have to think about XML or use a rather limited text based template engine. Another very cool feature of Mako is that you can do dynamic inheritance which is not possible in Jinja.
Mako is a great template engine if you know Python, if you need some logic in templates (and you know: logic in templates is not bad in every situation) and if you need the best performance. Without a doubt Mako is one of the fastest template engines for Python and the fastest template engine that does not use a C extension.
Then there is Jinja which is also a text based template engine like Mako. However the focus is on a completely different level. When Mako is like PHP, Jinja is like Smarty (even though Mako is a million times better than PHP as template engine). When I stated working with Python as programming language for web applications I stumbled about django. I looked at the template engine and thought: WTF is that? The syntax seemed odd and the restrictions ridiculous. Later on I loved the syntax (and apparently others do to: the mini template engine by Ian Bicking (tempita if I recall correctly) and the Genshi text templates are using that syntax or a similar one too) but some of the restrictions seem still ridiculous. When I looked at all those Django templates I created over the time I noticed that I often moved calculations into template tags that could be function calls, that I did other calculations in in the view functions that did not belong there and even more important: that you could replace 95% of the custom template tags with function calls or function calls with an enclosed template block if the template engine had proper expressions. This lead to the development of what is now known as Jinja. The syntax, the fact that it's sandboxed and the designed friendliness is still very similar to Django, but unlike Django python like expressions are possible in Jinja.
I'm using Jinja wherever I think web designers want to work on later on. For example as template engine for TextPress or other applications that should be styled by third party web designers.
Genshi on the other hand is an XML template engine. As a result of that it's slower but also "context aware". It knows when it's processing a CDATA section, it knows when it's inside a tag or an attribute etc. This makes it possible to defend XSS in an automatic way. Per default Genshi inserts the text into the output stream as text and not as markup. That means all the HTML entities are automatically escaped for you. And because it's stream based you can rewrite streams during the rendering process. This makes it possible to fill form fields automatically, use XInclude for simple layout templates and a lot more. You can even translate your XML based templates into HTML4 on the fly. So you can use your XML tool chain internally and output HTML4 and use the best of both worlds. But because of this high flexibility Genshi also has some problems to fight: You need to have XML knowledge to use it. No problem if you are a programmer, but not that good if you are a web designer doing fancy layouts. You are also forced to use XML templates everywhere. It's true that Genshi has text templates too to fill the gaps, but they are not comparable with real text template engines and you are still operating on an XML stream, just that you don't see it. And lastly: this whole stream processing makes Genshi slow. Not so slow that you can't use it for big applications, but noticeably slower than Mako or Jinja.
If you are using XML anyways in your application, Genshi is a very good idea. Also if you don't have template designers that don't know XML or if performance is not that much of a problem. Most of the time the bottleneck is the database anyways. I never had real problems with Genshi performance so far.
I hope this post sums up why I'm using all three template engines and why I think we should be happy that we can chose between a couple of template engines :-) Why I'm not covering other template engines like Cheetah or SimpleTAL? Mostly because I looked at them, tried them out and never used them for something big. Mostly because Mako looks a lot nicer than Cheetah to me and SimpleTAL is far too much away from Python for me.SQAAAANTAAAABGJvZHlSUwAAABlJIHdhcyBzbWFsbC10YWxraW5nIHdpdGggTAABRVMAAAABYUwA
AE0AAVMAAAAEaHJlZlMAAAAbaHR0cDovL3RlY2hzcG90Lnp6emVlay5vcmcvUwAAAAZ6enplZWtT
AAAXACBhYm91dCBzb21lIHRoaW5ncyB3aGVuIEkgdG9sZCBoaW0gdGhhdCBJJ20gdXNpbmcgSmlu
amEsIEdlbnNoaSBhbmQgTWFrbyBkZXBlbmRpbmcgb24gd2hhdCBJJ20gZG9pbmcuIEhlIHRvbGQg
bWUgdGhhdCBpdCdzIHVudXN1YWwgdG8gc3dpdGNoIHRvb2xzIGxpa2UgdGhhdCBidXQgSSBkb24n
dCB0aGluayBpdCdzIHRoYXQgdW51c3VhbC4KCkFsbCB0aHJlZSB0ZW1wbGF0ZSBlbmdpbmVzIGFy
ZSB0b3RhbGx5IGRpZmZlcmVudCBidXQgaGF2ZSBhIG9uZSB0aGluZyBpbiBjb21tb246IEFsbCB0
aHJlZSBhcmUgdGhlICJzZWNvbmQgZ2VuZXJhdGlvbiIgb2YgdGVtcGxhdGUgZW5naW5lcy4gR2Vu
c2hpIGlzIHRoZSBmb3JtYWwgc3VjY2Vzc29yIG9mIGtpZCwgTWFrbyBzb21ld2hhdCByZXBsYWNl
ZCBNeWd0aHkgYW5kIEppbmphIHdhcyBpbnNwaXJlZCBieSB0aGUgZGphbmdvIHRlbXBsYXRlcy4g
QWxsIHRocmVlIG9mIHRoZW0gYXJlIGZyYW1ld29yayBhZ25vc3RpYywgdXNlIHVuaWNvZGUgaW50
ZXJuYWxseSBhbmQgaGF2ZSBhIGNvb2wgQVBJIHlvdSBjYW4gdXNlIGluIFdTR0kgYXBwbGljYXRp
b25zIHdpdGhvdXQgc2NyYXRjaGluZyB5b3VyIGhlYWQuIEJ1dCB3aGF0IGluc3BpcmVkIHRob3Nl
IHRlbXBsYXRlIGVuZ2luZXMgYW5kIHdoaWNoIHRlbXBsYXRlIGVuZ2luZSB0byBjaG9zZSBmb3Ig
d2hpY2ggc2l0dWF0aW9uPwoKSSBvZnRlbiB1c2VkIFBIUCBpbiB0aGUgcGFzdCB0byBkbyBzaW1w
bGUgaGVhZGVyL2Zvb3RlciBpbmNsdXNpb24uIEJ1dCB3aGF0IGFsd2F5cyBkcm92ZSBtZSBudXRz
IHdhcyB0aGF0IEkgaGFkIHRvIHVzZSBtb2RfcmV3cml0ZSB0byBnZXQgbmljZSBVUkxzIG9yIHVz
ZSBhIGJ1bmNoIG9mIGZvbGRlcnMgd2l0aCBpbmRleC5waHAgZmlsZXMgb3IgdXNlIGZpbGVzIGFu
ZCBmb2xkZXJzIGFuZCBkcm9wIHRoZSBleHRlbnNpb24gaW4gdGhlIGFwYWNoZSBjb25maWcuIFdo
aWxlIHRoaXMgaXMgbmljZSwgdGhpcyBpcyBub3cgdGhhdCBwb3J0YWJsZSBhbmQgeW91IGNhbid0
IGhhdmUgZHluYW1pYyBwYXJ0cyBpbiB0aGUgVVJMIGFuZCBvbmNlIHlvdSB3YW50IHNvbWUgbW9y
ZSBkeW5hbWljIHN0dWZmIHN1Y2ggYXMgUlNTIGZlZWRzIGV0Yy4geW91IG5vdGljZSB0aGF0IHlv
dSBtYWRlIGEgbWlzdGFrZSBieSBjaG9vc2luZyBQSFAuIFNvbWUgZGF5cyBhZ28gSSB0aGVuIHN0
YXJ0ZWQgd29ya2luZyBvbiB0aGUgd2Vic2l0ZSBmb3IgVGV4dFByZXNzIChub3QgeWV0IG9ubGlu
ZSkgYW5kIHdhbnRlZCB0byB0cnkgc29tZXRoaW5nIG5ldzogSSB3cm90ZSBhIHRpbnkgV1NHSSBh
cHBsaWNhdGlvbiAoYWJvdXQgNTAgbGluZXMgb2YgY29kZSkgdGhhdCBqdXN0IHVzZXMgd2Vya3pl
dWcncyByb3V0aW5nIHN5c3RlbSBhbmQgdXNlcyB0ZW1wbGF0ZSBuYW1lcyBhcyBlbmRwb2ludHMu
IFRoZXNlIHRlbXBsYXRlcyBhcmUgdGhlbiBsb2FkZWQgd2l0aCBNYWtvLCByZW5kZXJlZCBhbmQg
cmV0dXJuZWQgYXMgcmVzcG9uc2VzLiBUaGlzIGlzIG5vdCBwb3NzaWJsZSBpbiB0aGUgc2FtZSB3
YXkgd2l0aCBKaW5qYSBiZWNhdXNlIHlvdSBkb24ndCBoYXZlIHB5dGhvbiBibG9ja3MgYW5kIG5v
dCBzbyBzaW1wbGUgYW5kIHN0cmFpZ2h0Zm9yd2FyZCB3aXRoIEdlbnNoaSBiZWNhdXNlIHlvdSBo
YXZlIHRvIHRoaW5rIGFib3V0IFhNTCBvciB1c2UgYSByYXRoZXIgbGltaXRlZCB0ZXh0IGJhc2Vk
IHRlbXBsYXRlIGVuZ2luZS4gQW5vdGhlciB2ZXJ5IGNvb2wgZmVhdHVyZSBvZiBNYWtvIGlzIHRo
YXQgeW91IGNhbiBkbyBkeW5hbWljIGluaGVyaXRhbmNlIHdoaWNoIGlzIG5vdCBwb3NzaWJsZSBp
biBKaW5qYS4KCk1ha28gaXMgYSBncmVhdCB0ZW1wbGF0ZSBlbmdpbmUgaWYgeW91IGtub3cgUHl0
aG9uLCBpZiB5b3UgbmVlZCBzb21lIGxvZ2ljIGluIHRlbXBsYXRlcyAoYW5kIHlvdSBrbm93OiBs
b2dpYyBpbiB0ZW1wbGF0ZXMgaXMgbm90IGJhZCBpbiBldmVyeSBzaXR1YXRpb24pIGFuZCBpZiB5
b3UgbmVlZCB0aGUgYmVzdCBwZXJmb3JtYW5jZS4gV2l0aG91dCBhIGRvdWJ0IE1ha28gaXMgb25l
IG9mIHRoZSBmYXN0ZXN0IHRlbXBsYXRlIGVuZ2luZXMgZm9yIFB5dGhvbiBhbmQgdGhlIGZhc3Rl
c3QgdGVtcGxhdGUgZW5naW5lIHRoYXQgZG9lcyBub3QgdXNlIGEgQyBleHRlbnNpb24uCgpUaGVu
IHRoZXJlIGlzIEppbmphIHdoaWNoIGlzIGFsc28gYSB0ZXh0IGJhc2VkIHRlbXBsYXRlIGVuZ2lu
ZSBsaWtlIE1ha28uIEhvd2V2ZXIgdGhlIGZvY3VzIGlzIG9uIGEgY29tcGxldGVseSBkaWZmZXJl
bnQgbGV2ZWwuIFdoZW4gTWFrbyBpcyBsaWtlIFBIUCwgSmluamEgaXMgbGlrZSBTbWFydHkgKGV2
ZW4gdGhvdWdoIE1ha28gaXMgYSBtaWxsaW9uIHRpbWVzIGJldHRlciB0aGFuIFBIUCBhcyB0ZW1w
bGF0ZSBlbmdpbmUpLiBXaGVuIEkgc3RhdGVkIHdvcmtpbmcgd2l0aCBQeXRob24gYXMgcHJvZ3Jh
bW1pbmcgbGFuZ3VhZ2UgZm9yIHdlYiBhcHBsaWNhdGlvbnMgSSBzdHVtYmxlZCBhYm91dCBkamFu
Z28uIEkgbG9va2VkIGF0IHRoZSB0ZW1wbGF0ZSBlbmdpbmUgYW5kIHRob3VnaHQ6IFdURiBpcyB0
aGF0PyBUaGUgc3ludGF4IHNlZW1lZCBvZGQgYW5kIHRoZSByZXN0cmljdGlvbnMgcmlkaWN1bG91
cy4gTGF0ZXIgb24gSSBsb3ZlZCB0aGUgc3ludGF4IChhbmQgYXBwYXJlbnRseSBvdGhlcnMgZG8g
dG86IHRoZSBtaW5pIHRlbXBsYXRlIGVuZ2luZSBieSBJYW4gQmlja2luZyAodGVtcGl0YSBpZiBJ
IHJlY2FsbCBjb3JyZWN0bHkpIGFuZCB0aGUgR2Vuc2hpIHRleHQgdGVtcGxhdGVzIGFyZSB1c2lu
ZyB0aGF0IHN5bnRheCBvciBhIHNpbWlsYXIgb25lIHRvbykgYnV0IHNvbWUgb2YgdGhlIHJlc3Ry
aWN0aW9ucyBzZWVtIHN0aWxsIHJpZGljdWxvdXMuIFdoZW4gSSBsb29rZWQgYXQgYWxsIHRob3Nl
IERqYW5nbyB0ZW1wbGF0ZXMgSSBjcmVhdGVkIG92ZXIgdGhlIHRpbWUgSSBub3RpY2VkIHRoYXQg
SSBvZnRlbiBtb3ZlZCBjYWxjdWxhdGlvbnMgaW50byB0ZW1wbGF0ZSB0YWdzIHRoYXQgY291bGQg
YmUgZnVuY3Rpb24gY2FsbHMsIHRoYXQgSSBkaWQgb3RoZXIgY2FsY3VsYXRpb25zIGluIGluIHRo
ZSB2aWV3IGZ1bmN0aW9ucyB0aGF0IGRpZCBub3QgYmVsb25nIHRoZXJlIGFuZCBldmVuIG1vcmUg
aW1wb3J0YW50OiB0aGF0IHlvdSBjb3VsZCByZXBsYWNlIDk1JSBvZiB0aGUgY3VzdG9tIHRlbXBs
YXRlIHRhZ3Mgd2l0aCBmdW5jdGlvbiBjYWxscyBvciBmdW5jdGlvbiBjYWxscyB3aXRoIGFuIGVu
Y2xvc2VkIHRlbXBsYXRlIGJsb2NrIGlmIHRoZSB0ZW1wbGF0ZSBlbmdpbmUgaGFkIHByb3BlciBl
eHByZXNzaW9ucy4gVGhpcyBsZWFkIHRvIHRoZSBkZXZlbG9wbWVudCBvZiB3aGF0IGlzIG5vdyBr
bm93biBhcyBKaW5qYS4gVGhlIHN5bnRheCwgdGhlIGZhY3QgdGhhdCBpdCdzIHNhbmRib3hlZCBh
bmQgdGhlIGRlc2lnbmVkIGZyaWVuZGxpbmVzcyBpcyBzdGlsbCB2ZXJ5IHNpbWlsYXIgdG8gRGph
bmdvLCBidXQgdW5saWtlIERqYW5nbyBweXRob24gbGlrZSBleHByZXNzaW9ucyBhcmUgcG9zc2li
bGUgaW4gSmluamEuCgpJJ20gdXNpbmcgSmluamEgd2hlcmV2ZXIgSSB0aGluayB3ZWIgZGVzaWdu
ZXJzIHdhbnQgdG8gd29yayBvbiBsYXRlciBvbi4gRm9yIGV4YW1wbGUgYXMgdGVtcGxhdGUgZW5n
aW5lIGZvciBUZXh0UHJlc3Mgb3Igb3RoZXIgYXBwbGljYXRpb25zIHRoYXQgc2hvdWxkIGJlIHN0
eWxlZCBieSB0aGlyZCBwYXJ0eSB3ZWIgZGVzaWduZXJzLgoKR2Vuc2hpIG9uIHRoZSBvdGhlciBo
YW5kIGlzIGFuIFhNTCB0ZW1wbGF0ZSBlbmdpbmUuIEFzIGEgcmVzdWx0IG9mIHRoYXQgaXQncyBz
bG93ZXIgYnV0IGFsc28gImNvbnRleHQgYXdhcmUiLiBJdCBrbm93cyB3aGVuIGl0J3MgcHJvY2Vz
c2luZyBhIENEQVRBIHNlY3Rpb24sIGl0IGtub3dzIHdoZW4gaXQncyBpbnNpZGUgYSB0YWcgb3Ig
YW4gYXR0cmlidXRlIGV0Yy4gVGhpcyBtYWtlcyBpdCBwb3NzaWJsZSB0byBkZWZlbmQgWFNTIGlu
IGFuIGF1dG9tYXRpYyB3YXkuIFBlciBkZWZhdWx0IEdlbnNoaSBpbnNlcnRzIHRoZSB0ZXh0IGlu
dG8gdGhlIG91dHB1dCBzdHJlYW0gYXMgdGV4dCBhbmQgbm90IGFzIG1hcmt1cC4gVGhhdCBtZWFu
cyBhbGwgdGhlIEhUTUwgZW50aXRpZXMgYXJlIGF1dG9tYXRpY2FsbHkgZXNjYXBlZCBmb3IgeW91
LiBBbmQgYmVjYXVzZSBpdCdzIHN0cmVhbSBiYXNlZCB5b3UgY2FuIHJld3JpdGUgc3RyZWFtcyBk
dXJpbmcgdGhlIHJlbmRlcmluZyBwcm9jZXNzLiBUaGlzIG1ha2VzIGl0IHBvc3NpYmxlIHRvIGZp
bGwgZm9ybSBmaWVsZHMgYXV0b21hdGljYWxseSwgdXNlIFhJbmNsdWRlIGZvciBzaW1wbGUgbGF5
b3V0IHRlbXBsYXRlcyBhbmQgYSBsb3QgbW9yZS4gWW91IGNhbiBldmVuIHRyYW5zbGF0ZSB5b3Vy
IFhNTCBiYXNlZCB0ZW1wbGF0ZXMgaW50byBIVE1MNCBvbiB0aGUgZmx5LiBTbyB5b3UgY2FuIHVz
ZSB5b3VyIFhNTCB0b29sIGNoYWluIGludGVybmFsbHkgYW5kIG91dHB1dCBIVE1MNCBhbmQgdXNl
IHRoZSBiZXN0IG9mIGJvdGggd29ybGRzLiBCdXQgYmVjYXVzZSBvZiB0aGlzIGhpZ2ggZmxleGli
aWxpdHkgR2Vuc2hpIGFsc28gaGFzIHNvbWUgcHJvYmxlbXMgdG8gZmlnaHQ6IFlvdSBuZWVkIHRv
IGhhdmUgWE1MIGtub3dsZWRnZSB0byB1c2UgaXQuIE5vIHByb2JsZW0gaWYgeW91IGFyZSBhIHBy
b2dyYW1tZXIsIGJ1dCBub3QgdGhhdCBnb29kIGlmIHlvdSBhcmUgYSB3ZWIgZGVzaWduZXIgZG9p
bmcgZmFuY3kgbGF5b3V0cy4gWW91IGFyZSBhbHNvIGZvcmNlZCB0byB1c2UgWE1MIHRlbXBsYXRl
cyBldmVyeXdoZXJlLiBJdCdzIHRydWUgdGhhdCBHZW5zaGkgaGFzIHRleHQgdGVtcGxhdGVzIHRv
byB0byBmaWxsIHRoZSBnYXBzLCBidXQgdGhleSBhcmUgbm90IGNvbXBhcmFibGUgd2l0aCByZWFs
IHRleHQgdGVtcGxhdGUgZW5naW5lcyBhbmQgeW91IGFyZSBzdGlsbCBvcGVyYXRpbmcgb24gYW4g
WE1MIHN0cmVhbSwganVzdCB0aGF0IHlvdSBkb24ndCBzZWUgaXQuIEFuZCBsYXN0bHk6IHRoaXMg
d2hvbGUgc3RyZWFtIHByb2Nlc3NpbmcgbWFrZXMgR2Vuc2hpIHNsb3cuIE5vdCBzbyBzbG93IHRo
YXQgeW91IGNhbid0IHVzZSBpdCBmb3IgYmlnIGFwcGxpY2F0aW9ucywgYnV0IG5vdGljZWFibHkg
c2xvd2VyIHRoYW4gTWFrbyBvciBKaW5qYS4KCklmIHlvdSBhcmUgdXNpbmcgWE1MIGFueXdheXMg
aW4geW91ciBhcHBsaWNhdGlvbiwgR2Vuc2hpIGlzIGEgdmVyeSBnb29kIGlkZWEuIEFsc28gaWYg
eW91IGRvbid0IGhhdmUgdGVtcGxhdGUgZGVzaWduZXJzIHRoYXQgZG9uJ3Qga25vdyBYTUwgb3Ig
aWYgcGVyZm9ybWFuY2UgaXMgbm90IHRoYXQgbXVjaCBvZiBhIHByb2JsZW0uIE1vc3Qgb2YgdGhl
IHRpbWUgdGhlIGJvdHRsZW5lY2sgaXMgdGhlIGRhdGFiYXNlIGFueXdheXMuIEkgbmV2ZXIgaGFk
IHJlYWwgcHJvYmxlbXMgd2l0aCBHZW5zaGkgcGVyZm9ybWFuY2Ugc28gZmFyLgoKSSBob3BlIHRo
aXMgcG9zdCBzdW1zIHVwIHdoeSBJJ20gdXNpbmcgYWxsIHRocmVlIHRlbXBsYXRlIGVuZ2luZXMg
YW5kIHdoeSBJIHRoaW5rIHdlIHNob3VsZCBiZSBoYXBweSB0aGF0IHdlIGNhbiBjaG9zZSBiZXR3
ZWVuIGEgY291cGxlIG9mIHRlbXBsYXRlIGVuZ2luZXMgOi0pIFdoeSBJJ20gbm90IGNvdmVyaW5n
IG90aGVyIHRlbXBsYXRlIGVuZ2luZXMgbGlrZSBDaGVldGFoIG9yIFNpbXBsZVRBTD8gTW9zdGx5
IGJlY2F1c2UgSSBsb29rZWQgYXQgdGhlbSwgdHJpZWQgdGhlbSBvdXQgYW5kIG5ldmVyIHVzZWQg
dGhlbSBmb3Igc29tZXRoaW5nIGJpZy4gTW9zdGx5IGJlY2F1c2UgTWFrbyBsb29rcyBhIGxvdCBu
aWNlciB0aGFuIENoZWV0YWggdG8gbWUgYW5kIFNpbXBsZVRBTCBpcyBmYXIgdG9vIG11Y2ggYXdh
eSBmcm9tIFB5dGhvbiBmb3IgbWUuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAA
TAAA
Braydon Fullercourier@braydon.comhttp://braydon.com/2008-01-01T23:35:12Znono0"I hope this post sums up why I’m using all three template engines and why I think we should be happy that we can chose between a couple of template engines :-)"
Word! :)
I am using Cheetah on a current project, and haven't run into any problems yet. I'll have to try out Mako and see how it compares, and what will work best for my different projects. I had a similar reaction to Django's templates at first, but haven't used them yet to get to know it better."I hope this post sums up why I’m using all three template engines and why I think we should be happy that we can chose between a couple of template engines :-)"
Word! :)
I am using Cheetah on a current project, and haven't run into any problems yet. I'll have to try out Mako and see how it compares, and what will work best for my different projects. I had a similar reaction to Django's templates at first, but haven't used them yet to get to know it better.SQAAAAJTAAAABGJvZHlSUwAAAdEiSSBob3BlIHRoaXMgcG9zdCBzdW1zIHVwIHdoeSBJ4oCZbSB1
c2luZyBhbGwgdGhyZWUgdGVtcGxhdGUgZW5naW5lcyBhbmQgd2h5IEkgdGhpbmsgd2Ugc2hvdWxk
IGJlIGhhcHB5IHRoYXQgd2UgY2FuIGNob3NlIGJldHdlZW4gYSBjb3VwbGUgb2YgdGVtcGxhdGUg
ZW5naW5lcyA6LSkiCgpXb3JkISA6KQoKSSBhbSB1c2luZyBDaGVldGFoIG9uIGEgY3VycmVudCBw
cm9qZWN0LCBhbmQgaGF2ZW4ndCBydW4gaW50byBhbnkgcHJvYmxlbXMgeWV0LiBJJ2xsIGhhdmUg
dG8gdHJ5IG91dCBNYWtvIGFuZCBzZWUgaG93IGl0IGNvbXBhcmVzLCBhbmQgd2hhdCB3aWxsIHdv
cmsgYmVzdCBmb3IgbXkgZGlmZmVyZW50IHByb2plY3RzLiBJIGhhZCBhIHNpbWlsYXIgcmVhY3Rp
b24gdG8gRGphbmdvJ3MgdGVtcGxhdGVzIGF0IGZpcnN0LCBidXQgaGF2ZW4ndCB1c2VkIHRoZW0g
eWV0IHRvIGdldCB0byBrbm93IGl0IGJldHRlci5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2008-01-02T02:02:42Znono0You must have been reading my mind as it was only a few days ago that I was trying to get hold of you on IRC to discuss your opinions on different templating solutions. You weren't around at the time though.
One question I still have though about Jinja is, in practice what it's sandboxing really means, given that in Python it is pretty well impossible to create a restricted execution environment that you can't break out of in some way.
So, what are the benefits of otherwise of sandboxing in Jinja?You must have been reading my mind as it was only a few days ago that I was trying to get hold of you on IRC to discuss your opinions on different templating solutions. You weren't around at the time though.
One question I still have though about Jinja is, in practice what it's sandboxing really means, given that in Python it is pretty well impossible to create a restricted execution environment that you can't break out of in some way.
So, what are the benefits of otherwise of sandboxing in Jinja?SQAAAAJTAAAABGJvZHlSUwAAAfhZb3UgbXVzdCBoYXZlIGJlZW4gcmVhZGluZyBteSBtaW5kIGFz
IGl0IHdhcyBvbmx5IGEgZmV3IGRheXMgYWdvIHRoYXQgSSB3YXMgdHJ5aW5nIHRvIGdldCBob2xk
IG9mIHlvdSBvbiBJUkMgdG8gZGlzY3VzcyB5b3VyIG9waW5pb25zIG9uIGRpZmZlcmVudCB0ZW1w
bGF0aW5nIHNvbHV0aW9ucy4gWW91IHdlcmVuJ3QgYXJvdW5kIGF0IHRoZSB0aW1lIHRob3VnaC4K
Ck9uZSBxdWVzdGlvbiBJIHN0aWxsIGhhdmUgdGhvdWdoIGFib3V0IEppbmphIGlzLCBpbiBwcmFj
dGljZSB3aGF0IGl0J3Mgc2FuZGJveGluZyByZWFsbHkgbWVhbnMsIGdpdmVuIHRoYXQgaW4gUHl0
aG9uIGl0IGlzIHByZXR0eSB3ZWxsIGltcG9zc2libGUgdG8gY3JlYXRlIGEgcmVzdHJpY3RlZCBl
eGVjdXRpb24gZW52aXJvbm1lbnQgdGhhdCB5b3UgY2FuJ3QgYnJlYWsgb3V0IG9mIGluIHNvbWUg
d2F5LgoKU28sIHdoYXQgYXJlIHRoZSBiZW5lZml0cyBvZiBvdGhlcndpc2Ugb2Ygc2FuZGJveGlu
ZyBpbiBKaW5qYT9MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2008-01-02T09:05:51Znono0Before the big parser rewrite Jinja wandered through the AST and intercepted all dangerous operations. This basically works the same with the new parser too, but some things such as "item assignment unpacking during iteration" is not allowed in the new syntax and so there is no check for that any more.
So basically what Jinja does currently is disallowing all access to attributes like "__subclasses__", disallowing attribute modifications on objects passed to the context, recursive includes, infinite loops etc.
I think as long as you can limit the syntax to expressions there are ways to restrict Python enough to allow the execution of untrusted code.Before the big parser rewrite Jinja wandered through the AST and intercepted all dangerous operations. This basically works the same with the new parser too, but some things such as "item assignment unpacking during iteration" is not allowed in the new syntax and so there is no check for that any more.
So basically what Jinja does currently is disallowing all access to attributes like "__subclasses__", disallowing attribute modifications on objects passed to the context, recursive includes, infinite loops etc.
I think as long as you can limit the syntax to expressions there are ways to restrict Python enough to allow the execution of untrusted code.SQAAAAJTAAAABGJvZHlSUwAAApNCZWZvcmUgdGhlIGJpZyBwYXJzZXIgcmV3cml0ZSBKaW5qYSB3
YW5kZXJlZCB0aHJvdWdoIHRoZSBBU1QgYW5kIGludGVyY2VwdGVkIGFsbCBkYW5nZXJvdXMgb3Bl
cmF0aW9ucy4gVGhpcyBiYXNpY2FsbHkgd29ya3MgdGhlIHNhbWUgd2l0aCB0aGUgbmV3IHBhcnNl
ciB0b28sIGJ1dCBzb21lIHRoaW5ncyBzdWNoIGFzICJpdGVtIGFzc2lnbm1lbnQgdW5wYWNraW5n
IGR1cmluZyBpdGVyYXRpb24iIGlzIG5vdCBhbGxvd2VkIGluIHRoZSBuZXcgc3ludGF4IGFuZCBz
byB0aGVyZSBpcyBubyBjaGVjayBmb3IgdGhhdCBhbnkgbW9yZS4KClNvIGJhc2ljYWxseSB3aGF0
IEppbmphIGRvZXMgY3VycmVudGx5IGlzIGRpc2FsbG93aW5nIGFsbCBhY2Nlc3MgdG8gYXR0cmli
dXRlcyBsaWtlICJfX3N1YmNsYXNzZXNfXyIsIGRpc2FsbG93aW5nIGF0dHJpYnV0ZSBtb2RpZmlj
YXRpb25zIG9uIG9iamVjdHMgcGFzc2VkIHRvIHRoZSBjb250ZXh0LCByZWN1cnNpdmUgaW5jbHVk
ZXMsIGluZmluaXRlIGxvb3BzIGV0Yy4KCkkgdGhpbmsgYXMgbG9uZyBhcyB5b3UgY2FuIGxpbWl0
IHRoZSBzeW50YXggdG8gZXhwcmVzc2lvbnMgdGhlcmUgYXJlIHdheXMgdG8gcmVzdHJpY3QgUHl0
aG9uIGVub3VnaCB0byBhbGxvdyB0aGUgZXhlY3V0aW9uIG9mIHVudHJ1c3RlZCBjb2RlLkwAAFMA
AAAGcGFyc2VyUwAAAARodG1s
Eric Larsoneric@ionrock.orghttp://ionrock.org/blog/2008-01-02T21:31:59Znono0Great overview of these excellent templating libraries.
If you (or anyone else) is interested in an XSLT based WSGI middleware templating solution, there is XSLTemplates (http://code.google.com/p/xsltemplates). I am the author, but really it is just a simple way to use XSLT with 4Suite/Amara within WSGI web applications.
I tried to use Kid and just couldn't grab onto the mix between XSLT and other templating languages, so I looked into BuffetXSLT, which was lacking the more obvious templating pieces like passing in parameters and data structures (node-set in XSLT). This lead me to XSLTemplates.
I'm aiming at making it easy to do things like adding your own helper functions and sending parameters and node-sets to templates. If any one does try it out, feel free to send along comments or suggestions.Great overview of these excellent templating libraries.
If you (or anyone else) is interested in an XSLT based WSGI middleware templating solution, there is XSLTemplates (http://code.google.com/p/xsltemplates). I am the author, but really it is just a simple way to use XSLT with 4Suite/Amara within WSGI web applications.
I tried to use Kid and just couldn't grab onto the mix between XSLT and other templating languages, so I looked into BuffetXSLT, which was lacking the more obvious templating pieces like passing in parameters and data structures (node-set in XSLT). This lead me to XSLTemplates.
I'm aiming at making it easy to do things like adding your own helper functions and sending parameters and node-sets to templates. If any one does try it out, feel free to send along comments or suggestions.SQAAAAJTAAAABGJvZHlSUwAAAy9HcmVhdCBvdmVydmlldyBvZiB0aGVzZSBleGNlbGxlbnQgdGVt
cGxhdGluZyBsaWJyYXJpZXMuIAoKSWYgeW91IChvciBhbnlvbmUgZWxzZSkgaXMgaW50ZXJlc3Rl
ZCBpbiBhbiBYU0xUIGJhc2VkIFdTR0kgbWlkZGxld2FyZSB0ZW1wbGF0aW5nIHNvbHV0aW9uLCB0
aGVyZSBpcyBYU0xUZW1wbGF0ZXMgKGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC94c2x0ZW1wbGF0
ZXMpLiBJIGFtIHRoZSBhdXRob3IsIGJ1dCByZWFsbHkgaXQgaXMganVzdCBhIHNpbXBsZSB3YXkg
dG8gdXNlIFhTTFQgd2l0aCA0U3VpdGUvQW1hcmEgd2l0aGluIFdTR0kgd2ViIGFwcGxpY2F0aW9u
cy4gCgpJIHRyaWVkIHRvIHVzZSBLaWQgYW5kIGp1c3QgY291bGRuJ3QgZ3JhYiBvbnRvIHRoZSBt
aXggYmV0d2VlbiBYU0xUIGFuZCBvdGhlciB0ZW1wbGF0aW5nIGxhbmd1YWdlcywgc28gSSBsb29r
ZWQgaW50byBCdWZmZXRYU0xULCB3aGljaCB3YXMgbGFja2luZyB0aGUgbW9yZSBvYnZpb3VzIHRl
bXBsYXRpbmcgcGllY2VzIGxpa2UgcGFzc2luZyBpbiBwYXJhbWV0ZXJzIGFuZCBkYXRhIHN0cnVj
dHVyZXMgKG5vZGUtc2V0IGluIFhTTFQpLiBUaGlzIGxlYWQgbWUgdG8gWFNMVGVtcGxhdGVzLiAK
CkknbSBhaW1pbmcgYXQgbWFraW5nIGl0IGVhc3kgdG8gZG8gdGhpbmdzIGxpa2UgYWRkaW5nIHlv
dXIgb3duIGhlbHBlciBmdW5jdGlvbnMgYW5kIHNlbmRpbmcgcGFyYW1ldGVycyBhbmQgbm9kZS1z
ZXRzIHRvIHRlbXBsYXRlcy4gSWYgYW55IG9uZSBkb2VzIHRyeSBpdCBvdXQsIGZlZWwgZnJlZSB0
byBzZW5kIGFsb25nIGNvbW1lbnRzIG9yIHN1Z2dlc3Rpb25zLkwAAFMAAAAGcGFyc2VyUwAAAARo
dG1s
No, no, It’s just restinghttp://lucumr.pocoo.org/cogitations/2007/12/23/no-no-its-just-resting/2007-12-23T22:28:10Z2007-12-23T22:28:10ZArmin Ronacherno-no-its-just-restingyesyes2Currently on <a href="http://pocoo.org/">pocoo.org</a> is a semi static webpage with a completely unmaintained semi static blog and completely outdated information. While pocoo is not dead yet (just resting) it's time to put something on the front page that represents the current state of the situation in a better way.
Let's see if we can get that updated in the next two weeks. Oh, and TextPress is now up to date again, a bunch of bugs were fixed and we're much nearer to a release than some weeks ago, but unfortunately we're behind the roadmap once again :-)Currently on <a href="http://pocoo.org/">pocoo.org</a> is a semi static webpage with a completely unmaintained semi static blog and completely outdated information. While pocoo is not dead yet (just resting) it's time to put something on the front page that represents the current state of the situation in a better way.
Let's see if we can get that updated in the next two weeks. Oh, and TextPress is now up to date again, a bunch of bugs were fixed and we're much nearer to a release than some weeks ago, but unfortunately we're behind the roadmap once again :-)SQAAAANTAAAABGJvZHlSUwAAAA1DdXJyZW50bHkgb24gTAABRVMAAAABYUwAAE0AAVMAAAAEaHJl
ZlMAAAARaHR0cDovL3BvY29vLm9yZy9TAAAACXBvY29vLm9yZ1MAAAH/IGlzIGEgc2VtaSBzdGF0
aWMgd2VicGFnZSB3aXRoIGEgY29tcGxldGVseSB1bm1haW50YWluZWQgc2VtaSBzdGF0aWMgYmxv
ZyBhbmQgY29tcGxldGVseSBvdXRkYXRlZCBpbmZvcm1hdGlvbi4gV2hpbGUgcG9jb28gaXMgbm90
IGRlYWQgeWV0IChqdXN0IHJlc3RpbmcpIGl0J3MgdGltZSB0byBwdXQgc29tZXRoaW5nIG9uIHRo
ZSBmcm9udCBwYWdlIHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgc2l0
dWF0aW9uIGluIGEgYmV0dGVyIHdheS4KCkxldCdzIHNlZSBpZiB3ZSBjYW4gZ2V0IHRoYXQgdXBk
YXRlZCBpbiB0aGUgbmV4dCB0d28gd2Vla3MuIE9oLCBhbmQgVGV4dFByZXNzIGlzIG5vdyB1cCB0
byBkYXRlIGFnYWluLCBhIGJ1bmNoIG9mIGJ1Z3Mgd2VyZSBmaXhlZCBhbmQgd2UncmUgbXVjaCBu
ZWFyZXIgdG8gYSByZWxlYXNlIHRoYW4gc29tZSB3ZWVrcyBhZ28sIGJ1dCB1bmZvcnR1bmF0ZWx5
IHdlJ3JlIGJlaGluZCB0aGUgcm9hZG1hcCBvbmNlIGFnYWluIDotKVMAAAAGcGFyc2VyUwAAAARo
dG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
johnjohn.w@web.de2007-12-28T18:18:58Znono0Ahh, you're just five days late, you can still release it in 2007 ;)
But great to see progress !!Ahh, you're just five days late, you can still release it in 2007 ;)
But great to see progress !!SQAAAAJTAAAABGJvZHlSUwAAAGJBaGgsIHlvdSdyZSBqdXN0IGZpdmUgZGF5cyBsYXRlLCB5b3Ug
Y2FuIHN0aWxsIHJlbGVhc2UgaXQgaW4gMjAwNyA7KQoKQnV0IGdyZWF0IHRvIHNlZSBwcm9ncmVz
cyAhIUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Merry Christmas!http://lucumr.pocoo.org/cogitations/2007/12/22/merry-christmas/2007-12-22T17:46:02Z2007-12-22T17:46:02ZArmin Ronachermerry-christmasyesyes2Again we're coming close to December the 24th, a day many people will spend with their families or friends to celebrate. I want to use this Christmas to say thank you to a couple of persons that helped me a lot the last years, either directly or indirectly due to their tremendous work in the Open Source community.
First of all I want to thank you Georg Brandl, who you thought me a lot about Python's internals. You had an answer to pretty all of my questions and you were the first person I worked with on a real Open Source project. Even though we still don't have Pocoo released it was great fun to work with you.
Thank you Benjamin Wiegand, Christoph Hack and Christopher Grebs for all your code contributions and your work on Pocoo and the Pocoo libraries.
A big thank you to the whole ubuntuusers team, also those of you who left the team in the past. We had many problems in the past but I looking back those three years I think most of the time we worked together in the past were plesant :-)
Thank you Marek Kubica for all those nice discussions we've had. And thanks for your work on the German Python community and your patches to the Pocoo libraries. I guess the python forum and wiki wouldn't be the same without you.
Of course a big thank you to Alexander Schremmer who keeps the pocoo server running. Learned a lot from you :-)
Also a big thank you to Fritz Cizmarov who introduced me to ubuntu. Unfortunately he passed away two years ago but I'll never forget him.
I also want to thank Mike Bayers for his work on SQLAlchemy which I use on a daily basis, all the guys over at edgewall for Genshi and Trac, the mercurial people for their ass-kicking DVCS, Martijn Faassen for lxml and all the people working on ubuntu.
Keep up the good work and Merry Christmas to you all!Again we're coming close to December the 24th, a day many people will spend with their families or friends to celebrate. I want to use this Christmas to say thank you to a couple of persons that helped me a lot the last years, either directly or indirectly due to their tremendous work in the Open Source community.
First of all I want to thank you Georg Brandl, who you thought me a lot about Python's internals. You had an answer to pretty all of my questions and you were the first person I worked with on a real Open Source project. Even though we still don't have Pocoo released it was great fun to work with you.
Thank you Benjamin Wiegand, Christoph Hack and Christopher Grebs for all your code contributions and your work on Pocoo and the Pocoo libraries.
A big thank you to the whole ubuntuusers team, also those of you who left the team in the past. We had many problems in the past but I looking back those three years I think most of the time we worked together in the past were plesant :-)
Thank you Marek Kubica for all those nice discussions we've had. And thanks for your work on the German Python community and your patches to the Pocoo libraries. I guess the python forum and wiki wouldn't be the same without you.
Of course a big thank you to Alexander Schremmer who keeps the pocoo server running. Learned a lot from you :-)
Also a big thank you to Fritz Cizmarov who introduced me to ubuntu. Unfortunately he passed away two years ago but I'll never forget him.
I also want to thank Mike Bayers for his work on SQLAlchemy which I use on a daily basis, all the guys over at edgewall for Genshi and Trac, the mercurial people for their ass-kicking DVCS, Martijn Faassen for lxml and all the people working on ubuntu.
Keep up the good work and Merry Christmas to you all!SQAAAANTAAAABGJvZHlSUwAABwVBZ2FpbiB3ZSdyZSBjb21pbmcgY2xvc2UgdG8gRGVjZW1iZXIg
dGhlIDI0dGgsIGEgZGF5IG1hbnkgcGVvcGxlIHdpbGwgc3BlbmQgd2l0aCB0aGVpciBmYW1pbGll
cyBvciBmcmllbmRzIHRvIGNlbGVicmF0ZS4gSSB3YW50IHRvIHVzZSB0aGlzIENocmlzdG1hcyB0
byBzYXkgdGhhbmsgeW91IHRvIGEgY291cGxlIG9mIHBlcnNvbnMgdGhhdCBoZWxwZWQgbWUgYSBs
b3QgdGhlIGxhc3QgeWVhcnMsIGVpdGhlciBkaXJlY3RseSBvciBpbmRpcmVjdGx5IGR1ZSB0byB0
aGVpciB0cmVtZW5kb3VzIHdvcmsgaW4gdGhlIE9wZW4gU291cmNlIGNvbW11bml0eS4KCkZpcnN0
IG9mIGFsbCBJIHdhbnQgdG8gdGhhbmsgeW91IEdlb3JnIEJyYW5kbCwgd2hvIHlvdSB0aG91Z2h0
IG1lIGEgbG90IGFib3V0IFB5dGhvbidzIGludGVybmFscy4gWW91IGhhZCBhbiBhbnN3ZXIgdG8g
cHJldHR5IGFsbCBvZiBteSBxdWVzdGlvbnMgYW5kIHlvdSB3ZXJlIHRoZSBmaXJzdCBwZXJzb24g
SSB3b3JrZWQgd2l0aCBvbiBhIHJlYWwgT3BlbiBTb3VyY2UgcHJvamVjdC4gRXZlbiB0aG91Z2gg
d2Ugc3RpbGwgZG9uJ3QgaGF2ZSBQb2NvbyByZWxlYXNlZCBpdCB3YXMgZ3JlYXQgZnVuIHRvIHdv
cmsgd2l0aCB5b3UuCgpUaGFuayB5b3UgQmVuamFtaW4gV2llZ2FuZCwgQ2hyaXN0b3BoIEhhY2sg
YW5kIENocmlzdG9waGVyIEdyZWJzIGZvciBhbGwgeW91ciBjb2RlIGNvbnRyaWJ1dGlvbnMgYW5k
IHlvdXIgd29yayBvbiBQb2NvbyBhbmQgdGhlIFBvY29vIGxpYnJhcmllcy4KCkEgYmlnIHRoYW5r
IHlvdSB0byB0aGUgd2hvbGUgdWJ1bnR1dXNlcnMgdGVhbSwgYWxzbyB0aG9zZSBvZiB5b3Ugd2hv
IGxlZnQgdGhlIHRlYW0gaW4gdGhlIHBhc3QuIFdlIGhhZCBtYW55IHByb2JsZW1zIGluIHRoZSBw
YXN0IGJ1dCBJIGxvb2tpbmcgYmFjayB0aG9zZSB0aHJlZSB5ZWFycyBJIHRoaW5rIG1vc3Qgb2Yg
dGhlIHRpbWUgd2Ugd29ya2VkIHRvZ2V0aGVyIGluIHRoZSBwYXN0IHdlcmUgcGxlc2FudCA6LSkK
ClRoYW5rIHlvdSBNYXJlayBLdWJpY2EgZm9yIGFsbCB0aG9zZSBuaWNlIGRpc2N1c3Npb25zIHdl
J3ZlIGhhZC4gQW5kIHRoYW5rcyBmb3IgeW91ciB3b3JrIG9uIHRoZSBHZXJtYW4gUHl0aG9uIGNv
bW11bml0eSBhbmQgeW91ciBwYXRjaGVzIHRvIHRoZSBQb2NvbyBsaWJyYXJpZXMuIEkgZ3Vlc3Mg
dGhlIHB5dGhvbiBmb3J1bSBhbmQgd2lraSB3b3VsZG4ndCBiZSB0aGUgc2FtZSB3aXRob3V0IHlv
dS4KCk9mIGNvdXJzZSBhIGJpZyB0aGFuayB5b3UgdG8gQWxleGFuZGVyIFNjaHJlbW1lciB3aG8g
a2VlcHMgdGhlIHBvY29vIHNlcnZlciBydW5uaW5nLiBMZWFybmVkIGEgbG90IGZyb20geW91IDot
KQoKQWxzbyBhIGJpZyB0aGFuayB5b3UgdG8gRnJpdHogQ2l6bWFyb3Ygd2hvIGludHJvZHVjZWQg
bWUgdG8gdWJ1bnR1LiBVbmZvcnR1bmF0ZWx5IGhlIHBhc3NlZCBhd2F5IHR3byB5ZWFycyBhZ28g
YnV0IEknbGwgbmV2ZXIgZm9yZ2V0IGhpbS4KCkkgYWxzbyB3YW50IHRvIHRoYW5rIE1pa2UgQmF5
ZXJzIGZvciBoaXMgd29yayBvbiBTUUxBbGNoZW15IHdoaWNoIEkgdXNlIG9uIGEgZGFpbHkgYmFz
aXMsIGFsbCB0aGUgZ3V5cyBvdmVyIGF0IGVkZ2V3YWxsIGZvciBHZW5zaGkgYW5kIFRyYWMsIHRo
ZSBtZXJjdXJpYWwgcGVvcGxlIGZvciB0aGVpciBhc3Mta2lja2luZyBEVkNTLCBNYXJ0aWpuIEZh
YXNzZW4gZm9yIGx4bWwgYW5kIGFsbCB0aGUgcGVvcGxlIHdvcmtpbmcgb24gdWJ1bnR1LgoKS2Vl
cCB1cCB0aGUgZ29vZCB3b3JrIGFuZCBNZXJyeSBDaHJpc3RtYXMgdG8geW91IGFsbCFMAABTAAAA
BnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
This Week in Pushin’ Bugs…http://lucumr.pocoo.org/cogitations/2007/12/17/this-week-in-pushin-bugs/2007-12-17T12:23:50Z2007-12-17T12:23:50ZArmin Ronacherthis-week-in-pushin-bugsyesyes2<a href="https://bugs.launchpad.net/ubuntu/+source/xkeyboard-config/+bug/59572">This wonderful feature request for the German Keyboard Layouts</a>. Open since quite a while and easy to fix (if someone knows how to do it).
And if one finds some intuitive places for emdash, endash, ellipsis and some other often used typographical characters and gets that into the next LTS he/she gets a hug :-)<a href="https://bugs.launchpad.net/ubuntu/+source/xkeyboard-config/+bug/59572">This wonderful feature request for the German Keyboard Layouts</a>. Open since quite a while and easy to fix (if someone knows how to do it).
And if one finds some intuitive places for emdash, endash, ellipsis and some other often used typographical characters and gets that into the next LTS he/she gets a hug :-)SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAEVodHRwczov
L2J1Z3MubGF1bmNocGFkLm5ldC91YnVudHUvK3NvdXJjZS94a2V5Ym9hcmQtY29uZmlnLytidWcv
NTk1NzJTAAAAPlRoaXMgd29uZGVyZnVsIGZlYXR1cmUgcmVxdWVzdCBmb3IgdGhlIEdlcm1hbiBL
ZXlib2FyZCBMYXlvdXRzUwAAAPkuIE9wZW4gc2luY2UgcXVpdGUgYSB3aGlsZSBhbmQgZWFzeSB0
byBmaXggKGlmIHNvbWVvbmUga25vd3MgaG93IHRvIGRvIGl0KS4KCkFuZCBpZiBvbmUgZmluZHMg
c29tZSBpbnR1aXRpdmUgcGxhY2VzIGZvciBlbWRhc2gsIGVuZGFzaCwgZWxsaXBzaXMgYW5kIHNv
bWUgb3RoZXIgb2Z0ZW4gdXNlZCB0eXBvZ3JhcGhpY2FsIGNoYXJhY3RlcnMgYW5kIGdldHMgdGhh
dCBpbnRvIHRoZSBuZXh0IExUUyBoZS9zaGUgZ2V0cyBhIGh1ZyA6LSlTAAAABnBhcnNlclMAAAAE
aHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Werkzeug Identity Crisis?http://lucumr.pocoo.org/cogitations/2007/12/15/werkzeug-identity-crisis/2007-12-15T22:00:48Z2007-12-15T22:00:48ZArmin Ronacherwerkzeug-identity-crisisyesyes2After the <a href="http://werkzeug.pocoo.org/">Werkzeug</a> 0.1 release I got some feedback by <a href="http://blog.ianbicking.org/">Ian Bicking</a>. Summarized it was about why Werkzeug pretty much does what webob does. Afterwards I thought about the issue and talked with some current Werkzeug users. And to sum it up: Werkzeug stays a standalone library without webob dependency and will stay with the current request/response object implementation.
While I agree that there are things webob does what Werkzeug (currently?) does not provide such as byteranges I still think it's on the right path. We have now a solid feature set in Werkzeug itself such as form data parsing, file uploads, conditional requests, simple redirects, useful exceptions, a good routing system, a simple bridge to wsgiref for a development server, a small helper library for management scripts and much more and additionally an optional contrib package with dozens of small helpers such as client side sessions, utilities for application sessions, the iterio library, a stream limiter for Django applications etc.
Even more important than having everything you need to get started with WSGI in one library the implementation is easy to understand, fast and written in a way that you will never hit a border. If you find a piece of code in Werkzeug that only solves 90% of your problem but provides absolute no way without side effects to get the full 100% solution that's a bug and should be fixed.
The minimal configuration you need to get a full featured web app running in a production environment with Werkzeug is currently something like Werkzeug + Genshi + SQLAlchemy + flup. Makes a total of four dependencies. It's not like I think dependencies are problems but what I noticed so far is the more libraries a user has to install the higher the number of problems and the lower the number of happy users. This is one thing Django does right: install django and you're done.
If you don't like that philosophy there is pylons with a whole string of dependencies ;-)After the <a href="http://werkzeug.pocoo.org/">Werkzeug</a> 0.1 release I got some feedback by <a href="http://blog.ianbicking.org/">Ian Bicking</a>. Summarized it was about why Werkzeug pretty much does what webob does. Afterwards I thought about the issue and talked with some current Werkzeug users. And to sum it up: Werkzeug stays a standalone library without webob dependency and will stay with the current request/response object implementation.
While I agree that there are things webob does what Werkzeug (currently?) does not provide such as byteranges I still think it's on the right path. We have now a solid feature set in Werkzeug itself such as form data parsing, file uploads, conditional requests, simple redirects, useful exceptions, a good routing system, a simple bridge to wsgiref for a development server, a small helper library for management scripts and much more and additionally an optional contrib package with dozens of small helpers such as client side sessions, utilities for application sessions, the iterio library, a stream limiter for Django applications etc.
Even more important than having everything you need to get started with WSGI in one library the implementation is easy to understand, fast and written in a way that you will never hit a border. If you find a piece of code in Werkzeug that only solves 90% of your problem but provides absolute no way without side effects to get the full 100% solution that's a bug and should be fixed.
The minimal configuration you need to get a full featured web app running in a production environment with Werkzeug is currently something like Werkzeug + Genshi + SQLAlchemy + flup. Makes a total of four dependencies. It's not like I think dependencies are problems but what I noticed so far is the more libraries a user has to install the higher the number of problems and the lower the number of happy users. This is one thing Django does right: install django and you're done.
If you don't like that philosophy there is pylons with a whole string of dependencies ;-)SQAAAANTAAAABGJvZHlSUwAAAApBZnRlciB0aGUgTAACRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMA
AAAaaHR0cDovL3dlcmt6ZXVnLnBvY29vLm9yZy9TAAAACFdlcmt6ZXVnUwAAACQgMC4xIHJlbGVh
c2UgSSBnb3Qgc29tZSBmZWVkYmFjayBieSBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAABtodHRw
Oi8vYmxvZy5pYW5iaWNraW5nLm9yZy9TAAAAC0lhbiBCaWNraW5nUwAAB3EuIFN1bW1hcml6ZWQg
aXQgd2FzIGFib3V0IHdoeSBXZXJremV1ZyBwcmV0dHkgbXVjaCBkb2VzIHdoYXQgd2Vib2IgZG9l
cy4gQWZ0ZXJ3YXJkcyBJIHRob3VnaHQgYWJvdXQgdGhlIGlzc3VlIGFuZCB0YWxrZWQgd2l0aCBz
b21lIGN1cnJlbnQgV2Vya3pldWcgdXNlcnMuIEFuZCB0byBzdW0gaXQgdXA6IFdlcmt6ZXVnIHN0
YXlzIGEgc3RhbmRhbG9uZSBsaWJyYXJ5IHdpdGhvdXQgd2Vib2IgZGVwZW5kZW5jeSBhbmQgd2ls
bCBzdGF5IHdpdGggdGhlIGN1cnJlbnQgcmVxdWVzdC9yZXNwb25zZSBvYmplY3QgaW1wbGVtZW50
YXRpb24uCgpXaGlsZSBJIGFncmVlIHRoYXQgdGhlcmUgYXJlIHRoaW5ncyB3ZWJvYiBkb2VzIHdo
YXQgV2Vya3pldWcgKGN1cnJlbnRseT8pIGRvZXMgbm90IHByb3ZpZGUgc3VjaCBhcyBieXRlcmFu
Z2VzIEkgc3RpbGwgdGhpbmsgaXQncyBvbiB0aGUgcmlnaHQgcGF0aC4gV2UgaGF2ZSBub3cgYSBz
b2xpZCBmZWF0dXJlIHNldCBpbiBXZXJremV1ZyBpdHNlbGYgc3VjaCBhcyBmb3JtIGRhdGEgcGFy
c2luZywgZmlsZSB1cGxvYWRzLCBjb25kaXRpb25hbCByZXF1ZXN0cywgc2ltcGxlIHJlZGlyZWN0
cywgdXNlZnVsIGV4Y2VwdGlvbnMsIGEgZ29vZCByb3V0aW5nIHN5c3RlbSwgYSBzaW1wbGUgYnJp
ZGdlIHRvIHdzZ2lyZWYgZm9yIGEgZGV2ZWxvcG1lbnQgc2VydmVyLCBhIHNtYWxsIGhlbHBlciBs
aWJyYXJ5IGZvciBtYW5hZ2VtZW50IHNjcmlwdHMgYW5kIG11Y2ggbW9yZSBhbmQgYWRkaXRpb25h
bGx5IGFuIG9wdGlvbmFsIGNvbnRyaWIgcGFja2FnZSB3aXRoIGRvemVucyBvZiBzbWFsbCBoZWxw
ZXJzIHN1Y2ggYXMgY2xpZW50IHNpZGUgc2Vzc2lvbnMsIHV0aWxpdGllcyBmb3IgYXBwbGljYXRp
b24gc2Vzc2lvbnMsIHRoZSBpdGVyaW8gbGlicmFyeSwgYSBzdHJlYW0gbGltaXRlciBmb3IgRGph
bmdvIGFwcGxpY2F0aW9ucyBldGMuCgpFdmVuIG1vcmUgaW1wb3J0YW50IHRoYW4gaGF2aW5nIGV2
ZXJ5dGhpbmcgeW91IG5lZWQgdG8gZ2V0IHN0YXJ0ZWQgd2l0aCBXU0dJIGluIG9uZSBsaWJyYXJ5
IHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBlYXN5IHRvIHVuZGVyc3RhbmQsIGZhc3QgYW5kIHdyaXR0
ZW4gaW4gYSB3YXkgdGhhdCB5b3Ugd2lsbCBuZXZlciBoaXQgYSBib3JkZXIuIElmIHlvdSBmaW5k
IGEgcGllY2Ugb2YgY29kZSBpbiBXZXJremV1ZyB0aGF0IG9ubHkgc29sdmVzIDkwJSBvZiB5b3Vy
IHByb2JsZW0gYnV0IHByb3ZpZGVzIGFic29sdXRlIG5vIHdheSB3aXRob3V0IHNpZGUgZWZmZWN0
cyB0byBnZXQgdGhlIGZ1bGwgMTAwJSBzb2x1dGlvbiB0aGF0J3MgYSBidWcgYW5kIHNob3VsZCBi
ZSBmaXhlZC4KClRoZSBtaW5pbWFsIGNvbmZpZ3VyYXRpb24geW91IG5lZWQgdG8gZ2V0IGEgZnVs
bCBmZWF0dXJlZCB3ZWIgYXBwIHJ1bm5pbmcgaW4gYSBwcm9kdWN0aW9uIGVudmlyb25tZW50IHdp
dGggV2Vya3pldWcgaXMgY3VycmVudGx5IHNvbWV0aGluZyBsaWtlIFdlcmt6ZXVnICsgR2Vuc2hp
ICsgU1FMQWxjaGVteSArIGZsdXAuIE1ha2VzIGEgdG90YWwgb2YgZm91ciBkZXBlbmRlbmNpZXMu
IEl0J3Mgbm90IGxpa2UgSSB0aGluayBkZXBlbmRlbmNpZXMgYXJlIHByb2JsZW1zIGJ1dCB3aGF0
IEkgbm90aWNlZCBzbyBmYXIgaXMgdGhlIG1vcmUgbGlicmFyaWVzIGEgdXNlciBoYXMgdG8gaW5z
dGFsbCB0aGUgaGlnaGVyIHRoZSBudW1iZXIgb2YgcHJvYmxlbXMgYW5kIHRoZSBsb3dlciB0aGUg
bnVtYmVyIG9mIGhhcHB5IHVzZXJzLiBUaGlzIGlzIG9uZSB0aGluZyBEamFuZ28gZG9lcyByaWdo
dDogaW5zdGFsbCBkamFuZ28gYW5kIHlvdSdyZSBkb25lLgoKSWYgeW91IGRvbid0IGxpa2UgdGhh
dCBwaGlsb3NvcGh5IHRoZXJlIGlzIHB5bG9ucyB3aXRoIGEgd2hvbGUgc3RyaW5nIG9mIGRlcGVu
ZGVuY2llcyA7LSlTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Braydon Fullercourier@braydon.comhttp://braydon.com2007-12-16T04:46:28Znono0I'm a fan of dependencies, but then again it's apt-get, and yum simplifies all that for us.
Werkzeug looks interesting, I will need to try it soon.I'm a fan of dependencies, but then again it's apt-get, and yum simplifies all that for us.
Werkzeug looks interesting, I will need to try it soon.SQAAAAJTAAAABGJvZHlSUwAAAJRJJ20gYSBmYW4gb2YgZGVwZW5kZW5jaWVzLCBidXQgdGhlbiBh
Z2FpbiBpdCdzIGFwdC1nZXQsIGFuZCB5dW0gc2ltcGxpZmllcyBhbGwgdGhhdCBmb3IgdXMuCgpX
ZXJremV1ZyBsb29rcyBpbnRlcmVzdGluZywgSSB3aWxsIG5lZWQgdG8gdHJ5IGl0IHNvb24uTAAA
UwAAAAZwYXJzZXJTAAAABGh0bWw=
Scott Benjaminscott.benjamin@gmail.comhttp://www.scott-benjamin.com/2007-12-17T03:47:07Znono0I think that Werkzeug is quite light on the dependencies. Those chosen, which just happens to be the developers choice, aren't as bad as 15 where you don't really have any idea how they fit together.I think that Werkzeug is quite light on the dependencies. Those chosen, which just happens to be the developers choice, aren't as bad as 15 where you don't really have any idea how they fit together.SQAAAAJTAAAABGJvZHlSUwAAAMhJIHRoaW5rIHRoYXQgV2Vya3pldWcgaXMgcXVpdGUgbGlnaHQg
b24gdGhlIGRlcGVuZGVuY2llcy4gVGhvc2UgY2hvc2VuLCAgd2hpY2gganVzdCBoYXBwZW5zIHRv
IGJlIHRoZSBkZXZlbG9wZXJzIGNob2ljZSwgYXJlbid0IGFzIGJhZCBhcyAxNSB3aGVyZSB5b3Ug
ZG9uJ3QgcmVhbGx5IGhhdmUgYW55IGlkZWEgaG93IHRoZXkgZml0IHRvZ2V0aGVyLkwAAFMAAAAG
cGFyc2VyUwAAAARodG1s
Secure Client Side Sessionshttp://lucumr.pocoo.org/cogitations/2007/12/15/secure-client-side-sessions/2007-12-15T17:19:56Z2007-12-15T17:19:56ZArmin Ronachersecure-client-side-sessionsyesyes2Since a few changesets <a href="http://werkzeug.pocoo.org/">Werkzeug</a> provides a module for client side sessions. While it's of course not yet perfect I think it's an interesting approach and we're currently replacing django's sessions with Werkzeug's secure cookie.
How does it work? Basically the data is stored as pickled data inside the cookie. The pickled data is hashed and added to the cookie too. Whenever the data is loaded from the cookie a new hash is created and the two hashes are compared. If they match the data is unserialized, otherwise a new SecureCookie object is created with empty data. As a matter of fact there is no "session key" so if you want to use it with django you have to fake the "session key" by inserting it into the data. We use the following session middleware as replacement for the django session middleware:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">try</span><span class="p">:</span>
<span class="k">from</span> <span class="nn">hashlib</span> <span class="k">import</span> <span class="n">md5</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="k">from</span> <span class="nn">md5</span> <span class="k">import</span> <span class="n">md5</span>
<span class="k">from</span> <span class="nn">time</span> <span class="k">import</span> <span class="n">time</span>
<span class="k">from</span> <span class="nn">random</span> <span class="k">import</span> <span class="n">random</span>
<span class="k">from</span> <span class="nn">django.conf</span> <span class="k">import</span> <span class="n">settings</span>
<span class="k">from</span> <span class="nn">django.utils.http</span> <span class="k">import</span> <span class="n">cookie_date</span>
<span class="k">from</span> <span class="nn">werkzeug.contrib.securecookie</span> <span class="k">import</span> <span class="n">SecureCookie</span>
<span class="k">class</span> <span class="nc">Session</span><span class="p">(</span><span class="n">SecureCookie</span><span class="p">):</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">session_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="s">'session_key'</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
<span class="bp">self</span><span class="p">[</span><span class="s">'session_key'</span><span class="p">]</span> <span class="o">=</span> <span class="n">md5</span><span class="p">(</span><span class="s">'</span><span class="si">%s%s%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">random</span><span class="p">(),</span> <span class="n">time</span><span class="p">(),</span>
<span class="n">settings</span><span class="o">.</span><span class="n">SECRET_KEY</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="k">return</span> <span class="bp">self</span><span class="p">[</span><span class="s">'session_key'</span><span class="p">]</span>
<span class="k">class</span> <span class="nc">ClientSideSessionMiddleware</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">process_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">COOKIES</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span><span class="p">)</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">Session</span><span class="o">.</span><span class="n">unserialize</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">SECRET_KEY</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">Session</span><span class="p">(</span><span class="n">secret_key</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">SECRET_KEY</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">session</span>
<span class="k">def</span> <span class="nf">process_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">modified</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">modified</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">if</span> <span class="n">modified</span> <span class="ow">or</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_SAVE_EVERY_REQUEST</span><span class="p">:</span>
<span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'is_permanent_session'</span><span class="p">):</span>
<span class="n">max_age</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_AGE</span>
<span class="n">expires_time</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_AGE</span>
<span class="n">expires</span> <span class="o">=</span> <span class="n">cookie_date</span><span class="p">(</span><span class="n">expires_time</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">max_age</span> <span class="o">=</span> <span class="n">expires</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">response</span><span class="o">.</span><span class="n">set_cookie</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span><span class="p">,</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">serialize</span><span class="p">(),</span>
<span class="n">max_age</span><span class="o">=</span><span class="n">max_age</span><span class="p">,</span> <span class="n">expires</span><span class="o">=</span><span class="n">expires</span><span class="p">,</span>
<span class="n">domain</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_DOMAIN</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_SECURE</span> <span class="ow">or</span> <span class="bp">None</span><span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>try:
from hashlib import md5
except ImportError:
from md5 import md5
from time import time
from random import random
from django.conf import settings
from django.utils.http import cookie_date
from werkzeug.contrib.securecookie import SecureCookie
class Session(SecureCookie):
@property
def session_key(self):
if not 'session_key' in self:
self['session_key'] = md5('%s%s%s' % (random(), time(),
settings.SECRET_KEY)).hexdigest()
return self['session_key']
class ClientSideSessionMiddleware(object):
def process_request(self, request):
data = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
if data:
session = Session.unserialize(data, settings.SECRET_KEY)
else:
session = Session(secret_key=settings.SECRET_KEY)
request.session = session
def process_response(self, request, response):
try:
modified = request.session.modified
except AttributeError:
return response
if modified or settings.SESSION_SAVE_EVERY_REQUEST:
if request.session.get('is_permanent_session'):
max_age = settings.SESSION_COOKIE_AGE
expires_time = time() + settings.SESSION_COOKIE_AGE
expires = cookie_date(expires_time)
else:
max_age = expires = None
response.set_cookie(settings.SESSION_COOKIE_NAME,
request.session.serialize(),
max_age=max_age, expires=expires,
domain=settings.SESSION_COOKIE_DOMAIN,
secure=settings.SESSION_COOKIE_SECURE or None)
return response<PYGMENTS_RAW -->
Additionally to the normal django session middleware this middleware can handle both persistent sessions and browser-session bound sessions. Per default a session ends at the end of the browser session, if you want to make it persistent you have to set "is_permanent_session" in the session data to True.
Keep in mind that cookies have a size limit and that users will be able to look at that data (but not alter it). The example above requires the current werkzeug tip and not the 0.1 release version.Since a few changesets <a href="http://werkzeug.pocoo.org/">Werkzeug</a> provides a module for client side sessions. While it's of course not yet perfect I think it's an interesting approach and we're currently replacing django's sessions with Werkzeug's secure cookie.
How does it work? Basically the data is stored as pickled data inside the cookie. The pickled data is hashed and added to the cookie too. Whenever the data is loaded from the cookie a new hash is created and the two hashes are compared. If they match the data is unserialized, otherwise a new SecureCookie object is created with empty data. As a matter of fact there is no "session key" so if you want to use it with django you have to fake the "session key" by inserting it into the data. We use the following session middleware as replacement for the django session middleware:
Additionally to the normal django session middleware this middleware can handle both persistent sessions and browser-session bound sessions. Per default a session ends at the end of the browser session, if you want to make it persistent you have to set "is_permanent_session" in the session data to True.
Keep in mind that cookies have a size limit and that users will be able to look at that data (but not alter it). The example above requires the current werkzeug tip and not the 0.1 release version.SQAAAANTAAAABGJvZHlSUwAAABdTaW5jZSBhIGZldyBjaGFuZ2VzZXRzIEwAAUVTAAAAAWFMAABN
AAFTAAAABGhyZWZTAAAAGmh0dHA6Ly93ZXJremV1Zy5wb2Nvby5vcmcvUwAAAAhXZXJremV1Z1MA
AAUJIHByb3ZpZGVzIGEgbW9kdWxlIGZvciBjbGllbnQgc2lkZSBzZXNzaW9ucy4gV2hpbGUgaXQn
cyBvZiBjb3Vyc2Ugbm90IHlldCBwZXJmZWN0IEkgdGhpbmsgaXQncyBhbiBpbnRlcmVzdGluZyBh
cHByb2FjaCBhbmQgd2UncmUgY3VycmVudGx5IHJlcGxhY2luZyBkamFuZ28ncyBzZXNzaW9ucyB3
aXRoIFdlcmt6ZXVnJ3Mgc2VjdXJlIGNvb2tpZS4KCkhvdyBkb2VzIGl0IHdvcms/IEJhc2ljYWxs
eSB0aGUgZGF0YSBpcyBzdG9yZWQgYXMgcGlja2xlZCBkYXRhIGluc2lkZSB0aGUgY29va2llLiAg
VGhlIHBpY2tsZWQgZGF0YSBpcyBoYXNoZWQgYW5kIGFkZGVkIHRvIHRoZSBjb29raWUgdG9vLiBX
aGVuZXZlciB0aGUgZGF0YSBpcyBsb2FkZWQgZnJvbSB0aGUgY29va2llIGEgbmV3IGhhc2ggaXMg
Y3JlYXRlZCBhbmQgdGhlIHR3byBoYXNoZXMgYXJlIGNvbXBhcmVkLiAgSWYgdGhleSBtYXRjaCB0
aGUgZGF0YSBpcyB1bnNlcmlhbGl6ZWQsIG90aGVyd2lzZSBhIG5ldyBTZWN1cmVDb29raWUgb2Jq
ZWN0IGlzIGNyZWF0ZWQgd2l0aCBlbXB0eSBkYXRhLiAgQXMgYSBtYXR0ZXIgb2YgZmFjdCB0aGVy
ZSBpcyBubyAic2Vzc2lvbiBrZXkiIHNvIGlmIHlvdSB3YW50IHRvIHVzZSBpdCB3aXRoIGRqYW5n
byB5b3UgaGF2ZSB0byBmYWtlIHRoZSAic2Vzc2lvbiBrZXkiIGJ5IGluc2VydGluZyBpdCBpbnRv
IHRoZSBkYXRhLiAgV2UgdXNlIHRoZSBmb2xsb3dpbmcgc2Vzc2lvbiBtaWRkbGV3YXJlIGFzIHJl
cGxhY2VtZW50IGZvciB0aGUgZGphbmdvIHNlc3Npb24gbWlkZGxld2FyZToKCgoKQWRkaXRpb25h
bGx5IHRvIHRoZSBub3JtYWwgZGphbmdvIHNlc3Npb24gbWlkZGxld2FyZSB0aGlzIG1pZGRsZXdh
cmUgY2FuIGhhbmRsZSBib3RoIHBlcnNpc3RlbnQgc2Vzc2lvbnMgYW5kIGJyb3dzZXItc2Vzc2lv
biBib3VuZCBzZXNzaW9ucy4gUGVyIGRlZmF1bHQgYSBzZXNzaW9uIGVuZHMgYXQgdGhlIGVuZCBv
ZiB0aGUgYnJvd3NlciBzZXNzaW9uLCBpZiB5b3Ugd2FudCB0byBtYWtlIGl0IHBlcnNpc3RlbnQg
eW91IGhhdmUgdG8gc2V0ICJpc19wZXJtYW5lbnRfc2Vzc2lvbiIgaW4gdGhlIHNlc3Npb24gZGF0
YSB0byBUcnVlLgoKS2VlcCBpbiBtaW5kIHRoYXQgY29va2llcyBoYXZlIGEgc2l6ZSBsaW1pdCBh
bmQgdGhhdCB1c2VycyB3aWxsIGJlIGFibGUgdG8gbG9vayBhdCB0aGF0IGRhdGEgKGJ1dCBub3Qg
YWx0ZXIgaXQpLiBUaGUgZXhhbXBsZSBhYm92ZSByZXF1aXJlcyB0aGUgY3VycmVudCB3ZXJremV1
ZyB0aXAgYW5kIG5vdCB0aGUgMC4xIHJlbGVhc2UgdmVyc2lvbi5TAAAABnBhcnNlclMAAAAEaHRt
bFMAAAAFaW50cm9SUwAAAABMAAA=
SmileyChrissmileychris@gmail.com2007-12-16T04:41:37Znono0Couldn't you have just written a custom session backend to do this?Couldn't you have just written a custom session backend to do this?SQAAAAJTAAAABGJvZHlSUwAAAENDb3VsZG4ndCB5b3UgaGF2ZSBqdXN0IHdyaXR0ZW4gYSBjdXN0
b20gc2Vzc2lvbiBiYWNrZW5kIHRvIGRvIHRoaXM/TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-16T10:50:25Znono0You mean a django session backend? Primarly because it wasn't written for django. That you can use it with django is just a goody that comes for free because the module doesn't require any specific Werkzeug implementation details.
And even if someone wants to integrate it into the django session system in the first place there would be no other way than writing a different session middleware because the session store cannot alter the cookie that is set.You mean a django session backend? Primarly because it wasn't written for django. That you can use it with django is just a goody that comes for free because the module doesn't require any specific Werkzeug implementation details.
And even if someone wants to integrate it into the django session system in the first place there would be no other way than writing a different session middleware because the session store cannot alter the cookie that is set.SQAAAAJTAAAABGJvZHlSUwAAAcpZb3UgbWVhbiBhIGRqYW5nbyBzZXNzaW9uIGJhY2tlbmQ/IFBy
aW1hcmx5IGJlY2F1c2UgaXQgd2Fzbid0IHdyaXR0ZW4gZm9yIGRqYW5nby4gVGhhdCB5b3UgY2Fu
IHVzZSBpdCB3aXRoIGRqYW5nbyBpcyBqdXN0IGEgZ29vZHkgdGhhdCBjb21lcyBmb3IgZnJlZSBi
ZWNhdXNlIHRoZSBtb2R1bGUgZG9lc24ndCByZXF1aXJlIGFueSBzcGVjaWZpYyBXZXJremV1ZyBp
bXBsZW1lbnRhdGlvbiBkZXRhaWxzLgoKQW5kIGV2ZW4gaWYgc29tZW9uZSB3YW50cyB0byBpbnRl
Z3JhdGUgaXQgaW50byB0aGUgZGphbmdvIHNlc3Npb24gc3lzdGVtIGluIHRoZSBmaXJzdCBwbGFj
ZSB0aGVyZSB3b3VsZCBiZSBubyBvdGhlciB3YXkgdGhhbiB3cml0aW5nIGEgZGlmZmVyZW50IHNl
c3Npb24gbWlkZGxld2FyZSBiZWNhdXNlIHRoZSBzZXNzaW9uIHN0b3JlIGNhbm5vdCBhbHRlciB0
aGUgY29va2llIHRoYXQgaXMgc2V0LkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Django’s Problems and Why 2.0 is a Bad Ideahttp://lucumr.pocoo.org/cogitations/2007/12/12/djangos-problems-and-why-20-is-a-bad-idea/2007-12-12T11:00:58Z2007-12-12T11:00:58ZArmin Ronacherdjangos-problems-and-why-20-is-a-bad-ideayesyes2I stumbled about <a href="http://groups.google.com/group/django-developers/browse_thread/thread/b4c237ad76f9eeca">this thread on django-developers</a> which proposes calling the Django 1.0 release Django 2.0. One the one hand version numbers say nothing. Just take Wine or Trac as two examples that are already very stable but still below the magical 1.0 release. Open Source software often takes some time until a 1.0 is released and that's perfectly fine. However skipping a version number is purely a marketing trick IMO. Just think of Java which currently names 1.6 Java 6 whereas 1.4 still was Java 2.
With django it looks like the plan is to keep up with Rails which went to 2.0 a few days ago. While I love to see that django kicks ass and it's moving toward a stable release I have a bad feeling naming it 2.0. Because there is currently a huge gap between rails and django unfortunately. Rails has gained really good integrated migrations, REST webservices, a debugger and many other things django is still lacking.
Django makes an incredible good framework if you get your problem into the use case of django. But as soon as you break out of it and need something that goes beyond what's possible in django you wish you have chosen something else. The django ORM is far from optimal, the admin rocks but as soon as the number of users exceeds 10.000 users it's impossible to use it (chose yourself in a dropdown of 50.000 users …) or becomes utterly complex. Complex data models also look awkward in the admin or become too complicated to manage. And if you want to stick with the admin you cannot replace the user model. Now what do you do if you have a forum and want to count the posts? Use a UserProfile module? And how do you want to display a list of users sorted by their number of posts?
Yes there are ways to hack around it but the more complex the application becomes the more you of django's strengths become obsolete. The application I'm working on right now now is only using two more contrib modules. The auth and the admin, and it looks like we have to drop them too, due to the limitations. All applications in that project hack around ORM limitations, we have an incredible number of recreated base middlewares, we have to monkey patch the request object to hack in subdomain support.
I was talking with David Cramer from curse gaming about some of the issues and he told me that they have forked django at a given point and patched the ORM. The django template engine was replaced by Jinja (our application does the same) and they are caching the hell out of the application to scale it. Bryan McLemore from the curse team told me some time ago that some pages have up to 30 queries on a page.
I don't want to say that django fails in what it's doing. But it's far from 2.0.I stumbled about <a href="http://groups.google.com/group/django-developers/browse_thread/thread/b4c237ad76f9eeca">this thread on django-developers</a> which proposes calling the Django 1.0 release Django 2.0. One the one hand version numbers say nothing. Just take Wine or Trac as two examples that are already very stable but still below the magical 1.0 release. Open Source software often takes some time until a 1.0 is released and that's perfectly fine. However skipping a version number is purely a marketing trick IMO. Just think of Java which currently names 1.6 Java 6 whereas 1.4 still was Java 2.
With django it looks like the plan is to keep up with Rails which went to 2.0 a few days ago. While I love to see that django kicks ass and it's moving toward a stable release I have a bad feeling naming it 2.0. Because there is currently a huge gap between rails and django unfortunately. Rails has gained really good integrated migrations, REST webservices, a debugger and many other things django is still lacking.
Django makes an incredible good framework if you get your problem into the use case of django. But as soon as you break out of it and need something that goes beyond what's possible in django you wish you have chosen something else. The django ORM is far from optimal, the admin rocks but as soon as the number of users exceeds 10.000 users it's impossible to use it (chose yourself in a dropdown of 50.000 users …) or becomes utterly complex. Complex data models also look awkward in the admin or become too complicated to manage. And if you want to stick with the admin you cannot replace the user model. Now what do you do if you have a forum and want to count the posts? Use a UserProfile module? And how do you want to display a list of users sorted by their number of posts?
Yes there are ways to hack around it but the more complex the application becomes the more you of django's strengths become obsolete. The application I'm working on right now now is only using two more contrib modules. The auth and the admin, and it looks like we have to drop them too, due to the limitations. All applications in that project hack around ORM limitations, we have an incredible number of recreated base middlewares, we have to monkey patch the request object to hack in subdomain support.
I was talking with David Cramer from curse gaming about some of the issues and he told me that they have forked django at a given point and patched the ORM. The django template engine was replaced by Jinja (our application does the same) and they are caching the hell out of the application to scale it. Bryan McLemore from the curse team told me some time ago that some pages have up to 30 queries on a page.
I don't want to say that django fails in what it's doing. But it's far from 2.0.SQAAAANTAAAABGJvZHlSUwAAABFJIHN0dW1ibGVkIGFib3V0IEwAAUVTAAAAAWFMAABNAAFTAAAA
BGhyZWZTAAAAVmh0dHA6Ly9ncm91cHMuZ29vZ2xlLmNvbS9ncm91cC9kamFuZ28tZGV2ZWxvcGVy
cy9icm93c2VfdGhyZWFkL3RocmVhZC9iNGMyMzdhZDc2ZjllZWNhUwAAACB0aGlzIHRocmVhZCBv
biBkamFuZ28tZGV2ZWxvcGVyc1MAAApjIHdoaWNoIHByb3Bvc2VzIGNhbGxpbmcgdGhlIERqYW5n
byAxLjAgcmVsZWFzZSBEamFuZ28gMi4wLiBPbmUgdGhlIG9uZSBoYW5kIHZlcnNpb24gbnVtYmVy
cyBzYXkgbm90aGluZy4gSnVzdCB0YWtlIFdpbmUgb3IgVHJhYyBhcyB0d28gZXhhbXBsZXMgdGhh
dCBhcmUgYWxyZWFkeSB2ZXJ5IHN0YWJsZSBidXQgc3RpbGwgYmVsb3cgdGhlIG1hZ2ljYWwgMS4w
IHJlbGVhc2UuIE9wZW4gU291cmNlIHNvZnR3YXJlIG9mdGVuIHRha2VzIHNvbWUgdGltZSB1bnRp
bCBhIDEuMCBpcyByZWxlYXNlZCBhbmQgdGhhdCdzIHBlcmZlY3RseSBmaW5lLiBIb3dldmVyIHNr
aXBwaW5nIGEgdmVyc2lvbiBudW1iZXIgaXMgcHVyZWx5IGEgbWFya2V0aW5nIHRyaWNrIElNTy4g
SnVzdCB0aGluayBvZiBKYXZhIHdoaWNoIGN1cnJlbnRseSBuYW1lcyAxLjYgSmF2YSA2IHdoZXJl
YXMgMS40IHN0aWxsIHdhcyBKYXZhIDIuCgpXaXRoIGRqYW5nbyBpdCBsb29rcyBsaWtlIHRoZSBw
bGFuIGlzIHRvIGtlZXAgdXAgd2l0aCBSYWlscyB3aGljaCB3ZW50IHRvIDIuMCBhIGZldyBkYXlz
IGFnby4gV2hpbGUgSSBsb3ZlIHRvIHNlZSB0aGF0IGRqYW5nbyBraWNrcyBhc3MgYW5kIGl0J3Mg
bW92aW5nIHRvd2FyZCBhIHN0YWJsZSByZWxlYXNlIEkgaGF2ZSBhIGJhZCBmZWVsaW5nIG5hbWlu
ZyBpdCAyLjAuIEJlY2F1c2UgdGhlcmUgaXMgY3VycmVudGx5IGEgaHVnZSBnYXAgYmV0d2VlbiBy
YWlscyBhbmQgZGphbmdvIHVuZm9ydHVuYXRlbHkuIFJhaWxzIGhhcyBnYWluZWQgcmVhbGx5IGdv
b2QgaW50ZWdyYXRlZCBtaWdyYXRpb25zLCBSRVNUIHdlYnNlcnZpY2VzLCBhIGRlYnVnZ2VyIGFu
ZCBtYW55IG90aGVyIHRoaW5ncyBkamFuZ28gaXMgc3RpbGwgbGFja2luZy4KCkRqYW5nbyBtYWtl
cyBhbiBpbmNyZWRpYmxlIGdvb2QgZnJhbWV3b3JrIGlmIHlvdSBnZXQgeW91ciBwcm9ibGVtIGlu
dG8gdGhlIHVzZSBjYXNlIG9mIGRqYW5nby4gQnV0IGFzIHNvb24gYXMgeW91IGJyZWFrIG91dCBv
ZiBpdCBhbmQgbmVlZCBzb21ldGhpbmcgdGhhdCBnb2VzIGJleW9uZCB3aGF0J3MgcG9zc2libGUg
aW4gZGphbmdvIHlvdSB3aXNoIHlvdSBoYXZlIGNob3NlbiBzb21ldGhpbmcgZWxzZS4gVGhlIGRq
YW5nbyBPUk0gaXMgZmFyIGZyb20gb3B0aW1hbCwgdGhlIGFkbWluIHJvY2tzIGJ1dCBhcyBzb29u
IGFzIHRoZSBudW1iZXIgb2YgdXNlcnMgZXhjZWVkcyAxMC4wMDAgdXNlcnMgaXQncyBpbXBvc3Np
YmxlIHRvIHVzZSBpdCAoY2hvc2UgeW91cnNlbGYgaW4gYSBkcm9wZG93biBvZiA1MC4wMDAgdXNl
cnMg4oCmKSBvciBiZWNvbWVzIHV0dGVybHkgY29tcGxleC4gQ29tcGxleCBkYXRhIG1vZGVscyBh
bHNvIGxvb2sgYXdrd2FyZCBpbiB0aGUgYWRtaW4gb3IgYmVjb21lIHRvbyBjb21wbGljYXRlZCB0
byBtYW5hZ2UuIEFuZCBpZiB5b3Ugd2FudCB0byBzdGljayB3aXRoIHRoZSBhZG1pbiB5b3UgY2Fu
bm90IHJlcGxhY2UgdGhlIHVzZXIgbW9kZWwuIE5vdyB3aGF0IGRvIHlvdSBkbyBpZiB5b3UgaGF2
ZSBhIGZvcnVtIGFuZCB3YW50IHRvIGNvdW50IHRoZSBwb3N0cz8gVXNlIGEgVXNlclByb2ZpbGUg
bW9kdWxlPyBBbmQgaG93IGRvIHlvdSB3YW50IHRvIGRpc3BsYXkgYSBsaXN0IG9mIHVzZXJzIHNv
cnRlZCBieSB0aGVpciBudW1iZXIgb2YgcG9zdHM/CgpZZXMgdGhlcmUgYXJlIHdheXMgdG8gaGFj
ayBhcm91bmQgaXQgYnV0IHRoZSBtb3JlIGNvbXBsZXggdGhlIGFwcGxpY2F0aW9uIGJlY29tZXMg
dGhlIG1vcmUgeW91IG9mIGRqYW5nbydzIHN0cmVuZ3RocyBiZWNvbWUgb2Jzb2xldGUuIFRoZSBh
cHBsaWNhdGlvbiBJJ20gd29ya2luZyBvbiByaWdodCBub3cgbm93IGlzIG9ubHkgdXNpbmcgdHdv
IG1vcmUgY29udHJpYiBtb2R1bGVzLiBUaGUgYXV0aCBhbmQgdGhlIGFkbWluLCBhbmQgaXQgbG9v
a3MgbGlrZSB3ZSBoYXZlIHRvIGRyb3AgdGhlbSB0b28sIGR1ZSB0byB0aGUgbGltaXRhdGlvbnMu
IEFsbCBhcHBsaWNhdGlvbnMgaW4gdGhhdCBwcm9qZWN0IGhhY2sgYXJvdW5kIE9STSBsaW1pdGF0
aW9ucywgd2UgaGF2ZSBhbiBpbmNyZWRpYmxlIG51bWJlciBvZiByZWNyZWF0ZWQgYmFzZSBtaWRk
bGV3YXJlcywgd2UgaGF2ZSB0byBtb25rZXkgcGF0Y2ggdGhlIHJlcXVlc3Qgb2JqZWN0IHRvIGhh
Y2sgaW4gc3ViZG9tYWluIHN1cHBvcnQuCgpJIHdhcyB0YWxraW5nIHdpdGggRGF2aWQgQ3JhbWVy
IGZyb20gY3Vyc2UgZ2FtaW5nIGFib3V0IHNvbWUgb2YgdGhlIGlzc3VlcyBhbmQgaGUgdG9sZCBt
ZSB0aGF0IHRoZXkgaGF2ZSBmb3JrZWQgZGphbmdvIGF0IGEgZ2l2ZW4gcG9pbnQgYW5kIHBhdGNo
ZWQgdGhlIE9STS4gVGhlIGRqYW5nbyB0ZW1wbGF0ZSBlbmdpbmUgd2FzIHJlcGxhY2VkIGJ5IEpp
bmphIChvdXIgYXBwbGljYXRpb24gZG9lcyB0aGUgc2FtZSkgYW5kIHRoZXkgYXJlIGNhY2hpbmcg
dGhlIGhlbGwgb3V0IG9mIHRoZSBhcHBsaWNhdGlvbiB0byBzY2FsZSBpdC4gQnJ5YW4gTWNMZW1v
cmUgZnJvbSB0aGUgY3Vyc2UgdGVhbSB0b2xkIG1lIHNvbWUgdGltZSBhZ28gdGhhdCBzb21lIHBh
Z2VzIGhhdmUgdXAgdG8gMzAgcXVlcmllcyBvbiBhIHBhZ2UuCgpJIGRvbid0IHdhbnQgdG8gc2F5
IHRoYXQgZGphbmdvIGZhaWxzIGluIHdoYXQgaXQncyBkb2luZy4gQnV0IGl0J3MgZmFyIGZyb20g
Mi4wLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Ericeric.nilsson@slaskpost.se2007-12-12T11:59:36Znono0I usally say django is great for websites and webapps while rails is great for services and APIs.
The whole discussion with version number is just overkill, just get it released in stead.
Also, webdevelopment is evolving each day. Something new and great today could be deprecated tomorrow, verison number doesnt say a shit.
So just use the svn revision number, tag it with a flashy name (like ubuntu do on their releases) and just get it out! Real webdevelopers will use the trunk anyway, because as i said, webdevelopment is evolving.I usally say django is great for websites and webapps while rails is great for services and APIs.
The whole discussion with version number is just overkill, just get it released in stead.
Also, webdevelopment is evolving each day. Something new and great today could be deprecated tomorrow, verison number doesnt say a shit.
So just use the svn revision number, tag it with a flashy name (like ubuntu do on their releases) and just get it out! Real webdevelopers will use the trunk anyway, because as i said, webdevelopment is evolving.SQAAAAJTAAAABGJvZHlSUwAAAh1JIHVzYWxseSBzYXkgZGphbmdvIGlzIGdyZWF0IGZvciB3ZWJz
aXRlcyBhbmQgd2ViYXBwcyB3aGlsZSByYWlscyBpcyBncmVhdCBmb3Igc2VydmljZXMgYW5kIEFQ
SXMuCgpUaGUgd2hvbGUgZGlzY3Vzc2lvbiB3aXRoIHZlcnNpb24gbnVtYmVyIGlzIGp1c3Qgb3Zl
cmtpbGwsIGp1c3QgZ2V0IGl0IHJlbGVhc2VkIGluIHN0ZWFkLiAKCkFsc28sIHdlYmRldmVsb3Bt
ZW50IGlzIGV2b2x2aW5nIGVhY2ggZGF5LiBTb21ldGhpbmcgbmV3IGFuZCBncmVhdCB0b2RheSBj
b3VsZCBiZSBkZXByZWNhdGVkIHRvbW9ycm93LCB2ZXJpc29uIG51bWJlciBkb2VzbnQgc2F5IGEg
c2hpdC4gCgpTbyBqdXN0IHVzZSB0aGUgc3ZuIHJldmlzaW9uIG51bWJlciwgdGFnIGl0IHdpdGgg
YSBmbGFzaHkgbmFtZSAobGlrZSB1YnVudHUgZG8gb24gdGhlaXIgcmVsZWFzZXMpIGFuZCBqdXN0
IGdldCBpdCBvdXQhIFJlYWwgd2ViZGV2ZWxvcGVycyB3aWxsIHVzZSB0aGUgdHJ1bmsgYW55d2F5
LCBiZWNhdXNlIGFzIGkgc2FpZCwgd2ViZGV2ZWxvcG1lbnQgaXMgZXZvbHZpbmcuTAAAUwAAAAZw
YXJzZXJTAAAABGh0bWw=
Ericeric.nilsson@slaskpost.se2007-12-12T12:08:24Znono0Also, rails is lacking great things from django aswell, as form handling with newsforms for example. I think i like the way django handles models better though it would of course be great with some kind of migrations supportAlso, rails is lacking great things from django aswell, as form handling with newsforms for example. I think i like the way django handles models better though it would of course be great with some kind of migrations supportSQAAAAJTAAAABGJvZHlSUwAAAOBBbHNvLCByYWlscyBpcyBsYWNraW5nIGdyZWF0IHRoaW5ncyBm
cm9tIGRqYW5nbyBhc3dlbGwsIGFzIGZvcm0gaGFuZGxpbmcgd2l0aCBuZXdzZm9ybXMgZm9yIGV4
YW1wbGUuIEkgdGhpbmsgaSBsaWtlIHRoZSB3YXkgZGphbmdvIGhhbmRsZXMgbW9kZWxzIGJldHRl
ciB0aG91Z2ggaXQgd291bGQgb2YgY291cnNlIGJlIGdyZWF0IHdpdGggc29tZSBraW5kIG9mIG1p
Z3JhdGlvbnMgc3VwcG9ydEwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Eric Florenzanofloguy@gmail.cimhttp://www.eflorenzano.com2007-12-12T12:39:00Znono0More than 10,000 admins on a site? Sounds like too many cooks in the kitchen to me. Seriously though, at that point you are definitely at the upper bound of the use case for the admin app, so it starts to sound silly to complain. At some point you need to code your own app.
Regarding ordering by number of posts: denormalization is your friend. It would take any competant coder 5-10 minutes to create some signals and callbacks to update a num_posts field on a UserProfile. Someday when aggregation support is included in the ORM, this will become even easier, but still, todays solition is pretty darn easy.
Beyond those two (non)issues, you really didn't make any points. The fact that you were able to easily swap in Jinja is actually a testament to the modularity of Django itself.More than 10,000 admins on a site? Sounds like too many cooks in the kitchen to me. Seriously though, at that point you are definitely at the upper bound of the use case for the admin app, so it starts to sound silly to complain. At some point you need to code your own app.
Regarding ordering by number of posts: denormalization is your friend. It would take any competant coder 5-10 minutes to create some signals and callbacks to update a num_posts field on a UserProfile. Someday when aggregation support is included in the ORM, this will become even easier, but still, todays solition is pretty darn easy.
Beyond those two (non)issues, you really didn't make any points. The fact that you were able to easily swap in Jinja is actually a testament to the modularity of Django itself.SQAAAAJTAAAABGJvZHlSUwAAAxxNb3JlIHRoYW4gMTAsMDAwIGFkbWlucyBvbiBhIHNpdGU/ICBT
b3VuZHMgbGlrZSB0b28gbWFueSBjb29rcyBpbiB0aGUga2l0Y2hlbiB0byBtZS4gIFNlcmlvdXNs
eSB0aG91Z2gsIGF0IHRoYXQgcG9pbnQgeW91IGFyZSBkZWZpbml0ZWx5IGF0IHRoZSB1cHBlciBi
b3VuZCBvZiB0aGUgdXNlIGNhc2UgZm9yIHRoZSBhZG1pbiBhcHAsIHNvIGl0IHN0YXJ0cyB0byBz
b3VuZCBzaWxseSB0byBjb21wbGFpbi4gIEF0IHNvbWUgcG9pbnQgeW91IG5lZWQgdG8gY29kZSB5
b3VyIG93biBhcHAuCgpSZWdhcmRpbmcgb3JkZXJpbmcgYnkgbnVtYmVyIG9mIHBvc3RzOiAgZGVu
b3JtYWxpemF0aW9uIGlzIHlvdXIgZnJpZW5kLiAgSXQgd291bGQgdGFrZSBhbnkgY29tcGV0YW50
IGNvZGVyIDUtMTAgbWludXRlcyB0byBjcmVhdGUgc29tZSBzaWduYWxzIGFuZCBjYWxsYmFja3Mg
dG8gdXBkYXRlIGEgbnVtX3Bvc3RzIGZpZWxkIG9uIGEgVXNlclByb2ZpbGUuICBTb21lZGF5IHdo
ZW4gYWdncmVnYXRpb24gc3VwcG9ydCBpcyBpbmNsdWRlZCBpbiB0aGUgT1JNLCB0aGlzIHdpbGwg
YmVjb21lIGV2ZW4gZWFzaWVyLCBidXQgc3RpbGwsIHRvZGF5cyBzb2xpdGlvbiBpcyBwcmV0dHkg
ZGFybiBlYXN5LgoKQmV5b25kIHRob3NlIHR3byAobm9uKWlzc3VlcywgeW91IHJlYWxseSBkaWRu
J3QgbWFrZSBhbnkgcG9pbnRzLiAgVGhlIGZhY3QgdGhhdCB5b3Ugd2VyZSBhYmxlIHRvIGVhc2ls
eSBzd2FwIGluIEppbmphIGlzIGFjdHVhbGx5IGEgdGVzdGFtZW50IHRvIHRoZSBtb2R1bGFyaXR5
IG9mIERqYW5nbyBpdHNlbGYuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-12T13:01:20Znono0Yes. newforms is django's killerfeature. It's so far the best form validation system I found. Also that the django core is translated is a very good thing. While our project is not multilingual it's not English and it's a cool that django can output German error messages.
Our problem is not the updating of the num_posts fields in the UserProfile, our problem is the displaying of a user list paginated and sorted by the number of posts. Yes we can (And do) sort the user profiles by the number of posts and resolve the associated user object but still the process is a lot more complex than we want it to be :-/
And no, we don't have 10.000 admins, just about 50.000 users and as many user objects :-) So we also have 50.000 items in a dropdown.Yes. newforms is django's killerfeature. It's so far the best form validation system I found. Also that the django core is translated is a very good thing. While our project is not multilingual it's not English and it's a cool that django can output German error messages.
Our problem is not the updating of the num_posts fields in the UserProfile, our problem is the displaying of a user list paginated and sorted by the number of posts. Yes we can (And do) sort the user profiles by the number of posts and resolve the associated user object but still the process is a lot more complex than we want it to be :-/
And no, we don't have 10.000 admins, just about 50.000 users and as many user objects :-) So we also have 50.000 items in a dropdown.SQAAAAJTAAAABGJvZHlSUwAAAu5ZZXMuIG5ld2Zvcm1zIGlzIGRqYW5nbydzIGtpbGxlcmZlYXR1
cmUuIEl0J3Mgc28gZmFyIHRoZSBiZXN0IGZvcm0gdmFsaWRhdGlvbiBzeXN0ZW0gSSBmb3VuZC4g
QWxzbyB0aGF0IHRoZSBkamFuZ28gY29yZSBpcyB0cmFuc2xhdGVkIGlzIGEgdmVyeSBnb29kIHRo
aW5nLiBXaGlsZSBvdXIgcHJvamVjdCBpcyBub3QgbXVsdGlsaW5ndWFsIGl0J3Mgbm90IEVuZ2xp
c2ggYW5kIGl0J3MgYSBjb29sIHRoYXQgZGphbmdvIGNhbiBvdXRwdXQgR2VybWFuIGVycm9yIG1l
c3NhZ2VzLgoKT3VyIHByb2JsZW0gaXMgbm90IHRoZSB1cGRhdGluZyBvZiB0aGUgbnVtX3Bvc3Rz
IGZpZWxkcyBpbiB0aGUgVXNlclByb2ZpbGUsIG91ciBwcm9ibGVtIGlzIHRoZSBkaXNwbGF5aW5n
IG9mIGEgdXNlciBsaXN0IHBhZ2luYXRlZCBhbmQgc29ydGVkIGJ5IHRoZSBudW1iZXIgb2YgcG9z
dHMuICBZZXMgd2UgY2FuIChBbmQgZG8pIHNvcnQgdGhlIHVzZXIgcHJvZmlsZXMgYnkgdGhlIG51
bWJlciBvZiBwb3N0cyBhbmQgcmVzb2x2ZSB0aGUgYXNzb2NpYXRlZCB1c2VyIG9iamVjdCBidXQg
c3RpbGwgdGhlIHByb2Nlc3MgaXMgYSBsb3QgbW9yZSBjb21wbGV4IHRoYW4gd2Ugd2FudCBpdCB0
byBiZSA6LS8KCkFuZCBubywgd2UgZG9uJ3QgaGF2ZSAxMC4wMDAgYWRtaW5zLCBqdXN0IGFib3V0
IDUwLjAwMCB1c2VycyBhbmQgYXMgbWFueSB1c2VyIG9iamVjdHMgOi0pIFNvIHdlIGFsc28gaGF2
ZSA1MC4wMDAgaXRlbXMgaW4gYSBkcm9wZG93bi5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Eric Florenzanofloguy@gmail.comhttp://www.eflorenzano.com/2007-12-12T13:17:40Znono0Haha, I see what you meant about the 50,000 users now. That makes it a much more valid point :) Still though, the admin app is modular enough that if you have 50,000 users, you should be able to write some Javascript to code in an autocomplete box or something.Haha, I see what you meant about the 50,000 users now. That makes it a much more valid point :) Still though, the admin app is modular enough that if you have 50,000 users, you should be able to write some Javascript to code in an autocomplete box or something.SQAAAAJTAAAABGJvZHlSUwAAAQdIYWhhLCBJIHNlZSB3aGF0IHlvdSBtZWFudCBhYm91dCB0aGUg
NTAsMDAwIHVzZXJzIG5vdy4gIFRoYXQgbWFrZXMgaXQgYSBtdWNoIG1vcmUgdmFsaWQgcG9pbnQg
OikgIFN0aWxsIHRob3VnaCwgdGhlIGFkbWluIGFwcCBpcyBtb2R1bGFyIGVub3VnaCB0aGF0IGlm
IHlvdSBoYXZlIDUwLDAwMCB1c2VycywgeW91IHNob3VsZCBiZSBhYmxlIHRvIHdyaXRlIHNvbWUg
SmF2YXNjcmlwdCB0byBjb2RlIGluIGFuIGF1dG9jb21wbGV0ZSBib3ggb3Igc29tZXRoaW5nLkwA
AFMAAAAGcGFyc2VyUwAAAARodG1s
Onnoonno@filosofie.behttp://filosofie.be2007-12-12T13:19:02Znono0The Admin is an app made with django. It is not Django, it is nice to have it if you need to make a website. But if you make an app then you better roll out your own Admin. I can't understand why people think the admin is Django and it should do al sorts of things. The Admin is Django + a admin application.
If you have 10.000 users you write your own user view.The Admin is an app made with django. It is not Django, it is nice to have it if you need to make a website. But if you make an app then you better roll out your own Admin. I can't understand why people think the admin is Django and it should do al sorts of things. The Admin is Django + a admin application.
If you have 10.000 users you write your own user view.SQAAAAJTAAAABGJvZHlSUwAAAW1UaGUgQWRtaW4gaXMgYW4gYXBwIG1hZGUgd2l0aCBkamFuZ28u
IEl0IGlzIG5vdCBEamFuZ28sIGl0IGlzIG5pY2UgdG8gaGF2ZSBpdCBpZiB5b3UgbmVlZCB0byBt
YWtlIGEgd2Vic2l0ZS4gQnV0IGlmIHlvdSBtYWtlIGFuIGFwcCB0aGVuIHlvdSBiZXR0ZXIgcm9s
bCBvdXQgeW91ciBvd24gQWRtaW4uIEkgY2FuJ3QgdW5kZXJzdGFuZCB3aHkgcGVvcGxlIHRoaW5r
IHRoZSBhZG1pbiBpcyBEamFuZ28gYW5kIGl0IHNob3VsZCBkbyBhbCBzb3J0cyBvZiB0aGluZ3Mu
IFRoZSBBZG1pbiBpcyBEamFuZ28gKyBhIGFkbWluIGFwcGxpY2F0aW9uLiAKCklmIHlvdSBoYXZl
IDEwLjAwMCB1c2VycyB5b3Ugd3JpdGUgeW91ciBvd24gdXNlciB2aWV3LkwAAFMAAAAGcGFyc2Vy
UwAAAARodG1s
Danieldaniel@eight.nlhttp://blog.eight.nl2007-12-12T13:19:24Znono0I can see why developers would argue that version numbers aren't important, but developers aren't the only ones to decide which technology is used. (sadly)
So some business decider with a project with huge stakes hears two camps of developers, one supporting a 0.xx version technology and the other supporting a 2.xx version.
The camp with the 0.xx version technology has got some explaining to do!
(instead of discussing what should be the issue: the features etc.)I can see why developers would argue that version numbers aren't important, but developers aren't the only ones to decide which technology is used. (sadly)
So some business decider with a project with huge stakes hears two camps of developers, one supporting a 0.xx version technology and the other supporting a 2.xx version.
The camp with the 0.xx version technology has got some explaining to do!
(instead of discussing what should be the issue: the features etc.)SQAAAAJTAAAABGJvZHlSUwAAAdJJIGNhbiBzZWUgd2h5IGRldmVsb3BlcnMgd291bGQgYXJndWUg
dGhhdCB2ZXJzaW9uIG51bWJlcnMgYXJlbid0IGltcG9ydGFudCwgYnV0IGRldmVsb3BlcnMgYXJl
bid0IHRoZSBvbmx5IG9uZXMgdG8gZGVjaWRlIHdoaWNoIHRlY2hub2xvZ3kgaXMgdXNlZC4gKHNh
ZGx5KQpTbyBzb21lIGJ1c2luZXNzIGRlY2lkZXIgd2l0aCBhIHByb2plY3Qgd2l0aCBodWdlIHN0
YWtlcyBoZWFycyB0d28gY2FtcHMgb2YgZGV2ZWxvcGVycywgb25lIHN1cHBvcnRpbmcgYSAwLnh4
IHZlcnNpb24gdGVjaG5vbG9neSBhbmQgdGhlIG90aGVyIHN1cHBvcnRpbmcgYSAyLnh4IHZlcnNp
b24uClRoZSBjYW1wIHdpdGggdGhlIDAueHggdmVyc2lvbiB0ZWNobm9sb2d5IGhhcyBnb3Qgc29t
ZSBleHBsYWluaW5nIHRvIGRvIQooaW5zdGVhZCBvZiBkaXNjdXNzaW5nIHdoYXQgc2hvdWxkIGJl
IHRoZSBpc3N1ZTogdGhlIGZlYXR1cmVzIGV0Yy4pTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Braydon Fullercourier@braydon.comhttp://braydon.com2007-12-12T13:27:39Znono0I'm not sure what the point of jumping to calling it v2. If they are departing, or breaking compatibility with previous versions, etc. then that would make sense. Or signal a major change, but if it's just to be a higher number for comparison reasons, that's kinda confusing.
Django, RoR seems to be most about convenience, than anything else. IMO Combining disparate pieces of software together leads to the most interesting software. Although everything isn't all in one place (from the developers point of view, documentation, dependencies, etc.) the diversity can be healthy and keep things agile flexible, and avoid becoming bloated.I'm not sure what the point of jumping to calling it v2. If they are departing, or breaking compatibility with previous versions, etc. then that would make sense. Or signal a major change, but if it's just to be a higher number for comparison reasons, that's kinda confusing.
Django, RoR seems to be most about convenience, than anything else. IMO Combining disparate pieces of software together leads to the most interesting software. Although everything isn't all in one place (from the developers point of view, documentation, dependencies, etc.) the diversity can be healthy and keep things agile flexible, and avoid becoming bloated.SQAAAAJTAAAABGJvZHlSUwAAAoBJJ20gbm90IHN1cmUgd2hhdCB0aGUgcG9pbnQgb2YganVtcGlu
ZyB0byBjYWxsaW5nIGl0IHYyLiBJZiB0aGV5IGFyZSBkZXBhcnRpbmcsIG9yIGJyZWFraW5nICBj
b21wYXRpYmlsaXR5IHdpdGggcHJldmlvdXMgdmVyc2lvbnMsIGV0Yy4gdGhlbiB0aGF0IHdvdWxk
IG1ha2Ugc2Vuc2UuIE9yIHNpZ25hbCBhIG1ham9yIGNoYW5nZSwgYnV0IGlmIGl0J3MganVzdCB0
byBiZSBhIGhpZ2hlciBudW1iZXIgZm9yIGNvbXBhcmlzb24gcmVhc29ucywgdGhhdCdzIGtpbmRh
IGNvbmZ1c2luZy4KCkRqYW5nbywgUm9SIHNlZW1zIHRvIGJlIG1vc3QgYWJvdXQgY29udmVuaWVu
Y2UsIHRoYW4gYW55dGhpbmcgZWxzZS4gSU1PIENvbWJpbmluZyBkaXNwYXJhdGUgcGllY2VzIG9m
IHNvZnR3YXJlIHRvZ2V0aGVyIGxlYWRzIHRvIHRoZSBtb3N0IGludGVyZXN0aW5nIHNvZnR3YXJl
LiBBbHRob3VnaCBldmVyeXRoaW5nIGlzbid0IGFsbCBpbiBvbmUgcGxhY2UgKGZyb20gdGhlIGRl
dmVsb3BlcnMgcG9pbnQgb2YgdmlldywgZG9jdW1lbnRhdGlvbiwgZGVwZW5kZW5jaWVzLCBldGMu
KSB0aGUgZGl2ZXJzaXR5IGNhbiBiZSBoZWFsdGh5IGFuZCBrZWVwIHRoaW5ncyBhZ2lsZSBmbGV4
aWJsZSwgYW5kIGF2b2lkIGJlY29taW5nIGJsb2F0ZWQuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Simon Willisonsimon@simonwillison.nethttp://simonwillison.nett/2007-12-12T13:29:19Znono0You should be able to solve the 50,000 users problem using the "raw_id_admin=True" flag on the ForeignKey field - that replaces the "select an object from this select dropdown" widget with a text field that you can enter an integer ID in along with a link that launches a search interface to help you find the ID.
If that doesn't solve your problem, this is a serious bug in Django's admin: it's meant to be able to scale up to large numbers of related objects.You should be able to solve the 50,000 users problem using the "raw_id_admin=True" flag on the ForeignKey field - that replaces the "select an object from this select dropdown" widget with a text field that you can enter an integer ID in along with a link that launches a search interface to help you find the ID.
If that doesn't solve your problem, this is a serious bug in Django's admin: it's meant to be able to scale up to large numbers of related objects.SQAAAAJTAAAABGJvZHlSUwAAAc5Zb3Ugc2hvdWxkIGJlIGFibGUgdG8gc29sdmUgdGhlIDUwLDAw
MCB1c2VycyBwcm9ibGVtIHVzaW5nIHRoZSAicmF3X2lkX2FkbWluPVRydWUiIGZsYWcgb24gdGhl
IEZvcmVpZ25LZXkgZmllbGQgLSB0aGF0IHJlcGxhY2VzIHRoZSAic2VsZWN0IGFuIG9iamVjdCBm
cm9tIHRoaXMgc2VsZWN0IGRyb3Bkb3duIiB3aWRnZXQgd2l0aCBhIHRleHQgZmllbGQgdGhhdCB5
b3UgY2FuIGVudGVyIGFuIGludGVnZXIgSUQgaW4gYWxvbmcgd2l0aCBhIGxpbmsgdGhhdCBsYXVu
Y2hlcyBhIHNlYXJjaCBpbnRlcmZhY2UgdG8gaGVscCB5b3UgZmluZCB0aGUgSUQuCgpJZiB0aGF0
IGRvZXNuJ3Qgc29sdmUgeW91ciBwcm9ibGVtLCB0aGlzIGlzIGEgc2VyaW91cyBidWcgaW4gRGph
bmdvJ3MgYWRtaW46IGl0J3MgbWVhbnQgdG8gYmUgYWJsZSB0byBzY2FsZSB1cCB0byBsYXJnZSBu
dW1iZXJzIG9mIHJlbGF0ZWQgb2JqZWN0cy5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Pradeep Gowdabtbytes@yahoo.comhttp://www.btbytes.com2007-12-12T14:31:55Znono0Having too many values in the drop down list is not a difficult problem to solve.
Our app (which used the automatic django admin interface to the fullest possible extent) had a purchase Order module in which the user keys in Item code. As you can imagine there are thousands of items in the item master table.
We got around this by using newforms and Javascript autocomplete.
Moving an app from automatic admin interface to newforms is pretty easy.Having too many values in the drop down list is not a difficult problem to solve.
Our app (which used the automatic django admin interface to the fullest possible extent) had a purchase Order module in which the user keys in Item code. As you can imagine there are thousands of items in the item master table.
We got around this by using newforms and Javascript autocomplete.
Moving an app from automatic admin interface to newforms is pretty easy.SQAAAAJTAAAABGJvZHlSUwAAAcVIYXZpbmcgdG9vIG1hbnkgdmFsdWVzIGluIHRoZSBkcm9wIGRv
d24gbGlzdCBpcyBub3QgYSBkaWZmaWN1bHQgcHJvYmxlbSB0byBzb2x2ZS4gCgpPdXIgYXBwICh3
aGljaCB1c2VkIHRoZSBhdXRvbWF0aWMgZGphbmdvIGFkbWluIGludGVyZmFjZSB0byB0aGUgZnVs
bGVzdCBwb3NzaWJsZSBleHRlbnQpIGhhZCBhIHB1cmNoYXNlIE9yZGVyIG1vZHVsZSBpbiB3aGlj
aCB0aGUgdXNlciBrZXlzIGluIEl0ZW0gY29kZS4gQXMgeW91IGNhbiBpbWFnaW5lIHRoZXJlIGFy
ZSB0aG91c2FuZHMgb2YgaXRlbXMgaW4gdGhlIGl0ZW0gbWFzdGVyIHRhYmxlLiAKCldlIGdvdCBh
cm91bmQgdGhpcyBieSB1c2luZyBuZXdmb3JtcyBhbmQgSmF2YXNjcmlwdCBhdXRvY29tcGxldGUu
CgpNb3ZpbmcgYW4gYXBwIGZyb20gYXV0b21hdGljIGFkbWluIGludGVyZmFjZSB0byBuZXdmb3Jt
cyBpcyBwcmV0dHkgZWFzeS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
neeleshneeleshs@gmail.comhttp://mirroronthenet.org2007-12-12T14:43:23Znono0An issue I bumped in to with Django was aggregate functions. There is not much support for SQL aggregate functions in Django.(http://code.djangoproject.com/ticket/3566) Rails wins here (count, avg etc) , by providing more aggregate functions and the ease with which you can use SQL directly (Whether its a good thing or not is another debate, but it helps getting things done).An issue I bumped in to with Django was aggregate functions. There is not much support for SQL aggregate functions in Django.(http://code.djangoproject.com/ticket/3566) Rails wins here (count, avg etc) , by providing more aggregate functions and the ease with which you can use SQL directly (Whether its a good thing or not is another debate, but it helps getting things done).SQAAAAJTAAAABGJvZHlSUwAAAXtBbiBpc3N1ZSBJIGJ1bXBlZCBpbiB0byB3aXRoIERqYW5nbyB3
YXMgYWdncmVnYXRlIGZ1bmN0aW9ucy4gIFRoZXJlIGlzIG5vdCBtdWNoIHN1cHBvcnQgZm9yIFNR
TCBhZ2dyZWdhdGUgZnVuY3Rpb25zIGluIERqYW5nby4oaHR0cDovL2NvZGUuZGphbmdvcHJvamVj
dC5jb20vdGlja2V0LzM1NjYpICBSYWlscyB3aW5zIGhlcmUgKGNvdW50LCBhdmcgZXRjKSAsIGJ5
IHByb3ZpZGluZyBtb3JlIGFnZ3JlZ2F0ZSBmdW5jdGlvbnMgYW5kIHRoZSBlYXNlIHdpdGggd2hp
Y2ggeW91IGNhbiB1c2UgU1FMIGRpcmVjdGx5IChXaGV0aGVyIGl0cyBhIGdvb2QgdGhpbmcgb3Ig
bm90IGlzIGFub3RoZXIgZGViYXRlLCBidXQgaXQgaGVscHMgZ2V0dGluZyB0aGluZ3MgZG9uZSku
TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Konradkonryd@gmail.comhttp://konryd.blogspot.com2007-12-12T16:27:49Znono0It's a funny thing though - there's no group of developers that can avoid bikeshed discussion.
www.yellow.bikeshed.comIt's a funny thing though - there's no group of developers that can avoid bikeshed discussion.
www.yellow.bikeshed.comSQAAAAJTAAAABGJvZHlSUwAAAHdJdCdzIGEgZnVubnkgdGhpbmcgdGhvdWdoIC0gdGhlcmUncyBu
byBncm91cCBvZiBkZXZlbG9wZXJzIHRoYXQgY2FuIGF2b2lkIGJpa2VzaGVkIGRpc2N1c3Npb24u
Cgp3d3cueWVsbG93LmJpa2VzaGVkLmNvbUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Jeff Croftjeff@jeffcroft.comhttp://jeffcroft.com/2007-12-12T17:06:47Znono0I actually agree with some of your points about the Django admin interface not being optimal Wilson designed it, what, three years ago, and it hasn't been touched since. It's definitely in need of an update, and has been for some time.
But, how can you use problems with the totally-optional admin app as a way to say, "Django isn't where Rails it at," when Rails doesn't include an admin application at all? If you don't like the admin app, you can do exactly what you'd do in Rails: build your own. The Django admin is simply a tool available that you can use if it works for you. If it doesn't, you'll build one, just like you would in Rails.
Same goes for auth. If you don't like it, don't use it. But, you can't say the optional auth app's problems make Django worse than Rails, when Rails doesn't include an auth app at all.
Right?I actually agree with some of your points about the Django admin interface not being optimal Wilson designed it, what, three years ago, and it hasn't been touched since. It's definitely in need of an update, and has been for some time.
But, how can you use problems with the totally-optional admin app as a way to say, "Django isn't where Rails it at," when Rails doesn't include an admin application at all? If you don't like the admin app, you can do exactly what you'd do in Rails: build your own. The Django admin is simply a tool available that you can use if it works for you. If it doesn't, you'll build one, just like you would in Rails.
Same goes for auth. If you don't like it, don't use it. But, you can't say the optional auth app's problems make Django worse than Rails, when Rails doesn't include an auth app at all.
Right?SQAAAAJTAAAABGJvZHlSUwAAA0lJIGFjdHVhbGx5IGFncmVlIHdpdGggc29tZSBvZiB5b3VyIHBv
aW50cyBhYm91dCB0aGUgRGphbmdvIGFkbWluIGludGVyZmFjZSBub3QgYmVpbmcgb3B0aW1hbCBX
aWxzb24gZGVzaWduZWQgaXQsIHdoYXQsIHRocmVlIHllYXJzIGFnbywgYW5kIGl0IGhhc24ndCBi
ZWVuIHRvdWNoZWQgc2luY2UuIEl0J3MgZGVmaW5pdGVseSBpbiBuZWVkIG9mIGFuIHVwZGF0ZSwg
YW5kIGhhcyBiZWVuIGZvciBzb21lIHRpbWUuIAoKQnV0LCBob3cgY2FuIHlvdSB1c2UgcHJvYmxl
bXMgd2l0aCB0aGUgdG90YWxseS1vcHRpb25hbCBhZG1pbiBhcHAgYXMgYSB3YXkgdG8gc2F5LCAi
RGphbmdvIGlzbid0IHdoZXJlIFJhaWxzIGl0IGF0LCIgd2hlbiBSYWlscyBkb2Vzbid0IGluY2x1
ZGUgYW4gYWRtaW4gYXBwbGljYXRpb24gYXQgYWxsPyBJZiB5b3UgZG9uJ3QgbGlrZSB0aGUgYWRt
aW4gYXBwLCB5b3UgY2FuIGRvIGV4YWN0bHkgd2hhdCB5b3UnZCBkbyBpbiBSYWlsczogYnVpbGQg
eW91ciBvd24uIFRoZSBEamFuZ28gYWRtaW4gaXMgc2ltcGx5IGEgdG9vbCBhdmFpbGFibGUgdGhh
dCB5b3UgY2FuIHVzZSBpZiBpdCB3b3JrcyBmb3IgeW91LiBJZiBpdCBkb2Vzbid0LCB5b3UnbGwg
YnVpbGQgb25lLCBqdXN0IGxpa2UgeW91IHdvdWxkIGluIFJhaWxzLgoKU2FtZSBnb2VzIGZvciBh
dXRoLiBJZiB5b3UgZG9uJ3QgbGlrZSBpdCwgZG9uJ3QgdXNlIGl0LiBCdXQsIHlvdSBjYW4ndCBz
YXkgdGhlIG9wdGlvbmFsIGF1dGggYXBwJ3MgcHJvYmxlbXMgbWFrZSBEamFuZ28gd29yc2UgdGhh
biBSYWlscywgd2hlbiBSYWlscyBkb2Vzbid0IGluY2x1ZGUgYW4gYXV0aCBhcHAgYXQgYWxsLgoK
UmlnaHQ/TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-12T17:45:56Znono0Woa. Quite a lot of response. Guess I have to straighten out some things.
Yes it's true that django admin is not strictly part of the framework and yes, it's an addon library. However very tightly integrated into the django system, especially the ORM. This is not a bad thing and there is huge potential. On the other hand it's also true that having an administration application being part of the framework is a plus over rails.
But if we look at django the framework has four major elements: The object relational mapper, the form validation library and the WSGI/mod_python/HTTP modules and finally the template engine. The first element, the ORM is "crippled" compared to SQLAlchemy. One the one hand because there is no session system which becomes pain in the ass pretty soon if you see what the session system does in an SQLAlchemy powered application. However there are also strengths of the ORM, namely that it's incredible user friendly. But zzzeek is working incredible hard on making SQLAlchemy easier and easier and recent versions are great fun to work with. And yes, you can of course use SQLAlchemy with django, but then you loose the admin and all the other great features that depend on the models.
The form validation and the admin system are certainly django's biggest plus over alternative solutions. But as it turns out the admin becomes problematic for more complex data models and you have to create your own administration interface anyways.
Python has a huge number of great libraries, don't forget about that. There is Genshi which, without doubt, is the so far best XML based template engine I found for an agile scripting language. There is SQLAlchemy which permanently blows my mind in what's possible and how you can use the library. There is WSGI and libraries that built up on it (like Paste, Werkzeug, Webob...). There is a huge number of libraries you probably don't know yet ;-) Those libraries combined together make (currently) a good scaling application if you know what you're doing.
Django certainly leaves TurboGears out in the rain. It's easy to integrate other libraries in django, even if others often claim that this is not the case. But you also lose all the strengths of django other frameworks don't have (admin, auth). And if you lose all of them you are left with a (well performing) WSGI library plus a bunch of utilities you could have otherwise to.
So I really would say: Make that a 1.0 release and blow our minds with cool additions in the future (like migrations, an even better extensible administrator interface, row based permissions, subclass-able models) and revive the SQLAlchemy branch which would be the ultimate feature in django.
Regards,
ArminWoa. Quite a lot of response. Guess I have to straighten out some things.
Yes it's true that django admin is not strictly part of the framework and yes, it's an addon library. However very tightly integrated into the django system, especially the ORM. This is not a bad thing and there is huge potential. On the other hand it's also true that having an administration application being part of the framework is a plus over rails.
But if we look at django the framework has four major elements: The object relational mapper, the form validation library and the WSGI/mod_python/HTTP modules and finally the template engine. The first element, the ORM is "crippled" compared to SQLAlchemy. One the one hand because there is no session system which becomes pain in the ass pretty soon if you see what the session system does in an SQLAlchemy powered application. However there are also strengths of the ORM, namely that it's incredible user friendly. But zzzeek is working incredible hard on making SQLAlchemy easier and easier and recent versions are great fun to work with. And yes, you can of course use SQLAlchemy with django, but then you loose the admin and all the other great features that depend on the models.
The form validation and the admin system are certainly django's biggest plus over alternative solutions. But as it turns out the admin becomes problematic for more complex data models and you have to create your own administration interface anyways.
Python has a huge number of great libraries, don't forget about that. There is Genshi which, without doubt, is the so far best XML based template engine I found for an agile scripting language. There is SQLAlchemy which permanently blows my mind in what's possible and how you can use the library. There is WSGI and libraries that built up on it (like Paste, Werkzeug, Webob...). There is a huge number of libraries you probably don't know yet ;-) Those libraries combined together make (currently) a good scaling application if you know what you're doing.
Django certainly leaves TurboGears out in the rain. It's easy to integrate other libraries in django, even if others often claim that this is not the case. But you also lose all the strengths of django other frameworks don't have (admin, auth). And if you lose all of them you are left with a (well performing) WSGI library plus a bunch of utilities you could have otherwise to.
So I really would say: Make that a 1.0 release and blow our minds with cool additions in the future (like migrations, an even better extensible administrator interface, row based permissions, subclass-able models) and revive the SQLAlchemy branch which would be the ultimate feature in django.
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAACp1Xb2EuIFF1aXRlIGEgbG90IG9mIHJlc3BvbnNlLiBHdWVzcyBJ
IGhhdmUgdG8gc3RyYWlnaHRlbiBvdXQgc29tZSB0aGluZ3MuCgpZZXMgaXQncyB0cnVlIHRoYXQg
ZGphbmdvIGFkbWluIGlzIG5vdCBzdHJpY3RseSBwYXJ0IG9mIHRoZSBmcmFtZXdvcmsgYW5kIHll
cywgaXQncyBhbiBhZGRvbiBsaWJyYXJ5LiBIb3dldmVyIHZlcnkgdGlnaHRseSBpbnRlZ3JhdGVk
IGludG8gdGhlIGRqYW5nbyBzeXN0ZW0sIGVzcGVjaWFsbHkgdGhlIE9STS4gVGhpcyBpcyBub3Qg
YSBiYWQgdGhpbmcgYW5kIHRoZXJlIGlzIGh1Z2UgcG90ZW50aWFsLiBPbiB0aGUgb3RoZXIgaGFu
ZCBpdCdzIGFsc28gdHJ1ZSB0aGF0IGhhdmluZyBhbiBhZG1pbmlzdHJhdGlvbiBhcHBsaWNhdGlv
biBiZWluZyBwYXJ0IG9mIHRoZSBmcmFtZXdvcmsgaXMgYSBwbHVzIG92ZXIgcmFpbHMuCgpCdXQg
aWYgd2UgbG9vayBhdCBkamFuZ28gdGhlIGZyYW1ld29yayBoYXMgZm91ciBtYWpvciBlbGVtZW50
czogVGhlIG9iamVjdCByZWxhdGlvbmFsIG1hcHBlciwgdGhlIGZvcm0gdmFsaWRhdGlvbiBsaWJy
YXJ5IGFuZCB0aGUgV1NHSS9tb2RfcHl0aG9uL0hUVFAgbW9kdWxlcyBhbmQgZmluYWxseSB0aGUg
dGVtcGxhdGUgZW5naW5lLiBUaGUgZmlyc3QgZWxlbWVudCwgdGhlIE9STSBpcyAiY3JpcHBsZWQi
IGNvbXBhcmVkIHRvIFNRTEFsY2hlbXkuIE9uZSB0aGUgb25lIGhhbmQgYmVjYXVzZSB0aGVyZSBp
cyBubyBzZXNzaW9uIHN5c3RlbSB3aGljaCBiZWNvbWVzIHBhaW4gaW4gdGhlIGFzcyBwcmV0dHkg
c29vbiBpZiB5b3Ugc2VlIHdoYXQgdGhlIHNlc3Npb24gc3lzdGVtIGRvZXMgaW4gYW4gU1FMQWxj
aGVteSBwb3dlcmVkIGFwcGxpY2F0aW9uLiBIb3dldmVyIHRoZXJlIGFyZSBhbHNvIHN0cmVuZ3Ro
cyBvZiB0aGUgT1JNLCBuYW1lbHkgdGhhdCBpdCdzIGluY3JlZGlibGUgdXNlciBmcmllbmRseS4g
QnV0IHp6emVlayBpcyB3b3JraW5nIGluY3JlZGlibGUgaGFyZCBvbiBtYWtpbmcgU1FMQWxjaGVt
eSBlYXNpZXIgYW5kIGVhc2llciBhbmQgcmVjZW50IHZlcnNpb25zIGFyZSBncmVhdCBmdW4gdG8g
d29yayB3aXRoLiBBbmQgeWVzLCB5b3UgY2FuIG9mIGNvdXJzZSB1c2UgU1FMQWxjaGVteSB3aXRo
IGRqYW5nbywgYnV0IHRoZW4geW91IGxvb3NlIHRoZSBhZG1pbiBhbmQgYWxsIHRoZSBvdGhlciBn
cmVhdCBmZWF0dXJlcyB0aGF0IGRlcGVuZCBvbiB0aGUgbW9kZWxzLgoKVGhlIGZvcm0gdmFsaWRh
dGlvbiBhbmQgdGhlIGFkbWluIHN5c3RlbSBhcmUgY2VydGFpbmx5IGRqYW5nbydzIGJpZ2dlc3Qg
cGx1cyBvdmVyIGFsdGVybmF0aXZlIHNvbHV0aW9ucy4gQnV0IGFzIGl0IHR1cm5zIG91dCB0aGUg
YWRtaW4gYmVjb21lcyBwcm9ibGVtYXRpYyBmb3IgbW9yZSBjb21wbGV4IGRhdGEgbW9kZWxzIGFu
ZCB5b3UgaGF2ZSB0byBjcmVhdGUgeW91ciBvd24gYWRtaW5pc3RyYXRpb24gaW50ZXJmYWNlIGFu
eXdheXMuCgpQeXRob24gaGFzIGEgaHVnZSBudW1iZXIgb2YgZ3JlYXQgbGlicmFyaWVzLCBkb24n
dCBmb3JnZXQgYWJvdXQgdGhhdC4gVGhlcmUgaXMgR2Vuc2hpIHdoaWNoLCB3aXRob3V0IGRvdWJ0
LCBpcyB0aGUgc28gZmFyIGJlc3QgWE1MIGJhc2VkIHRlbXBsYXRlIGVuZ2luZSBJIGZvdW5kIGZv
ciBhbiBhZ2lsZSBzY3JpcHRpbmcgbGFuZ3VhZ2UuIFRoZXJlIGlzIFNRTEFsY2hlbXkgd2hpY2gg
cGVybWFuZW50bHkgYmxvd3MgbXkgbWluZCBpbiB3aGF0J3MgcG9zc2libGUgYW5kIGhvdyB5b3Ug
Y2FuIHVzZSB0aGUgbGlicmFyeS4gVGhlcmUgaXMgV1NHSSBhbmQgbGlicmFyaWVzIHRoYXQgYnVp
bHQgdXAgb24gaXQgKGxpa2UgUGFzdGUsIFdlcmt6ZXVnLCBXZWJvYi4uLikuIFRoZXJlIGlzIGEg
aHVnZSBudW1iZXIgb2YgbGlicmFyaWVzIHlvdSBwcm9iYWJseSBkb24ndCBrbm93IHlldCA7LSkg
VGhvc2UgbGlicmFyaWVzIGNvbWJpbmVkIHRvZ2V0aGVyIG1ha2UgKGN1cnJlbnRseSkgYSBnb29k
IHNjYWxpbmcgYXBwbGljYXRpb24gaWYgeW91IGtub3cgd2hhdCB5b3UncmUgZG9pbmcuCgpEamFu
Z28gY2VydGFpbmx5IGxlYXZlcyBUdXJib0dlYXJzIG91dCBpbiB0aGUgcmFpbi4gSXQncyBlYXN5
IHRvIGludGVncmF0ZSBvdGhlciBsaWJyYXJpZXMgaW4gZGphbmdvLCBldmVuIGlmIG90aGVycyBv
ZnRlbiBjbGFpbSB0aGF0IHRoaXMgaXMgbm90IHRoZSBjYXNlLiBCdXQgeW91IGFsc28gbG9zZSBh
bGwgdGhlIHN0cmVuZ3RocyBvZiBkamFuZ28gb3RoZXIgZnJhbWV3b3JrcyBkb24ndCBoYXZlIChh
ZG1pbiwgYXV0aCkuIEFuZCBpZiB5b3UgbG9zZSBhbGwgb2YgdGhlbSB5b3UgYXJlIGxlZnQgd2l0
aCBhICh3ZWxsIHBlcmZvcm1pbmcpIFdTR0kgbGlicmFyeSBwbHVzIGEgYnVuY2ggb2YgdXRpbGl0
aWVzIHlvdSBjb3VsZCBoYXZlIG90aGVyd2lzZSB0by4KClNvIEkgcmVhbGx5IHdvdWxkIHNheTog
TWFrZSB0aGF0IGEgMS4wIHJlbGVhc2UgYW5kIGJsb3cgb3VyIG1pbmRzIHdpdGggY29vbCBhZGRp
dGlvbnMgaW4gdGhlIGZ1dHVyZSAobGlrZSBtaWdyYXRpb25zLCBhbiBldmVuIGJldHRlciBleHRl
bnNpYmxlIGFkbWluaXN0cmF0b3IgaW50ZXJmYWNlLCByb3cgYmFzZWQgcGVybWlzc2lvbnMsIHN1
YmNsYXNzLWFibGUgbW9kZWxzKSBhbmQgcmV2aXZlIHRoZSBTUUxBbGNoZW15IGJyYW5jaCB3aGlj
aCB3b3VsZCBiZSB0aGUgdWx0aW1hdGUgZmVhdHVyZSBpbiBkamFuZ28uCgpSZWdhcmRzLApBcm1p
bkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Paulpaul@prescod.net2007-12-12T17:51:46Znono0I think that one could just as easily make the case that Rails is immature compared to Django because of its (non-)handling of authentication, administration, Unicode and threading. Maybe Django should be at 3.0!I think that one could just as easily make the case that Rails is immature compared to Django because of its (non-)handling of authentication, administration, Unicode and threading. Maybe Django should be at 3.0!SQAAAAJTAAAABGJvZHlSUwAAANRJIHRoaW5rIHRoYXQgb25lIGNvdWxkIGp1c3QgYXMgZWFzaWx5
IG1ha2UgdGhlIGNhc2UgdGhhdCBSYWlscyBpcyBpbW1hdHVyZSBjb21wYXJlZCB0byBEamFuZ28g
YmVjYXVzZSBvZiBpdHMgKG5vbi0paGFuZGxpbmcgb2YgYXV0aGVudGljYXRpb24sIGFkbWluaXN0
cmF0aW9uLCBVbmljb2RlIGFuZCB0aHJlYWRpbmcuIE1heWJlIERqYW5nbyBzaG91bGQgYmUgYXQg
My4wIUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-12T18:04:29Znono0Paul: Rails is miles ahead of django so far. (Unfortunately). There are plugins that add auth/admin and other fancy stuff to it. And Rails does handle Unicode. And I wouldn't say that django handles threads much better than rails. While Rails might not be threadsafe, Python has a GIL and performs better in a Forking Environment too most of the time (of course consuming more memory).Paul: Rails is miles ahead of django so far. (Unfortunately). There are plugins that add auth/admin and other fancy stuff to it. And Rails does handle Unicode. And I wouldn't say that django handles threads much better than rails. While Rails might not be threadsafe, Python has a GIL and performs better in a Forking Environment too most of the time (of course consuming more memory).SQAAAAJTAAAABGJvZHlSUwAAAYFQYXVsOiBSYWlscyBpcyBtaWxlcyBhaGVhZCBvZiBkamFuZ28g
c28gZmFyLiAoVW5mb3J0dW5hdGVseSkuIFRoZXJlIGFyZSBwbHVnaW5zIHRoYXQgYWRkIGF1dGgv
YWRtaW4gYW5kIG90aGVyIGZhbmN5IHN0dWZmIHRvIGl0LiBBbmQgUmFpbHMgZG9lcyBoYW5kbGUg
VW5pY29kZS4gQW5kIEkgd291bGRuJ3Qgc2F5IHRoYXQgZGphbmdvIGhhbmRsZXMgdGhyZWFkcyBt
dWNoIGJldHRlciB0aGFuIHJhaWxzLiBXaGlsZSBSYWlscyBtaWdodCBub3QgYmUgdGhyZWFkc2Fm
ZSwgUHl0aG9uIGhhcyBhIEdJTCBhbmQgcGVyZm9ybXMgYmV0dGVyIGluIGEgRm9ya2luZyBFbnZp
cm9ubWVudCB0b28gbW9zdCBvZiB0aGUgdGltZSAob2YgY291cnNlIGNvbnN1bWluZyBtb3JlIG1l
bW9yeSkuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Chris McAvoychris.mcavoy@gmail.comhttp://weblog.lonelylion.com2007-12-12T18:19:46Znono0I think you make some good points, but they should really be directed at any of the full stack "2.0" web app frameworks. All ORM's end up getting in the way at some point (IMHO), you always end up saying "this would be way more efficient in straight SQL." I've been involved in projects that have addressed the issue in one of two ways, re-work the schema to fit the ORM or work around the ORM to get at raw sql. Both are good solutions depending on the situation. The real strength of Django, Rails, Turbogears, Pylons, and any other newish set of web tools is that they give you a set of usable defaults. However, there's no way to anticipate every need, so they'll all end up "failing" at some point. As long as they give you a reliable facility to fall back to some sort of "raw," you're in the clear.
So, given that limitation, my take on it is that the good frameworks are ones that perform well and are reliable. I've had to recommend Rails or Django in a few situations. Today, December 12th, 2007, I recommend using Django, as the base platform is easier to deploy, faster, and more reliable. The free stuff you get with it is a real bonus for the early stages of development. That said, I haven't looked at Rails 2.0, or the latest versions of Pylons or Turbogears.
As for 1.0 or 2.0, I don't give a crap.I think you make some good points, but they should really be directed at any of the full stack "2.0" web app frameworks. All ORM's end up getting in the way at some point (IMHO), you always end up saying "this would be way more efficient in straight SQL." I've been involved in projects that have addressed the issue in one of two ways, re-work the schema to fit the ORM or work around the ORM to get at raw sql. Both are good solutions depending on the situation. The real strength of Django, Rails, Turbogears, Pylons, and any other newish set of web tools is that they give you a set of usable defaults. However, there's no way to anticipate every need, so they'll all end up "failing" at some point. As long as they give you a reliable facility to fall back to some sort of "raw," you're in the clear.
So, given that limitation, my take on it is that the good frameworks are ones that perform well and are reliable. I've had to recommend Rails or Django in a few situations. Today, December 12th, 2007, I recommend using Django, as the base platform is easier to deploy, faster, and more reliable. The free stuff you get with it is a real bonus for the early stages of development. That said, I haven't looked at Rails 2.0, or the latest versions of Pylons or Turbogears.
As for 1.0 or 2.0, I don't give a crap.SQAAAAJTAAAABGJvZHlSUwAABTBJIHRoaW5rIHlvdSBtYWtlIHNvbWUgZ29vZCBwb2ludHMsIGJ1
dCB0aGV5IHNob3VsZCByZWFsbHkgYmUgZGlyZWN0ZWQgYXQgYW55IG9mIHRoZSBmdWxsIHN0YWNr
ICIyLjAiIHdlYiBhcHAgZnJhbWV3b3Jrcy4gIEFsbCBPUk0ncyBlbmQgdXAgZ2V0dGluZyBpbiB0
aGUgd2F5IGF0IHNvbWUgcG9pbnQgKElNSE8pLCB5b3UgYWx3YXlzIGVuZCB1cCBzYXlpbmcgInRo
aXMgd291bGQgYmUgd2F5IG1vcmUgZWZmaWNpZW50IGluIHN0cmFpZ2h0IFNRTC4iICBJJ3ZlIGJl
ZW4gaW52b2x2ZWQgaW4gcHJvamVjdHMgdGhhdCBoYXZlIGFkZHJlc3NlZCB0aGUgaXNzdWUgaW4g
b25lIG9mIHR3byB3YXlzLCByZS13b3JrIHRoZSBzY2hlbWEgdG8gZml0IHRoZSBPUk0gb3Igd29y
ayBhcm91bmQgdGhlIE9STSB0byBnZXQgYXQgcmF3IHNxbC4gIEJvdGggYXJlIGdvb2Qgc29sdXRp
b25zIGRlcGVuZGluZyBvbiB0aGUgc2l0dWF0aW9uLiAgVGhlIHJlYWwgc3RyZW5ndGggb2YgRGph
bmdvLCBSYWlscywgVHVyYm9nZWFycywgUHlsb25zLCBhbmQgYW55IG90aGVyIG5ld2lzaCBzZXQg
b2Ygd2ViIHRvb2xzIGlzIHRoYXQgdGhleSBnaXZlIHlvdSBhIHNldCBvZiB1c2FibGUgZGVmYXVs
dHMuICBIb3dldmVyLCB0aGVyZSdzIG5vIHdheSB0byBhbnRpY2lwYXRlIGV2ZXJ5IG5lZWQsIHNv
IHRoZXknbGwgYWxsIGVuZCB1cCAiZmFpbGluZyIgYXQgc29tZSBwb2ludC4gIEFzIGxvbmcgYXMg
dGhleSBnaXZlIHlvdSBhIHJlbGlhYmxlIGZhY2lsaXR5IHRvIGZhbGwgYmFjayB0byBzb21lIHNv
cnQgb2YgInJhdywiIHlvdSdyZSBpbiB0aGUgY2xlYXIuCgpTbywgZ2l2ZW4gdGhhdCBsaW1pdGF0
aW9uLCBteSB0YWtlIG9uIGl0IGlzIHRoYXQgdGhlIGdvb2QgZnJhbWV3b3JrcyBhcmUgb25lcyB0
aGF0IHBlcmZvcm0gd2VsbCBhbmQgYXJlIHJlbGlhYmxlLiAgSSd2ZSBoYWQgdG8gcmVjb21tZW5k
IFJhaWxzIG9yIERqYW5nbyBpbiBhIGZldyBzaXR1YXRpb25zLiAgVG9kYXksIERlY2VtYmVyIDEy
dGgsIDIwMDcsIEkgcmVjb21tZW5kIHVzaW5nIERqYW5nbywgYXMgdGhlIGJhc2UgcGxhdGZvcm0g
aXMgZWFzaWVyIHRvIGRlcGxveSwgZmFzdGVyLCBhbmQgbW9yZSByZWxpYWJsZS4gIFRoZSBmcmVl
IHN0dWZmIHlvdSBnZXQgd2l0aCBpdCBpcyBhIHJlYWwgYm9udXMgZm9yIHRoZSBlYXJseSBzdGFn
ZXMgb2YgZGV2ZWxvcG1lbnQuICBUaGF0IHNhaWQsIEkgaGF2ZW4ndCBsb29rZWQgYXQgUmFpbHMg
Mi4wLCBvciB0aGUgbGF0ZXN0IHZlcnNpb25zIG9mIFB5bG9ucyBvciBUdXJib2dlYXJzLiAKCkFz
IGZvciAxLjAgb3IgMi4wLCBJIGRvbid0IGdpdmUgYSBjcmFwLkwAAFMAAAAGcGFyc2VyUwAAAARo
dG1s
Marcelo Fernándezfernandezm22@yahoo.com.arhttp://marcelosoft.blogspot.com2007-12-12T18:55:13Znono0Hi Armin, I couldn't agree more with you. I've implemented Django and "suffered" the same things (mainly) with the ORM layer. On the other side, I think the template system is great, and the Jinja library is there to expand it.
http://jinja.pocoo.org/
Cheers!
MarceloHi Armin, I couldn't agree more with you. I've implemented Django and "suffered" the same things (mainly) with the ORM layer. On the other side, I think the template system is great, and the Jinja library is there to expand it.
http://jinja.pocoo.org/
Cheers!
MarceloSQAAAAJTAAAABGJvZHlSUwAAAQ1IaSBBcm1pbiwgSSBjb3VsZG4ndCBhZ3JlZSBtb3JlIHdpdGgg
eW91LiBJJ3ZlIGltcGxlbWVudGVkIERqYW5nbyBhbmQgInN1ZmZlcmVkIiB0aGUgc2FtZSB0aGlu
Z3MgKG1haW5seSkgd2l0aCB0aGUgT1JNIGxheWVyLiBPbiB0aGUgb3RoZXIgc2lkZSwgSSB0aGlu
ayB0aGUgdGVtcGxhdGUgc3lzdGVtIGlzIGdyZWF0LCBhbmQgdGhlIEppbmphIGxpYnJhcnkgaXMg
dGhlcmUgdG8gZXhwYW5kIGl0LgoKaHR0cDovL2ppbmphLnBvY29vLm9yZy8KCkNoZWVycyEKTWFy
Y2Vsb0wAAFMAAAAGcGFyc2VyUwAAAARodG1s
AkitaOnRailsfabioakita@gmail.comhttp://www.akitaonrails.com2007-12-12T19:09:23Znono0Though I realize this is a Django discussion, I couldn't resist trying a bit of Rails here. For those of you that never tried Rails, I've compiled a very very speed up "Rails 2.0 Screencast":http://www.akitaonrails.com/2007/12/10/the-first-rails-2-0-screencast-english. In less than 30 min you can see some of the new features and what can be accomplished.
About Rails not having an Admin app, it can be an advantage or disadvantage depending on your point of view. If you're mainly dealing with content management, this is a plus. Though mixing a Framework with a highly integrated App is arguably an optimal situation. I'd like to have Rails being the kitchen-sink and I can later add ActiveScaffold, for example, if I want very fast admin screens. Authentication can be done is several different ways and I also don't think it belongs to the framework, as we have several plugins to tackle this matter as well.
That said, I also don't think there only needs to be one framework, there is room for DJango, Rails, and many more.Though I realize this is a Django discussion, I couldn't resist trying a bit of Rails here. For those of you that never tried Rails, I've compiled a very very speed up "Rails 2.0 Screencast":http://www.akitaonrails.com/2007/12/10/the-first-rails-2-0-screencast-english. In less than 30 min you can see some of the new features and what can be accomplished.
About Rails not having an Admin app, it can be an advantage or disadvantage depending on your point of view. If you're mainly dealing with content management, this is a plus. Though mixing a Framework with a highly integrated App is arguably an optimal situation. I'd like to have Rails being the kitchen-sink and I can later add ActiveScaffold, for example, if I want very fast admin screens. Authentication can be done is several different ways and I also don't think it belongs to the framework, as we have several plugins to tackle this matter as well.
That said, I also don't think there only needs to be one framework, there is room for DJango, Rails, and many more.SQAAAAJTAAAABGJvZHlSUwAABAhUaG91Z2ggSSByZWFsaXplIHRoaXMgaXMgYSBEamFuZ28gZGlz
Y3Vzc2lvbiwgSSBjb3VsZG4ndCByZXNpc3QgdHJ5aW5nIGEgYml0IG9mIFJhaWxzIGhlcmUuIEZv
ciB0aG9zZSBvZiB5b3UgdGhhdCBuZXZlciB0cmllZCBSYWlscywgSSd2ZSBjb21waWxlZCBhIHZl
cnkgdmVyeSBzcGVlZCB1cCAiUmFpbHMgMi4wIFNjcmVlbmNhc3QiOmh0dHA6Ly93d3cuYWtpdGFv
bnJhaWxzLmNvbS8yMDA3LzEyLzEwL3RoZS1maXJzdC1yYWlscy0yLTAtc2NyZWVuY2FzdC1lbmds
aXNoLiBJbiBsZXNzIHRoYW4gMzAgbWluIHlvdSBjYW4gc2VlIHNvbWUgb2YgdGhlIG5ldyBmZWF0
dXJlcyBhbmQgd2hhdCBjYW4gYmUgYWNjb21wbGlzaGVkLiAKCkFib3V0IFJhaWxzIG5vdCBoYXZp
bmcgYW4gQWRtaW4gYXBwLCBpdCBjYW4gYmUgYW4gYWR2YW50YWdlIG9yIGRpc2FkdmFudGFnZSBk
ZXBlbmRpbmcgb24geW91ciBwb2ludCBvZiB2aWV3LiBJZiB5b3UncmUgbWFpbmx5IGRlYWxpbmcg
d2l0aCBjb250ZW50IG1hbmFnZW1lbnQsIHRoaXMgaXMgYSBwbHVzLiBUaG91Z2ggbWl4aW5nIGEg
RnJhbWV3b3JrIHdpdGggYSBoaWdobHkgaW50ZWdyYXRlZCBBcHAgaXMgYXJndWFibHkgYW4gb3B0
aW1hbCBzaXR1YXRpb24uIEknZCBsaWtlIHRvIGhhdmUgUmFpbHMgYmVpbmcgdGhlIGtpdGNoZW4t
c2luayBhbmQgSSBjYW4gbGF0ZXIgYWRkIEFjdGl2ZVNjYWZmb2xkLCBmb3IgZXhhbXBsZSwgaWYg
SSB3YW50IHZlcnkgZmFzdCBhZG1pbiBzY3JlZW5zLiBBdXRoZW50aWNhdGlvbiBjYW4gYmUgZG9u
ZSBpcyBzZXZlcmFsIGRpZmZlcmVudCB3YXlzIGFuZCBJIGFsc28gZG9uJ3QgdGhpbmsgaXQgYmVs
b25ncyB0byB0aGUgZnJhbWV3b3JrLCBhcyB3ZSBoYXZlIHNldmVyYWwgcGx1Z2lucyB0byB0YWNr
bGUgdGhpcyBtYXR0ZXIgYXMgd2VsbC4KClRoYXQgc2FpZCwgSSBhbHNvIGRvbid0IHRoaW5rIHRo
ZXJlIG9ubHkgbmVlZHMgdG8gYmUgb25lIGZyYW1ld29yaywgdGhlcmUgaXMgcm9vbSBmb3IgREph
bmdvLCBSYWlscywgYW5kIG1hbnkgbW9yZS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-12T19:25:10Znono0@AkitaOnRails: Python has more to offer than just Django. If one wants something like rails there is Pylons or a custom WSGI application which, thanks to SQLAlchemy, gives you a very good database access. Seriously. Replacing Django with Rails is like switching from one evil to the other. And even if Rails still leads the framework war, Django is doing great progress.
I just don't think that it's ready for 2.0 *yet* :-)
Regards,
Armin@AkitaOnRails: Python has more to offer than just Django. If one wants something like rails there is Pylons or a custom WSGI application which, thanks to SQLAlchemy, gives you a very good database access. Seriously. Replacing Django with Rails is like switching from one evil to the other. And even if Rails still leads the framework war, Django is doing great progress.
I just don't think that it's ready for 2.0 *yet* :-)
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAbhAQWtpdGFPblJhaWxzOiBQeXRob24gaGFzIG1vcmUgdG8gb2Zm
ZXIgdGhhbiBqdXN0IERqYW5nby4gSWYgb25lIHdhbnRzIHNvbWV0aGluZyBsaWtlIHJhaWxzIHRo
ZXJlIGlzIFB5bG9ucyBvciBhIGN1c3RvbSBXU0dJIGFwcGxpY2F0aW9uIHdoaWNoLCB0aGFua3Mg
dG8gU1FMQWxjaGVteSwgZ2l2ZXMgeW91IGEgdmVyeSBnb29kIGRhdGFiYXNlIGFjY2Vzcy4gU2Vy
aW91c2x5LiBSZXBsYWNpbmcgRGphbmdvIHdpdGggUmFpbHMgaXMgbGlrZSBzd2l0Y2hpbmcgZnJv
bSBvbmUgZXZpbCB0byB0aGUgb3RoZXIuIEFuZCBldmVuIGlmIFJhaWxzIHN0aWxsIGxlYWRzIHRo
ZSBmcmFtZXdvcmsgd2FyLCBEamFuZ28gaXMgZG9pbmcgZ3JlYXQgcHJvZ3Jlc3MuCgpJIGp1c3Qg
ZG9uJ3QgdGhpbmsgdGhhdCBpdCdzIHJlYWR5IGZvciAyLjAgKnlldCogOi0pCgpSZWdhcmRzLApB
cm1pbkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
casseencas@casoraaaa.com2007-12-12T21:46:11Znono0Rails is great and in my op is a littel more mature than django and other python frameworks. But the point is not rails vs django but rather python vs ruby. And as you all know, python is like poetry ; )Rails is great and in my op is a littel more mature than django and other python frameworks. But the point is not rails vs django but rather python vs ruby. And as you all know, python is like poetry ; )SQAAAAJTAAAABGJvZHlSUwAAAMtSYWlscyBpcyBncmVhdCBhbmQgaW4gbXkgb3AgaXMgYSBsaXR0
ZWwgbW9yZSBtYXR1cmUgdGhhbiBkamFuZ28gYW5kIG90aGVyIHB5dGhvbiBmcmFtZXdvcmtzLiBC
dXQgdGhlIHBvaW50IGlzIG5vdCByYWlscyB2cyBkamFuZ28gYnV0IHJhdGhlciBweXRob24gdnMg
cnVieS4gQW5kIGFzIHlvdSBhbGwga25vdywgcHl0aG9uIGlzIGxpa2UgcG9ldHJ5IDsgKUwAAFMA
AAAGcGFyc2VyUwAAAARodG1s
heraldsheofjq@hot.com2007-12-13T01:12:45Znono0"But the point is not rails vs django but rather python vs ruby. And as you all know, python is like poetry ; )"
Ruby is cleaner (except for 'end', but python forces you to indent+':' so that is not a huge compensational win, since you cant choose to not have that) than python. The ambiguity cat.meow() is a joke, the variable mandatory "self" name in python is a joke too. (I am not saying python itself is a joke, python has some great things going for it, which you notice if you see that really many use python)
To be honest... i think both python and ruby lost the battle of the www to...
PHP
And this makes me sad. Php is a horrible language, but people use it.
Everyone talks about the www. Django and RoR are web FRAMEWORKs.
WEB! This is where PHP won, and both python and ruby should focus
in GOOD deal with the www. Www is all about interacting with other people.
We dont need a fancy erlang - we need software from people, for people. And
when i write people, I mean BILLIONS of people! Everyone is a user!
The www has won.
PHP won the first round, it is time to make it lose again!"But the point is not rails vs django but rather python vs ruby. And as you all know, python is like poetry ; )"
Ruby is cleaner (except for 'end', but python forces you to indent+':' so that is not a huge compensational win, since you cant choose to not have that) than python. The ambiguity cat.meow() is a joke, the variable mandatory "self" name in python is a joke too. (I am not saying python itself is a joke, python has some great things going for it, which you notice if you see that really many use python)
To be honest... i think both python and ruby lost the battle of the www to...
PHP
And this makes me sad. Php is a horrible language, but people use it.
Everyone talks about the www. Django and RoR are web FRAMEWORKs.
WEB! This is where PHP won, and both python and ruby should focus
in GOOD deal with the www. Www is all about interacting with other people.
We dont need a fancy erlang - we need software from people, for people. And
when i write people, I mean BILLIONS of people! Everyone is a user!
The www has won.
PHP won the first round, it is time to make it lose again!SQAAAAJTAAAABGJvZHlSUwAABE8iQnV0IHRoZSBwb2ludCBpcyBub3QgcmFpbHMgdnMgZGphbmdv
IGJ1dCByYXRoZXIgcHl0aG9uIHZzIHJ1YnkuIEFuZCBhcyB5b3UgYWxsIGtub3csIHB5dGhvbiBp
cyBsaWtlIHBvZXRyeSA7ICkiClJ1YnkgaXMgY2xlYW5lciAoZXhjZXB0IGZvciAnZW5kJywgYnV0
IHB5dGhvbiBmb3JjZXMgeW91IHRvIGluZGVudCsnOicgc28gdGhhdCBpcyBub3QgYSBodWdlIGNv
bXBlbnNhdGlvbmFsIHdpbiwgc2luY2UgeW91IGNhbnQgY2hvb3NlIHRvIG5vdCBoYXZlIHRoYXQp
IHRoYW4gcHl0aG9uLiBUaGUgYW1iaWd1aXR5IGNhdC5tZW93KCkgaXMgYSBqb2tlLCB0aGUgdmFy
aWFibGUgbWFuZGF0b3J5ICJzZWxmIiBuYW1lIGluIHB5dGhvbiBpcyBhIGpva2UgdG9vLiAoSSBh
bSBub3Qgc2F5aW5nIHB5dGhvbiBpdHNlbGYgaXMgYSBqb2tlLCBweXRob24gaGFzIHNvbWUgZ3Jl
YXQgdGhpbmdzIGdvaW5nIGZvciBpdCwgd2hpY2ggeW91IG5vdGljZSBpZiB5b3Ugc2VlIHRoYXQg
cmVhbGx5IG1hbnkgdXNlIHB5dGhvbikKClRvIGJlIGhvbmVzdC4uLiBpIHRoaW5rIGJvdGggcHl0
aG9uIGFuZCBydWJ5IGxvc3QgdGhlIGJhdHRsZSBvZiB0aGUgd3d3IHRvLi4uClBIUAoKQW5kIHRo
aXMgbWFrZXMgbWUgc2FkLiBQaHAgaXMgYSBob3JyaWJsZSBsYW5ndWFnZSwgYnV0IHBlb3BsZSB1
c2UgaXQuIAoKRXZlcnlvbmUgdGFsa3MgYWJvdXQgdGhlIHd3dy4gRGphbmdvIGFuZCBSb1IgYXJl
IHdlYiBGUkFNRVdPUktzLgpXRUIhIFRoaXMgaXMgd2hlcmUgUEhQIHdvbiwgYW5kIGJvdGggcHl0
aG9uIGFuZCBydWJ5IHNob3VsZCBmb2N1cyAKaW4gR09PRCBkZWFsIHdpdGggdGhlIHd3dy4gV3d3
IGlzIGFsbCBhYm91dCBpbnRlcmFjdGluZyB3aXRoIG90aGVyIHBlb3BsZS4KV2UgZG9udCBuZWVk
IGEgZmFuY3kgZXJsYW5nIC0gd2UgbmVlZCBzb2Z0d2FyZSBmcm9tIHBlb3BsZSwgZm9yIHBlb3Bs
ZS4gQW5kIAp3aGVuIGkgd3JpdGUgcGVvcGxlLCBJIG1lYW4gQklMTElPTlMgb2YgcGVvcGxlISBF
dmVyeW9uZSBpcyBhIHVzZXIhCgpUaGUgd3d3IGhhcyB3b24uIAoKUEhQIHdvbiB0aGUgZmlyc3Qg
cm91bmQsIGl0IGlzIHRpbWUgdG8gbWFrZSBpdCBsb3NlIGFnYWluIUwAAFMAAAAGcGFyc2VyUwAA
AARodG1s
jamesjames_027@yahoo.com2007-12-13T04:51:39Znono0@AkitaOnRails: Django and Rails are both good web frameworks for the reason both of them are having a success. Since you're a rails user. does rails has something like Django's newforms? And I like what you can do to Django's middleware very powerful :). The only room for improvement I think Django should do is for the templates. In the end I agree with casseen, it's python vs ruby.
@Armin: Thanks for informing that SQLAlchemy is getting easier to use :)
Cheers@AkitaOnRails: Django and Rails are both good web frameworks for the reason both of them are having a success. Since you're a rails user. does rails has something like Django's newforms? And I like what you can do to Django's middleware very powerful :). The only room for improvement I think Django should do is for the templates. In the end I agree with casseen, it's python vs ruby.
@Armin: Thanks for informing that SQLAlchemy is getting easier to use :)
CheersSQAAAAJTAAAABGJvZHlSUwAAAdNAQWtpdGFPblJhaWxzOiBEamFuZ28gYW5kIFJhaWxzIGFyZSBi
b3RoIGdvb2Qgd2ViIGZyYW1ld29ya3MgZm9yIHRoZSByZWFzb24gYm90aCBvZiB0aGVtIGFyZSBo
YXZpbmcgYSBzdWNjZXNzLiBTaW5jZSB5b3UncmUgYSByYWlscyB1c2VyLiBkb2VzIHJhaWxzIGhh
cyBzb21ldGhpbmcgbGlrZSBEamFuZ28ncyBuZXdmb3Jtcz8gQW5kIEkgbGlrZSB3aGF0IHlvdSBj
YW4gZG8gdG8gRGphbmdvJ3MgbWlkZGxld2FyZSB2ZXJ5IHBvd2VyZnVsIDopLiBUaGUgb25seSBy
b29tIGZvciBpbXByb3ZlbWVudCBJIHRoaW5rIERqYW5nbyBzaG91bGQgZG8gaXMgZm9yIHRoZSB0
ZW1wbGF0ZXMuIEluIHRoZSBlbmQgSSBhZ3JlZSB3aXRoIGNhc3NlZW4sIGl0J3MgcHl0aG9uIHZz
IHJ1YnkuCgpAQXJtaW46IFRoYW5rcyBmb3IgaW5mb3JtaW5nIHRoYXQgU1FMQWxjaGVteSBpcyBn
ZXR0aW5nIGVhc2llciB0byB1c2UgOikKCkNoZWVyc0wAAFMAAAAGcGFyc2VyUwAAAARodG1s
AndrewSKkurinnyi@hotmail.com2007-12-13T07:08:37Znono0Have you tried monkey patching the User model itself, to add the number of user posts directly to User? It's incredibly easy.
http://www.amitu.com/blog/2007/july/django-extending-user-model/Have you tried monkey patching the User model itself, to add the number of user posts directly to User? It's incredibly easy.
http://www.amitu.com/blog/2007/july/django-extending-user-model/SQAAAAJTAAAABGJvZHlSUwAAAMBIYXZlIHlvdSB0cmllZCBtb25rZXkgcGF0Y2hpbmcgdGhlIFVz
ZXIgbW9kZWwgaXRzZWxmLCB0byBhZGQgdGhlIG51bWJlciBvZiB1c2VyIHBvc3RzIGRpcmVjdGx5
IHRvIFVzZXI/IEl0J3MgaW5jcmVkaWJseSBlYXN5LiAKCmh0dHA6Ly93d3cuYW1pdHUuY29tL2Js
b2cvMjAwNy9qdWx5L2RqYW5nby1leHRlbmRpbmctdXNlci1tb2RlbC9MAABTAAAABnBhcnNlclMA
AAAEaHRtbA==
Emptymtrier@gmail.comhttp://blog.michaeltrier.com2007-12-15T01:52:12Znono0Great post. I think Django is great. I blog about it, I write about it, and I spend considerable time helping people learn it. That said I think it's important to make a fair assessment about your strengths and weaknesses as a project, and constantly work to produce something that's better.
I agree with you on the whole 2.0 version number thing. It's nonsense.Great post. I think Django is great. I blog about it, I write about it, and I spend considerable time helping people learn it. That said I think it's important to make a fair assessment about your strengths and weaknesses as a project, and constantly work to produce something that's better.
I agree with you on the whole 2.0 version number thing. It's nonsense.SQAAAAJTAAAABGJvZHlSUwAAAXFHcmVhdCBwb3N0LiAgSSB0aGluayBEamFuZ28gaXMgZ3JlYXQu
ICBJIGJsb2cgYWJvdXQgaXQsIEkgd3JpdGUgYWJvdXQgaXQsIGFuZCBJIHNwZW5kIGNvbnNpZGVy
YWJsZSB0aW1lIGhlbHBpbmcgcGVvcGxlIGxlYXJuIGl0LiAgVGhhdCBzYWlkIEkgdGhpbmsgaXQn
cyBpbXBvcnRhbnQgdG8gbWFrZSBhIGZhaXIgYXNzZXNzbWVudCBhYm91dCB5b3VyIHN0cmVuZ3Ro
cyBhbmQgd2Vha25lc3NlcyBhcyBhIHByb2plY3QsIGFuZCBjb25zdGFudGx5IHdvcmsgdG8gcHJv
ZHVjZSBzb21ldGhpbmcgdGhhdCdzIGJldHRlci4gIAoKSSBhZ3JlZSB3aXRoIHlvdSBvbiB0aGUg
d2hvbGUgMi4wIHZlcnNpb24gbnVtYmVyIHRoaW5nLiAgSXQncyBub25zZW5zZS5MAABTAAAABnBh
cnNlclMAAAAEaHRtbA==
Benjamin Wiegandbeewee@ubuntuusers.de2007-12-15T19:39:29Znono0Thanks for your Post, AndrewSK. Your sollution is dirty but works :)Thanks for your Post, AndrewSK. Your sollution is dirty but works :)SQAAAAJTAAAABGJvZHlSUwAAAERUaGFua3MgZm9yIHlvdXIgUG9zdCwgQW5kcmV3U0suIFlvdXIg
c29sbHV0aW9uIGlzIGRpcnR5IGJ1dCB3b3JrcyA6KUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Extenuating Circumstances – links for 2008-01-07http://danhon.com/2008/01/07/links-for-2008-01-07/2008-01-07T10:20:53Znoyes0[...] Lucumr Cogitations » Blog Archive » Django’s Problems and Why 2.0 is a Bad Idea (tags: comparison django rails ruby webdev python orm curse fork development) [...][...] Lucumr Cogitations » Blog Archive » Django’s Problems and Why 2.0 is a Bad Idea (tags: comparison django rails ruby webdev python orm curse fork development) [...]SQAAAAJTAAAABGJvZHlSUwAAAK1bLi4uXSBMdWN1bXIgQ29naXRhdGlvbnMgwrsgQmxvZyBBcmNo
aXZlIMK7IERqYW5nb+KAmXMgUHJvYmxlbXMgYW5kIFdoeSAyLjAgaXMgYSBCYWQgSWRlYSAodGFn
czogY29tcGFyaXNvbiBkamFuZ28gcmFpbHMgcnVieSB3ZWJkZXYgcHl0aG9uIG9ybSBjdXJzZSBm
b3JrIGRldmVsb3BtZW50KSBbLi4uXUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Werkzeug Example Applications Onlinehttp://lucumr.pocoo.org/cogitations/2007/12/11/werkzeug-example-applications-online/2007-12-11T22:30:00Z2007-12-11T22:30:00ZArmin Ronacherwerkzeug-example-applications-onlineyesyes2I now installed the <a href="http://werkzeug.pocoo.org/">Werkzeug</a> example applications on pocoo.org. So you don't have to pull all the code if you want to try them out :-)
Here is the <a href="http://werkzeug.pocoo.org/e/simplewiki/">Wiki</a> and the <a href="http://werkzeug.pocoo.org/e/plnt/">Planet</a>. Have fun testing.I now installed the <a href="http://werkzeug.pocoo.org/">Werkzeug</a> example applications on pocoo.org. So you don't have to pull all the code if you want to try them out :-)
Here is the <a href="http://werkzeug.pocoo.org/e/simplewiki/">Wiki</a> and the <a href="http://werkzeug.pocoo.org/e/plnt/">Planet</a>. Have fun testing.SQAAAANTAAAABGJvZHlSUwAAABRJIG5vdyBpbnN0YWxsZWQgdGhlIEwAA0VTAAAAAWFMAABNAAFT
AAAABGhyZWZTAAAAGmh0dHA6Ly93ZXJremV1Zy5wb2Nvby5vcmcvUwAAAAhXZXJremV1Z1MAAAB5
IGV4YW1wbGUgYXBwbGljYXRpb25zIG9uIHBvY29vLm9yZy4gIFNvIHlvdSBkb24ndCBoYXZlIHRv
IHB1bGwgYWxsIHRoZSBjb2RlIGlmIHlvdSB3YW50IHRvIHRyeSB0aGVtIG91dCA6LSkKCkhlcmUg
aXMgdGhlIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAJ2h0dHA6Ly93ZXJremV1Zy5wb2Nvby5v
cmcvZS9zaW1wbGV3aWtpL1MAAAAEV2lraVMAAAAJIGFuZCB0aGUgRVMAAAABYUwAAE0AAVMAAAAE
aHJlZlMAAAAhaHR0cDovL3dlcmt6ZXVnLnBvY29vLm9yZy9lL3BsbnQvUwAAAAZQbGFuZXRTAAAA
Ey4gSGF2ZSBmdW4gdGVzdGluZy5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABM
AAA=
Werkzeug Debugger in Djangohttp://lucumr.pocoo.org/cogitations/2007/12/10/werkzeug-debugged-in-django/2007-12-10T17:30:24Z2007-12-10T17:30:24ZArmin Ronacherwerkzeug-debugged-in-djangoyesyes2(Thanks monkey patching). Ugly but works: <a href="http://dev.pocoo.org/projects/werkzeug/wiki/UsingDebuggerWithDjango">using the werkzeug debugger with django</a>.
Now digg/reddit it ;-)(Thanks monkey patching). Ugly but works: <a href="http://dev.pocoo.org/projects/werkzeug/wiki/UsingDebuggerWithDjango">using the werkzeug debugger with django</a>.
Now digg/reddit it ;-)SQAAAANTAAAABGJvZHlSUwAAACsoVGhhbmtzIG1vbmtleSBwYXRjaGluZykuICBVZ2x5IGJ1dCB3
b3JrczogTAABRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAABDaHR0cDovL2Rldi5wb2Nvby5vcmcv
cHJvamVjdHMvd2Vya3pldWcvd2lraS9Vc2luZ0RlYnVnZ2VyV2l0aERqYW5nb1MAAAAndXNpbmcg
dGhlIHdlcmt6ZXVnIGRlYnVnZ2VyIHdpdGggZGphbmdvUwAAABkuCgpOb3cgZGlnZy9yZWRkaXQg
aXQgOy0pUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Eric Florenzanofloguy@gmail.comhttp://www.eflorenzano.com/2007-12-10T20:21:20Znono0Cool stuff, I asked about this in a comment on your last blog post and today it's already patched in!Cool stuff, I asked about this in a comment on your last blog post and today it's already patched in!SQAAAAJTAAAABGJvZHlSUwAAAGVDb29sIHN0dWZmLCBJIGFza2VkIGFib3V0IHRoaXMgaW4gYSBj
b21tZW50IG9uIHlvdXIgbGFzdCBibG9nIHBvc3QgYW5kIHRvZGF5IGl0J3MgYWxyZWFkeSBwYXRj
aGVkIGluIUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Arnearne@rcs4u.dehttp://www.arnebrodowski.de/blog/2007-12-15T14:34:28Znono0I've added:
<pre>import django
from django.core.servers.basehttp import AdminMediaHandler
[...]
if __name__ == '__main__':
path = django.__path__[0] + '/contrib/admin/media/'
run_simple('localhost', 8080, DebuggedApplication(AdminMediaHandler(WSGIHandler(),path), True))</pre>
now it also serves my admin-media files correctly in the development environment, this is how django would do it, when the dev-server is used.I've added:
<pre>import django
from django.core.servers.basehttp import AdminMediaHandler
[...]
if __name__ == '__main__':
path = django.__path__[0] + '/contrib/admin/media/'
run_simple('localhost', 8080, DebuggedApplication(AdminMediaHandler(WSGIHandler(),path), True))</pre>
now it also serves my admin-media files correctly in the development environment, this is how django would do it, when the dev-server is used.SQAAAAJTAAAABGJvZHlSUwAAAAxJJ3ZlIGFkZGVkOgpMAAFFUwAAAANwcmVMAABNAABTAAABBWlt
cG9ydCBkamFuZ28KZnJvbSBkamFuZ28uY29yZS5zZXJ2ZXJzLmJhc2VodHRwIGltcG9ydCBBZG1p
bk1lZGlhSGFuZGxlcgpbLi4uXQppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgcGF0aCA9
IGRqYW5nby5fX3BhdGhfX1swXSArICcvY29udHJpYi9hZG1pbi9tZWRpYS8nCiAgICBydW5fc2lt
cGxlKCdsb2NhbGhvc3QnLCA4MDgwLCBEZWJ1Z2dlZEFwcGxpY2F0aW9uKEFkbWluTWVkaWFIYW5k
bGVyKFdTR0lIYW5kbGVyKCkscGF0aCksIFRydWUpKVMAAACQCgpub3cgaXQgYWxzbyBzZXJ2ZXMg
bXkgYWRtaW4tbWVkaWEgZmlsZXMgY29ycmVjdGx5IGluIHRoZSBkZXZlbG9wbWVudCBlbnZpcm9u
bWVudCwgdGhpcyBpcyBob3cgZGphbmdvIHdvdWxkIGRvIGl0LCB3aGVuIHRoZSBkZXYtc2VydmVy
IGlzIHVzZWQuUwAAAAZwYXJzZXJTAAAABGh0bWw=
Amazon byteflow: Дебаг Джангиhttp://piranha.org.ua/blog/2007/12/16/django-debug/2007-12-15T22:32:49Znoyes0[...] после одной отличной новости можно значительно облегчить себе [...][...] после одной отличной новости можно значительно облегчить себе [...]SQAAAAJTAAAABGJvZHlSUwAAAH9bLi4uXSDQv9C+0YHQu9C1INC+0LTQvdC+0Lkg0L7RgtC70LjR
h9C90L7QuSDQvdC+0LLQvtGB0YLQuCDQvNC+0LbQvdC+INC30L3QsNGH0LjRgtC10LvRjNC90L4g
0L7QsdC70LXQs9GH0LjRgtGMINGB0LXQsdC1IFsuLi5dTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Nickfignya@gmail.com2007-12-19T16:40:25Znono0only this modified version worked for me in Windows:
<pre>#!/usr/bin/env python
import os, sys
from os.path import abspath, dirname
from werkzeug import run_simple, DebuggedApplication
from django.views import debug
from django.core.handlers.wsgi import WSGIHandler
def null_technical_500_response(request, exc_type, exc_value, tb):
raise exc_type, exc_value, tb
debug.technical_500_response = null_technical_500_response
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
path = os.path.abspath(dirname(dirname(abspath(__file__))))
sys.path.append(path)
if __name__ == '__main__':
run_simple('localhost', 8080, DebuggedApplication(WSGIHandler(), True), True)</pre>only this modified version worked for me in Windows:
<pre>#!/usr/bin/env python
import os, sys
from os.path import abspath, dirname
from werkzeug import run_simple, DebuggedApplication
from django.views import debug
from django.core.handlers.wsgi import WSGIHandler
def null_technical_500_response(request, exc_type, exc_value, tb):
raise exc_type, exc_value, tb
debug.technical_500_response = null_technical_500_response
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
path = os.path.abspath(dirname(dirname(abspath(__file__))))
sys.path.append(path)
if __name__ == '__main__':
run_simple('localhost', 8080, DebuggedApplication(WSGIHandler(), True), True)</pre>SQAAAAJTAAAABGJvZHlSUwAAADZvbmx5IHRoaXMgbW9kaWZpZWQgdmVyc2lvbiB3b3JrZWQgZm9y
IG1lIGluIFdpbmRvd3M6CgpMAAFFUwAAAANwcmVMAABNAABTAAACZSMhL3Vzci9iaW4vZW52IHB5
dGhvbgppbXBvcnQgb3MsIHN5cwpmcm9tIG9zLnBhdGggaW1wb3J0IGFic3BhdGgsIGRpcm5hbWUK
CmZyb20gd2Vya3pldWcgaW1wb3J0IHJ1bl9zaW1wbGUsIERlYnVnZ2VkQXBwbGljYXRpb24KZnJv
bSBkamFuZ28udmlld3MgaW1wb3J0IGRlYnVnCmZyb20gZGphbmdvLmNvcmUuaGFuZGxlcnMud3Nn
aSBpbXBvcnQgV1NHSUhhbmRsZXIKCmRlZiBudWxsX3RlY2huaWNhbF81MDBfcmVzcG9uc2UocmVx
dWVzdCwgZXhjX3R5cGUsIGV4Y192YWx1ZSwgdGIpOgogICAgcmFpc2UgZXhjX3R5cGUsIGV4Y192
YWx1ZSwgdGIKZGVidWcudGVjaG5pY2FsXzUwMF9yZXNwb25zZSA9IG51bGxfdGVjaG5pY2FsXzUw
MF9yZXNwb25zZQoKb3MuZW52aXJvblsnREpBTkdPX1NFVFRJTkdTX01PRFVMRSddID0gJ3NldHRp
bmdzJwoKcGF0aCA9IG9zLnBhdGguYWJzcGF0aChkaXJuYW1lKGRpcm5hbWUoYWJzcGF0aChfX2Zp
bGVfXykpKSkKc3lzLnBhdGguYXBwZW5kKHBhdGgpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18n
OgogICAgcnVuX3NpbXBsZSgnbG9jYWxob3N0JywgODA4MCwgRGVidWdnZWRBcHBsaWNhdGlvbihX
U0dJSGFuZGxlcigpLCBUcnVlKSwgVHJ1ZSlTAAAAAFMAAAAGcGFyc2VyUwAAAARodG1s
We don’t need namespaces…http://lucumr.pocoo.org/cogitations/2007/12/10/we-dont-need-namespaces%e2%80%a6/2007-12-10T14:07:17Z2007-12-10T14:07:17ZArmin Ronacherwe-dont-need-namespaces%e2%80%a6yesyes2…because we use prefixes:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="cp"><?php</span>
<span class="k">class</span> <span class="nc">Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive</span>
<span class="k">extends</span> <span class="nx">Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(php)><?php
class Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive
extends Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum<PYGMENTS_RAW -->
Found in the Zend framework :-)…because we use prefixes:
Found in the Zend framework :-)SQAAAANTAAAABGJvZHlSUwAAAD7igKZiZWNhdXNlIHdlIHVzZSBwcmVmaXhlczoKCgoKRm91bmQg
aW4gdGhlIFplbmQgZnJhbWV3b3JrIDotKUwAAFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRy
b1JTAAAAAEwAAA==
Alex Jonesalex@weej.comhttp://alex.weej.com/2007-12-10T18:06:13Znono0Just count yourself lucky there aren't any FactoryFactoryFactoryFactory's in there.Just count yourself lucky there aren't any FactoryFactoryFactoryFactory's in there.SQAAAAJTAAAABGJvZHlSUwAAAFNKdXN0IGNvdW50IHlvdXJzZWxmIGx1Y2t5IHRoZXJlIGFyZW4n
dCBhbnkgRmFjdG9yeUZhY3RvcnlGYWN0b3J5RmFjdG9yeSdzIGluIHRoZXJlLkwAAFMAAAAGcGFy
c2VyUwAAAARodG1s
EvildeadEvildead@gmail.com2007-12-10T18:22:20Znono0OMG, I would rather die than doing this.OMG, I would rather die than doing this.SQAAAAJTAAAABGJvZHlSUwAAAChPTUcsIEkgd291bGQgcmF0aGVyIGRpZSB0aGFuIGRvaW5nIHRo
aXMuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Adeel Khanpyninja@gmail.comhttp://umbc.edu/~adeel2/2007-12-10T18:49:38Znono0The Zend framework is horrible.The Zend framework is horrible.SQAAAAJTAAAABGJvZHlSUwAAAB9UaGUgWmVuZCBmcmFtZXdvcmsgaXMgaG9ycmlibGUuTAAAUwAA
AAZwYXJzZXJTAAAABGh0bWw=
Brianbrian.cassidy@gmail.com2007-12-10T20:42:39Znono0Oddly enough, today i saw a post linking to this: http://news.php.net/php.internals/33694 (RFC: Dropping Namespace)Oddly enough, today i saw a post linking to this: http://news.php.net/php.internals/33694 (RFC: Dropping Namespace)SQAAAAJTAAAABGJvZHlSUwAAAHNPZGRseSBlbm91Z2gsIHRvZGF5IGkgc2F3IGEgcG9zdCBsaW5r
aW5nIHRvIHRoaXM6IGh0dHA6Ly9uZXdzLnBocC5uZXQvcGhwLmludGVybmFscy8zMzY5NCAoUkZD
OiBEcm9wcGluZyBOYW1lc3BhY2UpTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Werkzeug 0.1 Releasedhttp://lucumr.pocoo.org/cogitations/2007/12/09/werkzeug-01-released/2007-12-09T18:58:22Z2007-12-09T18:58:22ZArmin Ronacherwerkzeug-01-releasedyesyes2Finally (sorry for the long delay) <a href="http://werkzeug.pocoo.org/">Werkzeug</a> 0.1 is out. Here parts of the current featurelist:
<ul>
<li>Provides Request and Response objects for WSGI</li>
<li>Handles file uploads by using temporary files for incoming data.</li>
<li>Provides a middleware for static data for development purposes</li>
<li>Tiny wrapper around wsgiref for easier development (autoreload, optional
multithreaded enviornment)</li>
<li>Unicode aware data processing. Just use unicode everywhere, werkzeug
handles that for you.</li>
<li>Mini template engine. Sometimes string formattings just are not enough
and real template engines are too big for that tiny task.</li>
<li>Context locals. Don't pass request/user/database connections and
other objects around. Put them on a global context local object and
werkzeug makes sure that everyting is cleaned up end delivered well.</li>
<li>Test utilities. Create fake WSGI environments and requests to test
your application.</li>
<li>Interactive debugger. Application dies with an error? Hook the debugger
in and inspect every frame.</li>
</ul>
Here a screenshot of the debugger in action:
<img class="standalone" src="http://werkzeug.pocoo.org/static/debugger.png" alt="screenshot of the debugger">
Small werkzeug example applications can be found <a href="http://dev.pocoo.org/projects/werkzeug/browser/examples">in the trac</a>. In the werkzeug.contrib package are also some pieces of code that can be useful for django developers. For example there is a stream wrapper that limits incoming form data to a given number of bytes. This is useful for django because django streams into the memory and not to the file system.
Have fun and report bugs / feature wishes in the trac :-) Get it while it's hot from the <a href="http://cheeseshop.python.org/pypi/Werkzeug/0.1">Cheeseshop</a>.Finally (sorry for the long delay) <a href="http://werkzeug.pocoo.org/">Werkzeug</a> 0.1 is out. Here parts of the current featurelist:
<ul>
<li>Provides Request and Response objects for WSGI</li>
<li>Handles file uploads by using temporary files for incoming data.</li>
<li>Provides a middleware for static data for development purposes</li>
<li>Tiny wrapper around wsgiref for easier development (autoreload, optional
multithreaded enviornment)</li>
<li>Unicode aware data processing. Just use unicode everywhere, werkzeug
handles that for you.</li>
<li>Mini template engine. Sometimes string formattings just are not enough
and real template engines are too big for that tiny task.</li>
<li>Context locals. Don't pass request/user/database connections and
other objects around. Put them on a global context local object and
werkzeug makes sure that everyting is cleaned up end delivered well.</li>
<li>Test utilities. Create fake WSGI environments and requests to test
your application.</li>
<li>Interactive debugger. Application dies with an error? Hook the debugger
in and inspect every frame.</li>
</ul>
Here a screenshot of the debugger in action:
<img src="http://werkzeug.pocoo.org/static/debugger.png" alt="screenshot of the debugger" class="standalone">
Small werkzeug example applications can be found <a href="http://dev.pocoo.org/projects/werkzeug/browser/examples">in the trac</a>. In the werkzeug.contrib package are also some pieces of code that can be useful for django developers. For example there is a stream wrapper that limits incoming form data to a given number of bytes. This is useful for django because django streams into the memory and not to the file system.
Have fun and report bugs / feature wishes in the trac :-) Get it while it's hot from the <a href="http://cheeseshop.python.org/pypi/Werkzeug/0.1">Cheeseshop</a>.SQAAAANTAAAABGJvZHlSUwAAACNGaW5hbGx5IChzb3JyeSBmb3IgdGhlIGxvbmcgZGVsYXkpIEwA
BUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAGmh0dHA6Ly93ZXJremV1Zy5wb2Nvby5vcmcvUwAA
AAhXZXJremV1Z1MAAAA0IDAuMSBpcyBvdXQuIEhlcmUgcGFydHMgb2YgdGhlIGN1cnJlbnQgZmVh
dHVyZWxpc3Q6CkVTAAAAAnVsTAAJRVMAAAACbGlMAABNAABTAAAALlByb3ZpZGVzIFJlcXVlc3Qg
YW5kIFJlc3BvbnNlIG9iamVjdHMgZm9yIFdTR0lTAAAABQogICAgRVMAAAACbGlMAABNAABTAAAA
QEhhbmRsZXMgZmlsZSB1cGxvYWRzIGJ5IHVzaW5nIHRlbXBvcmFyeSBmaWxlcyBmb3IgaW5jb21p
bmcgZGF0YS5TAAAABgoKICAgIEVTAAAAAmxpTAAATQAAUwAAAD5Qcm92aWRlcyBhIG1pZGRsZXdh
cmUgZm9yIHN0YXRpYyBkYXRhIGZvciBkZXZlbG9wbWVudCBwdXJwb3Nlc1MAAAAFCiAgICBFUwAA
AAJsaUwAAE0AAFMAAABrVGlueSB3cmFwcGVyIGFyb3VuZCB3c2dpcmVmIGZvciBlYXNpZXIgZGV2
ZWxvcG1lbnQgKGF1dG9yZWxvYWQsIG9wdGlvbmFsCiAgICAgICAgbXVsdGl0aHJlYWRlZCBlbnZp
b3JubWVudClTAAAABQogICAgRVMAAAACbGlMAABNAABTAAAAYlVuaWNvZGUgYXdhcmUgZGF0YSBw
cm9jZXNzaW5nLiBKdXN0IHVzZSB1bmljb2RlIGV2ZXJ5d2hlcmUsIHdlcmt6ZXVnCiAgICAgICAg
aGFuZGxlcyB0aGF0IGZvciB5b3UuUwAAAAUKICAgIEVTAAAAAmxpTAAATQAAUwAAAIhNaW5pIHRl
bXBsYXRlIGVuZ2luZS4gU29tZXRpbWVzIHN0cmluZyBmb3JtYXR0aW5ncyBqdXN0IGFyZSBub3Qg
ZW5vdWdoCiAgICAgICAgYW5kIHJlYWwgdGVtcGxhdGUgZW5naW5lcyBhcmUgdG9vIGJpZyBmb3Ig
dGhhdCB0aW55IHRhc2suUwAAAAUKICAgIEVTAAAAAmxpTAAATQAAUwAAANtDb250ZXh0IGxvY2Fs
cy4gIERvbid0IHBhc3MgcmVxdWVzdC91c2VyL2RhdGFiYXNlIGNvbm5lY3Rpb25zIGFuZAogICAg
ICAgIG90aGVyIG9iamVjdHMgYXJvdW5kLiAgUHV0IHRoZW0gb24gYSBnbG9iYWwgY29udGV4dCBs
b2NhbCBvYmplY3QgYW5kCiAgICAgICAgd2Vya3pldWcgbWFrZXMgc3VyZSB0aGF0IGV2ZXJ5dGlu
ZyBpcyBjbGVhbmVkIHVwIGVuZCBkZWxpdmVyZWQgd2VsbC5TAAAABQogICAgRVMAAAACbGlMAABN
AABTAAAAXVRlc3QgdXRpbGl0aWVzLiAgQ3JlYXRlIGZha2UgV1NHSSBlbnZpcm9ubWVudHMgYW5k
IHJlcXVlc3RzIHRvIHRlc3QKICAgICAgICB5b3VyIGFwcGxpY2F0aW9uLlMAAAAFCiAgICBFUwAA
AAJsaUwAAE0AAFMAAABsSW50ZXJhY3RpdmUgZGVidWdnZXIuICBBcHBsaWNhdGlvbiBkaWVzIHdp
dGggYW4gZXJyb3I/IEhvb2sgdGhlIGRlYnVnZ2VyCiAgICAgICAgaW4gYW5kIGluc3BlY3QgZXZl
cnkgZnJhbWUuUwAAAAEKTQAAUwAAAAUKICAgIFMAAAAvCgpIZXJlIGEgc2NyZWVuc2hvdCBvZiB0
aGUgZGVidWdnZXIgaW4gYWN0aW9uOgpFUwAAAANpbWdMAABNAANTAAAAA3NyY1MAAAAtaHR0cDov
L3dlcmt6ZXVnLnBvY29vLm9yZy9zdGF0aWMvZGVidWdnZXIucG5nUwAAAANhbHRTAAAAGnNjcmVl
bnNob3Qgb2YgdGhlIGRlYnVnZ2VyUwAAAAVjbGFzc1MAAAAKc3RhbmRhbG9uZVMAAAAAUwAAADMK
ClNtYWxsIHdlcmt6ZXVnIGV4YW1wbGUgYXBwbGljYXRpb25zIGNhbiBiZSBmb3VuZCBFUwAAAAFh
TAAATQABUwAAAARocmVmUwAAADdodHRwOi8vZGV2LnBvY29vLm9yZy9wcm9qZWN0cy93ZXJremV1
Zy9icm93c2VyL2V4YW1wbGVzUwAAAAtpbiB0aGUgdHJhY1MAAAGCLiBJbiB0aGUgd2Vya3pldWcu
Y29udHJpYiBwYWNrYWdlIGFyZSBhbHNvIHNvbWUgcGllY2VzIG9mIGNvZGUgdGhhdCBjYW4gYmUg
dXNlZnVsIGZvciBkamFuZ28gZGV2ZWxvcGVycy4gRm9yIGV4YW1wbGUgdGhlcmUgaXMgYSBzdHJl
YW0gd3JhcHBlciB0aGF0IGxpbWl0cyBpbmNvbWluZyBmb3JtIGRhdGEgdG8gYSBnaXZlbiBudW1i
ZXIgb2YgYnl0ZXMuICBUaGlzIGlzIHVzZWZ1bCBmb3IgZGphbmdvIGJlY2F1c2UgZGphbmdvIHN0
cmVhbXMgaW50byB0aGUgbWVtb3J5IGFuZCBub3QgdG8gdGhlIGZpbGUgc3lzdGVtLgoKSGF2ZSBm
dW4gYW5kIHJlcG9ydCBidWdzIC8gZmVhdHVyZSB3aXNoZXMgaW4gdGhlIHRyYWMgOi0pIEdldCBp
dCB3aGlsZSBpdCdzIGhvdCBmcm9tIHRoZSBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAC5odHRw
Oi8vY2hlZXNlc2hvcC5weXRob24ub3JnL3B5cGkvV2Vya3pldWcvMC4xUwAAAApDaGVlc2VzaG9w
UwAAAAEuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Rafaelrafaelw@gmx.net2007-12-09T19:03:38Znono0Congratulations!
This is a really nice lib, thanks for it.
I'm using it with pleasure.Congratulations!
This is a really nice lib, thanks for it.
I'm using it with pleasure.SQAAAAJTAAAABGJvZHlSUwAAAFdDb25ncmF0dWxhdGlvbnMhClRoaXMgaXMgYSByZWFsbHkgbmlj
ZSBsaWIsIHRoYW5rcyBmb3IgaXQuCgpJJ20gdXNpbmcgaXQgd2l0aCBwbGVhc3VyZS5MAABTAAAA
BnBhcnNlclMAAAAEaHRtbA==
Eric Florenzanofloguy@gmail.comhttp://www.eflorenzano.com/2007-12-09T23:12:51Znono0We really could use this web-based console debugger as an option on Django's debug pages. How difficult was it for you to implement?We really could use this web-based console debugger as an option on Django's debug pages. How difficult was it for you to implement?SQAAAAJTAAAABGJvZHlSUwAAAIVXZSByZWFsbHkgY291bGQgdXNlIHRoaXMgd2ViLWJhc2VkIGNv
bnNvbGUgZGVidWdnZXIgYXMgYW4gb3B0aW9uIG9uIERqYW5nbydzIGRlYnVnIHBhZ2VzLiAgSG93
IGRpZmZpY3VsdCB3YXMgaXQgZm9yIHlvdSB0byBpbXBsZW1lbnQ/TAAAUwAAAAZwYXJzZXJTAAAA
BGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-10T07:31:48Znono0There are ways to get that debugger running in django but it's not that easy because django keeps on catching exceptions in the core. That means they are never forwarded to the WSGI layer where the werkzeug debugger operates.
If one adds a way to disable the internal debug view and hook in WSGI middlewares, adding werkzeug.debug should be a simple task.
Regards,
ArminThere are ways to get that debugger running in django but it's not that easy because django keeps on catching exceptions in the core. That means they are never forwarded to the WSGI layer where the werkzeug debugger operates.
If one adds a way to disable the internal debug view and hook in WSGI middlewares, adding werkzeug.debug should be a simple task.
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAXVUaGVyZSBhcmUgd2F5cyB0byBnZXQgdGhhdCBkZWJ1Z2dlciBy
dW5uaW5nIGluIGRqYW5nbyBidXQgaXQncyBub3QgdGhhdCBlYXN5IGJlY2F1c2UgZGphbmdvIGtl
ZXBzIG9uIGNhdGNoaW5nIGV4Y2VwdGlvbnMgaW4gdGhlIGNvcmUuICBUaGF0IG1lYW5zIHRoZXkg
YXJlIG5ldmVyIGZvcndhcmRlZCB0byB0aGUgV1NHSSBsYXllciB3aGVyZSB0aGUgd2Vya3pldWcg
ZGVidWdnZXIgb3BlcmF0ZXMuCgpJZiBvbmUgYWRkcyBhIHdheSB0byBkaXNhYmxlIHRoZSBpbnRl
cm5hbCBkZWJ1ZyB2aWV3IGFuZCBob29rIGluIFdTR0kgbWlkZGxld2FyZXMsIGFkZGluZyB3ZXJr
emV1Zy5kZWJ1ZyBzaG91bGQgYmUgYSBzaW1wbGUgdGFzay4KClJlZ2FyZHMsCkFybWluTAAAUwAA
AAZwYXJzZXJTAAAABGh0bWw=
Dannadako@gmail.com2007-12-10T07:53:42Znono0Your debugger is very nice. It even looks nicier that Paste's one. Do you have plans on releasing it as a separate package so every WSGI applications developers could use it? It would be great to have such a package. For example, we currently use Paste's evalexception debugger in our Zope3 development, but werkzeug's one looks so great, I'm going to try it with Zope3... :)Your debugger is very nice. It even looks nicier that Paste's one. Do you have plans on releasing it as a separate package so every WSGI applications developers could use it? It would be great to have such a package. For example, we currently use Paste's evalexception debugger in our Zope3 development, but werkzeug's one looks so great, I'm going to try it with Zope3... :)SQAAAAJTAAAABGJvZHlSUwAAAXdZb3VyIGRlYnVnZ2VyIGlzIHZlcnkgbmljZS4gSXQgZXZlbiBs
b29rcyBuaWNpZXIgdGhhdCBQYXN0ZSdzIG9uZS4gRG8geW91IGhhdmUgcGxhbnMgb24gcmVsZWFz
aW5nIGl0IGFzIGEgc2VwYXJhdGUgcGFja2FnZSBzbyBldmVyeSBXU0dJIGFwcGxpY2F0aW9ucyBk
ZXZlbG9wZXJzIGNvdWxkIHVzZSBpdD8gSXQgd291bGQgYmUgZ3JlYXQgdG8gaGF2ZSBzdWNoIGEg
cGFja2FnZS4gRm9yIGV4YW1wbGUsIHdlIGN1cnJlbnRseSB1c2UgUGFzdGUncyBldmFsZXhjZXB0
aW9uIGRlYnVnZ2VyIGluIG91ciBab3BlMyBkZXZlbG9wbWVudCwgYnV0IHdlcmt6ZXVnJ3Mgb25l
IGxvb2tzIHNvIGdyZWF0LCBJJ20gZ29pbmcgdG8gdHJ5IGl0IHdpdGggWm9wZTMuLi4gOilMAABT
AAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-10T08:11:22Znono0I already did that. That package is called werkzeug ;-) Seriously. Werkzeug plays very well with other packages and it's a very small package, about 3000 lines in total. So no real need to further unbundle the debugger.
Regards,
ArminI already did that. That package is called werkzeug ;-) Seriously. Werkzeug plays very well with other packages and it's a very small package, about 3000 lines in total. So no real need to further unbundle the debugger.
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAOtJIGFscmVhZHkgZGlkIHRoYXQuIFRoYXQgcGFja2FnZSBpcyBj
YWxsZWQgd2Vya3pldWcgOy0pIFNlcmlvdXNseS4gV2Vya3pldWcgcGxheXMgdmVyeSB3ZWxsIHdp
dGggb3RoZXIgcGFja2FnZXMgYW5kIGl0J3MgYSB2ZXJ5IHNtYWxsIHBhY2thZ2UsIGFib3V0IDMw
MDAgbGluZXMgaW4gdG90YWwuIFNvIG5vIHJlYWwgbmVlZCB0byBmdXJ0aGVyIHVuYnVuZGxlIHRo
ZSBkZWJ1Z2dlci4KClJlZ2FyZHMsCkFybWluTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Ali Afsharaafshar@gmail.comhttp://pida.co.uk/2007-12-10T13:57:23Znono0Excellent work! I have been using Werkzeug for a good while now, and I can strongly recommend it to any web developer.Excellent work! I have been using Werkzeug for a good while now, and I can strongly recommend it to any web developer.SQAAAAJTAAAABGJvZHlSUwAAAHZFeGNlbGxlbnQgd29yayEgSSBoYXZlIGJlZW4gdXNpbmcgV2Vy
a3pldWcgZm9yIGEgZ29vZCB3aGlsZSBub3csIGFuZCBJIGNhbiBzdHJvbmdseSByZWNvbW1lbmQg
aXQgdG8gYW55IHdlYiBkZXZlbG9wZXIuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Ian Bickingianb@colorstudy.comhttp://blog.ianbicking.org2007-12-10T18:39:43Znono0Werkzeug always leaves me a little... baffled. The feature list is so closely matched to Paste and its related libraries.
For instance:
request/response: paste.wsgiwrappers, and now webob
file uploads: well, the cgi module automatically does that
static files: paste.fileapp and paste.urlparser.StaticURLParser
wsgiref wrapper: paste.httpserver and paster serve
unicode: paste.wsgiwrappers/webob
mini template engine: tempita
context locals: paste.registry
test utilities: paste.fixture.TestApp and now webtest
interactive debugger: paste.evalexception and now weberror
I don't particularly mind this duplication, but I'm confused by it. Why reimplement everything? (And you aren't even the only one, Luke Arno's libraries have the same pattern of reimplementation.)Werkzeug always leaves me a little... baffled. The feature list is so closely matched to Paste and its related libraries.
For instance:
request/response: paste.wsgiwrappers, and now webob
file uploads: well, the cgi module automatically does that
static files: paste.fileapp and paste.urlparser.StaticURLParser
wsgiref wrapper: paste.httpserver and paster serve
unicode: paste.wsgiwrappers/webob
mini template engine: tempita
context locals: paste.registry
test utilities: paste.fixture.TestApp and now webtest
interactive debugger: paste.evalexception and now weberror
I don't particularly mind this duplication, but I'm confused by it. Why reimplement everything? (And you aren't even the only one, Luke Arno's libraries have the same pattern of reimplementation.)SQAAAAJTAAAABGJvZHlSUwAAAwVXZXJremV1ZyBhbHdheXMgbGVhdmVzIG1lIGEgbGl0dGxlLi4u
IGJhZmZsZWQuICBUaGUgZmVhdHVyZSBsaXN0IGlzIHNvIGNsb3NlbHkgbWF0Y2hlZCB0byBQYXN0
ZSBhbmQgaXRzIHJlbGF0ZWQgbGlicmFyaWVzLgoKRm9yIGluc3RhbmNlOiAKCnJlcXVlc3QvcmVz
cG9uc2U6IHBhc3RlLndzZ2l3cmFwcGVycywgYW5kIG5vdyB3ZWJvYgpmaWxlIHVwbG9hZHM6IHdl
bGwsIHRoZSBjZ2kgbW9kdWxlIGF1dG9tYXRpY2FsbHkgZG9lcyB0aGF0CnN0YXRpYyBmaWxlczog
cGFzdGUuZmlsZWFwcCBhbmQgcGFzdGUudXJscGFyc2VyLlN0YXRpY1VSTFBhcnNlcgp3c2dpcmVm
IHdyYXBwZXI6IHBhc3RlLmh0dHBzZXJ2ZXIgYW5kIHBhc3RlciBzZXJ2ZQp1bmljb2RlOiBwYXN0
ZS53c2dpd3JhcHBlcnMvd2Vib2IKbWluaSB0ZW1wbGF0ZSBlbmdpbmU6IHRlbXBpdGEKY29udGV4
dCBsb2NhbHM6IHBhc3RlLnJlZ2lzdHJ5CnRlc3QgdXRpbGl0aWVzOiBwYXN0ZS5maXh0dXJlLlRl
c3RBcHAgYW5kIG5vdyB3ZWJ0ZXN0CmludGVyYWN0aXZlIGRlYnVnZ2VyOiBwYXN0ZS5ldmFsZXhj
ZXB0aW9uIGFuZCBub3cgd2ViZXJyb3IKCkkgZG9uJ3QgcGFydGljdWxhcmx5IG1pbmQgdGhpcyBk
dXBsaWNhdGlvbiwgYnV0IEknbSBjb25mdXNlZCBieSBpdC4gIFdoeSByZWltcGxlbWVudCBldmVy
eXRoaW5nPyAgKEFuZCB5b3UgYXJlbid0IGV2ZW4gdGhlIG9ubHkgb25lLCBMdWtlIEFybm8ncyBs
aWJyYXJpZXMgaGF2ZSB0aGUgc2FtZSBwYXR0ZXJuIG9mIHJlaW1wbGVtZW50YXRpb24uKUwAAFMA
AAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-10T19:10:24Znono0Ian: Well. Unfortunately some project evolved next to each other. Colubrid started long ago and some parts of it are either bad implemented and/or silly. However it was still one of the smallest libraries so I thought about uncoupling the request and response objects, the debugger and some other functions there. I also wanted a slightly improved version of string.Template so that was that template engine thing.
However I missed for some time that you started a very similar thing namely webob and tempita. I guess if those projects would have existed for a little longer some parts of werkzeug would probably not exist as such.
One of the reasons why I never really felt that happy with paste was that it brings a lot of stuff I personally don't want to use and lacks things I need every day. There are exceptions for every status code, how many of those do you actually use? There are request objects but the file handling feels a lot like the cgi module thanks to the FieldStorage. Long time ago I had big problems with unicode because paste was lacking unicode support everywhere. Paste comes with interesting stuff but most of them I don't use (like paste deploy, SCGI, paste config, transactions) which make 20.000 lines of code and lack things I would actually use (like URL routing, the Werkzeug debugger [yes, there is evalexception, however my sense for aesthetics and usability prefers the Werkzeug one, sorry for that], a simple way to generate custom management scripts without installing PasteScript).
At the end of the day Werkzeug is a very small library bundling everything you need to bootstrap your own WSGI application in no time and I'm very happy with the feature/lines of code ratio. And even if I was the only person using Werkzeug the work of the last half year was worth the effort. And unlike Colubrid it's predecessor you can mix it with any other library out there which makes it a good addition to existing libraries.
Hope I could defend my POV :-)
Regards,
ArminIan: Well. Unfortunately some project evolved next to each other. Colubrid started long ago and some parts of it are either bad implemented and/or silly. However it was still one of the smallest libraries so I thought about uncoupling the request and response objects, the debugger and some other functions there. I also wanted a slightly improved version of string.Template so that was that template engine thing.
However I missed for some time that you started a very similar thing namely webob and tempita. I guess if those projects would have existed for a little longer some parts of werkzeug would probably not exist as such.
One of the reasons why I never really felt that happy with paste was that it brings a lot of stuff I personally don't want to use and lacks things I need every day. There are exceptions for every status code, how many of those do you actually use? There are request objects but the file handling feels a lot like the cgi module thanks to the FieldStorage. Long time ago I had big problems with unicode because paste was lacking unicode support everywhere. Paste comes with interesting stuff but most of them I don't use (like paste deploy, SCGI, paste config, transactions) which make 20.000 lines of code and lack things I would actually use (like URL routing, the Werkzeug debugger [yes, there is evalexception, however my sense for aesthetics and usability prefers the Werkzeug one, sorry for that], a simple way to generate custom management scripts without installing PasteScript).
At the end of the day Werkzeug is a very small library bundling everything you need to bootstrap your own WSGI application in no time and I'm very happy with the feature/lines of code ratio. And even if I was the only person using Werkzeug the work of the last half year was worth the effort. And unlike Colubrid it's predecessor you can mix it with any other library out there which makes it a good addition to existing libraries.
Hope I could defend my POV :-)
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAB9FJYW46IFdlbGwuIFVuZm9ydHVuYXRlbHkgc29tZSBwcm9qZWN0
IGV2b2x2ZWQgbmV4dCB0byBlYWNoIG90aGVyLiBDb2x1YnJpZCBzdGFydGVkIGxvbmcgYWdvIGFu
ZCBzb21lIHBhcnRzIG9mIGl0IGFyZSBlaXRoZXIgYmFkIGltcGxlbWVudGVkIGFuZC9vciBzaWxs
eS4gSG93ZXZlciBpdCB3YXMgc3RpbGwgb25lIG9mIHRoZSBzbWFsbGVzdCBsaWJyYXJpZXMgc28g
SSB0aG91Z2h0IGFib3V0IHVuY291cGxpbmcgdGhlIHJlcXVlc3QgYW5kIHJlc3BvbnNlIG9iamVj
dHMsIHRoZSBkZWJ1Z2dlciBhbmQgc29tZSBvdGhlciBmdW5jdGlvbnMgdGhlcmUuIEkgYWxzbyB3
YW50ZWQgYSBzbGlnaHRseSBpbXByb3ZlZCB2ZXJzaW9uIG9mIHN0cmluZy5UZW1wbGF0ZSBzbyB0
aGF0IHdhcyB0aGF0IHRlbXBsYXRlIGVuZ2luZSB0aGluZy4KCkhvd2V2ZXIgSSBtaXNzZWQgZm9y
IHNvbWUgdGltZSB0aGF0IHlvdSBzdGFydGVkIGEgdmVyeSBzaW1pbGFyIHRoaW5nIG5hbWVseSB3
ZWJvYiBhbmQgdGVtcGl0YS4gSSBndWVzcyBpZiB0aG9zZSBwcm9qZWN0cyB3b3VsZCBoYXZlIGV4
aXN0ZWQgZm9yIGEgbGl0dGxlIGxvbmdlciBzb21lIHBhcnRzIG9mIHdlcmt6ZXVnIHdvdWxkIHBy
b2JhYmx5IG5vdCBleGlzdCBhcyBzdWNoLgoKT25lIG9mIHRoZSByZWFzb25zIHdoeSBJIG5ldmVy
IHJlYWxseSBmZWx0IHRoYXQgaGFwcHkgd2l0aCBwYXN0ZSB3YXMgdGhhdCBpdCBicmluZ3MgYSBs
b3Qgb2Ygc3R1ZmYgSSBwZXJzb25hbGx5IGRvbid0IHdhbnQgdG8gdXNlIGFuZCBsYWNrcyB0aGlu
Z3MgSSBuZWVkIGV2ZXJ5IGRheS4gVGhlcmUgYXJlIGV4Y2VwdGlvbnMgZm9yIGV2ZXJ5IHN0YXR1
cyBjb2RlLCBob3cgbWFueSBvZiB0aG9zZSBkbyB5b3UgYWN0dWFsbHkgdXNlPyBUaGVyZSBhcmUg
cmVxdWVzdCBvYmplY3RzIGJ1dCB0aGUgZmlsZSBoYW5kbGluZyBmZWVscyBhIGxvdCBsaWtlIHRo
ZSBjZ2kgbW9kdWxlIHRoYW5rcyB0byB0aGUgRmllbGRTdG9yYWdlLiBMb25nIHRpbWUgYWdvIEkg
aGFkIGJpZyBwcm9ibGVtcyB3aXRoIHVuaWNvZGUgYmVjYXVzZSBwYXN0ZSB3YXMgbGFja2luZyB1
bmljb2RlIHN1cHBvcnQgZXZlcnl3aGVyZS4gUGFzdGUgY29tZXMgd2l0aCBpbnRlcmVzdGluZyBz
dHVmZiBidXQgbW9zdCBvZiB0aGVtIEkgZG9uJ3QgdXNlIChsaWtlIHBhc3RlIGRlcGxveSwgU0NH
SSwgcGFzdGUgY29uZmlnLCB0cmFuc2FjdGlvbnMpIHdoaWNoIG1ha2UgMjAuMDAwIGxpbmVzIG9m
IGNvZGUgYW5kIGxhY2sgdGhpbmdzIEkgd291bGQgYWN0dWFsbHkgdXNlIChsaWtlIFVSTCByb3V0
aW5nLCB0aGUgV2Vya3pldWcgZGVidWdnZXIgW3llcywgdGhlcmUgaXMgZXZhbGV4Y2VwdGlvbiwg
aG93ZXZlciBteSBzZW5zZSBmb3IgYWVzdGhldGljcyBhbmQgdXNhYmlsaXR5IHByZWZlcnMgdGhl
IFdlcmt6ZXVnIG9uZSwgc29ycnkgZm9yIHRoYXRdLCBhIHNpbXBsZSB3YXkgdG8gZ2VuZXJhdGUg
Y3VzdG9tIG1hbmFnZW1lbnQgc2NyaXB0cyB3aXRob3V0IGluc3RhbGxpbmcgUGFzdGVTY3JpcHQp
LgoKQXQgdGhlIGVuZCBvZiB0aGUgZGF5IFdlcmt6ZXVnIGlzIGEgdmVyeSBzbWFsbCBsaWJyYXJ5
IGJ1bmRsaW5nIGV2ZXJ5dGhpbmcgeW91IG5lZWQgdG8gYm9vdHN0cmFwIHlvdXIgb3duIFdTR0kg
YXBwbGljYXRpb24gaW4gbm8gdGltZSBhbmQgSSdtIHZlcnkgaGFwcHkgd2l0aCB0aGUgZmVhdHVy
ZS9saW5lcyBvZiBjb2RlIHJhdGlvLiBBbmQgZXZlbiBpZiBJIHdhcyB0aGUgb25seSBwZXJzb24g
dXNpbmcgV2Vya3pldWcgdGhlIHdvcmsgb2YgdGhlIGxhc3QgaGFsZiB5ZWFyIHdhcyB3b3J0aCB0
aGUgZWZmb3J0LiBBbmQgdW5saWtlIENvbHVicmlkIGl0J3MgcHJlZGVjZXNzb3IgeW91IGNhbiBt
aXggaXQgd2l0aCBhbnkgb3RoZXIgbGlicmFyeSBvdXQgdGhlcmUgd2hpY2ggbWFrZXMgaXQgYSBn
b29kIGFkZGl0aW9uIHRvIGV4aXN0aW5nIGxpYnJhcmllcy4KCkhvcGUgSSBjb3VsZCBkZWZlbmQg
bXkgUE9WIDotKQoKUmVnYXJkcywKQXJtaW5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2007-12-11T02:19:13Znono0FWIW, I personally feel that choice is good. I do not buy in to this argument that in Python there should always be only one way of doing things. If one were to pursue that ideal to the end then you will just end up with a monopolistic mono culture that would more than likely stagnate.
When different parties do implement similar things they are never really the same anyway, as each will incorporate different ideas as to how to go about solving the problem. This is important and any decent programmer would look at what other people are doing in the Python community and learn from others successes, as well as their failures. It is only through this cross fertilisation of ideas and learning from others that as a whole the quality and utility of code will move forward.
The other thing with competing solutions is that they usually have different trade offs, and as such, which one is better for a particular scenario will depend on the sort of application or environment it is used in. No one solution will always be the best at everything.
As such I feel that trying to suppress people from doing their own thing and trying to make them use a specific package is in the end run counter productive. If a solution is not good it will die its own death. If it is a good solution and for good reason, it could well become so successful as to replace all other existing solutions, even if only for a time.
So, empires will come and go, this will never change and we shouldn't try and stop it.FWIW, I personally feel that choice is good. I do not buy in to this argument that in Python there should always be only one way of doing things. If one were to pursue that ideal to the end then you will just end up with a monopolistic mono culture that would more than likely stagnate.
When different parties do implement similar things they are never really the same anyway, as each will incorporate different ideas as to how to go about solving the problem. This is important and any decent programmer would look at what other people are doing in the Python community and learn from others successes, as well as their failures. It is only through this cross fertilisation of ideas and learning from others that as a whole the quality and utility of code will move forward.
The other thing with competing solutions is that they usually have different trade offs, and as such, which one is better for a particular scenario will depend on the sort of application or environment it is used in. No one solution will always be the best at everything.
As such I feel that trying to suppress people from doing their own thing and trying to make them use a specific package is in the end run counter productive. If a solution is not good it will die its own death. If it is a good solution and for good reason, it could well become so successful as to replace all other existing solutions, even if only for a time.
So, empires will come and go, this will never change and we shouldn't try and stop it.SQAAAAJTAAAABGJvZHlSUwAABdtGV0lXLCBJIHBlcnNvbmFsbHkgZmVlbCB0aGF0IGNob2ljZSBp
cyBnb29kLiBJIGRvIG5vdCBidXkgaW4gdG8gdGhpcyBhcmd1bWVudCB0aGF0IGluIFB5dGhvbiB0
aGVyZSBzaG91bGQgYWx3YXlzIGJlIG9ubHkgb25lIHdheSBvZiBkb2luZyB0aGluZ3MuIElmIG9u
ZSB3ZXJlIHRvIHB1cnN1ZSB0aGF0IGlkZWFsIHRvIHRoZSBlbmQgdGhlbiB5b3Ugd2lsbCBqdXN0
IGVuZCB1cCB3aXRoIGEgbW9ub3BvbGlzdGljIG1vbm8gY3VsdHVyZSB0aGF0IHdvdWxkIG1vcmUg
dGhhbiBsaWtlbHkgc3RhZ25hdGUuCgpXaGVuIGRpZmZlcmVudCBwYXJ0aWVzIGRvIGltcGxlbWVu
dCBzaW1pbGFyIHRoaW5ncyB0aGV5IGFyZSBuZXZlciByZWFsbHkgdGhlIHNhbWUgYW55d2F5LCBh
cyBlYWNoIHdpbGwgaW5jb3Jwb3JhdGUgZGlmZmVyZW50IGlkZWFzIGFzIHRvIGhvdyB0byBnbyBh
Ym91dCBzb2x2aW5nIHRoZSBwcm9ibGVtLiBUaGlzIGlzIGltcG9ydGFudCBhbmQgYW55IGRlY2Vu
dCBwcm9ncmFtbWVyIHdvdWxkIGxvb2sgYXQgd2hhdCBvdGhlciBwZW9wbGUgYXJlIGRvaW5nIGlu
IHRoZSBQeXRob24gY29tbXVuaXR5IGFuZCBsZWFybiBmcm9tIG90aGVycyBzdWNjZXNzZXMsIGFz
IHdlbGwgYXMgdGhlaXIgZmFpbHVyZXMuIEl0IGlzIG9ubHkgdGhyb3VnaCB0aGlzIGNyb3NzIGZl
cnRpbGlzYXRpb24gb2YgaWRlYXMgYW5kIGxlYXJuaW5nIGZyb20gb3RoZXJzIHRoYXQgYXMgYSB3
aG9sZSB0aGUgcXVhbGl0eSBhbmQgdXRpbGl0eSBvZiBjb2RlIHdpbGwgbW92ZSBmb3J3YXJkLgoK
VGhlIG90aGVyIHRoaW5nIHdpdGggY29tcGV0aW5nIHNvbHV0aW9ucyBpcyB0aGF0IHRoZXkgdXN1
YWxseSBoYXZlIGRpZmZlcmVudCB0cmFkZSBvZmZzLCBhbmQgYXMgc3VjaCwgd2hpY2ggb25lIGlz
IGJldHRlciBmb3IgYSBwYXJ0aWN1bGFyIHNjZW5hcmlvIHdpbGwgZGVwZW5kIG9uIHRoZSBzb3J0
IG9mIGFwcGxpY2F0aW9uIG9yIGVudmlyb25tZW50IGl0IGlzIHVzZWQgaW4uIE5vIG9uZSBzb2x1
dGlvbiB3aWxsIGFsd2F5cyBiZSB0aGUgYmVzdCBhdCBldmVyeXRoaW5nLgoKQXMgc3VjaCBJIGZl
ZWwgdGhhdCB0cnlpbmcgdG8gc3VwcHJlc3MgcGVvcGxlIGZyb20gZG9pbmcgdGhlaXIgb3duIHRo
aW5nIGFuZCB0cnlpbmcgdG8gbWFrZSB0aGVtIHVzZSBhIHNwZWNpZmljIHBhY2thZ2UgaXMgaW4g
dGhlIGVuZCBydW4gY291bnRlciBwcm9kdWN0aXZlLiBJZiBhIHNvbHV0aW9uIGlzIG5vdCBnb29k
IGl0IHdpbGwgZGllIGl0cyBvd24gZGVhdGguIElmIGl0IGlzIGEgZ29vZCBzb2x1dGlvbiBhbmQg
Zm9yIGdvb2QgcmVhc29uLCBpdCBjb3VsZCB3ZWxsIGJlY29tZSBzbyBzdWNjZXNzZnVsIGFzIHRv
IHJlcGxhY2UgYWxsIG90aGVyIGV4aXN0aW5nIHNvbHV0aW9ucywgZXZlbiBpZiBvbmx5IGZvciBh
IHRpbWUuCgpTbywgZW1waXJlcyB3aWxsIGNvbWUgYW5kIGdvLCB0aGlzIHdpbGwgbmV2ZXIgY2hh
bmdlIGFuZCB3ZSBzaG91bGRuJ3QgdHJ5IGFuZCBzdG9wIGl0LkwAAFMAAAAGcGFyc2VyUwAAAARo
dG1s
Adam Hindsadam@b-ooks.co.ukhttp://www.b-ooks.co.uk2007-12-19T10:00:37Znono0Thank you for releasing this, have looking for something lightweight like this for a while.Thank you for releasing this, have looking for something lightweight like this for a while.SQAAAAJTAAAABGJvZHlSUwAAAFtUaGFuayB5b3UgZm9yIHJlbGVhc2luZyB0aGlzLCBoYXZlIGxv
b2tpbmcgZm9yIHNvbWV0aGluZyBsaWdodHdlaWdodCBsaWtlIHRoaXMgZm9yIGEgd2hpbGUuTAAA
UwAAAAZwYXJzZXJTAAAABGh0bWw=
In Nomine - The Lotus Land » Werkzeug 0.1 released - WSGI toolboxhttp://www.in-nomine.org/2007/12/21/werkzeug-01-released-wsgi-toolbox/2007-12-21T11:48:33Znoyes0[...] Ronacher has released Werkzeug 0.1 a little while ago. As the website for Werkzeug says: “Werkzeug is a collection of various utilities for WSGI [...][...] Ronacher has released Werkzeug 0.1 a little while ago. As the website for Werkzeug says: “Werkzeug is a collection of various utilities for WSGI [...]SQAAAAJTAAAABGJvZHlSUwAAAJ5bLi4uXSBSb25hY2hlciBoYXMgcmVsZWFzZWQgV2Vya3pldWcg
MC4xIGEgbGl0dGxlIHdoaWxlIGFnby4gQXMgdGhlIHdlYnNpdGUgZm9yIFdlcmt6ZXVnIHNheXM6
IOKAnFdlcmt6ZXVnIGlzIGEgY29sbGVjdGlvbiBvZiB2YXJpb3VzIHV0aWxpdGllcyBmb3IgV1NH
SSBbLi4uXUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
propanbutanpropanbutan@gmx.net2007-12-23T16:04:29Znono0Werkzeug is a gem, to the point, elegant, lean code. Luke Arno's libraries have a similar quality, the conventions are natural, the code is easy to follow, build upon and adapt to. Unlike Paste, where I first got turned off by StackedObjectProxy, after realizing it was just a glorious wrapper for threading.local. And while this generic header parser-composer is, well generic, I can deal with raw header strings just fine, hence I use Werkzeug. Thanks for sharing it.
PS. Is pocoo dead or just hibernating?Werkzeug is a gem, to the point, elegant, lean code. Luke Arno's libraries have a similar quality, the conventions are natural, the code is easy to follow, build upon and adapt to. Unlike Paste, where I first got turned off by StackedObjectProxy, after realizing it was just a glorious wrapper for threading.local. And while this generic header parser-composer is, well generic, I can deal with raw header strings just fine, hence I use Werkzeug. Thanks for sharing it.
PS. Is pocoo dead or just hibernating?SQAAAAJTAAAABGJvZHlSUwAAAfxXZXJremV1ZyBpcyBhIGdlbSwgdG8gdGhlIHBvaW50LCBlbGVn
YW50LCBsZWFuIGNvZGUuIEx1a2UgQXJubydzIGxpYnJhcmllcyBoYXZlIGEgc2ltaWxhciBxdWFs
aXR5LCB0aGUgY29udmVudGlvbnMgYXJlIG5hdHVyYWwsIHRoZSBjb2RlIGlzIGVhc3kgdG8gZm9s
bG93LCBidWlsZCB1cG9uIGFuZCBhZGFwdCB0by4gVW5saWtlIFBhc3RlLCB3aGVyZSBJIGZpcnN0
IGdvdCB0dXJuZWQgb2ZmIGJ5IFN0YWNrZWRPYmplY3RQcm94eSwgYWZ0ZXIgcmVhbGl6aW5nIGl0
IHdhcyBqdXN0IGEgZ2xvcmlvdXMgd3JhcHBlciBmb3IgdGhyZWFkaW5nLmxvY2FsLiBBbmQgd2hp
bGUgdGhpcyBnZW5lcmljIGhlYWRlciBwYXJzZXItY29tcG9zZXIgaXMsIHdlbGwgZ2VuZXJpYywg
SSBjYW4gZGVhbCB3aXRoIHJhdyBoZWFkZXIgc3RyaW5ncyBqdXN0IGZpbmUsIGhlbmNlIEkgdXNl
IFdlcmt6ZXVnLiBUaGFua3MgZm9yIHNoYXJpbmcgaXQuClBTLiBJcyBwb2NvbyBkZWFkIG9yIGp1
c3QgaGliZXJuYXRpbmc/TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Emptymtrier@gmail.comhttp://blog.michaeltrier.com2007-12-24T17:59:01Znono0Wow, very impressive. I plan to dig through this code just for the learning value if nothing else. I too would like to see this type of web-based console debugger available in Django. Thanks again for your contribution.Wow, very impressive. I plan to dig through this code just for the learning value if nothing else. I too would like to see this type of web-based console debugger available in Django. Thanks again for your contribution.SQAAAAJTAAAABGJvZHlSUwAAAN5Xb3csIHZlcnkgaW1wcmVzc2l2ZS4gIEkgcGxhbiB0byBkaWcg
dGhyb3VnaCB0aGlzIGNvZGUganVzdCBmb3IgdGhlIGxlYXJuaW5nIHZhbHVlIGlmIG5vdGhpbmcg
ZWxzZS4gIEkgdG9vIHdvdWxkIGxpa2UgdG8gc2VlIHRoaXMgdHlwZSBvZiB3ZWItYmFzZWQgY29u
c29sZSBkZWJ1Z2dlciBhdmFpbGFibGUgaW4gRGphbmdvLiAgVGhhbmtzIGFnYWluIGZvciB5b3Vy
IGNvbnRyaWJ1dGlvbi5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
German Django Communityhttp://lucumr.pocoo.org/cogitations/2007/12/08/german-django-community/2007-12-08T19:51:47Z2007-12-08T19:51:47ZArmin Ronachergerman-django-communityyesyes2Since yesterday a German community page for django exists: <a href="http://django-de.org/">django-de.org</a>. Good to see that people are working on that :-)Since yesterday a German community page for django exists: <a href="http://django-de.org/">django-de.org</a>. Good to see that people are working on that :-)SQAAAANTAAAABGJvZHlSUwAAADtTaW5jZSB5ZXN0ZXJkYXkgYSBHZXJtYW4gY29tbXVuaXR5IHBh
Z2UgZm9yIGRqYW5nbyBleGlzdHM6IEwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAFWh0dHA6
Ly9kamFuZ28tZGUub3JnL1MAAAANZGphbmdvLWRlLm9yZ1MAAAAxLiBHb29kIHRvIHNlZSB0aGF0
IHBlb3BsZSBhcmUgd29ya2luZyBvbiB0aGF0IDotKVMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVp
bnRyb1JTAAAAAEwAAA==
bgfullercourier@braydon.comhttp://braydon.com2007-12-08T22:01:24Znono0" Das Web Framework für Perfektionisten mit Deadlines." is kinda funny." Das Web Framework für Perfektionisten mit Deadlines." is kinda funny.SQAAAAJTAAAABGJvZHlSUwAAAEgiIERhcyBXZWIgRnJhbWV3b3JrIGbDvHIgUGVyZmVrdGlvbmlz
dGVuIG1pdCBEZWFkbGluZXMuIiBpcyBraW5kYSBmdW5ueS5MAABTAAAABnBhcnNlclMAAAAEaHRt
bA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-08T22:36:25Znono0A perfectly German version of that would be „Das Web-Rahmenwerk für Perfektionisten mit Stichtagen“, but that sounds awkward :-)
Regards,
ArminA perfectly German version of that would be „Das Web-Rahmenwerk für Perfektionisten mit Stichtagen“, but that sounds awkward :-)
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAJVBIHBlcmZlY3RseSBHZXJtYW4gdmVyc2lvbiBvZiB0aGF0IHdv
dWxkIGJlIOKAnkRhcyBXZWItUmFobWVud2VyayBmw7xyIFBlcmZla3Rpb25pc3RlbiBtaXQgU3Rp
Y2h0YWdlbuKAnCwgYnV0IHRoYXQgc291bmRzIGF3a3dhcmQgOi0pCgpSZWdhcmRzLApBcm1pbkwA
AFMAAAAGcGFyc2VyUwAAAARodG1s
jezdezjannis@leidel.infohttp://jannisleidel.com2007-12-08T23:28:53Znono0Hehe, stimmt klingt komisch, auf lange Sicht sollten wir uns da etwas passenderes ausdenken, also nicht einfach übersetzen :D
Danke für das Post!Hehe, stimmt klingt komisch, auf lange Sicht sollten wir uns da etwas passenderes ausdenken, also nicht einfach übersetzen :D
Danke für das Post!SQAAAAJTAAAABGJvZHlSUwAAAJRIZWhlLCBzdGltbXQga2xpbmd0IGtvbWlzY2gsIGF1ZiBsYW5n
ZSBTaWNodCBzb2xsdGVuIHdpciB1bnMgZGEgZXR3YXMgcGFzc2VuZGVyZXMgYXVzZGVua2VuLCBh
bHNvIG5pY2h0IGVpbmZhY2ggw7xiZXJzZXR6ZW4gOkQKCkRhbmtlIGbDvHIgZGFzIFBvc3QhTAAA
UwAAAAZwYXJzZXJTAAAABGh0bWw=
Listen to more…http://lucumr.pocoo.org/cogitations/2007/11/28/listen-to-more/2007-11-28T16:30:52Z2007-11-28T16:30:52ZArmin Ronacherlisten-to-moreyesyes2...<a href="http://ininagap.com/">Inina Gap</a>. Which you probably haven't heard by now. It's not rock, metal or any other stuff I normally listen to, in fact it's completely different, more like electronic fusion. And disclaimer: I a) saw them live, and b) a friend of mine is playing bass in that band :-)
Nonetheless: Check it out....<a href="http://ininagap.com/">Inina Gap</a>. Which you probably haven't heard by now. It's not rock, metal or any other stuff I normally listen to, in fact it's completely different, more like electronic fusion. And disclaimer: I a) saw them live, and b) a friend of mine is playing bass in that band :-)
Nonetheless: Check it out.SQAAAANTAAAABGJvZHlSUwAAAAMuLi5MAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAABRodHRw
Oi8vaW5pbmFnYXAuY29tL1MAAAAJSW5pbmEgR2FwUwAAASEuIFdoaWNoIHlvdSBwcm9iYWJseSBo
YXZlbid0IGhlYXJkIGJ5IG5vdy4gSXQncyBub3Qgcm9jaywgbWV0YWwgb3IgYW55IG90aGVyIHN0
dWZmIEkgbm9ybWFsbHkgbGlzdGVuIHRvLCBpbiBmYWN0IGl0J3MgY29tcGxldGVseSBkaWZmZXJl
bnQsIG1vcmUgbGlrZSBlbGVjdHJvbmljIGZ1c2lvbi4gQW5kIGRpc2NsYWltZXI6IEkgYSkgc2F3
IHRoZW0gbGl2ZSwgYW5kIGIpIGEgZnJpZW5kIG9mIG1pbmUgaXMgcGxheWluZyBiYXNzIGluIHRo
YXQgYmFuZCA6LSkKCk5vbmV0aGVsZXNzOiBDaGVjayBpdCBvdXQuUwAAAAZwYXJzZXJTAAAABGh0
bWxTAAAABWludHJvUlMAAAAATAAA
220…http://lucumr.pocoo.org/cogitations/2007/11/26/220/2007-11-26T18:36:40Z2007-11-26T18:36:40ZArmin Ronacher220yesyes2<big><a href="http://www.amnestyusa.org/document.php?lang=e&id=ENGUSA20070108001">...dead</a></big>. And that's a non lethal weapon?
<strong>update:</strong> Georg points out that it's called a "less lethal" weapon.<big><a href="http://www.amnestyusa.org/document.php?lang=e&id=ENGUSA20070108001">...dead</a></big>. And that's a non lethal weapon?
<strong>update:</strong> Georg points out that it's called a "less lethal" weapon.SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAANiaWdMAAFFUwAAAAFhTAAATQABUwAAAARocmVm
UwAAAEJodHRwOi8vd3d3LmFtbmVzdHl1c2Eub3JnL2RvY3VtZW50LnBocD9sYW5nPWUmaWQ9RU5H
VVNBMjAwNzAxMDgwMDFTAAAABy4uLmRlYWRTAAAAAE0AAFMAAAAAUwAAACMuIEFuZCB0aGF0J3Mg
YSBub24gbGV0aGFsIHdlYXBvbj8KCkVTAAAABnN0cm9uZ0wAAE0AAFMAAAAHdXBkYXRlOlMAAAA6
IEdlb3JnIHBvaW50cyBvdXQgdGhhdCBpdCdzIGNhbGxlZCBhICJsZXNzIGxldGhhbCIgd2VhcG9u
LlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Wiki Models with SQLAlchemyhttp://lucumr.pocoo.org/cogitations/2007/11/22/wiki-models-with-sqlalchemy/2007-11-22T00:34:28Z2007-11-22T00:34:28ZArmin Ronacherwiki-models-with-sqlalchemyyesyes2I was working on an <a href="http://dev.pocoo.org/projects/werkzeug/browser/examples/simplewiki">example application</a> for the upcoming <a href="http://werkzeug.pocoo.org/">Werkzeug</a> release and decided to make a wiki for that purpose. (The main reason is that I found the <a href="http://pypi.python.org/pypi/Creoleparser">Creoleparser</a> on the pypi index and thought that it would integrate into a genshi powered wiki well)
Now wikis have an interesting data structure. Basically you have pages and revisions, where a revision is bound to exactly one page. Simple to model and my database definition looks like that:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="n">page_table</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s">'pages'</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span>
<span class="n">Column</span><span class="p">(</span><span class="s">'page_id'</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="n">Column</span><span class="p">(</span><span class="s">'name'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mf">60</span><span class="p">),</span> <span class="n">unique</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">revision_table</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s">'revisions'</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span>
<span class="n">Column</span><span class="p">(</span><span class="s">'revision_id'</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
<span class="n">Column</span><span class="p">(</span><span class="s">'page_id'</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">'pages.page_id'</span><span class="p">)),</span>
<span class="n">Column</span><span class="p">(</span><span class="s">'timestamp'</span><span class="p">,</span> <span class="n">DateTime</span><span class="p">),</span>
<span class="n">Column</span><span class="p">(</span><span class="s">'text'</span><span class="p">,</span> <span class="n">String</span><span class="p">),</span>
<span class="n">Column</span><span class="p">(</span><span class="s">'change_note'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mf">200</span><span class="p">))</span>
<span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>page_table = Table('pages', metadata,
Column('page_id', Integer, primary_key=True),
Column('name', String(60), unique=True)
)
revision_table = Table('revisions', metadata,
Column('revision_id', Integer, primary_key=True),
Column('page_id', Integer, ForeignKey('pages.page_id')),
Column('timestamp', DateTime),
Column('text', String),
Column('change_note', String(200))
)<PYGMENTS_RAW -->
Very simple schema and you can easily bind it to two classes:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">class</span> <span class="nc">Revision</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">page</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">change_note</span><span class="o">=</span><span class="s">''</span><span class="p">,</span> <span class="n">timestamp</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">page</span><span class="p">,</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">long</span><span class="p">)):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">page_id</span> <span class="o">=</span> <span class="n">page</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">page</span> <span class="o">=</span> <span class="n">page</span>
<span class="bp">self</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">text</span>
<span class="bp">self</span><span class="o">.</span><span class="n">change_note</span> <span class="o">=</span> <span class="n">change_note</span>
<span class="bp">self</span><span class="o">.</span><span class="n">timestamp</span> <span class="o">=</span> <span class="n">timestamp</span> <span class="ow">or</span> <span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">"""Render the page text into a genshi stream."""</span>
<span class="k">if</span> <span class="n">request</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">get_request</span><span class="p">()</span>
<span class="k">if</span> <span class="n">request</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">'rendering requires request context'</span><span class="p">)</span>
<span class="k">return</span> <span class="n">parse_creole</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Page</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'_'</span><span class="p">,</span> <span class="s">' '</span><span class="p">)</span>
<span class="n">Session</span><span class="o">.</span><span class="n">mapper</span><span class="p">(</span><span class="n">Revision</span><span class="p">,</span> <span class="n">revision_table</span><span class="p">)</span>
<span class="n">Session</span><span class="o">.</span><span class="n">mapper</span><span class="p">(</span><span class="n">Page</span><span class="p">,</span> <span class="n">page_table</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span>
<span class="n">revisions</span><span class="o">=</span><span class="n">relation</span><span class="p">(</span><span class="n">Revision</span><span class="p">,</span> <span class="n">backref</span><span class="o">=</span><span class="s">'page'</span><span class="p">,</span> <span class="n">order_by</span><span class="o">=</span><span class="p">[</span><span class="n">desc</span><span class="p">(</span><span class="n">Revision</span><span class="o">.</span><span class="n">revision_id</span><span class="p">)])</span>
<span class="p">))</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>class Revision(object):
def __init__(self, page, text, change_note='', timestamp=None):
if isinstance(page, (int, long)):
self.page_id = page
else:
self.page = page
self.text = text
self.change_note = change_note
self.timestamp = timestamp or datetime.utcnow()
def render(self, request=None):
"""Render the page text into a genshi stream."""
if request is None:
request = get_request()
if request is None:
raise RuntimeError('rendering requires request context')
return parse_creole(request, self.text)
class Page(object):
def __init__(self, name):
self.name = name
@property
def title(self):
return self.name.replace('_', ' ')
Session.mapper(Revision, revision_table)
Session.mapper(Page, page_table, properties=dict(
revisions=relation(Revision, backref='page', order_by=[desc(Revision.revision_id)])
))<PYGMENTS_RAW -->
Works pretty well but as soon as you start putting your stuff into the template it feels unpythonic :-) You basically have to provide always two objects, the revision and the page. Why not combine that into one model? First I removed my database tables again and combined that into one table but then I found out that you can map joins to classes in SQLAlchemy. That and Python's ability to do multiple inheritance gives me the ability to combine both tables into one class:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">class</span> <span class="nc">RevisionedPage</span><span class="p">(</span><span class="n">Page</span><span class="p">,</span> <span class="n">Revision</span><span class="p">):</span>
<span class="k">pass</span>
<span class="n">Session</span><span class="o">.</span><span class="n">mapper</span><span class="p">(</span><span class="n">RevisionedPage</span><span class="p">,</span> <span class="n">join</span><span class="p">(</span><span class="n">page_table</span><span class="p">,</span> <span class="n">revision_table</span><span class="p">),</span> <span class="n">properties</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span>
<span class="n">page_id</span><span class="o">=</span><span class="p">[</span><span class="n">page_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">page_id</span><span class="p">,</span> <span class="n">revision_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">page_id</span><span class="p">],</span>
<span class="p">))</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>class RevisionedPage(Page, Revision):
pass
Session.mapper(RevisionedPage, join(page_table, revision_table), properties=dict(
page_id=[page_table.c.page_id, revision_table.c.page_id],
))<PYGMENTS_RAW -->
Very nice for the templates and also easy to query. It looks like a normal python class. I haven't tried if that also works for write access, but I doubt it. Because of that I have added an exception to the __init__ method to avoid creating pages and revisions via the RevisionedPage object.
The full example can be found <a href="http://dev.pocoo.org/projects/werkzeug/browser/examples/simplewiki/database.py">in the simplewiki sources</a>.I was working on an <a href="http://dev.pocoo.org/projects/werkzeug/browser/examples/simplewiki">example application</a> for the upcoming <a href="http://werkzeug.pocoo.org/">Werkzeug</a> release and decided to make a wiki for that purpose. (The main reason is that I found the <a href="http://pypi.python.org/pypi/Creoleparser">Creoleparser</a> on the pypi index and thought that it would integrate into a genshi powered wiki well)
Now wikis have an interesting data structure. Basically you have pages and revisions, where a revision is bound to exactly one page. Simple to model and my database definition looks like that:
Very simple schema and you can easily bind it to two classes:
Works pretty well but as soon as you start putting your stuff into the template it feels unpythonic :-) You basically have to provide always two objects, the revision and the page. Why not combine that into one model? First I removed my database tables again and combined that into one table but then I found out that you can map joins to classes in SQLAlchemy. That and Python's ability to do multiple inheritance gives me the ability to combine both tables into one class:
Very nice for the templates and also easy to query. It looks like a normal python class. I haven't tried if that also works for write access, but I doubt it. Because of that I have added an exception to the __init__ method to avoid creating pages and revisions via the RevisionedPage object.
The full example can be found <a href="http://dev.pocoo.org/projects/werkzeug/browser/examples/simplewiki/database.py">in the simplewiki sources</a>.SQAAAANTAAAABGJvZHlSUwAAABRJIHdhcyB3b3JraW5nIG9uIGFuIEwABEVTAAAAAWFMAABNAAFT
AAAABGhyZWZTAAAAQmh0dHA6Ly9kZXYucG9jb28ub3JnL3Byb2plY3RzL3dlcmt6ZXVnL2Jyb3dz
ZXIvZXhhbXBsZXMvc2ltcGxld2lraVMAAAATZXhhbXBsZSBhcHBsaWNhdGlvblMAAAASIGZvciB0
aGUgdXBjb21pbmcgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAaaHR0cDovL3dlcmt6ZXVnLnBv
Y29vLm9yZy9TAAAACFdlcmt6ZXVnUwAAAFsgcmVsZWFzZSBhbmQgZGVjaWRlZCB0byBtYWtlIGEg
d2lraSBmb3IgdGhhdCBwdXJwb3NlLiAoVGhlIG1haW4gcmVhc29uIGlzIHRoYXQgSSBmb3VuZCB0
aGUgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAoaHR0cDovL3B5cGkucHl0aG9uLm9yZy9weXBp
L0NyZW9sZXBhcnNlclMAAAAMQ3Jlb2xlcGFyc2VyUwAABHkgb24gdGhlIHB5cGkgaW5kZXggYW5k
IHRob3VnaHQgdGhhdCBpdCB3b3VsZCBpbnRlZ3JhdGUgaW50byBhIGdlbnNoaSBwb3dlcmVkIHdp
a2kgd2VsbCkKCk5vdyB3aWtpcyBoYXZlIGFuIGludGVyZXN0aW5nIGRhdGEgc3RydWN0dXJlLiBC
YXNpY2FsbHkgeW91IGhhdmUgcGFnZXMgYW5kIHJldmlzaW9ucywgd2hlcmUgYSByZXZpc2lvbiBp
cyBib3VuZCB0byBleGFjdGx5IG9uZSBwYWdlLiBTaW1wbGUgdG8gbW9kZWwgYW5kIG15IGRhdGFi
YXNlIGRlZmluaXRpb24gbG9va3MgbGlrZSB0aGF0OgoKVmVyeSBzaW1wbGUgc2NoZW1hIGFuZCB5
b3UgY2FuIGVhc2lseSBiaW5kIGl0IHRvIHR3byBjbGFzc2VzOgoKV29ya3MgcHJldHR5IHdlbGwg
YnV0IGFzIHNvb24gYXMgeW91IHN0YXJ0IHB1dHRpbmcgeW91ciBzdHVmZiBpbnRvIHRoZSB0ZW1w
bGF0ZSBpdCBmZWVscyB1bnB5dGhvbmljIDotKSBZb3UgYmFzaWNhbGx5IGhhdmUgdG8gcHJvdmlk
ZSBhbHdheXMgdHdvIG9iamVjdHMsIHRoZSByZXZpc2lvbiBhbmQgdGhlIHBhZ2UuIFdoeSBub3Qg
Y29tYmluZSB0aGF0IGludG8gb25lIG1vZGVsPyBGaXJzdCBJIHJlbW92ZWQgbXkgZGF0YWJhc2Ug
dGFibGVzIGFnYWluIGFuZCBjb21iaW5lZCB0aGF0IGludG8gb25lIHRhYmxlIGJ1dCB0aGVuIEkg
Zm91bmQgb3V0IHRoYXQgeW91IGNhbiBtYXAgam9pbnMgdG8gY2xhc3NlcyBpbiBTUUxBbGNoZW15
LiBUaGF0IGFuZCBQeXRob24ncyBhYmlsaXR5IHRvIGRvIG11bHRpcGxlIGluaGVyaXRhbmNlIGdp
dmVzIG1lIHRoZSBhYmlsaXR5IHRvIGNvbWJpbmUgYm90aCB0YWJsZXMgaW50byBvbmUgY2xhc3M6
CgpWZXJ5IG5pY2UgZm9yIHRoZSB0ZW1wbGF0ZXMgYW5kIGFsc28gZWFzeSB0byBxdWVyeS4gSXQg
bG9va3MgbGlrZSBhIG5vcm1hbCBweXRob24gY2xhc3MuIEkgaGF2ZW4ndCB0cmllZCBpZiB0aGF0
IGFsc28gd29ya3MgZm9yIHdyaXRlIGFjY2VzcywgYnV0IEkgZG91YnQgaXQuIEJlY2F1c2Ugb2Yg
dGhhdCBJIGhhdmUgYWRkZWQgYW4gZXhjZXB0aW9uIHRvIHRoZSBfX2luaXRfXyBtZXRob2QgdG8g
YXZvaWQgY3JlYXRpbmcgcGFnZXMgYW5kIHJldmlzaW9ucyB2aWEgdGhlIFJldmlzaW9uZWRQYWdl
IG9iamVjdC4KClRoZSBmdWxsIGV4YW1wbGUgY2FuIGJlIGZvdW5kIEVTAAAAAWFMAABNAAFTAAAA
BGhyZWZTAAAATmh0dHA6Ly9kZXYucG9jb28ub3JnL3Byb2plY3RzL3dlcmt6ZXVnL2Jyb3dzZXIv
ZXhhbXBsZXMvc2ltcGxld2lraS9kYXRhYmFzZS5weVMAAAAZaW4gdGhlIHNpbXBsZXdpa2kgc291
cmNlc1MAAAABLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
k4mlkamal@smach.nethttp://www.k4ml.com/2007-11-24T06:20:00Znono0Hi, any special reason not to use Jinja for the templates in this example ?Hi, any special reason not to use Jinja for the templates in this example ?SQAAAAJTAAAABGJvZHlSUwAAAEtIaSwgYW55IHNwZWNpYWwgcmVhc29uIG5vdCB0byB1c2UgSmlu
amEgZm9yIHRoZSB0ZW1wbGF0ZXMgaW4gdGhpcyBleGFtcGxlID9MAABTAAAABnBhcnNlclMAAAAE
aHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-11-24T19:01:10Znono0First of all creoleparser uses genshi internally so it plays nice with genshi itself of course. On the other hand I want to show that you can combine werkzeug with any library out there not just the pocoo libraries. :-)
Regards,
ArminFirst of all creoleparser uses genshi internally so it plays nice with genshi itself of course. On the other hand I want to show that you can combine werkzeug with any library out there not just the pocoo libraries. :-)
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAOtGaXJzdCBvZiBhbGwgY3Jlb2xlcGFyc2VyIHVzZXMgZ2Vuc2hp
IGludGVybmFsbHkgc28gaXQgcGxheXMgbmljZSB3aXRoIGdlbnNoaSBpdHNlbGYgb2YgY291cnNl
LiBPbiB0aGUgb3RoZXIgaGFuZCBJIHdhbnQgdG8gc2hvdyB0aGF0IHlvdSBjYW4gY29tYmluZSB3
ZXJremV1ZyB3aXRoIGFueSBsaWJyYXJ5IG91dCB0aGVyZSBub3QganVzdCB0aGUgcG9jb28gbGli
cmFyaWVzLiA6LSkKClJlZ2FyZHMsCkFybWluTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Wokdave.null@example.org2008-01-05T06:32:28Znono0Thank you for writing this bit, it does help conceptualising the thing. I saw how Django does that, I read the definitions of Active Record and Data Mapper, and your piece gives a clear Python example on how to do the second with SQLAlchemy.
Don’t want to say a word on Wikicreole. Rather writing reStructuredText alone than struggling with brackets! End of sarcasm :) Best regards, WokThank you for writing this bit, it does help conceptualising the thing. I saw how Django does that, I read the definitions of Active Record and Data Mapper, and your piece gives a clear Python example on how to do the second with SQLAlchemy.
Don’t want to say a word on Wikicreole. Rather writing reStructuredText alone than struggling with brackets! End of sarcasm :) Best regards, WokSQAAAAJTAAAABGJvZHlSUwAAAYVUaGFuayB5b3UgZm9yIHdyaXRpbmcgdGhpcyBiaXQsIGl0IGRv
ZXMgaGVscCBjb25jZXB0dWFsaXNpbmcgdGhlIHRoaW5nLiBJIHNhdyBob3cgRGphbmdvIGRvZXMg
dGhhdCwgSSByZWFkIHRoZSBkZWZpbml0aW9ucyBvZiBBY3RpdmUgUmVjb3JkIGFuZCBEYXRhIE1h
cHBlciwgYW5kIHlvdXIgcGllY2UgZ2l2ZXMgYSBjbGVhciBQeXRob24gZXhhbXBsZSBvbiBob3cg
dG8gZG8gdGhlIHNlY29uZCB3aXRoIFNRTEFsY2hlbXkuCgpEb27igJl0IHdhbnQgdG8gc2F5IGEg
d29yZCBvbiBXaWtpY3Jlb2xlLiBSYXRoZXIgd3JpdGluZyByZVN0cnVjdHVyZWRUZXh0IGFsb25l
IHRoYW4gc3RydWdnbGluZyB3aXRoIGJyYWNrZXRzISBFbmQgb2Ygc2FyY2FzbSA6KSBCZXN0IHJl
Z2FyZHMsIFdva0wAAFMAAAAGcGFyc2VyUwAAAARodG1s
Convert an internal iterator into an external in Pythonhttp://lucumr.pocoo.org/cogitations/2007/11/18/convert-an-internal-iterator-into-an-external-in-python/2007-11-18T21:42:47Z2007-11-18T21:42:47ZArmin Ronacherconvert-an-internal-iterator-into-an-external-in-pythonyesyes2<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">py.magic</span> <span class="k">import</span> <span class="n">greenlet</span>
<span class="k">def</span> <span class="nf">make_iterator</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
<span class="n">g1</span> <span class="o">=</span> <span class="n">greenlet</span><span class="o">.</span><span class="n">getcurrent</span><span class="p">()</span>
<span class="n">g2</span> <span class="o">=</span> <span class="n">greenlet</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="n">func</span><span class="p">(</span><span class="k">lambda</span> <span class="n">item</span><span class="p">:</span> <span class="n">g1</span><span class="o">.</span><span class="n">switch</span><span class="p">((</span><span class="n">item</span><span class="p">,))),</span> <span class="n">g1</span><span class="p">)</span>
<span class="k">while</span> <span class="mf">1</span><span class="p">:</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">g2</span><span class="o">.</span><span class="n">switch</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">rv</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">yield</span> <span class="n">rv</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from py.magic import greenlet
def make_iterator(func):
g1 = greenlet.getcurrent()
g2 = greenlet(lambda: func(lambda item: g1.switch((item,))), g1)
while 1:
rv = g2.switch()
if not rv:
return
yield rv[0]<PYGMENTS_RAW -->
Example usage:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">def</span> <span class="nf">my_internal_iterator</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mf">10</span><span class="p">):</span>
<span class="n">f</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
<span class="n">iterator</span> <span class="o">=</span> <span class="n">make_iterator</span><span class="p">(</span><span class="n">my_internal_iterator</span><span class="p">)</span>
<span class="n">iterator</span><span class="o">.</span><span class="n">next</span><span class="p">()</span> <span class="c"># yields 0</span>
<span class="n">iterator</span><span class="o">.</span><span class="n">next</span><span class="p">()</span> <span class="c"># yields 1</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>def my_internal_iterator(f):
for item in xrange(10):
f(item)
iterator = make_iterator(my_internal_iterator)
iterator.next() # yields 0
iterator.next() # yields 1<PYGMENTS_RAW -->
Example usage:
SQAAAANTAAAABGJvZHlSUwAAABAKRXhhbXBsZSB1c2FnZToKTAAAUwAAAAZwYXJzZXJTAAAABGh0
bWxTAAAABWludHJvUlMAAAAATAAA
convert a Request.write() into a WSGI yieldhttp://lucumr.pocoo.org/cogitations/2007/11/18/convert-a-requestwrite-into-a-wsgi-yield/2007-11-18T21:20:07Z2007-11-18T21:20:07ZArmin Ronacherconvert-a-requestwrite-into-a-wsgi-yieldyesyes2I tried that for a long time now using python generators with yield and send threads and much more. But I never got anything that looked easy to understand and worked at the same time. The problem basically occurs if you have an old python web application that has some sort of request object with a write method that directly writes to the output stream of the server interface (sys.stdout or some sort of fastcgi/mod_python output stream object) and you want to convert the application to WSGI. Take the following piece of code from an imaginary legacy application:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">def</span> <span class="nf">old_application</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="k">from</span> <span class="nn">time</span> <span class="k">import</span> <span class="n">sleep</span>
<span class="n">request</span><span class="o">.</span><span class="n">header</span><span class="p">(</span><span class="s">'Content-Type: text/html'</span><span class="p">)</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mf">10</span><span class="p">):</span>
<span class="n">request</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">+</span> <span class="s">' '</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="n">request</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'<br>And the next flush takes another second<br>'</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="n">sleep</span><span class="p">(</span><span class="mf">1</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'And done!'</span><span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>def old_application(request):
from time import sleep
request.header('Content-Type: text/html')
for x in xrange(10):
request.write(str(x) + ' ')
request.flush()
request.write('<br>And the next flush takes another second<br>')
request.flush()
sleep(1)
request.write('And done!')<PYGMENTS_RAW -->
Say we want to convert that into a WSGI application with those semantics:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">def</span> <span class="nf">wsgi_application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="k">from</span> <span class="nn">time</span> <span class="k">import</span> <span class="n">sleep</span>
<span class="n">start_response</span><span class="p">(</span><span class="s">'200 OK'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'Content-Type'</span><span class="p">,</span> <span class="s">'text/html'</span><span class="p">])</span>
<span class="k">yield</span> <span class="s">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mf">10</span><span class="p">))</span> <span class="o">+</span> <span class="s">' '</span>
<span class="k">yield</span> <span class="s">'<br>And the next flush takes another second<br>'</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">1</span><span class="p">)</span>
<span class="k">yield</span> <span class="s">'And Done!'</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>def wsgi_application(environ, start_response):
from time import sleep
start_response('200 OK', [('Content-Type', 'text/html'])
yield ' '.join(str(x) for x in xrange(10)) + ' '
yield '<br>And the next flush takes another second<br>'
time.sleep(1)
yield 'And Done!'<PYGMENTS_RAW -->
The main problem is the time.sleep and all those flush calls. That means we cannot just buffer the contents but convert the into a generator on the fly. What we need to get that done are either coroutines, greenlets or two threads that communicate with each other. The easiest and I guess also fastest approach are <a href="http://codespeak.net/py/dist/greenlet.html">greenlets</a>.
Here a function that converts an old legacy application like above into a WSGI application with the same semantics:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">py.magic</span> <span class="k">import</span> <span class="n">greenlet</span>
<span class="k">class</span> <span class="nc">Request</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="o">=</span> <span class="n">greenlet</span><span class="o">.</span><span class="n">getcurrent</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">environ</span> <span class="o">=</span> <span class="n">environ</span>
<span class="bp">self</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="s">'200 OK'</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">header</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">tuple</span><span class="p">(</span><span class="n">item</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">':'</span><span class="p">,</span> <span class="mf">1</span><span class="p">)))</span>
<span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">switch</span><span class="p">((</span><span class="s">'write'</span><span class="p">,</span> <span class="n">text</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">flush</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_parent</span><span class="o">.</span><span class="n">switch</span><span class="p">((</span><span class="s">'flush'</span><span class="p">,</span> <span class="bp">None</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">convert_app</span><span class="p">(</span><span class="n">application</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">wsgi_app</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">Request</span><span class="p">(</span><span class="n">environ</span><span class="p">)</span>
<span class="nb">buffer</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">headers_sent</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">flush</span><span class="p">():</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">headers_sent</span><span class="p">:</span>
<span class="n">start_response</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">status</span><span class="p">,</span> <span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">)</span>
<span class="n">headers_sent</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="s">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">data</span>
<span class="k">del</span> <span class="nb">buffer</span><span class="p">[:]</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
<span class="n">application</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="n">g</span> <span class="o">=</span> <span class="n">greenlet</span><span class="p">(</span><span class="n">run</span><span class="p">,</span> <span class="n">request</span><span class="o">.</span><span class="n">_parent</span><span class="p">)</span>
<span class="k">while</span> <span class="mf">1</span><span class="p">:</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">g</span><span class="o">.</span><span class="n">switch</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">rv</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">signal</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">rv</span>
<span class="k">if</span> <span class="n">signal</span> <span class="o">==</span> <span class="s">'flush'</span><span class="p">:</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">flush</span><span class="p">():</span>
<span class="k">yield</span> <span class="n">item</span>
<span class="k">elif</span> <span class="n">signal</span> <span class="o">==</span> <span class="s">'write'</span><span class="p">:</span>
<span class="nb">buffer</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">wsgi_app</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from py.magic import greenlet
class Request(object):
def __init__(self, environ):
self._parent = greenlet.getcurrent()
self.environ = environ
self.status = '200 OK'
self.headers = []
def header(self, item):
self.headers.append(tuple(item.split(':', 1)))
def write(self, text):
self._parent.switch(('write', text))
def flush(self):
self._parent.switch(('flush', None))
def convert_app(application):
def wsgi_app(environ, start_response):
request = Request(environ)
buffer = []
headers_sent = []
def flush():
if not headers_sent:
start_response(request.status, request.headers)
headers_sent.append(True)
data = ''.join(buffer)
if data:
yield data
del buffer[:]
def run():
application(request)
request.flush()
g = greenlet(run, request._parent)
while 1:
rv = g.switch()
if not rv:
break
signal, value = rv
if signal == 'flush':
for item in flush():
yield item
elif signal == 'write':
buffer.append(value)
return wsgi_app<PYGMENTS_RAW -->
Now that's a bunch of code. Let's go step by step through it. The first thing we do is creating a request class. This class should resemble the old request object as much as possible. All methods can work like they did before, the only differences are the write and flush methods. Those switch back to the parent greenlet (which is the greenlet that generated the request object, usually the main greenlet) and send some data to it (namely the name of the method and the argument). Whenever python encounters this statement it stops the execution and goes back to the point that switched into this greenlet. This point is in our example in a loop that generates a generator for our WSGI application.
That leads us to the convert_app function that is passed and old legacy application and returns a new WSGI application. Inside this new WSGI application we create a new request object, pass it the WSGI environment and create some objects and functions we need so that we can process the data from the greenlets and convert it into a valid WSGI response: A buffer for unsent data, a list we use a sentinel for sent data, a flush method that returns a generator with the data from the buffer, starts the response and cleans the buffer, and a run method that invokes the old application and calls request.flush() after the application has finished so that we don't have to do that in the application itself.
The mainloop after that basically switches between application greenlet and main greenlet until the return value of switch is None (that is the case if the application closed or someone switched into the main greenlet without arguments, which we don't do). If that is the case we return, otherwise we check if it's a flush or write call and handle that.
To launch the converted application with wsgiref all we have to do are those three lines of code:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">wsgiref.simple_server</span> <span class="k">import</span> <span class="n">make_server</span>
<span class="n">srv</span> <span class="o">=</span> <span class="n">make_server</span><span class="p">(</span><span class="s">'localhost'</span><span class="p">,</span> <span class="mf">5000</span><span class="p">,</span> <span class="n">convert_app</span><span class="p">(</span><span class="n">old_application</span><span class="p">))</span>
<span class="n">srv</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from wsgiref.simple_server import make_server
srv = make_server('localhost', 5000, convert_app(old_application))
srv.serve_forever()<PYGMENTS_RAW -->
Basically greenlets would make it possible to host mod_python applications inside arbitrary WSGI servers. Maybe in the future someone writes a module that allows us to convert some of the mod_python applications into WSGI applications without touching existing application code.I tried that for a long time now using python generators with yield and send threads and much more. But I never got anything that looked easy to understand and worked at the same time. The problem basically occurs if you have an old python web application that has some sort of request object with a write method that directly writes to the output stream of the server interface (sys.stdout or some sort of fastcgi/mod_python output stream object) and you want to convert the application to WSGI. Take the following piece of code from an imaginary legacy application:
Say we want to convert that into a WSGI application with those semantics:
The main problem is the time.sleep and all those flush calls. That means we cannot just buffer the contents but convert the into a generator on the fly. What we need to get that done are either coroutines, greenlets or two threads that communicate with each other. The easiest and I guess also fastest approach are <a href="http://codespeak.net/py/dist/greenlet.html">greenlets</a>.
Here a function that converts an old legacy application like above into a WSGI application with the same semantics:
Now that's a bunch of code. Let's go step by step through it. The first thing we do is creating a request class. This class should resemble the old request object as much as possible. All methods can work like they did before, the only differences are the write and flush methods. Those switch back to the parent greenlet (which is the greenlet that generated the request object, usually the main greenlet) and send some data to it (namely the name of the method and the argument). Whenever python encounters this statement it stops the execution and goes back to the point that switched into this greenlet. This point is in our example in a loop that generates a generator for our WSGI application.
That leads us to the convert_app function that is passed and old legacy application and returns a new WSGI application. Inside this new WSGI application we create a new request object, pass it the WSGI environment and create some objects and functions we need so that we can process the data from the greenlets and convert it into a valid WSGI response: A buffer for unsent data, a list we use a sentinel for sent data, a flush method that returns a generator with the data from the buffer, starts the response and cleans the buffer, and a run method that invokes the old application and calls request.flush() after the application has finished so that we don't have to do that in the application itself.
The mainloop after that basically switches between application greenlet and main greenlet until the return value of switch is None (that is the case if the application closed or someone switched into the main greenlet without arguments, which we don't do). If that is the case we return, otherwise we check if it's a flush or write call and handle that.
To launch the converted application with wsgiref all we have to do are those three lines of code:
Basically greenlets would make it possible to host mod_python applications inside arbitrary WSGI servers. Maybe in the future someone writes a module that allows us to convert some of the mod_python applications into WSGI applications without touching existing application code.SQAAAANTAAAABGJvZHlSUwAAA8BJIHRyaWVkIHRoYXQgZm9yIGEgbG9uZyB0aW1lIG5vdyB1c2lu
ZyBweXRob24gZ2VuZXJhdG9ycyB3aXRoIHlpZWxkIGFuZCBzZW5kIHRocmVhZHMgYW5kIG11Y2gg
bW9yZS4gQnV0IEkgbmV2ZXIgZ290IGFueXRoaW5nIHRoYXQgbG9va2VkIGVhc3kgdG8gdW5kZXJz
dGFuZCBhbmQgd29ya2VkIGF0IHRoZSBzYW1lIHRpbWUuIFRoZSBwcm9ibGVtIGJhc2ljYWxseSBv
Y2N1cnMgaWYgeW91IGhhdmUgYW4gb2xkIHB5dGhvbiB3ZWIgYXBwbGljYXRpb24gdGhhdCBoYXMg
c29tZSBzb3J0IG9mIHJlcXVlc3Qgb2JqZWN0IHdpdGggYSB3cml0ZSBtZXRob2QgdGhhdCBkaXJl
Y3RseSB3cml0ZXMgdG8gdGhlIG91dHB1dCBzdHJlYW0gb2YgdGhlIHNlcnZlciBpbnRlcmZhY2Ug
KHN5cy5zdGRvdXQgb3Igc29tZSBzb3J0IG9mIGZhc3RjZ2kvbW9kX3B5dGhvbiBvdXRwdXQgc3Ry
ZWFtIG9iamVjdCkgYW5kIHlvdSB3YW50IHRvIGNvbnZlcnQgdGhlIGFwcGxpY2F0aW9uIHRvIFdT
R0kuIFRha2UgdGhlIGZvbGxvd2luZyBwaWVjZSBvZiBjb2RlIGZyb20gYW4gaW1hZ2luYXJ5IGxl
Z2FjeSBhcHBsaWNhdGlvbjoKCgpTYXkgd2Ugd2FudCB0byBjb252ZXJ0IHRoYXQgaW50byBhIFdT
R0kgYXBwbGljYXRpb24gd2l0aCB0aG9zZSBzZW1hbnRpY3M6CgpUaGUgbWFpbiBwcm9ibGVtIGlz
IHRoZSB0aW1lLnNsZWVwIGFuZCBhbGwgdGhvc2UgZmx1c2ggY2FsbHMuIFRoYXQgbWVhbnMgd2Ug
Y2Fubm90IGp1c3QgYnVmZmVyIHRoZSBjb250ZW50cyBidXQgY29udmVydCB0aGUgaW50byBhIGdl
bmVyYXRvciBvbiB0aGUgZmx5LiBXaGF0IHdlIG5lZWQgdG8gZ2V0IHRoYXQgZG9uZSBhcmUgZWl0
aGVyIGNvcm91dGluZXMsIGdyZWVubGV0cyBvciB0d28gdGhyZWFkcyB0aGF0IGNvbW11bmljYXRl
IHdpdGggZWFjaCBvdGhlci4gVGhlIGVhc2llc3QgYW5kIEkgZ3Vlc3MgYWxzbyBmYXN0ZXN0IGFw
cHJvYWNoIGFyZSBMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACpodHRwOi8vY29kZXNwZWFr
Lm5ldC9weS9kaXN0L2dyZWVubGV0Lmh0bWxTAAAACWdyZWVubGV0c1MAAAjULgoKSGVyZSBhIGZ1
bmN0aW9uIHRoYXQgY29udmVydHMgYW4gb2xkIGxlZ2FjeSBhcHBsaWNhdGlvbiBsaWtlIGFib3Zl
IGludG8gYSBXU0dJIGFwcGxpY2F0aW9uIHdpdGggdGhlIHNhbWUgc2VtYW50aWNzOgoKTm93IHRo
YXQncyBhIGJ1bmNoIG9mIGNvZGUuIExldCdzIGdvIHN0ZXAgYnkgc3RlcCB0aHJvdWdoIGl0LiBU
aGUgZmlyc3QgdGhpbmcgd2UgZG8gaXMgY3JlYXRpbmcgYSByZXF1ZXN0IGNsYXNzLiBUaGlzIGNs
YXNzIHNob3VsZCByZXNlbWJsZSB0aGUgb2xkIHJlcXVlc3Qgb2JqZWN0IGFzIG11Y2ggYXMgcG9z
c2libGUuIEFsbCBtZXRob2RzIGNhbiB3b3JrIGxpa2UgdGhleSBkaWQgYmVmb3JlLCB0aGUgb25s
eSBkaWZmZXJlbmNlcyBhcmUgdGhlIHdyaXRlIGFuZCBmbHVzaCBtZXRob2RzLiBUaG9zZSBzd2l0
Y2ggYmFjayB0byB0aGUgcGFyZW50IGdyZWVubGV0ICh3aGljaCBpcyB0aGUgZ3JlZW5sZXQgdGhh
dCBnZW5lcmF0ZWQgdGhlIHJlcXVlc3Qgb2JqZWN0LCB1c3VhbGx5IHRoZSBtYWluIGdyZWVubGV0
KSBhbmQgc2VuZCBzb21lIGRhdGEgdG8gaXQgKG5hbWVseSB0aGUgbmFtZSBvZiB0aGUgbWV0aG9k
IGFuZCB0aGUgYXJndW1lbnQpLiBXaGVuZXZlciBweXRob24gZW5jb3VudGVycyB0aGlzIHN0YXRl
bWVudCBpdCBzdG9wcyB0aGUgZXhlY3V0aW9uIGFuZCBnb2VzIGJhY2sgdG8gdGhlIHBvaW50IHRo
YXQgc3dpdGNoZWQgaW50byB0aGlzIGdyZWVubGV0LiBUaGlzIHBvaW50IGlzIGluIG91ciBleGFt
cGxlIGluIGEgbG9vcCB0aGF0IGdlbmVyYXRlcyBhIGdlbmVyYXRvciBmb3Igb3VyIFdTR0kgYXBw
bGljYXRpb24uCgpUaGF0IGxlYWRzIHVzIHRvIHRoZSBjb252ZXJ0X2FwcCBmdW5jdGlvbiB0aGF0
IGlzIHBhc3NlZCBhbmQgb2xkIGxlZ2FjeSBhcHBsaWNhdGlvbiBhbmQgcmV0dXJucyBhIG5ldyBX
U0dJIGFwcGxpY2F0aW9uLiBJbnNpZGUgdGhpcyBuZXcgV1NHSSBhcHBsaWNhdGlvbiB3ZSBjcmVh
dGUgYSBuZXcgcmVxdWVzdCBvYmplY3QsIHBhc3MgaXQgdGhlIFdTR0kgZW52aXJvbm1lbnQgYW5k
IGNyZWF0ZSBzb21lIG9iamVjdHMgYW5kIGZ1bmN0aW9ucyB3ZSBuZWVkIHNvIHRoYXQgd2UgY2Fu
IHByb2Nlc3MgdGhlIGRhdGEgZnJvbSB0aGUgZ3JlZW5sZXRzIGFuZCBjb252ZXJ0IGl0IGludG8g
YSB2YWxpZCBXU0dJIHJlc3BvbnNlOiBBIGJ1ZmZlciBmb3IgdW5zZW50IGRhdGEsIGEgbGlzdCB3
ZSB1c2UgYSBzZW50aW5lbCBmb3Igc2VudCBkYXRhLCBhIGZsdXNoIG1ldGhvZCB0aGF0IHJldHVy
bnMgYSBnZW5lcmF0b3Igd2l0aCB0aGUgZGF0YSBmcm9tIHRoZSBidWZmZXIsIHN0YXJ0cyB0aGUg
cmVzcG9uc2UgYW5kIGNsZWFucyB0aGUgYnVmZmVyLCBhbmQgYSBydW4gbWV0aG9kIHRoYXQgaW52
b2tlcyB0aGUgb2xkIGFwcGxpY2F0aW9uIGFuZCBjYWxscyByZXF1ZXN0LmZsdXNoKCkgYWZ0ZXIg
dGhlIGFwcGxpY2F0aW9uIGhhcyBmaW5pc2hlZCBzbyB0aGF0IHdlIGRvbid0IGhhdmUgdG8gZG8g
dGhhdCBpbiB0aGUgYXBwbGljYXRpb24gaXRzZWxmLgoKVGhlIG1haW5sb29wIGFmdGVyIHRoYXQg
YmFzaWNhbGx5IHN3aXRjaGVzIGJldHdlZW4gYXBwbGljYXRpb24gZ3JlZW5sZXQgYW5kIG1haW4g
Z3JlZW5sZXQgdW50aWwgdGhlIHJldHVybiB2YWx1ZSBvZiBzd2l0Y2ggaXMgTm9uZSAodGhhdCBp
cyB0aGUgY2FzZSBpZiB0aGUgYXBwbGljYXRpb24gY2xvc2VkIG9yIHNvbWVvbmUgc3dpdGNoZWQg
aW50byB0aGUgbWFpbiBncmVlbmxldCB3aXRob3V0IGFyZ3VtZW50cywgd2hpY2ggd2UgZG9uJ3Qg
ZG8pLiBJZiB0aGF0IGlzIHRoZSBjYXNlIHdlIHJldHVybiwgb3RoZXJ3aXNlIHdlIGNoZWNrIGlm
IGl0J3MgYSBmbHVzaCBvciB3cml0ZSBjYWxsIGFuZCBoYW5kbGUgdGhhdC4KClRvIGxhdW5jaCB0
aGUgY29udmVydGVkIGFwcGxpY2F0aW9uIHdpdGggd3NnaXJlZiBhbGwgd2UgaGF2ZSB0byBkbyBh
cmUgdGhvc2UgdGhyZWUgbGluZXMgb2YgY29kZToKCgpCYXNpY2FsbHkgZ3JlZW5sZXRzIHdvdWxk
IG1ha2UgaXQgcG9zc2libGUgdG8gaG9zdCBtb2RfcHl0aG9uIGFwcGxpY2F0aW9ucyBpbnNpZGUg
YXJiaXRyYXJ5IFdTR0kgc2VydmVycy4gTWF5YmUgaW4gdGhlIGZ1dHVyZSBzb21lb25lIHdyaXRl
cyBhIG1vZHVsZSB0aGF0IGFsbG93cyB1cyB0byBjb252ZXJ0IHNvbWUgb2YgdGhlIG1vZF9weXRo
b24gYXBwbGljYXRpb25zIGludG8gV1NHSSBhcHBsaWNhdGlvbnMgd2l0aG91dCB0b3VjaGluZyBl
eGlzdGluZyBhcHBsaWNhdGlvbiBjb2RlLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JT
AAAAAEwAAA==
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2007-11-19T04:36:30Znono0I'd thought about writing a compatibility layer that would allow mod_python content handlers to run on top of mod_wsgi. It probably wouldn't be a true WSGI application and thus not portable to other WSGI hosting solutions, as to properly emulate mod_python you need to delve into some of the Apache internals. The idea here was to use the SWIG bindings for the Apache APIs I had been working on. The more I thought about it the more I disliked the idea. The main problem is that stuff like mod_python.publisher is broken in various ways and I didn't like the idea of propagating those mistakes or design problems. The request object interface has also grown organically over time and isn't necessarily consistent. The sort of person I am, I would want to fix such problems, but then by doing so various peoples code probably wouldn't work anymore as they are likely to depend on the suspect behaviour.
Anyway, got enough on my plate for a while before I could even think about new projects. When I get past those then I might fish around for ideas of what people might like to see me work on next. This greenlet stuff sounds interesting though. One of the issues with a WSGI 2.0 was that it would be hard to emulate the WSGI 1.0 write() interface in top of it. Using greenlets may make that easier as the concept of what is required isn't much different to what you have demonstrated above.I'd thought about writing a compatibility layer that would allow mod_python content handlers to run on top of mod_wsgi. It probably wouldn't be a true WSGI application and thus not portable to other WSGI hosting solutions, as to properly emulate mod_python you need to delve into some of the Apache internals. The idea here was to use the SWIG bindings for the Apache APIs I had been working on. The more I thought about it the more I disliked the idea. The main problem is that stuff like mod_python.publisher is broken in various ways and I didn't like the idea of propagating those mistakes or design problems. The request object interface has also grown organically over time and isn't necessarily consistent. The sort of person I am, I would want to fix such problems, but then by doing so various peoples code probably wouldn't work anymore as they are likely to depend on the suspect behaviour.
Anyway, got enough on my plate for a while before I could even think about new projects. When I get past those then I might fish around for ideas of what people might like to see me work on next. This greenlet stuff sounds interesting though. One of the issues with a WSGI 2.0 was that it would be hard to emulate the WSGI 1.0 write() interface in top of it. Using greenlets may make that easier as the concept of what is required isn't much different to what you have demonstrated above.SQAAAAJTAAAABGJvZHlSUwAABW9JJ2QgdGhvdWdodCBhYm91dCB3cml0aW5nIGEgY29tcGF0aWJp
bGl0eSBsYXllciB0aGF0IHdvdWxkIGFsbG93IG1vZF9weXRob24gY29udGVudCBoYW5kbGVycyB0
byBydW4gb24gdG9wIG9mIG1vZF93c2dpLiBJdCBwcm9iYWJseSB3b3VsZG4ndCBiZSBhIHRydWUg
V1NHSSBhcHBsaWNhdGlvbiBhbmQgdGh1cyBub3QgcG9ydGFibGUgdG8gb3RoZXIgV1NHSSBob3N0
aW5nIHNvbHV0aW9ucywgYXMgdG8gcHJvcGVybHkgZW11bGF0ZSBtb2RfcHl0aG9uIHlvdSBuZWVk
IHRvIGRlbHZlIGludG8gc29tZSBvZiB0aGUgQXBhY2hlIGludGVybmFscy4gVGhlIGlkZWEgaGVy
ZSB3YXMgdG8gdXNlIHRoZSBTV0lHIGJpbmRpbmdzIGZvciB0aGUgQXBhY2hlIEFQSXMgSSBoYWQg
YmVlbiB3b3JraW5nIG9uLiBUaGUgbW9yZSBJIHRob3VnaHQgYWJvdXQgaXQgdGhlIG1vcmUgSSBk
aXNsaWtlZCB0aGUgaWRlYS4gVGhlIG1haW4gcHJvYmxlbSBpcyB0aGF0IHN0dWZmIGxpa2UgbW9k
X3B5dGhvbi5wdWJsaXNoZXIgaXMgYnJva2VuIGluIHZhcmlvdXMgd2F5cyBhbmQgSSBkaWRuJ3Qg
bGlrZSB0aGUgaWRlYSBvZiBwcm9wYWdhdGluZyB0aG9zZSBtaXN0YWtlcyBvciBkZXNpZ24gcHJv
YmxlbXMuIFRoZSByZXF1ZXN0IG9iamVjdCBpbnRlcmZhY2UgaGFzIGFsc28gZ3Jvd24gb3JnYW5p
Y2FsbHkgb3ZlciB0aW1lIGFuZCBpc24ndCBuZWNlc3NhcmlseSBjb25zaXN0ZW50LiBUaGUgc29y
dCBvZiBwZXJzb24gSSBhbSwgSSB3b3VsZCB3YW50IHRvIGZpeCBzdWNoIHByb2JsZW1zLCBidXQg
dGhlbiBieSBkb2luZyBzbyB2YXJpb3VzIHBlb3BsZXMgY29kZSBwcm9iYWJseSB3b3VsZG4ndCB3
b3JrIGFueW1vcmUgYXMgdGhleSBhcmUgbGlrZWx5IHRvIGRlcGVuZCBvbiB0aGUgc3VzcGVjdCBi
ZWhhdmlvdXIuCgpBbnl3YXksIGdvdCBlbm91Z2ggb24gbXkgcGxhdGUgZm9yIGEgd2hpbGUgYmVm
b3JlIEkgY291bGQgZXZlbiB0aGluayBhYm91dCBuZXcgcHJvamVjdHMuIFdoZW4gSSBnZXQgcGFz
dCB0aG9zZSB0aGVuIEkgbWlnaHQgZmlzaCBhcm91bmQgZm9yIGlkZWFzIG9mIHdoYXQgcGVvcGxl
IG1pZ2h0IGxpa2UgdG8gc2VlIG1lIHdvcmsgb24gbmV4dC4gVGhpcyBncmVlbmxldCBzdHVmZiBz
b3VuZHMgaW50ZXJlc3RpbmcgdGhvdWdoLiBPbmUgb2YgdGhlIGlzc3VlcyB3aXRoIGEgV1NHSSAy
LjAgd2FzIHRoYXQgaXQgd291bGQgYmUgaGFyZCB0byBlbXVsYXRlIHRoZSBXU0dJIDEuMCB3cml0
ZSgpIGludGVyZmFjZSBpbiB0b3Agb2YgaXQuIFVzaW5nIGdyZWVubGV0cyBtYXkgbWFrZSB0aGF0
IGVhc2llciBhcyB0aGUgY29uY2VwdCBvZiB3aGF0IGlzIHJlcXVpcmVkIGlzbid0IG11Y2ggZGlm
ZmVyZW50IHRvIHdoYXQgeW91IGhhdmUgZGVtb25zdHJhdGVkIGFib3ZlLkwAAFMAAAAGcGFyc2Vy
UwAAAARodG1s
Broken iPod Harddisk is not necessarily Brokenhttp://lucumr.pocoo.org/cogitations/2007/11/18/broken-ipod-harddisk-is-not-necessarily-broken/2007-11-18T12:15:39Z2007-11-18T12:15:39ZArmin Ronacherbroken-ipod-harddisk-is-not-necessarily-brokenyesyes2My brother owns a 5th Generation Video iPod and since some time the iPod was freezing on some songs and I was unable to sync it properly. After about 2 GB transfered data OS X ejected the iPod and sometimes iTunes locked up in a way that the only way to kill iTunes and get working USB ports again was restarting the notebook.
However <a href="http://blog.dscpl.com.au/">Graham</a> sent me a link yesterday to some articles where people encountered the same problems. Among some solutions I haven't tried (like opening the ipod and putting a small pile paper behind the harddisk) there was one that proposed zeroing out the harddisk.
I did that and it didn't help. However I noticed that the disk ran a lot more silent than before. So I continued that process 7 times over the night and this morning I was able to reload the iPod without a problem. After a complet resync I tried all the songs on the device that made problems before and those pass. Of course now other songs could be broken but beside that it runs a lot faster now I haven't encountered any "funny harddisk sounds" during the testing.
Definitively worth a try. Don't give up on iPods that fast :-)My brother owns a 5th Generation Video iPod and since some time the iPod was freezing on some songs and I was unable to sync it properly. After about 2 GB transfered data OS X ejected the iPod and sometimes iTunes locked up in a way that the only way to kill iTunes and get working USB ports again was restarting the notebook.
However <a href="http://blog.dscpl.com.au/">Graham</a> sent me a link yesterday to some articles where people encountered the same problems. Among some solutions I haven't tried (like opening the ipod and putting a small pile paper behind the harddisk) there was one that proposed zeroing out the harddisk.
I did that and it didn't help. However I noticed that the disk ran a lot more silent than before. So I continued that process 7 times over the night and this morning I was able to reload the iPod without a problem. After a complet resync I tried all the songs on the device that made problems before and those pass. Of course now other songs could be broken but beside that it runs a lot faster now I haven't encountered any "funny harddisk sounds" during the testing.
Definitively worth a try. Don't give up on iPods that fast :-)SQAAAANTAAAABGJvZHlSUwAAAVBNeSBicm90aGVyIG93bnMgYSA1dGggR2VuZXJhdGlvbiBWaWRl
byBpUG9kIGFuZCBzaW5jZSBzb21lIHRpbWUgdGhlIGlQb2Qgd2FzIGZyZWV6aW5nIG9uIHNvbWUg
c29uZ3MgYW5kIEkgd2FzIHVuYWJsZSB0byBzeW5jIGl0IHByb3Blcmx5LiBBZnRlciBhYm91dCAy
IEdCIHRyYW5zZmVyZWQgZGF0YSBPUyBYIGVqZWN0ZWQgdGhlIGlQb2QgYW5kIHNvbWV0aW1lcyBp
VHVuZXMgbG9ja2VkIHVwIGluIGEgd2F5IHRoYXQgdGhlIG9ubHkgd2F5IHRvIGtpbGwgaVR1bmVz
IGFuZCBnZXQgd29ya2luZyBVU0IgcG9ydHMgYWdhaW4gd2FzIHJlc3RhcnRpbmcgdGhlIG5vdGVi
b29rLgoKSG93ZXZlciBMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAABlodHRwOi8vYmxvZy5k
c2NwbC5jb20uYXUvUwAAAAZHcmFoYW1TAAADEiBzZW50IG1lIGEgbGluayB5ZXN0ZXJkYXkgdG8g
c29tZSBhcnRpY2xlcyB3aGVyZSBwZW9wbGUgZW5jb3VudGVyZWQgdGhlIHNhbWUgcHJvYmxlbXMu
IEFtb25nIHNvbWUgc29sdXRpb25zIEkgaGF2ZW4ndCB0cmllZCAobGlrZSBvcGVuaW5nIHRoZSBp
cG9kIGFuZCBwdXR0aW5nIGEgc21hbGwgcGlsZSBwYXBlciBiZWhpbmQgdGhlIGhhcmRkaXNrKSB0
aGVyZSB3YXMgb25lIHRoYXQgcHJvcG9zZWQgemVyb2luZyBvdXQgdGhlIGhhcmRkaXNrLgoKSSBk
aWQgdGhhdCBhbmQgaXQgZGlkbid0IGhlbHAuIEhvd2V2ZXIgSSBub3RpY2VkIHRoYXQgdGhlIGRp
c2sgcmFuIGEgbG90IG1vcmUgc2lsZW50IHRoYW4gYmVmb3JlLiBTbyBJIGNvbnRpbnVlZCB0aGF0
IHByb2Nlc3MgNyB0aW1lcyBvdmVyIHRoZSBuaWdodCBhbmQgdGhpcyBtb3JuaW5nIEkgd2FzIGFi
bGUgdG8gcmVsb2FkIHRoZSBpUG9kIHdpdGhvdXQgYSBwcm9ibGVtLiBBZnRlciBhIGNvbXBsZXQg
cmVzeW5jIEkgdHJpZWQgYWxsIHRoZSBzb25ncyBvbiB0aGUgZGV2aWNlIHRoYXQgbWFkZSBwcm9i
bGVtcyBiZWZvcmUgYW5kIHRob3NlIHBhc3MuIE9mIGNvdXJzZSBub3cgb3RoZXIgc29uZ3MgY291
bGQgYmUgYnJva2VuIGJ1dCBiZXNpZGUgdGhhdCBpdCBydW5zIGEgbG90IGZhc3RlciBub3cgSSBo
YXZlbid0IGVuY291bnRlcmVkIGFueSAiZnVubnkgaGFyZGRpc2sgc291bmRzIiBkdXJpbmcgdGhl
IHRlc3RpbmcuCgpEZWZpbml0aXZlbHkgd29ydGggYSB0cnkuIERvbid0IGdpdmUgdXAgb24gaVBv
ZHMgdGhhdCBmYXN0IDotKVMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2007-11-19T06:40:40Znono0Glad to hear you got it working, was meaning to ask. :-)Glad to hear you got it working, was meaning to ask. :-)SQAAAAJTAAAABGJvZHlSUwAAADhHbGFkIHRvIGhlYXIgeW91IGdvdCBpdCB3b3JraW5nLCB3YXMg
bWVhbmluZyB0byBhc2suIDotKUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Jinja 1.2 Releasedhttp://lucumr.pocoo.org/cogitations/2007/11/17/jinja-12-released/2007-11-17T23:02:00Z2007-11-17T23:02:00ZArmin Ronacherjinja-12-releasedyesyes2Finally <a href="http://jinja.pocoo.org/">Jinja 1.2</a> is released. It took a long time because this release introduces basically a complete rewrite of the parser and parts of the lexer. With Jinja 1.2 onwards the template engine has its own parser which makes it possible to introduce new syntactical elements and change operator precedence (especially regarding the filter operator which finally binds harder than plus). We added more unittests to check if Jinja stays compatible with the python semantics we had previously and all 153 tests pass :-)
With the new parser we also simplified the syntax a bit, made the "call" a keyword now and added a couple of new features. For example the debugger (with the optional c extension compiled) is now able to rewrite all jinja frames in a traceback so you will never find yourself in the situation where line numbers don't match the template line numbers.
Another new syntax feature are conditional expressions derived from python2.5 (<code>{{ foo if expr else bar }}</code>). <code>foo.0</code> is now the same as <code>foo[0]</code> for compatibility with django and tuples are finally tuples and not lists which makes it possible to use string formattings with more than one value. Test functions with one parameter don't need parentheses so <code>{{ foo is feeling(well) }}</code> can now be written as <code>{{ foo is feeling well }}</code>.
We also added a concatenation operator that converts all arguments into a string automatically to concatenate them. This is very useful if you have some integers and other values you want to join: <code>{{ foo ~ bar ~ baz }}</code>, which is equivalent to <code>{{ foo|string + bar|string + baz|string }}</code>.
Another great new feature (if you are a django user) is the new django support module which makes it a lot easier to integrate Jinja into django. It makes it possible to use django filters in Jinja and load from the same folders.
Aside from that there are couple of improvements and bugfixes. As always you can easy install Jinja directly from pypi or <a href="http://pypi.python.org/pypi/Jinja/1.2">download it</a>.Finally <a href="http://jinja.pocoo.org/">Jinja 1.2</a> is released. It took a long time because this release introduces basically a complete rewrite of the parser and parts of the lexer. With Jinja 1.2 onwards the template engine has its own parser which makes it possible to introduce new syntactical elements and change operator precedence (especially regarding the filter operator which finally binds harder than plus). We added more unittests to check if Jinja stays compatible with the python semantics we had previously and all 153 tests pass :-)
With the new parser we also simplified the syntax a bit, made the "call" a keyword now and added a couple of new features. For example the debugger (with the optional c extension compiled) is now able to rewrite all jinja frames in a traceback so you will never find yourself in the situation where line numbers don't match the template line numbers.
Another new syntax feature are conditional expressions derived from python2.5 (<code>{{ foo if expr else bar }}</code>). <code>foo.0</code> is now the same as <code>foo[0]</code> for compatibility with django and tuples are finally tuples and not lists which makes it possible to use string formattings with more than one value. Test functions with one parameter don't need parentheses so <code>{{ foo is feeling(well) }}</code> can now be written as <code>{{ foo is feeling well }}</code>.
We also added a concatenation operator that converts all arguments into a string automatically to concatenate them. This is very useful if you have some integers and other values you want to join: <code>{{ foo ~ bar ~ baz }}</code>, which is equivalent to <code>{{ foo|string + bar|string + baz|string }}</code>.
Another great new feature (if you are a django user) is the new django support module which makes it a lot easier to integrate Jinja into django. It makes it possible to use django filters in Jinja and load from the same folders.
Aside from that there are couple of improvements and bugfixes. As always you can easy install Jinja directly from pypi or <a href="http://pypi.python.org/pypi/Jinja/1.2">download it</a>.SQAAAANTAAAABGJvZHlSUwAAAAhGaW5hbGx5IEwACUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAA
F2h0dHA6Ly9qaW5qYS5wb2Nvby5vcmcvUwAAAAlKaW5qYSAxLjJTAAADoyBpcyByZWxlYXNlZC4g
SXQgdG9vayBhIGxvbmcgdGltZSBiZWNhdXNlIHRoaXMgcmVsZWFzZSBpbnRyb2R1Y2VzIGJhc2lj
YWxseSBhIGNvbXBsZXRlIHJld3JpdGUgb2YgdGhlIHBhcnNlciBhbmQgcGFydHMgb2YgdGhlIGxl
eGVyLiBXaXRoIEppbmphIDEuMiBvbndhcmRzIHRoZSB0ZW1wbGF0ZSBlbmdpbmUgaGFzIGl0cyBv
d24gcGFyc2VyIHdoaWNoIG1ha2VzIGl0IHBvc3NpYmxlIHRvIGludHJvZHVjZSBuZXcgc3ludGFj
dGljYWwgZWxlbWVudHMgYW5kIGNoYW5nZSBvcGVyYXRvciBwcmVjZWRlbmNlIChlc3BlY2lhbGx5
IHJlZ2FyZGluZyB0aGUgZmlsdGVyIG9wZXJhdG9yIHdoaWNoIGZpbmFsbHkgYmluZHMgaGFyZGVy
IHRoYW4gcGx1cykuIFdlIGFkZGVkIG1vcmUgdW5pdHRlc3RzIHRvIGNoZWNrIGlmIEppbmphIHN0
YXlzIGNvbXBhdGlibGUgd2l0aCB0aGUgcHl0aG9uIHNlbWFudGljcyB3ZSBoYWQgcHJldmlvdXNs
eSBhbmQgYWxsIDE1MyB0ZXN0cyBwYXNzIDotKQoKV2l0aCB0aGUgbmV3IHBhcnNlciB3ZSBhbHNv
IHNpbXBsaWZpZWQgdGhlIHN5bnRheCBhIGJpdCwgbWFkZSB0aGUgImNhbGwiIGEga2V5d29yZCBu
b3cgYW5kIGFkZGVkIGEgY291cGxlIG9mIG5ldyBmZWF0dXJlcy4gRm9yIGV4YW1wbGUgdGhlIGRl
YnVnZ2VyICh3aXRoIHRoZSBvcHRpb25hbCBjIGV4dGVuc2lvbiBjb21waWxlZCkgaXMgbm93IGFi
bGUgdG8gcmV3cml0ZSBhbGwgamluamEgZnJhbWVzIGluIGEgdHJhY2ViYWNrIHNvIHlvdSB3aWxs
IG5ldmVyIGZpbmQgeW91cnNlbGYgaW4gdGhlIHNpdHVhdGlvbiB3aGVyZSBsaW5lIG51bWJlcnMg
ZG9uJ3QgbWF0Y2ggdGhlIHRlbXBsYXRlIGxpbmUgbnVtYmVycy4KCkFub3RoZXIgbmV3IHN5bnRh
eCBmZWF0dXJlIGFyZSBjb25kaXRpb25hbCBleHByZXNzaW9ucyBkZXJpdmVkIGZyb20gcHl0aG9u
Mi41IChFUwAAAARjb2RlTAAATQAAUwAAABp7eyBmb28gaWYgZXhwciBlbHNlIGJhciB9fVMAAAAD
KS4gRVMAAAAEY29kZUwAAE0AAFMAAAAFZm9vLjBTAAAAFCBpcyBub3cgdGhlIHNhbWUgYXMgRVMA
AAAEY29kZUwAAE0AAFMAAAAGZm9vWzBdUwAAANMgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBkamFu
Z28gYW5kIHR1cGxlcyBhcmUgZmluYWxseSB0dXBsZXMgYW5kIG5vdCBsaXN0cyB3aGljaCBtYWtl
cyBpdCBwb3NzaWJsZSB0byB1c2Ugc3RyaW5nIGZvcm1hdHRpbmdzIHdpdGggbW9yZSB0aGFuIG9u
ZSB2YWx1ZS4gVGVzdCBmdW5jdGlvbnMgd2l0aCBvbmUgcGFyYW1ldGVyIGRvbid0IG5lZWQgcGFy
ZW50aGVzZXMgc28gRVMAAAAEY29kZUwAAE0AAFMAAAAae3sgZm9vIGlzIGZlZWxpbmcod2VsbCkg
fX1TAAAAFyBjYW4gbm93IGJlIHdyaXR0ZW4gYXMgRVMAAAAEY29kZUwAAE0AAFMAAAAZe3sgZm9v
IGlzIGZlZWxpbmcgd2VsbCB9fVMAAADILgoKV2UgYWxzbyBhZGRlZCBhIGNvbmNhdGVuYXRpb24g
b3BlcmF0b3IgdGhhdCBjb252ZXJ0cyBhbGwgYXJndW1lbnRzIGludG8gYSBzdHJpbmcgYXV0b21h
dGljYWxseSB0byBjb25jYXRlbmF0ZSB0aGVtLiBUaGlzIGlzIHZlcnkgdXNlZnVsIGlmIHlvdSBo
YXZlIHNvbWUgaW50ZWdlcnMgYW5kIG90aGVyIHZhbHVlcyB5b3Ugd2FudCB0byBqb2luOiBFUwAA
AARjb2RlTAAATQAAUwAAABV7eyBmb28gfiBiYXIgfiBiYXogfX1TAAAAGSwgd2hpY2ggaXMgZXF1
aXZhbGVudCB0byBFUwAAAARjb2RlTAAATQAAUwAAACp7eyBmb298c3RyaW5nICsgYmFyfHN0cmlu
ZyArIGJhenxzdHJpbmcgfX1TAAABZC4KCkFub3RoZXIgZ3JlYXQgbmV3IGZlYXR1cmUgKGlmIHlv
dSBhcmUgYSBkamFuZ28gdXNlcikgaXMgdGhlIG5ldyBkamFuZ28gc3VwcG9ydCBtb2R1bGUgd2hp
Y2ggbWFrZXMgaXQgYSBsb3QgZWFzaWVyIHRvIGludGVncmF0ZSBKaW5qYSBpbnRvIGRqYW5nby4g
SXQgbWFrZXMgaXQgcG9zc2libGUgdG8gdXNlIGRqYW5nbyBmaWx0ZXJzIGluIEppbmphIGFuZCBs
b2FkIGZyb20gdGhlIHNhbWUgZm9sZGVycy4KCkFzaWRlIGZyb20gdGhhdCB0aGVyZSBhcmUgY291
cGxlIG9mIGltcHJvdmVtZW50cyBhbmQgYnVnZml4ZXMuIEFzIGFsd2F5cyB5b3UgY2FuIGVhc3kg
aW5zdGFsbCBKaW5qYSBkaXJlY3RseSBmcm9tIHB5cGkgb3IgRVMAAAABYUwAAE0AAVMAAAAEaHJl
ZlMAAAAlaHR0cDovL3B5cGkucHl0aG9uLm9yZy9weXBpL0ppbmphLzEuMlMAAAALZG93bmxvYWQg
aXRTAAAAAS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Wokdave.null@example.org2007-12-10T06:46:11Znono0I deeply like APT, so I won’t upgrade manually but wait for the package to come, hope that doesn’t take too long. Keep on the good work.I deeply like APT, so I won’t upgrade manually but wait for the package to come, hope that doesn’t take too long. Keep on the good work.SQAAAAJTAAAABGJvZHlSUwAAAIxJIGRlZXBseSBsaWtlIEFQVCwgc28gSSB3b27igJl0IHVwZ3Jh
ZGUgbWFudWFsbHkgYnV0IHdhaXQgZm9yIHRoZSBwYWNrYWdlIHRvIGNvbWUsIGhvcGUgdGhhdCBk
b2VzbuKAmXQgdGFrZSB0b28gbG9uZy4gS2VlcCBvbiB0aGUgZ29vZCB3b3JrLkwAAFMAAAAGcGFy
c2VyUwAAAARodG1s
What about… Pocoo?http://lucumr.pocoo.org/cogitations/2007/11/16/what-about%e2%80%a6-pocoo/2007-11-16T19:18:42Z2007-11-16T19:18:42ZArmin Ronacherwhat-about%e2%80%a6-pocooyesyes2If you have a look at the current pocoo homepage or the trac you will find out that the project is more or less unmaintained right now. There are many reasons for that but the most important one is that we will probably rework some parts of the webpage in the next time. Why is it like that? About two years ago I was working together with some other people (some of them are now part of the pocoo team) on the German ubuntu portal ubuntuusers.de. We have used and still use a heavily modified phpBB, MoinMoin wiki engine and some other components implemented as django pre-magic removal. Back then WSGI was something that just was a PEP and no implementation.
My big plan was to create a replacement for phpBB in Python and integrate it with Moin. However, two years later it looks like that this is not the best solution either. The main problem with have on ubuntuusers is not, that we have different programming languages, we have different auth systems, templates, databases, storage systems etc. One minor change in a template requires modifications in three different applications.
While we don't have a solution for ubuntuusers *yet* it turns out that pocoo won't be one either. However pocoo was and is no failure. One the long path to pocoo we created some good and not so good libraries. There was Colubrid which was one of the first WSGI dispatchers out there and it's successor Werkzeug which will have it's first release in two weeks. There is Jinja which is now used on a couple of big django projects, there is Pygments which soon became the favorite sourcecode highlighter of many developers, there will be TextPress around this Christmas, which will be the first big python blog engine as far as I know. Georg Brandl also started the new python documentation project in the pocoo repositories where some of us contributed some code or knowledege.
But what will happen to pocoo? Right now nothing, just that we will probably replace the pocoo.org index page with something that points directly to the projects. After christmas (in fact after the TextPress release) I want to have another look at the pocoo sourcecode and make parts of the code standalone packages. For example the config file parser. And after all that half of the team will have finished a different project which currently takes some of our time and continue working on the pocoo forum, probably with a different name and finally based on all the libraries that evolved around it.
Why I'm writing that today? Around that date two years ago I was setting up the pocoo.org server and reading the WSGI specs. From then on two years of hacking on multiple pieces of software where some of them became popular enough that people are using them :-)
So in that sense: Thanks Georg, Alexander, Benjamin, Christopher, Lukas, Ferdinand, Tassilo and all the others that worked on the pocoo projects :-)If you have a look at the current pocoo homepage or the trac you will find out that the project is more or less unmaintained right now. There are many reasons for that but the most important one is that we will probably rework some parts of the webpage in the next time. Why is it like that? About two years ago I was working together with some other people (some of them are now part of the pocoo team) on the German ubuntu portal ubuntuusers.de. We have used and still use a heavily modified phpBB, MoinMoin wiki engine and some other components implemented as django pre-magic removal. Back then WSGI was something that just was a PEP and no implementation.
My big plan was to create a replacement for phpBB in Python and integrate it with Moin. However, two years later it looks like that this is not the best solution either. The main problem with have on ubuntuusers is not, that we have different programming languages, we have different auth systems, templates, databases, storage systems etc. One minor change in a template requires modifications in three different applications.
While we don't have a solution for ubuntuusers *yet* it turns out that pocoo won't be one either. However pocoo was and is no failure. One the long path to pocoo we created some good and not so good libraries. There was Colubrid which was one of the first WSGI dispatchers out there and it's successor Werkzeug which will have it's first release in two weeks. There is Jinja which is now used on a couple of big django projects, there is Pygments which soon became the favorite sourcecode highlighter of many developers, there will be TextPress around this Christmas, which will be the first big python blog engine as far as I know. Georg Brandl also started the new python documentation project in the pocoo repositories where some of us contributed some code or knowledege.
But what will happen to pocoo? Right now nothing, just that we will probably replace the pocoo.org index page with something that points directly to the projects. After christmas (in fact after the TextPress release) I want to have another look at the pocoo sourcecode and make parts of the code standalone packages. For example the config file parser. And after all that half of the team will have finished a different project which currently takes some of our time and continue working on the pocoo forum, probably with a different name and finally based on all the libraries that evolved around it.
Why I'm writing that today? Around that date two years ago I was setting up the pocoo.org server and reading the WSGI specs. From then on two years of hacking on multiple pieces of software where some of them became popular enough that people are using them :-)
So in that sense: Thanks Georg, Alexander, Benjamin, Christopher, Lukas, Ferdinand, Tassilo and all the others that worked on the pocoo projects :-)SQAAAANTAAAABGJvZHlSUwAAC0JJZiB5b3UgaGF2ZSBhIGxvb2sgYXQgdGhlIGN1cnJlbnQgcG9j
b28gaG9tZXBhZ2Ugb3IgdGhlIHRyYWMgeW91IHdpbGwgZmluZCBvdXQgdGhhdCB0aGUgcHJvamVj
dCBpcyBtb3JlIG9yIGxlc3MgdW5tYWludGFpbmVkIHJpZ2h0IG5vdy4gVGhlcmUgYXJlIG1hbnkg
cmVhc29ucyBmb3IgdGhhdCBidXQgdGhlIG1vc3QgaW1wb3J0YW50IG9uZSBpcyB0aGF0IHdlIHdp
bGwgcHJvYmFibHkgcmV3b3JrIHNvbWUgcGFydHMgb2YgdGhlIHdlYnBhZ2UgaW4gdGhlIG5leHQg
dGltZS4gV2h5IGlzIGl0IGxpa2UgdGhhdD8gQWJvdXQgdHdvIHllYXJzIGFnbyBJIHdhcyB3b3Jr
aW5nIHRvZ2V0aGVyIHdpdGggc29tZSBvdGhlciBwZW9wbGUgKHNvbWUgb2YgdGhlbSBhcmUgbm93
IHBhcnQgb2YgdGhlIHBvY29vIHRlYW0pIG9uIHRoZSBHZXJtYW4gdWJ1bnR1IHBvcnRhbCB1YnVu
dHV1c2Vycy5kZS4gV2UgaGF2ZSB1c2VkIGFuZCBzdGlsbCB1c2UgYSBoZWF2aWx5IG1vZGlmaWVk
IHBocEJCLCBNb2luTW9pbiB3aWtpIGVuZ2luZSBhbmQgc29tZSBvdGhlciBjb21wb25lbnRzIGlt
cGxlbWVudGVkIGFzIGRqYW5nbyBwcmUtbWFnaWMgcmVtb3ZhbC4gQmFjayB0aGVuIFdTR0kgd2Fz
IHNvbWV0aGluZyB0aGF0IGp1c3Qgd2FzIGEgUEVQIGFuZCBubyBpbXBsZW1lbnRhdGlvbi4KCk15
IGJpZyBwbGFuIHdhcyB0byBjcmVhdGUgYSByZXBsYWNlbWVudCBmb3IgcGhwQkIgaW4gUHl0aG9u
IGFuZCBpbnRlZ3JhdGUgaXQgd2l0aCBNb2luLiBIb3dldmVyLCB0d28geWVhcnMgbGF0ZXIgaXQg
bG9va3MgbGlrZSB0aGF0IHRoaXMgaXMgbm90IHRoZSBiZXN0IHNvbHV0aW9uIGVpdGhlci4gVGhl
IG1haW4gcHJvYmxlbSB3aXRoIGhhdmUgb24gdWJ1bnR1dXNlcnMgaXMgbm90LCB0aGF0IHdlIGhh
dmUgZGlmZmVyZW50IHByb2dyYW1taW5nIGxhbmd1YWdlcywgd2UgaGF2ZSBkaWZmZXJlbnQgYXV0
aCBzeXN0ZW1zLCB0ZW1wbGF0ZXMsIGRhdGFiYXNlcywgc3RvcmFnZSBzeXN0ZW1zIGV0Yy4gT25l
IG1pbm9yIGNoYW5nZSBpbiBhIHRlbXBsYXRlIHJlcXVpcmVzIG1vZGlmaWNhdGlvbnMgaW4gdGhy
ZWUgZGlmZmVyZW50IGFwcGxpY2F0aW9ucy4KCldoaWxlIHdlIGRvbid0IGhhdmUgYSBzb2x1dGlv
biBmb3IgdWJ1bnR1dXNlcnMgKnlldCogaXQgdHVybnMgb3V0IHRoYXQgcG9jb28gd29uJ3QgYmUg
b25lIGVpdGhlci4gSG93ZXZlciBwb2NvbyB3YXMgYW5kIGlzIG5vIGZhaWx1cmUuIE9uZSB0aGUg
bG9uZyBwYXRoIHRvIHBvY29vIHdlIGNyZWF0ZWQgc29tZSBnb29kIGFuZCBub3Qgc28gZ29vZCBs
aWJyYXJpZXMuIFRoZXJlIHdhcyBDb2x1YnJpZCB3aGljaCB3YXMgb25lIG9mIHRoZSBmaXJzdCBX
U0dJIGRpc3BhdGNoZXJzIG91dCB0aGVyZSBhbmQgaXQncyBzdWNjZXNzb3IgV2Vya3pldWcgd2hp
Y2ggd2lsbCBoYXZlIGl0J3MgZmlyc3QgcmVsZWFzZSBpbiB0d28gd2Vla3MuIFRoZXJlIGlzIEpp
bmphIHdoaWNoIGlzIG5vdyB1c2VkIG9uIGEgY291cGxlIG9mIGJpZyBkamFuZ28gcHJvamVjdHMs
IHRoZXJlIGlzIFB5Z21lbnRzIHdoaWNoIHNvb24gYmVjYW1lIHRoZSBmYXZvcml0ZSBzb3VyY2Vj
b2RlIGhpZ2hsaWdodGVyIG9mIG1hbnkgZGV2ZWxvcGVycywgdGhlcmUgd2lsbCBiZSBUZXh0UHJl
c3MgYXJvdW5kIHRoaXMgQ2hyaXN0bWFzLCB3aGljaCB3aWxsIGJlIHRoZSBmaXJzdCBiaWcgcHl0
aG9uIGJsb2cgZW5naW5lIGFzIGZhciBhcyBJIGtub3cuIEdlb3JnIEJyYW5kbCBhbHNvIHN0YXJ0
ZWQgdGhlIG5ldyBweXRob24gZG9jdW1lbnRhdGlvbiBwcm9qZWN0IGluIHRoZSBwb2NvbyByZXBv
c2l0b3JpZXMgd2hlcmUgc29tZSBvZiB1cyBjb250cmlidXRlZCBzb21lIGNvZGUgb3Iga25vd2xl
ZGVnZS4KCkJ1dCB3aGF0IHdpbGwgaGFwcGVuIHRvIHBvY29vPyBSaWdodCBub3cgbm90aGluZywg
anVzdCB0aGF0IHdlIHdpbGwgcHJvYmFibHkgcmVwbGFjZSB0aGUgcG9jb28ub3JnIGluZGV4IHBh
Z2Ugd2l0aCBzb21ldGhpbmcgdGhhdCBwb2ludHMgZGlyZWN0bHkgdG8gdGhlIHByb2plY3RzLiBB
ZnRlciBjaHJpc3RtYXMgKGluIGZhY3QgYWZ0ZXIgdGhlIFRleHRQcmVzcyByZWxlYXNlKSBJIHdh
bnQgdG8gaGF2ZSBhbm90aGVyIGxvb2sgYXQgdGhlIHBvY29vIHNvdXJjZWNvZGUgYW5kIG1ha2Ug
cGFydHMgb2YgdGhlIGNvZGUgc3RhbmRhbG9uZSBwYWNrYWdlcy4gRm9yIGV4YW1wbGUgdGhlIGNv
bmZpZyBmaWxlIHBhcnNlci4gQW5kIGFmdGVyIGFsbCB0aGF0IGhhbGYgb2YgdGhlIHRlYW0gd2ls
bCBoYXZlIGZpbmlzaGVkIGEgZGlmZmVyZW50IHByb2plY3Qgd2hpY2ggY3VycmVudGx5IHRha2Vz
IHNvbWUgb2Ygb3VyIHRpbWUgYW5kIGNvbnRpbnVlIHdvcmtpbmcgb24gdGhlIHBvY29vIGZvcnVt
LCBwcm9iYWJseSB3aXRoIGEgZGlmZmVyZW50IG5hbWUgYW5kIGZpbmFsbHkgYmFzZWQgb24gYWxs
IHRoZSBsaWJyYXJpZXMgdGhhdCBldm9sdmVkIGFyb3VuZCBpdC4KCldoeSBJJ20gd3JpdGluZyB0
aGF0IHRvZGF5PyBBcm91bmQgdGhhdCBkYXRlIHR3byB5ZWFycyBhZ28gSSB3YXMgc2V0dGluZyB1
cCB0aGUgcG9jb28ub3JnIHNlcnZlciBhbmQgcmVhZGluZyB0aGUgV1NHSSBzcGVjcy4gRnJvbSB0
aGVuIG9uIHR3byB5ZWFycyBvZiBoYWNraW5nIG9uIG11bHRpcGxlIHBpZWNlcyBvZiBzb2Z0d2Fy
ZSB3aGVyZSBzb21lIG9mIHRoZW0gYmVjYW1lIHBvcHVsYXIgZW5vdWdoIHRoYXQgcGVvcGxlIGFy
ZSB1c2luZyB0aGVtIDotKQoKU28gaW4gdGhhdCBzZW5zZTogVGhhbmtzIEdlb3JnLCBBbGV4YW5k
ZXIsIEJlbmphbWluLCBDaHJpc3RvcGhlciwgTHVrYXMsIEZlcmRpbmFuZCwgVGFzc2lsbyBhbmQg
YWxsIHRoZSBvdGhlcnMgdGhhdCB3b3JrZWQgb24gdGhlIHBvY29vIHByb2plY3RzIDotKUwAAFMA
AAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
EnTeQuAkcg@webshox.orghttp://ubuntuusers.de2007-11-17T11:21:33Znono0And of course: Thank you for founding most of the projects you mentioned above.
I hope that TextPress will grow up fast to get a new nice and big community. I think TextPress will be a big rival for Wordpress. Of course it needs some time to write all the plugins and features Wordpress (and others) implements. But I think TextPress' infastrucutre is as nice as most of your work Armin.
So keep on working and have a nice day!And of course: Thank you for founding most of the projects you mentioned above.
I hope that TextPress will grow up fast to get a new nice and big community. I think TextPress will be a big rival for Wordpress. Of course it needs some time to write all the plugins and features Wordpress (and others) implements. But I think TextPress' infastrucutre is as nice as most of your work Armin.
So keep on working and have a nice day!SQAAAAJTAAAABGJvZHlSUwAAAa1BbmQgb2YgY291cnNlOiBUaGFuayB5b3UgZm9yIGZvdW5kaW5n
IG1vc3Qgb2YgdGhlIHByb2plY3RzIHlvdSBtZW50aW9uZWQgYWJvdmUuCgpJIGhvcGUgdGhhdCBU
ZXh0UHJlc3Mgd2lsbCBncm93IHVwIGZhc3QgdG8gZ2V0IGEgbmV3IG5pY2UgYW5kIGJpZyBjb21t
dW5pdHkuIEkgdGhpbmsgVGV4dFByZXNzIHdpbGwgYmUgYSBiaWcgcml2YWwgZm9yIFdvcmRwcmVz
cy4gT2YgY291cnNlIGl0IG5lZWRzIHNvbWUgdGltZSB0byB3cml0ZSBhbGwgdGhlIHBsdWdpbnMg
YW5kIGZlYXR1cmVzIFdvcmRwcmVzcyAoYW5kIG90aGVycykgaW1wbGVtZW50cy4gQnV0IEkgdGhp
bmsgVGV4dFByZXNzJyBpbmZhc3RydWN1dHJlIGlzIGFzIG5pY2UgYXMgbW9zdCBvZiB5b3VyIHdv
cmsgQXJtaW4uCgpTbyBrZWVwIG9uIHdvcmtpbmcgYW5kIGhhdmUgYSBuaWNlIGRheSFMAABTAAAA
BnBhcnNlclMAAAAEaHRtbA==
Christianchristian.soeder@gmail.comhttp://www.christian-soeder.de2007-11-17T12:45:03Znono0I’m looking forward to the release of TextPress, although I don’t know yet if I’ll be able to find a nice hoster which supports Python. Anyway, good luck to you. :)I’m looking forward to the release of TextPress, although I don’t know yet if I’ll be able to find a nice hoster which supports Python. Anyway, good luck to you. :)SQAAAAJTAAAABGJvZHlSUwAAAKpJ4oCZbSBsb29raW5nIGZvcndhcmQgdG8gdGhlIHJlbGVhc2Ug
b2YgVGV4dFByZXNzLCBhbHRob3VnaCBJIGRvbuKAmXQga25vdyB5ZXQgaWYgSeKAmWxsIGJlIGFi
bGUgdG8gZmluZCBhIG5pY2UgaG9zdGVyIHdoaWNoIHN1cHBvcnRzIFB5dGhvbi4gQW55d2F5LCBn
b29kIGx1Y2sgdG8geW91LiA6KUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Python Wishlisthttp://lucumr.pocoo.org/cogitations/2007/11/15/python-wishlist/2007-11-15T14:46:35Z2007-11-15T14:46:35ZArmin Ronacherpython-wishlistyesyes2<ul>
<li>new, non-flat stdlib that follows PEP 8</li>
<li>absolute imports only</li>
<li>coroutines</li>
<li>assignments as expressions</li>
<li>better scoping</li>
<li>a with-statement that executes blocks instead of wrapping code</li>
</ul><ul>
<li>new, non-flat stdlib that follows PEP 8</li>
<li>absolute imports only</li>
<li>coroutines</li>
<li>assignments as expressions</li>
<li>better scoping</li>
<li>a with-statement that executes blocks instead of wrapping code</li>
</ul>SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAJ1bEwABkVTAAAAAmxpTAAATQAAUwAAACduZXcs
IG5vbi1mbGF0IHN0ZGxpYiB0aGF0IGZvbGxvd3MgUEVQIDhTAAAAAwogIEVTAAAAAmxpTAAATQAA
UwAAABVhYnNvbHV0ZSBpbXBvcnRzIG9ubHlTAAAAAwogIEVTAAAAAmxpTAAATQAAUwAAAApjb3Jv
dXRpbmVzUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAAaYXNzaWdubWVudHMgYXMgZXhwcmVzc2lv
bnNTAAAAAwogIEVTAAAAAmxpTAAATQAAUwAAAA5iZXR0ZXIgc2NvcGluZ1MAAAADCiAgRVMAAAAC
bGlMAABNAABTAAAAPmEgd2l0aC1zdGF0ZW1lbnQgdGhhdCBleGVjdXRlcyBibG9ja3MgaW5zdGVh
ZCBvZiB3cmFwcGluZyBjb2RlUwAAAAEKTQAAUwAAAAMKICBTAAAAAFMAAAAGcGFyc2VyUwAAAARo
dG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Brettbrett@python.orghttp://drbrett.ca2007-11-16T02:52:19Znono0You will get 1 and 2 in Python 3.0.
Not sure what you are after in 3, but if you want the ability to set variables in an enclosing scope you have that in 2.6.
You will never get 3, period. Too prone to errors by overlooking the assignment. Or a typo where you meant a comparison.
Not sure what you are after for 4.
5 is not going to happen as that would require new syntax that we most likely would have found by now for lambda.You will get 1 and 2 in Python 3.0.
Not sure what you are after in 3, but if you want the ability to set variables in an enclosing scope you have that in 2.6.
You will never get 3, period. Too prone to errors by overlooking the assignment. Or a typo where you meant a comparison.
Not sure what you are after for 4.
5 is not going to happen as that would require new syntax that we most likely would have found by now for lambda.SQAAAAJTAAAABGJvZHlSUwAAAbJZb3Ugd2lsbCBnZXQgMSBhbmQgMiBpbiBQeXRob24gMy4wLgoK
Tm90IHN1cmUgd2hhdCB5b3UgYXJlIGFmdGVyIGluIDMsIGJ1dCBpZiB5b3Ugd2FudCB0aGUgYWJp
bGl0eSB0byBzZXQgdmFyaWFibGVzIGluIGFuIGVuY2xvc2luZyBzY29wZSB5b3UgaGF2ZSB0aGF0
IGluIDIuNi4KCllvdSB3aWxsIG5ldmVyIGdldCAzLCBwZXJpb2QuICBUb28gcHJvbmUgdG8gZXJy
b3JzIGJ5IG92ZXJsb29raW5nIHRoZSBhc3NpZ25tZW50LiAgT3IgYSB0eXBvIHdoZXJlIHlvdSBt
ZWFudCBhIGNvbXBhcmlzb24uCgpOb3Qgc3VyZSB3aGF0IHlvdSBhcmUgYWZ0ZXIgZm9yIDQuCgo1
IGlzIG5vdCBnb2luZyB0byBoYXBwZW4gYXMgdGhhdCB3b3VsZCByZXF1aXJlIG5ldyBzeW50YXgg
dGhhdCB3ZSBtb3N0IGxpa2VseSB3b3VsZCBoYXZlIGZvdW5kIGJ5IG5vdyBmb3IgbGFtYmRhLkwA
AFMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-11-16T09:11:10Znono0I think you mixed up the numbers. Coroutines is something I normally don't miss. But when it comes to writing, say, a mod_python compatibility interface for WSGI you would need coroutines, otherwise there is no way to make a request.write("...") emit a yield "...".
I know that the assignments as expressions thing is something I will never get but I can tell you that I know countless people that think Python is lacking exactly that :-)
The scoping problems I have are mostly fixed in Python 3 with the introduction of the nonlocal keyword. However because assignments are not expressions and afair nonlocal is no expression either we still can't do “something(lambda x: nonlocal foo = x)” and have to create a function in a function (which yes, is the same, but a lot more verbose).
Yes, with backwards compatibility for the current with one would have to find a new syntax for that.
Regards,
ArminI think you mixed up the numbers. Coroutines is something I normally don't miss. But when it comes to writing, say, a mod_python compatibility interface for WSGI you would need coroutines, otherwise there is no way to make a request.write("...") emit a yield "...".
I know that the assignments as expressions thing is something I will never get but I can tell you that I know countless people that think Python is lacking exactly that :-)
The scoping problems I have are mostly fixed in Python 3 with the introduction of the nonlocal keyword. However because assignments are not expressions and afair nonlocal is no expression either we still can't do “something(lambda x: nonlocal foo = x)” and have to create a function in a function (which yes, is the same, but a lot more verbose).
Yes, with backwards compatibility for the current with one would have to find a new syntax for that.
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAA45JIHRoaW5rIHlvdSBtaXhlZCB1cCB0aGUgbnVtYmVycy4gQ29y
b3V0aW5lcyBpcyBzb21ldGhpbmcgSSBub3JtYWxseSBkb24ndCBtaXNzLiBCdXQgd2hlbiBpdCBj
b21lcyB0byB3cml0aW5nLCBzYXksIGEgbW9kX3B5dGhvbiBjb21wYXRpYmlsaXR5IGludGVyZmFj
ZSBmb3IgV1NHSSB5b3Ugd291bGQgbmVlZCBjb3JvdXRpbmVzLCBvdGhlcndpc2UgdGhlcmUgaXMg
bm8gd2F5IHRvIG1ha2UgYSByZXF1ZXN0LndyaXRlKCIuLi4iKSBlbWl0IGEgeWllbGQgIi4uLiIu
CgpJIGtub3cgdGhhdCB0aGUgYXNzaWdubWVudHMgYXMgZXhwcmVzc2lvbnMgdGhpbmcgaXMgc29t
ZXRoaW5nIEkgd2lsbCBuZXZlciBnZXQgYnV0IEkgY2FuIHRlbGwgeW91IHRoYXQgSSBrbm93IGNv
dW50bGVzcyBwZW9wbGUgdGhhdCB0aGluayBQeXRob24gaXMgbGFja2luZyBleGFjdGx5IHRoYXQg
Oi0pCgpUaGUgc2NvcGluZyBwcm9ibGVtcyBJIGhhdmUgYXJlIG1vc3RseSBmaXhlZCBpbiBQeXRo
b24gMyB3aXRoIHRoZSBpbnRyb2R1Y3Rpb24gb2YgdGhlIG5vbmxvY2FsIGtleXdvcmQuIEhvd2V2
ZXIgYmVjYXVzZSBhc3NpZ25tZW50cyBhcmUgbm90IGV4cHJlc3Npb25zIGFuZCBhZmFpciBub25s
b2NhbCBpcyBubyBleHByZXNzaW9uIGVpdGhlciB3ZSBzdGlsbCBjYW4ndCBkbyDigJxzb21ldGhp
bmcobGFtYmRhIHg6IG5vbmxvY2FsIGZvbyA9IHgp4oCdIGFuZCBoYXZlIHRvIGNyZWF0ZSBhIGZ1
bmN0aW9uIGluIGEgZnVuY3Rpb24gKHdoaWNoIHllcywgaXMgdGhlIHNhbWUsIGJ1dCBhIGxvdCBt
b3JlIHZlcmJvc2UpLgoKWWVzLCB3aXRoIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGZvciB0aGUg
Y3VycmVudCB3aXRoIG9uZSB3b3VsZCBoYXZlIHRvIGZpbmQgYSBuZXcgc3ludGF4IGZvciB0aGF0
LiAKClJlZ2FyZHMsCkFybWluTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Brynjarbrymag@gmail.com2007-11-29T09:41:55Znono0Stackless python has coroutinesStackless python has coroutinesSQAAAAJTAAAABGJvZHlSUwAAAB9TdGFja2xlc3MgcHl0aG9uIGhhcyBjb3JvdXRpbmVzTAAAUwAA
AAZwYXJzZXJTAAAABGh0bWw=
The Latest Downtimehttp://lucumr.pocoo.org/cogitations/2007/11/15/the-latest-downtime/2007-11-15T13:19:03Z2007-11-15T13:19:03ZArmin Ronacherthe-latest-downtimeyesyes2From yesterday 18:00 until now pocoo.org and all the related domains (including wiki.python.de and pygments.org) where down because we moved all the xen instances to a new hetzner server. However the RAM usage by the instances is still unchanged so there will be another small downtime in the next few days. And small is ~20 minutes. Because I expected that the migration will take less time I have to postpone the upcoming Jinja release until Saturday.
Additionally we're struggling with a mod_wsgi bug that is probably not mod_wsgi's fault. Under certain conditions a C extension seems to not release the GIL which the result that one apache process consumes all the processor power available.
Sorry for the inconveniences caused.
<strong>Update:</strong> resource relocation done (for the moment at least)From yesterday 18:00 until now pocoo.org and all the related domains (including wiki.python.de and pygments.org) where down because we moved all the xen instances to a new hetzner server. However the RAM usage by the instances is still unchanged so there will be another small downtime in the next few days. And small is ~20 minutes. Because I expected that the migration will take less time I have to postpone the upcoming Jinja release until Saturday.
Additionally we're struggling with a mod_wsgi bug that is probably not mod_wsgi's fault. Under certain conditions a C extension seems to not release the GIL which the result that one apache process consumes all the processor power available.
Sorry for the inconveniences caused.
<strong>Update:</strong> resource relocation done (for the moment at least)SQAAAANTAAAABGJvZHlSUwAAAuBGcm9tIHllc3RlcmRheSAxODowMCB1bnRpbCBub3cgcG9jb28u
b3JnIGFuZCBhbGwgdGhlIHJlbGF0ZWQgZG9tYWlucyAoaW5jbHVkaW5nIHdpa2kucHl0aG9uLmRl
IGFuZCBweWdtZW50cy5vcmcpIHdoZXJlIGRvd24gYmVjYXVzZSB3ZSBtb3ZlZCBhbGwgdGhlIHhl
biBpbnN0YW5jZXMgdG8gYSBuZXcgaGV0em5lciBzZXJ2ZXIuIEhvd2V2ZXIgdGhlIFJBTSB1c2Fn
ZSBieSB0aGUgaW5zdGFuY2VzIGlzIHN0aWxsIHVuY2hhbmdlZCBzbyB0aGVyZSB3aWxsIGJlIGFu
b3RoZXIgc21hbGwgZG93bnRpbWUgaW4gdGhlIG5leHQgZmV3IGRheXMuIEFuZCBzbWFsbCBpcyB+
MjAgbWludXRlcy4gQmVjYXVzZSBJIGV4cGVjdGVkIHRoYXQgdGhlIG1pZ3JhdGlvbiB3aWxsIHRh
a2UgbGVzcyB0aW1lIEkgaGF2ZSB0byBwb3N0cG9uZSB0aGUgdXBjb21pbmcgSmluamEgcmVsZWFz
ZSB1bnRpbCBTYXR1cmRheS4KCkFkZGl0aW9uYWxseSB3ZSdyZSBzdHJ1Z2dsaW5nIHdpdGggYSBt
b2Rfd3NnaSBidWcgdGhhdCBpcyBwcm9iYWJseSBub3QgbW9kX3dzZ2kncyBmYXVsdC4gVW5kZXIg
Y2VydGFpbiBjb25kaXRpb25zIGEgQyBleHRlbnNpb24gc2VlbXMgdG8gbm90IHJlbGVhc2UgdGhl
IEdJTCB3aGljaCB0aGUgcmVzdWx0IHRoYXQgb25lIGFwYWNoZSBwcm9jZXNzIGNvbnN1bWVzIGFs
bCB0aGUgcHJvY2Vzc29yIHBvd2VyIGF2YWlsYWJsZS4KClNvcnJ5IGZvciB0aGUgaW5jb252ZW5p
ZW5jZXMgY2F1c2VkLgoKTAABRVMAAAAGc3Ryb25nTAAATQAAUwAAAAdVcGRhdGU6UwAAADMgcmVz
b3VyY2UgcmVsb2NhdGlvbiBkb25lIChmb3IgdGhlIG1vbWVudCBhdCBsZWFzdClTAAAABnBhcnNl
clMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2007-11-15T22:09:08Znono0FWIW, if it is correct that it is the C extension module that is blocking or going into a tight loop without releasing the GIL, then technically this could cause a problem with mod_python or even if being used in a standalone Python based web server. This is what makes the problem so strange, as one would expect to see such other hosting systems also affected.
In the case of mod_python, or embedded mode of mod_wsgi, then one process no longer processing requests would cause Apache to go and create extra child processes, up to its max, in order process new requests. Thus, although host performance would be reduced if something is running in a tight loop, the server would still keep functioning, at least until enough processes got stuck in this state that the machine just couldn't handle the load. I have actually heard of some cases like this, so it may be the same issue.
For a standalone Python web server running in a single process, then the whole server would just hang and only restarting it would fix it.
The question thus is whether the issue is being seen with other hosting solutions, or whether for some reason the problematic C extension module is acting a bit differently when run under mod_wsgi.
Anyway, on the presumption that the problems are caused by a C extension module not releasing the GIL, have added code for mod_wsgi 2.0 which will detect a deadlock on the Python GIL and forcibly shutdown the daemon process.
http://groups.google.com/group/modwsgi/browse_frm/thread/1f1e8139123465d6
This should help to at least recover from such a problem occurring with a problematic C extension module.FWIW, if it is correct that it is the C extension module that is blocking or going into a tight loop without releasing the GIL, then technically this could cause a problem with mod_python or even if being used in a standalone Python based web server. This is what makes the problem so strange, as one would expect to see such other hosting systems also affected.
In the case of mod_python, or embedded mode of mod_wsgi, then one process no longer processing requests would cause Apache to go and create extra child processes, up to its max, in order process new requests. Thus, although host performance would be reduced if something is running in a tight loop, the server would still keep functioning, at least until enough processes got stuck in this state that the machine just couldn't handle the load. I have actually heard of some cases like this, so it may be the same issue.
For a standalone Python web server running in a single process, then the whole server would just hang and only restarting it would fix it.
The question thus is whether the issue is being seen with other hosting solutions, or whether for some reason the problematic C extension module is acting a bit differently when run under mod_wsgi.
Anyway, on the presumption that the problems are caused by a C extension module not releasing the GIL, have added code for mod_wsgi 2.0 which will detect a deadlock on the Python GIL and forcibly shutdown the daemon process.
http://groups.google.com/group/modwsgi/browse_frm/thread/1f1e8139123465d6
This should help to at least recover from such a problem occurring with a problematic C extension module.SQAAAAJTAAAABGJvZHlSUwAABmBGV0lXLCBpZiBpdCBpcyBjb3JyZWN0IHRoYXQgaXQgaXMgdGhl
IEMgZXh0ZW5zaW9uIG1vZHVsZSB0aGF0IGlzIGJsb2NraW5nIG9yIGdvaW5nIGludG8gYSB0aWdo
dCBsb29wIHdpdGhvdXQgcmVsZWFzaW5nIHRoZSBHSUwsIHRoZW4gdGVjaG5pY2FsbHkgdGhpcyBj
b3VsZCBjYXVzZSBhIHByb2JsZW0gd2l0aCBtb2RfcHl0aG9uIG9yIGV2ZW4gaWYgYmVpbmcgdXNl
ZCBpbiBhIHN0YW5kYWxvbmUgUHl0aG9uIGJhc2VkIHdlYiBzZXJ2ZXIuIFRoaXMgaXMgd2hhdCBt
YWtlcyB0aGUgcHJvYmxlbSBzbyBzdHJhbmdlLCBhcyBvbmUgd291bGQgZXhwZWN0IHRvIHNlZSBz
dWNoIG90aGVyIGhvc3Rpbmcgc3lzdGVtcyBhbHNvIGFmZmVjdGVkLgoKSW4gdGhlIGNhc2Ugb2Yg
bW9kX3B5dGhvbiwgb3IgZW1iZWRkZWQgbW9kZSBvZiBtb2Rfd3NnaSwgdGhlbiBvbmUgcHJvY2Vz
cyBubyBsb25nZXIgcHJvY2Vzc2luZyByZXF1ZXN0cyB3b3VsZCBjYXVzZSBBcGFjaGUgdG8gZ28g
YW5kIGNyZWF0ZSBleHRyYSBjaGlsZCBwcm9jZXNzZXMsIHVwIHRvIGl0cyBtYXgsIGluIG9yZGVy
IHByb2Nlc3MgbmV3IHJlcXVlc3RzLiBUaHVzLCBhbHRob3VnaCBob3N0IHBlcmZvcm1hbmNlIHdv
dWxkIGJlIHJlZHVjZWQgaWYgc29tZXRoaW5nIGlzIHJ1bm5pbmcgaW4gYSB0aWdodCBsb29wLCB0
aGUgc2VydmVyIHdvdWxkIHN0aWxsIGtlZXAgZnVuY3Rpb25pbmcsIGF0IGxlYXN0IHVudGlsIGVu
b3VnaCBwcm9jZXNzZXMgZ290IHN0dWNrIGluIHRoaXMgc3RhdGUgdGhhdCB0aGUgbWFjaGluZSBq
dXN0IGNvdWxkbid0IGhhbmRsZSB0aGUgbG9hZC4gSSBoYXZlIGFjdHVhbGx5IGhlYXJkIG9mIHNv
bWUgY2FzZXMgbGlrZSB0aGlzLCBzbyBpdCBtYXkgYmUgdGhlIHNhbWUgaXNzdWUuCgpGb3IgYSBz
dGFuZGFsb25lIFB5dGhvbiB3ZWIgc2VydmVyIHJ1bm5pbmcgaW4gYSBzaW5nbGUgcHJvY2Vzcywg
dGhlbiB0aGUgd2hvbGUgc2VydmVyIHdvdWxkIGp1c3QgaGFuZyBhbmQgb25seSByZXN0YXJ0aW5n
IGl0IHdvdWxkIGZpeCBpdC4KClRoZSBxdWVzdGlvbiB0aHVzIGlzIHdoZXRoZXIgdGhlIGlzc3Vl
IGlzIGJlaW5nIHNlZW4gd2l0aCBvdGhlciBob3N0aW5nIHNvbHV0aW9ucywgb3Igd2hldGhlciBm
b3Igc29tZSByZWFzb24gdGhlIHByb2JsZW1hdGljIEMgZXh0ZW5zaW9uIG1vZHVsZSBpcyBhY3Rp
bmcgYSBiaXQgZGlmZmVyZW50bHkgd2hlbiBydW4gdW5kZXIgbW9kX3dzZ2kuCgpBbnl3YXksIG9u
IHRoZSBwcmVzdW1wdGlvbiB0aGF0IHRoZSBwcm9ibGVtcyBhcmUgY2F1c2VkIGJ5IGEgQyBleHRl
bnNpb24gbW9kdWxlIG5vdCByZWxlYXNpbmcgdGhlIEdJTCwgaGF2ZSBhZGRlZCBjb2RlIGZvciBt
b2Rfd3NnaSAyLjAgd2hpY2ggd2lsbCBkZXRlY3QgYSBkZWFkbG9jayBvbiB0aGUgUHl0aG9uIEdJ
TCBhbmQgZm9yY2libHkgc2h1dGRvd24gdGhlIGRhZW1vbiBwcm9jZXNzLgoKICBodHRwOi8vZ3Jv
dXBzLmdvb2dsZS5jb20vZ3JvdXAvbW9kd3NnaS9icm93c2VfZnJtL3RocmVhZC8xZjFlODEzOTEy
MzQ2NWQ2CgpUaGlzIHNob3VsZCBoZWxwIHRvIGF0IGxlYXN0IHJlY292ZXIgZnJvbSBzdWNoIGEg
cHJvYmxlbSBvY2N1cnJpbmcgd2l0aCBhIHByb2JsZW1hdGljIEMgZXh0ZW5zaW9uIG1vZHVsZS5M
AABTAAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-11-15T22:12:29Znono0I upgraded the server to wsgi trunk today and it successfully recovered from one of those deadlocks/gil problems/“funny things”. We also disabled the loading of the svn module and the problem still appeared so svn lib (unfortunately) is not to blame.
Maybe some libraries have problems when run in a sub interpreter. That would explain why things behave differently when run under mod_wsgi.I upgraded the server to wsgi trunk today and it successfully recovered from one of those deadlocks/gil problems/“funny things”. We also disabled the loading of the svn module and the problem still appeared so svn lib (unfortunately) is not to blame.
Maybe some libraries have problems when run in a sub interpreter. That would explain why things behave differently when run under mod_wsgi.SQAAAAJTAAAABGJvZHlSUwAAAYtJIHVwZ3JhZGVkIHRoZSBzZXJ2ZXIgdG8gd3NnaSB0cnVuayB0
b2RheSBhbmQgaXQgc3VjY2Vzc2Z1bGx5IHJlY292ZXJlZCBmcm9tIG9uZSBvZiB0aG9zZSBkZWFk
bG9ja3MvZ2lsIHByb2JsZW1zL+KAnGZ1bm55IHRoaW5nc+KAnS4gV2UgYWxzbyBkaXNhYmxlZCB0
aGUgbG9hZGluZyBvZiB0aGUgc3ZuIG1vZHVsZSBhbmQgdGhlIHByb2JsZW0gc3RpbGwgYXBwZWFy
ZWQgc28gc3ZuIGxpYiAodW5mb3J0dW5hdGVseSkgaXMgbm90IHRvIGJsYW1lLgoKTWF5YmUgc29t
ZSBsaWJyYXJpZXMgaGF2ZSBwcm9ibGVtcyB3aGVuIHJ1biBpbiBhIHN1YiBpbnRlcnByZXRlci4g
VGhhdCB3b3VsZCBleHBsYWluIHdoeSB0aGluZ3MgYmVoYXZlIGRpZmZlcmVudGx5IHdoZW4gcnVu
IHVuZGVyIG1vZF93c2dpLkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2007-11-16T00:25:50Znono0Good to hear the deadlock check worked in practice then.
As for it being to do with a sub interpreter rather than being the main interpreter, don't think this is the case as other site seeing this issue is definitely setting WSGIApplicationGroup to %{GLOBAL} and so forcing use of main interpreter.
The other site was also suspicious of ClearSilver and database adapter. I haven't completely ruled out yet something odd happening in mod_wsgi, but then seems to only occur when using Trac.Good to hear the deadlock check worked in practice then.
As for it being to do with a sub interpreter rather than being the main interpreter, don't think this is the case as other site seeing this issue is definitely setting WSGIApplicationGroup to %{GLOBAL} and so forcing use of main interpreter.
The other site was also suspicious of ClearSilver and database adapter. I haven't completely ruled out yet something odd happening in mod_wsgi, but then seems to only occur when using Trac.SQAAAAJTAAAABGJvZHlSUwAAAepHb29kIHRvIGhlYXIgdGhlIGRlYWRsb2NrIGNoZWNrIHdvcmtl
ZCBpbiBwcmFjdGljZSB0aGVuLgoKQXMgZm9yIGl0IGJlaW5nIHRvIGRvIHdpdGggYSBzdWIgaW50
ZXJwcmV0ZXIgcmF0aGVyIHRoYW4gYmVpbmcgdGhlIG1haW4gaW50ZXJwcmV0ZXIsIGRvbid0IHRo
aW5rIHRoaXMgaXMgdGhlIGNhc2UgYXMgb3RoZXIgc2l0ZSBzZWVpbmcgdGhpcyBpc3N1ZSBpcyBk
ZWZpbml0ZWx5IHNldHRpbmcgV1NHSUFwcGxpY2F0aW9uR3JvdXAgdG8gJXtHTE9CQUx9IGFuZCBz
byBmb3JjaW5nIHVzZSBvZiBtYWluIGludGVycHJldGVyLgoKVGhlIG90aGVyIHNpdGUgd2FzIGFs
c28gc3VzcGljaW91cyBvZiBDbGVhclNpbHZlciBhbmQgZGF0YWJhc2UgYWRhcHRlci4gSSBoYXZl
bid0IGNvbXBsZXRlbHkgcnVsZWQgb3V0IHlldCBzb21ldGhpbmcgb2RkIGhhcHBlbmluZyBpbiBt
b2Rfd3NnaSwgYnV0IHRoZW4gc2VlbXMgdG8gb25seSBvY2N1ciB3aGVuIHVzaW5nIFRyYWMuTAAA
UwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-11-16T09:35:33Znono0We use trac 0.11, so no clearsilver. But both trac-hacks and pocoo.org use postgres :-/We use trac 0.11, so no clearsilver. But both trac-hacks and pocoo.org use postgres :-/SQAAAAJTAAAABGJvZHlSUwAAAFdXZSB1c2UgdHJhYyAwLjExLCBzbyBubyBjbGVhcnNpbHZlci4g
QnV0IGJvdGggdHJhYy1oYWNrcyBhbmQgcG9jb28ub3JnIHVzZSBwb3N0Z3JlcyA6LS9MAABTAAAA
BnBhcnNlclMAAAAEaHRtbA==
Hello Planet Ubuntuhttp://lucumr.pocoo.org/cogitations/2007/11/14/hello-planet-ubuntu/2007-11-14T10:47:58Z2007-11-14T10:47:58ZArmin Ronacherhello-planet-ubuntuyesyes2Although I'm blogging for quite a long time and I'm active in the German locoteam I haven't blogged much about ubuntu so far. As a matter of fact I haven't added myself to the ubuntu planet. However that will change now because of many reasons, one of them is that we are cleaning up some of the code that runs <a href="http://ubuntuusers.de/">ubuntuusers</a> and I find countless things that are worth mentioning.
But because the blog is quite high traffic and there are more Python or Ruby related posts than ubuntu related things I've only submitted posts tagged as "planetubuntu" to the planet. So it's worth reading the blog behind that funny head too if you're interested in one of those topics.
So: Hello Planet Ubuntu!Although I'm blogging for quite a long time and I'm active in the German locoteam I haven't blogged much about ubuntu so far. As a matter of fact I haven't added myself to the ubuntu planet. However that will change now because of many reasons, one of them is that we are cleaning up some of the code that runs <a href="http://ubuntuusers.de/">ubuntuusers</a> and I find countless things that are worth mentioning.
But because the blog is quite high traffic and there are more Python or Ruby related posts than ubuntu related things I've only submitted posts tagged as "planetubuntu" to the planet. So it's worth reading the blog behind that funny head too if you're interested in one of those topics.
So: Hello Planet Ubuntu!SQAAAANTAAAABGJvZHlSUwAAATdBbHRob3VnaCBJJ20gYmxvZ2dpbmcgZm9yIHF1aXRlIGEgbG9u
ZyB0aW1lIGFuZCBJJ20gYWN0aXZlIGluIHRoZSBHZXJtYW4gbG9jb3RlYW0gSSBoYXZlbid0IGJs
b2dnZWQgbXVjaCBhYm91dCB1YnVudHUgc28gZmFyLiBBcyBhIG1hdHRlciBvZiBmYWN0IEkgaGF2
ZW4ndCBhZGRlZCBteXNlbGYgdG8gdGhlIHVidW50dSBwbGFuZXQuIEhvd2V2ZXIgdGhhdCB3aWxs
IGNoYW5nZSBub3cgYmVjYXVzZSBvZiBtYW55IHJlYXNvbnMsIG9uZSBvZiB0aGVtIGlzIHRoYXQg
d2UgYXJlIGNsZWFuaW5nIHVwIHNvbWUgb2YgdGhlIGNvZGUgdGhhdCBydW5zIEwAAUVTAAAAAWFM
AABNAAFTAAAABGhyZWZTAAAAFmh0dHA6Ly91YnVudHV1c2Vycy5kZS9TAAAAC3VidW50dXVzZXJz
UwAAAXEgYW5kIEkgZmluZCBjb3VudGxlc3MgdGhpbmdzIHRoYXQgYXJlIHdvcnRoIG1lbnRpb25p
bmcuCgpCdXQgYmVjYXVzZSB0aGUgYmxvZyBpcyBxdWl0ZSBoaWdoIHRyYWZmaWMgYW5kIHRoZXJl
IGFyZSBtb3JlIFB5dGhvbiBvciBSdWJ5IHJlbGF0ZWQgcG9zdHMgdGhhbiB1YnVudHUgcmVsYXRl
ZCB0aGluZ3MgSSd2ZSBvbmx5IHN1Ym1pdHRlZCBwb3N0cyB0YWdnZWQgYXMgInBsYW5ldHVidW50
dSIgdG8gdGhlIHBsYW5ldC4gU28gaXQncyB3b3J0aCByZWFkaW5nIHRoZSBibG9nIGJlaGluZCB0
aGF0IGZ1bm55IGhlYWQgdG9vIGlmIHlvdSdyZSBpbnRlcmVzdGVkIGluIG9uZSBvZiB0aG9zZSB0
b3BpY3MuCgpTbzogSGVsbG8gUGxhbmV0IFVidW50dSFTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAF
aW50cm9SUwAAAABMAAA=
Christopher Denterspammenot@the-space-station.comhttp://www.the-space-station.com/blog2007-11-14T13:13:11Znono0Hi Armin!
Nice to see you here, too. :)
regardsHi Armin!
Nice to see you here, too. :)
regardsSQAAAAJTAAAABGJvZHlSUwAAADBIaSBBcm1pbiEKTmljZSB0byBzZWUgeW91IGhlcmUsIHRvby4g
OikKCnJlZ2FyZHNMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Christoph Hackchristoph@tux21b.orghttp://www.tux21b.org/2007-11-14T17:45:26Znono0Hi Armin,
seems that you are going to like planets. But I must admit that I am already addicted to our local planet too. :D
RegardsHi Armin,
seems that you are going to like planets. But I must admit that I am already addicted to our local planet too. :D
RegardsSQAAAAJTAAAABGJvZHlSUwAAAIRIaSBBcm1pbiwKc2VlbXMgdGhhdCB5b3UgYXJlIGdvaW5nIHRv
IGxpa2UgcGxhbmV0cy4gQnV0IEkgbXVzdCBhZG1pdCB0aGF0IEkgYW0gYWxyZWFkeSBhZGRpY3Rl
ZCB0byBvdXIgbG9jYWwgcGxhbmV0IHRvby4gOkQKClJlZ2FyZHNMAABTAAAABnBhcnNlclMAAAAE
aHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-11-14T18:05:11Znono0Which local? :D
Regards,
ArminWhich local? :D
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAB9XaGljaCBsb2NhbD8gOkQKClJlZ2FyZHMsCkFybWluTAAAUwAA
AAZwYXJzZXJTAAAABGh0bWw=
Christoph Hackchristoph@tux21b.orghttp://www.tux21b.org/2007-11-14T18:16:03Znono0Why are you asking? Of course I mean the "best-planet-ever" (beside of planet.ubuntu.com - you now have readers from there, right? *g*)
RegardsWhy are you asking? Of course I mean the "best-planet-ever" (beside of planet.ubuntu.com - you now have readers from there, right? *g*)
RegardsSQAAAAJTAAAABGJvZHlSUwAAAJBXaHkgYXJlIHlvdSBhc2tpbmc/IE9mIGNvdXJzZSBJIG1lYW4g
dGhlICJiZXN0LXBsYW5ldC1ldmVyIiAoYmVzaWRlIG9mIHBsYW5ldC51YnVudHUuY29tIC0geW91
IG5vdyBoYXZlIHJlYWRlcnMgZnJvbSB0aGVyZSwgcmlnaHQ/ICpnKikKClJlZ2FyZHNMAABTAAAA
BnBhcnNlclMAAAAEaHRtbA==
Two Finger Scrolling on Ubuntuhttp://lucumr.pocoo.org/cogitations/2007/11/13/two-finger-scrolling-on-ubuntu/2007-11-13T07:05:53Z2007-11-13T07:05:53ZArmin Ronachertwo-finger-scrolling-on-ubuntuyesyes2One of the things I love about Macbook is that it has this nifty two finger scrolling enabled by default. But thanks to the awesome synaptics linux driver you can get that on any ubuntu system too as long as your touchpad isn't too old. There are countless tutorials on that on the web, however there is one stupid pitfall.
If you enable two finger scrolling you will most likely hit a “feature” of Firefox. It will go forward and backward in history under some strange conditions. It may be useful if one can figure out how to trigger it, but the better way is to disable it like it's on OS X. Set the following settings in your about:config:
<pre>mousewheel.horizscroll.withnokey.action = 0
mousewheel.horizscroll.withnokey.sysnumlines = true</pre>
Just for completeness here my xorg.conf settings:
<pre>Section "InputDevice"
Identifier "Synaptics Touchpad"
Driver "synaptics"
Option "SendCoreEvents" "true"
Option "Device" "/dev/psaux"
Option "Protocol" "auto-dev"
Option "MaxTapTime" "120"
Option "MaxTapMove" "150"
Option "VertTwoFingerScroll" "true"
Option "HorizTwoFingerScroll" "true"
Option "VertEdgeScroll" "false"
Option "HorizEdgeScroll" "false"
Option "TapButton1" "1"
Option "TapButton2" "3"
Option "TapButton3" "2"
Option "Emulate3Buttons" "true"
Option "SHMConfig" "true"
EndSection</pre>One of the things I love about Macbook is that it has this nifty two finger scrolling enabled by default. But thanks to the awesome synaptics linux driver you can get that on any ubuntu system too as long as your touchpad isn't too old. There are countless tutorials on that on the web, however there is one stupid pitfall.
If you enable two finger scrolling you will most likely hit a “feature” of Firefox. It will go forward and backward in history under some strange conditions. It may be useful if one can figure out how to trigger it, but the better way is to disable it like it's on OS X. Set the following settings in your about:config:
<pre>mousewheel.horizscroll.withnokey.action = 0
mousewheel.horizscroll.withnokey.sysnumlines = true</pre>
Just for completeness here my xorg.conf settings:
<pre>Section "InputDevice"
Identifier "Synaptics Touchpad"
Driver "synaptics"
Option "SendCoreEvents" "true"
Option "Device" "/dev/psaux"
Option "Protocol" "auto-dev"
Option "MaxTapTime" "120"
Option "MaxTapMove" "150"
Option "VertTwoFingerScroll" "true"
Option "HorizTwoFingerScroll" "true"
Option "VertEdgeScroll" "false"
Option "HorizEdgeScroll" "false"
Option "TapButton1" "1"
Option "TapButton2" "3"
Option "TapButton3" "2"
Option "Emulate3Buttons" "true"
Option "SHMConfig" "true"
EndSection</pre>SQAAAANTAAAABGJvZHlSUwAAAolPbmUgb2YgdGhlIHRoaW5ncyBJIGxvdmUgYWJvdXQgTWFjYm9v
ayBpcyB0aGF0IGl0IGhhcyB0aGlzIG5pZnR5IHR3byBmaW5nZXIgc2Nyb2xsaW5nIGVuYWJsZWQg
YnkgZGVmYXVsdC4gQnV0IHRoYW5rcyB0byB0aGUgYXdlc29tZSBzeW5hcHRpY3MgbGludXggZHJp
dmVyIHlvdSBjYW4gZ2V0IHRoYXQgb24gYW55IHVidW50dSBzeXN0ZW0gdG9vIGFzIGxvbmcgYXMg
eW91ciB0b3VjaHBhZCBpc24ndCB0b28gb2xkLiBUaGVyZSBhcmUgY291bnRsZXNzIHR1dG9yaWFs
cyBvbiB0aGF0IG9uIHRoZSB3ZWIsIGhvd2V2ZXIgdGhlcmUgaXMgb25lIHN0dXBpZCBwaXRmYWxs
LgoKSWYgeW91IGVuYWJsZSB0d28gZmluZ2VyIHNjcm9sbGluZyB5b3Ugd2lsbCBtb3N0IGxpa2Vs
eSBoaXQgYSDigJxmZWF0dXJl4oCdIG9mIEZpcmVmb3guIEl0IHdpbGwgZ28gZm9yd2FyZCBhbmQg
YmFja3dhcmQgaW4gaGlzdG9yeSB1bmRlciBzb21lIHN0cmFuZ2UgY29uZGl0aW9ucy4gSXQgbWF5
IGJlIHVzZWZ1bCBpZiBvbmUgY2FuIGZpZ3VyZSBvdXQgaG93IHRvIHRyaWdnZXIgaXQsIGJ1dCB0
aGUgYmV0dGVyIHdheSBpcyB0byBkaXNhYmxlIGl0IGxpa2UgaXQncyBvbiBPUyBYLiBTZXQgdGhl
IGZvbGxvd2luZyBzZXR0aW5ncyBpbiB5b3VyIGFib3V0OmNvbmZpZzoKTAACRVMAAAADcHJlTAAA
TQAAUwAAAF9tb3VzZXdoZWVsLmhvcml6c2Nyb2xsLndpdGhub2tleS5hY3Rpb24gPSAwCm1vdXNl
d2hlZWwuaG9yaXpzY3JvbGwud2l0aG5va2V5LnN5c251bWxpbmVzID0gdHJ1ZVMAAAA0CgpKdXN0
IGZvciBjb21wbGV0ZW5lc3MgaGVyZSBteSB4b3JnLmNvbmYgc2V0dGluZ3M6CkVTAAAAA3ByZUwA
AE0AAFMAAAN0U2VjdGlvbiAiSW5wdXREZXZpY2UiCiAgICAgICAgSWRlbnRpZmllciAgICAgICJT
eW5hcHRpY3MgVG91Y2hwYWQiCiAgICAgICAgRHJpdmVyICAgICAgICAgICJzeW5hcHRpY3MiCiAg
ICAgICAgT3B0aW9uICAgICAgICAgICJTZW5kQ29yZUV2ZW50cyIgICAgICAgICJ0cnVlIgogICAg
ICAgIE9wdGlvbiAgICAgICAgICAiRGV2aWNlIiAgICAgICAgICAgICAgICAiL2Rldi9wc2F1eCIK
ICAgICAgICBPcHRpb24gICAgICAgICAgIlByb3RvY29sIiAgICAgICAgICAgICAgImF1dG8tZGV2
IgogICAgICAgIE9wdGlvbiAgICAgICAgICAiTWF4VGFwVGltZSIgICAgICAgICAgICAiMTIwIgog
ICAgICAgIE9wdGlvbiAgICAgICAgICAiTWF4VGFwTW92ZSIgICAgICAgICAgICAiMTUwIgogICAg
ICAgIE9wdGlvbiAgICAgICAgICAiVmVydFR3b0ZpbmdlclNjcm9sbCIgICAidHJ1ZSIKICAgICAg
ICBPcHRpb24gICAgICAgICAgIkhvcml6VHdvRmluZ2VyU2Nyb2xsIiAgInRydWUiCiAgICAgICAg
T3B0aW9uICAgICAgICAgICJWZXJ0RWRnZVNjcm9sbCIgICAgICAgICJmYWxzZSIKICAgICAgICBP
cHRpb24gICAgICAgICAgIkhvcml6RWRnZVNjcm9sbCIgICAgICAgImZhbHNlIgogICAgICAgIE9w
dGlvbiAgICAgICAgICAiVGFwQnV0dG9uMSIgICAgICAgICAgICAiMSIKICAgICAgICBPcHRpb24g
ICAgICAgICAgIlRhcEJ1dHRvbjIiICAgICAgICAgICAgIjMiCiAgICAgICAgT3B0aW9uICAgICAg
ICAgICJUYXBCdXR0b24zIiAgICAgICAgICAgICIyIgogICAgICAgIE9wdGlvbiAgICAgICAgICAi
RW11bGF0ZTNCdXR0b25zIiAgICAgICAidHJ1ZSIKICAgICAgICBPcHRpb24gICAgICAgICAgIlNI
TUNvbmZpZyIgICAgICAgICAgICAgInRydWUiCkVuZFNlY3Rpb25TAAAAAFMAAAAGcGFyc2VyUwAA
AARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
bsheepthebsheep@gmail.com2007-11-14T11:35:01Znono0Does it work for non macbook laptop ?Does it work for non macbook laptop ?SQAAAAJTAAAABGJvZHlSUwAAACVEb2VzIGl0IHdvcmsgZm9yIG5vbiBtYWNib29rIGxhcHRvcCA/
TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Stenever@use.your.real.mail2007-11-14T15:00:56Znono0Dank Dir, das kannte ich noch nicht. Sehr nützlich!Dank Dir, das kannte ich noch nicht. Sehr nützlich!SQAAAAJTAAAABGJvZHlSUwAAADREYW5rIERpciwgZGFzIGthbm50ZSBpY2ggbm9jaCBuaWNodC4g
U2VociBuw7x0emxpY2ghTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-11-14T16:34:22Znono0Yes it works with other notebooks too. I have three notebooks here (one as old as 5 years) and it works with all of them. However the driver documentation states that it requires hardware support so I guess that feature does not exist in every synaptics touchpad.Yes it works with other notebooks too. I have three notebooks here (one as old as 5 years) and it works with all of them. However the driver documentation states that it requires hardware support so I guess that feature does not exist in every synaptics touchpad.SQAAAAJTAAAABGJvZHlSUwAAAQlZZXMgaXQgd29ya3Mgd2l0aCBvdGhlciBub3RlYm9va3MgdG9v
LiAgSSBoYXZlIHRocmVlIG5vdGVib29rcyBoZXJlIChvbmUgYXMgb2xkIGFzIDUgeWVhcnMpIGFu
ZCBpdCB3b3JrcyB3aXRoIGFsbCBvZiB0aGVtLiAgSG93ZXZlciB0aGUgZHJpdmVyIGRvY3VtZW50
YXRpb24gc3RhdGVzIHRoYXQgaXQgcmVxdWlyZXMgaGFyZHdhcmUgc3VwcG9ydCBzbyBJIGd1ZXNz
IHRoYXQgZmVhdHVyZSBkb2VzIG5vdCBleGlzdCBpbiBldmVyeSBzeW5hcHRpY3MgdG91Y2hwYWQu
TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
quinnten83dksluis@hotmail.com2007-11-16T10:43:57Znono0Thanks for this.
I don't use the two finger scrolling, but the effects in FF were driving me nuts. I just disabled them.Thanks for this.
I don't use the two finger scrolling, but the effects in FF were driving me nuts. I just disabled them.SQAAAAJTAAAABGJvZHlSUwAAAHhUaGFua3MgZm9yIHRoaXMuCkkgZG9uJ3QgdXNlIHRoZSB0d28g
ZmluZ2VyIHNjcm9sbGluZywgYnV0IHRoZSBlZmZlY3RzIGluIEZGIHdlcmUgZHJpdmluZyBtZSBu
dXRzLiBJIGp1c3QgZGlzYWJsZWQgdGhlbS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
bonq.net/flipp » Blog Archive » daily del.icio.ushttp://bonq.net/flipp/2007/12/29/daily-delicious-18/2007-12-30T02:20:44Znoyes0[...] Lucumr Cogitations » Blog Archive » Two Finger Scrolling on Ubuntu [...][...] Lucumr Cogitations » Blog Archive » Two Finger Scrolling on Ubuntu [...]SQAAAAJTAAAABGJvZHlSUwAAAFFbLi4uXSBMdWN1bXIgQ29naXRhdGlvbnMgwrsgQmxvZyBBcmNo
aXZlIMK7IFR3byBGaW5nZXIgU2Nyb2xsaW5nIG9uIFVidW50dSAgWy4uLl1MAABTAAAABnBhcnNl
clMAAAAEaHRtbA==
One Code Styleguide Per Programming Language Is Not Sillyhttp://lucumr.pocoo.org/cogitations/2007/11/04/one-code-styleguide-per-programming-language-is-not-silly/2007-11-04T09:35:03Z2007-11-04T09:35:03ZArmin Ronacherone-code-styleguide-per-programming-language-is-not-sillyyesyes2I love Python but there are things where I look at Ruby or Java and want to switch right away. What do have Ruby and Java in common? Nearly all of their libraries follow the same function/method/class naming conventions. <code>foo_bar_baz</code> in Ruby and <code>fooBarBaz</code> in Java. In Python there we have that PEP8 thing, but not even the standard library is PEP8 compatible. Many people tell me that not having the same naming guidelines for all libraries is a problem. I would argue that different naming guidelines among different libraries is a bigger problem than different indentation etc.
The reason for that is that in Python we often subclass clases from other libraries. Just take the threading module as example. Now we are forced to use different names in your own libraries/code too. Now one has to start thinking about the names of methods. (Is is <code>get_some_foo()</code> or <code>some_foo</code> or <code>getSomeFoo()</code>). It becomes even worse if you use mixin classes with one styleguide in a subclass of a class with a different one. I've seen people using the `DictMixin` in classes with camel case method names. But even the lowercase names are not coherent. Is it <code>iteritems</code> or <code>iter_items</code>? This example might be answered easily because I never saw <code>iter_items</code> but I saw countless occurrences of both <code>getcurrentuser</code> and <code>get_current_user</code>.
The more different name styles in a code the more I have to use dir(), help(), external documentation or the ipython source introspection. And that's not the fault of the library developers, it starts with the python language itself. The internal types are all lowercase although they are classes. It's true that this is because of backwards compatibility (when dict, list and others were just functions) but a big language change like Python3 would have made changing some of those names possible.
</rant>I love Python but there are things where I look at Ruby or Java and want to switch right away. What do have Ruby and Java in common? Nearly all of their libraries follow the same function/method/class naming conventions. <code>foo_bar_baz</code> in Ruby and <code>fooBarBaz</code> in Java. In Python there we have that PEP8 thing, but not even the standard library is PEP8 compatible. Many people tell me that not having the same naming guidelines for all libraries is a problem. I would argue that different naming guidelines among different libraries is a bigger problem than different indentation etc.
The reason for that is that in Python we often subclass clases from other libraries. Just take the threading module as example. Now we are forced to use different names in your own libraries/code too. Now one has to start thinking about the names of methods. (Is is <code>get_some_foo()</code> or <code>some_foo</code> or <code>getSomeFoo()</code>). It becomes even worse if you use mixin classes with one styleguide in a subclass of a class with a different one. I've seen people using the `DictMixin` in classes with camel case method names. But even the lowercase names are not coherent. Is it <code>iteritems</code> or <code>iter_items</code>? This example might be answered easily because I never saw <code>iter_items</code> but I saw countless occurrences of both <code>getcurrentuser</code> and <code>get_current_user</code>.
The more different name styles in a code the more I have to use dir(), help(), external documentation or the ipython source introspection. And that's not the fault of the library developers, it starts with the python language itself. The internal types are all lowercase although they are classes. It's true that this is because of backwards compatibility (when dict, list and others were just functions) but a big language change like Python3 would have made changing some of those names possible.
</rant>SQAAAANTAAAABGJvZHlSUwAAAN1JIGxvdmUgUHl0aG9uIGJ1dCB0aGVyZSBhcmUgdGhpbmdzIHdo
ZXJlIEkgbG9vayBhdCBSdWJ5IG9yIEphdmEgYW5kIHdhbnQgdG8gc3dpdGNoIHJpZ2h0IGF3YXku
IFdoYXQgZG8gaGF2ZSBSdWJ5IGFuZCBKYXZhIGluIGNvbW1vbj8gTmVhcmx5IGFsbCBvZiB0aGVp
ciBsaWJyYXJpZXMgZm9sbG93IHRoZSBzYW1lIGZ1bmN0aW9uL21ldGhvZC9jbGFzcyBuYW1pbmcg
Y29udmVudGlvbnMuIEwACkVTAAAABGNvZGVMAABNAABTAAAAC2Zvb19iYXJfYmF6UwAAAA0gaW4g
UnVieSBhbmQgRVMAAAAEY29kZUwAAE0AAFMAAAAJZm9vQmFyQmF6UwAAAlAgaW4gSmF2YS4gSW4g
UHl0aG9uIHRoZXJlIHdlIGhhdmUgdGhhdCBQRVA4IHRoaW5nLCBidXQgbm90IGV2ZW4gdGhlIHN0
YW5kYXJkIGxpYnJhcnkgaXMgUEVQOCBjb21wYXRpYmxlLiBNYW55IHBlb3BsZSB0ZWxsIG1lIHRo
YXQgbm90IGhhdmluZyB0aGUgc2FtZSBuYW1pbmcgZ3VpZGVsaW5lcyBmb3IgYWxsIGxpYnJhcmll
cyBpcyBhIHByb2JsZW0uIEkgd291bGQgYXJndWUgdGhhdCBkaWZmZXJlbnQgbmFtaW5nIGd1aWRl
bGluZXMgYW1vbmcgZGlmZmVyZW50IGxpYnJhcmllcyBpcyBhIGJpZ2dlciBwcm9ibGVtIHRoYW4g
ZGlmZmVyZW50IGluZGVudGF0aW9uIGV0Yy4KClRoZSByZWFzb24gZm9yIHRoYXQgaXMgdGhhdCBp
biBQeXRob24gd2Ugb2Z0ZW4gc3ViY2xhc3MgY2xhc2VzIGZyb20gb3RoZXIgbGlicmFyaWVzLiBK
dXN0IHRha2UgdGhlIHRocmVhZGluZyBtb2R1bGUgYXMgZXhhbXBsZS4gTm93IHdlIGFyZSBmb3Jj
ZWQgdG8gdXNlIGRpZmZlcmVudCBuYW1lcyBpbiB5b3VyIG93biBsaWJyYXJpZXMvY29kZSB0b28u
IE5vdyBvbmUgaGFzIHRvIHN0YXJ0IHRoaW5raW5nIGFib3V0IHRoZSBuYW1lcyBvZiBtZXRob2Rz
LiAoSXMgaXMgRVMAAAAEY29kZUwAAE0AAFMAAAAOZ2V0X3NvbWVfZm9vKClTAAAABCBvciBFUwAA
AARjb2RlTAAATQAAUwAAAAhzb21lX2Zvb1MAAAAEIG9yIEVTAAAABGNvZGVMAABNAABTAAAADGdl
dFNvbWVGb28oKVMAAAD7KS4gSXQgYmVjb21lcyBldmVuIHdvcnNlIGlmIHlvdSB1c2UgbWl4aW4g
Y2xhc3NlcyB3aXRoIG9uZSBzdHlsZWd1aWRlIGluIGEgc3ViY2xhc3Mgb2YgYSBjbGFzcyB3aXRo
IGEgZGlmZmVyZW50IG9uZS4gSSd2ZSBzZWVuIHBlb3BsZSB1c2luZyB0aGUgYERpY3RNaXhpbmAg
aW4gY2xhc3NlcyB3aXRoIGNhbWVsIGNhc2UgbWV0aG9kIG5hbWVzLiAgQnV0IGV2ZW4gdGhlIGxv
d2VyY2FzZSBuYW1lcyBhcmUgbm90IGNvaGVyZW50LiBJcyBpdCBFUwAAAARjb2RlTAAATQAAUwAA
AAlpdGVyaXRlbXNTAAAABCBvciBFUwAAAARjb2RlTAAATQAAUwAAAAppdGVyX2l0ZW1zUwAAADw/
IFRoaXMgZXhhbXBsZSBtaWdodCBiZSBhbnN3ZXJlZCBlYXNpbHkgYmVjYXVzZSBJIG5ldmVyIHNh
dyBFUwAAAARjb2RlTAAATQAAUwAAAAppdGVyX2l0ZW1zUwAAACkgYnV0IEkgc2F3IGNvdW50bGVz
cyBvY2N1cnJlbmNlcyBvZiBib3RoIEVTAAAABGNvZGVMAABNAABTAAAADmdldGN1cnJlbnR1c2Vy
UwAAAAUgYW5kIEVTAAAABGNvZGVMAABNAABTAAAAEGdldF9jdXJyZW50X3VzZXJTAAAB/i4KClRo
ZSBtb3JlIGRpZmZlcmVudCBuYW1lIHN0eWxlcyBpbiBhIGNvZGUgdGhlIG1vcmUgSSBoYXZlIHRv
IHVzZSBkaXIoKSwgaGVscCgpLCBleHRlcm5hbCBkb2N1bWVudGF0aW9uIG9yIHRoZSBpcHl0aG9u
IHNvdXJjZSBpbnRyb3NwZWN0aW9uLiBBbmQgdGhhdCdzIG5vdCB0aGUgZmF1bHQgb2YgdGhlIGxp
YnJhcnkgZGV2ZWxvcGVycywgaXQgc3RhcnRzIHdpdGggdGhlIHB5dGhvbiBsYW5ndWFnZSBpdHNl
bGYuIFRoZSBpbnRlcm5hbCB0eXBlcyBhcmUgYWxsIGxvd2VyY2FzZSBhbHRob3VnaCB0aGV5IGFy
ZSBjbGFzc2VzLiBJdCdzIHRydWUgdGhhdCB0aGlzIGlzIGJlY2F1c2Ugb2YgYmFja3dhcmRzIGNv
bXBhdGliaWxpdHkgKHdoZW4gZGljdCwgbGlzdCBhbmQgb3RoZXJzIHdlcmUganVzdCBmdW5jdGlv
bnMpIGJ1dCBhIGJpZyBsYW5ndWFnZSBjaGFuZ2UgbGlrZSBQeXRob24zIHdvdWxkIGhhdmUgbWFk
ZSBjaGFuZ2luZyBzb21lIG9mIHRob3NlIG5hbWVzIHBvc3NpYmxlLgoKPC9yYW50PlMAAAAGcGFy
c2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Brettbrett@python.org2007-11-04T19:50:14Znono0The biggest problem is that PEP 8 was not around when a bunch of stuff went into the stdlib (it didn't come until being until July 2001 which is over 11.5 years after Python's creation). While the module names will get fixed in Python 3.0, changing method and functions are harder as those can't be automated.
Hopefully we can, at some point, either rename methods and function slowly, or just replace/remove old modules.The biggest problem is that PEP 8 was not around when a bunch of stuff went into the stdlib (it didn't come until being until July 2001 which is over 11.5 years after Python's creation). While the module names will get fixed in Python 3.0, changing method and functions are harder as those can't be automated.
Hopefully we can, at some point, either rename methods and function slowly, or just replace/remove old modules.SQAAAAJTAAAABGJvZHlSUwAAAadUaGUgYmlnZ2VzdCBwcm9ibGVtIGlzIHRoYXQgUEVQIDggd2Fz
IG5vdCBhcm91bmQgd2hlbiBhIGJ1bmNoIG9mIHN0dWZmIHdlbnQgaW50byB0aGUgc3RkbGliIChp
dCBkaWRuJ3QgY29tZSB1bnRpbCBiZWluZyB1bnRpbCBKdWx5IDIwMDEgd2hpY2ggaXMgb3ZlciAx
MS41IHllYXJzIGFmdGVyIFB5dGhvbidzIGNyZWF0aW9uKS4gIFdoaWxlIHRoZSBtb2R1bGUgbmFt
ZXMgd2lsbCBnZXQgZml4ZWQgaW4gUHl0aG9uIDMuMCwgY2hhbmdpbmcgbWV0aG9kIGFuZCBmdW5j
dGlvbnMgYXJlIGhhcmRlciBhcyB0aG9zZSBjYW4ndCBiZSBhdXRvbWF0ZWQuCgpIb3BlZnVsbHkg
d2UgY2FuLCBhdCBzb21lIHBvaW50LCBlaXRoZXIgcmVuYW1lIG1ldGhvZHMgYW5kIGZ1bmN0aW9u
IHNsb3dseSwgb3IganVzdCByZXBsYWNlL3JlbW92ZSBvbGQgbW9kdWxlcy5MAABTAAAABnBhcnNl
clMAAAAEaHRtbA==
mqfoo@bar.baz2007-11-10T16:06:26Znono0Fully agreed. The names in the stdlib suck, and it sucks even more that many people and libraries don't adapt the PEP 8 style.Fully agreed. The names in the stdlib suck, and it sucks even more that many people and libraries don't adapt the PEP 8 style.SQAAAAJTAAAABGJvZHlSUwAAAH5GdWxseSBhZ3JlZWQuIFRoZSBuYW1lcyBpbiB0aGUgc3RkbGli
IHN1Y2ssIGFuZCBpdCBzdWNrcyBldmVuIG1vcmUgdGhhdCBtYW55IHBlb3BsZSBhbmQgbGlicmFy
aWVzIGRvbid0IGFkYXB0IHRoZSBQRVAgOCBzdHlsZS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
pretty, a python pprint successorhttp://lucumr.pocoo.org/cogitations/2007/10/21/pretty-a-python-pprint-successor/2007-10-21T20:24:20Z2007-10-21T20:24:20ZArmin Ronacherpretty-a-python-pprint-successoryesyes2The ubuntuusers team acquired two new webdesigners this week and the first thing that they missed was a <code>var_dump</code> replacement. In fact that thing is really missing. Python does have a pprint library but it's not extensible. Impossible to dump normal objects.
I worked today on a port of ruby's pp library (wanted to call it pp, but that's already reserved by parallel python). Check it out in the cheeseshop: <a href="http://pypi.python.org/pypi/pretty">pretty</a>.
Classes can implement <code>__pretty__</code> to prettyprint their structure.
I would love to see that as replacement for the builtin pprint library which is impossible to extend. pretty is not yet 100% backwards compatible, some reprs look different, but that's extensible. Check out the module docstring for some examples.The ubuntuusers team acquired two new webdesigners this week and the first thing that they missed was a <code>var_dump</code> replacement. In fact that thing is really missing. Python does have a pprint library but it's not extensible. Impossible to dump normal objects.
I worked today on a port of ruby's pp library (wanted to call it pp, but that's already reserved by parallel python). Check it out in the cheeseshop: <a href="http://pypi.python.org/pypi/pretty">pretty</a>.
Classes can implement <code>__pretty__</code> to prettyprint their structure.
I would love to see that as replacement for the builtin pprint library which is impossible to extend. pretty is not yet 100% backwards compatible, some reprs look different, but that's extensible. Check out the module docstring for some examples.SQAAAANTAAAABGJvZHlSUwAAAGhUaGUgdWJ1bnR1dXNlcnMgdGVhbSBhY3F1aXJlZCB0d28gbmV3
IHdlYmRlc2lnbmVycyB0aGlzIHdlZWsgYW5kIHRoZSBmaXJzdCB0aGluZyB0aGF0IHRoZXkgbWlz
c2VkIHdhcyBhIEwAA0VTAAAABGNvZGVMAABNAABTAAAACHZhcl9kdW1wUwAAASkgcmVwbGFjZW1l
bnQuIEluIGZhY3QgdGhhdCB0aGluZyBpcyByZWFsbHkgbWlzc2luZy4gUHl0aG9uIGRvZXMgaGF2
ZSBhIHBwcmludCBsaWJyYXJ5IGJ1dCBpdCdzIG5vdCBleHRlbnNpYmxlLiBJbXBvc3NpYmxlIHRv
IGR1bXAgbm9ybWFsIG9iamVjdHMuCgpJIHdvcmtlZCB0b2RheSBvbiBhIHBvcnQgb2YgcnVieSdz
IHBwIGxpYnJhcnkgKHdhbnRlZCB0byBjYWxsIGl0IHBwLCBidXQgdGhhdCdzIGFscmVhZHkgcmVz
ZXJ2ZWQgYnkgcGFyYWxsZWwgcHl0aG9uKS4gQ2hlY2sgaXQgb3V0IGluIHRoZSBjaGVlc2VzaG9w
OiBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACJodHRwOi8vcHlwaS5weXRob24ub3JnL3B5cGkv
cHJldHR5UwAAAAZwcmV0dHlTAAAAGS4KCkNsYXNzZXMgY2FuIGltcGxlbWVudCBFUwAAAARjb2Rl
TAAATQAAUwAAAApfX3ByZXR0eV9fUwAAARggdG8gcHJldHR5cHJpbnQgdGhlaXIgc3RydWN0dXJl
LgoKSSB3b3VsZCBsb3ZlIHRvIHNlZSB0aGF0IGFzIHJlcGxhY2VtZW50IGZvciB0aGUgYnVpbHRp
biBwcHJpbnQgbGlicmFyeSB3aGljaCBpcyBpbXBvc3NpYmxlIHRvIGV4dGVuZC4gcHJldHR5IGlz
IG5vdCB5ZXQgMTAwJSBiYWNrd2FyZHMgY29tcGF0aWJsZSwgc29tZSByZXBycyBsb29rIGRpZmZl
cmVudCwgYnV0IHRoYXQncyBleHRlbnNpYmxlLiBDaGVjayBvdXQgdGhlIG1vZHVsZSBkb2NzdHJp
bmcgZm9yIHNvbWUgZXhhbXBsZXMuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAA
TAAA
Female Nicknameshttp://lucumr.pocoo.org/cogitations/2007/10/16/female-nicknames/2007-10-16T14:39:06Z2007-10-16T14:39:06ZArmin Ronacherfemale-nicknamesyesyes2<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">* </span><span class="gi">Blindraven (n=tony@...optusnet.com.au) has joined #ubuntuusers-webteam</span>
<span class="cp">[15:46] </span><span class="nt"><Blindraven> ></span><
<span class="cp">[15:47] </span><span class="k">* </span><span class="gi">juliux (n=juliux@ubuntu/member/juliux) has joined #ubuntuusers-webteam</span>
<span class="cp">[15:47] </span><span class="nt"><mitsuhiko> </span>hi juliux
<span class="cp">[15:47] </span><span class="k">* </span><span class="gi">Blindraven ponders</span>
<span class="cp">[15:47] </span><span class="nt"><juliux> </span>hi mitsuhiko
<span class="cp">[15:48] </span><span class="nt"><Blindraven> </span>lol i join, nothing. you join with a remotely
female *ish* name and you get a hello.. LOL
<span class="cp">[15:48] </span><span class="k">* </span><span class="gi">Blindraven (n=tony@...optusnet.com.au) has left #ubuntuusers-webteam</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(irc)>* Blindraven (n=tony@...optusnet.com.au) has joined #ubuntuusers-webteam
[15:46] <Blindraven> ><
[15:47] * juliux (n=juliux@ubuntu/member/juliux) has joined #ubuntuusers-webteam
[15:47] <mitsuhiko> hi juliux
[15:47] * Blindraven ponders
[15:47] <juliux> hi mitsuhiko
[15:48] <Blindraven> lol i join, nothing. you join with a remotely
female *ish* name and you get a hello.. LOL
[15:48] * Blindraven (n=tony@...optusnet.com.au) has left #ubuntuusers-webteam<PYGMENTS_RAW -->
<small>just for the record: <a href="http://juliux.de/">julius</a> is not female ;-)</small>
<small>just for the record: <a href="http://juliux.de/">julius</a> is not female ;-)</small>SQAAAANTAAAABGJvZHlSUwAAAAEKTAABRVMAAAAFc21hbGxMAAFFUwAAAAFhTAAATQABUwAAAARo
cmVmUwAAABFodHRwOi8vanVsaXV4LmRlL1MAAAAGanVsaXVzUwAAABIgaXMgbm90IGZlbWFsZSA7
LSlNAABTAAAAFWp1c3QgZm9yIHRoZSByZWNvcmQ6IFMAAAAAUwAAAAZwYXJzZXJTAAAABGh0bWxT
AAAABWludHJvUlMAAAAATAAA
Blindraventhisemailisfake@becauseyouarespam.comhttp://www.blindraven.org2007-10-31T21:58:25Znono0Haha, I said female *name*.
What part did you not understand?
Anyway, another controversial quote - more inter-webz fame for me *shrug*.Haha, I said female *name*.
What part did you not understand?
Anyway, another controversial quote - more inter-webz fame for me *shrug*.SQAAAAJTAAAABGJvZHlSUwAAAIlIYWhhLCBJIHNhaWQgZmVtYWxlICpuYW1lKi4KV2hhdCBwYXJ0
IGRpZCB5b3Ugbm90IHVuZGVyc3RhbmQ/CgpBbnl3YXksIGFub3RoZXIgY29udHJvdmVyc2lhbCBx
dW90ZSAtIG1vcmUgaW50ZXItd2VieiBmYW1lIGZvciBtZSAqc2hydWcqLkwAAFMAAAAGcGFyc2Vy
UwAAAARodG1s
Rails Motivationhttp://lucumr.pocoo.org/cogitations/2007/10/16/rails-motivation/2007-10-16T13:20:50Z2007-10-16T13:20:50ZArmin Ronacherrails-motivationyesyes2<img class="standalone" src="http://pocoo.org/~mitsuhiko/rails_motivation.jpg" alt="fuck you"/>
<small>via __doc__</small><img src="http://pocoo.org/~mitsuhiko/rails_motivation.jpg" alt="fuck you" class="standalone">
<small>via __doc__</small>SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAANpbWdMAABNAANTAAAAA3NyY1MAAAAwaHR0cDov
L3BvY29vLm9yZy9+bWl0c3VoaWtvL3JhaWxzX21vdGl2YXRpb24uanBnUwAAAANhbHRTAAAACGZ1
Y2sgeW91UwAAAAVjbGFzc1MAAAAKc3RhbmRhbG9uZVMAAAAAUwAAAAEKRVMAAAAFc21hbGxMAABN
AABTAAAAC3ZpYSBfX2RvY19fUwAAAABTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAA
AABMAAA=
Pygments 0.9 – Herbstzeitlose Releasedhttp://lucumr.pocoo.org/cogitations/2007/10/14/pygments-09-%e2%80%93-herbstzeitlose-released/2007-10-14T21:08:05Z2007-10-14T21:08:05ZArmin Ronacherpygments-09-%e2%80%93-herbstzeitlose-releasedyesyes2The new version of <a href="http://pygments.org/">Pygments</a> is out now. The changelog is once again quite long and a couple of new lexers were added:
<ul>
<li>Erlang</li>
<li>ActionScript</li>
<li>Literate Haskell</li>
<li>Common Lisp</li>
<li>Various assembly languages</li>
<li>Gettext catalogs</li>
<li>Squid configuration</li>
<li>Debian control files</li>
<li>MySQL-style SQL</li>
<li>MOOCode</li>
</ul>
Some old lexers got updates too:
<ul>
<li>Greatly improved the Haskell and OCaml lexers.</li>
<li>Improved the Bash lexer's handling of nested constructs.</li>
<li>The C# and Java lexers exhibited abysmal performance with some input code; this should now be fixed.</li>
<li>The IRC logs lexer is now able to colorize weechat logs too.</li>
<li>The Lua lexer now recognizes multi-line comments.</li>
<li>Fixed bugs in the D and MiniD lexer.</li>
</ul>
There are also two new formatters. One that outputs SVG documents and a terminal formatter that uses 256 different colors if the terminals support that. There is also a new style which resembles the vim7 default style.
For the full list of changes have a look at the <a href="http://dev.pocoo.org/projects/pygments/browser/CHANGES">changelog</a>. You can download pygments from the <a href="http://pygments.org/download/">download page</a>. Happy coloring!The new version of <a href="http://pygments.org/">Pygments</a> is out now. The changelog is once again quite long and a couple of new lexers were added:
<ul>
<li>Erlang</li>
<li>ActionScript</li>
<li>Literate Haskell</li>
<li>Common Lisp</li>
<li>Various assembly languages</li>
<li>Gettext catalogs</li>
<li>Squid configuration</li>
<li>Debian control files</li>
<li>MySQL-style SQL</li>
<li>MOOCode</li>
</ul>
Some old lexers got updates too:
<ul>
<li>Greatly improved the Haskell and OCaml lexers.</li>
<li>Improved the Bash lexer's handling of nested constructs.</li>
<li>The C# and Java lexers exhibited abysmal performance with some input code; this should now be fixed.</li>
<li>The IRC logs lexer is now able to colorize weechat logs too.</li>
<li>The Lua lexer now recognizes multi-line comments.</li>
<li>Fixed bugs in the D and MiniD lexer.</li>
</ul>
There are also two new formatters. One that outputs SVG documents and a terminal formatter that uses 256 different colors if the terminals support that. There is also a new style which resembles the vim7 default style.
For the full list of changes have a look at the <a href="http://dev.pocoo.org/projects/pygments/browser/CHANGES">changelog</a>. You can download pygments from the <a href="http://pygments.org/download/">download page</a>. Happy coloring!SQAAAANTAAAABGJvZHlSUwAAABNUaGUgbmV3IHZlcnNpb24gb2YgTAAFRVMAAAABYUwAAE0AAVMA
AAAEaHJlZlMAAAAUaHR0cDovL3B5Z21lbnRzLm9yZy9TAAAACFB5Z21lbnRzUwAAAFsgaXMgb3V0
IG5vdy4gVGhlIGNoYW5nZWxvZyBpcyBvbmNlIGFnYWluIHF1aXRlIGxvbmcgYW5kIGEgY291cGxl
IG9mIG5ldyBsZXhlcnMgd2VyZSBhZGRlZDoKRVMAAAACdWxMAApFUwAAAAJsaUwAAE0AAFMAAAAG
RXJsYW5nUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAAMQWN0aW9uU2NyaXB0UwAAAAMKICBFUwAA
AAJsaUwAAE0AAFMAAAAQTGl0ZXJhdGUgSGFza2VsbFMAAAADCiAgRVMAAAACbGlMAABNAABTAAAA
C0NvbW1vbiBMaXNwUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAAaVmFyaW91cyBhc3NlbWJseSBs
YW5ndWFnZXNTAAAAAwogIEVTAAAAAmxpTAAATQAAUwAAABBHZXR0ZXh0IGNhdGFsb2dzUwAAAAMK
ICBFUwAAAAJsaUwAAE0AAFMAAAATU3F1aWQgY29uZmlndXJhdGlvblMAAAADCiAgRVMAAAACbGlM
AABNAABTAAAAFERlYmlhbiBjb250cm9sIGZpbGVzUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAAP
TXlTUUwtc3R5bGUgU1FMUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAAHTU9PQ29kZVMAAAABCk0A
AFMAAAADCiAgUwAAACIKU29tZSBvbGQgbGV4ZXJzIGdvdCB1cGRhdGVzIHRvbzoKRVMAAAACdWxM
AAZFUwAAAAJsaUwAAE0AAFMAAAAuR3JlYXRseSBpbXByb3ZlZCB0aGUgSGFza2VsbCBhbmQgT0Nh
bWwgbGV4ZXJzLlMAAAADCiAgRVMAAAACbGlMAABNAABTAAAAOEltcHJvdmVkIHRoZSBCYXNoIGxl
eGVyJ3MgaGFuZGxpbmcgb2YgbmVzdGVkIGNvbnN0cnVjdHMuUwAAAAMKICBFUwAAAAJsaUwAAE0A
AFMAAABkVGhlIEMjIGFuZCBKYXZhIGxleGVycyBleGhpYml0ZWQgYWJ5c21hbCBwZXJmb3JtYW5j
ZSB3aXRoIHNvbWUgaW5wdXQgY29kZTsgdGhpcyBzaG91bGQgbm93IGJlIGZpeGVkLlMAAAADCiAg
RVMAAAACbGlMAABNAABTAAAAPFRoZSBJUkMgbG9ncyBsZXhlciBpcyBub3cgYWJsZSB0byBjb2xv
cml6ZSB3ZWVjaGF0IGxvZ3MgdG9vLlMAAAADCiAgRVMAAAACbGlMAABNAABTAAAAMVRoZSBMdWEg
bGV4ZXIgbm93IHJlY29nbml6ZXMgbXVsdGktbGluZSBjb21tZW50cy5TAAAAAwogIEVTAAAAAmxp
TAAATQAAUwAAACRGaXhlZCBidWdzIGluIHRoZSBEIGFuZCBNaW5pRCBsZXhlci5TAAAAAQpNAABT
AAAAAwogIFMAAAENClRoZXJlIGFyZSBhbHNvIHR3byBuZXcgZm9ybWF0dGVycy4gT25lIHRoYXQg
b3V0cHV0cyBTVkcgZG9jdW1lbnRzIGFuZCBhIHRlcm1pbmFsIGZvcm1hdHRlciB0aGF0IHVzZXMg
MjU2IGRpZmZlcmVudCBjb2xvcnMgaWYgdGhlIHRlcm1pbmFscyBzdXBwb3J0IHRoYXQuIFRoZXJl
IGlzIGFsc28gYSBuZXcgc3R5bGUgd2hpY2ggcmVzZW1ibGVzIHRoZSB2aW03IGRlZmF1bHQgc3R5
bGUuCgpGb3IgdGhlIGZ1bGwgbGlzdCBvZiBjaGFuZ2VzIGhhdmUgYSBsb29rIGF0IHRoZSBFUwAA
AAFhTAAATQABUwAAAARocmVmUwAAADZodHRwOi8vZGV2LnBvY29vLm9yZy9wcm9qZWN0cy9weWdt
ZW50cy9icm93c2VyL0NIQU5HRVNTAAAACWNoYW5nZWxvZ1MAAAAlLiBZb3UgY2FuIGRvd25sb2Fk
IHB5Z21lbnRzIGZyb20gdGhlIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAHWh0dHA6Ly9weWdt
ZW50cy5vcmcvZG93bmxvYWQvUwAAAA1kb3dubG9hZCBwYWdlUwAAABEuIEhhcHB5IGNvbG9yaW5n
IVMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
About Bug-Fixing and Politenesshttp://lucumr.pocoo.org/cogitations/2007/10/13/about-bug-fixing-and-politeness/2007-10-13T15:46:37Z2007-10-13T15:46:37ZArmin Ronacherabout-bug-fixing-and-politenessyesyes2<a href="http://lucumr.pocoo.org/cogitations/2007/10/13/counting-days/">It took less than a day</a>. And yes I was an asshole. I can't blame the django team for fixing things too slow because being Python's biggest framework you can break existing code easily and fixes often requires careful consideration.
All in all I'm very happy with django and love using it, but the trac always gives me a feeling I cannot really describe. If you query open tickets you can find around 800 of them and tickets I posted so far never got real attention. However that's not a big problem because most of them where proposals or feature requests.
Two days ago someone posted <a href="http://code.djangoproject.com/ticket/5738">that URL bug</a> in the IRC Channel and I bookmarked it. I thought that someone of the developers would have the timeline in the RSS reader and fix that. Yesterday I then added a patch that ignores malformed unicode in those URLs and thought I could get that fixed quickly if I sent the link to the ticket to ubernostrum and got as response something like: "that requires discussing on the mailing list, I'm not sure if ignoring is the correct behavior." And I guess my answer was something like "I've better things to do".
That and the <a href="http://lucumr.pocoo.org/cogitations/2007/10/13/counting-days/">following blog post</a> was just rude and unacceptable. I promise that I won't do that again :-)
<small>disclaimer: Europe/Vienna</small><a href="http://lucumr.pocoo.org/cogitations/2007/10/13/counting-days/">It took less than a day</a>. And yes I was an asshole. I can't blame the django team for fixing things too slow because being Python's biggest framework you can break existing code easily and fixes often requires careful consideration.
All in all I'm very happy with django and love using it, but the trac always gives me a feeling I cannot really describe. If you query open tickets you can find around 800 of them and tickets I posted so far never got real attention. However that's not a big problem because most of them where proposals or feature requests.
Two days ago someone posted <a href="http://code.djangoproject.com/ticket/5738">that URL bug</a> in the IRC Channel and I bookmarked it. I thought that someone of the developers would have the timeline in the RSS reader and fix that. Yesterday I then added a patch that ignores malformed unicode in those URLs and thought I could get that fixed quickly if I sent the link to the ticket to ubernostrum and got as response something like: "that requires discussing on the mailing list, I'm not sure if ignoring is the correct behavior." And I guess my answer was something like "I've better things to do".
That and the <a href="http://lucumr.pocoo.org/cogitations/2007/10/13/counting-days/">following blog post</a> was just rude and unacceptable. I promise that I won't do that again :-)
<small>disclaimer: Europe/Vienna</small>SQAAAANTAAAABGJvZHlSUwAAAABMAARFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAD1odHRwOi8v
bHVjdW1yLnBvY29vLm9yZy9jb2dpdGF0aW9ucy8yMDA3LzEwLzEzL2NvdW50aW5nLWRheXMvUwAA
ABdJdCB0b29rIGxlc3MgdGhhbiBhIGRheVMAAAI0LiBBbmQgeWVzIEkgd2FzIGFuIGFzc2hvbGUu
IEkgY2FuJ3QgYmxhbWUgdGhlIGRqYW5nbyB0ZWFtIGZvciBmaXhpbmcgdGhpbmdzIHRvbyBzbG93
IGJlY2F1c2UgYmVpbmcgUHl0aG9uJ3MgYmlnZ2VzdCBmcmFtZXdvcmsgeW91IGNhbiBicmVhayBl
eGlzdGluZyBjb2RlIGVhc2lseSBhbmQgZml4ZXMgb2Z0ZW4gcmVxdWlyZXMgY2FyZWZ1bCBjb25z
aWRlcmF0aW9uLgoKQWxsIGluIGFsbCBJJ20gdmVyeSBoYXBweSB3aXRoIGRqYW5nbyBhbmQgbG92
ZSB1c2luZyBpdCwgYnV0IHRoZSB0cmFjIGFsd2F5cyBnaXZlcyBtZSBhIGZlZWxpbmcgSSBjYW5u
b3QgcmVhbGx5IGRlc2NyaWJlLiBJZiB5b3UgcXVlcnkgb3BlbiB0aWNrZXRzIHlvdSBjYW4gZmlu
ZCBhcm91bmQgODAwIG9mIHRoZW0gYW5kIHRpY2tldHMgSSBwb3N0ZWQgc28gZmFyIG5ldmVyIGdv
dCByZWFsIGF0dGVudGlvbi4gSG93ZXZlciB0aGF0J3Mgbm90IGEgYmlnIHByb2JsZW0gYmVjYXVz
ZSBtb3N0IG9mIHRoZW0gd2hlcmUgcHJvcG9zYWxzIG9yIGZlYXR1cmUgcmVxdWVzdHMuCgpUd28g
ZGF5cyBhZ28gc29tZW9uZSBwb3N0ZWQgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAApaHR0cDov
L2NvZGUuZGphbmdvcHJvamVjdC5jb20vdGlja2V0LzU3MzhTAAAADHRoYXQgVVJMIGJ1Z1MAAAIK
IGluIHRoZSBJUkMgQ2hhbm5lbCBhbmQgSSBib29rbWFya2VkIGl0LiBJIHRob3VnaHQgdGhhdCBz
b21lb25lIG9mIHRoZSBkZXZlbG9wZXJzIHdvdWxkIGhhdmUgdGhlIHRpbWVsaW5lIGluIHRoZSBS
U1MgcmVhZGVyIGFuZCBmaXggdGhhdC4gWWVzdGVyZGF5IEkgdGhlbiBhZGRlZCBhIHBhdGNoIHRo
YXQgaWdub3JlcyBtYWxmb3JtZWQgdW5pY29kZSBpbiB0aG9zZSBVUkxzIGFuZCB0aG91Z2h0IEkg
Y291bGQgZ2V0IHRoYXQgZml4ZWQgcXVpY2tseSBpZiBJIHNlbnQgdGhlIGxpbmsgdG8gdGhlIHRp
Y2tldCB0byB1YmVybm9zdHJ1bSBhbmQgZ290IGFzIHJlc3BvbnNlIHNvbWV0aGluZyBsaWtlOiAi
dGhhdCByZXF1aXJlcyBkaXNjdXNzaW5nIG9uIHRoZSBtYWlsaW5nIGxpc3QsIEknbSBub3Qgc3Vy
ZSBpZiBpZ25vcmluZyBpcyB0aGUgY29ycmVjdCBiZWhhdmlvci4iIEFuZCBJIGd1ZXNzIG15IGFu
c3dlciB3YXMgc29tZXRoaW5nIGxpa2UgIkkndmUgYmV0dGVyIHRoaW5ncyB0byBkbyIuCgpUaGF0
IGFuZCB0aGUgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAA9aHR0cDovL2x1Y3Vtci5wb2Nvby5v
cmcvY29naXRhdGlvbnMvMjAwNy8xMC8xMy9jb3VudGluZy1kYXlzL1MAAAATZm9sbG93aW5nIGJs
b2cgcG9zdFMAAABLIHdhcyBqdXN0IHJ1ZGUgYW5kIHVuYWNjZXB0YWJsZS4gSSBwcm9taXNlIHRo
YXQgSSB3b24ndCBkbyB0aGF0IGFnYWluIDotKQoKRVMAAAAFc21hbGxMAABNAABTAAAAGWRpc2Ns
YWltZXI6IEV1cm9wZS9WaWVubmFTAAAAAFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JT
AAAAAEwAAA==
Tiberiu Ichimtibi@pixelblaster.rohttp://play.pixelblaster.ro2007-10-14T08:35:43Znono0I'm not sure how you came to the conclusion that Django is "python's biggest framework".
Number of users? Core developers? Popularity? What difference would it make in fixing a bug?
Code size? Maybe that... and I'm pretty sure that's not true (for better or worse, Zope, the one that I know, seems to be bigger).I'm not sure how you came to the conclusion that Django is "python's biggest framework".
Number of users? Core developers? Popularity? What difference would it make in fixing a bug?
Code size? Maybe that... and I'm pretty sure that's not true (for better or worse, Zope, the one that I know, seems to be bigger).SQAAAAJTAAAABGJvZHlSUwAAATlJJ20gbm90IHN1cmUgaG93IHlvdSBjYW1lIHRvIHRoZSBjb25j
bHVzaW9uIHRoYXQgRGphbmdvIGlzICJweXRob24ncyBiaWdnZXN0IGZyYW1ld29yayIuCk51bWJl
ciBvZiB1c2Vycz8gQ29yZSBkZXZlbG9wZXJzPyBQb3B1bGFyaXR5PyBXaGF0IGRpZmZlcmVuY2Ug
d291bGQgaXQgbWFrZSBpbiBmaXhpbmcgYSBidWc/IApDb2RlIHNpemU/IE1heWJlIHRoYXQuLi4g
YW5kIEknbSBwcmV0dHkgc3VyZSB0aGF0J3Mgbm90IHRydWUgKGZvciBiZXR0ZXIgb3Igd29yc2Us
IFpvcGUsIHRoZSBvbmUgdGhhdCBJIGtub3csIHNlZW1zIHRvIGJlIGJpZ2dlcikuTAAAUwAAAAZw
YXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-10-14T17:10:34Znono0I came to that conclusion because of the number of actual users. The more users you have in a framework the more likely the chance that your change breaks someone's code, even if it's just a bugfix.
In terms of code size pylons with all the dependencies is probably about the same in size. And Zope is not a framework, it's an application server ^^.I came to that conclusion because of the number of actual users. The more users you have in a framework the more likely the chance that your change breaks someone's code, even if it's just a bugfix.
In terms of code size pylons with all the dependencies is probably about the same in size. And Zope is not a framework, it's an application server ^^.SQAAAAJTAAAABGJvZHlSUwAAAV5JIGNhbWUgdG8gdGhhdCBjb25jbHVzaW9uIGJlY2F1c2Ugb2Yg
dGhlIG51bWJlciBvZiBhY3R1YWwgdXNlcnMuIFRoZSBtb3JlIHVzZXJzIHlvdSBoYXZlIGluIGEg
ZnJhbWV3b3JrIHRoZSBtb3JlIGxpa2VseSB0aGUgY2hhbmNlIHRoYXQgeW91ciBjaGFuZ2UgYnJl
YWtzIHNvbWVvbmUncyBjb2RlLCBldmVuIGlmIGl0J3MganVzdCBhIGJ1Z2ZpeC4KCkluIHRlcm1z
IG9mIGNvZGUgc2l6ZSBweWxvbnMgd2l0aCBhbGwgdGhlIGRlcGVuZGVuY2llcyBpcyBwcm9iYWJs
eSBhYm91dCB0aGUgc2FtZSBpbiBzaXplLiBBbmQgWm9wZSBpcyBub3QgYSBmcmFtZXdvcmssIGl0
J3MgYW4gYXBwbGljYXRpb24gc2VydmVyIF5eLkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Tiberiu Ichimtibi@pixelblaster.rohttp://play.pixelblaster.ro2007-10-15T11:25:33Znono0Without any intention to continue this, I'll point two things:
1. An (old-ish) comparison of code sizes for Django, Turbogears and Zope 3:
http://www.peterbe.com/plog/size-Zope3,Django,TurboGears
I'm pretty sure Pylons is not that far from Turbogears, for example, even taking SQLAlchemy into consideration.
2. Zope 3.4 has been splitted into components and it's now possible to treat your code as "the application" instead of an addon to the Zope 3 appserver.
http://blog.delaguardia.com.mx/index.php?op=ViewArticle&articleId=72&blogId=1Without any intention to continue this, I'll point two things:
1. An (old-ish) comparison of code sizes for Django, Turbogears and Zope 3:
http://www.peterbe.com/plog/size-Zope3,Django,TurboGears
I'm pretty sure Pylons is not that far from Turbogears, for example, even taking SQLAlchemy into consideration.
2. Zope 3.4 has been splitted into components and it's now possible to treat your code as "the application" instead of an addon to the Zope 3 appserver.
http://blog.delaguardia.com.mx/index.php?op=ViewArticle&articleId=72&blogId=1SQAAAAJTAAAABGJvZHlSUwAAAh1XaXRob3V0IGFueSBpbnRlbnRpb24gdG8gY29udGludWUgdGhp
cywgSSdsbCBwb2ludCB0d28gdGhpbmdzOgoKMS4gQW4gKG9sZC1pc2gpIGNvbXBhcmlzb24gb2Yg
Y29kZSBzaXplcyBmb3IgRGphbmdvLCBUdXJib2dlYXJzIGFuZCBab3BlIDM6Cmh0dHA6Ly93d3cu
cGV0ZXJiZS5jb20vcGxvZy9zaXplLVpvcGUzLERqYW5nbyxUdXJib0dlYXJzCkknbSBwcmV0dHkg
c3VyZSBQeWxvbnMgaXMgbm90IHRoYXQgZmFyIGZyb20gVHVyYm9nZWFycywgZm9yIGV4YW1wbGUs
IGV2ZW4gdGFraW5nIFNRTEFsY2hlbXkgaW50byBjb25zaWRlcmF0aW9uLgoKMi4gWm9wZSAzLjQg
aGFzIGJlZW4gc3BsaXR0ZWQgaW50byBjb21wb25lbnRzIGFuZCBpdCdzIG5vdyBwb3NzaWJsZSB0
byB0cmVhdCB5b3VyIGNvZGUgYXMgInRoZSBhcHBsaWNhdGlvbiIgaW5zdGVhZCBvZiBhbiBhZGRv
biB0byB0aGUgWm9wZSAzIGFwcHNlcnZlci4gCmh0dHA6Ly9ibG9nLmRlbGFndWFyZGlhLmNvbS5t
eC9pbmRleC5waHA/b3A9Vmlld0FydGljbGUmYXJ0aWNsZUlkPTcyJmJsb2dJZD0xTAAAUwAAAAZw
YXJzZXJTAAAABGh0bWw=
Counting dayshttp://lucumr.pocoo.org/cogitations/2007/10/13/counting-days/2007-10-12T22:06:35Z2007-10-12T22:06:35ZArmin Ronachercounting-daysyesyes2Let's see how long it takes until a rather severe bug gets its patch applied.
<!-- said bug is this one: http://code.djangoproject.com/ticket/5738 -->
<strong>update</strong>: fixed „its“Let's see how long it takes until a rather severe bug gets its patch applied.
<strong>update</strong>: fixed „its“SQAAAANTAAAABGJvZHlSUwAAAFBMZXQncyBzZWUgaG93IGxvbmcgaXQgdGFrZXMgdW50aWwgYSBy
YXRoZXIgc2V2ZXJlIGJ1ZyBnZXRzIGl0cyBwYXRjaCBhcHBsaWVkLgoKCkwAAUVTAAAABnN0cm9u
Z0wAAE0AAFMAAAAGdXBkYXRlUwAAABE6IGZpeGVkIOKAnml0c+KAnFMAAAAGcGFyc2VyUwAAAARo
dG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
SuperJaredme@superjared.comhttp://superjared.com/2007-10-12T23:13:10Znono0Okay, I'm curious... What bug?Okay, I'm curious... What bug?SQAAAAJTAAAABGJvZHlSUwAAAB5Pa2F5LCBJJ20gY3VyaW91cy4uLiBXaGF0IGJ1Zz9MAABTAAAA
BnBhcnNlclMAAAAEaHRtbA==
Marcelo Minholiminholi@gmail.comhttp://minholi.blogspot.com2007-10-12T23:53:40Znono0Are you talking about the django 1.0 version?Are you talking about the django 1.0 version?SQAAAAJTAAAABGJvZHlSUwAAAC1BcmUgeW91IHRhbGtpbmcgYWJvdXQgdGhlIGRqYW5nbyAxLjAg
dmVyc2lvbj9MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Jacob Kaplan-Mossjacob@jacobian.orghttp://jacobian.org/2007-10-12T23:59:11Znono0You know, you might have an easier time of it if you mentioned which bug, and helped us understand why you find it "rather severe"...You know, you might have an easier time of it if you mentioned which bug, and helped us understand why you find it "rather severe"...SQAAAAJTAAAABGJvZHlSUwAAAIVZb3Uga25vdywgeW91IG1pZ2h0IGhhdmUgYW4gZWFzaWVyIHRp
bWUgb2YgaXQgaWYgeW91IG1lbnRpb25lZCB3aGljaCBidWcsIGFuZCBoZWxwZWQgdXMgdW5kZXJz
dGFuZCB3aHkgeW91IGZpbmQgaXQgInJhdGhlciBzZXZlcmUiLi4uTAAAUwAAAAZwYXJzZXJTAAAA
BGh0bWw=
anonymousanonymous@anonymous.com2007-10-13T00:42:23Znono0I see the ticket you filed describing the bug, but you didn't provide a patch implementing the missing feature. Maybe if you wrote a patch, the mystery of how long it will take to fix will be slightly less mysterious.I see the ticket you filed describing the bug, but you didn't provide a patch implementing the missing feature. Maybe if you wrote a patch, the mystery of how long it will take to fix will be slightly less mysterious.SQAAAAJTAAAABGJvZHlSUwAAANlJIHNlZSB0aGUgdGlja2V0IHlvdSBmaWxlZCBkZXNjcmliaW5n
IHRoZSBidWcsIGJ1dCB5b3UgZGlkbid0IHByb3ZpZGUgYSBwYXRjaCBpbXBsZW1lbnRpbmcgdGhl
IG1pc3NpbmcgZmVhdHVyZS4gTWF5YmUgaWYgeW91IHdyb3RlIGEgcGF0Y2gsIHRoZSBteXN0ZXJ5
IG9mIGhvdyBsb25nIGl0IHdpbGwgdGFrZSB0byBmaXggd2lsbCBiZSBzbGlnaHRseSBsZXNzIG15
c3RlcmlvdXMuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Adrian Holovatyfoo@example.comhttp://www.holovaty.com/2007-10-13T03:00:05Znono0Fixed. Now, let's see how long it takes until you change this blog entry to use the correct form of "its"!Fixed. Now, let's see how long it takes until you change this blog entry to use the correct form of "its"!SQAAAAJTAAAABGJvZHlSUwAAAGpGaXhlZC4gTm93LCBsZXQncyBzZWUgaG93IGxvbmcgaXQgdGFr
ZXMgdW50aWwgeW91IGNoYW5nZSB0aGlzIGJsb2cgZW50cnkgdG8gdXNlIHRoZSBjb3JyZWN0IGZv
cm0gb2YgIml0cyIhTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Sethseth@eseth.comhttp://eseth.org/2007-10-13T05:20:54Znono0One! One day. Two! Two days...ah! ah!One! One day. Two! Two days...ah! ah!SQAAAAJTAAAABGJvZHlSUwAAACVPbmUhIE9uZSBkYXkuIFR3byEgVHdvIGRheXMuLi5haCEgYWgh
TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Collincollin@collingrady.comhttp://collingrady.com/2007-10-13T07:14:17Znono0Bit of an asshole-ish attitude for someone with "better things to do" than report the issue properly, don't you think?Bit of an asshole-ish attitude for someone with "better things to do" than report the issue properly, don't you think?SQAAAAJTAAAABGJvZHlSUwAAAHZCaXQgb2YgYW4gYXNzaG9sZS1pc2ggYXR0aXR1ZGUgZm9yIHNv
bWVvbmUgd2l0aCAiYmV0dGVyIHRoaW5ncyB0byBkbyIgdGhhbiByZXBvcnQgdGhlIGlzc3VlIHBy
b3Blcmx5LCBkb24ndCB5b3UgdGhpbms/TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Lucumr Cogitations » Blog Archive » About Bug-Fixing and Politenesshttp://lucumr.pocoo.org/cogitations/2007/10/13/about-bug-fixing-and-politeness/2007-10-13T15:46:40Znoyes0[...] It took less than a day. And yes I was an asshole. I can’t blame the django team for fixing things too slow because being Python’s biggest framework you can break existing code easily and fixes often requires careful consideration. [...][...] It took less than a day. And yes I was an asshole. I can’t blame the django team for fixing things too slow because being Python’s biggest framework you can break existing code easily and fixes often requires careful consideration. [...]SQAAAAJTAAAABGJvZHlSUwAAAPdbLi4uXSBJdCB0b29rIGxlc3MgdGhhbiBhIGRheS4gQW5kIHll
cyBJIHdhcyBhbiBhc3Nob2xlLiBJIGNhbuKAmXQgYmxhbWUgdGhlIGRqYW5nbyB0ZWFtIGZvciBm
aXhpbmcgdGhpbmdzIHRvbyBzbG93IGJlY2F1c2UgYmVpbmcgUHl0aG9u4oCZcyBiaWdnZXN0IGZy
YW1ld29yayB5b3UgY2FuIGJyZWFrIGV4aXN0aW5nIGNvZGUgZWFzaWx5IGFuZCBmaXhlcyBvZnRl
biByZXF1aXJlcyBjYXJlZnVsIGNvbnNpZGVyYXRpb24uIFsuLi5dTAAAUwAAAAZwYXJzZXJTAAAA
BGh0bWw=
Marc Garciagarcia.marc@gmail.comhttp://vaig.be2007-10-16T00:25:17Znono0In my opinion the subject is not how difficult is fixing bugs in Django, or how much time it costs.
The subject is why you can't be thankful for having this great application for free (free as in freedom), and you waste your time in this kind of posts, instead to contributing in a productive way.
But now, I think that best you can do is post another entry about how far bugs are fixed, and how Django community takes care on its lost sheeps. :)In my opinion the subject is not how difficult is fixing bugs in Django, or how much time it costs.
The subject is why you can't be thankful for having this great application for free (free as in freedom), and you waste your time in this kind of posts, instead to contributing in a productive way.
But now, I think that best you can do is post another entry about how far bugs are fixed, and how Django community takes care on its lost sheeps. :)SQAAAAJTAAAABGJvZHlSUwAAAcBJbiBteSBvcGluaW9uIHRoZSBzdWJqZWN0IGlzIG5vdCBob3cg
ZGlmZmljdWx0IGlzIGZpeGluZyBidWdzIGluIERqYW5nbywgb3IgaG93IG11Y2ggdGltZSBpdCBj
b3N0cy4KClRoZSBzdWJqZWN0IGlzIHdoeSB5b3UgY2FuJ3QgYmUgdGhhbmtmdWwgZm9yIGhhdmlu
ZyB0aGlzIGdyZWF0IGFwcGxpY2F0aW9uIGZvciBmcmVlIChmcmVlIGFzIGluIGZyZWVkb20pLCBh
bmQgeW91IHdhc3RlIHlvdXIgdGltZSBpbiB0aGlzIGtpbmQgb2YgcG9zdHMsIGluc3RlYWQgdG8g
Y29udHJpYnV0aW5nIGluIGEgcHJvZHVjdGl2ZSB3YXkuCgpCdXQgbm93LCBJIHRoaW5rIHRoYXQg
YmVzdCB5b3UgY2FuIGRvIGlzIHBvc3QgYW5vdGhlciBlbnRyeSBhYm91dCBob3cgZmFyIGJ1Z3Mg
YXJlIGZpeGVkLCBhbmQgaG93IERqYW5nbyBjb21tdW5pdHkgdGFrZXMgY2FyZSBvbiBpdHMgbG9z
dCBzaGVlcHMuIDopTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
A Band is more than a Frontmanhttp://lucumr.pocoo.org/cogitations/2007/10/05/a-band-is-more-than-a-frontman/2007-10-05T20:06:56Z2007-10-05T20:06:56ZArmin Ronachera-band-is-more-than-a-frontmanyesyes2A band is much more than the man/woman that is in the center of all fan art of a band. Much more. Just take Dream Theater as an example. La Brie is certainly a good singer but not the center of the band. The center are without a doubt Petrucci and Portnoy. And there are other bands out there that make great music but you might not know the names of the other band members.
One example was Nightwish. Until they kicked out their old frontwoman. And it was certainly a good choice because If you listen to their new album they haven't lost anything. Tarja was never the kind of musician that wrote the music. But she earned all the fame.
And the new album certainly rocks. Although Tarja might be pissed now, but Anette does a very good job and fits into the arrangement perfectly. So if you were a Nightwish listener until Tarja left, give the new album a try.A band is much more than the man/woman that is in the center of all fan art of a band. Much more. Just take Dream Theater as an example. La Brie is certainly a good singer but not the center of the band. The center are without a doubt Petrucci and Portnoy. And there are other bands out there that make great music but you might not know the names of the other band members.
One example was Nightwish. Until they kicked out their old frontwoman. And it was certainly a good choice because If you listen to their new album they haven't lost anything. Tarja was never the kind of musician that wrote the music. But she earned all the fame.
And the new album certainly rocks. Although Tarja might be pissed now, but Anette does a very good job and fits into the arrangement perfectly. So if you were a Nightwish listener until Tarja left, give the new album a try.SQAAAANTAAAABGJvZHlSUwAAA19BIGJhbmQgaXMgbXVjaCBtb3JlIHRoYW4gdGhlIG1hbi93b21h
biB0aGF0IGlzIGluIHRoZSBjZW50ZXIgb2YgYWxsIGZhbiBhcnQgb2YgYSBiYW5kLiBNdWNoIG1v
cmUuIEp1c3QgdGFrZSBEcmVhbSBUaGVhdGVyIGFzIGFuIGV4YW1wbGUuIExhIEJyaWUgaXMgY2Vy
dGFpbmx5IGEgZ29vZCBzaW5nZXIgYnV0IG5vdCB0aGUgY2VudGVyIG9mIHRoZSBiYW5kLiBUaGUg
Y2VudGVyIGFyZSB3aXRob3V0IGEgZG91YnQgUGV0cnVjY2kgYW5kIFBvcnRub3kuIEFuZCB0aGVy
ZSBhcmUgb3RoZXIgYmFuZHMgb3V0IHRoZXJlIHRoYXQgbWFrZSBncmVhdCBtdXNpYyBidXQgeW91
IG1pZ2h0IG5vdCBrbm93IHRoZSBuYW1lcyBvZiB0aGUgb3RoZXIgYmFuZCBtZW1iZXJzLgoKT25l
IGV4YW1wbGUgd2FzIE5pZ2h0d2lzaC4gVW50aWwgdGhleSBraWNrZWQgb3V0IHRoZWlyIG9sZCBm
cm9udHdvbWFuLiBBbmQgaXQgd2FzIGNlcnRhaW5seSBhIGdvb2QgY2hvaWNlIGJlY2F1c2UgSWYg
eW91IGxpc3RlbiB0byB0aGVpciBuZXcgYWxidW0gdGhleSBoYXZlbid0IGxvc3QgYW55dGhpbmcu
IFRhcmphIHdhcyBuZXZlciB0aGUga2luZCBvZiBtdXNpY2lhbiB0aGF0IHdyb3RlIHRoZSBtdXNp
Yy4gQnV0IHNoZSBlYXJuZWQgYWxsIHRoZSBmYW1lLgoKQW5kIHRoZSBuZXcgYWxidW0gY2VydGFp
bmx5IHJvY2tzLiBBbHRob3VnaCBUYXJqYSBtaWdodCBiZSBwaXNzZWQgbm93LCBidXQgQW5ldHRl
IGRvZXMgYSB2ZXJ5IGdvb2Qgam9iIGFuZCBmaXRzIGludG8gdGhlIGFycmFuZ2VtZW50IHBlcmZl
Y3RseS4gU28gaWYgeW91IHdlcmUgYSBOaWdodHdpc2ggbGlzdGVuZXIgdW50aWwgVGFyamEgbGVm
dCwgZ2l2ZSB0aGUgbmV3IGFsYnVtIGEgdHJ5LkwAAFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVp
bnRyb1JTAAAAAEwAAA==
dejotspam@josef-behr.de2007-10-24T00:19:28Znono0thats right, tarja never wrothe the music, but the music wasnt ever special. the voice was. and anette olzon, sry, sounds a lot like sharon van den adel, which makes nightwish just another metal band with female singer out there. and there are a lot. some better, some worse.
the new album isnt that much different from the old ones (except the voice, o' course). lot of power chords, orchestra, keyboard and, ye, a few very nice melodies, but fortunately slighty overproduced like the last one. its music w/o a soul, just random, exchangeable, bit better than average music.
they are talented musicians, especially Holopainen and Hietala, who is in fact a good singer too, and could do a lot better in my opinion. my few euros :)thats right, tarja never wrothe the music, but the music wasnt ever special. the voice was. and anette olzon, sry, sounds a lot like sharon van den adel, which makes nightwish just another metal band with female singer out there. and there are a lot. some better, some worse.
the new album isnt that much different from the old ones (except the voice, o' course). lot of power chords, orchestra, keyboard and, ye, a few very nice melodies, but fortunately slighty overproduced like the last one. its music w/o a soul, just random, exchangeable, bit better than average music.
they are talented musicians, especially Holopainen and Hietala, who is in fact a good singer too, and could do a lot better in my opinion. my few euros :)SQAAAAJTAAAABGJvZHlSUwAAAtp0aGF0cyByaWdodCwgdGFyamEgbmV2ZXIgd3JvdGhlIHRoZSBt
dXNpYywgYnV0IHRoZSBtdXNpYyB3YXNudCBldmVyIHNwZWNpYWwuIHRoZSB2b2ljZSB3YXMuIGFu
ZCBhbmV0dGUgb2x6b24sIHNyeSwgc291bmRzIGEgbG90IGxpa2Ugc2hhcm9uIHZhbiBkZW4gYWRl
bCwgd2hpY2ggbWFrZXMgbmlnaHR3aXNoIGp1c3QgYW5vdGhlciBtZXRhbCBiYW5kIHdpdGggZmVt
YWxlIHNpbmdlciBvdXQgdGhlcmUuIGFuZCB0aGVyZSBhcmUgYSBsb3QuIHNvbWUgYmV0dGVyLCBz
b21lIHdvcnNlLgp0aGUgbmV3IGFsYnVtIGlzbnQgdGhhdCBtdWNoIGRpZmZlcmVudCBmcm9tIHRo
ZSBvbGQgb25lcyAoZXhjZXB0IHRoZSB2b2ljZSwgbycgY291cnNlKS4gbG90IG9mIHBvd2VyIGNo
b3Jkcywgb3JjaGVzdHJhLCBrZXlib2FyZCBhbmQsIHllLCBhIGZldyB2ZXJ5IG5pY2UgbWVsb2Rp
ZXMsIGJ1dCBmb3J0dW5hdGVseSBzbGlnaHR5IG92ZXJwcm9kdWNlZCBsaWtlIHRoZSBsYXN0IG9u
ZS4gaXRzIG11c2ljIHcvbyBhIHNvdWwsIGp1c3QgcmFuZG9tLCBleGNoYW5nZWFibGUsIGJpdCBi
ZXR0ZXIgdGhhbiBhdmVyYWdlIG11c2ljLgp0aGV5IGFyZSB0YWxlbnRlZCBtdXNpY2lhbnMsIGVz
cGVjaWFsbHkgSG9sb3BhaW5lbiBhbmQgSGlldGFsYSwgd2hvIGlzIGluIGZhY3QgYSBnb29kIHNp
bmdlciB0b28sIGFuZCBjb3VsZCBkbyBhIGxvdCBiZXR0ZXIgaW4gbXkgb3Bpbmlvbi4gbXkgZmV3
IGV1cm9zIDopTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-10-28T22:23:07Znono0Let's see how their next album will sound like. (And their live performances). But I expected much less when I heard that they kicked Tarja. :-)Let's see how their next album will sound like. (And their live performances). But I expected much less when I heard that they kicked Tarja. :-)SQAAAAJTAAAABGJvZHlSUwAAAJBMZXQncyBzZWUgaG93IHRoZWlyIG5leHQgYWxidW0gd2lsbCBz
b3VuZCBsaWtlLiAoQW5kIHRoZWlyIGxpdmUgcGVyZm9ybWFuY2VzKS4gQnV0IEkgZXhwZWN0ZWQg
bXVjaCBsZXNzIHdoZW4gSSBoZWFyZCB0aGF0IHRoZXkga2lja2VkIFRhcmphLiA6LSlMAABTAAAA
BnBhcnNlclMAAAAEaHRtbA==
Abusing XHTMLhttp://lucumr.pocoo.org/cogitations/2007/10/05/abusing-xhtml/2007-10-05T18:35:29Z2007-10-05T18:35:29ZArmin Ronacherabusing-xhtmlyesyes2As small resumption to <a href="http://lucumr.pocoo.org/cogitations/2007/10/03/doctype-woes-back-to-html4/">my previous post about XHTML/HTML</a> here a small list of websites using XHTML that break when rendered on a browser in XHTML mode:
<ul>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/adobe.jpg">adobe</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/alistapart.jpg">alistapart</a> (although not everywhere)</li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/digg.jpg">digg.com</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/djangoproject.jpg">django webpage</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/drupal.jpg">drupal webpage</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/netscape.jpg">netscape portal</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/php.jpg">php documentation</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/python.jpg">python webpage</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/reddit.jpg">reddit</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/ruby-doc.jpg">ruby documentation</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/sourceforge.jpg">sourceforge</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/trac.jpg">trac</a></li>
</ul>
Not that all my XHTML pages are valid, but if they fail... How should browser vendors implement XHTML if that would break the internets?As small resumption to <a href="http://lucumr.pocoo.org/cogitations/2007/10/03/doctype-woes-back-to-html4/">my previous post about XHTML/HTML</a> here a small list of websites using XHTML that break when rendered on a browser in XHTML mode:
<ul>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/adobe.jpg">adobe</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/alistapart.jpg">alistapart</a> (although not everywhere)</li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/digg.jpg">digg.com</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/djangoproject.jpg">django webpage</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/drupal.jpg">drupal webpage</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/netscape.jpg">netscape portal</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/php.jpg">php documentation</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/python.jpg">python webpage</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/reddit.jpg">reddit</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/ruby-doc.jpg">ruby documentation</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/sourceforge.jpg">sourceforge</a></li>
<li><a href="http://pocoo.org/~mitsuhiko/xhtmlfun/trac.jpg">trac</a></li>
</ul>
Not that all my XHTML pages are valid, but if they fail... How should browser vendors implement XHTML if that would break the internets?SQAAAANTAAAABGJvZHlSUwAAABdBcyBzbWFsbCByZXN1bXB0aW9uIHRvIEwAAkVTAAAAAWFMAABN
AAFTAAAABGhyZWZTAAAASmh0dHA6Ly9sdWN1bXIucG9jb28ub3JnL2NvZ2l0YXRpb25zLzIwMDcv
MTAvMDMvZG9jdHlwZS13b2VzLWJhY2stdG8taHRtbDQvUwAAACFteSBwcmV2aW91cyBwb3N0IGFi
b3V0IFhIVE1ML0hUTUxTAAAAYCBoZXJlIGEgc21hbGwgbGlzdCBvZiB3ZWJzaXRlcyB1c2luZyBY
SFRNTCB0aGF0IGJyZWFrIHdoZW4gcmVuZGVyZWQgb24gYSBicm93c2VyIGluIFhIVE1MIG1vZGU6
CkVTAAAAAnVsTAAMRVMAAAACbGlMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAC5odHRwOi8v
cG9jb28ub3JnL35taXRzdWhpa28veGh0bWxmdW4vYWRvYmUuanBnUwAAAAVhZG9iZVMAAAAATQAA
UwAAAABTAAAAAwogIEVTAAAAAmxpTAABRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAzaHR0cDov
L3BvY29vLm9yZy9+bWl0c3VoaWtvL3hodG1sZnVuL2FsaXN0YXBhcnQuanBnUwAAAAphbGlzdGFw
YXJ0UwAAABogKGFsdGhvdWdoIG5vdCBldmVyeXdoZXJlKU0AAFMAAAAAUwAAAAMKICBFUwAAAAJs
aUwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAALWh0dHA6Ly9wb2Nvby5vcmcvfm1pdHN1aGlr
by94aHRtbGZ1bi9kaWdnLmpwZ1MAAAAIZGlnZy5jb21TAAAAAE0AAFMAAAAAUwAAAAMKICBFUwAA
AAJsaUwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAANmh0dHA6Ly9wb2Nvby5vcmcvfm1pdHN1
aGlrby94aHRtbGZ1bi9kamFuZ29wcm9qZWN0LmpwZ1MAAAAOZGphbmdvIHdlYnBhZ2VTAAAAAE0A
AFMAAAAAUwAAAAMKICBFUwAAAAJsaUwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAL2h0dHA6
Ly9wb2Nvby5vcmcvfm1pdHN1aGlrby94aHRtbGZ1bi9kcnVwYWwuanBnUwAAAA5kcnVwYWwgd2Vi
cGFnZVMAAAAATQAAUwAAAABTAAAAAwogIEVTAAAAAmxpTAABRVMAAAABYUwAAE0AAVMAAAAEaHJl
ZlMAAAAxaHR0cDovL3BvY29vLm9yZy9+bWl0c3VoaWtvL3hodG1sZnVuL25ldHNjYXBlLmpwZ1MA
AAAPbmV0c2NhcGUgcG9ydGFsUwAAAABNAABTAAAAAFMAAAADCiAgRVMAAAACbGlMAAFFUwAAAAFh
TAAATQABUwAAAARocmVmUwAAACxodHRwOi8vcG9jb28ub3JnL35taXRzdWhpa28veGh0bWxmdW4v
cGhwLmpwZ1MAAAARcGhwIGRvY3VtZW50YXRpb25TAAAAAE0AAFMAAAAAUwAAAAMKICBFUwAAAAJs
aUwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAL2h0dHA6Ly9wb2Nvby5vcmcvfm1pdHN1aGlr
by94aHRtbGZ1bi9weXRob24uanBnUwAAAA5weXRob24gd2VicGFnZVMAAAAATQAAUwAAAABTAAAA
AwogIEVTAAAAAmxpTAABRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAvaHR0cDovL3BvY29vLm9y
Zy9+bWl0c3VoaWtvL3hodG1sZnVuL3JlZGRpdC5qcGdTAAAABnJlZGRpdFMAAAAATQAAUwAAAABT
AAAAAwogIEVTAAAAAmxpTAABRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAxaHR0cDovL3BvY29v
Lm9yZy9+bWl0c3VoaWtvL3hodG1sZnVuL3J1YnktZG9jLmpwZ1MAAAAScnVieSBkb2N1bWVudGF0
aW9uUwAAAABNAABTAAAAAFMAAAADCiAgRVMAAAACbGlMAAFFUwAAAAFhTAAATQABUwAAAARocmVm
UwAAADRodHRwOi8vcG9jb28ub3JnL35taXRzdWhpa28veGh0bWxmdW4vc291cmNlZm9yZ2UuanBn
UwAAAAtzb3VyY2Vmb3JnZVMAAAAATQAAUwAAAABTAAAAAwogIEVTAAAAAmxpTAABRVMAAAABYUwA
AE0AAVMAAAAEaHJlZlMAAAAtaHR0cDovL3BvY29vLm9yZy9+bWl0c3VoaWtvL3hodG1sZnVuL3Ry
YWMuanBnUwAAAAR0cmFjUwAAAABNAABTAAAAAFMAAAABCk0AAFMAAAADCiAgUwAAAIoKCk5vdCB0
aGF0IGFsbCBteSBYSFRNTCBwYWdlcyBhcmUgdmFsaWQsIGJ1dCBpZiB0aGV5IGZhaWwuLi4gSG93
IHNob3VsZCBicm93c2VyIHZlbmRvcnMgaW1wbGVtZW50IFhIVE1MIGlmIHRoYXQgd291bGQgYnJl
YWsgdGhlIGludGVybmV0cz9TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
faxi0fx@gmx.net2007-10-30T21:38:10Znono0Ok, this shows only that these sites did not validate their stuff. So what - Anybody who delivers content with an xml content type will have to reckon with that.
It's not that difficult to run the W3C log validator on one's server each week and fix any broken pages. If xhtml content is not well-formed, then browsers *should* refuse to display it when it is delivered as application/html+xml. Otherwise xhtml support in mainstream browsers would become as spoiled as legacy html support.
If people *see* that their content is broken, because the browser brings this fact up, then it will be fixed. Otherwise bad practices will continue. But the sites that you mention would know what they are doing if they should start delivering their content with an xml-based mime type at some point.Ok, this shows only that these sites did not validate their stuff. So what - Anybody who delivers content with an xml content type will have to reckon with that.
It's not that difficult to run the W3C log validator on one's server each week and fix any broken pages. If xhtml content is not well-formed, then browsers *should* refuse to display it when it is delivered as application/html+xml. Otherwise xhtml support in mainstream browsers would become as spoiled as legacy html support.
If people *see* that their content is broken, because the browser brings this fact up, then it will be fixed. Otherwise bad practices will continue. But the sites that you mention would know what they are doing if they should start delivering their content with an xml-based mime type at some point.SQAAAAJTAAAABGJvZHlSUwAAAxdPaywgdGhpcyBzaG93cyBvbmx5IHRoYXQgdGhlc2Ugc2l0ZXMg
ZGlkIG5vdCB2YWxpZGF0ZSB0aGVpciBzdHVmZi4gU28gd2hhdCAtIEFueWJvZHkgd2hvIGRlbGl2
ZXJzIGNvbnRlbnQgd2l0aCBhbiB4bWwgY29udGVudCB0eXBlIHdpbGwgaGF2ZSB0byByZWNrb24g
d2l0aCB0aGF0LiAKCkl0J3Mgbm90IHRoYXQgZGlmZmljdWx0IHRvIHJ1biB0aGUgVzNDIGxvZyB2
YWxpZGF0b3Igb24gb25lJ3Mgc2VydmVyIGVhY2ggd2VlayBhbmQgZml4IGFueSBicm9rZW4gcGFn
ZXMuIElmIHhodG1sIGNvbnRlbnQgaXMgbm90IHdlbGwtZm9ybWVkLCB0aGVuIGJyb3dzZXJzICpz
aG91bGQqIHJlZnVzZSB0byBkaXNwbGF5IGl0IHdoZW4gaXQgaXMgZGVsaXZlcmVkIGFzIGFwcGxp
Y2F0aW9uL2h0bWwreG1sLiBPdGhlcndpc2UgeGh0bWwgc3VwcG9ydCBpbiBtYWluc3RyZWFtIGJy
b3dzZXJzIHdvdWxkIGJlY29tZSBhcyBzcG9pbGVkIGFzIGxlZ2FjeSBodG1sIHN1cHBvcnQuCgpJ
ZiBwZW9wbGUgKnNlZSogdGhhdCB0aGVpciBjb250ZW50IGlzIGJyb2tlbiwgYmVjYXVzZSB0aGUg
YnJvd3NlciBicmluZ3MgdGhpcyBmYWN0IHVwLCB0aGVuIGl0IHdpbGwgYmUgZml4ZWQuIE90aGVy
d2lzZSBiYWQgcHJhY3RpY2VzIHdpbGwgY29udGludWUuIEJ1dCB0aGUgc2l0ZXMgdGhhdCB5b3Ug
bWVudGlvbiB3b3VsZCBrbm93IHdoYXQgdGhleSBhcmUgZG9pbmcgaWYgdGhleSBzaG91bGQgc3Rh
cnQgZGVsaXZlcmluZyB0aGVpciBjb250ZW50IHdpdGggYW4geG1sLWJhc2VkIG1pbWUgdHlwZSBh
dCBzb21lIHBvaW50LkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Doctype Woes (back to HTML4)http://lucumr.pocoo.org/cogitations/2007/10/03/doctype-woes-back-to-html4/2007-10-03T06:39:56Z2007-10-03T06:39:56ZArmin Ronacherdoctype-woes-back-to-html4yesyes2At the moment I'm working together with the rest of the webteam of the ubuntuusers Team on the new portal of ubuntuusers.de based on django. One of the things we will do is consolidating all templates. And while doing so we have to decide to use an HTML/XHTML standard which we will use including the correct mimetype and doctype.
And selecting that is the hardest part because once you've decided on something you have to live with the consequences and cannot really change. For example HTML and XHTML have a slightly different DOM or different rules for CSS (CSS for example has an exception that allows background colors on the body-tag to affect the whole page, this exception does not exist for XHTML). Without a doubt many people use XHTML in a wrong way. Just have a look how many people serve their webpages as text/html and only use HTML semantics. They break if you serve them as application/xml+xhtml or render in a wrong way.
But why does XML and SGML have different semantics? SGML itself was created long ago (I assume IBM has something to do with it, at least it's predecessor was created there) and is an insane specification. At least that's what the web told me. I cannot tell you if that's true or not because the standard itself is not available without paying for it :-/
From what sources tell me XML is an subset of SGML. I wonder how that's possible tough, because there are syntactic elements that in my opinion are not compatible. For example clash XML's self closing tags with null end tags in SGML:
<!-- PYGMENTS_CACHE><div class="highlight"><pre>XML <br /><br />
SGML: <p/This is some text in a paragraph/
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(text)>
XML <br /><br />
SGML: <p/This is some text in a paragraph/
<PYGMENTS_RAW -->
Because the slash has a special meaning in tags in SGML it clashes with the closing slash of XML tags. Also SGML is apparently case insensitive where XML is not. Maybe I'm also wrong there and that part is up to the DTD, but quite frankly. I don't care. I don't even are about clashing slashes in tags because no browser implements the correct SGML behavior. And if they would do, we would all see invalid output because the web is not valid. It's not and it will never be.
But what's indeed ridiculous is that it's incredible hard to write pages that are semantical and syntactical correct to both HTML4 and XHTML. However you <em>have to</em> make your documents compatible to both if you want to your page to be valid XHTML <em>and</em> render correctly. The reason is that no browser today selects the render mode by Doctype, and even if they would do, other browsers would break then on the huge number of pages that incorrectly use XHTML.
XML is strict, very strict. Syntactical errors appear as big red error messages. I for myself have to work on the wiki markup for the new portal and one of the things I have to deal with is balancing elements. That is possible and simple, but what's harder is adding paragraphs without breaking things. And that's not that easy because not every element is allowed in a paragraph and a paragraph cannot be mixed with every element thanks to inline versus block elements.
Even HTML5 disallows that mixing of different element types but at least it doesn't complain. Sure, I could send the output through a validator and tell the user that his markup is bullshit and he should correct it. But I won't do that. Users give a fuck about their markup. And I cannot bloat the parser more than it is now. Server resources are limited and additional validation for such a high traffic site is nearly impossible.
Fortunately browsers will never show you those errors because they parse XHTML with their tagsoup parser they use for HTML too. Even tough, if we cannot ensure that all of our pages are valid XML and XHTML we are not allowed to use the doctype because it would break browsers that support XHTML.
While this is hard for webdesigners and especially for programmers that want to create parsers that generate XHTML it's an even harder job for the developers of browsers. In the end they have to have two independent parsers for HTML and XHTML. This makes it hard enough for the big browser vendors Microsoft, Mozilla, Opera and Apple, but even harder if you are new to the market and want to ship your own one. Because you not only have to be compatible with the new XHTML standard, but also the old HTML one. Nobody will translate all the old documents to XHTML I'm sure ;-)
Details about the issues are summarized here:
<ul>
<li><a href="http://blogs.msdn.com/ie/archive/2005/09/15/467901.aspx">The <?xml> prolog, strict mode, and XHTML in IE</a> — Chris Wilson, Microsoft</li>
<li><a href="http://webkit.org/blog/68/understanding-html-xml-and-xhtml/">Understanding HTML, XML and XHTML</a> — Surfin' Safari Weblog</a></li>
<li><a href="http://www.hixie.ch/advocacy/xhtml">Sending XHTML as text/html Considered Harmful</a> — Ian Hickson</li>
<li><a href="http://annevankesteren.nl/2004/08/xhtml">Quick Guide to XHTML</a> — Anne van Kesteren</li>
<li><a href="http://www.xml.com/pub/a/2003/03/19/dive-into-xml.html">The Road to XHTML 2.0: MIME Types</a> — Mark Pilgrim</li>
</ul>
Without a doubt we will have fun with XHTML in the future. Probably the web stays like it's today, we will still use the tag soup parsers, people will write XHTML that is HTML in fact and browsers will interpret it like that.
For me the decision is HTML4 at the moment, with the subset that is valid for both HTML4 and HTML5. That could make it easier for transition once the standard is ready (and I hope it's earlier than 2022) and it's good idea now too. Who needs an u-Tag anyway?At the moment I'm working together with the rest of the webteam of the ubuntuusers Team on the new portal of ubuntuusers.de based on django. One of the things we will do is consolidating all templates. And while doing so we have to decide to use an HTML/XHTML standard which we will use including the correct mimetype and doctype.
And selecting that is the hardest part because once you've decided on something you have to live with the consequences and cannot really change. For example HTML and XHTML have a slightly different DOM or different rules for CSS (CSS for example has an exception that allows background colors on the body-tag to affect the whole page, this exception does not exist for XHTML). Without a doubt many people use XHTML in a wrong way. Just have a look how many people serve their webpages as text/html and only use HTML semantics. They break if you serve them as application/xml+xhtml or render in a wrong way.
But why does XML and SGML have different semantics? SGML itself was created long ago (I assume IBM has something to do with it, at least it's predecessor was created there) and is an insane specification. At least that's what the web told me. I cannot tell you if that's true or not because the standard itself is not available without paying for it :-/
From what sources tell me XML is an subset of SGML. I wonder how that's possible tough, because there are syntactic elements that in my opinion are not compatible. For example clash XML's self closing tags with null end tags in SGML:
Because the slash has a special meaning in tags in SGML it clashes with the closing slash of XML tags. Also SGML is apparently case insensitive where XML is not. Maybe I'm also wrong there and that part is up to the DTD, but quite frankly. I don't care. I don't even are about clashing slashes in tags because no browser implements the correct SGML behavior. And if they would do, we would all see invalid output because the web is not valid. It's not and it will never be.
But what's indeed ridiculous is that it's incredible hard to write pages that are semantical and syntactical correct to both HTML4 and XHTML. However you <em>have to</em> make your documents compatible to both if you want to your page to be valid XHTML <em>and</em> render correctly. The reason is that no browser today selects the render mode by Doctype, and even if they would do, other browsers would break then on the huge number of pages that incorrectly use XHTML.
XML is strict, very strict. Syntactical errors appear as big red error messages. I for myself have to work on the wiki markup for the new portal and one of the things I have to deal with is balancing elements. That is possible and simple, but what's harder is adding paragraphs without breaking things. And that's not that easy because not every element is allowed in a paragraph and a paragraph cannot be mixed with every element thanks to inline versus block elements.
Even HTML5 disallows that mixing of different element types but at least it doesn't complain. Sure, I could send the output through a validator and tell the user that his markup is bullshit and he should correct it. But I won't do that. Users give a fuck about their markup. And I cannot bloat the parser more than it is now. Server resources are limited and additional validation for such a high traffic site is nearly impossible.
Fortunately browsers will never show you those errors because they parse XHTML with their tagsoup parser they use for HTML too. Even tough, if we cannot ensure that all of our pages are valid XML and XHTML we are not allowed to use the doctype because it would break browsers that support XHTML.
While this is hard for webdesigners and especially for programmers that want to create parsers that generate XHTML it's an even harder job for the developers of browsers. In the end they have to have two independent parsers for HTML and XHTML. This makes it hard enough for the big browser vendors Microsoft, Mozilla, Opera and Apple, but even harder if you are new to the market and want to ship your own one. Because you not only have to be compatible with the new XHTML standard, but also the old HTML one. Nobody will translate all the old documents to XHTML I'm sure ;-)
Details about the issues are summarized here:
<ul>
<li><a href="http://blogs.msdn.com/ie/archive/2005/09/15/467901.aspx">The <?xml> prolog, strict mode, and XHTML in IE</a> — Chris Wilson, Microsoft</li>
<li><a href="http://webkit.org/blog/68/understanding-html-xml-and-xhtml/">Understanding HTML, XML and XHTML</a> — Surfin' Safari Weblog</li>
<li><a href="http://www.hixie.ch/advocacy/xhtml">Sending XHTML as text/html Considered Harmful</a> — Ian Hickson</li>
<li><a href="http://annevankesteren.nl/2004/08/xhtml">Quick Guide to XHTML</a> — Anne van Kesteren</li>
<li><a href="http://www.xml.com/pub/a/2003/03/19/dive-into-xml.html">The Road to XHTML 2.0: MIME Types</a> — Mark Pilgrim</li>
</ul>
Without a doubt we will have fun with XHTML in the future. Probably the web stays like it's today, we will still use the tag soup parsers, people will write XHTML that is HTML in fact and browsers will interpret it like that.
For me the decision is HTML4 at the moment, with the subset that is valid for both HTML4 and HTML5. That could make it easier for transition once the standard is ready (and I hope it's earlier than 2022) and it's good idea now too. Who needs an u-Tag anyway?SQAAAANTAAAABGJvZHlSUwAACG9BdCB0aGUgbW9tZW50IEknbSB3b3JraW5nIHRvZ2V0aGVyIHdp
dGggdGhlIHJlc3Qgb2YgdGhlIHdlYnRlYW0gb2YgdGhlIHVidW50dXVzZXJzIFRlYW0gb24gdGhl
IG5ldyBwb3J0YWwgb2YgdWJ1bnR1dXNlcnMuZGUgYmFzZWQgb24gZGphbmdvLiBPbmUgb2YgdGhl
IHRoaW5ncyB3ZSB3aWxsIGRvIGlzIGNvbnNvbGlkYXRpbmcgYWxsIHRlbXBsYXRlcy4gQW5kIHdo
aWxlIGRvaW5nIHNvIHdlIGhhdmUgdG8gZGVjaWRlIHRvIHVzZSBhbiBIVE1ML1hIVE1MIHN0YW5k
YXJkIHdoaWNoIHdlIHdpbGwgdXNlIGluY2x1ZGluZyB0aGUgY29ycmVjdCBtaW1ldHlwZSBhbmQg
ZG9jdHlwZS4KCkFuZCBzZWxlY3RpbmcgdGhhdCBpcyB0aGUgaGFyZGVzdCBwYXJ0IGJlY2F1c2Ug
b25jZSB5b3UndmUgZGVjaWRlZCBvbiBzb21ldGhpbmcgeW91IGhhdmUgdG8gbGl2ZSB3aXRoIHRo
ZSBjb25zZXF1ZW5jZXMgYW5kIGNhbm5vdCByZWFsbHkgY2hhbmdlLiBGb3IgZXhhbXBsZSBIVE1M
IGFuZCBYSFRNTCBoYXZlIGEgc2xpZ2h0bHkgZGlmZmVyZW50IERPTSBvciBkaWZmZXJlbnQgcnVs
ZXMgZm9yIENTUyAoQ1NTIGZvciBleGFtcGxlIGhhcyBhbiBleGNlcHRpb24gdGhhdCBhbGxvd3Mg
YmFja2dyb3VuZCBjb2xvcnMgb24gdGhlIGJvZHktdGFnIHRvIGFmZmVjdCB0aGUgd2hvbGUgcGFn
ZSwgdGhpcyBleGNlcHRpb24gZG9lcyBub3QgZXhpc3QgZm9yIFhIVE1MKS4gV2l0aG91dCBhIGRv
dWJ0IG1hbnkgcGVvcGxlIHVzZSBYSFRNTCBpbiBhIHdyb25nIHdheS4gSnVzdCBoYXZlIGEgbG9v
ayBob3cgbWFueSBwZW9wbGUgc2VydmUgdGhlaXIgd2VicGFnZXMgYXMgdGV4dC9odG1sIGFuZCBv
bmx5IHVzZSBIVE1MIHNlbWFudGljcy4gVGhleSBicmVhayBpZiB5b3Ugc2VydmUgdGhlbSBhcyBh
cHBsaWNhdGlvbi94bWwreGh0bWwgb3IgcmVuZGVyIGluIGEgd3Jvbmcgd2F5LgoKQnV0IHdoeSBk
b2VzIFhNTCBhbmQgU0dNTCBoYXZlIGRpZmZlcmVudCBzZW1hbnRpY3M/IFNHTUwgaXRzZWxmIHdh
cyBjcmVhdGVkIGxvbmcgYWdvIChJIGFzc3VtZSBJQk0gaGFzIHNvbWV0aGluZyB0byBkbyB3aXRo
IGl0LCBhdCBsZWFzdCBpdCdzIHByZWRlY2Vzc29yIHdhcyBjcmVhdGVkIHRoZXJlKSBhbmQgaXMg
YW4gaW5zYW5lIHNwZWNpZmljYXRpb24uIEF0IGxlYXN0IHRoYXQncyB3aGF0IHRoZSB3ZWIgdG9s
ZCBtZS4gSSBjYW5ub3QgdGVsbCB5b3UgaWYgdGhhdCdzIHRydWUgb3Igbm90IGJlY2F1c2UgdGhl
IHN0YW5kYXJkIGl0c2VsZiBpcyBub3QgYXZhaWxhYmxlIHdpdGhvdXQgcGF5aW5nIGZvciBpdCA6
LS8KCkZyb20gd2hhdCBzb3VyY2VzIHRlbGwgbWUgWE1MIGlzIGFuIHN1YnNldCBvZiBTR01MLiBJ
IHdvbmRlciBob3cgdGhhdCdzIHBvc3NpYmxlIHRvdWdoLCBiZWNhdXNlIHRoZXJlIGFyZSBzeW50
YWN0aWMgZWxlbWVudHMgdGhhdCBpbiBteSBvcGluaW9uIGFyZSBub3QgY29tcGF0aWJsZS4gRm9y
IGV4YW1wbGUgY2xhc2ggWE1MJ3Mgc2VsZiBjbG9zaW5nIHRhZ3Mgd2l0aCBudWxsIGVuZCB0YWdz
IGluIFNHTUw6CgpCZWNhdXNlIHRoZSBzbGFzaCBoYXMgYSBzcGVjaWFsIG1lYW5pbmcgaW4gdGFn
cyBpbiBTR01MIGl0IGNsYXNoZXMgd2l0aCB0aGUgY2xvc2luZyBzbGFzaCBvZiBYTUwgdGFncy4g
QWxzbyBTR01MIGlzIGFwcGFyZW50bHkgY2FzZSBpbnNlbnNpdGl2ZSB3aGVyZSBYTUwgaXMgbm90
LiBNYXliZSBJJ20gYWxzbyB3cm9uZyB0aGVyZSBhbmQgdGhhdCBwYXJ0IGlzIHVwIHRvIHRoZSBE
VEQsIGJ1dCBxdWl0ZSBmcmFua2x5LiBJIGRvbid0IGNhcmUuIEkgZG9uJ3QgZXZlbiBhcmUgYWJv
dXQgY2xhc2hpbmcgc2xhc2hlcyBpbiB0YWdzIGJlY2F1c2Ugbm8gYnJvd3NlciBpbXBsZW1lbnRz
IHRoZSBjb3JyZWN0IFNHTUwgYmVoYXZpb3IuIEFuZCBpZiB0aGV5IHdvdWxkIGRvLCB3ZSB3b3Vs
ZCBhbGwgc2VlIGludmFsaWQgb3V0cHV0IGJlY2F1c2UgdGhlIHdlYiBpcyBub3QgdmFsaWQuIEl0
J3Mgbm90IGFuZCBpdCB3aWxsIG5ldmVyIGJlLgoKQnV0IHdoYXQncyBpbmRlZWQgcmlkaWN1bG91
cyBpcyB0aGF0IGl0J3MgaW5jcmVkaWJsZSBoYXJkIHRvIHdyaXRlIHBhZ2VzIHRoYXQgYXJlIHNl
bWFudGljYWwgYW5kIHN5bnRhY3RpY2FsIGNvcnJlY3QgdG8gYm90aCBIVE1MNCBhbmQgWEhUTUwu
IEhvd2V2ZXIgeW91IEwAA0VTAAAAAmVtTAAATQAAUwAAAAdoYXZlIHRvUwAAAFMgbWFrZSB5b3Vy
IGRvY3VtZW50cyBjb21wYXRpYmxlIHRvIGJvdGggaWYgeW91IHdhbnQgdG8geW91ciBwYWdlIHRv
IGJlIHZhbGlkIFhIVE1MIEVTAAAAAmVtTAAATQAAUwAAAANhbmRTAAAH8CByZW5kZXIgY29ycmVj
dGx5LiBUaGUgcmVhc29uIGlzIHRoYXQgbm8gYnJvd3NlciB0b2RheSBzZWxlY3RzIHRoZSByZW5k
ZXIgbW9kZSBieSBEb2N0eXBlLCBhbmQgZXZlbiBpZiB0aGV5IHdvdWxkIGRvLCBvdGhlciBicm93
c2VycyB3b3VsZCBicmVhayB0aGVuIG9uIHRoZSBodWdlIG51bWJlciBvZiBwYWdlcyB0aGF0IGlu
Y29ycmVjdGx5IHVzZSBYSFRNTC4KClhNTCBpcyBzdHJpY3QsIHZlcnkgc3RyaWN0LiBTeW50YWN0
aWNhbCBlcnJvcnMgYXBwZWFyIGFzIGJpZyByZWQgZXJyb3IgbWVzc2FnZXMuIEkgZm9yIG15c2Vs
ZiBoYXZlIHRvIHdvcmsgb24gdGhlIHdpa2kgbWFya3VwIGZvciB0aGUgbmV3IHBvcnRhbCBhbmQg
b25lIG9mIHRoZSB0aGluZ3MgSSBoYXZlIHRvIGRlYWwgd2l0aCBpcyBiYWxhbmNpbmcgZWxlbWVu
dHMuIFRoYXQgaXMgcG9zc2libGUgYW5kIHNpbXBsZSwgYnV0IHdoYXQncyBoYXJkZXIgaXMgYWRk
aW5nIHBhcmFncmFwaHMgd2l0aG91dCBicmVha2luZyB0aGluZ3MuIEFuZCB0aGF0J3Mgbm90IHRo
YXQgZWFzeSBiZWNhdXNlIG5vdCBldmVyeSBlbGVtZW50IGlzIGFsbG93ZWQgaW4gYSBwYXJhZ3Jh
cGggYW5kIGEgcGFyYWdyYXBoIGNhbm5vdCBiZSBtaXhlZCB3aXRoIGV2ZXJ5IGVsZW1lbnQgdGhh
bmtzIHRvIGlubGluZSB2ZXJzdXMgYmxvY2sgZWxlbWVudHMuCgpFdmVuIEhUTUw1IGRpc2FsbG93
cyB0aGF0IG1peGluZyBvZiBkaWZmZXJlbnQgZWxlbWVudCB0eXBlcyBidXQgYXQgbGVhc3QgaXQg
ZG9lc24ndCBjb21wbGFpbi4gU3VyZSwgSSBjb3VsZCBzZW5kIHRoZSBvdXRwdXQgdGhyb3VnaCBh
IHZhbGlkYXRvciBhbmQgdGVsbCB0aGUgdXNlciB0aGF0IGhpcyBtYXJrdXAgaXMgYnVsbHNoaXQg
YW5kIGhlIHNob3VsZCBjb3JyZWN0IGl0LiBCdXQgSSB3b24ndCBkbyB0aGF0LiBVc2VycyBnaXZl
IGEgZnVjayBhYm91dCB0aGVpciBtYXJrdXAuIEFuZCBJIGNhbm5vdCBibG9hdCB0aGUgcGFyc2Vy
IG1vcmUgdGhhbiBpdCBpcyBub3cuIFNlcnZlciByZXNvdXJjZXMgYXJlIGxpbWl0ZWQgYW5kIGFk
ZGl0aW9uYWwgdmFsaWRhdGlvbiBmb3Igc3VjaCBhIGhpZ2ggdHJhZmZpYyBzaXRlIGlzIG5lYXJs
eSBpbXBvc3NpYmxlLgoKRm9ydHVuYXRlbHkgYnJvd3NlcnMgd2lsbCBuZXZlciBzaG93IHlvdSB0
aG9zZSBlcnJvcnMgYmVjYXVzZSB0aGV5IHBhcnNlIFhIVE1MIHdpdGggdGhlaXIgdGFnc291cCBw
YXJzZXIgdGhleSB1c2UgZm9yIEhUTUwgdG9vLiBFdmVuIHRvdWdoLCBpZiB3ZSBjYW5ub3QgZW5z
dXJlIHRoYXQgYWxsIG9mIG91ciBwYWdlcyBhcmUgdmFsaWQgWE1MIGFuZCBYSFRNTCB3ZSBhcmUg
bm90IGFsbG93ZWQgdG8gdXNlIHRoZSBkb2N0eXBlIGJlY2F1c2UgaXQgd291bGQgYnJlYWsgYnJv
d3NlcnMgdGhhdCBzdXBwb3J0IFhIVE1MLgoKV2hpbGUgdGhpcyBpcyBoYXJkIGZvciB3ZWJkZXNp
Z25lcnMgYW5kIGVzcGVjaWFsbHkgZm9yIHByb2dyYW1tZXJzIHRoYXQgd2FudCB0byBjcmVhdGUg
cGFyc2VycyB0aGF0IGdlbmVyYXRlIFhIVE1MIGl0J3MgYW4gZXZlbiBoYXJkZXIgam9iIGZvciB0
aGUgZGV2ZWxvcGVycyBvZiBicm93c2Vycy4gSW4gdGhlIGVuZCB0aGV5IGhhdmUgdG8gaGF2ZSB0
d28gaW5kZXBlbmRlbnQgcGFyc2VycyBmb3IgSFRNTCBhbmQgWEhUTUwuIFRoaXMgbWFrZXMgaXQg
aGFyZCBlbm91Z2ggZm9yIHRoZSBiaWcgYnJvd3NlciB2ZW5kb3JzIE1pY3Jvc29mdCwgTW96aWxs
YSwgT3BlcmEgYW5kIEFwcGxlLCBidXQgZXZlbiBoYXJkZXIgaWYgeW91IGFyZSBuZXcgdG8gdGhl
IG1hcmtldCBhbmQgd2FudCB0byBzaGlwIHlvdXIgb3duIG9uZS4gQmVjYXVzZSB5b3Ugbm90IG9u
bHkgaGF2ZSB0byBiZSBjb21wYXRpYmxlIHdpdGggdGhlIG5ldyBYSFRNTCBzdGFuZGFyZCwgYnV0
IGFsc28gdGhlIG9sZCBIVE1MIG9uZS4gTm9ib2R5IHdpbGwgdHJhbnNsYXRlIGFsbCB0aGUgb2xk
IGRvY3VtZW50cyB0byBYSFRNTCBJJ20gc3VyZSA7LSkKCkRldGFpbHMgYWJvdXQgdGhlIGlzc3Vl
cyBhcmUgc3VtbWFyaXplZCBoZXJlOgpFUwAAAAJ1bEwABUVTAAAAAmxpTAABRVMAAAABYUwAAE0A
AVMAAAAEaHJlZlMAAAA3aHR0cDovL2Jsb2dzLm1zZG4uY29tL2llL2FyY2hpdmUvMjAwNS8wOS8x
NS80Njc5MDEuYXNweFMAAAAvVGhlIDw/eG1sPiBwcm9sb2csIHN0cmljdCBtb2RlLCBhbmQgWEhU
TUwgaW4gSUVTAAAAHCDigJQgQ2hyaXMgV2lsc29uLCBNaWNyb3NvZnRNAABTAAAAAFMAAAADCiAg
RVMAAAACbGlMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADtodHRwOi8vd2Via2l0Lm9yZy9i
bG9nLzY4L3VuZGVyc3RhbmRpbmctaHRtbC14bWwtYW5kLXhodG1sL1MAAAAhVW5kZXJzdGFuZGlu
ZyBIVE1MLCBYTUwgYW5kIFhIVE1MUwAAABog4oCUIFN1cmZpbicgU2FmYXJpIFdlYmxvZ00AAFMA
AAAAUwAAAAMKICBFUwAAAAJsaUwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAImh0dHA6Ly93
d3cuaGl4aWUuY2gvYWR2b2NhY3kveGh0bWxTAAAALVNlbmRpbmcgWEhUTUwgYXMgdGV4dC9odG1s
IENvbnNpZGVyZWQgSGFybWZ1bFMAAAAQIOKAlCBJYW4gSGlja3Nvbk0AAFMAAAAAUwAAAAMKICBF
UwAAAAJsaUwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAJ2h0dHA6Ly9hbm5ldmFua2VzdGVy
ZW4ubmwvMjAwNC8wOC94aHRtbFMAAAAUUXVpY2sgR3VpZGUgdG8gWEhUTUxTAAAAFiDigJQgQW5u
ZSB2YW4gS2VzdGVyZW5NAABTAAAAAFMAAAADCiAgRVMAAAACbGlMAAFFUwAAAAFhTAAATQABUwAA
AARocmVmUwAAADZodHRwOi8vd3d3LnhtbC5jb20vcHViL2EvMjAwMy8wMy8xOS9kaXZlLWludG8t
eG1sLmh0bWxTAAAAIVRoZSBSb2FkIHRvIFhIVE1MIDIuMDogTUlNRSBUeXBlc1MAAAARIOKAlCBN
YXJrIFBpbGdyaW1NAABTAAAAAFMAAAABCk0AAFMAAAADCiAgUwAAAecKCldpdGhvdXQgYSBkb3Vi
dCB3ZSB3aWxsIGhhdmUgZnVuIHdpdGggWEhUTUwgaW4gdGhlIGZ1dHVyZS4gUHJvYmFibHkgdGhl
IHdlYiBzdGF5cyBsaWtlIGl0J3MgdG9kYXksIHdlIHdpbGwgc3RpbGwgdXNlIHRoZSB0YWcgc291
cCBwYXJzZXJzLCBwZW9wbGUgd2lsbCB3cml0ZSBYSFRNTCB0aGF0IGlzIEhUTUwgaW4gZmFjdCBh
bmQgYnJvd3NlcnMgd2lsbCBpbnRlcnByZXQgaXQgbGlrZSB0aGF0LgoKRm9yIG1lIHRoZSBkZWNp
c2lvbiBpcyBIVE1MNCBhdCB0aGUgbW9tZW50LCB3aXRoIHRoZSBzdWJzZXQgdGhhdCBpcyB2YWxp
ZCBmb3IgYm90aCBIVE1MNCBhbmQgSFRNTDUuIFRoYXQgY291bGQgbWFrZSBpdCBlYXNpZXIgZm9y
IHRyYW5zaXRpb24gb25jZSB0aGUgc3RhbmRhcmQgaXMgcmVhZHkgKGFuZCBJIGhvcGUgaXQncyBl
YXJsaWVyIHRoYW4gMjAyMikgYW5kIGl0J3MgZ29vZCBpZGVhIG5vdyB0b28uIFdobyBuZWVkcyBh
biB1LVRhZyBhbnl3YXk/UwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
karl dubost, w3ckarl@w3.orghttp://www.w3.org/QA/2007-10-03T22:13:07Znono0You said: "Fortunately browsers will never show you those errors because they parse XHTML with their tagsoup parser they use for HTML too."
But that will be true for HTML too. What is your incentive to write conformant HTML 4.01?You said: "Fortunately browsers will never show you those errors because they parse XHTML with their tagsoup parser they use for HTML too."
But that will be true for HTML too. What is your incentive to write conformant HTML 4.01?SQAAAAJTAAAABGJvZHlSUwAAAOZZb3Ugc2FpZDogIkZvcnR1bmF0ZWx5IGJyb3dzZXJzIHdpbGwg
bmV2ZXIgc2hvdyB5b3UgdGhvc2UgZXJyb3JzIGJlY2F1c2UgdGhleSBwYXJzZSBYSFRNTCB3aXRo
IHRoZWlyIHRhZ3NvdXAgcGFyc2VyIHRoZXkgdXNlIGZvciBIVE1MIHRvby4iCgpCdXQgdGhhdCB3
aWxsIGJlIHRydWUgZm9yIEhUTUwgdG9vLiBXaGF0IGlzIHlvdXIgaW5jZW50aXZlIHRvIHdyaXRl
IGNvbmZvcm1hbnQgSFRNTCA0LjAxP0wAAFMAAAAGcGFyc2VyUwAAAARodG1s
Alan Hynesahynes@cch.com.au2007-10-03T22:40:35Znono0I'm afraid it is true, XML is a (true) subset of SGML. SGML has an incredible amount of customisation available through the declaration of their DTDs, tag omissibility, short referencing, case-insensitivity, etc. etc. If you play around long enough, you can create SGML that is XML (through declarations and things, although there are always minor exceptions such as quoting of attribute values).
There's a really good reason that XML came along, SGML was just too flexible and incredibly difficult to write tools around that catered entirely to the specification and the freedom the declaration allowed. There are tools capable of displaying SGML rather well, but they aren't common and they usually aren't free.I'm afraid it is true, XML is a (true) subset of SGML. SGML has an incredible amount of customisation available through the declaration of their DTDs, tag omissibility, short referencing, case-insensitivity, etc. etc. If you play around long enough, you can create SGML that is XML (through declarations and things, although there are always minor exceptions such as quoting of attribute values).
There's a really good reason that XML came along, SGML was just too flexible and incredibly difficult to write tools around that catered entirely to the specification and the freedom the declaration allowed. There are tools capable of displaying SGML rather well, but they aren't common and they usually aren't free.SQAAAAJTAAAABGJvZHlSUwAAAslJJ20gYWZyYWlkIGl0IGlzIHRydWUsIFhNTCBpcyBhICh0cnVl
KSBzdWJzZXQgb2YgU0dNTC4gU0dNTCBoYXMgYW4gaW5jcmVkaWJsZSBhbW91bnQgb2YgY3VzdG9t
aXNhdGlvbiBhdmFpbGFibGUgdGhyb3VnaCB0aGUgZGVjbGFyYXRpb24gb2YgdGhlaXIgRFREcywg
dGFnIG9taXNzaWJpbGl0eSwgc2hvcnQgcmVmZXJlbmNpbmcsIGNhc2UtaW5zZW5zaXRpdml0eSwg
ZXRjLiBldGMuIElmIHlvdSBwbGF5IGFyb3VuZCBsb25nIGVub3VnaCwgeW91IGNhbiBjcmVhdGUg
U0dNTCB0aGF0IGlzIFhNTCAodGhyb3VnaCBkZWNsYXJhdGlvbnMgYW5kIHRoaW5ncywgYWx0aG91
Z2ggdGhlcmUgYXJlIGFsd2F5cyBtaW5vciBleGNlcHRpb25zIHN1Y2ggYXMgcXVvdGluZyBvZiBh
dHRyaWJ1dGUgdmFsdWVzKS4KVGhlcmUncyBhIHJlYWxseSBnb29kIHJlYXNvbiB0aGF0IFhNTCBj
YW1lIGFsb25nLCBTR01MIHdhcyBqdXN0IHRvbyBmbGV4aWJsZSBhbmQgaW5jcmVkaWJseSBkaWZm
aWN1bHQgdG8gd3JpdGUgdG9vbHMgYXJvdW5kIHRoYXQgY2F0ZXJlZCBlbnRpcmVseSB0byB0aGUg
c3BlY2lmaWNhdGlvbiBhbmQgdGhlIGZyZWVkb20gdGhlIGRlY2xhcmF0aW9uIGFsbG93ZWQuIFRo
ZXJlIGFyZSB0b29scyBjYXBhYmxlIG9mIGRpc3BsYXlpbmcgU0dNTCByYXRoZXIgd2VsbCwgYnV0
IHRoZXkgYXJlbid0IGNvbW1vbiBhbmQgdGhleSB1c3VhbGx5IGFyZW4ndCBmcmVlLkwAAFMAAAAG
cGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-10-05T18:17:43Znono0@Karl: Of course that's true for HTML. But at least as far as I know HTML was designed with the fail silently approach in mind. Which by the way was a very good idea for the early web because I allowed browser vendors to extend it. And I don't have a problem with the fact that XHTML has to by syntactically correct, it's just that it doesn't make things that much easier. The number of pages that incorrectly use XHTML is insane. If now browsers would implement XHTML like the w3c specified it half of the web2.0 breaks.
XHTML would probably have a brighter future if there wouldn't have been such a hype around it some years ago. People certainly misunderstood XHTML and started using it when browsers haven't supported it at all. And now browsers have the same problem like IE had ten years ago. They had to implement all the bugs of Netscape too so stay compatible.
Well. Let's see what the future brings, but so far XHTML just makes things a lot harder for the average developer.@Karl: Of course that's true for HTML. But at least as far as I know HTML was designed with the fail silently approach in mind. Which by the way was a very good idea for the early web because I allowed browser vendors to extend it. And I don't have a problem with the fact that XHTML has to by syntactically correct, it's just that it doesn't make things that much easier. The number of pages that incorrectly use XHTML is insane. If now browsers would implement XHTML like the w3c specified it half of the web2.0 breaks.
XHTML would probably have a brighter future if there wouldn't have been such a hype around it some years ago. People certainly misunderstood XHTML and started using it when browsers haven't supported it at all. And now browsers have the same problem like IE had ten years ago. They had to implement all the bugs of Netscape too so stay compatible.
Well. Let's see what the future brings, but so far XHTML just makes things a lot harder for the average developer.SQAAAAJTAAAABGJvZHlSUwAAA9pAS2FybDogT2YgY291cnNlIHRoYXQncyB0cnVlIGZvciBIVE1M
LiBCdXQgYXQgbGVhc3QgYXMgZmFyIGFzIEkga25vdyBIVE1MIHdhcyBkZXNpZ25lZCB3aXRoIHRo
ZSBmYWlsIHNpbGVudGx5IGFwcHJvYWNoIGluIG1pbmQuIFdoaWNoIGJ5IHRoZSB3YXkgd2FzIGEg
dmVyeSBnb29kIGlkZWEgZm9yIHRoZSBlYXJseSB3ZWIgYmVjYXVzZSBJIGFsbG93ZWQgYnJvd3Nl
ciB2ZW5kb3JzIHRvIGV4dGVuZCBpdC4gQW5kIEkgZG9uJ3QgaGF2ZSBhIHByb2JsZW0gd2l0aCB0
aGUgZmFjdCB0aGF0IFhIVE1MIGhhcyB0byBieSBzeW50YWN0aWNhbGx5IGNvcnJlY3QsIGl0J3Mg
anVzdCB0aGF0IGl0IGRvZXNuJ3QgbWFrZSB0aGluZ3MgdGhhdCBtdWNoIGVhc2llci4gVGhlIG51
bWJlciBvZiBwYWdlcyB0aGF0IGluY29ycmVjdGx5IHVzZSBYSFRNTCBpcyBpbnNhbmUuIElmIG5v
dyBicm93c2VycyB3b3VsZCBpbXBsZW1lbnQgWEhUTUwgbGlrZSB0aGUgdzNjIHNwZWNpZmllZCBp
dCBoYWxmIG9mIHRoZSB3ZWIyLjAgYnJlYWtzLgoKWEhUTUwgd291bGQgcHJvYmFibHkgaGF2ZSBh
IGJyaWdodGVyIGZ1dHVyZSBpZiB0aGVyZSB3b3VsZG4ndCBoYXZlIGJlZW4gc3VjaCBhIGh5cGUg
YXJvdW5kIGl0IHNvbWUgeWVhcnMgYWdvLiBQZW9wbGUgY2VydGFpbmx5IG1pc3VuZGVyc3Rvb2Qg
WEhUTUwgYW5kIHN0YXJ0ZWQgdXNpbmcgaXQgd2hlbiBicm93c2VycyBoYXZlbid0IHN1cHBvcnRl
ZCBpdCBhdCBhbGwuIEFuZCBub3cgYnJvd3NlcnMgaGF2ZSB0aGUgc2FtZSBwcm9ibGVtIGxpa2Ug
SUUgaGFkIHRlbiB5ZWFycyBhZ28uIFRoZXkgaGFkIHRvIGltcGxlbWVudCBhbGwgdGhlIGJ1Z3Mg
b2YgTmV0c2NhcGUgdG9vIHNvIHN0YXkgY29tcGF0aWJsZS4KCldlbGwuIExldCdzIHNlZSB3aGF0
IHRoZSBmdXR1cmUgYnJpbmdzLCBidXQgc28gZmFyIFhIVE1MIGp1c3QgbWFrZXMgdGhpbmdzIGEg
bG90IGhhcmRlciBmb3IgdGhlIGF2ZXJhZ2UgZGV2ZWxvcGVyLkwAAFMAAAAGcGFyc2VyUwAAAARo
dG1s
Lucumr Cogitations » Blog Archive » Abusing XHTMLhttp://lucumr.pocoo.org/cogitations/2007/10/05/abusing-xhtml/2007-10-05T18:35:31Znoyes0[...] small resumption to my previous post about XHTML/HTML here a small list of websites using XHTML that break when rendered on a browser in XHTML [...][...] small resumption to my previous post about XHTML/HTML here a small list of websites using XHTML that break when rendered on a browser in XHTML [...]SQAAAAJTAAAABGJvZHlSUwAAAJpbLi4uXSBzbWFsbCByZXN1bXB0aW9uIHRvIG15IHByZXZpb3Vz
IHBvc3QgYWJvdXQgWEhUTUwvSFRNTCBoZXJlIGEgc21hbGwgbGlzdCBvZiB3ZWJzaXRlcyB1c2lu
ZyBYSFRNTCB0aGF0IGJyZWFrIHdoZW4gcmVuZGVyZWQgb24gYSBicm93c2VyIGluIFhIVE1MIFsu
Li5dTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Pushing Apache Performancehttp://lucumr.pocoo.org/cogitations/2007/09/30/pushing-apache-performance/2007-09-30T21:56:28Z2007-09-30T21:56:28ZArmin Ronacherpushing-apache-performanceyesyes2You might know that pocoo.org had a an interesting availability, far below 99%. The problem we have had is that all pocoo services (and that are quite a lot) are hosted on a XEN instance with less less than 400MB RAM. With two different database servers (MySQL and postgres), hgweb, 7 trac instances, one pastebin, one dynamic project webpage, a blog and a bunch of static webpages apache loved to eat more memory than being available thus swapping.
Although there would certainly a possibility to get a better server or allocate more memory for the XEN instance it's possible to reconfigure things so that you can still use them. Here is what we did one week ago. We managed it to have a load of around 0.1 - 1.5 since a week, and a memory usage of around 200MB. Before that our load was between 2 and 50, depending on the time of the last apache restart ;-)
Step one: switch to worker. Apache prefork is certainly the worst thing you can do if you have few memory in your server. The reason for this is that prefork forks. While I agree that threads are problematic in many terms (especially PHP) they are the best way to keep your memory usage low. But worker means that you cannot use mod_php4/5. Because TextPress is still not ready I needed PHP support, so I've chosen to host it as CGI, more later.
The worker MPM has quite a lot of configuration parameters, and to be fair, I have no idea how the work in detail. The basics are covered in <a href="http://httpd.apache.org/docs/2.0/mod/worker.html">the apache documentation</a>. The configuration values that worked best for us where these:
<pre syntax="apache">
<IfModule worker.c>
ServerLimit 5
StartServers 1
MaxClients 30
MinSpareThreads 5
MaxSpareThreads 30
ThreadsPerChild 15
MaxRequestsPerChild 500
</IfModule></pre>
These settings start between 1 and 5 server processes (usually two because of MaxClients) where each of them handles 15 threads. After 500 requests the dispatcher is restarted. The latter is a very good idea because nearly every application leaks memory.
Now because I lost my blog a second after installing the worker module that was the next thing I changed. With version 5 onwards PHP is usually compiled as cgi/fastcgi binary so ready to rumble if you have mod_fastcgi. We do, but I have disabled it together with all unused modules. Although FastCGI is a lot faster than CGI and a really good idea if you expect many hits I've chosen CGI for the blog to not have a persistent PHP interpreter in the memory. Sadly this blog has the fewest hits of all our sites so until more visitors come here CGI is the way to go. If you are too lazy too look up the configuration, here is ours:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="nb">AddType</span> application/x-httpd-php .php
<span class="nb">Action</span> application/x-httpd-php <span class="sx">/php5-cgi</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(apache)>
AddType application/x-httpd-php .php
Action application/x-httpd-php /php5-cgi
<PYGMENTS_RAW -->
It's that simple. If you want to switch to fastcgi, all you have to do is to enable the FastCGI module and enable it for /php5-cgi.
But PHP will disappear on that server sooner or later anyways, so let's continue with speeding up the snakes. There the answer is simple: If you have an apache, use mod_wsgi. And then it depends on your applications. If you have different applications that do not interfere with each other and are threadsafe put them into the same process group and enable threading. Otherwise put them into different groups and use threading if they are thread safe. And let mod_wsgi kill processes after a thousand requests. The <a href="http://code.google.com/p/modwsgi/">mod_wsgi wiki</a> is full of examples, you will find all there.
The last step is making apache as such faster. Remove all .htaccess files and put their contents into the apache configs. Then set AllowOverride to None so that apache doesn't test for them any more. Set down your connection timeout to say 150 seconds, the number of MaxKeepAliveRequests down to something lower like 100 and the KeepAliveTimeout to 3. That might be annoying for people with slow network connections but it gives the apache the opportunity to mark worker threads as available sooner. Enable logrotation, log fewer stuff and do not log hostnames (check if HostnameLookup is set to Off).
That being said the only thing that is left is playing around with some of the configuration values of your database servers and other running processes that might consume memory.
Here the result as a fancy graph:
<img src="http://pocoo.org/~mitsuhiko/apache_config_effect.png" alt="swap status"/>.You might know that pocoo.org had a an interesting availability, far below 99%. The problem we have had is that all pocoo services (and that are quite a lot) are hosted on a XEN instance with less less than 400MB RAM. With two different database servers (MySQL and postgres), hgweb, 7 trac instances, one pastebin, one dynamic project webpage, a blog and a bunch of static webpages apache loved to eat more memory than being available thus swapping.
Although there would certainly a possibility to get a better server or allocate more memory for the XEN instance it's possible to reconfigure things so that you can still use them. Here is what we did one week ago. We managed it to have a load of around 0.1 - 1.5 since a week, and a memory usage of around 200MB. Before that our load was between 2 and 50, depending on the time of the last apache restart ;-)
Step one: switch to worker. Apache prefork is certainly the worst thing you can do if you have few memory in your server. The reason for this is that prefork forks. While I agree that threads are problematic in many terms (especially PHP) they are the best way to keep your memory usage low. But worker means that you cannot use mod_php4/5. Because TextPress is still not ready I needed PHP support, so I've chosen to host it as CGI, more later.
The worker MPM has quite a lot of configuration parameters, and to be fair, I have no idea how the work in detail. The basics are covered in <a href="http://httpd.apache.org/docs/2.0/mod/worker.html">the apache documentation</a>. The configuration values that worked best for us where these:
<pre syntax="apache"><ifmodule worker.c="">
ServerLimit 5
StartServers 1
MaxClients 30
MinSpareThreads 5
MaxSpareThreads 30
ThreadsPerChild 15
MaxRequestsPerChild 500
</ifmodule></pre>
These settings start between 1 and 5 server processes (usually two because of MaxClients) where each of them handles 15 threads. After 500 requests the dispatcher is restarted. The latter is a very good idea because nearly every application leaks memory.
Now because I lost my blog a second after installing the worker module that was the next thing I changed. With version 5 onwards PHP is usually compiled as cgi/fastcgi binary so ready to rumble if you have mod_fastcgi. We do, but I have disabled it together with all unused modules. Although FastCGI is a lot faster than CGI and a really good idea if you expect many hits I've chosen CGI for the blog to not have a persistent PHP interpreter in the memory. Sadly this blog has the fewest hits of all our sites so until more visitors come here CGI is the way to go. If you are too lazy too look up the configuration, here is ours:
It's that simple. If you want to switch to fastcgi, all you have to do is to enable the FastCGI module and enable it for /php5-cgi.
But PHP will disappear on that server sooner or later anyways, so let's continue with speeding up the snakes. There the answer is simple: If you have an apache, use mod_wsgi. And then it depends on your applications. If you have different applications that do not interfere with each other and are threadsafe put them into the same process group and enable threading. Otherwise put them into different groups and use threading if they are thread safe. And let mod_wsgi kill processes after a thousand requests. The <a href="http://code.google.com/p/modwsgi/">mod_wsgi wiki</a> is full of examples, you will find all there.
The last step is making apache as such faster. Remove all .htaccess files and put their contents into the apache configs. Then set AllowOverride to None so that apache doesn't test for them any more. Set down your connection timeout to say 150 seconds, the number of MaxKeepAliveRequests down to something lower like 100 and the KeepAliveTimeout to 3. That might be annoying for people with slow network connections but it gives the apache the opportunity to mark worker threads as available sooner. Enable logrotation, log fewer stuff and do not log hostnames (check if HostnameLookup is set to Off).
That being said the only thing that is left is playing around with some of the configuration values of your database servers and other running processes that might consume memory.
Here the result as a fancy graph:
<img src="http://pocoo.org/~mitsuhiko/apache_config_effect.png" alt="swap status">.SQAAAANTAAAABGJvZHlSUwAABapZb3UgbWlnaHQga25vdyB0aGF0IHBvY29vLm9yZyBoYWQgYSBh
biBpbnRlcmVzdGluZyBhdmFpbGFiaWxpdHksIGZhciBiZWxvdyA5OSUuIFRoZSBwcm9ibGVtIHdl
IGhhdmUgaGFkIGlzIHRoYXQgYWxsIHBvY29vIHNlcnZpY2VzIChhbmQgdGhhdCBhcmUgcXVpdGUg
YSBsb3QpIGFyZSBob3N0ZWQgb24gYSBYRU4gaW5zdGFuY2Ugd2l0aCBsZXNzIGxlc3MgdGhhbiA0
MDBNQiBSQU0uIFdpdGggdHdvIGRpZmZlcmVudCBkYXRhYmFzZSBzZXJ2ZXJzIChNeVNRTCBhbmQg
cG9zdGdyZXMpLCBoZ3dlYiwgNyB0cmFjIGluc3RhbmNlcywgb25lIHBhc3RlYmluLCBvbmUgZHlu
YW1pYyBwcm9qZWN0IHdlYnBhZ2UsIGEgYmxvZyBhbmQgYSBidW5jaCBvZiBzdGF0aWMgd2VicGFn
ZXMgYXBhY2hlIGxvdmVkIHRvIGVhdCBtb3JlIG1lbW9yeSB0aGFuIGJlaW5nIGF2YWlsYWJsZSB0
aHVzIHN3YXBwaW5nLgoKQWx0aG91Z2ggdGhlcmUgd291bGQgY2VydGFpbmx5IGEgcG9zc2liaWxp
dHkgdG8gZ2V0IGEgYmV0dGVyIHNlcnZlciBvciBhbGxvY2F0ZSBtb3JlIG1lbW9yeSBmb3IgdGhl
IFhFTiBpbnN0YW5jZSBpdCdzIHBvc3NpYmxlIHRvIHJlY29uZmlndXJlIHRoaW5ncyBzbyB0aGF0
IHlvdSBjYW4gc3RpbGwgdXNlIHRoZW0uIEhlcmUgaXMgd2hhdCB3ZSBkaWQgb25lIHdlZWsgYWdv
LiBXZSBtYW5hZ2VkIGl0IHRvIGhhdmUgYSBsb2FkIG9mIGFyb3VuZCAwLjEgLSAxLjUgc2luY2Ug
YSB3ZWVrLCBhbmQgYSBtZW1vcnkgdXNhZ2Ugb2YgYXJvdW5kIDIwME1CLiBCZWZvcmUgdGhhdCBv
dXIgbG9hZCB3YXMgYmV0d2VlbiAyIGFuZCA1MCwgZGVwZW5kaW5nIG9uIHRoZSB0aW1lIG9mIHRo
ZSBsYXN0IGFwYWNoZSByZXN0YXJ0IDstKQoKU3RlcCBvbmU6IHN3aXRjaCB0byB3b3JrZXIuIEFw
YWNoZSBwcmVmb3JrIGlzIGNlcnRhaW5seSB0aGUgd29yc3QgdGhpbmcgeW91IGNhbiBkbyBpZiB5
b3UgaGF2ZSBmZXcgbWVtb3J5IGluIHlvdXIgc2VydmVyLiBUaGUgcmVhc29uIGZvciB0aGlzIGlz
IHRoYXQgcHJlZm9yayBmb3Jrcy4gV2hpbGUgSSBhZ3JlZSB0aGF0IHRocmVhZHMgYXJlIHByb2Js
ZW1hdGljIGluIG1hbnkgdGVybXMgKGVzcGVjaWFsbHkgUEhQKSB0aGV5IGFyZSB0aGUgYmVzdCB3
YXkgdG8ga2VlcCB5b3VyIG1lbW9yeSB1c2FnZSBsb3cuIEJ1dCB3b3JrZXIgbWVhbnMgdGhhdCB5
b3UgY2Fubm90IHVzZSBtb2RfcGhwNC81LiBCZWNhdXNlIFRleHRQcmVzcyBpcyBzdGlsbCBub3Qg
cmVhZHkgSSBuZWVkZWQgUEhQIHN1cHBvcnQsIHNvIEkndmUgY2hvc2VuIHRvIGhvc3QgaXQgYXMg
Q0dJLCBtb3JlIGxhdGVyLgoKVGhlIHdvcmtlciBNUE0gaGFzIHF1aXRlIGEgbG90IG9mIGNvbmZp
Z3VyYXRpb24gcGFyYW1ldGVycywgYW5kIHRvIGJlIGZhaXIsIEkgaGF2ZSBubyBpZGVhIGhvdyB0
aGUgd29yayBpbiBkZXRhaWwuIFRoZSBiYXNpY3MgYXJlIGNvdmVyZWQgaW4gTAAERVMAAAABYUwA
AE0AAVMAAAAEaHJlZlMAAAAwaHR0cDovL2h0dHBkLmFwYWNoZS5vcmcvZG9jcy8yLjAvbW9kL3dv
cmtlci5odG1sUwAAABh0aGUgYXBhY2hlIGRvY3VtZW50YXRpb25TAAAAQC4gVGhlIGNvbmZpZ3Vy
YXRpb24gdmFsdWVzIHRoYXQgd29ya2VkIGJlc3QgZm9yIHVzIHdoZXJlIHRoZXNlOgpFUwAAAANw
cmVMAAFFUwAAAAhpZm1vZHVsZUwAAE0AAVMAAAAId29ya2VyLmNTAAAAAFMAAACwClNlcnZlckxp
bWl0ICAgICAgICAgICAgNQpTdGFydFNlcnZlcnMgICAgICAgICAgIDEKTWF4Q2xpZW50cyAgICAg
ICAgICAgIDMwCk1pblNwYXJlVGhyZWFkcyAgICAgICAgNQpNYXhTcGFyZVRocmVhZHMgICAgICAg
MzAKVGhyZWFkc1BlckNoaWxkICAgICAgIDE1Ck1heFJlcXVlc3RzUGVyQ2hpbGQgIDUwMApTAAAA
AE0AAVMAAAAGc3ludGF4UwAAAAZhcGFjaGVTAAAAAFMAAAYAClRoZXNlIHNldHRpbmdzIHN0YXJ0
IGJldHdlZW4gMSBhbmQgNSBzZXJ2ZXIgcHJvY2Vzc2VzICh1c3VhbGx5IHR3byBiZWNhdXNlIG9m
IE1heENsaWVudHMpIHdoZXJlIGVhY2ggb2YgdGhlbSBoYW5kbGVzIDE1IHRocmVhZHMuIEFmdGVy
IDUwMCByZXF1ZXN0cyB0aGUgZGlzcGF0Y2hlciBpcyByZXN0YXJ0ZWQuIFRoZSBsYXR0ZXIgaXMg
YSB2ZXJ5IGdvb2QgaWRlYSBiZWNhdXNlIG5lYXJseSBldmVyeSBhcHBsaWNhdGlvbiBsZWFrcyBt
ZW1vcnkuCgpOb3cgYmVjYXVzZSBJIGxvc3QgbXkgYmxvZyBhIHNlY29uZCBhZnRlciBpbnN0YWxs
aW5nIHRoZSB3b3JrZXIgbW9kdWxlIHRoYXQgd2FzIHRoZSBuZXh0IHRoaW5nIEkgY2hhbmdlZC4g
V2l0aCB2ZXJzaW9uIDUgb253YXJkcyBQSFAgaXMgdXN1YWxseSBjb21waWxlZCBhcyBjZ2kvZmFz
dGNnaSBiaW5hcnkgc28gcmVhZHkgdG8gcnVtYmxlIGlmIHlvdSBoYXZlIG1vZF9mYXN0Y2dpLiBX
ZSBkbywgYnV0IEkgaGF2ZSBkaXNhYmxlZCBpdCB0b2dldGhlciB3aXRoIGFsbCB1bnVzZWQgbW9k
dWxlcy4gQWx0aG91Z2ggRmFzdENHSSBpcyBhIGxvdCBmYXN0ZXIgdGhhbiBDR0kgYW5kIGEgcmVh
bGx5IGdvb2QgaWRlYSBpZiB5b3UgZXhwZWN0IG1hbnkgaGl0cyBJJ3ZlIGNob3NlbiBDR0kgZm9y
IHRoZSBibG9nIHRvIG5vdCBoYXZlIGEgcGVyc2lzdGVudCBQSFAgaW50ZXJwcmV0ZXIgaW4gdGhl
IG1lbW9yeS4gU2FkbHkgdGhpcyBibG9nIGhhcyB0aGUgZmV3ZXN0IGhpdHMgb2YgYWxsIG91ciBz
aXRlcyBzbyB1bnRpbCBtb3JlIHZpc2l0b3JzIGNvbWUgaGVyZSBDR0kgaXMgdGhlIHdheSB0byBn
by4gSWYgeW91IGFyZSB0b28gbGF6eSB0b28gbG9vayB1cCB0aGUgY29uZmlndXJhdGlvbiwgaGVy
ZSBpcyBvdXJzOgoKSXQncyB0aGF0IHNpbXBsZS4gSWYgeW91IHdhbnQgdG8gc3dpdGNoIHRvIGZh
c3RjZ2ksIGFsbCB5b3UgaGF2ZSB0byBkbyBpcyB0byBlbmFibGUgdGhlIEZhc3RDR0kgbW9kdWxl
IGFuZCBlbmFibGUgaXQgZm9yIC9waHA1LWNnaS4KCkJ1dCBQSFAgd2lsbCBkaXNhcHBlYXIgb24g
dGhhdCBzZXJ2ZXIgc29vbmVyIG9yIGxhdGVyIGFueXdheXMsIHNvIGxldCdzIGNvbnRpbnVlIHdp
dGggc3BlZWRpbmcgdXAgdGhlIHNuYWtlcy4gVGhlcmUgdGhlIGFuc3dlciBpcyBzaW1wbGU6IElm
IHlvdSBoYXZlIGFuIGFwYWNoZSwgdXNlIG1vZF93c2dpLiBBbmQgdGhlbiBpdCBkZXBlbmRzIG9u
IHlvdXIgYXBwbGljYXRpb25zLiBJZiB5b3UgaGF2ZSBkaWZmZXJlbnQgYXBwbGljYXRpb25zIHRo
YXQgZG8gbm90IGludGVyZmVyZSB3aXRoIGVhY2ggb3RoZXIgYW5kIGFyZSB0aHJlYWRzYWZlIHB1
dCB0aGVtIGludG8gdGhlIHNhbWUgcHJvY2VzcyBncm91cCBhbmQgZW5hYmxlIHRocmVhZGluZy4g
T3RoZXJ3aXNlIHB1dCB0aGVtIGludG8gZGlmZmVyZW50IGdyb3VwcyBhbmQgdXNlIHRocmVhZGlu
ZyBpZiB0aGV5IGFyZSB0aHJlYWQgc2FmZS4gQW5kIGxldCBtb2Rfd3NnaSBraWxsIHByb2Nlc3Nl
cyBhZnRlciBhIHRob3VzYW5kIHJlcXVlc3RzLiBUaGUgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMA
AAAhaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL21vZHdzZ2kvUwAAAA1tb2Rfd3NnaSB3aWtpUwAA
A2IgaXMgZnVsbCBvZiBleGFtcGxlcywgeW91IHdpbGwgZmluZCBhbGwgdGhlcmUuCgpUaGUgbGFz
dCBzdGVwIGlzIG1ha2luZyBhcGFjaGUgYXMgc3VjaCBmYXN0ZXIuIFJlbW92ZSBhbGwgLmh0YWNj
ZXNzIGZpbGVzIGFuZCBwdXQgdGhlaXIgY29udGVudHMgaW50byB0aGUgYXBhY2hlIGNvbmZpZ3Mu
IFRoZW4gc2V0IEFsbG93T3ZlcnJpZGUgdG8gTm9uZSBzbyB0aGF0IGFwYWNoZSBkb2Vzbid0IHRl
c3QgZm9yIHRoZW0gYW55IG1vcmUuIFNldCBkb3duIHlvdXIgY29ubmVjdGlvbiB0aW1lb3V0IHRv
IHNheSAxNTAgc2Vjb25kcywgdGhlIG51bWJlciBvZiBNYXhLZWVwQWxpdmVSZXF1ZXN0cyBkb3du
IHRvIHNvbWV0aGluZyBsb3dlciBsaWtlIDEwMCBhbmQgdGhlIEtlZXBBbGl2ZVRpbWVvdXQgdG8g
My4gVGhhdCBtaWdodCBiZSBhbm5veWluZyBmb3IgcGVvcGxlIHdpdGggc2xvdyBuZXR3b3JrIGNv
bm5lY3Rpb25zIGJ1dCBpdCBnaXZlcyB0aGUgYXBhY2hlIHRoZSBvcHBvcnR1bml0eSB0byBtYXJr
IHdvcmtlciB0aHJlYWRzIGFzIGF2YWlsYWJsZSBzb29uZXIuIEVuYWJsZSBsb2dyb3RhdGlvbiwg
bG9nIGZld2VyIHN0dWZmIGFuZCBkbyBub3QgbG9nIGhvc3RuYW1lcyAoY2hlY2sgaWYgSG9zdG5h
bWVMb29rdXAgaXMgc2V0IHRvIE9mZikuCgpUaGF0IGJlaW5nIHNhaWQgdGhlIG9ubHkgdGhpbmcg
dGhhdCBpcyBsZWZ0IGlzIHBsYXlpbmcgYXJvdW5kIHdpdGggc29tZSBvZiB0aGUgY29uZmlndXJh
dGlvbiB2YWx1ZXMgb2YgeW91ciBkYXRhYmFzZSBzZXJ2ZXJzIGFuZCBvdGhlciBydW5uaW5nIHBy
b2Nlc3NlcyB0aGF0IG1pZ2h0IGNvbnN1bWUgbWVtb3J5LgoKSGVyZSB0aGUgcmVzdWx0IGFzIGEg
ZmFuY3kgZ3JhcGg6CkVTAAAAA2ltZ0wAAE0AAlMAAAADc3JjUwAAADRodHRwOi8vcG9jb28ub3Jn
L35taXRzdWhpa28vYXBhY2hlX2NvbmZpZ19lZmZlY3QucG5nUwAAAANhbHRTAAAAC3N3YXAgc3Rh
dHVzUwAAAABTAAAAAS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2007-10-01T04:15:47Znono0A further way of reducing what Apache is doing is to turn off logging of requests into the access log altogether. This can be done by not defining CustomLog directive and as far as raw performance goes has more impact than one would expect. Of course, since the bottleneck of web applications is generally elsewhere, eg. database access, in the greater scheme of things the lower overhead may not be noticeable. Although this can help in increasing raw throughput for simple requests and static files, I'm not sure how memory use is affected, so if you did try this would be interested in any feedback.
Now if you like having the access log present so you can gather your own site statistics, one alternative would be to setup all your pages to include tags for Google Analytics and use it to track site usage instead. This way the overhead of tracking site usage is pushed onto the client browser and Google instead, and you aren't wasting your own systems limited resources.
BTW, this only disables logging of requests, any details of exceptional events would still be logged to the error log. Thus, if your Python web applications throw a wobbly, you will still be able to see why. :-)A further way of reducing what Apache is doing is to turn off logging of requests into the access log altogether. This can be done by not defining CustomLog directive and as far as raw performance goes has more impact than one would expect. Of course, since the bottleneck of web applications is generally elsewhere, eg. database access, in the greater scheme of things the lower overhead may not be noticeable. Although this can help in increasing raw throughput for simple requests and static files, I'm not sure how memory use is affected, so if you did try this would be interested in any feedback.
Now if you like having the access log present so you can gather your own site statistics, one alternative would be to setup all your pages to include tags for Google Analytics and use it to track site usage instead. This way the overhead of tracking site usage is pushed onto the client browser and Google instead, and you aren't wasting your own systems limited resources.
BTW, this only disables logging of requests, any details of exceptional events would still be logged to the error log. Thus, if your Python web applications throw a wobbly, you will still be able to see why. :-)SQAAAAJTAAAABGJvZHlSUwAABKZBIGZ1cnRoZXIgd2F5IG9mIHJlZHVjaW5nIHdoYXQgQXBhY2hl
IGlzIGRvaW5nIGlzIHRvIHR1cm4gb2ZmIGxvZ2dpbmcgb2YgcmVxdWVzdHMgaW50byB0aGUgYWNj
ZXNzIGxvZyBhbHRvZ2V0aGVyLiBUaGlzIGNhbiBiZSBkb25lIGJ5IG5vdCBkZWZpbmluZyBDdXN0
b21Mb2cgZGlyZWN0aXZlIGFuZCBhcyBmYXIgYXMgcmF3IHBlcmZvcm1hbmNlIGdvZXMgaGFzIG1v
cmUgaW1wYWN0IHRoYW4gb25lIHdvdWxkIGV4cGVjdC4gT2YgY291cnNlLCBzaW5jZSB0aGUgYm90
dGxlbmVjayBvZiB3ZWIgYXBwbGljYXRpb25zIGlzIGdlbmVyYWxseSBlbHNld2hlcmUsIGVnLiBk
YXRhYmFzZSBhY2Nlc3MsIGluIHRoZSBncmVhdGVyIHNjaGVtZSBvZiB0aGluZ3MgdGhlIGxvd2Vy
IG92ZXJoZWFkIG1heSBub3QgYmUgbm90aWNlYWJsZS4gQWx0aG91Z2ggdGhpcyBjYW4gaGVscCBp
biBpbmNyZWFzaW5nIHJhdyB0aHJvdWdocHV0IGZvciBzaW1wbGUgcmVxdWVzdHMgYW5kIHN0YXRp
YyBmaWxlcywgSSdtIG5vdCBzdXJlIGhvdyBtZW1vcnkgdXNlIGlzIGFmZmVjdGVkLCBzbyBpZiB5
b3UgZGlkIHRyeSB0aGlzIHdvdWxkIGJlIGludGVyZXN0ZWQgaW4gYW55IGZlZWRiYWNrLgoKTm93
IGlmIHlvdSBsaWtlIGhhdmluZyB0aGUgYWNjZXNzIGxvZyBwcmVzZW50IHNvIHlvdSBjYW4gZ2F0
aGVyIHlvdXIgb3duIHNpdGUgc3RhdGlzdGljcywgb25lIGFsdGVybmF0aXZlIHdvdWxkIGJlIHRv
IHNldHVwIGFsbCB5b3VyIHBhZ2VzIHRvIGluY2x1ZGUgdGFncyBmb3IgR29vZ2xlIEFuYWx5dGlj
cyBhbmQgdXNlIGl0IHRvIHRyYWNrIHNpdGUgdXNhZ2UgaW5zdGVhZC4gVGhpcyB3YXkgdGhlIG92
ZXJoZWFkIG9mIHRyYWNraW5nIHNpdGUgdXNhZ2UgaXMgcHVzaGVkIG9udG8gdGhlIGNsaWVudCBi
cm93c2VyIGFuZCBHb29nbGUgaW5zdGVhZCwgYW5kIHlvdSBhcmVuJ3Qgd2FzdGluZyB5b3VyIG93
biBzeXN0ZW1zIGxpbWl0ZWQgcmVzb3VyY2VzLgoKQlRXLCB0aGlzIG9ubHkgZGlzYWJsZXMgbG9n
Z2luZyBvZiByZXF1ZXN0cywgYW55IGRldGFpbHMgb2YgZXhjZXB0aW9uYWwgZXZlbnRzIHdvdWxk
IHN0aWxsIGJlIGxvZ2dlZCB0byB0aGUgZXJyb3IgbG9nLiBUaHVzLCBpZiB5b3VyIFB5dGhvbiB3
ZWIgYXBwbGljYXRpb25zIHRocm93IGEgd29iYmx5LCB5b3Ugd2lsbCBzdGlsbCBiZSBhYmxlIHRv
IHNlZSB3aHkuIDotKUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Alexander Solovyovpiranha@piranha.org.uahttp://piranha.org.ua/2007-10-01T07:58:41Znono0IMHO better way to go is installing of nginx as frontend and serving static images through it. After that you can disable KeepAlive in apache completely.IMHO better way to go is installing of nginx as frontend and serving static images through it. After that you can disable KeepAlive in apache completely.SQAAAAJTAAAABGJvZHlSUwAAAJlJTUhPIGJldHRlciB3YXkgdG8gZ28gaXMgaW5zdGFsbGluZyBv
ZiBuZ2lueCBhcyBmcm9udGVuZCBhbmQgc2VydmluZyBzdGF0aWMgaW1hZ2VzIHRocm91Z2ggaXQu
IEFmdGVyIHRoYXQgeW91IGNhbiBkaXNhYmxlIEtlZXBBbGl2ZSBpbiBhcGFjaGUgY29tcGxldGVs
eS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-10-01T09:10:51Znono0@Graham: I'll come back to that once we run out of resources again :-)
@Alexander: nginx is certainly a good server for static files and I may think about it once the load increases again but for the moment every additional process requires more time to maintain and update it.@Graham: I'll come back to that once we run out of resources again :-)
@Alexander: nginx is certainly a good server for static files and I may think about it once the load increases again but for the moment every additional process requires more time to maintain and update it.SQAAAAJTAAAABGJvZHlSUwAAARVAR3JhaGFtOiBJJ2xsIGNvbWUgYmFjayB0byB0aGF0IG9uY2Ug
d2UgcnVuIG91dCBvZiByZXNvdXJjZXMgYWdhaW4gOi0pCkBBbGV4YW5kZXI6IG5naW54IGlzIGNl
cnRhaW5seSBhIGdvb2Qgc2VydmVyIGZvciBzdGF0aWMgZmlsZXMgYW5kIEkgbWF5IHRoaW5rIGFi
b3V0IGl0IG9uY2UgdGhlIGxvYWQgaW5jcmVhc2VzIGFnYWluIGJ1dCBmb3IgdGhlIG1vbWVudCBl
dmVyeSBhZGRpdGlvbmFsIHByb2Nlc3MgcmVxdWlyZXMgbW9yZSB0aW1lIHRvIG1haW50YWluIGFu
ZCB1cGRhdGUgaXQuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Paulpaul@findlay.net.nzhttp://findlay.net.nz/paul/2007-10-01T10:01:22Znono0Hey this may seem like a weird request, but when you switch over to Textpress can you remember to redirect your http://lucumr.pocoo.org/cogitations/feed/atom/ feed as well?Hey this may seem like a weird request, but when you switch over to Textpress can you remember to redirect your http://lucumr.pocoo.org/cogitations/feed/atom/ feed as well?SQAAAAJTAAAABGJvZHlSUwAAAKxIZXkgdGhpcyBtYXkgc2VlbSBsaWtlIGEgd2VpcmQgcmVxdWVz
dCwgYnV0IHdoZW4geW91IHN3aXRjaCBvdmVyIHRvIFRleHRwcmVzcyBjYW4geW91IHJlbWVtYmVy
IHRvIHJlZGlyZWN0IHlvdXIgaHR0cDovL2x1Y3Vtci5wb2Nvby5vcmcvY29naXRhdGlvbnMvZmVl
ZC9hdG9tLyBmZWVkIGFzIHdlbGw/TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
sapphirecatno@example.comhttp://www.sapphirepaw.org/2007-10-01T17:36:40Znono0mod_php most certainly does support threads, but only if it's compiled to do so. Obviously a canned mod_php for prefork won't run with worker, but worker isn't fundamentally incompatible with mod_php. This is what TSRM is all about! (And although TSRM can't protect you if you try to use non-threadsafe C libraries from worker, that's not technically PHP's fault.)mod_php most certainly does support threads, but only if it's compiled to do so. Obviously a canned mod_php for prefork won't run with worker, but worker isn't fundamentally incompatible with mod_php. This is what TSRM is all about! (And although TSRM can't protect you if you try to use non-threadsafe C libraries from worker, that's not technically PHP's fault.)SQAAAAJTAAAABGJvZHlSUwAAAWxtb2RfcGhwIG1vc3QgY2VydGFpbmx5IGRvZXMgc3VwcG9ydCB0
aHJlYWRzLCBidXQgb25seSBpZiBpdCdzIGNvbXBpbGVkIHRvIGRvIHNvLiBPYnZpb3VzbHkgYSBj
YW5uZWQgbW9kX3BocCBmb3IgcHJlZm9yayB3b24ndCBydW4gd2l0aCB3b3JrZXIsIGJ1dCB3b3Jr
ZXIgaXNuJ3QgZnVuZGFtZW50YWxseSBpbmNvbXBhdGlibGUgd2l0aCBtb2RfcGhwLiBUaGlzIGlz
IHdoYXQgVFNSTSBpcyBhbGwgYWJvdXQhIChBbmQgYWx0aG91Z2ggVFNSTSBjYW4ndCBwcm90ZWN0
IHlvdSBpZiB5b3UgdHJ5IHRvIHVzZSBub24tdGhyZWFkc2FmZSBDIGxpYnJhcmllcyBmcm9tIHdv
cmtlciwgdGhhdCdzIG5vdCB0ZWNobmljYWxseSBQSFAncyBmYXVsdC4pTAAAUwAAAAZwYXJzZXJT
AAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-10-01T19:31:34Znono0Well, mod_php might be threadsafe to some part if compiled with support for that but before I compile mod_php by hand I use a binary. That has the advantage that apt-get keeps it up to date automatically.
@Paul: I hope I don't forget ;-)Well, mod_php might be threadsafe to some part if compiled with support for that but before I compile mod_php by hand I use a binary. That has the advantage that apt-get keeps it up to date automatically.
@Paul: I hope I don't forget ;-)SQAAAAJTAAAABGJvZHlSUwAAAO5XZWxsLCBtb2RfcGhwIG1pZ2h0IGJlIHRocmVhZHNhZmUgdG8g
c29tZSBwYXJ0IGlmIGNvbXBpbGVkIHdpdGggc3VwcG9ydCBmb3IgdGhhdCBidXQgYmVmb3JlIEkg
Y29tcGlsZSBtb2RfcGhwIGJ5IGhhbmQgSSB1c2UgYSBiaW5hcnkuIFRoYXQgaGFzIHRoZSBhZHZh
bnRhZ2UgdGhhdCBhcHQtZ2V0IGtlZXBzIGl0IHVwIHRvIGRhdGUgYXV0b21hdGljYWxseS4KCkBQ
YXVsOiBJIGhvcGUgSSBkb24ndCBmb3JnZXQgOy0pTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
On Sandboxing Genshihttp://lucumr.pocoo.org/cogitations/2007/09/26/on-sandboxing-genshi/2007-09-26T19:12:10Z2007-09-26T19:12:10ZArmin Ronacheron-sandboxing-genshiyesyes2One of the big advantages of django templates is that they are sandboxed. And the django sandbox is pretty secure because templates provide nearly no possibility to screw things up, especially because there is no way to put logic into django templates. The only possibility you have to add a security problem to django templates is writing broken template tags or stuff like that. Now Jinja has real expressions and with them the possibility to screw things up. But the Jinja core itself restricts access to python internals and as long as you keep your objects save nobody will be able to execute arbitrary python code in a template or access the filesystem.
Some time ago Christopher Lenz <a href="http://www.cmlenz.net/blog/2007/07/more-on-logic-i.html">blogged about logic in templates</a>, and one of the things he stated there was the following sentence about Genshi:
<blockquote>But even though I personally prefer working with a template language that allows me to use a real programming language (Python, Ruby, etc), there is definitely room for template languages that put severe restrictions on what you can do with them. An obvious example is that you're running a site such as Typepad, and want to allow users to manage their own custom templates. As things currently stand, you wouldn't be able to do that using Genshi.</blockquote>
Just because Genshi doesn't support it by now this doesn't mean it will stay like that. In fact the great architecture of Genshi makes sandboxing Genshi quite simple. To see how secure we can get Genshi I <a href="http://svn.edgewall.org/repos/genshi/branches/experimental/sandboxed/">started a Genshi branch today</a>. Maybe you can use Genshi soon for user provided templates :-)
<small>Other notice, I got quite a few mails that my blog is/was broken. As you might now we have had some problems with the load of our server the last months. To resolve that problem i tweaked the apache the last two days and while doing that various services behaved strangely or caused problems. By now everything should work again.</small>One of the big advantages of django templates is that they are sandboxed. And the django sandbox is pretty secure because templates provide nearly no possibility to screw things up, especially because there is no way to put logic into django templates. The only possibility you have to add a security problem to django templates is writing broken template tags or stuff like that. Now Jinja has real expressions and with them the possibility to screw things up. But the Jinja core itself restricts access to python internals and as long as you keep your objects save nobody will be able to execute arbitrary python code in a template or access the filesystem.
Some time ago Christopher Lenz <a href="http://www.cmlenz.net/blog/2007/07/more-on-logic-i.html">blogged about logic in templates</a>, and one of the things he stated there was the following sentence about Genshi:
<blockquote>But even though I personally prefer working with a template language that allows me to use a real programming language (Python, Ruby, etc), there is definitely room for template languages that put severe restrictions on what you can do with them. An obvious example is that you're running a site such as Typepad, and want to allow users to manage their own custom templates. As things currently stand, you wouldn't be able to do that using Genshi.</blockquote>
Just because Genshi doesn't support it by now this doesn't mean it will stay like that. In fact the great architecture of Genshi makes sandboxing Genshi quite simple. To see how secure we can get Genshi I <a href="http://svn.edgewall.org/repos/genshi/branches/experimental/sandboxed/">started a Genshi branch today</a>. Maybe you can use Genshi soon for user provided templates :-)
<small>Other notice, I got quite a few mails that my blog is/was broken. As you might now we have had some problems with the load of our server the last months. To resolve that problem i tweaked the apache the last two days and while doing that various services behaved strangely or caused problems. By now everything should work again.</small>SQAAAANTAAAABGJvZHlSUwAAArRPbmUgb2YgdGhlIGJpZyBhZHZhbnRhZ2VzIG9mIGRqYW5nbyB0
ZW1wbGF0ZXMgaXMgdGhhdCB0aGV5IGFyZSBzYW5kYm94ZWQuIEFuZCB0aGUgZGphbmdvIHNhbmRi
b3ggaXMgcHJldHR5IHNlY3VyZSBiZWNhdXNlIHRlbXBsYXRlcyBwcm92aWRlIG5lYXJseSBubyBw
b3NzaWJpbGl0eSB0byBzY3JldyB0aGluZ3MgdXAsIGVzcGVjaWFsbHkgYmVjYXVzZSB0aGVyZSBp
cyBubyB3YXkgdG8gcHV0IGxvZ2ljIGludG8gZGphbmdvIHRlbXBsYXRlcy4gVGhlIG9ubHkgcG9z
c2liaWxpdHkgeW91IGhhdmUgdG8gYWRkIGEgc2VjdXJpdHkgcHJvYmxlbSB0byBkamFuZ28gdGVt
cGxhdGVzIGlzIHdyaXRpbmcgYnJva2VuIHRlbXBsYXRlIHRhZ3Mgb3Igc3R1ZmYgbGlrZSB0aGF0
LiBOb3cgSmluamEgaGFzIHJlYWwgZXhwcmVzc2lvbnMgYW5kIHdpdGggdGhlbSB0aGUgcG9zc2li
aWxpdHkgdG8gc2NyZXcgdGhpbmdzIHVwLiBCdXQgdGhlIEppbmphIGNvcmUgaXRzZWxmIHJlc3Ry
aWN0cyBhY2Nlc3MgdG8gcHl0aG9uIGludGVybmFscyBhbmQgYXMgbG9uZyBhcyB5b3Uga2VlcCB5
b3VyIG9iamVjdHMgc2F2ZSBub2JvZHkgd2lsbCBiZSBhYmxlIHRvIGV4ZWN1dGUgYXJiaXRyYXJ5
IHB5dGhvbiBjb2RlIGluIGEgdGVtcGxhdGUgb3IgYWNjZXNzIHRoZSBmaWxlc3lzdGVtLgoKU29t
ZSB0aW1lIGFnbyBDaHJpc3RvcGhlciBMZW56IEwABEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAA
N2h0dHA6Ly93d3cuY21sZW56Lm5ldC9ibG9nLzIwMDcvMDcvbW9yZS1vbi1sb2dpYy1pLmh0bWxT
AAAAIGJsb2dnZWQgYWJvdXQgbG9naWMgaW4gdGVtcGxhdGVzUwAAAFEsIGFuZCBvbmUgb2YgdGhl
IHRoaW5ncyBoZSBzdGF0ZWQgdGhlcmUgd2FzIHRoZSBmb2xsb3dpbmcgc2VudGVuY2UgYWJvdXQg
R2Vuc2hpOgpFUwAAAApibG9ja3F1b3RlTAAATQAAUwAAAb9CdXQgZXZlbiB0aG91Z2ggSSBwZXJz
b25hbGx5IHByZWZlciB3b3JraW5nIHdpdGggYSB0ZW1wbGF0ZSBsYW5ndWFnZSB0aGF0IGFsbG93
cyBtZSB0byB1c2UgYSByZWFsIHByb2dyYW1taW5nIGxhbmd1YWdlIChQeXRob24sIFJ1YnksIGV0
YyksIHRoZXJlIGlzIGRlZmluaXRlbHkgcm9vbSBmb3IgdGVtcGxhdGUgbGFuZ3VhZ2VzIHRoYXQg
cHV0IHNldmVyZSByZXN0cmljdGlvbnMgb24gd2hhdCB5b3UgY2FuIGRvIHdpdGggdGhlbS4gQW4g
b2J2aW91cyBleGFtcGxlIGlzIHRoYXQgeW91J3JlIHJ1bm5pbmcgYSBzaXRlIHN1Y2ggYXMgVHlw
ZXBhZCwgYW5kIHdhbnQgdG8gYWxsb3cgdXNlcnMgdG8gbWFuYWdlIHRoZWlyIG93biBjdXN0b20g
dGVtcGxhdGVzLiBBcyB0aGluZ3MgY3VycmVudGx5IHN0YW5kLCB5b3Ugd291bGRuJ3QgYmUgYWJs
ZSB0byBkbyB0aGF0IHVzaW5nIEdlbnNoaS5TAAAAzwoKSnVzdCBiZWNhdXNlIEdlbnNoaSBkb2Vz
bid0IHN1cHBvcnQgaXQgYnkgbm93IHRoaXMgZG9lc24ndCBtZWFuIGl0IHdpbGwgc3RheSBsaWtl
IHRoYXQuIEluIGZhY3QgdGhlIGdyZWF0IGFyY2hpdGVjdHVyZSBvZiBHZW5zaGkgbWFrZXMgc2Fu
ZGJveGluZyBHZW5zaGkgcXVpdGUgc2ltcGxlLiBUbyBzZWUgaG93IHNlY3VyZSB3ZSBjYW4gZ2V0
IEdlbnNoaSBJIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAARWh0dHA6Ly9zdm4uZWRnZXdhbGwu
b3JnL3JlcG9zL2dlbnNoaS9icmFuY2hlcy9leHBlcmltZW50YWwvc2FuZGJveGVkL1MAAAAdc3Rh
cnRlZCBhIEdlbnNoaSBicmFuY2ggdG9kYXlTAAAAQS4gTWF5YmUgeW91IGNhbiB1c2UgR2Vuc2hp
IHNvb24gZm9yIHVzZXIgcHJvdmlkZWQgdGVtcGxhdGVzIDotKQoKRVMAAAAFc21hbGxMAABNAABT
AAABSU90aGVyIG5vdGljZSwgSSBnb3QgcXVpdGUgYSBmZXcgbWFpbHMgdGhhdCBteSBibG9nIGlz
L3dhcyBicm9rZW4uIEFzIHlvdSBtaWdodCBub3cgd2UgaGF2ZSBoYWQgc29tZSBwcm9ibGVtcyB3
aXRoIHRoZSBsb2FkIG9mIG91ciBzZXJ2ZXIgdGhlIGxhc3QgbW9udGhzLiBUbyByZXNvbHZlIHRo
YXQgcHJvYmxlbSBpIHR3ZWFrZWQgdGhlIGFwYWNoZSB0aGUgbGFzdCB0d28gZGF5cyBhbmQgd2hp
bGUgZG9pbmcgdGhhdCB2YXJpb3VzIHNlcnZpY2VzIGJlaGF2ZWQgc3RyYW5nZWx5IG9yIGNhdXNl
ZCBwcm9ibGVtcy4gQnkgbm93IGV2ZXJ5dGhpbmcgc2hvdWxkIHdvcmsgYWdhaW4uUwAAAABTAAAA
BnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Christopher Lenzcmlenz@gmx.dehttp://www.cmlenz.net/2007-09-27T12:37:41Znono0Btw, about Django templates being sandboxed/secure:
<a href="http://groups.google.com/group/django-developers/browse_thread/thread/28eac0b3787de93/51e1946f5b97e97e#51e1946f5b97e97e" rel="nofollow">include tag security hole</a>
(Hope that comes out right, there are no hints here about how comments are supposed to be formatted to include links etc)Btw, about Django templates being sandboxed/secure:
<a href="http://groups.google.com/group/django-developers/browse_thread/thread/28eac0b3787de93/51e1946f5b97e97e#51e1946f5b97e97e" rel="nofollow">include tag security hole</a>
(Hope that comes out right, there are no hints here about how comments are supposed to be formatted to include links etc)SQAAAAJTAAAABGJvZHlSUwAAADdCdHcsIGFib3V0IERqYW5nbyB0ZW1wbGF0ZXMgYmVpbmcgc2Fu
ZGJveGVkL3NlY3VyZToKCiAgTAABRVMAAAABYUwAAE0AAlMAAAAEaHJlZlMAAAB3aHR0cDovL2dy
b3Vwcy5nb29nbGUuY29tL2dyb3VwL2RqYW5nby1kZXZlbG9wZXJzL2Jyb3dzZV90aHJlYWQvdGhy
ZWFkLzI4ZWFjMGIzNzg3ZGU5My81MWUxOTQ2ZjViOTdlOTdlIzUxZTE5NDZmNWI5N2U5N2VTAAAA
A3JlbFMAAAAIbm9mb2xsb3dTAAAAGWluY2x1ZGUgdGFnIHNlY3VyaXR5IGhvbGVTAAAAewoKKEhv
cGUgdGhhdCBjb21lcyBvdXQgcmlnaHQsIHRoZXJlIGFyZSBubyBoaW50cyBoZXJlIGFib3V0IGhv
dyBjb21tZW50cyBhcmUgc3VwcG9zZWQgdG8gYmUgZm9ybWF0dGVkIHRvIGluY2x1ZGUgbGlua3Mg
ZXRjKVMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-09-27T16:17:53Znono0I have no idea how comments are parsed in WordPress, probably some limited amount of HTML, i shortened the link in the admin.
That thing is definitively bad, I thought the django template loader makes sure nothing outside of the django root is included. That couldn't happen with Genshi ;-)I have no idea how comments are parsed in WordPress, probably some limited amount of HTML, i shortened the link in the admin.
That thing is definitively bad, I thought the django template loader makes sure nothing outside of the django root is included. That couldn't happen with Genshi ;-)SQAAAAJTAAAABGJvZHlSUwAAASNJIGhhdmUgbm8gaWRlYSBob3cgY29tbWVudHMgYXJlIHBhcnNl
ZCBpbiBXb3JkUHJlc3MsIHByb2JhYmx5IHNvbWUgbGltaXRlZCBhbW91bnQgb2YgSFRNTCwgaSBz
aG9ydGVuZWQgdGhlIGxpbmsgaW4gdGhlIGFkbWluLgoKVGhhdCB0aGluZyBpcyBkZWZpbml0aXZl
bHkgYmFkLCBJIHRob3VnaHQgdGhlIGRqYW5nbyB0ZW1wbGF0ZSBsb2FkZXIgbWFrZXMgc3VyZSBu
b3RoaW5nIG91dHNpZGUgb2YgdGhlIGRqYW5nbyByb290IGlzIGluY2x1ZGVkLiBUaGF0IGNvdWxk
bid0IGhhcHBlbiB3aXRoIEdlbnNoaSA7LSlMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Where is Dawn of Ubuntu?http://lucumr.pocoo.org/cogitations/2007/09/21/where-is-dawn-of-ubuntu/2007-09-20T22:25:14Z2007-09-20T22:25:14ZArmin Ronacherwhere-is-dawn-of-ubuntuyesyes2<a href="http://lifehacker.com/photogallery/Desktop-Show-and-Tell-for-Linux/2684085">And one more time</a> I have to find my wallpaper on an ubuntu screenshot with a message like this below:
<blockquote>I'm running Ubuntu 7.04 (Feisty Fawn) with Compiz Fusion version 0.5.5 at the time of this screenshot. Wallpaper is the Dawn of Ubuntu wallpaper that for some reason wasn't included in Feisty, but if you can find it on Flickr or Google Images if you like it.</blockquote>
So why is that wallpaper not in ubuntu any more? The reason is a misunderstanding and my own personal lack of license knowledge. I released it with a limited CC license which was not compatible with the ubuntu license, just that nobody noticed till (edgy? feisty?) no idea. Anyhow. If someone is missing that wallpaper, you can find it in the art section. And if one wants to have that in ubuntu again, file a bug in launchpad. I will do my best then to resolve that licensing issue.<a href="http://lifehacker.com/photogallery/Desktop-Show-and-Tell-for-Linux/2684085">And one more time</a> I have to find my wallpaper on an ubuntu screenshot with a message like this below:
<blockquote>I'm running Ubuntu 7.04 (Feisty Fawn) with Compiz Fusion version 0.5.5 at the time of this screenshot. Wallpaper is the Dawn of Ubuntu wallpaper that for some reason wasn't included in Feisty, but if you can find it on Flickr or Google Images if you like it.</blockquote>
So why is that wallpaper not in ubuntu any more? The reason is a misunderstanding and my own personal lack of license knowledge. I released it with a limited CC license which was not compatible with the ubuntu license, just that nobody noticed till (edgy? feisty?) no idea. Anyhow. If someone is missing that wallpaper, you can find it in the art section. And if one wants to have that in ubuntu again, file a bug in launchpad. I will do my best then to resolve that licensing issue.SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAEpodHRwOi8v
bGlmZWhhY2tlci5jb20vcGhvdG9nYWxsZXJ5L0Rlc2t0b3AtU2hvdy1hbmQtVGVsbC1mb3ItTGlu
dXgvMjY4NDA4NVMAAAARQW5kIG9uZSBtb3JlIHRpbWVTAAAAVSBJIGhhdmUgdG8gZmluZCBteSB3
YWxscGFwZXIgb24gYW4gdWJ1bnR1IHNjcmVlbnNob3Qgd2l0aCBhIG1lc3NhZ2UgbGlrZSB0aGlz
IGJlbG93OgpFUwAAAApibG9ja3F1b3RlTAAATQAAUwAAAQJJJ20gcnVubmluZyBVYnVudHUgNy4w
NCAoRmVpc3R5IEZhd24pIHdpdGggQ29tcGl6IEZ1c2lvbiB2ZXJzaW9uIDAuNS41IGF0IHRoZSB0
aW1lIG9mIHRoaXMgc2NyZWVuc2hvdC4gV2FsbHBhcGVyIGlzIHRoZSBEYXduIG9mIFVidW50dSB3
YWxscGFwZXIgdGhhdCBmb3Igc29tZSByZWFzb24gd2Fzbid0IGluY2x1ZGVkIGluIEZlaXN0eSwg
YnV0IGlmIHlvdSBjYW4gZmluZCBpdCBvbiBGbGlja3Igb3IgR29vZ2xlIEltYWdlcyBpZiB5b3Ug
bGlrZSBpdC5TAAAB5ApTbyB3aHkgaXMgdGhhdCB3YWxscGFwZXIgbm90IGluIHVidW50dSBhbnkg
bW9yZT8gVGhlIHJlYXNvbiBpcyBhIG1pc3VuZGVyc3RhbmRpbmcgYW5kIG15IG93biBwZXJzb25h
bCBsYWNrIG9mIGxpY2Vuc2Uga25vd2xlZGdlLiBJIHJlbGVhc2VkIGl0IHdpdGggYSBsaW1pdGVk
IENDIGxpY2Vuc2Ugd2hpY2ggd2FzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIHVidW50dSBsaWNl
bnNlLCBqdXN0IHRoYXQgbm9ib2R5IG5vdGljZWQgdGlsbCAoZWRneT8gZmVpc3R5Pykgbm8gaWRl
YS4gQW55aG93LiBJZiBzb21lb25lIGlzIG1pc3NpbmcgdGhhdCB3YWxscGFwZXIsIHlvdSBjYW4g
ZmluZCBpdCBpbiB0aGUgYXJ0IHNlY3Rpb24uIEFuZCBpZiBvbmUgd2FudHMgdG8gaGF2ZSB0aGF0
IGluIHVidW50dSBhZ2FpbiwgZmlsZSBhIGJ1ZyBpbiBsYXVuY2hwYWQuIEkgd2lsbCBkbyBteSBi
ZXN0IHRoZW4gdG8gcmVzb2x2ZSB0aGF0IGxpY2Vuc2luZyBpc3N1ZS5TAAAABnBhcnNlclMAAAAE
aHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Great Cover Versionshttp://lucumr.pocoo.org/cogitations/2007/09/19/great-cover-versions/2007-09-19T14:50:33Z2007-09-19T14:50:33ZArmin Ronachergreat-cover-versionsyesyes2<a href="http://www.synflood.at/blog/">AK</a> <a href="http://www.synflood.at/blog/exit.php?url_id=1497&entry_id=700">blogged</a> <a href="http://www.synflood.at/blog/index.php?/archives/700-Coverversionen-II.html">about</a> <a href="http://en.wikipedia.org/wiki/Cover_version">it</a> some time ago, now I have to do it too. I bought the new <a href="http://www.apocalyptica.com/">apocalyptica</a> album <a href="http://en.wikipedia.org/wiki/Worlds_Collide_(album)">worlds collide</a> and one of the tracks is called "Helden", the singer for that particular track is Till Lindemann of Rammstein. Believe it or not, that's a German cover of David Bowies "heroes". And darn, I hate Bowie, I hate "heroes", but the apocalyptica cover is awesome. And one of the best covers I've ever heard.<a href="http://www.synflood.at/blog/">AK</a> <a href="http://www.synflood.at/blog/exit.php?url_id=1497&entry_id=700">blogged</a> <a href="http://www.synflood.at/blog/index.php?/archives/700-Coverversionen-II.html">about</a> <a href="http://en.wikipedia.org/wiki/Cover_version">it</a> some time ago, now I have to do it too. I bought the new <a href="http://www.apocalyptica.com/">apocalyptica</a> album <a href="http://en.wikipedia.org/wiki/Worlds_Collide_(album)">worlds collide</a> and one of the tracks is called "Helden", the singer for that particular track is Till Lindemann of Rammstein. Believe it or not, that's a German cover of David Bowies "heroes". And darn, I hate Bowie, I hate "heroes", but the apocalyptica cover is awesome. And one of the best covers I've ever heard.SQAAAANTAAAABGJvZHlSUwAAAABMAAZFUwAAAAFhTAAATQABUwAAAARocmVmUwAAABxodHRwOi8v
d3d3LnN5bmZsb29kLmF0L2Jsb2cvUwAAAAJBS1MAAAABIEVTAAAAAWFMAABNAAFTAAAABGhyZWZT
AAAAPWh0dHA6Ly93d3cuc3luZmxvb2QuYXQvYmxvZy9leGl0LnBocD91cmxfaWQ9MTQ5NyZlbnRy
eV9pZD03MDBTAAAAB2Jsb2dnZWRTAAAAASBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAEpodHRw
Oi8vd3d3LnN5bmZsb29kLmF0L2Jsb2cvaW5kZXgucGhwPy9hcmNoaXZlcy83MDAtQ292ZXJ2ZXJz
aW9uZW4tSUkuaHRtbFMAAAAFYWJvdXRTAAAAASBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACpo
dHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvdmVyX3ZlcnNpb25TAAAAAml0UwAAADogc29t
ZSB0aW1lIGFnbywgbm93IEkgaGF2ZSB0byBkbyBpdCB0b28uIEkgYm91Z2h0IHRoZSBuZXcgRVMA
AAABYUwAAE0AAVMAAAAEaHJlZlMAAAAcaHR0cDovL3d3dy5hcG9jYWx5cHRpY2EuY29tL1MAAAAM
YXBvY2FseXB0aWNhUwAAAAcgYWxidW0gRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAzaHR0cDov
L2VuLndpa2lwZWRpYS5vcmcvd2lraS9Xb3JsZHNfQ29sbGlkZV8oYWxidW0pUwAAAA53b3JsZHMg
Y29sbGlkZVMAAAEuIGFuZCBvbmUgb2YgdGhlIHRyYWNrcyBpcyBjYWxsZWQgIkhlbGRlbiIsIHRo
ZSBzaW5nZXIgZm9yIHRoYXQgcGFydGljdWxhciB0cmFjayBpcyBUaWxsIExpbmRlbWFubiBvZiBS
YW1tc3RlaW4uIEJlbGlldmUgaXQgb3Igbm90LCB0aGF0J3MgYSBHZXJtYW4gY292ZXIgb2YgRGF2
aWQgQm93aWVzICJoZXJvZXMiLiBBbmQgZGFybiwgSSBoYXRlIEJvd2llLCBJIGhhdGUgImhlcm9l
cyIsIGJ1dCB0aGUgYXBvY2FseXB0aWNhIGNvdmVyIGlzIGF3ZXNvbWUuIEFuZCBvbmUgb2YgdGhl
IGJlc3QgY292ZXJzIEkndmUgZXZlciBoZWFyZC5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50
cm9SUwAAAABMAAA=
Rachel Evans12345eldoradolover@globalintranet.net2007-09-20T06:55:25Znono0Of course it's awesome, it's Till Lindemann. That man is awesome personified!Of course it's awesome, it's Till Lindemann. That man is awesome personified!SQAAAAJTAAAABGJvZHlSUwAAAE1PZiBjb3Vyc2UgaXQncyBhd2Vzb21lLCBpdCdzIFRpbGwgTGlu
ZGVtYW5uLiBUaGF0IG1hbiBpcyBhd2Vzb21lIHBlcnNvbmlmaWVkIUwAAFMAAAAGcGFyc2VyUwAA
AARodG1s
Waiting in Line for…http://lucumr.pocoo.org/cogitations/2007/09/18/waiting-in-line-for/2007-09-18T20:44:45Z2007-09-18T20:44:45ZArmin Ronacherwaiting-in-line-foryesyes2...for what? Being the first one that discovers the hidden bugs and limitations before anyone else does? There was only one product in my life I bought on the Launchday. And that way a Nintendo DS which I bought on the same day as two of my best friends. And now I think even that was a bad decision because until the DS Lite came out I only owned two games. If I would have waited until then I would have had the new revision and saved some money too.
Why do I say that? Because <a href="http://www.youtube.com/watch?v=xlcygXYK_Y0">Bill Maher</a> got it exactly right some days ago, even if people <a href="http://www.jonholato.com/2007/09/18/bill-maher-bashes-iphone-early-adopters/">disagree</a>. There is absolutely no need to buy things on the first day. Wait for the other fools that do so. Let them find out if said product really does what the company says in the advertisements. Or try it a week after launch in a store nearby, which is the even better idea. And if you wait for longer than half a year you can then find out if you really, really wanted it. If you don't even think about it any more there was no need in buying. That saves money and spares nerves. And on the long run you will be happier too, I promise....for what? Being the first one that discovers the hidden bugs and limitations before anyone else does? There was only one product in my life I bought on the Launchday. And that way a Nintendo DS which I bought on the same day as two of my best friends. And now I think even that was a bad decision because until the DS Lite came out I only owned two games. If I would have waited until then I would have had the new revision and saved some money too.
Why do I say that? Because <a href="http://www.youtube.com/watch?v=xlcygXYK_Y0">Bill Maher</a> got it exactly right some days ago, even if people <a href="http://www.jonholato.com/2007/09/18/bill-maher-bashes-iphone-early-adopters/">disagree</a>. There is absolutely no need to buy things on the first day. Wait for the other fools that do so. Let them find out if said product really does what the company says in the advertisements. Or try it a week after launch in a store nearby, which is the even better idea. And if you wait for longer than half a year you can then find out if you really, really wanted it. If you don't even think about it any more there was no need in buying. That saves money and spares nerves. And on the long run you will be happier too, I promise.SQAAAANTAAAABGJvZHlSUwAAAeEuLi5mb3Igd2hhdD8gQmVpbmcgdGhlIGZpcnN0IG9uZSB0aGF0
IGRpc2NvdmVycyB0aGUgaGlkZGVuIGJ1Z3MgYW5kIGxpbWl0YXRpb25zIGJlZm9yZSBhbnlvbmUg
ZWxzZSBkb2VzPyBUaGVyZSB3YXMgb25seSBvbmUgcHJvZHVjdCBpbiBteSBsaWZlIEkgYm91Z2h0
IG9uIHRoZSBMYXVuY2hkYXkuIEFuZCB0aGF0IHdheSBhIE5pbnRlbmRvIERTIHdoaWNoIEkgYm91
Z2h0IG9uIHRoZSBzYW1lIGRheSBhcyB0d28gb2YgbXkgYmVzdCBmcmllbmRzLiBBbmQgbm93IEkg
dGhpbmsgZXZlbiB0aGF0IHdhcyBhIGJhZCBkZWNpc2lvbiBiZWNhdXNlIHVudGlsIHRoZSBEUyBM
aXRlIGNhbWUgb3V0IEkgb25seSBvd25lZCB0d28gZ2FtZXMuIElmIEkgd291bGQgaGF2ZSB3YWl0
ZWQgdW50aWwgdGhlbiBJIHdvdWxkIGhhdmUgaGFkIHRoZSBuZXcgcmV2aXNpb24gYW5kIHNhdmVk
IHNvbWUgbW9uZXkgdG9vLgoKV2h5IGRvIEkgc2F5IHRoYXQ/IEJlY2F1c2UgTAACRVMAAAABYUwA
AE0AAVMAAAAEaHJlZlMAAAAqaHR0cDovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PXhsY3lnWFlL
X1kwUwAAAApCaWxsIE1haGVyUwAAADQgZ290IGl0IGV4YWN0bHkgcmlnaHQgc29tZSBkYXlzIGFn
bywgZXZlbiBpZiBwZW9wbGUgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAABMaHR0cDovL3d3dy5q
b25ob2xhdG8uY29tLzIwMDcvMDkvMTgvYmlsbC1tYWhlci1iYXNoZXMtaXBob25lLWVhcmx5LWFk
b3B0ZXJzL1MAAAAIZGlzYWdyZWVTAAACEy4gVGhlcmUgaXMgYWJzb2x1dGVseSBubyBuZWVkIHRv
IGJ1eSB0aGluZ3Mgb24gdGhlIGZpcnN0IGRheS4gV2FpdCBmb3IgdGhlIG90aGVyIGZvb2xzIHRo
YXQgZG8gc28uIExldCB0aGVtIGZpbmQgb3V0IGlmIHNhaWQgcHJvZHVjdCByZWFsbHkgZG9lcyB3
aGF0IHRoZSBjb21wYW55IHNheXMgaW4gdGhlIGFkdmVydGlzZW1lbnRzLiBPciB0cnkgaXQgYSB3
ZWVrIGFmdGVyIGxhdW5jaCBpbiBhIHN0b3JlIG5lYXJieSwgd2hpY2ggaXMgdGhlIGV2ZW4gYmV0
dGVyIGlkZWEuIEFuZCBpZiB5b3Ugd2FpdCBmb3IgbG9uZ2VyIHRoYW4gaGFsZiBhIHllYXIgeW91
IGNhbiB0aGVuIGZpbmQgb3V0IGlmIHlvdSByZWFsbHksIHJlYWxseSB3YW50ZWQgaXQuIElmIHlv
dSBkb24ndCBldmVuIHRoaW5rIGFib3V0IGl0IGFueSBtb3JlIHRoZXJlIHdhcyBubyBuZWVkIGlu
IGJ1eWluZy4gVGhhdCBzYXZlcyBtb25leSBhbmQgc3BhcmVzIG5lcnZlcy4gQW5kIG9uIHRoZSBs
b25nIHJ1biB5b3Ugd2lsbCBiZSBoYXBwaWVyIHRvbywgSSBwcm9taXNlLlMAAAAGcGFyc2VyUwAA
AARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Using CleverCSS in Djangohttp://lucumr.pocoo.org/cogitations/2007/09/17/using-clevercss-in-django/2007-09-17T07:02:49Z2007-09-17T07:02:49ZArmin Ronacherusing-clevercss-in-djangoyesyes2A few minutes ago I pushed <a href="http://sandbox.pocoo.org/clevercss/">CleverCSS</a> to the cheeseshop. So far there is no framework support, once again you have to hack up the bridge yourself, but in this post I'll show a simple way to get CleverCSS running in django and simplify your CSS files.
The preferred way to use CleverCSS is compiling the clevercss files into css, and not doing that dynamically. But because during development this can be annoying, if you have to recompile your files by hand all the time, I suggest using a view that serves those files dynamically during development. In production usage you just overlay the view URL with an apache directive etc. that points to the folder with the static css files in.
Here the view function, you can store it directly in your urls.py because it's that small. Otherwise move it into a application responsible for static stuff:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">import</span> <span class="nn">clevercss</span>
<span class="k">from</span> <span class="nn">os</span> <span class="k">import</span> <span class="n">path</span>
<span class="k">from</span> <span class="nn">django.http</span> <span class="k">import</span> <span class="n">HttpResponse</span><span class="p">,</span> <span class="n">Http404</span>
<span class="k">def</span> <span class="nf">serve_ccss_file</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
<span class="n">fn</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">__file__</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">pardir</span><span class="p">,</span> <span class="s">'styles'</span><span class="p">,</span> <span class="n">filename</span> <span class="o">+</span> <span class="s">'.dcss'</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">Http404</span><span class="p">()</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">file</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">css</span> <span class="o">=</span> <span class="n">clevercss</span><span class="o">.</span><span class="n">convert</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span>
<span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">css</span><span class="p">,</span> <span class="n">mimetype</span><span class="o">=</span><span class="s">'text/css'</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>import clevercss
from os import path
from django.http import HttpResponse, Http404
def serve_ccss_file(request, filename):
fn = path.join(path.dirname(__file__), path.pardir, 'styles', filename + '.dcss')
if not path.exists(fn):
raise Http404()
f = file(fn):
try:
css = clevercss.convert(f.read().decode('utf-8'))
return HttpResponse(css, mimetype='text/css')
finally:
f.close()<PYGMENTS_RAW -->
Now you only have to create an URL rule for that:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="k">import</span> <span class="o">*</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">''</span><span class="p">,</span>
<span class="p">(</span><span class="s">r'style/([a-zA-Z_]+).css'</span><span class="p">,</span> <span class="n">serve_ccss_file</span><span class="p">)</span>
<span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'style/([a-zA-Z_]+)\.css', serve_ccss_file)
)<PYGMENTS_RAW -->
All you clevercss files now should go to <tt>yourproject/styles</tt>, as <tt>filename.ccss</tt>. If you enter production mode you just open your shell, go to that directory and execute <tt>clevercss.py *</tt>. (That requires that you have symlinked the clevercss.py file into your PATH.)
To test that, just drop a <tt>test.ccss</tt> file with the following contents in your styles folder and open <tt>http://localhost:8080/styles/test.css</tt>:
<!-- PYGMENTS_CACHE><div class="highlight"><pre>link_color = red
body:
background-color: white.darken(10)
font-family: 'Lucida Sans', Verdana, sans-serif;
a:
color: $link_color
&:hover:
color: $link_color.brighten(10)
&:visited:
color: $link_color.darken(20)
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(text)>link_color = red
body:
background-color: white.darken(10)
font-family: 'Lucida Sans', Verdana, sans-serif;
a:
color: $link_color
&:hover:
color: $link_color.brighten(10)
&:visited:
color: $link_color.darken(20)<PYGMENTS_RAW -->A few minutes ago I pushed <a href="http://sandbox.pocoo.org/clevercss/">CleverCSS</a> to the cheeseshop. So far there is no framework support, once again you have to hack up the bridge yourself, but in this post I'll show a simple way to get CleverCSS running in django and simplify your CSS files.
The preferred way to use CleverCSS is compiling the clevercss files into css, and not doing that dynamically. But because during development this can be annoying, if you have to recompile your files by hand all the time, I suggest using a view that serves those files dynamically during development. In production usage you just overlay the view URL with an apache directive etc. that points to the folder with the static css files in.
Here the view function, you can store it directly in your urls.py because it's that small. Otherwise move it into a application responsible for static stuff:
Now you only have to create an URL rule for that:
All you clevercss files now should go to <tt>yourproject/styles</tt>, as <tt>filename.ccss</tt>. If you enter production mode you just open your shell, go to that directory and execute <tt>clevercss.py *</tt>. (That requires that you have symlinked the clevercss.py file into your PATH.)
To test that, just drop a <tt>test.ccss</tt> file with the following contents in your styles folder and open <tt>http://localhost:8080/styles/test.css</tt>:
SQAAAANTAAAABGJvZHlSUwAAABtBIGZldyBtaW51dGVzIGFnbyBJIHB1c2hlZCBMAAZFUwAAAAFh
TAAATQABUwAAAARocmVmUwAAACNodHRwOi8vc2FuZGJveC5wb2Nvby5vcmcvY2xldmVyY3NzL1MA
AAAJQ2xldmVyQ1NTUwAAA4ogdG8gdGhlIGNoZWVzZXNob3AuIFNvIGZhciB0aGVyZSBpcyBubyBm
cmFtZXdvcmsgc3VwcG9ydCwgb25jZSBhZ2FpbiB5b3UgaGF2ZSB0byBoYWNrIHVwIHRoZSBicmlk
Z2UgeW91cnNlbGYsIGJ1dCBpbiB0aGlzIHBvc3QgSSdsbCBzaG93IGEgc2ltcGxlIHdheSB0byBn
ZXQgQ2xldmVyQ1NTIHJ1bm5pbmcgaW4gZGphbmdvIGFuZCBzaW1wbGlmeSB5b3VyIENTUyBmaWxl
cy4KClRoZSBwcmVmZXJyZWQgd2F5IHRvIHVzZSBDbGV2ZXJDU1MgaXMgY29tcGlsaW5nIHRoZSBj
bGV2ZXJjc3MgZmlsZXMgaW50byBjc3MsIGFuZCBub3QgZG9pbmcgdGhhdCBkeW5hbWljYWxseS4g
QnV0IGJlY2F1c2UgZHVyaW5nIGRldmVsb3BtZW50IHRoaXMgY2FuIGJlIGFubm95aW5nLCBpZiB5
b3UgaGF2ZSB0byByZWNvbXBpbGUgeW91ciBmaWxlcyBieSBoYW5kIGFsbCB0aGUgdGltZSwgSSBz
dWdnZXN0IHVzaW5nIGEgdmlldyB0aGF0IHNlcnZlcyB0aG9zZSBmaWxlcyBkeW5hbWljYWxseSBk
dXJpbmcgZGV2ZWxvcG1lbnQuIEluIHByb2R1Y3Rpb24gdXNhZ2UgeW91IGp1c3Qgb3ZlcmxheSB0
aGUgdmlldyBVUkwgd2l0aCBhbiBhcGFjaGUgZGlyZWN0aXZlIGV0Yy4gdGhhdCBwb2ludHMgdG8g
dGhlIGZvbGRlciB3aXRoIHRoZSBzdGF0aWMgY3NzIGZpbGVzIGluLgoKSGVyZSB0aGUgdmlldyBm
dW5jdGlvbiwgeW91IGNhbiBzdG9yZSBpdCBkaXJlY3RseSBpbiB5b3VyIHVybHMucHkgYmVjYXVz
ZSBpdCdzIHRoYXQgc21hbGwuIE90aGVyd2lzZSBtb3ZlIGl0IGludG8gYSBhcHBsaWNhdGlvbiBy
ZXNwb25zaWJsZSBmb3Igc3RhdGljIHN0dWZmOgoKCgpOb3cgeW91IG9ubHkgaGF2ZSB0byBjcmVh
dGUgYW4gVVJMIHJ1bGUgZm9yIHRoYXQ6CgoKQWxsIHlvdSBjbGV2ZXJjc3MgZmlsZXMgbm93IHNo
b3VsZCBnbyB0byBFUwAAAAJ0dEwAAE0AAFMAAAASeW91cnByb2plY3Qvc3R5bGVzUwAAAAUsIGFz
IEVTAAAAAnR0TAAATQAAUwAAAA1maWxlbmFtZS5jY3NzUwAAAFouIElmIHlvdSBlbnRlciBwcm9k
dWN0aW9uIG1vZGUgeW91IGp1c3Qgb3BlbiB5b3VyIHNoZWxsLCBnbyB0byB0aGF0IGRpcmVjdG9y
eSBhbmQgZXhlY3V0ZSBFUwAAAAJ0dEwAAE0AAFMAAAAOY2xldmVyY3NzLnB5ICpTAAAAay4gKFRo
YXQgcmVxdWlyZXMgdGhhdCB5b3UgaGF2ZSBzeW1saW5rZWQgdGhlIGNsZXZlcmNzcy5weSBmaWxl
IGludG8geW91ciBQQVRILikKClRvIHRlc3QgdGhhdCwganVzdCBkcm9wIGEgRVMAAAACdHRMAABN
AABTAAAACXRlc3QuY2Nzc1MAAABBIGZpbGUgd2l0aCB0aGUgZm9sbG93aW5nIGNvbnRlbnRzIGlu
IHlvdXIgc3R5bGVzIGZvbGRlciBhbmQgb3BlbiBFUwAAAAJ0dEwAAE0AAFMAAAAlaHR0cDovL2xv
Y2FsaG9zdDo4MDgwL3N0eWxlcy90ZXN0LmNzc1MAAAACOgpTAAAABnBhcnNlclMAAAAEaHRtbFMA
AAAFaW50cm9SUwAAAABMAAA=
roScripts - Webmaster resources and websiteshttp://www.roscripts.com/nominate/show/25692007-09-17T17:01:15Znono0<strong>Lucumr Cogitations » Blog Archive » Using CleverCSS in Django...</strong>
Lucumr Cogitations » Blog Archive » Using CleverCSS in Django...<strong>Lucumr Cogitations » Blog Archive » Using CleverCSS in Django...</strong>
Lucumr Cogitations » Blog Archive » Using CleverCSS in Django...SQAAAAJTAAAABGJvZHlSUwAAAABMAAFFUwAAAAZzdHJvbmdMAABNAABTAAAAQkx1Y3VtciBDb2dp
dGF0aW9ucyDCuyBCbG9nIEFyY2hpdmUgwrsgVXNpbmcgQ2xldmVyQ1NTIGluIERqYW5nby4uLlMA
AABECgpMdWN1bXIgQ29naXRhdGlvbnMgwrsgQmxvZyBBcmNoaXZlIMK7IFVzaW5nIENsZXZlckNT
UyBpbiBEamFuZ28uLi5TAAAABnBhcnNlclMAAAAEaHRtbA==
jake elliott @ dai5ychain» Blog Archive » Lucumr Cogitations » Blog Archive » Using CleverCSS in Djangohttp://dai5ychain.net/jake/2007/09/18/lucumr-cogitations-%c2%bb-blog-archive-%c2%bb-using-clevercss-in-django/2007-09-18T15:47:48Znoyes0[...] Lucumr Cogitations » Blog Archive » Using CleverCSS in Django [...][...] Lucumr Cogitations » Blog Archive » Using CleverCSS in Django [...]SQAAAAJTAAAABGJvZHlSUwAAAEtbLi4uXSBMdWN1bXIgQ29naXRhdGlvbnMgwrsgQmxvZyBBcmNo
aXZlIMK7IFVzaW5nIENsZXZlckNTUyBpbiBEamFuZ28gWy4uLl1MAABTAAAABnBhcnNlclMAAAAE
aHRtbA==
links for 2007-09-18 PaxoBloghttp://paxoblog.wordpress.com/2007/09/18/links-for-2007-09-18/2007-09-18T23:20:46Znoyes0[...] Lucumr Cogitations » Blog Archive » Using CleverCSS in Django once again you have to hack up the bridge yourself, but in this post I’ll show a simple way to get CleverCSS running in django and simplify your CSS files. (tags: css django python clevercss) [...][...] Lucumr Cogitations » Blog Archive » Using CleverCSS in Django once again you have to hack up the bridge yourself, but in this post I’ll show a simple way to get CleverCSS running in django and simplify your CSS files. (tags: css django python clevercss) [...]SQAAAAJTAAAABGJvZHlSUwAAAQ1bLi4uXSBMdWN1bXIgQ29naXRhdGlvbnMgwrsgQmxvZyBBcmNo
aXZlIMK7IFVzaW5nIENsZXZlckNTUyBpbiBEamFuZ28gb25jZSBhZ2FpbiB5b3UgaGF2ZSB0byBo
YWNrIHVwIHRoZSBicmlkZ2UgeW91cnNlbGYsIGJ1dCBpbiB0aGlzIHBvc3QgSeKAmWxsIHNob3cg
YSBzaW1wbGUgd2F5IHRvIGdldCBDbGV2ZXJDU1MgcnVubmluZyBpbiBkamFuZ28gYW5kIHNpbXBs
aWZ5IHlvdXIgQ1NTIGZpbGVzLiAodGFnczogY3NzIGRqYW5nbyBweXRob24gY2xldmVyY3NzKSBb
Li4uXUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Wolfram Kriesingwolfram@kriesing.dehttp://wolfram.kriesing.de/blog2007-11-23T09:50:00Znono0nice idea, but actually I would really prefer to stick to the CSS syntax and hide the additional functionality (like variables) inside comments. Why? Simply because the syntax you are suggesting here doesnt work with any syntax highlighter, so finding errors is too hard, anbd you need to learn a new syntax (also if it is not too hard).
And sticking to the current style would not be so hard.
my 2 cents
Wolframnice idea, but actually I would really prefer to stick to the CSS syntax and hide the additional functionality (like variables) inside comments. Why? Simply because the syntax you are suggesting here doesnt work with any syntax highlighter, so finding errors is too hard, anbd you need to learn a new syntax (also if it is not too hard).
And sticking to the current style would not be so hard.
my 2 cents
WolframSQAAAAJTAAAABGJvZHlSUwAAAZ9uaWNlIGlkZWEsIGJ1dCBhY3R1YWxseSBJIHdvdWxkIHJlYWxs
eSBwcmVmZXIgdG8gc3RpY2sgdG8gdGhlIENTUyBzeW50YXggYW5kIGhpZGUgdGhlIGFkZGl0aW9u
YWwgZnVuY3Rpb25hbGl0eSAobGlrZSB2YXJpYWJsZXMpIGluc2lkZSBjb21tZW50cy4gV2h5PyBT
aW1wbHkgYmVjYXVzZSB0aGUgc3ludGF4IHlvdSBhcmUgc3VnZ2VzdGluZyBoZXJlIGRvZXNudCB3
b3JrIHdpdGggYW55IHN5bnRheCBoaWdobGlnaHRlciwgc28gZmluZGluZyBlcnJvcnMgaXMgdG9v
IGhhcmQsIGFuYmQgeW91IG5lZWQgdG8gbGVhcm4gYSBuZXcgc3ludGF4IChhbHNvIGlmIGl0IGlz
IG5vdCB0b28gaGFyZCkuCkFuZCBzdGlja2luZyB0byB0aGUgY3VycmVudCBzdHlsZSB3b3VsZCBu
b3QgYmUgc28gaGFyZC4gCgpteSAyIGNlbnRzCgpXb2xmcmFtTAAAUwAAAAZwYXJzZXJTAAAABGh0
bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-11-23T23:46:46Znono0That's what I heard from quite a few people. Converting the indention based parser into a parser that uses braces to group sections wouldn't be that hard.
Regards,
ArminThat's what I heard from quite a few people. Converting the indention based parser into a parser that uses braces to group sections wouldn't be that hard.
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAKpUaGF0J3Mgd2hhdCBJIGhlYXJkIGZyb20gcXVpdGUgYSBmZXcg
cGVvcGxlLiBDb252ZXJ0aW5nIHRoZSBpbmRlbnRpb24gYmFzZWQgcGFyc2VyIGludG8gYSBwYXJz
ZXIgdGhhdCB1c2VzIGJyYWNlcyB0byBncm91cCBzZWN0aW9ucyB3b3VsZG4ndCBiZSB0aGF0IGhh
cmQuCgpSZWdhcmRzLApBcm1pbkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Steal, and steal and keep on stealinghttp://lucumr.pocoo.org/cogitations/2007/09/17/steal-and-steal-and-keep-on-stealing/2007-09-17T05:59:01Z2007-09-17T05:59:01ZArmin Ronachersteal-and-steal-and-keep-on-stealingyesyes2I must admit that I'm not the biggest Nine Inch Nails fan, but some of their songs are really good. A friend of mine told me that Nine Inch Nails are now very angry about us Austrians because of this years <a href="http://frequency.at/">Frequency</a>. Guess not necessarily the crowd was to blame (well, it was somehow), but who in god's name puts NIN right between Beatstakes and Die Ärzte? Well, we probably will never find out, but that was a very bad idea. Totally different types of music.
But the main reason why I write this post and why the headline looks that flashy, is this video: <a href="http://www.youtube.com/watch?v=TJ5iHaV0dP4">NIN live in Sydney</a>. And the words at the beginning are (without a joke):
<blockquote>I called them [my record label] out for being greedy fucking assholes. I didn't get a chance to check, has the price come down at all? I see a no, a no... Has anyone seen the price come down? Okay, well, you know what that means - Steal it!. Steal away. Steal and steal and steal some more and give it to all your friends and keep on stealing. Because one way or another these motherfuckers will get it through their head that they're ripping people off and that that's not right.</blockquote>
Trent Reznor said something similar a year ago, afair in a magazine, about the ridiculous prices down in Australia, and according to him that's because his record label thinks: "that there are great fans there, which are willed to pay more money".
Now his message doesn't mean that you should start stealing all kinds of music, all around the world. As far as I understand this Trent is very, very angry about his recording company and their insane policies. The problem is that nowadays the labels make the money, not so much the artists. And then there are some creepy organizations that do stuff like suing moms for listening to illegally downloaded "Gangsta Rap", want to get their underage daughters to curt to say out against them.
The music business is without a doubt, completely fucked up. And I don't think that will become any better, even worse. Now where we all start buying compressed music online they don't have to spend any money on printing or booklets. And the bad sound quality (yes, I *can* hear the difference) and the missing booklets are the reason why I still go to my local music store and buy CDs.
Maybe some more, especially independent artists, should stand up and start publishing their music on their own. Hopefully something in that broken system improves the next years... I really hope so.
<small>Speaking of music, listen to some more <a href="http://www.purereasonrevolution.com/">Pure Reason Revolution</a>.</small>I must admit that I'm not the biggest Nine Inch Nails fan, but some of their songs are really good. A friend of mine told me that Nine Inch Nails are now very angry about us Austrians because of this years <a href="http://frequency.at/">Frequency</a>. Guess not necessarily the crowd was to blame (well, it was somehow), but who in god's name puts NIN right between Beatstakes and Die Ärzte? Well, we probably will never find out, but that was a very bad idea. Totally different types of music.
But the main reason why I write this post and why the headline looks that flashy, is this video: <a href="http://www.youtube.com/watch?v=TJ5iHaV0dP4">NIN live in Sydney</a>. And the words at the beginning are (without a joke):
<blockquote>I called them [my record label] out for being greedy fucking assholes. I didn't get a chance to check, has the price come down at all? I see a no, a no... Has anyone seen the price come down? Okay, well, you know what that means - Steal it!. Steal away. Steal and steal and steal some more and give it to all your friends and keep on stealing. Because one way or another these motherfuckers will get it through their head that they're ripping people off and that that's not right.</blockquote>
Trent Reznor said something similar a year ago, afair in a magazine, about the ridiculous prices down in Australia, and according to him that's because his record label thinks: "that there are great fans there, which are willed to pay more money".
Now his message doesn't mean that you should start stealing all kinds of music, all around the world. As far as I understand this Trent is very, very angry about his recording company and their insane policies. The problem is that nowadays the labels make the money, not so much the artists. And then there are some creepy organizations that do stuff like suing moms for listening to illegally downloaded "Gangsta Rap", want to get their underage daughters to curt to say out against them.
The music business is without a doubt, completely fucked up. And I don't think that will become any better, even worse. Now where we all start buying compressed music online they don't have to spend any money on printing or booklets. And the bad sound quality (yes, I *can* hear the difference) and the missing booklets are the reason why I still go to my local music store and buy CDs.
Maybe some more, especially independent artists, should stand up and start publishing their music on their own. Hopefully something in that broken system improves the next years... I really hope so.
<small>Speaking of music, listen to some more <a href="http://www.purereasonrevolution.com/">Pure Reason Revolution</a>.</small>SQAAAANTAAAABGJvZHlSUwAAAM5JIG11c3QgYWRtaXQgdGhhdCBJJ20gbm90IHRoZSBiaWdnZXN0
IE5pbmUgSW5jaCBOYWlscyBmYW4sIGJ1dCBzb21lIG9mIHRoZWlyIHNvbmdzIGFyZSByZWFsbHkg
Z29vZC4gQSBmcmllbmQgb2YgbWluZSB0b2xkIG1lIHRoYXQgTmluZSBJbmNoIE5haWxzIGFyZSBu
b3cgdmVyeSBhbmdyeSBhYm91dCB1cyBBdXN0cmlhbnMgYmVjYXVzZSBvZiB0aGlzIHllYXJzIEwA
BEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAFGh0dHA6Ly9mcmVxdWVuY3kuYXQvUwAAAAlGcmVx
dWVuY3lTAAABWC4gR3Vlc3Mgbm90IG5lY2Vzc2FyaWx5IHRoZSBjcm93ZCB3YXMgdG8gYmxhbWUg
KHdlbGwsIGl0IHdhcyBzb21laG93KSwgYnV0IHdobyBpbiBnb2QncyBuYW1lIHB1dHMgTklOIHJp
Z2h0IGJldHdlZW4gQmVhdHN0YWtlcyBhbmQgRGllIMOEcnp0ZT8gV2VsbCwgd2UgcHJvYmFibHkg
d2lsbCBuZXZlciBmaW5kIG91dCwgYnV0IHRoYXQgd2FzIGEgdmVyeSBiYWQgaWRlYS4gVG90YWxs
eSBkaWZmZXJlbnQgdHlwZXMgb2YgbXVzaWMuCgpCdXQgdGhlIG1haW4gcmVhc29uIHdoeSBJIHdy
aXRlIHRoaXMgcG9zdCBhbmQgd2h5IHRoZSBoZWFkbGluZSBsb29rcyB0aGF0IGZsYXNoeSwgaXMg
dGhpcyB2aWRlbzogRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAqaHR0cDovL3d3dy55b3V0dWJl
LmNvbS93YXRjaD92PVRKNWlIYVYwZFA0UwAAABJOSU4gbGl2ZSBpbiBTeWRuZXlTAAAANy4gQW5k
IHRoZSB3b3JkcyBhdCB0aGUgYmVnaW5uaW5nIGFyZSAod2l0aG91dCBhIGpva2UpOgpFUwAAAApi
bG9ja3F1b3RlTAAATQAAUwAAAeBJIGNhbGxlZCB0aGVtIFtteSByZWNvcmQgbGFiZWxdIG91dCBm
b3IgYmVpbmcgZ3JlZWR5IGZ1Y2tpbmcgYXNzaG9sZXMuIEkgZGlkbid0IGdldCBhIGNoYW5jZSB0
byBjaGVjaywgaGFzIHRoZSBwcmljZSBjb21lIGRvd24gYXQgYWxsPyBJIHNlZSBhIG5vLCBhIG5v
Li4uIEhhcyBhbnlvbmUgc2VlbiB0aGUgcHJpY2UgY29tZSBkb3duPyBPa2F5LCB3ZWxsLCB5b3Ug
a25vdyB3aGF0IHRoYXQgbWVhbnMgLSBTdGVhbCBpdCEuIFN0ZWFsIGF3YXkuIFN0ZWFsIGFuZCBz
dGVhbCBhbmQgc3RlYWwgc29tZSBtb3JlIGFuZCBnaXZlIGl0IHRvIGFsbCB5b3VyIGZyaWVuZHMg
YW5kIGtlZXAgb24gc3RlYWxpbmcuIEJlY2F1c2Ugb25lIHdheSBvciBhbm90aGVyIHRoZXNlIG1v
dGhlcmZ1Y2tlcnMgd2lsbCBnZXQgaXQgdGhyb3VnaCB0aGVpciBoZWFkIHRoYXQgdGhleSdyZSBy
aXBwaW5nIHBlb3BsZSBvZmYgYW5kIHRoYXQgdGhhdCdzIG5vdCByaWdodC5TAAAFMQpUcmVudCBS
ZXpub3Igc2FpZCBzb21ldGhpbmcgc2ltaWxhciBhIHllYXIgYWdvLCBhZmFpciBpbiBhIG1hZ2F6
aW5lLCBhYm91dCB0aGUgcmlkaWN1bG91cyBwcmljZXMgZG93biBpbiBBdXN0cmFsaWEsIGFuZCBh
Y2NvcmRpbmcgdG8gaGltIHRoYXQncyBiZWNhdXNlIGhpcyByZWNvcmQgbGFiZWwgdGhpbmtzOiAi
dGhhdCB0aGVyZSBhcmUgZ3JlYXQgZmFucyB0aGVyZSwgd2hpY2ggYXJlIHdpbGxlZCB0byBwYXkg
bW9yZSBtb25leSIuCgpOb3cgaGlzIG1lc3NhZ2UgZG9lc24ndCBtZWFuIHRoYXQgeW91IHNob3Vs
ZCBzdGFydCBzdGVhbGluZyBhbGwga2luZHMgb2YgbXVzaWMsIGFsbCBhcm91bmQgdGhlIHdvcmxk
LiBBcyBmYXIgYXMgSSB1bmRlcnN0YW5kIHRoaXMgVHJlbnQgaXMgdmVyeSwgdmVyeSBhbmdyeSBh
Ym91dCBoaXMgcmVjb3JkaW5nIGNvbXBhbnkgYW5kIHRoZWlyIGluc2FuZSBwb2xpY2llcy4gVGhl
IHByb2JsZW0gaXMgdGhhdCBub3dhZGF5cyB0aGUgbGFiZWxzIG1ha2UgdGhlIG1vbmV5LCBub3Qg
c28gbXVjaCB0aGUgYXJ0aXN0cy4gQW5kIHRoZW4gdGhlcmUgYXJlIHNvbWUgY3JlZXB5IG9yZ2Fu
aXphdGlvbnMgdGhhdCBkbyBzdHVmZiBsaWtlIHN1aW5nIG1vbXMgZm9yIGxpc3RlbmluZyB0byBp
bGxlZ2FsbHkgZG93bmxvYWRlZCAiR2FuZ3N0YSBSYXAiLCB3YW50IHRvIGdldCB0aGVpciB1bmRl
cmFnZSBkYXVnaHRlcnMgdG8gY3VydCB0byBzYXkgb3V0IGFnYWluc3QgdGhlbS4KClRoZSBtdXNp
YyBidXNpbmVzcyBpcyB3aXRob3V0IGEgZG91YnQsIGNvbXBsZXRlbHkgZnVja2VkIHVwLiBBbmQg
SSBkb24ndCB0aGluayB0aGF0IHdpbGwgYmVjb21lIGFueSBiZXR0ZXIsIGV2ZW4gd29yc2UuIE5v
dyB3aGVyZSB3ZSBhbGwgc3RhcnQgYnV5aW5nIGNvbXByZXNzZWQgbXVzaWMgb25saW5lIHRoZXkg
ZG9uJ3QgaGF2ZSB0byBzcGVuZCBhbnkgbW9uZXkgb24gcHJpbnRpbmcgb3IgYm9va2xldHMuIEFu
ZCB0aGUgYmFkIHNvdW5kIHF1YWxpdHkgKHllcywgSSAqY2FuKiBoZWFyIHRoZSBkaWZmZXJlbmNl
KSBhbmQgdGhlIG1pc3NpbmcgYm9va2xldHMgYXJlIHRoZSByZWFzb24gd2h5IEkgc3RpbGwgZ28g
dG8gbXkgbG9jYWwgbXVzaWMgc3RvcmUgYW5kIGJ1eSBDRHMuCgpNYXliZSBzb21lIG1vcmUsIGVz
cGVjaWFsbHkgaW5kZXBlbmRlbnQgYXJ0aXN0cywgc2hvdWxkIHN0YW5kIHVwIGFuZCBzdGFydCBw
dWJsaXNoaW5nIHRoZWlyIG11c2ljIG9uIHRoZWlyIG93bi4gSG9wZWZ1bGx5IHNvbWV0aGluZyBp
biB0aGF0IGJyb2tlbiBzeXN0ZW0gaW1wcm92ZXMgdGhlIG5leHQgeWVhcnMuLi4gSSByZWFsbHkg
aG9wZSBzby4KCkVTAAAABXNtYWxsTAABRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAkaHR0cDov
L3d3dy5wdXJlcmVhc29ucmV2b2x1dGlvbi5jb20vUwAAABZQdXJlIFJlYXNvbiBSZXZvbHV0aW9u
UwAAAAEuTQAAUwAAACdTcGVha2luZyBvZiBtdXNpYywgbGlzdGVuIHRvIHNvbWUgbW9yZSBTAAAA
AFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Marek Kubicapythonmailing@web.de2007-09-23T12:41:22Znono0Yes, the Ärzte fans were kinda assholes. Ok, they were waiting for Die Ärzte but couldn't they just shut up and wait? It didn't last any shorter and they had to stand in the rain anyway after the NIN performance.
Or do you stand in line at Aldi/Hofer and start shouting that you absolutely want to pay now, upsetting everyone else?Yes, the Ärzte fans were kinda assholes. Ok, they were waiting for Die Ärzte but couldn't they just shut up and wait? It didn't last any shorter and they had to stand in the rain anyway after the NIN performance.
Or do you stand in line at Aldi/Hofer and start shouting that you absolutely want to pay now, upsetting everyone else?SQAAAAJTAAAABGJvZHlSUwAAAU5ZZXMsIHRoZSDDhHJ6dGUgZmFucyB3ZXJlIGtpbmRhIGFzc2hv
bGVzLiBPaywgdGhleSB3ZXJlIHdhaXRpbmcgZm9yIERpZSDDhHJ6dGUgYnV0IGNvdWxkbid0IHRo
ZXkganVzdCBzaHV0IHVwIGFuZCB3YWl0PyBJdCBkaWRuJ3QgbGFzdCBhbnkgc2hvcnRlciBhbmQg
dGhleSBoYWQgdG8gc3RhbmQgaW4gdGhlIHJhaW4gYW55d2F5IGFmdGVyIHRoZSBOSU4gcGVyZm9y
bWFuY2UuCgpPciBkbyB5b3Ugc3RhbmQgaW4gbGluZSBhdCBBbGRpL0hvZmVyIGFuZCBzdGFydCBz
aG91dGluZyB0aGF0IHlvdSBhYnNvbHV0ZWx5IHdhbnQgdG8gcGF5IG5vdywgdXBzZXR0aW5nIGV2
ZXJ5b25lIGVsc2U/TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-09-23T16:15:50Znono0No. But me and one of my friend waited in the line at the local Spar to get "Extrawurstsemmeln", but then we disappeared after saying in a loud tone that we try our luck at the Billa. But that was more or less a joke ;-) We disappeared nonetheless.No. But me and one of my friend waited in the line at the local Spar to get "Extrawurstsemmeln", but then we disappeared after saying in a loud tone that we try our luck at the Billa. But that was more or less a joke ;-) We disappeared nonetheless.SQAAAAJTAAAABGJvZHlSUwAAAPhOby4gQnV0IG1lIGFuZCBvbmUgb2YgbXkgZnJpZW5kIHdhaXRl
ZCBpbiB0aGUgbGluZSBhdCB0aGUgbG9jYWwgU3BhciB0byBnZXQgIkV4dHJhd3Vyc3RzZW1tZWxu
IiwgYnV0IHRoZW4gd2UgZGlzYXBwZWFyZWQgYWZ0ZXIgc2F5aW5nIGluIGEgbG91ZCB0b25lIHRo
YXQgd2UgdHJ5IG91ciBsdWNrIGF0IHRoZSBCaWxsYS4gQnV0IHRoYXQgd2FzIG1vcmUgb3IgbGVz
cyBhIGpva2UgOy0pIFdlIGRpc2FwcGVhcmVkIG5vbmV0aGVsZXNzLkwAAFMAAAAGcGFyc2VyUwAA
AARodG1s
Working hard on a bad Image huh?http://lucumr.pocoo.org/cogitations/2007/09/15/working-hard-on-a-bad-image-huh/2007-09-15T13:18:26Z2007-09-15T13:18:26ZArmin Ronacherworking-hard-on-a-bad-image-huhyesyes2Oh apple, what are you doing. Yes, I'm quite mad about you recently. Additionally to the funny problems I had last week I now have two more. The scroll "wheel" of my myghty mouse broke and my TFT thinks contrast is for sissies. The contrast problem is btw fixable by plugging in an external monitor and rotating it clockwise and counter clockwise from the display control panel.
But what really, really makes me mad is how closed their stack is. Although their operating system is based on an open source kernel nearly all of the other stuff is closed like nothing else. I was a happy iPod user the last years but I will be the last one i buy. Now where they have a checksum in their stupid binary crap library they call iTunes DB which makes it impossible to access it with other tools I'm just not interested in it any more...Oh apple, what are you doing. Yes, I'm quite mad about you recently. Additionally to the funny problems I had last week I now have two more. The scroll "wheel" of my myghty mouse broke and my TFT thinks contrast is for sissies. The contrast problem is btw fixable by plugging in an external monitor and rotating it clockwise and counter clockwise from the display control panel.
But what really, really makes me mad is how closed their stack is. Although their operating system is based on an open source kernel nearly all of the other stuff is closed like nothing else. I was a happy iPod user the last years but I will be the last one i buy. Now where they have a checksum in their stupid binary crap library they call iTunes DB which makes it impossible to access it with other tools I'm just not interested in it any more...SQAAAANTAAAABGJvZHlSUwAAAz1PaCBhcHBsZSwgd2hhdCBhcmUgeW91IGRvaW5nLiBZZXMsIEkn
bSBxdWl0ZSBtYWQgYWJvdXQgeW91IHJlY2VudGx5LiBBZGRpdGlvbmFsbHkgdG8gdGhlIGZ1bm55
IHByb2JsZW1zIEkgaGFkIGxhc3Qgd2VlayBJIG5vdyBoYXZlIHR3byBtb3JlLiBUaGUgc2Nyb2xs
ICJ3aGVlbCIgb2YgbXkgbXlnaHR5IG1vdXNlIGJyb2tlIGFuZCBteSBURlQgdGhpbmtzIGNvbnRy
YXN0IGlzIGZvciBzaXNzaWVzLiBUaGUgY29udHJhc3QgcHJvYmxlbSBpcyBidHcgZml4YWJsZSBi
eSBwbHVnZ2luZyBpbiBhbiBleHRlcm5hbCBtb25pdG9yIGFuZCByb3RhdGluZyBpdCBjbG9ja3dp
c2UgYW5kIGNvdW50ZXIgY2xvY2t3aXNlIGZyb20gdGhlIGRpc3BsYXkgY29udHJvbCBwYW5lbC4K
CkJ1dCB3aGF0IHJlYWxseSwgcmVhbGx5IG1ha2VzIG1lIG1hZCBpcyBob3cgY2xvc2VkIHRoZWly
IHN0YWNrIGlzLiBBbHRob3VnaCB0aGVpciBvcGVyYXRpbmcgc3lzdGVtIGlzIGJhc2VkIG9uIGFu
IG9wZW4gc291cmNlIGtlcm5lbCBuZWFybHkgYWxsIG9mIHRoZSBvdGhlciBzdHVmZiBpcyBjbG9z
ZWQgbGlrZSBub3RoaW5nIGVsc2UuIEkgd2FzIGEgaGFwcHkgaVBvZCB1c2VyIHRoZSBsYXN0IHll
YXJzIGJ1dCBJIHdpbGwgYmUgdGhlIGxhc3Qgb25lIGkgYnV5LiBOb3cgd2hlcmUgdGhleSBoYXZl
IGEgY2hlY2tzdW0gaW4gdGhlaXIgc3R1cGlkIGJpbmFyeSBjcmFwIGxpYnJhcnkgdGhleSBjYWxs
IGlUdW5lcyBEQiB3aGljaCBtYWtlcyBpdCBpbXBvc3NpYmxlIHRvIGFjY2VzcyBpdCB3aXRoIG90
aGVyIHRvb2xzIEknbSBqdXN0IG5vdCBpbnRlcmVzdGVkIGluIGl0IGFueSBtb3JlLi4uTAAAUwAA
AAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
CleverCSShttp://lucumr.pocoo.org/cogitations/2007/09/14/clevercss/2007-09-14T13:25:00Z2007-09-14T13:25:00ZArmin Ronacherclevercssyesyes2I was working on TextPress the last days, (I got motivated by the fact that WordPress has got security problems once more) and had to notice that CSS could need some variables. I wanted to write a simple preprocessor for css that inserts variables but ended up writing a small parser that accepts indented CSS code with inline expressions.
Basically what it does is converting this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre>// Single Line Comment
foo = 4px
font_family = 'Verdana', sans-serif
base_size = 0.9em
/*
this is a multiline comment
*/
body:
padding: $foo * 4
font ->
family: $font_family
size: $base_size + 0.2em
a.foo:
background-image: url(foo.png)
span:
display: none
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(text)>// Single Line Comment
foo = 4px
font_family = 'Verdana', sans-serif
base_size = 0.9em
/*
this is a multiline comment
*/
body:
padding: $foo * 4
font ->
family: $font_family
size: $base_size + 0.2em
a.foo:
background-image: url(foo.png)
span:
display: none<PYGMENTS_RAW -->
Into this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="nt">body</span> <span class="p">{</span>
<span class="k">padding</span><span class="o">:</span> <span class="m">16px</span><span class="p">;</span>
<span class="k">font-family</span><span class="o">:</span> <span class="n">Verdana</span><span class="o">,</span> <span class="k">sans-serif</span><span class="p">;</span>
<span class="k">font-size</span><span class="o">:</span> <span class="m">1.1em</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">a</span><span class="nc">.foo</span> <span class="p">{</span>
<span class="k">background-image</span><span class="o">:</span> <span class="sx">url(foo.png)</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">a</span><span class="nc">.foo</span> <span class="nt">span</span> <span class="p">{</span>
<span class="k">display</span><span class="o">:</span> <span class="k">none</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(css)>body {
padding: 16px;
font-family: Verdana, sans-serif;
font-size: 1.1em;
}
a.foo {
background-image: url(foo.png);
}
a.foo span {
display: none;
}<PYGMENTS_RAW -->
The advantage might not be visible in that small example but consider complex layouts etc. One thing I would love to add is some support for layout extending. Say you have a base layout and you can say <tt>@extends('layout.ccss')</tt> and would get all the layout informations from the layout file. But I don't know how useful this is.
Right now the conversion process is quite slow, but I wouldn't generate such stylesheets on request. It's a much better idea to do generate them from a script. During development one could still generate them automatically.
The module is available in the sandbox hg repo: <a href="http://dev.pocoo.org/hg/sandbox/raw-file/-1/clevercss.py">clevercss.py</a>. Just call <tt>clevercss.convert</tt> and pass it the CleverCSS markup.
Things that don't work yet are unit conversions. For example you cannot do "1cm + 11mm".I was working on TextPress the last days, (I got motivated by the fact that WordPress has got security problems once more) and had to notice that CSS could need some variables. I wanted to write a simple preprocessor for css that inserts variables but ended up writing a small parser that accepts indented CSS code with inline expressions.
Basically what it does is converting this:
Into this:
The advantage might not be visible in that small example but consider complex layouts etc. One thing I would love to add is some support for layout extending. Say you have a base layout and you can say <tt>@extends('layout.ccss')</tt> and would get all the layout informations from the layout file. But I don't know how useful this is.
Right now the conversion process is quite slow, but I wouldn't generate such stylesheets on request. It's a much better idea to do generate them from a script. During development one could still generate them automatically.
The module is available in the sandbox hg repo: <a href="http://dev.pocoo.org/hg/sandbox/raw-file/-1/clevercss.py">clevercss.py</a>. Just call <tt>clevercss.convert</tt> and pass it the CleverCSS markup.
Things that don't work yet are unit conversions. For example you cannot do "1cm + 11mm".SQAAAANTAAAABGJvZHlSUwAAAlhJIHdhcyB3b3JraW5nIG9uIFRleHRQcmVzcyB0aGUgbGFzdCBk
YXlzLCAoSSBnb3QgbW90aXZhdGVkIGJ5IHRoZSBmYWN0IHRoYXQgV29yZFByZXNzIGhhcyBnb3Qg
c2VjdXJpdHkgcHJvYmxlbXMgb25jZSBtb3JlKSBhbmQgaGFkIHRvIG5vdGljZSB0aGF0IENTUyBj
b3VsZCBuZWVkIHNvbWUgdmFyaWFibGVzLiBJIHdhbnRlZCB0byB3cml0ZSBhIHNpbXBsZSBwcmVw
cm9jZXNzb3IgZm9yIGNzcyB0aGF0IGluc2VydHMgdmFyaWFibGVzIGJ1dCBlbmRlZCB1cCB3cml0
aW5nIGEgc21hbGwgcGFyc2VyIHRoYXQgYWNjZXB0cyBpbmRlbnRlZCBDU1MgY29kZSB3aXRoIGlu
bGluZSBleHByZXNzaW9ucy4KCkJhc2ljYWxseSB3aGF0IGl0IGRvZXMgaXMgY29udmVydGluZyB0
aGlzOgoKSW50byB0aGlzOgoKClRoZSBhZHZhbnRhZ2UgbWlnaHQgbm90IGJlIHZpc2libGUgaW4g
dGhhdCBzbWFsbCBleGFtcGxlIGJ1dCBjb25zaWRlciBjb21wbGV4IGxheW91dHMgZXRjLiBPbmUg
dGhpbmcgSSB3b3VsZCBsb3ZlIHRvIGFkZCBpcyBzb21lIHN1cHBvcnQgZm9yIGxheW91dCBleHRl
bmRpbmcuIFNheSB5b3UgaGF2ZSBhIGJhc2UgbGF5b3V0IGFuZCB5b3UgY2FuIHNheSBMAANFUwAA
AAJ0dEwAAE0AAFMAAAAXQGV4dGVuZHMoJ2xheW91dC5jY3NzJylTAAABeCBhbmQgd291bGQgZ2V0
IGFsbCB0aGUgbGF5b3V0IGluZm9ybWF0aW9ucyBmcm9tIHRoZSBsYXlvdXQgZmlsZS4gQnV0IEkg
ZG9uJ3Qga25vdyBob3cgdXNlZnVsIHRoaXMgaXMuCgpSaWdodCBub3cgdGhlIGNvbnZlcnNpb24g
cHJvY2VzcyBpcyBxdWl0ZSBzbG93LCBidXQgSSB3b3VsZG4ndCBnZW5lcmF0ZSBzdWNoIHN0eWxl
c2hlZXRzIG9uIHJlcXVlc3QuIEl0J3MgYSBtdWNoIGJldHRlciBpZGVhIHRvIGRvIGdlbmVyYXRl
IHRoZW0gZnJvbSBhIHNjcmlwdC4gRHVyaW5nIGRldmVsb3BtZW50IG9uZSBjb3VsZCBzdGlsbCBn
ZW5lcmF0ZSB0aGVtIGF1dG9tYXRpY2FsbHkuCgpUaGUgbW9kdWxlIGlzIGF2YWlsYWJsZSBpbiB0
aGUgc2FuZGJveCBoZyByZXBvOiBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADhodHRwOi8vZGV2
LnBvY29vLm9yZy9oZy9zYW5kYm94L3Jhdy1maWxlLy0xL2NsZXZlcmNzcy5weVMAAAAMY2xldmVy
Y3NzLnB5UwAAAAwuIEp1c3QgY2FsbCBFUwAAAAJ0dEwAAE0AAFMAAAARY2xldmVyY3NzLmNvbnZl
cnRTAAAAfCBhbmQgcGFzcyBpdCB0aGUgQ2xldmVyQ1NTIG1hcmt1cC4KClRoaW5ncyB0aGF0IGRv
bid0IHdvcmsgeWV0IGFyZSB1bml0IGNvbnZlcnNpb25zLiBGb3IgZXhhbXBsZSB5b3UgY2Fubm90
IGRvICIxY20gKyAxMW1tIi5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Multi Trac / Django Hosting with mod_wsgihttp://lucumr.pocoo.org/cogitations/2007/09/12/multi-trac-django-hosting-with-mod_wsgi/2007-09-11T22:42:57Z2007-09-11T22:42:57ZArmin Ronachermulti-trac-django-hosting-with-mod_wsgiyesyes2As you might now we switched the pocoo trac to mercurial, mod_wsgi and splitted it in the same go. The new structure is can be found at <a href="http://dev.pocoo.org/">dev.pocoo.org</a>. What you cannot see there is how all that is implemented. And I tell you. It's dead simple.
Basically we use mod_wsgi for hosting the tracs. There are many reasons for that but the most important one is that you can host multiple trac instances without much configuration. Basically the configuration binds a wsgi application to a URL match rule. One important thing is the <tt>maximum-requests</tt> setting. To understand this parameter you have to know that mod_wsgi does not only keep a pool of running python interpreters, but also your application with all data in the memory. Now that's a big difference to mod_php where your application is sourced on request and removed from the memory after the reqest. So basically you cannot create memory holes, which you can do in python. If your application leaks memory (and trac tends to do so) you can tell mod_wsgi to restart one python interpreter after 500 requests for example. That setting of course depends on your trac version, the number of plugins etc. And especially how many memory you have in your application. Here the Apache config:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="nt"><VirtualHost</span> <span class="s">*:80</span><span class="nt">></span>
<span class="nb">ServerName</span> dev.example.org
<span class="nb">RewriteEngine</span> <span class="k">On</span>
<span class="nb">WSGIDaemonProcess</span> tracs threads=10 maximum-requests=500
<span class="nb">RewriteCond</span> %{REQUEST_URI} ^/([a-z_]+)
<span class="nb">RewriteRule</span> . - [E=TRAC_ID:%1]
<span class="nb">WSGIScriptAliasMatch</span> ^/([a-z_]+) <span class="sx">/var/trac/trac.wsgi</span>
<span class="nt"><Directory</span> <span class="s">/var/trac</span><span class="nt">></span>
<span class="nb">WSGIProcessGroup</span> tracs
<span class="nb">WSGIApplicationGroup</span> %{GLOBAL}
<span class="nb">Order</span> deny,allow
<span class="nb">Allow</span> from <span class="k">all</span>
<span class="nt"></Directory></span>
<span class="nt"><LocationMatch</span> <span class="s">/([a-z_]+)/login</span><span class="nt">></span>
<span class="nb">AuthType</span> <span class="s2">"Basic"</span>
<span class="nb">AuthName</span> <span class="s2">"Trac Instances Login"</span>
<span class="nb">AuthUserFile</span> <span class="sx">/var/trac/users</span>
<span class="nb">Require</span> valid-user
<span class="nt"></LocationMatch></span>
<span class="nt"></VirtualHost></span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(apache)><VirtualHost *:80>
ServerName dev.example.org
RewriteEngine On
WSGIDaemonProcess tracs threads=10 maximum-requests=500
RewriteCond %{REQUEST_URI} ^/([a-z_]+)
RewriteRule . - [E=TRAC_ID:%1]
WSGIScriptAliasMatch ^/([a-z_]+) /var/trac/trac.wsgi
<Directory /var/trac>
WSGIProcessGroup tracs
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
<LocationMatch /([a-z_]+)/login>
AuthType "Basic"
AuthName "Trac Instances Login"
AuthUserFile /var/trac/users
Require valid-user
</LocationMatch>
</VirtualHost><PYGMENTS_RAW -->
Then we need a <tt>trac.wsgi</tt> file which is basically just a minimal WSGI application that dispatches our key. Say we have our trac instances in <tt>/var/trac/instances</tt>, every trac in it's own folder. Then we can use this code:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="k">from</span> <span class="nn">os</span> <span class="k">import</span> <span class="n">environ</span><span class="p">,</span> <span class="n">path</span>
<span class="k">from</span> <span class="nn">trac.web.main</span> <span class="k">import</span> <span class="n">dispatch_request</span>
<span class="k">def</span> <span class="nf">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="n">trac_path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">'/var/trac/instances'</span><span class="p">,</span> <span class="n">environ</span><span class="p">[</span><span class="s">'TRAC_ID'</span><span class="p">])</span>
<span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">trac_path</span><span class="p">):</span>
<span class="n">environ</span><span class="p">[</span><span class="s">'trac.env_path'</span><span class="p">]</span> <span class="o">=</span> <span class="n">trac_path</span>
<span class="k">return</span> <span class="n">dispatch_request</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
<span class="n">start_response</span><span class="p">(</span><span class="s">'404 NOT FOUND'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'Content-Type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)])</span>
<span class="k">return</span> <span class="p">[</span><span class="s">'Not Found'</span><span class="p">]</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>#!/usr/bin/python
from os import environ, path
from trac.web.main import dispatch_request
def application(environ, start_response):
trac_path = path.join('/var/trac/instances', environ['TRAC_ID'])
if path.exists(trac_path):
environ['trac.env_path'] = trac_path
return dispatch_request(environ, start_response)
start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
return ['Not Found']<PYGMENTS_RAW -->
You can of course modify that not found message, maybe render a fancy HTML page or just redirect to the index of that domain or whatever. The important thing is that you set the path to the trac instance before calling the dispatch_request function. In theory you can do that from the apache config too, but in that situation you cannot check if the trac really exists.
And now about the django hosting part. Basically you can do the same for django. Django basically has a environment key called the <tt>DJANGO_SETTINGS_MODULE</tt> key. This key basically controls what settings module django will import. Unfortunately the whole django core is not process safe, so you cannot run two different django powered applications in the same python interpreter. This however is not that much of an issue with mod_wsgi, because you can tell mod_wsgi to not share the interpreter. (In the trac config above we shared the interpreter to save some memory)
Your config could look like this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="nt"><VirtualHost</span> <span class="s">*:80</span><span class="nt">></span>
<span class="nb">ServerName</span> www.example.org
<span class="nb">WSGIDaemonProcess</span> django_app1 threads=10 maximum-requests=5000
<span class="nb">WSGIScriptAlias</span> <span class="sx">/app1</span> <span class="sx">/var/www/django_app1.wsgi</span>
<span class="nb">WSGIDaemonProcess</span> django_app2 threads=10 maximum-requests=5000
<span class="nb">WSGIScriptAlias</span> <span class="sx">/app2</span> <span class="sx">/var/www/django_app2.wsgi</span>
<span class="nt"><Location</span> <span class="s">/app1</span><span class="nt">></span>
<span class="nb">WSGIProcessGroup</span> django_app1
<span class="nb">WSGIApplicationGroup</span> %{GLOBAL}
<span class="nt"></Location></span>
<span class="nt"><Location</span> <span class="s">/app2</span><span class="nt">></span>
<span class="nb">WSGIProcessGroup</span> django_app2
<span class="nb">WSGIApplicationGroup</span> %{GLOBAL}
<span class="nt"></Location></span>
<span class="nt"></VirtualHost></span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(apache)><VirtualHost *:80>
ServerName www.example.org
WSGIDaemonProcess django_app1 threads=10 maximum-requests=5000
WSGIScriptAlias /app1 /var/www/django_app1.wsgi
WSGIDaemonProcess django_app2 threads=10 maximum-requests=5000
WSGIScriptAlias /app2 /var/www/django_app2.wsgi
<Location /app1>
WSGIProcessGroup django_app1
WSGIApplicationGroup %{GLOBAL}
</Location>
<Location /app2>
WSGIProcessGroup django_app2
WSGIApplicationGroup %{GLOBAL}
</Location>
</VirtualHost><PYGMENTS_RAW -->
The actual "django_appX.wsgi" file is very, very simple. It just adds the folder and instanciates the django wsgi app:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="k">import</span> <span class="nn">sys</span><span class="o">,</span> <span class="nn">os</span>
<span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s">'/path/to/django_appX'</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">'DJANGO_SETTINGS_MODULE'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'django_appX.settings'</span>
<span class="k">from</span> <span class="nn">django.core.handlers.wsgi</span> <span class="k">import</span> <span class="n">WSGIHandler</span>
<span class="n">application</span> <span class="o">=</span> <span class="n">WSGIHandler</span><span class="p">()</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>#!/usr/bin/python
import sys, os
sys.path.insert(0, '/path/to/django_appX')
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_appX.settings'
from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler()<PYGMENTS_RAW -->
Hope I could help a little bit, if you have some questions to our server setup just send me a mail or write a comment. Finally, we first encountered some problems with mod_wsgi two months ago, but at the moment everything is working well, a lot better than any other server setup we used. You can even put python applications into the context of another user which basically replaces fastcgi + suexec.
And btw, the support we got from Graham is really, really good :)
<strong>Update:</strong> removed WSGIPassAuthorization like Graham suggested in the comments below.As you might now we switched the pocoo trac to mercurial, mod_wsgi and splitted it in the same go. The new structure is can be found at <a href="http://dev.pocoo.org/">dev.pocoo.org</a>. What you cannot see there is how all that is implemented. And I tell you. It's dead simple.
Basically we use mod_wsgi for hosting the tracs. There are many reasons for that but the most important one is that you can host multiple trac instances without much configuration. Basically the configuration binds a wsgi application to a URL match rule. One important thing is the <tt>maximum-requests</tt> setting. To understand this parameter you have to know that mod_wsgi does not only keep a pool of running python interpreters, but also your application with all data in the memory. Now that's a big difference to mod_php where your application is sourced on request and removed from the memory after the reqest. So basically you cannot create memory holes, which you can do in python. If your application leaks memory (and trac tends to do so) you can tell mod_wsgi to restart one python interpreter after 500 requests for example. That setting of course depends on your trac version, the number of plugins etc. And especially how many memory you have in your application. Here the Apache config:
Then we need a <tt>trac.wsgi</tt> file which is basically just a minimal WSGI application that dispatches our key. Say we have our trac instances in <tt>/var/trac/instances</tt>, every trac in it's own folder. Then we can use this code:
You can of course modify that not found message, maybe render a fancy HTML page or just redirect to the index of that domain or whatever. The important thing is that you set the path to the trac instance before calling the dispatch_request function. In theory you can do that from the apache config too, but in that situation you cannot check if the trac really exists.
And now about the django hosting part. Basically you can do the same for django. Django basically has a environment key called the <tt>DJANGO_SETTINGS_MODULE</tt> key. This key basically controls what settings module django will import. Unfortunately the whole django core is not process safe, so you cannot run two different django powered applications in the same python interpreter. This however is not that much of an issue with mod_wsgi, because you can tell mod_wsgi to not share the interpreter. (In the trac config above we shared the interpreter to save some memory)
Your config could look like this:
The actual "django_appX.wsgi" file is very, very simple. It just adds the folder and instanciates the django wsgi app:
Hope I could help a little bit, if you have some questions to our server setup just send me a mail or write a comment. Finally, we first encountered some problems with mod_wsgi two months ago, but at the moment everything is working well, a lot better than any other server setup we used. You can even put python applications into the context of another user which basically replaces fastcgi + suexec.
And btw, the support we got from Graham is really, really good :)
<strong>Update:</strong> removed WSGIPassAuthorization like Graham suggested in the comments below.SQAAAANTAAAABGJvZHlSUwAAAIhBcyB5b3UgbWlnaHQgbm93IHdlIHN3aXRjaGVkIHRoZSBwb2Nv
byB0cmFjIHRvIG1lcmN1cmlhbCwgbW9kX3dzZ2kgYW5kIHNwbGl0dGVkIGl0IGluIHRoZSBzYW1l
IGdvLiBUaGUgbmV3IHN0cnVjdHVyZSBpcyBjYW4gYmUgZm91bmQgYXQgTAAGRVMAAAABYUwAAE0A
AVMAAAAEaHJlZlMAAAAVaHR0cDovL2Rldi5wb2Nvby5vcmcvUwAAAA1kZXYucG9jb28ub3JnUwAA
AXkuIFdoYXQgeW91IGNhbm5vdCBzZWUgdGhlcmUgaXMgaG93IGFsbCB0aGF0IGlzIGltcGxlbWVu
dGVkLiBBbmQgSSB0ZWxsIHlvdS4gSXQncyBkZWFkIHNpbXBsZS4KCkJhc2ljYWxseSB3ZSB1c2Ug
bW9kX3dzZ2kgZm9yIGhvc3RpbmcgdGhlIHRyYWNzLiBUaGVyZSBhcmUgbWFueSByZWFzb25zIGZv
ciB0aGF0IGJ1dCB0aGUgbW9zdCBpbXBvcnRhbnQgb25lIGlzIHRoYXQgeW91IGNhbiBob3N0IG11
bHRpcGxlIHRyYWMgaW5zdGFuY2VzIHdpdGhvdXQgbXVjaCBjb25maWd1cmF0aW9uLiBCYXNpY2Fs
bHkgdGhlIGNvbmZpZ3VyYXRpb24gYmluZHMgYSB3c2dpIGFwcGxpY2F0aW9uIHRvIGEgVVJMIG1h
dGNoIHJ1bGUuIE9uZSBpbXBvcnRhbnQgdGhpbmcgaXMgdGhlIEVTAAAAAnR0TAAATQAAUwAAABBt
YXhpbXVtLXJlcXVlc3RzUwAAAssgc2V0dGluZy4gVG8gdW5kZXJzdGFuZCB0aGlzIHBhcmFtZXRl
ciB5b3UgaGF2ZSB0byBrbm93IHRoYXQgbW9kX3dzZ2kgZG9lcyBub3Qgb25seSBrZWVwIGEgcG9v
bCBvZiBydW5uaW5nIHB5dGhvbiBpbnRlcnByZXRlcnMsIGJ1dCBhbHNvIHlvdXIgYXBwbGljYXRp
b24gd2l0aCBhbGwgZGF0YSBpbiB0aGUgbWVtb3J5LiBOb3cgdGhhdCdzIGEgYmlnIGRpZmZlcmVu
Y2UgdG8gbW9kX3BocCB3aGVyZSB5b3VyIGFwcGxpY2F0aW9uIGlzIHNvdXJjZWQgb24gcmVxdWVz
dCBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBtZW1vcnkgYWZ0ZXIgdGhlIHJlcWVzdC4gU28gYmFzaWNh
bGx5IHlvdSBjYW5ub3QgY3JlYXRlIG1lbW9yeSBob2xlcywgd2hpY2ggeW91IGNhbiBkbyBpbiBw
eXRob24uIElmIHlvdXIgYXBwbGljYXRpb24gbGVha3MgbWVtb3J5IChhbmQgdHJhYyB0ZW5kcyB0
byBkbyBzbykgeW91IGNhbiB0ZWxsIG1vZF93c2dpIHRvIHJlc3RhcnQgb25lIHB5dGhvbiBpbnRl
cnByZXRlciBhZnRlciA1MDAgcmVxdWVzdHMgZm9yIGV4YW1wbGUuIFRoYXQgc2V0dGluZyBvZiBj
b3Vyc2UgZGVwZW5kcyBvbiB5b3VyIHRyYWMgdmVyc2lvbiwgdGhlIG51bWJlciBvZiBwbHVnaW5z
IGV0Yy4gQW5kIGVzcGVjaWFsbHkgaG93IG1hbnkgbWVtb3J5IHlvdSBoYXZlIGluIHlvdXIgYXBw
bGljYXRpb24uIEhlcmUgdGhlIEFwYWNoZSBjb25maWc6CgoKVGhlbiB3ZSBuZWVkIGEgRVMAAAAC
dHRMAABNAABTAAAACXRyYWMud3NnaVMAAAB0IGZpbGUgd2hpY2ggaXMgYmFzaWNhbGx5IGp1c3Qg
YSBtaW5pbWFsIFdTR0kgYXBwbGljYXRpb24gdGhhdCBkaXNwYXRjaGVzIG91ciBrZXkuIFNheSB3
ZSBoYXZlIG91ciB0cmFjIGluc3RhbmNlcyBpbiBFUwAAAAJ0dEwAAE0AAFMAAAATL3Zhci90cmFj
L2luc3RhbmNlc1MAAAI0LCBldmVyeSB0cmFjIGluIGl0J3Mgb3duIGZvbGRlci4gVGhlbiB3ZSBj
YW4gdXNlIHRoaXMgY29kZToKCgpZb3UgY2FuIG9mIGNvdXJzZSBtb2RpZnkgdGhhdCBub3QgZm91
bmQgbWVzc2FnZSwgbWF5YmUgcmVuZGVyIGEgZmFuY3kgSFRNTCBwYWdlIG9yIGp1c3QgcmVkaXJl
Y3QgdG8gdGhlIGluZGV4IG9mIHRoYXQgZG9tYWluIG9yIHdoYXRldmVyLiBUaGUgaW1wb3J0YW50
IHRoaW5nIGlzIHRoYXQgeW91IHNldCB0aGUgcGF0aCB0byB0aGUgdHJhYyBpbnN0YW5jZSBiZWZv
cmUgY2FsbGluZyB0aGUgZGlzcGF0Y2hfcmVxdWVzdCBmdW5jdGlvbi4gSW4gdGhlb3J5IHlvdSBj
YW4gZG8gdGhhdCBmcm9tIHRoZSBhcGFjaGUgY29uZmlnIHRvbywgYnV0IGluIHRoYXQgc2l0dWF0
aW9uIHlvdSBjYW5ub3QgY2hlY2sgaWYgdGhlIHRyYWMgcmVhbGx5IGV4aXN0cy4KCkFuZCBub3cg
YWJvdXQgdGhlIGRqYW5nbyBob3N0aW5nIHBhcnQuIEJhc2ljYWxseSB5b3UgY2FuIGRvIHRoZSBz
YW1lIGZvciBkamFuZ28uIERqYW5nbyBiYXNpY2FsbHkgaGFzIGEgZW52aXJvbm1lbnQga2V5IGNh
bGxlZCB0aGUgRVMAAAACdHRMAABNAABTAAAAFkRKQU5HT19TRVRUSU5HU19NT0RVTEVTAAAEESBr
ZXkuIFRoaXMga2V5IGJhc2ljYWxseSBjb250cm9scyB3aGF0IHNldHRpbmdzIG1vZHVsZSBkamFu
Z28gd2lsbCBpbXBvcnQuIFVuZm9ydHVuYXRlbHkgdGhlIHdob2xlIGRqYW5nbyBjb3JlIGlzIG5v
dCBwcm9jZXNzIHNhZmUsIHNvIHlvdSBjYW5ub3QgcnVuIHR3byBkaWZmZXJlbnQgZGphbmdvIHBv
d2VyZWQgYXBwbGljYXRpb25zIGluIHRoZSBzYW1lIHB5dGhvbiBpbnRlcnByZXRlci4gVGhpcyBo
b3dldmVyIGlzIG5vdCB0aGF0IG11Y2ggb2YgYW4gaXNzdWUgd2l0aCBtb2Rfd3NnaSwgYmVjYXVz
ZSB5b3UgY2FuIHRlbGwgbW9kX3dzZ2kgdG8gbm90IHNoYXJlIHRoZSBpbnRlcnByZXRlci4gKElu
IHRoZSB0cmFjIGNvbmZpZyBhYm92ZSB3ZSBzaGFyZWQgdGhlIGludGVycHJldGVyIHRvIHNhdmUg
c29tZSBtZW1vcnkpCgpZb3VyIGNvbmZpZyBjb3VsZCBsb29rIGxpa2UgdGhpczoKCgpUaGUgYWN0
dWFsICJkamFuZ29fYXBwWC53c2dpIiBmaWxlIGlzIHZlcnksIHZlcnkgc2ltcGxlLiBJdCBqdXN0
IGFkZHMgdGhlIGZvbGRlciBhbmQgaW5zdGFuY2lhdGVzIHRoZSBkamFuZ28gd3NnaSBhcHA6CgoK
SG9wZSBJIGNvdWxkIGhlbHAgYSBsaXR0bGUgYml0LCBpZiB5b3UgaGF2ZSBzb21lIHF1ZXN0aW9u
cyB0byBvdXIgc2VydmVyIHNldHVwIGp1c3Qgc2VuZCBtZSBhIG1haWwgb3Igd3JpdGUgYSBjb21t
ZW50LiBGaW5hbGx5LCB3ZSBmaXJzdCBlbmNvdW50ZXJlZCBzb21lIHByb2JsZW1zIHdpdGggbW9k
X3dzZ2kgdHdvIG1vbnRocyBhZ28sIGJ1dCBhdCB0aGUgbW9tZW50IGV2ZXJ5dGhpbmcgaXMgd29y
a2luZyB3ZWxsLCBhIGxvdCBiZXR0ZXIgdGhhbiBhbnkgb3RoZXIgc2VydmVyIHNldHVwIHdlIHVz
ZWQuIFlvdSBjYW4gZXZlbiBwdXQgcHl0aG9uIGFwcGxpY2F0aW9ucyBpbnRvIHRoZSBjb250ZXh0
IG9mIGFub3RoZXIgdXNlciB3aGljaCBiYXNpY2FsbHkgcmVwbGFjZXMgZmFzdGNnaSArIHN1ZXhl
Yy4KQW5kIGJ0dywgdGhlIHN1cHBvcnQgd2UgZ290IGZyb20gR3JhaGFtIGlzIHJlYWxseSwgcmVh
bGx5IGdvb2QgOikKCkVTAAAABnN0cm9uZ0wAAE0AAFMAAAAHVXBkYXRlOlMAAABLIHJlbW92ZWQg
V1NHSVBhc3NBdXRob3JpemF0aW9uIGxpa2UgR3JhaGFtIHN1Z2dlc3RlZCBpbiB0aGUgY29tbWVu
dHMgYmVsb3cuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2007-09-12T01:24:34Znono0To use mod_rewrite to check for the actual existence of a Trac instance, see example right at the bottom of:
http://code.google.com/p/modwsgi/wiki/IntegrationWithTrac
This means you do not have to do it in the WSGI script file.
I don't have my mod_rewrite book with me at the moment so I can look up how to do it, but instead of returning Forbidden, you could even possibly have it redirect to some index page listing available sites. The rewrite rules can probably also be comprised into one group to avoid having to match the URL more than once by using [S] modifier to RewriteRule. When I can look up the book and work out how to clean it up, I'll fix the example.To use mod_rewrite to check for the actual existence of a Trac instance, see example right at the bottom of:
http://code.google.com/p/modwsgi/wiki/IntegrationWithTrac
This means you do not have to do it in the WSGI script file.
I don't have my mod_rewrite book with me at the moment so I can look up how to do it, but instead of returning Forbidden, you could even possibly have it redirect to some index page listing available sites. The rewrite rules can probably also be comprised into one group to avoid having to match the URL more than once by using [S] modifier to RewriteRule. When I can look up the book and work out how to clean it up, I'll fix the example.SQAAAAJTAAAABGJvZHlSUwAAAqBUbyB1c2UgbW9kX3Jld3JpdGUgdG8gY2hlY2sgZm9yIHRoZSBh
Y3R1YWwgZXhpc3RlbmNlIG9mIGEgVHJhYyBpbnN0YW5jZSwgc2VlIGV4YW1wbGUgcmlnaHQgYXQg
dGhlIGJvdHRvbSBvZjoKCiAgaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL21vZHdzZ2kvd2lraS9J
bnRlZ3JhdGlvbldpdGhUcmFjCgpUaGlzIG1lYW5zIHlvdSBkbyBub3QgaGF2ZSB0byBkbyBpdCBp
biB0aGUgV1NHSSBzY3JpcHQgZmlsZS4KCkkgZG9uJ3QgaGF2ZSBteSBtb2RfcmV3cml0ZSBib29r
IHdpdGggbWUgYXQgdGhlIG1vbWVudCBzbyBJIGNhbiBsb29rIHVwIGhvdyB0byBkbyBpdCwgYnV0
IGluc3RlYWQgb2YgcmV0dXJuaW5nIEZvcmJpZGRlbiwgeW91IGNvdWxkIGV2ZW4gcG9zc2libHkg
aGF2ZSBpdCByZWRpcmVjdCB0byBzb21lIGluZGV4IHBhZ2UgbGlzdGluZyBhdmFpbGFibGUgc2l0
ZXMuIFRoZSByZXdyaXRlIHJ1bGVzIGNhbiBwcm9iYWJseSBhbHNvIGJlIGNvbXByaXNlZCBpbnRv
IG9uZSBncm91cCB0byBhdm9pZCBoYXZpbmcgdG8gbWF0Y2ggdGhlIFVSTCBtb3JlIHRoYW4gb25j
ZSBieSB1c2luZyBbU10gbW9kaWZpZXIgdG8gUmV3cml0ZVJ1bGUuIFdoZW4gSSBjYW4gbG9vayB1
cCB0aGUgYm9vayBhbmQgd29yayBvdXQgaG93IHRvIGNsZWFuIGl0IHVwLCBJJ2xsIGZpeCB0aGUg
ZXhhbXBsZS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Graham DumpletonGraham.Dumpleton@gmail.comhttp://blog.dscpl.com.au2007-09-12T02:43:45Znono0BTW, you shouldn't need:
WSGIPassAuthorization On
This is because Apache is handling authentication and not Trac. All Trac needs to see passed through is the REMOTE_USER variable which will still be passed even if WSGIPassAuthorization is not set to On.BTW, you shouldn't need:
WSGIPassAuthorization On
This is because Apache is handling authentication and not Trac. All Trac needs to see passed through is the REMOTE_USER variable which will still be passed even if WSGIPassAuthorization is not set to On.SQAAAAJTAAAABGJvZHlSUwAAAQFCVFcsIHlvdSBzaG91bGRuJ3QgbmVlZDoKCiAgV1NHSVBhc3NB
dXRob3JpemF0aW9uIE9uCgpUaGlzIGlzIGJlY2F1c2UgQXBhY2hlIGlzIGhhbmRsaW5nIGF1dGhl
bnRpY2F0aW9uIGFuZCBub3QgVHJhYy4gQWxsIFRyYWMgbmVlZHMgdG8gc2VlIHBhc3NlZCB0aHJv
dWdoIGlzIHRoZSBSRU1PVEVfVVNFUiB2YXJpYWJsZSB3aGljaCB3aWxsIHN0aWxsIGJlIHBhc3Nl
ZCBldmVuIGlmIFdTR0lQYXNzQXV0aG9yaXphdGlvbiBpcyBub3Qgc2V0IHRvIE9uLkwAAFMAAAAG
cGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-09-12T10:35:47Znono0Right. One could check with RewriteCond /filename/ -f. Haven't thought about that and assemble full paths directly from the config. So many ways :-)Right. One could check with RewriteCond /filename/ -f. Haven't thought about that and assemble full paths directly from the config. So many ways :-)SQAAAAJTAAAABGJvZHlSUwAAAJRSaWdodC4gT25lIGNvdWxkIGNoZWNrIHdpdGggUmV3cml0ZUNv
bmQgL2ZpbGVuYW1lLyAtZi4gSGF2ZW4ndCB0aG91Z2h0IGFib3V0IHRoYXQgYW5kIGFzc2VtYmxl
IGZ1bGwgcGF0aHMgZGlyZWN0bHkgZnJvbSB0aGUgY29uZmlnLiBTbyBtYW55IHdheXMgOi0pTAAA
UwAAAAZwYXJzZXJTAAAABGh0bWw=
BrDbram@bramd.nl2007-09-12T18:04:20Znono0Are there advantages with mod_wsgi in comparison with fastcgi+suexec?Are there advantages with mod_wsgi in comparison with fastcgi+suexec?SQAAAAJTAAAABGJvZHlSUwAAAEVBcmUgdGhlcmUgYWR2YW50YWdlcyB3aXRoIG1vZF93c2dpIGlu
IGNvbXBhcmlzb24gd2l0aCBmYXN0Y2dpK3N1ZXhlYz9MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-09-12T19:16:26Znono0The biggest advantage is certainly that it gracefully kills the processes after n requests. That ensures that if the application is leaky, it won't trash the server. And other big advantage is that you have one possible point of failure less because you don't need the python module that connects to FastCGI. You just have mod_wsgi which looks for the file you defined in the apache config and all the rest is controlled from the apache config.
No daemon process you have to kill yourself (the ruby guys from eins.de for example use fastcgi for their rails hosting and wrote a script that kill processes that life longer than 30 minutes etc.) and no daemon process you have to start yourself (although apache is able to manage your fastcgi processes).
Of course there are disadvantages too. You have the same problem like with any other mod_foobar module i guess. So don't let two applications in your apache link to different versions of the same library, don't expect that mod_wsgi works on lighttpd.
But nonetheless my favorite hosting solution for the moment.The biggest advantage is certainly that it gracefully kills the processes after n requests. That ensures that if the application is leaky, it won't trash the server. And other big advantage is that you have one possible point of failure less because you don't need the python module that connects to FastCGI. You just have mod_wsgi which looks for the file you defined in the apache config and all the rest is controlled from the apache config.
No daemon process you have to kill yourself (the ruby guys from eins.de for example use fastcgi for their rails hosting and wrote a script that kill processes that life longer than 30 minutes etc.) and no daemon process you have to start yourself (although apache is able to manage your fastcgi processes).
Of course there are disadvantages too. You have the same problem like with any other mod_foobar module i guess. So don't let two applications in your apache link to different versions of the same library, don't expect that mod_wsgi works on lighttpd.
But nonetheless my favorite hosting solution for the moment.SQAAAAJTAAAABGJvZHlSUwAABCpUaGUgYmlnZ2VzdCBhZHZhbnRhZ2UgaXMgY2VydGFpbmx5IHRo
YXQgaXQgZ3JhY2VmdWxseSBraWxscyB0aGUgcHJvY2Vzc2VzIGFmdGVyIG4gcmVxdWVzdHMuIFRo
YXQgZW5zdXJlcyB0aGF0IGlmIHRoZSBhcHBsaWNhdGlvbiBpcyBsZWFreSwgaXQgd29uJ3QgdHJh
c2ggdGhlIHNlcnZlci4gQW5kIG90aGVyIGJpZyBhZHZhbnRhZ2UgaXMgdGhhdCB5b3UgaGF2ZSBv
bmUgcG9zc2libGUgcG9pbnQgb2YgZmFpbHVyZSBsZXNzIGJlY2F1c2UgeW91IGRvbid0IG5lZWQg
dGhlIHB5dGhvbiBtb2R1bGUgdGhhdCBjb25uZWN0cyB0byBGYXN0Q0dJLiBZb3UganVzdCBoYXZl
IG1vZF93c2dpIHdoaWNoIGxvb2tzIGZvciB0aGUgZmlsZSB5b3UgZGVmaW5lZCBpbiB0aGUgYXBh
Y2hlIGNvbmZpZyBhbmQgYWxsIHRoZSByZXN0IGlzIGNvbnRyb2xsZWQgZnJvbSB0aGUgYXBhY2hl
IGNvbmZpZy4KCk5vIGRhZW1vbiBwcm9jZXNzIHlvdSBoYXZlIHRvIGtpbGwgeW91cnNlbGYgKHRo
ZSBydWJ5IGd1eXMgZnJvbSBlaW5zLmRlIGZvciBleGFtcGxlIHVzZSBmYXN0Y2dpIGZvciB0aGVp
ciByYWlscyBob3N0aW5nIGFuZCB3cm90ZSBhIHNjcmlwdCB0aGF0IGtpbGwgcHJvY2Vzc2VzIHRo
YXQgbGlmZSBsb25nZXIgdGhhbiAzMCBtaW51dGVzIGV0Yy4pIGFuZCBubyBkYWVtb24gcHJvY2Vz
cyB5b3UgaGF2ZSB0byBzdGFydCB5b3Vyc2VsZiAoYWx0aG91Z2ggYXBhY2hlIGlzIGFibGUgdG8g
bWFuYWdlIHlvdXIgZmFzdGNnaSBwcm9jZXNzZXMpLgoKT2YgY291cnNlIHRoZXJlIGFyZSBkaXNh
ZHZhbnRhZ2VzIHRvby4gWW91IGhhdmUgdGhlIHNhbWUgcHJvYmxlbSBsaWtlIHdpdGggYW55IG90
aGVyIG1vZF9mb29iYXIgbW9kdWxlIGkgZ3Vlc3MuIFNvIGRvbid0IGxldCB0d28gYXBwbGljYXRp
b25zIGluIHlvdXIgYXBhY2hlIGxpbmsgdG8gZGlmZmVyZW50IHZlcnNpb25zIG9mIHRoZSBzYW1l
IGxpYnJhcnksIGRvbid0IGV4cGVjdCB0aGF0IG1vZF93c2dpIHdvcmtzIG9uIGxpZ2h0dHBkLgoK
QnV0IG5vbmV0aGVsZXNzIG15IGZhdm9yaXRlIGhvc3Rpbmcgc29sdXRpb24gZm9yIHRoZSBtb21l
bnQuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Paulpb@e-scribe.comhttp://e-scribe.com/news/2007-09-13T12:51:09Znono0Thanks for posting this. It inspired me to pursue the (much less ambitious) project of converting a small Trac-managed repo from Subversion to Mercurial. It only took a few minutes, all history was preserved via hgsvn, and it seems to be working great.Thanks for posting this. It inspired me to pursue the (much less ambitious) project of converting a small Trac-managed repo from Subversion to Mercurial. It only took a few minutes, all history was preserved via hgsvn, and it seems to be working great.SQAAAAJTAAAABGJvZHlSUwAAAPxUaGFua3MgZm9yIHBvc3RpbmcgdGhpcy4gSXQgaW5zcGlyZWQg
bWUgdG8gcHVyc3VlIHRoZSAobXVjaCBsZXNzIGFtYml0aW91cykgcHJvamVjdCBvZiBjb252ZXJ0
aW5nIGEgc21hbGwgVHJhYy1tYW5hZ2VkIHJlcG8gZnJvbSBTdWJ2ZXJzaW9uIHRvIE1lcmN1cmlh
bC4gSXQgb25seSB0b29rIGEgZmV3IG1pbnV0ZXMsIGFsbCBoaXN0b3J5IHdhcyBwcmVzZXJ2ZWQg
dmlhIGhnc3ZuLCBhbmQgaXQgc2VlbXMgdG8gYmUgd29ya2luZyBncmVhdC5MAABTAAAABnBhcnNl
clMAAAAEaHRtbA==
DJango vs Railshttp://lucumr.pocoo.org/cogitations/2007/09/10/django-vs-rails/2007-09-10T19:21:33Z2007-09-10T19:21:33ZArmin Ronacherdjango-vs-railsyesyes2<a href="http://www.youtube.com/watch?v=PLUS00QrYWw">django is a hip hopper now</a>... and i thought django was playing jazz. And obviously he's unable to pronounce his name correctly.<a href="http://www.youtube.com/watch?v=PLUS00QrYWw">django is a hip hopper now</a>... and i thought django was playing jazz. And obviously he's unable to pronounce his name correctly.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACpodHRwOi8v
d3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9UExVUzAwUXJZV3dTAAAAGmRqYW5nbyBpcyBhIGhpcCBo
b3BwZXIgbm93UwAAAGUuLi4gYW5kIGkgdGhvdWdodCBkamFuZ28gd2FzIHBsYXlpbmcgamF6ei4g
QW5kIG9idmlvdXNseSBoZSdzIHVuYWJsZSB0byBwcm9ub3VuY2UgaGlzIG5hbWUgY29ycmVjdGx5
LlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Wade Mealingwmealing@gmail.comhttp://blog.subverted.net2007-09-12T01:41:29Znono0He must be a new djangonaut from php land.He must be a new djangonaut from php land.SQAAAAJTAAAABGJvZHlSUwAAACpIZSBtdXN0IGJlIGEgbmV3IGRqYW5nb25hdXQgZnJvbSBwaHAg
bGFuZC5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
luckystarrluckystarr@iname.com2007-09-12T16:34:13Znono0I think it's funny. "DJ Ango" in da house. :)I think it's funny. "DJ Ango" in da house. :)SQAAAAJTAAAABGJvZHlSUwAAAC1JIHRoaW5rIGl0J3MgZnVubnkuICJESiBBbmdvIiBpbiBkYSBo
b3VzZS4gOilMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Alan Trickatrick@kastanet.orghttp://tricks.webfactional.com/trick2007-09-17T03:08:31Znono0Even the Ruby guy pronounces django wrong. In IPA, he says [dʌˈʤeiŋgou] instead of [ˈʤeiŋgou] (i.e. the ‘d’ is supposed to be silent).Even the Ruby guy pronounces django wrong. In IPA, he says [dʌˈʤeiŋgou] instead of [ˈʤeiŋgou] (i.e. the ‘d’ is supposed to be silent).SQAAAAJTAAAABGJvZHlSUwAAAJFFdmVuIHRoZSBSdWJ5IGd1eSBwcm9ub3VuY2VzIGRqYW5nbyB3
cm9uZy4gSW4gSVBBLCBoZSBzYXlzIFtkyozLiMqkZWnFi2dvdV0gaW5zdGVhZCBvZiBby4jKpGVp
xYtnb3VdIChpLmUuIHRoZSDigJhk4oCZIGlzIHN1cHBvc2VkIHRvIGJlIHNpbGVudCkuTAAAUwAA
AAZwYXJzZXJTAAAABGh0bWw=
Tom von Schwerdtnertomvons@gmail.com2007-09-24T21:02:16Znono0I want [ˈʤeiŋgou] on a T-shirt...I want [ˈʤeiŋgou] on a T-shirt...SQAAAAJTAAAABGJvZHlSUwAAACRJIHdhbnQgW8uIyqRlacWLZ291XSBvbiBhIFQtc2hpcnQuLi5M
AABTAAAABnBhcnNlclMAAAAEaHRtbA==
You’re hired. D’oh, you’re not!http://lucumr.pocoo.org/cogitations/2007/09/09/youre-hired-doh-youre-not/2007-09-09T17:26:54Z2007-09-09T17:26:54ZArmin Ronacheryoure-hired-doh-youre-notyesyes2Someone gave me a link to one of DHH's <a href="http://www.loudthinking.com/arc/000433.html">old blog posts</a> where he was referring to Mac OS X as best operating system for developers. And what made me wonder a few words later was this:
<blockquote>While I can certainly understand the reasons why some people go with Linux, I have run all but dry of understanding for programmers that willfully pick Windows as their platform of choice. I know a few that are still stuck in the rut for various reasons — none of them desire.</blockquote>
And furthermore
<blockquote>I would have a hard time imagining hiring a programmer who was still on Windows for 37signals. If you don't care enough about your tools to get the best, your burden of proof just got a lot heavier.</blockquote>
That's ridiculous. It might be true that more and more hackers buy themselves apple notebooks and obviously I'm one of them, but I would never consider Mac OS X being the best developer platform. Being in the linux community for not so long and a pupil until two months ago I had to work with Windows for a long time. And I would never say that Windows is a bad operating system or that you cannot develop good applications on a windows machine. In fact the only reason why I don't use Windows is the bad terminal and the missing apt-get. In one of the comments on the linked page DHH states that "I'm primarily charging the lack of passion for your tools, which seems to be what a great many developers still left on Windows are citing at least in part for staying. '...covers both needs just fine', 'Windows simply because we are able to quite easily'.".
Except of rhythmbox and some other GNOME applications I used on a daily basis I can get all of my developer tools for a windows box too. It's just more work. And god I know that there are many people using Vim on Windows. Even better, if we're talking about good tools, there is an awful lot of good tools only available for windows. For example there is Visual Studio. You won't find an IDE that can compete with it, although Eclipse is certainly on a good way. Still, there are tools you cannot get on Linux and Mac OS X. The only tool I can think of DHH could have had in mind is "TextMate"...
And I can tell you what's the problem with TextMate: It's just a normal editor. I admit that everytime I watched a something screencast TextMate in it, I wanted to use that cool thing. But then again, now where I have a TextMate license it's just a normal editor. And not even the best I fear. I'm used to Vim and over the last years I configured it to such a high level that everytime I use a different editor I'm just less productive. So in general, that's not my sort of tool. Though, obviously it would stop me from getting hired by somethingsignals.
So what does people think Mac OS X is the best operating system? There are things solved very well on OS X. dmg and bundles is something that looks really nice. I think Linux is definitively missing something like that. ALso the Design of all the apple products and especially of their user interface is gorgeous.
But then again whenever I see a apple user interface I wished the font rendering was powered by libfreetype which gives me the possibility to configure my font rendering in the way I like my fonts to be displayed. I'm used to the fact that I'm the only person interested in the font rendering but that's one of the things I just hate about OS X. The only thing you can configure regarding font rendering is the threshold for non antialiased fonts (And the strength of the hinting which doesn't make things that better). And text is the thing I look at most of the time. Whenever I complained about that in the last few weeks people pointed me to articles that showed off that apple decides to render the fonts like they would appear on the paper and that this approach is better. Well, TextMate is better too, isn't it? But I can use Vim instead of TextMate. I cannot get OS X to render fonts like I want them to be rendered.
The next problem you have with OS X is that it's darn expensive. OS X as such might be a darn lot cheaper than Windows. But every single piece of software consts. Tired of mud mousing? Pay 30 bucks. Tired of Finder? Pay 30 bucks. Chaotic window manager feeling? Pay 15 bucks. Want to have more than one QuickTime window? Pay 30 bucks. Virtual Desktops? Wait for Leopard or pay 30 bucks. Different themes for your OS X? 20 bucks. Those are problems you don't have on Windows (because of tons of freeware) or Linux (because of tons of open source software).
And still, I'm not that unhappy with my Macbook because there are good aspects too. Though. I <strong>hate</strong> it when people praise OS X as <strong>the best</strong> developer platform or find amusing or bad accuses for problems you have on OS X. Apple is not a religious group or enlightened or whatever. They make mistakes too, not less than any other software company. Just that you have to pay more for them. So please. Don't let the decision of hiring depend on the operating system a developer users. They might have good reasons for doing so. And not everybody has the same idea of aesthetics.Someone gave me a link to one of DHH's <a href="http://www.loudthinking.com/arc/000433.html">old blog posts</a> where he was referring to Mac OS X as best operating system for developers. And what made me wonder a few words later was this:
<blockquote>While I can certainly understand the reasons why some people go with Linux, I have run all but dry of understanding for programmers that willfully pick Windows as their platform of choice. I know a few that are still stuck in the rut for various reasons — none of them desire.</blockquote>
And furthermore
<blockquote>I would have a hard time imagining hiring a programmer who was still on Windows for 37signals. If you don't care enough about your tools to get the best, your burden of proof just got a lot heavier.</blockquote>
That's ridiculous. It might be true that more and more hackers buy themselves apple notebooks and obviously I'm one of them, but I would never consider Mac OS X being the best developer platform. Being in the linux community for not so long and a pupil until two months ago I had to work with Windows for a long time. And I would never say that Windows is a bad operating system or that you cannot develop good applications on a windows machine. In fact the only reason why I don't use Windows is the bad terminal and the missing apt-get. In one of the comments on the linked page DHH states that "I'm primarily charging the lack of passion for your tools, which seems to be what a great many developers still left on Windows are citing at least in part for staying. '...covers both needs just fine', 'Windows simply because we are able to quite easily'.".
Except of rhythmbox and some other GNOME applications I used on a daily basis I can get all of my developer tools for a windows box too. It's just more work. And god I know that there are many people using Vim on Windows. Even better, if we're talking about good tools, there is an awful lot of good tools only available for windows. For example there is Visual Studio. You won't find an IDE that can compete with it, although Eclipse is certainly on a good way. Still, there are tools you cannot get on Linux and Mac OS X. The only tool I can think of DHH could have had in mind is "TextMate"...
And I can tell you what's the problem with TextMate: It's just a normal editor. I admit that everytime I watched a something screencast TextMate in it, I wanted to use that cool thing. But then again, now where I have a TextMate license it's just a normal editor. And not even the best I fear. I'm used to Vim and over the last years I configured it to such a high level that everytime I use a different editor I'm just less productive. So in general, that's not my sort of tool. Though, obviously it would stop me from getting hired by somethingsignals.
So what does people think Mac OS X is the best operating system? There are things solved very well on OS X. dmg and bundles is something that looks really nice. I think Linux is definitively missing something like that. ALso the Design of all the apple products and especially of their user interface is gorgeous.
But then again whenever I see a apple user interface I wished the font rendering was powered by libfreetype which gives me the possibility to configure my font rendering in the way I like my fonts to be displayed. I'm used to the fact that I'm the only person interested in the font rendering but that's one of the things I just hate about OS X. The only thing you can configure regarding font rendering is the threshold for non antialiased fonts (And the strength of the hinting which doesn't make things that better). And text is the thing I look at most of the time. Whenever I complained about that in the last few weeks people pointed me to articles that showed off that apple decides to render the fonts like they would appear on the paper and that this approach is better. Well, TextMate is better too, isn't it? But I can use Vim instead of TextMate. I cannot get OS X to render fonts like I want them to be rendered.
The next problem you have with OS X is that it's darn expensive. OS X as such might be a darn lot cheaper than Windows. But every single piece of software consts. Tired of mud mousing? Pay 30 bucks. Tired of Finder? Pay 30 bucks. Chaotic window manager feeling? Pay 15 bucks. Want to have more than one QuickTime window? Pay 30 bucks. Virtual Desktops? Wait for Leopard or pay 30 bucks. Different themes for your OS X? 20 bucks. Those are problems you don't have on Windows (because of tons of freeware) or Linux (because of tons of open source software).
And still, I'm not that unhappy with my Macbook because there are good aspects too. Though. I <strong>hate</strong> it when people praise OS X as <strong>the best</strong> developer platform or find amusing or bad accuses for problems you have on OS X. Apple is not a religious group or enlightened or whatever. They make mistakes too, not less than any other software company. Just that you have to pay more for them. So please. Don't let the decision of hiring depend on the operating system a developer users. They might have good reasons for doing so. And not everybody has the same idea of aesthetics.SQAAAANTAAAABGJvZHlSUwAAACdTb21lb25lIGdhdmUgbWUgYSBsaW5rIHRvIG9uZSBvZiBESEgn
cyBMAAVFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACtodHRwOi8vd3d3LmxvdWR0aGlua2luZy5j
b20vYXJjLzAwMDQzMy5odG1sUwAAAA5vbGQgYmxvZyBwb3N0c1MAAACBIHdoZXJlIGhlIHdhcyBy
ZWZlcnJpbmcgdG8gTWFjIE9TIFggYXMgYmVzdCBvcGVyYXRpbmcgc3lzdGVtIGZvciBkZXZlbG9w
ZXJzLiBBbmQgd2hhdCBtYWRlIG1lIHdvbmRlciBhIGZldyB3b3JkcyBsYXRlciB3YXMgdGhpczoK
RVMAAAAKYmxvY2txdW90ZUwAAE0AAFMAAAEWV2hpbGUgSSBjYW4gY2VydGFpbmx5IHVuZGVyc3Rh
bmQgdGhlIHJlYXNvbnMgd2h5IHNvbWUgcGVvcGxlIGdvIHdpdGggTGludXgsIEkgaGF2ZSBydW4g
YWxsIGJ1dCBkcnkgb2YgdW5kZXJzdGFuZGluZyBmb3IgcHJvZ3JhbW1lcnMgdGhhdCB3aWxsZnVs
bHkgcGljayBXaW5kb3dzIGFzIHRoZWlyIHBsYXRmb3JtIG9mIGNob2ljZS4gSSBrbm93IGEgZmV3
IHRoYXQgYXJlIHN0aWxsIHN0dWNrIGluIHRoZSBydXQgZm9yIHZhcmlvdXMgcmVhc29ucyDigJQg
bm9uZSBvZiB0aGVtIGRlc2lyZS5TAAAAEQpBbmQgZnVydGhlcm1vcmUKRVMAAAAKYmxvY2txdW90
ZUwAAE0AAFMAAADGSSB3b3VsZCBoYXZlIGEgaGFyZCB0aW1lIGltYWdpbmluZyBoaXJpbmcgYSBw
cm9ncmFtbWVyIHdobyB3YXMgc3RpbGwgb24gV2luZG93cyBmb3IgMzdzaWduYWxzLiBJZiB5b3Ug
ZG9uJ3QgY2FyZSBlbm91Z2ggYWJvdXQgeW91ciB0b29scyB0byBnZXQgdGhlIGJlc3QsIHlvdXIg
YnVyZGVuIG9mIHByb29mIGp1c3QgZ290IGEgbG90IGhlYXZpZXIuUwAAD0MKVGhhdCdzIHJpZGlj
dWxvdXMuIEl0IG1pZ2h0IGJlIHRydWUgdGhhdCBtb3JlIGFuZCBtb3JlIGhhY2tlcnMgYnV5IHRo
ZW1zZWx2ZXMgYXBwbGUgbm90ZWJvb2tzIGFuZCBvYnZpb3VzbHkgSSdtIG9uZSBvZiB0aGVtLCBi
dXQgSSB3b3VsZCBuZXZlciBjb25zaWRlciBNYWMgT1MgWCBiZWluZyB0aGUgYmVzdCBkZXZlbG9w
ZXIgcGxhdGZvcm0uIEJlaW5nIGluIHRoZSBsaW51eCBjb21tdW5pdHkgZm9yIG5vdCBzbyBsb25n
IGFuZCBhIHB1cGlsIHVudGlsIHR3byBtb250aHMgYWdvIEkgaGFkIHRvIHdvcmsgd2l0aCBXaW5k
b3dzIGZvciBhIGxvbmcgdGltZS4gQW5kIEkgd291bGQgbmV2ZXIgc2F5IHRoYXQgV2luZG93cyBp
cyBhIGJhZCBvcGVyYXRpbmcgc3lzdGVtIG9yIHRoYXQgeW91IGNhbm5vdCBkZXZlbG9wIGdvb2Qg
YXBwbGljYXRpb25zIG9uIGEgd2luZG93cyBtYWNoaW5lLiBJbiBmYWN0IHRoZSBvbmx5IHJlYXNv
biB3aHkgSSBkb24ndCB1c2UgV2luZG93cyBpcyB0aGUgYmFkIHRlcm1pbmFsIGFuZCB0aGUgbWlz
c2luZyBhcHQtZ2V0LiBJbiBvbmUgb2YgdGhlIGNvbW1lbnRzIG9uIHRoZSBsaW5rZWQgcGFnZSBE
SEggc3RhdGVzIHRoYXQgICJJJ20gcHJpbWFyaWx5IGNoYXJnaW5nIHRoZSBsYWNrIG9mIHBhc3Np
b24gZm9yIHlvdXIgdG9vbHMsIHdoaWNoIHNlZW1zIHRvIGJlIHdoYXQgYSBncmVhdCBtYW55IGRl
dmVsb3BlcnMgc3RpbGwgbGVmdCBvbiBXaW5kb3dzIGFyZSBjaXRpbmcgYXQgbGVhc3QgaW4gcGFy
dCBmb3Igc3RheWluZy4gJy4uLmNvdmVycyBib3RoIG5lZWRzIGp1c3QgZmluZScsICdXaW5kb3dz
IHNpbXBseSBiZWNhdXNlIHdlIGFyZSBhYmxlIHRvIHF1aXRlIGVhc2lseScuIi4KCkV4Y2VwdCBv
ZiByaHl0aG1ib3ggYW5kIHNvbWUgb3RoZXIgR05PTUUgYXBwbGljYXRpb25zIEkgdXNlZCBvbiBh
IGRhaWx5IGJhc2lzIEkgY2FuIGdldCBhbGwgb2YgbXkgZGV2ZWxvcGVyIHRvb2xzIGZvciBhIHdp
bmRvd3MgYm94IHRvby4gSXQncyBqdXN0IG1vcmUgd29yay4gQW5kIGdvZCBJIGtub3cgdGhhdCB0
aGVyZSBhcmUgbWFueSBwZW9wbGUgdXNpbmcgVmltIG9uIFdpbmRvd3MuIEV2ZW4gYmV0dGVyLCBp
ZiB3ZSdyZSB0YWxraW5nIGFib3V0IGdvb2QgdG9vbHMsIHRoZXJlIGlzIGFuIGF3ZnVsIGxvdCBv
ZiBnb29kIHRvb2xzIG9ubHkgYXZhaWxhYmxlIGZvciB3aW5kb3dzLiBGb3IgZXhhbXBsZSB0aGVy
ZSBpcyBWaXN1YWwgU3R1ZGlvLiBZb3Ugd29uJ3QgZmluZCBhbiBJREUgdGhhdCBjYW4gY29tcGV0
ZSB3aXRoIGl0LCBhbHRob3VnaCBFY2xpcHNlIGlzIGNlcnRhaW5seSBvbiBhIGdvb2Qgd2F5LiBT
dGlsbCwgdGhlcmUgYXJlIHRvb2xzIHlvdSBjYW5ub3QgZ2V0IG9uIExpbnV4IGFuZCBNYWMgT1Mg
WC4gVGhlIG9ubHkgdG9vbCBJIGNhbiB0aGluayBvZiBESEggY291bGQgaGF2ZSBoYWQgaW4gbWlu
ZCBpcyAiVGV4dE1hdGUiLi4uCgpBbmQgSSBjYW4gdGVsbCB5b3Ugd2hhdCdzIHRoZSBwcm9ibGVt
IHdpdGggVGV4dE1hdGU6IEl0J3MganVzdCBhIG5vcm1hbCBlZGl0b3IuIEkgYWRtaXQgdGhhdCBl
dmVyeXRpbWUgSSB3YXRjaGVkIGEgc29tZXRoaW5nIHNjcmVlbmNhc3QgVGV4dE1hdGUgaW4gaXQs
IEkgd2FudGVkIHRvIHVzZSB0aGF0IGNvb2wgdGhpbmcuIEJ1dCB0aGVuIGFnYWluLCBub3cgd2hl
cmUgSSBoYXZlIGEgVGV4dE1hdGUgbGljZW5zZSBpdCdzIGp1c3QgYSBub3JtYWwgZWRpdG9yLiBB
bmQgbm90IGV2ZW4gdGhlIGJlc3QgSSBmZWFyLiBJJ20gdXNlZCB0byBWaW0gYW5kIG92ZXIgdGhl
IGxhc3QgeWVhcnMgSSBjb25maWd1cmVkIGl0IHRvIHN1Y2ggYSBoaWdoIGxldmVsIHRoYXQgZXZl
cnl0aW1lIEkgdXNlIGEgZGlmZmVyZW50IGVkaXRvciBJJ20ganVzdCBsZXNzIHByb2R1Y3RpdmUu
IFNvIGluIGdlbmVyYWwsIHRoYXQncyBub3QgbXkgc29ydCBvZiB0b29sLiBUaG91Z2gsIG9idmlv
dXNseSBpdCB3b3VsZCBzdG9wIG1lIGZyb20gZ2V0dGluZyBoaXJlZCBieSBzb21ldGhpbmdzaWdu
YWxzLgoKU28gd2hhdCBkb2VzIHBlb3BsZSB0aGluayBNYWMgT1MgWCBpcyB0aGUgYmVzdCBvcGVy
YXRpbmcgc3lzdGVtPyBUaGVyZSBhcmUgdGhpbmdzIHNvbHZlZCB2ZXJ5IHdlbGwgb24gT1MgWC4g
ZG1nIGFuZCBidW5kbGVzIGlzIHNvbWV0aGluZyB0aGF0IGxvb2tzIHJlYWxseSBuaWNlLiBJIHRo
aW5rIExpbnV4IGlzIGRlZmluaXRpdmVseSBtaXNzaW5nIHNvbWV0aGluZyBsaWtlIHRoYXQuIEFM
c28gdGhlIERlc2lnbiBvZiBhbGwgdGhlIGFwcGxlIHByb2R1Y3RzIGFuZCBlc3BlY2lhbGx5IG9m
IHRoZWlyIHVzZXIgaW50ZXJmYWNlIGlzIGdvcmdlb3VzLgoKQnV0IHRoZW4gYWdhaW4gd2hlbmV2
ZXIgSSBzZWUgYSBhcHBsZSB1c2VyIGludGVyZmFjZSBJIHdpc2hlZCB0aGUgZm9udCByZW5kZXJp
bmcgd2FzIHBvd2VyZWQgYnkgbGliZnJlZXR5cGUgd2hpY2ggZ2l2ZXMgbWUgdGhlIHBvc3NpYmls
aXR5IHRvIGNvbmZpZ3VyZSBteSBmb250IHJlbmRlcmluZyBpbiB0aGUgd2F5IEkgbGlrZSBteSBm
b250cyB0byBiZSBkaXNwbGF5ZWQuIEknbSB1c2VkIHRvIHRoZSBmYWN0IHRoYXQgSSdtIHRoZSBv
bmx5IHBlcnNvbiBpbnRlcmVzdGVkIGluIHRoZSBmb250IHJlbmRlcmluZyBidXQgdGhhdCdzIG9u
ZSBvZiB0aGUgdGhpbmdzIEkganVzdCBoYXRlIGFib3V0IE9TIFguIFRoZSBvbmx5IHRoaW5nIHlv
dSBjYW4gY29uZmlndXJlIHJlZ2FyZGluZyBmb250IHJlbmRlcmluZyBpcyB0aGUgdGhyZXNob2xk
IGZvciBub24gYW50aWFsaWFzZWQgZm9udHMgKEFuZCB0aGUgc3RyZW5ndGggb2YgdGhlIGhpbnRp
bmcgd2hpY2ggZG9lc24ndCBtYWtlIHRoaW5ncyB0aGF0IGJldHRlcikuIEFuZCB0ZXh0IGlzIHRo
ZSB0aGluZyBJIGxvb2sgYXQgbW9zdCBvZiB0aGUgdGltZS4gV2hlbmV2ZXIgSSBjb21wbGFpbmVk
IGFib3V0IHRoYXQgaW4gdGhlIGxhc3QgZmV3IHdlZWtzIHBlb3BsZSBwb2ludGVkIG1lIHRvIGFy
dGljbGVzIHRoYXQgc2hvd2VkIG9mZiB0aGF0IGFwcGxlIGRlY2lkZXMgdG8gcmVuZGVyIHRoZSBm
b250cyBsaWtlIHRoZXkgd291bGQgYXBwZWFyIG9uIHRoZSBwYXBlciBhbmQgdGhhdCB0aGlzIGFw
cHJvYWNoIGlzIGJldHRlci4gV2VsbCwgVGV4dE1hdGUgaXMgYmV0dGVyIHRvbywgaXNuJ3QgaXQ/
IEJ1dCBJIGNhbiB1c2UgVmltIGluc3RlYWQgb2YgVGV4dE1hdGUuIEkgY2Fubm90IGdldCBPUyBY
IHRvIHJlbmRlciBmb250cyBsaWtlIEkgd2FudCB0aGVtIHRvIGJlIHJlbmRlcmVkLgoKVGhlIG5l
eHQgcHJvYmxlbSB5b3UgaGF2ZSB3aXRoIE9TIFggaXMgdGhhdCBpdCdzIGRhcm4gZXhwZW5zaXZl
LiBPUyBYIGFzIHN1Y2ggbWlnaHQgYmUgYSBkYXJuIGxvdCBjaGVhcGVyIHRoYW4gV2luZG93cy4g
QnV0IGV2ZXJ5IHNpbmdsZSBwaWVjZSBvZiBzb2Z0d2FyZSBjb25zdHMuIFRpcmVkIG9mIG11ZCBt
b3VzaW5nPyBQYXkgMzAgYnVja3MuIFRpcmVkIG9mIEZpbmRlcj8gUGF5IDMwIGJ1Y2tzLiBDaGFv
dGljIHdpbmRvdyBtYW5hZ2VyIGZlZWxpbmc/IFBheSAxNSBidWNrcy4gV2FudCB0byBoYXZlIG1v
cmUgdGhhbiBvbmUgUXVpY2tUaW1lIHdpbmRvdz8gUGF5IDMwIGJ1Y2tzLiBWaXJ0dWFsIERlc2t0
b3BzPyBXYWl0IGZvciBMZW9wYXJkIG9yIHBheSAzMCBidWNrcy4gRGlmZmVyZW50IHRoZW1lcyBm
b3IgeW91ciBPUyBYPyAyMCBidWNrcy4gVGhvc2UgYXJlIHByb2JsZW1zIHlvdSBkb24ndCBoYXZl
IG9uIFdpbmRvd3MgKGJlY2F1c2Ugb2YgdG9ucyBvZiBmcmVld2FyZSkgb3IgTGludXggKGJlY2F1
c2Ugb2YgdG9ucyBvZiBvcGVuIHNvdXJjZSBzb2Z0d2FyZSkuCgpBbmQgc3RpbGwsIEknbSBub3Qg
dGhhdCB1bmhhcHB5IHdpdGggbXkgTWFjYm9vayBiZWNhdXNlIHRoZXJlIGFyZSBnb29kIGFzcGVj
dHMgdG9vLiBUaG91Z2guIEkgRVMAAAAGc3Ryb25nTAAATQAAUwAAAARoYXRlUwAAAB8gaXQgd2hl
biBwZW9wbGUgcHJhaXNlIE9TIFggYXMgRVMAAAAGc3Ryb25nTAAATQAAUwAAAAh0aGUgYmVzdFMA
AAGzIGRldmVsb3BlciBwbGF0Zm9ybSBvciBmaW5kIGFtdXNpbmcgb3IgYmFkIGFjY3VzZXMgZm9y
IHByb2JsZW1zIHlvdSBoYXZlIG9uIE9TIFguIEFwcGxlIGlzIG5vdCBhIHJlbGlnaW91cyBncm91
cCBvciBlbmxpZ2h0ZW5lZCBvciB3aGF0ZXZlci4gVGhleSBtYWtlIG1pc3Rha2VzIHRvbywgbm90
IGxlc3MgdGhhbiBhbnkgb3RoZXIgc29mdHdhcmUgY29tcGFueS4gSnVzdCB0aGF0IHlvdSBoYXZl
IHRvIHBheSBtb3JlIGZvciB0aGVtLiBTbyBwbGVhc2UuIERvbid0IGxldCB0aGUgZGVjaXNpb24g
b2YgaGlyaW5nIGRlcGVuZCBvbiB0aGUgb3BlcmF0aW5nIHN5c3RlbSBhIGRldmVsb3BlciB1c2Vy
cy4gVGhleSBtaWdodCBoYXZlIGdvb2QgcmVhc29ucyBmb3IgZG9pbmcgc28uIEFuZCBub3QgZXZl
cnlib2R5IGhhcyB0aGUgc2FtZSBpZGVhIG9mIGFlc3RoZXRpY3MuUwAAAAZwYXJzZXJTAAAABGh0
bWxTAAAABWludHJvUlMAAAAATAAA
mqfoo@bar.baz2007-09-09T18:23:42Znono0Well, the main problem when discussing about OS X is that nearly all people who have a opinion on this topic (a one that's more than "hm, looks nice") have quite strong feelings about it - I always get the impression that most OS X users are Apple/OS X fanboys (at least many more than in other communities), while most people who don't like it are trollish and/or don't accept that it has it's good sides.
Of course, there's a lot of people who don't think so (hey, you're one of them :D), but I don't see nearly as many people with such strong feelings about a topic in any other community.Well, the main problem when discussing about OS X is that nearly all people who have a opinion on this topic (a one that's more than "hm, looks nice") have quite strong feelings about it - I always get the impression that most OS X users are Apple/OS X fanboys (at least many more than in other communities), while most people who don't like it are trollish and/or don't accept that it has it's good sides.
Of course, there's a lot of people who don't think so (hey, you're one of them :D), but I don't see nearly as many people with such strong feelings about a topic in any other community.SQAAAAJTAAAABGJvZHlSUwAAAlBXZWxsLCB0aGUgbWFpbiBwcm9ibGVtIHdoZW4gZGlzY3Vzc2lu
ZyBhYm91dCBPUyBYIGlzIHRoYXQgbmVhcmx5IGFsbCBwZW9wbGUgd2hvIGhhdmUgYSBvcGluaW9u
IG9uIHRoaXMgdG9waWMgKGEgb25lIHRoYXQncyBtb3JlIHRoYW4gImhtLCBsb29rcyBuaWNlIikg
aGF2ZSBxdWl0ZSBzdHJvbmcgZmVlbGluZ3MgYWJvdXQgaXQgLSBJIGFsd2F5cyBnZXQgdGhlIGlt
cHJlc3Npb24gdGhhdCBtb3N0IE9TIFggdXNlcnMgYXJlIEFwcGxlL09TIFggZmFuYm95cyAoYXQg
bGVhc3QgbWFueSBtb3JlIHRoYW4gaW4gb3RoZXIgY29tbXVuaXRpZXMpLCB3aGlsZSBtb3N0IHBl
b3BsZSB3aG8gZG9uJ3QgbGlrZSBpdCBhcmUgdHJvbGxpc2ggYW5kL29yIGRvbid0IGFjY2VwdCB0
aGF0IGl0IGhhcyBpdCdzIGdvb2Qgc2lkZXMuCk9mIGNvdXJzZSwgdGhlcmUncyBhIGxvdCBvZiBw
ZW9wbGUgd2hvIGRvbid0IHRoaW5rIHNvIChoZXksIHlvdSdyZSBvbmUgb2YgdGhlbSA6RCksIGJ1
dCBJIGRvbid0IHNlZSBuZWFybHkgYXMgbWFueSBwZW9wbGUgd2l0aCBzdWNoIHN0cm9uZyBmZWVs
aW5ncyBhYm91dCBhIHRvcGljIGluIGFueSBvdGhlciBjb21tdW5pdHkuTAAAUwAAAAZwYXJzZXJT
AAAABGh0bWw=
Michael Johnstonlastobelus@mac.com2007-12-14T21:41:05Znono0My experience with freeware on windows is that the amount of time it takes to find & install a good solution for whatever problem I need to solve while avoiding inadvertently installing malware makes it cost more than buying something for OS X, even if I only value my free time at 30-40$ an hour.My experience with freeware on windows is that the amount of time it takes to find & install a good solution for whatever problem I need to solve while avoiding inadvertently installing malware makes it cost more than buying something for OS X, even if I only value my free time at 30-40$ an hour.SQAAAAJTAAAABGJvZHlSUwAAASlNeSBleHBlcmllbmNlIHdpdGggZnJlZXdhcmUgb24gd2luZG93
cyBpcyB0aGF0IHRoZSBhbW91bnQgb2YgdGltZSBpdCB0YWtlcyB0byBmaW5kICYgaW5zdGFsbCBh
IGdvb2Qgc29sdXRpb24gZm9yIHdoYXRldmVyIHByb2JsZW0gSSBuZWVkIHRvIHNvbHZlIHdoaWxl
IGF2b2lkaW5nIGluYWR2ZXJ0ZW50bHkgaW5zdGFsbGluZyBtYWx3YXJlIG1ha2VzIGl0IGNvc3Qg
bW9yZSB0aGFuIGJ1eWluZyBzb21ldGhpbmcgZm9yIE9TIFgsIGV2ZW4gaWYgSSBvbmx5IHZhbHVl
IG15IGZyZWUgdGltZSBhdCAzMC00MCQgYW4gaG91ci5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Weekly Updateshttp://lucumr.pocoo.org/cogitations/2007/09/09/weekly-updates/2007-09-08T23:01:05Z2007-09-08T23:01:05ZArmin Ronacherweekly-updatesyesyes2Wohoo. We finally migrated all of our subversion hosted projects to mercurial. And the best part: we now have a separate trac instance for each of those projects. mod_wsgi does a great job hosting all those tracs without having to add each trac to the config separately. I will post a commented version of our mod_wsgi config in the next days, for the moment still some other things are in the pipeline.
The new developer platform of Jinja, Pygments and all the other projects is on <a href="http://dev.pocoo.org/">dev.pocoo.org</a>. Note that most tracs are still empty because we haven't had the time to move the tickets and wiki pages over. For that we have to write a conversion script first.
The plan for the next weeks is releasing Jinja 1.2 and Werkzeug 0.1. The latter is missing some unittests. After that I want to work on pocoo to finally get a working version. TextPress itself is now in the repositories (if you don't know what it is, just ignore it for now), guess most of use will contribute some code in the next weeks but don't expect an release. Want to convert this blog here soon though.
Last but not least: hello planet django :)Wohoo. We finally migrated all of our subversion hosted projects to mercurial. And the best part: we now have a separate trac instance for each of those projects. mod_wsgi does a great job hosting all those tracs without having to add each trac to the config separately. I will post a commented version of our mod_wsgi config in the next days, for the moment still some other things are in the pipeline.
The new developer platform of Jinja, Pygments and all the other projects is on <a href="http://dev.pocoo.org/">dev.pocoo.org</a>. Note that most tracs are still empty because we haven't had the time to move the tickets and wiki pages over. For that we have to write a conversion script first.
The plan for the next weeks is releasing Jinja 1.2 and Werkzeug 0.1. The latter is missing some unittests. After that I want to work on pocoo to finally get a working version. TextPress itself is now in the repositories (if you don't know what it is, just ignore it for now), guess most of use will contribute some code in the next weeks but don't expect an release. Want to convert this blog here soon though.
Last but not least: hello planet django :)SQAAAANTAAAABGJvZHlSUwAAAeRXb2hvby4gV2UgZmluYWxseSBtaWdyYXRlZCBhbGwgb2Ygb3Vy
IHN1YnZlcnNpb24gaG9zdGVkIHByb2plY3RzIHRvIG1lcmN1cmlhbC4gQW5kIHRoZSBiZXN0IHBh
cnQ6IHdlIG5vdyBoYXZlIGEgc2VwYXJhdGUgdHJhYyBpbnN0YW5jZSBmb3IgZWFjaCBvZiB0aG9z
ZSBwcm9qZWN0cy4gbW9kX3dzZ2kgZG9lcyBhIGdyZWF0IGpvYiBob3N0aW5nIGFsbCB0aG9zZSB0
cmFjcyB3aXRob3V0IGhhdmluZyB0byBhZGQgZWFjaCB0cmFjIHRvIHRoZSBjb25maWcgc2VwYXJh
dGVseS4gSSB3aWxsIHBvc3QgYSBjb21tZW50ZWQgdmVyc2lvbiBvZiBvdXIgbW9kX3dzZ2kgY29u
ZmlnIGluIHRoZSBuZXh0IGRheXMsIGZvciB0aGUgbW9tZW50IHN0aWxsIHNvbWUgb3RoZXIgdGhp
bmdzIGFyZSBpbiB0aGUgcGlwZWxpbmUuCgpUaGUgbmV3IGRldmVsb3BlciBwbGF0Zm9ybSBvZiBK
aW5qYSwgUHlnbWVudHMgYW5kIGFsbCB0aGUgb3RoZXIgcHJvamVjdHMgaXMgb24gTAABRVMAAAAB
YUwAAE0AAVMAAAAEaHJlZlMAAAAVaHR0cDovL2Rldi5wb2Nvby5vcmcvUwAAAA1kZXYucG9jb28u
b3JnUwAAAmwuIE5vdGUgdGhhdCBtb3N0IHRyYWNzIGFyZSBzdGlsbCBlbXB0eSBiZWNhdXNlIHdl
IGhhdmVuJ3QgaGFkIHRoZSB0aW1lIHRvIG1vdmUgdGhlIHRpY2tldHMgYW5kIHdpa2kgcGFnZXMg
b3Zlci4gRm9yIHRoYXQgd2UgaGF2ZSB0byB3cml0ZSBhIGNvbnZlcnNpb24gc2NyaXB0IGZpcnN0
LgoKVGhlIHBsYW4gZm9yIHRoZSBuZXh0IHdlZWtzIGlzIHJlbGVhc2luZyBKaW5qYSAxLjIgYW5k
IFdlcmt6ZXVnIDAuMS4gVGhlIGxhdHRlciBpcyBtaXNzaW5nIHNvbWUgdW5pdHRlc3RzLiBBZnRl
ciB0aGF0IEkgd2FudCB0byB3b3JrIG9uIHBvY29vIHRvIGZpbmFsbHkgZ2V0IGEgd29ya2luZyB2
ZXJzaW9uLiBUZXh0UHJlc3MgaXRzZWxmIGlzIG5vdyBpbiB0aGUgcmVwb3NpdG9yaWVzIChpZiB5
b3UgZG9uJ3Qga25vdyB3aGF0IGl0IGlzLCBqdXN0IGlnbm9yZSBpdCBmb3Igbm93KSwgZ3Vlc3Mg
bW9zdCBvZiB1c2Ugd2lsbCBjb250cmlidXRlIHNvbWUgY29kZSBpbiB0aGUgbmV4dCB3ZWVrcyBi
dXQgZG9uJ3QgZXhwZWN0IGFuIHJlbGVhc2UuIFdhbnQgdG8gY29udmVydCB0aGlzIGJsb2cgaGVy
ZSBzb29uIHRob3VnaC4KCkxhc3QgYnV0IG5vdCBsZWFzdDogaGVsbG8gcGxhbmV0IGRqYW5nbyA6
KVMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Jaskojkottler@asl-abq.com2007-09-10T22:38:37Znono0I've been looking for a distributed source control solution - not because I of the distribution, but because of the improved branch / merge over svn and the ability to have local checkpoints. I was interested in Bazaar, but Trac integration is a big deal for me. How's the Trac / hg combo?I've been looking for a distributed source control solution - not because I of the distribution, but because of the improved branch / merge over svn and the ability to have local checkpoints. I was interested in Bazaar, but Trac integration is a big deal for me. How's the Trac / hg combo?SQAAAAJTAAAABGJvZHlSUwAAASFJJ3ZlIGJlZW4gbG9va2luZyBmb3IgYSBkaXN0cmlidXRlZCBz
b3VyY2UgY29udHJvbCBzb2x1dGlvbiAtIG5vdCBiZWNhdXNlIEkgb2YgdGhlIGRpc3RyaWJ1dGlv
biwgYnV0IGJlY2F1c2Ugb2YgdGhlIGltcHJvdmVkIGJyYW5jaCAvIG1lcmdlIG92ZXIgc3ZuIGFu
ZCB0aGUgYWJpbGl0eSB0byBoYXZlIGxvY2FsIGNoZWNrcG9pbnRzLiBJIHdhcyBpbnRlcmVzdGVk
IGluIEJhemFhciwgYnV0IFRyYWMgaW50ZWdyYXRpb24gaXMgYSBiaWcgZGVhbCBmb3IgbWUuIEhv
dydzIHRoZSBUcmFjIC8gaGcgY29tYm8/TAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-09-11T05:38:04Znono0It's working very well. The only problem that exists right now is that trac doesn't support multiple repositories for one trac. So if you want to branch into a new repository you have to setup a second trac or just display the main repository in your trac. If you do per repository branches that of course works.
I hope the trac guys address this issue in trac 0.12. Especially now where more and more people convert away from subversion to more sophisticated solutions like hg/git/darcs/bzr. :-)It's working very well. The only problem that exists right now is that trac doesn't support multiple repositories for one trac. So if you want to branch into a new repository you have to setup a second trac or just display the main repository in your trac. If you do per repository branches that of course works.
I hope the trac guys address this issue in trac 0.12. Especially now where more and more people convert away from subversion to more sophisticated solutions like hg/git/darcs/bzr. :-)SQAAAAJTAAAABGJvZHlSUwAAAfFJdCdzIHdvcmtpbmcgdmVyeSB3ZWxsLiBUaGUgb25seSBwcm9i
bGVtIHRoYXQgZXhpc3RzIHJpZ2h0IG5vdyBpcyB0aGF0IHRyYWMgZG9lc24ndCBzdXBwb3J0IG11
bHRpcGxlIHJlcG9zaXRvcmllcyBmb3Igb25lIHRyYWMuIFNvIGlmIHlvdSB3YW50IHRvIGJyYW5j
aCBpbnRvIGEgbmV3IHJlcG9zaXRvcnkgeW91IGhhdmUgdG8gc2V0dXAgYSBzZWNvbmQgdHJhYyBv
ciBqdXN0IGRpc3BsYXkgdGhlIG1haW4gcmVwb3NpdG9yeSBpbiB5b3VyIHRyYWMuIElmIHlvdSBk
byBwZXIgcmVwb3NpdG9yeSBicmFuY2hlcyB0aGF0IG9mIGNvdXJzZSB3b3Jrcy4KCkkgaG9wZSB0
aGUgdHJhYyBndXlzIGFkZHJlc3MgdGhpcyBpc3N1ZSBpbiB0cmFjIDAuMTIuIEVzcGVjaWFsbHkg
bm93IHdoZXJlIG1vcmUgYW5kIG1vcmUgcGVvcGxlIGNvbnZlcnQgYXdheSBmcm9tIHN1YnZlcnNp
b24gdG8gbW9yZSBzb3BoaXN0aWNhdGVkIHNvbHV0aW9ucyBsaWtlIGhnL2dpdC9kYXJjcy9ienIu
IDotKUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Django Support in Jinja 1.2http://lucumr.pocoo.org/cogitations/2007/09/06/django-support-in-jinja-12/2007-09-06T17:54:54Z2007-09-06T17:54:54ZArmin Ronacherdjango-support-in-jinja-12yesyes2Jinja 1.2 is about to be released, I just want to switch all the pocoo projects from subversion to mercurial first. One of the new features in Jinja 1.2 is the django support. Thanks to Bryan McLemore from curse for his contributions.
I refactored his code a bit so that it integrates a little nicer into django applications, the original code had some other names for functions and used idioms from curse that feel unnatural in django applications.
Basically to get started in Jinja 1.2 you have to do nothing more than adding the following thing into your urls.py file, right at the beginning:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">jinja.contrib</span> <span class="k">import</span> <span class="n">djangosupport</span>
<span class="n">djangosupport</span><span class="o">.</span><span class="n">configure</span><span class="p">()</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from jinja.contrib import djangosupport
djangosupport.configure()<PYGMENTS_RAW -->
That automatically configures Jinja for django and adds a virtual module called "django.contrib.jinja" that contains versions of the django shortcuts that work with Jinja. This module also provides the environment that is automatically set up based on your django configuration.
Basically if you have used in your views this code so far:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">django.shortcuts</span> <span class="k">import</span> <span class="n">render_to_response</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">req</span><span class="p">):</span>
<span class="k">return</span> <span class="n">render_to_response</span><span class="p">(</span><span class="s">"foo.html"</span><span class="p">,</span> <span class="n">context_dict</span><span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from django.shortcuts import render_to_response
def foo(req):
return render_to_response("foo.html", context_dict)<PYGMENTS_RAW -->
The only thing you have to change is the import:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">django.contrib.jinja</span> <span class="k">import</span> <span class="n">render_to_response</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from django.contrib.jinja import render_to_response<PYGMENTS_RAW -->
Another change is that Jinja users a plain old dictionary instead of a Context instance. So there is no RequestContext. Just pass it a third parameter that points to the request object to get your context processors called.
What the jinja contrib module also provides is a `render_to_string` method that works like render_to_response, but returns a unicode object, a register object that you can use to register filters, objects and tests on the jinja environment. If you want to use some django filters that are not known to Jinja you can use the `convert_django_filter` function that returns a converted filter if you pass it a django one. The Jinja environment instance is available as "env" in that module too.
If you want to try it out right now you can check out the <a href="http://trac.pocoo.org/repos/jinja/branches/new-parser">new-parser</a> branch. Information about the usage of the django integration are so far only in the <a href="http://trac.pocoo.org/repos/jinja/branches/new-parser/jinja/contrib/djangosupport.py">module docstring</a>. Happy testing :-)Jinja 1.2 is about to be released, I just want to switch all the pocoo projects from subversion to mercurial first. One of the new features in Jinja 1.2 is the django support. Thanks to Bryan McLemore from curse for his contributions.
I refactored his code a bit so that it integrates a little nicer into django applications, the original code had some other names for functions and used idioms from curse that feel unnatural in django applications.
Basically to get started in Jinja 1.2 you have to do nothing more than adding the following thing into your urls.py file, right at the beginning:
That automatically configures Jinja for django and adds a virtual module called "django.contrib.jinja" that contains versions of the django shortcuts that work with Jinja. This module also provides the environment that is automatically set up based on your django configuration.
Basically if you have used in your views this code so far:
The only thing you have to change is the import:
Another change is that Jinja users a plain old dictionary instead of a Context instance. So there is no RequestContext. Just pass it a third parameter that points to the request object to get your context processors called.
What the jinja contrib module also provides is a `render_to_string` method that works like render_to_response, but returns a unicode object, a register object that you can use to register filters, objects and tests on the jinja environment. If you want to use some django filters that are not known to Jinja you can use the `convert_django_filter` function that returns a converted filter if you pass it a django one. The Jinja environment instance is available as "env" in that module too.
If you want to try it out right now you can check out the <a href="http://trac.pocoo.org/repos/jinja/branches/new-parser">new-parser</a> branch. Information about the usage of the django integration are so far only in the <a href="http://trac.pocoo.org/repos/jinja/branches/new-parser/jinja/contrib/djangosupport.py">module docstring</a>. Happy testing :-)SQAAAANTAAAABGJvZHlSUwAABudKaW5qYSAxLjIgaXMgYWJvdXQgdG8gYmUgcmVsZWFzZWQsIEkg
anVzdCB3YW50IHRvIHN3aXRjaCBhbGwgdGhlIHBvY29vIHByb2plY3RzIGZyb20gc3VidmVyc2lv
biB0byBtZXJjdXJpYWwgZmlyc3QuIE9uZSBvZiB0aGUgbmV3IGZlYXR1cmVzIGluIEppbmphIDEu
MiBpcyB0aGUgZGphbmdvIHN1cHBvcnQuIFRoYW5rcyB0byBCcnlhbiBNY0xlbW9yZSBmcm9tIGN1
cnNlIGZvciBoaXMgY29udHJpYnV0aW9ucy4KCkkgcmVmYWN0b3JlZCBoaXMgY29kZSBhIGJpdCBz
byB0aGF0IGl0IGludGVncmF0ZXMgYSBsaXR0bGUgbmljZXIgaW50byBkamFuZ28gYXBwbGljYXRp
b25zLCB0aGUgb3JpZ2luYWwgY29kZSBoYWQgc29tZSBvdGhlciBuYW1lcyBmb3IgZnVuY3Rpb25z
IGFuZCB1c2VkIGlkaW9tcyBmcm9tIGN1cnNlIHRoYXQgZmVlbCB1bm5hdHVyYWwgaW4gZGphbmdv
IGFwcGxpY2F0aW9ucy4KCkJhc2ljYWxseSB0byBnZXQgc3RhcnRlZCBpbiBKaW5qYSAxLjIgeW91
IGhhdmUgdG8gZG8gbm90aGluZyBtb3JlIHRoYW4gYWRkaW5nIHRoZSBmb2xsb3dpbmcgdGhpbmcg
aW50byB5b3VyIHVybHMucHkgZmlsZSwgcmlnaHQgYXQgdGhlIGJlZ2lubmluZzoKCgoKVGhhdCBh
dXRvbWF0aWNhbGx5IGNvbmZpZ3VyZXMgSmluamEgZm9yIGRqYW5nbyBhbmQgYWRkcyBhIHZpcnR1
YWwgbW9kdWxlIGNhbGxlZCAiZGphbmdvLmNvbnRyaWIuamluamEiIHRoYXQgY29udGFpbnMgdmVy
c2lvbnMgb2YgdGhlIGRqYW5nbyBzaG9ydGN1dHMgdGhhdCB3b3JrIHdpdGggSmluamEuIFRoaXMg
bW9kdWxlIGFsc28gcHJvdmlkZXMgdGhlIGVudmlyb25tZW50IHRoYXQgaXMgYXV0b21hdGljYWxs
eSBzZXQgdXAgYmFzZWQgb24geW91ciBkamFuZ28gY29uZmlndXJhdGlvbi4KCkJhc2ljYWxseSBp
ZiB5b3UgaGF2ZSB1c2VkIGluIHlvdXIgdmlld3MgdGhpcyBjb2RlIHNvIGZhcjoKClRoZSBvbmx5
IHRoaW5nIHlvdSBoYXZlIHRvIGNoYW5nZSBpcyB0aGUgaW1wb3J0OgoKCkFub3RoZXIgY2hhbmdl
IGlzIHRoYXQgSmluamEgdXNlcnMgYSBwbGFpbiBvbGQgZGljdGlvbmFyeSBpbnN0ZWFkIG9mIGEg
Q29udGV4dCBpbnN0YW5jZS4gU28gdGhlcmUgaXMgbm8gUmVxdWVzdENvbnRleHQuIEp1c3QgcGFz
cyBpdCBhIHRoaXJkIHBhcmFtZXRlciB0aGF0IHBvaW50cyB0byB0aGUgcmVxdWVzdCBvYmplY3Qg
dG8gZ2V0IHlvdXIgY29udGV4dCBwcm9jZXNzb3JzIGNhbGxlZC4KCldoYXQgdGhlIGppbmphIGNv
bnRyaWIgbW9kdWxlIGFsc28gcHJvdmlkZXMgaXMgYSBgcmVuZGVyX3RvX3N0cmluZ2AgbWV0aG9k
IHRoYXQgd29ya3MgbGlrZSByZW5kZXJfdG9fcmVzcG9uc2UsIGJ1dCByZXR1cm5zIGEgdW5pY29k
ZSBvYmplY3QsIGEgcmVnaXN0ZXIgb2JqZWN0IHRoYXQgeW91IGNhbiB1c2UgdG8gcmVnaXN0ZXIg
ZmlsdGVycywgb2JqZWN0cyBhbmQgdGVzdHMgb24gdGhlIGppbmphIGVudmlyb25tZW50LiBJZiB5
b3Ugd2FudCB0byB1c2Ugc29tZSBkamFuZ28gZmlsdGVycyB0aGF0IGFyZSBub3Qga25vd24gdG8g
SmluamEgeW91IGNhbiB1c2UgdGhlIGBjb252ZXJ0X2RqYW5nb19maWx0ZXJgIGZ1bmN0aW9uIHRo
YXQgcmV0dXJucyBhIGNvbnZlcnRlZCBmaWx0ZXIgaWYgeW91IHBhc3MgaXQgYSBkamFuZ28gb25l
LiBUaGUgSmluamEgZW52aXJvbm1lbnQgaW5zdGFuY2UgaXMgYXZhaWxhYmxlIGFzICJlbnYiIGlu
IHRoYXQgbW9kdWxlIHRvby4KCklmIHlvdSB3YW50IHRvIHRyeSBpdCBvdXQgcmlnaHQgbm93IHlv
dSBjYW4gY2hlY2sgb3V0IHRoZSBMAAJFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADVodHRwOi8v
dHJhYy5wb2Nvby5vcmcvcmVwb3MvamluamEvYnJhbmNoZXMvbmV3LXBhcnNlclMAAAAKbmV3LXBh
cnNlclMAAABWIGJyYW5jaC4gSW5mb3JtYXRpb24gYWJvdXQgdGhlIHVzYWdlIG9mIHRoZSBkamFu
Z28gaW50ZWdyYXRpb24gYXJlIHNvIGZhciBvbmx5IGluIHRoZSBFUwAAAAFhTAAATQABUwAAAARo
cmVmUwAAAFRodHRwOi8vdHJhYy5wb2Nvby5vcmcvcmVwb3MvamluamEvYnJhbmNoZXMvbmV3LXBh
cnNlci9qaW5qYS9jb250cmliL2RqYW5nb3N1cHBvcnQucHlTAAAAEG1vZHVsZSBkb2NzdHJpbmdT
AAAAEy4gSGFwcHkgdGVzdGluZyA6LSlTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAA
AABMAAA=
Billions and Billionshttp://lucumr.pocoo.org/cogitations/2007/09/05/billions-and-billions/2007-09-05T21:04:09Z2007-09-05T21:04:09ZArmin Ronacherbillions-and-billionsyesyes2<a href="http://www.comedycentral.com/motherload/player.jhtml?ml_video=91998&ml_collection=&ml_gateway=&ml_gateway_id=&ml_comedian=&ml_runtime=&ml_context=show&ml_origin_url=/shows/the_daily_show/videos/most_recent/index.jhtml%3Fstart%3D16&ml_playlist=&lnk=&is_large=true">The American Way to Restore The Balance of Power</a>.<a href="http://www.comedycentral.com/motherload/player.jhtml?ml_video=91998&ml_collection=&ml_gateway=&ml_gateway_id=&ml_comedian=&ml_runtime=&ml_context=show&ml_origin_url=/shows/the_daily_show/videos/most_recent/index.jhtml%3Fstart%3D16&ml_playlist=&lnk=&is_large=true">The American Way to Restore The Balance of Power</a>.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAQZodHRwOi8v
d3d3LmNvbWVkeWNlbnRyYWwuY29tL21vdGhlcmxvYWQvcGxheWVyLmpodG1sP21sX3ZpZGVvPTkx
OTk4Jm1sX2NvbGxlY3Rpb249Jm1sX2dhdGV3YXk9Jm1sX2dhdGV3YXlfaWQ9Jm1sX2NvbWVkaWFu
PSZtbF9ydW50aW1lPSZtbF9jb250ZXh0PXNob3cmbWxfb3JpZ2luX3VybD0vc2hvd3MvdGhlX2Rh
aWx5X3Nob3cvdmlkZW9zL21vc3RfcmVjZW50L2luZGV4LmpodG1sJTNGc3RhcnQlM0QxNiZtbF9w
bGF5bGlzdD0mbG5rPSZpc19sYXJnZT10cnVlUwAAADBUaGUgQW1lcmljYW4gV2F5IHRvIFJlc3Rv
cmUgVGhlIEJhbGFuY2Ugb2YgUG93ZXJTAAAAAS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50
cm9SUwAAAABMAAA=
Mad World Tabshttp://lucumr.pocoo.org/cogitations/2007/09/04/mad-world-tabs/2007-09-04T15:12:55Z2007-09-04T15:12:55ZArmin Ronachermad-world-tabsyesyes2When I was on holiday in Tuscany with my family we were there with a second family, that happened to be the family of my friend Lukas (<a href="http://lucumr.pocoo.org/static/pictures/orange_sky.png">the photographer of this picture</a>). I had my guitar with me and played some tunes down there. His sister Isabella asked me if I could play Mad World (Tears for Fears or Gary Jules, both versions are interesting). Unfortunately I had no tabs with me, nor was i able to find proper chords for the melody.
That weekend I invited my friends to my place and Isabella asked me once again if I could play that. Now I decided to play that but I wanted to experiment a little. So here the tabs I wrote for that song:
<pre>Mad World
=========
Tabbed by Armin Ronacher
Capo on first fret, standard tuning (E A D G B E)
Intro
|----7--------------------------|----7-----------------------------|
|------7p8-5p7------------------|------7p8-5p7-8p10-10-------------|
|--------------7p6----2-----2---|-------------------9-----2-----2--|
|------7--------------2-----2---|-------------------------2-----2--|
|--------------7---0-----0------|------7---------------0-----0-----|
|--0----------------------------|--0-------------------------------|
Verse Progression
|-------------------------------|-------------------------------|
|-------------------------------|-------------------------------|
|-------------------------------|-----1------1------1-------1---|
|-----2------2------0-------0---|-----0------0------1-------1---|
|-----2------2------0-------0---|----------------0------0-------|
|--0------0------3------3-------|--1------1---------------------|
Refrain
(3 times)
|----||-------------------|-----------------||
|----||:-----------2------|----2---2-------:||
|----||----0---0---2------|------2---0------||
|----||--2---2---0---2----|--2---------2----||
|----||:-2----------------|------------2---:||
|--0-||-------------------|-----------------||
|----7--------------------------|----7-----------------------------|
|------7p8-5p7------------------|------7p8-5p7-8p10-10-------------|
|--------------7p6----2-----2---|-------------------9-----2-----2--|
|------7--------------2-----2---|-------------------------2-----2--|
|--------------7---0-----0------|------7---------------0-----0-----|
|--0----------------------------|--0-------------------------------|</pre>
Please keep in mind that I'm very bad at tabbing (that's my first tab ever) and that I changed some harmonics a little bit. Makes it more interesting :-)
Maybe one finds it useful.When I was on holiday in Tuscany with my family we were there with a second family, that happened to be the family of my friend Lukas (<a href="http://lucumr.pocoo.org/static/pictures/orange_sky.png">the photographer of this picture</a>). I had my guitar with me and played some tunes down there. His sister Isabella asked me if I could play Mad World (Tears for Fears or Gary Jules, both versions are interesting). Unfortunately I had no tabs with me, nor was i able to find proper chords for the melody.
That weekend I invited my friends to my place and Isabella asked me once again if I could play that. Now I decided to play that but I wanted to experiment a little. So here the tabs I wrote for that song:
<pre>Mad World
=========
Tabbed by Armin Ronacher
Capo on first fret, standard tuning (E A D G B E)
Intro
|----7--------------------------|----7-----------------------------|
|------7p8-5p7------------------|------7p8-5p7-8p10-10-------------|
|--------------7p6----2-----2---|-------------------9-----2-----2--|
|------7--------------2-----2---|-------------------------2-----2--|
|--------------7---0-----0------|------7---------------0-----0-----|
|--0----------------------------|--0-------------------------------|
Verse Progression
|-------------------------------|-------------------------------|
|-------------------------------|-------------------------------|
|-------------------------------|-----1------1------1-------1---|
|-----2------2------0-------0---|-----0------0------1-------1---|
|-----2------2------0-------0---|----------------0------0-------|
|--0------0------3------3-------|--1------1---------------------|
Refrain
(3 times)
|----||-------------------|-----------------||
|----||:-----------2------|----2---2-------:||
|----||----0---0---2------|------2---0------||
|----||--2---2---0---2----|--2---------2----||
|----||:-2----------------|------------2---:||
|--0-||-------------------|-----------------||
|----7--------------------------|----7-----------------------------|
|------7p8-5p7------------------|------7p8-5p7-8p10-10-------------|
|--------------7p6----2-----2---|-------------------9-----2-----2--|
|------7--------------2-----2---|-------------------------2-----2--|
|--------------7---0-----0------|------7---------------0-----0-----|
|--0----------------------------|--0-------------------------------|</pre>
Please keep in mind that I'm very bad at tabbing (that's my first tab ever) and that I changed some harmonics a little bit. Makes it more interesting :-)
Maybe one finds it useful.SQAAAANTAAAABGJvZHlSUwAAAIdXaGVuIEkgd2FzIG9uIGhvbGlkYXkgaW4gVHVzY2FueSB3aXRo
IG15IGZhbWlseSB3ZSB3ZXJlIHRoZXJlIHdpdGggYSBzZWNvbmQgZmFtaWx5LCB0aGF0IGhhcHBl
bmVkIHRvIGJlIHRoZSBmYW1pbHkgb2YgbXkgZnJpZW5kIEx1a2FzIChMAAJFUwAAAAFhTAAATQAB
UwAAAARocmVmUwAAADZodHRwOi8vbHVjdW1yLnBvY29vLm9yZy9zdGF0aWMvcGljdHVyZXMvb3Jh
bmdlX3NreS5wbmdTAAAAIHRoZSBwaG90b2dyYXBoZXIgb2YgdGhpcyBwaWN0dXJlUwAAAd0pLiBJ
IGhhZCBteSBndWl0YXIgd2l0aCBtZSBhbmQgcGxheWVkIHNvbWUgdHVuZXMgZG93biB0aGVyZS4g
SGlzIHNpc3RlciBJc2FiZWxsYSBhc2tlZCBtZSBpZiBJIGNvdWxkIHBsYXkgTWFkIFdvcmxkIChU
ZWFycyBmb3IgRmVhcnMgb3IgR2FyeSBKdWxlcywgYm90aCB2ZXJzaW9ucyBhcmUgaW50ZXJlc3Rp
bmcpLiBVbmZvcnR1bmF0ZWx5IEkgaGFkIG5vIHRhYnMgd2l0aCBtZSwgbm9yIHdhcyBpIGFibGUg
dG8gZmluZCBwcm9wZXIgY2hvcmRzIGZvciB0aGUgbWVsb2R5LgoKVGhhdCB3ZWVrZW5kIEkgaW52
aXRlZCBteSBmcmllbmRzIHRvIG15IHBsYWNlIGFuZCBJc2FiZWxsYSBhc2tlZCBtZSBvbmNlIGFn
YWluIGlmIEkgY291bGQgcGxheSB0aGF0LiBOb3cgSSBkZWNpZGVkIHRvIHBsYXkgdGhhdCBidXQg
SSB3YW50ZWQgdG8gZXhwZXJpbWVudCBhIGxpdHRsZS4gU28gaGVyZSB0aGUgdGFicyBJIHdyb3Rl
IGZvciB0aGF0IHNvbmc6CgpFUwAAAANwcmVMAABNAABTAAAGlU1hZCBXb3JsZAo9PT09PT09PT0K
ClRhYmJlZCBieSBBcm1pbiBSb25hY2hlcgpDYXBvIG9uIGZpcnN0IGZyZXQsIHN0YW5kYXJkIHR1
bmluZyAoRSBBIEQgRyBCIEUpCgoKSW50cm8KCnwtLS0tNy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tfC0tLS03LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CnwtLS0tLS03cDgtNXA3LS0t
LS0tLS0tLS0tLS0tLS0tfC0tLS0tLTdwOC01cDctOHAxMC0xMC0tLS0tLS0tLS0tLS18CnwtLS0t
LS0tLS0tLS0tLTdwNi0tLS0yLS0tLS0yLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS05LS0tLS0yLS0t
LS0yLS18CnwtLS0tLS03LS0tLS0tLS0tLS0tLS0yLS0tLS0yLS0tfC0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0yLS0tLS0yLS18CnwtLS0tLS0tLS0tLS0tLTctLS0wLS0tLS0wLS0tLS0tfC0tLS0t
LTctLS0tLS0tLS0tLS0tLS0wLS0tLS0wLS0tLS18CnwtLTAtLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tfC0tMC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CgpWZXJzZSBQcm9ncmVz
c2lvbgoKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLXwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18
LS0tLS0xLS0tLS0tMS0tLS0tLTEtLS0tLS0tMS0tLXwKfC0tLS0tMi0tLS0tLTItLS0tLS0wLS0t
LS0tLTAtLS18LS0tLS0wLS0tLS0tMC0tLS0tLTEtLS0tLS0tMS0tLXwKfC0tLS0tMi0tLS0tLTIt
LS0tLS0wLS0tLS0tLTAtLS18LS0tLS0tLS0tLS0tLS0tLTAtLS0tLS0wLS0tLS0tLXwKfC0tMC0t
LS0tLTAtLS0tLS0zLS0tLS0tMy0tLS0tLS18LS0xLS0tLS0tMS0tLS0tLS0tLS0tLS0tLS0tLS0t
LXwKClJlZnJhaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMyB0aW1lcykK
fC0tLS18fC0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS18fAp8LS0tLXx8Oi0t
LS0tLS0tLS0tMi0tLS0tLXwtLS0tMi0tLTItLS0tLS0tOnx8CnwtLS0tfHwtLS0tMC0tLTAtLS0y
LS0tLS0tfC0tLS0tLTItLS0wLS0tLS0tfHwKfC0tLS18fC0tMi0tLTItLS0wLS0tMi0tLS18LS0y
LS0tLS0tLS0tMi0tLS18fAp8LS0tLXx8Oi0yLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0y
LS0tOnx8CnwtLTAtfHwtLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tfHwKCnwt
LS0tNy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS03LS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS18CnwtLS0tLS03cDgtNXA3LS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLTdwOC01cDct
OHAxMC0xMC0tLS0tLS0tLS0tLS18CnwtLS0tLS0tLS0tLS0tLTdwNi0tLS0yLS0tLS0yLS0tfC0t
LS0tLS0tLS0tLS0tLS0tLS05LS0tLS0yLS0tLS0yLS18CnwtLS0tLS03LS0tLS0tLS0tLS0tLS0y
LS0tLS0yLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0yLS0tLS0yLS18CnwtLS0tLS0tLS0t
LS0tLTctLS0wLS0tLS0wLS0tLS0tfC0tLS0tLTctLS0tLS0tLS0tLS0tLS0wLS0tLS0wLS0tLS18
CnwtLTAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tMC0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS18UwAAALcKClBsZWFzZSBrZWVwIGluIG1pbmQgdGhhdCBJJ20gdmVyeSBiYWQg
YXQgdGFiYmluZyAodGhhdCdzIG15IGZpcnN0IHRhYiBldmVyKSBhbmQgdGhhdCBJIGNoYW5nZWQg
c29tZSBoYXJtb25pY3MgYSBsaXR0bGUgYml0LiBNYWtlcyBpdCBtb3JlIGludGVyZXN0aW5nIDot
KQoKTWF5YmUgb25lIGZpbmRzIGl0IHVzZWZ1bC5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50
cm9SUwAAAABMAAA=
Screw You Applehttp://lucumr.pocoo.org/cogitations/2007/08/30/screw-you-apple/2007-08-30T08:01:03Z2007-08-30T08:01:03ZArmin Ronacherscrew-you-appleyesyes2I now have that notebook for less than one week in use. Now the enter key that looked wanky for the first few days stopped working completely (i assume they forgot about one of those rubber things) and the space bar and another key makes strange noises when in use a higher temperatures which that notebook reaches automatically. The even warn you to not use it on your lap, that could cause burnings.
But the best part about all that is the service. Or the not service. No idea how you call that. The only chance to fix that problem is going to a certified apple partner. I'm living in Hermagor, I city in the middle of nowhere so the next on is in either 200km or roughly 450km. Or I go to Italy where I get an Italian layout and have to pay some highway toll.
I'm seriously pissed. You pay more than 2000€ for something you have to pay some more money in order to get to a store that will fix your goddamn keyboard which already is crappy (see previous posts).I now have that notebook for less than one week in use. Now the enter key that looked wanky for the first few days stopped working completely (i assume they forgot about one of those rubber things) and the space bar and another key makes strange noises when in use a higher temperatures which that notebook reaches automatically. The even warn you to not use it on your lap, that could cause burnings.
But the best part about all that is the service. Or the not service. No idea how you call that. The only chance to fix that problem is going to a certified apple partner. I'm living in Hermagor, I city in the middle of nowhere so the next on is in either 200km or roughly 450km. Or I go to Italy where I get an Italian layout and have to pay some highway toll.
I'm seriously pissed. You pay more than 2000€ for something you have to pay some more money in order to get to a store that will fix your goddamn keyboard which already is crappy (see previous posts).SQAAAANTAAAABGJvZHlSUwAAA8dJIG5vdyBoYXZlIHRoYXQgbm90ZWJvb2sgZm9yIGxlc3MgdGhh
biBvbmUgd2VlayBpbiB1c2UuIE5vdyB0aGUgZW50ZXIga2V5IHRoYXQgbG9va2VkIHdhbmt5IGZv
ciB0aGUgZmlyc3QgZmV3IGRheXMgc3RvcHBlZCB3b3JraW5nIGNvbXBsZXRlbHkgKGkgYXNzdW1l
IHRoZXkgZm9yZ290IGFib3V0IG9uZSBvZiB0aG9zZSBydWJiZXIgdGhpbmdzKSBhbmQgdGhlIHNw
YWNlIGJhciBhbmQgYW5vdGhlciBrZXkgbWFrZXMgc3RyYW5nZSBub2lzZXMgd2hlbiBpbiB1c2Ug
YSBoaWdoZXIgdGVtcGVyYXR1cmVzIHdoaWNoIHRoYXQgbm90ZWJvb2sgcmVhY2hlcyBhdXRvbWF0
aWNhbGx5LiBUaGUgZXZlbiB3YXJuIHlvdSB0byBub3QgdXNlIGl0IG9uIHlvdXIgbGFwLCB0aGF0
IGNvdWxkIGNhdXNlIGJ1cm5pbmdzLgoKQnV0IHRoZSBiZXN0IHBhcnQgYWJvdXQgYWxsIHRoYXQg
aXMgdGhlIHNlcnZpY2UuIE9yIHRoZSBub3Qgc2VydmljZS4gTm8gaWRlYSBob3cgeW91IGNhbGwg
dGhhdC4gVGhlIG9ubHkgY2hhbmNlIHRvIGZpeCB0aGF0IHByb2JsZW0gaXMgZ29pbmcgdG8gYSBj
ZXJ0aWZpZWQgYXBwbGUgcGFydG5lci4gSSdtIGxpdmluZyBpbiBIZXJtYWdvciwgSSBjaXR5IGlu
IHRoZSBtaWRkbGUgb2Ygbm93aGVyZSBzbyB0aGUgbmV4dCBvbiBpcyBpbiBlaXRoZXIgMjAwa20g
b3Igcm91Z2hseSA0NTBrbS4gT3IgSSBnbyB0byBJdGFseSB3aGVyZSBJIGdldCBhbiBJdGFsaWFu
IGxheW91dCBhbmQgaGF2ZSB0byBwYXkgc29tZSBoaWdod2F5IHRvbGwuCgpJJ20gc2VyaW91c2x5
IHBpc3NlZC4gWW91IHBheSBtb3JlIHRoYW4gMjAwMOKCrCBmb3Igc29tZXRoaW5nIHlvdSBoYXZl
IHRvIHBheSBzb21lIG1vcmUgbW9uZXkgaW4gb3JkZXIgdG8gZ2V0IHRvIGEgc3RvcmUgdGhhdCB3
aWxsIGZpeCB5b3VyIGdvZGRhbW4ga2V5Ym9hcmQgd2hpY2ggYWxyZWFkeSBpcyBjcmFwcHkgKHNl
ZSBwcmV2aW91cyBwb3N0cykuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAA
TAAA
Font Renderinghttp://lucumr.pocoo.org/cogitations/2007/08/29/font-rendering/2007-08-29T16:59:06Z2007-08-29T16:59:06ZArmin Ronacherfont-renderingyesyes2The font rendering debate will never change. I'm pretty darn sure. But at least for me the font rendering results I got on ubuntu with a patched freetype was a lot better than the results I have to look at on my new macbook. Both are in my opinion better than the results you get on Windows XP, but with some ClearType customizing you can improve the Windows Rendering too.
But just to show what I mean, here two screenshots: This is what a typical TextPress post looks like on my ubuntu installation: <a href="http://pocoo.org/~mitsuhiko/textpress_blog.png">textpress on ubuntu</a>
And this is what it looks like on OS X: <a href="http://pocoo.org/~mitsuhiko/textpress_alpha3.png">textpress on OS X</a>
Maybe it's just me, but I like the ubuntu one a lot more. Anyone an idea of how to get the Mac version look less blurry?The font rendering debate will never change. I'm pretty darn sure. But at least for me the font rendering results I got on ubuntu with a patched freetype was a lot better than the results I have to look at on my new macbook. Both are in my opinion better than the results you get on Windows XP, but with some ClearType customizing you can improve the Windows Rendering too.
But just to show what I mean, here two screenshots: This is what a typical TextPress post looks like on my ubuntu installation: <a href="http://pocoo.org/~mitsuhiko/textpress_blog.png">textpress on ubuntu</a>
And this is what it looks like on OS X: <a href="http://pocoo.org/~mitsuhiko/textpress_alpha3.png">textpress on OS X</a>
Maybe it's just me, but I like the ubuntu one a lot more. Anyone an idea of how to get the Mac version look less blurry?SQAAAANTAAAABGJvZHlSUwAAAfdUaGUgZm9udCByZW5kZXJpbmcgZGViYXRlIHdpbGwgbmV2ZXIg
Y2hhbmdlLiBJJ20gcHJldHR5IGRhcm4gc3VyZS4gQnV0IGF0IGxlYXN0IGZvciBtZSB0aGUgZm9u
dCByZW5kZXJpbmcgcmVzdWx0cyBJIGdvdCBvbiB1YnVudHUgd2l0aCBhIHBhdGNoZWQgZnJlZXR5
cGUgd2FzIGEgbG90IGJldHRlciB0aGFuIHRoZSByZXN1bHRzIEkgaGF2ZSB0byBsb29rIGF0IG9u
IG15IG5ldyBtYWNib29rLiBCb3RoIGFyZSBpbiBteSBvcGluaW9uIGJldHRlciB0aGFuIHRoZSBy
ZXN1bHRzIHlvdSBnZXQgb24gV2luZG93cyBYUCwgYnV0IHdpdGggc29tZSBDbGVhclR5cGUgY3Vz
dG9taXppbmcgeW91IGNhbiBpbXByb3ZlIHRoZSBXaW5kb3dzIFJlbmRlcmluZyB0b28uCgpCdXQg
anVzdCB0byBzaG93IHdoYXQgSSBtZWFuLCBoZXJlIHR3byBzY3JlZW5zaG90czogVGhpcyBpcyB3
aGF0IGEgdHlwaWNhbCBUZXh0UHJlc3MgcG9zdCBsb29rcyBsaWtlIG9uIG15IHVidW50dSBpbnN0
YWxsYXRpb246IEwAAkVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAALmh0dHA6Ly9wb2Nvby5vcmcv
fm1pdHN1aGlrby90ZXh0cHJlc3NfYmxvZy5wbmdTAAAAE3RleHRwcmVzcyBvbiB1YnVudHVTAAAA
KQpBbmQgdGhpcyBpcyB3aGF0IGl0IGxvb2tzIGxpa2Ugb24gT1MgWDogRVMAAAABYUwAAE0AAVMA
AAAEaHJlZlMAAAAwaHR0cDovL3BvY29vLm9yZy9+bWl0c3VoaWtvL3RleHRwcmVzc19hbHBoYTMu
cG5nUwAAABF0ZXh0cHJlc3Mgb24gT1MgWFMAAAB6CgpNYXliZSBpdCdzIGp1c3QgbWUsIGJ1dCBJ
IGxpa2UgdGhlIHVidW50dSBvbmUgYSBsb3QgbW9yZS4gQW55b25lIGFuIGlkZWEgb2YgaG93IHRv
IGdldCB0aGUgTWFjIHZlcnNpb24gbG9vayBsZXNzIGJsdXJyeT9TAAAABnBhcnNlclMAAAAEaHRt
bFMAAAAFaW50cm9SUwAAAABMAAA=
Alexander Solovyovpiranha@piranha.org.uahttp://piranha.org.ua2007-08-30T06:07:43Znono0+1, I don't like Mac OS X font anti-aliasing at all and it looks for me like winxp.+1, I don't like Mac OS X font anti-aliasing at all and it looks for me like winxp.SQAAAAJTAAAABGJvZHlSUwAAAFMrMSwgSSBkb24ndCBsaWtlIE1hYyBPUyBYIGZvbnQgYW50aS1h
bGlhc2luZyBhdCBhbGwgYW5kIGl0IGxvb2tzIGZvciBtZSBsaWtlIHdpbnhwLkwAAFMAAAAGcGFy
c2VyUwAAAARodG1s
Jono’s Jackethttp://lucumr.pocoo.org/cogitations/2007/08/28/jonos-jacket/2007-08-28T20:56:16Z2007-08-28T20:56:16ZArmin Ronacherjonos-jacketyesyes2<a href="http://www.jonobacon.org/?p=1016">Jono's jacket returns</a>. That's a cool story.<a href="http://www.jonobacon.org/?p=1016">Jono's jacket returns</a>. That's a cool story.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACBodHRwOi8v
d3d3Lmpvbm9iYWNvbi5vcmcvP3A9MTAxNlMAAAAVSm9ubydzIGphY2tldCByZXR1cm5zUwAAABYu
IFRoYXQncyBhIGNvb2wgc3RvcnkuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAA
TAAA
Keyboard Woeshttp://lucumr.pocoo.org/cogitations/2007/08/28/keyboard-woes/2007-08-27T22:02:21Z2007-08-27T22:02:21ZArmin Ronacherkeyboard-woesyesyes2Day with the Mac the second. Mouse still accelerating but i found out that there is a application that hooks into the HID thingy and repositions the mouse. Too hackish imho, i will live with the acceleration.
But the keyboard layout still kills me. Who ever created the German keyboard layout should be waterboarded. The situation is not a problem for english keyboards i suppose, there you don't have an alt gr key which can get lost from windows/linux to mac os x :) The best solution i found so far is changing the alt mappings to the windows alt gr mappings using a custom keyboard layout created with <a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=ukelele">ukelele</a> and map the return key to alt using <a href="http://doublecommand.sourceforge.net/">doublecommand</a>. This doesn't give the best feeling but i can live with it for the moment. Later i guess i will use an US layout for development in os x.
So please dear apple guys: either remove the goddamn limitation that the right apple key is linked to the left one or add an alt gr key for future macbooks. The current keyboard situation is just crap.Day with the Mac the second. Mouse still accelerating but i found out that there is a application that hooks into the HID thingy and repositions the mouse. Too hackish imho, i will live with the acceleration.
But the keyboard layout still kills me. Who ever created the German keyboard layout should be waterboarded. The situation is not a problem for english keyboards i suppose, there you don't have an alt gr key which can get lost from windows/linux to mac os x :) The best solution i found so far is changing the alt mappings to the windows alt gr mappings using a custom keyboard layout created with <a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=ukelele">ukelele</a> and map the return key to alt using <a href="http://doublecommand.sourceforge.net/">doublecommand</a>. This doesn't give the best feeling but i can live with it for the moment. Later i guess i will use an US layout for development in os x.
So please dear apple guys: either remove the goddamn limitation that the right apple key is linked to the left one or add an alt gr key for future macbooks. The current keyboard situation is just crap.SQAAAANTAAAABGJvZHlSUwAAAl9EYXkgd2l0aCB0aGUgTWFjIHRoZSBzZWNvbmQuIE1vdXNlIHN0
aWxsIGFjY2VsZXJhdGluZyBidXQgaSBmb3VuZCBvdXQgdGhhdCB0aGVyZSBpcyBhIGFwcGxpY2F0
aW9uIHRoYXQgaG9va3MgaW50byB0aGUgSElEIHRoaW5neSBhbmQgcmVwb3NpdGlvbnMgdGhlIG1v
dXNlLiBUb28gaGFja2lzaCBpbWhvLCBpIHdpbGwgbGl2ZSB3aXRoIHRoZSBhY2NlbGVyYXRpb24u
CgpCdXQgdGhlIGtleWJvYXJkIGxheW91dCBzdGlsbCBraWxscyBtZS4gV2hvIGV2ZXIgY3JlYXRl
ZCB0aGUgR2VybWFuIGtleWJvYXJkIGxheW91dCBzaG91bGQgYmUgd2F0ZXJib2FyZGVkLiBUaGUg
c2l0dWF0aW9uIGlzIG5vdCBhIHByb2JsZW0gZm9yIGVuZ2xpc2gga2V5Ym9hcmRzIGkgc3VwcG9z
ZSwgdGhlcmUgeW91IGRvbid0IGhhdmUgYW4gYWx0IGdyIGtleSB3aGljaCBjYW4gZ2V0IGxvc3Qg
ZnJvbSB3aW5kb3dzL2xpbnV4IHRvIG1hYyBvcyB4IDopIFRoZSBiZXN0IHNvbHV0aW9uIGkgZm91
bmQgc28gZmFyIGlzIGNoYW5naW5nIHRoZSBhbHQgbWFwcGluZ3MgdG8gdGhlIHdpbmRvd3MgYWx0
IGdyIG1hcHBpbmdzIHVzaW5nIGEgY3VzdG9tIGtleWJvYXJkIGxheW91dCBjcmVhdGVkIHdpdGgg
TAACRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAABIaHR0cDovL3NjcmlwdHMuc2lsLm9yZy9jbXMv
c2NyaXB0cy9wYWdlLnBocD9zaXRlX2lkPW5yc2kmaXRlbV9pZD11a2VsZWxlUwAAAAd1a2VsZWxl
UwAAACUgYW5kIG1hcCB0aGUgcmV0dXJuIGtleSB0byBhbHQgdXNpbmcgRVMAAAABYUwAAE0AAVMA
AAAEaHJlZlMAAAAlaHR0cDovL2RvdWJsZWNvbW1hbmQuc291cmNlZm9yZ2UubmV0L1MAAAANZG91
YmxlY29tbWFuZFMAAAFVLiBUaGlzIGRvZXNuJ3QgZ2l2ZSB0aGUgYmVzdCBmZWVsaW5nIGJ1dCBp
IGNhbiBsaXZlIHdpdGggaXQgZm9yIHRoZSBtb21lbnQuIExhdGVyIGkgZ3Vlc3MgaSB3aWxsIHVz
ZSBhbiBVUyBsYXlvdXQgZm9yIGRldmVsb3BtZW50IGluIG9zIHguCgpTbyBwbGVhc2UgZGVhciBh
cHBsZSBndXlzOiBlaXRoZXIgcmVtb3ZlIHRoZSBnb2RkYW1uIGxpbWl0YXRpb24gdGhhdCB0aGUg
cmlnaHQgYXBwbGUga2V5IGlzIGxpbmtlZCB0byB0aGUgbGVmdCBvbmUgb3IgYWRkIGFuIGFsdCBn
ciBrZXkgZm9yIGZ1dHVyZSBtYWNib29rcy4gVGhlIGN1cnJlbnQga2V5Ym9hcmQgc2l0dWF0aW9u
IGlzIGp1c3QgY3JhcC5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
twiggygustafsson.g@gmail.com2007-10-23T20:36:31Znono0First i thought this was just a little bit odd but now i'm just pissed about it since i can't even type in a damn pipe in the terminal (atleast i don't know yet)First i thought this was just a little bit odd but now i'm just pissed about it since i can't even type in a damn pipe in the terminal (atleast i don't know yet)SQAAAAJTAAAABGJvZHlSUwAAAKFGaXJzdCBpIHRob3VnaHQgdGhpcyB3YXMganVzdCBhIGxpdHRs
ZSBiaXQgb2RkIGJ1dCBub3cgaSdtIGp1c3QgcGlzc2VkIGFib3V0IGl0IHNpbmNlIGkgY2FuJ3Qg
ZXZlbiB0eXBlIGluIGEgZGFtbiBwaXBlIGluIHRoZSB0ZXJtaW5hbCAoYXRsZWFzdCBpIGRvbid0
IGtub3cgeWV0KUwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Mac Pro and Conshttp://lucumr.pocoo.org/cogitations/2007/08/26/mac-pro-and-cons/2007-08-26T13:26:35Z2007-08-26T13:26:35ZArmin Ronachermac-pro-and-consyesyes2So time or the first "switch to mac summary". Expect more later.
So far things i like:
<ul>
<li>UNIX</li>
<li>awesome design</li>
<li>the hardware looks solid</li>
<li>the screen is pretty bright and non glossy!</li>
<li>nice internals, big memory</li>
<li>bootcamp</li>
</ul>
Things i don't like
<ul>
<li>Finder, hmmmm. I want Konqueror</li>
<li>Keyboard, Mouse and Internationalization settings, hmmm. I want my GNOME</li>
<li>terminal. Even with iterm the keybindings have crazy bad defaults. I want my linux and keyboard</li>
<li>where in gods name is alt gr?</li>
<li>completely different shortcuts etc.</li>
<li>nearly impossible to use the german keyboard layout for development, i guess i have to use an UK layout</li>
<li>Development, i want my apt-get</li>
</ul>
Guess i'll switch to ubuntu again for most of my development purposes, especially because i found a keyboard mapping so that the keyboard behaves like an ordinary QWERTZ one.So time or the first "switch to mac summary". Expect more later.
So far things i like:
<ul>
<li>UNIX</li>
<li>awesome design</li>
<li>the hardware looks solid</li>
<li>the screen is pretty bright and non glossy!</li>
<li>nice internals, big memory</li>
<li>bootcamp</li>
</ul>
Things i don't like
<ul>
<li>Finder, hmmmm. I want Konqueror</li>
<li>Keyboard, Mouse and Internationalization settings, hmmm. I want my GNOME</li>
<li>terminal. Even with iterm the keybindings have crazy bad defaults. I want my linux and keyboard</li>
<li>where in gods name is alt gr?</li>
<li>completely different shortcuts etc.</li>
<li>nearly impossible to use the german keyboard layout for development, i guess i have to use an UK layout</li>
<li>Development, i want my apt-get</li>
</ul>
Guess i'll switch to ubuntu again for most of my development purposes, especially because i found a keyboard mapping so that the keyboard behaves like an ordinary QWERTZ one.SQAAAANTAAAABGJvZHlSUwAAAFhTbyB0aW1lIG9yIHRoZSBmaXJzdCAic3dpdGNoIHRvIG1hYyBz
dW1tYXJ5Ii4gRXhwZWN0IG1vcmUgbGF0ZXIuCgpTbyBmYXIgdGhpbmdzIGkgbGlrZToKTAACRVMA
AAACdWxMAAZFUwAAAAJsaUwAAE0AAFMAAAAEVU5JWFMAAAADCiAgRVMAAAACbGlMAABNAABTAAAA
DmF3ZXNvbWUgZGVzaWduUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAAYdGhlIGhhcmR3YXJlIGxv
b2tzIHNvbGlkUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAArdGhlIHNjcmVlbiBpcyBwcmV0dHkg
YnJpZ2h0IGFuZCBub24gZ2xvc3N5IVMAAAADCiAgRVMAAAACbGlMAABNAABTAAAAGm5pY2UgaW50
ZXJuYWxzLCBiaWcgbWVtb3J5UwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAAIYm9vdGNhbXBTAAAA
AQpNAABTAAAAAwogIFMAAAAWCgpUaGluZ3MgaSBkb24ndCBsaWtlCkVTAAAAAnVsTAAHRVMAAAAC
bGlMAABNAABTAAAAH0ZpbmRlciwgaG1tbW0uIEkgd2FudCBLb25xdWVyb3JTAAAAAwogIEVTAAAA
AmxpTAAATQAAUwAAAEhLZXlib2FyZCwgTW91c2UgYW5kIEludGVybmF0aW9uYWxpemF0aW9uIHNl
dHRpbmdzLCBobW1tLiBJIHdhbnQgbXkgR05PTUVTAAAAAwogIEVTAAAAAmxpTAAATQAAUwAAAF90
ZXJtaW5hbC4gRXZlbiB3aXRoIGl0ZXJtIHRoZSBrZXliaW5kaW5ncyBoYXZlIGNyYXp5IGJhZCBk
ZWZhdWx0cy4gSSB3YW50IG15IGxpbnV4IGFuZCBrZXlib2FyZFMAAAADCiAgRVMAAAACbGlMAABN
AABTAAAAHXdoZXJlIGluIGdvZHMgbmFtZSBpcyBhbHQgZ3I/UwAAAAMKICBFUwAAAAJsaUwAAE0A
AFMAAAAjY29tcGxldGVseSBkaWZmZXJlbnQgc2hvcnRjdXRzIGV0Yy5TAAAAAwogIEVTAAAAAmxp
TAAATQAAUwAAAGduZWFybHkgaW1wb3NzaWJsZSB0byB1c2UgdGhlIGdlcm1hbiBrZXlib2FyZCBs
YXlvdXQgZm9yIGRldmVsb3BtZW50LCBpIGd1ZXNzIGkgaGF2ZSB0byB1c2UgYW4gVUsgbGF5b3V0
UwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAAAeRGV2ZWxvcG1lbnQsIGkgd2FudCBteSBhcHQtZ2V0
UwAAAAEKTQAAUwAAAAMKICBTAAAAsAoKR3Vlc3MgaSdsbCBzd2l0Y2ggdG8gdWJ1bnR1IGFnYWlu
IGZvciBtb3N0IG9mIG15IGRldmVsb3BtZW50IHB1cnBvc2VzLCBlc3BlY2lhbGx5IGJlY2F1c2Ug
aSBmb3VuZCBhIGtleWJvYXJkIG1hcHBpbmcgc28gdGhhdCB0aGUga2V5Ym9hcmQgYmVoYXZlcyBs
aWtlIGFuIG9yZGluYXJ5IFFXRVJUWiBvbmUuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJv
UlMAAAAATAAA
EnTeQuAkcg@webshox.orghttp://webshox.org2007-08-30T12:09:09Znono0"where in gods name is alt gr?"
Maybe you can use strg+alt instead? (don't know if it's also on the mac keyboard as on a english one)
But by the way it would be intresting whitch MacBook did you buy?
Best regards,
Christopher Grebs"where in gods name is alt gr?"
Maybe you can use strg+alt instead? (don't know if it's also on the mac keyboard as on a english one)
But by the way it would be intresting whitch MacBook did you buy?
Best regards,
Christopher GrebsSQAAAAJTAAAABGJvZHlSUwAAAOoid2hlcmUgaW4gZ29kcyBuYW1lIGlzIGFsdCBncj8iCgpNYXli
ZSB5b3UgY2FuIHVzZSBzdHJnK2FsdCBpbnN0ZWFkPyAoZG9uJ3Qga25vdyBpZiBpdCdzIGFsc28g
b24gdGhlIG1hYyBrZXlib2FyZCBhcyBvbiBhIGVuZ2xpc2ggb25lKQoKQnV0IGJ5IHRoZSB3YXkg
aXQgd291bGQgYmUgaW50cmVzdGluZyB3aGl0Y2ggTWFjQm9vayBkaWQgeW91IGJ1eT8KCkJlc3Qg
cmVnYXJkcywKQ2hyaXN0b3BoZXIgR3JlYnNMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-09-04T15:16:47Znono0No, the mapping is completely different. And before I write a keyboard layout that maps ctrl+alt something, I better map alt something.No, the mapping is completely different. And before I write a keyboard layout that maps ctrl+alt something, I better map alt something.SQAAAAJTAAAABGJvZHlSUwAAAIdObywgdGhlIG1hcHBpbmcgaXMgY29tcGxldGVseSBkaWZmZXJl
bnQuIEFuZCBiZWZvcmUgSSB3cml0ZSBhIGtleWJvYXJkIGxheW91dCB0aGF0IG1hcHMgY3RybCth
bHQgc29tZXRoaW5nLCBJIGJldHRlciBtYXAgYWx0IHNvbWV0aGluZy5MAABTAAAABnBhcnNlclMA
AAAEaHRtbA==
Macbook Prohttp://lucumr.pocoo.org/cogitations/2007/08/26/macbook-pro/2007-08-25T22:35:27Z2007-08-25T22:35:27ZArmin Ronachermacbook-proyesyes2Since today I'm a proud owner of an Apple Macbook Pro. Well. Proud and annoyed at the same time. I was aware that switching over to a Macbook would take me some time but It's a whole lot harder than imagined. The hardest part is that the keyboard layout is totally different. And even if some of the keys work the same (normal letters) you still have the problem that all keyboard shortcuts are different. One the one hand because you have to use the apple sign where you would expect the control key if you're used to linux.
The keyboard is definitively the worst part of the Macbook Pro. It's missing a delete key and the alt gr key which you usually find on German keyboards. The Alt Gr key replaces the normal second alt key so that you can enter some of the symbols you use in programming languages (square brackets, or even the simple at sign). On German keyboards the "[" sign is on alt gr + 7. On a german macbook pro it's on alt + 5 and not even displayed on the keyboard. While this is probably not a problem on OS X it will become a problem as soon as you try to install ubuntu on that machine.
But the keyboard is not the only annoyance. The mouse isn't much better. I'm used to have acceleration on touchpads, but not on normal mouses. But on OS X there is no way to make the mouse movement linear, at least not a non hackish way.
Also the way windows are managed is totally new to me. I would expect that the maximize button maximizes the window. But it just makes it a bit bigger, as big as the window manager thinks it shoud be?
So far I don't think I will install ubuntu right now, i have to much problems getting into OS X. And the problems i would have with a German mac keyboard on a linux machine are too much right now :-(
<small>BTW: I'm back from Italy</small>Since today I'm a proud owner of an Apple Macbook Pro. Well. Proud and annoyed at the same time. I was aware that switching over to a Macbook would take me some time but It's a whole lot harder than imagined. The hardest part is that the keyboard layout is totally different. And even if some of the keys work the same (normal letters) you still have the problem that all keyboard shortcuts are different. One the one hand because you have to use the apple sign where you would expect the control key if you're used to linux.
The keyboard is definitively the worst part of the Macbook Pro. It's missing a delete key and the alt gr key which you usually find on German keyboards. The Alt Gr key replaces the normal second alt key so that you can enter some of the symbols you use in programming languages (square brackets, or even the simple at sign). On German keyboards the "[" sign is on alt gr + 7. On a german macbook pro it's on alt + 5 and not even displayed on the keyboard. While this is probably not a problem on OS X it will become a problem as soon as you try to install ubuntu on that machine.
But the keyboard is not the only annoyance. The mouse isn't much better. I'm used to have acceleration on touchpads, but not on normal mouses. But on OS X there is no way to make the mouse movement linear, at least not a non hackish way.
Also the way windows are managed is totally new to me. I would expect that the maximize button maximizes the window. But it just makes it a bit bigger, as big as the window manager thinks it shoud be?
So far I don't think I will install ubuntu right now, i have to much problems getting into OS X. And the problems i would have with a German mac keyboard on a linux machine are too much right now :-(
<small>BTW: I'm back from Italy</small>SQAAAANTAAAABGJvZHlSUwAABtZTaW5jZSB0b2RheSBJJ20gYSBwcm91ZCBvd25lciBvZiBhbiBB
cHBsZSBNYWNib29rIFByby4gV2VsbC4gUHJvdWQgYW5kIGFubm95ZWQgYXQgdGhlIHNhbWUgdGlt
ZS4gSSB3YXMgYXdhcmUgdGhhdCBzd2l0Y2hpbmcgb3ZlciB0byBhIE1hY2Jvb2sgd291bGQgdGFr
ZSBtZSBzb21lIHRpbWUgYnV0IEl0J3MgYSB3aG9sZSBsb3QgaGFyZGVyIHRoYW4gaW1hZ2luZWQu
IFRoZSBoYXJkZXN0IHBhcnQgaXMgdGhhdCB0aGUga2V5Ym9hcmQgbGF5b3V0IGlzIHRvdGFsbHkg
ZGlmZmVyZW50LiBBbmQgZXZlbiBpZiBzb21lIG9mIHRoZSBrZXlzIHdvcmsgdGhlIHNhbWUgKG5v
cm1hbCBsZXR0ZXJzKSB5b3Ugc3RpbGwgaGF2ZSB0aGUgcHJvYmxlbSB0aGF0IGFsbCBrZXlib2Fy
ZCBzaG9ydGN1dHMgYXJlIGRpZmZlcmVudC4gT25lIHRoZSBvbmUgaGFuZCBiZWNhdXNlIHlvdSBo
YXZlIHRvIHVzZSB0aGUgYXBwbGUgc2lnbiB3aGVyZSB5b3Ugd291bGQgZXhwZWN0IHRoZSBjb250
cm9sIGtleSBpZiB5b3UncmUgdXNlZCB0byBsaW51eC4KClRoZSBrZXlib2FyZCBpcyBkZWZpbml0
aXZlbHkgdGhlIHdvcnN0IHBhcnQgb2YgdGhlIE1hY2Jvb2sgUHJvLiBJdCdzIG1pc3NpbmcgYSBk
ZWxldGUga2V5IGFuZCB0aGUgYWx0IGdyIGtleSB3aGljaCB5b3UgdXN1YWxseSBmaW5kIG9uIEdl
cm1hbiBrZXlib2FyZHMuIFRoZSBBbHQgR3Iga2V5IHJlcGxhY2VzIHRoZSBub3JtYWwgc2Vjb25k
IGFsdCBrZXkgc28gdGhhdCB5b3UgY2FuIGVudGVyIHNvbWUgb2YgdGhlIHN5bWJvbHMgeW91IHVz
ZSBpbiBwcm9ncmFtbWluZyBsYW5ndWFnZXMgKHNxdWFyZSBicmFja2V0cywgb3IgZXZlbiB0aGUg
c2ltcGxlIGF0IHNpZ24pLiBPbiBHZXJtYW4ga2V5Ym9hcmRzIHRoZSAiWyIgc2lnbiBpcyBvbiBh
bHQgZ3IgKyA3LiBPbiBhIGdlcm1hbiBtYWNib29rIHBybyBpdCdzIG9uIGFsdCArIDUgYW5kIG5v
dCBldmVuIGRpc3BsYXllZCBvbiB0aGUga2V5Ym9hcmQuIFdoaWxlIHRoaXMgaXMgcHJvYmFibHkg
bm90IGEgcHJvYmxlbSBvbiBPUyBYIGl0IHdpbGwgYmVjb21lIGEgcHJvYmxlbSBhcyBzb29uIGFz
IHlvdSB0cnkgdG8gaW5zdGFsbCB1YnVudHUgb24gdGhhdCBtYWNoaW5lLgoKQnV0IHRoZSBrZXli
b2FyZCBpcyBub3QgdGhlIG9ubHkgYW5ub3lhbmNlLiBUaGUgbW91c2UgaXNuJ3QgbXVjaCBiZXR0
ZXIuIEknbSB1c2VkIHRvIGhhdmUgYWNjZWxlcmF0aW9uIG9uIHRvdWNocGFkcywgYnV0IG5vdCBv
biBub3JtYWwgbW91c2VzLiBCdXQgb24gT1MgWCB0aGVyZSBpcyBubyB3YXkgdG8gbWFrZSB0aGUg
bW91c2UgbW92ZW1lbnQgbGluZWFyLCBhdCBsZWFzdCBub3QgYSBub24gaGFja2lzaCB3YXkuCgpB
bHNvIHRoZSB3YXkgd2luZG93cyBhcmUgbWFuYWdlZCBpcyB0b3RhbGx5IG5ldyB0byBtZS4gSSB3
b3VsZCBleHBlY3QgdGhhdCB0aGUgbWF4aW1pemUgYnV0dG9uIG1heGltaXplcyB0aGUgd2luZG93
LiBCdXQgaXQganVzdCBtYWtlcyBpdCBhIGJpdCBiaWdnZXIsIGFzIGJpZyBhcyB0aGUgd2luZG93
IG1hbmFnZXIgdGhpbmtzIGl0IHNob3VkIGJlPwoKU28gZmFyIEkgZG9uJ3QgdGhpbmsgSSB3aWxs
IGluc3RhbGwgdWJ1bnR1IHJpZ2h0IG5vdywgaSBoYXZlIHRvIG11Y2ggcHJvYmxlbXMgZ2V0dGlu
ZyBpbnRvIE9TIFguIEFuZCB0aGUgcHJvYmxlbXMgaSB3b3VsZCBoYXZlIHdpdGggYSBHZXJtYW4g
bWFjIGtleWJvYXJkIG9uIGEgbGludXggbWFjaGluZSBhcmUgdG9vIG11Y2ggcmlnaHQgbm93IDot
KAoKTAABRVMAAAAFc21hbGxMAABNAABTAAAAGEJUVzogSSdtIGJhY2sgZnJvbSBJdGFseVMAAAAA
UwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Two Weeks Holidayshttp://lucumr.pocoo.org/cogitations/2007/08/10/two-weeks-holidays/2007-08-10T20:53:53Z2007-08-10T20:53:53ZArmin Ronachertwo-weeks-holidaysyesyes2Okay. I'm off to Italy for two weeks now. I will be offline most of the time but constantly check my emails, so if there is anything important just mail me. I'm back on Saturday the 25th of August.Okay. I'm off to Italy for two weeks now. I will be offline most of the time but constantly check my emails, so if there is anything important just mail me. I'm back on Saturday the 25th of August.SQAAAANTAAAABGJvZHlSUwAAAMVPa2F5LiBJJ20gb2ZmIHRvIEl0YWx5IGZvciB0d28gd2Vla3Mg
bm93LiBJIHdpbGwgYmUgb2ZmbGluZSBtb3N0IG9mIHRoZSB0aW1lIGJ1dCBjb25zdGFudGx5IGNo
ZWNrIG15IGVtYWlscywgc28gaWYgdGhlcmUgaXMgYW55dGhpbmcgaW1wb3J0YW50IGp1c3QgbWFp
bCBtZS4gSSdtIGJhY2sgb24gU2F0dXJkYXkgdGhlIDI1dGggb2YgQXVndXN0LkwAAFMAAAAGcGFy
c2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Industry Versus Common Sensehttp://lucumr.pocoo.org/cogitations/2007/08/10/industry-versus-common-sense/2007-08-09T22:00:09Z2007-08-09T22:00:09ZArmin Ronacherindustry-versus-common-senseyesyes2<a href="http://www.time.com/time/health/article/0,8599,1650352,00.html">I'm shocked</a>. They needed a study to find out that baby talk is not helpful for the language development. But maybe I'm all wrong and "baba, wawa, dada" helps children to understand the words "bottle, water and father" better.<a href="http://www.time.com/time/health/article/0,8599,1650352,00.html">I'm shocked</a>. They needed a study to find out that baby talk is not helpful for the language development. But maybe I'm all wrong and "baba, wawa, dada" helps children to understand the words "bottle, water and father" better.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAD5odHRwOi8v
d3d3LnRpbWUuY29tL3RpbWUvaGVhbHRoL2FydGljbGUvMCw4NTk5LDE2NTAzNTIsMDAuaHRtbFMA
AAALSSdtIHNob2NrZWRTAAAA1i4gVGhleSBuZWVkZWQgYSBzdHVkeSB0byBmaW5kIG91dCB0aGF0
IGJhYnkgdGFsayBpcyBub3QgaGVscGZ1bCBmb3IgdGhlIGxhbmd1YWdlIGRldmVsb3BtZW50LiBC
dXQgbWF5YmUgSSdtIGFsbCB3cm9uZyBhbmQgImJhYmEsIHdhd2EsIGRhZGEiIGhlbHBzIGNoaWxk
cmVuIHRvIHVuZGVyc3RhbmQgdGhlIHdvcmRzICJib3R0bGUsIHdhdGVyIGFuZCBmYXRoZXIiIGJl
dHRlci5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Book Review: “Learning jQuery”http://lucumr.pocoo.org/cogitations/2007/08/09/book-review-learning-jquery/2007-08-09T20:24:13Z2007-08-09T20:24:13ZArmin Ronacherbook-review-learning-jqueryyesyes2<img class="thumbright" alt="photo of the book's cover" src="http://pocoo.org/~mitsuhiko/learningjquery.png">With the Web 2.0 movement JavaScript got a a second chance to show off its abilities. And the second life of JavaScript is certainly a lot more interesting with advanced features such as XML processing, DOM modification and the possibility to send HTTP requests from a script to the server loading data on the fly. Because JavaScript still has to suffer from some of its design mistakes and browser incompatibilities a bunch of JavaScript libraries were created over the last four years that not only fix those problems but also extend the JavaScript core with new functions and objects that make it fun to work with.
One of the most interesting libraries is definitely jQuery by John Resig. Because the author of sees JavaScript as functional language and uses "chaining" of calls to make code shorter. If you don't know jQuery already but have used Prototype or similar JavaScript libraries you should absolutely try it out, the results are stunning as jQuery's expressive and short statements make the code easy to understand and very compact. For web applications this is a huge advantage because less code makes pages load faster which often is more important than actual runtime performance.
And more important than a working and powerful library is a good documentation or a guide that is written in a way that makes readers understand the design principles to get the best results of a library.
The book "Learning jQuery" (Packt Publishing) is without doubt the best guide to jQuery so far. The examples in the book are useful, down-to-earth and written without any side effects. Whenever an example in the book might introduce side effects you are warned and shown how alternate solutions for slightly different situations may look like.
The book is organized into 10 chapters: in the quick start the reader is introduced to jQuery, but not JavaScript itself. It's probably a good idea to read a JavaScript book first if you haven't worked with JavaScript so far. However jQuery is somehow a language on its own and you can get started quickly with novice JavaScript skills too. The next few chapters cover everyday problem situations and possible solutions using jQuery. It's very likely that often occurring problems are already covered in the book and the solutins require only minor modifications to fulfil specific requirements.
AJAX is of course covered too, although most of the examples are framework and scripting language independent. The few AJAX examples that require server-side content processing are implemented PHP, unfortunately the code quality of the PHP examples is rather bad, fortunately there are few of them.
The book also covers some of the more popular jQuery plugins like Dimensions, Interface and Form and a quick introduction to jQuery plugin development.
The appendix is also worth reading because it includes a bunch of useful links to JavaScript and web-development resources, development tools and also a short introduction to JavaScript closures and how to avoid memory leakage in internet explorer.
The only real negative aspect of the book is the font used for the source code examples. There is no visible difference between an uppercased "O" and zero (0). Also noteworthy is the price of $ 39.99 is quite pricey, but on the other hand you get more than 300 pages full of useful information and some of the money goes directly to the jQuery project.
Conclusion: If you're interested in jQuery and need a good book for the first steps you should definitively have a look at "learning jQuery". If you're already an advanced user and you probably don't find that much of new information in this book.
<a href="http://www.packtpub.com/jQuery/book/mid/1004077zztq0">buy the book at packt publishing</a><img src="http://pocoo.org/~mitsuhiko/learningjquery.png" alt="photo of the book's cover" class="thumbright">With the Web 2.0 movement JavaScript got a a second chance to show off its abilities. And the second life of JavaScript is certainly a lot more interesting with advanced features such as XML processing, DOM modification and the possibility to send HTTP requests from a script to the server loading data on the fly. Because JavaScript still has to suffer from some of its design mistakes and browser incompatibilities a bunch of JavaScript libraries were created over the last four years that not only fix those problems but also extend the JavaScript core with new functions and objects that make it fun to work with.
One of the most interesting libraries is definitely jQuery by John Resig. Because the author of sees JavaScript as functional language and uses "chaining" of calls to make code shorter. If you don't know jQuery already but have used Prototype or similar JavaScript libraries you should absolutely try it out, the results are stunning as jQuery's expressive and short statements make the code easy to understand and very compact. For web applications this is a huge advantage because less code makes pages load faster which often is more important than actual runtime performance.
And more important than a working and powerful library is a good documentation or a guide that is written in a way that makes readers understand the design principles to get the best results of a library.
The book "Learning jQuery" (Packt Publishing) is without doubt the best guide to jQuery so far. The examples in the book are useful, down-to-earth and written without any side effects. Whenever an example in the book might introduce side effects you are warned and shown how alternate solutions for slightly different situations may look like.
The book is organized into 10 chapters: in the quick start the reader is introduced to jQuery, but not JavaScript itself. It's probably a good idea to read a JavaScript book first if you haven't worked with JavaScript so far. However jQuery is somehow a language on its own and you can get started quickly with novice JavaScript skills too. The next few chapters cover everyday problem situations and possible solutions using jQuery. It's very likely that often occurring problems are already covered in the book and the solutins require only minor modifications to fulfil specific requirements.
AJAX is of course covered too, although most of the examples are framework and scripting language independent. The few AJAX examples that require server-side content processing are implemented PHP, unfortunately the code quality of the PHP examples is rather bad, fortunately there are few of them.
The book also covers some of the more popular jQuery plugins like Dimensions, Interface and Form and a quick introduction to jQuery plugin development.
The appendix is also worth reading because it includes a bunch of useful links to JavaScript and web-development resources, development tools and also a short introduction to JavaScript closures and how to avoid memory leakage in internet explorer.
The only real negative aspect of the book is the font used for the source code examples. There is no visible difference between an uppercased "O" and zero (0). Also noteworthy is the price of $ 39.99 is quite pricey, but on the other hand you get more than 300 pages full of useful information and some of the money goes directly to the jQuery project.
Conclusion: If you're interested in jQuery and need a good book for the first steps you should definitively have a look at "learning jQuery". If you're already an advanced user and you probably don't find that much of new information in this book.
<a href="http://www.packtpub.com/jQuery/book/mid/1004077zztq0">buy the book at packt publishing</a>SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAANpbWdMAABNAANTAAAAA3NyY1MAAAAuaHR0cDov
L3BvY29vLm9yZy9+bWl0c3VoaWtvL2xlYXJuaW5nanF1ZXJ5LnBuZ1MAAAADYWx0UwAAABlwaG90
byBvZiB0aGUgYm9vaydzIGNvdmVyUwAAAAVjbGFzc1MAAAAKdGh1bWJyaWdodFMAAAAAUwAADktX
aXRoIHRoZSBXZWIgMi4wIG1vdmVtZW50IEphdmFTY3JpcHQgZ290IGEgYSBzZWNvbmQgY2hhbmNl
IHRvIHNob3cgb2ZmIGl0cyBhYmlsaXRpZXMuIEFuZCB0aGUgc2Vjb25kIGxpZmUgb2YgSmF2YVNj
cmlwdCBpcyBjZXJ0YWlubHkgYSBsb3QgbW9yZSBpbnRlcmVzdGluZyB3aXRoIGFkdmFuY2VkIGZl
YXR1cmVzIHN1Y2ggYXMgWE1MIHByb2Nlc3NpbmcsIERPTSBtb2RpZmljYXRpb24gYW5kIHRoZSBw
b3NzaWJpbGl0eSB0byBzZW5kIEhUVFAgcmVxdWVzdHMgZnJvbSBhIHNjcmlwdCB0byB0aGUgc2Vy
dmVyIGxvYWRpbmcgZGF0YSBvbiB0aGUgZmx5LiBCZWNhdXNlIEphdmFTY3JpcHQgc3RpbGwgaGFz
IHRvIHN1ZmZlciBmcm9tIHNvbWUgb2YgaXRzIGRlc2lnbiBtaXN0YWtlcyBhbmQgYnJvd3NlciBp
bmNvbXBhdGliaWxpdGllcyBhIGJ1bmNoIG9mIEphdmFTY3JpcHQgbGlicmFyaWVzIHdlcmUgY3Jl
YXRlZCBvdmVyIHRoZSBsYXN0IGZvdXIgeWVhcnMgdGhhdCBub3Qgb25seSBmaXggdGhvc2UgcHJv
YmxlbXMgYnV0IGFsc28gZXh0ZW5kIHRoZSBKYXZhU2NyaXB0IGNvcmUgd2l0aCBuZXcgZnVuY3Rp
b25zIGFuZCBvYmplY3RzIHRoYXQgbWFrZSBpdCBmdW4gdG8gd29yayB3aXRoLgoKT25lIG9mIHRo
ZSBtb3N0IGludGVyZXN0aW5nIGxpYnJhcmllcyBpcyBkZWZpbml0ZWx5IGpRdWVyeSBieSBKb2hu
IFJlc2lnLiBCZWNhdXNlIHRoZSBhdXRob3Igb2Ygc2VlcyBKYXZhU2NyaXB0IGFzIGZ1bmN0aW9u
YWwgbGFuZ3VhZ2UgYW5kIHVzZXMgImNoYWluaW5nIiBvZiBjYWxscyB0byBtYWtlIGNvZGUgc2hv
cnRlci4gSWYgeW91IGRvbid0IGtub3cgalF1ZXJ5IGFscmVhZHkgYnV0IGhhdmUgdXNlZCBQcm90
b3R5cGUgb3Igc2ltaWxhciBKYXZhU2NyaXB0IGxpYnJhcmllcyB5b3Ugc2hvdWxkIGFic29sdXRl
bHkgdHJ5IGl0IG91dCwgdGhlIHJlc3VsdHMgYXJlIHN0dW5uaW5nIGFzIGpRdWVyeSdzIGV4cHJl
c3NpdmUgYW5kIHNob3J0IHN0YXRlbWVudHMgbWFrZSB0aGUgY29kZSBlYXN5IHRvIHVuZGVyc3Rh
bmQgYW5kIHZlcnkgY29tcGFjdC4gRm9yIHdlYiBhcHBsaWNhdGlvbnMgdGhpcyBpcyBhIGh1Z2Ug
YWR2YW50YWdlIGJlY2F1c2UgbGVzcyBjb2RlIG1ha2VzIHBhZ2VzIGxvYWQgZmFzdGVyIHdoaWNo
IG9mdGVuIGlzIG1vcmUgaW1wb3J0YW50IHRoYW4gYWN0dWFsIHJ1bnRpbWUgcGVyZm9ybWFuY2Uu
CgpBbmQgbW9yZSBpbXBvcnRhbnQgdGhhbiBhIHdvcmtpbmcgYW5kIHBvd2VyZnVsIGxpYnJhcnkg
aXMgYSBnb29kIGRvY3VtZW50YXRpb24gb3IgYSBndWlkZSB0aGF0IGlzIHdyaXR0ZW4gaW4gYSB3
YXkgdGhhdCBtYWtlcyByZWFkZXJzIHVuZGVyc3RhbmQgdGhlIGRlc2lnbiBwcmluY2lwbGVzIHRv
IGdldCB0aGUgYmVzdCByZXN1bHRzIG9mIGEgbGlicmFyeS4gCgpUaGUgYm9vayAiTGVhcm5pbmcg
alF1ZXJ5IiAoUGFja3QgUHVibGlzaGluZykgaXMgd2l0aG91dCBkb3VidCB0aGUgYmVzdCBndWlk
ZSB0byBqUXVlcnkgc28gZmFyLiBUaGUgZXhhbXBsZXMgaW4gdGhlIGJvb2sgYXJlIHVzZWZ1bCwg
ZG93bi10by1lYXJ0aCBhbmQgd3JpdHRlbiB3aXRob3V0IGFueSBzaWRlIGVmZmVjdHMuIFdoZW5l
dmVyIGFuIGV4YW1wbGUgaW4gdGhlIGJvb2sgbWlnaHQgaW50cm9kdWNlIHNpZGUgZWZmZWN0cyB5
b3UgYXJlIHdhcm5lZCBhbmQgc2hvd24gaG93IGFsdGVybmF0ZSBzb2x1dGlvbnMgZm9yIHNsaWdo
dGx5IGRpZmZlcmVudCBzaXR1YXRpb25zIG1heSBsb29rIGxpa2UuCgpUaGUgYm9vayBpcyBvcmdh
bml6ZWQgaW50byAxMCBjaGFwdGVyczogaW4gdGhlIHF1aWNrIHN0YXJ0IHRoZSByZWFkZXIgaXMg
aW50cm9kdWNlZCB0byBqUXVlcnksIGJ1dCBub3QgSmF2YVNjcmlwdCBpdHNlbGYuIEl0J3MgcHJv
YmFibHkgYSBnb29kIGlkZWEgdG8gcmVhZCBhIEphdmFTY3JpcHQgYm9vayBmaXJzdCBpZiB5b3Ug
aGF2ZW4ndCB3b3JrZWQgd2l0aCBKYXZhU2NyaXB0IHNvIGZhci4gSG93ZXZlciBqUXVlcnkgaXMg
c29tZWhvdyBhIGxhbmd1YWdlIG9uIGl0cyBvd24gYW5kIHlvdSBjYW4gZ2V0IHN0YXJ0ZWQgcXVp
Y2tseSB3aXRoIG5vdmljZSBKYXZhU2NyaXB0IHNraWxscyB0b28uIFRoZSBuZXh0IGZldyBjaGFw
dGVycyBjb3ZlciBldmVyeWRheSBwcm9ibGVtIHNpdHVhdGlvbnMgYW5kIHBvc3NpYmxlIHNvbHV0
aW9ucyB1c2luZyBqUXVlcnkuIEl0J3MgdmVyeSBsaWtlbHkgdGhhdCBvZnRlbiBvY2N1cnJpbmcg
cHJvYmxlbXMgYXJlIGFscmVhZHkgY292ZXJlZCBpbiB0aGUgYm9vayBhbmQgdGhlIHNvbHV0aW5z
IHJlcXVpcmUgb25seSBtaW5vciBtb2RpZmljYXRpb25zIHRvIGZ1bGZpbCBzcGVjaWZpYyByZXF1
aXJlbWVudHMuIAoKQUpBWCBpcyBvZiBjb3Vyc2UgY292ZXJlZCB0b28sIGFsdGhvdWdoIG1vc3Qg
b2YgdGhlIGV4YW1wbGVzIGFyZSBmcmFtZXdvcmsgYW5kIHNjcmlwdGluZyBsYW5ndWFnZSBpbmRl
cGVuZGVudC4gVGhlIGZldyBBSkFYIGV4YW1wbGVzIHRoYXQgcmVxdWlyZSBzZXJ2ZXItc2lkZSBj
b250ZW50IHByb2Nlc3NpbmcgYXJlIGltcGxlbWVudGVkIFBIUCwgdW5mb3J0dW5hdGVseSB0aGUg
Y29kZSAgcXVhbGl0eSBvZiB0aGUgUEhQIGV4YW1wbGVzIGlzIHJhdGhlciBiYWQsIGZvcnR1bmF0
ZWx5IHRoZXJlIGFyZSBmZXcgb2YgdGhlbS4KClRoZSBib29rIGFsc28gY292ZXJzIHNvbWUgb2Yg
dGhlIG1vcmUgcG9wdWxhciBqUXVlcnkgcGx1Z2lucyBsaWtlIERpbWVuc2lvbnMsIEludGVyZmFj
ZSBhbmQgRm9ybSBhbmQgYSBxdWljayBpbnRyb2R1Y3Rpb24gdG8galF1ZXJ5IHBsdWdpbiBkZXZl
bG9wbWVudC4gCgpUaGUgYXBwZW5kaXggaXMgYWxzbyB3b3J0aCByZWFkaW5nIGJlY2F1c2UgaXQg
aW5jbHVkZXMgYSBidW5jaCBvZiB1c2VmdWwgbGlua3MgdG8gSmF2YVNjcmlwdCBhbmQgd2ViLWRl
dmVsb3BtZW50IHJlc291cmNlcywgZGV2ZWxvcG1lbnQgdG9vbHMgYW5kIGFsc28gYSBzaG9ydCBp
bnRyb2R1Y3Rpb24gdG8gSmF2YVNjcmlwdCBjbG9zdXJlcyBhbmQgaG93IHRvIGF2b2lkIG1lbW9y
eSBsZWFrYWdlIGluIGludGVybmV0IGV4cGxvcmVyLiAKClRoZSBvbmx5IHJlYWwgbmVnYXRpdmUg
YXNwZWN0IG9mIHRoZSBib29rIGlzIHRoZSBmb250IHVzZWQgZm9yIHRoZSBzb3VyY2UgY29kZSBl
eGFtcGxlcy4gVGhlcmUgaXMgbm8gdmlzaWJsZSBkaWZmZXJlbmNlIGJldHdlZW4gYW4gdXBwZXJj
YXNlZCAiTyIgYW5kIHplcm8gKDApLiBBbHNvIG5vdGV3b3J0aHkgaXMgdGhlIHByaWNlIG9mICQg
MzkuOTkgaXMgcXVpdGUgcHJpY2V5LCBidXQgb24gdGhlIG90aGVyIGhhbmQgeW91IGdldCBtb3Jl
IHRoYW4gMzAwIHBhZ2VzIGZ1bGwgb2YgdXNlZnVsIGluZm9ybWF0aW9uIGFuZCBzb21lIG9mIHRo
ZSBtb25leSBnb2VzIGRpcmVjdGx5IHRvIHRoZSBqUXVlcnkgcHJvamVjdC4KCkNvbmNsdXNpb246
IElmIHlvdSdyZSBpbnRlcmVzdGVkIGluIGpRdWVyeSBhbmQgbmVlZCBhIGdvb2QgYm9vayBmb3Ig
dGhlIGZpcnN0IHN0ZXBzIHlvdSBzaG91bGQgZGVmaW5pdGl2ZWx5IGhhdmUgYSBsb29rIGF0ICJs
ZWFybmluZyBqUXVlcnkiLiBJZiB5b3UncmUgYWxyZWFkeSBhbiBhZHZhbmNlZCB1c2VyIGFuZCB5
b3UgcHJvYmFibHkgZG9uJ3QgZmluZCB0aGF0IG11Y2ggb2YgbmV3IGluZm9ybWF0aW9uIGluIHRo
aXMgYm9vay4KCkVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAANGh0dHA6Ly93d3cucGFja3RwdWIu
Y29tL2pRdWVyeS9ib29rL21pZC8xMDA0MDc3enp0cTBTAAAAIGJ1eSB0aGUgYm9vayBhdCBwYWNr
dCBwdWJsaXNoaW5nUwAAAABTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Im Übrigen bin ich der Meinung da kann man noch mehr Geld verdienenhttp://lucumr.pocoo.org/cogitations/2007/08/07/im-ubrigen-bin-ich-der-meinung-da-kann-man-noch-mehr-geld-verdienen/2007-08-07T16:50:57Z2007-08-07T16:50:57ZArmin Ronacherim-ubrigen-bin-ich-der-meinung-da-kann-man-noch-mehr-geld-verdienenyesyes2Im Grunde sollten Mütter pauschal 200€ an die DPMA zahlen, schließlich sei das Gehirn des Neugeborenen unverkennbar dazu bestimmt sich Melodien, Filmsequencen etc. im Kopf zu behalten. Wäre eigentlich nur <a href="http://www.heise.de/newsticker/meldung/93998">die logische Schlussforderung</a>.Im Grunde sollten Mütter pauschal 200€ an die DPMA zahlen, schließlich sei das Gehirn des Neugeborenen unverkennbar dazu bestimmt sich Melodien, Filmsequencen etc. im Kopf zu behalten. Wäre eigentlich nur <a href="http://www.heise.de/newsticker/meldung/93998">die logische Schlussforderung</a>.SQAAAANTAAAABGJvZHlSUwAAANJJbSBHcnVuZGUgc29sbHRlbiBNw7x0dGVyIHBhdXNjaGFsIDIw
MOKCrCBhbiBkaWUgRFBNQSB6YWhsZW4sIHNjaGxpZcOfbGljaCBzZWkgZGFzIEdlaGlybiBkZXMg
TmV1Z2Vib3JlbmVuIHVudmVya2VubmJhciBkYXp1IGJlc3RpbW10IHNpY2ggTWVsb2RpZW4sIEZp
bG1zZXF1ZW5jZW4gZXRjLiBpbSBLb3BmIHp1IGJlaGFsdGVuLiBXw6RyZSBlaWdlbnRsaWNoIG51
ciBMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACxodHRwOi8vd3d3LmhlaXNlLmRlL25ld3N0
aWNrZXIvbWVsZHVuZy85Mzk5OFMAAAAdZGllIGxvZ2lzY2hlIFNjaGx1c3Nmb3JkZXJ1bmdTAAAA
AS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
TextPress and other lost stuff…http://lucumr.pocoo.org/cogitations/2007/08/04/textpress-and-other-lost-stuff/2007-08-04T20:21:51Z2007-08-04T20:21:51ZArmin Ronachertextpress-and-other-lost-stuffyesyes2Some time ago I wrote a blog engine in Python to replace this wordpress installation. As you can see that never really happened although the blog software is already in a usable state (at least the basic administration and plugin interface works). One of the reasons is that i would have to port over the theme which is one of those stupid tasks i just hate, another one is that i haven't had time to improve it any further. Another piece of software I recently discovered again is a python powered wiki called ordo which I wrote one year ago i guess. It's a shame that those applications never where released or properly licensed. ordo lingers around in my svn repository but textpress does not.
TextPress won't for a few reasons. One is the name, it's obviously taken from wordpress and want to rename it before I release it, the other reason is that i don't have the time to maintain the code right now. There are already many other projects and I don't feel like I want to maintain too much code at the same time.
But because TextPress has some really unique features I at least want to show what it does :)
<a href="http://pocoo.org/~mitsuhiko/textpress_blog.png"><img class="standalone" src="http://pocoo.org/~mitsuhiko/textpress_blog_thumb.png" alt="screenshot of the textpress blog"></a>
The screenshot above shows the default theme, the admin panel <a href="http://pocoo.org/~mitsuhiko/textpress_admin.png">looks like this</a> and <a href="http://pocoo.org/~mitsuhiko/textpress_login.png">this</a>. It has a pretty interesting plugin interface. The event system was inspired by dokuwiki, the way the syntax based plugins work is IMHO unique :)
Basically what it does is lexing the post sgml markup into a DOM like structure which you can query and transform. Here for example the complete sourcecode of the pygments plugin:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">textpress.api</span> <span class="k">import</span> <span class="o">*</span>
<span class="k">from</span> <span class="nn">textpress.htmlprocessor</span> <span class="k">import</span> <span class="n">DataNode</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">from</span> <span class="nn">pygments</span> <span class="k">import</span> <span class="n">highlight</span>
<span class="k">from</span> <span class="nn">pygments.lexers</span> <span class="k">import</span> <span class="n">get_lexer_by_name</span>
<span class="k">from</span> <span class="nn">pygments.formatters</span> <span class="k">import</span> <span class="n">HtmlFormatter</span>
<span class="n">have_pygments</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="n">have_pygments</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">class</span> <span class="nc">PygmentsHighlighter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">style</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">formatter</span> <span class="o">=</span> <span class="n">HtmlFormatter</span><span class="p">(</span><span class="n">style</span><span class="o">=</span><span class="n">style</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">process_doc_tree</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
<span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">event</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="s">'doctree'</span><span class="p">]</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s">'pre[@tp:lang]'</span><span class="p">):</span>
<span class="n">lexer</span> <span class="o">=</span> <span class="n">get_lexer_by_name</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s">'tp:lang'</span><span class="p">))</span>
<span class="n">output</span> <span class="o">=</span> <span class="n">highlight</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="n">lexer</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatter</span><span class="p">)</span>
<span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">children</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">DataNode</span><span class="p">(</span><span class="n">output</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">get_style</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">formatter</span><span class="o">.</span><span class="n">get_style_defs</span><span class="p">(),</span> <span class="n">mimetype</span><span class="o">=</span><span class="s">'text/css'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">inject_style</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
<span class="n">add_link</span><span class="p">(</span><span class="s">'stylesheet'</span><span class="p">,</span> <span class="n">url_for</span><span class="p">(</span><span class="s">'pygments_support/style'</span><span class="p">),</span> <span class="s">'text/css'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">setup</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">plugin</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">have_pygments</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">app</span><span class="o">.</span><span class="n">add_config_var</span><span class="p">(</span><span class="s">'pygments_support/style'</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">,</span> <span class="s">u'default'</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">add_url_rule</span><span class="p">(</span><span class="s">'/_shared/pygments_support/style.css'</span><span class="p">,</span>
<span class="n">endpoint</span><span class="o">=</span><span class="s">'pygments_support/style'</span><span class="p">)</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">PygmentsHighlighter</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">cfg</span><span class="p">[</span><span class="s">'pygments_support/style'</span><span class="p">])</span>
<span class="n">app</span><span class="o">.</span><span class="n">connect_event</span><span class="p">(</span><span class="s">'process-doc-tree'</span><span class="p">,</span> <span class="n">c</span><span class="o">.</span><span class="n">process_doc_tree</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">connect_event</span><span class="p">(</span><span class="s">'after-request-setup'</span><span class="p">,</span> <span class="n">c</span><span class="o">.</span><span class="n">inject_style</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">add_view</span><span class="p">(</span><span class="s">'pygments_support/style'</span><span class="p">,</span> <span class="n">c</span><span class="o">.</span><span class="n">get_style</span><span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from textpress.api import *
from textpress.htmlprocessor import DataNode
try:
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter
have_pygments = True
except ImportError:
have_pygments = False
class PygmentsHighlighter(object):
def __init__(self, style):
self.formatter = HtmlFormatter(style=style)
def process_doc_tree(self, event):
for node in event.data['doctree'].query('pre[@tp:lang]'):
lexer = get_lexer_by_name(node.attributes.pop('tp:lang'))
output = highlight(node.text, lexer, self.formatter)
node.parent.children.replace(node, DataNode(output))
def get_style(self, req):
return Response(self.formatter.get_style_defs(), mimetype='text/css')
def inject_style(self, event):
add_link('stylesheet', url_for('pygments_support/style'), 'text/css')
def setup(app, plugin):
if not have_pygments:
return
app.add_config_var('pygments_support/style', unicode, u'default')
app.add_url_rule('/_shared/pygments_support/style.css',
endpoint='pygments_support/style')
c = PygmentsHighlighter(app.cfg['pygments_support/style'])
app.connect_event('process-doc-tree', c.process_doc_tree)
app.connect_event('after-request-setup', c.inject_style)
app.add_view('pygments_support/style', c.get_style)<PYGMENTS_RAW -->
You can see the event and doc tree system in action in the snippet above. The way the DOM is queried is inspired by jQuery ;-)Some time ago I wrote a blog engine in Python to replace this wordpress installation. As you can see that never really happened although the blog software is already in a usable state (at least the basic administration and plugin interface works). One of the reasons is that i would have to port over the theme which is one of those stupid tasks i just hate, another one is that i haven't had time to improve it any further. Another piece of software I recently discovered again is a python powered wiki called ordo which I wrote one year ago i guess. It's a shame that those applications never where released or properly licensed. ordo lingers around in my svn repository but textpress does not.
TextPress won't for a few reasons. One is the name, it's obviously taken from wordpress and want to rename it before I release it, the other reason is that i don't have the time to maintain the code right now. There are already many other projects and I don't feel like I want to maintain too much code at the same time.
But because TextPress has some really unique features I at least want to show what it does :)
<a href="http://pocoo.org/~mitsuhiko/textpress_blog.png"><img src="http://pocoo.org/~mitsuhiko/textpress_blog_thumb.png" alt="screenshot of the textpress blog" class="standalone"></a>
The screenshot above shows the default theme, the admin panel <a href="http://pocoo.org/~mitsuhiko/textpress_admin.png">looks like this</a> and <a href="http://pocoo.org/~mitsuhiko/textpress_login.png">this</a>. It has a pretty interesting plugin interface. The event system was inspired by dokuwiki, the way the syntax based plugins work is IMHO unique :)
Basically what it does is lexing the post sgml markup into a DOM like structure which you can query and transform. Here for example the complete sourcecode of the pygments plugin:
You can see the event and doc tree system in action in the snippet above. The way the DOM is queried is inspired by jQuery ;-)SQAAAANTAAAABGJvZHlSUwAABFtTb21lIHRpbWUgYWdvIEkgd3JvdGUgYSBibG9nIGVuZ2luZSBp
biBQeXRob24gdG8gcmVwbGFjZSB0aGlzIHdvcmRwcmVzcyBpbnN0YWxsYXRpb24uIEFzIHlvdSBj
YW4gc2VlIHRoYXQgbmV2ZXIgcmVhbGx5IGhhcHBlbmVkIGFsdGhvdWdoIHRoZSBibG9nIHNvZnR3
YXJlIGlzIGFscmVhZHkgaW4gYSB1c2FibGUgc3RhdGUgKGF0IGxlYXN0IHRoZSBiYXNpYyBhZG1p
bmlzdHJhdGlvbiBhbmQgcGx1Z2luIGludGVyZmFjZSB3b3JrcykuIE9uZSBvZiB0aGUgcmVhc29u
cyBpcyB0aGF0IGkgd291bGQgaGF2ZSB0byBwb3J0IG92ZXIgdGhlIHRoZW1lIHdoaWNoIGlzIG9u
ZSBvZiB0aG9zZSBzdHVwaWQgdGFza3MgaSBqdXN0IGhhdGUsIGFub3RoZXIgb25lIGlzIHRoYXQg
aSBoYXZlbid0IGhhZCB0aW1lIHRvIGltcHJvdmUgaXQgYW55IGZ1cnRoZXIuIEFub3RoZXIgcGll
Y2Ugb2Ygc29mdHdhcmUgSSByZWNlbnRseSBkaXNjb3ZlcmVkIGFnYWluIGlzIGEgcHl0aG9uIHBv
d2VyZWQgd2lraSBjYWxsZWQgb3JkbyB3aGljaCBJIHdyb3RlIG9uZSB5ZWFyIGFnbyBpIGd1ZXNz
LiBJdCdzIGEgc2hhbWUgdGhhdCB0aG9zZSBhcHBsaWNhdGlvbnMgbmV2ZXIgd2hlcmUgcmVsZWFz
ZWQgb3IgcHJvcGVybHkgbGljZW5zZWQuIG9yZG8gbGluZ2VycyBhcm91bmQgaW4gbXkgc3ZuIHJl
cG9zaXRvcnkgYnV0IHRleHRwcmVzcyBkb2VzIG5vdC4KClRleHRQcmVzcyB3b24ndCBmb3IgYSBm
ZXcgcmVhc29ucy4gT25lIGlzIHRoZSBuYW1lLCBpdCdzIG9idmlvdXNseSB0YWtlbiBmcm9tIHdv
cmRwcmVzcyBhbmQgd2FudCB0byByZW5hbWUgaXQgYmVmb3JlIEkgcmVsZWFzZSBpdCwgdGhlIG90
aGVyIHJlYXNvbiBpcyB0aGF0IGkgZG9uJ3QgaGF2ZSB0aGUgdGltZSB0byBtYWludGFpbiB0aGUg
Y29kZSByaWdodCBub3cuIFRoZXJlIGFyZSBhbHJlYWR5IG1hbnkgb3RoZXIgcHJvamVjdHMgYW5k
IEkgZG9uJ3QgZmVlbCBsaWtlIEkgd2FudCB0byBtYWludGFpbiB0b28gbXVjaCBjb2RlIGF0IHRo
ZSBzYW1lIHRpbWUuCgpCdXQgYmVjYXVzZSBUZXh0UHJlc3MgaGFzIHNvbWUgcmVhbGx5IHVuaXF1
ZSBmZWF0dXJlcyBJIGF0IGxlYXN0IHdhbnQgdG8gc2hvdyB3aGF0IGl0IGRvZXMgOikKCkwAA0VT
AAAAAWFMAAFFUwAAAANpbWdMAABNAANTAAAAA3NyY1MAAAA0aHR0cDovL3BvY29vLm9yZy9+bWl0
c3VoaWtvL3RleHRwcmVzc19ibG9nX3RodW1iLnBuZ1MAAAADYWx0UwAAACBzY3JlZW5zaG90IG9m
IHRoZSB0ZXh0cHJlc3MgYmxvZ1MAAAAFY2xhc3NTAAAACnN0YW5kYWxvbmVTAAAAAFMAAAAATQAB
UwAAAARocmVmUwAAAC5odHRwOi8vcG9jb28ub3JnL35taXRzdWhpa28vdGV4dHByZXNzX2Jsb2cu
cG5nUwAAAABTAAAAQAoKVGhlIHNjcmVlbnNob3QgYWJvdmUgc2hvd3MgdGhlIGRlZmF1bHQgdGhl
bWUsIHRoZSBhZG1pbiBwYW5lbCBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAC9odHRwOi8vcG9j
b28ub3JnL35taXRzdWhpa28vdGV4dHByZXNzX2FkbWluLnBuZ1MAAAAPbG9va3MgbGlrZSB0aGlz
UwAAAAUgYW5kIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAL2h0dHA6Ly9wb2Nvby5vcmcvfm1p
dHN1aGlrby90ZXh0cHJlc3NfbG9naW4ucG5nUwAAAAR0aGlzUwAAAccuIEl0IGhhcyBhIHByZXR0
eSBpbnRlcmVzdGluZyBwbHVnaW4gaW50ZXJmYWNlLiBUaGUgZXZlbnQgc3lzdGVtIHdhcyBpbnNw
aXJlZCBieSBkb2t1d2lraSwgdGhlIHdheSB0aGUgc3ludGF4IGJhc2VkIHBsdWdpbnMgd29yayBp
cyBJTUhPIHVuaXF1ZSA6KQoKQmFzaWNhbGx5IHdoYXQgaXQgZG9lcyBpcyBsZXhpbmcgdGhlIHBv
c3Qgc2dtbCBtYXJrdXAgaW50byBhIERPTSBsaWtlIHN0cnVjdHVyZSB3aGljaCB5b3UgY2FuIHF1
ZXJ5IGFuZCB0cmFuc2Zvcm0uIEhlcmUgZm9yIGV4YW1wbGUgdGhlIGNvbXBsZXRlIHNvdXJjZWNv
ZGUgb2YgdGhlIHB5Z21lbnRzIHBsdWdpbjoKCllvdSBjYW4gc2VlIHRoZSBldmVudCBhbmQgZG9j
IHRyZWUgc3lzdGVtIGluIGFjdGlvbiBpbiB0aGUgc25pcHBldCBhYm92ZS4gVGhlIHdheSB0aGUg
RE9NIGlzIHF1ZXJpZWQgaXMgaW5zcGlyZWQgYnkgalF1ZXJ5IDstKVMAAAAGcGFyc2VyUwAAAARo
dG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Alexander Solovyovpiranha@piranha.org.uahttp://blog.piranha.org.ua/2007-08-04T21:20:55Znono0Hi. I'm definitely interested in this piece of software - I'm writing my own blog software (really it is almost written - with django - but it is very simple and I don't have inspiration to end it), but your are a lot much more interesting than my. :)
So maybe you'll release it? I'm interested into developing (and maintaining too) cool blog system and if you will accept my help, I'll be glad to do that. :)
P.S. TextPress is definitely not very good name. :) But my thought cannot move forward from just 'byteflow' or 'wordflow'.Hi. I'm definitely interested in this piece of software - I'm writing my own blog software (really it is almost written - with django - but it is very simple and I don't have inspiration to end it), but your are a lot much more interesting than my. :)
So maybe you'll release it? I'm interested into developing (and maintaining too) cool blog system and if you will accept my help, I'll be glad to do that. :)
P.S. TextPress is definitely not very good name. :) But my thought cannot move forward from just 'byteflow' or 'wordflow'.SQAAAAJTAAAABGJvZHlSUwAAAhZIaS4gSSdtIGRlZmluaXRlbHkgaW50ZXJlc3RlZCBpbiB0aGlz
IHBpZWNlIG9mIHNvZnR3YXJlIC0gSSdtIHdyaXRpbmcgbXkgb3duIGJsb2cgc29mdHdhcmUgKHJl
YWxseSBpdCBpcyBhbG1vc3Qgd3JpdHRlbiAtIHdpdGggZGphbmdvIC0gYnV0IGl0IGlzIHZlcnkg
c2ltcGxlIGFuZCBJIGRvbid0IGhhdmUgaW5zcGlyYXRpb24gdG8gZW5kIGl0KSwgYnV0IHlvdXIg
YXJlIGEgbG90IG11Y2ggbW9yZSBpbnRlcmVzdGluZyB0aGFuIG15LiA6KQoKU28gbWF5YmUgeW91
J2xsIHJlbGVhc2UgaXQ/IEknbSBpbnRlcmVzdGVkIGludG8gZGV2ZWxvcGluZyAoYW5kIG1haW50
YWluaW5nIHRvbykgY29vbCBibG9nIHN5c3RlbSBhbmQgaWYgeW91IHdpbGwgYWNjZXB0IG15IGhl
bHAsIEknbGwgYmUgZ2xhZCB0byBkbyB0aGF0LiA6KQoKUC5TLiBUZXh0UHJlc3MgaXMgZGVmaW5p
dGVseSBub3QgdmVyeSBnb29kIG5hbWUuIDopIEJ1dCBteSB0aG91Z2h0IGNhbm5vdCBtb3ZlIGZv
cndhcmQgZnJvbSBqdXN0ICdieXRlZmxvdycgb3IgJ3dvcmRmbG93Jy5MAABTAAAABnBhcnNlclMA
AAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-08-05T13:45:30Znono0If there is enough interest in the project I guess I could probably speed up the open sourcing process. But I don't want to lose control over TextPress too much, especially because much of the internal architecture -- which once again is pretty complex -- is undocumented and can be abused or misused easily.
Regards,
ArminIf there is enough interest in the project I guess I could probably speed up the open sourcing process. But I don't want to lose control over TextPress too much, especially because much of the internal architecture -- which once again is pretty complex -- is undocumented and can be abused or misused easily.
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAURJZiB0aGVyZSBpcyBlbm91Z2ggaW50ZXJlc3QgaW4gdGhlIHBy
b2plY3QgSSBndWVzcyBJIGNvdWxkIHByb2JhYmx5IHNwZWVkIHVwIHRoZSBvcGVuIHNvdXJjaW5n
IHByb2Nlc3MuIEJ1dCBJIGRvbid0IHdhbnQgdG8gbG9zZSBjb250cm9sIG92ZXIgVGV4dFByZXNz
IHRvbyBtdWNoLCBlc3BlY2lhbGx5IGJlY2F1c2UgbXVjaCBvZiB0aGUgaW50ZXJuYWwgYXJjaGl0
ZWN0dXJlIC0tIHdoaWNoIG9uY2UgYWdhaW4gaXMgcHJldHR5IGNvbXBsZXggLS0gaXMgdW5kb2N1
bWVudGVkIGFuZCBjYW4gYmUgYWJ1c2VkIG9yIG1pc3VzZWQgZWFzaWx5LgoKUmVnYXJkcywKQXJt
aW5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Alexander Solovyovpiranha@piranha.org.uahttp://blog.piranha.org.ua/2007-08-05T16:52:48Znono0Ah, I understand. :) So yes, I'm very interested by your description, so I'll wait for this project. :)Ah, I understand. :) So yes, I'm very interested by your description, so I'll wait for this project. :)SQAAAAJTAAAABGJvZHlSUwAAAGdBaCwgSSB1bmRlcnN0YW5kLiA6KSBTbyB5ZXMsIEknbSB2ZXJ5
IGludGVyZXN0ZWQgYnkgeW91ciBkZXNjcmlwdGlvbiwgc28gSSdsbCB3YWl0IGZvciB0aGlzIHBy
b2plY3QuIDopTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
johnjohn.w@web.de2007-12-21T15:55:23Znono0I wonder whether TextPress 0.1 will be released in time ;)I wonder whether TextPress 0.1 will be released in time ;)SQAAAAJTAAAABGJvZHlSUwAAADpJIHdvbmRlciB3aGV0aGVyIFRleHRQcmVzcyAwLjEgd2lsbCBi
ZSByZWxlYXNlZCBpbiB0aW1lIDspTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-21T16:55:50Znono0Probably not ;-) But I will work on itProbably not ;-) But I will work on itSQAAAAJTAAAABGJvZHlSUwAAACZQcm9iYWJseSBub3QgOy0pIEJ1dCBJIHdpbGwgd29yayBvbiBp
dEwAAFMAAAAGcGFyc2VyUwAAAARodG1s
johnjohn.w@web.de2007-12-21T17:09:44Znono0So no christmas for me then this year :(
Seriously: I wish you all the best for christmas and new year and such.
And ohh: Will check-back soon *GSo no christmas for me then this year :(
Seriously: I wish you all the best for christmas and new year and such.
And ohh: Will check-back soon *GSQAAAAJTAAAABGJvZHlSUwAAAJNTbyBubyBjaHJpc3RtYXMgZm9yIG1lIHRoZW4gdGhpcyB5ZWFy
IDooCgpTZXJpb3VzbHk6IEkgd2lzaCB5b3UgYWxsIHRoZSBiZXN0IGZvciBjaHJpc3RtYXMgYW5k
IG5ldyB5ZWFyIGFuZCBzdWNoLgoKQW5kIG9oaDogV2lsbCBjaGVjay1iYWNrIHNvb24gKkdMAABT
AAAABnBhcnNlclMAAAAEaHRtbA==
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-21T19:23:17Znono0Sorry for that :-) Well, but at least Werkzeug 0.1 was released. That's a good start and maybe we can get a TextPress release this year :-)Sorry for that :-) Well, but at least Werkzeug 0.1 was released. That's a good start and maybe we can get a TextPress release this year :-)SQAAAAJTAAAABGJvZHlSUwAAAItTb3JyeSBmb3IgdGhhdCA6LSkgV2VsbCwgYnV0IGF0IGxlYXN0
IFdlcmt6ZXVnIDAuMSB3YXMgcmVsZWFzZWQuIFRoYXQncyBhIGdvb2Qgc3RhcnQgYW5kIG1heWJl
IHdlIGNhbiBnZXQgYSBUZXh0UHJlc3MgcmVsZWFzZSB0aGlzIHllYXIgOi0pTAAAUwAAAAZwYXJz
ZXJTAAAABGh0bWw=
Vim File Templateshttp://lucumr.pocoo.org/cogitations/2007/08/03/vim-file-templates/2007-08-03T12:24:33Z2007-08-03T12:24:33ZArmin Ronachervim-file-templatesyesyes2All python modules I use have the same header. Usually I copy other modules but why not load a default template into a python file in vim?
Here a small snippet that does exactly that:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">function</span><span class="p">!</span> LoadFileTemplate<span class="p">()</span>
<span class="k">silent</span><span class="p">!</span> <span class="m">0</span>r <span class="p">~</span><span class="sr">/.vim/</span>templates/%:<span class="k">e</span>.tmpl
<span class="nb">syn</span> <span class="k">match</span> vimTemplateMarker <span class="c">"<+.++>" containedin=ALL</span>
<span class="nb">hi</span> vimTemplateMarker guifg<span class="p">=</span>#<span class="m">67</span>a<span class="m">42</span>c guibg<span class="p">=</span>#<span class="m">112300</span> gui<span class="p">=</span>bold
<span class="k">endfunction</span>
<span class="k">function</span><span class="p">!</span> JumpToNextPlaceholder<span class="p">()</span>
<span class="k">let</span> old_query <span class="p">=</span> getreg<span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
echo search<span class="p">(</span><span class="s2">"<+.\++>"</span><span class="p">)</span>
exec <span class="c">"norm! c/+>/e<CR>"</span>
<span class="k">call</span> setreg<span class="p">(</span><span class="s1">'/'</span><span class="p">,</span> old_query<span class="p">)</span>
<span class="k">endfunction</span>
autocmd <span class="nb">BufNewFile</span> * :<span class="k">call</span> LoadFileTemplate<span class="p">()</span>
nnoremap <span class="p"><</span>C<span class="p">-</span>J<span class="p">></span> :<span class="k">call</span> JumpToNextPlaceholder<span class="p">()<</span>CR<span class="p">></span>a
inoremap <span class="p"><</span>C<span class="p">-</span>J<span class="p">></span> <span class="p"><</span>ESC<span class="p">></span>:<span class="k">call</span> JumpToNextPlaceholder<span class="p">()<</span>CR<span class="p">></span>a
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(vim)>function! LoadFileTemplate()
silent! 0r ~/.vim/templates/%:e.tmpl
syn match vimTemplateMarker "<+.\++>" containedin=ALL
hi vimTemplateMarker guifg=#67a42c guibg=#112300 gui=bold
endfunction
function! JumpToNextPlaceholder()
let old_query = getreg('/')
echo search("<+.\\++>")
exec "norm! c/+>/e\<CR>"
call setreg('/', old_query)
endfunction
autocmd BufNewFile * :call LoadFileTemplate()
nnoremap <C-J> :call JumpToNextPlaceholder()<CR>a
inoremap <C-J> <ESC>:call JumpToNextPlaceholder()<CR>a<PYGMENTS_RAW -->
What it does is looking for a template called "extension.tmpl" in <tt>~/.vim/templates</tt>. If it finds one it loads it and highlights everything between "<+" and "+>" as placeholder. Hitting Ctrl+J jumps to the next placeholder.
An example template could look like this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">"""</span>
<span class="sd"><+ MODULE_NAME +></span>
<span class="sd"><+ DESCRIPTION +></span>
<span class="sd">Licensed under the <+ LICENSE +> license, see X for more details etc.</span>
<span class="sd">Copyright by ...</span>
<span class="sd">"""</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)># -*- coding: utf-8 -*-
"""
<+ MODULE_NAME +>
<+ DESCRIPTION +>
Licensed under the <+ LICENSE +> license, see X for more details etc.
Copyright by ...
"""<PYGMENTS_RAW -->
If you want to load a file without a template, just hit "u" right at the beginning and the inserted template will disappear.All python modules I use have the same header. Usually I copy other modules but why not load a default template into a python file in vim?
Here a small snippet that does exactly that:
What it does is looking for a template called "extension.tmpl" in <tt>~/.vim/templates</tt>. If it finds one it loads it and highlights everything between "<+" and "+>" as placeholder. Hitting Ctrl+J jumps to the next placeholder.
An example template could look like this:
If you want to load a file without a template, just hit "u" right at the beginning and the inserted template will disappear.SQAAAANTAAAABGJvZHlSUwAAAP1BbGwgcHl0aG9uIG1vZHVsZXMgSSB1c2UgaGF2ZSB0aGUgc2Ft
ZSBoZWFkZXIuIFVzdWFsbHkgSSBjb3B5IG90aGVyIG1vZHVsZXMgYnV0IHdoeSBub3QgbG9hZCBh
IGRlZmF1bHQgdGVtcGxhdGUgaW50byBhIHB5dGhvbiBmaWxlIGluIHZpbT8KCkhlcmUgYSBzbWFs
bCBzbmlwcGV0IHRoYXQgZG9lcyBleGFjdGx5IHRoYXQ6CgoKV2hhdCBpdCBkb2VzIGlzIGxvb2tp
bmcgZm9yIGEgdGVtcGxhdGUgY2FsbGVkICJleHRlbnNpb24udG1wbCIgaW4gTAABRVMAAAACdHRM
AABNAABTAAAAEH4vLnZpbS90ZW1wbGF0ZXNTAAABNC4gSWYgaXQgZmluZHMgb25lIGl0IGxvYWRz
IGl0IGFuZCBoaWdobGlnaHRzIGV2ZXJ5dGhpbmcgYmV0d2VlbiAiPCsiIGFuZCAiKz4iIGFzIHBs
YWNlaG9sZGVyLiBIaXR0aW5nIEN0cmwrSiBqdW1wcyB0byB0aGUgbmV4dCBwbGFjZWhvbGRlci4K
CkFuIGV4YW1wbGUgdGVtcGxhdGUgY291bGQgbG9vayBsaWtlIHRoaXM6CgpJZiB5b3Ugd2FudCB0
byBsb2FkIGEgZmlsZSB3aXRob3V0IGEgdGVtcGxhdGUsIGp1c3QgaGl0ICJ1IiByaWdodCBhdCB0
aGUgYmVnaW5uaW5nIGFuZCB0aGUgaW5zZXJ0ZWQgdGVtcGxhdGUgd2lsbCBkaXNhcHBlYXIuUwAA
AAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Wokdave.null@example.org2007-12-10T06:21:58Znono0Hey, you’re a Vim user, I definitely love you ;)
Thanks for this code, although I won’t use it at present since I don’t grok vim scripting. I currently rely on two Nautilus templates to create a new module or script. I used Geany for a while and then Gedit, both of which support some kind of templates or code snippets, but Geany crashes and Gedit is stupid, so I use Gvim: it integrates well with my desktop environnement and lets me learn the commands step by step. I use the python.vim script from the Python 3.0a1 source and I understand the basic stuff it does yet I can’t even change the way tabs are displayed (^I being ugly and hindering reading), I forgot where I read about that in the doc. The big problem is domesticating windows, tabs and buffers. Well, looking forward to read more entries about Vim :)Hey, you’re a Vim user, I definitely love you ;)
Thanks for this code, although I won’t use it at present since I don’t grok vim scripting. I currently rely on two Nautilus templates to create a new module or script. I used Geany for a while and then Gedit, both of which support some kind of templates or code snippets, but Geany crashes and Gedit is stupid, so I use Gvim: it integrates well with my desktop environnement and lets me learn the commands step by step. I use the python.vim script from the Python 3.0a1 source and I understand the basic stuff it does yet I can’t even change the way tabs are displayed (^I being ugly and hindering reading), I forgot where I read about that in the doc. The big problem is domesticating windows, tabs and buffers. Well, looking forward to read more entries about Vim :)SQAAAAJTAAAABGJvZHlSUwAAAzpIZXksIHlvdeKAmXJlIGEgVmltIHVzZXIsIEkgZGVmaW5pdGVs
eSBsb3ZlIHlvdSA7KQoKVGhhbmtzIGZvciB0aGlzIGNvZGUsIGFsdGhvdWdoIEkgd29u4oCZdCB1
c2UgaXQgYXQgcHJlc2VudCBzaW5jZSBJIGRvbuKAmXQgZ3JvayB2aW0gc2NyaXB0aW5nLiBJIGN1
cnJlbnRseSByZWx5IG9uIHR3byBOYXV0aWx1cyB0ZW1wbGF0ZXMgdG8gY3JlYXRlIGEgbmV3IG1v
ZHVsZSBvciBzY3JpcHQuIEkgdXNlZCBHZWFueSBmb3IgYSB3aGlsZSBhbmQgdGhlbiBHZWRpdCwg
Ym90aCBvZiB3aGljaCBzdXBwb3J0IHNvbWUga2luZCBvZiB0ZW1wbGF0ZXMgb3IgY29kZSBzbmlw
cGV0cywgYnV0IEdlYW55IGNyYXNoZXMgYW5kIEdlZGl0IGlzIHN0dXBpZCwgc28gSSB1c2UgR3Zp
bTogaXQgaW50ZWdyYXRlcyB3ZWxsIHdpdGggbXkgZGVza3RvcCBlbnZpcm9ubmVtZW50IGFuZCBs
ZXRzIG1lIGxlYXJuIHRoZSBjb21tYW5kcyBzdGVwIGJ5IHN0ZXAuIEkgdXNlIHRoZSBweXRob24u
dmltIHNjcmlwdCBmcm9tIHRoZSBQeXRob24gMy4wYTEgc291cmNlIGFuZCBJIHVuZGVyc3RhbmQg
dGhlIGJhc2ljIHN0dWZmIGl0IGRvZXMgeWV0IEkgY2Fu4oCZdCBldmVuIGNoYW5nZSB0aGUgd2F5
IHRhYnMgYXJlIGRpc3BsYXllZCAoXkkgYmVpbmcgdWdseSBhbmQgaGluZGVyaW5nIHJlYWRpbmcp
LCBJIGZvcmdvdCB3aGVyZSBJIHJlYWQgYWJvdXQgdGhhdCBpbiB0aGUgZG9jLiBUaGUgYmlnIHBy
b2JsZW0gaXMgZG9tZXN0aWNhdGluZyB3aW5kb3dzLCB0YWJzIGFuZCBidWZmZXJzLiBXZWxsLCBs
b29raW5nIGZvcndhcmQgdG8gcmVhZCBtb3JlIGVudHJpZXMgYWJvdXQgVmltIDopTAAAUwAAAAZw
YXJzZXJTAAAABGh0bWw=
Jinja Updateshttp://lucumr.pocoo.org/cogitations/2007/08/02/jinja-updates/2007-08-01T22:50:43Z2007-08-01T22:50:43ZArmin Ronacherjinja-updatesyesyes2The new parser works quite well so far, in fact too well. So far all unittests pass which is something i really, really hate. Usually it means that there are unittests missing :)
The new parser supports some new stuff. For example <tt>{{ foo.0 }}</tt> is supported for easier django template transition. A regular expression literal so that the "matching" filter finally makes sense, a set literal, conditional expressions and the debugger is finally a real help.
It's still not in the trunk because some of the changes are too big for a simple merging. If someone has really, really complex templates, try the new-parser branch and try to render the templates there. If you encounter any errors, just poke me, i'll fix it and add a unittest :DThe new parser works quite well so far, in fact too well. So far all unittests pass which is something i really, really hate. Usually it means that there are unittests missing :)
The new parser supports some new stuff. For example <tt>{{ foo.0 }}</tt> is supported for easier django template transition. A regular expression literal so that the "matching" filter finally makes sense, a set literal, conditional expressions and the debugger is finally a real help.
It's still not in the trunk because some of the changes are too big for a simple merging. If someone has really, really complex templates, try the new-parser branch and try to render the templates there. If you encounter any errors, just poke me, i'll fix it and add a unittest :DSQAAAANTAAAABGJvZHlSUwAAAOhUaGUgbmV3IHBhcnNlciB3b3JrcyBxdWl0ZSB3ZWxsIHNvIGZh
ciwgaW4gZmFjdCB0b28gd2VsbC4gU28gZmFyIGFsbCB1bml0dGVzdHMgcGFzcyB3aGljaCBpcyBz
b21ldGhpbmcgaSByZWFsbHksIHJlYWxseSBoYXRlLiBVc3VhbGx5IGl0IG1lYW5zIHRoYXQgdGhl
cmUgYXJlIHVuaXR0ZXN0cyBtaXNzaW5nIDopCgpUaGUgbmV3IHBhcnNlciBzdXBwb3J0cyBzb21l
IG5ldyBzdHVmZi4gRm9yIGV4YW1wbGUgTAABRVMAAAACdHRMAABNAABTAAAAC3t7IGZvby4wIH19
UwAAAe4gaXMgc3VwcG9ydGVkIGZvciBlYXNpZXIgZGphbmdvIHRlbXBsYXRlIHRyYW5zaXRpb24u
IEEgcmVndWxhciBleHByZXNzaW9uIGxpdGVyYWwgc28gdGhhdCB0aGUgIm1hdGNoaW5nIiBmaWx0
ZXIgZmluYWxseSBtYWtlcyBzZW5zZSwgYSBzZXQgbGl0ZXJhbCwgY29uZGl0aW9uYWwgZXhwcmVz
c2lvbnMgYW5kIHRoZSBkZWJ1Z2dlciBpcyBmaW5hbGx5IGEgcmVhbCBoZWxwLgoKSXQncyBzdGls
bCBub3QgaW4gdGhlIHRydW5rIGJlY2F1c2Ugc29tZSBvZiB0aGUgY2hhbmdlcyBhcmUgdG9vIGJp
ZyBmb3IgYSBzaW1wbGUgbWVyZ2luZy4gSWYgc29tZW9uZSBoYXMgcmVhbGx5LCByZWFsbHkgY29t
cGxleCB0ZW1wbGF0ZXMsIHRyeSB0aGUgbmV3LXBhcnNlciBicmFuY2ggYW5kIHRyeSB0byByZW5k
ZXIgdGhlIHRlbXBsYXRlcyB0aGVyZS4gSWYgeW91IGVuY291bnRlciBhbnkgZXJyb3JzLCBqdXN0
IHBva2UgbWUsIGknbGwgZml4IGl0IGFuZCBhZGQgYSB1bml0dGVzdCA6RFMAAAAGcGFyc2VyUwAA
AARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Other Updates…http://lucumr.pocoo.org/cogitations/2007/07/29/other-updates/2007-07-29T20:27:35Z2007-07-29T20:27:35ZArmin Ronacherother-updatesyesyes2I'm back in the <a href="http://www.ubuntuusers.de/">ubuntuusers</a> team and currently helping out <a href="http://amix.dk/">amix</a> on <a href="http://todoist.com/">todoist</a>.I'm back in the <a href="http://www.ubuntuusers.de/">ubuntuusers</a> team and currently helping out <a href="http://amix.dk/">amix</a> on <a href="http://todoist.com/">todoist</a>.SQAAAANTAAAABGJvZHlSUwAAABBJJ20gYmFjayBpbiB0aGUgTAADRVMAAAABYUwAAE0AAVMAAAAE
aHJlZlMAAAAaaHR0cDovL3d3dy51YnVudHV1c2Vycy5kZS9TAAAAC3VidW50dXVzZXJzUwAAACAg
dGVhbSBhbmQgY3VycmVudGx5IGhlbHBpbmcgb3V0IEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAA
D2h0dHA6Ly9hbWl4LmRrL1MAAAAEYW1peFMAAAAEIG9uIEVTAAAAAWFMAABNAAFTAAAABGhyZWZT
AAAAE2h0dHA6Ly90b2RvaXN0LmNvbS9TAAAAB3RvZG9pc3RTAAAAAS5TAAAABnBhcnNlclMAAAAE
aHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
New Jinja Parserhttp://lucumr.pocoo.org/cogitations/2007/07/29/new-jinja-parser/2007-07-29T20:06:14Z2007-07-29T20:06:14ZArmin Ronachernew-jinja-parseryesyes2Uha. One day of programming and Jinja got a new parser :D 129 out of 131 tests pass, and nearly all of the old semantics still work. I changed some things so far that probably make more sense. Syntax changes from 1.1 to 1.2:
<ul>
<li><tt>call</tt> and <tt>endcall</tt> are keywords now. I wanted to do that in 1.3, not 1.2 but because it's easy to change it's a good thing to do the change now.</li>
<li>tuples are tuples now, not lists. That will make strings formatting easier too -- it really was a bad idea to uniform lists and tuples. This change shouldn't cause many problems because the namespace is more or less read only. So there are no concatenation issues that will appear because a list and tuple are mixed together.</li>
<li>__getslice__ is currently not supported. Parsing the python slice rules is not that simple and for the moment slice objects are easier. So <tt>foo[1:2]</tt> results in <tt>get_attribute(foo, slice(1, 2, None))</tt>. I will add some more unittests to check if this breaks stuff.</li>
<li><tt>foo|escape + bar|escape</tt> is possible now.</li>
</ul>
The code is not in trunk by now because there are still some things to fix (string escaping, streaming system) and i don't know if the change has any side effects on bigger code. If someone wants to try out the new parser tough you can check it out from here: <a href="http://trac.pocoo.org/repos/jinja/branches/new-parser/">new-parser</a>.
Backward incompatible changes: the lexer tokenstream, the lexer tokenize method (not the tokeniter one which is public) and the parse functions because the new parser looks different and has different nodes from different modules (no compiler.ast any more). I hope that there are few hardcore users that analyse the Jinja ast but if there are some, you probably have to change some code.Uha. One day of programming and Jinja got a new parser :D 129 out of 131 tests pass, and nearly all of the old semantics still work. I changed some things so far that probably make more sense. Syntax changes from 1.1 to 1.2:
<ul>
<li><tt>call</tt> and <tt>endcall</tt> are keywords now. I wanted to do that in 1.3, not 1.2 but because it's easy to change it's a good thing to do the change now.</li>
<li>tuples are tuples now, not lists. That will make strings formatting easier too -- it really was a bad idea to uniform lists and tuples. This change shouldn't cause many problems because the namespace is more or less read only. So there are no concatenation issues that will appear because a list and tuple are mixed together.</li>
<li>__getslice__ is currently not supported. Parsing the python slice rules is not that simple and for the moment slice objects are easier. So <tt>foo[1:2]</tt> results in <tt>get_attribute(foo, slice(1, 2, None))</tt>. I will add some more unittests to check if this breaks stuff.</li>
<li><tt>foo|escape + bar|escape</tt> is possible now.</li>
</ul>
The code is not in trunk by now because there are still some things to fix (string escaping, streaming system) and i don't know if the change has any side effects on bigger code. If someone wants to try out the new parser tough you can check it out from here: <a href="http://trac.pocoo.org/repos/jinja/branches/new-parser/">new-parser</a>.
Backward incompatible changes: the lexer tokenstream, the lexer tokenize method (not the tokeniter one which is public) and the parse functions because the new parser looks different and has different nodes from different modules (no compiler.ast any more). I hope that there are few hardcore users that analyse the Jinja ast but if there are some, you probably have to change some code.SQAAAANTAAAABGJvZHlSUwAAAOFVaGEuIE9uZSBkYXkgb2YgcHJvZ3JhbW1pbmcgYW5kIEppbmph
IGdvdCBhIG5ldyBwYXJzZXIgOkQgMTI5IG91dCBvZiAxMzEgdGVzdHMgcGFzcywgYW5kIG5lYXJs
eSBhbGwgb2YgdGhlIG9sZCBzZW1hbnRpY3Mgc3RpbGwgd29yay4gSSBjaGFuZ2VkIHNvbWUgdGhp
bmdzIHNvIGZhciB0aGF0IHByb2JhYmx5IG1ha2UgbW9yZSBzZW5zZS4gU3ludGF4IGNoYW5nZXMg
ZnJvbSAxLjEgdG8gMS4yOgpMAAJFUwAAAAJ1bEwABEVTAAAAAmxpTAACRVMAAAACdHRMAABNAABT
AAAABGNhbGxTAAAABSBhbmQgRVMAAAACdHRMAABNAABTAAAAB2VuZGNhbGxTAAAAfiBhcmUga2V5
d29yZHMgbm93LiBJIHdhbnRlZCB0byBkbyB0aGF0IGluIDEuMywgbm90IDEuMiBidXQgYmVjYXVz
ZSBpdCdzIGVhc3kgdG8gY2hhbmdlIGl0J3MgYSBnb29kIHRoaW5nIHRvIGRvIHRoZSBjaGFuZ2Ug
bm93Lk0AAFMAAAAAUwAAAAEKRVMAAAACbGlMAABNAABTAAABRXR1cGxlcyBhcmUgdHVwbGVzIG5v
dywgbm90IGxpc3RzLiBUaGF0IHdpbGwgbWFrZSBzdHJpbmdzIGZvcm1hdHRpbmcgZWFzaWVyIHRv
byAtLSBpdCByZWFsbHkgd2FzIGEgYmFkIGlkZWEgdG8gdW5pZm9ybSBsaXN0cyBhbmQgdHVwbGVz
LiBUaGlzIGNoYW5nZSBzaG91bGRuJ3QgY2F1c2UgbWFueSBwcm9ibGVtcyBiZWNhdXNlIHRoZSBu
YW1lc3BhY2UgaXMgbW9yZSBvciBsZXNzIHJlYWQgb25seS4gU28gdGhlcmUgYXJlIG5vIGNvbmNh
dGVuYXRpb24gaXNzdWVzIHRoYXQgd2lsbCBhcHBlYXIgYmVjYXVzZSBhIGxpc3QgYW5kIHR1cGxl
IGFyZSBtaXhlZCB0b2dldGhlci5TAAAAAQpFUwAAAAJsaUwAAkVTAAAAAnR0TAAATQAAUwAAAAhm
b29bMToyXVMAAAAMIHJlc3VsdHMgaW4gRVMAAAACdHRMAABNAABTAAAAJWdldF9hdHRyaWJ1dGUo
Zm9vLCBzbGljZSgxLCAyLCBOb25lKSlTAAAAPy4gSSB3aWxsIGFkZCBzb21lIG1vcmUgdW5pdHRl
c3RzIHRvIGNoZWNrIGlmIHRoaXMgYnJlYWtzIHN0dWZmLk0AAFMAAACLX19nZXRzbGljZV9fIGlz
IGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkLiBQYXJzaW5nIHRoZSBweXRob24gc2xpY2UgcnVsZXMg
aXMgbm90IHRoYXQgc2ltcGxlIGFuZCBmb3IgdGhlIG1vbWVudCBzbGljZSBvYmplY3RzIGFyZSBl
YXNpZXIuIFNvIFMAAAABCkVTAAAAAmxpTAABRVMAAAACdHRMAABNAABTAAAAF2Zvb3xlc2NhcGUg
KyBiYXJ8ZXNjYXBlUwAAABEgaXMgcG9zc2libGUgbm93Lk0AAFMAAAAAUwAAAAEKTQAAUwAAAAEK
UwAAAQYKClRoZSBjb2RlIGlzIG5vdCBpbiB0cnVuayBieSBub3cgYmVjYXVzZSB0aGVyZSBhcmUg
c3RpbGwgc29tZSB0aGluZ3MgdG8gZml4IChzdHJpbmcgZXNjYXBpbmcsIHN0cmVhbWluZyBzeXN0
ZW0pIGFuZCBpIGRvbid0IGtub3cgaWYgdGhlIGNoYW5nZSBoYXMgYW55IHNpZGUgZWZmZWN0cyBv
biBiaWdnZXIgY29kZS4gSWYgc29tZW9uZSB3YW50cyB0byB0cnkgb3V0IHRoZSBuZXcgcGFyc2Vy
IHRvdWdoIHlvdSBjYW4gY2hlY2sgaXQgb3V0IGZyb20gaGVyZTogRVMAAAABYUwAAE0AAVMAAAAE
aHJlZlMAAAA2aHR0cDovL3RyYWMucG9jb28ub3JnL3JlcG9zL2ppbmphL2JyYW5jaGVzL25ldy1w
YXJzZXIvUwAAAApuZXctcGFyc2VyUwAAAYYuCgpCYWNrd2FyZCBpbmNvbXBhdGlibGUgY2hhbmdl
czogdGhlIGxleGVyIHRva2Vuc3RyZWFtLCB0aGUgbGV4ZXIgdG9rZW5pemUgbWV0aG9kIChub3Qg
dGhlIHRva2VuaXRlciBvbmUgd2hpY2ggaXMgcHVibGljKSBhbmQgdGhlIHBhcnNlIGZ1bmN0aW9u
cyBiZWNhdXNlIHRoZSBuZXcgcGFyc2VyIGxvb2tzIGRpZmZlcmVudCBhbmQgaGFzIGRpZmZlcmVu
dCBub2RlcyBmcm9tIGRpZmZlcmVudCBtb2R1bGVzIChubyBjb21waWxlci5hc3QgYW55IG1vcmUp
LiBJIGhvcGUgdGhhdCB0aGVyZSBhcmUgZmV3IGhhcmRjb3JlIHVzZXJzIHRoYXQgYW5hbHlzZSB0
aGUgSmluamEgYXN0IGJ1dCBpZiB0aGVyZSBhcmUgc29tZSwgeW91IHByb2JhYmx5IGhhdmUgdG8g
Y2hhbmdlIHNvbWUgY29kZS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Pocoo and Jinja Updatehttp://lucumr.pocoo.org/cogitations/2007/07/28/pocoo-and-jinja-update/2007-07-28T07:59:09Z2007-07-28T07:59:09ZArmin Ronacherpocoo-and-jinja-updateyesyes2First of all: Pocoo gets some love recently. EnTeQuAk joined the team and is working on finishing the changes I haven't finished (conversion to werkzeug and splitting up the packages). That's great news, but don't expect checkins the next nine days, he's on holiday currently.
The other news affects Jinja. The plan was to introduce a new module system for the next Jinja version so that the loaders reload better and that you can use macros without including a module into the current namespace. So <tt>{% include foo = "foo.html" %} {{ foo.macro() }}</tt> should work.
This however was postponed for a simple reason. The compiler package Jinja is using internally is deprecated because with Python 2.5 the AST is a core Python feature and automatically in sync with the parser Python uses itself. But because maintaining a version for python2.5/2.6, python3 and python2.4 and lower is too much work Jinja will get a hand-written parser for the current syntax.
I expect that this will Jinja also a lot more lightweight because some of the trickeries I do with the AST will become redundant. So that will become the next thing to do.First of all: Pocoo gets some love recently. EnTeQuAk joined the team and is working on finishing the changes I haven't finished (conversion to werkzeug and splitting up the packages). That's great news, but don't expect checkins the next nine days, he's on holiday currently.
The other news affects Jinja. The plan was to introduce a new module system for the next Jinja version so that the loaders reload better and that you can use macros without including a module into the current namespace. So <tt>{% include foo = "foo.html" %} {{ foo.macro() }}</tt> should work.
This however was postponed for a simple reason. The compiler package Jinja is using internally is deprecated because with Python 2.5 the AST is a core Python feature and automatically in sync with the parser Python uses itself. But because maintaining a version for python2.5/2.6, python3 and python2.4 and lower is too much work Jinja will get a hand-written parser for the current syntax.
I expect that this will Jinja also a lot more lightweight because some of the trickeries I do with the AST will become redundant. So that will become the next thing to do.SQAAAANTAAAABGJvZHlSUwAAAfVGaXJzdCBvZiBhbGw6IFBvY29vIGdldHMgc29tZSBsb3ZlIHJl
Y2VudGx5LiBFblRlUXVBayBqb2luZWQgdGhlIHRlYW0gYW5kIGlzIHdvcmtpbmcgb24gZmluaXNo
aW5nIHRoZSBjaGFuZ2VzIEkgaGF2ZW4ndCBmaW5pc2hlZCAoY29udmVyc2lvbiB0byB3ZXJremV1
ZyBhbmQgc3BsaXR0aW5nIHVwIHRoZSBwYWNrYWdlcykuIFRoYXQncyBncmVhdCBuZXdzLCBidXQg
ZG9uJ3QgZXhwZWN0IGNoZWNraW5zIHRoZSBuZXh0IG5pbmUgZGF5cywgaGUncyBvbiBob2xpZGF5
IGN1cnJlbnRseS4KClRoZSBvdGhlciBuZXdzIGFmZmVjdHMgSmluamEuIFRoZSBwbGFuIHdhcyB0
byBpbnRyb2R1Y2UgYSBuZXcgbW9kdWxlIHN5c3RlbSBmb3IgdGhlIG5leHQgSmluamEgdmVyc2lv
biBzbyB0aGF0IHRoZSBsb2FkZXJzIHJlbG9hZCBiZXR0ZXIgYW5kIHRoYXQgeW91IGNhbiB1c2Ug
bWFjcm9zIHdpdGhvdXQgaW5jbHVkaW5nIGEgbW9kdWxlIGludG8gdGhlIGN1cnJlbnQgbmFtZXNw
YWNlLiBTbyBMAAFFUwAAAAJ0dEwAAE0AAFMAAAAweyUgaW5jbHVkZSBmb28gPSAiZm9vLmh0bWwi
ICV9IHt7IGZvby5tYWNybygpIH19UwAAAkEgc2hvdWxkIHdvcmsuClRoaXMgaG93ZXZlciB3YXMg
cG9zdHBvbmVkIGZvciBhIHNpbXBsZSByZWFzb24uIFRoZSBjb21waWxlciBwYWNrYWdlIEppbmph
IGlzIHVzaW5nIGludGVybmFsbHkgaXMgZGVwcmVjYXRlZCBiZWNhdXNlIHdpdGggUHl0aG9uIDIu
NSB0aGUgQVNUIGlzIGEgY29yZSBQeXRob24gZmVhdHVyZSBhbmQgYXV0b21hdGljYWxseSBpbiBz
eW5jIHdpdGggdGhlIHBhcnNlciBQeXRob24gdXNlcyBpdHNlbGYuIEJ1dCBiZWNhdXNlIG1haW50
YWluaW5nIGEgdmVyc2lvbiBmb3IgcHl0aG9uMi41LzIuNiwgcHl0aG9uMyBhbmQgcHl0aG9uMi40
IGFuZCBsb3dlciBpcyB0b28gbXVjaCB3b3JrIEppbmphIHdpbGwgZ2V0IGEgaGFuZC13cml0dGVu
IHBhcnNlciBmb3IgdGhlIGN1cnJlbnQgc3ludGF4LgoKSSBleHBlY3QgdGhhdCB0aGlzIHdpbGwg
SmluamEgYWxzbyBhIGxvdCBtb3JlIGxpZ2h0d2VpZ2h0IGJlY2F1c2Ugc29tZSBvZiB0aGUgdHJp
Y2tlcmllcyBJIGRvIHdpdGggdGhlIEFTVCB3aWxsIGJlY29tZSByZWR1bmRhbnQuIFNvIHRoYXQg
d2lsbCBiZWNvbWUgdGhlIG5leHQgdGhpbmcgdG8gZG8uUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAA
BWludHJvUlMAAAAATAAA
OMG! Access Deniedhttp://lucumr.pocoo.org/cogitations/2007/07/27/omg-access-denied/2007-07-27T21:57:25Z2007-07-27T21:57:25ZArmin Ronacheromg-access-deniedyesyes2<a href="http://digg.com/linux_unix/Ubuntu_in_a_Marvel_Comic_Picture">it was on digg</a> and probably some more blogs. An GRUB that starts up ubuntu is featured in issue #4 of the Marvel Comic Mighty Avengers. Together with a cool "access denied" bar which obviously has not the same resolution as the GRUB ;)
<img src="http://pocoo.org/~mitsuhiko/ubuntu_comic_alternative.png" alt="alternative version of the comic" class="standalone"/>
Well. That's not the original comic, but the text makes IMHO more sense :-)
<a href="http://pocoo.org/~mitsuhiko/ubuntu_comic_original.png">the original one is here</a>.<a href="http://digg.com/linux_unix/Ubuntu_in_a_Marvel_Comic_Picture">it was on digg</a> and probably some more blogs. An GRUB that starts up ubuntu is featured in issue #4 of the Marvel Comic Mighty Avengers. Together with a cool "access denied" bar which obviously has not the same resolution as the GRUB ;)
<img src="http://pocoo.org/~mitsuhiko/ubuntu_comic_alternative.png" alt="alternative version of the comic" class="standalone">
Well. That's not the original comic, but the text makes IMHO more sense :-)
<a href="http://pocoo.org/~mitsuhiko/ubuntu_comic_original.png">the original one is here</a>.SQAAAANTAAAABGJvZHlSUwAAAABMAANFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADtodHRwOi8v
ZGlnZy5jb20vbGludXhfdW5peC9VYnVudHVfaW5fYV9NYXJ2ZWxfQ29taWNfUGljdHVyZVMAAAAO
aXQgd2FzIG9uIGRpZ2dTAAAA3yBhbmQgcHJvYmFibHkgc29tZSBtb3JlIGJsb2dzLiBBbiBHUlVC
IHRoYXQgc3RhcnRzIHVwIHVidW50dSBpcyBmZWF0dXJlZCBpbiBpc3N1ZSAjNCBvZiB0aGUgTWFy
dmVsIENvbWljIE1pZ2h0eSBBdmVuZ2Vycy4gVG9nZXRoZXIgd2l0aCBhIGNvb2wgImFjY2VzcyBk
ZW5pZWQiIGJhciB3aGljaCBvYnZpb3VzbHkgaGFzIG5vdCB0aGUgc2FtZSByZXNvbHV0aW9uIGFz
IHRoZSBHUlVCIDspCgpFUwAAAANpbWdMAABNAANTAAAAA3NyY1MAAAA4aHR0cDovL3BvY29vLm9y
Zy9+bWl0c3VoaWtvL3VidW50dV9jb21pY19hbHRlcm5hdGl2ZS5wbmdTAAAAA2FsdFMAAAAgYWx0
ZXJuYXRpdmUgdmVyc2lvbiBvZiB0aGUgY29taWNTAAAABWNsYXNzUwAAAApzdGFuZGFsb25lUwAA
AABTAAAATQpXZWxsLiBUaGF0J3Mgbm90IHRoZSBvcmlnaW5hbCBjb21pYywgYnV0IHRoZSB0ZXh0
IG1ha2VzIElNSE8gbW9yZSBzZW5zZSA6LSkKRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAA1aHR0
cDovL3BvY29vLm9yZy9+bWl0c3VoaWtvL3VidW50dV9jb21pY19vcmlnaW5hbC5wbmdTAAAAGHRo
ZSBvcmlnaW5hbCBvbmUgaXMgaGVyZVMAAAABLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRy
b1JTAAAAAEwAAA==
Pygments is soooo big…http://lucumr.pocoo.org/cogitations/2007/07/27/pygments-is-soooo-big/2007-07-27T20:56:35Z2007-07-27T20:56:35ZArmin Ronacherpygments-is-soooo-bigyesyes2...that it appears two times on the <a href="http://www.flickr.com/photos/jacobian/866880979/">django powered pages mosaic</a>. 7;13 and 1;18....that it appears two times on the <a href="http://www.flickr.com/photos/jacobian/866880979/">django powered pages mosaic</a>. 7;13 and 1;18.SQAAAANTAAAABGJvZHlSUwAAACQuLi50aGF0IGl0IGFwcGVhcnMgdHdvIHRpbWVzIG9uIHRoZSBM
AAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADBodHRwOi8vd3d3LmZsaWNrci5jb20vcGhvdG9z
L2phY29iaWFuLzg2Njg4MDk3OS9TAAAAG2RqYW5nbyBwb3dlcmVkIHBhZ2VzIG1vc2FpY1MAAAAQ
LiA3OzEzIGFuZCAxOzE4LlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Music you *have* to listen tohttp://lucumr.pocoo.org/cogitations/2007/07/27/music-you-have-to-listen-to/2007-07-27T16:10:29Z2007-07-27T16:10:29ZArmin Ronachermusic-you-have-to-listen-toyesyes2Sacrificed Sons, Ocatavarium and Stream Of Consciousness by Dream Theater.Sacrificed Sons, Ocatavarium and Stream Of Consciousness by Dream Theater.SQAAAANTAAAABGJvZHlSUwAAAEpTYWNyaWZpY2VkIFNvbnMsIE9jYXRhdmFyaXVtIGFuZCBTdHJl
YW0gT2YgQ29uc2Npb3VzbmVzcyBieSBEcmVhbSBUaGVhdGVyLkwAAFMAAAAGcGFyc2VyUwAAAARo
dG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Curse on Jinjahttp://lucumr.pocoo.org/cogitations/2007/07/25/curse-on-jinja/2007-07-25T08:14:32Z2007-07-25T08:14:32ZArmin Ronachercurse-on-jinjayesyes2Since yesterday curse-gaming is now <a href="http://www.curse.com/">curse</a> and running on Jinja. Awesome :) They are using a loader that loads the template bytecode from memcached servers. Thanks to Bryan McLemore that loader is part of Jinja since some time.Since yesterday curse-gaming is now <a href="http://www.curse.com/">curse</a> and running on Jinja. Awesome :) They are using a loader that loads the template bytecode from memcached servers. Thanks to Bryan McLemore that loader is part of Jinja since some time.SQAAAANTAAAABGJvZHlSUwAAACRTaW5jZSB5ZXN0ZXJkYXkgY3Vyc2UtZ2FtaW5nIGlzIG5vdyBM
AAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAABVodHRwOi8vd3d3LmN1cnNlLmNvbS9TAAAABWN1
cnNlUwAAALkgYW5kIHJ1bm5pbmcgb24gSmluamEuIEF3ZXNvbWUgOikgVGhleSBhcmUgdXNpbmcg
YSBsb2FkZXIgdGhhdCBsb2FkcyB0aGUgdGVtcGxhdGUgYnl0ZWNvZGUgZnJvbSBtZW1jYWNoZWQg
c2VydmVycy4gVGhhbmtzIHRvIEJyeWFuIE1jTGVtb3JlIHRoYXQgbG9hZGVyIGlzIHBhcnQgb2Yg
SmluamEgc2luY2Ugc29tZSB0aW1lLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAA
AEwAAA==
Lodgeit Vim Scripthttp://lucumr.pocoo.org/cogitations/2007/07/23/lodgeit-vim-script/2007-07-23T09:37:33Z2007-07-23T09:37:33ZArmin Ronacherlodgeit-vim-scriptyesyes2Currently I constantly go to paste.pocoo.org to paste stuff i copied from my vim there. Why not just paste directly from within vim? So I wrote a small vim plugin (requires python) that pastes to lodgeit: <a href="http://www.vim.org/scripts/script.php?script_id=1965">lodgeit.vim</a>.
Oh. And from the werkzeug plaintext view you can paste directly into the lodgeit now too :-)
<strong>Update:</strong> Improved version online. It now converts to utf-8 automatically and allows to download pastes directly into vim via <tt>:Lodgeit URL</tt>. If you have done your change you can push it back to the server via <tt>:Lodgeit</tt>.Currently I constantly go to paste.pocoo.org to paste stuff i copied from my vim there. Why not just paste directly from within vim? So I wrote a small vim plugin (requires python) that pastes to lodgeit: <a href="http://www.vim.org/scripts/script.php?script_id=1965">lodgeit.vim</a>.
Oh. And from the werkzeug plaintext view you can paste directly into the lodgeit now too :-)
<strong>Update:</strong> Improved version online. It now converts to utf-8 automatically and allows to download pastes directly into vim via <tt>:Lodgeit URL</tt>. If you have done your change you can push it back to the server via <tt>:Lodgeit</tt>.SQAAAANTAAAABGJvZHlSUwAAAM1DdXJyZW50bHkgSSBjb25zdGFudGx5IGdvIHRvIHBhc3RlLnBv
Y29vLm9yZyB0byBwYXN0ZSBzdHVmZiBpIGNvcGllZCBmcm9tIG15IHZpbSB0aGVyZS4gV2h5IG5v
dCBqdXN0IHBhc3RlIGRpcmVjdGx5IGZyb20gd2l0aGluIHZpbT8gU28gSSB3cm90ZSBhIHNtYWxs
IHZpbSBwbHVnaW4gKHJlcXVpcmVzIHB5dGhvbikgdGhhdCBwYXN0ZXMgdG8gbG9kZ2VpdDogTAAE
RVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAA0aHR0cDovL3d3dy52aW0ub3JnL3NjcmlwdHMvc2Ny
aXB0LnBocD9zY3JpcHRfaWQ9MTk2NVMAAAALbG9kZ2VpdC52aW1TAAAAYS4KCk9oLiBBbmQgZnJv
bSB0aGUgd2Vya3pldWcgcGxhaW50ZXh0IHZpZXcgeW91IGNhbiBwYXN0ZSBkaXJlY3RseSBpbnRv
IHRoZSBsb2RnZWl0IG5vdyB0b28gOi0pCgpFUwAAAAZzdHJvbmdMAABNAABTAAAAB1VwZGF0ZTpT
AAAAdSBJbXByb3ZlZCB2ZXJzaW9uIG9ubGluZS4gSXQgbm93IGNvbnZlcnRzIHRvIHV0Zi04IGF1
dG9tYXRpY2FsbHkgYW5kIGFsbG93cyB0byBkb3dubG9hZCBwYXN0ZXMgZGlyZWN0bHkgaW50byB2
aW0gdmlhIEVTAAAAAnR0TAAATQAAUwAAAAw6TG9kZ2VpdCBVUkxTAAAARi4gSWYgeW91IGhhdmUg
ZG9uZSB5b3VyIGNoYW5nZSB5b3UgY2FuIHB1c2ggaXQgYmFjayB0byB0aGUgc2VydmVyIHZpYSBF
UwAAAAJ0dEwAAE0AAFMAAAAIOkxvZGdlaXRTAAAAAS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAF
aW50cm9SUwAAAABMAAA=
The last two weeks…http://lucumr.pocoo.org/cogitations/2007/07/22/the-last-two-weeks/2007-07-22T21:31:34Z2007-07-22T21:31:34ZArmin Ronacherthe-last-two-weeksyesyes2Alright. No posts for quite a long time. But just because the blog was pretty dead that doesn't mean that nothing is happening. In fact I'm working hard on a couple of things I cannot announce yet. Unfortunately my notebook harddisk once again broke which is somewhat annoying. Looks like this summer is more expensive then all the summers before :) Guess my next notebook will be a macbook pro.
Oh. And in <a href="http://pyside.blogspot.com/2007/06/introducing-py-rest-doc.html">the new python documentation</a> (which btw <a href="http://pyside.blogspot.com/2007/07/python-documentation-team-looking-for.html">needs your help</a>) you can now comment on keywords on pages too:
<img src="http://pocoo.org/~mitsuhiko/repydoc_comments.png" class="standalone" alt="screenshot of the new python docs with the new comment dialog" />Alright. No posts for quite a long time. But just because the blog was pretty dead that doesn't mean that nothing is happening. In fact I'm working hard on a couple of things I cannot announce yet. Unfortunately my notebook harddisk once again broke which is somewhat annoying. Looks like this summer is more expensive then all the summers before :) Guess my next notebook will be a macbook pro.
Oh. And in <a href="http://pyside.blogspot.com/2007/06/introducing-py-rest-doc.html">the new python documentation</a> (which btw <a href="http://pyside.blogspot.com/2007/07/python-documentation-team-looking-for.html">needs your help</a>) you can now comment on keywords on pages too:
<img src="http://pocoo.org/~mitsuhiko/repydoc_comments.png" alt="screenshot of the new python docs with the new comment dialog" class="standalone">SQAAAANTAAAABGJvZHlSUwAAAZhBbHJpZ2h0LiBObyBwb3N0cyBmb3IgcXVpdGUgYSBsb25nIHRp
bWUuIEJ1dCBqdXN0IGJlY2F1c2UgdGhlIGJsb2cgd2FzIHByZXR0eSBkZWFkIHRoYXQgZG9lc24n
dCBtZWFuIHRoYXQgbm90aGluZyBpcyBoYXBwZW5pbmcuIEluIGZhY3QgSSdtIHdvcmtpbmcgaGFy
ZCBvbiBhIGNvdXBsZSBvZiB0aGluZ3MgSSBjYW5ub3QgYW5ub3VuY2UgeWV0LiBVbmZvcnR1bmF0
ZWx5IG15IG5vdGVib29rIGhhcmRkaXNrIG9uY2UgYWdhaW4gYnJva2Ugd2hpY2ggaXMgc29tZXdo
YXQgYW5ub3lpbmcuIExvb2tzIGxpa2UgdGhpcyBzdW1tZXIgaXMgbW9yZSBleHBlbnNpdmUgdGhl
biBhbGwgdGhlIHN1bW1lcnMgYmVmb3JlIDopIEd1ZXNzIG15IG5leHQgbm90ZWJvb2sgd2lsbCBi
ZSBhIG1hY2Jvb2sgcHJvLgoKT2guIEFuZCBpbiBMAANFUwAAAAFhTAAATQABUwAAAARocmVmUwAA
AD9odHRwOi8vcHlzaWRlLmJsb2dzcG90LmNvbS8yMDA3LzA2L2ludHJvZHVjaW5nLXB5LXJlc3Qt
ZG9jLmh0bWxTAAAAHHRoZSBuZXcgcHl0aG9uIGRvY3VtZW50YXRpb25TAAAADCAod2hpY2ggYnR3
IEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAATWh0dHA6Ly9weXNpZGUuYmxvZ3Nwb3QuY29tLzIw
MDcvMDcvcHl0aG9uLWRvY3VtZW50YXRpb24tdGVhbS1sb29raW5nLWZvci5odG1sUwAAAA9uZWVk
cyB5b3VyIGhlbHBTAAAAMCkgeW91IGNhbiBub3cgY29tbWVudCBvbiBrZXl3b3JkcyBvbiBwYWdl
cyB0b286CkVTAAAAA2ltZ0wAAE0AA1MAAAADc3JjUwAAADBodHRwOi8vcG9jb28ub3JnL35taXRz
dWhpa28vcmVweWRvY19jb21tZW50cy5wbmdTAAAAA2FsdFMAAAA9c2NyZWVuc2hvdCBvZiB0aGUg
bmV3IHB5dGhvbiBkb2NzIHdpdGggdGhlIG5ldyBjb21tZW50IGRpYWxvZ1MAAAAFY2xhc3NTAAAA
CnN0YW5kYWxvbmVTAAAAAFMAAAAAUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAA
TAAA
Fun with Ruby Syntaxhttp://lucumr.pocoo.org/cogitations/2007/07/19/fun-with-ruby-syntax/2007-07-18T23:39:06Z2007-07-18T23:39:06ZArmin Ronacherfun-with-ruby-syntaxyesyes2Smilies:
<pre>smilies = :-? /:-/ :-D</pre>
That's nonsense code, smilies just gets /:-/ assigned. Fun nevertheless. Why that works? The first thing is a symbol literal, then there is a ternary operator, first result expression is a regular expression literal, the second is the negative version of the "D" constant. Because the symbol is true the second return expression is never evaluated and nobody complains about the missing constant D.Smilies:
<pre>smilies = :-? /:-/ :-D</pre>
That's nonsense code, smilies just gets /:-/ assigned. Fun nevertheless. Why that works? The first thing is a symbol literal, then there is a ternary operator, first result expression is a regular expression literal, the second is the negative version of the "D" constant. Because the symbol is true the second return expression is never evaluated and nobody complains about the missing constant D.SQAAAANTAAAABGJvZHlSUwAAAAlTbWlsaWVzOgpMAAFFUwAAAANwcmVMAABNAABTAAAAFnNtaWxp
ZXMgPSA6LT8gLzotLyA6LURTAAABjwpUaGF0J3Mgbm9uc2Vuc2UgY29kZSwgc21pbGllcyBqdXN0
IGdldHMgLzotLyBhc3NpZ25lZC4gRnVuIG5ldmVydGhlbGVzcy4gV2h5IHRoYXQgd29ya3M/IFRo
ZSBmaXJzdCB0aGluZyBpcyBhIHN5bWJvbCBsaXRlcmFsLCB0aGVuIHRoZXJlIGlzIGEgdGVybmFy
eSBvcGVyYXRvciwgZmlyc3QgcmVzdWx0IGV4cHJlc3Npb24gaXMgYSByZWd1bGFyIGV4cHJlc3Np
b24gbGl0ZXJhbCwgdGhlIHNlY29uZCBpcyB0aGUgbmVnYXRpdmUgdmVyc2lvbiBvZiB0aGUgIkQi
IGNvbnN0YW50LiBCZWNhdXNlIHRoZSBzeW1ib2wgaXMgdHJ1ZSB0aGUgc2Vjb25kIHJldHVybiBl
eHByZXNzaW9uIGlzIG5ldmVyIGV2YWx1YXRlZCBhbmQgbm9ib2R5IGNvbXBsYWlucyBhYm91dCB0
aGUgbWlzc2luZyBjb25zdGFudCBELlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAA
AEwAAA==
Back from Ioshttp://lucumr.pocoo.org/cogitations/2007/07/11/back-from-ios/2007-07-10T22:20:40Z2007-07-10T22:20:40ZArmin Ronacherback-from-iosyesyes2Alright. I'm back in Austria and once again my arrival in my home made me feel somewhat patriotic :-) Although we had much fun on the trip it's a great feeling to come home again. The next weeks will be quite busy because of various changes in my life (the most obvious one is that I'm not a pupil any more)
I was sure that i will be able to use most of my spare time for my projects and myself but as it turned out two days ago the newly gained freedom has some major disadvantages too. There's quite a lot of legal stuff I have to cope with and new opportunities I have to consider and probably take. In one of my last posts I wrote about myself being offline for two weeks -- that's just partially true. I'm back in Austria but I will be offline because biking from tomorrow.
Other news: I will buy <a href="http://ibanez.com/acoustic/guitar.aspx?m=AEG10EBK">a guitar</a> in the next two weeks, and because my harddisk once again broke in that darn notebook I want to buy a mac book as soon as Leopard is out. Expensive summer.Alright. I'm back in Austria and once again my arrival in my home made me feel somewhat patriotic :-) Although we had much fun on the trip it's a great feeling to come home again. The next weeks will be quite busy because of various changes in my life (the most obvious one is that I'm not a pupil any more)
I was sure that i will be able to use most of my spare time for my projects and myself but as it turned out two days ago the newly gained freedom has some major disadvantages too. There's quite a lot of legal stuff I have to cope with and new opportunities I have to consider and probably take. In one of my last posts I wrote about myself being offline for two weeks -- that's just partially true. I'm back in Austria but I will be offline because biking from tomorrow.
Other news: I will buy <a href="http://ibanez.com/acoustic/guitar.aspx?m=AEG10EBK">a guitar</a> in the next two weeks, and because my harddisk once again broke in that darn notebook I want to buy a mac book as soon as Leopard is out. Expensive summer.SQAAAANTAAAABGJvZHlSUwAAAyRBbHJpZ2h0LiBJJ20gYmFjayBpbiBBdXN0cmlhIGFuZCBvbmNl
IGFnYWluIG15IGFycml2YWwgaW4gbXkgaG9tZSBtYWRlIG1lIGZlZWwgc29tZXdoYXQgcGF0cmlv
dGljIDotKSBBbHRob3VnaCB3ZSBoYWQgbXVjaCBmdW4gb24gdGhlIHRyaXAgaXQncyBhIGdyZWF0
IGZlZWxpbmcgdG8gY29tZSBob21lIGFnYWluLiBUaGUgbmV4dCB3ZWVrcyB3aWxsIGJlIHF1aXRl
IGJ1c3kgYmVjYXVzZSBvZiB2YXJpb3VzIGNoYW5nZXMgaW4gbXkgbGlmZSAodGhlIG1vc3Qgb2J2
aW91cyBvbmUgaXMgdGhhdCBJJ20gbm90IGEgcHVwaWwgYW55IG1vcmUpCgpJIHdhcyBzdXJlIHRo
YXQgaSB3aWxsIGJlIGFibGUgdG8gdXNlIG1vc3Qgb2YgbXkgc3BhcmUgdGltZSBmb3IgbXkgcHJv
amVjdHMgYW5kIG15c2VsZiBidXQgYXMgaXQgdHVybmVkIG91dCB0d28gZGF5cyBhZ28gdGhlIG5l
d2x5IGdhaW5lZCBmcmVlZG9tIGhhcyBzb21lIG1ham9yIGRpc2FkdmFudGFnZXMgdG9vLiBUaGVy
ZSdzIHF1aXRlIGEgbG90IG9mIGxlZ2FsIHN0dWZmIEkgaGF2ZSB0byBjb3BlIHdpdGggYW5kIG5l
dyBvcHBvcnR1bml0aWVzIEkgaGF2ZSB0byBjb25zaWRlciBhbmQgcHJvYmFibHkgdGFrZS4gSW4g
b25lIG9mIG15IGxhc3QgcG9zdHMgSSB3cm90ZSBhYm91dCBteXNlbGYgYmVpbmcgb2ZmbGluZSBm
b3IgdHdvIHdlZWtzIC0tIHRoYXQncyBqdXN0IHBhcnRpYWxseSB0cnVlLiBJJ20gYmFjayBpbiBB
dXN0cmlhIGJ1dCBJIHdpbGwgYmUgb2ZmbGluZSBiZWNhdXNlIGJpa2luZyBmcm9tIHRvbW9ycm93
LgoKT3RoZXIgbmV3czogSSB3aWxsIGJ1eSBMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADFo
dHRwOi8vaWJhbmV6LmNvbS9hY291c3RpYy9ndWl0YXIuYXNweD9tPUFFRzEwRUJLUwAAAAhhIGd1
aXRhclMAAACcIGluIHRoZSBuZXh0IHR3byB3ZWVrcywgYW5kIGJlY2F1c2UgbXkgaGFyZGRpc2sg
b25jZSBhZ2FpbiBicm9rZSBpbiB0aGF0IGRhcm4gbm90ZWJvb2sgSSB3YW50IHRvIGJ1eSBhIG1h
YyBib29rIGFzIHNvb24gYXMgTGVvcGFyZCBpcyBvdXQuIEV4cGVuc2l2ZSBzdW1tZXIuUwAAAAZw
YXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Rafaelrafaelw@gmx.net2007-07-12T21:51:14Znono0Maybe <a href="http://www.apple.com/backtoschool/?cid=WWW-NAUS-BTS20070525-HAZF1&cp=BTS07-APL&sr=apl" rel="nofollow">this</a> is something for you.Maybe <a href="http://www.apple.com/backtoschool/?cid=WWW-NAUS-BTS20070525-HAZF1&cp=BTS07-APL&sr=apl" rel="nofollow">this</a> is something for you.SQAAAAJTAAAABGJvZHlSUwAAAAZNYXliZSBMAAFFUwAAAAFhTAAATQACUwAAAARocmVmUwAAAFVo
dHRwOi8vd3d3LmFwcGxlLmNvbS9iYWNrdG9zY2hvb2wvP2NpZD1XV1ctTkFVUy1CVFMyMDA3MDUy
NS1IQVpGMSZjcD1CVFMwNy1BUEwmc3I9YXBsUwAAAANyZWxTAAAACG5vZm9sbG93UwAAAAR0aGlz
UwAAABYgaXMgc29tZXRoaW5nIGZvciB5b3UuUwAAAAZwYXJzZXJTAAAABGh0bWw=
Font Settingshttp://lucumr.pocoo.org/cogitations/2007/07/10/font-settings/2007-07-10T14:49:31Z2007-07-10T14:49:31ZArmin Ronacherfont-settingsyesyes2In my old blog I had one article about font settings in ubuntu edgy. Unfortunately I don't have an online backup of that page and there was a request for the data there, so I just post it here again as blog post:
<blockquote>There are many ways to improve the font rendering. (That's because the ubuntu defaults are hideous). Since hoary I use my own font configs based on a configuration from someone I can't remember.
If you're looking for a screenshot have a look at the screenshots in the <a href="http://lucumr.pocoo.org/articles/vim-as-development-environment">vim article</a>.
<strong>xorg.conf</strong>
Locate Section "Monitor" and add the following line before !EndSection:
<pre>DisplaySize XXX YYY</pre>
You can calculate XXX and YYY using this formula:
<pre>DisplaySize = height / 96 * 25.4 width / 96 * 25.4</pre>
Here the values I use for various systems:
1024x768 = 270 203
1280x1024 = 338 270
1400x1050 = 370 277
<strong>selecting rendering method</strong>
<pre>dpkg-reconfigure fontconfig</pre>
Run a root and select "subpixel rendering".
<strong>local.conf</strong>
Create a file /etc/fonts/local.conf and paste the following lines:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="cp"><?xml version="1.0"?></span>
<span class="cp"><!DOCTYPE fontconfig SYSTEM "fonts.dtd"></span>
<span class="nt"><fontconfig></span>
<span class="nt"><include</span> <span class="na">ignore_missing=</span><span class="s">"yes"</span><span class="nt">></span>/var/lib/defoma/fontconfig.d/fonts.conf<span class="nt"></include></span>
<span class="nt"><match</span> <span class="na">target=</span><span class="s">"font"</span><span class="nt">></span>
<span class="nt"><test</span> <span class="na">compare=</span><span class="s">"more"</span> <span class="na">name=</span><span class="s">"pixelsize"</span> <span class="na">qual=</span><span class="s">"any"</span><span class="nt">></span>
<span class="nt"><double></span>12<span class="nt"></double></span>
<span class="nt"></test></span>
<span class="nt"><edit</span> <span class="na">name=</span><span class="s">"autohint"</span> <span class="na">mode=</span><span class="s">"assign"</span> <span class="nt">></span>
<span class="nt"><bool></span>true<span class="nt"></bool></span>
<span class="nt"></edit></span>
<span class="nt"><edit</span> <span class="na">mode=</span><span class="s">"assign"</span> <span class="na">name=</span><span class="s">"hinting"</span> <span class="nt">></span>
<span class="nt"><bool></span>true<span class="nt"></bool></span>
<span class="nt"></edit></span>
<span class="nt"><edit</span> <span class="na">mode=</span><span class="s">"assign"</span> <span class="na">name=</span><span class="s">"hintstyle"</span> <span class="nt">></span>
<span class="nt"><const></span>hintmedium<span class="nt"></const></span>
<span class="nt"></edit></span>
<span class="nt"></match></span>
<span class="nt"><match</span> <span class="na">target=</span><span class="s">"pattern"</span><span class="nt">></span>
<span class="nt"><test</span> <span class="na">qual=</span><span class="s">"any"</span> <span class="na">name=</span><span class="s">"family"</span><span class="nt">></span>
<span class="nt"><string></span>Bitstream Vera Sans<span class="nt"></string></span>
<span class="nt"></test></span>
<span class="nt"><edit</span> <span class="na">name=</span><span class="s">"family"</span> <span class="na">mode=</span><span class="s">"assign"</span><span class="nt">></span>
<span class="nt"><string></span>Arial<span class="nt"></string></span>
<span class="nt"></edit></span>
<span class="nt"></match></span>
<span class="nt"><match</span> <span class="na">target=</span><span class="s">"pattern"</span><span class="nt">></span>
<span class="nt"><test</span> <span class="na">qual=</span><span class="s">"any"</span> <span class="na">name=</span><span class="s">"family"</span><span class="nt">></span>
<span class="nt"><string></span>Helvetica<span class="nt"></string></span>
<span class="nt"></test></span>
<span class="nt"><edit</span> <span class="na">name=</span><span class="s">"family"</span> <span class="na">mode=</span><span class="s">"assign"</span><span class="nt">></span>
<span class="nt"><string></span>Arial<span class="nt"></string></span>
<span class="nt"></edit></span>
<span class="nt"></match></span>
<span class="nt"><match</span> <span class="na">target=</span><span class="s">"pattern"</span><span class="nt">></span>
<span class="nt"><test</span> <span class="na">qual=</span><span class="s">"any"</span> <span class="na">name=</span><span class="s">"family"</span><span class="nt">></span>
<span class="nt"><string></span>Palatino<span class="nt"></string></span>
<span class="nt"></test></span>
<span class="nt"><edit</span> <span class="na">name=</span><span class="s">"family"</span> <span class="na">mode=</span><span class="s">"assign"</span><span class="nt">></span>
<span class="nt"><string></span>Georgia<span class="nt"></string></span>
<span class="nt"></edit></span>
<span class="nt"></match></span>
<span class="nt"></fontconfig></span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(xml)>
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<include ignore_missing="yes">/var/lib/defoma/fontconfig.d/fonts.conf</include>
<match target="font">
<test compare="more" name="pixelsize" qual="any">
<double>12</double>
</test>
<edit name="autohint" mode="assign" >
<bool>true</bool>
</edit>
<edit mode="assign" name="hinting" >
<bool>true</bool>
</edit>
<edit mode="assign" name="hintstyle" >
<const>hintmedium</const>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Bitstream Vera Sans</string>
</test>
<edit name="family" mode="assign">
<string>Arial</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Helvetica</string>
</test>
<edit name="family" mode="assign">
<string>Arial</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Palatino</string>
</test>
<edit name="family" mode="assign">
<string>Georgia</string>
</edit>
</match>
</fontconfig>
<PYGMENTS_RAW -->
<strong>even better settings</strong>
You still don't have what you want? Then try out the patches from <a href="http://www.ubuntuforums.org/showthread.php?t=180647"> this thread on ubuntuforums</a>. But use my local.conf which produces better bold fonts.</blockquote>In my old blog I had one article about font settings in ubuntu edgy. Unfortunately I don't have an online backup of that page and there was a request for the data there, so I just post it here again as blog post:
<blockquote>There are many ways to improve the font rendering. (That's because the ubuntu defaults are hideous). Since hoary I use my own font configs based on a configuration from someone I can't remember.
If you're looking for a screenshot have a look at the screenshots in the <a href="http://lucumr.pocoo.org/articles/vim-as-development-environment">vim article</a>.
<strong>xorg.conf</strong>
Locate Section "Monitor" and add the following line before !EndSection:
<pre>DisplaySize XXX YYY</pre>
You can calculate XXX and YYY using this formula:
<pre>DisplaySize = height / 96 * 25.4 width / 96 * 25.4</pre>
Here the values I use for various systems:
1024x768 = 270 203
1280x1024 = 338 270
1400x1050 = 370 277
<strong>selecting rendering method</strong>
<pre>dpkg-reconfigure fontconfig</pre>
Run a root and select "subpixel rendering".
<strong>local.conf</strong>
Create a file /etc/fonts/local.conf and paste the following lines:
<strong>even better settings</strong>
You still don't have what you want? Then try out the patches from <a href="http://www.ubuntuforums.org/showthread.php?t=180647"> this thread on ubuntuforums</a>. But use my local.conf which produces better bold fonts.</blockquote>SQAAAANTAAAABGJvZHlSUwAAANZJbiBteSBvbGQgYmxvZyBJIGhhZCBvbmUgYXJ0aWNsZSBhYm91
dCBmb250IHNldHRpbmdzIGluIHVidW50dSBlZGd5LiBVbmZvcnR1bmF0ZWx5IEkgZG9uJ3QgaGF2
ZSBhbiBvbmxpbmUgYmFja3VwIG9mIHRoYXQgcGFnZSBhbmQgdGhlcmUgd2FzIGEgcmVxdWVzdCBm
b3IgdGhlIGRhdGEgdGhlcmUsIHNvIEkganVzdCBwb3N0IGl0IGhlcmUgYWdhaW4gYXMgYmxvZyBw
b3N0OgoKTAABRVMAAAAKYmxvY2txdW90ZUwACUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAP2h0
dHA6Ly9sdWN1bXIucG9jb28ub3JnL2FydGljbGVzL3ZpbS1hcy1kZXZlbG9wbWVudC1lbnZpcm9u
bWVudFMAAAALdmltIGFydGljbGVTAAAAAy4KCkVTAAAABnN0cm9uZ0wAAE0AAFMAAAAJeG9yZy5j
b25mUwAAAEoKTG9jYXRlIFNlY3Rpb24gIk1vbml0b3IiIGFuZCBhZGQgdGhlIGZvbGxvd2luZyBs
aW5lIGJlZm9yZSAhRW5kU2VjdGlvbjoKCkVTAAAAA3ByZUwAAE0AAFMAAAAXRGlzcGxheVNpemUg
ICAgIFhYWCBZWVlTAAAANApZb3UgY2FuIGNhbGN1bGF0ZSBYWFggYW5kIFlZWSB1c2luZyB0aGlz
IGZvcm11bGE6CgpFUwAAAANwcmVMAABNAABTAAAAMkRpc3BsYXlTaXplID0gaGVpZ2h0IC8gOTYg
KiAyNS40IHdpZHRoIC8gOTYgKiAyNS40UwAAAGkKCkhlcmUgdGhlIHZhbHVlcyBJIHVzZSBmb3Ig
dmFyaW91cyBzeXN0ZW1zOgoxMDI0eDc2OCA9IDI3MCAyMDMKMTI4MHgxMDI0ID0gMzM4IDI3MAox
NDAweDEwNTAgPSAzNzAgMjc3CgpFUwAAAAZzdHJvbmdMAABNAABTAAAAGnNlbGVjdGluZyByZW5k
ZXJpbmcgbWV0aG9kUwAAAAEKRVMAAAADcHJlTAAATQAAUwAAABtkcGtnLXJlY29uZmlndXJlIGZv
bnRjb25maWdTAAAALgpSdW4gYSByb290IGFuZCBzZWxlY3QgInN1YnBpeGVsIHJlbmRlcmluZyIu
CgpFUwAAAAZzdHJvbmdMAABNAABTAAAACmxvY2FsLmNvbmZTAAAARwpDcmVhdGUgYSBmaWxlIC9l
dGMvZm9udHMvbG9jYWwuY29uZiBhbmQgcGFzdGUgdGhlIGZvbGxvd2luZyBsaW5lczoKCgoKRVMA
AAAGc3Ryb25nTAAATQAAUwAAABRldmVuIGJldHRlciBzZXR0aW5nc1MAAABDCllvdSBzdGlsbCBk
b24ndCBoYXZlIHdoYXQgeW91IHdhbnQ/IFRoZW4gdHJ5IG91dCB0aGUgcGF0Y2hlcyBmcm9tIEVT
AAAAAWFMAABNAAFTAAAABGhyZWZTAAAAM2h0dHA6Ly93d3cudWJ1bnR1Zm9ydW1zLm9yZy9zaG93
dGhyZWFkLnBocD90PTE4MDY0N1MAAAAcIHRoaXMgdGhyZWFkIG9uIHVidW50dWZvcnVtc1MAAAA5
LiBCdXQgdXNlIG15IGxvY2FsLmNvbmYgd2hpY2ggcHJvZHVjZXMgYmV0dGVyIGJvbGQgZm9udHMu
TQAAUwAAAQ1UaGVyZSBhcmUgbWFueSB3YXlzIHRvIGltcHJvdmUgdGhlIGZvbnQgcmVuZGVyaW5n
LiAoVGhhdCdzIGJlY2F1c2UgdGhlIHVidW50dSBkZWZhdWx0cyBhcmUgaGlkZW91cykuIFNpbmNl
IGhvYXJ5IEkgdXNlIG15IG93biBmb250IGNvbmZpZ3MgYmFzZWQgb24gYSBjb25maWd1cmF0aW9u
IGZyb20gc29tZW9uZSBJIGNhbid0IHJlbWVtYmVyLgoKSWYgeW91J3JlIGxvb2tpbmcgZm9yIGEg
c2NyZWVuc2hvdCBoYXZlIGEgbG9vayBhdCB0aGUgc2NyZWVuc2hvdHMgaW4gdGhlIFMAAAAAUwAA
AAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
I did it!http://lucumr.pocoo.org/cogitations/2007/06/29/i-did-it/2007-06-29T12:17:48Z2007-06-29T12:17:48ZArmin Ronacheri-did-ityesyes2Finally I've made the <a href="http://en.wikipedia.org/wiki/Matura">Matura</a> :D I got a "Guter Erfolg", I would have got a "Ausgezeichneter Erfolg" if there wasn't the huge amout of spelling mistakes I made in my written German exam. But I'm happy nevertheless.
Especially the oral Matura was just awesome. Because I wrote a so called "Fachbereitsarbeit" in computer science i had one written exam less than normal. So I only had English, Maths and German as written subjects and Religion, English and computer science as oral subjects. So as you can see darn simple matura, especially because in Austria you can choose one out of two general questions and a special question out of your special subject you worked out the weeks before the Matura.
My topic for the computer science "Fachbereichsarbeit" was security in web applications and apparently my presentation was that impressive that I got some applause which was a very, very cool experience. I had one of the last exams and usually the teachers and the examiner are already so bored that nobody listens to your ten-minute talk. It's a really cool feeling that you were able to somehow impress the persons in the room.
I still don't know the final results but I know that I got a "Guter Erfolg" which is the second best result you can get.
Plans for the next two weeks: Off to <a href="http://en.wikipedia.org/wiki/Ios_Island">Ios</a> with friends :-) and relaxing. So basically off from Sunday the first till Friday the 13th :-)Finally I've made the <a href="http://en.wikipedia.org/wiki/Matura">Matura</a> :D I got a "Guter Erfolg", I would have got a "Ausgezeichneter Erfolg" if there wasn't the huge amout of spelling mistakes I made in my written German exam. But I'm happy nevertheless.
Especially the oral Matura was just awesome. Because I wrote a so called "Fachbereitsarbeit" in computer science i had one written exam less than normal. So I only had English, Maths and German as written subjects and Religion, English and computer science as oral subjects. So as you can see darn simple matura, especially because in Austria you can choose one out of two general questions and a special question out of your special subject you worked out the weeks before the Matura.
My topic for the computer science "Fachbereichsarbeit" was security in web applications and apparently my presentation was that impressive that I got some applause which was a very, very cool experience. I had one of the last exams and usually the teachers and the examiner are already so bored that nobody listens to your ten-minute talk. It's a really cool feeling that you were able to somehow impress the persons in the room.
I still don't know the final results but I know that I got a "Guter Erfolg" which is the second best result you can get.
Plans for the next two weeks: Off to <a href="http://en.wikipedia.org/wiki/Ios_Island">Ios</a> with friends :-) and relaxing. So basically off from Sunday the first till Friday the 13th :-)SQAAAANTAAAABGJvZHlSUwAAABZGaW5hbGx5IEkndmUgbWFkZSB0aGUgTAACRVMAAAABYUwAAE0A
AVMAAAAEaHJlZlMAAAAjaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9NYXR1cmFTAAAABk1h
dHVyYVMAAATwIDpEIEkgZ290IGEgIkd1dGVyIEVyZm9sZyIsIEkgd291bGQgaGF2ZSBnb3QgYSAi
QXVzZ2V6ZWljaG5ldGVyIEVyZm9sZyIgaWYgdGhlcmUgd2Fzbid0IHRoZSBodWdlIGFtb3V0IG9m
IHNwZWxsaW5nIG1pc3Rha2VzIEkgbWFkZSBpbiBteSB3cml0dGVuIEdlcm1hbiBleGFtLiBCdXQg
SSdtIGhhcHB5IG5ldmVydGhlbGVzcy4KCkVzcGVjaWFsbHkgdGhlIG9yYWwgTWF0dXJhIHdhcyBq
dXN0IGF3ZXNvbWUuIEJlY2F1c2UgSSB3cm90ZSBhIHNvIGNhbGxlZCAiRmFjaGJlcmVpdHNhcmJl
aXQiIGluIGNvbXB1dGVyIHNjaWVuY2UgaSBoYWQgb25lIHdyaXR0ZW4gZXhhbSBsZXNzIHRoYW4g
bm9ybWFsLiBTbyBJIG9ubHkgaGFkIEVuZ2xpc2gsIE1hdGhzIGFuZCBHZXJtYW4gYXMgd3JpdHRl
biBzdWJqZWN0cyBhbmQgUmVsaWdpb24sIEVuZ2xpc2ggYW5kIGNvbXB1dGVyIHNjaWVuY2UgYXMg
b3JhbCBzdWJqZWN0cy4gU28gYXMgeW91IGNhbiBzZWUgZGFybiBzaW1wbGUgbWF0dXJhLCBlc3Bl
Y2lhbGx5IGJlY2F1c2UgaW4gQXVzdHJpYSB5b3UgY2FuIGNob29zZSBvbmUgb3V0IG9mIHR3byBn
ZW5lcmFsIHF1ZXN0aW9ucyBhbmQgYSBzcGVjaWFsIHF1ZXN0aW9uIG91dCBvZiB5b3VyIHNwZWNp
YWwgc3ViamVjdCB5b3Ugd29ya2VkIG91dCB0aGUgd2Vla3MgYmVmb3JlIHRoZSBNYXR1cmEuCgpN
eSB0b3BpYyBmb3IgdGhlIGNvbXB1dGVyIHNjaWVuY2UgIkZhY2hiZXJlaWNoc2FyYmVpdCIgd2Fz
IHNlY3VyaXR5IGluIHdlYiBhcHBsaWNhdGlvbnMgYW5kIGFwcGFyZW50bHkgbXkgcHJlc2VudGF0
aW9uIHdhcyB0aGF0IGltcHJlc3NpdmUgdGhhdCBJIGdvdCBzb21lIGFwcGxhdXNlIHdoaWNoIHdh
cyBhIHZlcnksIHZlcnkgY29vbCBleHBlcmllbmNlLiBJIGhhZCBvbmUgb2YgdGhlIGxhc3QgZXhh
bXMgYW5kIHVzdWFsbHkgdGhlIHRlYWNoZXJzIGFuZCB0aGUgZXhhbWluZXIgYXJlIGFscmVhZHkg
c28gYm9yZWQgdGhhdCBub2JvZHkgbGlzdGVucyB0byB5b3VyIHRlbi1taW51dGUgdGFsay4gSXQn
cyBhIHJlYWxseSBjb29sIGZlZWxpbmcgdGhhdCB5b3Ugd2VyZSBhYmxlIHRvIHNvbWVob3cgaW1w
cmVzcyB0aGUgcGVyc29ucyBpbiB0aGUgcm9vbS4KCkkgc3RpbGwgZG9uJ3Qga25vdyB0aGUgZmlu
YWwgcmVzdWx0cyBidXQgSSBrbm93IHRoYXQgSSBnb3QgYSAiR3V0ZXIgRXJmb2xnIiB3aGljaCBp
cyB0aGUgc2Vjb25kIGJlc3QgcmVzdWx0IHlvdSBjYW4gZ2V0LgoKUGxhbnMgZm9yIHRoZSBuZXh0
IHR3byB3ZWVrczogT2ZmIHRvIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAJ2h0dHA6Ly9lbi53
aWtpcGVkaWEub3JnL3dpa2kvSW9zX0lzbGFuZFMAAAADSW9zUwAAAF8gd2l0aCBmcmllbmRzIDot
KSBhbmQgcmVsYXhpbmcuIFNvIGJhc2ljYWxseSBvZmYgZnJvbSBTdW5kYXkgdGhlIGZpcnN0IHRp
bGwgRnJpZGF5IHRoZSAxM3RoIDotKVMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAA
AEwAAA==
lunarbasti.wiesner@gmx.net2007-07-01T12:40:23Znono0Congratulations!Congratulations!SQAAAAJTAAAABGJvZHlSUwAAABBDb25ncmF0dWxhdGlvbnMhTAAAUwAAAAZwYXJzZXJTAAAABGh0
bWw=
I know I should learn…http://lucumr.pocoo.org/cogitations/2007/06/26/i-know-i-should-learn/2007-06-26T18:37:56Z2007-06-26T18:37:56ZArmin Ronacheri-know-i-should-learnyesyes2...but my random playlist played "No Quarter" by Led Zeppelin and I thought I was listening to Porcupine Tree. After a quick check I found what made me think so: The beginning of "My Ashes" by Porcupine Tree is definitively inspired by "No Quarter".
And now back learning....but my random playlist played "No Quarter" by Led Zeppelin and I thought I was listening to Porcupine Tree. After a quick check I found what made me think so: The beginning of "My Ashes" by Porcupine Tree is definitively inspired by "No Quarter".
And now back learning.SQAAAANTAAAABGJvZHlSUwAAAREuLi5idXQgbXkgcmFuZG9tIHBsYXlsaXN0IHBsYXllZCAiTm8g
UXVhcnRlciIgYnkgTGVkIFplcHBlbGluIGFuZCBJIHRob3VnaHQgSSB3YXMgbGlzdGVuaW5nIHRv
IFBvcmN1cGluZSBUcmVlLiBBZnRlciBhIHF1aWNrIGNoZWNrIEkgZm91bmQgd2hhdCBtYWRlIG1l
IHRoaW5rIHNvOiBUaGUgYmVnaW5uaW5nIG9mICJNeSBBc2hlcyIgYnkgUG9yY3VwaW5lIFRyZWUg
aXMgZGVmaW5pdGl2ZWx5IGluc3BpcmVkIGJ5ICJObyBRdWFydGVyIi4KCkFuZCBub3cgYmFjayBs
ZWFybmluZy5MAABTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Jinja on Cursehttp://lucumr.pocoo.org/cogitations/2007/06/24/jinja-on-curse/2007-06-24T06:33:15Z2007-06-24T06:33:15ZArmin Ronacherjinja-on-curseyesyes2The <a href="http://www.curse-gaming.com/">curse gaming</a> team is currently replacing the django template engine with Jinja for their webpage. Awesome :DThe <a href="http://www.curse-gaming.com/">curse gaming</a> team is currently replacing the django template engine with Jinja for their webpage. Awesome :DSQAAAANTAAAABGJvZHlSUwAAAARUaGUgTAABRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAcaHR0
cDovL3d3dy5jdXJzZS1nYW1pbmcuY29tL1MAAAAMY3Vyc2UgZ2FtaW5nUwAAAGAgdGVhbSBpcyBj
dXJyZW50bHkgcmVwbGFjaW5nIHRoZSBkamFuZ28gdGVtcGxhdGUgZW5naW5lIHdpdGggSmluamEg
Zm9yIHRoZWlyIHdlYnBhZ2UuIEF3ZXNvbWUgOkRTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50
cm9SUwAAAABMAAA=
Georg Brandl runs a Blog nowhttp://lucumr.pocoo.org/cogitations/2007/06/24/georg-brandl-runs-a-blog-now/2007-06-24T06:00:14Z2007-06-24T06:00:14ZArmin Ronachergeorg-brandl-runs-a-blog-nowyesyes2Georg Brandl with whom I work together at various open source projects hosted on pocoo.org now runs a blog at <a href="http://pyside.blogspot.com/">pyside.blogspot.com</a>. He's currently working on the new python documentation, and also the lead developer of the pygments source highlighter. Cool stuff!
<small>Happy blogging Georg :-)</small>Georg Brandl with whom I work together at various open source projects hosted on pocoo.org now runs a blog at <a href="http://pyside.blogspot.com/">pyside.blogspot.com</a>. He's currently working on the new python documentation, and also the lead developer of the pygments source highlighter. Cool stuff!
<small>Happy blogging Georg :-)</small>SQAAAANTAAAABGJvZHlSUwAAAG5HZW9yZyBCcmFuZGwgd2l0aCB3aG9tIEkgd29yayB0b2dldGhl
ciBhdCB2YXJpb3VzIG9wZW4gc291cmNlIHByb2plY3RzIGhvc3RlZCBvbiBwb2Nvby5vcmcgbm93
IHJ1bnMgYSBibG9nIGF0IEwAAkVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAG2h0dHA6Ly9weXNp
ZGUuYmxvZ3Nwb3QuY29tL1MAAAATcHlzaWRlLmJsb2dzcG90LmNvbVMAAACHLiBIZSdzIGN1cnJl
bnRseSB3b3JraW5nIG9uIHRoZSBuZXcgcHl0aG9uIGRvY3VtZW50YXRpb24sIGFuZCBhbHNvIHRo
ZSBsZWFkIGRldmVsb3BlciBvZiB0aGUgcHlnbWVudHMgc291cmNlIGhpZ2hsaWdodGVyLiBDb29s
IHN0dWZmIQoKRVMAAAAFc21hbGxMAABNAABTAAAAGEhhcHB5IGJsb2dnaW5nIEdlb3JnIDotKVMA
AAAAUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Ruby XMLRPC Vulnerabilityhttp://lucumr.pocoo.org/cogitations/2007/06/23/ruby-xmlrpc-vulnerability/2007-06-23T15:30:35Z2007-06-23T15:30:35ZArmin Ronacherruby-xmlrpc-vulnerabilityyesyes2Looks like the Ruby XMLRPC implementation still has a vulnerability:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="c1">#!/usr/bin/env ruby</span>
<span class="nb">require</span> <span class="s1">'xmlrpc/server'</span>
<span class="k">class</span> <span class="nc">TestHandler</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="mi">42</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">if</span> <span class="bp">__FILE__</span> <span class="o">==</span> <span class="vg">$0</span>
<span class="n">srv</span> <span class="o">=</span> <span class="no">XMLRPC</span><span class="o">::</span><span class="no">Server</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">5000</span><span class="p">)</span>
<span class="n">srv</span><span class="o">.</span><span class="n">add_handler</span><span class="p">(</span><span class="s1">'test'</span><span class="p">,</span> <span class="no">TestHandler</span><span class="o">.</span><span class="n">new</span><span class="p">)</span>
<span class="n">srv</span><span class="o">.</span><span class="n">serve</span>
<span class="k">end</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(ruby)>#!/usr/bin/env ruby
require 'xmlrpc/server'
class TestHandler
def foo
42
end
end
if __FILE__ == $0
srv = XMLRPC::Server.new(5000)
srv.add_handler('test', TestHandler.new)
srv.serve
end<PYGMENTS_RAW -->
Connecting to it with the python shell now does this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="gp">>>> </span><span class="k">from</span> <span class="nn">xmlrpclib</span> <span class="k">import</span> <span class="n">ServerProxy</span>
<span class="gp">>>> </span><span class="n">p</span> <span class="o">=</span> <span class="n">ServerProxy</span><span class="p">(</span><span class="s">"http://localhost:5000/"</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">p</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">'foo'</span><span class="p">)</span>
<span class="go">42</span>
<span class="gp">>>> </span><span class="n">p</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">'`'</span><span class="p">,</span> <span class="s">'echo "Shit"'</span><span class="p">)</span>
<span class="go">'Shit\\n'</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(pycon)>>>> from xmlrpclib import ServerProxy
>>> p = ServerProxy("http://localhost:5000/")
>>> p.test.send('foo')
42
>>> p.test.send('`', 'echo "Shit"')
'Shit\\\\n'<PYGMENTS_RAW -->
And something tells me there is no way to avoid this problem, so better just not use add_handler with a class. Explicit is better than implicit.
<strong>Update</strong> after some googeling i found someone that discovered the same: <a href="http://blogfranz.blogspot.com/2007/03/ruby-xml-rpc-server-arbitrary-shell.html">Ruby, Python, and an XML-RPC Server Arbitrary Shell Command Execution Flaw</a>.Looks like the Ruby XMLRPC implementation still has a vulnerability:
Connecting to it with the python shell now does this:
And something tells me there is no way to avoid this problem, so better just not use add_handler with a class. Explicit is better than implicit.
<strong>Update</strong> after some googeling i found someone that discovered the same: <a href="http://blogfranz.blogspot.com/2007/03/ruby-xml-rpc-server-arbitrary-shell.html">Ruby, Python, and an XML-RPC Server Arbitrary Shell Command Execution Flaw</a>.SQAAAANTAAAABGJvZHlSUwAAARJMb29rcyBsaWtlIHRoZSBSdWJ5IFhNTFJQQyBpbXBsZW1lbnRh
dGlvbiBzdGlsbCBoYXMgYSB2dWxuZXJhYmlsaXR5OgoKCgpDb25uZWN0aW5nIHRvIGl0IHdpdGgg
dGhlIHB5dGhvbiBzaGVsbCBub3cgZG9lcyB0aGlzOgoKCkFuZCBzb21ldGhpbmcgdGVsbHMgbWUg
dGhlcmUgaXMgbm8gd2F5IHRvIGF2b2lkIHRoaXMgcHJvYmxlbSwgc28gYmV0dGVyIGp1c3Qgbm90
IHVzZSBhZGRfaGFuZGxlciB3aXRoIGEgY2xhc3MuIEV4cGxpY2l0IGlzIGJldHRlciB0aGFuIGlt
cGxpY2l0LgoKTAACRVMAAAAGc3Ryb25nTAAATQAAUwAAAAZVcGRhdGVTAAAAQCBhZnRlciBzb21l
IGdvb2dlbGluZyBpIGZvdW5kIHNvbWVvbmUgdGhhdCBkaXNjb3ZlcmVkIHRoZSBzYW1lOiBFUwAA
AAFhTAAATQABUwAAAARocmVmUwAAAE5odHRwOi8vYmxvZ2ZyYW56LmJsb2dzcG90LmNvbS8yMDA3
LzAzL3J1YnkteG1sLXJwYy1zZXJ2ZXItYXJiaXRyYXJ5LXNoZWxsLmh0bWxTAAAASlJ1YnksIFB5
dGhvbiwgYW5kIGFuIFhNTC1SUEMgU2VydmVyIEFyYml0cmFyeSBTaGVsbCBDb21tYW5kIEV4ZWN1
dGlvbiBGbGF3UwAAAAEuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
I have four words for you…http://lucumr.pocoo.org/cogitations/2007/06/21/i-have-four-words-for-you/2007-06-21T20:55:24Z2007-06-21T20:55:24ZArmin Ronacheri-have-four-words-for-youyesyes2<a href="http://tirania.org/blog/archive/2007/Jun-21.html">I LOVE THIS TEAM</a><a href="http://tirania.org/blog/archive/2007/Jun-21.html">I LOVE THIS TEAM</a>SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADBodHRwOi8v
dGlyYW5pYS5vcmcvYmxvZy9hcmNoaXZlLzIwMDcvSnVuLTIxLmh0bWxTAAAAEEkgTE9WRSBUSElT
IFRFQU1TAAAAAFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
It’s a Patchday (sort of)http://lucumr.pocoo.org/cogitations/2007/06/21/its-a-patchday-sort-of/2007-06-21T20:14:47Z2007-06-21T20:14:47ZArmin Ronacherits-a-patchday-sort-ofyesyes2Today they released a new Wordpress version and there are a few security fixes in. Because I don't feel like upgrading I patched the holes myself, here what you should fix if you use wordpress:
Look for that in <tt>wp-includes/class-phpmailer.php</tt>:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="nv">$sendmail</span> <span class="o">=</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s">"%s -oi -f %s -t"</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="n">Sendmail</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="n">Sender</span><span class="p">);</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(perl)>$sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, $this->Sender);<PYGMENTS_RAW -->
Those **** forgot to escape shell commands, they forward it to popen a few lines later. How stupid...? Here's however is the fix:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="nv">$sendmail</span> <span class="o">=</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s">"%s -oi -f %s -t"</span><span class="p">,</span>
<span class="nv">$this</span><span class="o">-></span><span class="n">Sendmail</span><span class="p">,</span> <span class="n">escapeshellarg</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="n">Sender</span><span class="p">));</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(perl)>$sendmail = sprintf("%s -oi -f %s -t",
$this->Sendmail, escapeshellarg($this->Sender));<PYGMENTS_RAW -->
Then once again the xmlrpc.php file. Either delete it or make a cron that downloads the <a href="http://trac.wordpress.org/browser/trunk/xmlrpc.php?format=raw">the most recent one</a> automatically. They upgrade more escaping bugs then they actually announce...
And in the kubrick theme (if you use it or a derived theme) there is an XSS whole, they don't escape REQUEST_URI, just replace
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="cp"><?php</span> <span class="k">echo</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'REQUEST_URI'</span><span class="p">];</span> <span class="cp">?></span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(html+php)><?php echo $_SERVER['REQUEST_URI']; ?><PYGMENTS_RAW -->
with
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="cp"><?php</span> <span class="k">echo</span> <span class="nf">htmlspecialchars</span><span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'REQUEST_URI'</span><span class="p">]);</span> <span class="cp">?></span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(html+php)><?php echo htmlspecialchars($_SERVER['REQUEST_URI']); ?><PYGMENTS_RAW -->
<del datetime="2007-06-21T20:16:40+00:00">And the most interesting part about this update: <a href="http://trac.wordpress.org/query?status=closed&milestone=2.2.1&resolution=fixed&order=priority">security updates</a> are marked as "minor", a missing "<em>" is marked as major...</del>
<strong>Update:</strong> they just inverted the colors... my faultToday they released a new Wordpress version and there are a few security fixes in. Because I don't feel like upgrading I patched the holes myself, here what you should fix if you use wordpress:
Look for that in <tt>wp-includes/class-phpmailer.php</tt>:
Those **** forgot to escape shell commands, they forward it to popen a few lines later. How stupid...? Here's however is the fix:
Then once again the xmlrpc.php file. Either delete it or make a cron that downloads the <a href="http://trac.wordpress.org/browser/trunk/xmlrpc.php?format=raw">the most recent one</a> automatically. They upgrade more escaping bugs then they actually announce...
And in the kubrick theme (if you use it or a derived theme) there is an XSS whole, they don't escape REQUEST_URI, just replace
with
<del datetime="2007-06-21T20:16:40+00:00">And the most interesting part about this update: <a href="http://trac.wordpress.org/query?status=closed&milestone=2.2.1&resolution=fixed&order=priority">security updates</a> are marked as "minor", a missing "<em>" is marked as major...</del>
<strong>Update:</strong> they just inverted the colors... my faultSQAAAANTAAAABGJvZHlSUwAAANRUb2RheSB0aGV5IHJlbGVhc2VkIGEgbmV3IFdvcmRwcmVzcyB2
ZXJzaW9uIGFuZCB0aGVyZSBhcmUgYSBmZXcgc2VjdXJpdHkgZml4ZXMgaW4uIEJlY2F1c2UgSSBk
b24ndCBmZWVsIGxpa2UgdXBncmFkaW5nIEkgcGF0Y2hlZCB0aGUgaG9sZXMgbXlzZWxmLCBoZXJl
IHdoYXQgeW91IHNob3VsZCBmaXggaWYgeW91IHVzZSB3b3JkcHJlc3M6CgpMb29rIGZvciB0aGF0
IGluIEwABEVTAAAAAnR0TAAATQAAUwAAAB93cC1pbmNsdWRlcy9jbGFzcy1waHBtYWlsZXIucGhw
UwAAAN86CgpUaG9zZSAqKioqIGZvcmdvdCB0byBlc2NhcGUgc2hlbGwgY29tbWFuZHMsIHRoZXkg
Zm9yd2FyZCBpdCB0byBwb3BlbiBhIGZldyBsaW5lcyBsYXRlci4gSG93IHN0dXBpZC4uLj8gSGVy
ZSdzIGhvd2V2ZXIgaXMgdGhlIGZpeDoKCgpUaGVuIG9uY2UgYWdhaW4gdGhlIHhtbHJwYy5waHAg
ZmlsZS4gRWl0aGVyIGRlbGV0ZSBpdCBvciBtYWtlIGEgY3JvbiB0aGF0IGRvd25sb2FkcyB0aGUg
RVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAA9aHR0cDovL3RyYWMud29yZHByZXNzLm9yZy9icm93
c2VyL3RydW5rL3htbHJwYy5waHA/Zm9ybWF0PXJhd1MAAAATdGhlIG1vc3QgcmVjZW50IG9uZVMA
AADXIGF1dG9tYXRpY2FsbHkuIFRoZXkgdXBncmFkZSBtb3JlIGVzY2FwaW5nIGJ1Z3MgdGhlbiB0
aGV5IGFjdHVhbGx5IGFubm91bmNlLi4uCgpBbmQgaW4gdGhlIGt1YnJpY2sgdGhlbWUgKGlmIHlv
dSB1c2UgaXQgb3IgYSBkZXJpdmVkIHRoZW1lKSB0aGVyZSBpcyBhbiBYU1Mgd2hvbGUsIHRoZXkg
ZG9uJ3QgZXNjYXBlIFJFUVVFU1RfVVJJLCBqdXN0IHJlcGxhY2UKCndpdGgKCgpFUwAAAANkZWxM
AAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAF1odHRwOi8vdHJhYy53b3JkcHJlc3Mub3JnL3F1
ZXJ5P3N0YXR1cz1jbG9zZWQmbWlsZXN0b25lPTIuMi4xJnJlc29sdXRpb249Zml4ZWQmb3JkZXI9
cHJpb3JpdHlTAAAAEHNlY3VyaXR5IHVwZGF0ZXNTAAAAPiBhcmUgbWFya2VkIGFzICJtaW5vciIs
IGEgbWlzc2luZyAiPGVtPiIgaXMgbWFya2VkIGFzIG1ham9yLi4uTQABUwAAAAhkYXRldGltZVMA
AAAZMjAwNy0wNi0yMVQyMDoxNjo0MCswMDowMFMAAAAxQW5kIHRoZSBtb3N0IGludGVyZXN0aW5n
IHBhcnQgYWJvdXQgdGhpcyB1cGRhdGU6IFMAAAACCgpFUwAAAAZzdHJvbmdMAABNAABTAAAAB1Vw
ZGF0ZTpTAAAAKiB0aGV5IGp1c3QgaW52ZXJ0ZWQgdGhlIGNvbG9ycy4uLiBteSBmYXVsdFMAAAAG
cGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Schweiz ist lustighttp://lucumr.pocoo.org/cogitations/2007/06/21/schweiz-ist-lustig/2007-06-21T07:24:39Z2007-06-21T07:24:39ZArmin Ronacherschweiz-ist-lustigyesyes2<pre><__doc__> mitsuhiko: wenn du einen panzerfahrausweis (ausgestellt vom schweizer
militär) hast, und sie wieder eine rüstungsmaterialversteigerung machen,
kannst nen panzer mit nach hause nehmen (darfst aber keine munition für
ham). und im falle von radpanzern kriegst dafür ne strassenzulassung.
<__doc__> mitsuhiko: du darfst dir in der schweiz auch eine flak kanone in den
vorgarten stellen, solange du keine munition dafür hast.
<zod> braucht man auch unbedingt
<__doc__> schon
<__doc__> gab mal nen gerichtsfall hier, wo einer mit nem radpanzer mit
strassenzulassung an ampeln den geschützturm auf verkehrsteilnehmer
rotiert hat.</pre><pre><__doc__> mitsuhiko: wenn du einen panzerfahrausweis (ausgestellt vom schweizer
militär) hast, und sie wieder eine rüstungsmaterialversteigerung machen,
kannst nen panzer mit nach hause nehmen (darfst aber keine munition für
ham). und im falle von radpanzern kriegst dafür ne strassenzulassung.
<__doc__> mitsuhiko: du darfst dir in der schweiz auch eine flak kanone in den
vorgarten stellen, solange du keine munition dafür hast.
<zod> braucht man auch unbedingt
<__doc__> schon
<__doc__> gab mal nen gerichtsfall hier, wo einer mit nem radpanzer mit
strassenzulassung an ampeln den geschützturm auf verkehrsteilnehmer
rotiert hat.</pre>SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAANwcmVMAABNAABTAAACvjxfX2RvY19fPiBtaXRz
dWhpa286IHdlbm4gZHUgZWluZW4gcGFuemVyZmFocmF1c3dlaXMgKGF1c2dlc3RlbGx0IHZvbSBz
Y2h3ZWl6ZXIKICAgICAgICAgIG1pbGl0w6RyKSBoYXN0LCB1bmQgc2llIHdpZWRlciBlaW5lIHLD
vHN0dW5nc21hdGVyaWFsdmVyc3RlaWdlcnVuZyBtYWNoZW4sCiAgICAgICAgICBrYW5uc3QgbmVu
IHBhbnplciBtaXQgbmFjaCBoYXVzZSBuZWhtZW4gKGRhcmZzdCBhYmVyIGtlaW5lIG11bml0aW9u
IGbDvHIKICAgICAgICAgIGhhbSkuIHVuZCBpbSBmYWxsZSB2b24gcmFkcGFuemVybiBrcmllZ3N0
IGRhZsO8ciBuZSBzdHJhc3Nlbnp1bGFzc3VuZy4KPF9fZG9jX18+IG1pdHN1aGlrbzogZHUgZGFy
ZnN0IGRpciBpbiBkZXIgc2Nod2VpeiBhdWNoIGVpbmUgZmxhayBrYW5vbmUgaW4gZGVuCiAgICAg
ICAgICB2b3JnYXJ0ZW4gc3RlbGxlbiwgc29sYW5nZSBkdSBrZWluZSBtdW5pdGlvbiBkYWbDvHIg
aGFzdC4KICAgIDx6b2Q+IGJyYXVjaHQgbWFuIGF1Y2ggdW5iZWRpbmd0CjxfX2RvY19fPiBzY2hv
bgo8X19kb2NfXz4gZ2FiIG1hbCBuZW4gZ2VyaWNodHNmYWxsIGhpZXIsIHdvIGVpbmVyIG1pdCBu
ZW0gcmFkcGFuemVyIG1pdAogICAgICAgICAgc3RyYXNzZW56dWxhc3N1bmcgYW4gYW1wZWxuIGRl
biBnZXNjaMO8dHp0dXJtIGF1ZiB2ZXJrZWhyc3RlaWxuZWhtZXIKICAgICAgICAgIHJvdGllcnQg
aGF0LlMAAAAAUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Python 3000 Status Updatehttp://lucumr.pocoo.org/cogitations/2007/06/19/python-3000-status-update/2007-06-19T12:15:11Z2007-06-19T12:15:11ZArmin Ronacherpython-3000-status-updateyesyes2Guido gives a nice Python3000 status update: <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=208549">Python 3000 Status Update (Long!)</a>. One the one hand it's cool to see what changes, on the other hand I fear that porting all those WSGI apps over to Python 3000 will be a huge task.Guido gives a nice Python3000 status update: <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=208549">Python 3000 Status Update (Long!)</a>. One the one hand it's cool to see what changes, on the other hand I fear that porting all those WSGI apps over to Python 3000 will be a huge task.SQAAAANTAAAABGJvZHlSUwAAAC1HdWlkbyBnaXZlcyBhIG5pY2UgUHl0aG9uMzAwMCBzdGF0dXMg
dXBkYXRlOiBMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADhodHRwOi8vd3d3LmFydGltYS5j
b20vd2VibG9ncy92aWV3cG9zdC5qc3A/dGhyZWFkPTIwODU0OVMAAAAhUHl0aG9uIDMwMDAgU3Rh
dHVzIFVwZGF0ZSAoTG9uZyEpUwAAAJQuIE9uZSB0aGUgb25lIGhhbmQgaXQncyBjb29sIHRvIHNl
ZSB3aGF0IGNoYW5nZXMsIG9uIHRoZSBvdGhlciBoYW5kIEkgZmVhciB0aGF0IHBvcnRpbmcgYWxs
IHRob3NlIFdTR0kgYXBwcyBvdmVyIHRvIFB5dGhvbiAzMDAwIHdpbGwgYmUgYSBodWdlIHRhc2su
UwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
One Cloudhttp://lucumr.pocoo.org/cogitations/2007/06/18/one-cloud/2007-06-18T18:08:47Z2007-06-18T18:08:47ZArmin Ronacherone-cloudyesyes2<a href="http://www.youtube.com/watch?v=O4vvhpF6jz0">One Cloud</a>, played by Rob Martino on a <a href="http://en.wikipedia.org/wiki/Chapman_Stick">Chapman Stick</a>. Awesome :-)<a href="http://www.youtube.com/watch?v=O4vvhpF6jz0">One Cloud</a>, played by Rob Martino on a <a href="http://en.wikipedia.org/wiki/Chapman_Stick">Chapman Stick</a>. Awesome :-)SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACpodHRwOi8v
d3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9TzR2dmhwRjZqejBTAAAACU9uZSBDbG91ZFMAAAAdLCBw
bGF5ZWQgYnkgUm9iIE1hcnRpbm8gb24gYSBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACpodHRw
Oi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NoYXBtYW5fU3RpY2tTAAAADUNoYXBtYW4gU3RpY2tT
AAAADS4gQXdlc29tZSA6LSlTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
JavaScript Client Side Image Thumbnailinghttp://lucumr.pocoo.org/cogitations/2007/06/17/javascript-client-side-image-thumbnailing/2007-06-17T08:54:54Z2007-06-17T08:54:54ZArmin Ronacherjavascript-client-side-image-thumbnailingyesyes2First of all, the Quality of the thumbnail is quite bad, at least by now (just tested in firefox). Furthermore it's a bad idea to do thumbnailing on the clientside but it works.
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">function</span> <span class="nx">makeThumb</span><span class="p">(</span><span class="nx">src</span><span class="o">,</span> <span class="nx">canvas</span><span class="o">,</span> <span class="nx">width</span><span class="o">,</span> <span class="nx">height</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">canvas</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">width</span><span class="o">;</span>
<span class="nx">canvas</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span><span class="o">;</span>
<span class="k">var</span> <span class="nx">ctx</span> <span class="o">=</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">getContext</span><span class="p">(</span><span class="s1">'2d'</span><span class="p">);</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nx">scale</span><span class="p">(</span>
<span class="nx">width</span> <span class="o">/</span> <span class="nx">src</span><span class="p">.</span><span class="nx">width</span><span class="o">,</span>
<span class="nx">height</span> <span class="o">/</span> <span class="nx">src</span><span class="p">.</span><span class="nx">height</span>
<span class="p">);</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nx">drawImage</span><span class="p">(</span><span class="nx">src</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(javascript)>function makeThumb(src, canvas, width, height) {
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.scale(
width / src.width,
height / src.height
);
ctx.drawImage(src, 0, 0);
}<PYGMENTS_RAW -->
<strong>src</strong> must be an Image, <strong>canvas</strong> a canvas element and width/height is the size of the resulting thumbnail. If you want to get the image data of the thumbnail for saving on the server or whatever, you can do <tt>canvas.toDataURL()</tt> which returns the data of the image as base64 version of a png.First of all, the Quality of the thumbnail is quite bad, at least by now (just tested in firefox). Furthermore it's a bad idea to do thumbnailing on the clientside but it works.
<strong>src</strong> must be an Image, <strong>canvas</strong> a canvas element and width/height is the size of the resulting thumbnail. If you want to get the image data of the thumbnail for saving on the server or whatever, you can do <tt>canvas.toDataURL()</tt> which returns the data of the image as base64 version of a png.SQAAAANTAAAABGJvZHlSUwAAALNGaXJzdCBvZiBhbGwsIHRoZSBRdWFsaXR5IG9mIHRoZSB0aHVt
Ym5haWwgaXMgcXVpdGUgYmFkLCBhdCBsZWFzdCBieSBub3cgKGp1c3QgdGVzdGVkIGluIGZpcmVm
b3gpLiBGdXJ0aGVybW9yZSBpdCdzIGEgYmFkIGlkZWEgdG8gZG8gdGh1bWJuYWlsaW5nIG9uIHRo
ZSBjbGllbnRzaWRlIGJ1dCBpdCB3b3Jrcy4KCkwAA0VTAAAABnN0cm9uZ0wAAE0AAFMAAAADc3Jj
UwAAABMgbXVzdCBiZSBhbiBJbWFnZSwgRVMAAAAGc3Ryb25nTAAATQAAUwAAAAZjYW52YXNTAAAA
ryBhIGNhbnZhcyBlbGVtZW50IGFuZCB3aWR0aC9oZWlnaHQgaXMgdGhlIHNpemUgb2YgdGhlIHJl
c3VsdGluZyB0aHVtYm5haWwuIElmIHlvdSB3YW50IHRvIGdldCB0aGUgaW1hZ2UgZGF0YSBvZiB0
aGUgdGh1bWJuYWlsIGZvciBzYXZpbmcgb24gdGhlIHNlcnZlciBvciB3aGF0ZXZlciwgeW91IGNh
biBkbyBFUwAAAAJ0dEwAAE0AAFMAAAASY2FudmFzLnRvRGF0YVVSTCgpUwAAAEAgd2hpY2ggcmV0
dXJucyB0aGUgZGF0YSBvZiB0aGUgaW1hZ2UgYXMgYmFzZTY0IHZlcnNpb24gb2YgYSBwbmcuUwAA
AAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Another Way to Capture Print in Pythonhttp://lucumr.pocoo.org/cogitations/2007/06/17/another-way-to-capture-print-in-python/2007-06-16T23:04:53Z2007-06-16T23:04:53ZArmin Ronacheranother-way-to-capture-print-in-pythonyesyes2When working with the Python ast module i found the pycodegen which generates bytecode from an ast. Basically what you can do with it is modifying the ast before compiling the code. So one use case is compiling code and patching all Print/Printnl nodes without a destination to buffer into a stream:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">import</span> <span class="nn">compiler</span>
<span class="k">def</span> <span class="nf">compile_with_stream</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">stream</span><span class="p">,</span> <span class="n">filename</span><span class="o">=</span><span class="s">'?'</span><span class="p">):</span>
<span class="n">print_nodes</span> <span class="o">=</span> <span class="p">[</span><span class="n">compiler</span><span class="o">.</span><span class="n">ast</span><span class="o">.</span><span class="n">Print</span><span class="p">,</span> <span class="n">compiler</span><span class="o">.</span><span class="n">ast</span><span class="o">.</span><span class="n">Printnl</span><span class="p">]</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">compiler</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
<span class="n">nodes</span> <span class="o">=</span> <span class="p">[</span><span class="n">rv</span><span class="p">]</span>
<span class="k">while</span> <span class="n">nodes</span><span class="p">:</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">nodes</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">node</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span>
<span class="k">if</span> <span class="n">node</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">in</span> <span class="n">print_nodes</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">dest</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">node</span><span class="o">.</span><span class="n">dest</span> <span class="o">=</span> <span class="n">compiler</span><span class="o">.</span><span class="n">ast</span><span class="o">.</span><span class="n">Const</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">lineno</span><span class="p">)</span>
<span class="n">nodes</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">getChildNodes</span><span class="p">())</span>
<span class="n">gen</span> <span class="o">=</span> <span class="n">compiler</span><span class="o">.</span><span class="n">pycodegen</span><span class="o">.</span><span class="n">ModuleCodeGenerator</span><span class="p">(</span><span class="n">rv</span><span class="p">)</span>
<span class="k">return</span> <span class="n">gen</span><span class="o">.</span><span class="n">getCode</span><span class="p">()</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>import compiler
def compile_with_stream(code, stream, filename='?'):
print_nodes = [compiler.ast.Print, compiler.ast.Printnl]
rv = compiler.parse(code)
nodes = [rv]
while nodes:
node = nodes.pop()
node.filename = filename
if node.__class__ in print_nodes and node.dest is None:
node.dest = compiler.ast.Const(stream, node.lineno)
nodes.extend(node.getChildNodes())
gen = compiler.pycodegen.ModuleCodeGenerator(rv)
return gen.getCode()<PYGMENTS_RAW -->
Instead of using compiler.ast.Const you can also use compiler.ast.Name and point to a variable that contains the stream. This would allow caching the bytecode too. Now what it does is translating "print 'Hello World'" to "print >> stream, 'Hello World'" if there is no given destination. This can be useful for template engines (once again ^^).
Example usage:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">StringIO</span> <span class="k">import</span> <span class="n">StringIO</span>
<span class="n">stream</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
<span class="k">exec</span> <span class="n">compile_with_stream</span><span class="p">(</span><span class="s">'print "Hello World"'</span><span class="p">,</span> <span class="n">stream</span><span class="p">)</span>
<span class="k">print</span> <span class="s">'Captured: </span><span class="si">%r</span><span class="s">'</span> <span class="o">%</span> <span class="n">stream</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from StringIO import StringIO
stream = StringIO()
exec compile_with_stream('print "Hello World"', stream)
print 'Captured: %r' % stream.getvalue()<PYGMENTS_RAW -->When working with the Python ast module i found the pycodegen which generates bytecode from an ast. Basically what you can do with it is modifying the ast before compiling the code. So one use case is compiling code and patching all Print/Printnl nodes without a destination to buffer into a stream:
Instead of using compiler.ast.Const you can also use compiler.ast.Name and point to a variable that contains the stream. This would allow caching the bytecode too. Now what it does is translating "print 'Hello World'" to "print >> stream, 'Hello World'" if there is no given destination. This can be useful for template engines (once again ^^).
Example usage:
SQAAAANTAAAABGJvZHlSUwAAApZXaGVuIHdvcmtpbmcgd2l0aCB0aGUgUHl0aG9uIGFzdCBtb2R1
bGUgaSBmb3VuZCB0aGUgcHljb2RlZ2VuIHdoaWNoIGdlbmVyYXRlcyBieXRlY29kZSBmcm9tIGFu
IGFzdC4gQmFzaWNhbGx5IHdoYXQgeW91IGNhbiBkbyB3aXRoIGl0IGlzIG1vZGlmeWluZyB0aGUg
YXN0IGJlZm9yZSBjb21waWxpbmcgdGhlIGNvZGUuIFNvIG9uZSB1c2UgY2FzZSBpcyBjb21waWxp
bmcgY29kZSBhbmQgcGF0Y2hpbmcgYWxsIFByaW50L1ByaW50bmwgbm9kZXMgd2l0aG91dCBhIGRl
c3RpbmF0aW9uIHRvIGJ1ZmZlciBpbnRvIGEgc3RyZWFtOgoKSW5zdGVhZCBvZiB1c2luZyBjb21w
aWxlci5hc3QuQ29uc3QgeW91IGNhbiBhbHNvIHVzZSBjb21waWxlci5hc3QuTmFtZSBhbmQgcG9p
bnQgdG8gYSB2YXJpYWJsZSB0aGF0IGNvbnRhaW5zIHRoZSBzdHJlYW0uIFRoaXMgd291bGQgYWxs
b3cgY2FjaGluZyB0aGUgYnl0ZWNvZGUgdG9vLiBOb3cgd2hhdCBpdCBkb2VzIGlzIHRyYW5zbGF0
aW5nICJwcmludCAnSGVsbG8gV29ybGQnIiB0byAicHJpbnQgPj4gc3RyZWFtLCAnSGVsbG8gV29y
bGQnIiBpZiB0aGVyZSBpcyBubyBnaXZlbiBkZXN0aW5hdGlvbi4gVGhpcyBjYW4gYmUgdXNlZnVs
IGZvciB0ZW1wbGF0ZSBlbmdpbmVzIChvbmNlIGFnYWluIF5eKS4KCkV4YW1wbGUgdXNhZ2U6CkwA
AFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
any/all for Python2.4http://lucumr.pocoo.org/cogitations/2007/06/16/anyall-for-python24/2007-06-16T19:49:15Z2007-06-16T19:49:15ZArmin Ronacheranyall-for-python24yesyes2Want to use any/all in Python2.4? Here the minimal implementation that break on the first not matching value like any and all in Python2.5 do:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">def</span> <span class="nf">any</span><span class="p">(</span><span class="n">iterable</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">False</span> <span class="ow">in</span> <span class="p">(</span><span class="ow">not</span> <span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">iterable</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">all</span><span class="p">(</span><span class="n">iterable</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">True</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="ow">not</span> <span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">iterable</span><span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>def any(iterable):
return False in (not x for x in iterable)
def all(iterable):
return True not in (not x for x in iterable)<PYGMENTS_RAW -->
<small>Credit for the idea goes to BlackJack from the German python forum</small>Want to use any/all in Python2.4? Here the minimal implementation that break on the first not matching value like any and all in Python2.5 do:
<small>Credit for the idea goes to BlackJack from the German python forum</small>SQAAAANTAAAABGJvZHlSUwAAAJBXYW50IHRvIHVzZSBhbnkvYWxsIGluIFB5dGhvbjIuND8gSGVy
ZSB0aGUgbWluaW1hbCBpbXBsZW1lbnRhdGlvbiB0aGF0IGJyZWFrIG9uIHRoZSBmaXJzdCBub3Qg
bWF0Y2hpbmcgdmFsdWUgbGlrZSBhbnkgYW5kIGFsbCBpbiBQeXRob24yLjUgZG86CgpMAAFFUwAA
AAVzbWFsbEwAAE0AAFMAAABCQ3JlZGl0IGZvciB0aGUgaWRlYSBnb2VzIHRvIEJsYWNrSmFjayBm
cm9tIHRoZSBHZXJtYW4gcHl0aG9uIGZvcnVtUwAAAABTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAF
aW50cm9SUwAAAABMAAA=
Patching Python Tracebacks — Part Twohttp://lucumr.pocoo.org/cogitations/2007/06/16/patching-python-tracebacks-part-two/2007-06-16T09:54:44Z2007-06-16T09:54:44ZArmin Ronacherpatching-python-tracebacks-part-twoyesyes2<a href="http://lucumr.pocoo.org/cogitations/2007/06/15/patching-python-tracebacks/">After posting this</a> I hacked up a "tbtools" module that contains various traceback helper functions to modify tracebacks. You can find it here: <a href="http://lucumr.pocoo.org/trac/repos/tbtools/">tbtools</a>.
It's far from stable and I want to ask some of the authors of other template engines (namely zzeeek) for their ideas. There is also an example of the werkzeug minitmpl engine with support for tbtools. Now what it does is the following:
It converts this useless traceback of a template engine with code generation:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"templating.py"</span>, line <span class="m">151</span>, in <span class="n-Identifier"><module></span>
<span class="k">print</span> <span class="n">tmpl</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">broken</span><span class="o">=</span><span class="n">broken</span><span class="p">)</span>
File <span class="nb">"templating.py"</span>, line <span class="m">120</span>, in <span class="n-Identifier">render</span>
<span class="k">return</span> <span class="n">u</span><span class="s">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">tuple</span><span class="p">(</span><span class="n">tmp</span><span class="p">[</span><span class="s">'__generate'</span><span class="p">]()))</span>
File <span class="nb">"<template>"</span>, line <span class="m">10</span>, in <span class="n-Identifier">__generate</span>
File <span class="nb">"templating.py"</span>, line <span class="m">149</span>, in <span class="n-Identifier">broken</span>
<span class="n">foo</span><span class="p">()</span>
File <span class="nb">"templating.py"</span>, line <span class="m">148</span>, in <span class="n-Identifier">foo</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">"nested broken"</span><span class="p">)</span>
<span class="nc">RuntimeError</span>: <span class="n-Identifier">nested broken</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(pycon)>Traceback (most recent call last):
File "templating.py", line 151, in <module>
print tmpl.render(broken=broken)
File "templating.py", line 120, in render
return u''.join(tuple(tmp['__generate']()))
File "<template>", line 10, in __generate
File "templating.py", line 149, in broken
foo()
File "templating.py", line 148, in foo
raise RuntimeError("nested broken")
RuntimeError: nested broken<PYGMENTS_RAW -->
Into this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"templating.py"</span>, line <span class="m">151</span>, in <span class="n-Identifier"><module></span>
<span class="k">print</span> <span class="n">tmpl</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">broken</span><span class="o">=</span><span class="n">broken</span><span class="p">)</span>
File <span class="nb">"test.html"</span>, line <span class="m">3</span>, in <span class="n-Identifier"><module></span>
<span class="o"><%=</span> <span class="n">broken</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="o">%></span>
File <span class="nb">"templating.py"</span>, line <span class="m">149</span>, in <span class="n-Identifier">broken</span>
<span class="n">foo</span><span class="p">()</span>
File <span class="nb">"templating.py"</span>, line <span class="m">148</span>, in <span class="n-Identifier">foo</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s">"nested broken"</span><span class="p">)</span>
<span class="nc">RuntimeError</span>: <span class="n-Identifier">nested broken</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(pycon)>Traceback (most recent call last):
File "templating.py", line 151, in <module>
print tmpl.render(broken=broken)
File "test.html", line 3, in <module>
<%= broken(item) %>
File "templating.py", line 149, in broken
foo()
File "templating.py", line 148, in foo
raise RuntimeError("nested broken")
RuntimeError: nested broken<PYGMENTS_RAW -->
Because Python locks the traceback object a minimal C module is required. ctypes also doesn't work because the python API doesn't export the struct we need.<a href="http://lucumr.pocoo.org/cogitations/2007/06/15/patching-python-tracebacks/">After posting this</a> I hacked up a "tbtools" module that contains various traceback helper functions to modify tracebacks. You can find it here: <a href="http://lucumr.pocoo.org/trac/repos/tbtools/">tbtools</a>.
It's far from stable and I want to ask some of the authors of other template engines (namely zzeeek) for their ideas. There is also an example of the werkzeug minitmpl engine with support for tbtools. Now what it does is the following:
It converts this useless traceback of a template engine with code generation:
Into this:
Because Python locks the traceback object a minimal C module is required. ctypes also doesn't work because the python API doesn't export the struct we need.SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAEpodHRwOi8v
bHVjdW1yLnBvY29vLm9yZy9jb2dpdGF0aW9ucy8yMDA3LzA2LzE1L3BhdGNoaW5nLXB5dGhvbi10
cmFjZWJhY2tzL1MAAAASQWZ0ZXIgcG9zdGluZyB0aGlzUwAAAH0gSSBoYWNrZWQgdXAgYSAidGJ0
b29scyIgbW9kdWxlIHRoYXQgY29udGFpbnMgdmFyaW91cyB0cmFjZWJhY2sgaGVscGVyIGZ1bmN0
aW9ucyB0byBtb2RpZnkgdHJhY2ViYWNrcy4gWW91IGNhbiBmaW5kIGl0IGhlcmU6IEVTAAAAAWFM
AABNAAFTAAAABGhyZWZTAAAAK2h0dHA6Ly9sdWN1bXIucG9jb28ub3JnL3RyYWMvcmVwb3MvdGJ0
b29scy9TAAAAB3RidG9vbHNTAAAB6C4KCkl0J3MgZmFyIGZyb20gc3RhYmxlIGFuZCBJIHdhbnQg
dG8gYXNrIHNvbWUgb2YgdGhlIGF1dGhvcnMgb2Ygb3RoZXIgdGVtcGxhdGUgZW5naW5lcyAobmFt
ZWx5IHp6ZWVlaykgZm9yIHRoZWlyIGlkZWFzLiBUaGVyZSBpcyBhbHNvIGFuIGV4YW1wbGUgb2Yg
dGhlIHdlcmt6ZXVnIG1pbml0bXBsIGVuZ2luZSB3aXRoIHN1cHBvcnQgZm9yIHRidG9vbHMuIE5v
dyB3aGF0IGl0IGRvZXMgaXMgdGhlIGZvbGxvd2luZzoKCkl0IGNvbnZlcnRzIHRoaXMgdXNlbGVz
cyB0cmFjZWJhY2sgb2YgYSB0ZW1wbGF0ZSBlbmdpbmUgd2l0aCBjb2RlIGdlbmVyYXRpb246CgoK
SW50byB0aGlzOgoKQmVjYXVzZSBQeXRob24gbG9ja3MgdGhlIHRyYWNlYmFjayBvYmplY3QgYSBt
aW5pbWFsIEMgbW9kdWxlIGlzIHJlcXVpcmVkLiBjdHlwZXMgYWxzbyBkb2Vzbid0IHdvcmsgYmVj
YXVzZSB0aGUgcHl0aG9uIEFQSSBkb2Vzbid0IGV4cG9ydCB0aGUgc3RydWN0IHdlIG5lZWQuUwAA
AAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Pylons Screencastshttp://lucumr.pocoo.org/cogitations/2007/06/15/pylons-screencasts/2007-06-15T20:36:10Z2007-06-15T20:36:10ZArmin Ronacherpylons-screencastsyesyes2<a href="http://www.inklesspen.com/pylons/part-2.html">Part 3</a> of the <a href="http://pylonshq.com/">pylons</a> screencast is online. Good work Chairos.<a href="http://www.inklesspen.com/pylons/part-2.html">Part 3</a> of the <a href="http://pylonshq.com/">pylons</a> screencast is online. Good work Chairos.SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACxodHRwOi8v
d3d3Lmlua2xlc3NwZW4uY29tL3B5bG9ucy9wYXJ0LTIuaHRtbFMAAAAGUGFydCAzUwAAAAggb2Yg
dGhlIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAFGh0dHA6Ly9weWxvbnNocS5jb20vUwAAAAZw
eWxvbnNTAAAAKSBzY3JlZW5jYXN0IGlzIG9ubGluZS4gR29vZCB3b3JrIENoYWlyb3MuUwAAAAZw
YXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Patching Python Tracebackshttp://lucumr.pocoo.org/cogitations/2007/06/15/patching-python-tracebacks/2007-06-15T16:31:30Z2007-06-15T16:31:30ZArmin Ronacherpatching-python-tracebacksyesyes2So what's one of the greatest features Python has? Correct. Exceptions and Tracebacks. Especially the latter is a cool thing but it's also limited. Say you have a <a href="http://jinja.pocoo.org/">template engine</a> that generates code before executing the template. So if an runtime error occurs the message is correct but the line number points to the generated code and not the source line.
So how to fix? The plan basically is:
<ul>
<li>Have a generated line <-> source line mapping somewhere</li>
<li>catch exceptions that happen in the code execution and skip the first one or two frames until you reach the frame where the generated code is</li>
<li>reraise the exception in a isolated namespace but in the new line (hackish)</li>
<li>patch the traceback and inject your new traceback from the isolated frame (nearly impossible)</li>
</ul>
Now the mapping is the smallest problem, as well as the frame skipping (just access tb_next a couple of times). The real problems is reraising the exception in a different line and patching that new traceback into the traceback chain. There are solutions but it requires a C extension module and some code that you better hide. Still, it works :D
If you want to see how it's implemented check those files:
<ul>
<li><a href="http://trac.pocoo.org/browser/jinja/trunk/jinja/_debugger.c">_debugger.c</a></li>
<li><a href="http://trac.pocoo.org/browser/jinja/trunk/jinja/debugger.py">debugger.py</a></li>
</ul>
So yes. You can patch tracebacks and customize them, but it's deeper magic.So what's one of the greatest features Python has? Correct. Exceptions and Tracebacks. Especially the latter is a cool thing but it's also limited. Say you have a <a href="http://jinja.pocoo.org/">template engine</a> that generates code before executing the template. So if an runtime error occurs the message is correct but the line number points to the generated code and not the source line.
So how to fix? The plan basically is:
<ul>
<li>Have a generated line <-> source line mapping somewhere</li>
<li>catch exceptions that happen in the code execution and skip the first one or two frames until you reach the frame where the generated code is</li>
<li>reraise the exception in a isolated namespace but in the new line (hackish)</li>
<li>patch the traceback and inject your new traceback from the isolated frame (nearly impossible)</li>
</ul>
Now the mapping is the smallest problem, as well as the frame skipping (just access tb_next a couple of times). The real problems is reraising the exception in a different line and patching that new traceback into the traceback chain. There are solutions but it requires a C extension module and some code that you better hide. Still, it works :D
If you want to see how it's implemented check those files:
<ul>
<li><a href="http://trac.pocoo.org/browser/jinja/trunk/jinja/_debugger.c">_debugger.c</a></li>
<li><a href="http://trac.pocoo.org/browser/jinja/trunk/jinja/debugger.py">debugger.py</a></li>
</ul>
So yes. You can patch tracebacks and customize them, but it's deeper magic.SQAAAANTAAAABGJvZHlSUwAAAKNTbyB3aGF0J3Mgb25lIG9mIHRoZSBncmVhdGVzdCBmZWF0dXJl
cyBQeXRob24gaGFzPyBDb3JyZWN0LiBFeGNlcHRpb25zIGFuZCBUcmFjZWJhY2tzLiBFc3BlY2lh
bGx5IHRoZSBsYXR0ZXIgaXMgYSBjb29sIHRoaW5nIGJ1dCBpdCdzIGFsc28gbGltaXRlZC4gU2F5
IHlvdSBoYXZlIGEgTAADRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAXaHR0cDovL2ppbmphLnBv
Y29vLm9yZy9TAAAAD3RlbXBsYXRlIGVuZ2luZVMAAADaIHRoYXQgZ2VuZXJhdGVzIGNvZGUgYmVm
b3JlIGV4ZWN1dGluZyB0aGUgdGVtcGxhdGUuIFNvIGlmIGFuIHJ1bnRpbWUgZXJyb3Igb2NjdXJz
IHRoZSBtZXNzYWdlIGlzIGNvcnJlY3QgYnV0IHRoZSBsaW5lIG51bWJlciBwb2ludHMgdG8gdGhl
IGdlbmVyYXRlZCBjb2RlIGFuZCBub3QgdGhlIHNvdXJjZSBsaW5lLgoKU28gaG93IHRvIGZpeD8g
VGhlIHBsYW4gYmFzaWNhbGx5IGlzOgpFUwAAAAJ1bEwABEVTAAAAAmxpTAAATQAAUwAAADdIYXZl
IGEgZ2VuZXJhdGVkIGxpbmUgPC0+IHNvdXJjZSBsaW5lIG1hcHBpbmcgc29tZXdoZXJlUwAAAAMK
ICBFUwAAAAJsaUwAAE0AAFMAAACNY2F0Y2ggZXhjZXB0aW9ucyB0aGF0IGhhcHBlbiBpbiB0aGUg
Y29kZSBleGVjdXRpb24gYW5kIHNraXAgdGhlIGZpcnN0IG9uZSBvciB0d28gZnJhbWVzIHVudGls
IHlvdSByZWFjaCB0aGUgZnJhbWUgd2hlcmUgdGhlIGdlbmVyYXRlZCBjb2RlIGlzUwAAAAMKICBF
UwAAAAJsaUwAAE0AAFMAAABLcmVyYWlzZSB0aGUgZXhjZXB0aW9uIGluIGEgaXNvbGF0ZWQgbmFt
ZXNwYWNlIGJ1dCBpbiB0aGUgbmV3IGxpbmUgKGhhY2tpc2gpUwAAAAMKICBFUwAAAAJsaUwAAE0A
AFMAAABdcGF0Y2ggdGhlIHRyYWNlYmFjayBhbmQgaW5qZWN0IHlvdXIgbmV3IHRyYWNlYmFjayBm
cm9tIHRoZSBpc29sYXRlZCBmcmFtZSAobmVhcmx5IGltcG9zc2libGUpUwAAAAEKTQAAUwAAAAMK
ICBTAAABmQoKTm93IHRoZSBtYXBwaW5nIGlzIHRoZSBzbWFsbGVzdCBwcm9ibGVtLCBhcyB3ZWxs
IGFzIHRoZSBmcmFtZSBza2lwcGluZyAoanVzdCBhY2Nlc3MgdGJfbmV4dCBhIGNvdXBsZSBvZiB0
aW1lcykuIFRoZSByZWFsIHByb2JsZW1zIGlzIHJlcmFpc2luZyB0aGUgZXhjZXB0aW9uIGluIGEg
ZGlmZmVyZW50IGxpbmUgYW5kIHBhdGNoaW5nIHRoYXQgbmV3IHRyYWNlYmFjayBpbnRvIHRoZSB0
cmFjZWJhY2sgY2hhaW4uIFRoZXJlIGFyZSBzb2x1dGlvbnMgYnV0IGl0IHJlcXVpcmVzIGEgQyBl
eHRlbnNpb24gbW9kdWxlIGFuZCBzb21lIGNvZGUgdGhhdCB5b3UgYmV0dGVyIGhpZGUuIFN0aWxs
LCBpdCB3b3JrcyA6RAoKSWYgeW91IHdhbnQgdG8gc2VlIGhvdyBpdCdzIGltcGxlbWVudGVkIGNo
ZWNrIHRob3NlIGZpbGVzOgpFUwAAAAJ1bEwAAkVTAAAAAmxpTAABRVMAAAABYUwAAE0AAVMAAAAE
aHJlZlMAAAA7aHR0cDovL3RyYWMucG9jb28ub3JnL2Jyb3dzZXIvamluamEvdHJ1bmsvamluamEv
X2RlYnVnZ2VyLmNTAAAAC19kZWJ1Z2dlci5jUwAAAABNAABTAAAAAFMAAAADCiAgRVMAAAACbGlM
AAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADtodHRwOi8vdHJhYy5wb2Nvby5vcmcvYnJvd3Nl
ci9qaW5qYS90cnVuay9qaW5qYS9kZWJ1Z2dlci5weVMAAAALZGVidWdnZXIucHlTAAAAAE0AAFMA
AAAAUwAAAAEKTQAAUwAAAAMKICBTAAAATQoKU28geWVzLiBZb3UgY2FuIHBhdGNoIHRyYWNlYmFj
a3MgYW5kIGN1c3RvbWl6ZSB0aGVtLCBidXQgaXQncyBkZWVwZXIgbWFnaWMuUwAAAAZwYXJzZXJT
AAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Lucumr Cogitations » Blog Archive » Patching Python Tracebacks -- Part Twohttp://lucumr.pocoo.org/cogitations/2007/06/16/patching-python-tracebacks-part-two/2007-06-16T09:54:49Znoyes0[...] as response to this I hacked up a “tbtools” module that contains various traceback helper functions to modify tracebacks. You can find it here: tbtools. [...][...] as response to this I hacked up a “tbtools” module that contains various traceback helper functions to modify tracebacks. You can find it here: tbtools. [...]SQAAAAJTAAAABGJvZHlSUwAAAKhbLi4uXSBhcyByZXNwb25zZSB0byB0aGlzIEkgaGFja2VkIHVw
IGEg4oCcdGJ0b29sc+KAnSBtb2R1bGUgdGhhdCBjb250YWlucyB2YXJpb3VzIHRyYWNlYmFjayBo
ZWxwZXIgZnVuY3Rpb25zIHRvIG1vZGlmeSB0cmFjZWJhY2tzLiBZb3UgY2FuIGZpbmQgaXQgaGVy
ZTogdGJ0b29scy4gWy4uLl1MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
HTML5 Aheadhttp://lucumr.pocoo.org/cogitations/2007/06/14/html5-ahead/2007-06-14T21:31:25Z2007-06-14T21:31:25ZArmin Ronacherhtml5-aheadyesyes2<a href="http://dev.w3.org/cvsweb/~checkout~/html5/html4-differences/Overview.html">changes from HTML4</a> -- awesome. Let's forget about XHTML and friends and go with HTML5. The specs rock, rock, rock!<a href="http://dev.w3.org/cvsweb/~checkout~/html5/html4-differences/Overview.html">changes from HTML4</a> -- awesome. Let's forget about XHTML and friends and go with HTML5. The specs rock, rock, rock!SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAElodHRwOi8v
ZGV2LnczLm9yZy9jdnN3ZWIvfmNoZWNrb3V0fi9odG1sNS9odG1sNC1kaWZmZXJlbmNlcy9PdmVy
dmlldy5odG1sUwAAABJjaGFuZ2VzIGZyb20gSFRNTDRTAAAAYCAtLSBhd2Vzb21lLiBMZXQncyBm
b3JnZXQgYWJvdXQgWEhUTUwgYW5kIGZyaWVuZHMgYW5kIGdvIHdpdGggSFRNTDUuIFRoZSBzcGVj
cyByb2NrLCByb2NrLCByb2NrIVMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwA
AA==
Adrian Holovaty at Youtubehttp://lucumr.pocoo.org/cogitations/2007/06/14/adrian-holovati-at-youtube/2007-06-14T19:48:08Z2007-06-14T19:48:08ZArmin Ronacheradrian-holovati-at-youtubeyesyes2<a href="http://www.youtube.com/user/adrianholovaty">adrianholovaty</a> -- I didn't know that he posts videos of himself playing guitar there.<a href="http://www.youtube.com/user/adrianholovaty">adrianholovaty</a> -- I didn't know that he posts videos of himself playing guitar there.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACpodHRwOi8v
d3d3LnlvdXR1YmUuY29tL3VzZXIvYWRyaWFuaG9sb3ZhdHlTAAAADmFkcmlhbmhvbG92YXR5UwAA
AEcgLS0gSSBkaWRuJ3Qga25vdyB0aGF0IGhlIHBvc3RzIHZpZGVvcyBvZiBoaW1zZWxmIHBsYXlp
bmcgZ3VpdGFyIHRoZXJlLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Rafaelrafaelw@gmx.net2007-06-15T12:05:44Znono0Yeah, he do. His version of the MacGyver soundtrack <a href="http://holovaty.com/blog/archive/2007/04/30/1521" rel="nofollow">was one of the top featured videos</a> on YouTube for a short time.Yeah, he do. His version of the MacGyver soundtrack <a href="http://holovaty.com/blog/archive/2007/04/30/1521" rel="nofollow">was one of the top featured videos</a> on YouTube for a short time.SQAAAAJTAAAABGJvZHlSUwAAADRZZWFoLCBoZSBkby4gSGlzIHZlcnNpb24gb2YgdGhlIE1hY0d5
dmVyIHNvdW5kdHJhY2sgTAABRVMAAAABYUwAAE0AAlMAAAAEaHJlZlMAAAAwaHR0cDovL2hvbG92
YXR5LmNvbS9ibG9nL2FyY2hpdmUvMjAwNy8wNC8zMC8xNTIxUwAAAANyZWxTAAAACG5vZm9sbG93
UwAAACJ3YXMgb25lIG9mIHRoZSB0b3AgZmVhdHVyZWQgdmlkZW9zUwAAAB0gb24gWW91VHViZSBm
b3IgYSBzaG9ydCB0aW1lLlMAAAAGcGFyc2VyUwAAAARodG1s
Ville Säävuoriville@unessa.nethttp://www.unessa.net/en/2007-06-15T20:43:03Znono0His name is Holovaty, not Holovati.His name is Holovaty, not Holovati.SQAAAAJTAAAABGJvZHlSUwAAACNIaXMgbmFtZSBpcyBIb2xvdmF0eSwgbm90IEhvbG92YXRpLkwA
AFMAAAAGcGFyc2VyUwAAAARodG1s
mitsuhikoarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-06-17T09:25:48Znono0Oh dammit. Fixed it :)Oh dammit. Fixed it :)SQAAAAJTAAAABGJvZHlSUwAAABZPaCBkYW1taXQuIEZpeGVkIGl0IDopTAAAUwAAAAZwYXJzZXJT
AAAABGh0bWw=
SQLAlchemy Book Arrivinghttp://lucumr.pocoo.org/cogitations/2007/06/14/sqlalchemy-book-arriving/2007-06-14T19:31:30Z2007-06-14T19:31:30ZArmin Ronachersqlalchemy-book-arrivingyesyes2<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="nt"><zzzeek_> </span>well now im writing a book and the three or four little lines
on the web page are going to be like 15 pages for you to read, harder to iss
...
<span class="nt"><beachcoder> </span>zzzeeek - what book are you writing ?
<span class="nt"><zzzeek_> </span><span class="na">beachcoder:</span> the SA book
<span class="nt"><zzzeek_> </span>details to follow
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(irc)><zzzeek_> well now im writing a book and the three or four little lines
on the web page are going to be like 15 pages for you to read, harder to iss
...
<beachcoder> zzzeeek - what book are you writing ?
<zzzeek_> beachcoder: the SA book
<zzzeek_> details to follow<PYGMENTS_RAW -->
seen on #pylons, some minutes ago
seen on #pylons, some minutes agoSQAAAANTAAAABGJvZHlSUwAAACIKc2VlbiBvbiAjcHlsb25zLCBzb21lIG1pbnV0ZXMgYWdvTAAA
UwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Give us today our daily FUD…http://lucumr.pocoo.org/cogitations/2007/06/14/give-us-today-our-daily-fud/2007-06-14T19:19:16Z2007-06-14T19:19:16ZArmin Ronachergive-us-today-our-daily-fudyesyes2Microsoft once again supported a study that should prove that Microsoft products are superior to Open Source projects. This time the company that did the dirty work this time is <a href="http://www.wipro.com/">Wipro</a>, an Indian based technology company. Conclusion first: schools are happier with Microsoft solutions than with Open Source solutions, being Microsoft powered also means that your system is more stable and of course cheaper too. I guess nobody is surprised about those results.
But what's remarkable about that <em>study</em> is this:
<blockquote>For the purpose of study segmentation Wipro defines Open Source schools as any school that has adopted greater than 50% use of an OSS solution — in terms of installed base — on any one of the three ICT platform aspects. All schools not meeting these criteria are defined as Microsoft schools.</blockquote>
First of all: What's a school? Surprisingly there is no definition in that paper. There are enough schools powered by non Microsoft UNIX systems which are not open-sourced. So are those Microsoft schools now? It's interesting because it looks like that fight Microsoft is fighting is only against Open Source, leaving out proprietary solutions of competitors. The cool thing about this study is that they actually found open source schools:
<table class="standalone">
<tr><th>Country</th><th>Microsoft Schools</th><th>OSS Schools</th></tr>
<tr><td>France</td><td>8</td><td>8</td></tr>
<tr><td>Italy</td><td>10</td><td>7</td></tr>
<tr><td>Poland</td><td>6</td><td>8</td></tr>
<tr><td>Spain</td><td>7</td><td>10</td></tr>
<tr><td>Sweden</td><td>3</td><td>1</td></tr>
<tr><td>UK</td><td>5</td><td>0</td></tr>
</table>
For me this is great news. I expected that the result of the study would be: there are no open source schools. Because with the definition of what's an open source school from above in mind there are at least 73 schools in Europe that use more than 50% open source software. My school advertised some time ago that they used Linux on their computers but that was two years ago, only additionally to windows, nobody knew how to use LILO and the rest of the system was closed. So there is hope :D
Also the quotes are.... well.... priceless:
<blockquote>"We have about 20 dual-boot machines that came preloaded with Linux but no one ever uses them; everyone just prefers Windows." -- ICT Manager, Spanish secondary school</blockquote>
Everybody prefers in th in this context basically means: "everybody just knows". But hey, they came preloaded with Linux, that's good news, so there are actually companies shipping Linux.
<blockquote>"At our school, many of the computers are equipped with both Microsoft Office and Open Office -- but the students have a significant preference for the Microsoft solutions. -- Director of ICT for a secondary school in France</blockquote>
Who's surprised this time? Raise your hands. <strong>Now!</strong>. No hands? <small>except of some hands in the digg corner</small>
That really reminds me of my school, two years ago. We had (and still have) a proxy that filters incoming and outgoing data for "bad content". Usually you don't see that proxy, it just asks you for a password and blocks some useless websites like any URL with the word "nintendo" in it. That worked for a long time pretty well until /var was full and the proxy just locked any access because there was no more space for logging and $admin was unable to enabled log rotation or just find the issue. However. The result was that I installed portable firefox und my homefolder and just not enabled that darn proxy in the settings. After the issue was resolved by an external administrator I continued using firefox. Two weeks later the proxy was once again down but when I logged in I found out that one of my friends copied the portable firefox installer to the communication drive and even some really dumb users were using it. That trend continued and even when the network was working flawlessly again the firefox was still in use.
Two years later: Firefox is installed by default, just with the proxies enabled in the config. Because $admin is still the same nobody locked those configuration values (although it's possible) and most of the users just disable that proxy because it takes equally long to enter your password or just disable the proxy. And nowadays you see far more firefox users than IE users in the computer rooms.
So what's the conclusion of that firefox story? (At least in our school) people pick the default because it's the default and not because it's better. If you are used to IE, MS Office and friends you won't switch yourself because it "just works". But not necessarily better.
The rest of the paper isn't better, just another quote that is equally funny:
<blockquote>The ICT Manager pointed to the role of Microsoft PowerPoint in lesson
presentation. He stated that, “simply put, on Open Office, our results do not have the same visual quality as the
lessons our teachers create using Microsoft PowerPoint.”</blockquote>
<a href="http://tirania.org/blog/archive/2007/Jun-10.html">Visual quality</a>?
If you are still interested in that paper, it's downloadable as PDF from the Microsoft website here: <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a99aadb1-696d-4e09-bb0d-e62cb92522aa&DisplayLang=en">Wipro: ICT in European Schools</a>.Microsoft once again supported a study that should prove that Microsoft products are superior to Open Source projects. This time the company that did the dirty work this time is <a href="http://www.wipro.com/">Wipro</a>, an Indian based technology company. Conclusion first: schools are happier with Microsoft solutions than with Open Source solutions, being Microsoft powered also means that your system is more stable and of course cheaper too. I guess nobody is surprised about those results.
But what's remarkable about that <em>study</em> is this:
<blockquote>For the purpose of study segmentation Wipro defines Open Source schools as any school that has adopted greater than 50% use of an OSS solution — in terms of installed base — on any one of the three ICT platform aspects. All schools not meeting these criteria are defined as Microsoft schools.</blockquote>
First of all: What's a school? Surprisingly there is no definition in that paper. There are enough schools powered by non Microsoft UNIX systems which are not open-sourced. So are those Microsoft schools now? It's interesting because it looks like that fight Microsoft is fighting is only against Open Source, leaving out proprietary solutions of competitors. The cool thing about this study is that they actually found open source schools:
<table class="standalone">
<tbody><tr><th>Country</th><th>Microsoft Schools</th><th>OSS Schools</th></tr>
<tr><td>France</td><td>8</td><td>8</td></tr>
<tr><td>Italy</td><td>10</td><td>7</td></tr>
<tr><td>Poland</td><td>6</td><td>8</td></tr>
<tr><td>Spain</td><td>7</td><td>10</td></tr>
<tr><td>Sweden</td><td>3</td><td>1</td></tr>
<tr><td>UK</td><td>5</td><td>0</td></tr>
</tbody></table>
For me this is great news. I expected that the result of the study would be: there are no open source schools. Because with the definition of what's an open source school from above in mind there are at least 73 schools in Europe that use more than 50% open source software. My school advertised some time ago that they used Linux on their computers but that was two years ago, only additionally to windows, nobody knew how to use LILO and the rest of the system was closed. So there is hope :D
Also the quotes are.... well.... priceless:
<blockquote>"We have about 20 dual-boot machines that came preloaded with Linux but no one ever uses them; everyone just prefers Windows." -- ICT Manager, Spanish secondary school</blockquote>
Everybody prefers in th in this context basically means: "everybody just knows". But hey, they came preloaded with Linux, that's good news, so there are actually companies shipping Linux.
<blockquote>"At our school, many of the computers are equipped with both Microsoft Office and Open Office -- but the students have a significant preference for the Microsoft solutions. -- Director of ICT for a secondary school in France</blockquote>
Who's surprised this time? Raise your hands. <strong>Now!</strong>. No hands? <small>except of some hands in the digg corner</small>
That really reminds me of my school, two years ago. We had (and still have) a proxy that filters incoming and outgoing data for "bad content". Usually you don't see that proxy, it just asks you for a password and blocks some useless websites like any URL with the word "nintendo" in it. That worked for a long time pretty well until /var was full and the proxy just locked any access because there was no more space for logging and $admin was unable to enabled log rotation or just find the issue. However. The result was that I installed portable firefox und my homefolder and just not enabled that darn proxy in the settings. After the issue was resolved by an external administrator I continued using firefox. Two weeks later the proxy was once again down but when I logged in I found out that one of my friends copied the portable firefox installer to the communication drive and even some really dumb users were using it. That trend continued and even when the network was working flawlessly again the firefox was still in use.
Two years later: Firefox is installed by default, just with the proxies enabled in the config. Because $admin is still the same nobody locked those configuration values (although it's possible) and most of the users just disable that proxy because it takes equally long to enter your password or just disable the proxy. And nowadays you see far more firefox users than IE users in the computer rooms.
So what's the conclusion of that firefox story? (At least in our school) people pick the default because it's the default and not because it's better. If you are used to IE, MS Office and friends you won't switch yourself because it "just works". But not necessarily better.
The rest of the paper isn't better, just another quote that is equally funny:
<blockquote>The ICT Manager pointed to the role of Microsoft PowerPoint in lesson
presentation. He stated that, “simply put, on Open Office, our results do not have the same visual quality as the
lessons our teachers create using Microsoft PowerPoint.”</blockquote>
<a href="http://tirania.org/blog/archive/2007/Jun-10.html">Visual quality</a>?
If you are still interested in that paper, it's downloadable as PDF from the Microsoft website here: <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a99aadb1-696d-4e09-bb0d-e62cb92522aa&DisplayLang=en">Wipro: ICT in European Schools</a>.SQAAAANTAAAABGJvZHlSUwAAALJNaWNyb3NvZnQgb25jZSBhZ2FpbiBzdXBwb3J0ZWQgYSBzdHVk
eSB0aGF0IHNob3VsZCBwcm92ZSB0aGF0IE1pY3Jvc29mdCBwcm9kdWN0cyBhcmUgc3VwZXJpb3Ig
dG8gT3BlbiBTb3VyY2UgcHJvamVjdHMuIFRoaXMgdGltZSB0aGUgY29tcGFueSB0aGF0IGRpZCB0
aGUgZGlydHkgd29yayB0aGlzIHRpbWUgaXMgTAALRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAV
aHR0cDovL3d3dy53aXByby5jb20vUwAAAAVXaXByb1MAAAE3LCBhbiBJbmRpYW4gYmFzZWQgdGVj
aG5vbG9neSBjb21wYW55LiBDb25jbHVzaW9uIGZpcnN0OiBzY2hvb2xzIGFyZSBoYXBwaWVyIHdp
dGggTWljcm9zb2Z0IHNvbHV0aW9ucyB0aGFuIHdpdGggT3BlbiBTb3VyY2Ugc29sdXRpb25zLCBi
ZWluZyBNaWNyb3NvZnQgcG93ZXJlZCBhbHNvIG1lYW5zIHRoYXQgeW91ciBzeXN0ZW0gaXMgbW9y
ZSBzdGFibGUgYW5kIG9mIGNvdXJzZSBjaGVhcGVyIHRvby4gSSBndWVzcyBub2JvZHkgaXMgc3Vy
cHJpc2VkIGFib3V0IHRob3NlIHJlc3VsdHMuCgpCdXQgd2hhdCdzIHJlbWFya2FibGUgYWJvdXQg
dGhhdCBFUwAAAAJlbUwAAE0AAFMAAAAFc3R1ZHlTAAAACiBpcyB0aGlzOgpFUwAAAApibG9ja3F1
b3RlTAAATQAAUwAAAShGb3IgdGhlIHB1cnBvc2Ugb2Ygc3R1ZHkgc2VnbWVudGF0aW9uIFdpcHJv
IGRlZmluZXMgT3BlbiBTb3VyY2Ugc2Nob29scyBhcyBhbnkgc2Nob29sIHRoYXQgaGFzIGFkb3B0
ZWQgZ3JlYXRlciB0aGFuIDUwJSB1c2Ugb2YgYW4gT1NTIHNvbHV0aW9uIOKAlCBpbiB0ZXJtcyBv
ZiBpbnN0YWxsZWQgYmFzZSDigJQgb24gYW55IG9uZSBvZiB0aGUgdGhyZWUgSUNUIHBsYXRmb3Jt
IGFzcGVjdHMuIEFsbCBzY2hvb2xzIG5vdCBtZWV0aW5nIHRoZXNlIGNyaXRlcmlhIGFyZSBkZWZp
bmVkIGFzIE1pY3Jvc29mdCBzY2hvb2xzLlMAAAG7CgpGaXJzdCBvZiBhbGw6IFdoYXQncyBhIHNj
aG9vbD8gU3VycHJpc2luZ2x5IHRoZXJlIGlzIG5vIGRlZmluaXRpb24gaW4gdGhhdCBwYXBlci4g
VGhlcmUgYXJlIGVub3VnaCBzY2hvb2xzIHBvd2VyZWQgYnkgbm9uIE1pY3Jvc29mdCBVTklYIHN5
c3RlbXMgd2hpY2ggYXJlIG5vdCBvcGVuLXNvdXJjZWQuIFNvIGFyZSB0aG9zZSBNaWNyb3NvZnQg
c2Nob29scyBub3c/IEl0J3MgaW50ZXJlc3RpbmcgYmVjYXVzZSBpdCBsb29rcyBsaWtlIHRoYXQg
ZmlnaHQgTWljcm9zb2Z0IGlzIGZpZ2h0aW5nIGlzIG9ubHkgYWdhaW5zdCBPcGVuIFNvdXJjZSwg
bGVhdmluZyBvdXQgcHJvcHJpZXRhcnkgc29sdXRpb25zIG9mIGNvbXBldGl0b3JzLiBUaGUgY29v
bCB0aGluZyBhYm91dCB0aGlzIHN0dWR5IGlzIHRoYXQgdGhleSBhY3R1YWxseSBmb3VuZCBvcGVu
IHNvdXJjZSBzY2hvb2xzOgpFUwAAAAV0YWJsZUwAAUVTAAAABXRib2R5TAAHRVMAAAACdHJMAANF
UwAAAAJ0aEwAAE0AAFMAAAAHQ291bnRyeVMAAAAARVMAAAACdGhMAABNAABTAAAAEU1pY3Jvc29m
dCBTY2hvb2xzUwAAAABFUwAAAAJ0aEwAAE0AAFMAAAALT1NTIFNjaG9vbHNTAAAAAE0AAFMAAAAA
UwAAAAMKICBFUwAAAAJ0ckwAA0VTAAAAAnRkTAAATQAAUwAAAAZGcmFuY2VTAAAAAEVTAAAAAnRk
TAAATQAAUwAAAAE4UwAAAABFUwAAAAJ0ZEwAAE0AAFMAAAABOFMAAAAATQAAUwAAAABTAAAAAwog
IEVTAAAAAnRyTAADRVMAAAACdGRMAABNAABTAAAABUl0YWx5UwAAAABFUwAAAAJ0ZEwAAE0AAFMA
AAACMTBTAAAAAEVTAAAAAnRkTAAATQAAUwAAAAE3UwAAAABNAABTAAAAAFMAAAADCiAgRVMAAAAC
dHJMAANFUwAAAAJ0ZEwAAE0AAFMAAAAGUG9sYW5kUwAAAABFUwAAAAJ0ZEwAAE0AAFMAAAABNlMA
AAAARVMAAAACdGRMAABNAABTAAAAAThTAAAAAE0AAFMAAAAAUwAAAAMKICBFUwAAAAJ0ckwAA0VT
AAAAAnRkTAAATQAAUwAAAAVTcGFpblMAAAAARVMAAAACdGRMAABNAABTAAAAATdTAAAAAEVTAAAA
AnRkTAAATQAAUwAAAAIxMFMAAAAATQAAUwAAAABTAAAAAwogIEVTAAAAAnRyTAADRVMAAAACdGRM
AABNAABTAAAABlN3ZWRlblMAAAAARVMAAAACdGRMAABNAABTAAAAATNTAAAAAEVTAAAAAnRkTAAA
TQAAUwAAAAExUwAAAABNAABTAAAAAFMAAAADCiAgRVMAAAACdHJMAANFUwAAAAJ0ZEwAAE0AAFMA
AAACVUtTAAAAAEVTAAAAAnRkTAAATQAAUwAAAAE1UwAAAABFUwAAAAJ0ZEwAAE0AAFMAAAABMFMA
AAAATQAAUwAAAABTAAAAAQpNAABTAAAAAFMAAAAATQABUwAAAAVjbGFzc1MAAAAKc3RhbmRhbG9u
ZVMAAAADCiAgUwAAAh4KCkZvciBtZSB0aGlzIGlzIGdyZWF0IG5ld3MuIEkgZXhwZWN0ZWQgdGhh
dCB0aGUgcmVzdWx0IG9mIHRoZSBzdHVkeSB3b3VsZCBiZTogdGhlcmUgYXJlIG5vIG9wZW4gc291
cmNlIHNjaG9vbHMuIEJlY2F1c2Ugd2l0aCB0aGUgZGVmaW5pdGlvbiBvZiB3aGF0J3MgYW4gb3Bl
biBzb3VyY2Ugc2Nob29sIGZyb20gYWJvdmUgaW4gbWluZCB0aGVyZSBhcmUgYXQgbGVhc3QgNzMg
c2Nob29scyBpbiBFdXJvcGUgdGhhdCB1c2UgbW9yZSB0aGFuIDUwJSBvcGVuIHNvdXJjZSBzb2Z0
d2FyZS4gTXkgc2Nob29sIGFkdmVydGlzZWQgc29tZSB0aW1lIGFnbyB0aGF0IHRoZXkgdXNlZCBM
aW51eCBvbiB0aGVpciBjb21wdXRlcnMgYnV0IHRoYXQgd2FzIHR3byB5ZWFycyBhZ28sIG9ubHkg
YWRkaXRpb25hbGx5IHRvIHdpbmRvd3MsIG5vYm9keSBrbmV3IGhvdyB0byB1c2UgTElMTyBhbmQg
dGhlIHJlc3Qgb2YgdGhlIHN5c3RlbSB3YXMgY2xvc2VkLiBTbyB0aGVyZSBpcyBob3BlIDpECgpB
bHNvIHRoZSBxdW90ZXMgYXJlLi4uLiB3ZWxsLi4uLiBwcmljZWxlc3M6CkVTAAAACmJsb2NrcXVv
dGVMAABNAABTAAAApyJXZSBoYXZlIGFib3V0IDIwIGR1YWwtYm9vdCBtYWNoaW5lcyB0aGF0IGNh
bWUgcHJlbG9hZGVkIHdpdGggTGludXggYnV0IG5vIG9uZSBldmVyIHVzZXMgdGhlbTsgZXZlcnlv
bmUganVzdCBwcmVmZXJzIFdpbmRvd3MuIiAtLSBJQ1QgTWFuYWdlciwgU3BhbmlzaCBzZWNvbmRh
cnkgc2Nob29sUwAAAL4KRXZlcnlib2R5IHByZWZlcnMgaW4gdGggaW4gdGhpcyBjb250ZXh0IGJh
c2ljYWxseSBtZWFuczogImV2ZXJ5Ym9keSBqdXN0IGtub3dzIi4gQnV0IGhleSwgdGhleSBjYW1l
IHByZWxvYWRlZCB3aXRoIExpbnV4LCB0aGF0J3MgZ29vZCBuZXdzLCBzbyB0aGVyZSBhcmUgYWN0
dWFsbHkgY29tcGFuaWVzIHNoaXBwaW5nIExpbnV4LgoKRVMAAAAKYmxvY2txdW90ZUwAAE0AAFMA
AADgIkF0IG91ciBzY2hvb2wsIG1hbnkgb2YgdGhlIGNvbXB1dGVycyBhcmUgZXF1aXBwZWQgd2l0
aCBib3RoIE1pY3Jvc29mdCBPZmZpY2UgYW5kIE9wZW4gT2ZmaWNlIC0tIGJ1dCB0aGUgc3R1ZGVu
dHMgaGF2ZSBhIHNpZ25pZmljYW50IHByZWZlcmVuY2UgZm9yIHRoZSBNaWNyb3NvZnQgc29sdXRp
b25zLiAtLSBEaXJlY3RvciBvZiBJQ1QgZm9yIGEgc2Vjb25kYXJ5IHNjaG9vbCBpbiBGcmFuY2VT
AAAALgpXaG8ncyBzdXJwcmlzZWQgdGhpcyB0aW1lPyBSYWlzZSB5b3VyIGhhbmRzLiBFUwAAAAZz
dHJvbmdMAABNAABTAAAABE5vdyFTAAAADC4gTm8gaGFuZHM/IEVTAAAABXNtYWxsTAAATQAAUwAA
ACdleGNlcHQgb2Ygc29tZSBoYW5kcyBpbiB0aGUgZGlnZyBjb3JuZXJTAAAG/gpUaGF0IHJlYWxs
eSByZW1pbmRzIG1lIG9mIG15IHNjaG9vbCwgdHdvIHllYXJzIGFnby4gV2UgaGFkIChhbmQgc3Rp
bGwgaGF2ZSkgYSBwcm94eSB0aGF0IGZpbHRlcnMgaW5jb21pbmcgYW5kIG91dGdvaW5nIGRhdGEg
Zm9yICJiYWQgY29udGVudCIuIFVzdWFsbHkgeW91IGRvbid0IHNlZSB0aGF0IHByb3h5LCBpdCBq
dXN0IGFza3MgeW91IGZvciBhIHBhc3N3b3JkIGFuZCBibG9ja3Mgc29tZSB1c2VsZXNzIHdlYnNp
dGVzIGxpa2UgYW55IFVSTCB3aXRoIHRoZSB3b3JkICJuaW50ZW5kbyIgaW4gaXQuIFRoYXQgd29y
a2VkIGZvciBhIGxvbmcgdGltZSBwcmV0dHkgd2VsbCB1bnRpbCAvdmFyIHdhcyBmdWxsIGFuZCB0
aGUgcHJveHkganVzdCBsb2NrZWQgYW55IGFjY2VzcyBiZWNhdXNlIHRoZXJlIHdhcyBubyBtb3Jl
IHNwYWNlIGZvciBsb2dnaW5nIGFuZCAkYWRtaW4gd2FzIHVuYWJsZSB0byBlbmFibGVkIGxvZyBy
b3RhdGlvbiBvciBqdXN0IGZpbmQgdGhlIGlzc3VlLiBIb3dldmVyLiBUaGUgcmVzdWx0IHdhcyB0
aGF0IEkgaW5zdGFsbGVkIHBvcnRhYmxlIGZpcmVmb3ggdW5kIG15IGhvbWVmb2xkZXIgYW5kIGp1
c3Qgbm90IGVuYWJsZWQgdGhhdCBkYXJuIHByb3h5IGluIHRoZSBzZXR0aW5ncy4gQWZ0ZXIgdGhl
IGlzc3VlIHdhcyByZXNvbHZlZCBieSBhbiBleHRlcm5hbCBhZG1pbmlzdHJhdG9yIEkgY29udGlu
dWVkIHVzaW5nIGZpcmVmb3guIFR3byB3ZWVrcyBsYXRlciB0aGUgcHJveHkgd2FzIG9uY2UgYWdh
aW4gZG93biBidXQgd2hlbiBJIGxvZ2dlZCBpbiBJIGZvdW5kIG91dCB0aGF0IG9uZSBvZiBteSBm
cmllbmRzIGNvcGllZCB0aGUgcG9ydGFibGUgZmlyZWZveCBpbnN0YWxsZXIgdG8gdGhlIGNvbW11
bmljYXRpb24gZHJpdmUgYW5kIGV2ZW4gc29tZSByZWFsbHkgZHVtYiB1c2VycyB3ZXJlIHVzaW5n
IGl0LiBUaGF0IHRyZW5kIGNvbnRpbnVlZCBhbmQgZXZlbiB3aGVuIHRoZSBuZXR3b3JrIHdhcyB3
b3JraW5nIGZsYXdsZXNzbHkgYWdhaW4gdGhlIGZpcmVmb3ggd2FzIHN0aWxsIGluIHVzZS4KVHdv
IHllYXJzIGxhdGVyOiBGaXJlZm94IGlzIGluc3RhbGxlZCBieSBkZWZhdWx0LCBqdXN0IHdpdGgg
dGhlIHByb3hpZXMgZW5hYmxlZCBpbiB0aGUgY29uZmlnLiBCZWNhdXNlICRhZG1pbiBpcyBzdGls
bCB0aGUgc2FtZSBub2JvZHkgbG9ja2VkIHRob3NlIGNvbmZpZ3VyYXRpb24gdmFsdWVzIChhbHRo
b3VnaCBpdCdzIHBvc3NpYmxlKSBhbmQgbW9zdCBvZiB0aGUgdXNlcnMganVzdCBkaXNhYmxlIHRo
YXQgcHJveHkgYmVjYXVzZSBpdCB0YWtlcyBlcXVhbGx5IGxvbmcgdG8gZW50ZXIgeW91ciBwYXNz
d29yZCBvciBqdXN0IGRpc2FibGUgdGhlIHByb3h5LiBBbmQgbm93YWRheXMgeW91IHNlZSBmYXIg
bW9yZSBmaXJlZm94IHVzZXJzIHRoYW4gSUUgdXNlcnMgaW4gdGhlIGNvbXB1dGVyIHJvb21zLgoK
U28gd2hhdCdzIHRoZSBjb25jbHVzaW9uIG9mIHRoYXQgZmlyZWZveCBzdG9yeT8gKEF0IGxlYXN0
IGluIG91ciBzY2hvb2wpIHBlb3BsZSBwaWNrIHRoZSBkZWZhdWx0IGJlY2F1c2UgaXQncyB0aGUg
ZGVmYXVsdCBhbmQgbm90IGJlY2F1c2UgaXQncyBiZXR0ZXIuIElmIHlvdSBhcmUgdXNlZCB0byBJ
RSwgTVMgT2ZmaWNlIGFuZCBmcmllbmRzIHlvdSB3b24ndCBzd2l0Y2ggeW91cnNlbGYgYmVjYXVz
ZSBpdCAianVzdCB3b3JrcyIuIEJ1dCBub3QgbmVjZXNzYXJpbHkgYmV0dGVyLgoKVGhlIHJlc3Qg
b2YgdGhlIHBhcGVyIGlzbid0IGJldHRlciwganVzdCBhbm90aGVyIHF1b3RlIHRoYXQgaXMgZXF1
YWxseSBmdW5ueToKRVMAAAAKYmxvY2txdW90ZUwAAE0AAFMAAAD0VGhlIElDVCBNYW5hZ2VyIHBv
aW50ZWQgdG8gdGhlIHJvbGUgb2YgTWljcm9zb2Z0IFBvd2VyUG9pbnQgaW4gbGVzc29uCnByZXNl
bnRhdGlvbi4gSGUgc3RhdGVkIHRoYXQsIOKAnHNpbXBseSBwdXQsIG9uIE9wZW4gT2ZmaWNlLCBv
dXIgcmVzdWx0cyBkbyBub3QgaGF2ZSB0aGUgc2FtZSB2aXN1YWwgcXVhbGl0eSBhcyB0aGUKbGVz
c29ucyBvdXIgdGVhY2hlcnMgY3JlYXRlIHVzaW5nIE1pY3Jvc29mdCBQb3dlclBvaW50LuKAnVMA
AAABCkVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAMGh0dHA6Ly90aXJhbmlhLm9yZy9ibG9nL2Fy
Y2hpdmUvMjAwNy9KdW4tMTAuaHRtbFMAAAAOVmlzdWFsIHF1YWxpdHlTAAAAaD8KCklmIHlvdSBh
cmUgc3RpbGwgaW50ZXJlc3RlZCBpbiB0aGF0IHBhcGVyLCBpdCdzIGRvd25sb2FkYWJsZSBhcyBQ
REYgZnJvbSB0aGUgTWljcm9zb2Z0IHdlYnNpdGUgaGVyZTogRVMAAAABYUwAAE0AAVMAAAAEaHJl
ZlMAAABsaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL2Rvd25sb2Fkcy9kZXRhaWxzLmFzcHg/RmFt
aWx5SUQ9YTk5YWFkYjEtNjk2ZC00ZTA5LWJiMGQtZTYyY2I5MjUyMmFhJkRpc3BsYXlMYW5nPWVu
UwAAAB5XaXBybzogSUNUIGluIEV1cm9wZWFuIFNjaG9vbHNTAAAAAS5TAAAABnBhcnNlclMAAAAE
aHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Dream Theater — Scorehttp://lucumr.pocoo.org/cogitations/2007/06/14/dream-theater-score/2007-06-14T16:09:04Z2007-06-14T16:09:04ZArmin Ronacherdream-theater-scoreyesyes2Bought today as DVD, watched instantly. Paralyzed now. <a href="http://www.amazon.com/Dream-Theater-Anniversary-Octavarium-Orchestra/dp/B000GIWS7E/">buy it :-)</a>Bought today as DVD, watched instantly. Paralyzed now. <a href="http://www.amazon.com/Dream-Theater-Anniversary-Octavarium-Orchestra/dp/B000GIWS7E/">buy it :-)</a>SQAAAANTAAAABGJvZHlSUwAAADdCb3VnaHQgdG9kYXkgYXMgRFZELCB3YXRjaGVkIGluc3RhbnRs
eS4gUGFyYWx5emVkIG5vdy4gTAABRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAABTaHR0cDovL3d3
dy5hbWF6b24uY29tL0RyZWFtLVRoZWF0ZXItQW5uaXZlcnNhcnktT2N0YXZhcml1bS1PcmNoZXN0
cmEvZHAvQjAwMEdJV1M3RS9TAAAACmJ1eSBpdCA6LSlTAAAAAFMAAAAGcGFyc2VyUwAAAARodG1s
UwAAAAVpbnRyb1JTAAAAAEwAAA==
ERB for JavaScripthttp://lucumr.pocoo.org/cogitations/2007/06/14/erb-for-javascript/2007-06-14T14:18:11Z2007-06-14T14:18:11ZArmin Ronachererb-for-javascriptyesyes2Today I found <a href="http://cfis.savagexi.com/articles/2007/06/13/a-simple-lightweight-javascript-templating-engine">this</a> at <a href="http://programming.reddit.com/info/1y7xp/comments">reddit</a> and was stunned by the way it was implemented. I now created a similar implementation, it's just a little smaller, supports escaping and doesn't use an evil delimiter hack and it also supports all of the ERB goodness including the leading-percent sign block support.
Example:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">JSTemplate</span><span class="p">(</span><span class="s1">'\\</span>
<span class="s1"> <%# This is a nice little comment %>\\</span>
<span class="s1"> <p>Total number of users: <%= this.users.length %></p>\\</span>
<span class="s1"> <ul>\\</span>
<span class="s1"> <% each(this.users, function(user, idx) { %>\\</span>
<span class="s1"> <li>#<%= idx + 1 %> <%= escape(user) %></li>\\</span>
<span class="s1"> <% }) %>\\</span>
<span class="s1"> </ul>\\</span>
<span class="s1"> <p>Last updated on: <%= this.lastUpdate %>\\</span>
<span class="s1">'</span><span class="p">);</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'output'</span><span class="p">).</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">template</span><span class="p">.</span><span class="nx">render</span><span class="p">({</span>
<span class="nx">users</span><span class="o">:</span> <span class="p">[</span><span class="s1">'H4><0r'</span><span class="o">,</span> <span class="s1">'peter'</span><span class="o">,</span> <span class="s1">'anton'</span><span class="p">]</span><span class="o">,</span>
<span class="nx">lastUpdate</span><span class="o">:</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">()</span>
<span class="p">});</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(javascript)>var template = new JSTemplate('\\\\
<%# This is a nice little comment %>\\\\
<p>Total number of users: <%= this.users.length %></p>\\\\
<ul>\\\\
<% each(this.users, function(user, idx) { %>\\\\
<li>#<%= idx + 1 %> <%= escape(user) %></li>\\\\
<% }) %>\\\\
</ul>\\\\
<p>Last updated on: <%= this.lastUpdate %>\\\\
');
document.getElementById('output').innerHTML = template.render({
users: ['H4><0r', 'peter', 'anton'],
lastUpdate: new Date()
});<PYGMENTS_RAW -->
Available helper functions are <tt>each</tt> and <tt>escape</tt>, now guess what they do.
Sourcecode is here: <a href="http://lucumr.pocoo.org/trac/repos/jstemplates/">jstemplates</a>
<strong>Update:</strong> It can process ERB % statements now too.Today I found <a href="http://cfis.savagexi.com/articles/2007/06/13/a-simple-lightweight-javascript-templating-engine">this</a> at <a href="http://programming.reddit.com/info/1y7xp/comments">reddit</a> and was stunned by the way it was implemented. I now created a similar implementation, it's just a little smaller, supports escaping and doesn't use an evil delimiter hack and it also supports all of the ERB goodness including the leading-percent sign block support.
Example:
Available helper functions are <tt>each</tt> and <tt>escape</tt>, now guess what they do.
Sourcecode is here: <a href="http://lucumr.pocoo.org/trac/repos/jstemplates/">jstemplates</a>
<strong>Update:</strong> It can process ERB % statements now too.SQAAAANTAAAABGJvZHlSUwAAAA5Ub2RheSBJIGZvdW5kIEwABkVTAAAAAWFMAABNAAFTAAAABGhy
ZWZTAAAAXmh0dHA6Ly9jZmlzLnNhdmFnZXhpLmNvbS9hcnRpY2xlcy8yMDA3LzA2LzEzL2Etc2lt
cGxlLWxpZ2h0d2VpZ2h0LWphdmFzY3JpcHQtdGVtcGxhdGluZy1lbmdpbmVTAAAABHRoaXNTAAAA
BCBhdCBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADFodHRwOi8vcHJvZ3JhbW1pbmcucmVkZGl0
LmNvbS9pbmZvLzF5N3hwL2NvbW1lbnRzUwAAAAZyZWRkaXRTAAABNiBhbmQgd2FzIHN0dW5uZWQg
YnkgdGhlIHdheSBpdCB3YXMgaW1wbGVtZW50ZWQuIEkgbm93IGNyZWF0ZWQgYSBzaW1pbGFyIGlt
cGxlbWVudGF0aW9uLCBpdCdzIGp1c3QgYSBsaXR0bGUgc21hbGxlciwgc3VwcG9ydHMgZXNjYXBp
bmcgYW5kIGRvZXNuJ3QgdXNlIGFuIGV2aWwgZGVsaW1pdGVyIGhhY2sgYW5kIGl0IGFsc28gc3Vw
cG9ydHMgYWxsIG9mIHRoZSBFUkIgZ29vZG5lc3MgaW5jbHVkaW5nIHRoZSBsZWFkaW5nLXBlcmNl
bnQgc2lnbiBibG9jayBzdXBwb3J0LgoKRXhhbXBsZToKCkF2YWlsYWJsZSBoZWxwZXIgZnVuY3Rp
b25zIGFyZSBFUwAAAAJ0dEwAAE0AAFMAAAAEZWFjaFMAAAAFIGFuZCBFUwAAAAJ0dEwAAE0AAFMA
AAAGZXNjYXBlUwAAAC8sIG5vdyBndWVzcyB3aGF0IHRoZXkgZG8uCgpTb3VyY2Vjb2RlIGlzIGhl
cmU6IEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAL2h0dHA6Ly9sdWN1bXIucG9jb28ub3JnL3Ry
YWMvcmVwb3MvanN0ZW1wbGF0ZXMvUwAAAAtqc3RlbXBsYXRlc1MAAAACCgpFUwAAAAZzdHJvbmdM
AABNAABTAAAAB1VwZGF0ZTpTAAAAKSBJdCBjYW4gcHJvY2VzcyBFUkIgJSBzdGF0ZW1lbnRzIG5v
dyB0b28uUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
David Edelsteindbe2@lehigh.edu2007-07-10T01:36:57Znono0Very cool bit of code. I was fooling with it, trying to load the template text using an XMLHttpRequest, with the target document just a plain text document containing the markup, but I was having issues with preparing the template string to instantiate JSTemplate. To make it work for me I had to prepare the responseText as follows:
<pre> var req=new XMLHttpRequest();
req.open("GET", "sample.jst",false);
req.send(null);
var txt=req.responseText;
txt=txt.replace(/[\\n\\r]/g,""); //!!!!IMPORTANT
var template=new JSTemplate(txt);
document.getElementById('output').innerHTML=
template.render({
users: ['H4>
</pre>Very cool bit of code. I was fooling with it, trying to load the template text using an XMLHttpRequest, with the target document just a plain text document containing the markup, but I was having issues with preparing the template string to instantiate JSTemplate. To make it work for me I had to prepare the responseText as follows:
<pre>
var req=new XMLHttpRequest();
req.open("GET", "sample.jst",false);
req.send(null);
var txt=req.responseText;
txt=txt.replace(/[\\n\\r]/g,""); //!!!!IMPORTANT
var template=new JSTemplate(txt);
document.getElementById('output').innerHTML=
template.render({
users: ['H4>
</pre>SQAAAAJTAAAABGJvZHlSUwAAAVFWZXJ5IGNvb2wgYml0IG9mIGNvZGUuICBJIHdhcyBmb29saW5n
IHdpdGggaXQsIHRyeWluZyB0byBsb2FkIHRoZSB0ZW1wbGF0ZSB0ZXh0IHVzaW5nIGFuIFhNTEh0
dHBSZXF1ZXN0LCB3aXRoIHRoZSB0YXJnZXQgZG9jdW1lbnQganVzdCBhIHBsYWluIHRleHQgZG9j
dW1lbnQgY29udGFpbmluZyB0aGUgbWFya3VwLCBidXQgSSB3YXMgaGF2aW5nIGlzc3VlcyB3aXRo
IHByZXBhcmluZyB0aGUgdGVtcGxhdGUgc3RyaW5nIHRvIGluc3RhbnRpYXRlIEpTVGVtcGxhdGUu
ICBUbyBtYWtlIGl0IHdvcmsgZm9yIG1lIEkgaGFkIHRvIHByZXBhcmUgdGhlIHJlc3BvbnNlVGV4
dCBhcyBmb2xsb3dzOgoKTAABRVMAAAADcHJlTAAATQAAUwAAASsJCXZhciByZXE9bmV3IFhNTEh0
dHBSZXF1ZXN0KCk7CgkJcmVxLm9wZW4oIkdFVCIsICJzYW1wbGUuanN0IixmYWxzZSk7CgkJcmVx
LnNlbmQobnVsbCk7CgkJdmFyIHR4dD1yZXEucmVzcG9uc2VUZXh0OwoJCXR4dD10eHQucmVwbGFj
ZSgvW1xcblxccl0vZywiIik7IC8vISEhIUlNUE9SVEFOVAoJCXZhciB0ZW1wbGF0ZT1uZXcgSlNU
ZW1wbGF0ZSh0eHQpOwoJCWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvdXRwdXQnKS5pbm5lckhU
TUw9CgkJCXRlbXBsYXRlLnJlbmRlcih7CgkJCSAgICB1c2VyczogICAgICAgIFsnSDQ+ClMAAAAA
UwAAAAZwYXJzZXJTAAAABGh0bWw=
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-07-11T22:05:18Znono0In theory the newline replacement shouldn't be necessary. I wonder which browser you're using, probably the parser has to cope with the carriage return character too.In theory the newline replacement shouldn't be necessary. I wonder which browser you're using, probably the parser has to cope with the carriage return character too.SQAAAAJTAAAABGJvZHlSUwAAAKZJbiB0aGVvcnkgdGhlIG5ld2xpbmUgcmVwbGFjZW1lbnQgc2hv
dWxkbid0IGJlIG5lY2Vzc2FyeS4gSSB3b25kZXIgd2hpY2ggYnJvd3NlciB5b3UncmUgdXNpbmcs
IHByb2JhYmx5IHRoZSBwYXJzZXIgaGFzIHRvIGNvcGUgd2l0aCB0aGUgY2FycmlhZ2UgcmV0dXJu
IGNoYXJhY3RlciB0b28uTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
David Edelsteindbe2@lehigh.edu2007-07-12T14:12:22Znono0Hrm, your comment system cut off half my comment, I think that it didn't like that those > < in H4><or (so im going to use html-entities)....Anyways, It was word for word from your example code and you caught my drift anyways.
I'm using firefox, but maybe I should see how IE does it, but I doubt that it would work as expected either.
More interestingly though, your script does some pretty neat stuff that you didn't include in your example. check this example template out and you'll see that it works too!
<pre><% this.fcn=function(){%><p>P function called</p><%} ;%>\\
<%# This is a nice little comment %>\\
<p>Total number of users: <%= this.users.length %></p>\\
<ul>\\
<% each(this.users, function(user, idx) { %>\\
<li>#<%= idx + 1 %> <%= escape(user) %></li>\\n\\
<% }) %>\\
</ul>\\
<%this.fcn();%>\\
<p>Last updated on: <%= this.lastUpdate %>\\
');</pre>
I also made an iif function to include along with each and escape (can leave out the else function and this still works):
<pre> function iif(cond, t_stmt, f_stmt) {
if(cond){
return t_stmt();
}else if(f_stmt){
return f_stmt();
}
}</pre>
example:
<pre> <% iif(true,function(){%><br>is true<%}, function(){%><br>is false<%}) %>\\</pre>
you can even use the iif function using a template function as a parameter and it works too!
very nice.
- DaveHrm, your comment system cut off half my comment, I think that it didn't like that those > < in H4><or (so im going to use html-entities)....Anyways, It was word for word from your example code and you caught my drift anyways.
I'm using firefox, but maybe I should see how IE does it, but I doubt that it would work as expected either.
More interestingly though, your script does some pretty neat stuff that you didn't include in your example. check this example template out and you'll see that it works too!
<pre><% this.fcn=function(){%><p>P function called</p><%} ;%>\\
<%# This is a nice little comment %>\\
<p>Total number of users: <%= this.users.length %></p>\\
<ul>\\
<% each(this.users, function(user, idx) { %>\\
<li>#<%= idx + 1 %> <%= escape(user) %></li>\\n\\
<% }) %>\\
</ul>\\
<%this.fcn();%>\\
<p>Last updated on: <%= this.lastUpdate %>\\
');</pre>
I also made an iif function to include along with each and escape (can leave out the else function and this still works):
<pre> function iif(cond, t_stmt, f_stmt) {
if(cond){
return t_stmt();
}else if(f_stmt){
return f_stmt();
}
}</pre>
example:
<pre> <% iif(true,function(){%><br>is true<%}, function(){%><br>is false<%}) %>\\</pre>
you can even use the iif function using a template function as a parameter and it works too!
very nice.
- DaveSQAAAAJTAAAABGJvZHlSUwAAAgRIcm0sIHlvdXIgY29tbWVudCBzeXN0ZW0gY3V0IG9mZiBoYWxm
IG15IGNvbW1lbnQsIEkgdGhpbmsgdGhhdCBpdCBkaWRuJ3QgbGlrZSB0aGF0IHRob3NlID4gPCBp
biBIND48b3IgKHNvIGltIGdvaW5nIHRvIHVzZSBodG1sLWVudGl0aWVzKS4uLi5Bbnl3YXlzLCBJ
dCB3YXMgd29yZCBmb3Igd29yZCBmcm9tIHlvdXIgZXhhbXBsZSBjb2RlIGFuZCB5b3UgY2F1Z2h0
IG15IGRyaWZ0IGFueXdheXMuICAKCkknbSB1c2luZyBmaXJlZm94LCBidXQgbWF5YmUgSSBzaG91
bGQgc2VlIGhvdyBJRSBkb2VzIGl0LCBidXQgSSBkb3VidCB0aGF0IGl0IHdvdWxkIHdvcmsgYXMg
ZXhwZWN0ZWQgZWl0aGVyLgoKTW9yZSBpbnRlcmVzdGluZ2x5IHRob3VnaCwgeW91ciBzY3JpcHQg
ZG9lcyBzb21lIHByZXR0eSBuZWF0IHN0dWZmIHRoYXQgeW91IGRpZG4ndCBpbmNsdWRlIGluIHlv
dXIgZXhhbXBsZS4gIGNoZWNrIHRoaXMgZXhhbXBsZSB0ZW1wbGF0ZSBvdXQgYW5kIHlvdSdsbCBz
ZWUgdGhhdCBpdCB3b3JrcyB0b28hCgpMAANFUwAAAANwcmVMAABNAABTAAABfjwlIHRoaXMuZmNu
PWZ1bmN0aW9uKCl7JT48cD5QIGZ1bmN0aW9uIGNhbGxlZDwvcD48JX0gOyU+XFwKICAgIDwlIyBU
aGlzIGlzIGEgbmljZSBsaXR0bGUgY29tbWVudCAlPlxcCiAgICA8cD5Ub3RhbCBudW1iZXIgb2Yg
dXNlcnM6IDwlPSB0aGlzLnVzZXJzLmxlbmd0aCAlPjwvcD5cXAogICAgPHVsPlxcCiAgICA8JSBl
YWNoKHRoaXMudXNlcnMsIGZ1bmN0aW9uKHVzZXIsIGlkeCkgeyAlPlxcCiAgICAgIDxsaT4jPCU9
IGlkeCArIDEgJT4gPCU9IGVzY2FwZSh1c2VyKSAlPjwvbGk+XFxuXFwKICAgIDwlIH0pICU+XFwK
ICAgIDwvdWw+XFwKICAgIDwldGhpcy5mY24oKTslPlxcCiAgICA8cD5MYXN0IHVwZGF0ZWQgb246
IDwlPSB0aGlzLmxhc3RVcGRhdGUgJT5cXAonKTtTAAAAfQoKSSBhbHNvIG1hZGUgYW4gaWlmIGZ1
bmN0aW9uIHRvIGluY2x1ZGUgYWxvbmcgd2l0aCBlYWNoIGFuZCBlc2NhcGUgKGNhbiBsZWF2ZSBv
dXQgdGhlIGVsc2UgZnVuY3Rpb24gYW5kIHRoaXMgc3RpbGwgd29ya3MpOgoKRVMAAAADcHJlTAAA
TQAAUwAAAHggIGZ1bmN0aW9uIGlpZihjb25kLCB0X3N0bXQsIGZfc3RtdCkgewogICAgaWYoY29u
ZCl7CglyZXR1cm4gdF9zdG10KCk7CiAgICB9ZWxzZSBpZihmX3N0bXQpewoJcmV0dXJuIGZfc3Rt
dCgpOwogICAgfQogIH1TAAAADAoKZXhhbXBsZToKCkVTAAAAA3ByZUwAAE0AAFMAAABMIDwlIGlp
Zih0cnVlLGZ1bmN0aW9uKCl7JT48YnI+aXMgdHJ1ZTwlfSwgZnVuY3Rpb24oKXslPjxicj5pcyBm
YWxzZTwlfSkgJT5cXFMAAAByCgp5b3UgY2FuIGV2ZW4gdXNlIHRoZSBpaWYgZnVuY3Rpb24gdXNp
bmcgYSB0ZW1wbGF0ZSBmdW5jdGlvbiBhcyBhIHBhcmFtZXRlciBhbmQgaXQgd29ya3MgdG9vIQoK
dmVyeSBuaWNlLgoKLSBEYXZlUwAAAAZwYXJzZXJTAAAABGh0bWw=
Charles Cookegroups@codebiz.ca2007-07-22T22:58:32Znono0Hiya, wanted this working in IE6 and found a couple things that made it work:
-the split function doesn't behave properly with regexp captures (used http://blog.stevenlevithan.com/archives/cross-browser-split to fix)
-indexing strings in IE doesn't work, so replaced all string indexes (part[0], etc.) w/ part.charAt(0)
-eval function in IE doesn't work, fix is at http://arrix.blogspot.com/2007/04/eval-bug-in-ie.htmlHiya, wanted this working in IE6 and found a couple things that made it work:
-the split function doesn't behave properly with regexp captures (used http://blog.stevenlevithan.com/archives/cross-browser-split to fix)
-indexing strings in IE doesn't work, so replaced all string indexes (part[0], etc.) w/ part.charAt(0)
-eval function in IE doesn't work, fix is at http://arrix.blogspot.com/2007/04/eval-bug-in-ie.htmlSQAAAAJTAAAABGJvZHlSUwAAAaJIaXlhLCB3YW50ZWQgdGhpcyB3b3JraW5nIGluIElFNiBhbmQg
Zm91bmQgYSBjb3VwbGUgdGhpbmdzIHRoYXQgbWFkZSBpdCB3b3JrOgotdGhlIHNwbGl0IGZ1bmN0
aW9uIGRvZXNuJ3QgYmVoYXZlIHByb3Blcmx5IHdpdGggcmVnZXhwIGNhcHR1cmVzICh1c2VkIGh0
dHA6Ly9ibG9nLnN0ZXZlbmxldml0aGFuLmNvbS9hcmNoaXZlcy9jcm9zcy1icm93c2VyLXNwbGl0
IHRvIGZpeCkKLWluZGV4aW5nIHN0cmluZ3MgaW4gSUUgZG9lc24ndCB3b3JrLCBzbyByZXBsYWNl
ZCBhbGwgc3RyaW5nIGluZGV4ZXMgKHBhcnRbMF0sIGV0Yy4pIHcvIHBhcnQuY2hhckF0KDApCi1l
dmFsIGZ1bmN0aW9uIGluIElFIGRvZXNuJ3Qgd29yaywgZml4IGlzIGF0IGh0dHA6Ly9hcnJpeC5i
bG9nc3BvdC5jb20vMjAwNy8wNC9ldmFsLWJ1Zy1pbi1pZS5odG1sTAAAUwAAAAZwYXJzZXJTAAAA
BGh0bWw=
DBUS Introspectionhttp://lucumr.pocoo.org/cogitations/2007/06/13/dbus-introspection/2007-06-13T16:06:03Z2007-06-13T16:06:03ZArmin Ronacherdbus-introspectionyesyes2Small snippet to get all the methods an DBus object supports:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">dbus</span> <span class="k">import</span> <span class="n">SessionBus</span><span class="p">,</span> <span class="n">Interface</span>
<span class="k">from</span> <span class="nn">dbus.introspect_parser</span> <span class="k">import</span> <span class="n">process_introspection_data</span>
<span class="k">def</span> <span class="nf">introspect_object</span><span class="p">(</span><span class="n">named_service</span><span class="p">,</span> <span class="n">object_path</span><span class="p">):</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">SessionBus</span><span class="p">()</span><span class="o">.</span><span class="n">get_object</span><span class="p">(</span><span class="n">named_service</span><span class="p">,</span> <span class="n">object_path</span><span class="p">)</span>
<span class="n">iface</span> <span class="o">=</span> <span class="n">Interface</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">'org.freedesktop.DBus.Introspectable'</span><span class="p">)</span>
<span class="k">return</span> <span class="n">process_introspection_data</span><span class="p">(</span><span class="n">iface</span><span class="o">.</span><span class="n">Introspect</span><span class="p">())</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from dbus import SessionBus, Interface
from dbus.introspect_parser import process_introspection_data
def introspect_object(named_service, object_path):
obj = SessionBus().get_object(named_service, object_path)
iface = Interface(obj, 'org.freedesktop.DBus.Introspectable')
return process_introspection_data(iface.Introspect())<PYGMENTS_RAW -->
Example usage:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="gp">>>> </span><span class="n">introspect_object</span><span class="p">(</span><span class="s">'org.gnome.Rhythmbox'</span><span class="p">,</span> <span class="s">'/org/gnome/Rhythmbox/Shell'</span><span class="p">)</span>
<span class="go">{'org.freedesktop.DBus.Introspectable.Introspect': '',</span>
<span class="go"> 'org.freedesktop.DBus.Properties.Get': 'ss',</span>
<span class="go"> 'org.freedesktop.DBus.Properties.Set': 'ssv',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.addToQueue': 's',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.clearQueue': '',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.getPlayer': '',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.getPlaylistManager': '',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.getSongProperties': 's',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.loadURI': 'sb',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.present': 'u',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.quit': '',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.removeFromQueue': 's',</span>
<span class="go"> 'org.gnome.Rhythmbox.Shell.setSongProperty': 'ssv'}</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(pycon)>>>> introspect_object('org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Shell')
{'org.freedesktop.DBus.Introspectable.Introspect': '',
'org.freedesktop.DBus.Properties.Get': 'ss',
'org.freedesktop.DBus.Properties.Set': 'ssv',
'org.gnome.Rhythmbox.Shell.addToQueue': 's',
'org.gnome.Rhythmbox.Shell.clearQueue': '',
'org.gnome.Rhythmbox.Shell.getPlayer': '',
'org.gnome.Rhythmbox.Shell.getPlaylistManager': '',
'org.gnome.Rhythmbox.Shell.getSongProperties': 's',
'org.gnome.Rhythmbox.Shell.loadURI': 'sb',
'org.gnome.Rhythmbox.Shell.present': 'u',
'org.gnome.Rhythmbox.Shell.quit': '',
'org.gnome.Rhythmbox.Shell.removeFromQueue': 's',
'org.gnome.Rhythmbox.Shell.setSongProperty': 'ssv'}<PYGMENTS_RAW -->
Unfortunately this does not show the names of the arguments, just the types thereof. If you remove the process_introspection_data call you get back a string with the XML data containing all the introspection information. You can then parse it on your own, the format is straightforward.Small snippet to get all the methods an DBus object supports:
Example usage:
Unfortunately this does not show the names of the arguments, just the types thereof. If you remove the process_introspection_data call you get back a string with the XML data containing all the introspection information. You can then parse it on your own, the format is straightforward.SQAAAANTAAAABGJvZHlSUwAAAW1TbWFsbCBzbmlwcGV0IHRvIGdldCBhbGwgdGhlIG1ldGhvZHMg
YW4gREJ1cyBvYmplY3Qgc3VwcG9ydHM6CgpFeGFtcGxlIHVzYWdlOgoKVW5mb3J0dW5hdGVseSB0
aGlzIGRvZXMgbm90IHNob3cgdGhlIG5hbWVzIG9mIHRoZSBhcmd1bWVudHMsIGp1c3QgdGhlIHR5
cGVzIHRoZXJlb2YuIElmIHlvdSByZW1vdmUgdGhlIHByb2Nlc3NfaW50cm9zcGVjdGlvbl9kYXRh
IGNhbGwgeW91IGdldCBiYWNrIGEgc3RyaW5nIHdpdGggdGhlIFhNTCBkYXRhIGNvbnRhaW5pbmcg
YWxsIHRoZSBpbnRyb3NwZWN0aW9uIGluZm9ybWF0aW9uLiBZb3UgY2FuIHRoZW4gcGFyc2UgaXQg
b24geW91ciBvd24sIHRoZSBmb3JtYXQgaXMgc3RyYWlnaHRmb3J3YXJkLkwAAFMAAAAGcGFyc2Vy
UwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Expression Based XChat Commands via the Python Plugin Interfacehttp://lucumr.pocoo.org/cogitations/2007/06/13/expression-based-xchat-commands-via-the-python-plugin-interface/2007-06-13T13:58:30Z2007-06-13T13:58:30ZArmin Ronacherexpression-based-xchat-commands-via-the-python-plugin-interfaceyesyes2XChat does not support implicit or regular expression based hooks or something similar. You can only register a callback for a <tt>/SOMETHING</tt> command. But there are ways.
Basically what you have to do is to register your callback to the <tt>""</tt> command and make sure that it handles it's own dispatching. Here a small example that converts <tt>[[Foo]]</tt> to <tt>http://en.wikipedia.org/wiki/Foo</tt>:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">import</span> <span class="nn">re</span>
<span class="k">from</span> <span class="nn">urllib</span> <span class="k">import</span> <span class="n">quote</span>
<span class="n">link_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">r'</span><span class="se">\\</span><span class="s">[</span><span class="se">\\</span><span class="s">[([^</span><span class="se">\\</span><span class="s">]]+)</span><span class="se">\\</span><span class="s">]</span><span class="se">\\</span><span class="s">]'</span><span class="p">)</span>
<span class="n">link_base</span> <span class="o">=</span> <span class="s">'http://en.wikipedia.org/wiki/'</span>
<span class="n">listening</span> <span class="o">=</span> <span class="p">[</span><span class="bp">True</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">expand_wikipedia_link</span><span class="p">(</span><span class="n">word</span><span class="p">,</span> <span class="n">word_eol</span><span class="p">,</span> <span class="n">userdata</span><span class="p">):</span>
<span class="k">if</span> <span class="n">listening</span> <span class="ow">and</span> <span class="n">word_eol</span><span class="p">:</span>
<span class="k">del</span> <span class="n">listening</span><span class="p">[:]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">has_match</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">handle_match</span><span class="p">(</span><span class="n">m</span><span class="p">):</span>
<span class="n">has_match</span><span class="p">[:]</span> <span class="o">=</span> <span class="p">[</span><span class="bp">True</span><span class="p">]</span>
<span class="k">return</span> <span class="n">link_base</span> <span class="o">+</span> <span class="n">quote</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span> <span class="s">'_'</span><span class="p">)</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">link_re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="n">handle_match</span><span class="p">,</span> <span class="n">word_eol</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">if</span> <span class="n">has_match</span><span class="p">:</span>
<span class="n">xchat</span><span class="o">.</span><span class="n">command</span><span class="p">(</span><span class="s">'say '</span> <span class="o">+</span> <span class="n">text</span><span class="p">)</span>
<span class="k">return</span> <span class="n">xchat</span><span class="o">.</span><span class="n">EAT_ALL</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">listening</span><span class="p">[:]</span> <span class="o">=</span> <span class="p">[</span><span class="bp">True</span><span class="p">]</span>
<span class="n">xchat</span><span class="o">.</span><span class="n">hook_command</span><span class="p">(</span><span class="s">''</span><span class="p">,</span> <span class="n">expand_wikipedia_link</span><span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>import re
from urllib import quote
link_re = re.compile(r'\\\\[\\\\[([^\\\\]]+)\\\\]\\\\]')
link_base = 'http://en.wikipedia.org/wiki/'
listening = [True]
def expand_wikipedia_link(word, word_eol, userdata):
if listening and word_eol:
del listening[:]
try:
has_match = []
def handle_match(m):
has_match[:] = [True]
return link_base + quote(m.group(1).replace(' ', '_')
text = link_re.sub(handle_match, word_eol[0])
if has_match:
xchat.command('say ' + text)
return xchat.EAT_ALL
finally:
listening[:] = [True]
xchat.hook_command('', expand_wikipedia_link)<PYGMENTS_RAW -->
Yes. This code is ugly and it requires a lot of closure hacking but at least it shows that it's possible.XChat does not support implicit or regular expression based hooks or something similar. You can only register a callback for a <tt>/SOMETHING</tt> command. But there are ways.
Basically what you have to do is to register your callback to the <tt>""</tt> command and make sure that it handles it's own dispatching. Here a small example that converts <tt>[[Foo]]</tt> to <tt>http://en.wikipedia.org/wiki/Foo</tt>:
Yes. This code is ugly and it requires a lot of closure hacking but at least it shows that it's possible.SQAAAANTAAAABGJvZHlSUwAAAH9YQ2hhdCBkb2VzIG5vdCBzdXBwb3J0IGltcGxpY2l0IG9yIHJl
Z3VsYXIgZXhwcmVzc2lvbiBiYXNlZCBob29rcyBvciBzb21ldGhpbmcgc2ltaWxhci4gWW91IGNh
biBvbmx5IHJlZ2lzdGVyIGEgY2FsbGJhY2sgZm9yIGEgTAAERVMAAAACdHRMAABNAABTAAAACi9T
T01FVEhJTkdTAAAAYSBjb21tYW5kLiBCdXQgdGhlcmUgYXJlIHdheXMuCgpCYXNpY2FsbHkgd2hh
dCB5b3UgaGF2ZSB0byBkbyBpcyB0byByZWdpc3RlciB5b3VyIGNhbGxiYWNrIHRvIHRoZSBFUwAA
AAJ0dEwAAE0AAFMAAAACIiJTAAAAYCBjb21tYW5kIGFuZCBtYWtlIHN1cmUgdGhhdCBpdCBoYW5k
bGVzIGl0J3Mgb3duIGRpc3BhdGNoaW5nLiBIZXJlIGEgc21hbGwgZXhhbXBsZSB0aGF0IGNvbnZl
cnRzIEVTAAAAAnR0TAAATQAAUwAAAAdbW0Zvb11dUwAAAAQgdG8gRVMAAAACdHRMAABNAABTAAAA
IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRm9vUwAAAGw6CgpZZXMuIFRoaXMgY29kZSBp
cyB1Z2x5IGFuZCBpdCByZXF1aXJlcyBhIGxvdCBvZiBjbG9zdXJlIGhhY2tpbmcgYnV0IGF0IGxl
YXN0IGl0IHNob3dzIHRoYXQgaXQncyBwb3NzaWJsZS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAF
aW50cm9SUwAAAABMAAA=
Python Interpreter in X-Chathttp://lucumr.pocoo.org/cogitations/2007/06/12/python-interpreter-in-x-chat/2007-06-12T16:58:22Z2007-06-12T16:58:22ZArmin Ronacherpython-interpreter-in-x-chatyesyes2<a href="http://lucumr.pocoo.org/trac/repos/xchat/python_interpreter.py">python_interpreter.py</a> -- a small plugin that lets you execute code in the context of xchat and sends input and output formatted like an interactive python session to the current channel. I now use it in #python.de for posting small examples.
Keep in mind that it can easily screw up your xchat if you do something wrong.
Usage: <tt>>>> print 2**5</tt><a href="http://lucumr.pocoo.org/trac/repos/xchat/python_interpreter.py">python_interpreter.py</a> -- a small plugin that lets you execute code in the context of xchat and sends input and output formatted like an interactive python session to the current channel. I now use it in #python.de for posting small examples.
Keep in mind that it can easily screw up your xchat if you do something wrong.
Usage: <tt>>>> print 2**5</tt>SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAD5odHRwOi8v
bHVjdW1yLnBvY29vLm9yZy90cmFjL3JlcG9zL3hjaGF0L3B5dGhvbl9pbnRlcnByZXRlci5weVMA
AAAVcHl0aG9uX2ludGVycHJldGVyLnB5UwAAATUgLS0gYSBzbWFsbCBwbHVnaW4gdGhhdCBsZXRz
IHlvdSBleGVjdXRlIGNvZGUgaW4gdGhlIGNvbnRleHQgb2YgeGNoYXQgYW5kIHNlbmRzIGlucHV0
IGFuZCBvdXRwdXQgZm9ybWF0dGVkIGxpa2UgYW4gaW50ZXJhY3RpdmUgcHl0aG9uIHNlc3Npb24g
dG8gdGhlIGN1cnJlbnQgY2hhbm5lbC4gSSBub3cgdXNlIGl0IGluICNweXRob24uZGUgZm9yIHBv
c3Rpbmcgc21hbGwgZXhhbXBsZXMuCgpLZWVwIGluIG1pbmQgdGhhdCBpdCBjYW4gZWFzaWx5IHNj
cmV3IHVwIHlvdXIgeGNoYXQgaWYgeW91IGRvIHNvbWV0aGluZyB3cm9uZy4KClVzYWdlOiBFUwAA
AAJ0dEwAAE0AAFMAAAAOPj4+IHByaW50IDIqKjVTAAAAAFMAAAAGcGFyc2VyUwAAAARodG1sUwAA
AAVpbnRyb1JTAAAAAEwAAA==
CVS Version of Vim-Rubyhttp://lucumr.pocoo.org/cogitations/2007/06/12/cvs-version-of-vim-ruby/2007-06-12T15:22:15Z2007-06-12T15:22:15ZArmin Ronachercvs-version-of-vim-rubyyesyes2The new CVS Version of the vim ruby support rocks the house:
<img class="standalone" src="http://lucumr.pocoo.org/static/pictures/vim-ruby.png" alt="screenshot of vim with a ruby code sample that says 'vim rocks the house' in a funny way." />
Special thanks to Tim Pope for fixing some of the bugs i found that quickly.
You can find it here: <a href="http://vim-ruby.rubyforge.org/">vim-ruby.rubyforge.org</a>.The new CVS Version of the vim ruby support rocks the house:
<img src="http://lucumr.pocoo.org/static/pictures/vim-ruby.png" alt="screenshot of vim with a ruby code sample that says 'vim rocks the house' in a funny way." class="standalone">
Special thanks to Tim Pope for fixing some of the bugs i found that quickly.
You can find it here: <a href="http://vim-ruby.rubyforge.org/">vim-ruby.rubyforge.org</a>.SQAAAANTAAAABGJvZHlSUwAAAD1UaGUgbmV3IENWUyBWZXJzaW9uIG9mIHRoZSB2aW0gcnVieSBz
dXBwb3J0IHJvY2tzIHRoZSBob3VzZToKTAACRVMAAAADaW1nTAAATQADUwAAAANzcmNTAAAANGh0
dHA6Ly9sdWN1bXIucG9jb28ub3JnL3N0YXRpYy9waWN0dXJlcy92aW0tcnVieS5wbmdTAAAAA2Fs
dFMAAABZc2NyZWVuc2hvdCBvZiB2aW0gd2l0aCBhIHJ1YnkgY29kZSBzYW1wbGUgdGhhdCBzYXlz
ICd2aW0gcm9ja3MgdGhlIGhvdXNlJyBpbiBhIGZ1bm55IHdheS5TAAAABWNsYXNzUwAAAApzdGFu
ZGFsb25lUwAAAABTAAAAZgoKU3BlY2lhbCB0aGFua3MgdG8gVGltIFBvcGUgZm9yIGZpeGluZyBz
b21lIG9mIHRoZSBidWdzIGkgZm91bmQgdGhhdCBxdWlja2x5LgoKWW91IGNhbiBmaW5kIGl0IGhl
cmU6IEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAHmh0dHA6Ly92aW0tcnVieS5ydWJ5Zm9yZ2Uu
b3JnL1MAAAAWdmltLXJ1YnkucnVieWZvcmdlLm9yZ1MAAAABLlMAAAAGcGFyc2VyUwAAAARodG1s
UwAAAAVpbnRyb1JTAAAAAEwAAA==
What about a PHP-like Python Application?http://lucumr.pocoo.org/cogitations/2007/06/12/what-about-a-php-like-python-application/2007-06-12T14:45:45Z2007-06-12T14:45:45ZArmin Ronacherwhat-about-a-php-like-python-applicationyesyes2Actually there are so many people that want to have a PHP like Python, so why not give it a try? Using <a href="http://www.makotemplates.org/">Mako</a> and <a href="http://werkzeug.pocoo.org/">Werkzeug</a> it's easy to create such an application.
Basically all what I did is processing *.mako as Mako template that knows about the current request and response, and serving everything else as static file. Inside the templates you have access to GET, POST, FILES, COOKIES, REQUEST and RESPONSE and can use all of mako's power.
Example template:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="cp"><%</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">GET</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'data'</span><span class="p">,</span> <span class="s">'World'</span><span class="p">)</span>
<span class="cp">%></span>
<span class="nt"><title></span>Hello <span class="cp">${</span><span class="n">data</span><span class="o">|</span><span class="n">h</span><span class="cp">}</span><span class="nt"></title></span>
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"style.css"</span> <span class="na">type=</span><span class="s">"text/css"</span><span class="nt">></span>
<span class="nt"><h1></span>Hello <span class="cp">${</span><span class="n">data</span><span class="o">|</span><span class="n">h</span><span class="cp">}</span><span class="nt"></h1></span>
<span class="nt"><p></span>
Welcome on the PHP like Python application.
<span class="nt"></p></span>
<span class="nt"><p></span>
Say hello <span class="nt"><a</span> <span class="na">href=</span><span class="s">"?data=Daddy"</span><span class="nt">></span>daddy<span class="nt"></a></span> or show
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"missing"</span><span class="nt">></span>a missing page<span class="nt"></a></span>. There is also
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"special.mako"</span><span class="nt">></span>a special page<span class="nt"></a></span>.
<span class="nt"></p></span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(html+mako)><%
data = GET.get('data', 'World')
%>
<title>Hello ${data|h}</title>
<link rel="stylesheet" href="style.css" type="text/css">
<h1>Hello ${data|h}</h1>
<p>
Welcome on the PHP like Python application.
</p>
<p>
Say hello <a href="?data=Daddy">daddy</a> or show
<a href="missing">a missing page</a>. There is also
<a href="special.mako">a special page</a>.
</p><PYGMENTS_RAW -->
The full sourcecode is available here: <a href="http://lucumr.pocoo.org/trac/repos/phplikepy/">phplikepy</a>
It needs the SVN version of Werkzeug, Mako and Python2.4 or Python 2.3 with wsgiref.Actually there are so many people that want to have a PHP like Python, so why not give it a try? Using <a href="http://www.makotemplates.org/">Mako</a> and <a href="http://werkzeug.pocoo.org/">Werkzeug</a> it's easy to create such an application.
Basically all what I did is processing *.mako as Mako template that knows about the current request and response, and serving everything else as static file. Inside the templates you have access to GET, POST, FILES, COOKIES, REQUEST and RESPONSE and can use all of mako's power.
Example template:
The full sourcecode is available here: <a href="http://lucumr.pocoo.org/trac/repos/phplikepy/">phplikepy</a>
It needs the SVN version of Werkzeug, Mako and Python2.4 or Python 2.3 with wsgiref.SQAAAANTAAAABGJvZHlSUwAAAGdBY3R1YWxseSB0aGVyZSBhcmUgc28gbWFueSBwZW9wbGUgdGhh
dCB3YW50IHRvIGhhdmUgYSBQSFAgbGlrZSBQeXRob24sIHNvIHdoeSBub3QgZ2l2ZSBpdCBhIHRy
eT8gVXNpbmcgTAADRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAdaHR0cDovL3d3dy5tYWtvdGVt
cGxhdGVzLm9yZy9TAAAABE1ha29TAAAABSBhbmQgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAa
aHR0cDovL3dlcmt6ZXVnLnBvY29vLm9yZy9TAAAACFdlcmt6ZXVnUwAAAX4gaXQncyBlYXN5IHRv
IGNyZWF0ZSBzdWNoIGFuIGFwcGxpY2F0aW9uLgoKQmFzaWNhbGx5IGFsbCB3aGF0IEkgZGlkIGlz
IHByb2Nlc3NpbmcgKi5tYWtvIGFzIE1ha28gdGVtcGxhdGUgdGhhdCBrbm93cyBhYm91dCB0aGUg
Y3VycmVudCByZXF1ZXN0IGFuZCByZXNwb25zZSwgYW5kIHNlcnZpbmcgZXZlcnl0aGluZyBlbHNl
IGFzIHN0YXRpYyBmaWxlLiBJbnNpZGUgdGhlIHRlbXBsYXRlcyB5b3UgaGF2ZSBhY2Nlc3MgdG8g
R0VULCBQT1NULCBGSUxFUywgQ09PS0lFUywgUkVRVUVTVCBhbmQgUkVTUE9OU0UgYW5kIGNhbiB1
c2UgYWxsIG9mIG1ha28ncyBwb3dlci4KCkV4YW1wbGUgdGVtcGxhdGU6CgoKVGhlIGZ1bGwgc291
cmNlY29kZSBpcyBhdmFpbGFibGUgaGVyZTogRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAtaHR0
cDovL2x1Y3Vtci5wb2Nvby5vcmcvdHJhYy9yZXBvcy9waHBsaWtlcHkvUwAAAAlwaHBsaWtlcHlT
AAAAVgoKSXQgbmVlZHMgdGhlIFNWTiB2ZXJzaW9uIG9mIFdlcmt6ZXVnLCBNYWtvIGFuZCBQeXRo
b24yLjQgb3IgUHl0aG9uIDIuMyB3aXRoIHdzZ2lyZWYuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAA
BWludHJvUlMAAAAATAAA
Why Python Suckshttp://lucumr.pocoo.org/cogitations/2007/06/11/why-python-sucks/2007-06-11T13:27:06Z2007-06-11T13:27:06ZArmin Ronacherwhy-python-sucksyesyes2And of course also why it sucks a lot less than any other language. But it's not perfect. My personal problems with python:
<ul>
<li>It's dict and not Dict, it's list and not List and you cannot subclass them without overriding every method.......</li>
<li>it's copy.copy and not just copy. Why in god's name is that an import?</li>
<li>clean up the stdlib</li>
<li>there is BaseHTTPServer and not py.http.baseserver or something like that. Why is that darn stdlib flat?</li>
<li>there are soo many bad libraries in the stdlib and so many good ones not...</li>
<li>no goddamn styleguide for the stdlib. it's UnitTest.assertEqual and not UnitTest.assert_equal like PEP 8 proposes</li>
<li>By now you cannot reassign a variable from and outer scope. (there is a pep!)</li>
<li>clean up the stdlib</li>
<li>assignments are not expressions. gaaaaa. I want to do <tt>(foo |= []).append(42)</tt> and not <tt>foo |= []; foo.append(42) </tt> etc.</li>
<li>No regexp literal and match objects are not instances of a Regexp class. Move the sre module into the core, add a <tt>@/foo/</tt> literal and create a Regexp class instead of something like _sre.SRE_Pattern which you cannot import to make isinstance tests</li>
<li>missing blocks. darn. i want blocks</li>
<li>unify unicode and string. quick! (waiting for Python 3000)</li>
<li>clean up the stdlib</li>
</ul>
Why it still sucks less? Good question. Probably because the meta programming capabilities are great, the libraries are awesome, indention based syntax is hip, <strong>first class functions</strong>, quite fast, many bindings (PyGTW FTW!) and the community is nice and friendly. And there is WSGI!And of course also why it sucks a lot less than any other language. But it's not perfect. My personal problems with python:
<ul>
<li>It's dict and not Dict, it's list and not List and you cannot subclass them without overriding every method.......</li>
<li>it's copy.copy and not just copy. Why in god's name is that an import?</li>
<li>clean up the stdlib</li>
<li>there is BaseHTTPServer and not py.http.baseserver or something like that. Why is that darn stdlib flat?</li>
<li>there are soo many bad libraries in the stdlib and so many good ones not...</li>
<li>no goddamn styleguide for the stdlib. it's UnitTest.assertEqual and not UnitTest.assert_equal like PEP 8 proposes</li>
<li>By now you cannot reassign a variable from and outer scope. (there is a pep!)</li>
<li>clean up the stdlib</li>
<li>assignments are not expressions. gaaaaa. I want to do <tt>(foo |= []).append(42)</tt> and not <tt>foo |= []; foo.append(42) </tt> etc.</li>
<li>No regexp literal and match objects are not instances of a Regexp class. Move the sre module into the core, add a <tt>@/foo/</tt> literal and create a Regexp class instead of something like _sre.SRE_Pattern which you cannot import to make isinstance tests</li>
<li>missing blocks. darn. i want blocks</li>
<li>unify unicode and string. quick! (waiting for Python 3000)</li>
<li>clean up the stdlib</li>
</ul>
Why it still sucks less? Good question. Probably because the meta programming capabilities are great, the libraries are awesome, indention based syntax is hip, <strong>first class functions</strong>, quite fast, many bindings (PyGTW FTW!) and the community is nice and friendly. And there is WSGI!SQAAAANTAAAABGJvZHlSUwAAAHxBbmQgb2YgY291cnNlIGFsc28gd2h5IGl0IHN1Y2tzIGEgbG90
IGxlc3MgdGhhbiBhbnkgb3RoZXIgbGFuZ3VhZ2UuIEJ1dCBpdCdzIG5vdCBwZXJmZWN0LiBNeSBw
ZXJzb25hbCBwcm9ibGVtcyB3aXRoIHB5dGhvbjoKTAACRVMAAAACdWxMAA1FUwAAAAJsaUwAAE0A
AFMAAABySXQncyBkaWN0IGFuZCBub3QgRGljdCwgaXQncyBsaXN0IGFuZCBub3QgTGlzdCBhbmQg
eW91IGNhbm5vdCBzdWJjbGFzcyB0aGVtIHdpdGhvdXQgb3ZlcnJpZGluZyBldmVyeSBtZXRob2Qu
Li4uLi4uUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAABGaXQncyBjb3B5LmNvcHkgYW5kIG5vdCBq
dXN0IGNvcHkuIFdoeSBpbiBnb2QncyBuYW1lIGlzIHRoYXQgYW4gaW1wb3J0P1MAAAADCiAgRVMA
AAACbGlMAABNAABTAAAAE2NsZWFuIHVwIHRoZSBzdGRsaWJTAAAAAwogIEVTAAAAAmxpTAAATQAA
UwAAAGh0aGVyZSBpcyBCYXNlSFRUUFNlcnZlciBhbmQgbm90IHB5Lmh0dHAuYmFzZXNlcnZlciBv
ciBzb21ldGhpbmcgbGlrZSB0aGF0LiBXaHkgaXMgdGhhdCBkYXJuIHN0ZGxpYiBmbGF0P1MAAAAD
CiAgRVMAAAACbGlMAABNAABTAAAAS3RoZXJlIGFyZSBzb28gbWFueSBiYWQgbGlicmFyaWVzIGlu
IHRoZSBzdGRsaWIgYW5kIHNvIG1hbnkgZ29vZCBvbmVzIG5vdC4uLlMAAAADCiAgRVMAAAACbGlM
AABNAABTAAAAcW5vIGdvZGRhbW4gc3R5bGVndWlkZSBmb3IgdGhlIHN0ZGxpYi4gaXQncyBVbml0
VGVzdC5hc3NlcnRFcXVhbCBhbmQgbm90IFVuaXRUZXN0LmFzc2VydF9lcXVhbCBsaWtlIFBFUCA4
IHByb3Bvc2VzUwAAAAMKICBFUwAAAAJsaUwAAE0AAFMAAABNQnkgbm93IHlvdSBjYW5ub3QgcmVh
c3NpZ24gYSB2YXJpYWJsZSBmcm9tIGFuZCBvdXRlciBzY29wZS4gKHRoZXJlIGlzIGEgcGVwISlT
AAAAAwogIEVTAAAAAmxpTAAATQAAUwAAABNjbGVhbiB1cCB0aGUgc3RkbGliUwAAAAMKICBFUwAA
AAJsaUwAAkVTAAAAAnR0TAAATQAAUwAAABYoZm9vIHw9IFtdKS5hcHBlbmQoNDIpUwAAAAkgYW5k
IG5vdCBFUwAAAAJ0dEwAAE0AAFMAAAAaZm9vIHw9IFtdOyBmb28uYXBwZW5kKDQyKSBTAAAABSBl
dGMuTQAAUwAAADZhc3NpZ25tZW50cyBhcmUgbm90IGV4cHJlc3Npb25zLiBnYWFhYWEuIEkgd2Fu
dCB0byBkbyBTAAAAAwogIEVTAAAAAmxpTAABRVMAAAACdHRMAABNAABTAAAABkAvZm9vL1MAAAB+
IGxpdGVyYWwgYW5kIGNyZWF0ZSBhIFJlZ2V4cCBjbGFzcyBpbnN0ZWFkIG9mIHNvbWV0aGluZyBs
aWtlIF9zcmUuU1JFX1BhdHRlcm4gd2hpY2ggeW91IGNhbm5vdCBpbXBvcnQgdG8gbWFrZSBpc2lu
c3RhbmNlIHRlc3RzTQAAUwAAAHJObyByZWdleHAgbGl0ZXJhbCBhbmQgbWF0Y2ggb2JqZWN0cyBh
cmUgbm90IGluc3RhbmNlcyBvZiBhIFJlZ2V4cCBjbGFzcy4gTW92ZSB0aGUgc3JlIG1vZHVsZSBp
bnRvIHRoZSBjb3JlLCBhZGQgYSBTAAAAAwogIEVTAAAAAmxpTAAATQAAUwAAACNtaXNzaW5nIGJs
b2Nrcy4gZGFybi4gaSB3YW50IGJsb2Nrc1MAAAADCiAgRVMAAAACbGlMAABNAABTAAAAOnVuaWZ5
IHVuaWNvZGUgYW5kIHN0cmluZy4gcXVpY2shICh3YWl0aW5nIGZvciBQeXRob24gMzAwMClTAAAA
AwogIEVTAAAAAmxpTAAATQAAUwAAABNjbGVhbiB1cCB0aGUgc3RkbGliUwAAAAEKTQAAUwAAAAMK
ICBTAAAAoQpXaHkgaXQgc3RpbGwgc3Vja3MgbGVzcz8gR29vZCBxdWVzdGlvbi4gUHJvYmFibHkg
YmVjYXVzZSB0aGUgbWV0YSBwcm9ncmFtbWluZyBjYXBhYmlsaXRpZXMgYXJlIGdyZWF0LCB0aGUg
bGlicmFyaWVzIGFyZSBhd2Vzb21lLCBpbmRlbnRpb24gYmFzZWQgc3ludGF4IGlzIGhpcCwgRVMA
AAAGc3Ryb25nTAAATQAAUwAAABVmaXJzdCBjbGFzcyBmdW5jdGlvbnNTAAAAYywgcXVpdGUgZmFz
dCwgbWFueSBiaW5kaW5ncyAoUHlHVFcgRlRXISkgYW5kIHRoZSBjb21tdW5pdHkgaXMgbmljZSBh
bmQgZnJpZW5kbHkuIEFuZCB0aGVyZSBpcyBXU0dJIVMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVp
bnRyb1JTAAAAAEwAAA==
Internationalized PyGTK Applicationshttp://lucumr.pocoo.org/cogitations/2007/06/10/internationalized-pygtk-applications/2007-06-10T08:25:45Z2007-06-10T08:25:45ZArmin Ronacherinternationalized-pygtk-applicationsyesyes2I now wrote down a small tutorial for PyGTK applications with gettext support. You can find it here: <a href="http://lucumr.pocoo.org/articles/internationalized-pygtk-applications">Internationalized PyGTK Applications</a>.
The sourcecode for a small example project is here: <a href="http://pocoo.org/~mitsuhiko/pygtki18nexample.tar.gz">pygtki18nexample.tar.gz</a>
I hope it helps :-)I now wrote down a small tutorial for PyGTK applications with gettext support. You can find it here: <a href="http://lucumr.pocoo.org/articles/internationalized-pygtk-applications">Internationalized PyGTK Applications</a>.
The sourcecode for a small example project is here: <a href="http://pocoo.org/~mitsuhiko/pygtki18nexample.tar.gz">pygtki18nexample.tar.gz</a>
I hope it helps :-)SQAAAANTAAAABGJvZHlSUwAAAGVJIG5vdyB3cm90ZSBkb3duIGEgc21hbGwgdHV0b3JpYWwgZm9y
IFB5R1RLIGFwcGxpY2F0aW9ucyB3aXRoIGdldHRleHQgc3VwcG9ydC4gWW91IGNhbiBmaW5kIGl0
IGhlcmU6IEwAAkVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAARWh0dHA6Ly9sdWN1bXIucG9jb28u
b3JnL2FydGljbGVzL2ludGVybmF0aW9uYWxpemVkLXB5Z3RrLWFwcGxpY2F0aW9uc1MAAAAkSW50
ZXJuYXRpb25hbGl6ZWQgUHlHVEsgQXBwbGljYXRpb25zUwAAADcuCgpUaGUgc291cmNlY29kZSBm
b3IgYSBzbWFsbCBleGFtcGxlIHByb2plY3QgaXMgaGVyZTogRVMAAAABYUwAAE0AAVMAAAAEaHJl
ZlMAAAAzaHR0cDovL3BvY29vLm9yZy9+bWl0c3VoaWtvL3B5Z3RraTE4bmV4YW1wbGUudGFyLmd6
UwAAABdweWd0a2kxOG5leGFtcGxlLnRhci5nelMAAAAVCgpJIGhvcGUgaXQgaGVscHMgOi0pUwAA
AAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Mirek Simekmiroslav.simek@gmail.com2007-12-28T13:46:24Znono0Just what I needed. thanks.Just what I needed. thanks.SQAAAAJTAAAABGJvZHlSUwAAABtKdXN0IHdoYXQgSSBuZWVkZWQuIHRoYW5rcy5MAABTAAAABnBh
cnNlclMAAAAEaHRtbA==
Super-sizing YouTubehttp://lucumr.pocoo.org/cogitations/2007/06/09/super-sizing-youtube/2007-06-09T06:53:26Z2007-06-09T06:53:26ZArmin Ronachersuper-sizing-youtubeyesyes2<a href="http://conferences.oreillynet.com/cs/os2007/view/e_sess/13435">Talk about Python at youtube</a> -- Thursday, July 26 2007. I hope they will put videos online.<a href="http://conferences.oreillynet.com/cs/os2007/view/e_sess/13435">Talk about Python at youtube</a> -- Thursday, July 26 2007. I hope they will put videos online.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAD1odHRwOi8v
Y29uZmVyZW5jZXMub3JlaWxseW5ldC5jb20vY3Mvb3MyMDA3L3ZpZXcvZV9zZXNzLzEzNDM1UwAA
ABxUYWxrIGFib3V0IFB5dGhvbiBhdCB5b3V0dWJlUwAAAD8gLS0gVGh1cnNkYXksIEp1bHkgMjYg
MjAwNy4gSSBob3BlIHRoZXkgd2lsbCBwdXQgdmlkZW9zIG9ubGluZS5TAAAABnBhcnNlclMAAAAE
aHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Fracturehttp://lucumr.pocoo.org/cogitations/2007/06/08/fracture/2007-06-08T20:16:30Z2007-06-08T20:16:30ZArmin Ronacherfractureyesyes2Yesterday I watched <a href="http://en.wikipedia.org/wiki/Fracture_%28film%29">fracture</a> with friends and it was stunned. The plan was watching Oceans 13 (which I hopefully will do in the next week) but because one of us promised a colleague to watch it together with him we picked this movie -- more or less by chance. The movie was really good in my opinion. The characters are authentic and the story is straightforward but nonetheless astonishing.Yesterday I watched <a href="http://en.wikipedia.org/wiki/Fracture_%28film%29">fracture</a> with friends and it was stunned. The plan was watching Oceans 13 (which I hopefully will do in the next week) but because one of us promised a colleague to watch it together with him we picked this movie -- more or less by chance. The movie was really good in my opinion. The characters are authentic and the story is straightforward but nonetheless astonishing.SQAAAANTAAAABGJvZHlSUwAAABRZZXN0ZXJkYXkgSSB3YXRjaGVkIEwAAUVTAAAAAWFMAABNAAFT
AAAABGhyZWZTAAAAMGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRnJhY3R1cmVfJTI4Zmls
bSUyOVMAAAAIZnJhY3R1cmVTAAABayB3aXRoIGZyaWVuZHMgYW5kIGl0IHdhcyBzdHVubmVkLiBU
aGUgcGxhbiB3YXMgd2F0Y2hpbmcgT2NlYW5zIDEzICh3aGljaCBJIGhvcGVmdWxseSB3aWxsIGRv
IGluIHRoZSBuZXh0IHdlZWspIGJ1dCBiZWNhdXNlIG9uZSBvZiB1cyBwcm9taXNlZCBhIGNvbGxl
YWd1ZSB0byB3YXRjaCBpdCB0b2dldGhlciB3aXRoIGhpbSB3ZSBwaWNrZWQgdGhpcyBtb3ZpZSAt
LSBtb3JlIG9yIGxlc3MgYnkgY2hhbmNlLiBUaGUgbW92aWUgd2FzIHJlYWxseSBnb29kIGluIG15
IG9waW5pb24uIFRoZSBjaGFyYWN0ZXJzIGFyZSBhdXRoZW50aWMgYW5kIHRoZSBzdG9yeSBpcyBz
dHJhaWdodGZvcndhcmQgYnV0IG5vbmV0aGVsZXNzIGFzdG9uaXNoaW5nLlMAAAAGcGFyc2VyUwAA
AARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
gPyreTest goes i18nhttp://lucumr.pocoo.org/cogitations/2007/06/08/gpyretest-goes-i18n/2007-06-08T20:05:27Z2007-06-08T20:05:27ZArmin Ronachergpyretest-goes-i18nyesyes2I googled for pygtk internationalization and found out that gettext integration is straightforward. In fact it required less than 30 lines changes in the code and now it would be possible to translate <a href="/projects/gpyretest/">gPyreTest</a>.
Here a screen of gPyreTest in German language (the regexp syntax error translation sounds strange, maybe someone wants to contribute patches ^^)
<img class="standalone" src="http://lucumr.pocoo.org/static/pictures/gpyretesti18n_zoomed.png" alt="screenshot of gPyreTest with a strange sounding German translation" />I googled for pygtk internationalization and found out that gettext integration is straightforward. In fact it required less than 30 lines changes in the code and now it would be possible to translate <a href="/projects/gpyretest/">gPyreTest</a>.
Here a screen of gPyreTest in German language (the regexp syntax error translation sounds strange, maybe someone wants to contribute patches ^^)
<img src="http://lucumr.pocoo.org/static/pictures/gpyretesti18n_zoomed.png" alt="screenshot of gPyreTest with a strange sounding German translation" class="standalone">SQAAAANTAAAABGJvZHlSUwAAAMlJIGdvb2dsZWQgZm9yIHB5Z3RrIGludGVybmF0aW9uYWxpemF0
aW9uIGFuZCBmb3VuZCBvdXQgdGhhdCBnZXR0ZXh0IGludGVncmF0aW9uIGlzIHN0cmFpZ2h0Zm9y
d2FyZC4gSW4gZmFjdCBpdCByZXF1aXJlZCBsZXNzIHRoYW4gMzAgbGluZXMgY2hhbmdlcyBpbiB0
aGUgY29kZSBhbmQgbm93IGl0IHdvdWxkIGJlIHBvc3NpYmxlIHRvIHRyYW5zbGF0ZSBMAAJFUwAA
AAFhTAAATQABUwAAAARocmVmUwAAABQvcHJvamVjdHMvZ3B5cmV0ZXN0L1MAAAAJZ1B5cmVUZXN0
UwAAAJQuCgpIZXJlIGEgc2NyZWVuIG9mIGdQeXJlVGVzdCBpbiBHZXJtYW4gbGFuZ3VhZ2UgKHRo
ZSByZWdleHAgc3ludGF4IGVycm9yIHRyYW5zbGF0aW9uIHNvdW5kcyBzdHJhbmdlLCBtYXliZSBz
b21lb25lIHdhbnRzIHRvIGNvbnRyaWJ1dGUgcGF0Y2hlcyBeXikKRVMAAAADaW1nTAAATQADUwAA
AANzcmNTAAAAQGh0dHA6Ly9sdWN1bXIucG9jb28ub3JnL3N0YXRpYy9waWN0dXJlcy9ncHlyZXRl
c3RpMThuX3pvb21lZC5wbmdTAAAAA2FsdFMAAABCc2NyZWVuc2hvdCBvZiBnUHlyZVRlc3Qgd2l0
aCBhIHN0cmFuZ2Ugc291bmRpbmcgR2VybWFuIHRyYW5zbGF0aW9uUwAAAAVjbGFzc1MAAAAKc3Rh
bmRhbG9uZVMAAAAAUwAAAABTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Super Smash Bros Dojo Wiimote compatiblehttp://lucumr.pocoo.org/cogitations/2007/06/08/super-smash-bros-dojo-wiimote-compatible/2007-06-08T15:10:31Z2007-06-08T15:10:31ZArmin Ronachersuper-smash-bros-dojo-wiimote-compatibleyesyes2<a href="http://www.smashbros.com/en_us/gamemode/various/various01.html">awesome news</a>. SSBD will work with the Wiimote, Wiimote + Nunchuck, GameCube Controller and the Classic one too. Cooooooool :D<a href="http://www.smashbros.com/en_us/gamemode/various/various01.html">awesome news</a>. SSBD will work with the Wiimote, Wiimote + Nunchuck, GameCube Controller and the Classic one too. Cooooooool :DSQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAD5odHRwOi8v
d3d3LnNtYXNoYnJvcy5jb20vZW5fdXMvZ2FtZW1vZGUvdmFyaW91cy92YXJpb3VzMDEuaHRtbFMA
AAAMYXdlc29tZSBuZXdzUwAAAHEuIFNTQkQgd2lsbCB3b3JrIHdpdGggdGhlIFdpaW1vdGUsIFdp
aW1vdGUgKyBOdW5jaHVjaywgR2FtZUN1YmUgQ29udHJvbGxlciBhbmQgdGhlIENsYXNzaWMgb25l
IHRvby4gQ29vb29vb29vbCA6RFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwA
AA==
Seen on Digg (Part 1)http://lucumr.pocoo.org/cogitations/2007/06/07/seen-on-digg-part-1/2007-06-07T10:34:52Z2007-06-07T10:34:52ZArmin Ronacherseen-on-digg-part-1yesyes2Someone <a href="http://digg.com/users/taylorwbuley">digged</a> a <a href="http://www.anakata.hack.se/">one year old message</a> by one of the Pirate Bay guys and the <a href="http://digg.com/world_news/PirateBay_proprieter_raided_by_Swedish_police">whole crowd</a> discusses that as if it would have happened today.Someone <a href="http://digg.com/users/taylorwbuley">digged</a> a <a href="http://www.anakata.hack.se/">one year old message</a> by one of the Pirate Bay guys and the <a href="http://digg.com/world_news/PirateBay_proprieter_raided_by_Swedish_police">whole crowd</a> discusses that as if it would have happened today.SQAAAANTAAAABGJvZHlSUwAAAAhTb21lb25lIEwAA0VTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAA
Imh0dHA6Ly9kaWdnLmNvbS91c2Vycy90YXlsb3J3YnVsZXlTAAAABmRpZ2dlZFMAAAADIGEgRVMA
AAABYUwAAE0AAVMAAAAEaHJlZlMAAAAbaHR0cDovL3d3dy5hbmFrYXRhLmhhY2suc2UvUwAAABRv
bmUgeWVhciBvbGQgbWVzc2FnZVMAAAAnIGJ5IG9uZSBvZiB0aGUgUGlyYXRlIEJheSBndXlzIGFu
ZCB0aGUgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAABIaHR0cDovL2RpZ2cuY29tL3dvcmxkX25l
d3MvUGlyYXRlQmF5X3Byb3ByaWV0ZXJfcmFpZGVkX2J5X1N3ZWRpc2hfcG9saWNlUwAAAAt3aG9s
ZSBjcm93ZFMAAAA0IGRpc2N1c3NlcyB0aGF0IGFzICBpZiBpdCB3b3VsZCBoYXZlIGhhcHBlbmVk
IHRvZGF5LlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
gPyreTest — a regular expression testerhttp://lucumr.pocoo.org/cogitations/2007/06/07/gpyretest-a-regular-expression-tester/2007-06-06T22:34:40Z2007-06-06T22:34:40ZArmin Ronachergpyretest-a-regular-expression-testeryesyes2On the German python forum I found a thread where someone mentioned <a href="http://kodos.sourceforge.net/">kodos</a> which reminded me about one of my old projects which was pretty much the same, just for GTK. I now restored the sourcecode and cleaned it up a bit (it originally contained tabs and various constructs I could have avoided and a hardcoded GUI). I also added escape / unescape / export / import features.
So the result looks like this:
<img class="standalone" src="http://lucumr.pocoo.org/static/pictures/gpyretest_zoomed.png" alt="screenshot of gpyretest" />
I added it to my projects section now: <a href="http://lucumr.pocoo.org/projects/gpyretest/">gPyreTest</a>
And now have fun testing your python regular expressions :DOn the German python forum I found a thread where someone mentioned <a href="http://kodos.sourceforge.net/">kodos</a> which reminded me about one of my old projects which was pretty much the same, just for GTK. I now restored the sourcecode and cleaned it up a bit (it originally contained tabs and various constructs I could have avoided and a hardcoded GUI). I also added escape / unescape / export / import features.
So the result looks like this:
<img src="http://lucumr.pocoo.org/static/pictures/gpyretest_zoomed.png" alt="screenshot of gpyretest" class="standalone">
I added it to my projects section now: <a href="http://lucumr.pocoo.org/projects/gpyretest/">gPyreTest</a>
And now have fun testing your python regular expressions :DSQAAAANTAAAABGJvZHlSUwAAAERPbiB0aGUgR2VybWFuIHB5dGhvbiBmb3J1bSBJIGZvdW5kIGEg
dGhyZWFkIHdoZXJlIHNvbWVvbmUgbWVudGlvbmVkIEwAA0VTAAAAAWFMAABNAAFTAAAABGhyZWZT
AAAAHWh0dHA6Ly9rb2Rvcy5zb3VyY2Vmb3JnZS5uZXQvUwAAAAVrb2Rvc1MAAAFPIHdoaWNoIHJl
bWluZGVkIG1lIGFib3V0IG9uZSBvZiBteSBvbGQgcHJvamVjdHMgd2hpY2ggd2FzIHByZXR0eSBt
dWNoIHRoZSBzYW1lLCBqdXN0IGZvciBHVEsuIEkgbm93IHJlc3RvcmVkIHRoZSBzb3VyY2Vjb2Rl
IGFuZCBjbGVhbmVkIGl0IHVwIGEgYml0IChpdCBvcmlnaW5hbGx5IGNvbnRhaW5lZCB0YWJzIGFu
ZCB2YXJpb3VzIGNvbnN0cnVjdHMgSSBjb3VsZCBoYXZlIGF2b2lkZWQgYW5kIGEgaGFyZGNvZGVk
IEdVSSkuIEkgYWxzbyBhZGRlZCBlc2NhcGUgLyB1bmVzY2FwZSAvIGV4cG9ydCAvIGltcG9ydCBm
ZWF0dXJlcy4KClNvIHRoZSByZXN1bHQgbG9va3MgbGlrZSB0aGlzOgpFUwAAAANpbWdMAABNAANT
AAAAA3NyY1MAAAA8aHR0cDovL2x1Y3Vtci5wb2Nvby5vcmcvc3RhdGljL3BpY3R1cmVzL2dweXJl
dGVzdF96b29tZWQucG5nUwAAAANhbHRTAAAAF3NjcmVlbnNob3Qgb2YgZ3B5cmV0ZXN0UwAAAAVj
bGFzc1MAAAAKc3RhbmRhbG9uZVMAAAAAUwAAACkKCkkgYWRkZWQgaXQgdG8gbXkgcHJvamVjdHMg
c2VjdGlvbiBub3c6IEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAK2h0dHA6Ly9sdWN1bXIucG9j
b28ub3JnL3Byb2plY3RzL2dweXJldGVzdC9TAAAACWdQeXJlVGVzdFMAAAA9CgpBbmQgbm93IGhh
dmUgZnVuIHRlc3RpbmcgeW91ciBweXRob24gcmVndWxhciBleHByZXNzaW9ucyA6RFMAAAAGcGFy
c2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Knight of WSGIhttp://lucumr.pocoo.org/cogitations/2007/06/05/knight-of-wsgi/2007-06-05T13:27:07Z2007-06-05T13:27:07ZArmin Ronacherknight-of-wsgiyesyes2I have that title in the <a href="http://www.python-forum.de/">German Python Forum</a> for some time already and now I wanted to have an avatar for that. So I tried to draw one, unfortunately I'm not that good at drawing so the result is not the best. Still. Here the full version:
<img class="standalone" src="http://lucumr.pocoo.org/static/pictures/knightofwsgi.png" alt="a knight with a WSGI banner" />
and here the small one for the forum:
<img class="standalone" src="http://pocoo.org/~mitsuhiko/knightofwsgi_ava.png" alt="same as above just in smaller, so small that you can't read the banner any more" />I have that title in the <a href="http://www.python-forum.de/">German Python Forum</a> for some time already and now I wanted to have an avatar for that. So I tried to draw one, unfortunately I'm not that good at drawing so the result is not the best. Still. Here the full version:
<img src="http://lucumr.pocoo.org/static/pictures/knightofwsgi.png" alt="a knight with a WSGI banner" class="standalone">
and here the small one for the forum:
<img src="http://pocoo.org/~mitsuhiko/knightofwsgi_ava.png" alt="same as above just in smaller, so small that you can't read the banner any more" class="standalone">SQAAAANTAAAABGJvZHlSUwAAABlJIGhhdmUgdGhhdCB0aXRsZSBpbiB0aGUgTAADRVMAAAABYUwA
AE0AAVMAAAAEaHJlZlMAAAAbaHR0cDovL3d3dy5weXRob24tZm9ydW0uZGUvUwAAABNHZXJtYW4g
UHl0aG9uIEZvcnVtUwAAAMQgZm9yIHNvbWUgdGltZSBhbHJlYWR5IGFuZCBub3cgSSB3YW50ZWQg
dG8gaGF2ZSBhbiBhdmF0YXIgZm9yIHRoYXQuIFNvIEkgdHJpZWQgdG8gZHJhdyBvbmUsIHVuZm9y
dHVuYXRlbHkgSSdtIG5vdCB0aGF0IGdvb2QgYXQgZHJhd2luZyBzbyB0aGUgcmVzdWx0IGlzIG5v
dCB0aGUgYmVzdC4gU3RpbGwuIEhlcmUgdGhlIGZ1bGwgdmVyc2lvbjoKRVMAAAADaW1nTAAATQAD
UwAAAANzcmNTAAAAOGh0dHA6Ly9sdWN1bXIucG9jb28ub3JnL3N0YXRpYy9waWN0dXJlcy9rbmln
aHRvZndzZ2kucG5nUwAAAANhbHRTAAAAG2Ega25pZ2h0IHdpdGggYSBXU0dJIGJhbm5lclMAAAAF
Y2xhc3NTAAAACnN0YW5kYWxvbmVTAAAAAFMAAAAnCmFuZCBoZXJlIHRoZSBzbWFsbCBvbmUgZm9y
IHRoZSBmb3J1bToKRVMAAAADaW1nTAAATQADUwAAAANzcmNTAAAAMGh0dHA6Ly9wb2Nvby5vcmcv
fm1pdHN1aGlrby9rbmlnaHRvZndzZ2lfYXZhLnBuZ1MAAAADYWx0UwAAAE9zYW1lIGFzIGFib3Zl
IGp1c3QgaW4gc21hbGxlciwgc28gc21hbGwgdGhhdCB5b3UgY2FuJ3QgcmVhZCB0aGUgYmFubmVy
IGFueSBtb3JlUwAAAAVjbGFzc1MAAAAKc3RhbmRhbG9uZVMAAAAAUwAAAABTAAAABnBhcnNlclMA
AAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Rafaelrafaelw@gmx.net2007-06-05T15:50:24Znono0Hoi,
nice, but the "WSGI" isn't really identifiable in the avatar.Hoi,
nice, but the "WSGI" isn't really identifiable in the avatar.SQAAAAJTAAAABGJvZHlSUwAAAENIb2ksCgpuaWNlLCBidXQgdGhlICJXU0dJIiBpc24ndCByZWFs
bHkgaWRlbnRpZmlhYmxlIGluIHRoZSBhdmF0YXIuTAAAUwAAAAZwYXJzZXJTAAAABGh0bWw=
Jinja 1.2 Planshttp://lucumr.pocoo.org/cogitations/2007/06/04/jinja-12-plans/2007-06-04T20:59:10Z2007-06-04T20:59:10ZArmin Ronacherjinja-12-plansyesyes2Jinja 1.1 released, it's arrived in debian too (Thanks Piotr Ożarowski for uploading it that quick) and I can start thinking about what to put into 1.2. Actually the plans for 1.2 exist for longer than 1.0 but implementing the Features for 1.0 and 1.1 took incredible long because more and more ideas came up.
Actually the Jinja code is quite stable by now and hopefully stable enough for the import system which will be the major change for 1.2. Basically what Jinja does by now is doing inheritance before generating the bytecode. Basically what I want to have in 1.2 is an import system so that you can import macros into a namespace and do dynamic layouts. This could slow things down a bit that's why I want to keep the static inheritance if possible and switch to the dynamic one if necessary. Currently Jinja does that implementation switching in other situations too, like in the Jinja 1.1 shorthand block syntax.
Basically what I want it to do is on the one hand this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="cp">{%</span> <span class="k">include</span> <span class="nv">helpers</span><span class="o">=</span><span class="s1">'helpers.html'</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">call</span> <span class="nv">helpers.dialog</span><span class="o">(</span><span class="s1">'foo'</span><span class="o">)</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> This is the dialog text.</span>
<span class="cp">{%</span> <span class="k">endcall</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(jinja)>{% include helpers='helpers.html' %}
{% call helpers.dialog('foo') %}
This is the dialog text.
{% endcall %}<PYGMENTS_RAW -->
And on the other hand dynamic inheritance is another thing I want in Jinja:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="cp">{%</span> <span class="k">if</span> <span class="nv">show_details</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">set</span> <span class="nv">template_to_use</span><span class="o">=</span><span class="s1">'with_details.html'</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span><span class="x"></span>
<span class="x"> </span><span class="cp">{%</span> <span class="k">set</span> <span class="nv">template_to_use</span><span class="o">=</span><span class="s1">'without_details.html'</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">extends</span> <span class="nv">template_to_use</span> <span class="cp">%}</span><span class="x"></span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">body</span> <span class="cp">%}</span><span class="x">content goes here</span><span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span><span class="x"></span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(jinja)>{% if show_details %}
{% set template_to_use='with_details.html' %}
{% else %}
{% set template_to_use='without_details.html' %}
{% endif %}
{% extends template_to_use %}
{% block body %}content goes here{% endblock %}<PYGMENTS_RAW -->
Also the limitation for trans tags that simple variables must now follow variable expressions should go (currently it must be <tt>{% trans foo, bar=baz, blah=blah %}</tt> instead of <tt>{% trans foo, bar=baz, blah %}</tt> because Jinja just reuses the rule for function calls)
I guess not all of that will make it into Jinja 1.2, and maybe I come up with better ideas but that's the plan so far.Jinja 1.1 released, it's arrived in debian too (Thanks Piotr Ożarowski for uploading it that quick) and I can start thinking about what to put into 1.2. Actually the plans for 1.2 exist for longer than 1.0 but implementing the Features for 1.0 and 1.1 took incredible long because more and more ideas came up.
Actually the Jinja code is quite stable by now and hopefully stable enough for the import system which will be the major change for 1.2. Basically what Jinja does by now is doing inheritance before generating the bytecode. Basically what I want to have in 1.2 is an import system so that you can import macros into a namespace and do dynamic layouts. This could slow things down a bit that's why I want to keep the static inheritance if possible and switch to the dynamic one if necessary. Currently Jinja does that implementation switching in other situations too, like in the Jinja 1.1 shorthand block syntax.
Basically what I want it to do is on the one hand this:
And on the other hand dynamic inheritance is another thing I want in Jinja:
Also the limitation for trans tags that simple variables must now follow variable expressions should go (currently it must be <tt>{% trans foo, bar=baz, blah=blah %}</tt> instead of <tt>{% trans foo, bar=baz, blah %}</tt> because Jinja just reuses the rule for function calls)
I guess not all of that will make it into Jinja 1.2, and maybe I come up with better ideas but that's the plan so far.SQAAAANTAAAABGJvZHlSUwAABKNKaW5qYSAxLjEgcmVsZWFzZWQsIGl0J3MgYXJyaXZlZCBpbiBk
ZWJpYW4gdG9vIChUaGFua3MgUGlvdHIgT8W8YXJvd3NraSBmb3IgdXBsb2FkaW5nIGl0IHRoYXQg
cXVpY2spIGFuZCBJIGNhbiBzdGFydCB0aGlua2luZyBhYm91dCB3aGF0IHRvIHB1dCBpbnRvIDEu
Mi4gQWN0dWFsbHkgdGhlIHBsYW5zIGZvciAxLjIgZXhpc3QgZm9yIGxvbmdlciB0aGFuIDEuMCBi
dXQgaW1wbGVtZW50aW5nIHRoZSBGZWF0dXJlcyBmb3IgMS4wIGFuZCAxLjEgdG9vayBpbmNyZWRp
YmxlIGxvbmcgYmVjYXVzZSBtb3JlIGFuZCBtb3JlIGlkZWFzIGNhbWUgdXAuCgpBY3R1YWxseSB0
aGUgSmluamEgY29kZSBpcyBxdWl0ZSBzdGFibGUgYnkgbm93IGFuZCBob3BlZnVsbHkgc3RhYmxl
IGVub3VnaCBmb3IgdGhlIGltcG9ydCBzeXN0ZW0gd2hpY2ggd2lsbCBiZSB0aGUgbWFqb3IgY2hh
bmdlIGZvciAxLjIuIEJhc2ljYWxseSB3aGF0IEppbmphIGRvZXMgYnkgbm93IGlzIGRvaW5nIGlu
aGVyaXRhbmNlIGJlZm9yZSBnZW5lcmF0aW5nIHRoZSBieXRlY29kZS4gQmFzaWNhbGx5IHdoYXQg
SSB3YW50IHRvIGhhdmUgaW4gMS4yIGlzIGFuIGltcG9ydCBzeXN0ZW0gc28gdGhhdCB5b3UgY2Fu
IGltcG9ydCBtYWNyb3MgaW50byBhIG5hbWVzcGFjZSBhbmQgZG8gZHluYW1pYyBsYXlvdXRzLiBU
aGlzIGNvdWxkIHNsb3cgdGhpbmdzIGRvd24gYSBiaXQgdGhhdCdzIHdoeSBJIHdhbnQgdG8ga2Vl
cCB0aGUgc3RhdGljIGluaGVyaXRhbmNlIGlmIHBvc3NpYmxlIGFuZCBzd2l0Y2ggdG8gdGhlIGR5
bmFtaWMgb25lIGlmIG5lY2Vzc2FyeS4gQ3VycmVudGx5IEppbmphIGRvZXMgdGhhdCBpbXBsZW1l
bnRhdGlvbiBzd2l0Y2hpbmcgaW4gb3RoZXIgc2l0dWF0aW9ucyB0b28sIGxpa2UgaW4gdGhlIEpp
bmphIDEuMSBzaG9ydGhhbmQgYmxvY2sgc3ludGF4LgoKQmFzaWNhbGx5IHdoYXQgSSB3YW50IGl0
IHRvIGRvIGlzIG9uIHRoZSBvbmUgaGFuZCB0aGlzOgoKCkFuZCBvbiB0aGUgb3RoZXIgaGFuZCBk
eW5hbWljIGluaGVyaXRhbmNlIGlzIGFub3RoZXIgdGhpbmcgSSB3YW50IGluIEppbmphOgoKCkFs
c28gdGhlIGxpbWl0YXRpb24gZm9yIHRyYW5zIHRhZ3MgdGhhdCBzaW1wbGUgdmFyaWFibGVzIG11
c3Qgbm93IGZvbGxvdyB2YXJpYWJsZSBleHByZXNzaW9ucyBzaG91bGQgZ28gKGN1cnJlbnRseSBp
dCBtdXN0IGJlIEwAAkVTAAAAAnR0TAAATQAAUwAAACN7JSB0cmFucyBmb28sIGJhcj1iYXosIGJs
YWg9YmxhaCAlfVMAAAAMIGluc3RlYWQgb2YgRVMAAAACdHRMAABNAABTAAAAHnslIHRyYW5zIGZv
bywgYmFyPWJheiwgYmxhaCAlfVMAAACvIGJlY2F1c2UgSmluamEganVzdCByZXVzZXMgdGhlIHJ1
bGUgZm9yIGZ1bmN0aW9uIGNhbGxzKQoKSSBndWVzcyBub3QgYWxsIG9mIHRoYXQgd2lsbCBtYWtl
IGl0IGludG8gSmluamEgMS4yLCBhbmQgbWF5YmUgSSBjb21lIHVwIHdpdGggYmV0dGVyIGlkZWFz
IGJ1dCB0aGF0J3MgdGhlIHBsYW4gc28gZmFyLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRy
b1JTAAAAAEwAAA==
XML Editing in Vimhttp://lucumr.pocoo.org/cogitations/2007/06/04/xml-editing-in-vim/2007-06-04T13:58:32Z2007-06-04T13:58:32ZArmin Ronacherxml-editing-in-vimyesyes2Today i started finishing the pocoo package split branch and tried to convert one template. That again reminded me that my Vim configuration sucked ass for that sort of job. Now I looked for something better and found something that seems to work quite well.
Basically the first thing I did was removing snippets emu completely. It's a really, really great extension but it's a bit too slow for me. I guess textmate solves that better than SnippetsEmu, I liked it in the beginning but in real world use cases I just forgot about using it or was faster by actually typing the snippet.
I formerly used the snippets to insert doctype and some tags and closed them myself. Some time before i used the xml.vim plugin but that has some severe bugs like the funny problem i would call "delete a greater than sign and reinsert it to insert yet another closing tag". Especially stupid if you want to add an attribute to an already existing tag.
The solution: <a href="http://vim.sourceforge.net/scripts/script.php?script_id=13">closetag</a> and <a href="http://vim.sourceforge.net/scripts/script.php?script_id=1211">XML indent</a> with this configuration:
<pre>let g:closetag_default_xml=1
autocmd FileType html,htmljinja,eruby let b:closetag_html_style=1
autocmd FileType html,xhtml,xml,htmljinja,eruby source ~/.vim/scripts/closetag.vim</pre>
Closing tags is as easy as <tt>^_</tt> and indention works very well.Today i started finishing the pocoo package split branch and tried to convert one template. That again reminded me that my Vim configuration sucked ass for that sort of job. Now I looked for something better and found something that seems to work quite well.
Basically the first thing I did was removing snippets emu completely. It's a really, really great extension but it's a bit too slow for me. I guess textmate solves that better than SnippetsEmu, I liked it in the beginning but in real world use cases I just forgot about using it or was faster by actually typing the snippet.
I formerly used the snippets to insert doctype and some tags and closed them myself. Some time before i used the xml.vim plugin but that has some severe bugs like the funny problem i would call "delete a greater than sign and reinsert it to insert yet another closing tag". Especially stupid if you want to add an attribute to an already existing tag.
The solution: <a href="http://vim.sourceforge.net/scripts/script.php?script_id=13">closetag</a> and <a href="http://vim.sourceforge.net/scripts/script.php?script_id=1211">XML indent</a> with this configuration:
<pre>let g:closetag_default_xml=1
autocmd FileType html,htmljinja,eruby let b:closetag_html_style=1
autocmd FileType html,xhtml,xml,htmljinja,eruby source ~/.vim/scripts/closetag.vim</pre>
Closing tags is as easy as <tt>^_</tt> and indention works very well.SQAAAANTAAAABGJvZHlSUwAAA7pUb2RheSBpIHN0YXJ0ZWQgZmluaXNoaW5nIHRoZSBwb2NvbyBw
YWNrYWdlIHNwbGl0IGJyYW5jaCBhbmQgdHJpZWQgdG8gY29udmVydCBvbmUgdGVtcGxhdGUuIFRo
YXQgYWdhaW4gcmVtaW5kZWQgbWUgdGhhdCBteSBWaW0gY29uZmlndXJhdGlvbiBzdWNrZWQgYXNz
IGZvciB0aGF0IHNvcnQgb2Ygam9iLiBOb3cgSSBsb29rZWQgZm9yIHNvbWV0aGluZyBiZXR0ZXIg
YW5kIGZvdW5kIHNvbWV0aGluZyB0aGF0IHNlZW1zIHRvIHdvcmsgcXVpdGUgd2VsbC4KCkJhc2lj
YWxseSB0aGUgZmlyc3QgdGhpbmcgSSBkaWQgd2FzIHJlbW92aW5nIHNuaXBwZXRzIGVtdSBjb21w
bGV0ZWx5LiBJdCdzIGEgcmVhbGx5LCByZWFsbHkgZ3JlYXQgZXh0ZW5zaW9uIGJ1dCBpdCdzIGEg
Yml0IHRvbyBzbG93IGZvciBtZS4gSSBndWVzcyB0ZXh0bWF0ZSBzb2x2ZXMgdGhhdCBiZXR0ZXIg
IHRoYW4gU25pcHBldHNFbXUsIEkgbGlrZWQgaXQgaW4gdGhlIGJlZ2lubmluZyBidXQgaW4gcmVh
bCB3b3JsZCB1c2UgY2FzZXMgSSBqdXN0IGZvcmdvdCBhYm91dCB1c2luZyBpdCBvciB3YXMgZmFz
dGVyIGJ5IGFjdHVhbGx5IHR5cGluZyB0aGUgc25pcHBldC4KCkkgZm9ybWVybHkgdXNlZCB0aGUg
c25pcHBldHMgdG8gaW5zZXJ0IGRvY3R5cGUgYW5kIHNvbWUgdGFncyBhbmQgY2xvc2VkIHRoZW0g
bXlzZWxmLiBTb21lIHRpbWUgYmVmb3JlIGkgdXNlZCB0aGUgeG1sLnZpbSBwbHVnaW4gYnV0IHRo
YXQgaGFzIHNvbWUgc2V2ZXJlIGJ1Z3MgbGlrZSB0aGUgZnVubnkgcHJvYmxlbSBpIHdvdWxkIGNh
bGwgImRlbGV0ZSBhIGdyZWF0ZXIgdGhhbiBzaWduIGFuZCByZWluc2VydCBpdCB0byBpbnNlcnQg
eWV0IGFub3RoZXIgY2xvc2luZyB0YWciLiBFc3BlY2lhbGx5IHN0dXBpZCBpZiB5b3Ugd2FudCB0
byBhZGQgYW4gYXR0cmlidXRlIHRvIGFuIGFscmVhZHkgZXhpc3RpbmcgdGFnLgoKVGhlIHNvbHV0
aW9uOiBMAARFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADpodHRwOi8vdmltLnNvdXJjZWZvcmdl
Lm5ldC9zY3JpcHRzL3NjcmlwdC5waHA/c2NyaXB0X2lkPTEzUwAAAAhjbG9zZXRhZ1MAAAAFIGFu
ZCBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADxodHRwOi8vdmltLnNvdXJjZWZvcmdlLm5ldC9z
Y3JpcHRzL3NjcmlwdC5waHA/c2NyaXB0X2lkPTEyMTFTAAAAClhNTCBpbmRlbnRTAAAAGiB3aXRo
IHRoaXMgY29uZmlndXJhdGlvbjoKRVMAAAADcHJlTAAATQAAUwAAALFsZXQgZzpjbG9zZXRhZ19k
ZWZhdWx0X3htbD0xCmF1dG9jbWQgRmlsZVR5cGUgaHRtbCxodG1samluamEsZXJ1YnkgbGV0IGI6
Y2xvc2V0YWdfaHRtbF9zdHlsZT0xCmF1dG9jbWQgRmlsZVR5cGUgaHRtbCx4aHRtbCx4bWwsaHRt
bGppbmphLGVydWJ5IHNvdXJjZSB+Ly52aW0vc2NyaXB0cy9jbG9zZXRhZy52aW1TAAAAHApDbG9z
aW5nIHRhZ3MgaXMgYXMgZWFzeSBhcyBFUwAAAAJ0dEwAAE0AAFMAAAACXl9TAAAAHyBhbmQgaW5k
ZW50aW9uIHdvcmtzIHZlcnkgd2VsbC5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAA
AABMAAA=
Miguel de Icaza about Monohttp://lucumr.pocoo.org/cogitations/2007/06/04/miguel-de-icaza-about-mono/2007-06-04T10:24:56Z2007-06-04T10:24:56ZArmin Ronachermiguel-de-icaza-about-monoyesyes2Actually not that up to date, I think it's about one year old but I accidentally found it just now: <a href="http://video.google.com/videoplay?docid=2735372863334368534&q=Miguel+de+Icaza">Miguel de Icaza about Mono</a> at Microsoft. (In an interview on <a href="http://port25.technet.com/">port25</a>)Actually not that up to date, I think it's about one year old but I accidentally found it just now: <a href="http://video.google.com/videoplay?docid=2735372863334368534&q=Miguel+de+Icaza">Miguel de Icaza about Mono</a> at Microsoft. (In an interview on <a href="http://port25.technet.com/">port25</a>)SQAAAANTAAAABGJvZHlSUwAAAGRBY3R1YWxseSBub3QgdGhhdCB1cCB0byBkYXRlLCBJIHRoaW5r
IGl0J3MgYWJvdXQgb25lIHllYXIgb2xkIGJ1dCBJIGFjY2lkZW50YWxseSBmb3VuZCBpdCBqdXN0
IG5vdzogTAACRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAABNaHR0cDovL3ZpZGVvLmdvb2dsZS5j
b20vdmlkZW9wbGF5P2RvY2lkPTI3MzUzNzI4NjMzMzQzNjg1MzQmcT1NaWd1ZWwrZGUrSWNhemFT
AAAAGk1pZ3VlbCBkZSBJY2F6YSBhYm91dCBNb25vUwAAACMgYXQgTWljcm9zb2Z0LiAoSW4gYW4g
aW50ZXJ2aWV3IG9uIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAGmh0dHA6Ly9wb3J0MjUudGVj
aG5ldC5jb20vUwAAAAZwb3J0MjVTAAAAASlTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9S
UwAAAABMAAA=
Implicit Python Propertieshttp://lucumr.pocoo.org/cogitations/2007/06/03/implicit-python-properties/2007-06-03T10:41:10Z2007-06-03T10:41:10ZArmin Ronacherimplicit-python-propertiesyesyes2Everybody knows that nice <tt>property</tt> function that uses the python descriptor protocol to call functions when getting or settings values. But the disadvantage: For read/write properties it requires two helper functions which causes code that looks like this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">foo</span> <span class="o">=</span> <span class="n">initial</span>
<span class="k">def</span> <span class="nf">_get_foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_foo</span>
<span class="k">def</span> <span class="nf">_set_foo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_foo</span> <span class="o">=</span> <span class="n">value</span>
<span class="n">foo</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_foo</span><span class="p">,</span> <span class="n">_set_foo</span><span class="p">,</span> <span class="s">'The docstring'</span><span class="p">)</span>
<span class="k">del</span> <span class="n">_get_foo</span><span class="p">,</span> <span class="n">_set_foo</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>class Foo(object):
def __init__(self, initial):
self.foo = initial
def _get_foo(self):
return self._foo
def _set_foo(self, value):
self._foo = value
foo = property(_get_foo, _set_foo, 'The docstring')
del _get_foo, _set_foo<PYGMENTS_RAW -->
I thought about introspecting the call frame and retrieving wrapped functions but because the python bytecode uses STORE_FAST/LOAD_FAST opcodes this doesn't work. But with a little bit of bytecode hacking I got a decorator working that is both magical and implicit (and quite slow on application startup, but equally fast at execution because it just creates a normal property). It looks like this when in use:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">foo</span> <span class="o">=</span> <span class="n">initial</span>
<span class="nd">@autoproperty</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
<span class="sd">'''The docstring'''</span>
<span class="k">def</span> <span class="nf">fget</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_foo</span>
<span class="k">def</span> <span class="nf">fset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_foo</span> <span class="o">=</span> <span class="n">value</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>class Foo(object):
def __init__(self, initial):
self.foo = initial
@autoproperty
def foo():
'''The docstring'''
def fget(self):
return self._foo
def fset(self, value):
self._foo = value<PYGMENTS_RAW -->
The module that implements this decorator is available here: <a href="http://lucumr.pocoo.org/trac/repos/autoproperty.py">autoproperty.py</a>
It's cool to see what's possible with python, even if it makes no sense and nobody would ever use it :DEverybody knows that nice <tt>property</tt> function that uses the python descriptor protocol to call functions when getting or settings values. But the disadvantage: For read/write properties it requires two helper functions which causes code that looks like this:
I thought about introspecting the call frame and retrieving wrapped functions but because the python bytecode uses STORE_FAST/LOAD_FAST opcodes this doesn't work. But with a little bit of bytecode hacking I got a decorator working that is both magical and implicit (and quite slow on application startup, but equally fast at execution because it just creates a normal property). It looks like this when in use:
The module that implements this decorator is available here: <a href="http://lucumr.pocoo.org/trac/repos/autoproperty.py">autoproperty.py</a>
It's cool to see what's possible with python, even if it makes no sense and nobody would ever use it :DSQAAAANTAAAABGJvZHlSUwAAABpFdmVyeWJvZHkga25vd3MgdGhhdCBuaWNlIEwAAkVTAAAAAnR0
TAAATQAAUwAAAAhwcm9wZXJ0eVMAAAK5IGZ1bmN0aW9uIHRoYXQgdXNlcyB0aGUgcHl0aG9uIGRl
c2NyaXB0b3IgcHJvdG9jb2wgdG8gY2FsbCBmdW5jdGlvbnMgd2hlbiBnZXR0aW5nIG9yIHNldHRp
bmdzIHZhbHVlcy4gQnV0IHRoZSBkaXNhZHZhbnRhZ2U6IEZvciByZWFkL3dyaXRlIHByb3BlcnRp
ZXMgaXQgcmVxdWlyZXMgdHdvIGhlbHBlciBmdW5jdGlvbnMgd2hpY2ggY2F1c2VzIGNvZGUgdGhh
dCBsb29rcyBsaWtlIHRoaXM6CgpJIHRob3VnaHQgYWJvdXQgaW50cm9zcGVjdGluZyB0aGUgY2Fs
bCBmcmFtZSBhbmQgcmV0cmlldmluZyB3cmFwcGVkIGZ1bmN0aW9ucyBidXQgYmVjYXVzZSB0aGUg
cHl0aG9uIGJ5dGVjb2RlIHVzZXMgU1RPUkVfRkFTVC9MT0FEX0ZBU1Qgb3Bjb2RlcyB0aGlzIGRv
ZXNuJ3Qgd29yay4gQnV0IHdpdGggYSBsaXR0bGUgYml0IG9mIGJ5dGVjb2RlIGhhY2tpbmcgSSBn
b3QgYSBkZWNvcmF0b3Igd29ya2luZyB0aGF0IGlzIGJvdGggbWFnaWNhbCBhbmQgaW1wbGljaXQg
KGFuZCBxdWl0ZSBzbG93IG9uIGFwcGxpY2F0aW9uIHN0YXJ0dXAsIGJ1dCBlcXVhbGx5IGZhc3Qg
YXQgZXhlY3V0aW9uIGJlY2F1c2UgaXQganVzdCBjcmVhdGVzIGEgbm9ybWFsIHByb3BlcnR5KS4g
SXQgbG9va3MgbGlrZSB0aGlzIHdoZW4gaW4gdXNlOgoKVGhlIG1vZHVsZSB0aGF0IGltcGxlbWVu
dHMgdGhpcyBkZWNvcmF0b3IgaXMgYXZhaWxhYmxlIGhlcmU6IEVTAAAAAWFMAABNAAFTAAAABGhy
ZWZTAAAAMmh0dHA6Ly9sdWN1bXIucG9jb28ub3JnL3RyYWMvcmVwb3MvYXV0b3Byb3BlcnR5LnB5
UwAAAA9hdXRvcHJvcGVydHkucHlTAAAAaQoKSXQncyBjb29sIHRvIHNlZSB3aGF0J3MgcG9zc2li
bGUgd2l0aCBweXRob24sIGV2ZW4gaWYgaXQgbWFrZXMgbm8gc2Vuc2UgYW5kIG5vYm9keSB3b3Vs
ZCBldmVyIHVzZSBpdCA6RFMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
koderkoder.mail@gmail.comhttp://Notyet2007-06-11T13:01:31Znono0Interesting post. I use other code, but it don't work with lambda's :
<pre>def mkprop(func):
gfunc = sfunc = dfunc = None
for i in func.func_code.co_consts:
if isinstance(i,types.CodeType):
if i.co_name == 'get':
gfunc = new.function(i,globals())
elif i.co_name == 'set':
sfunc = new.function(i,globals())
elif i.co_name == 'set':
sfunc = new.function(i,globals())
if not gfunc and not sfunc and not dfunc:
raise ValueError("Can't found and function to make property")
else:
return property(fget = gfunc,fset = sfunc,
fdel = dfunc,doc = func.__doc__)
class Test(object):
@mkprop
def prop():
"property"
def set(self,val):
self._val = val
def get(self):
return self._val
#but not like this
#def prop():
# get = lambda self : self._val
# set = my_other_function</pre>
> It’s cool to see what’s possible with python, even if it makes no sense and nobody would
> ever use it :D
I'm gonna use it, instead o my one's ;).
P.S. +1 on Python cool.Interesting post. I use other code, but it don't work with lambda's :
<pre>def mkprop(func):
gfunc = sfunc = dfunc = None
for i in func.func_code.co_consts:
if isinstance(i,types.CodeType):
if i.co_name == 'get':
gfunc = new.function(i,globals())
elif i.co_name == 'set':
sfunc = new.function(i,globals())
elif i.co_name == 'set':
sfunc = new.function(i,globals())
if not gfunc and not sfunc and not dfunc:
raise ValueError("Can't found and function to make property")
else:
return property(fget = gfunc,fset = sfunc,
fdel = dfunc,doc = func.__doc__)
class Test(object):
@mkprop
def prop():
"property"
def set(self,val):
self._val = val
def get(self):
return self._val
#but not like this
#def prop():
# get = lambda self : self._val
# set = my_other_function</pre>
> It’s cool to see what’s possible with python, even if it makes no sense and nobody would
> ever use it :D
I'm gonna use it, instead o my one's ;).
P.S. +1 on Python cool.SQAAAAJTAAAABGJvZHlSUwAAAEhJbnRlcmVzdGluZyAgcG9zdC4gSSB1c2Ugb3RoZXIgY29kZSwg
YnV0IGl0IGRvbid0IHdvcmsgd2l0aCBsYW1iZGEncyA6CgpMAAFFUwAAAANwcmVMAABNAABTAAAD
jWRlZiBta3Byb3AoZnVuYyk6CiAgICBnZnVuYyA9IHNmdW5jID0gZGZ1bmMgPSBOb25lCiAgICBm
b3IgaSBpbiBmdW5jLmZ1bmNfY29kZS5jb19jb25zdHM6CiAgICAgICAgaWYgaXNpbnN0YW5jZShp
LHR5cGVzLkNvZGVUeXBlKToKICAgICAgICAgICAgaWYgaS5jb19uYW1lID09ICdnZXQnOgogICAg
ICAgICAgICAgICAgZ2Z1bmMgPSBuZXcuZnVuY3Rpb24oaSxnbG9iYWxzKCkpCiAgICAgICAgICAg
IGVsaWYgaS5jb19uYW1lID09ICdzZXQnOgogICAgICAgICAgICAgICAgc2Z1bmMgPSBuZXcuZnVu
Y3Rpb24oaSxnbG9iYWxzKCkpCiAgICAgICAgICAgIGVsaWYgaS5jb19uYW1lID09ICdzZXQnOgog
ICAgICAgICAgICAgICAgc2Z1bmMgPSBuZXcuZnVuY3Rpb24oaSxnbG9iYWxzKCkpCiAgICBpZiBu
b3QgZ2Z1bmMgYW5kIG5vdCBzZnVuYyBhbmQgbm90IGRmdW5jOgogICAgICAgIHJhaXNlIFZhbHVl
RXJyb3IoIkNhbid0IGZvdW5kIGFuZCBmdW5jdGlvbiB0byBtYWtlIHByb3BlcnR5IikKICAgIGVs
c2U6CiAgICAgICAgcmV0dXJuIHByb3BlcnR5KGZnZXQgPSBnZnVuYyxmc2V0ID0gc2Z1bmMsCiAg
ICAgICAgICAgICAgICAgICAgICAgIGZkZWwgPSBkZnVuYyxkb2MgPSBmdW5jLl9fZG9jX18pCmNs
YXNzIFRlc3Qob2JqZWN0KToKICAgIEBta3Byb3AKICAgIGRlZiBwcm9wKCk6CiAgICAgICAgInBy
b3BlcnR5IgogICAgICAgIGRlZiBzZXQoc2VsZix2YWwpOgogICAgICAgICAgICBzZWxmLl92YWwg
PSB2YWwKICAgICAgICBkZWYgZ2V0KHNlbGYpOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fdmFs
CiAgICAjYnV0IG5vdCBsaWtlIHRoaXMKICAgICNkZWYgcHJvcCgpOgogICAgIyAgICBnZXQgPSBs
YW1iZGEgc2VsZiA6IHNlbGYuX3ZhbAogICAgIyAgICBzZXQgPSBteV9vdGhlcl9mdW5jdGlvblMA
AAC1Cgo+IEl04oCZcyBjb29sIHRvIHNlZSB3aGF04oCZcyBwb3NzaWJsZSB3aXRoIHB5dGhvbiwg
ZXZlbiBpZiBpdCBtYWtlcyBubyBzZW5zZSBhbmQgbm9ib2R5IHdvdWxkICAKPiBldmVyIHVzZSBp
dCA6RAoKSSdtIGdvbm5hIHVzZSBpdCwgaW5zdGVhZCBvIG15IG9uZSdzIDspLgpQLlMuICsxIG9u
IFB5dGhvbiBjb29sLlMAAAAGcGFyc2VyUwAAAARodG1s
Filename Completionhttp://lucumr.pocoo.org/cogitations/2007/06/03/filename-completion/2007-06-03T08:02:27Z2007-06-03T08:02:27ZArmin Ronacherfilename-completionyesyes2I knew <tt>^N</tt> which completes used names from all buffers. But i didn't know <tt>^X^F</tt> which completes filenames. Awesome :DI knew <tt>^N</tt> which completes used names from all buffers. But i didn't know <tt>^X^F</tt> which completes filenames. Awesome :DSQAAAANTAAAABGJvZHlSUwAAAAdJIGtuZXcgTAACRVMAAAACdHRMAABNAABTAAAAAl5OUwAAAEAg
d2hpY2ggY29tcGxldGVzIHVzZWQgbmFtZXMgZnJvbSBhbGwgYnVmZmVycy4gQnV0IGkgZGlkbid0
IGtub3cgRVMAAAACdHRMAABNAABTAAAABF5YXkZTAAAAJiB3aGljaCBjb21wbGV0ZXMgZmlsZW5h
bWVzLiBBd2Vzb21lIDpEUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Just Another Ruby Hackerhttp://lucumr.pocoo.org/cogitations/2007/06/02/just-another-ruby-hacker/2007-06-02T18:31:24Z2007-06-02T18:31:24ZArmin Ronacherjust-another-ruby-hackeryesyes2<pre>class<<self;define_method(%_>6E9@50>:DD:?8_.tr(%_0-f_,%_\\_-t_)){|*_|@_\\
=_};end;(Just another Ruby hacker!);(_,@_=@_;$><<_<<%_ _)while@_;$><<$/</pre>
Looks like another testcase for <a href="http://pygments.org/">pygments</a>, but it's my new signature for the german ruby forum :D<pre>class<<self;define_method(%_>6E9@50>:DD:?8_.tr(%_0-f_,%_\\_-t_)){|*_|@_\\
=_};end;(Just another Ruby hacker!);(_,@_=@_;$><<_<<%_ _)while@_;$><<$/</pre>
Looks like another testcase for <a href="http://pygments.org/">pygments</a>, but it's my new signature for the german ruby forum :DSQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAANwcmVMAABNAABTAAAAkWNsYXNzPDxzZWxmO2Rl
ZmluZV9tZXRob2QoJV8+NkU5QDUwPjpERDo/OF8udHIoJV8wLWZfLCVfXFxfLXRfKSl7fCpffEBf
XFwKPV99O2VuZDsoSnVzdCBhbm90aGVyIFJ1YnkgaGFja2VyISk7KF8sQF89QF87JD48PF88PCVf
IF8pd2hpbGVAXzskPjw8JC9TAAAAIQpMb29rcyBsaWtlIGFub3RoZXIgdGVzdGNhc2UgZm9yIEVT
AAAAAWFMAABNAAFTAAAABGhyZWZTAAAAFGh0dHA6Ly9weWdtZW50cy5vcmcvUwAAAAhweWdtZW50
c1MAAAA4LCBidXQgaXQncyBteSBuZXcgc2lnbmF0dXJlIGZvciB0aGUgZ2VybWFuIHJ1YnkgZm9y
dW0gOkRTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
This is Rubyhttp://lucumr.pocoo.org/cogitations/2007/06/02/this-is-ruby/2007-06-02T15:44:34Z2007-06-02T15:44:34ZArmin Ronacherthis-is-rubyyesyes2<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">def</span> <span class="nf">method_missing</span><span class="o">*</span><span class="n">_</span><span class="p">;</span><span class="vi">@_</span><span class="o">=</span><span class="n">_</span><span class="p">;</span><span class="k">end</span>
<span class="no">Is</span> <span class="n">this</span> <span class="no">Ruby</span><span class="p">?</span> <span class="no">Yes</span> <span class="n">it</span> <span class="n">is</span><span class="o">.</span>
<span class="no">It</span><span class="s1">'s really rockin'</span><span class="o">.</span>
<span class="no">Ruby</span> <span class="n">is</span> <span class="n">cool</span> <span class="ss">:D</span>
<span class="nb">puts</span><span class="vi">@_</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">' '</span><span class="p">)</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/s(it|d)/i</span><span class="p">,</span><span class="s1">'!'</span><span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(ruby)>def method_missing*_;@_=_;end
Is this Ruby? Yes it is.
It's really rockin'.
Ruby is cool :D
puts@_.join(' ').gsub(/\s(it|d)/i,'!')<PYGMENTS_RAW -->
Output:
<pre>Is this Ruby? Yes!! Ruby is cool!</pre>
Output:
<pre>Is this Ruby? Yes!! Ruby is cool!</pre>SQAAAANTAAAABGJvZHlSUwAAAAkKT3V0cHV0OgpMAAFFUwAAAANwcmVMAABNAABTAAAAIUlzIHRo
aXMgUnVieT8gWWVzISEgUnVieSBpcyBjb29sIVMAAAAAUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAA
BWludHJvUlMAAAAATAAA
The Power of Nightmareshttp://lucumr.pocoo.org/cogitations/2007/06/02/the-power-of-nightmares/2007-06-02T14:04:33Z2007-06-02T14:04:33ZArmin Ronacherthe-power-of-nightmaresyesyes2<img class="standalone" src="/static/pictures/terroristic-plan.jpg" alt="secret terroristic plan" />
<small>as answer to <a href="http://video.google.com/videoplay?docid=881321004838285177">#1</a>, <a href="http://video.google.com/videoplay?docid=4602171665328041876">#2</a>, and <a href="http://video.google.com/videoplay?docid=2081592330319789254">#3</a>.</small><img src="/static/pictures/terroristic-plan.jpg" alt="secret terroristic plan" class="standalone">
<small>as answer to <a href="http://video.google.com/videoplay?docid=881321004838285177">#1</a>, <a href="http://video.google.com/videoplay?docid=4602171665328041876">#2</a>, and <a href="http://video.google.com/videoplay?docid=2081592330319789254">#3</a>.</small>SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAANpbWdMAABNAANTAAAAA3NyY1MAAAAlL3N0YXRp
Yy9waWN0dXJlcy90ZXJyb3Jpc3RpYy1wbGFuLmpwZ1MAAAADYWx0UwAAABdzZWNyZXQgdGVycm9y
aXN0aWMgcGxhblMAAAAFY2xhc3NTAAAACnN0YW5kYWxvbmVTAAAAAFMAAAABCkVTAAAABXNtYWxs
TAADRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAA6aHR0cDovL3ZpZGVvLmdvb2dsZS5jb20vdmlk
ZW9wbGF5P2RvY2lkPTg4MTMyMTAwNDgzODI4NTE3N1MAAAACIzFTAAAAAiwgRVMAAAABYUwAAE0A
AVMAAAAEaHJlZlMAAAA7aHR0cDovL3ZpZGVvLmdvb2dsZS5jb20vdmlkZW9wbGF5P2RvY2lkPTQ2
MDIxNzE2NjUzMjgwNDE4NzZTAAAAAiMyUwAAAAYsIGFuZCBFUwAAAAFhTAAATQABUwAAAARocmVm
UwAAADtodHRwOi8vdmlkZW8uZ29vZ2xlLmNvbS92aWRlb3BsYXk/ZG9jaWQ9MjA4MTU5MjMzMDMx
OTc4OTI1NFMAAAACIzNTAAAAAS5NAABTAAAADWFzIGFuc3dlciB0byBTAAAAAFMAAAAGcGFyc2Vy
UwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Jinja 1.1 Releasedhttp://lucumr.pocoo.org/cogitations/2007/06/02/jinja-11-released/2007-06-02T12:35:45Z2007-06-02T12:35:45ZArmin Ronacherjinja-11-releasedyesyes2<p>Jinja 1.1 codenname sinka is out! And with more changes then ever. Here a
small summary of the new features and improvements:</p>
<ul>
<li>blocks now support <tt>{{ super() }}</tt> to render the parent output.</li>
<li>the template lexer keeps not track of brace, parenthesis and bracket balance in order to not break variable tags apart if they are configured to look like this: <tt>${expr}</tt>. This also fixes the problem with nested dicts in variable expressions.</li>
<li>added whitespace management system for the template designer.</li>
<li>many new filters and helpers such as <tt>lipsum</tt>, <tt>batch</tt>, <tt>slice</tt>, <tt>sum</tt>, <tt>abs</tt>, <tt>round</tt>, <tt>striptags</tt> and others.</li>
<li>reimplemented Buffet plugin so that you can use Jinja in pylons.</li>
<li>added optional C-implementation of the context baseclass.</li>
<li>it's now possible to stream templates.</li>
<li>reworked loader layer. All the cached loaders now have "private" non cached baseclasses so that you can easily mix your own caching layers in.</li>
<li>added <tt>MemcachedLoaderMixin</tt> and <tt>MemcachedFileSystemLoader</tt> contributed by Bryan McLemore.</li>
<li>many new unittests, bugfixes and improvements.</li>
</ul>
<p>The whole list of changes can be found in the <a href="http://jinja.pocoo.org/documentation/changelog#version-1-1">changelog</a>. Get it while it's hot from the <a href="http://cheeseshop.python.org/pypi/Jinja/1.1">cheeseshop</a>.</p><p>Jinja 1.1 codenname sinka is out! And with more changes then ever. Here a
small summary of the new features and improvements:</p>
<ul>
<li>blocks now support <tt>{{ super() }}</tt> to render the parent output.</li>
<li>the template lexer keeps not track of brace, parenthesis and bracket balance in order to not break variable tags apart if they are configured to look like this: <tt>${expr}</tt>. This also fixes the problem with nested dicts in variable expressions.</li>
<li>added whitespace management system for the template designer.</li>
<li>many new filters and helpers such as <tt>lipsum</tt>, <tt>batch</tt>, <tt>slice</tt>, <tt>sum</tt>, <tt>abs</tt>, <tt>round</tt>, <tt>striptags</tt> and others.</li>
<li>reimplemented Buffet plugin so that you can use Jinja in pylons.</li>
<li>added optional C-implementation of the context baseclass.</li>
<li>it's now possible to stream templates.</li>
<li>reworked loader layer. All the cached loaders now have "private" non cached baseclasses so that you can easily mix your own caching layers in.</li>
<li>added <tt>MemcachedLoaderMixin</tt> and <tt>MemcachedFileSystemLoader</tt> contributed by Bryan McLemore.</li>
<li>many new unittests, bugfixes and improvements.</li>
</ul>
<p>The whole list of changes can be found in the <a href="http://jinja.pocoo.org/documentation/changelog#version-1-1">changelog</a>. Get it while it's hot from the <a href="http://cheeseshop.python.org/pypi/Jinja/1.1">cheeseshop</a>.</p>SQAAAANTAAAABGJvZHlSUwAAAABMAANFUwAAAAFwTAAATQAAUwAAAH1KaW5qYSAxLjEgY29kZW5u
YW1lIHNpbmthIGlzIG91dCEgQW5kIHdpdGggbW9yZSBjaGFuZ2VzIHRoZW4gZXZlci4gSGVyZSBh
CnNtYWxsIHN1bW1hcnkgb2YgdGhlIG5ldyBmZWF0dXJlcyBhbmQgaW1wcm92ZW1lbnRzOlMAAAAB
CkVTAAAAAnVsTAAKRVMAAAACbGlMAAFFUwAAAAJ0dEwAAE0AAFMAAAANe3sgc3VwZXIoKSB9fVMA
AAAdIHRvIHJlbmRlciB0aGUgcGFyZW50IG91dHB1dC5NAABTAAAAE2Jsb2NrcyBub3cgc3VwcG9y
dCBTAAAAAwogIEVTAAAAAmxpTAABRVMAAAACdHRMAABNAABTAAAAByR7ZXhwcn1TAAAASC4gVGhp
cyBhbHNvIGZpeGVzIHRoZSBwcm9ibGVtIHdpdGggbmVzdGVkIGRpY3RzIGluIHZhcmlhYmxlIGV4
cHJlc3Npb25zLk0AAFMAAAChdGhlIHRlbXBsYXRlIGxleGVyIGtlZXBzIG5vdCB0cmFjayBvZiBi
cmFjZSwgcGFyZW50aGVzaXMgYW5kIGJyYWNrZXQgYmFsYW5jZSBpbiBvcmRlciB0byBub3QgYnJl
YWsgdmFyaWFibGUgdGFncyBhcGFydCBpZiB0aGV5IGFyZSBjb25maWd1cmVkIHRvIGxvb2sgbGlr
ZSB0aGlzOiBTAAAAAwogIEVTAAAAAmxpTAAATQAAUwAAAD1hZGRlZCB3aGl0ZXNwYWNlIG1hbmFn
ZW1lbnQgc3lzdGVtIGZvciB0aGUgdGVtcGxhdGUgZGVzaWduZXIuUwAAAAMKICBFUwAAAAJsaUwA
B0VTAAAAAnR0TAAATQAAUwAAAAZsaXBzdW1TAAAAAiwgRVMAAAACdHRMAABNAABTAAAABWJhdGNo
UwAAAAIsIEVTAAAAAnR0TAAATQAAUwAAAAVzbGljZVMAAAACLCBFUwAAAAJ0dEwAAE0AAFMAAAAD
c3VtUwAAAAIsIEVTAAAAAnR0TAAATQAAUwAAAANhYnNTAAAAAiwgRVMAAAACdHRMAABNAABTAAAA
BXJvdW5kUwAAAAIsIEVTAAAAAnR0TAAATQAAUwAAAAlzdHJpcHRhZ3NTAAAADCBhbmQgb3RoZXJz
Lk0AAFMAAAAlbWFueSBuZXcgZmlsdGVycyBhbmQgaGVscGVycyBzdWNoIGFzIFMAAAADCiAgRVMA
AAACbGlMAABNAABTAAAAQHJlaW1wbGVtZW50ZWQgQnVmZmV0IHBsdWdpbiBzbyB0aGF0IHlvdSBj
YW4gdXNlIEppbmphIGluIHB5bG9ucy5TAAAAAwogIEVTAAAAAmxpTAAATQAAUwAAADlhZGRlZCBv
cHRpb25hbCBDLWltcGxlbWVudGF0aW9uIG9mIHRoZSBjb250ZXh0IGJhc2VjbGFzcy5TAAAAAwog
IEVTAAAAAmxpTAAATQAAUwAAACZpdCdzIG5vdyBwb3NzaWJsZSB0byBzdHJlYW0gdGVtcGxhdGVz
LlMAAAADCiAgRVMAAAACbGlMAABNAABTAAAAjnJld29ya2VkIGxvYWRlciBsYXllci4gQWxsIHRo
ZSBjYWNoZWQgbG9hZGVycyBub3cgaGF2ZSAicHJpdmF0ZSIgbm9uIGNhY2hlZCBiYXNlY2xhc3Nl
cyBzbyB0aGF0IHlvdSBjYW4gZWFzaWx5IG1peCB5b3VyIG93biBjYWNoaW5nIGxheWVycyBpbi5T
AAAAAwogIEVTAAAAAmxpTAACRVMAAAACdHRMAABNAABTAAAAFE1lbWNhY2hlZExvYWRlck1peGlu
UwAAAAUgYW5kIEVTAAAAAnR0TAAATQAAUwAAABlNZW1jYWNoZWRGaWxlU3lzdGVtTG9hZGVyUwAA
AB8gY29udHJpYnV0ZWQgYnkgQnJ5YW4gTWNMZW1vcmUuTQAAUwAAAAZhZGRlZCBTAAAAAwogIEVT
AAAAAmxpTAAATQAAUwAAAC5tYW55IG5ldyB1bml0dGVzdHMsIGJ1Z2ZpeGVzIGFuZCBpbXByb3Zl
bWVudHMuUwAAAAEKTQAAUwAAAAMKICBTAAAAAQpFUwAAAAFwTAACRVMAAAABYUwAAE0AAVMAAAAE
aHJlZlMAAAA6aHR0cDovL2ppbmphLnBvY29vLm9yZy9kb2N1bWVudGF0aW9uL2NoYW5nZWxvZyN2
ZXJzaW9uLTEtMVMAAAAJY2hhbmdlbG9nUwAAACEuIEdldCBpdCB3aGlsZSBpdCdzIGhvdCBmcm9t
IHRoZSBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACtodHRwOi8vY2hlZXNlc2hvcC5weXRob24u
b3JnL3B5cGkvSmluamEvMS4xUwAAAApjaGVlc2VzaG9wUwAAAAEuTQAAUwAAAC5UaGUgd2hvbGUg
bGlzdCBvZiBjaGFuZ2VzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUwAAAABTAAAABnBhcnNlclMAAAAE
aHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Jinja 1.1 Delayedhttp://lucumr.pocoo.org/cogitations/2007/06/02/jinja-11-delayed/2007-06-01T23:52:18Z2007-06-01T23:52:18ZArmin Ronacherjinja-11-delayedyesyes2<a href="/cogitations/2007/05/29/jinja-11-in-feature-freeze/">I was wrong</a>, Jinja is not in feature freeze and I haven't released. Why? Because Bryan McLemore contributed a memcached loader mixin and I then reworked the loader system a bit so that it's now easier to write custom loaders with various caching mixins or mixing your own caching mixin into an existing loader.
All unittests still pass and I will hopefully release tomorrow^Wtoday tough.<a href="/cogitations/2007/05/29/jinja-11-in-feature-freeze/">I was wrong</a>, Jinja is not in feature freeze and I haven't released. Why? Because Bryan McLemore contributed a memcached loader mixin and I then reworked the loader system a bit so that it's now easier to write custom loaders with various caching mixins or mixing your own caching mixin into an existing loader.
All unittests still pass and I will hopefully release tomorrow^Wtoday tough.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADMvY29naXRh
dGlvbnMvMjAwNy8wNS8yOS9qaW5qYS0xMS1pbi1mZWF0dXJlLWZyZWV6ZS9TAAAAC0kgd2FzIHdy
b25nUwAAAXksIEppbmphIGlzIG5vdCBpbiBmZWF0dXJlIGZyZWV6ZSBhbmQgSSBoYXZlbid0IHJl
bGVhc2VkLiBXaHk/IEJlY2F1c2UgQnJ5YW4gTWNMZW1vcmUgY29udHJpYnV0ZWQgYSBtZW1jYWNo
ZWQgbG9hZGVyIG1peGluIGFuZCBJIHRoZW4gcmV3b3JrZWQgdGhlIGxvYWRlciBzeXN0ZW0gYSBi
aXQgc28gdGhhdCBpdCdzIG5vdyBlYXNpZXIgdG8gd3JpdGUgY3VzdG9tIGxvYWRlcnMgd2l0aCB2
YXJpb3VzIGNhY2hpbmcgbWl4aW5zIG9yIG1peGluZyB5b3VyIG93biBjYWNoaW5nIG1peGluIGlu
dG8gYW4gZXhpc3RpbmcgbG9hZGVyLgoKQWxsIHVuaXR0ZXN0cyBzdGlsbCBwYXNzIGFuZCBJIHdp
bGwgaG9wZWZ1bGx5IHJlbGVhc2UgdG9tb3Jyb3deV3RvZGF5IHRvdWdoLlMAAAAGcGFyc2VyUwAA
AARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Kind of Directory Traversalhttp://lucumr.pocoo.org/cogitations/2007/06/01/kind-of-directory-traversal/2007-06-01T12:41:59Z2007-06-01T12:41:59ZArmin Ronacherkind-of-directory-traversalyesyes2If you see this code: what's wrong?
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">os</span> <span class="k">import</span> <span class="n">path</span>
<span class="n">page_id</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'page_id'</span><span class="p">,</span> <span class="s">'index'</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">__file__</span><span class="p">),</span> <span class="s">'includes'</span><span class="p">,</span> <span class="n">page_id</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">file</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="n">handle_not_found</span><span class="p">()</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from os import path
page_id = req.args.get('page_id', 'index')
filename = path.join(path.dirname(__file__), 'includes', page_id)
try:
f = file(filename)
except IOError:
handle_not_found()<PYGMENTS_RAW -->
First of all, the page_id comes from an user submitted variable in a web application. It's in fact a variable from the query string. Now someone could say <tt>?page_id=../../../etc/htpasswd</tt> etc. There are numerous ways to fix that. For example you can do this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">os</span> <span class="k">import</span> <span class="n">path</span>
<span class="n">fn</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="o">*</span><span class="p">[</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">fn</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="o">!=</span> <span class="s">'..'</span><span class="p">])</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from os import path
fn = path.join(*[x for x in fn.split('/') if x != '..'])<PYGMENTS_RAW -->
This also makes sure that the path separator is valid. I guess everybody that knows about security also knows how to defend those problems.
What you might not know is that python itself doesn't accept null bytes in the "file/open" call. This is some sort of built in security feature. Other languages such as PHP forward the nullbyte to the C layer. Thus an attacker could cut off a string at a given position to gain further control over the input layer (cutting of a .php extension etc). This is more severe in Perl where you can also pipe stuff in the file call.
This security feature however doesn't raise an IOError but a TypeError! So the corrected example from above looks like this:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="k">from</span> <span class="nn">os</span> <span class="k">import</span> <span class="n">path</span>
<span class="n">page_id</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'page_id'</span><span class="p">,</span> <span class="s">'index'</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">__file__</span><span class="p">),</span> <span class="s">'includes'</span><span class="p">,</span>
<span class="o">*</span><span class="p">[</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">page_id</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="o">!=</span> <span class="s">'..'</span><span class="p">])</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">file</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">IOError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
<span class="n">handle_not_found</span><span class="p">()</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(python)>from os import path
page_id = req.args.get('page_id', 'index')
filename = path.join(path.dirname(__file__), 'includes',
*[x for x in page_id.split('/') if x != '..'])
try:
f = file(filename)
except (IOError, TypeError):
handle_not_found()<PYGMENTS_RAW -->If you see this code: what's wrong?
First of all, the page_id comes from an user submitted variable in a web application. It's in fact a variable from the query string. Now someone could say <tt>?page_id=../../../etc/htpasswd</tt> etc. There are numerous ways to fix that. For example you can do this:
This also makes sure that the path separator is valid. I guess everybody that knows about security also knows how to defend those problems.
What you might not know is that python itself doesn't accept null bytes in the "file/open" call. This is some sort of built in security feature. Other languages such as PHP forward the nullbyte to the C layer. Thus an attacker could cut off a string at a given position to gain further control over the input layer (cutting of a .php extension etc). This is more severe in Perl where you can also pipe stuff in the file call.
This security feature however doesn't raise an IOError but a TypeError! So the corrected example from above looks like this:
SQAAAANTAAAABGJvZHlSUwAAAMBJZiB5b3Ugc2VlIHRoaXMgY29kZTogd2hhdCdzIHdyb25nPwoK
Rmlyc3Qgb2YgYWxsLCB0aGUgcGFnZV9pZCBjb21lcyBmcm9tIGFuIHVzZXIgc3VibWl0dGVkIHZh
cmlhYmxlIGluIGEgd2ViIGFwcGxpY2F0aW9uLiBJdCdzIGluIGZhY3QgYSB2YXJpYWJsZSBmcm9t
IHRoZSBxdWVyeSBzdHJpbmcuIE5vdyBzb21lb25lIGNvdWxkIHNheSBMAAFFUwAAAAJ0dEwAAE0A
AFMAAAAeP3BhZ2VfaWQ9Li4vLi4vLi4vZXRjL2h0cGFzc3dkUwAAAv4gZXRjLiBUaGVyZSBhcmUg
bnVtZXJvdXMgd2F5cyB0byBmaXggdGhhdC4gRm9yIGV4YW1wbGUgeW91IGNhbiBkbyB0aGlzOgoK
VGhpcyBhbHNvIG1ha2VzIHN1cmUgdGhhdCB0aGUgcGF0aCBzZXBhcmF0b3IgaXMgdmFsaWQuIEkg
Z3Vlc3MgZXZlcnlib2R5IHRoYXQga25vd3MgYWJvdXQgc2VjdXJpdHkgYWxzbyBrbm93cyBob3cg
dG8gZGVmZW5kIHRob3NlIHByb2JsZW1zLgoKV2hhdCB5b3UgbWlnaHQgbm90IGtub3cgaXMgdGhh
dCBweXRob24gaXRzZWxmIGRvZXNuJ3QgYWNjZXB0IG51bGwgYnl0ZXMgaW4gdGhlICJmaWxlL29w
ZW4iIGNhbGwuIFRoaXMgaXMgc29tZSBzb3J0IG9mIGJ1aWx0IGluIHNlY3VyaXR5IGZlYXR1cmUu
IE90aGVyIGxhbmd1YWdlcyBzdWNoIGFzIFBIUCBmb3J3YXJkIHRoZSBudWxsYnl0ZSB0byB0aGUg
QyBsYXllci4gVGh1cyBhbiBhdHRhY2tlciBjb3VsZCBjdXQgb2ZmIGEgc3RyaW5nIGF0IGEgZ2l2
ZW4gcG9zaXRpb24gdG8gZ2FpbiBmdXJ0aGVyIGNvbnRyb2wgb3ZlciB0aGUgaW5wdXQgbGF5ZXIg
KGN1dHRpbmcgb2YgYSAucGhwIGV4dGVuc2lvbiBldGMpLiBUaGlzIGlzIG1vcmUgc2V2ZXJlIGlu
IFBlcmwgd2hlcmUgeW91IGNhbiBhbHNvIHBpcGUgc3R1ZmYgaW4gdGhlIGZpbGUgY2FsbC4KClRo
aXMgc2VjdXJpdHkgZmVhdHVyZSBob3dldmVyIGRvZXNuJ3QgcmFpc2UgYW4gSU9FcnJvciBidXQg
YSBUeXBlRXJyb3IhIFNvIHRoZSBjb3JyZWN0ZWQgZXhhbXBsZSBmcm9tIGFib3ZlIGxvb2tzIGxp
a2UgdGhpczoKUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Megadeth — À Tout Le Mondehttp://lucumr.pocoo.org/cogitations/2007/06/01/megadeth-a-tout-le-monde/2007-06-01T10:18:20Z2007-06-01T10:18:20ZArmin Ronachermegadeth-a-tout-le-mondeyesyes2<a href="http://www.youtube.com/watch?v=gEHNvxkVvqc">beautiful acoustic version</a> of "À Tout Le Monde" by Megadeth -- live and unplugged. Awesome.<a href="http://www.youtube.com/watch?v=gEHNvxkVvqc">beautiful acoustic version</a> of "À Tout Le Monde" by Megadeth -- live and unplugged. Awesome.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACpodHRwOi8v
d3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9Z0VITnZ4a1Z2cWNTAAAAGmJlYXV0aWZ1bCBhY291c3Rp
YyB2ZXJzaW9uUwAAAEIgb2YgIsOAIFRvdXQgTGUgTW9uZGUiIGJ5IE1lZ2FkZXRoIC0tIGxpdmUg
YW5kIHVucGx1Z2dlZC4gQXdlc29tZS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAA
AABMAAA=
PyCentral broken?http://lucumr.pocoo.org/cogitations/2007/05/31/pycentral-broken/2007-05-31T08:17:19Z2007-05-31T08:17:19ZArmin Ronacherpycentral-brokenyesyes2<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="go">INFO: using old version '/usr/bin/python2.4'</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"/usr/bin/pycentral"</span>, line <span class="m">1348</span>, in <span class="n-Identifier"><module></span>
<span class="n">main</span><span class="p">()</span>
File <span class="nb">"/usr/bin/pycentral"</span>, line <span class="m">1342</span>, in <span class="n-Identifier">main</span>
<span class="n">rv</span> <span class="o">=</span> <span class="n">action</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">global_options</span><span class="p">)</span>
File <span class="nb">"/usr/bin/pycentral"</span>, line <span class="m">1077</span>, in <span class="n-Identifier">run</span>
<span class="n">pkg</span><span class="o">.</span><span class="n">update_bytecode_files</span><span class="p">(</span><span class="n">runtimes</span><span class="p">,</span> <span class="n">default_rt</span><span class="p">,</span> <span class="n">bc_option</span><span class="p">)</span>
File <span class="nb">"/usr/bin/pycentral"</span>, line <span class="m">714</span>, in <span class="n-Identifier">update_bytecode_files</span>
<span class="bp">self</span><span class="o">.</span><span class="n">default_runtime</span><span class="o">.</span><span class="n">byte_compile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">private_files</span><span class="p">,</span>
<span class="nc">AttributeError</span>: <span class="n-Identifier">'NoneType' object has no attribute 'byte_compile'</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(pycon)>INFO: using old version '/usr/bin/python2.4'
Traceback (most recent call last):
File "/usr/bin/pycentral", line 1348, in <module>
main()
File "/usr/bin/pycentral", line 1342, in main
rv = action.run(global_options)
File "/usr/bin/pycentral", line 1077, in run
pkg.update_bytecode_files(runtimes, default_rt, bc_option)
File "/usr/bin/pycentral", line 714, in update_bytecode_files
self.default_runtime.byte_compile(self.private_files,
AttributeError: 'NoneType' object has no attribute 'byte_compile'<PYGMENTS_RAW -->
This will fix it:
<pre>root@volverine:/usr/bin# rm python && ln -sf python2.5 /usr/bin/python</pre>
pycentral doesn't like absolute links.
This will fix it:
<pre>root@volverine:/usr/bin# rm python && ln -sf python2.5 /usr/bin/python</pre>
pycentral doesn't like absolute links.SQAAAANTAAAABGJvZHlSUwAAABMKVGhpcyB3aWxsIGZpeCBpdDoKTAABRVMAAAADcHJlTAAATQAA
UwAAAEZyb290QHZvbHZlcmluZTovdXNyL2JpbiMgcm0gcHl0aG9uICYmIGxuIC1zZiBweXRob24y
LjUgL3Vzci9iaW4vcHl0aG9uUwAAACcKcHljZW50cmFsIGRvZXNuJ3QgbGlrZSBhYnNvbHV0ZSBs
aW5rcy5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
JavaScript 1.8http://lucumr.pocoo.org/cogitations/2007/05/31/javascript-18/2007-05-31T07:27:28Z2007-05-31T07:27:28ZArmin Ronacherjavascript-18yesyes2Wohoo. <a href="http://ejohn.org/blog/javascript-18-progress/">John Resig about JavaScript 1.8</a>. Some of the new things are <a href="http://lucumr.pocoo.org/articles/evolve-javascript-dont-reinvent-it">on my wishlist</a> for quite a long time :-)Wohoo. <a href="http://ejohn.org/blog/javascript-18-progress/">John Resig about JavaScript 1.8</a>. Some of the new things are <a href="http://lucumr.pocoo.org/articles/evolve-javascript-dont-reinvent-it">on my wishlist</a> for quite a long time :-)SQAAAANTAAAABGJvZHlSUwAAAAdXb2hvby4gTAACRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAt
aHR0cDovL2Vqb2huLm9yZy9ibG9nL2phdmFzY3JpcHQtMTgtcHJvZ3Jlc3MvUwAAAB9Kb2huIFJl
c2lnIGFib3V0IEphdmFTY3JpcHQgMS44UwAAAB0uIFNvbWUgb2YgdGhlIG5ldyB0aGluZ3MgYXJl
IEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAQ2h0dHA6Ly9sdWN1bXIucG9jb28ub3JnL2FydGlj
bGVzL2V2b2x2ZS1qYXZhc2NyaXB0LWRvbnQtcmVpbnZlbnQtaXRTAAAADm9uIG15IHdpc2hsaXN0
UwAAABogZm9yIHF1aXRlIGEgbG9uZyB0aW1lIDotKVMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVp
bnRyb1JTAAAAAEwAAA==
New Stuff in Perl 6http://lucumr.pocoo.org/cogitations/2007/05/30/new-stuff-in-perl-6/2007-05-30T19:26:22Z2007-05-30T19:26:22ZArmin Ronachernew-stuff-in-perl-6yesyes2Here some nice blog posts by Austin Seipp about new things in Perl 6: <a href="http://diveintoperl6.blogspot.com/2007/05/perl-6-round-1_22.html">#1</a> and <a href="http://diveintoperl6.blogspot.com/2007/05/perl-6-round-2.html">#2</a>.Here some nice blog posts by Austin Seipp about new things in Perl 6: <a href="http://diveintoperl6.blogspot.com/2007/05/perl-6-round-1_22.html">#1</a> and <a href="http://diveintoperl6.blogspot.com/2007/05/perl-6-round-2.html">#2</a>.SQAAAANTAAAABGJvZHlSUwAAAEZIZXJlIHNvbWUgbmljZSBibG9nIHBvc3RzIGJ5IEF1c3RpbiBT
ZWlwcCBhYm91dCBuZXcgdGhpbmdzIGluIFBlcmwgNjogTAACRVMAAAABYUwAAE0AAVMAAAAEaHJl
ZlMAAABAaHR0cDovL2RpdmVpbnRvcGVybDYuYmxvZ3Nwb3QuY29tLzIwMDcvMDUvcGVybC02LXJv
dW5kLTFfMjIuaHRtbFMAAAACIzFTAAAABSBhbmQgRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAA9
aHR0cDovL2RpdmVpbnRvcGVybDYuYmxvZ3Nwb3QuY29tLzIwMDcvMDUvcGVybC02LXJvdW5kLTIu
aHRtbFMAAAACIzJTAAAAAS5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Polymorphic Associations with SQLAlchemyhttp://lucumr.pocoo.org/cogitations/2007/05/30/polymorphic-associations-with-sqlalchemy/2007-05-30T16:08:02Z2007-05-30T16:08:02ZArmin Ronacherpolymorphic-associations-with-sqlalchemyyesyes2<a href="http://techspot.zzzeek.org/?p=13">zzeeek</a> explains how to create rails like polymorphic associations with SQLAlchemy. Well done!<a href="http://techspot.zzzeek.org/?p=13">zzeeek</a> explains how to create rails like polymorphic associations with SQLAlchemy. Well done!SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACBodHRwOi8v
dGVjaHNwb3Quenp6ZWVrLm9yZy8/cD0xM1MAAAAGenplZWVrUwAAAFcgZXhwbGFpbnMgaG93IHRv
IGNyZWF0ZSByYWlscyBsaWtlIHBvbHltb3JwaGljIGFzc29jaWF0aW9ucyB3aXRoIFNRTEFsY2hl
bXkuIFdlbGwgZG9uZSFTAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
G8 Gipfel in Genuahttp://lucumr.pocoo.org/cogitations/2007/05/30/g8-gipfel-in-genua/2007-05-30T15:24:45Z2007-05-30T15:24:45ZArmin Ronacherg8-gipfel-in-genuayesyes2<a href="http://video.google.de/videoplay?docid=-8876259762606192748">G8 Gipfel in Genua 2001</a> -- ohne Worte.<a href="http://video.google.de/videoplay?docid=-8876259762606192748">G8 Gipfel in Genua 2001</a> -- ohne Worte.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAADtodHRwOi8v
dmlkZW8uZ29vZ2xlLmRlL3ZpZGVvcGxheT9kb2NpZD0tODg3NjI1OTc2MjYwNjE5Mjc0OFMAAAAX
RzggR2lwZmVsIGluIEdlbnVhIDIwMDFTAAAADyAtLSBvaG5lIFdvcnRlLlMAAAAGcGFyc2VyUwAA
AARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Pygments 0.8 Maikäfer Releasedhttp://lucumr.pocoo.org/cogitations/2007/05/30/pygments-08-maikafer-released/2007-05-30T15:00:16Z2007-05-30T15:00:16ZArmin Ronacherpygments-08-maikafer-releasedyesyes2The new version of <a href="http://pygments.org/">Pygments</a> 0.8 aka Maikäfter is out now. Changes in this release:
<ul>
<li>Lexers added:<ul>
<li>Haskell, thanks to Adam Blinkinsop</li>
<li>Redcode, thanks to Adam Blinkinsop</li>
<li>D, thanks to Kirk McDonald</li>
<li>MuPad, thanks to Christopher Creutzig</li>
<li>MiniD, thanks to Jarrett Billingsley</li>
<li>Vim Script, by Tim Hatch</li>
</ul></li>
<li>The HTML formatter now has a second line-numbers mode in which it will just integrate the numbers in the same <tt><pre></tt> tag as the code.</li>
<li>The <tt>CSharpLexer</tt> now is Unicode-aware, which means that it has an option that can be set so that it correctly lexes Unicode identifiers allowed by the C# specs.</li>
<li>Added a <tt>RaiseOnErrorTokenFilter</tt> that raises an exception when the lexer generates an error token, and a <tt>VisibleWhitespaceFilter</tt> that converts whitespace (spaces, tabs, newlines) into visible characters.</li>
<li>Fixed the <tt>do_insertions()</tt> helper function to yield correct indices.</li>
<li>The ReST lexer now automatically highlights source code blocks in <tt>.. sourcecode:: language</tt> and <tt>.. code:: language</tt> directive blocks.</li>
<li>Improved the default style (thanks to Tiberius Teng). The old default is still available as the "emacs" style (which was an alias before).</li>
<li>The <tt>get_style_defs</tt> method of HTML formatters now uses the <tt>cssclass</tt> option as the default selector if it was given.</li>
<li>Improved the ReST and Bash lexers a bit.</li>
<li>and again improved highlighting and fixed some bugs</li>
</ul>
Get it while it's hot from <a href="http://cheeseshop.python.org/pypi/Pygments/0.8">the cheeseshop</a>.The new version of <a href="http://pygments.org/">Pygments</a> 0.8 aka Maikäfter is out now. Changes in this release:
<ul>
<li>Lexers added:<ul>
<li>Haskell, thanks to Adam Blinkinsop</li>
<li>Redcode, thanks to Adam Blinkinsop</li>
<li>D, thanks to Kirk McDonald</li>
<li>MuPad, thanks to Christopher Creutzig</li>
<li>MiniD, thanks to Jarrett Billingsley</li>
<li>Vim Script, by Tim Hatch</li>
</ul></li>
<li>The HTML formatter now has a second line-numbers mode in which it will just integrate the numbers in the same <tt><pre></tt> tag as the code.</li>
<li>The <tt>CSharpLexer</tt> now is Unicode-aware, which means that it has an option that can be set so that it correctly lexes Unicode identifiers allowed by the C# specs.</li>
<li>Added a <tt>RaiseOnErrorTokenFilter</tt> that raises an exception when the lexer generates an error token, and a <tt>VisibleWhitespaceFilter</tt> that converts whitespace (spaces, tabs, newlines) into visible characters.</li>
<li>Fixed the <tt>do_insertions()</tt> helper function to yield correct indices.</li>
<li>The ReST lexer now automatically highlights source code blocks in <tt>.. sourcecode:: language</tt> and <tt>.. code:: language</tt> directive blocks.</li>
<li>Improved the default style (thanks to Tiberius Teng). The old default is still available as the "emacs" style (which was an alias before).</li>
<li>The <tt>get_style_defs</tt> method of HTML formatters now uses the <tt>cssclass</tt> option as the default selector if it was given.</li>
<li>Improved the ReST and Bash lexers a bit.</li>
<li>and again improved highlighting and fixed some bugs</li>
</ul>
Get it while it's hot from <a href="http://cheeseshop.python.org/pypi/Pygments/0.8">the cheeseshop</a>.SQAAAANTAAAABGJvZHlSUwAAABNUaGUgbmV3IHZlcnNpb24gb2YgTAADRVMAAAABYUwAAE0AAVMA
AAAEaHJlZlMAAAAUaHR0cDovL3B5Z21lbnRzLm9yZy9TAAAACFB5Z21lbnRzUwAAADogMC44IGFr
YSBNYWlrw6RmdGVyIGlzIG91dCBub3cuIENoYW5nZXMgaW4gdGhpcyByZWxlYXNlOgoKRVMAAAAC
dWxMAApFUwAAAAJsaUwAAUVTAAAAAnVsTAAGRVMAAAACbGlMAABNAABTAAAAIkhhc2tlbGwsIHRo
YW5rcyB0byBBZGFtIEJsaW5raW5zb3BTAAAABQogICAgRVMAAAACbGlMAABNAABTAAAAIlJlZGNv
ZGUsIHRoYW5rcyB0byBBZGFtIEJsaW5raW5zb3BTAAAABQogICAgRVMAAAACbGlMAABNAABTAAAA
GkQsIHRoYW5rcyB0byBLaXJrIE1jRG9uYWxkUwAAAAUKICAgIEVTAAAAAmxpTAAATQAAUwAAACVN
dVBhZCwgdGhhbmtzIHRvIENocmlzdG9waGVyIENyZXV0emlnUwAAAAUKICAgIEVTAAAAAmxpTAAA
TQAAUwAAACRNaW5pRCwgdGhhbmtzIHRvIEphcnJldHQgQmlsbGluZ3NsZXlTAAAABQogICAgRVMA
AAACbGlMAABNAABTAAAAGFZpbSBTY3JpcHQsIGJ5IFRpbSBIYXRjaFMAAAADCiAgTQAAUwAAAAUK
ICAgIFMAAAAATQAAUwAAAA1MZXhlcnMgYWRkZWQ6UwAAAAMKICBFUwAAAAJsaUwAAUVTAAAAAnR0
TAAATQAAUwAAAAU8cHJlPlMAAAARIHRhZyBhcyB0aGUgY29kZS5NAABTAAAAblRoZSBIVE1MIGZv
cm1hdHRlciBub3cgaGFzIGEgc2Vjb25kIGxpbmUtbnVtYmVycyBtb2RlIGluIHdoaWNoIGl0IHdp
bGwganVzdCBpbnRlZ3JhdGUgdGhlIG51bWJlcnMgaW4gdGhlIHNhbWUgUwAAAAMKICBFUwAAAAJs
aUwAAUVTAAAAAnR0TAAATQAAUwAAAAtDU2hhcnBMZXhlclMAAACQIG5vdyBpcyBVbmljb2RlLWF3
YXJlLCB3aGljaCBtZWFucyB0aGF0IGl0IGhhcyBhbiBvcHRpb24gdGhhdCBjYW4gYmUgc2V0IHNv
IHRoYXQgaXQgY29ycmVjdGx5IGxleGVzIFVuaWNvZGUgaWRlbnRpZmllcnMgYWxsb3dlZCBieSB0
aGUgQyMgc3BlY3MuTQAAUwAAAARUaGUgUwAAAAMKICBFUwAAAAJsaUwAAkVTAAAAAnR0TAAATQAA
UwAAABdSYWlzZU9uRXJyb3JUb2tlbkZpbHRlclMAAABJIHRoYXQgcmFpc2VzIGFuIGV4Y2VwdGlv
biB3aGVuIHRoZSBsZXhlciBnZW5lcmF0ZXMgYW4gZXJyb3IgdG9rZW4sIGFuZCBhIEVTAAAAAnR0
TAAATQAAUwAAABdWaXNpYmxlV2hpdGVzcGFjZUZpbHRlclMAAABLIHRoYXQgY29udmVydHMgd2hp
dGVzcGFjZSAoc3BhY2VzLCB0YWJzLCBuZXdsaW5lcykgaW50byB2aXNpYmxlIGNoYXJhY3RlcnMu
TQAAUwAAAAhBZGRlZCBhIFMAAAADCiAgRVMAAAACbGlMAAFFUwAAAAJ0dEwAAE0AAFMAAAAPZG9f
aW5zZXJ0aW9ucygpUwAAACogaGVscGVyIGZ1bmN0aW9uIHRvIHlpZWxkIGNvcnJlY3QgaW5kaWNl
cy5NAABTAAAACkZpeGVkIHRoZSBTAAAAAwogIEVTAAAAAmxpTAACRVMAAAACdHRMAABNAABTAAAA
GC4uIHNvdXJjZWNvZGU6OiBsYW5ndWFnZVMAAAAFIGFuZCBFUwAAAAJ0dEwAAE0AAFMAAAASLi4g
Y29kZTo6IGxhbmd1YWdlUwAAABIgZGlyZWN0aXZlIGJsb2Nrcy5NAABTAAAAQlRoZSBSZVNUIGxl
eGVyIG5vdyBhdXRvbWF0aWNhbGx5IGhpZ2hsaWdodHMgc291cmNlIGNvZGUgYmxvY2tzIGluIFMA
AAADCiAgRVMAAAACbGlMAABNAABTAAAAikltcHJvdmVkIHRoZSBkZWZhdWx0IHN0eWxlICh0aGFu
a3MgdG8gVGliZXJpdXMgVGVuZykuIFRoZSBvbGQgZGVmYXVsdCBpcyBzdGlsbCBhdmFpbGFibGUg
YXMgdGhlICJlbWFjcyIgc3R5bGUgKHdoaWNoIHdhcyBhbiBhbGlhcyBiZWZvcmUpLlMAAAADCiAg
RVMAAAACbGlMAAJFUwAAAAJ0dEwAAE0AAFMAAAAOZ2V0X3N0eWxlX2RlZnNTAAAAKCBtZXRob2Qg
b2YgSFRNTCBmb3JtYXR0ZXJzIG5vdyB1c2VzIHRoZSBFUwAAAAJ0dEwAAE0AAFMAAAAIY3NzY2xh
c3NTAAAAMCBvcHRpb24gYXMgdGhlIGRlZmF1bHQgc2VsZWN0b3IgaWYgaXQgd2FzIGdpdmVuLk0A
AFMAAAAEVGhlIFMAAAADCiAgRVMAAAACbGlMAABNAABTAAAAKEltcHJvdmVkIHRoZSBSZVNUIGFu
ZCBCYXNoIGxleGVycyBhIGJpdC5TAAAAAwogIEVTAAAAAmxpTAAATQAAUwAAADNhbmQgYWdhaW4g
aW1wcm92ZWQgaGlnaGxpZ2h0aW5nIGFuZCBmaXhlZCBzb21lIGJ1Z3NTAAAAAQpNAABTAAAAAwog
IFMAAAAdCgpHZXQgaXQgd2hpbGUgaXQncyBob3QgZnJvbSBFUwAAAAFhTAAATQABUwAAAARocmVm
UwAAAC5odHRwOi8vY2hlZXNlc2hvcC5weXRob24ub3JnL3B5cGkvUHlnbWVudHMvMC44UwAAAA50
aGUgY2hlZXNlc2hvcFMAAAABLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwA
AA==
Pygments in Wordpresshttp://lucumr.pocoo.org/cogitations/2007/05/30/pygments-in-wordpress/2007-05-30T13:34:58Z2007-05-30T13:34:58ZArmin Ronacherpygments-in-wordpressyesyes2I wanted to have pygments support in wordpress and so I hacked up a small wordpress plugin that enables pygments support in wordpress. Because I was lazy and PHP sucks like hell I just supported the case of a php.ini with magic slashes disabled. Somehow wordpress reinserts some of those annoying things automatically in some places though.
If you want to try it out: <a href="/trac/repos/pygments.php">pygments.php</a>. Note that I do not support it, it's released under the BSD license like Pygments itself, it requires an installed pygments with the pygmentize script, no idea which PHP version, disabled magic quotes I guess and that you generate a pygments.css file yourself that matches the style defined in the plugin.
It caches in the text, and has few overhead on rendering Basically all you have to do is typing <tt><pre lang="LANGUAGE">code</pre></tt> instead of using a normal pre tag. Escaping happens automatically.
Example:
<!-- PYGMENTS_CACHE><div class="highlight"><pre><span class="c1"># Server: ruby p2p.rb password server server-uri merge-servers</span>
<span class="c1"># Sample: ruby p2p.rb foobar server druby://localhost:1337 druby://foo.bar:1337</span>
<span class="c1"># Client: ruby p2p.rb password client server-uri download-pattern</span>
<span class="c1"># Sample: ruby p2p.rb foobar client druby://localhost:1337 *.rb</span>
<span class="nb">require</span><span class="s1">'drb'</span><span class="p">;</span><span class="n">F</span><span class="p">,</span><span class="n">D</span><span class="p">,</span><span class="n">C</span><span class="p">,</span><span class="n">P</span><span class="p">,</span><span class="n">M</span><span class="p">,</span><span class="n">U</span><span class="p">,</span><span class="o">*</span><span class="n">O</span><span class="o">=</span><span class="no">File</span><span class="p">,</span><span class="no">Class</span><span class="p">,</span><span class="no">Dir</span><span class="p">,</span><span class="o">*</span><span class="no">ARGV</span><span class="p">;</span><span class="k">def</span> <span class="nf">s</span><span class="p">(</span><span class="nb">p</span><span class="p">)</span><span class="n">F</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="nb">p</span><span class="o">[/[^|].</span><span class="n">*</span><span class="o">/]</span><span class="p">)</span><span class="o">[-</span><span class="mi">1</span>
<span class="o">]</span><span class="k">end</span><span class="p">;</span><span class="k">def</span> <span class="nf">c</span><span class="p">(</span><span class="n">u</span><span class="p">);</span><span class="no">DRbObject</span><span class="o">.</span><span class="n">new</span><span class="p">((),</span><span class="n">u</span><span class="p">)</span><span class="k">end</span><span class="p">;</span><span class="k">def</span> <span class="nf">x</span><span class="p">(</span><span class="n">u</span><span class="p">)</span><span class="o">[</span><span class="n">P</span><span class="p">,</span><span class="n">u</span><span class="o">].</span><span class="n">hash</span><span class="p">;</span><span class="k">end</span><span class="p">;</span><span class="n">M</span><span class="o">==</span><span class="s2">"client"</span><span class="o">&&</span><span class="n">c</span><span class="p">(</span><span class="n">U</span><span class="p">)</span><span class="o">.</span><span class="n">f</span><span class="p">(</span>
<span class="n">x</span><span class="p">(</span><span class="n">U</span><span class="p">))</span><span class="o">.</span><span class="n">each</span><span class="p">{</span><span class="o">|</span><span class="n">n</span><span class="o">|</span><span class="nb">p</span><span class="p">,</span><span class="n">c</span><span class="o">=</span><span class="n">x</span><span class="p">(</span><span class="n">n</span><span class="p">),</span><span class="n">c</span><span class="p">(</span><span class="n">n</span><span class="p">);(</span><span class="n">c</span><span class="o">.</span><span class="n">f</span><span class="p">(</span><span class="nb">p</span><span class="p">,</span><span class="n">O</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">map</span><span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span><span class="n">s</span> <span class="n">f</span><span class="p">}</span><span class="o">-</span><span class="n">D</span><span class="o">[</span><span class="s2">"*"</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">each</span><span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span><span class="n">F</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">f</span><span class="p">,</span>
<span class="s2">"w"</span><span class="p">){</span><span class="o">|</span><span class="n">o</span><span class="o">|</span><span class="n">o</span><span class="o"><<</span><span class="n">c</span><span class="o">.</span><span class="n">f</span><span class="p">(</span><span class="nb">p</span><span class="p">,</span><span class="n">f</span><span class="p">,</span><span class="mi">1</span><span class="p">)}}}</span><span class="o">||</span><span class="p">(</span><span class="no">DRb</span><span class="o">.</span><span class="n">start_service</span> <span class="n">U</span><span class="p">,</span><span class="n">C</span><span class="o">.</span><span class="n">new</span><span class="p">{</span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">c</span><span class="p">,</span><span class="n">a</span><span class="o">=[]</span><span class="p">,</span><span class="n">t</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span><span class="n">c</span><span class="o">==</span><span class="n">x</span><span class="p">(</span><span class="n">U</span><span class="p">)</span><span class="o">&&</span><span class="p">(</span>
<span class="n">t</span><span class="o">==</span><span class="mi">0</span><span class="o">&&</span><span class="n">D</span><span class="o">[</span><span class="n">s</span><span class="p">(</span><span class="n">a</span><span class="p">)</span><span class="o">]||</span><span class="n">t</span><span class="o">==</span><span class="mi">1</span><span class="o">&&</span><span class="n">F</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">s</span><span class="p">(</span><span class="n">a</span><span class="p">))</span><span class="o">||</span><span class="nb">p</span><span class="p">(</span><span class="n">a</span><span class="p">))</span><span class="k">end</span><span class="p">;</span><span class="k">def</span> <span class="nf">y</span><span class="p">()(</span><span class="nb">p</span><span class="p">(</span><span class="n">U</span><span class="p">)</span><span class="o">+</span><span class="nb">p</span><span class="p">)</span><span class="o">.</span><span class="n">each</span><span class="p">{</span><span class="o">|</span><span class="n">u</span><span class="o">|</span><span class="n">c</span><span class="p">(</span><span class="n">u</span><span class="p">)</span><span class="o">.</span><span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">(</span><span class="n">u</span><span class="p">),</span>
<span class="nb">p</span><span class="p">(</span><span class="n">U</span><span class="p">))</span><span class="k">rescue</span><span class="p">()};</span><span class="nb">self</span><span class="p">;</span><span class="k">end</span><span class="p">;</span><span class="kp">private</span><span class="p">;</span><span class="k">def</span> <span class="nf">p</span><span class="p">(</span><span class="n">x</span><span class="o">=[]</span><span class="p">);</span><span class="n">O</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="o">*</span><span class="n">x</span><span class="p">)</span><span class="o">.</span><span class="n">uniq!</span><span class="p">;</span><span class="n">O</span><span class="p">;</span><span class="k">end</span><span class="p">}</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">y</span><span class="p">;</span><span class="nb">sleep</span><span class="p">)</span>
</pre></div>
<PYGMENTS_CACHE --><!-- PYGMENTS_RAW(ruby)># Server: ruby p2p.rb password server server-uri merge-servers
# Sample: ruby p2p.rb foobar server druby://localhost:1337 druby://foo.bar:1337
# Client: ruby p2p.rb password client server-uri download-pattern
# Sample: ruby p2p.rb foobar client druby://localhost:1337 *.rb
require'drb';F,D,C,P,M,U,*O=File,Class,Dir,*ARGV;def s(p)F.split(p[/[^|].*/])[-1
]end;def c(u);DRbObject.new((),u)end;def x(u)[P,u].hash;end;M=="client"&&c(U).f(
x(U)).each{|n|p,c=x(n),c(n);(c.f(p,O[0],0).map{|f|s f}-D["*"]).each{|f|F.open(f,
"w"){|o|o<<c.f(p,f,1)}}}||(DRb.start_service U,C.new{def f(c,a=[],t=2)c==x(U)&&(
t==0&&D[s(a)]||t==1&&F.read(s(a))||p(a))end;def y()(p(U)+p).each{|u|c(u).f(x(u),
p(U))rescue()};self;end;private;def p(x=[]);O.push(*x).uniq!;O;end}.new.y;sleep)<PYGMENTS_RAW -->I wanted to have pygments support in wordpress and so I hacked up a small wordpress plugin that enables pygments support in wordpress. Because I was lazy and PHP sucks like hell I just supported the case of a php.ini with magic slashes disabled. Somehow wordpress reinserts some of those annoying things automatically in some places though.
If you want to try it out: <a href="/trac/repos/pygments.php">pygments.php</a>. Note that I do not support it, it's released under the BSD license like Pygments itself, it requires an installed pygments with the pygmentize script, no idea which PHP version, disabled magic quotes I guess and that you generate a pygments.css file yourself that matches the style defined in the plugin.
It caches in the text, and has few overhead on rendering Basically all you have to do is typing <tt><pre lang="LANGUAGE">code</pre></tt> instead of using a normal pre tag. Escaping happens automatically.
Example:
SQAAAANTAAAABGJvZHlSUwAAAXFJIHdhbnRlZCB0byBoYXZlIHB5Z21lbnRzIHN1cHBvcnQgaW4g
d29yZHByZXNzIGFuZCBzbyBJIGhhY2tlZCB1cCBhIHNtYWxsIHdvcmRwcmVzcyBwbHVnaW4gdGhh
dCBlbmFibGVzIHB5Z21lbnRzIHN1cHBvcnQgaW4gd29yZHByZXNzLiBCZWNhdXNlIEkgd2FzIGxh
enkgYW5kIFBIUCBzdWNrcyBsaWtlIGhlbGwgSSBqdXN0IHN1cHBvcnRlZCB0aGUgY2FzZSBvZiBh
IHBocC5pbmkgd2l0aCBtYWdpYyBzbGFzaGVzIGRpc2FibGVkLiBTb21laG93IHdvcmRwcmVzcyBy
ZWluc2VydHMgc29tZSBvZiB0aG9zZSBhbm5veWluZyB0aGluZ3MgYXV0b21hdGljYWxseSBpbiBz
b21lIHBsYWNlcyB0aG91Z2guCgpJZiB5b3Ugd2FudCB0byB0cnkgaXQgb3V0OiBMAAJFUwAAAAFh
TAAATQABUwAAAARocmVmUwAAABgvdHJhYy9yZXBvcy9weWdtZW50cy5waHBTAAAADHB5Z21lbnRz
LnBocFMAAAGULiBOb3RlIHRoYXQgSSBkbyBub3Qgc3VwcG9ydCBpdCwgaXQncyByZWxlYXNlZCB1
bmRlciB0aGUgQlNEIGxpY2Vuc2UgbGlrZSBQeWdtZW50cyBpdHNlbGYsIGl0IHJlcXVpcmVzIGFu
IGluc3RhbGxlZCBweWdtZW50cyB3aXRoIHRoZSBweWdtZW50aXplIHNjcmlwdCwgbm8gaWRlYSB3
aGljaCBQSFAgdmVyc2lvbiwgZGlzYWJsZWQgbWFnaWMgcXVvdGVzIEkgZ3Vlc3MgYW5kIHRoYXQg
eW91IGdlbmVyYXRlIGEgcHlnbWVudHMuY3NzIGZpbGUgeW91cnNlbGYgdGhhdCBtYXRjaGVzIHRo
ZSBzdHlsZSBkZWZpbmVkIGluIHRoZSBwbHVnaW4uCgpJdCBjYWNoZXMgaW4gdGhlIHRleHQsIGFu
ZCBoYXMgZmV3IG92ZXJoZWFkIG9uIHJlbmRlcmluZyBCYXNpY2FsbHkgYWxsIHlvdSBoYXZlIHRv
IGRvIGlzIHR5cGluZyBFUwAAAAJ0dEwAAE0AAFMAAAAfPHByZSBsYW5nPSJMQU5HVUFHRSI+Y29k
ZTwvcHJlPlMAAABOIGluc3RlYWQgb2YgdXNpbmcgYSBub3JtYWwgcHJlIHRhZy4gRXNjYXBpbmcg
aGFwcGVucyBhdXRvbWF0aWNhbGx5LgoKRXhhbXBsZToKUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAA
BWludHJvUlMAAAAATAAA
Lior Gradsteinlior@gradstein.infohttp://www.gradstein.info/2007-07-03T07:45:55Znono0Just a note: pygments.php uses the function stream_get_contents() which requires at least PHP 5.Just a note: pygments.php uses the function stream_get_contents() which requires at least PHP 5.SQAAAAJTAAAABGJvZHlSUwAAAGBKdXN0IGEgbm90ZTogcHlnbWVudHMucGhwIHVzZXMgdGhlIGZ1
bmN0aW9uIHN0cmVhbV9nZXRfY29udGVudHMoKSB3aGljaCByZXF1aXJlcyBhdCBsZWFzdCBQSFAg
NS5MAABTAAAABnBhcnNlclMAAAAEaHRtbA==
from learning import * » Blog Archive » Wordpress, Pygments syntax highlighting, Autohotkeyhttp://learningdjango.soulguidedtelescope.com/?p=132008-01-24T22:25:20Znoyes0[...] website of Armin Ronacher (incidentally, a contributor to Pygments). More relevantly, I found the plugin he created to enable Pygments support for Wordpress. Problem is, it doesn't work for [...][...] website of Armin Ronacher (incidentally, a contributor to Pygments). More relevantly, I found the plugin he created to enable Pygments support for Wordpress. Problem is, it doesn't work for [...]SQAAAAJTAAAABGJvZHlSUwAAAMlbLi4uXSB3ZWJzaXRlIG9mIEFybWluIFJvbmFjaGVyIChpbmNp
ZGVudGFsbHksIGEgY29udHJpYnV0b3IgdG8gUHlnbWVudHMpLiBNb3JlIHJlbGV2YW50bHksIEkg
Zm91bmQgdGhlIHBsdWdpbiBoZSBjcmVhdGVkIHRvIGVuYWJsZSBQeWdtZW50cyBzdXBwb3J0IGZv
ciBXb3JkcHJlc3MuIFByb2JsZW0gaXMsIGl0IGRvZXNuJ3Qgd29yayBmb3IgWy4uLl1MAABTAAAA
BnBhcnNlclMAAAAEaHRtbA==
Wie funktioniert Geld?http://lucumr.pocoo.org/cogitations/2007/05/30/wie-funktioniert-geld/2007-05-30T09:10:36Z2007-05-30T09:10:36ZArmin Ronacherwie-funktioniert-geldyesyes2Nettes und amüsantes Video über das Geldsystem. <a href="http://youtube.com/watch?v=9BrLrwbkQWQ">#1</a>, <a href="http://youtube.com/watch?v=aK2yZlHk4cA">#2</a>, and <a href="http://youtube.com/watch?v=0VOtdQrCoyk">#3</a>.Nettes und amüsantes Video über das Geldsystem. <a href="http://youtube.com/watch?v=9BrLrwbkQWQ">#1</a>, <a href="http://youtube.com/watch?v=aK2yZlHk4cA">#2</a>, and <a href="http://youtube.com/watch?v=0VOtdQrCoyk">#3</a>.SQAAAANTAAAABGJvZHlSUwAAADJOZXR0ZXMgdW5kIGFtw7xzYW50ZXMgVmlkZW8gw7xiZXIgZGFz
IEdlbGRzeXN0ZW0uIEwAA0VTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAJmh0dHA6Ly95b3V0dWJl
LmNvbS93YXRjaD92PTlCckxyd2JrUVdRUwAAAAIjMVMAAAACLCBFUwAAAAFhTAAATQABUwAAAARo
cmVmUwAAACZodHRwOi8veW91dHViZS5jb20vd2F0Y2g/dj1hSzJ5WmxIazRjQVMAAAACIzJTAAAA
BiwgYW5kIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAJmh0dHA6Ly95b3V0dWJlLmNvbS93YXRj
aD92PTBWT3RkUXJDb3lrUwAAAAIjM1MAAAABLlMAAAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRy
b1JTAAAAAEwAAA==
Pygments GTK Renderinghttp://lucumr.pocoo.org/cogitations/2007/05/30/pygments-gtk-rendering/2007-05-30T06:27:43Z2007-05-30T06:27:43ZArmin Ronacherpygments-gtk-renderingyesyes2I found <a href="http://www.progbox.co.uk/wordpress/?p=300">in Pete Savage's blog</a> and entry about using GtkSourceView in pygtk. The new version of GtkSourceView absolutely rocks, the old one does not because the ruby highlighter and more complex stuff simply does not work because the library is somewhat limited.
As a proof of concept I tried to integrate <a href="http://pygments.org/">pygments</a> into a pygtk window and it worked :-) Of course it doesn't allow realtime updating thus it's impossible to use it as editor component (at least for now) but it makes a good source view.
You can find the sources here: <a href="http://lucumr.pocoo.org/trac/repos/gtkpygments.py">gtkpygments.py</a>I found <a href="http://www.progbox.co.uk/wordpress/?p=300">in Pete Savage's blog</a> and entry about using GtkSourceView in pygtk. The new version of GtkSourceView absolutely rocks, the old one does not because the ruby highlighter and more complex stuff simply does not work because the library is somewhat limited.
As a proof of concept I tried to integrate <a href="http://pygments.org/">pygments</a> into a pygtk window and it worked :-) Of course it doesn't allow realtime updating thus it's impossible to use it as editor component (at least for now) but it makes a good source view.
You can find the sources here: <a href="http://lucumr.pocoo.org/trac/repos/gtkpygments.py">gtkpygments.py</a>SQAAAANTAAAABGJvZHlSUwAAAAhJIGZvdW5kIEwAA0VTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAA
KWh0dHA6Ly93d3cucHJvZ2JveC5jby51ay93b3JkcHJlc3MvP3A9MzAwUwAAABVpbiBQZXRlIFNh
dmFnZSdzIGJsb2dTAAABFSBhbmQgZW50cnkgYWJvdXQgdXNpbmcgR3RrU291cmNlVmlldyBpbiBw
eWd0ay4gVGhlIG5ldyB2ZXJzaW9uIG9mIEd0a1NvdXJjZVZpZXcgYWJzb2x1dGVseSByb2Nrcywg
dGhlIG9sZCBvbmUgZG9lcyBub3QgYmVjYXVzZSB0aGUgcnVieSBoaWdobGlnaHRlciBhbmQgbW9y
ZSBjb21wbGV4IHN0dWZmIHNpbXBseSBkb2VzIG5vdCB3b3JrIGJlY2F1c2UgdGhlIGxpYnJhcnkg
aXMgc29tZXdoYXQgbGltaXRlZC4KCkFzIGEgcHJvb2Ygb2YgY29uY2VwdCBJIHRyaWVkIHRvIGlu
dGVncmF0ZSBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAABRodHRwOi8vcHlnbWVudHMub3JnL1MA
AAAIcHlnbWVudHNTAAAA2yBpbnRvIGEgcHlndGsgd2luZG93IGFuZCBpdCB3b3JrZWQgOi0pIE9m
IGNvdXJzZSBpdCBkb2Vzbid0IGFsbG93IHJlYWx0aW1lIHVwZGF0aW5nIHRodXMgaXQncyBpbXBv
c3NpYmxlIHRvIHVzZSBpdCBhcyBlZGl0b3IgY29tcG9uZW50IChhdCBsZWFzdCBmb3Igbm93KSBi
dXQgaXQgbWFrZXMgYSBnb29kIHNvdXJjZSB2aWV3LgoKWW91IGNhbiBmaW5kIHRoZSBzb3VyY2Vz
IGhlcmU6IEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAMWh0dHA6Ly9sdWN1bXIucG9jb28ub3Jn
L3RyYWMvcmVwb3MvZ3RrcHlnbWVudHMucHlTAAAADmd0a3B5Z21lbnRzLnB5UwAAAABTAAAABnBh
cnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Wokdave.null@example.org2007-12-10T06:54:58Znono0Could you please update the link? I landed on some strange code browser, was bewildered and couldn’t find it. Thank you.Could you please update the link? I landed on some strange code browser, was bewildered and couldn’t find it. Thank you.SQAAAAJTAAAABGJvZHlSUwAAAHpDb3VsZCB5b3UgcGxlYXNlIHVwZGF0ZSB0aGUgbGluaz8gSSBs
YW5kZWQgb24gc29tZSBzdHJhbmdlIGNvZGUgYnJvd3Nlciwgd2FzIGJld2lsZGVyZWQgYW5kIGNv
dWxkbuKAmXQgZmluZCBpdC4gVGhhbmsgeW91LkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Armin Ronacherarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-12-10T07:30:02Znono0Hi. It's now part of the sandbox mercurial repository: http://dev.pocoo.org/hg/sandbox
Because there are no partial checkouts in mercurial yet, here the direct link to the file on the webinterface: http://dev.pocoo.org/hg/sandbox/file/tip/gtkpygments.py
Regards,
ArminHi. It's now part of the sandbox mercurial repository: http://dev.pocoo.org/hg/sandbox
Because there are no partial checkouts in mercurial yet, here the direct link to the file on the webinterface: http://dev.pocoo.org/hg/sandbox/file/tip/gtkpygments.py
Regards,
ArminSQAAAAJTAAAABGJvZHlSUwAAAQ1IaS4gSXQncyBub3cgcGFydCBvZiB0aGUgc2FuZGJveCBtZXJj
dXJpYWwgcmVwb3NpdG9yeTogaHR0cDovL2Rldi5wb2Nvby5vcmcvaGcvc2FuZGJveApCZWNhdXNl
IHRoZXJlIGFyZSBubyBwYXJ0aWFsIGNoZWNrb3V0cyBpbiBtZXJjdXJpYWwgeWV0LCBoZXJlIHRo
ZSBkaXJlY3QgbGluayB0byB0aGUgZmlsZSBvbiB0aGUgd2ViaW50ZXJmYWNlOiBodHRwOi8vZGV2
LnBvY29vLm9yZy9oZy9zYW5kYm94L2ZpbGUvdGlwL2d0a3B5Z21lbnRzLnB5CgpSZWdhcmRzLApB
cm1pbkwAAFMAAAAGcGFyc2VyUwAAAARodG1s
Wokdave.null@example.org2008-01-05T03:40:56Znono0Hi. I since discovered that the sentences summing up the revision were links, so I can yet browse Mercurial-managed code. Thought you would be glad to know you helped me learn something. Besides, nice proof of concept. Regards, WokHi. I since discovered that the sentences summing up the revision were links, so I can yet browse Mercurial-managed code. Thought you would be glad to know you helped me learn something. Besides, nice proof of concept. Regards, WokSQAAAAJTAAAABGJvZHlSUwAAAOdIaS4gSSBzaW5jZSBkaXNjb3ZlcmVkIHRoYXQgdGhlIHNlbnRl
bmNlcyBzdW1taW5nIHVwIHRoZSByZXZpc2lvbiB3ZXJlIGxpbmtzLCBzbyBJIGNhbiB5ZXQgYnJv
d3NlIE1lcmN1cmlhbC1tYW5hZ2VkIGNvZGUuIFRob3VnaHQgeW91IHdvdWxkIGJlIGdsYWQgdG8g
a25vdyB5b3UgaGVscGVkIG1lIGxlYXJuIHNvbWV0aGluZy4gQmVzaWRlcywgbmljZSBwcm9vZiBv
ZiBjb25jZXB0LiBSZWdhcmRzLCBXb2tMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
__loader__ support in djangohttp://lucumr.pocoo.org/cogitations/2007/05/29/__loader__-support-in-django/2007-05-29T20:52:21Z2007-05-29T20:52:21ZArmin Ronacher__loader__-support-in-djangoyesyes2Totally missed that, but someone applied <a href="http://code.djangoproject.com/ticket/3734">my django patch</a> for the debug system. With django [5051] onwards it's possible to debug Jinja and eggs in django :-)Totally missed that, but someone applied <a href="http://code.djangoproject.com/ticket/3734">my django patch</a> for the debug system. With django [5051] onwards it's possible to debug Jinja and eggs in django :-)SQAAAANTAAAABGJvZHlSUwAAAClUb3RhbGx5IG1pc3NlZCB0aGF0LCBidXQgc29tZW9uZSBhcHBs
aWVkIEwAAUVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAKWh0dHA6Ly9jb2RlLmRqYW5nb3Byb2pl
Y3QuY29tL3RpY2tldC8zNzM0UwAAAA9teSBkamFuZ28gcGF0Y2hTAAAAZSBmb3IgdGhlIGRlYnVn
IHN5c3RlbS4gV2l0aCBkamFuZ28gWzUwNTFdIG9ud2FyZHMgaXQncyBwb3NzaWJsZSB0byBkZWJ1
ZyBKaW5qYSBhbmQgZWdncyBpbiBkamFuZ28gOi0pUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWlu
dHJvUlMAAAAATAAA
syck vs syckhttp://lucumr.pocoo.org/cogitations/2007/05/29/syck-vs-syck/2007-05-29T19:19:13Z2007-05-29T19:19:13ZArmin Ronachersyck-vs-syckyesyes2<pre>$ time python -c "import syck; syck.load(file('yaml').read())"
real 0m2.255s
user 0m1.572s
sys 0m0.088s</pre>
<pre>$ time ruby -ryaml -e "YAML.load(File.open('yaml'))"
real 0m9.455s
user 0m7.984s
sys 0m0.080s</pre><pre>$ time python -c "import syck; syck.load(file('yaml').read())"
real 0m2.255s
user 0m1.572s
sys 0m0.088s</pre>
<pre>$ time ruby -ryaml -e "YAML.load(File.open('yaml'))"
real 0m9.455s
user 0m7.984s
sys 0m0.080s</pre>SQAAAANTAAAABGJvZHlSUwAAAABMAAJFUwAAAANwcmVMAABNAABTAAAAcSQgdGltZSBweXRob24g
LWMgImltcG9ydCBzeWNrOyBzeWNrLmxvYWQoZmlsZSgneWFtbCcpLnJlYWQoKSkiCnJlYWwgICAg
MG0yLjI1NXMKdXNlciAgICAwbTEuNTcycwpzeXMgICAgIDBtMC4wODhzUwAAAAIKCkVTAAAAA3By
ZUwAAE0AAFMAAABnJCB0aW1lIHJ1YnkgLXJ5YW1sIC1lICJZQU1MLmxvYWQoRmlsZS5vcGVuKCd5
YW1sJykpIgpyZWFsICAgIDBtOS40NTVzCnVzZXIgICAgMG03Ljk4NHMKc3lzICAgICAwbTAuMDgw
c1MAAAAAUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Python Dict Rehashinghttp://lucumr.pocoo.org/cogitations/2007/05/29/python-dict-rehashing/2007-05-29T18:30:23Z2007-05-29T18:30:23ZArmin Ronacherpython-dict-rehashingyesyes2With <a href="/cogitations/2007/05/29/mutable-hash-keys/">this</a> in mind I was looking for a way to rehash a dict in python. Things that do not work: <tt>d = dict(d)</tt> and <tt>d.update(d)</tt> because the first copies the structure of the dict over, the second does nothing because the dict is the merged dict. What works is <tt>d.update(d.iteritems())</tt>With <a href="/cogitations/2007/05/29/mutable-hash-keys/">this</a> in mind I was looking for a way to rehash a dict in python. Things that do not work: <tt>d = dict(d)</tt> and <tt>d.update(d)</tt> because the first copies the structure of the dict over, the second does nothing because the dict is the merged dict. What works is <tt>d.update(d.iteritems())</tt>SQAAAANTAAAABGJvZHlSUwAAAAVXaXRoIEwABEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAKi9j
b2dpdGF0aW9ucy8yMDA3LzA1LzI5L211dGFibGUtaGFzaC1rZXlzL1MAAAAEdGhpc1MAAABWIGlu
IG1pbmQgSSB3YXMgbG9va2luZyBmb3IgYSB3YXkgdG8gcmVoYXNoIGEgZGljdCBpbiBweXRob24u
IFRoaW5ncyB0aGF0IGRvIG5vdCB3b3JrOiBFUwAAAAJ0dEwAAE0AAFMAAAALZCA9IGRpY3QoZClT
AAAABSBhbmQgRVMAAAACdHRMAABNAABTAAAAC2QudXBkYXRlKGQpUwAAAIUgYmVjYXVzZSB0aGUg
Zmlyc3QgY29waWVzIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRpY3Qgb3ZlciwgdGhlIHNlY29uZCBk
b2VzIG5vdGhpbmcgYmVjYXVzZSB0aGUgZGljdCBpcyB0aGUgbWVyZ2VkIGRpY3QuIFdoYXQgd29y
a3MgaXMgRVMAAAACdHRMAABNAABTAAAAF2QudXBkYXRlKGQuaXRlcml0ZW1zKCkpUwAAAABTAAAA
BnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Nice Captchahttp://lucumr.pocoo.org/cogitations/2007/05/29/nice-captcha/2007-05-29T18:10:01Z2007-05-29T18:10:01ZArmin Ronachernice-captchayesyes2<a href="http://research.microsoft.com/asirra/">asirra</a> -- Asirra is a human interactive proof that asks users to identify photos of cats and dogs. It's powered by over two million photos from our unique partnership with Petfinder.com.<a href="http://research.microsoft.com/asirra/">asirra</a> -- Asirra is a human interactive proof that asks users to identify photos of cats and dogs. It's powered by over two million photos from our unique partnership with Petfinder.com.SQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACVodHRwOi8v
cmVzZWFyY2gubWljcm9zb2Z0LmNvbS9hc2lycmEvUwAAAAZhc2lycmFTAAAAtCAtLSBBc2lycmEg
aXMgYSBodW1hbiBpbnRlcmFjdGl2ZSBwcm9vZiB0aGF0IGFza3MgdXNlcnMgdG8gaWRlbnRpZnkg
cGhvdG9zIG9mIGNhdHMgYW5kIGRvZ3MuIEl0J3MgcG93ZXJlZCBieSBvdmVyIHR3byBtaWxsaW9u
IHBob3RvcyBmcm9tIG91ciB1bmlxdWUgcGFydG5lcnNoaXAgd2l0aCBQZXRmaW5kZXIuY29tLlMA
AAAGcGFyc2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Niemand hat die Absicht, einen Überwachungsstaat zu errichtenhttp://lucumr.pocoo.org/cogitations/2007/05/29/niemand-hat-die-absicht-einen-uberwachungsstaat-zu-errichten/2007-05-29T16:25:37Z2007-05-29T16:25:37ZArmin Ronacherniemand-hat-die-absicht-einen-uberwachungsstaat-zu-errichtenyesyes2<a href="http://video.google.com/videoplay?docid=6233111545394191802&hl=de">"Es hat niemand vor, einen Überwachungsstaat in Deutschland zu errichten"</a> -- Wolfgang Bosbach<a href="http://video.google.com/videoplay?docid=6233111545394191802&hl=de">"Es hat niemand vor, einen Überwachungsstaat in Deutschland zu errichten"</a> -- Wolfgang BosbachSQAAAANTAAAABGJvZHlSUwAAAABMAAFFUwAAAAFhTAAATQABUwAAAARocmVmUwAAAEFodHRwOi8v
dmlkZW8uZ29vZ2xlLmNvbS92aWRlb3BsYXk/ZG9jaWQ9NjIzMzExMTU0NTM5NDE5MTgwMiZobD1k
ZVMAAABKIkVzIGhhdCBuaWVtYW5kIHZvciwgZWluZW4gw5xiZXJ3YWNodW5nc3N0YWF0IGluIERl
dXRzY2hsYW5kIHp1IGVycmljaHRlbiJTAAAAFSAtLSAgV29sZmdhbmcgQm9zYmFjaFMAAAAGcGFy
c2VyUwAAAARodG1sUwAAAAVpbnRyb1JTAAAAAEwAAA==
Jinja 1.1 in Feature Freezehttp://lucumr.pocoo.org/cogitations/2007/05/29/jinja-11-in-feature-freeze/2007-05-29T16:24:00Z2007-05-29T16:24:00ZArmin Ronacherjinja-11-in-feature-freezeyesyes2I now pushed <a href="http://jinja.pocoo.org/">Jinja</a> 1.1 into feature freeze. The trunk is now only used to improve stability, write some more unittests and fix spelling mistakes and stuff like that in the documentation. You can expect a release in about one week.
The <a href="http://jinja.pocoo.org/documentation/changelog#version-1-1">changelog</a> so far is huge and the items here are only a very, very short summary with the most important things.
The probably biggest change is the support for <tt>{{ super() }}</tt>. It works like <tt>{{ block.super }}</tt> in django, just that it's a lot more flexible because you can use it like any other function. So you can apply filters on it, put it into a variable, pass it around etc. The whole block system is not a lot more complex in the background, you can render all parents and because of that we also reworked the way Jinja stores debug information. It's now not a requirement any more to have the sourcecode of the template -- the bytecode knows about the debug infos.
We also improved the debugging messages and added support for brace balancing. Now you can set the delimiters of the blocks to <tt>${</tt> and <tt>}</tt> and still use dict literals in it. You can also have the same delimiters for blocks and variables now, similar to smarty. Other synax improvements: You can now use parentheses for macro definitions: <tt>{% macro foo(bar, baz %}</tt> instead of <tt>{% macro foo bar, baz %}</tt> which is a lot easier to read if the editor doesn't highlight the function name.
Strings without unicode characters are now stored as bytestrings. While this is a bit slower than unicode everywhere it allows to use datetime.strptime and friends which only accept bytestrings. On the other hand an optional C implementation of the context baseclass was added. Variable lookups in the Jinja context are now a lot faster if installed with this module.
A bunch of bugs were also fixed, especially regarding old-style classes and invalid signatures for exceptions. Also the CachedLoader mixing works now for both memory and disk caching which just partially worked in the 1.0 release version.
Last but not least: A new <tt>{% call %}</tt> tag is available that allows to pass executable template code to a macro. It works exactly like Ruby blocks, just for Jinja templates :-)
If you want to upgrade to the development version to help fixing the latest bugs etc. consider deleting the cache files of your templates first if you have the disk cache enabled.
You can find other changes in the changelog, it's quite long :-)
<strong>Update:</strong> here the results from the bigtable benchmark:
<pre>Django Templates 415.52 ms
Jinja Templates 142.40 ms
Kid Templates 1202.83 ms
Genshi Templates 635.37 ms
Cheetah Templates 56.52 ms
Mako Templates 50.09 ms</pre>I now pushed <a href="http://jinja.pocoo.org/">Jinja</a> 1.1 into feature freeze. The trunk is now only used to improve stability, write some more unittests and fix spelling mistakes and stuff like that in the documentation. You can expect a release in about one week.
The <a href="http://jinja.pocoo.org/documentation/changelog#version-1-1">changelog</a> so far is huge and the items here are only a very, very short summary with the most important things.
The probably biggest change is the support for <tt>{{ super() }}</tt>. It works like <tt>{{ block.super }}</tt> in django, just that it's a lot more flexible because you can use it like any other function. So you can apply filters on it, put it into a variable, pass it around etc. The whole block system is not a lot more complex in the background, you can render all parents and because of that we also reworked the way Jinja stores debug information. It's now not a requirement any more to have the sourcecode of the template -- the bytecode knows about the debug infos.
We also improved the debugging messages and added support for brace balancing. Now you can set the delimiters of the blocks to <tt>${</tt> and <tt>}</tt> and still use dict literals in it. You can also have the same delimiters for blocks and variables now, similar to smarty. Other synax improvements: You can now use parentheses for macro definitions: <tt>{% macro foo(bar, baz %}</tt> instead of <tt>{% macro foo bar, baz %}</tt> which is a lot easier to read if the editor doesn't highlight the function name.
Strings without unicode characters are now stored as bytestrings. While this is a bit slower than unicode everywhere it allows to use datetime.strptime and friends which only accept bytestrings. On the other hand an optional C implementation of the context baseclass was added. Variable lookups in the Jinja context are now a lot faster if installed with this module.
A bunch of bugs were also fixed, especially regarding old-style classes and invalid signatures for exceptions. Also the CachedLoader mixing works now for both memory and disk caching which just partially worked in the 1.0 release version.
Last but not least: A new <tt>{% call %}</tt> tag is available that allows to pass executable template code to a macro. It works exactly like Ruby blocks, just for Jinja templates :-)
If you want to upgrade to the development version to help fixing the latest bugs etc. consider deleting the cache files of your templates first if you have the disk cache enabled.
You can find other changes in the changelog, it's quite long :-)
<strong>Update:</strong> here the results from the bigtable benchmark:
<pre>Django Templates 415.52 ms
Jinja Templates 142.40 ms
Kid Templates 1202.83 ms
Genshi Templates 635.37 ms
Cheetah Templates 56.52 ms
Mako Templates 50.09 ms</pre>SQAAAANTAAAABGJvZHlSUwAAAA1JIG5vdyBwdXNoZWQgTAALRVMAAAABYUwAAE0AAVMAAAAEaHJl
ZlMAAAAXaHR0cDovL2ppbmphLnBvY29vLm9yZy9TAAAABUppbmphUwAAANogMS4xIGludG8gZmVh
dHVyZSBmcmVlemUuIFRoZSB0cnVuayBpcyBub3cgb25seSB1c2VkIHRvIGltcHJvdmUgc3RhYmls
aXR5LCB3cml0ZSBzb21lIG1vcmUgdW5pdHRlc3RzIGFuZCBmaXggc3BlbGxpbmcgbWlzdGFrZXMg
YW5kIHN0dWZmIGxpa2UgdGhhdCBpbiB0aGUgZG9jdW1lbnRhdGlvbi4gWW91IGNhbiBleHBlY3Qg
YSByZWxlYXNlIGluIGFib3V0IG9uZSB3ZWVrLgoKVGhlIEVTAAAAAWFMAABNAAFTAAAABGhyZWZT
AAAAOmh0dHA6Ly9qaW5qYS5wb2Nvby5vcmcvZG9jdW1lbnRhdGlvbi9jaGFuZ2Vsb2cjdmVyc2lv
bi0xLTFTAAAACWNoYW5nZWxvZ1MAAACXIHNvIGZhciBpcyBodWdlIGFuZCB0aGUgaXRlbXMgaGVy
ZSBhcmUgb25seSBhIHZlcnksIHZlcnkgc2hvcnQgc3VtbWFyeSB3aXRoIHRoZSBtb3N0IGltcG9y
dGFudCB0aGluZ3MuCgpUaGUgcHJvYmFibHkgYmlnZ2VzdCBjaGFuZ2UgaXMgdGhlIHN1cHBvcnQg
Zm9yIEVTAAAAAnR0TAAATQAAUwAAAA17eyBzdXBlcigpIH19UwAAABAuIEl0IHdvcmtzIGxpa2Ug
RVMAAAACdHRMAABNAABTAAAAEXt7IGJsb2NrLnN1cGVyIH19UwAAAk8gaW4gZGphbmdvLCBqdXN0
IHRoYXQgaXQncyBhIGxvdCBtb3JlIGZsZXhpYmxlIGJlY2F1c2UgeW91IGNhbiB1c2UgaXQgbGlr
ZSBhbnkgb3RoZXIgZnVuY3Rpb24uIFNvIHlvdSBjYW4gYXBwbHkgZmlsdGVycyBvbiBpdCwgcHV0
IGl0IGludG8gYSB2YXJpYWJsZSwgcGFzcyBpdCBhcm91bmQgZXRjLiBUaGUgd2hvbGUgYmxvY2sg
c3lzdGVtIGlzIG5vdCBhIGxvdCBtb3JlIGNvbXBsZXggaW4gdGhlIGJhY2tncm91bmQsIHlvdSBj
YW4gcmVuZGVyIGFsbCBwYXJlbnRzIGFuZCBiZWNhdXNlIG9mIHRoYXQgd2UgYWxzbyByZXdvcmtl
ZCB0aGUgd2F5IEppbmphIHN0b3JlcyBkZWJ1ZyBpbmZvcm1hdGlvbi4gSXQncyBub3cgbm90IGEg
cmVxdWlyZW1lbnQgYW55IG1vcmUgdG8gaGF2ZSB0aGUgc291cmNlY29kZSBvZiB0aGUgdGVtcGxh
dGUgLS0gdGhlIGJ5dGVjb2RlIGtub3dzIGFib3V0IHRoZSBkZWJ1ZyBpbmZvcy4KCldlIGFsc28g
aW1wcm92ZWQgdGhlIGRlYnVnZ2luZyBtZXNzYWdlcyBhbmQgYWRkZWQgc3VwcG9ydCBmb3IgYnJh
Y2UgYmFsYW5jaW5nLiBOb3cgeW91IGNhbiBzZXQgdGhlIGRlbGltaXRlcnMgb2YgdGhlIGJsb2Nr
cyB0byBFUwAAAAJ0dEwAAE0AAFMAAAACJHtTAAAABSBhbmQgRVMAAAACdHRMAABNAABTAAAAAX1T
AAAAyCBhbmQgc3RpbGwgdXNlIGRpY3QgbGl0ZXJhbHMgaW4gaXQuIFlvdSBjYW4gYWxzbyBoYXZl
IHRoZSBzYW1lIGRlbGltaXRlcnMgZm9yIGJsb2NrcyBhbmQgdmFyaWFibGVzIG5vdywgc2ltaWxh
ciB0byBzbWFydHkuIE90aGVyIHN5bmF4IGltcHJvdmVtZW50czogWW91IGNhbiBub3cgdXNlIHBh
cmVudGhlc2VzIGZvciBtYWNybyBkZWZpbml0aW9uczogRVMAAAACdHRMAABNAABTAAAAGHslIG1h
Y3JvIGZvbyhiYXIsIGJheiAlfVMAAAAMIGluc3RlYWQgb2YgRVMAAAACdHRMAABNAABTAAAAGHsl
IG1hY3JvIGZvbyBiYXIsIGJheiAlfVMAAALOIHdoaWNoIGlzIGEgbG90IGVhc2llciB0byByZWFk
IGlmIHRoZSBlZGl0b3IgZG9lc24ndCBoaWdobGlnaHQgdGhlIGZ1bmN0aW9uIG5hbWUuCgpTdHJp
bmdzIHdpdGhvdXQgdW5pY29kZSBjaGFyYWN0ZXJzIGFyZSBub3cgc3RvcmVkIGFzIGJ5dGVzdHJp
bmdzLiBXaGlsZSB0aGlzIGlzIGEgYml0IHNsb3dlciB0aGFuIHVuaWNvZGUgZXZlcnl3aGVyZSBp
dCBhbGxvd3MgdG8gdXNlIGRhdGV0aW1lLnN0cnB0aW1lIGFuZCBmcmllbmRzIHdoaWNoIG9ubHkg
YWNjZXB0IGJ5dGVzdHJpbmdzLiBPbiB0aGUgb3RoZXIgaGFuZCBhbiBvcHRpb25hbCBDIGltcGxl
bWVudGF0aW9uIG9mIHRoZSBjb250ZXh0IGJhc2VjbGFzcyB3YXMgYWRkZWQuIFZhcmlhYmxlIGxv
b2t1cHMgaW4gdGhlIEppbmphIGNvbnRleHQgYXJlIG5vdyBhIGxvdCBmYXN0ZXIgaWYgaW5zdGFs
bGVkIHdpdGggdGhpcyBtb2R1bGUuCgpBIGJ1bmNoIG9mIGJ1Z3Mgd2VyZSBhbHNvIGZpeGVkLCBl
c3BlY2lhbGx5IHJlZ2FyZGluZyBvbGQtc3R5bGUgY2xhc3NlcyBhbmQgaW52YWxpZCBzaWduYXR1
cmVzIGZvciBleGNlcHRpb25zLiBBbHNvIHRoZSBDYWNoZWRMb2FkZXIgbWl4aW5nIHdvcmtzIG5v
dyBmb3IgYm90aCBtZW1vcnkgYW5kIGRpc2sgY2FjaGluZyB3aGljaCBqdXN0IHBhcnRpYWxseSB3
b3JrZWQgaW4gdGhlIDEuMCByZWxlYXNlIHZlcnNpb24uCgpMYXN0IGJ1dCBub3QgbGVhc3Q6IEEg
bmV3IEVTAAAAAnR0TAAATQAAUwAAAAp7JSBjYWxsICV9UwAAAYMgdGFnIGlzIGF2YWlsYWJsZSB0
aGF0IGFsbG93cyB0byBwYXNzIGV4ZWN1dGFibGUgdGVtcGxhdGUgY29kZSB0byBhIG1hY3JvLiBJ
dCB3b3JrcyBleGFjdGx5IGxpa2UgUnVieSBibG9ja3MsIGp1c3QgZm9yIEppbmphIHRlbXBsYXRl
cyA6LSkKCklmIHlvdSB3YW50IHRvIHVwZ3JhZGUgdG8gdGhlIGRldmVsb3BtZW50IHZlcnNpb24g
dG8gaGVscCBmaXhpbmcgdGhlIGxhdGVzdCBidWdzIGV0Yy4gY29uc2lkZXIgZGVsZXRpbmcgdGhl
IGNhY2hlIGZpbGVzIG9mIHlvdXIgdGVtcGxhdGVzIGZpcnN0IGlmIHlvdSBoYXZlIHRoZSBkaXNr
IGNhY2hlIGVuYWJsZWQuCgpZb3UgY2FuIGZpbmQgb3RoZXIgY2hhbmdlcyBpbiB0aGUgY2hhbmdl
bG9nLCBpdCdzIHF1aXRlIGxvbmcgOi0pCgpFUwAAAAZzdHJvbmdMAABNAABTAAAAB1VwZGF0ZTpT
AAAALyBoZXJlIHRoZSByZXN1bHRzIGZyb20gdGhlIGJpZ3RhYmxlIGJlbmNobWFyazoKRVMAAAAD
cHJlTAAATQAAUwAAAU9EamFuZ28gVGVtcGxhdGVzICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgNDE1LjUyIG1zCkppbmphIFRlbXBsYXRlcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAxNDIuNDAgbXMKS2lkIFRlbXBsYXRlcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
MTIwMi44MyBtcwpHZW5zaGkgVGVtcGxhdGVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
NjM1LjM3IG1zCkNoZWV0YWggVGVtcGxhdGVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
NTYuNTIgbXMKTWFrbyBUZW1wbGF0ZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA1
MC4wOSBtc1MAAAAAUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Wokdave.null@example.org2007-12-10T05:58:58Znono0Great, keep on the good work ;)
I see you don’t get much comments but I guess hits and downloads speak for themselves. Cheers.Great, keep on the good work ;)
I see you don’t get much comments but I guess hits and downloads speak for themselves. Cheers.SQAAAAJTAAAABGJvZHlSUwAAAIFHcmVhdCwga2VlcCBvbiB0aGUgZ29vZCB3b3JrIDspCgpJIHNl
ZSB5b3UgZG9u4oCZdCBnZXQgbXVjaCBjb21tZW50cyBidXQgSSBndWVzcyBoaXRzIGFuZCBkb3du
bG9hZHMgc3BlYWsgZm9yIHRoZW1zZWx2ZXMuIENoZWVycy5MAABTAAAABnBhcnNlclMAAAAEaHRt
bA==
Wokdave.null@example.org2007-12-10T06:43:32Znono0Well, sorry for commenting about something outdated :-| Didn’t see the announcement for the 1.2 (truth to be told, I didn’t read the date of this entry either). I’m going to comment on the newer entry, please delete these two comments. Please excuse my enthusiasm to comment here :)Well, sorry for commenting about something outdated :-| Didn’t see the announcement for the 1.2 (truth to be told, I didn’t read the date of this entry either). I’m going to comment on the newer entry, please delete these two comments. Please excuse my enthusiasm to comment here :)SQAAAAJTAAAABGJvZHlSUwAAASBXZWxsLCBzb3JyeSBmb3IgY29tbWVudGluZyBhYm91dCBzb21l
dGhpbmcgb3V0ZGF0ZWQgOi18IERpZG7igJl0IHNlZSB0aGUgYW5ub3VuY2VtZW50IGZvciB0aGUg
MS4yICh0cnV0aCB0byBiZSB0b2xkLCBJIGRpZG7igJl0IHJlYWQgdGhlIGRhdGUgb2YgdGhpcyBl
bnRyeSBlaXRoZXIpLiBJ4oCZbSBnb2luZyB0byBjb21tZW50IG9uIHRoZSBuZXdlciBlbnRyeSwg
cGxlYXNlIGRlbGV0ZSB0aGVzZSB0d28gY29tbWVudHMuIFBsZWFzZSBleGN1c2UgbXkgZW50aHVz
aWFzbSB0byBjb21tZW50IGhlcmUgOilMAABTAAAABnBhcnNlclMAAAAEaHRtbA==
Mutable Hash Keyshttp://lucumr.pocoo.org/cogitations/2007/05/29/mutable-hash-keys/2007-05-29T14:42:44Z2007-05-29T14:42:44ZArmin Ronachermutable-hash-keysyesyes2Caveat. Mutable hash keys in ruby obviously behave different than you would expect:
<pre>>> foo = [1, 2, 3]
[1, 2, 3]
>> bar = {foo => 42}
{[1, 2, 3]=>42}
>> foo << 4
[1, 2, 3, 4]
>> bar[foo]
nil</pre>
<strong>Update:</strong> there is Hash#rehash.Caveat. Mutable hash keys in ruby obviously behave different than you would expect:
<pre>>> foo = [1, 2, 3]
[1, 2, 3]
>> bar = {foo => 42}
{[1, 2, 3]=>42}
>> foo << 4
[1, 2, 3, 4]
>> bar[foo]
nil</pre>
<strong>Update:</strong> there is Hash#rehash.SQAAAANTAAAABGJvZHlSUwAAAFRDYXZlYXQuIE11dGFibGUgaGFzaCBrZXlzIGluIHJ1Ynkgb2J2
aW91c2x5IGJlaGF2ZSBkaWZmZXJlbnQgdGhhbiB5b3Ugd291bGQgZXhwZWN0OgpMAAJFUwAAAANw
cmVMAABNAABTAAAAaj4+IGZvbyA9IFsxLCAyLCAzXQpbMSwgMiwgM10KPj4gYmFyID0ge2ZvbyA9
PiA0Mn0Ke1sxLCAyLCAzXT0+NDJ9Cj4+IGZvbyA8PCA0ClsxLCAyLCAzLCA0XQo+PiBiYXJbZm9v
XQpuaWxTAAAAAQpFUwAAAAZzdHJvbmdMAABNAABTAAAAB1VwZGF0ZTpTAAAAFiB0aGVyZSBpcyBI
YXNoI3JlaGFzaC5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Scientology and Mehttp://lucumr.pocoo.org/cogitations/2007/05/29/scientology-and-me/2007-05-29T12:34:55Z2007-05-29T12:34:55ZArmin Ronacherscientology-and-meyesyes2<a href="http://blog.fefe.de/?ts=b8a57a58">via</a> fefe's blog. A BBC production about the "cult" scientology: <a href=http://www.youtube.com/watch?v=Y3pG49lg5AU>#1</a>, <a href=http://www.youtube.com/watch?v=pnG--NCL4KI>#2</a>, <a href=http://www.youtube.com/watch?v=wGecZssWc5M>#3</a>, and <a href=http://www.youtube.com/watch?v=Gv8IQ0Z_G_U>#4</a><a href="http://blog.fefe.de/?ts=b8a57a58">via</a> fefe's blog. A BBC production about the "cult" scientology: <a href="http://www.youtube.com/watch?v=Y3pG49lg5AU">#1</a>, <a href="http://www.youtube.com/watch?v=pnG--NCL4KI">#2</a>, <a href="http://www.youtube.com/watch?v=wGecZssWc5M">#3</a>, and <a href="http://www.youtube.com/watch?v=Gv8IQ0Z_G_U">#4</a>SQAAAANTAAAABGJvZHlSUwAAAABMAAVFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACBodHRwOi8v
YmxvZy5mZWZlLmRlLz90cz1iOGE1N2E1OFMAAAADdmlhUwAAAD0gZmVmZSdzIGJsb2cuIEEgQkJD
IHByb2R1Y3Rpb24gYWJvdXQgdGhlICJjdWx0IiBzY2llbnRvbG9neTogRVMAAAABYUwAAE0AAVMA
AAAEaHJlZlMAAAAqaHR0cDovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PVkzcEc0OWxnNUFVUwAA
AAIjMVMAAAACLCBFUwAAAAFhTAAATQABUwAAAARocmVmUwAAACpodHRwOi8vd3d3LnlvdXR1YmUu
Y29tL3dhdGNoP3Y9cG5HLS1OQ0w0S0lTAAAAAiMyUwAAAAIsIEVTAAAAAWFMAABNAAFTAAAABGhy
ZWZTAAAAKmh0dHA6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj13R2VjWnNzV2M1TVMAAAACIzNT
AAAABiwgYW5kIEVTAAAAAWFMAABNAAFTAAAABGhyZWZTAAAAKmh0dHA6Ly93d3cueW91dHViZS5j
b20vd2F0Y2g/dj1HdjhJUTBaX0dfVVMAAAACIzRTAAAAAFMAAAAGcGFyc2VyUwAAAARodG1sUwAA
AAVpbnRyb1JTAAAAAEwAAA==
Lucofsll@gmail.com2007-05-30T04:27:55Znono0What a boring show...What a boring show...SQAAAAJTAAAABGJvZHlSUwAAABVXaGF0IGEgYm9yaW5nIHNob3cuLi5MAABTAAAABnBhcnNlclMA
AAAEaHRtbA==
mitsuhikoarmin.ronacher@active-4.comhttp://lucumr.pocoo.org/2007-05-30T20:17:05Znono0Well. I found it quite interesting.Well. I found it quite interesting.SQAAAAJTAAAABGJvZHlSUwAAACNXZWxsLiBJIGZvdW5kIGl0IHF1aXRlIGludGVyZXN0aW5nLkwA
AFMAAAAGcGFyc2VyUwAAAARodG1s
Organizing Python Applicationshttp://lucumr.pocoo.org/cogitations/2007/05/28/organizing-python-applications/2007-05-28T19:31:18Z2007-05-28T19:31:18ZArmin Ronacherorganizing-python-applicationsyesyes2I just found again a python library that uses relative imports (the python 2.4 way) and star imports and two days ago mika asked my how to organize Python applications. Interestingly this topic is not often discussed and you can do it terrible wrong because of a fundamental design mistake in Python 2.
Basically the problem occurs as soon as you have more than just one module and make a package around them. This is a good thing. Python packages are an awesome thing, they don't cause namespace clashes and they work well. But a folder with a __init__.py file in does not automatically make this package importable. Many developers solve that by importing the modules in that package with so-called relative imports (<tt>from mymodule import foobar</tt>). That works because Python currently looks also in the folder of the module for moduls, no matter how deep in the package structure. The correct way would be <tt>from mypackage.mymodule import foobar</tt>, but that requires mypackage being in the pythonpath which is not the case per default if the bootstrapping code is also part of the package. Confused? Basically there <strong>must</strong> be a special file for any python application that starts that application up. In case of a WSGI application this for example is a myapplication.fcgi or whatever. The module that imports all other stuff has a problem. That problem is called __main__. The module that starts up any python powered application is not imported with its normal import name (for example myapplication.main) but as __main__ and can be imported twice because of this. So just create a file called <tt>myapplication-bin</tt> or something like that, import myapplication.main and start the main function from there.
Now all modules in that package can do <tt>from myapplication.somemodule import something</tt> because the working directory is the the folder the package "myapplication" is located in and that folder is automatically part of the pythonpath.
Also an example file structure for a GTK application could look like this:
<pre>myapplication-bin
lib/
myapplication/
__init__.py
main.py
something_else.py
shipped_dependency/
__init__.py
shared
some_files.glade</pre>
In that case the myapplication-bin must add the "lib" to the pythonpath (by appending that folder to sys.path) and notify the application when starting about the location of shared. This also allows moving the shared files to /usr/share, the application code to /usr/lib or /usr/share too and myapplication-bin into /usr/bin.I just found again a python library that uses relative imports (the python 2.4 way) and star imports and two days ago mika asked my how to organize Python applications. Interestingly this topic is not often discussed and you can do it terrible wrong because of a fundamental design mistake in Python 2.
Basically the problem occurs as soon as you have more than just one module and make a package around them. This is a good thing. Python packages are an awesome thing, they don't cause namespace clashes and they work well. But a folder with a __init__.py file in does not automatically make this package importable. Many developers solve that by importing the modules in that package with so-called relative imports (<tt>from mymodule import foobar</tt>). That works because Python currently looks also in the folder of the module for moduls, no matter how deep in the package structure. The correct way would be <tt>from mypackage.mymodule import foobar</tt>, but that requires mypackage being in the pythonpath which is not the case per default if the bootstrapping code is also part of the package. Confused? Basically there <strong>must</strong> be a special file for any python application that starts that application up. In case of a WSGI application this for example is a myapplication.fcgi or whatever. The module that imports all other stuff has a problem. That problem is called __main__. The module that starts up any python powered application is not imported with its normal import name (for example myapplication.main) but as __main__ and can be imported twice because of this. So just create a file called <tt>myapplication-bin</tt> or something like that, import myapplication.main and start the main function from there.
Now all modules in that package can do <tt>from myapplication.somemodule import something</tt> because the working directory is the the folder the package "myapplication" is located in and that folder is automatically part of the pythonpath.
Also an example file structure for a GTK application could look like this:
<pre>myapplication-bin
lib/
myapplication/
__init__.py
main.py
something_else.py
shipped_dependency/
__init__.py
shared
some_files.glade</pre>
In that case the myapplication-bin must add the "lib" to the pythonpath (by appending that folder to sys.path) and notify the application when starting about the location of shared. This also allows moving the shared files to /usr/share, the application code to /usr/lib or /usr/share too and myapplication-bin into /usr/bin.SQAAAANTAAAABGJvZHlSUwAAAtBJIGp1c3QgZm91bmQgYWdhaW4gYSBweXRob24gbGlicmFyeSB0
aGF0IHVzZXMgcmVsYXRpdmUgaW1wb3J0cyAodGhlIHB5dGhvbiAyLjQgd2F5KSBhbmQgc3RhciBp
bXBvcnRzIGFuZCB0d28gZGF5cyBhZ28gbWlrYSBhc2tlZCBteSBob3cgdG8gb3JnYW5pemUgUHl0
aG9uIGFwcGxpY2F0aW9ucy4gSW50ZXJlc3RpbmdseSB0aGlzIHRvcGljIGlzIG5vdCBvZnRlbiBk
aXNjdXNzZWQgYW5kIHlvdSBjYW4gZG8gaXQgdGVycmlibGUgd3JvbmcgYmVjYXVzZSBvZiBhIGZ1
bmRhbWVudGFsIGRlc2lnbiBtaXN0YWtlIGluIFB5dGhvbiAyLgoKQmFzaWNhbGx5IHRoZSBwcm9i
bGVtIG9jY3VycyBhcyBzb29uIGFzIHlvdSBoYXZlIG1vcmUgdGhhbiBqdXN0IG9uZSBtb2R1bGUg
YW5kIG1ha2UgYSBwYWNrYWdlIGFyb3VuZCB0aGVtLiBUaGlzIGlzIGEgZ29vZCB0aGluZy4gUHl0
aG9uIHBhY2thZ2VzIGFyZSBhbiBhd2Vzb21lIHRoaW5nLCB0aGV5IGRvbid0IGNhdXNlIG5hbWVz
cGFjZSBjbGFzaGVzIGFuZCB0aGV5IHdvcmsgd2VsbC4gQnV0IGEgZm9sZGVyIHdpdGggYSBfX2lu
aXRfXy5weSBmaWxlIGluIGRvZXMgbm90IGF1dG9tYXRpY2FsbHkgbWFrZSB0aGlzIHBhY2thZ2Ug
aW1wb3J0YWJsZS4gTWFueSBkZXZlbG9wZXJzIHNvbHZlIHRoYXQgYnkgaW1wb3J0aW5nIHRoZSBt
b2R1bGVzIGluIHRoYXQgcGFja2FnZSB3aXRoIHNvLWNhbGxlZCByZWxhdGl2ZSBpbXBvcnRzIChM
AAZFUwAAAAJ0dEwAAE0AAFMAAAAbZnJvbSBteW1vZHVsZSBpbXBvcnQgZm9vYmFyUwAAAKApLiBU
aGF0IHdvcmtzIGJlY2F1c2UgUHl0aG9uIGN1cnJlbnRseSBsb29rcyBhbHNvIGluIHRoZSBmb2xk
ZXIgb2YgdGhlIG1vZHVsZSBmb3IgbW9kdWxzLCBubyBtYXR0ZXIgaG93IGRlZXAgaW4gdGhlIHBh
Y2thZ2Ugc3RydWN0dXJlLiBUaGUgY29ycmVjdCB3YXkgd291bGQgYmUgRVMAAAACdHRMAABNAABT
AAAAJWZyb20gbXlwYWNrYWdlLm15bW9kdWxlIGltcG9ydCBmb29iYXJTAAAAqSwgYnV0IHRoYXQg
cmVxdWlyZXMgbXlwYWNrYWdlIGJlaW5nIGluIHRoZSBweXRob25wYXRoIHdoaWNoIGlzIG5vdCB0
aGUgY2FzZSBwZXIgZGVmYXVsdCBpZiB0aGUgYm9vdHN0cmFwcGluZyBjb2RlIGlzIGFsc28gcGFy
dCBvZiB0aGUgcGFja2FnZS4gQ29uZnVzZWQ/IEJhc2ljYWxseSB0aGVyZSBFUwAAAAZzdHJvbmdM
AABNAABTAAAABG11c3RTAAAB2SBiZSBhIHNwZWNpYWwgZmlsZSBmb3IgYW55IHB5dGhvbiBhcHBs
aWNhdGlvbiB0aGF0IHN0YXJ0cyB0aGF0IGFwcGxpY2F0aW9uIHVwLiBJbiBjYXNlIG9mIGEgV1NH
SSBhcHBsaWNhdGlvbiB0aGlzIGZvciBleGFtcGxlIGlzIGEgbXlhcHBsaWNhdGlvbi5mY2dpIG9y
IHdoYXRldmVyLiBUaGUgbW9kdWxlIHRoYXQgaW1wb3J0cyBhbGwgb3RoZXIgc3R1ZmYgaGFzIGEg
cHJvYmxlbS4gVGhhdCBwcm9ibGVtIGlzIGNhbGxlZCBfX21haW5fXy4gVGhlIG1vZHVsZSB0aGF0
IHN0YXJ0cyB1cCBhbnkgcHl0aG9uIHBvd2VyZWQgYXBwbGljYXRpb24gaXMgbm90IGltcG9ydGVk
IHdpdGggaXRzIG5vcm1hbCBpbXBvcnQgbmFtZSAoZm9yIGV4YW1wbGUgbXlhcHBsaWNhdGlvbi5t
YWluKSBidXQgYXMgX19tYWluX18gYW5kIGNhbiBiZSBpbXBvcnRlZCB0d2ljZSBiZWNhdXNlIG9m
IHRoaXMuIFNvIGp1c3QgY3JlYXRlIGEgZmlsZSBjYWxsZWQgRVMAAAACdHRMAABNAABTAAAAEW15
YXBwbGljYXRpb24tYmluUwAAAIMgb3Igc29tZXRoaW5nIGxpa2UgdGhhdCwgaW1wb3J0IG15YXBw
bGljYXRpb24ubWFpbiBhbmQgc3RhcnQgdGhlIG1haW4gZnVuY3Rpb24gZnJvbSB0aGVyZS4KCk5v
dyBhbGwgbW9kdWxlcyBpbiB0aGF0IHBhY2thZ2UgY2FuIGRvIEVTAAAAAnR0TAAATQAAUwAAAC5m
cm9tIG15YXBwbGljYXRpb24uc29tZW1vZHVsZSBpbXBvcnQgc29tZXRoaW5nUwAAAOAgYmVjYXVz
ZSB0aGUgd29ya2luZyBkaXJlY3RvcnkgaXMgdGhlIHRoZSBmb2xkZXIgdGhlIHBhY2thZ2UgIm15
YXBwbGljYXRpb24iIGlzIGxvY2F0ZWQgaW4gYW5kIHRoYXQgZm9sZGVyIGlzIGF1dG9tYXRpY2Fs
bHkgcGFydCBvZiB0aGUgcHl0aG9ucGF0aC4KCkFsc28gYW4gZXhhbXBsZSBmaWxlIHN0cnVjdHVy
ZSBmb3IgYSBHVEsgYXBwbGljYXRpb24gY291bGQgbG9vayBsaWtlIHRoaXM6CkVTAAAAA3ByZUwA
AE0AAFMAAACrbXlhcHBsaWNhdGlvbi1iaW4KICBsaWIvCiAgICBteWFwcGxpY2F0aW9uLwogICAg
ICBfX2luaXRfXy5weQogICAgICBtYWluLnB5CiAgICAgIHNvbWV0aGluZ19lbHNlLnB5CiAgICBz
aGlwcGVkX2RlcGVuZGVuY3kvCiAgICAgIF9faW5pdF9fLnB5CiAgc2hhcmVkCiAgICBzb21lX2Zp
bGVzLmdsYWRlUwAAAUcKCkluIHRoYXQgY2FzZSB0aGUgbXlhcHBsaWNhdGlvbi1iaW4gbXVzdCBh
ZGQgdGhlICJsaWIiIHRvIHRoZSBweXRob25wYXRoIChieSBhcHBlbmRpbmcgdGhhdCBmb2xkZXIg
dG8gc3lzLnBhdGgpIGFuZCBub3RpZnkgdGhlIGFwcGxpY2F0aW9uIHdoZW4gc3RhcnRpbmcgYWJv
dXQgdGhlIGxvY2F0aW9uIG9mIHNoYXJlZC4gVGhpcyBhbHNvIGFsbG93cyBtb3ZpbmcgdGhlIHNo
YXJlZCBmaWxlcyB0byAvdXNyL3NoYXJlLCB0aGUgYXBwbGljYXRpb24gY29kZSB0byAvdXNyL2xp
YiBvciAvdXNyL3NoYXJlIHRvbyBhbmQgbXlhcHBsaWNhdGlvbi1iaW4gaW50byAvdXNyL2Jpbi5T
AAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Experimental Python Documentationhttp://lucumr.pocoo.org/cogitations/2007/05/28/experimental-python-documentation/2007-05-28T16:42:14Z2007-05-28T16:42:14ZArmin Ronacherexperimental-python-documentationyesyes2Over the last few weeks Georg Brandl from the <a href="http://trac.pocoo.org/wiki/PocooTeam">pocoo team</a> worked on an ass kicking building system that generates reStructuredText files out of the original python LaTeX sources. I helped him a bit with the web part and the result is a nifty WSGI application and offline documentation in .html format that does everything what the current docs do, just better :-)
The sources as rst have some real advantages. First of all the whole build system is written in python. Thus it's a lot easier to have a platform independent build system (what we now have) and write a web documentation interface with patch functionality (editing the sources and sending a patch to the python documentation mailinglist right from the web interface, with preview). The web application also has comments that a user can attach to any page that was generated from rst sources.
Also the web version of the documentation knows about keywords (unique references). So you can jump to <tt>os.path.exists</tt> without any clicking. Just go to <tt>/os.path.exists</tt> (or enter the keyword in the quicksearch box) and you will be redirected to the page that documents that function. It also provides a fuzzy search, similar to the php documentation. If you type a function wrong or don't know the name of the module where it's in it will present you a list of up to 20 possible results.
We don't know if it will really replace the current python documentation but the first responses in the <a href="http://news.gmane.org/find-root.php?message_id=%3cf2nb8o%24g7v%241%40sea.gmane.org%3e">thread on python-dev</a> sound positive. You can try out the interactive, online version at <a href="http://pydoc.gbrandl.de:3000/">pydoc.gbrandl.de:3000</a>.
If you have suggestions, ideas etc. feel free to join the discussion in the thread above or post your comments here.Over the last few weeks Georg Brandl from the <a href="http://trac.pocoo.org/wiki/PocooTeam">pocoo team</a> worked on an ass kicking building system that generates reStructuredText files out of the original python LaTeX sources. I helped him a bit with the web part and the result is a nifty WSGI application and offline documentation in .html format that does everything what the current docs do, just better :-)
The sources as rst have some real advantages. First of all the whole build system is written in python. Thus it's a lot easier to have a platform independent build system (what we now have) and write a web documentation interface with patch functionality (editing the sources and sending a patch to the python documentation mailinglist right from the web interface, with preview). The web application also has comments that a user can attach to any page that was generated from rst sources.
Also the web version of the documentation knows about keywords (unique references). So you can jump to <tt>os.path.exists</tt> without any clicking. Just go to <tt>/os.path.exists</tt> (or enter the keyword in the quicksearch box) and you will be redirected to the page that documents that function. It also provides a fuzzy search, similar to the php documentation. If you type a function wrong or don't know the name of the module where it's in it will present you a list of up to 20 possible results.
We don't know if it will really replace the current python documentation but the first responses in the <a href="http://news.gmane.org/find-root.php?message_id=%3cf2nb8o%24g7v%241%40sea.gmane.org%3e">thread on python-dev</a> sound positive. You can try out the interactive, online version at <a href="http://pydoc.gbrandl.de:3000/">pydoc.gbrandl.de:3000</a>.
If you have suggestions, ideas etc. feel free to join the discussion in the thread above or post your comments here.SQAAAANTAAAABGJvZHlSUwAAAC5PdmVyIHRoZSBsYXN0IGZldyB3ZWVrcyBHZW9yZyBCcmFuZGwg
ZnJvbSB0aGUgTAAFRVMAAAABYUwAAE0AAVMAAAAEaHJlZlMAAAAkaHR0cDovL3RyYWMucG9jb28u
b3JnL3dpa2kvUG9jb29UZWFtUwAAAApwb2NvbyB0ZWFtUwAAA4cgd29ya2VkIG9uIGFuIGFzcyBr
aWNraW5nIGJ1aWxkaW5nIHN5c3RlbSB0aGF0IGdlbmVyYXRlcyByZVN0cnVjdHVyZWRUZXh0IGZp
bGVzIG91dCBvZiB0aGUgb3JpZ2luYWwgcHl0aG9uIExhVGVYIHNvdXJjZXMuIEkgaGVscGVkIGhp
bSBhIGJpdCB3aXRoIHRoZSB3ZWIgcGFydCBhbmQgdGhlIHJlc3VsdCBpcyBhIG5pZnR5IFdTR0kg
YXBwbGljYXRpb24gYW5kIG9mZmxpbmUgZG9jdW1lbnRhdGlvbiBpbiAuaHRtbCBmb3JtYXQgdGhh
dCBkb2VzIGV2ZXJ5dGhpbmcgd2hhdCB0aGUgY3VycmVudCBkb2NzIGRvLCBqdXN0IGJldHRlciA6
LSkKClRoZSBzb3VyY2VzIGFzIHJzdCBoYXZlIHNvbWUgcmVhbCBhZHZhbnRhZ2VzLiBGaXJzdCBv
ZiBhbGwgdGhlIHdob2xlIGJ1aWxkIHN5c3RlbSBpcyB3cml0dGVuIGluIHB5dGhvbi4gVGh1cyBp
dCdzIGEgbG90IGVhc2llciB0byBoYXZlIGEgcGxhdGZvcm0gaW5kZXBlbmRlbnQgYnVpbGQgc3lz
dGVtICh3aGF0IHdlIG5vdyBoYXZlKSBhbmQgd3JpdGUgYSB3ZWIgZG9jdW1lbnRhdGlvbiBpbnRl
cmZhY2Ugd2l0aCBwYXRjaCBmdW5jdGlvbmFsaXR5IChlZGl0aW5nIHRoZSBzb3VyY2VzIGFuZCBz
ZW5kaW5nIGEgcGF0Y2ggdG8gdGhlIHB5dGhvbiBkb2N1bWVudGF0aW9uIG1haWxpbmdsaXN0IHJp
Z2h0IGZyb20gdGhlIHdlYiBpbnRlcmZhY2UsIHdpdGggcHJldmlldykuIFRoZSB3ZWIgYXBwbGlj
YXRpb24gYWxzbyBoYXMgY29tbWVudHMgdGhhdCBhIHVzZXIgY2FuIGF0dGFjaCB0byBhbnkgcGFn
ZSB0aGF0IHdhcyBnZW5lcmF0ZWQgZnJvbSByc3Qgc291cmNlcy4KCkFsc28gdGhlIHdlYiB2ZXJz
aW9uIG9mIHRoZSBkb2N1bWVudGF0aW9uIGtub3dzIGFib3V0IGtleXdvcmRzICh1bmlxdWUgcmVm
ZXJlbmNlcykuIFNvIHlvdSBjYW4ganVtcCB0byBFUwAAAAJ0dEwAAE0AAFMAAAAOb3MucGF0aC5l
eGlzdHNTAAAAIiB3aXRob3V0IGFueSBjbGlja2luZy4gSnVzdCBnbyB0byBFUwAAAAJ0dEwAAE0A
AFMAAAAPL29zLnBhdGguZXhpc3RzUwAAAakgKG9yIGVudGVyIHRoZSBrZXl3b3JkIGluIHRoZSBx
dWlja3NlYXJjaCBib3gpIGFuZCB5b3Ugd2lsbCBiZSByZWRpcmVjdGVkIHRvIHRoZSBwYWdlIHRo
YXQgZG9jdW1lbnRzIHRoYXQgZnVuY3Rpb24uIEl0IGFsc28gcHJvdmlkZXMgYSBmdXp6eSBzZWFy
Y2gsIHNpbWlsYXIgdG8gdGhlIHBocCBkb2N1bWVudGF0aW9uLiBJZiB5b3UgdHlwZSBhIGZ1bmN0
aW9uIHdyb25nIG9yIGRvbid0IGtub3cgdGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB3aGVyZSBpdCdz
IGluIGl0IHdpbGwgcHJlc2VudCB5b3UgYSBsaXN0IG9mIHVwIHRvIDIwIHBvc3NpYmxlIHJlc3Vs
dHMuCgpXZSBkb24ndCBrbm93IGlmIGl0IHdpbGwgcmVhbGx5IHJlcGxhY2UgdGhlIGN1cnJlbnQg
cHl0aG9uIGRvY3VtZW50YXRpb24gYnV0IHRoZSBmaXJzdCByZXNwb25zZXMgaW4gdGhlIEVTAAAA
AWFMAABNAAFTAAAABGhyZWZTAAAAVWh0dHA6Ly9uZXdzLmdtYW5lLm9yZy9maW5kLXJvb3QucGhw
P21lc3NhZ2VfaWQ9JTNjZjJuYjhvJTI0Zzd2JTI0MSU0MHNlYS5nbWFuZS5vcmclM2VTAAAAFHRo
cmVhZCBvbiBweXRob24tZGV2UwAAAEQgc291bmQgcG9zaXRpdmUuIFlvdSBjYW4gdHJ5IG91dCB0
aGUgaW50ZXJhY3RpdmUsIG9ubGluZSB2ZXJzaW9uIGF0IEVTAAAAAWFMAABNAAFTAAAABGhyZWZT
AAAAHWh0dHA6Ly9weWRvYy5nYnJhbmRsLmRlOjMwMDAvUwAAABVweWRvYy5nYnJhbmRsLmRlOjMw
MDBTAAAAdy4KCklmIHlvdSBoYXZlIHN1Z2dlc3Rpb25zLCBpZGVhcyBldGMuIGZlZWwgZnJlZSB0
byBqb2luIHRoZSBkaXNjdXNzaW9uIGluIHRoZSB0aHJlYWQgYWJvdmUgb3IgcG9zdCB5b3VyIGNv
bW1lbnRzIGhlcmUuUwAAAAZwYXJzZXJTAAAABGh0bWxTAAAABWludHJvUlMAAAAATAAA
Blogging Againhttp://lucumr.pocoo.org/cogitations/2007/05/28/blogging-again/2007-05-28T15:32:09Z2007-05-28T15:32:09ZArmin Ronacherblogging-againyesyes2As you probably know I had a blog some time ago that was written in django. I guess everybody sooner or later writes his own blog and the codebase starts sucking sooner or later. In fact the wordpress codebase sucks too but I don't have to maintain it :-)
I will use this blog from now on to jot down some ideas, real-life things and other stuff that occurs, just not articles, those will stay where they are currently.
I do have a "blogroll", just that it's part of the <a href="/links">lucumr links</a> section and not the blog itself.As you probably know I had a blog some time ago that was written in django. I guess everybody sooner or later writes his own blog and the codebase starts sucking sooner or later. In fact the wordpress codebase sucks too but I don't have to maintain it :-)
I will use this blog from now on to jot down some ideas, real-life things and other stuff that occurs, just not articles, those will stay where they are currently.
I do have a "blogroll", just that it's part of the <a href="/links">lucumr links</a> section and not the blog itself.SQAAAANTAAAABGJvZHlSUwAAAdlBcyB5b3UgcHJvYmFibHkga25vdyBJIGhhZCBhIGJsb2cgc29t
ZSB0aW1lIGFnbyB0aGF0IHdhcyB3cml0dGVuIGluIGRqYW5nby4gSSBndWVzcyBldmVyeWJvZHkg
c29vbmVyIG9yIGxhdGVyIHdyaXRlcyBoaXMgb3duIGJsb2cgYW5kIHRoZSBjb2RlYmFzZSBzdGFy
dHMgc3Vja2luZyBzb29uZXIgb3IgbGF0ZXIuIEluIGZhY3QgdGhlIHdvcmRwcmVzcyBjb2RlYmFz
ZSBzdWNrcyB0b28gYnV0IEkgZG9uJ3QgaGF2ZSB0byBtYWludGFpbiBpdCA6LSkKCkkgd2lsbCB1
c2UgdGhpcyBibG9nIGZyb20gbm93IG9uIHRvIGpvdCBkb3duIHNvbWUgaWRlYXMsIHJlYWwtbGlm
ZSB0aGluZ3MgYW5kIG90aGVyIHN0dWZmIHRoYXQgb2NjdXJzLCBqdXN0IG5vdCBhcnRpY2xlcywg
dGhvc2Ugd2lsbCBzdGF5IHdoZXJlIHRoZXkgYXJlIGN1cnJlbnRseS4KCkkgZG8gaGF2ZSBhICJi
bG9ncm9sbCIsIGp1c3QgdGhhdCBpdCdzIHBhcnQgb2YgdGhlIEwAAUVTAAAAAWFMAABNAAFTAAAA
BGhyZWZTAAAABi9saW5rc1MAAAAMbHVjdW1yIGxpbmtzUwAAACEgc2VjdGlvbiBhbmQgbm90IHRo
ZSBibG9nIGl0c2VsZi5TAAAABnBhcnNlclMAAAAEaHRtbFMAAAAFaW50cm9SUwAAAABMAAA=
Armin RonacherIQ==
$usernameyes