2014-12-30

How Django shows the “It worked!” page?

If you do the following, you will see a “It worked!” page at http://127.0.0.1:8000

$ django-admin.py startproject myproject
$ python manage.py runserver

Let's find out how it is done.

First search the django package to find the phrase “It worked!”. Assuming you are at the root of the django package:

$ grep -ri "it worked!" --include=*.py .
./views/debug.py:  <h1>It worked!</h1>

Look into debug.py and you will see “It worked!” is defined in the string “DEFAULT_URLCONF_TEMPLATE”.

“DEFAULT_URLCONF_TEMPLATE” is used in a module level function “default_urlconf()” in the same file.

The “default_urlconf()” function is called by another module level function “technical_404_response()” in the same file.

Portion of “technical_404_response() is listed below:

    try:
        tried = exception.args[0]['tried']
    except (IndexError, TypeError, KeyError):
        tried = []
    else:
        if (not tried # empty URLconf
            or (request.path == '/'
                and len(tried) == 1 # default URLconf
                and len(tried[0]) == 1
                and getattr(tried[0][0], 'app_name', '') == 
                        getattr(tried[0][0], 'namespace', '') == 'admin')):
            return default_urlconf(request)

You can see that it checks for the special case of hitting the root url “/” and filtering out the admin site.

Let's do a search on technical_404_response():

$ grep -ri "technical_404_response" --include=*.py .
./views/debug.py:def technical_404_response(request, exception):
./contrib/staticfiles/handlers.py:   return debug.technical_404_response(request, e)
./core/handlers/base.py:             response = debug.technical_404_response(request, e)

The relevant file is “base.py”. In the definition of class BaseHandler(object) in base.py, if the DEBUG setting is True, then it will call technical_404_response() and eventually returns the “It worked!” page, as illustrated in the code fragment below.

        except http.Http404 as e:
            logger.warning('Not Found: %s', request.path,
                        extra={
                            'status_code': 404,
                            'request': request
                        })
            if settings.DEBUG:
                response = debug.technical_404_response(request, e)

2014-12-23

How to install a python package for one particular webapp in WebFaction

Both of the following examples are based on a Django 1.7 / Python 3.4 app.

Example 1: ReportLab
$ pip3.4 install --user -U setuptools
$ cd ~/webapps/APP
$ PYTHONPATH=$PWD/lib/python3.4 pip3.4 install \
  --install-option="--install-scripts=$PWD/bin" \
  --install-option="--install-lib=$PWD/lib/python3.4" \
  reportlab==3.1.8

$ python3.4 manage.py shell
>>> import reportlab
>>> reportlab.__file__ # to verify
Example 2: django-taggit
$ pip3.4 install --user -U setuptools
$ cd ~/webapps/APP
$ PYTHONPATH=$PWD/lib/python3.4 pip3.4 install -t $PWD/lib/python3.4 \
  django-taggit

$ python3.4 manage.py shell
>>> import taggit
>>> taggit.__file__ # to verify
The exact method to use depends on how the package is built.

2014-12-16

Ever wondering what does {% load staticfiles %} mean?

It means Django will loop through all INSTALLED_APPS directory to look for a “templatetags” subdirectory.

If found, it will in turn look for a “staticfiles.py” file inside the templatetags subdirectory.

If staticfiles.py is found, then it will import it.

For example, if django.contrib.staticfiles is in the INSTALLED_APPS, then
{% load staticfiles %}
will import the following file:
django/contrib/staticfiles/templatetags/staticfiles.py
There is a module level function called “static” defined in staticfiles.py, which is the “static” in the {% static %} template tag.

2014-12-02

How Django deals with methods renaming

A RenameMethodsBase metaclass is defined in the django.utils.deprecation module. It seems that Django uses it to deal with methods renaming. Below is a simplified explanation of how it works.

First we subclass the RenameMethodsBase to specify the old and new method names, as well as the type of warning. Then we use it as a metaclass on two classes Field1 and Field2.
import warnings
warnings.simplefilter("always")

from django.utils.deprecation import *

class RenameFieldMethods(RenameMethodsBase):
    renamed_methods = (
        ('_has_changed', 'has_changed', DeprecationWarning),
    )

class Field1(metaclass=RenameFieldMethods):
    def _has_changed(self):
        print('_has_changed')

class Field2(metaclass=RenameFieldMethods):
    def has_changed(self):
        print('has_changed')
If we instantiate Field1 and call both old and new methods, the following results:
>>> f1 = Field1()
>>> f1.has_changed()
_has_changed
>>> f1._has_changed()
__main__:1: DeprecationWarning: `Field1._has_changed` is deprecated, use `has_changed` instead.
_has_changed
On the other hand if we instantiate Field2 and call both old and new methods, the following results:
>>> f2 = t2.Field2()
>>> f2.has_changed()
has_changed
>>> f2._has_changed()
__main__:1: DeprecationWarning: `Field2._has_changed` is deprecated, use `has_changed` instead.
has_changed
In short, both methods will succeed, but if called by the name of the old method, a warning is issued.

2014-11-09

Surprise in Django render()

The doc says render() (Note 1) is the same as a call to render_to_response() with a context_instance argument that forces the use of a RequestContext.

It happens that render() takes a request object as its first argument, and a context_instance and a dictionary as two of its optional arguments. The context_instance is the context instance to render the template with. By default, the template will be rendered with a RequestContext instance (filled with values from request and dictionary).

As a Django beginner, I naively assume the request object will be automatically available in the template as I pass it as the first argument in the first place, and also because the context_instance argument forces the use of a RequestContext instance which is filled with values from the request object. Turns out that is not the case.

The request object is for the construction of the RequestContext only, which by default (as of Django 1.7) does not include the request object itself (Note2). It took me some time to figure that out.

To have the request object available in the template, I will have to pass it to render() in the dictionary argument:
    return render(request, template_name, {'request':request})
Or enable the request context processor at the settings, such that the request object will be automatically added to every RequestContext instance:
=== settings.py ===

from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS += (
    'django.core.context_processors.request',
)

2014-11-02

Appending to Django default settings

You can have a very minimal settings.py file in Django 1.7. Have you ever wondered how Django provides all the default settings?

All the default settings are defined in the module django/conf/global_settings.

There is usually no need to access the global_setting directly as explained in the doc..

The settings object will automatically get the default from the global_setting module on demand:
from django.conf import settings

if settings.DEBUG:
    # Do something
Or you can override a setting in settings.py like below:
DEBUG = True
However, if you ever want to add something to an existing setting instead of replacing it, you will need to do something like below in settings.py:
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS += (
    'django.core.context_processors.request',
)

2014-10-29

What is a Python decorator?

Suppose we have a function that returns the boiling point of water in celsius:
def boiling_point():
    return 100

print boiling_point() # returns 100
Suppose we are now at high altitude and the boiling point is now 97 degree. We can wrap the function like this:
def calibrate(f):
    def g():
        return f() - 3
    return g

def boiling_point():
    return 100

print boiling_point() # returns 100

boiling_point_calibrated = calibrate(boiling_point)
print boiling_point_calibrated() # returns 97
In fact, we can do better. We can assign the calibrated function back to the original function name. As a result, nothing is changed on the calling side:
def calibrate(f):
    def g():
        return f() - 3
    return g

def boiling_point():
    return 100

print boiling_point() # return 100

boiling_point = calibrate(boiling_point)
print boiling_point() # returns 97
When used in this way, the function calibrate() is called a decorator, and there is a shortcut for it:
def calibrate(f):
    def g():
        return f() - 3
    return g

@calibrate
def boiling_point():
    return 100

print boiling_point() # returns 97
Even better is for the offset to be configurable. The boiling point is dependent on the altitude after all. What we can do is to create a function which returns a function that decorates a function:
def calibrate_offset(offset):
    def calibrate(f):
        def g():
            return f() - offset
        return g
    return calibrate
    
@calibrate_offset(3)
def boiling_point():
    return 100

print boiling_point() # returns 97
Finally we can generalize the original function by adding *args and **kwargs to it:
def calibrate_offset(offset):
    def calibrate(f):
        def g(*args, **kwargs):
            return f(*args, **kwargs) - offset
        return g
    return calibrate
    
@calibrate_offset(3)
def boiling_point():
    return 100

print boiling_point() # returns 97
Lastly, decorator can be nested. What do you think x will be in the following case?
def calibrate_offset(offset):
    def calibrate(f):
        def g(*args, **kwargs):
            return f(*args, **kwargs) - offset
        return g
    return calibrate
    
@calibrate_offset(3)
@calibrate_offset(4)
def boiling_point():
    return 100

x = boiling_point()

2014-10-12

Django user login & logout signals

I would like to do something when a user logs in and out from my Django 1.7 project. The best way to do it is to take advantage of the Django Authentication System Login and Logout signals.

First I need to define the signal handlers in a signals submodule in one of Django application. (Note 1) In this case, I just write a log entry whenever a user logs in or logs out.
=== myapp/signals.py ===

from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.dispatch import receiver
from django.conf import settings

@receiver(user_logged_in)
def sig_user_logged_in(sender, user, request, **kwargs):
    logger = logging.getLogger(__name__)
    logger.info("user logged in: %s at %s" % (user, request.META['REMOTE_ADDR']))

@receiver(user_logged_out)
def sig_user_logged_out(sender, user, request, **kwargs):
    logger = logging.getLogger(__name__)
    logger.info("user logged out: %s at %s" % (user, request.META['REMOTE_ADDR']))
Then I create an application config in an apps submodule and override the Ready() method to register the signals. (Note 2)
=== myapp/apps.py ===

from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'MyApp'
    verbose_name = "My Application"

    def ready(self):
        import myapp.signals # register the signals
Finally I put 'myapp.apps.MyAppConfig' in the INSTALLED_APPS setting. (Note 3)
=== myproject/settings.py ===

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp.apps.MyAppConfig',
)
The log will look like something similar to the following.
=== app.log === 

[2014-10-09 05:08:28,372] INFO [myapp.signals:10] user logged in: david at 127.0.0.1
[2014-10-09 05:08:29,791] INFO [myapp.signals:15] user logged out: david at 127.0.0.1

2014-10-06

Migrating from Django 1.6 to 1.7

Recently I upgraded a simple Django project from Django 1.6 (running on Python 2.7) to Django 1.7 (running on Python 3.4). Below are some of the steps taken.
1. Switch to new syntax of relative import

OLD> from local_setting import *
NEW> from .local_setting import *

2. Change HttpResponse() argument from mimetype to content_type

OLD> response = HttpResponse(mimetype='text/csv')
NEW> response = HttpResponse(content_type='text/csv')

3. Specify binary mode in open() to avoid UnicodeDecodeError

OLD> with open("binary_file") as
NEW> with open("binary_file", "rb") as

4. Replace __unicode__() with __str__()

OLD> def __unicode__(self):
NEW> def __str__(self):

I also updated my .vimrc to exclude the __pycache__ directories from showing up in netrw.
=== ~/.vimrc ===

let g:netrw_list_hide= '.*\.pyc$,.*\.swp$,__pycache__'

2014-09-28

Add a button to export the search results in Django

I have a simple search page with a form at the top for the user to enter the search criteria (e.g. last name, first name, age, etc), and the search results are shown in the bottom half of the page.
What I want to do is to add a button to the form to export the search results as a CSV file. At first, I tried to have the search and export buttons post to two different URLs, but of course that did not work because an HTML form can only post to one and one only one URL.
Then I tried to have both the search button and the export button post to the same URL, and have the Django view handling the difference based on which button the user has clicked to submit the form, e.g. if the search button is clicked, then routes to the search view, else if the export button is clicked, then routes to the export view. It worked but there is a problem.
Since the user can change the search criteria before clicking the export button, and since it is a POST, the export view will execute the search based on the newly entered search criteria and export the new search results, which will be different from what the user sees in the bottom half of the search page. This is counter-intuitive and unacceptable to me.
My third attempt is to have the search and export button post to two different URLs. When a user clicks the search button, the search view will execute the search and save the search criteria (e.g. last name, first name, age, etc) in a Django session variable. If the user then clicks the export button, the export view will grab the search criteria from the session variable, execute the search, and export the results. It works, but it is not very portable because whenever I change the search form, I will need to change the views.
My next approach is to save the Django QuerySet in a session variable instead of the search criteria. It didn't work because a QuerySet is not JSON serializable. I cannot get Django to save the QuerySet in a session variable.
My final approach is to save the QuerySet query (rather than the search criteria) in a session variable. Then it works perfectly. I don't have to modify the views when the form changes. The export view grabs the QuerySet query from the session and then execute it as a raw SQL query. The performance hit of saving the QuerySet query is negligible, although the session variable itself will be wasted if the user eventually does not click the export button. But that is really just a small price to pay.
=== search view sample code ===

last_name = form.cleaned_data['last_name'] or None
first_name = form.cleaned_data['first_name'] or None
age = form.cleaned_data['age'] or None

if last_name: kw['last_name__icontains'] = last_name
if first_name: kw['first_name__icontains'] = first_name
if age: kw['age__exact'] = age

object_list = Person.objects.filter(**kw) # for the search
request.session['search_sql'] = str(Person.objects.filter(**kw).query) # for the export

=== export view sample code ===

sql = request.session.get('search_sql')
object_list = Person.objects.raw(sql)

2014-09-21

Reset button that works across postback to same page

By definition, a HTML Reset button does not work after a form is postback to the same page, because the posted back values then become the "default" values of the form.
Although you can use Javascript to reset all the fields in the form, I usually resort to a more simple way. Just create a button with an onClick handler to visit the same page. The difference this time is that it will be a GET instead of a POST, so all fields in the form will be cleared and reset to the original defaults.
Yes, it takes a round trip to the server, but the logic is simple and portable.
=== Sample Code ===

<input type="button" onclick="window.location=''" value="Reset" />

2014-09-15

Using a datepicker in Django model form

If your front end framework (e.g. Bootstrap) has a datepicker CSS class that you would like to use in a Django model form, how can you do that?
It turns out we can add any attribute to a HTML input element in a Django model form via the formfield_callback defined in the model form. We can make use of this technique to add the datepicker class (an attribute) to a model DateField (an HTML input element).
The following is an example of adding the datepicker class to all the DateFields in a model form. You will also have to make sure the datepicker class definition is available, probably by including the front end framework files in the base template.
=== forms.py (model datefield) ===

from django.forms import ModelForm
from django.db import models
from .models import MyModel

def make_custom_datefield(f):
    # f is a model field
    # if f is a date field, add the datepicker class to it
    # return a form field
    formfield = f.formfield()
    if isinstance(f, models.DateField):
        formfield.widget.attrs.update({'class':'datePicker'})
    return formfield

class MyForm(ModelForm):
    formfield_callback = make_custom_datefield
    class Meta:
        model = MyModel

=== html rendered ===

<input class="datePicker" id="id_datefield" name="datefield" type="text" value="" />
How about adding the datepicker class to a form DateField (instead of a model DateField)? We can just add an attribute directly in the form DateField definition. The following is an example of it.
=== forms.py (form datefield) ===

class MyForm(ModelForm):
    somedate = forms.DateField(
                 widget=forms.TextInput(attrs={'class':'datePicker'}))
    class Meta:
        model = MyModel

EDITED 2015-07-07 If the form uses a custom widget, add a keyword argument to the formfield_callback function like below, otherwise you will have a "make_custom_datefield() got an unexpected keyword argument 'widget'" error.
def make_custom_datefield(f, **kwargs):
    formfield = f.formfield(**kwargs)
    if isinstance(f, models.DateField):
        formfield.widget.attrs.update({'class':'datePicker'})
    return formfield

2014-09-07

Leverage Django Permission System

Django comes with a simple permission system which is used by the Django admin site. The doc says we can use the Django permission system in our own code as well.
How can we leverage the Django Permission System for our own use? One way is to create an app specifically for the purpose, and use a model to create the custom permissions that we need.
For example, if we want a user to have "export" permission in order to export data, and "download" permission in order to download stuff, then we can create an app called "permission" with a model called "Permission", and add custom permissions to it.
After adding the "permission" app to INSTALLED_APPS in settings.py and run syncdb, we can then use Django admin site to assign permission to a user, or better yet assign permissions to a group and then assign users to the group. Then we can check if a user has "export" or "download" permission by using the Django permission system.
Creating an app for this purpose may be an overkill, but I found it modular in design and easy to maintain.

=== permission/models.py ===

from django.db import models

class Permission(models.Model):
    class Meta:
        permissions = (
            ("export", "Can export data"),
            ("download", "Can download stuff"),
        )

=== settings.py ===

INSTALLED_APPS = (
    ...
    'permission',
)

=== Usage ===

from django.contrib.auth.models import User
john = User.objects.get(username='john')
john.has_perm("permission.export")

or

@permission_required('permission.export')
def some_view(request):
    ...

-End-

2014-09-01

Show the Django project version in the login page

I would like to display my Django project version string in the login page. However my project uses the Django Authentication System, which provides a login view (django.contrib.auth.views.login) which in turn uses my template file. Since I do not have control over the login view, how can I pass the version string into the template?
Turn out that the login view is a generic view and all generic views take an extra optional parameter, extra_context, which is a dictionary of objects that will be added to the template's context.
All we have to do is to add the version string to extra_context. We can do that in the urls.py. The url() function takes an optional argument which is a dictionary of extra keyword arguments to pass to the view function.
=== urls.py ===

VERSION = "1.0"

urlpatterns = patterns('',
    ...
    url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'extra_context': {'version':VERSION}}),
)

=== template.html ===

{% extends "base.html" %}
{% block title %}Project Name {{ version }}{% endblock %}
{% block content %}{% endblock %}

2014-08-28

Pyramid Single File Tasks Tutorial runs under mod_wsgi

I try to make the Pyramid Single File Tasks Tutorial runs under mod_wsgi, and figure that two changes are needed to make it runs both standalone (http://localhost:6543) and under mod_wsgi (http://localhost/task).

I would like to share these two changes:

[tasks.py]

FROM:
if __name__ == '__main__':
    # configuration settings
    settings = {}
    settings['reload_all'] = True
    settings['debug_all'] = True
    settings['mako.directories'] = os.path.join(here, 'templates')
    settings['db'] = os.path.join(here, 'tasks.db')
    # session factory
    session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet')
    # configuration setup
    config = Configurator(settings=settings, session_factory=session_factory)
    # routes setup
    config.add_route('list', '/')
    config.add_route('new', '/new')
    config.add_route('close', '/close/{id}')
    # static view setup
    config.add_static_view('static', os.path.join(here, 'static'))
    # scan for @view_config and @subscriber decorators
    config.scan()
    # serve app
    app = config.make_wsgi_app()
    server = make_server('0.0.0.0', 8080, app)
    server.serve_forever()


TO:
def get_app():
    # configuration settings
    settings = {}
    settings['reload_all'] = True
    settings['debug_all'] = True
    settings['mako.directories'] = os.path.join(here, 'templates')
    settings['db'] = os.path.join(here, 'tasks.db')
    # session factory
    session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet')
    # configuration setup
    config = Configurator(settings=settings, session_factory=session_factory)
    # routes setup
    config.add_route('list', '/')
    config.add_route('new', '/new')
    config.add_route('close', '/close/{id}')
    # static view setup
    config.add_static_view('static', os.path.join(here, 'static'))
    # scan for @view_config and @subscriber decorators
    config.scan()
    # serve app
    app = config.make_wsgi_app()
    return app

application = get_app()
if __name__ == '__main__':
    server = make_server('0.0.0.0', 8080, application)
    server.serve_forever()


[templates/layout.mako]

FROM:
  <link rel="shortcut icon" href="/static/favicon.ico">
  <link rel="stylesheet" href="/static/style.css">

TO:
  <link rel="shortcut icon" href="${request.application_url}/static/favicon.ico">
  <link rel="stylesheet" href="${request.application_url}/static/style.css">


I am using Debian 6, and the following is the relevant section in /etc/apache2/mods-enabled/wsgi.conf, where task.wsgi is a symbolic link to task.py in the same directory.

WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On

WSGIDaemonProcess pyramid user=david group=david threads=4 \
   python-path=/home/david/tasks/env/lib/python2.6/site-packages

WSGIScriptAlias /task /home/david/tasks/env/task/task.wsgi

<Directory /home/david/tasks/env>
  WSGIProcessGroup pyramid
  Order allow,deny
  Allow from all
</Directory>


[end]

2014-08-25

Django logging setting, part 2

This is a follow up to the Django logging setting post in 2013.
This time, it makes use of the hierarchical nature of the logging system, removing the need to define a separate section for each app in the settings file. Notice the dot after the <project_name> in U_LOGGER_ROOT.
=== settings.py ===

U_LOGFILE_NAME = r'/path/to/log.txt'
U_LOGFILE_SIZE = 1 * 1024 * 1024
U_LOGFILE_COUNT = 2
U_LOGGER_ROOT = '<project_name>.'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'logfile': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': U_LOGFILE_NAME,
            'maxBytes': U_LOGFILE_SIZE,
            'backupCount': U_LOGFILE_COUNT,
            'formatter': 'standard',
        },
    },
    'loggers': {
        U_LOGGER_ROOT.rstrip('.'): {
            'handlers': ['logfile'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

=== in any app module ===

import logging
from  import settings

logger = logging.getLogger(settings.U_LOGGER_ROOT + __name__)
logger.info('some useful information')

2014-08-19

Showing the description of a choice in a Django template

Sometimes you would like to show the description of a choice instead of its code in a Django template.  One way to achieve that is to define a property in the model and referencing it in a template as below:

    {{ object.status_desc }}

=== models.py ===

from django.db.models import IntegerField, CharField, Model

class Invoice(Model):

    STATUS_TYPE = (
        ('A', 'Active'),
        ('I', 'Inactive'),
    )

    invoice_no = IntegerField()
    status = CharField(max_length=1, choices=STATUS_TYPE, default='A')

    @property
    def status_desc(self):
        return dict(self.STATUS_TYPE)[self.status]
 
EDITED 2015-07-13 Turn out there is a django function for this purpose: Model.get_FOO_display()

2014-08-16

Django File Upload

The following is a minimalistic but complete example of handling file upload in Django 1.6.


=== forms.py ===

from django import forms

class UploadFileForm(forms.Form):
    file = forms.FileField()

=== views.py ===

import os.path
from django.http import HttpResponse
from django.shortcuts import render
from .forms import UploadFileForm
          
def home(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponse("Upload Successful.")
    else:
        form = UploadFileForm()
    return render(request, 'home.html', {'form': form})

def handle_uploaded_file(f):
    with open(os.path.join('/path/to/', f.name), 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

=== home.html ===
<html>
<body>

<form action="" method="post" {% if form.is_multipart %}enctype="multipart/form-data"{% endif %}>
  {{ form.as_p }}
  {% csrf_token %}
  <input type="submit" value="Submit" />
</form>

</body>
</html>

2014-06-09

How is_authenticated() is done in Django?


I tried to understand how is_authenticated() is done in Django, so I did a code search in Django's GitHub repository and found two definitions of it in django/contrib/auth/models.py as shown below:


I am surprised that one definition always return true, while the other always return false, as I was expecting some sort of logic to check if a user is logged or not.

Turn out it is simpler than that. The is_authenticated() method is bound to either a User object or an AnonymousUser object. So at the time is_authenticated() is called, it already knows whether the user is authenticated or not by the type of the object.

Neat.

2014-06-02

Getting back the terminal border in Ubuntu 14.04 LTS

I have set my gnome-terminal colors green on black (easy for my eyes).

Unfortunately the gnome-terminal application in Ubuntu 14.04 LTS does not have a border by default, making it difficult for me to get hold of the boundary of overlapping terminal windows, especially I have set my background to black as well (to conserve battery life).

Assuming Ambiance is the active theme, the following change is how I get the terminal border back:

$ vim /usr/share/themes/Ambiance/gtk-3.0/apps/unity.css

change:

UnityDecoration {
    -UnityDecoration-extents: 28px 0 0 0;

to:

UnityDecoration {
    -UnityDecoration-extents: 28px 1px 1px 1px;


2014-05-01

Cookies Signing

When I sign a letter and send it to you, my signature is a proof to you that I write that letter.

In the case of signing a cookie, the opposite is true.

If I send you a signed cookie, I am actually making sure when you return the cookie to me, it is the same cookie that I send to you earlier on.  The signature is for my benefit, not yours.

It is like I put a letter in a transparent box with a padlock and send it to you.  You can read the letter, but you cannot change it.

When I ask for my letter back, and if I can open the box with my key, I can be sure it is the original letter, because I am the only one who has the matching key to unlock the box.

On the other hand, if somebody changes the letter and put it in a box with a different padlock, I will not be able to open it with my key because the padlock is different.

I can still read the letter (because the box is transparent), but I know it is not the same one I send to you in the first place.