C++11 vs Python – not quite there yet

Although not exactly fair, while reading the C++ Primer book to refresh my C++11 knowledge during Christmas break (OK, after kids went asleep), I came across the example given for the new C++11 features (lambdas), strings and STL usage in chapter 16, which does nothing more than counting words in a text file. This is a rather classical example and I happen to have it as a part of the Python course I give to my colleagues. Of course I couldn’t hold myself from comparing C++11 and Python as C++11 actually tries to get higher level and closer to languages like Python. Here is what I’ve got.
Continue reading “C++11 vs Python – not quite there yet”

Scan and create multipage .pdf files from .jpeg

Recently I needed to scan and mail multi-page documents. I have a rather simple scanner that can produce descent .jpeg files, but when combining into a document it sucks. Therefore I prefer to scan in 100% quality and then produce documents depending on my needs.

E.g. hereby some commands to put two scanned pages into a single .pdf document with 75% quality (reducing ~2.3MB images into ~800KB):


convert -quality 75 page_1.jpeg page_1_75.jpeg
convert -quality 75 page_2.jpeg page_2_75.jpeg
convert -page A4 -compress jpeg page_1_75.jpeg page_2_75.jpeg document.pdf

One-liner to rename files in bash

To rename many files from one pattern to another use e.g.

for i in *.jpeg; do mv $i ${i//exampel/example}; done

Some useful patterns:

${parameter//substring/replacement}
${parameter##remove_matching_prefix}
${parameter%%remove_matching_suffix}
${parameter:offset}
${parameter:offset:length}
${parameter:offset:length}

To check whether the parameter is null:

${parameter:+use this if param is NOT null}
${parameter:-use this if param is null}
${parameter:=use this and assign to param if param is null}
${parameter:?show this error if param is null}

Joomla! upgrade

Unbelievable that such a simple thing as an upgrade to a newer version of CMS may cause any headache these times. Recently I have received a warning message from my host (lunarpages.com) that I still use an old version (1.7.2) of Joomla! for my company site, while a newer version is available. I have tried to follow official upgrade procedures for about an hour without success, resulting in wrong layouts and half-working admin functionality, and finally ended up just downloading the complete package for Joomla_3.1.5-Stable-Full_Package.zip and simply unzipping it to the current installation folder. That did the trick (well, almost) leaving me with the similarly popular warning message

Joomla upgrade warning Error
Your host needs to disable magic_quotes_gpc to run this version of Joomla!

After some googling around the following solution worked. I have created two files as shown below in the folder with Joomla! installation (so not affecting other websites) and that did the trick.


[php.ini]
magic_quotes_gpc = Off
session.save_path = "/home/<user>/tmp"


[.htaccess]
/home/<user>/www/<site>/php.ini

Enjoy!

Configuring Django under wsgi

A small reminder for settings up Django under wsgi. Apparently the following snippet helps getting the path correct avoiding the dreadful


self.load_middleware()
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/core/handlers/base.py", line 39, in load_middleware
for middleware_path in settings.MIDDLEWARE_CLASSES:
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/utils/functional.py", line 184, in inner
self._setup()
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/conf/__init__.py", line 42, in _setup
self._wrapped = Settings(settings_module)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/conf/__init__.py", line 95, in __init__
raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'xxx.settings' (Is it on sys.path?): No module named xxx.settings

messages from Apache (well, instead of ‘xxx’ your project name will be mentioned of course).

The fix
import sys

# Correct path.
app_path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..'))
if app_path not in sys.path:
sys.path.append(app_path)

For completeness, the sites-enables/xxx looks like

WSGIPythonPath /var/www/path/to/project

<VirtualHost *:80>
DocumentRoot /var/www/path/to/project
ServerAdmin admin@example.com
ServerName my.example.com

Alias /static/ /var/www/path/to/project/

Order deny,allow
Allow from all

WSGIDaemonProcess project_name
WSGIScriptAlias / /var/www/path/to/project/wsgi.py

</VirtualHost>

Happy Djangoing!

UPDATE: when multiple Django applications are configured under Apache apparently a request could be routed to the Apache instance hosting wrong application. The server will not load application and Apache log files would show:


Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/core/handlers/wsgi.py", line 219, in __call__
self.load_middleware()
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/core/handlers/base.py", line 39, in load_middleware
for middleware_path in settings.MIDDLEWARE_CLASSES:
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/utils/functional.py", line 184, in inner
self._setup()
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/conf/__init__.py", line 42, in _setup
self._wrapped = Settings(settings_module)
File "/usr/local/lib/python2.7/dist-packages/Django-1.4.3-py2.7.egg/django/conf/__init__.py", line 95, in __init__
raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'xxx.settings' (Is it on sys.path?): No module named xxx.settings

basically failing to load settings from the wrong application. More on this topic in this blog post, but the fix seem to be specifying WSGIDaemonProcess per application.

Setting up Dango i18n, i10n

Anything related to i18n/i10n subject seem to be somehow quirkier than it looks at first glance. Python (2.x) itself and handling of unicode is a story apart.

This time I was looking into building a small website that has to provide UI in different languages. As this is one of the things you want to have right away I’ve started experimenting with adding i18n and i10n support.

First step is easy, the settings.py already had proper settings. Then for .py files it is rather straightforward to add e.g. (for forms):


from django.utils.translation import ugettext_lazy as _
...
city_name = forms.CharField( required = False, label = _('City:'))

For the .html files something like


{% load i18n %}

{% trans "Hello there!" %}

Then create under project folder folder ‘conf/locale’ (if you don’t do this it will complain), and then run

django-admin.py makemessages -l ru

Edit the resulting django.po file, add translations to your messages.

Warning: don’t forget to edit the following field, which comes EMPTY first, even while you have given it a parameter! Otherwise this file will be not used properly.

"Language: ru\n"

Then compile your nice and shiny translations:

django-admin.py compilemessages

Now we get all messages available. At least they should. But there is another trick missed in the Django documentation/tutorials: you HAVE TO specify the location of the message files explicitly in your settings.py otherwise your texts will continue coming up in default (en) language no matter how hard you try. E.g.:

LOCALE_PATHS = (
os.path.join(os.path.dirname(__file__), 'conf', 'locale').replace('\\','/'),
)

Well, after all this it seems to work. But it costs quite some searching and poking around to come to this. I can imagine after several rounds this becomes obvious, but you don’t get any errors, warnings, whatsoever, it just does not what you want it to do. Well, I hope it will do it for you now :).

Happy Djangoing!