Category Archives: Uncategorized

Django Themes (or where to put base.html?)

The Wrong Way

I used to create a new directory to hold common templates like “base.html”, and add it TEMPLATES_DIR in the settings.py file:

TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates') ,)

But in most cases the “base.html” would need to use CSS, JS, and image files to be functional, so I changed the url routing to access them (from the DEBUG mode only), something like:

$ vi apps/urls.py
:
# Serve Static Files 
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += patterns('django.views.static',
        url(r'^(?P<path>(js|css|img)/.*)$', 'serve', {'document_root':  settings.BASE_DIR+'/../www'}),
        )

This setup isn’t ideal for many reasons:

  • I had to modify settings.py and urls.py with complicated settings.
  • Theme design span multiple directories, and it isn’t self contained.
  • Switching the design is complicated, and include many changes.

Django Simple Themes

Nowadays I create a new Django application e.g. “my_theme” to hold my “base.html” template and all needed static files (CSS, JS, Images, etc …).

./manage.py startapp my_theme

Then add it to INSTALLED_APPS:

INSTALLED_APPS = (
    # django core apps ...
    'my_theme',
    # other apps ...
)

The directory structure for my new app looks like this:

my_theme/
    templates/
        base.html
    static/
        my_theme/
            css/
            js/
            img/

and from my “base.html” (or any other template) I could access the static file using the static tag:

{% load staticfiles %}
<img src="{% static "my_theme/img/logo.png" %}" />

I don’t even need to change the “urls.py” file to access the static file, since the development server (i.e. ./manage.py runserver) already knows how to find them.

But for production I have to define:

STATIC_ROOT = os.path.join(BASE_DIR, '../www/static')

and run:

./manage.py collectstatic --noinput

New Theme

By having all theme files inside an application I can start new theme by copying “my_theme” to something like “new_theme” and replace it in the INSTALLED_APPS in the settings.py.

What about uploaded files?

To access uploaded file from development server you need to define both MEDIA_URL and MEDIA_ROOT and change your “urls.py”:

$ vi apps/urls.py
:
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Source: Serving files uploaded by a user during development

Sample Theme

You can download my sample theme from:
https://github.com/rayed/django_theme

Protect your Server with Fail2Ban

Fail2ban is a program that scan your log files for any malicious behavior, and automatically block the offending IP.

The default Fail2ban installation on Ubuntu will protect ssh, but in this article I will show how to protect against WordPress comment spammers too, to slow them down.

Installation & Configuration

# Install fail2ban
$ sudo apt-get install fail2ban

# Copy default config to custom config
$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Add your own IPs so they never get blocked
$ sudo vi /etc/fail2ban/jail.local
:
ignoreip = 127.0.0.1/8 10.0.0.0/8 192.168.1.5
:

# restart it
$ sudo service fail2ban restart

Fail2ban is now configured and running.

You can use the following commands to inspect and trouble shoot its operation:

# fail2ban usually add new rules to your IPTables
$ sudo iptables -L

# You can check the status of specific rules using the command:
$ sudo fail2ban-client status ssh

# and of course check log to see if it is working:
$ sudo tail -f /var/log/fail2ban.log 

Protecting WordPress Comments

By default fail2ban protect many ssh but let’s assume you want to protect WordPress from spam bots trying to post comments on your blog.

First we add a filter to catch the attempts by creating new filter file named “/etc/fail2ban/filter.d/wordpress-comment.conf”:

$ sudo vi /etc/fail2ban/filter.d/wordpress-comment.conf 
#
# Block IPs trying to post many comments
#
[Definition]
failregex = ^<HOST> -.*POST /wordpress/wp-comments-post.php

Then we create a new JAIL by adding the following to “jail.local” file:

$ sudo vi /etc/fail2ban/jail.local
:
:
[wordpress-comment]
enabled = true
port = http,https
filter = wordpress-comment
logpath = /var/log/apache2/*access*.log
bantime = 3600
maxretry = 5

Then restart fail2ban using:

sudo service fail2ban restart

كيف تنشئ موقع انترنت مجانا

هل تملك عنوان بريد الكتروني تحت gmail او hotmail؟ ماذا لو بحثت عن اسمك هل ستظهر صفحتك في تويتر او فيس بوك؟

لماذا لا تقوم بحجز اسم نطاق خاص بك مثل www.rr.sa ويكون عنوانك البريدي هو rayed@rr.sa، وبالمجان ايضاً.

نحتاج للخدمات ما يلي:

  1. تسجيل اسم النطاق domain: المركز السعودي لمعلومات الشبكة (SaudiNIC) يقدم نطاق تحت العنوان “.sa” مجانا.
  2. استضافة اسم النطاق: موقع ClouDNS يقدم خدمة استضافة النطاقات مجانا. (نعم تسجيل النطاق شئ واستضافته شئ آخر) اتمنى لو يقدم المركز السعودي هذه الخدمة مجانا ايضاً.
  3. استضافة موقع الويب، والخيارات هنا عديدة ما اعرفها هي:
    1. Github Pages مع اسم نطاق مخصص Setting up a custom domain with GitHub Pages
    2. موقع tumblr.com مع اسم نطاق مخصص Using a custom domain name
  4. استضافة البريد: موقع ClouDNS يقدم خدمة استقبال واعادة ارسال البريد Email Forwarding لثلاث حسابات مجانا.

Accelerating Postgres connections with PgBouncer

PgBouncer is a lightweight connection pooler for PostgreSQL, connection pooling makes Postgres connection much faster, which is important in Web applications.

Here I will explain the steps I used to configure it under Ubuntu 14.04 LTS.

Step 1: We would configure users allowed to connect to PgBouncer:

$ sudo vi /etc/pgbouncer/userlist.txt
"rayed"  "pgbouncer_password_for_rayed"

Step 2: We configure databases PgBouncer will pool for, and how PgBouncer will authenticate user:

$ sudo vi /etc/pgbouncer/pgbouncer.ini
:
[databases]
rayed = host=localhost user=rayed password=postgres_password_for_rayed
:
auth_type = md5
;auth_file = /8.0/main/global/pg_auth
auth_file = /etc/pgbouncer/userlist.txt


The default value for “auth_type” is “trust” which means a system user “rayed” will be allowed to connect to Postgres user “rayed”, I change to “md5″ to force a password checking from the file “/etc/pgbouncer/userlist.txt”.

Step 3: We will allow PgBouncer to start:

$ sudo vi /etc/default/pgbouncer 
:
START=1
:


The default value is “0” which means don’t start PgBouncer ever, it is a way to make sure you know what you are doing :)

Step 4: Starting pgBouncer:

$ sudo service pgbouncer start

Step 5: Test the connection, by default “psql” connect using port “5432”, and pgBouncer use “6432”, so to test a pgBouncer connection we would use the following command:

$ psql -p 6432 


If you get “Auth failed” error make, make sure the password you entered is the one you typed in step 1, if the command doesn’t ask for password try it with “-W” option, e.g. “psql -p 6432 -W”.

Translation in Django

Settings

In your project “settings.py” setup the following values:

LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
    )
LANGUAGE_CODE = 'ar'

Here we defined the location of our translation files, by default Django will look for it under application directories under “locale” directory, but here we define it for the whole project.

The LANGUAGE_CODE line define a fixed translation to Arabia “ar”.

Source Code

For Python source code Django uses “ugettext” function aliased as “_” (underscore) to translate text strings:

from django.utils.translation import ugettext as _
from django.http import HttpResponse
from django.shortcuts import render

def page1(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)

def page2(request, template_name='index.html'):
    return render(request, template_name)

Template

Inside Django templates, Django uses trans template tag with the text to translate, don’t forget to load the tag using “{% load i18n %}”

{% load i18n %}

<h1>{% trans "Hello World" %}</h1>

Commands

After preparing the code we the following steps:

  • Collect translation string using “django-admin.py makemessages” command.
  • Edit the translation file “django.po”
  • Compile the translation to “django.mo”.

$ cd project_home

# Make the "locale" directory to store translation data
$ mkdir locale

# scan the project for translation strings
$ django-admin.py makemessages -l ar

# Edit the translation file and add your translation
$ vi locale/ar/LC_MESSAGES/django.po
:
msgid "Hello World"
msgstr "مرحبا يا عالم"
:

# compile django.po to django.mo
$ django-admin.py compilemessages

That’s it, you should be able to see your applications translated!

Graph you Data and Email It

I have a new website and I want to know the number of new signup every day, so I wrote a small script new_users.sh that will print the number of new signups today.

$ new_users.sh
280

I ran this script daily using a cron job and add it to user.dat file:

0 0 * * *   /home/rayed/bin/new_users.sh >> /home/rayed/var/user.dat

After few days the file will look like this:

#Users
50
104
202
298
290
289
291
310
311
280

I could send this file daily and read, but it wouldn’t give a good picture of how new user signup is changing by time, so the next logical step is to convert it to a graph for easier understanding.

I used gnuplot to convert the textual data to a graph, and automatically email it to me.

So I wrote the following small script, email_graph.sh:

#!/bin/sh

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

from_email="rayed@example.com"
to_email="rayed@example.com"

plot="
set terminal png \
	medium \
	size 800,400;
plot  'user.dat' with lines;
"

img_base64=`echo $plot | gnuplot | base64`

sendmail $to_email <<EOF
From: <$from_email>
To: <$to_email>
Subject: Plot and Inline image from CLI
Mime-Version: 1.0
Content-Type: multipart/related; boundary="boundary-example"; type="text/html"

--boundary-example
Content-Type: text/html; charset="US-ASCII"

This email sent from Linux CLI:
<br>
<IMG SRC="cid:plot_image_1" ALT="Plot">

--boundary-example
Content-ID: <plot_image_1>
Content-Type: IMAGE/PNG
Content-Transfer-Encoding: BASE64

$img_base64

--boundary-example--
EOF

When you run it you will receive the following graph on your email:

plot

Of course you can edit the email HTML template, add new graph, or do whatever you like to customise it.

I hope you find it useful.

Free Electronics Video Courses

PyroElectro have decent and recent courses on electronics that cover different fields.

Each course is 10 videos ranging from 7 to minutes, no prior knowledge to electronics needed.

Currently they provide 4 courses:

They also have 2 more courses planned:

  • FPGA
  • Sensor

Courses are free so check them out:
PyroEdu

Thank you PyroEdu for the great courses, and thank you for you Kickstarter supporter who make it happens.