РЕКЛАМА 
сервер россия Циклевка паркета цена, реставрация паркета , шлифовка полировка мрамора

Настройка авторизации с помощью сертификатов в SSH

Довольно часто возникает необходимость настроить вход на удаленный сервер без участия пользователя. (Например если вход выполняется из скрипта или пароль был сгенерирован злобным админом и нет возможности запомнить это безобразие). Я делал это для связки Mac OS OpenSSH Server и Ubuntu Linux. Итак последовательность действий на клиенте следующая:

  • Проверяем, есть ли в домашней папке папка .ssh, для этого выполняем команду

     ls -ld ~/.ssh


    Если папки не существует, то создадим ее

    mkdir ~/.ssh

  • Переходим в созданную папку:

    cd ~/.ssh

  • Генерируем открытый и закрытый ключ


    ssh-keygen -b 1024 -t dsa -f id_dsa -P ''

    Эта команда сгенерирует открытый и закрытый ключи. Флаг -b устанавливает длину ключей в 1024 бита, -t определяет использование DSA алгоритма, -f устанавливает имя файла, а P '' устанавливает нулевой пароль к закрытому ключу, что дает возможность использовать его для автоматического логина.

  • Создадим файл authorized_keys2:

    touch authorized_keys2

  • Скопируем в этот файл открытый ключ:

    cat id_dsa.pub >> authorized_keys2


  • Установим закрытому ключу правильные права:

    chmod 400 id_dsa

  • Копируем файл на удаленный сервер:

    scp authorized_keys2 username@remotemachine:~/.ssh/




Первоисточник:
Setting Up Key-Based SSH Login

Добавление кнопки на панель инструментов Excel и назначение ёй макроса

Настройка Excel

   

Для этого необходимо открыть файл с макросом, который Вам нужен. Например pers.xls который находиться D:\Справочник\pers.xls и на вопрос системы безопасности:

Вопрос ситемы безопасности Excel

Вопрос ситемы безопасности Excel

ответить нажатием на кнопку "Не отключать макросы".
После чего на панели инструментов необходимо кликнуть правой кнопкой мыши:

Вызов меню настройки панели инструментов Excel

Вызов меню настройки панели инструментов Excel

и выбрать пункт "Настройка...". Появиться окно:

Окно настройки панелей инструментов

Окно настройки панелей инструментовВ списке "Категории:" - выбрать "Макросы", а в списке "Команды:" выбрать "Настраиваемая кнопка". Зажать левой кнопкой мыши "Настраиваемая кнопка" и перетащить на панель инструментов в удобное место: Добавление кнопки на панель инструментов

после чего нажать на кнопку "Изменить выделенный объект" и в появившемся окне ввести имя кнопки "Внести данные" и выбрать "Только текст(всегда)":

Выбор показа только текста в названии кнопки

Выбор показа только текста в названии кнопки

Теперь осталось назначить макрос. Снова нажимаем кнопку "Изменить выделенный объект" и в появившемся окне выбираем "Назначить макрос...". Появляется окно выбора макроса:

Выбор макроса

Выбор макроса

где нужно выбрать строку PERS.XLS!TestMacros и нажать кнопку "ОК".
Кнопка готова, после чего на окне "Настройка" нажимаем кнопку "Закрыть" и имеем подготовленный к работе Excel.

Если макроса PERS.XLS! TestMacros нет в списке нужно проверить в первую очередь этот список:

Выбор макроса из списка открытых книг

Выбор макроса из списка открытых книг

и выбрать там пункт "Все открытые книги". Если макросы не появились значит или не открыта книга pers.xls который находиться d:\Справочник\pers.xls или на вопрос системы безопасности:

Вопрос ситемы безопасности Excel

Вопрос ситемы безопасности Excel

ответили нажатием на кнопку "Отключить макросы" или необходимо посмотреть настройки системы безопасности. Пункт меню "Сервис"->"Макрос"->"Безопасность":

Доступ к меню управления безопасностью

Доступ к меню управления безопасностью

появиться такое окно:

Установка уровня безопасности Excel

Установка уровня безопасности Excel

Необходимо выбрать средний уровень безопасности. Закрыть Excel. И при следующем запуске Excel уровень безопасности будет средним.

З.Ы. По настойчивой просьбе моего друга

Как записать видео с экрана

Довольно часто возникает необходимость записать видео с рабочего стола, или последовательность каких-то действий, а затем переслать это знакомым/заказчику и т.д Мой случай осложнялся тем, что нужно было записать видео на MacOS. Погуглив немного я не нашел бесплатного решения для этой ОС, но наткнулся на давно известный, но временно мною забытый проект pyvnc2swf . Написан он на языке python ,а значит кросплатформенный, что тоже хорошо. Недостатком данного подхода является то, что вам необходимо иметь установленный VNC сервер. Для MacOS я поставил бесплатный Vine VNC сервер для MacOS, в линукс дистрибутивах VNC зачастую предустановлен, если же его все же нет, то он легко ставится из репозитярия. Для windows рекомндую TightVNC или UltraVNC Когда VNC сервер запущен и установлен, дело за малым. Запустив скрипт vnc2svf.py вы увидите окошко:

В меню опций необходимо выбрать запись видео:

Если собираетесь записывать видео с удаленной машины, то в опциях необходимо указать имя(или ip адресс) и порт удаленной машины.

VNC сервер по умолчанию становится на порт 5900

Когда все это сделано, жмем кнопку 'Start' и далее, в зависимости от настройки VNC сервера, либо вводим пароль к VNC серверу, либо запись началась уже началась и осталось только записать. то что мы планировали записать.

sphinx и поиск по русским страницам в mediawiki

В предыдущей публикации про полнотекстовый поиск Полнотекстовый поиск в mediawiki я не упомянул про поиск по рускоязычным страницам, по причине отсутствия таковых в моей wiki на тот момент. Когда поиск понадобился, то я обнаружил что он не работает. Сначала я грешил на sphinx, но попробовав искать русские слова из командной строки убедился, что поисковой движок в порядке. Начал копать глубже и нашел довольно интересное место в файле SphinxSearch_body.php. Код приведенный ниже:

 
 
# don't do anything for blank searches
if (!preg_match('/[\w\d]/', $term)) {
return $found;
}
 

никогда не пропускает меня дальше для русских слов и нормально отрабатывает для английских. Я запостил баг разработчикам и сделал фикс для себя sphinxsearch-Bugs-2015817 ] SphinxSearch doesn't work for Russian pages. Разработчики пока никак не отреагировали, а с фиксом русский поиск работает :).

Скрипт для создания рамки фотографии (GIMP+Python)

Часто приходиться добавлять рамку к фотографиям перед печатью. Фотография до применения скрипта

и после применения:

Скопируйте скрипт в файл 'frame.py' и положите файл в папку '/usr/share/gimp/2.0/plug-ins' или в '~/.gimp/plug-ins', установите файлу разрешение на выполнение, и в меню Python-fu/Decor/Border вы сможете выполнить скрипт. (Следует отметить что скрипт не тестировался на Windows системах!!!)

 
#!/usr/bin/env python
 
#   Gimp-Python - allows the writing of Gimp plugins in Python.
#   Copyright (C) 1997  James Henstridge <james@daa.com.au>
#
#   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.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
from gimpfu import *
 
def PythonFrame(image, layer, \
                    median_color, \
                    outer_width, outer_color):
 
    def CreateFrame(name, width, color):
        image_width  = pdb.gimp_image_width(image)
        image_height = pdb.gimp_image_height(image)
        # get a copy of background
        background_copy = pdb.gimp_image_get_active_layer (image)
        border = pdb.gimp_layer_copy(background_copy,0)
        pdb.gimp_image_add_layer(image, border, -1)
        #select and make stroke
        pdb.gimp_rect_select(image, outer_width, outer_width,  image_width - 2*outer_width , image_height - 2*outer_width , CHANNEL_OP_REPLACE,  0, 0.0)
        pdb.gimp_context_set_foreground(median_color)
        drawable = pdb.gimp_image_active_drawable (image)
        # TODO somehow set the width for the stroke
        pdb.gimp_edit_stroke(drawable)
        # fill by foreground color
        pdb.gimp_selection_invert(image)
        pdb.gimp_context_set_foreground(outer_color)
        drawable = pdb.gimp_image_active_drawable (image)
        pdb.gimp_bucket_fill(drawable,FG_BUCKET_FILL,NORMAL_MODE,100,0,0,outer_width/2,outer_width/2)
        pdb.gimp_layer_set_opacity(border,50)
        pdb.gimp_selection_none (image)
        # megre visible layers
        pdb.gimp_image_merge_visible_layers(image,EXPAND_AS_NECESSARY)
 
    image.undo_group_start()
    CreateFrame('Frame Border', outer_width, outer_color)
    image.undo_group_end()
 
register(
        "python_fu_borders",
        "Add frame to the image",
        "Add frame to the image",
        "Alexander Darovsky & Dmytro Golub",
        "Alexander Darovsky & Dmytro Golub",
        "2006-2008",
        "<Image>/Python-Fu/Decor/_Borders",
        "RGB*",
        [
                (PF_COLOR, "median_color",  "Median Frame Color", (255,255,255)),
                (PF_INT,   "outer_width",  "Outer Frame Width",  20),
                (PF_COLOR, "outer_color",  "Outer Frame Color",   (  0,  0,  0)),
        ],
        [],
        PythonFrame)
 
main()
 

Из недостатков которые необходимо устранить стоит отметить, что пока нет возможности указать ширину 'Median Frame'. Это существенный недостаток, т.к сейчас это приходиться делать вручную. Выделите произвольную область на фотографии, затем 'Edit'->'Stroke selection' и установите 'Line Width' в необходимую ширину, после этого скрипт будет использовать установленную ширину для операции 'Stroke selection'. Со временем я постараюсь устранить этот недостаток.

Ссылки по теме:
Про скрипты в GIMP

Gimp PDB Documentation

Примонтировать iso образ в Linux

В целом задача тривиальная, но когда нужно сделать мне всегда приходиться искать в интернете ибо всегда забуду указать какой-то параметр.

Для начала создайте точку монтирования

 
 mkdir /mnt/iso
 

и дальше примонтируйте ваш образ

 
mount myiso.iso /mnt/iso/ -t iso9660 -o ro,loop=/dev/loop0
 

где myiso.iso ваш образ

Ссылки:
How to mount an ISO image in Linux

Переключение между H и CPP файлами в Visual Studio 7/7.1/8/9

Мне достаточно часто необходимо переключаться между H и CPP файлами в процессе разработки. На работе обычно у меня стоит Visual Assist X, для которого это одна из многих опций. Но вот понадобилось сделать тоже самое, но без Visual Assist X, борьба за использование только лицензионного ПО. В 2005 студии есть набор макросов,один из которых умеет переключаться между H и CPP, а вот в 2003 не нашел. Поискал в интернете и нашел этот макрос.

 
    Sub GetFriendFile()
        'DESCRIPTION: Opens the corresponding .h / .cpp file
        Dim currentFileName As String
        Dim newFileName As String
        currentFileName = Application.ActiveDocument.FullName
        newFileName = ""
 
        If (UCase(Right(currentFileName, 2)) = ".H") Then
            newFileName = Left(currentFileName, Len(currentFileName) - 2) + ".CPP"
        ElseIf (UCase(Right(currentFileName, 4)) = ".CPP") Then
            newFileName = Left(currentFileName, Len(currentFileName) - 4) + ".H"
        End If
 
        If newFileName <> "" Then Application.Documents.Open(newFileName)
 
    End Sub
 

Для того чтобы его использовать идете в Tools | Macros | Macros IDE появится новое окно в котором будет открыт MyMacros проект. Добавьте новый модуль, назовите его скажем Switch2cpp. И далее вставьте в него функцию GetFriendFile, сохраните и затем назначьте сочетание клавиш.

Для этого выберите Tools|Options|Environment|Keyboard и там выберите из лист бокса Macros.MyMacros.Switch2cpp.GetFriendFile и сочетание клавиш, которые будут выполнять данный макрос, после этого не забудьте нажать кнопку Assign - наслаждайтесь.

Материал испльзуемый при написании поста:

Sequence diagram editor

Вчера нужно было быстренько нарисовать sequence diagram для участка кода и я нашел достаточно интересную програмку Quick Sequence Diagram Editor. Программа интересна тем, что имеет командную строку и интерпритатор, вводишь правильную комманду и сразу видишь результат. Пример кода (взят с оф. сайта):

 
 
bfs:BFS[a]
/queue:FIFO
someNode:Node
node:Node
adjList:List
adj:Node
 
bfs:queue.new
bfs:someNode.setLevel(0)
bfs:queue.insert(someNode)
[c:loop while queue != ()]
  bfs:node=queue.remove()
  bfs:level=node.getLevel()
  bfs:adjList=node.getAdjacentNodes()
  [c:loop 0 <= i < #adjList]
    bfs:adj=adjList.get(i)
    bfs:nodeLevel=adj.getLevel()
    [c:alt nodeLevel IS NOT defined]
      bfs:adj.setLevel(level+1)
      bfs:queue.insert(adj)
      --[else]
      bfs:nothing to do
    [/c]
  [/c]
[/c]
bfs:queue.destroy()
 

и результат

Results

По воле рока, так случилось, иль MFC CMap vs STL std::map и stdext::hash_map

На работе в проекте используется MFC, причем везде и много. При запуске иногда программа серьйозно притормаживает. Натравить профайлер не могу, BoundChecker просто загнулся, а остальные я не пробовал, т.к руководству это не нужно и, соответственно, времени отпрофайлить мне никто не даст. Так вот, найдя проблемный участок кода, я обнаружил, что там происходит вставка элементов в CMap (класс MFC реализованный с помощью хеш-массива ) , причем при увеличении кол-ва элементов, время на вставку возростало. Попрошу извинить меня за предложения типа "при увеличении кол-ва элементов, время на вставку возростало" , из отсутствия профайлера я более точно сказать не могу, в проекте все замерял на глаз. Но эти наблюдения сподвигли меня написать маленький тест по сравнению производительности STL и MFC.

Тест достаточно простой - вставка элементов в CMap, std::map и stdext::hash_map. С помощью кода ниже я нагенерировал неповторяющиеся последовательноси символов

 
void GenerateSequence(const std::string& file_name,int nNumCh)
{
	if(nNumCh&gt;16)
		return;
 	char buf[]="0123456789abcdefg";
	std::string sRealStr(buf,buf+nNumCh);
 	int nCount=0;
	std::ofstream f(file_name.c_str(),std::ios::out|std::ios::trunc);
 
	while(std::next_permutation(sRealStr.begin(),sRealStr.end()))
 	{
 		++nCount;
 		f<<" "<<sRealStr;
 		if(!(nCount%15))
 			f<<std::endl;
	}
}
 

тестировал на последовательностях из 6,7,8 и 9 символов, соответственно 720, 5040, 40320 и 362880 элементов. Результаты приведены ниже в виде таблицы и диаграммы, время в секундах


STL map MFC map Initialized MFC map STL hashmap
719 0.0006866790 0.0004520130 0.0003318860 0.0004151370
5039 0.00598372 0.00580493 0.00249222 0.00312610
40319 0.07176890 0.69810400 0.02297470 0.02608380
362879 0.77434000 241.62900000 0.24009400 11.61740000

Results

Пару слов о легенде, думаю не совсем понятно, что такое Initialized MFC map - это перед использованием CMap контейнер инициализируется количеством элементов которые в него вставят.После этого теста многое стало на свои места - мы используем тот случай, который имеет самый высокий столбец на графике. Вот так вот ...

boost::serialization - бинарная сериализация

Довольно часто приходться сериализовать\десериализовать объекты например при передачи их по сети. Вместо того, чтобы передавать MessageID и потом, расспознав его, принимать остальную часть сообщения, можно использовать библиотеку которая будет выполнять эту работу сама. Одной из библиотек котороя обладает вышеописанной функциональностью является boost::serialization По ссылке находится вполне исчерпывающая документация, но я столкнулся со сложностью и внятного ответа в документации не нашел. Проблема была в следующем, хотелось бы иметь возможность передавать по сети объекты наследованные от какого-нибудь базового класса и затем десериализовать их через указатель на базовый класс. Например:

 
class Base
{
};
 
class Derived:public Base
{
  int nValue;
};
 
//....
 
void save()
{
  Base* pDerived = new Derived;
  binarystream_out << pDerived;
};
 
void load()
{
  Base* pDerived = 0;
  binarystream_in >> pDerived;
};
 

Проблема заключается в том, что при десериализации член nValue класса Derived не будет корректно десериализован, он будет содержать какой-то мусор. В примерах к библиотеке эта проблема решается оригинальным способом, первый раз десериализовать объект явно указав его тип.

 
void load()
{
  Derived* pDerived ;
  binarystream_in >> pDerived;
  //после этого класс регистрируется  и ниже в коде можна вызывать
  Base* pDerived2;
  binarystream_in >> pDerived2;
  //десериализация проходит корректно
};
 

Наверное нелишним будет упомянуть, что я столкнулся с этой же ситуацией в MFC и долго просидел в дебагере пока понял что не так.

Проблема решается достаточно просто, достаточно зарегистрировать класс в input stream.

 
void load()
{
  Base* pDerived ;
  binarystream_in.register_type(static_cast<Derived*>(0));
  binarystream_in >> pDerived;
};
 

boost::serialization example