Posts

Showing posts from May, 2013

Mayan - An Electronic Documents Management System

Image
I just deployed an electronic documents management system (e-DMS) named Mayan. Mayan is based on Django framework. And it's just great!

- Mayan's official website : http://www.mayan-edms.com/

- Source code repo: https://github.com/rosarior/mayan

- Documentations: https://mayan.readthedocs.org/en/latest/

Mayan has so many features which are so awesome: optical characters recognition, tagging, ACL, revisions...

Noted: if you want to make a specific document can only be able to see by its creator and admin, please follow the instructions: https://mayan.readthedocs.org/en/latest/topics/permissions.html

Here are some screenshots of the dashboard:

Django best practices

Here is an great online book about Django Best Practices: http://lincolnloop.com/django-best-practices/index.html

Django + Gunicorn + Nginx + Supervisor

Here is an example to run and control a web application in a production server:

1. Django: our web development platform - https://www.djangoproject.com/

I have a django project located at '/home/projects/my_project/'

2. Gunicorn: the Python WSGI HTTP server, I use it to run our web application - http://gunicorn.org/

I will create a bash shell to run the gunicorn server at port 8000inside themy_envvirtual environment, named gunicorn.sh, place it inside the root dir of my django project (/home/projects/my_project/gunicorn.sh):

Fix error: Geany tried to access the Unix Domain socket of another instance...

If you open geany and get this error:

"Geany tried to access the Unix Domain socket of another instance running as another user. This is a fatal error and Geany will now quit."


Try this solution:

In your home directory go to  .config/geany  and delete the  geany_socket  file and try again.

Upgrade to Ubuntu 13.04 - Fix ImportError in Virtualenv

1. The ImportError: cannot import name MAXREPEATappears inside a virtualenv environment when I run the command python manage.py runserver,after I upgraded my Ubuntu from 12.10 to 13.04. The problem was that Ubuntu 13.04 use python 2.7.4. That makes conflict with the Python version of thevirtualenv

It can be fixed easily by entering the following command:

cp /usr/bin/python /path/to/my/env/bin/




2. ImportError: No module named _sysconfigdata_nd
appears when create a new virtualenv environment: $ virtualenv /.venv/new_env
Fix by create a softlink of module _sysconfigdata_nd.py in python2.7 dir:


cd /usr/lib/python2.7 sudo ln -s plat-x86_64-linux-gnu/_sysconfigdata_nd.py .

MariaDB + Virtualenv + Python

Install dependencies sudo apt-get install libmariadbclient-dev
sudo apt-get build-dep python-mysqldb
Inside a virtualenv environment, Install MySQL-python with pip/virtualenv
pip install -E default/ MySQL-python

Handle uploaded file in Django

Image
Here is the case: we want to import data to our database from a data file (csv, excel...). For example, we want to import user accounts from a csv file:

data.csv:


remember to save its format as following:


- We have the Account model which data will be imported from the above csv file:  my_app.models.py:

Messages notification in Django

Firstly, read the documentation carefully: https://docs.djangoproject.com/en/dev/ref/contrib/messages/
Following instructions in the documentation to enable messages framework and use it in your django application.

Example:

views.py:

...
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib import messages
from my_app import forms

def my_view(request):
    if request.method == 'POST':
        my_form = forms.MyForm(request.POST, request.FILES)
        if my_form.is_valid():
            my_form.save()
messages.add_message(request, messages.INFO, "Success")
        else:
messages.add_message(request, messages.ERROR, "Fail")
    else:
        my_form = forms.MyForm()

    return render_to_response('my_templatle.html', locals(), context_instance=RequestContext(request))
...

my_template.html:
...

{% if messages %} <ul class="messages"> {% for message in messages %} <li{% if message.tags %}…

Some tips on python's subprocess module

Here is a weird case I faced when using Subprocess module, or because I do not know deep enough about it:

As you knew, we can execute terminal shell script by calling subprocess: for example, we want to archive all of the pdf file to a tar ball, and delete all of pdf file after that:

>>> import subprocess
>>> tar_path = "/home/projects/mytar.tar.gz"
>>> files_path = "/home/projects/*.pdf"
>>> command = ["tar", "-cvvf", tar_path, files_path, "--remove-files"]
>>> subprocess.call(command)

But, those above command will add all pdf files including their path to the tar ball.

I found a solution, and it's pretty easy: instead of declaring command as a list, stating it as a string of command

>>> command = 'tar -cvvf ' + tar_path + ' ' + files_path + ' --remove-files'
>>> subprocess.call(command, shell=True)

(Be careful with 'shell=True')

Downloading a file in Django

Creating a view in Django to download a certain file is pretty easy. Actually the HttpResponse object will do a lot of works for us, and the only thing we need to do is to tell django what is the type of your file which will be returned:

For example, I want to create a view which help user download a pdf file:
views.py:

from django.http import HttpResponse

def download_pdf(request):

    pdf_file = open('/path/to/pdffile.pdf', 'r')
    response = HttpResponse(pdf_file, content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename=mypdf.pdf'

    return response

The content_type parameter is the mimetype of your file.

Generate PDF document from SVG template in Django with Inkscape

In the last blog post, I show how to convert a svg vector image to a pdf file using Inkscape command line tool. We will go one step further, generate pdf document with provided data and SVG template in Django.

For example, we have a svg template which contains some tokens such as "{{username}}", "{{blah}}":

1/ open the svg template, get its content (it's xml), and close it.

svg_file = open("/path/to/data.svg", 'r')
svg_content = svg_file.read()
svg_file.close()

2/ Process content of the svg: replace pre-defined token (e.g. '{{username}}' ) with your data (e.g superman)

new_content = svg_content.replace("{{username}}", "superman")

If you pass variable to replace, make sure it is a string, not an Unicode object:

new_content = svg_content.replace("{{username}}", str(myusername))


3/ Create a new file with '.svg' extension (e.g data.svg), then write the processed data to that file

4/ Using the Inkscape comma…

Convert SVG to PDF in Django with Inkscape

We can convert a SVG to PDF file using the following command line provided by Inkscape Vector Graphics Editor:

$ inkscape -z -C -A /path/to/drawing.pdf -f /path/to/drawing.svg

Convert drawing.svg to drawing.pdf, using the entire page (option -C), and NOT using any GUI (-z).

With subprocess python module, we will take advantage of that tool in python:


>>> command = ["inkscape", "-z", "-C", "-A", "/path/to/drawing.pdf", "-f", "/path/to/drawing.svg"]
>>> subprocess.call(command)



Awesomeness!!1

Control your Windows machines through SSH and Paramiko

1. On the Windows machine:

- Install SSHD using Cywin: check http://www.howtogeek.com/howto/41560/how-to-get-ssh-command-line-access-to-windows-7-using-cygwin/

- Assuming that you create a user name genius with administrator permission, including ssh access.

2. On the other machine which installed python and paramiko module:
Before going further, I prefer you read the following article carefully about paramiko and its capability: jessenoller.com/blog/2009/02/05/ssh-programming-with-paramiko-completely-different

Write the client class which will connect to ssh server (the Windows) and execute command from that server for you, ssh_client.py:

Running multiple Django Projects on a same machine

You only need to do 2 things:

1. Run those Django projects on different ports

2. Set different session cookie names for them. Example:

- Project1: settings.py:
SESSION_COOKIE_NAME = 'project1'

- Project2: settings.py:
SESSION_COOKIE_NAME = 'project2'


In addition, if your Django servers are under a nginx reverse proxy:

Using jQuery Cookie to store state of an element

This is just an amazing jQuery plugin to manipulate cookies: https://github.com/carhartl/jquery-cookie#readme

The plugin is so awesome because it helped me to get rid of the complicated and repeated line of code I use to return to the template to render state of an element, (e.g the current selected menu item). I was use something stupid like:

views.py:

...
def my_view(request):
      selected_nav = 'First menu'
....

my_template.html: I then get the return value and choose which menu is in the selected state:

...

<script type="text/javascript">
console.log("{{ selected_nav }}");
jQuery("#nav a").each(function(){ jQuery(this).removeClass("selected"); });
jQuery("#nav a:contains('{{ selected_nav }}')").addClass("selected");
</script>

...

I thought about session and cookie, It was really annoying when have to write to the session the value I want whenever I define a view. My code was a mess.

Today, I found the j…

Firefox OS Simulator add-on review

Image
I'm so excited right now to write apps for Firefox OS, the hottest mobile operating system of Mozilla.

- Everything is here: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS
The only phone maker right now which produces phones that runs Firefox OS is Geekphone (a Spain company, http://www.geeksphone.com/), but all of the there Firefox OS powered phones were sold old in just a couple of hours after launch. So, I and so many other fan-boy all over the world cannot have a chance to buy it. So, the only thing I can do right now is write apps and test it on the Simulator.
These are screenshots of the Simulator add-on (Firefox browser, of-course):

Cloning Django model instance

As you read the Django's documentation, you can easily copy/clone a model isntance as simple as set the pk of the instance to None. Here is the re-usable function:




Noted:
The above method will not clone many_to_many field values of the old model instance. We have to do it like this:

...

# get values of the many_to_many fields of the old model before cloning it
# because after cloning, the old model will actually be the new one
my_m2m_field_value = old_obj.my_m2m_field.all()

# clone a new model instance
new_obj = clone_model_instance(old_obj)
new_obj.my_m2m_field = my_m2m_field_value
new_obj.save()

...

Live switching forms in Django with jQuery

I want to change the rendered form when I select type of the form. So, I use the following solution:

- Whenever user click to select a type (radio buttons), use jQuery to make an ajax call to write to the session the current selected type.
- In the view code, get the current selected type from the session, create the form of the current selected type, and return to the template.


For example, I have 2 type: teacher, and student. Teacher and Student form have different input fields:



Pseudo-interactive shell using paramiko python module

Just taking note a very interesting example in using paramiko of Jesse Noller (http://jessenoller.com/blog/2009/02/05/ssh-programming-with-paramiko-completely-different)

Query public information of a Facebook page

I will base on this article: http://bitsofpy.blogspot.com/2010/04/in-my-cosc-lab-today-few-students-were.html to make a query to Facebook Graph API to get public information of my fanpage :


For more options, take a look at Facebook developers documentation: http://developers.facebook.com/docs/reference/api/page/




Authenticate user via LDAP in Django

To authenticate your user via a LDAP server, we need:

- python-ldap module: install this before install django_auth_ldap:

$ sudo apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev $ pip install python-ldap

- django_auth_ldap module: http://pythonhosted.org/django-auth-ldap/


Add the following settings to your Django settings.py:

########################################################################
# LDAP Authentication
########################################################################
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, PosixGroupType
#AUTH_LDAP_START_TLS = True
AUTH_LDAP_GLOBAL_OPTIONS = {
ldap.OPT_X_TLS_REQUIRE_CERT: False,
ldap.OPT_REFERRALS: False,
}
# Baseline configuration.
AUTH_LDAP_SERVER_URI = "ldap://my.ldap.domain"
AUTH_LDAP_BIND_DN = "cn=admin,dc=my,dc=ldap,dc=domain"
AUTH_LDAP_BIND_PASSWORD = "myP@ssw0rd"
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=Users,dc=my,dc=ldap,dc=domain", ldap.SCOPE_S…

Using facebox with jwysiwyg

Image
Recently I worked on a project which is required me to create an interface for emailing. I decided to use an ajax form, and I found facebox which is initial made by defunkt (founder of github): https://github.com/defunkt/facebox. I folked and modified facebox to fit my project's needs: https://github.com/dangtrinh/facebox.

All I have to do is apply the power of jwysiwyg library (https://github.com/jwysiwyg/jwysiwyg) to apply the rich format text-editor to the textarea:

facebox.js:

...