https://github.com/Sepuka/mysql2mongodb
Архив за месяц: Декабрь 2013
Отладка Android-приложения на устройстве
Тут написано как отлаживать на устройстве под Android, точнее как сделать так что бы при запросе списка устройств мы видели не знаки вопросов, а верное имя.
Запросить список устройств можно так
1 | ~/adt-bundle-linux-x86-20131030/sdk/platform-tools/adb devices |
~/adt-bundle-linux-x86-20131030/sdk/platform-tools/adb devices
и если мы видим что-то вроде
1 2 3 | List of devices attached
emulator-5554 device
???????????? no permissions |
List of devices attached emulator-5554 device ???????????? no permissions
Нужно склонировать git clone https://code.google.com/p/51-android/ репозиторий с вендорами (я выбрал этот путь), а можно прописать только одно устройство, как написано в статье по ссылке
А как узнать что писать в idVendor и в idProduct ? Попробовать посмотреть (при включенном устройстве) командой lsusb
1 2 3 4 5 6 7 | [14:58:54]shlomin@localhost:/tmp>lsusb Bus 001 Device 002: ID 0bda:0181 Realtek Semiconductor Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub |
[14:58:54]shlomin@localhost:/tmp>lsusb Bus 001 Device 002: ID 0bda:0181 Realtek Semiconductor Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
вот и все. Есть кстати список вендоров тут http://developer.android.com/tools/device.html
dialog. Управление Apache
В журнале «Системный администратор» 2005 год за февраль наткнулся на статью про использование UNIX-утилиты dialog с помощью которой можно делать ASCII-графические приложения для удобного администрирования. Тот пример который был в журнале у меня не работал, поэтому я его модернизировал и вот выкладываю.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #!/bin/sh dialog --title "Apache interface" --menu " Данный сценарий управляет web-сервером Apache. Выберите действие из предложенных ниже:" 15 50 7 start "Запуск сервера Apache" stop "Останов сервера Apache" restart ""Жесткий" перезапуск" graceful ""Мягкий" перезапуск" configtest "Тест конфигурационного файла" 2>apctl.tmp UCOMMAND=`cat apctl.tmp` if [[ $UCOMMAND != "" ]]; then dialog --title "confirm command" --yesno "Выполнить следующую команду ${UCOMMAND}?" 10 40 if [ $? = 0 ]; then if [ $UCOMMAND = "configtest" ]; then sudo /usr/sbin/apache2ctl -S else sudo /usr/sbin/apache2ctl -k $UCOMMAND fi fi fi rm apctl.tmp |
#!/bin/sh dialog --title "Apache interface" --menu " Данный сценарий управляет web-сервером Apache. Выберите действие из предложенных ниже:" 15 50 7 start "Запуск сервера Apache" stop "Останов сервера Apache" restart ""Жесткий" перезапуск" graceful ""Мягкий" перезапуск" configtest "Тест конфигурационного файла" 2>apctl.tmp UCOMMAND=`cat apctl.tmp` if [[ $UCOMMAND != "" ]]; then dialog --title "confirm command" --yesno "Выполнить следующую команду ${UCOMMAND}?" 10 40 if [ $? = 0 ]; then if [ $UCOMMAND = "configtest" ]; then sudo /usr/sbin/apache2ctl -S else sudo /usr/sbin/apache2ctl -k $UCOMMAND fi fi fi rm apctl.tmp
Не забываем поменять владельца файла
1 | chown root:root ФАЙЛ |
chown root:root ФАЙЛ
и дать ему SUID и сделать выполняемым
1 2 | chmod 766 ФАЙЛ chmod +S ФАЙЛ |
chmod 766 ФАЙЛ chmod +S ФАЙЛ
В итоге получаем такую картину:
После выбора нужного пункта появится подтверждение. Нужно нажимать скорее ДА, ты же не делал бы этого если бы был не уверен! Ведь правда?
Фоновое логгирование tcpdump
Пример команды для отлова «значащих» пакетов от конкретного пользователя на конкретный сайт. Размеры от 600 до 700 символов выбраны мной экспериментально. В пакетах такой величины с наибольшей долей вероятности будет содержаться логин и пароль, но конечно при условии если пользователь залогинится после запуска программы. Если он уже в системе, то можно брать cookie, но логин с паролем конечно иметь интереснее.
1 | tcpdump -s 0 -l -A dst vkontakte.ru and src 192.168.0.11 and greater 600 and less 700 -w /opt/var/log/vkontakte.log & |
tcpdump -s 0 -l -A dst vkontakte.ru and src 192.168.0.11 and greater 600 and less 700 -w /opt/var/log/vkontakte.log &
Привожу пример запроса которые поймался
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | POST /?act=login HTTP/1.1 Host: login.vk.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2.12) Gecko/20101026 SUSE/3.6.12-0.7.1 Firefox/3.6.12 GTB7.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Referer: http://vkontakte.ru/ Content-Type: application/x-www-form-urlencoded Content-Length: 112 from_host=vkontakte.ru&captcha_key=&captcha_sid=&expire=&al_frame=1&email=user%40yandex.ru&pass=password |
POST /?act=login HTTP/1.1 Host: login.vk.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2.12) Gecko/20101026 SUSE/3.6.12-0.7.1 Firefox/3.6.12 GTB7.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Referer: http://vkontakte.ru/ Content-Type: application/x-www-form-urlencoded Content-Length: 112 from_host=vkontakte.ru&captcha_key=&captcha_sid=&expire=&al_frame=1&email=user%40yandex.ru&pass=password
Это просто «мем» для себя. Параметр -l здесь необходим для того чтобы при демонизации процесса с помощью & программа писала вывод в файл, если не указать, то файл останется пустым. Еще нужно помнить о том, что в этом случае мы не сможем прочитать сами запросы, они запишутся в бинарном виде. А заголовки сможем. Поэтому если нужно читать сами тела запросов, не указывайте параметр -l и не пишите в файл, а пишите на экран, там будет все видно.
p.s. Контакт давно перешел на https и с помощью этого примера поймать авторизацию не удасться
Выделение связанной группы строк компонента Ext.grid.Panel
Недавно понадобилось выделить произвольную группу строк в элементе таблицы grid, решения сходу не нашлось. В основном предлагалось править css-свойства строк, что для меня показалось слишком сложным. Поясню точную задачу которая передо мной стояла: строки в таблице связаны между собой некоторым полем ID_Parent указывающим на поле ID_Operation, т.о. одна строка как бы порождает другую, затем эта другая следующую… При этом строки могут порождать несколько строк параллельно, создавая различные ветки.
Для того чтобы начать работу алгоритма нужно повесить обработчик событий click на таблицу
itemclick: {fn: function(self, record, item, index, e, opts) {} }
Затем найдем корневую строку в этом списке
root = findRootOperation(record); с помощью функции описанной ниже function findRootOperation(record) { parent = store.find("ID_Operation", record.get("ID_Parent")); if (parent == -1) return record else return findRootOperation(store.data.getAt(parent)) }
Теперь можно получить весь список строк-детей в массив
var toHighLight = new Array(); function collectionRowIndexes(parent) { rowIndex = store.find("ID_Operation", parent.get("ID_Operation")); toHighLight.push(rowIndex); var childIndex = store.find("ID_Parent", parent.get("ID_Operation")); while (childIndex != -1) { collectionRowIndexes(store.data.getAt(childIndex)); // Ветки иногда распараллеливаются, поищем еще детей var childIndex = store.find("ID_Parent", parent.get("ID_Operation"), childIndex + 1); } }
Все. Проходим по массиву и подсвечиваем нужные строки
for (var key in toHighLight) { grid.getSelectionModel().select(toHighLight[key], new Boolean(true)); } toHighLight = new Array();
Собственно все что написано — лишнее, суть только в строке grid.getSelectionModel().select(номер строки, не отчищать другие строки) + нужно не забыть сделать grid.getSelectionModel().setSelectionMode(«MULTI»); т.е. добавить возможность множественного выделения строк.
Последний код следует добавить в itemclick. В итоге получается вот так
Логгирование с повторным использованием параметров
В проекте discounter я использовал простое логирование с помощью модуля logging. Проект состоит из модулей которые пишут свои сообщения в один и тот же файл. Понятно, что можно изменить шаблон логов таким образом для определения того кто пишет
logging.Formatter("%(asctime)-15s %(levelname)-8s [%(moduleName)-10s] %(message)s")
Где moduleName есть имя модуля. Это все довольно просто. Но мне не нравится всегда писать длинные конструкции вроде
self._log.info("Лог в файл %s", var, moduleName=moduleName)
Т.е. вечно пихать в и так длинную строку еще имя модуля. Т.о. предлагаю такое решение: В классе модуля переопределить __getattr таким образом
def __getattr__(self, name): try: return self._logNamesPart[name] except KeyError: obj = getattr(self._log, name) if obj is not None: part = partial(obj, moduleName=self.__class__.__name__) self._logNamesPart[name] = part return part else: self._log.error("Попытка вызова несуществующего типа лога "%s"", name, moduleName=self.__class__.__name__)
Теперь при создании лога я пишу так
self.debug("Запущен парсер")
и все. При этом создается запись с необходимым именем модуля. Объясню код: существует удобная функция partial с помощью которой можно повторно вызывать функцию не повторяя каждый раз параметры вызова, а указывать только изменившиеся. Получается что при вызове лога с уровнем info, создается partial-функция и сохраняется во внутреннее свойство _logNamesPart, в следующий раз при вызове info, partial будет взят от туда, а если будет вызван другой метод, например debug, он также будет создан и сохранен для последующего использования. В результате я укоротил вызов лога с
self._log.debug("Запущен парсер", moduleName=moduleName)
до
self.debug("Запущен парсер")
Работа с twitter API
Используя twitter API я написал короткую программу которая пишет сообщения в твиттер. Реализована также возможность читать твиты, но она не используется.
Программа размещена на github и работает по принципу UNIX pipe, например:
1 | echo "сообщение" | logotwit.py |
echo "сообщение" | logotwit.py
Настраивается через конфигурационный файл config.ini
Т.о. я пишу через cron разные системные сообщения сервера и слежу за его состоянием. Примеры сообщений:
1 2 3 4 | uptime | logotwit.py # аптайм sensors | logotwit.py #температура #проценты остатка места на харде df | sed "1d" | awk "{print $1,$5}" | tr "\n" "; " | logotwit.py |
uptime | logotwit.py # аптайм sensors | logotwit.py #температура #проценты остатка места на харде df | sed "1d" | awk "{print $1,$5}" | tr "\n" "; " | logotwit.py
Замедление работы сети
Используя ip-relay можно замедлить сеть. Пример:
1 | ip_relay -b 2048 8033:127.0.0.1:3306 |
ip_relay -b 2048 8033:127.0.0.1:3306
т.о. натравливаем приложение на порт 8033 и оно будет общаться с тем кто его слушает на порту 3306 через эту программу со скоростью не превышающей 2Б/с
Очень удобно когда нужно смоделировать сильнонагруженную БД или что-либо и посмотреть как на это реагирует приложение.
Быстрый прокси-сервер
1 | ssh -4 -D 8080 -p 1234 user@111.222.333.444 |
ssh -4 -D 8080 -p 1234 user@111.222.333.444
Параметр -4 тут потому что я получал ошибку bind: Cannot assign requested address
Работа с удаленными ФС
Иногда нужно смонтировать удаленную файловую систему, например, я разрабатываю ПО которое организовано в виде deb-пакета, причем делаю я это на rpm-based машине, т.е. устанавливать такой пакет будет затруднительно для тестирования. Можно исходные данные поместить на тестовый сервер и править текст на своем любимом редакторе на локальной машине. Пример:
1 | sshfs -p 8022 shlomin@127.0.0.1:/home/user/vcard /home/user/server.gates/ |
sshfs -p 8022 shlomin@127.0.0.1:/home/user/vcard /home/user/server.gates/
Это вообще говоря довольно простой и известный способ, но я хотел указать на то, что специально указал порт 8022, чтобы показать что тот сервер который я хочу юзать находится во внутренней сети доступ к которую есть через третий сервер, а этот самый третий сервер я предварительно проксирую через ssh, например так:
1 | sudo ssh -L 8022:192.168.77.80:22 user@server |
sudo ssh -L 8022:192.168.77.80:22 user@server
получается ssh слушает 8022 и проксирует трафик через третий сервер на целевую машину 192.168.77.80 уже на 22 порт. Чтобы размонтировать ресурс, достаточно выполнить команду
1 | fusermount -u /home/user/server.gates/ |
fusermount -u /home/user/server.gates/
где /home/user/server.gates/ есть точка монтирования.