ads

"Делай что можешь с тем, что имеешь, там, где ты есть". Теодор Рузвельт

понедельник, 2 июня 2014 г.

Batch-файлы в Windows

Несколько полезных скриптов для командной оболочки cmd в Windows (bat-файлы).

Скрипт с использованием системной утилиты wmic. Для его работы оболочка должна быть запущена от администратора. Помещает каталог указанного процесса в PATH и выполняет bat-файл.

:: egax
:: Добавляем в PATH каталог исполняемого файла %1 процесса.
:: Запускаем если передан .bat %2

@echo off
wmic /? > nul
for /f "delims=" %%a in ('wmic process where ^(name^="%1"^) get ExecutablePath^|find 
/V "ExecutablePath"^|findstr /V "^$"') do (
  echo Сервис найден %%a
  set PATH=%%~dpa
  if "%2" == "" goto end
  call "%~dp0\%2" %1 && goto end
)
if not exist "%~fs$PATH:1" (
  echo Запущенный сервис не найден.
  echo Запустите %1 и запустите вручную 'checkproc.bat %1 %2'.
)
:end
Скрипт используется для загрузки базы данных PostgreSQL
checkproc.bat postgres.exe install-bd.bat
Вот текст скрипта install-bd.bat для восстановления базы postgresql из sql-дампа, созданного pg_dump.
:: egax
:: Распаковка базы mybd

@echo off
::имя базы и архива
set dbname=mybd
set initsql=}initsql{.sql
echo Установка базы %dbname% (требуется пароль postgres) . . .
pushd "%~dp0"
for /f %%a in ('dir /B "%dbname%"') do (
  echo drop database %dbname%; >> %initsql%
  echo create database %dbname% encoding 'win' template template0; >> %initsql%
  echo \connect %dbname% >> %initsql%
  echo \i %%a >> %initsql%
  echo vacuum full analyze; >> %initsql%
  psql -U postgres -f %initsql% template1 > nul 2>install-%dbname%.log
  del /q %initsql%
)
:end
popd

воскресенье, 6 апреля 2014 г.

gdal_translate и gdalwarp для перепроицирования изображений

В составе проекта GDAL есть полезные утилиты для работы с изображениями через консоль

  • gdal_translate
  • gdalwarp

Для своего проекта dbCartajs мне потребовались изображения для разных проекций. Изображения я хочу вывести на канвас вместе с векторными данными. Для этого цели из программы Orbitron я позаимствовал картинку с плоской картой Земли в небольшом разрешении.

worldmap.jpg

Она отлично подходит для экспериментов, но как быть с другими проекциями - меркатор, сфера? Я нашел несколько картинок в разных проекциях, но все они оказались в разных цветовых сочетаниях и разрешениях, поэтому решил попробовать самостоятельно преобразовать исходную картинку с помощью утилит gdal, используя их описание и примеры.

Сначала, преобразуем исходную картинку в формат tiff - родной формат gdal - и задаем координаты привязки изображения.

gdal_translate -of Gtiff -co "TFW=YES" -a_ullr -180 90 180 -90 worldmap.png worldmap.tif

Для проекции Меркатора нужно ограничить размеры на полюсах (80-85 градусов).

gdal_translate -of Gtiff -projwin -180 84 180 -84 worldmap.tif worldmap-1.tif

Теперь формируем изображение в проекции Меркатора в формате tiff.

gdalwarp -s_srs EPSG:4326 -t_srs EPSG:3857 worldmap-1.tif worldmap-merc.tif

Браузер не работают с tiff, поэтому переводим его в jpeg.

gdal_translate -of JPEG worldmap-merc.tif worldmap-merc.jpg

Вот результат

worldmap-merc.jpg

Аналогично получаем картинки для других проекций, например ortho.

gdalwarp -s_srs EPSG:4326 -t_srs "+proj=ortho +lon_0=0 +lat_0=0" worldmap-1.tif worldmap-ortho.tif
gdal_translate -of JPEG worldmap-ortho.tif worldmap-ortho.jpg
worldmap-ortho.jpg

понедельник, 31 марта 2014 г.

Конфиг c анонимным доступом для vsftpd

Конфиг-файл для FTP-сервера vsftpd под Linux.

Включает анонимный доступ (пользователи ftp, anonymous) с маской файлов rw.

Корневой каталог /.

listen=yes
tcp_wrappers=yes

write_enable=yes
anon_root=/
anon_mkdir_write_enable=yes
anon_other_write_enable=yes
anon_upload_enable=yes
anon_umask=000

вторник, 11 февраля 2014 г.

Создание self-extract архива tar

Созданием самораспаковывающийся архив .run в среде Linux - аналог архива .exe в Windows.

Создаем файл скрипта распаковки архива extract.sh.

#!/bin/bash
echo ""
echo "Self Extracting Installer"
echo ""

export TMPDIR=`mktemp -d /tmp/selfextract.XXXXXX`

ARCHIVE=`awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' $0`

tail -n+$ARCHIVE $0 | tar -xzv - -C $TMPDIR

CDIR=`pwd`
cd $TMPDIR
./installer

cd $CDIR
rm -rf $TMPDIR

exit 0

# newline after
__ARCHIVE_BELOW__

Пакуем скрипт запуска и архив tar.gz в bundle

cat extract.sh a.tar.gz > installer.run

Запускаем

sh installer.run

Использование Samba для скачивания/закачивания каталогов

Чтобы "скачать" через консоль каталог файлов по сети с машины под Windows (Samba-сервером под Linux) удобно воспользоваться утилитой smbclient из пакета samba. Например.

Список доступных сетевых папок

smbclient -L 192.168.0.9 -U Администратор

Подключаемся

smbclient //192.168.0.9/E$ -U Администратор

В оболочке Samba вводим команды для "скачивания" рекурсивно папки в текущий каталог

smb:/> recurse
smb:/> prompt
smb:/> mget Документы

Аналогично можно закачать папку из текущего каталога

smb:/> recurse
smb:/> prompt
smb:/> mput home

Текущим путем является текущий путь в терминале, в котором был запущен smbclient.

Расширенный аналог утилиты wc в Linux

Скрипт рекурсивно считает число строк в файлах каталогов. Можно задавать маски поиска имен файлов на вхождение или не вхождение. Скрипт использовался в средах Windows и Linux (локаль koi8-r) для версии языка Python 2.4. Подробности вызова смотри в исходнике или в справке при вызове без параметров:

python pywc.py

Текст:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Выводит число строк, байт для каждого файла каталога рекурсивно и итоговую строку."""

import sys, os, re
import fileinput as i
import fnmatch as f

__version__ = '0.3'

E = lambda text: text.encode({'posix':'koi8-r', 'nt':'cp866'}.get(os.name))
_E = lambda text: text.decode({'posix':'koi8-r', 'nt':'cp866'}.get(os.name))
E_OS = lambda text: text.encode({'posix':'koi8-r', 'nt':'cp1251'}.get(os.name))
_E_OS = lambda text: text.decode({'posix':'koi8-r', 'nt':'cp1251'}.get(os.name))

STR_HELP = u"""\
Вызов: python pywc.py <папка> [<файл_масок> | - ]
Выводит число строк, байт для каждого файла в ПАПКЕ по маскам из ФАЙЛА_МАСОК.

ФАЙЛ_МАСОК содержит маски поиска на включение и исключение файлов, разделенных пустой строкой.
Если ФАЙЛ_МАСОК задан как -, читает стандартный ввод, если не задан, подсчитываются все файлы.

Пример файла:
  # включать
  *.c *.cpp
  *.h *.asm

  # исключать
  *\.svn\* *\stdafx.h

Примеры использования:
  python pywc.py .               Считать все файлы в текущем каталоге и ниже. 
  python pywc.py тест1 dir       Считать файлы в test1 и ниже, используя файл масок dir."""

REG_COL = '(?:[ \t]*#.*\r?\n?)*((?:[^\r\n]+\r?\n?)+)'
REG_ROW = '([^ \t\r\n]+)'

def subinfo(lines, size, files, _files, ts, lastprint=True):
    """Выводит расчеты в stdout."""
    print lines, size, ts
    print E(u'Посчитано файлов'), files, E(u'из'), files + _files             
    if (lastprint):
        print

args = sys.argv[1:]

if (not args):
    print E(STR_HELP)
    sys.exit(2)

# файл масок поиска и исключений
_wcfile = []
if (len(args) > 1):
    if (args[1] == '-'):
        wcfile = sys.stdin
    else:
        wcfile = file(args[1])
    _wcfile = re.findall(REG_COL, _E_OS(wcfile.read()))

res = []
for x in _wcfile:
    res += [re.findall(REG_ROW, x)]

# каталог подсчетов    
os.chdir(args[0])

dd = sublines = subsize = subfiles = _subfiles = None
totallines = totalsize = totalfiles = _totalfiles = 0
for root, dirs, files in os.walk(u'.', topdown=False):
    # подпапки
    if (root != dd):
        if (sublines):
            subinfo(sublines, subsize, subfiles, _subfiles, E(u'ИТОГО'))
        sublines = subsize = subfiles = _subfiles = 0
        dd = root
    for name in files:
        curname = os.path.normpath(os.path.join(root, name))
        absname = os.path.join(_E_OS(os.getcwd()), curname)
        if (res):      
            p = e = False        
            # вхождения
            for x in res[0]:
                p = (f.fnmatch(name, x) or f.fnmatch(curname, x) or f.fnmatch(absname, x))
                if (p):
                    break
            # исключения
            if (len(res) > 1 and p):            
                for x in res[1]:
                    e = (f.fnmatch(name, x) or f.fnmatch(curname, x) or f.fnmatch(absname, x))
                    if (e):
                        break                    
            if (not (p and (not e))):
                print >> sys.stderr, E(u'Игнорируем'), E(curname)
                _subfiles += 1
                _totalfiles += 1
                continue
        for line in i.input(E_OS(absname)):
            pass
        else:
            curlines, cursize = i.filelineno(), os.stat(curname)[6]            
            # по подпапкам
            sublines += curlines
            subsize += cursize
            subfiles += 1
            # всего
            totallines += curlines
            totalsize += cursize
            totalfiles += 1
            print curlines, cursize, E(curname)
            i.close()
else:
    if (sublines):
        subinfo(sublines, subsize, subfiles, _subfiles, E(u'ИТОГО'))

if (totallines):
    subinfo(totallines, totalsize, totalfiles, _totalfiles, E(u'ВСЕГО'), lastprint=False)