woensdag 8 augustus 2012

raw_input in matplotlib with plot interaction?

When working with data, you sometimes need to view the data and give input on how to continue. However, a simple
plot([1,2],[1,2])
answer = raw_input()
will not work: the plot GUI will block while the raw_input() is waiting. The following is a (admittedly hacky) solution to this problem: run raw_input() in a seperate thread, and poll the GUI using waitforbuttonpress():
import threading
import matplotlib
from __builtin__ import raw_input as original_raw_input

def raw_input(*args, **kwargs):
    value = []
    ri = lambda: value.append(original_raw_input(*args, **kwargs))
    
    t = threading.Thread(target=ri)
    t.start()
    while t.isAlive():
        if matplotlib._pylab_helpers.Gcf.get_all_fig_managers():
            matplotlib.pylab.waitforbuttonpress(timeout=0.1)
        else:
            t.join()
    
    return value[0]
raw_input.__doc__ = original_raw_input.__doc__

if __name__=="__main__":
    plot([1,2],[1,2])
    print raw_input("...> ")
When a value is entered, the program might wait (for up to 0.1s), which is a fairly minor issue. There's probably also a way to deadlock it - but hey, a data analysis script is not production code ;-)

dinsdag 12 oktober 2010

git-http-backend on shared hosting, with push

There are several posts describing how to get git pull using git-http-backend working on shared hosting, for example this post by mobiphil. However, following those steps, I was left with an unclear 'code 22' error when pushing.

In this post, I will describe shortly how I set-up git on my shared hosting account in a way that does allow pushing.

It should be possible to do this without shell access, but I have not tried this.

1. Getting git


Git was not available on the server by default, so I downloaded a reasonable RPM package:


~ $ mkdir git && cd git
~/git $ wget http://packages.sw.be/git/git-1.7.3-1.el5.rf.x86_64.rpm
~/git $ rpm2cpio git-1.7.3-1.el5.rf.x86_64.rpm | cpio -idmv
25926 blocks
~/git $ usr/bin/git
usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
[-p|--paginate|--no-pager] [--no-replace-objects]
[--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
[-c name=value] [--help]
COMMAND [ARGS]


2. Create a CGI handler script




~ $ cat > public_html/cgi_bin/git.cgi
#!/bin/sh
export GIT_PROJECT_ROOT=/home/me/git/repos/

if [ -z "$REMOTE_USER" ]
then
export REMOTE_USER=$REDIRECT_REMOTE_USER
fi

/home/me/git/usr/libexec/git-core/git-http-backend

Using absolute paths is probably not necessary, but hey, why not.

Important things to notice:

  1. The GIT_PROJECT_ROOT variable should be defined correctly
  2. If you want to export all git repositories by default, add export GIT_HTTP_EXPORT_ALL=T
  3. REMOTE_USER needs to be defined for pushing to work. Due to redirects, sometimes only REDIRECT_REMOTE_USER is defined. Hence, REMOTE_USER will then be set to REDIRECT_REMOTE_USER.
  4. git-http-backend is not in usr/bin but in usr/libexec/git-core


This is enough to get public read access working onder an URL such as http://host/cgi-bin/git.cgi/repos. If you want a nicer URL, read on.

Note: Pushing will fail with error code '22'.

3. htaccess URL rewriting and authentication


At the moment I only have a few repositories, so I chose the following approach. In public_html, create a directory structure git/repos1, git/repos2, etc. In each of these directories, add an .htaccess file:


~/public_html/git/repos1 $ cat > .htaccess

AuthType Basic
AuthName "Git repository I"
AuthUserFile "/home/me/.htpasswds/gitrepos1/passwd"
require valid-user
RewriteEngine On
RewriteBase /git/repos1
RewriteRule ^(.*)$ /cgi-bin/git.cgi/repos1/$1


This will now allow access using the (authenticated) url http://host/git/repos1, which will allow you to push /and/ pull!

4. Preventing direct access to git.cgi


To prevent people from accessing git.cgi directly, I used the following snippet on top of the git.cgi file:

if [[ $REQUEST_URI != /git/* ]]
then
echo Status: 403 Forbidden
echo Content-type: text/plain
echo
echo Direct access to git.cgi is not allowed
exit
fi