IOError: decoder jpeg not available

for x64 OS

pip uninstall PIL
sudo apt-get install libjpeg8-dev
sudo ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib
pip install PIL

for x32 OS
pip uninstall PIL
sudo apt-get install libjpeg8-dev
sudo ln -s /usr/lib/i386-linux-gnu/libjpeg.so /usr/lib
pip install PIL
# sudo apt-get install python-dev libjpeg-dev libfreetype6-dev zlib1g-dev

// create these links, if already exists, remove it and re-link it
# ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib
# ln -s /usr/lib/x86_64-linux-gnu/libfreetype.so /usr/lib
# ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib

// reinstall PIL
# pip uninstall PIL
# pip install PIL

Конвертація mysql таблиць і полів

mysql --database=dbname -B -N -e "SHOW TABLES" \ 
| awk '{print "ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;"}' \
| mysql --database=dbname

Кілька версій Django на одній системі

Стикнувся з проблемкою, коли потрібно одночасно розробляти кілька проектів під різні версії Django. Один з варіантів вирішення: felecan.com/2011/definitive-guide-installing-django-ubuntu/

zoneminder: images to avi converter

#!/bin/bash

MYSQL_HOST="localhost"
MYSQL_USER="user"
MYSQL_DB="zm"
MYSQL_PASS="pass"

CACHE_DIR="/var/cache/zoneminder/events"
VIDEO_DIR="video-archive"
cameras=(
 5 # kafedra
 1 # krapka1
 2 # krapka2
 6 # krapka2in
 3 # krapka3
 4 # stoyanka
)

for i in ${cameras[@]}; do
    echo
    echo "Monitor $i"
    echo

    if [ ! -d $CACHE_DIR/$i/$VIDEO_DIR ]; then
 mkdir $CACHE_DIR/$i/$VIDEO_DIR
    fi

    IFS=$'\t\n'
    #MYSQL_RESULT=(`mysql --skip-column-names -h$MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASS $MYSQL_DB -e "SELECT StartTime, EndTime FROM Events WHERE MonitorId='$i' AND EndTime IS NOT NULL"`)
    MYSQL_RESULT=(`mysql --skip-column-names -h$MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASS $MYSQL_DB -e "SELECT StartTime FROM Events WHERE MonitorId='$i' AND EndTime IS NOT NULL"`)
    IFS=$' \t\n'

    for (( j=0 ; j<${#MYSQL_RESULT[*]}; j++ )) ; do 
 echo "${MYSQL_RESULT[j][1]}"
 PARSED_DATE=(`echo ${MYSQL_RESULT[j]} | sed -e 's/[:-]/ /g'`)
 YEAR=${PARSED_DATE[0]:2:3}
 MONTH=${PARSED_DATE[1]}
 DAY=${PARSED_DATE[2]}
 HOUR=${PARSED_DATE[3]}
 MINUTE=${PARSED_DATE[4]}
 SECOND=${PARSED_DATE[5]}
 #echo ${PARSED_DATE[*]}

 if [ -d  $CACHE_DIR/$i/$YEAR/$MONTH/$DAY/$HOUR/$MINUTE/$SECOND ]; then
     ffmpeg -f image2 -framerate 5 -r 5 -i $CACHE_DIR/$i/$YEAR/$MONTH/$DAY/$HOUR/$MINUTE/$SECOND/%03d-capture.jpg -s 640x480 $CACHE_DIR/$i/$VIDEO_DIR/${YEAR}.${MONTH}.${DAY}-${HOUR}.${MINUTE}.${SECOND}.avi
     rm -rf $CACHE_DIR/$i/$YEAR/$MONTH/$DAY/$HOUR/$MINUTE/$SECOND
 fi
 
    done
done

Google Maps v3 marker і infowindow

Невеличка мапа з marker'ами і infowindow'ами. Робочий варіант зроблено для газети "Тернопіль вечірній".
Не дуже мені подобається як вписані координати, але в наступному таску вже оптимізую, бо в цьому варіанті надто довго вводились координати.

<!DOCTYPE html>
<html>
<head>
    <title>Пункти набору води в Тернополі</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript">
        infos = [];

        function initialize() {
            var map = new google.maps.Map(document.getElementById('map'), {
                zoom: 13,
                center: new google.maps.LatLng(49.553517,25.599367),
                mapTypeId: google.maps.MapTypeId.TERRAIN
            });

            var image = new google.maps.MarkerImage(
                    'http://t-v.te.ua/media/icons/waterdrop.png',
                    new google.maps.Size(32,37),
                    new google.maps.Point(0,0),
                    new google.maps.Point(16,37)
            );

            var shadow = new google.maps.MarkerImage(
                    'http://t-v.te.ua/media/icons/shadow.png',
                    new google.maps.Size(54,37),
                    new google.maps.Point(0,0),
                    new google.maps.Point(16,37)
            );

            var shape = {
                coord: [29,0,30,1,31,2,31,3,31,4,31,5,31,6,31,7,31,8,31,9,31,10,31,11,31,12,31,13,31,14,31,15,31,16,31,17,31,18,31,19,31,20,31,21,31,22,31,23,31,24,31,25,31,26,31,27,31,28,31,29,30,30,29,31,23,32,22,33,21,34,20,35,19,36,12,36,11,35,10,34,9,33,8,32,2,31,1,30,0,29,0,28,0,27,0,26,0,25,0,24,0,23,0,22,0,21,0,20,0,19,0,18,0,17,0,16,0,15,0,14,0,13,0,12,0,11,0,10,0,9,0,8,0,7,0,6,0,5,0,4,0,3,0,2,1,1,2,0,29,0],
                type: 'poly'
            };


            var marker_data = new Array(
                {
                    "lat": 49.55754,
                    "lon": 25.600934,
                    "info": 'вул. Городня, 3'
                },
                {
                    "lat": 49.558931,
                    "lon": 25.600934,
                    "info": 'вул. Квіткова, 7'
                },
                {
                    "lat": 49.558845,
                    "lon": 25.605833,
                    "info": 'вул. Квіткова, 17'
                },
                {
                    "lat": 49.558486,
                    "lon": 25.623937,
                    "info": 'вул. Євгена Коновальця, 20'
                },
                {
                    "lat": 49.55498,
                    "lon": 25.647893,
                    "info": 'вул. Корольова, 8'
                },
                {
                    "lat": 49.552496,
                    "lon": 25.596755,
                    "info": 'вул. Олени Кульчицької, 9'
                },
                {
                    "lat": 49.548563,
                    "lon": 25.553841,
                    "info": 'вул. Бережанська, 53'
                },
                {
                    "lat": 49.544802,
                    "lon": 25.575731,
                    "info": 'вул. Дружби, 6'
                },
                {
                    "lat": 49.544802,
                    "lon": 25.575721,
                    "info": 'вул. Дружби, 1'
                },
                {
                    "lat": 49.561946,
                    "lon": 25.604931,
                    "info": 'вул. Лозовецька, 4'
                },
                {
                    "lat": 49.550777,
                    "lon": 25.568645,
                    "info": 'вул. Гетьмана Мазепи, 7'
                },
                {
                    "lat": 49.55804,
                    "lon": 25.64666,
                    "info": 'вул. Василя Стуса, 6'
                },
                {
                    "lat": 49.558098,
                    "lon": 25.560745,
                    "info": 'вул. Тернопільська, 2'
                },
                {
                    "lat": 49.561109,
                    "lon": 25.562083,
                    "info": 'вул. Хліборобна, 30'
                },
                {
                    "lat": 49.552493,
                    "lon": 25.570616,
                    "info": 'вул. Чумацька, 25'
                },
                {
                    "lat": 49.537832,
                    "lon": 25.596608,
                    "info": 'вул. Чернівецька, 13'
                },
                {
                    "lat": 49.540207,
                    "lon": 25.603161,
                    "info": 'вул. Садова, 4'
                },
                {
                    "lat": 49.552556,
                    "lon": 25.592973,
                    "info": 'вул. Мостова, 13'
                },
                {
                    "lat": 49.523277,
                    "lon": 25.605182,
                    "info": 'вул. Микулинецька, 48'
                },
                {
                    "lat": 49.546598,
                    "lon": 25.598245,
                    "info": 'вул. Острозького, 44'
                },
                {
                    "lat": 49.554734,
                    "lon": 25.591591,
                    "info": 'вул. Грушевського, 7'
                },
                {
                    "lat": 49.558937,
                    "lon": 25.590875,
                    "info": 'вул. Броварна, 10'
                },
                {
                    "lat": 49.560114,
                    "lon": 25.586896,
                    "info": 'вул. Білецька, 19'
                },
                {
                    "lat": 49.542154,
                    "lon": 25.600716,
                    "info": 'вул. Софії Стадникової, 19'
                },
                {
                    "lat": 49.560779,
                    "lon": 25.600199,
                    "info": 'вул. Збаразька, 5'
                },
                {
                    "lat": 49.552556,
                    "lon": 25.592965,
                    "info": 'вул. Валова, 7'
                }
            );

            for (var x = 0; x < marker_data.length; x++) {
                var marker = new google.maps.Marker({
                    position: new google.maps.LatLng(marker_data[x]['lat'],marker_data[x]['lon']),
                    map: map,
                    shape: shape,
                    raiseOnDrag: false,
                    icon: image,
                    shadow: shadow,
                    content:'<div class="info-window-content"><p>' + marker_data[x]['info'] + '</p></div>',
                });

                google.maps.event.addListener(marker, 'click', function() {
                    closeInfos();
                    var info = new google.maps.InfoWindow({content: this.content});
                    info.open(map,this);
                    infos[0]=info;
                });
            }

            google.maps.event.addListener(map, 'click', function() {
                closeInfos();
            });

        }

        function closeInfos(){
            if(infos.length > 0){
                infos[0].set("marker", null);
                infos[0].close();
                infos.length = 0;
            }
        }
    </script>
</head>
<body onload="initialize()">
    <div id="map" style="width: 600px; height: 600px;"></div>
</body>
</html>

mcedit і mc кольори

Стандартна убунтівська кольорова схема для mcedit просто виїдає мозок. Є кусок роботи, де потрібно правити код в mcedit таки. Вставляємо наступний сніпєтц в .bashrc

автоматизація підключення WebDAV-шари

Є багато машин, на кожну потрібно підключити відповідну webdav-шару. Формат http://davhost/pc_0xx і 192.168.0.xx клієнт, відповідно.
#!/bin/bash

IP=`ifconfig | grep -v '127.0.0.1' | sed -n 's/.*inet addr:\([0-9.]\+\)\s.*/\1/p'`
IP_ARRAY=(${IP//./ })

FSTAB=/etc/fstab
USER_HOME=/home/user
CLIENT_DIR=$USER_HOME/client
DAVFS_DIR=.davfs2
CLIENT_SECRET=secrets

if [ ! -d $CLIENT_DIR ]; then
    echo "create $CLIENT_DIR"
    mkdir $CLIENT_DIR
    chown user:user $CLIENT_DIR
else
    echo "exist $CLIENT_DIR"
fi

if [ ! -d $USER_HOME/$DAVFS_DIR ]; then
    echo "create $USER_HOME/$DAVFS_DIR"
    mkdir $USER_HOME/$DAVFS_DIR
    chown user:user $USER_HOME/$DAVFS_DIR
else
    echo "exist $USER_HOME/$DAVFS_DIR"
fi

if [ ! -f $USER_HOME/$DAVFS_DIR/$CLIENT_SECRET ]; then
    echo "create $USER_HOME/$DAVFS_DIR/$CLIENT_SECRET"
    touch $USER_HOME/$DAVFS_DIR/$CLIENT_SECRET
    chown user:user $USER_HOME/$DAVFS_DIR/$CLIENT_SECRET
    chmod 0600 $USER_HOME/$DAVFS_DIR/$CLIENT_SECRET
    echo "http://davhost/pc_0${IP_ARRAY[3]} user user" >> $USER_HOME/$DAVFS_DIR/$CLIENT_SECRET
else
    echo "exist $USER_HOME/$DAVFS_DIR/$CLIENT_SECRET"
fi

if grep "http://davhost/pc_0${IP_ARRAY[3]}" $FSTAB
then
    echo "exist mount access in $FSTAB"
else
    echo "create mount access in $FSTAB"
    echo "http://davhost/pc_0${IP_ARRAY[3]} /home/user/client davfs user,rw,auto,_netdev 0 0" >> $FSTAB
fi

chmod u+s /sbin/mount.davfs
usermod -a -G davfs2 user

files list file for package 'xxx' is missing final newline

Сьогодні при оновленні Ubuntu отримав САБЖ помилку. Наступний вигуглений скрипт вирішує проблему.
#!/usr/bin/python


# 8th November, 2009
# update manager failed, giving me the error:
#       'files list file for package 'xxx' is missing final newline' for every package.
# some Googling revealed that this problem was due to corrupt files(s) in /var/lib/dpkg/info/
# looping though those files revealed that some did not have a final new line
# this script will resolve that problem by appending a newline to all files that are missing it
# NOTE: you will need to run this script as root, e.g. sudo python newline_fixer.py

import os

dpkg_path = '/var/lib/dpkg/info/'
paths = os.listdir(dpkg_path)
for path in paths:
    path = dpkg_path + path
    f = open(path, 'a+')
    data = f.read()
    if len(data) > 1 and data[-1:] != '\n':
        f.write('\n')
        print 'added newline character to:', path
    f.close() 

Підбираємо опримальний об'єм пам'яті для zoneminder

#!/bin/sh
# Copyright (C) 2010 Chris "Pada" Kistner
# Modified by PacoLM to check only shared memory settings
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# if you find errors, check that coreutils are installed, if not, run the command below
# apt-get -y install coreutils bc
echo "--- Checking memory setting..."
page_size=$(getconf PAGE_SIZE)
mem_bytes=$(awk '/MemTotal:/ { printf "%0.f",$2 * 1024}' /proc/meminfo)
mb=1048576
mem_bytes_mb=$(expr $mem_bytes / $mb)
shmmax=$(echo "$mem_bytes * 0.90" | bc | cut -f 1 -d '.')
shmmax_mb=$(expr $shmmax / $mb)
shmall=$(expr $mem_bytes / $page_size)
shmmax_cur=$(sysctl -n kernel.shmmax)
shmmax_cur_mb=$(expr $shmmax_cur / $mb)
shmall_cur=$(sysctl -n kernel.shmall)
echo "-- Total memory = $mem_bytes B = $mem_bytes_mb MB"
echo "-- Page size = $page_size B"
echo "-- Current kernel.shmmax = $shmmax_cur B = $shmmax_cur_mb MB"
echo "-- Current kernel.shmall = $shmall_cur pages"
if [ "$shmmax" -eq "$shmmax_cur" ] && [ "$shmall" -eq "$shmall_cur" ]; then
    echo "-- Recommended shm values already set"
else
    echo "-- Recommended: kernel.shmmax = $shmmax B = $shmmax_mb MB"
    echo "-- Recommended: kernel.shmall = $shmall pages"
fi
# Done
echo "--- Done."