Kung FuKung Fu

Fujian White Crane Kung Fu

ZopeZope

What I have and am doing with Zope

PhotosPhotos

Photoalbum, both old and new.

ReceptsamlingenReceptsamlingen

In Swedish only. About my "Collection of Recipes" website.

Contact meContact me

My contact details and how to contact me.

  Mobile version of this page Mobile version of this page

RSS

Hot topics

by : My son has been getting red hot ears (usually one) for years. It is due to...

One hot ear

by : here are the lyrics lolli lolli lolli lolli let me see u pop that body x2...

Find song by lyrics

by : I wana do like they do on the discovery channel...

Find song by lyrics

by AUNiA: NO SW33Ti3 THAT iSz A LiL WAYN3 SONG. MYSPAC3.COM/23617291...

Find song by lyrics

by Kobie: please my phone was stolen yesterday and i just want to find out how to blo...

Lost my mobile phone

by Peter: Remember all those websites that used to tell you that the site has been 'o...

Button tag in bloody Internet Explorer

by aditya: somebody stolen my nokia n95 but i dont know there imei no. i have no box,n...

Lost my mobile phone

by Krishna Satani: Dear Sir/Madam, Lost my Nokia 6233 Lost Date: 20/07/2008 I.M.E.I: 35291502...

Lost my mobile phone

by Clebermag: This is the lyric oh oh oh oh oh oh does it's our reggae night will ja...

Find song by lyrics

by Clebermag: Ok, Let me post a lyric of a music that I can't find the name of singer or ...

Find song by lyrics

Old entries


April, 2008
pwdf - a mix of ls and pwd
Lesson learnt with creating DOM element with jQuery

March, 2008
One thing I hate about Linux: cron
How to uninstall nginx with apt
Tip: Printer friendly pages with Page Templates in Zope
apple.com/store doesn't work in Firefox (on Linux)
Mocking a Python standard library
See you at PyCon 2008
File check before delete
"Confessions of a College Callgirl" is the new "My Secret Life As A Prostitute"

February, 2008
January, 2008
2007
2006
2005
2004
2003

 

7th of April

pwdf - a mix of ls and pwd

I often need to know the path to a file so that I can put that in an email for example. The only way I know is to copy and paste the output of pwd followed by a slash / followed by the name of the file. This is too much work so I wrote a quick bash script to combine this into one. Now I can do this:

 $ cd bin
 $ pwdf todo.sh 
 /home/peterbe/bin/todo.sh

I call it pwdf since it's pwd + file. Here's the code for the curious:

 #!/bin/bash
 echo -n `pwd`
 echo -n '/'
 echo $1

Is there no easier way built in into Linux already?

3rd of April

Lesson learnt with creating DOM element with jQuery

This took me some seriously wasted time to figure out yesterday. What I was trying to do was to create a DOM element of tag type A and insert it into the DOM tree of my page. As I was coding along, everything was working just fine in Firefox but the damn thing wouldn't show up anywhere in IE 6. I debugged and debugged and tried all kinds of different approaches and I just couldn't work it out. Then Karl Rudd gave the right hint on the jQuery mailing list.

Basically, what I was doing was something like this:

 var a = $("<a>").attr('href','#').click(somefunction);
 $('#toolbar').append(a);

What was then so strange is now less surprising. When I changed the <a> to a <span> it actually worked but just looked wrong with the rest of the site I was working on. Here's the correct way of doing it:

 var a = $("<a></a>").attr('href','#').click(somefunction);
 $('#toolbar').append(a);

Notice the difference between <a> and <a></a>. The strange thing is that to reproduce this I created this test.html page but here I noticed that in IE 6 it won't let you add any elements that are enclosing ones that are written as singulars. That's really strange since in the same javascript as the above stuff I did a $("<div>") which was working fine. I'll have to get back to figuring out why that one worked nad the A one didn't.

31st of March

One thing I hate about Linux: cron

First of all, I understand that the problem cron solves is a hard one but come on, it's been many years now without much progress. At least not in the usability field of cron jobs. Secondly, I don't know of an operating system that does this better. Perhaps there is one. All I'm saying here is that this aspect of Linux sucks. The issues I have with cron are:

Beef number 1 Is it root, user1 or user2 running a crontab job? I'll have to su into each suspected user and run crontab -l. Granted, some jobs require root access and others don't but it nevertheless makes it hard to find the configured jobs when maintaining someones server.

Beef number 2 Even though they do such a similar thing, it feels like /etc/cron.* is a different battlefield from crontab. Why can't this all be in one coherent place?

Beef number 3 The crontab syntax. How difficult would it be to allow an interface to accept user input as "every 10 minutes" or "01.30 every day"?

Beef number 4 With there being 12 different ways (sarcasm) to write cron job scripts there's no coherent place to collect all log and errors that happen from cron. Couldn't it be default to always write to /var/log/cron/access.log and all executions that cause a write to stderr could append to /var/log/cron/error.log

I don't think Anacron would make me any happier since the problem Anacron solves was not one of the problems I listed above. And lastly, I wouldn't be surprised if there's a semi-abandoned Open Source project on SourceForge that is user friendly but what I'm after is something to get into stock Linux. Kind of like apt/aptitude/dselect is for dpkg maybe?

28th of March

How to uninstall nginx with apt

My colleague Jan showed me how to do this so I'm going to blog about it to not forget and perhaps by being here other people might be able to search and find the solution too. I installed nginx because I wanted to play with it as an alternative to apache on my laptop. Now I've played enough and I'm going to want to remove it. My first attempt didn't work:

 peterbe@trillian:~ $ sudo apt-get --purge remove nginx
 Reading package lists... Done
 Building dependency tree
 Reading state information... Done
 The following packages will be REMOVED:
  nginx*
 0 upgraded, 0 newly installed, 1 to remove and 116 not upgraded.
 1 not fully installed or removed.
 Need to get 0B of archives.
 After unpacking 528kB disk space will be freed.
 Do you want to continue [Y/n]?
 (Reading database ... 242827 files and directories currently installed.)
 Removing nginx ...
 Stopping nginx: invoke-rc.d: initscript nginx, action "stop" failed.
 dpkg: error processing nginx (--purge):
  subprocess pre-removal script returned error exit status 1
 Starting nginx: invoke-rc.d: initscript nginx, action "start" failed.
 dpkg: error while cleaning up:
  subprocess post-installation script returned error exit status 1
 Errors were encountered while processing:
  nginx
 E: Sub-process /usr/bin/dpkg returned an error code (1)

I tried this both before and after having stopped and started nginx. Nothing worked. The trick is to fiddle with the init script /etc/init.d/nginx and insert a exit 0 at the top so that it now starts like this:

 #!/bin/sh
 exit 0

Once saved and you try apt-get --purge remove nginx it will work. It might warn you that /var/log/nginx aren't removed because they're not empty but you can safely remove them manually unless you want to keep them.

24th of March

Tip: Printer friendly pages with Page Templates in Zope

Since I've seen so many poor solutions to this problem I thought I'd share mine. Here's how I make printer friendly pages.

1. Add a method in your base class that looks like this:

  def getMainTemplate(self):
       """ return the suitable METAL header object """
       # assuming zpt/main_template.zpt
       template_obj = self.main_template

       # assuming the "first" line of main_template.zpt to
       # look like this:
       # <metal:block metal:define-macro="master">
       return template_obj.macros['master']

2. Change all your Page Templates to refer to a method rather than a macro directly so that pages like index_html.zpt start like this:

 <html metal:use-macro="here/getMainTemplate">

I've seen the hard coded way too many times where people do something like this <html metal:use-macro="here/main_template/macros/master"> which gives you no flexibility.

3. Now make a copy of main_template.zpt called print_main_template.zpt and the most important change is to make print.css load by default. Here's what it should look like this somewhere inside the <head> tag:

 <link rel="stylesheet" type="text/css" href="/screen.css" media="screen" />
 <link rel="stylesheet" type="text/css" href="/print.css" />

Note how the print.css link tag is now not conditional. Before in main_template.zpt it should have looked like this:

 <link rel="stylesheet" type="text/css" href="/print.css" media="print" /> 
 <link rel="stylesheet" type="text/css" href="/screen.css" media="screen" />

And note how the order is stacked just to be extra safe to weird browsers that don't understand the media condition.

As a last optional feature you should add is to add these lines at the bottom of the template 'print_main_template.zpt':

 <script type="text/javascript">
 window.print();
 </script>
 </body>
 </html>

Another tip is to add something like this to the footer because it becomes useful when you look at a printed copy:

 <div id="footer">
    Printed from <span tal:replace="here/absolute_url"></span> on 
    <span tal:replace="python:here.ZopeTime().strftime('%Y/%m/%d')"></span>

4. Now rewrite the method getMainTemplate() to become usefully intelligent:

   def getMainTemplate(self):
       """ return the suitable METAL header object """
       if self.REQUEST.get('print-version'):
           # assuming zpt/print_main_template.zpt
           template_obj = self.print_main_template
       else:
           # assuming zpt/main_template.zpt
           template_obj = self.main_template

       # assuming the "first" line of main_template.zpt to
       # look like this:
       # <metal:block metal:define-macro="master">
       return template_obj.macros['master']

5. Prepare the interface now for the printer friendly page. This can be done in two different ways. One way is to put a link in the footer or byline like this:

 <a href="?print-version=1">Print this page</a>

Or if you want to force a particular page to always be printer friendly, for example print_invoice.zpt then write it like this:

 <tal:item define="dummy python:request.set('print-version',1)"
           replace="nothing" 
  /><html metal:use-macro="here/getMainTemplate">

As a final point; how you solve your web design with screen.css and print.css varies. One way is to define multiple css files each suitable for individual things like this example shows:

 <link rel="stylesheet" type="text/css" href="/typography.css" /> 
 <link rel="stylesheet" type="text/css" href="/print.css" media="print" /> 
 <link rel="stylesheet" type="text/css" href="/screen.css" media="screen" />

An alternative solution is to don't expect print.css to stand on its own two legs but only be a supplement of the general css file. When doing this you're probably just going to want to override some things and hide some other things like this example from a 'print.css':

 body {
    width:100% !important
 }

 form#login, #navigation, .also-online {
   display:none
 }

To conclude

This gives you a robust framework for enabling printer friendly pages that are quite different from the main template and doing it like this means that you don't have add conditional hacks to your main template that displays certain things if in printer friendly mode or not.

Most importantly, this gives you the framework for adding other versions of main template. For example these:

  • mobile_main_template.zpt (guess what for)
  • minimal_main_template.zpt (for things like Help page popups)

A healthy and fair use of METAL macros is also key to asserting that you don't have to repeat yourself too much in the copies of main_template.pt.

Good luck!

19th of March

apple.com/store doesn't work in Firefox (on Linux)

apple.com/store doesn't work in Firefox (on Linux) If you do web design, making your pages work in different browsers can be very frustrating. The most common troublemaker is Internet Explorer and I think everyone who's ever tried hand-coding CSS has experienced. Another thing that makes it hard is simply lack of time to test it in all different browsers and platforms.

But! if it makes you feel any better even Apple is struggling as this screenshot shows.

I've seen Apple.com/store work in Firefox on other computers so clearly it's not a problem on all Firefoxes but you'd think a big site like this must have heard of this and done something about it. If you think that what happens is that the images aren't loaded that not the case. This problem has been around for a while for me now. And no, I don't have Firebug or any other debuggers switched on as I open this site.

14th of March

Mocking a Python standard library

Here's one of many things I've learnt today at PyCon. Inspired by code that Grig Gheorghiu showed in his slides on automated testing, you can monkey patch a standard library that your application is using in your unit tests to, in my case, mock a remote service without having to run a server. I've done lots of monkey-patching in Zope but then I've only been monkey patching individual methods or attributes of imported classes. This is very similar to that. Here's what my application does:

 from poplib import POP3
 class MyZopeApp(...):
    def check4mail(self, hostname, port, user, pwd):
        connection = POP3(hostname, port=port)
        ...download emails and process them...

Adjacent to this I have a unit/integration test that looks like this:

 class TestCase(ZopeTestCase):
    def test_check4mail(self):
        # monkey patch!
        # note that this imports a module, not a class
        from Products.IssueTrackerProduct import IssueTracker 
        FakePOP3.files = ('test1.email',)
        IssueTracker.POP3 = FakePOP3

        # now check what happens when check4mail() is run
        result = self.folder.tracker.check4mail()
        assert ...


>Read the whole text (299 more words)

10th of March

See you at PyCon 2008

I'm going to Chicago on Wednesday for the PyCon 2008 conference. I'm going to stay at the Crowne Plaza (or whatever it was called) like many of the other people at the conference.

This is what I look like:

See you at PyCon 2008

If you see this mug, go up to it and say Hi. It speaks British, Swedish and some American and loves food, beer and tea which might be helpful to know if you would feel like to talk more to it. Its interests for this conference are: Grok, Zope, Django, Plone, buildout, automated testing, agile development and Javascript. Its main claim-to-fame is an Open Source bug/issue tracker program called IssueTrackerProduct which it is more than delighted to talk about.

I've never been to Chicago before and I'm really excited about Tuesday night as I've bought tickets to a Chicago Bulls NBA game (basketball). All other nights I'm hoping to socialise, get drunk, get full and get down and dirty nerdy all week. See you there!

6th of March

File check before delete

Because I always forget, here's how to check if a file exists before attempting to delete it in bash:

 [ -f foobar.html ] && rm foobar.html

If you don't do it this way and the file doesn't exist you get this:

 rm: cannot remove `foobar.html': No such file or directory

2nd of March

"Confessions of a College Callgirl" is the new "My Secret Life As A Prostitute"

http://collegecallgirl.blogspot.com/ 

Back in 2004 I used to sometimes read a blog called My Secret Life As A Prostitute which was both sexy, sobering and kind of educational. That blog was also a callgirl who wrote about her work-experiences, sex life in general and problems she had with her boyfriend. Sadly that blog disappeared suddenly. Perhaps the girl who wrote it got "discovered". By that I might mean that a colleague of hers at some investment bank found out what she was spending so much time on in her lunch breaks. Jokes aside, it's hard to tell if this is for real or just made up based on someone's fantasy of being an escort girl. Sometimes the blog gets very technical to the point that it's hard to imagine her not being a real call girl.

As I'm skimming through this new blog I find that it's so similar to the one I was skimming back in 2004. She's very blunt and has the same sense of humor and just like the 2004 blog every now and then, as she describes her encounters/jobs she also describes how she herself gets off on it.

Another similarity is that reading this gives the same feeling of shame of reading it. I'm obviously not so ashamed that I can't confess that I'm reading up it does feel a bit intimate and "dirty" at the same time. It's like reading an Bret Easton Ellis book which is sold in respectable normal bookshops but whose content is sometimes worse than porn.

And for people who've seen Flight of the Concordes, check out this post

29th of February

hostip.info - Look up the location from an IP

http://www.hostip.info/ 

I've never really needed it but I've been looking for a tool that is super easy to use that quickly looks up the location of an IP address. The super easy tool is called hostip.info and this is what happens when you do a lookup on www.peterbe.com's IP at http://api.hostip.info/get_html.php?ip=80.68.212.7 :

 Country: UNITED KINGDOM (UK)
 City: (Unknown city)

Cool. I'll remember that till next I really need this. I discovered hostip.info by reading this cool blog by Corey Goldberg

21st of February

CommandLineApp by Doug Hellmann

http://www.doughellmann.com...cts/CommandLineApp/ 

I just read the feature article "Command line programs are classes, too!" by Doug Hellmann in the January 2008 issue of Python Magazine about his program CommandLineApp and I've tried it out on one of my old Python programs where I do the opt parsing manually with getopt. The results are beautiful and quick. It's sprinkled with Doug specific magic but I quickly got over that when I saw out easy it was to work with. There are still a few questions of things I didn't manage to work out but that will unfortunately have to wait.

If anything, the worst thing about this library is that it's not part of the standard library so either you have to tell people to sudo easy_install CommandLineApp in the instructions or include it yourself in your packages if you prefer to ship things with a kitchen sink included.

If you want to check it out in action, either subscribe to the magazine (and support the effort) or just download csvcat

12th of February

If Americans knew - An interesting insight into the Israeli Palestine conflict

http://www.ifamericansonlyknew.org/ 

If Americans knew - An interesting insight into the Israeli Palestine conflict I'm not a political editor and I can't confirm the validity of these statistics but if they're at least close to true it's a hell of a scary picture of the injustice in the Israeli/Palestine conflict.

Israel receives $6.8 million per day in aid. I doubt that all of that money goes towards building better schools for Israeli families.


>Read the whole text (41 more words)

9th of February

Chinese New Year and the Persecution of Falun Gong in China

http://www.youtube.com/watch?v=9LPksYo2WUQ 

Chinese New Year and the Persecution of Falun Gong in China Today I'm celebrating the Chinese New Year with a big dinner in Chinatown in central London. I love the Chinese people, their food, their culture and am perpetually interested in learning more about them and their ways.

But we mustn't forget that this otherwise great country also has a very very dark side which we must never accept or forget: The Persecution of Falun Gong.

Didn't the nazi persecution of jews teach us anything? Are you aware that Falun Gong practitioners are imprisoned, bullied and tortured? Do you know that this oppression is fully sponsored by the government and not rogue individual groups?

I was made aware of this website (warning: graphical content) and this video just a few days ago. I'm fully aware that China is a big country where many "bad" things can happen due to the sheer numerical chances with such large numbers and such many different internal cultures but that's never an excuse for this barbaric behavior.

Think about it. Remember it.

6th of February

logrotating all my Zope event logs

I've installed a lot of Zope instances on my laptop since version 2.7.3 and out of curiosity and desperate need for more hard drive space I thought I'd log rotate them all with the standard Linux logrotate program.

Before doing the log rotate, the total size of all my event.log files came to about 290Mb! After running logrotate (twice of course to go from event.log.1 to event.log.2.gz) the total size become 20Mb. Not a huge significance in the world of gigabyte hard drives but at least something.

 

Older entriesOrder entries
BackBack