This is a howto to install Redmine on Ubuntu Natty (probably works on Debian too) with Nginx, Mongrel and Supervisord. The listed commands usually assume root permissions.

Involved software:

Redmine
Duh, the software you want to install :)
Nginx
A fast webserver/proxy from Russia
Mongrel
The software used to serve redmine
Supervisor
A supervisor daemon written in Python, it automatically restarts the Mongrel process in case it dies.

First, add the PPA for the currently stable Nginx version (the Ubuntu version is outdated).

add-apt-repository ppa:nginx/stable

Then install redmine using your desired backend (e.g. redmine-sqlite), and the supervisor and nginx packages.

aptitude install redmine redmine-sqlite nginx supervisor

Install the mongrel gem.

gem install mongrel

Set up redmine…

cd /usr/share/redmine
touch log/production.log
chmod 777 log log/production.log

Then add the mongrel initializer to redmine (see this bug):

cd config/initializers
wget 'https://gist.github.com/raw/826692/cb0dcf784c30e6a6d00c631f350de99ab99e389d/mongrel.rb'

Configure nginx:

cd /etc/nginx/sites-enabled
touch ../sites-available/redmine
ln -s ../sites-available/redmine
vim redmine

Add the following configuration (adjust to your likings):

upstream redmine_server {
        server localhost:3000 fail_timeout=0;
}
 
server {
        listen 80;
        server_name domain.example.com;
 
        root /usr/share/redmine/public;
 
        access_log /var/log/nginx/redmine.access.log;
        error_log /var/log/nginx/redmine.error.log info;
 
        keepalive_timeout 5;
 
        location / {
                try_files $uri/index.html $uri.html $uri @mongrel;
        }
 
        location @mongrel {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;
                proxy_pass http://redmine_server;
        }
}

Then edit /etc/supervisord/supervisord.conf and add the following program definition at the end:

[program:redmine]
command=ruby /usr/share/redmine/script/server -e production
directory=/usr/share/redmine/public/
user=www-data
autostart=true
autorestart=true
redirect_stderr=True

Now restart nginx and supervisord:

/etc/init.d/supervisord stop
/etc/init.d/supervisord start
/etc/init.d/nginx restart

(The supervisord restart command is broken in current Ubuntu and Debian versions)

That’s it, now your redmine installation should be up and running. In case of questions, feel free to comment.

Fork me on GitHub

Um Soundcloud-Songs direkt in ein phpBB Forum einzubinden, einfach folgenden BB-Code im Backend erstellen:

Soundcloud BBCode Configuration Screenshot

Benutzung

[Soundcloud]{URL}[/Soundcloud]

HTML Ersetzung

<object height="81" width="100%">
<param name="movie"
value="http://player.soundcloud.com/player.swf?url={URL}&amp;g=bb"></param>
<param name="allowscriptaccess" value="always"></param>
<embed allowscriptaccess="always" height="81"
src="http://player.soundcloud.com/player.swf?url={URL}&amp;g=bb"
type="application/x-shockwave-flash" width="100%"></embed>
</object> <a href="{URL}">{URL}</a>

Tipp-Anzeige

[Soundcloud]http://soundcloud.com/user/track[/Soundcloud]

As many other dwm users do, I customized my .xinitrc file and the dwm status bar in to display some useful information. Here is my configuration:

.xinitrc

This is what my .xinitrc looks like:

# set keyboard layout to Swiss German
setxkbmap ch
 
# Load .Xresources file
xrdb -merge ~/.Xresources
 
# Start xbindkeys
xbindkeys &
 
# Set some defaults
export BROWSER=chromium &
export EDITOR=vim &
xdg-mime default evince.desktop application/pdf &
 
# Loop
while true
do
    # Set root title
    sh .xsetroot.sh
 
    # Check battery level
    BATT=$( acpi -b | sed 's/.*[charging|unknown], \([0-9]*\)%.*/\1/gi' )
    STATUS=$( acpi -b | sed 's/.*: \([a-zA-Z]*\),.*/\1/gi' )
    if ([ $BATT -le 5 ] && [ $STATUS == 'Discharging' ]); then
        # Beep
        echo -e "\007" >/dev/tty10 && sleep 0.2 
        echo -e "\007" >/dev/tty10 && sleep 0.2 
        echo -e "\007" >/dev/tty10 && sleep 0.2 
        # Blink
        echo 'on' > /proc/acpi/ibm/light && sleep 1
        echo 'off' > /proc/acpi/ibm/light
    fi  
 
    # Update every 10s
    sleep 10s
done &
 
# Set up rotated dual screen without touching my xorg.conf
xrandr --output DVI-1 --auto --rotate left --pos 0x0 --output DVI-0 --auto --pos 1080x720 --rotate normal
 
# Read .xsessionrc
sh ~/.xsessionrc &
 
# Set wallpaper
feh --bg-scale ~/.xwallpaper-dwm.png
 
# Set WM name (for Java apps)
wmname LG3D
 
# Run dwm
exec dwm

.Xresources

In my .Xresources, I’m setting the UXTerm color to white on black, as well as fixing a bug with the Alt key in SSH sessions. The last line is to set the window URGENT flag when the window uses the system bell.

UXTerm*eightBitInput: false
UXTerm*metaSendsEscape: true
UXTerm*reverseVideo: true
UXTerm*bellIsUrgent: true

.xsetroot.sh

As you’ve seen in my .xinitrc file, I didn’t want to keep my xsetroot commands in the .xinitrc file. The main reason for this is that now I can update the status information from an external script, e.g. when pushing some volume buttons on my notebook.

DATETIME=`date`
UPTIME=`uptime | sed 's/.*up\s*//' | sed 's/,\s*[0-9]* user.*//' | sed 's/  / /g'`
VOLUME=$( amixer sget Master | grep -e 'Front Left:' | sed 's/[^\[]*\[\([0-9]\{1,3\}%\).*\(on\|off\).*/\2 \1/' | sed 's/off/M/' | sed 's/on //' )
UNREADMAIL=`cat .unreadmail`
BATTERYSTATE=$( acpi -b | awk '{ split($5,a,":"); print substr($3,0,2), $4, "["a[1]":"a[2]"]" }' | tr -d ',' )
if [ `date +%S` == 30 -o `date +%S` == 00 ]; then python imap_check_unread.py > .unreadmail; fi
xsetroot -name "Unread ${UNREADMAIL} | ${VOLUME} | ${DATETIME} | Up ${UPTIME}h | ${BATTERYSTATE}"

The uptime value doesn’t look perfect, there are bugs if the uptime is <1h. But that doesn’t bug me :)

In summary, my status bar displays the following things:

  • Unread e-mail count
  • Volume
  • Date and time
  • Uptime
  • Battery status

imap_check_unread.py

To check the unread mail count in my IMAP account, I created a little Python script. But because I don’t want to query the server every second, I’m caching the value in a file and updating it every 30 seconds. Create a cronjob or similar to update the file.

#!/usr/bin/env python
 
import imaplib
 
obj = imaplib.IMAP4_SSL('xxx.xxx.xxx.xxx', '993')
obj.login('user', 'password')
obj.select()
print len(obj.search(None, 'UnSeen')[1][0].split())

Unfortunately, the django-sphinx module is not very thoroughly documented. One thing which I could not figure out is how to do sorting. I thought that I had to set some kind of keyword argument on the SphinxSearch instance… (I have to admit though that the sorting is indeed demonstrated in the project README.rst – I simply overlooked it…)

But the solution was much simpler – you can use order_by directly on the SphinxSearch instance.

Model.search.query('spam').order_by('-amount')

Make sure that the selected sorting key is marked as a sortable attribute (e.g. sql_attr_uint or sql_attr_str2ordinal) in your sphinx.conf.

Today I was looking for a nice graphical on/off switch to replace checkboxes on a webpage I’m working on. I found a beautiful solution, but the button was too large. Instead of changing the button size, I made my own switch using jQuery JavaScript and CSS.

This is what it looks like:

Screenshot of Toggles

1. HTML

<div class="switch">
  <label for="mycheckbox" class="switch-toggle" data-on="On" data-off="Off"></label>
  <input type="checkbox" id="mycheckbox" />
</div>

The element containing the checkbox and the label should have the class switch assigned. The label element needs the class switch-toggle as well as the data-on and data-on attributes to define the label texts for the two statuses.

It is important that the .switch element contains only one checkbox and that the checkbox and the label are direct children of the .switch element.

2. CSS

label.switch-toggle {
    background: url('switch.png') repeat-y;
    display: block !important;
    height: 12px;
    padding-left: 26px;
    cursor: pointer;
    display: none;
}
label.switch-toggle.on {
    background-position: 0px 12px;
}
label.switch-toggle.off {
    background-position: 0px 0px;
}
label.switch-toggle.hidden {
    display: none;
}

Don’t forget to download the switch.png file.

3. jQuery

$(document).ready( function(){ 
    $('.switch').each(function() {
        var checkbox = $(this).children('input[type=checkbox]');
        var toggle = $(this).children('label.switch-toggle');
 
        if (checkbox.length) {
            checkbox.addClass('hidden');
            toggle.removeClass('hidden');
            if (checkbox[0].checked) {
                toggle.addClass('on');
                toggle.removeClass('off');
                toggle.text(toggle.attr('data-on'));
            } else {
                toggle.addClass('off');
                toggle.removeClass('on');
                toggle.text(toggle.attr('data-off'));
            };  
        }   
    }); 
 
    $('.switch-toggle').click(function(){
        var checkbox = $(this).siblings('input[type=checkbox]')[0];
        var toggle = $(this);
 
        // We need to inverse the logic here, because at the time of processing,
        // the checked status has not been enabled yet.
        if (checkbox.checked) {
            toggle.addClass('off');
            toggle.removeClass('on');
            toggle.text(toggle.attr('data-off'));
        } else {
            toggle.addClass('on');
            toggle.removeClass('off');
            toggle.text(toggle.attr('data-on'));
        };  
    }); 
});

Yes, I violated the DRY principle, but the logic works, so that’s good enough for now ;)

Credits: The image used was taken from the Heise’s socialshareprivacy plugin which I’m also using on this blog.

Sometimes you want to validate only parts of a Django form. A use case for this would be a user profile. A user may have an extensive user profile, but sometimes you only want to validate a subset of the form fields, e.g. the city and the phone number, when providing a profile edit form. On another page you might want to offer a username change. If you try to validate one of those forms using POST data for the provided fields only, the validation will fail because there are other mandatory fields.

In that case, Python’s support for multiple inheritance will help you.

Multiple form inheritance

First, define a form for all the form field subsets you might need to validate.

class FormA(forms.Form):
    username = forms.CharField(required=True, label=_(u'Username'))
 
 
class FormB(forms.Form):
    city = forms.CharField(required=True, label=_(u'City'))
    phone = forms.IntegerField(required=True, label=_(u'Phone'))

Then create a third form that extends both the first and the second form. You may also add additional fields.

class FormAB(FormA, FormB):
    language = forms.CharField(required=True, label=_(u'Language'))

Display the forms:

    <h2>Change Username</h2>
    {{ formA.as_ul }}
 
    <h2>Change City/Phone</h2>
    {{ formB.as_ul }}
 
    <h2>Entire Userprofile</h2>
    {{ formAB.as_ul }}

The result looks correct:

>>> a = FormA({'username': 'danilo'})
>>> a.is_valid()
True
>>> b = FormB({'city': 'Bern', 'phone': '0791112233'})
>>> b.is_valid()
True
>>> c = FormAB({'username': 'danilo', 'city': 'Bern', 'phone': '0791112233'})
>>> c.is_valid()
False
>>> c = FormAB({'username': 'danilo', 'city': 'Bern',
...             'phone': '0791112233', 'language': 'de'})
>>> c.is_valid()
True

Kategorien

Seite 1 von 6212345...102030...Last »

Switch to our mobile site