The Tsonny Blog

Posts with tag 'Web dev'

Quick and dirty MySQL 4 -> 5 and latin1 to utf8 conversion April 26, 2008

I spent most of this Sunday trying to migrate a MySQL 4.x databse to MySQL 5.x. What is easy in theory was impossible in practice: Using the standard mysqldump and import way always produced wrong character encodings in my DB. In fact, the old DB was in latin1, and I wanted the new (5.x) also to be in latin1. But importing the data always produced encodings in utf8 (although MySQL thought it was having latin1). So, I tried almost all but nothing worked but this trick:

  1. Dump the table definition and import into the new DB. You only need the tables, not the data!
  2. Convert all tables in the new DB to utf8 as default character encoding: alter table BLAH convert to character set utf8;. When done, also change the encoding for the entire DB: alter database MYDB character set = utf8;.
  3. Export the table data from the old DB without table creation statements (-t): mysqldump -t --default-character-set=utf8 MYDB > MYDB.sql.
  4. Import the sql dump as usual.

If you are using PHP to connect to the DB, make sure to tell the database connection it should use utf8 als encoding. With ADODB, this can be done like this:

 $db_charset = $db->Execute( "SHOW VARIABLES LIKE 'character_set_database'" ); $db->Execute( "SET NAMES '" . $db_charset->fields['Value'] . "'" ); 

Alchemist's Handbook for Plone April 7, 2008

These are just some quick and dirty installation instructions for collective.tin, collective.lead, collective.mercury etc. What I really want to do is to use SQL content types within Plone 3.0 in a Zope3-ish way.

Unfortunately, I could not find information on how to install the collective.* packages, so here's my hack:

  1. Install SQLAlchemy 0.4.x. Straightforward, since it's an egg. Just remember to use the same python that is used to run Zope/Plone. If you're on a Mac, for example, set the $PATH variable so it finds your Plone package's python executable first (on OSX, Plone3, that is: /Applications/Plone-3.x/Python-2.4.x/python2.4)
    The package is then installed in Python-2.4.x/lib/site-packages of your Plone directory.
  2. Start with the SVN version of collective.lead. It's a Python egg, so just do python setup.py install. Again, remember to use the correct python execs.
  3. Now, checkout collective.mercury and collective.tin from SVN. Put the directories trunk/collective/tin and trunk/collective/mercury to the collective.lead-directory that was created by the python egg installation. It's important to put it there, otherwise my python could not find it. Not sure how to do this in a proper way...
  4. Then, basically follow the steps in the tutorial. Important:
  5. Create the products directory (eg. Timesheets). Then, change into the Plone instance directory, that is, the directory just above Products.
  6. Start the Zope debug server from within the very same directory and import codegen from collective.mercury, like described in the tutorial. If you're on MySQL, use Annotate=False, as it only works in PostgreSQL.

ALL DONE! Easy if you know how. Not so easy without any documentation...

Web 2.0 Workshop November 22, 2006

Web 2.0 Workshop

UPDATE: More pictures on my Flickr page

The first and hopefully not last workshop on Web 2.0 is over. Actually, workshop is the wrong word, since it was more a roadshow of web 2.0 related technologies and concepts (including Django). Anyways, I hope the participants enjoyed it as much as I did.

This workshop was held in our family's holiday home in the Swiss mountains. We had great luck with the weather, which was very mild and rather dry. The temperature inside the house was at some chilly 20 degrees C, turning the entrance hall into a cosy conference room (or cinema room at night).

Apart from drinking far too little beer (that will be taken care of at New Year's Eve, I'm sure), we also listened to a couple of talks and made some progress in the development of the Activity rewrite. The latter will be available in written form soon, the workshop talks will be put online as PDF as soon as I get all the slides.

The conference room

A cosy way to listen to talks!

Coach explains the math...

I'd like to thank all participants with special thanks going to my father and Claude Berner of Vitus GmbH.

Update: A short movie of some impressions is now ready for your viewing pleasures.

Update: Slides in chronological order:

  • Web 2.0 - Analyse eines Paradigmenwechsels (PDF | QT)
  • Was sind Webapplikationen? (PDF | QT)
  • Webbased Projects using PHP (PDF)
  • Django - Python Framework für Leute mit Deadlines (PDF | QT)

ASP.net training videos November 2, 2006

I'm an open-minded person. Over the last 8 years, I have looked into a bunch of different web technologies, such as Perl, Python, PHP and Java - heck, even ColdFusion. After a long, unhappy relationship with PHP I've settled with Perl and Python.

While the .net framework and C# in particular are considered a rather good product (for something coming out of Redmond, that is), the ASP.net part is conceived with mixed feelings in the community. This seems to be mainly for technical reasons: While some of them concern the tight integration of Visual Studio to the development process "making hard things easy but easy things impossible", others do not like the fact that while ASP.net provides you with an extremely complex framework, it doesn't make it obvious to write maintainable code - it seems, for instance, unclear if MVC design patterns are (practically) applicable to ASP.net.

Leaving the technical discussion to those who understand more about ASP.net than me, I'll add this to the list of ASP.net unhappyness: Why-oh-why is it impossible for a non-Windows person to learn about ASP.net? MSDN has a huge collection of well-made video tutorials that will - no doubt - give you a good insight into the development process. Apart from that, its just a cool thing...

However, it's simply impossible to watch these videos unless you have Windows XP SP2 with Windows Media Player 11 installed. Full stop - take a break. When you try to reach developers used to PHP, Perl etc., shouldn't you make your learning resources available to your intended audience? It seems Microsoft only wants to talk to confident I-buy-every-MS-shit-out-there fanatics that are on the ASP track since so long or complete dummies in web development that have never ever seen something else than Windows.

To be precise: I've got almost anything here: Linux, W2K and Mac OS X. I installed the newest Microsoft Windows Media Player on the latter two (version 9), but those damn videos require newer versions - an unfortunate situation, given the fact that Microsoft will not continue support for Windows Media Player under W2K and OS X.

Don't get me wrong - it's their choice to make the videos only available to those already developing with Windows. But it fits just perfectly into the typical Microsoft picture of a closed community, where you have no choice in the tools you use, where you are bounded to a specific platform and server software for deployment, and where you have to pay for each piece of crappy code extra.

One in four webservers runs MS IIS, 2 of three run Apache. Like with the training video codec situation, Microsoft cripples their own products for 'political' reasons. Besides, what's be so bad about running ASP.net on Apache? Quite frankly, I would have tried it out if ASP.net didn't require me to buy an extra machine and all the MS software just to try it out.

I start to understand why ASP.net has yet failed to build a strong community. Don't get me wrong, there certainly are many ASP.net centric sites on the net - but they're usually driven by companies who even charge you to read the forum. It seems to me ASP.net development is focused on developer teams in companies that are not used to share with the outside world - why should you, when you had to pay for every bit yourself?

Is this really the situation Microsoft strives for? PHP might win hands down against ASP.net - not meaning it's better, simply because people 'like' it more. Microsoft still underestimates that in web development, people DO have other choices.

It's a damn shame that I have now a bad impression of ASP.net not for technical but the same reasons that give a salty taste to every Microsoft product so far: They always piss you off by fooling you in one or another way.

My Django redesign October 24, 2006

My Django redesign

It's been a long while since I last updated my old page. Reason was that it was cumbersome even to change small things, since it did not feature a web interface, but required me to login via SSH.

All in all, it was a technically cool solution but rather impractical from a user's point of view. Now, since Django, the Python Web Framework, is getting so much attention recently, I gave it a try at redesigning my old page. In fact, I didn't just want to redesign, but extend it with a blog application.

I started diving into Django without having any idea of Python at all (I do however have several years of experience in PHP and Perl/mod_perl and other MVC web frameworks).

How it is done

Django installation and configuration is pretty well-covered on the Django project site and I won't repeat it here again. I'll assume you've successfully installed Django and created your own project.

My page has a number of sections (top navigation bar), which are all based on Django's internal django.contrib.flatpages. The blog section, on the other hand, is a custom application. All it needs is the following model:

 from django.db import models class Tag(models.Model): slug = models.SlugField(prepopulate_from=('title',)) title = models.CharField(maxlength=30) description = models.TextField(help_text='Short summary of this tag') def __str__(self): return self.title def get_absolute_url(self): return "/blog/tag/%s/" % self.slug class Admin: list_display = ('slug', 'title',) search_fields = ('title', 'description',) class Meta: ordering = ('title',) class Post(models.Model): slug = models.SlugField(prepopulate_from=('title',), help_text='Automatically built from the title.' ) assoc_tags = models.ManyToManyField(Tag) title = models.CharField(maxlength=80) date = models.DateTimeField(auto_now_add=True) body = models.TextField() image = models.ImageField( 'Attach Image', upload_to='blog', blank=True ) def __str__(self): return self.title def get_absolute_url(self): return "/blog/%s/%s/" % (self.date.strftime("%Y/%b/%d").lower(), self.slug) class Admin: list_display = ('slug', 'title', 'date',) search_fields = ('title', 'body',) date_hierarchy = 'date' class Meta: get_latest_by = 'date' ordering = ('-date',) 

To display the tag list on the right of this page, I used a simple template tag like this:

 from django import template from tsonny.blog.models import Tag class TagListNode(template.Node): def __init__(self, varname): self.varname = varname def render(self, context): context[self.varname] = Tag.objects.all() return '' def do_get_tag_list(parser, token): """ {% get_tag_list as tag_list %} """ bits = token.contents.split() if len(bits) != 3: raise template.TemplateSyntaxError, "'%s' tag takes two arguments" % bits[0] if bits[1] != "as": raise template.TemplateSyntaxError, "First argument to '%s' tag must be 'as'" % bits[0] return TagListNode(bits[2]) register = template.Library() register.tag('get_tag_list', do_get_tag_list) 

To include the "latest news" from other website's RSS feeds, I simply took the aggregator code from djangoproject.com (it's in the Trac repository) and modified it a bit.

To make life easier, the interested reader may also want to download the complete code, ready to use (but without templates, of course).

Debian: Apache1.3 + SSL June 19, 2005

This document describes the setup needed to run Apache with SSL encryption. It is based on a Debian woody/sarge installation, but should work with other Linux/Unix systems as well. The approach shown here is using the command line only. You can use graphical tools such as TinyCA if you like that better.

Requirements

Under Debian, the following packages have to be installed via apt-get:

  • apache-ssl
  • openssl
  • libapache-mod-ssl (will automatically be installed by apache-ssl)

The SSL certification process consists of three basic steps:

  • If not done already, create a certificate authority (CA), which we will use to sign our own certificate.
  • Create a new certificate request
  • Sign the request with our CA to obtain a valid certificate.

Create a certificate authority

The OpenSSL package comes with a default openssl.cnf file under /usr/lib/ssl/openssl.cnf. We will edit the default values slightly, ie. we change the default path from demoCA to ourCA. To do so, copy /usr/lib/ssl/openssl.cnf to /etc/ssl/openssl.cnf and change the line

 dir = ./demoCA 

to

 dir = /etc/ssl/ourCA 

For security reasons, you will have to create the necessary file and directory structure manually. In particular, you have to create the following folders and files:

  • /etc/ssl/ourCA/
  • /etc/ssl/ourCA/index.txt (empty file)
  • /etc/ssl/ourCA/newcerts/
  • /etc/ssl/ourCA/private/
  • /etc/ssl/ourCA/serial (file containing "01" as the first and only line)

We can now tell openssl to create a new certification authority for us:

 openssl req -new -x509 -keyout /etc/ssl/ourCA/private/cakey.pem \ -out /etc/ssl/ourCA/cacert.pem -config /etc/ssl/openssl.cnf 

You will be asked a few questions about the new CA. Just enter information that makes sense and is valid. Also, choose a good passphrase, since you'll have to remember it every time you want to validate and sign a new certificate request.

Issue a certificate request

We are now ready for the interesting part of this tutorial. To create a certificate request, execute

 openssl req -new -keyout newkey.pem -out newreq.pem -days 365 

OpenSSL will again ask you a few questions. Make sure that you enter the hostname of your SSL server as "Common Name". This is very important and things will break if you don't do it.

If everything went fine, this will give you two new files in the directory where you ran this command. The first is our certificate private key and the second file (newreq.pem) is the certificate request for the CA.

There is one obstacle with the private key in the current form: It requires a passphrase to be used. That means, if you want Apache to use this SSL key, you'll have to supply the passphrase at Apache's startup. This is not very handy, for sure. We can however, remove the passphrase by running:

 openssl rsa -in newkey.pem -out nopwkey.pem 

You will be asked for the private's key passphrase. If things went right, you will have a new private key called nopwkey.pem, which is not passphrase protected anymore.

To let a CA sign a certificate request, they need both, our private key and the certificate request. We can combine both into one file by cat'ing them together:

 cat newreq.pem nopwkey.pem > new.pem 

Signing the certificate

The last step consists of the actual signing process. Just issue

 openssl ca -policy policy_anything -out newcert.pem \ -config /etc/ssl/openssl.cnf -infiles new.pem 

in the same directory where your certification request files are stored. You will first be asked for the CA passphrase (now you know why it is important to remember it!) and you can then either sign or reject the certificate.

You should now copy newcert.pem and nopwkey.pem to some convenient place, since Apache will only need those two files to operate in SSL mode.

Apache-SSL configuration

Under Debian, the SSL enabled Apache version has its own configuration file, available under /etc/apache-ssl/httpd.conf. Edit and change or add the following lines:

 SLCertificateFile /path/to/newcert.pem //This is our signed certificate SSLCertificateKeyFile /path/to/nopwkey.pem //This is our unencrypted private key. 

Start Apache-SSL by executing

 /etc/init.d/apache-ssl start