Friday, December 16, 2011

tofigureout: Django apps prefix

If all of all my Django apps are in the "apps" dir, is there something I can set so that I can directly write the app name instead of "apps.app_name" everytime.

It seems like I can do this only with sys.path or PYTHONPATH, which applies to all the django projects in the environment. This doesn't seem like a satisfactory solution. ... my summer project MozSecWorld didn't have this problem, I wonder what magic the setup for that did.

Setting up new Django project (with virtualenv(wrapper))

Download Django for Ubuntu in root:

1. cd /usr/local/lib, mkdir django-1.3.1 and cd into it

2a. wget http://www.djangoproject.com/download/1.3.1/tarball/ -O Django-1.3.1.tar.gz, got this step from here

2b. cd Django-1.3.1.tar.gz

2c. sudo python setup.py install

So my Django path is:
/usr/local/lib/django-1.3.1/Django-1.3.1

In user:
1. mkvirtualenv --no-site-packages vocab this is virtualenvwrapper setting up a new environment. Setup is logged in this old post.

$ mkvirtualenv --no-site-packages vocab
New python executable in vocab/bin/python
Installing setuptools............done.
Installing pip...............done.
virtualenvwrapper.user_scripts creating /home/my_username/.virtualenvs/vocab/bin/predeactivate
virtualenvwrapper.user_scripts creating /home/my_username/.virtualenvs/vocab/bin/postdeactivate
virtualenvwrapper.user_scripts creating /home/my_username/.virtualenvs/vocab/bin/preactivate
virtualenvwrapper.user_scripts creating /home/my_username/.virtualenvs/vocab/bin/postactivate
virtualenvwrapper.user_scripts creating /home/my_username/.virtualenvs/vocab/bin/get_env_details
mkdir: cannot create directory `/home/my_username/Projects/vocab': No such file or directory
-bash: cd: /home/my_username/Projects/vocab: No such file or directory
Searching for readline
Reading http://pypi.python.org/simple/readline/
Reading http://www.python.org/
Reading http://github.com/ludwigschwardt/python-readline
Best match: readline 6.2.1
Downloading http://pypi.python.org/packages/source/r/readline/readline-6.2.1.tar.gz#md5=9604527863378512247fcaf938100797
Processing readline-6.2.1.tar.gz
Running readline-6.2.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-9h67Mv/readline-6.2.1/egg-dist-tmp-nNoSrj
/usr/bin/ld: cannot find -lncurses
collect2: ld returned 1 exit status
error: Setup script exited with error: command 'gcc' failed with exit status 1
Downloading/unpacking Jinja2==2.3.1
  Downloading Jinja2-2.3.1.tar.gz (428Kb): 428Kb downloaded
  Running setup.py egg_info for package Jinja2
    
    warning: no previously-included files matching '*' found under directory 'docs/_build/doctrees'
Downloading/unpacking MySQL-python==1.2.3c1
  Downloading MySQL-python-1.2.3c1.tar.gz (89Kb): 89Kb downloaded
  Running setup.py egg_info for package MySQL-python
    
Downloading/unpacking lxml==2.2.6
  Downloading lxml-2.2.6.tar.gz (2.9Mb): 2.9Mb downloaded
  Running setup.py egg_info for package lxml
    Building lxml version 2.2.6.
    NOTE: Trying to build without Cython, pre-generated 'src/lxml/lxml.etree.c' needs to be available.
    ERROR: /bin/sh: xslt-config: not found
    
    ** make sure the development packages of libxml2 and libxslt are installed **
    
    Using build configuration of libxslt
    
    warning: no previously-included files found matching '*.py'
Downloading/unpacking PIL
  Downloading PIL-1.1.7.tar.gz (506Kb): 506Kb downloaded
  Running setup.py egg_info for package PIL
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    
Obtaining check from git+git://github.com/jbalogh/check.git#egg=check
  Cloning git://github.com/jbalogh/check.git to /home/my_username/.virtualenvs/vocab/src/check
  Running setup.py egg_info for package check
    
Downloading/unpacking pyflakes (from check)
  Downloading pyflakes-0.5.0.tar.gz
  Running setup.py egg_info for package pyflakes
    
Downloading/unpacking pep8 (from check)
  Downloading pep8-0.6.1.tar.gz
  Running setup.py egg_info for package pep8
    
Downloading/unpacking path.py (from check)
  Error  while getting http://pypi.python.org/packages/source/p/path.py/path.py-2.2.2.tar.gz#md5=3a3262b9049d294ddbd6f7453d45e699 (from http://pypi.python.org/simple/path.py/)
Exception:
Traceback (most recent call last):
  File "/home/my_username/.virtualenvs/vocab/local/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg/pip/basecommand.py", line 126, in main
    self.run(options, args)
  File "/home/my_username/.virtualenvs/vocab/local/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg/pip/commands/install.py", line 223, in run
    requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
  File "/home/my_username/.virtualenvs/vocab/local/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg/pip/req.py", line 961, in prepare_files
    self.unpack_url(url, location, self.is_download)
  File "/home/my_username/.virtualenvs/vocab/local/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg/pip/req.py", line 1079, in unpack_url
    return unpack_http_url(link, location, self.download_cache, only_download)
  File "/home/my_username/.virtualenvs/vocab/local/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg/pip/download.py", line 429, in unpack_http_url
    resp = _get_response_from_url(target_url, link)
  File "/home/my_username/.virtualenvs/vocab/local/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg/pip/download.py", line 465, in _get_response_from_url
    resp = urlopen(target_url)
  File "/home/my_username/.virtualenvs/vocab/local/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg/pip/download.py", line 84, in __call__
    response = urllib2.urlopen(self.get_request(url))
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 391, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 409, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1185, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1160, in do_open
    raise URLError(err)
URLError: 

Storing complete log in /home/my_username/.pip/pip.log

2. Since I installed with no-site-packages, I need to add Django to the virtualenv
add2virtualenv /usr/local/lib/django-1.3.1/Django-1.3.1

3. follow the Django tutorial

3b. In python manage.py sql app_name I got this error:
...
raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module: No module named MySQLdb
so I did
pip install MySQL-python

3c. I installed my app inside an "apps" folder, so here is what I did:
mkdir apps; touch apps/__init__.py
python manage.py startapp app_name
mv app_name apps
vim settings.py and add into INSTALLED_APPS 'apps.apps_name'
python manage.py sql app_name
Note that you should have 'apps.app_name' in INSTALLED_APPS or else it's not going to find it and give you this error instead:
Error: No module named app_name

Friday, November 11, 2011

Linux show total lines of files in a directory (sorted by line numbers)

Linux showing total number of lines of each file in a directory:

wc -l *

Even better, you can have the results sorted by line numbers:

wc -l * | sort -n -k1

-n         compare according to string numerical value
-k#       define start position

Friday, October 21, 2011

Deploying Django

I can either do it the right way or the cheating way in screen, that might crash Django when certain errors are encountered. The screnning way might need this to keep the process running when I logout


TODO, suggested by mark:
with apache in front, mod_wsgi handles the processes for you
.. and standard server config takes care of the apache stuff

----

SSL .. Django admin through port forwarding?

Setting up MSW on Rackspace

./manage.py shell

django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module: No module named MySQLdb

In root install: pip install mysql-python.

If you I got another error ...
In file included from _mysql.c:29:0:
pymemcompat.h:10:20: fatal error: Python.h: No such file or directory
compilation terminated.
error: command 'gcc' failed with exit status 1
... then you need to install sudo apt-get install python-dev

(I searched for solutions for a long time, trying to find my "/usr/local/mysql" on ubuntu, but I don't have it (even though I have mysql).)


Now ./manage.py shell has
ImportError: No module named OpenSSL
From root, pip install pyopenssl


Now ./manage.py shell has
ImportError: No module named bycrypt
From root, pip install py-bcrypt

AND THEN I GOT MANAGE.PY SHELL!!!
import django! works on it too!!!!!!!!
$ ./manage.py shell
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import django

Whoa I can even run it on my rackspace IP! :D Even though it crashes, at least it can get the request!

$ ./manage.py runserver 50.57.147.82:8000
Validating models...

0 errors found
Django version 1.3.1, using settings 'MozSecWorld.settings_local'
Development server is running at http://50.57.147.82:8000/
Quit the server with CONTROL-C.
[21/Oct/2011 03:23:36] "GET / HTTP/1.1" 301 0

Traceback (most recent call last):
...
TemplateSyntaxError: Caught ImportError while rendering: No module named jinja2
[21/Oct/2011 03:23:37] "GET /msw/ HTTP/1.1" 500 2909
So I did, from root, pip install jinja2

AND MOZSECWORLD IS UP at http://50.57.147.82:8000/!!!!!!!! :D:D:D

Setting up more Django on a clean Ubuntu server

Get virtualenvs and virtualenvwrapper following this and this and this (with an informative video)

On root account:
1. sudo apt-get install python-setuptools

2. sudo easy_install virtualenv

3.
virtualenv ve_msw
New python executable in ve_msw/bin/python
Installing setuptools............done.
Installing pip...............done.

4. easy_install pip (I could also have done "pip install virtualenv" or "easy_install virtualenvwrapper"

5. pip install virtualenvwrapper

On user account:
6. mkdir ~/.virtualenvs

7. Add to end of ~/.bashrc:
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

8.
$ mkvirtualenv ve_msw
New python executable in ve_msw/bin/python
Installing setuptools............done.
Installing pip...............done.
virtualenvwrapper.user_scripts creating /home/haoqili/.virtualenvs/ve_msw/bin/predeactivate
virtualenvwrapper.user_scripts creating /home/haoqili/.virtualenvs/ve_msw/bin/postdeactivate
virtualenvwrapper.user_scripts creating /home/haoqili/.virtualenvs/ve_msw/bin/preactivate
virtualenvwrapper.user_scripts creating /home/haoqili/.virtualenvs/ve_msw/bin/postactivate
virtualenvwrapper.user_scripts creating /home/haoqili/.virtualenvs/ve_msw/bin/get_env_details

9. Added to ~/.virtualenvs/postmkvirtualenv
proj_name=$(echo $VIRTUAL_ENV|awk -F'/' '{print $NF}')
mkdir $HOME/Projects/$proj_name
add2virtualenv $HOME/Projects/$proj_name
cd $HOME/Projects/$proj_name
easy_install readline ipython
pip install -e git://github.com/jbalogh/check.git#egg=check Jinja2==2.3.1 \
    MySQL-python==1.2.3c1 lxml==2.2.6 PIL

10. Now I can call workon ve_msw

MSW already have playdoh set up at the very beginning
11. To set up where virtualenvwrapper's "workon" takes us to add this to
~/.virtualenvs/ve_msw/bin/postactivate
cd ~/path/to/mswdir

Thursday, October 20, 2011

Set up new mysql user

CREATE USER 'new_username'@'localhost' IDENTIFIED BY 'password_for_new_username';
GRANT ALL ON *.* TO 'new_username'@'localhost';

source

rackspace todo

set up django: https://docs.djangoproject.com/en/1.3/intro/install/

show alex ssh. :D

Linux add user

adduser username
not useradd username

Story: 

######## Stage 1. Stuck & Confused ############

I'm was trying to set up my Rackspace server and I ran into some questions during my created user account.

From root, I added a user with "useradd alice". When I discovered that ~/ failed, I had to sudo mkdir /home/alice.

Q0: It's so strange that the user home dir has to be manually created

Then I logged in as alice, but found that the prompt is not customized and lacks color. Since useradd copied /etc/skel/.bashrc from root to alice, I thought that I can just "cp /etc/skel/.bashrc ~/.bashrc", but when I did that (with sudo), "echo $PS1" still shows the old original prompt settings.

Q1: How come the ~/.bashrc, identical in root and user alice, does not work in alice?

I even uncommented out "force_color_prompt=yes", but its still not working.

Q2: How come user alice needs sudo to edit ~/.bashrc in the first place when its permissions are (from ls -l):
        alice@simba:~$ ls -l ~/.bashrc
        -rw-r--r-- 1 root root 141 2011-10-20 05:19 /home/alice/.bashrc

Answer: Because the user and group of /home/alice/.bashrc are both set to "root" (The user is the one that matters here)

Then I tried to "sudo chown alice:alice ~/.bashrc", but was denied permission because I was on alice.


######### Stage 2. Found good resource ############

Then I read this informative article and learned:

useradd -D shows the defaults of useradd. You can change the shell to bash by specifying useradd -D -s /bin/bash . Then you can use useradd alice followed by passwd alice to set its password.  BUT!! This still doesn't automatically make /home/alice for you


######## Stage 3. Problems solved! ################

adduser alice worked beautifully
0: home dir created automatically :D
1: bashrc and xterm-color both work :D
2: home dir's files are automatically made with alice as the user
# adduser alice
Adding user `alice' ...
Adding new group `alice' (1001) ...
Adding new user `alice' (1001) with group `alice' ...
Creating home directory `/home/alice' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for alice
Enter the new value, or press ENTER for the default
        Full Name []: Alice P Hacker
        Room Number []: 
        Work Phone []: 
        Home Phone []: 
        Other []: 
Is the information correct? [Y/n] y
... Why does it care about the room number? haha

Wednesday, October 19, 2011

Give user sudo

You have to edit the /etc/sudoers file, which starts off with a scary text: This file MUST be edited with the 'visudo' command as root. OMG!

So I do visudo but it takes me to the nano editor.
I want vim instead! So I did export EDITOR="vim", which if you want to be your default editor, add this line to ~/.bashrc.

Copy and modify root   ALL=(ALL:ALL) ALL

Thursday, October 13, 2011

Setting up rackspace server

First I would like to say: thank you Rackspace, you have given me back the fire spark in life that has been swallowed by the fire hose.  Your superb user experience with instant server setup and live technical chat support has been a very pleasant surprise.  I can get all that for just $0.015/hour ($10.8/month)?

Anyways ... the things I did/learned from setting up my first Rackspace server:

1. Setting up apache for Python. I do want to run some Django apps, so I followed steps 1 and 2 of a previous setup.

2. DNS ... When I set up a domain name inside rackspace, it's going to be an internal lookup. I'll give my registered domain on name.com the general rackspace name. Then rackspace is going to do an internal lookup to find my specific machine that hosts the domain name.

3. History is found in ~/.bash_history


I created a user from root. How come the user only has sh shell but not the better bash shell like root?
Edit: I think there is more to it: useradd -D --shell <shell-to-set>

4. Check the shell with ps or echo $SHELL

5. Check the shell a particular user is running in /etc/passwd, or view it like grep username /etc/passwd

6. So I changed my user's entry in /etc/passwd from /bin/sh to /bin/bash

7. Move /bin/bash to the top of /etc/shells


Now my user has bash, but it doesn't have .bashrc. There is more to it.

8. Copy root's /etc/skel directory. "The /etc/skel directory contains files and directories that are automatically copied over to a new user's home directory when such user is created by the useradd program." ~ source 

It turns out that I do have them copied, but I have to manually copy them again into ~/, which I'll have to create first, but I need sudo powers for my user, see next post.

Friday, September 30, 2011

Git resolve merge conflicts

So you have

$git merge repo
Auto-merging path/to/file1
Auto-merging path/to/file2
CONFLICT (content): Merge conflict in path/to/file3
Auto-merging path/to/file4
CONFLICT (content): Merge conflict in path/to/file5
Automatic merge failed; fix conflicts and then commit the result.

To fix:

For all files with conflicts, do:
1.vim path/to/file3 and then compare the text

<<<<<<<

=======

with

======

>>>>>>>
Make sure you delete those indicator lines too.

2. git update-index [path/to/file3]

source

Sunday, September 25, 2011

Github as the second remote

This is a brute-force way of setting up github as a second remote/backup to your code.

1. $ cp -r repo repo_backup
2. $ cd repo_backup and then vim .git/config
delete the old [remote "origin"]
3. $ git remote add origin git@github.com:username/repo_name. Now you should see its corresponding lines in .git/config
4. I want to push my local branch "b1" to a branch on github named "branch1", so I did git push -u origin b1:refs/heads/branch1

multiple git remotes

One is the real git remote, one is a backup I would like to have on github.


==============
.git/config's remote fetch = +refs/heads ...
explained here


Finally,
fetch = +refs/heads/*:refs/remotes/origin/*
That means if you do
git fetch origin
It will actually do:
git fetch origin +refs/heads/*:refs/remotes/origin/*
Which means a remote heads/foobar will be local remotes/origin/foobar, and the plus sign means they'll be updated even if they are not fast-forward.

answered by felipec

================
http://stackoverflow.com/questions/849308/pull-push-from-multiple-remote-locations/849960#849960

Thursday, September 15, 2011

error: expected expression before ')' token

Maybe you have an extra comma at the end of your list of arguments. ;)

C programming compare pointers to numbers

You want to check if a particular pointer is at an address.
If the pointer is of uint32_t* type, trying to make an address in in uint32_t might throw you this error: error: this decimal constant is unsigned only in ISO C90.
Here is what you can do:
uint32_t* ptr;

ptr = get_it_some_how();
cprintf("  get the int of address: %08d \n", ptr);
 
int* target = (int *)  -267296968;  // this is the int you copy from the printout above

if( ptr == (uint32_t*) target )       // look! a cast!
    cprintf(" yay the pointer is at target!\n");
else
    cprintf("  noo! the pointer is not at target\n");

Friday, September 9, 2011

git edit commit message and push to github

Steps to edit a git commit message and also have it show up to Githb:

1. To edit your last commit message:

git commit --amend

2. Edit your commit message on top. If you're using vim, to save and quit, do esc+":wq"

3. Push to Github:

git push --force


Note that if you don't have the "--force", you'll get this error message:

$ git push
To git@github.com:your/repo.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:your/repo.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.
So remember to git push --force!

Friday, August 5, 2011

scp command

copy from current location to another machine which has an IP

scp [-r] source destination
scp -r path/to/src-dir/ username@machine-to-go-to-IP:/path/to/dest-dir

git branch

git branch

git fetch origin
git co branchname

css drop shadows without images

really cool!

Wednesday, August 3, 2011

Django vendor-local adding package

playdoh (master)$ pip install --no-install --build=vendor-local/packages --src=vendor-local/src -I django-csp
Downloading/unpacking django-csp
  Downloading django_csp-1.0.2.tar.gz
  Running setup.py egg_info for package django-csp

which installed django-csp into vendor-local/packages

and then I added the path to vendor-local/vendor.pth:
packages/django-csp

FYI, the contents:
playdoh/vendor-local/packages/django-csp (master)$ ls -R
PKG-INFO            django_csp.egg-info setup.cfg
csp                 pip-egg-info        setup.py

./csp:
__init__.py   decorators.py middleware.py urls.py       views.py

./django_csp.egg-info:
PKG-INFO             dependency_links.txt
SOURCES.txt          top_level.txt

./pip-egg-info:
django_csp.egg-info

./pip-egg-info/django_csp.egg-info:
PKG-INFO             dependency_links.txt
SOURCES.txt          top_level.txt



The Resource

Tuesday, August 2, 2011

stick something on the bottom right


#stick-me-to-bottom-right {
position: fixed;
bottom: 0;
right: 0;
}

x-frame-options old notes

Taken from old mozsecworld.org page on x-frame-options

What to do

Add in this line to your HTTP Response Headers: X-Frame-Options: deny


How to check

Firefox's Firebug or Chrome's "Inspect Elements": Go to "Net" option, refresh page, and click on the link that shows up, select "Headers" and you should see "X-Frame-Options: DENY" under "Response Headers"

Terminal: >telnet [insert IP-address of your site] 8000 Press enter and put in GET /en-US/msw/ HTTP/1.1 Press enter twice, and scroll to the very top of the output, should see "x-frame-options: DENY".

What I did

Playdoh automatically sets the "X-Frame-Options" to "deny". But if you want to set it automatically in Django, use response['x-frame-options'] = 'DENY'


In views.py:
# X-Frame-Options
def xfo_deny(request):
    html = " ... my html stuff ... "
    response = HttpResponse(html)
    response['x-frame-options'] = 'DENY'
    return response


Notes on how Django does x-frame-options

In vendor/src/commonware/commonware/response/middleware.py:

from django.conf import settings

class FrameOptionsHeader(object):
    """
    Set an X-Frame-Options header. Default to DENY. Set
    response['x-frame-options'] = 'SAMEORIGIN'
    to override.
    """

    def process_response(self, request, response):
        if hasattr(response, 'no_frame_options'):
            return response

        if not 'x-frame-options' in response:
            response['x-frame-options'] = 'DENY'
        

In vendor/src/commonware/commonware/response/decorators.py:

from functools import wraps

from django.utils.decorators import available_attrs


def xframe_sameorigin(view_fn):
    @wraps(view_fn, assigned=available_attrs(view_fn))
    def _wrapped_view(request, *args, **kwargs):
        response = view_fn(request, *args, **kwargs)
        response['x-frame-options'] = 'SAMEORIGIN'
        return response
    return _wrapped_view


def xframe_allow(view_fn):
    @wraps(view_fn, assigned=available_attrs(view_fn))
    def _wrapped_view(request, *args, **kwargs):
        response = view_fn(request, *args, **kwargs)
        response.no_frame_options = True
        return response
    return _wrapped_view


def xframe_deny(view_fn):
    @wraps(view_fn, assigned=available_attrs(view_fn))
    def _wrapped_view(request, *args, **kwargs):
        response = view_fn(request, *args, **kwargs)
        response['x-frame-options'] = 'DENY'
        return response
    return _wrapped_view
        

Thursday, July 28, 2011

Wildcard in CSP

For certain rules, you can set "*" to allow all. When you do so, be sure to delete any other statements, or else they would narrow down the search, making "*" ineffective.

More details

Wednesday, July 27, 2011

discovered ~/.bash_aliases :) bash command shortcuts

wow this could have saved me so much time

Python Check.py!

pip install -e git://github.com/jbalogh/check.git#egg=check

Pip Install Django Debug Toolbar

pip install django-debug-toolbar

So you get to do python manage.py debugsqlshell and have a debug sidebar.

It's awesome

Pypi

Tuesday, July 26, 2011

Randomizing in Django QuerySet and Python List

Django QuerySet:

my_queryset.order_by('?')

Python List:

import random

random.shuffle(my_list)


And then you can use slice to just keep n elements, e.g.
n = 5
my_queryset.order_by('?')[:n]

Sunday, July 24, 2011

Django get user object in views.py

In views.py
def index(request):
    # get user
    try:
        the_user = User.objects.get(username = request.user)
    except User.DoesNotExist:
        return HttpResponse("Invalid username")

Saturday, July 23, 2011

How adopted-kitsune Django upload works.

0. forms.py
class ImageAttachmentUploadForm(forms.Form):
    """Image upload form."""
    print "############################in form"
    image = forms.ImageField(error_messages={'required': MSG_IMAGE_REQUIRED,
                                             'max_length': MSG_IMAGE_LONG},
                             max_length=settings.MAX_FILENAME_LENGTH)


1. views.py

for fileupload page if request.method == 'POST':
    form = forms.ImageAttachmentUploadForm(request.POST, request.FILES)
    if form.is_valid()

2. playdoh/vendor/src/django/django/forms/fields.py

class ImageField(FileField):
    def to_python(self, data):

        """
        Checks that the file-upload field data contains a valid image (GIF, JPG,
        PNG, possibly others -- whatever the Python Imaging Library supports).
        """

Thursday, July 21, 2011

Cannot shutdown Ubuntu, always restarts

Solution:
sudo shutdown -h now

MySQL Dump Database

Dump:

1. mysqldump -u root -p database_name > db_backup.sql

2. somehow get db_backup.sql to the machine where you want to dump, and make sure you can see db_backup.sql from ls

3. mysql -u root -p

4. use database_you_want_to_dump_name

5. source db_backup.sql

6. show tables;

Yay!

source

Ubuntu pip install record

MozSecWorld$ sudo pip install -r requirements/compiled.txt 
Downloading/unpacking py-bcrypt==0.2 (from -r requirements/compiled.txt (line 7))
  Running setup.py egg_info for package py-bcrypt
Downloading/unpacking hashlib==20081119 (from -r requirements/compiled.txt (line 6))
  Running setup.py egg_info for package hashlib
    Using OpenSSL version 0x009080ff from
     Headers: /usr/include
     Library: /usr/lib/libssl.so
    no previously-included directories found matching 'build'
    no previously-included directories found matching 'dist'
    no previously-included directories found matching 'RCS'
    no previously-included directories found matching 'CVS'
    no previously-included directories found matching '.svn'
Downloading/unpacking Jinja2==2.5.5 (from -r requirements/compiled.txt (line 2))
  Running setup.py egg_info for package Jinja2
    warning: no previously-included files matching '*' found under directory 'docs/_build'
    warning: no previously-included files matching '*.pyc' found under directory 'jinja2'
    warning: no previously-included files matching '*.pyc' found under directory 'docs'
    warning: no previously-included files matching '*.pyo' found under directory 'jinja2'
    warning: no previously-included files matching '*.pyo' found under directory 'docs'
Downloading/unpacking MySQL-python==1.2.3c1 (from -r requirements/compiled.txt (line 1))
  Running setup.py egg_info for package MySQL-python
    sh: mysql_config: not found
    Traceback (most recent call last):
      File "", line 14, in 
      File "/home/haoqili/Desktop/MozSecWorld/build/MySQL-python/setup.py", line 15, in 
        metadata, options = get_config()
      File "setup_posix.py", line 43, in get_config
        libs = mysql_config("libs_r")
      File "setup_posix.py", line 24, in mysql_config
        raise EnvironmentError("%s not found" % (mysql_config.path,))
    EnvironmentError: mysql_config not found
    Complete output from command python setup.py egg_info:
    sh: mysql_config: not found

Traceback (most recent call last):

  File "", line 14, in 

  File "/home/haoqili/Desktop/MozSecWorld/build/MySQL-python/setup.py", line 15, in 

    metadata, options = get_config()

  File "setup_posix.py", line 43, in get_config

    libs = mysql_config("libs_r")

  File "setup_posix.py", line 24, in mysql_config

    raise EnvironmentError("%s not found" % (mysql_config.path,))

EnvironmentError: mysql_config not found

----------------------------------------
Command python setup.py egg_info failed with error code 1
Storing complete log in /home/haoqili/.pip/pip.log

and then python manage.py runserver still gives "ImportError: No module named bcrypt" error.

so sudo pip install py-bcrypt worked

Set up SSH

sudo aptitude install openssh-server openssh-client

Wednesday, July 20, 2011

Preparing to Set up MozSecWorld on Linux

Since the permanent host for MozSecWorld will be on linux.

1. Install libapache2-mod-wsgi. This is a Python apache!
sudo apt-get install libapache2-mod-wsgi

2. Install Apache2. /etc/init.d/apache2 status should say that "Apache2 is running"

3. Configure Apache2.

4. clone repository git clone https://github.com/haoqili/MozSecWorld

5. Get the vendor. cd MozSecWorld/vendor and then git clone --recursive git://github.com/mozilla/playdoh-lib.git .
follow the Setup Section until
python manage.py runserver does not complain about any missing modules

Getting Image Upload to work on Django

Learned form r1cky that jpeg and PIL are packages that need to be recompiled for other people, especially those on different operating systems

haoqili: how can I tell if a package needs to be recompiled on the VM or not?
r1cky: hmm, that is a good question. if it is only .py source files then it doesnt need compiling
r1cky: but some libraries have C in them
r1cky: the ones that we use that need compiling are
r1cky: MySQL-python, Jinja2, PIL, lxml
r1cky: and the jpeg one
r1cky: those are installed separately (not copied into the repository)

1. Install PIL into my vendor-local

playdoh (master)$  pip install -I --install-option="--home=`pwd`/vendor-local" pil
Downloading/unpacking pil
  Downloading PIL-1.1.7.tar.gz (506Kb): 506Kb downloaded
  Running setup.py egg_info for package pil
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    
Installing collected packages: pil
  Running setup.py install for pil
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    --- using frameworks at /System/Library/Frameworks
    building '_imaging' extension
    /usr/bin/cc -fno-strict-aliasing -O3 -w -pipe -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DHAVE_LIBZ -I/System/Library/Frameworks/Tcl.framework/Headers -I/System/Library/Frameworks/Tk.framework/Headers -IlibImaging -I/Users/haoqili/.virtualenvs/playdoh/include -I/usr/local/include -I/usr/include -I/usr/local/Cellar/python/2.7.1/include/python2.7 -c _imaging.c -o build/temp.macosx-10.4-x86_64-2.7/_imaging.o
    ...
    /usr/bin/cc -L/usr/local/Cellar/readline/6.2.1/lib -bundle -undefined dynamic_lookup -L/usr/local/Cellar/readline/6.2.1/lib build/temp.macosx-10.4-x86_64-2.7/_imagingmath.o -L/usr/local/lib -L/Users/haoqili/.virtualenvs/playdoh/lib -L/usr/lib -o build/lib.macosx-10.4-x86_64-2.7/_imagingmath.so
    --------------------------------------------------------------------
    PIL 1.1.7 SETUP SUMMARY
    --------------------------------------------------------------------
    version       1.1.7
    platform      darwin 2.7.1 (r271:86832, Jun  6 2011, 13:57:48)
                  [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
    --------------------------------------------------------------------
    --- TKINTER support available
    *** JPEG support not available
    --- ZLIB (PNG/ZIP) support available
    *** FREETYPE2 support not available
    *** LITTLECMS support not available
    --------------------------------------------------------------------
    To add a missing option, make sure you have the required
    library, and set the corresponding ROOT variable in the
    setup.py script.
    
    To check the build, run the selftest.py script.
    changing mode of build/scripts-2.7/pilconvert.py from 644 to 755
    changing mode of build/scripts-2.7/pildriver.py from 644 to 755
    changing mode of build/scripts-2.7/pilfile.py from 644 to 755
    changing mode of build/scripts-2.7/pilfont.py from 644 to 755
    changing mode of build/scripts-2.7/pilprint.py from 644 to 755
    
    changing mode of /Users/haoqili/dev/playdoh/playdoh/playdoh/vendor-local/bin/pilconvert.py to 755
    changing mode of /Users/haoqili/dev/playdoh/playdoh/playdoh/vendor-local/bin/pildriver.py to 755
    changing mode of /Users/haoqili/dev/playdoh/playdoh/playdoh/vendor-local/bin/pilfile.py to 755
    changing mode of /Users/haoqili/dev/playdoh/playdoh/playdoh/vendor-local/bin/pilfont.py to 755
    changing mode of /Users/haoqili/dev/playdoh/playdoh/playdoh/vendor-local/bin/pilprint.py to 755
Successfully installed pil
Cleaning up...

2. Trying to get JPEG to be supported:
playdoh/vendor-local (master)$ brew install jpeg
Warning: Xcode is not installed! Builds may fail!
==> Downloading http://www.ijg.org/files/jpegsrc.v8c.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/jpeg/8c --disable-dependency-tracking
==> make install
/usr/local/Cellar/jpeg/8c: 17 files, 1.6M, built in 13 seconds

3. Rebuild PIL
)$ pip install PIL==1.1.7 --upgrade
Downloading/unpacking PIL==1.1.7
  Downloading PIL-1.1.7.tar.gz (506Kb): 506Kb downloaded
  Running setup.py egg_info for package PIL
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    
Installing collected packages: PIL
  Found existing installation: PIL 1.1.7
    Uninstalling PIL:
      Successfully uninstalled PIL
  Running setup.py install for PIL
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py
    --- using frameworks at /System/Library/Frameworks
    building '_imaging' extension
    /usr/bin/cc -fno-strict-aliasing -O3 -w -pipe -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DHAVE_LIBJPEG -DHAVE_LIBZ -I/System/Library/Frameworks/Tcl.framework/Headers -I/System/Library/Frameworks/Tk.framework/Headers -IlibImaging -I/Users/haoqili/.virtualenvs/playdoh/include -I/usr/local/include -I/usr/include -I/usr/local/Cellar/python/2.7.1/include/python2.7 -c _imaging.c -o build/temp.macosx-10.4-x86_64-2.7/_imaging.o
    ...
    /usr/bin/cc -L/usr/local/Cellar/readline/6.2.1/lib -bundle -undefined dynamic_lookup -L/usr/local/Cellar/readline/6.2.1/lib build/temp.macosx-10.4-x86_64-2.7/_imagingmath.o -L/usr/local/lib -L/Users/haoqili/.virtualenvs/playdoh/lib -L/usr/lib -o build/lib.macosx-10.4-x86_64-2.7/_imagingmath.so
    --------------------------------------------------------------------
    PIL 1.1.7 SETUP SUMMARY
    --------------------------------------------------------------------
    version       1.1.7
    platform      darwin 2.7.1 (r271:86832, Jun  6 2011, 13:57:48)
                  [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
    --------------------------------------------------------------------
    --- TKINTER support available
    --- JPEG support available
    --- ZLIB (PNG/ZIP) support available
    *** FREETYPE2 support not available
    *** LITTLECMS support not available
    --------------------------------------------------------------------
    To add a missing option, make sure you have the required
    library, and set the corresponding ROOT variable in the
    setup.py script.
    
    To check the build, run the selftest.py script.
    changing mode of build/scripts-2.7/pilconvert.py from 644 to 755
    changing mode of build/scripts-2.7/pildriver.py from 644 to 755
    changing mode of build/scripts-2.7/pilfile.py from 644 to 755
    changing mode of build/scripts-2.7/pilfont.py from 644 to 755
    changing mode of build/scripts-2.7/pilprint.py from 644 to 755
    
    changing mode of /Users/haoqili/.virtualenvs/playdoh/bin/pilconvert.py to 755
    changing mode of /Users/haoqili/.virtualenvs/playdoh/bin/pildriver.py to 755
    changing mode of /Users/haoqili/.virtualenvs/playdoh/bin/pilfile.py to 755
    changing mode of /Users/haoqili/.virtualenvs/playdoh/bin/pilfont.py to 755
    changing mode of /Users/haoqili/.virtualenvs/playdoh/bin/pilprint.py to 755
Successfully installed PIL
Cleaning up...

Tuesday, July 19, 2011

My Project's Packages

Todo:

1. update my own vendor with git clone --recursive git://github.com/mozilla/playdoh-lib.git ./vendor from playdoh doc

2. clean up my imports

3. clean up my vendor-local from virutal enviorments below from /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages


haoqili@host-3-248:15:44:10:~/.virtualenvs/playdoh/lib/python2.7/site-packages$ ls -l
total 1016
drwxr-xr-x  11 haoqili  staff     374 Jun 15 10:39 Crypto
drwxr-xr-x   4 haoqili  staff     136 Jun 30 09:41 Django-1.3-py2.7.egg
drwxr-xr-x  10 haoqili  staff     340 Jun  6 14:58 Jinja2-2.5.5-py2.7.egg-info
drwxr-xr-x   7 haoqili  staff     238 Jun  6 14:58 MySQL_python-1.2.3c1-py2.7.egg-info
drwxr-xr-x  15 haoqili  staff     510 Jun  6 14:58 MySQLdb
drwxr-xr-x  12 haoqili  staff     408 Jun 15 11:44 OpenSSL
drwxr-xr-x   4 haoqili  staff     136 Jun 15 10:09 Twisted-11.0.0_r32122-py2.7-macosx-10.4-x86_64.egg
-rwxr-xr-x   1 haoqili  staff   18328 Jun  6 14:58 _hashlib.so
-rwxr-xr-x   1 haoqili  staff   70072 Jun  6 14:58 _mysql.so
-rw-r--r--   1 haoqili  staff    2306 Jun  6 14:57 _mysql_exceptions.py
-rw-r--r--   1 haoqili  staff    4559 Jun  6 14:58 _mysql_exceptions.pyc
drwxr-xr-x   5 haoqili  staff     170 Jun 14 16:40 backports
drwxr-xr-x   7 haoqili  staff     238 Jun 14 16:40 backports.ssl_match_hostname-3.2a3-py2.7.egg-info
drwxr-xr-x   5 haoqili  staff     170 Jun  6 14:54 bcrypt
-rw-r--r--   1 haoqili  staff      48 Jun 13 12:00 bleach.egg-link
-rw-r--r--   1 haoqili  staff    6032 Jul  6 13:44 django_csp-1.0.1-py2.7.egg
-rw-r--r--   1 haoqili  staff    6854 Jun 30 09:41 django_ratelimit-0.1-py2.7.egg
drwxr-xr-x   7 haoqili  staff     238 Jun 29 19:46 django_registration-0.7-py2.7.egg-info
-rw-r--r--   1 haoqili  staff     509 Jul  6 13:44 easy-install.pth
drwxr-xr-x   7 haoqili  staff     238 Jun  6 14:58 hashlib-20081119-py2.7.egg-info
-rw-r--r--   1 haoqili  staff    4993 Jun  6 14:58 hashlib.py
-rw-r--r--   1 haoqili  staff    4452 Jun  6 14:58 hashlib.pyc
drwxr-xr-x   9 haoqili  staff     306 Jun  6 14:58 hmac-20101005-py2.7.egg-info
-rw-r--r--   1 haoqili  staff    4531 Jun  6 14:57 hmac.py
-rw-r--r--   1 haoqili  staff    4892 Jun  6 14:58 hmac.pyc
drwxr-xr-x  24 haoqili  staff     816 Jun 13 12:00 html5lib
drwxr-xr-x   7 haoqili  staff     238 Jun 13 12:00 html5lib-0.90-py2.7.egg-info
drwxr-xr-x  49 haoqili  staff    1666 Jun  6 14:58 jinja2
drwxr-xr-x   4 haoqili  staff     136 Jun  6 14:23 pip-1.0.1-py2.7.egg
drwxr-xr-x   8 haoqili  staff     272 Jun 15 11:44 pyOpenSSL-0.12-py2.7.egg-info
drwxr-xr-x   7 haoqili  staff     238 Jun  6 14:54 py_bcrypt-0.2-py2.7.egg-info
-rw-r--r--   1 haoqili  staff     629 Jun 15 10:46 pycrypto-2.0.1-py2.7.egg-info
-rw-r--r--   1 haoqili  staff    8399 Jun 29 20:31 recaptcha_client-1.0.6-py2.7.egg
drwxr-xr-x  18 haoqili  staff     612 Jun 29 19:46 registration
-rw-r--r--   1 haoqili  staff  332005 Jun  6 14:12 setuptools-0.6c11-py2.7.egg
-rw-r--r--   1 haoqili  staff      30 Jun 15 10:09 setuptools.pth
drwxr-xr-x   4 haoqili  staff     136 Jun 15 10:09 zope.interface-3.6.3-py2.7-macosx-10.4-x86_64.egg

Regex Combine lines

takes any end whitespace and combine with starting whitespace of next line
:%s/\s*$\n\s*/ /g

Django Playdoh Package Locations

I was confused when reading how to add packages and seeing that packages live in different locations.

jsocol clarified:

/packages is old-and-busted, use lib/python for non-git things
but you can't put any libraries with compiled components into the vendor lib (it means vendor can't contain anything with c/c++ components)
it's just a question of installing via git (or, well, pip install vcs+vcs://) or using PyPI and the name (e.g. "pip install foo")


pip install foo gives vendor-local/lib/python/foo

using git to install foo gives vendor-local/src/foo



This is what I did, with help from groovecoder. :D

playdoh (master)$ pip install --no-install --build=vendor-local/packages --src=vendor-local/src -I cef
Downloading/unpacking cef
  Downloading cef-0.2.tar.gz
  Running setup.py egg_info for package cef
    
Successfully downloaded cef

And then I found that cef is inside vendor-local/packages. :D

Now I need to add this path to vendor.pth. Groovecoder told me that "*.pth files are automatically included by the python interpreter"

playdoh/vendor-local (master)$ cat vendor.pth 
packages/cef

Now I can use cef!
playdoh (master)$ python manage.py shell
...
>>> from cef import log_cef
>>>

I could also have done
/playdoh (master)$ pip install -I --install-option="--home=`pwd`/vendor-local" cef
Downloading/unpacking cef
  Downloading cef-0.2.tar.gz
  Running setup.py egg_info for package cef
    
Installing collected packages: cef
  Running setup.py install for cef
    
Successfully installed cef
Cleaning up...
and have
playdoh/vendor-local/lib/python (master)$ ls
cef-0.2-py2.7.egg-info cef.py                 cef.pyc

Django urls, best practice

First iteration:
template html:
<a href="/msw/{{ page.slug }}/">back</a><



Second iteration:
template html:
<a href="{{ url('detail', 'richtext_and_safe_url') }}">back</a>
with
urls.py:
url(r'^(?P<input_slug>\w+)/$', views.detail, name='detail')


Third (best) iteration
template html:
<h1><a href="{{ page.reverse_url() }}">back</a></h1>
in models.py:
class Page(models.Model):
    slug = models.SlugField() # another way
    ....
    def reverse:_url(self):
        return reverse('detail', args=[self.slug])
        #return reverse('detail', args=['richtext_and_safe_url']) # hard coded way
be sure to pass in "page" in your views.py

inspiration

Sunday, July 17, 2011

jQuery hosting

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

I am tired of going to my site every time and get it from its source.

Friday, July 15, 2011

MySQL Update

update table_name set col_name='val_new' where col_name='val_indicator';

Where MySQL .frm files are located

1. Get into your mysql prompt

2. mysql> SHOW VARIABLES LIKE 'datadir';

go to the location of the value and cd into your database as the directory

Or you can use find!!

find -name . *.frm

Read more

Thursday, July 14, 2011

Wednesday, July 13, 2011

Django shell add user permissions and group permissions

Django doc

1. Start the shell, go to your maange.py
>>> python manage.py shell


2. Get the user

Either load one ...
>>> from django.contrib.auth import authenticate
>>> user = authenticate(username="johndoe", password="yourpw")

Or create one ...
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user(username='johndoe', email="",  password="yourpw")
Django should silently automatically save it, and you should see it under Users in your admin page. But if you want save it yourself, do:
>>> user.is_staff = False
>>> user.save


3. Check the user's permissions
user.get_all_permissions()
or
user.user_permissions.all()



1. Start the shell, go to your maange.py
>>> python manage.py shell

2. Create the group
>>> from django.contrib.auth.models import Group
>>> group = Group(name="GroupName")
>>> group.save()

NOTE that Django pre-made permissions are only suggestions, they only go as far as their string names. YOU have to implement them if you want to use them.

Python Lambda Function

Really nice article with nice examples.

Monday, July 11, 2011

Django reference/link to media/js from apps/myapp/views.py

I had to change a javascript file in media/js/my.js on every refresh of a page (apps/myapp/views.py), the path to open that js file is: f = open('media/js/my.js', 'r+').

See a live demo of this here.

Google recaptcha with CSP, hosting javascript locally

I display google's recaptcha from google's recaptcha javascript hosted on my own server after a little manipulation (since I have CSP turned on, I have to bypass the in-body script and setInterval). But I still need to ping google every time for a new challenge.

1. So I saved my domain's equivalent of the RecaptchaState javascript medai/js/google/recState.js.

2. Refresh this file in views.py's by calling this function:
def recaptchaRefresh():
    # get the Recaptcha state.
    url = "https://www.google.com/recaptcha/api/challenge?k=%s" % settings.RECAPTCHA_PUBLIC_KEY
    resock = urllib.urlopen(url)
    data = resock.read()
    resock.close()

    # extract the recaptcha state part of the string
    docloc = data.find("document.write")

    recaptchaState = data[:docloc]

    f = open('media/js/google/recState.js', 'r+')
    f.write(recaptchaState)
    f.close()

3. Copy paste recaptcha.js and make the following changes for CSP compatibility:

3.1 CSP blocks setIntervals that takes string parameters, so change it into a function:
//Recaptcha.timer_id = setInterval("Recaptcha.reload('t');", (a.timeout - 300) * 1E3) 
// -->
Recaptcha.timer_id = setInterval( function() {Recaptcha.reload('t'); }, (a.timeout - 300) * 1E3)

3.2 CSP blocks in-body javascript, host it externally
//} else document.write('<div id="recaptcha_widget_div" style="display:none"></div>'), document.write('<script>Recaptcha.widget = Recaptcha.$("recaptcha_widget_div"); Recaptcha.challenge_callback();<\/script>');
// -->
} else document.write('<div id="recaptcha_widget_div" style="display:none"></div>'), document.write('<script src="http://haoqili.scripts.mit.edu/js/test3.js"><\/script>');

where http://haoqili.scripts.mit.edu/js/test3.js has "Recaptcha.widget = Recaptcha.$("recaptcha_widget_div"); Recaptcha.challenge_callback();"

4. and in your template.html include the javascript from step 2 and 3.

5. Change your settings.py's CSP policies to have "http[s]://www.google.com" allowed in many places. See example

Recaptcha Hunt

The hunt to figure out how to do recaptcha with CSP is on its 4th day. A few things learned:

--> don't assume anything. I could have figured out the CSP_REPORT_ONLY if I actually tried amo's settings word by word.
--> copy paste the entire chunk

--> read and try to make sence of error messages. think about them.

Vim comment/uncomment block of lines with commands

Vim comment/uncomment block of lines with commands

working on lines 24 to 314

comment:
:24,314s/^/#/g

uncomment:
:24,314s/^#//g

Javascript indentation with beautifier

So useful!!!

Javascript comma!

The comma operator evaluates both of its operands (from left to right) and returns the value of the second operand.

as seen in Google recaptcha's js:

if (RecaptchaOptions.theme == "custom") {
    if (RecaptchaOptions.custom_theme_widget) Recaptcha.widget = Recaptcha.$(RecaptchaOptions.custom_theme_widget);
    Recaptcha.challenge_callback()
} else 
    document.write('<div id="recaptcha_widget_div" style="display:none"></div>'),
    document.write('<script>Recaptcha.widget = Recaptcha.$("recaptcha_widget_div"); Recaptcha.challenge_callback();<\/script>');

Sunday, July 10, 2011

How ReCaptcha should not work with in-body script

Big Question: Why doesn't my ReCaptchaField show up while AMO's ReCaptcha show up if our ReCaptchaField stuff matches exactly, including the parts that displays the in-body javascript? Issue on github

Skip to solution

How an In-Body Javascript is ultimately introduced in Google Recaptcha:

1. Your Django Form has ReCaptchaField. e.g. File: apps/users/forms.py
import captcha.fields

class UserRegisterForm(happyforms.ModelForm, PasswordMixin):
    passwords ...  
               
    recaptcha = captcha.fields.ReCaptchaField()

    ... irrelevent stuff ...

2. captcha.fields.ReCaptchaField() in zamboni/vendors (not shown on zamboni github), but it's on Mozilla's django-recaptcha
from django.conf import settings
from django import forms
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy as _

from recaptcha.client import captcha

from captcha.widgets import ReCaptcha

class ReCaptchaField(forms.CharField):

    default_error_messages = {
        'captcha_invalid': _(u'Invalid captcha')
    }

    def __init__(self, *args, **kwargs):
        self.widget = ReCaptcha
        self.required = True
        super(ReCaptchaField, self).__init__(*args, **kwargs)

    def clean(self, values):
        super(ReCaptchaField, self).clean(values[1])
        recaptcha_challenge_value = smart_unicode(values[0])
        recaptcha_response_value = smart_unicode(values[1])
        check_captcha = captcha.submit(recaptcha_challenge_value,
            recaptcha_response_value, settings.RECAPTCHA_PRIVATE_KEY, {})
        if not check_captcha.is_valid:
            raise forms.util.ValidationError(
                    self.error_messages['captcha_invalid'])
        return values[0]

3. from captcha.widgets import ReCaptcha
from django import forms
from django.utils.safestring import mark_safe
from django.conf import settings
from recaptcha.client import captcha

class ReCaptcha(forms.widgets.Widget):
    recaptcha_challenge_name = 'recaptcha_challenge_field'
    recaptcha_response_name = 'recaptcha_response_field'

    def render(self, name, value, attrs=None):
        use_ssl = False
        if 'RECAPTCHA_USE_SSL' in settings.__members__:
            use_ssl = settings.RECAPTCHA_USE_SSL
        return mark_safe(u'%s' %
                         captcha.displayhtml(settings.RECAPTCHA_PUBLIC_KEY,
                                             use_ssl=use_ssl))
     ...

4. from recaptcha.client (which is from Python's recaptcha client) import captcha
API_SSL_SERVER="https://api-secure.recaptcha.net"
API_SERVER="http://api.recaptcha.net"

def displayhtml (public_key,
                 use_ssl = False,
                 error = None):
    """Gets the HTML to display for reCAPTCHA

    public_key -- The public api key
    use_ssl -- Should the request be sent over ssl?
    error -- An error message to display (from RecaptchaResponse.error_code)"""

    error_param = ''
    if error:
        error_param = '&error=%s' % error

    if use_ssl:
        server = API_SSL_SERVER
    else:
        server = API_SERVER

    return """<script type="text/javascript" src="%(ApiServer)s/challenge?k=%(PublicKey)s%(ErrorParam)s"></script> # this src contains in-body script!!

<noscript>
  <iframe src="%(ApiServer)s/noscript?k=%(PublicKey)s%(ErrorParam)s" height="300" width="500" frameborder="0"></iframe><br />
  <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
  <input type='hidden' name='recaptcha_response_field' value='manual_challenge' />
</noscript>
""" % { 
        'ApiServer' : server,
        'PublicKey' : public_key,
        'ErrorParam' : error_param,
        }   

5. The src directs to (key varies for host, content is the same) https://www.google.com/recaptcha/api/challenge?k=6LcCCsYSAAAAACm9eF4n2ttYMU4TFbDMXMO-Bw2q


6. Which then directs to https://www.google.com/recaptcha/api/js/recaptcha.js that contains an in-body script:
document.write('<script>Recaptcha.widget = Recaptcha.$("recaptcha_widget_div"); Recaptcha.challenge_callback();<\/script>');

SOLVED!!!: click to see commit 2 break throughs, 1 question:

BT1: change into amo register's custom RecaptchaOptions to avoid in-body script.
BT2: have to allow setInterval like 'CSP_OPTIONS = ("eval-script",)'.
Q1: How come amo register does not have "setInterval blocked by CSP" problem even without CSP_OPTIONS?

BT1: In-body script is skipped with a custom RecaptchaOptions
as seen in Google recaptcha's js, note the javascript comma:
if (RecaptchaOptions.theme == "custom") {
    if (RecaptchaOptions.custom_theme_widget) Recaptcha.widget = Recaptcha.$(RecaptchaOptions.custom_theme_widget);
    Recaptcha.challenge_callback()
} else 
    document.write('<div id="recaptcha_widget_div" style="display:none"></div>'),
    document.write('<script>Recaptcha.widget = Recaptcha.$("recaptcha_widget_div"); Recaptcha.challenge_callback();<\/script>');
So the entire "else", which contains the in-body javascript, is skipped!

BT2: Make CSP policy allow setInterval
add CSP_OPTIONS = ("eval-script",) into settings.py
solves the "call to setInterval blocked by CSP" issue (seen in Firebug).

Q1: Why doesn't amo have this issue?

Solved: because amo has CSP_REPORT_ONLY, meaning that CSP is not actually enforced, but only reported!

---------

Have to get around setInterval(). CSP only blocks setInterval if it's called with a string argument.

So let's call it with a function!

Continued on this post.

How Add-ons Mozilla does ReCaptcha

Firefox add-ons register

Code comments are potentially mine.

1. def register in apps/users/views.py
@anonymous_csrf
def register(request):
    if request.user.is_authenticated():
        messages.info(request, _("You are already logged in to an account."))
        form = None
    elif request.method == 'POST':

        form = forms.UserRegisterForm(request.POST) # Always have recaptcha

        if form.is_valid(): # is_valid() does all the form clean()
            ... [save form stuff] ...
    else:
        form = forms.UserRegisterForm()
    return jingo.render(request, 'users/register.html', {'form': form, })

2. UserRegisterForm has ReCaptchaField. File: apps/users/forms.py
import captcha.fields

class UserRegisterForm(happyforms.ModelForm, PasswordMixin):
    passwords ...  
               
    recaptcha = captcha.fields.ReCaptchaField()

    ... irrelevent stuff ...

3. captcha.fields.ReCaptchaField() in zamboni/vendors (not shown on zamboni github), but it's on Mozilla's django-recaptcha
from django.conf import settings
from django import forms
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy as _

from recaptcha.client import captcha

from captcha.widgets import ReCaptcha

class ReCaptchaField(forms.CharField):

    default_error_messages = {
        'captcha_invalid': _(u'Invalid captcha')
    }

    def __init__(self, *args, **kwargs):
        self.widget = ReCaptcha
        self.required = True
        super(ReCaptchaField, self).__init__(*args, **kwargs)

    def clean(self, values):
        super(ReCaptchaField, self).clean(values[1])
        recaptcha_challenge_value = smart_unicode(values[0])
        recaptcha_response_value = smart_unicode(values[1])
        check_captcha = captcha.submit(recaptcha_challenge_value,
            recaptcha_response_value, settings.RECAPTCHA_PRIVATE_KEY, {})
        if not check_captcha.is_valid:
            raise forms.util.ValidationError(
                    self.error_messages['captcha_invalid'])
        return values[0]

Which, btw is exactly what I have for my ReCaptchaField. The ReCaptcha widget will ultimately introduce an in-body javascript.
Click to read more about ReCaptcha and In-Line Javascript / CSP

So the only difference in reCaptcha is how it's displayed on the html page. Let's investigate.

4. Register page template: apps/users/templates/users/register.html, taken from step 1 views.py
{% block js %}{% include("amo/recaptcha_js.html") %}{% endblock %}
...
{% if settings.RECAPTCHA_PRIVATE_KEY %}
    {{ recaptcha(form) }}
{% else %}
    <p>
       Welcome Robots, ReCaptcha has been disabled for your convenience.
       Spam at Wil.
     </p>
{% endif %}
The apps/amo/templates/amo/recaptcha_js.html has:
{% if request.user.is_anonymous() %}
  <script type="text/javascript" src="{{ settings.RECAPTCHA_URL }}"></script>
{% endif %}
where
# in settings.py
RECAPTCHA_PUBLIC_KEY = "blah"
RECAPTCHA_PRIVATE_KEY = "blah"
RECAPTCHA_URL = ('https://www.google.com/recaptcha/api/challenge?k=%s' %
                 RECAPTCHA_PUBLIC_KEY)

Unless you have the private key (which bots don't), you can see the recaptcha form.


5. def recaptcha() in apps/amo/helpers.py
Read about the inclusion_tag
@register.inclusion_tag('amo/recaptcha.html')
@jinja2.contextfunction
def recaptcha(context, form):
    d = dict(context.items())
    d.update(form=form)
    return d

6. recaptcha.html lives in apps/amo/templates/amo/recaptcha.hhtml"
{% from 'includes/forms.html' import required %}
<label for="recaptcha_response_field">
  {{ _('Are you human?') }} {{ required() }}
</label>
{% trans %}
  <p>
    Please enter <strong>both words</strong> below,
    <strong>separated by a space</strong>.
  </p>
  <p>
    If this is hard to read, you can
    <a href="#" id="recaptcha_different">try different words</a> or
    <a href="#" id="recaptcha_audio">listen to something</a> instead.
  </p>
{% endtrans %}
<div id="recaptcha_image"></div>
<p>
  <input type="text" name="recaptcha_response_field"
         id="recaptcha_response_field" size="30" />
</p>
<p><a href="#" id="recaptcha_help">{{ _("What's this?") }}</a></p>
{{ form.recaptcha.errors }}

7. div ids link to function in javascript here: media/js/zamboni/users.js
// Recaptcha
var RecaptchaOptions = { theme : 'custom' };

$('#recaptcha_different').click(function(e) {
    e.preventDefault();
    Recaptcha.reload();
});

$('#recaptcha_audio').click(function(e) {
    e.preventDefault();
    Recaptcha.switch_type('audio');
});

$('#recaptcha_help').click(function(e) {
    e.preventDefault();
    Recaptcha.showhelp();
});
These Recaptcha's functions are defined in Google's recaptcha.

Saturday, July 9, 2011

Find where a module is

Run python manage.py shell.
Import captcha.fields
help(captcha.fields) or captcha.__file__ or captcha.fields shown below
    In [3]: import captcha.fields
     
    In [4]: captcha.fields?
    Type:      module
    Base Class:     <type 'module'>
    String Form:    <module 'captcha.fields' from '/Users/jbalogh/dev/zamboni/vendor/src/django-recaptcha/captcha/fields.pyc'>
    Namespace:      Interactive
    File:      /Users/uname/dev/zamboni/vendor/src/django-recaptcha/captcha/fields.py
    Docstring:
        <no docstring> 

It's actually here: django-recaptcha already done before!!, not here. I wish I had know that the django-recaptcha existed before I did this.

Friday, July 8, 2011

Where to see CSP Policy

x-content-security-policy... policy-uri /path/to/policy

and then go to www.domain.name/path/to/poloice

How Django form calls clean() method

I was reading the Django docs on forms which says:
Validation of a Form is split into several steps ... [calls]
- [1] to_python()
- [2] validate()
- [3] run_validators()
- [4] clean()
- [5] clean_()


This is how these things work in the source code:

1. each field's clean() method takes care of the first 3 items

# src/django/django/forms/fields.py, comments mine

    class Field(object):
        ...
        def clean(self, value):
            """
            Validates the given value and returns its "cleaned" value as an
            appropriate Python object.

            Raises ValidationError for any errors.
            """
            value = self.to_python(value)    # [1]
            self.validate(value)             # [2]
            self.run_validators(value)       # [3]
            return value

2. aoeu

# src/django/django/forms/fields.py, comments mine

    class BaseForm(StrAndUnicode):
        ...
        def full_clean(self):
            """
            Cleans all of self.data and populates self._errors and
            self.cleaned_data.
            """
            self._errors = ErrorDict()
            if not self.is_bound: # Stop further processing.
                return
            self.cleaned_data = {}
            # If the form is permitted to be empty, and none of the form data has
            # changed from the initial data, short circuit any validation.
            if self.empty_permitted and not self.has_changed():
                return
            self._clean_fields()
            self._clean_form()
            self._post_clean()
            if self._errors:
                del self.cleaned_data

        def _clean_fields(self):
            for name, field in self.fields.items():
                # value_from_datadict() gets the data from the data dictionaries.
                # Each widget type knows how to retrieve its own data, because some
                # widgets split data over several HTML fields.
                value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
                try:
                    if isinstance(field, FileField):
                        initial = self.initial.get(name, field.initial)
                        # calls step 1's stuff
                        value = field.clean(value, initial) 
                    else:
                        value = field.clean(value)
                    self.cleaned_data[name] = value
                    if hasattr(self, 'clean_%s' % name):
                        value = getattr(self, 'clean_%s' % name)()
                        self.cleaned_data[name] = value
                except ValidationError, e:
                    self._errors[name] = self.error_class(e.messages)
                    if name in self.cleaned_data:
                        del self.cleaned_data[name]

... calls some alias ...
figure it out yourself

Thursday, July 7, 2011

Wednesday, July 6, 2011

When you can't onclick() in html

Change:

<button onclick="myFunction()">Click me</button>

To one of:
way 1 with .onclick with anonymous function
<body>
    <button id="myButton">Click me</button>
    <script>document.getElementById("myButton").onclick = function(){ stuff };</script>
</body>

way 2 with .onclick with named function
<body>
    <button id="myButton">Click me</button>
    <script>function myFunction() { stuff };
    document.getElementById("myButton").onclick = myFunction;</script>
</body>

way 3 with .addEventListener() with named function
<body>
    <button id="myButton">Click me</button>
    <script>document.getElementById("myButton").addEventListener('click', myFunction, false);</script>
</body>

Remember to put the addEventListener script after you have created the button. If you have to put it in the head, put the line of script inside a jQuery ready like
<!-- try not to do this though -->
<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            document.getElementById("myButton").addEventListener('click', myFunction, false);
        }
</script>
</head> 

<body>
    <button id="checkButton">Click me</button>
</body>

But it's better practice to put js right before the closing of the body tag.



If your function has arguments...

Change:

<button onclick="myFunction('arg1')">Click me</button>

To
<body>
    <button id="myButton">Click me</button>
    <script>document.getElementById("myButton").addEventListener('click', function(){ myFunction('arg1') }, false);</script>
</body>

Where to put JS

I learned that JS is executed as soon as its parsed. So it's best to put <script> right before the </body> closing tag. For example: http://support.mozilla.com/en-US/home 

Tuesday, July 5, 2011

SQL Query for Top 500 Passwords

It's actually 499 because "0" was repeated. Source.

insert into table_name (password_column) values ("123456"),("porsche"),("firebird"),("prince"),("rosebud"),("password"),("guitar"),("butter"),("beach"),("jaguar"),("12345678"),("chelsea"),("united"),("amateur"),("great"),("1234"),("black"),("turtle"),("7777777"),("cool"),("pussy"),("diamond"),("steelers"),("muffin"),("cooper"),("12345"),("nascar"),("tiffany"),("redsox"),("1313"),("dragon"),("jackson"),("zxcvbn"),("star"),("scorpio"),("qwerty"),("cameron"),("tomcat"),("testing"),("mountain"),("696969"),("654321"),("golf"),("shannon"),("madison"),("mustang"),("computer"),("bond007"),("murphy"),("987654"),("letmein"),("amanda"),("bear"),("frank"),("brazil"),("baseball"),("wizard"),("tiger"),("hannah"),("lauren"),("master"),("xxxxxxxx"),("doctor"),("dave"),("japan"),("michael"),("money"),("gateway"),("eagle1"),("naked"),("football"),("phoenix"),("gators"),("11111"),("squirt"),("shadow"),("mickey"),("angel"),("mother"),("stars"),("monkey"),("bailey"),("junior"),("nathan"),("apple"),("abc123"),("knight"),("thx1138"),("raiders"),("alexis"),("pass"),("iceman"),("porno"),("steve"),("aaaa"),("fuckme"),("tigers"),("badboy"),("forever"),("bonnie"),("6969"),("purple"),("debbie"),("angela"),("peaches"),("jordan"),("andrea"),("spider"),("viper"),("jasmine"),("harley"),("horny"),("melissa"),("ou812"),("kevin"),("ranger"),("dakota"),("booger"),("jake"),("matt"),("iwantu"),("aaaaaa"),("1212"),("lovers"),("qwertyui"),("jennifer"),("player"),("flyers"),("suckit"),("danielle"),("hunter"),("sunshine"),("fish"),("gregory"),("beaver"),("fuck"),("morgan"),("porn"),("buddy"),("4321"),("2000"),("starwars"),("matrix"),("whatever"),("4128"),("test"),("boomer"),("teens"),("young"),("runner"),("batman"),("cowboys"),("scooby"),("nicholas"),("swimming"),("trustno1"),("edward"),("jason"),("lucky"),("dolphin"),("thomas"),("charles"),("walter"),("helpme"),("gordon"),("tigger"),("girls"),("cumshot"),("jackie"),("casper"),("robert"),("booboo"),("boston"),("monica"),("stupid"),("access"),("coffee"),("braves"),("midnight"),("shit"),("love"),("xxxxxx"),("yankee"),("college"),("saturn"),("buster"),("bulldog"),("lover"),("baby"),("gemini"),("1234567"),("ncc1701"),("barney"),("cunt"),("apples"),("soccer"),("rabbit"),("victor"),("brian"),("august"),("hockey"),("peanut"),("tucker"),("mark"),("3333"),("killer"),("john"),("princess"),("startrek"),("canada"),("george"),("johnny"),("mercedes"),("sierra"),("blazer"),("sexy"),("gandalf"),("5150"),("leather"),("cumming"),("andrew"),("spanky"),("doggie"),("232323"),("hunting"),("charlie"),("winter"),("zzzzzz"),("4444"),("kitty"),("superman"),("brandy"),("gunner"),("beavis"),("rainbow"),("asshole"),("compaq"),("horney"),("bigcock"),("112233"),("fuckyou"),("carlos"),("bubba"),("happy"),("arthur"),("dallas"),("tennis"),("2112"),("sophie"),("cream"),("jessica"),("james"),("fred"),("ladies"),("calvin"),("panties"),("mike"),("johnson"),("naughty"),("shaved"),("pepper"),("brandon"),("xxxxx"),("giants"),("surfer"),("1111"),("fender"),("tits"),("booty"),("samson"),("austin"),("anthony"),("member"),("blonde"),("kelly"),("william"),("blowme"),("boobs"),("fucked"),("paul"),("daniel"),("ferrari"),("donald"),("golden"),("mine"),("golfer"),("cookie"),("bigdaddy"),("king"),("summer"),("chicken"),("bronco"),("fire"),("racing"),("heather"),("maverick"),("penis"),("sandra"),("5555"),("hammer"),("chicago"),("voyager"),("pookie"),("eagle"),("yankees"),("joseph"),("rangers"),("packers"),("hentai"),("joshua"),("diablo"),("birdie"),("einstein"),("newyork"),("maggie"),("sexsex"),("trouble"),("dolphins"),("little"),("biteme"),("hardcore"),("white"),("0"),("redwings"),("enter"),("666666"),("topgun"),("chevy"),("smith"),("ashley"),("willie"),("bigtits"),("winston"),("sticky"),("thunder"),("welcome"),("bitches"),("warrior"),("cocacola"),("cowboy"),("chris"),("green"),("sammy"),("animal"),("silver"),("panther"),("super"),("slut"),("broncos"),("richard"),("yamaha"),("qazwsx"),("8675309"),("private"),("fucker"),("justin"),("magic"),("zxcvbnm"),("skippy"),("orange"),("banana"),("lakers"),("nipples"),("marvin"),("merlin"),("driver"),("rachel"),("power"),("blondes"),("michelle"),("marine"),("slayer"),("victoria"),("enjoy"),("corvette"),("angels"),("scott"),("asdfgh"),("girl"),("bigdog"),("fishing"),("2222"),("vagina"),("apollo"),("cheese"),("david"),("asdf"),("toyota"),("parker"),("matthew"),("maddog"),("video"),("travis"),("qwert"),("121212"),("hooters"),("london"),("hotdog"),("time"),("patrick"),("wilson"),("7777"),("paris"),("sydney"),("martin"),("butthead"),("marlboro"),("rock"),("women"),("freedom"),("dennis"),("srinivas"),("xxxx"),("voodoo"),("ginger"),("fucking"),("internet"),("extreme"),("magnum"),("blowjob"),("captain"),("action"),("redskins"),("juice"),("nicole"),("bigdick"),("carter"),("erotic"),("abgrtyu"),("sparky"),("chester"),("jasper"),("dirty"),("777777"),("yellow"),("smokey"),("monster"),("ford"),("dreams"),("camaro"),("xavier"),("teresa"),("freddy"),("maxwell"),("secret"),("steven"),("jeremy"),("arsenal"),("music"),("dick"),("viking"),("11111111"),("access14"),("rush2112"),("falcon"),("snoopy"),("bill"),("wolf"),("russia"),("taylor"),("blue"),("crystal"),("nipple"),("scorpion"),("111111"),("eagles"),("peter"),("iloveyou"),("rebecca"),("131313"),("winner"),("pussies"),("alex"),("tester"),("123123"),("samantha"),("cock"),("florida"),("mistress"),("bitch"),("house"),("beer"),("eric"),("phantom"),("hello"),("miller"),("rocket"),("legend"),("billy"),("scooter"),("flower"),("theman"),("movie"),("6666"),("please"),("jack"),("oliver"),("success"),("albert");

ReCaptcha on Django

These steps are a simplified/less-hassle version of marcofucci's directions. Thank you marcofucci for helping me setting up recaptcha initially.

1. Get your public and private recaptcha keys

2. Add keys to your settings: settings_local.py, or settings.py if you don't have your code in public
        RECAPTCHA_PUBLIC_KEY = 'insert your public key'
        RECAPTCHA_PRIVATE_KEY = 'insert your private key'

3. Download Python's Recaptcha-client
        1. cd to the directory, e.g. recaptcha-client-x.x.x
        2. python setup.py install

Click for alternative steps 3 and 4
3. pip or easy_install to get Python's Recaptcha-client

4. don't copy anything

5. all the same except the line
from your_app.captcha import submit, displayhtml
is changed into
from captcha import submit, displayhtml

4. Copy captcha.py to your app folder: cp recaptcha-client-x.x.x/recaptcha/client/captcha.py path_to_your_django/apps/your_app So now you should see that this exists: path_to_your_django/apps/your_app/captcha.py

5. Add ReCaptchaField into your forms Differences to marcofucci's step 4 are highlighted.
#add to path_to_your_django/apps/your_app/forms.py

from django.conf import settings
from django import forms
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe

from your_app.captcha import submit, displayhtml

class ReCaptchaField(forms.CharField):
    default_error_messages = {
        'captcha_invalid': _(u'Invalid captcha')
    }

    def __init__(self, *args, **kwargs):
        self.widget = ReCaptcha
        self.required = True
        super(ReCaptchaField, self).__init__(*args, **kwargs)

    def clean(self, values):
        super(ReCaptchaField, self).clean(values[1])
        recaptcha_challenge_value = smart_unicode(values[0])
        recaptcha_response_value = smart_unicode(values[1])
        check_captcha = submit(recaptcha_challenge_value,
            recaptcha_response_value, settings.RECAPTCHA_PRIVATE_KEY, {})
        if not check_captcha.is_valid:
            raise forms.util.ValidationError(self.error_messages['captcha_invalid'])
        return values[0]

class ReCaptcha(forms.widgets.Widget):
    recaptcha_challenge_name = 'recaptcha_challenge_field'
    recaptcha_response_name = 'recaptcha_response_field'

    def render(self, name, value, attrs=None):
        return mark_safe(u'%s' % displayhtml(settings.RECAPTCHA_PUBLIC_KEY))

    def value_from_datadict(self, data, files, name):
        return [data.get(self.recaptcha_challenge_name, None),
            data.get(self.recaptcha_response_name, None)]

6. Put it in my form! In contrast to, marcifucci's version, I use the built-in forms.
#add to path_to_your_django/apps/your_app/forms.py

from django.contrib.auth import forms as auth_forms

class UserCreationForm(auth_forms.UserCreationForm):
    recaptcha = ReCaptchaField(label="I'm a human")

class AuthenticationForm(auth_forms.AuthenticationForm):
    recaptcha = ReCaptchaField(label="I'm a human")

7. See my examples on github:
- step 4 copied in captcha.py
- step 5, 6 forms.py

8. If you have more questions, feel free to email me.

Sunday, July 3, 2011

Django Authentication / Login

It's a mess to learn this. The best way is to follow someone's example and pick out pieces (login, register, logout) that you need.
Examples:
- TODO: insert my simple example here
zabmoni's users


Tutorial:
Django Book's big chapter on Authentication, Users and Registration. A little bit of everything.  I would consider this to be a good intro, if you have the patience to read through it all thoroughly.


Django User Authentication
- user fields
user methods
built-in forms
- group and permission stuff.


Django Sessions
important SESSIONS settings (see this blog post about my bad session experience)
session (dictionary) methods

---

 The Django Book's Forms.

Solved - Django "Your Web browser doesn't appear to have cookies enabled."

If you get this error message on your Django login-page:


     Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in.

and you have made sure that your browser DOES have cookies enabled, then you should check your settings.py's SESSION_* configurations very carefully.

Maybe you have the SESSION_COOKIE_SECURE set to True accidentally when you don't have SSL.
Maybe you have the SESSION_COOKIE_DOMAIN set to a domain that's actually not your domain.

#settings.py

# If not SSL, should be false
SESSION_COOKIE_SECURE = False
# Check other SESSION_* settings too

bashrc improvements for git

show which brach on
git auto complete

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;34m\]\u@\h\[\033[00m\]:\[\033[01;33m\]\t\[\033[ 00m\]:\[\033[01;32m\]\w\[\033[00m\]$(__git_ps1 " (%s)")\$ '


source /usr/local/etc/bash_completion.d/git-completion.bash

Friday, July 1, 2011

Google Prettify

Languages from stack overflow.

Put on blogger.

PHP concat variable name with str/string

In PHP, concatenate variable names with strings by using curly brackets {}.

The Shorter version
<?php
       // setting every $nvar* to ":)"
       $nameArray = array("Alice", "Bob", "Charlie");
       foreach ($nameArray as $name) {
           ${ "nvar" . $name } = ":)"; 
       }
?>

and

The Longer version
<?php
       // setting every $nvar* to ":)"
       $nameArray = array("Alice", "Bob", "Charlie");
       foreach ($nameArray as $name) {
           $nameVar = "nvar" . $name;
           ${ $nameVar } = ":)"; 
       }   
?>

are the same as

The Brute-force version
<?php
       // setting every $nvar* to ":)"
       $nvarAlice = ":)";
       $nvarBob = ":)";
       $nvarCharlie = ":)";
?>

Read documentations here.

Thursday, June 30, 2011

install jsocol's ratelimit

(playdoh)haoqili@host-7-136:09:41:17:~/dev/playdoh/playdoh/playdoh/django-ratelimit$ python setup.py install
installation outputs
running install
running bdist_egg
running egg_info
creating django_ratelimit.egg-info
writing requirements to django_ratelimit.egg-info/requires.txt
writing django_ratelimit.egg-info/PKG-INFO
writing top-level names to django_ratelimit.egg-info/top_level.txt
writing dependency_links to django_ratelimit.egg-info/dependency_links.txt
writing requirements to django_ratelimit.egg-info/requires.txt
writing django_ratelimit.egg-info/PKG-INFO
writing top-level names to django_ratelimit.egg-info/top_level.txt
writing dependency_links to django_ratelimit.egg-info/dependency_links.txt
writing manifest file 'django_ratelimit.egg-info/SOURCES.txt'
reading manifest file 'django_ratelimit.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'django_ratelimit.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.4-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/ratelimit
copying ratelimit/__init__.py -> build/lib/ratelimit
copying ratelimit/decorators.py -> build/lib/ratelimit
creating build/lib/ratelimit/backends
copying ratelimit/backends/__init__.py -> build/lib/ratelimit/backends
copying ratelimit/backends/cachebe.py -> build/lib/ratelimit/backends
creating build/bdist.macosx-10.4-x86_64
creating build/bdist.macosx-10.4-x86_64/egg
creating build/bdist.macosx-10.4-x86_64/egg/ratelimit
copying build/lib/ratelimit/__init__.py -> build/bdist.macosx-10.4-x86_64/egg/ratelimit
creating build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends
copying build/lib/ratelimit/backends/__init__.py -> build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends
copying build/lib/ratelimit/backends/cachebe.py -> build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends
copying build/lib/ratelimit/decorators.py -> build/bdist.macosx-10.4-x86_64/egg/ratelimit
byte-compiling build/bdist.macosx-10.4-x86_64/egg/ratelimit/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends/cachebe.py to cachebe.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/ratelimit/decorators.py to decorators.pyc
creating build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/PKG-INFO -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/SOURCES.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/dependency_links.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/requires.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/top_level.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating dist
creating 'dist/django_ratelimit-0.1-py2.7.egg' and adding 'build/bdist.macosx-10.4-x86_64/egg' to it
removing 'build/bdist.macosx-10.4-x86_64/egg' (and everything under it)
Processing django_ratelimit-0.1-py2.7.egg
Copying django_ratelimit-0.1-py2.7.egg to /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages
Adding django-ratelimit 0.1 to easy-install.pth file

Installed /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages/django_ratelimit-0.1-py2.7.egg
Processing dependencies for django-ratelimit==0.1
Searching for django
Reading http://pypi.python.org/simple/django/
Reading http://www.djangoproject.com/
Best match: Django 1.3
Downloading http://media.djangoproject.com/releases/1.3/Django-1.3.tar.gz
Processing Django-1.3.tar.gz
Running Django-1.3/setup.py -q bdist_egg --dist-dir /var/folders/yl/yltlIu+3EZy3rSMmgXn6yE+++TI/-Tmp-/easy_install-TVy96n/Django-1.3/egg-dist-tmp-MUK8NL
zip_safe flag not set; analyzing archive contents...
django.conf.__init__: module references __file__
django.conf.project_template.manage: module references __file__
django.contrib.admindocs.views: module references __file__
django.contrib.auth.tests.views: module references __file__
django.contrib.flatpages.tests.csrf: module references __file__
django.contrib.flatpages.tests.middleware: module references __file__
django.contrib.flatpages.tests.templatetags: module references __file__
django.contrib.flatpages.tests.views: module references __file__
django.contrib.formtools.tests.__init__: module references __file__
django.contrib.gis.geometry.test_data: module references __file__
django.contrib.gis.tests.geo3d.tests: module references __file__
django.contrib.gis.tests.geogapp.tests: module references __file__
django.contrib.gis.tests.layermap.tests: module references __file__
django.contrib.sitemaps.tests.basic: module references __file__
django.contrib.staticfiles.storage: module references __file__
django.core.management.__init__: module references __file__
django.core.management.__init__: module references __path__
django.core.management.base: module references __path__
django.core.management.sql: module references __file__
django.core.management.commands.loaddata: module references __file__
django.core.management.commands.loaddata: module references __path__
django.core.management.commands.makemessages: module references __file__
django.core.servers.basehttp: module references __path__
django.db.utils: module references __file__
django.db.models.loading: module references __file__
django.template.loaders.app_directories: module references __file__
django.test._doctest: module references __file__
django.test._doctest: module MAY be using inspect.getsourcefile
django.test.simple: module references __file__
django.utils.autoreload: module references __file__
django.utils.module_loading: module references __path__
django.utils.version: module references __path__
django.utils.translation.__init__: module references __file__
django.utils.translation.trans_real: module references __file__
django.utils.unittest.collector: module references __file__
django.utils.unittest.loader: module references __file__
django.views.i18n: module references __file__
Adding Django 1.3 to easy-install.pth file
Installing django-admin.py script to /Users/haoqili/.virtualenvs/playdoh/bin

Installed /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages/Django-1.3-py2.7.egg
Finished processing dependencies for django-ratelimit==0.1