This accidentally fell out of her pocket when I bumped into her. Took me four goes.

Thursday, June 29

Geek

Warning Warning Warning

This site may hiccup a little, because I'm converting it to Minx.

Do not panic!

It doesn't help.

Posted by: Pixy Misa at 02:22 AM | Comments (3) | Add Comment | Trackbacks (Suck)
Post contains 24 words, total size 1 kb.

Tuesday, June 27

Geek

Quote Of The Day

SESSION is an associative array (aka Dictionary). When the session times out, things like 'Tempfile' are no longer defined. (PHP has an unset() function that undefines a reference.) But when PHP sees an undeclared reference, it doesn't error out -- instead it substitutes '' (a blank string) if the reference occurs within a string. So now the user is executing

rm -r /var/public_www/

As you might imagine, this behavior makes PHP very dangerous in the hands of an idiot.

Yeah.

Posted by: Pixy Misa at 12:25 AM | Comments (5) | Add Comment | Trackbacks (Suck)
Post contains 87 words, total size 1 kb.

Friday, June 23

Geek

Irregular Expressions

I hate regular expressions.

There's this thing I call information density*. Regular expressions are extremely information-dense. So are (for example) Forth and APL. With any of these, you can express a very complex algorithm in a very short sequence of symbols, but that comes with a cost.

People are used to dealing with information density within a certain range. For the most part, the information we receive has massive amounts of redundancy; you can often miss half the message and still understand it. Not so with regular expressions - every single bit matters. There are no (or almost no) cues to what is going on; you have to inspect each symbol one at a time, parse them into groups, interpret the groups, work out the relationships between the groups... And do it all correctly.

Computers are good at that. Humans not so much.

Well, computers are supposed to be good at it, anyway.

The subject arose because I needed a string-formatting language for the templating system in Minx. Python has fairly good formatting for numbers, dates, and times, but it has no equivalent formatting library for strings. It thinks it has several, but it doesn't. What it has is libraries that format things into strings, but nothing to format the strings themselves.

Except regexps.

So I used those. And the first example - not particularly complicated - sent the template engine into what appeared to be an infinite loop. Worked fine in the examples I tested. Worked fine for the first three items on the page. Raised an exception for the next item (quite validly). And then tried to process the item after that and was never heard from again.

I'm sure I could fix it, but it remains that it happened to me, and I wrote the blasted thing. If it happens to me, then a week after launching the software I'm going to find the server with a load average of 700 doing nothing but processing regular expressions for ever and ever.

So I wrote a little text-formatting library instead.

With plugin support.

Sixty lines of code, does almost everything I need.

* There's a specific term for it, but I can't recall it at the moment. But it relates to randomness and entropy.

Posted by: Pixy Misa at 08:03 AM | No Comments | Add Comment | Trackbacks (Suck)
Post contains 380 words, total size 2 kb.

Thursday, June 22

Geek

Aha! (Maybe)

It's not the memory - Memtest-86 gives it a clean bill of health.

It's not the disk - checkdsk runs fine, and my applications have no problems.

Windows says it's a disk problem but it acts like it's a memory problem.

What can cause that?

The pagefile. The evil, good-for-nothing, rat bastard pagefile.

I thought to myself If this were a real operating system, it would have a log of all these errors.

Then I thought, It is a real operating system. A crappy one, but a real OS nonetheless.

And it has crappy log files, but they exist, and they were full of errors - all relating to the pagefile.

As soon as I manage to get the darn thing to boot, I'm going to disable it.

Again. I already disabled it, but it didn't take. Who knows why; this is Windows.

Okay, it finished booting, and now has no pagefile.

Let's see if it crashes.

...

So far, so good. I did get one of those "delayed write failed" errors (so maybe it is the disk after all), but I managed to watch last week's episode of Haruhi Suzumiya on my new TV without anything catching fire, blowing up, crashing, or collapsing into a closed space.

Which is good enough for now.

Tomorrow I send the motherboard from my new PC back for replacement. Then I plan to (finally!) get the forms processing working in Minx. This is an example of what you can do with fairly simple templates; I intend to expand on that. A lot.

Posted by: Pixy Misa at 06:19 AM | Comments (2) | Add Comment | Trackbacks (Suck)
Post contains 263 words, total size 2 kb.

Wednesday, June 21

Geek

Okay Then

Either not the memory, or not only the memory.

Joy.

Update: Memtest-86 is on the third pass without finding any errors.

Not the memory, then.

Not the disk drive, since I swapped that yesterday and it died within ten minutes.

It happens whether I'm on battery or mains power.

Grr.

Dell is having a sale right now...

Posted by: Pixy Misa at 02:26 PM | Comments (4) | Add Comment | Trackbacks (Suck)
Post contains 61 words, total size 1 kb.

Geek

It Was The Memory

I'm just hoping it was only the memory.

Swapped drives in my notebook: BSOD within 10 minutes.

Pulled out the original 256MB of memory: No BSOD so far.

Windows Explorer has restarted a couple of times, but that is not exactly unusual. I'm going to run another checkdsk, because if the memory was playing up, there could be some nasty things lurking in my filesystem.

No progress on the media centre box; looks like that will have to go back for the friendly folks at EYO to take a look at. I've been buying stuff from them for years, and this is the first time something has just plain not worked. Video cards that don't run under Linux, sure. Network cards that are incompatible with my motherboard, yep. And the Hard Drive Destruction Bunny is always lurking around the next corner. But this is the first time I haven't been able to get a new toy to at least boot.

Posted by: Pixy Misa at 07:33 AM | No Comments | Add Comment | Trackbacks (Suck)
Post contains 168 words, total size 1 kb.

Wednesday, June 14

Geek

Where The Time Goes

Timings:

Standard PythonPython + Psyco
No Comments0.260.22
Inline Comments0.920.68
Sanitised Comments1.310.92

For last 500 entries on Munuviana. All times in seconds. Offer void where prohibited by federal, state or local laws, regulations or institutional policy. Offer ends June 30, 2006. Benchmarked on a Pentium D 820 running Centos 4.2. Python 2.4.2 compiled with GCC 3.4.4. Mileage may vary. Contents may ship during shrinking. Do not eat iPod shuffle. Sanitisation of comments only guarantees valid HTML. The content is your own problem.

Posted by: Pixy Misa at 02:58 AM | Comments (1) | Add Comment | Trackbacks (Suck)
Post contains 89 words, total size 1 kb.

Monday, June 12

Geek

Fun With Templates

Minx is currently parasitic* on the MT database and user interface, but it has a template system all its own.

The pages are now fully templated, with no funny stuff going on, so I'll show you what it looks like:

Page Template
<html><head>
<title>Minx Dynamic Pages for Movable Type</title>
<link rel="stylesheet" href="http://ai.mu.nu/styles-site.css" type="text/css" />
<script language="JavaScript" src="http://blog2.mu.nu/cgi/showhide.js"></script>
</head>
<body>
<div id="container"><div id="center"><div class="content">
<center><b>[blog.name]</b></center><p>
[posts:here]
[magic.pager]
[magic.stats]
</div></div></div>
</body></html>
Very simple. You start with a standard HTML/XHTML page, and the Minx tags are marked with [square brackets]. If you have something in your template that's in square brackets that's not a Minx tag - intentionally or unintentionally - it just gets spat out unchanged. (The divs look a bit odd, but that's because I'm using an unmodified MT3 stylesheet for testing.)

We can see three types of tags here:
A simple tag, [blog.name], which just looks up the matching database field for the currently active blog and inserts it into the page at that point.

A here tag, which is used to simplify block processing. The [posts.here] and [comments.here] are the most common examples of this. Without any parameters** they loop through the posts or comments using the default settings for your blog and the default post/comment template, as appropriate.

The post and comment templates look like this:

Post Template
<h2>[post.newdate]</h2><p>
<b>[post.title]</b><p>
[post.text]  
<p class="posted">
Posted by: [post.authorlink] at
<a href="[post.url]">[post.time]</a>
| <a href="#" onClick="ShowHide('cc[post.id]'); return false;">Comments ([post.comments])</a>
| <a href="http://blog2.mu.nu/cgi/mcomment.cgi?post=[post.id]">Add Comment</a>
| Trackbacks (Suck)
</p>   
<div id="cc[post.id]" style="display:none">
[comments:here]
<p class="posted">
<a href="#" onClick="ShowHide('cc[post.id]'); return false;">Hide Comments</a>
| <a href="http://blog2.mu.nu/cgi/mcomment.cgi?post=[post.id]">Add Comment</a>
</p>   
</div>

Comment Template

<div id="c[comment.id]">[comment.text]</div>
<p class="posted">
Posted by: [comment.authorlink] at [comment.datetime] </p>
Again, we have regular HTML, with just a bunch of simple tags to insert the desired values.

Minx is intended to let you have full control of post and comment selection from the template, overriding the default settings, but those tags are more complex to process and don't work yet.

Finally, we have magic tags. We have two examples of this, the pager and the stats. Magic tags do magic stuff that isn't necessarily available using regular template substitution. The pager lets you go to the next/previous page of the blog (a fancier pager is coming); the stats show performance information (and a fancier version of that is coming too).

The central idea is to make as much of the feature set as possible available without making the templates scary. So you don't need to have a complex nested structure of post tags and comment tags. Just put [posts.here] in your page template (with maybe some optional parameters) and [comments:here] in your post template. Set the appropriate settings on your blog options screen and you're in business!

Next up: A user interface...

Update: Minx now pulls its templates dynamically from the MT database. If you create index templates called mxPage, mxPost, and mxComment, Minx will use them to override the default templates. (Which are loaded dynamically as well.)

You can also include templates using the [include template] tag. The template to be included must also begin with "mx", since Minx only looks at those, but you don't actually specify the "mx" when you use the tag. So, for example, you can create a blogroll template called mxBlogroll and include it with the tag [include blogroll]. (It's not case-sensitive.)

Update: Conditional processing with if and ifn. if and ifn can be used with any simple tag to test whether the value of that tag is "true" or not. A tag is true if it is a non-zero number or a non-empty string, otherwise it is false. Any text between [if tag] and [/if] is included if the value of the tag is true. And any text between [ifn tag] and [/ifn] is included only if the value of the tag is false.

You can't nest if tags, though you can nest an ifn inside an if and vice-versa. If you want to get more complicated than that, for now you'll need to use sub-templates with include.

* Or rather, symbiotic.
** And, um, parameters aren't working yet.

Posted by: Pixy Misa at 11:45 PM | No Comments | Add Comment | Trackbacks (Suck)
Post contains 662 words, total size 5 kb.

Geek

Whee!

It works!

Rather than writing everything from scratch to start with, I put together what I had and pointed it at our existing Movable Type database (which has a number of changes over the original, admittedly). And it works.

40 milliseconds is a bit depressing, though. I'll have to see if I can speed that up a bit.

Okay, some timings: Last 200 entries at Munuviana, with inline comments: 420ms. Without inline comments: 90ms. Having inline comments causes a lot of extra SQL queries; I don't know if it's that or the text processing that's taking the time.

A normal page only shows 20 entries, and takes around 45ms with comments and 15ms without. It's a bit hard to time that more precisely, which is why I bumped the page size up.

Every post and comment has to be passed through the template engine; every comment is also processed through a SGML parser to strip out unwanted or invalid HTML tags. I'd love to get a complete page out in 10ms, but I don't think I can. Well, if it's cached, then sure, but not if the whole thing needs to be dynamically generated.

<Pause.>

<Goes off to implement caching system.>

...

<Comes back again.>

Retrieved from cache, processing time 0.0 seconds.

Yeah, that'll do.

Only problem is that saving the text up to be cached takes an extra 10ms or so. I need to try the StringIO/cStringIO functions and see if they help.

Update: cStringIO provides no performance advantage at all. Which is good in that I know that the easy way to code it is just as efficient, but bad in that I can't speed it up at all.

Posted by: Pixy Misa at 03:27 PM | Comments (2) | Add Comment | Trackbacks (Suck)
Post contains 283 words, total size 2 kb.

Sunday, June 11

Geek

Dum De Dum

I've been working on the blog-code, all the live-long day night...

It's good to be doing development again, rather than running around like a hamster on crack trying to shore up systems under attack by hackers, spammers, and just plain lousy other-people's-code.

What I've mostly been doing so far, though, is installing stuff. Python needed an update, as did Apache. Didn't have PIL installed, or Numpy or Pyrex. Pysco has been patched. Memcached and its prerequisites. Bumped MySQL up to 5.0.22, and PostgreSQL up to 8.1.4. (I may end up just using MySQL, but at this stage I'm keeping my options open.) CherryPy and Django and ReportLab. And PHP 5.1.4... (fixeds MySQL option) And PHP 5.1.4 (fixes MySQL option correctly) And PHP 5.1.4 (what do you mean, you can't find zlib? How should I know where it is?)

Okay never mind PHP 5.1.4. I'll do that later.

To work!

Oh, yes: I'm doing all of this on my notebook. Hooray for VMWare Player!

Posted by: Pixy Misa at 09:01 PM | Comments (2) | Add Comment | Trackbacks (Suck)
Post contains 169 words, total size 1 kb.

<< Page 1 of 2 >>
74kb generated in CPU 0.0227, elapsed 0.2652 seconds.
57 queries taking 0.2534 seconds, 363 records returned.
Powered by Minx 1.1.6c-pink.
Using https / https://ai.mee.nu / 361