jquery slider to scroll a div with dynamic image sizes

April 22, 2011 by · Leave a Comment 

Usually the class .content-item has the width parameter defined so you can easily set the #content-holder width with the exact size, but what if you want to use all images with different width size ?

This worked for me.

var t = 0;
    $('#content-holder .content-item').each(function() {
        t += $(this).outerWidth( true );
    $('#content-holder').css('width', t + 20);

For the complete script go here

invalid literal for int() with base 10: ” Nginx

April 11, 2011 by · Leave a Comment 

I was doing changes to some pages the other day and I came across to an error when trying to update anything in django admin (these models use ImageField).

invalid literal for int() with base 10: ”

I googled for same issues but none of the fixes were working, until I decide to take a look to my nginx config file since I knew a few days ago I made some modifications. Right away I noticed that the following line was commented :(

#fastcgi_param  CONTENT_TYPE       $content_type;

After activating the line – restarted nginx and everything was back to normal.

django-tracking

March 3, 2010 by · Leave a Comment 

I just finished intalling django-tracking in one of my clients projects in webfaction. Here are my steps.

PYTHONPATH=$HOME/webapps/my_django_app/lib/python2.5 easy_install-2.5 -s $HOME/webapps/my_django_app/bin -d $HOME/webapps/my_django_app/lib/python2.5 django-tracking

This installed django-traking under the my project python path,
you could install it globally with:

easy_install-2.5 -s $HOME/bin -d $HOME/lib/python2.5 django-tracking

The rest is quick, just follow the instructions as in django-tracking.
1) Add tracking to your list of INSTALLED_APPS in settings.py:

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',

'tracking',
)

2) django-tracking Options:
Visitor Tracking
Add tracking.middleware.VisitorTrackingMiddleware to your MIDDLEWARE_CLASSES in settings.py. It must be underneath the AuthenticationMiddleware, so that request.user exists.

Automatic Visitor Clean-Up
If you want to have Django automatically clean past visitor information out your database, put tracking.middleware.VisitorCleanUpMiddlewarein your MIDDLEWARE_CLASSES.

IP Banning
Add tracking.middleware.BannedIPMiddleware to your MIDDLEWARE_CLASSES in settings.py. I would recommend making this the very first item in MIDDLEWARE_CLASSES so your banned users do not have to drill through any other middleware before Django realizes they don’t belong on your site.

Visitors on Page (template tag)
Make sure that django.core.context_processors.request is somewhere in your TEMPLATE_CONTEXT_PROCESSORS tuple. This context processor makes the request object accessible to your templates. This application uses the request object to determine what page the user is looking at in a template tag.

Active Visitors Map

If you’re interested in seeing where your visitors are at a given point in time, you might enjoy the active visitor map feature. Be sure you have added a line to your main URLconf, as follows:

#you must add this even if you are not using Active Visitors Map other wise you might get and error.
from django.conf.urls.defaults import *

urlpatterns = patterns('',
   (r'^tracking/', include('tracking.urls')),  
)

view all available django-tracking settings

Add the following to admin.py to view the data collected in django admin.

from tracking.models import Visitor

class VisitorAdmin(admin.ModelAdmin):
    list_display = ('ip_address','referrer','url','page_views','last_update',)
    ordering = ('last_update',)

admin.site.register(Visitor, VisitorAdmin)

Nginx-Django Webfaction

November 14, 2009 by · 6 Comments 

Struggling with django trying to keep memory usage low in Webfaction, I tried it all

- DEBUG = False
- Caching entire the site
- Serving the static media with apache

basically all the tips I could find in webfaction forum,  till I read some people were recommending to install nginx and it will make your life easier in regards to memory. So I g00gled for anyone having this kind of setup in webfaction and this great article came up. Now all memory problems are solved.

1) First we need to create a new app in the Webfaction control panel I’m naming this for reference wf-app you can name it anything you like. Choose from the drop down menu “new app listening on port” this will give you a custom port which you will use later.

2) We need to create directories in our webapp folder and install Django and Flup (needed for the FCGI support later) so go ahead and ssh into your account and do the following.

cd ~/webapps/wf-app
mkdir -p bin lib/python2.5
PYTHONPATH=lib/python2.5 easy_install-2.5 -d lib/python2.5 -s bin http://www.djangoproject.com/download/1.1.1/tarball/ flup
./bin/django-admin.py startproject your_project

3) Now we need to download and untar the latest stable versions of Nginx, Nginx_UploadProgress_Module and PCRE (for the embeded perl in Nginx). Updated added Open SSL.

wget http://sysoev.ru/nginx/nginx-0.7.61.tar.gz
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.9.tar.gz
wget http://www.openssl.org/source/openssl-0.9.8m.tar.gz (if you want SSL)
wget http://wiki.nginx.org/images/8/83/Nginx_uploadprogress_module-0.5.tar.gz
tar -xzf nginx-0.7.61.tar.gz
tar -xzf pcre-7.9.tar.gz
tar -xzf openssl-0.9.8m.tar.gz
tar -xzf Nginx_uploadprogress_module-0.5.tar.gz

4) Now lets configure, make and install Nginx
Without SSL

cd pcre-7.9
./configure --prefix=/home/username/webapps/wf-app/pcre
cd ../nginx-0.7.61
./configure --prefix=/home/username/webapps/wf-app/ --with-pcre=/home/username/webapps/wf-app/pcre-7.9/ --add-module=/home/username/webapps/wf-app/nginx_uploadprogress_module/

With SSL

./configure --prefix=/home/username/webapps/wf-app/ --with-pcre=/home/username/webapps/wf-app/pcre-7.9/ --add-module=/home/username/webapps/wf-app/nginx_uploadprogress_module/ --with-http_ssl_module --with-openssl=/home/username/webapps/wf-app/openssl-0.9.8k/

let’s say all went well and we have no errors.

make
make install

At this point we should have a working install of Nginx and Django.

Now we have some issues to worry about

  • What happens if the Webfaction support team ever need to reboot the server?
  • What happens if our Django App crashes?

We could solve this by adding a cron job to restart our stack every few minutes but because Nginx doesn’t spawn our FCGI Django process it gets quite complex, and we have no easy way to monitor the status.

The solution as suggested here is to use supervisor to control our server processes and then make sure that we have a cron job to check and restart supervisor.

1) Now go back to webfaction control panel and create a new app listening on port to reserve a port for Supervisor to run on, and make a note of the port number for later.

2) First we need to create a start script for Django so that supervisor can monitor it, use your favorite editor to create a file called runserver.py in your django project directory

/home/username/webapps/wf-app/your_project/runserver.py

with the following content:

#!/usr/local/bin/python2.5
import sys
import os
sys.path.append('/home/username/webapps/wf-app/your_project')
sys.path.append('/home/username/webapps/wf-app/lib/python2.5/django/bin')
sys.path.append('/home/username/webapps/wf-app/lib/python2.5/django')

if __name__ == '__main__':
from flup.server.fcgi_fork import WSGIServer
from django.core.handlers.wsgi import WSGIHandler
WSGIServer(WSGIHandler(),maxSpare=1, maxChildren=1, debug=False).run()

Make it executable

chmod +x runserver.py

3) We also need to change our django settings.py file and change the ROOT_URLCONF to:

ROOT_URLCONF = 'urls'

Because supervisor can only interact with non daemonized processes we need to make a minor change to our nginx.conf file and add the following line right at the begining:

daemon off;

4) Time to install supervisor

easy_install-2.5 supervisor

5) Then create a file called supervisord.conf in your home directory with the following content replace port_number with the number you’ve got when you created the supervisor app. Make sure to replace the values that apply to your environment.

; Webfaction supervisor config file.

[inet_http_server]                          ; inet (TCP) server setings
port=127.0.0.1:your_port_number                    ; (ip_address:port specifier, *:port for all iface)
username=<username>                           ; (default is no username (open server))
password=<password>                                 ; (default is no password (open server))

[supervisord]
logfile=/home/your_username/logs/user/supervisor/supervisord.log         ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=20MB                               ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=4                                 ; (num of main logfile rotation backups;default 10)
loglevel=debug                                       ; (log level;default info; others: debug,warn,trace)
pidfile=/home/your_username/supervisord.pid                                  ; (supervisord pidfile;default supervisord.pid)
nodaemon=false                                      ; (start in foreground if true;default false)
minfds=1024                                         ; (min. avail startup file descriptors;default 1024)
minprocs=200                                        ; (min. avail process descriptors;default 200)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=http://127.0.0.1:your_port_number
username=<username>
password=<password>

[program:nginx]
command=/home/your_username/webapps/wf-app/sbin/nginx -c /home/your_username/webapps/wf-app/conf/nginx.conf
autostart=true
autorestart=true
redirect_stderr=true
exitcodes=0

[fcgi-program:your_project]
socket=unix:///home/your_username/webapps/wf-app/your_project/django.sock
process_name=%(program_name)s_%(process_num)02d
numprocs=1
command = python2.5 /home/your_username/webapps/wf-app/your_project/runserver.py
environment=DJANGO_SETTINGS_MODULE=settings
autostart=true
autorestart=true
redirect_stderr=true

Assuming that all values have been replaced properly we could now start supervisor – however we would still suffer from the problem of supervisor not being started on a reboot. Let’s fix that – create a file called start_supervisor.sh in your home directory with the following content:

#! /bin/bash

NAME=supervisord
SUPERVISORD=/home/your_username/bin/supervisord
SUPERVISORCTL=/home/your_username/bin/supervisorctl
PIDFILE=/home/your_username/supervisord.pid
OPTS="-c /home/your_username/supervisord.conf"
PS=$NAME
TRUE=1
FALSE=0

test -x $SUPERVISORD || exit 0

export PATH="${PATH:+$PATH:}/usr/local/bin:/usr/sbin:/sbin:/home/your_username/bin:"

isRunning(){
pidof_daemon
PID=$?

if [ $PID -gt 0 ]; then
return 1
else
return 0
fi
}

pidof_daemon() {
PIDS=`pidof -x $PS` || true

[ -e $PIDFILE ] && PIDS2=`cat $PIDFILE`

for i in $PIDS; do
if [ "$i" = "$PIDS2" ]; then
return 1
fi
done
return 0
}

start () {
echo "Starting Supervisor daemon manager..."
isRunning
isAlive=$?

if [ "${isAlive}" -eq $TRUE ]; then
echo "Supervisor is already running."
else
$SUPERVISORD $OPTS || echo "Failed...!"
echo "OK"
fi
}

stop () {
echo "Stopping Supervisor daemon manager..."
$SUPERVISORCTL shutdown ||  echo "Failed...!"
echo "OK"
}

case "$1" in
start)
start
;;

stop)
stop
;;

restart|reload|force-reload)
stop
start
;;

esac

exit 0

We’ll use this script to start and stop supervisor so we need to make it executable.

chmod +x ~/start_supervisor.sh

Now we need to add it to a cron job to make sure that it runs every few minutes (the script checks that supervisor is running so won’t start multiple instances of it) this will allow us to be back up and running a few minutes after the server comes back up.

crontab -e

Assuming you know the basics of VIM add the following, this will run the script every 10 min.

*/10 * * * * ~/start_supervisor.sh start

You should now be running on supervisor and your site should be up.
If you’d like to be able to see that status of your processes then mount the supervisor app we created at the start on a subdomain such as status.mydomain.com and then browse to that url (you’ll need to enter the user and password that you put into the supervisor.conf file)

Supervisor Screenshot

supervisor

supervisor

Here is how my nginx.conf looks like, and how to add multiple sites.

daemon off;
worker_processes  1;

events {
worker_connections  1024;
}

http {
include       mime.types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;

server {
listen       your_custom_app_port_number;
server_name  example.com;

    location / {

    fastcgi_pass   unix:/home/your_username/webapps/wf-app/your_project/django.sock;

    fastcgi_param  CONTENT_TYPE     $content_type;
    fastcgi_param  CONTENT_LENGTH   $content_length;
    fastcgi_param  PATH_INFO        $fastcgi_script_name;
    fastcgi_param  QUERY_STRING     $query_string;
    fastcgi_param  REQUEST_METHOD   $request_method;
    fastcgi_param  SERVER_NAME      $server_name;
    fastcgi_param  SERVER_PORT      $server_port;
    fastcgi_param  SERVER_PROTOCOL  $server_protocol;

    }
}
# To use SSL you need to create another <tt>listening port app</tt>
    server {
        listen       custom_app_listening_port;
        server_name  domain.com;
     
        ssl                  on;
       # I created the folder cert under the app and put the certificate files there.
        ssl_certificate      /home/username/webapps/wf-app/cert/mycert.cert;
        ssl_certificate_key  /home/username/webapps/wf-app/cert/mycert.key;
        ssl_session_timeout  5m;

        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        access_log /home/username/webapps/wf-app/logs/access.log;
        error_log /home/username/webapps/wf-app/logs/error.log;
       
        location / {
         #   root   html;
         #  index  index.html index.htm;
            fastcgi_pass   unix:/home/username/webapps/wf-app/your_project/django.sock;

            fastcgi_param  CONTENT_TYPE     $content_type;

            fastcgi_param  CONTENT_LENGTH   $content_length;
            fastcgi_param  PATH_INFO        $fastcgi_script_name;
            fastcgi_param  QUERY_STRING     $query_string;
            fastcgi_param  REQUEST_METHOD   $request_method;
            fastcgi_param  SERVER_NAME      $server_name;
            fastcgi_param  SERVER_PORT      $server_port;
            fastcgi_param  SERVER_PROTOCOL  $server_protocol;
           
        }
    }
# Setting up project2, project3, project4, etc..
# Make sure to add another [fcgi-program:you_project2] with the proper values in supervisor config file
# Also don't forget to add  runserver.py with the proper values as well.
#    server {
#        listen       your_custom_app2_port_number;
#        server_name  example2.com;

#        location / {

#            fastcgi_pass   unix:/home/your_username/webapps/wf-app/you_project/django.sock;

#            fastcgi_param  CONTENT_TYPE     $content_type;
#            fastcgi_param  CONTENT_LENGTH   $content_length;
#           fastcgi_param  PATH_INFO        $fastcgi_script_name;
#            fastcgi_param  QUERY_STRING     $query_string;
#            fastcgi_param  REQUEST_METHOD   $request_method;
#            fastcgi_param  SERVER_NAME      $server_name;
#            fastcgi_param  SERVER_PORT      $server_port;
#            fastcgi_param  SERVER_PROTOCOL  $server_protocol;
#        }
#    }
}

Thanks Richard Cooper for this tutorial, great work!