17 Июль 2009

Colored svn diff

С подачи Тапа делаем svn diff а-ля гит - цветной и в less'е:

1 #!/bin/sh
2 svn diff | awk '/^\+(.*)$/ { print "\033[32m" $0 "\033[0m"}; /^-(.*)$/ { print "\033[31m" $0 "\033[0m"}; /^[^+-].*$/ {print $0}' | less -r

14 Июль 2009

О моветоне в поведении моего блога

Обратил внимание после того, как мне пришёл комментарий. Внезапно в ленте руникса всплыли все (или многие, не суть) мои записи про линукс. Подозреваю в этом глюк гугла, который недавно заподозрил мой блог в спаме и заблокировал, вероятно происшедшее - результат разблокирования. Хотя в ридере лента этого блога не обновилась (да, я читаю себя и иногда даже нахожу опечатки и отправляюсь править пост), так что это может быть и глюк агрегатора руникса. Делайте выводы.

Роутинг в Camping, Regexp'ы в Ruby

Если коротко - не следуйте документации в способе задания роутов для контроллеров. Документация советует так:

147   class AccountAck < R '/([\dabcdef]+)/'
А надо так:
147   class AccountAck < R %r!/([\dabcdef]+)/!
иначе может статься, что на более сложных роутах вы получите 404.
PS: если кто запамятовал, то %r!regexp! (где вместо ! может быть и другой символ) - это такой способ обрамить регексп, наряду с /regexp/

12 Июль 2009

Github'но-тестировочное

Смотрел я тут скринкаст на тему ObjC, было там немного про тестирование, и понял я - дальше так нельзя - тестировать. Полез в гугль (хотя кхе, туда я за этим давно залезал, руки не доходили применить), тот меня выкинул сначала на одного из коммитеров в Camping с его тестсьюитом 'camping/test', а потом и на mosquito в репозитарии автора того самого скринкаста. Скажу сразу, москит отстал от жизни и не работает, зато в том репозитории нашлось много полезного: ruby-style категории над основными Cocoa классами, скрипты для правильной максимизации окна (очень пригождается с MacVim) и куча пищи для размышлений.

Заодно накидал Rake task для дампа фикстур из используемого кемпингом (и только кемпингом, забудем про Rails, аминь) sqlite:

 1 require 'rake'
 2
 3 require 'rubygems'
 4 require 'activerecord'
 5
 6 desc "Generate fixtures for all tables of current project"
 7 task :generate_fixtures do
 8   database = "#{ENV['HOME']}/.camping.db"
 9   ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => database)
10   project = File.basename(File.expand_path('.')).downcase
11   tables = `sqlite3 #{database} ".tables"`.split(' ').reject{ |t| t.include?("sessions") || t.include?("schema_infos")}.collect{|t| t if t.include? project}
12   tables.each do |table_name|
13     File.open("test/fixtures/#{table_name}.yml", 'w') do |file|
14       data = ActiveRecord::Base.connection.select_all("SELECT * FROM #{table_name}")
15       rows = {}
16
17       data.each do |record|
18         rows["#{table_name}_#{record['id']}"] = record
19       end
20
21       file.write rows.to_yaml
22     end
23   end
24 end

Там много 'длиннострочников', но понять можно. Дампит все таблицы используя в качестве имени проекта имя текущей директории.
Не могу не пнуть попутно юродивый svn - перед тестированием всего и вся разложил сорцы по полочкам, так svn положенный в другое место файл считает новым, в то время как гит даже частично патченный и перемещённый после этого файл понимает и считает именно перемещённым.
Думается, пора покрыть тестами, оформить и выкинуть на гитхаб в виде библиотечки часть одного интересного проекта, но это уже как руки дойдут.
Stay tuned.

05 Июль 2009

ActiveSupport и Logger

NEVER Override Existing Methods.
Never, ever do this. Never override an existing method. Period, full stop, no excuse.
Rails Worst Practices: 13 Coding Nightmares You Should Avoid


Сначала грешил на Camping. А Camping использует ActiveSupport. И вот к чему это приводит.
ActiveSupport весь такой на белом коне приходит и превращает все сообщения стандартного логгера в абсолютно бесполезные puts без какой-либо полезной информации о времени и уровне сообщения. В документации способ отключения этого безобразия либо нерабочий либо нетривиальный - у меня не пошло. Ну так по рукам ему за это!
class Logger; undef format_message; alias format_message old_format_message;end

04 Июль 2009

ActionMailer с Gmail без Rails: Camping

В последнее время пишу прототип внутреннего сервиса на Camping. Попутно должен заметить, что это весьма хорошая штука от чокнутого _why для очень быстрого прототипирования - весь мой фронтэнд лежит в одном файле и занимает 150 строк.
И само собой, без отправки электронной почты не обошлось. А раз уж camping это такие очень маленькие рельсы - почему бы не встать на плечи ещё одного из гигантов мира рельс - ActionMailer. К условиям задачи добавилась и необходимость использования Google Apps for Domains.
Первым делом нужно научить Ruby <= 1.8.7 там авторизоваться:

sudo gem install openrain-action_mailer_tls -s http://gems.github.com

подробнее
и в корне проекта с camping приложением создаём mailer.rb

# for this example the folder structure should be as follow
#
# --+ camping_project_root
#   |-- mailer.rb (this file)
#   |--+ mailer
#      |-- new_account.erb
 
require 'rubygems'
require 'action_mailer'
require "smtp_tls"
 
class Mailer < ActionMailer::Base
  def new_account(bar)
    recipients recipient
    from      "noreply@company.com"
    subject   "New account confirmation"
    body      :foo => bar
  end
 
end
 
Mailer.template_root = File.dirname(__FILE__)
 
Mailer.smtp_settings = {
  :address  => "smtp.gmail.com",
  :domain => "company.com",
  :port  => 587,
  :user_name  => "noreply@company.com",
  :password  => "noway",
  :authentication => :plain,
  :enable_starttls_auto => true
}


И в camping приложении подключаем этот мэйлер.

20 Июнь 2009

Использование акселерометра мака для симулятора

Захотелось мне использовать в своём приложении акселерометр, симулятор его не поддерживает, а железяка для тестирования ещё в пути. А тут такая оказия - на ловца и пост с описанием и решением проблемы бежит.
Если очень коротко, то идея состоит в захвате данных с акселерометра мака и посылке этих данных по сети приложению в симуляторе.
Итак, берём Unimotion, собираем, туда же кладём питон скрипт, приведённый в указанном выше посте. Запускаем эту связку:

./motion -f 17 | python sendaccsim.py

Из симулятора акселерометра берём два файла (AccelerometerSimulation.h и AccelerometerSimulation.m) и подключаем хедер там, где используем акселерометр. Запускаем симулятор, крутим наш мак и так и сяк. Со стороны выглядит странно, внимание, использовать только при наличии вменяемых коллег.

Пара MacOs полезностей

Как и всякий свитчер, пытаюсь прогнуть под себя новое окружение. Сгладить неровности отсутствующих возможностей. И вот две из них.

Возможность развернуть окно по хотекею.
Ну что за моветон, показывать в окне лишь часть необходимого для восприятия содержимого, и не иметь в самой keyboard-friendly системе шортката для разворачивания окна? Solved. Читаем пост, пишем скрипт, вешаем на хоткей в QuickSilver.

Возможность запретить показ иконки запущенного приложения в доке.
Я и так знаю, что у меня бегут QuickSilver и Namely, мне не нужны их иконки в доке. И если первый имеет для такого опцию - что с остальным? Dock Dodger в помощь. Читаем дисклеймер, не пугаемся - всё обратимо, отучаем приложения от дурного поведения.
Пока всё, остался открытым вопрос файлового менеджера.

14 Июнь 2009

Linux -> MacOs switcher'ство

Ну вот вам и первый свитчерский пост.
Я не буду говорить, как хорош или плох мак и линукс, я яростно ненавижу макодрочеров и не понимаю оголтелых линупсоедов (да-да, можете начинать отписываться), скажу в этой заметке лишь о том, чего мне не хватало в маке после линукса.
Вообще, хорошей отправной точкой может послужить SIMBL с его плагинами, из которых я сразу поставил InputSwitcher, дабы в каждом окне была своя раскладка клавиатуры (согласитесь, глупо иметь в терминале русский и в IM, за редким случаем, английский) и Visor - терминал должен быть под рукой всегда, на любом из Spaces, а это и zsh и git и vim и многое другое. В качестве замены gkrellm (не идеальной, не хватает иногда шкал, обновляемых в реальном времени) подойдёт iStatMenus - видно, когда процесс ушёл в бесконечный цикл, пора прибить обожравшийся памяти браузер или невовремя дорвавшийся до тарифицирумого траффика iTunes. Для быстрого запуска приложений в стиле автодополнения коммандной строки и krunner подойдёт namely.
Кроме того, нашёл мак сборки давно знакомых вещей - git, MacVim, zsh, arora, keepassx - это всё-таки такой специальный уличный юникс, много чего родного тут работает.
Чего не хватает до сих пор - толкового двухпанельного файлового менеджера и плеера (iTunes не предлагать, плавали  - знаем). Тут я готов прослыть извращенцем и поставить krusader & amarok в маковской сборке.
Такой вот кратенький забег. Для остального либо нашлись очевидные аналоги - либо вопрос пока открыт...

13 Июнь 2009

О текущем положении

В связи с некоторыми жизненными обстоятельствами, сдерживающими публикацию материалов, часть их пролежала даже не в столе а в голове, но Besser spät als gar nicht, как говорят немцы.
Итак, уже две недели я работаю в новой компании, основная сфера моей деятельности теперь будет связана с разработкой под маки и в частности под iPhone OS. Как вы понимаете, из этого вытекает несколько вероятных следствий:
  • появятся посты с мак и свитчерской тематикой
  • появятся посты о разработке в данной области
  • посты про Linux не пропадут, но упадёт их частота
  • к maemo возможно даже увеличение внимания - я стал чаще таскать свою таблетку
Ну вот, предупреждённый вооружён, думайте сами, а я пока продолжу просвещаться, радоваться жизни и черкать следующую заметку.
PS: Тап, опять тебе спасибо.

28 Май 2009

низкий уровень звука в maemo

Продолжая ковырять таблетку.
Как уже неоднократно убеждались владельцы, использовать maemo девайсы в качестве плеера крайне неудобно - они тихие.
А дело в том, что каждый раз при втыкании и вытыкании наушников программым методом снижается уровень pcm канала. Понаблюдать и порулить этим можно из миксера aumix, который водится в том же треде. И как одно из решений - тем же самым аумиксом по крону устанавливать звук на максимум (не бойтесь, не оглохнете - плеера управляют другим каналом):

aumix -w + 100

Это решение универсально и гарантированно выжмет максимум во всех приложениях. Правда, не кардинально, но ощутимо.

Ещё один путь - сорвать к чертям программный микшер, что, например, позволяет делать mplayer:
cat ~/.mplayer/config
softvol=1
softvol-max=300

300% от нормального - уже достаточно для мегаполиса и поездов с идущей в комплекте гарнитурой (даже слегка слишком - появляются шумы, которые слышны даже моему отдавленному взводом медведей уху). Минус - шумы, не все плееры поддерживают вывод через mplayer (kagu умеет).

В принципе, этого достаточно, хотя остаётся ещё несколько путей - replay gain, HAL, крутейшие наушники KOSS - но я уже слегка оглох...

27 Май 2009

идентификация ОС

Байка: в одном продукте под ОС семейства видовс версия ОС определялась по наличию в корне диска c: папок с именами windows, winnt и т.п., что приводило к странным флуктуациям при наличии нескольких или отсутствию таковых.

Призказка: работал на n810 плеер kagu, да и перестал. И UKMP тоже перестал. А без kagu n810 вообще не плеер, поскольку была в kagu самая главная возможность любого плеера - быстро поставить его на паузу (аппаратной кнопкой на корпусе или на родной гарнитуре).

Сказка: а причина была как в той самой байке - из-за странного способа идентификации ОС: по наличию определённого пути (который я удалил, дабы в автодополнении шелла не мешал). Вот так:

#/usr/bin/MediaCenter.py
if os.name=="posix" and os.path.exists('/media/mmc1'): ISMAEMO=1

Из-за этого устанавливалась неправильная глубина цвета и любое приложение, использовавшее pygame, падало.

Мораль: надо определять ОС другим способом. Хотя бы по ядру:
uname -a
Linux Nokia-N810-23-14 2.6.21-omap1 #2 Wed Jul 16 12:29:11 EEST 2008 armv6l unknown

12 Март 2009

дисковые буфера и hibernate в Linux

Пока нет ничего серьёзного к опубликованию, вот вам лёгенькая тема.
Заметил давно, что используемый мой метод hibernate в виде ядра с патчами tuxonice и скриптом оттуда же ну слишком уж медленный. Краткое раскидывание мозгами и раскапывание вопроса показало, что достаточно большую долю времени занимает сохранение дисковых буферов, что само по себе весьма экстравагантный финт - сохранять на винт кеш обращений к винту. Решил отключать кеш перед засыпанием и восстанавливать после просыпания:

#/etc/hibernate/common.conf
OnSuspend 10 echo 3 > /proc/sys/vm/drop_caches
OnResume 10 echo 0 > /proc/sys/vm/drop_caches

Время засыпания теперь - "как в лучших домах Лондона и Филадельфии".

01 Март 2009

Убираем многословность в Kopete

Часто бывает - постишь код, кусок документации или просто цитату в Kopete и лог разговора моментально забивается так, что за деревьями леса не видно. Скальпель!
В папке с темой оформления окна разговора Kopete (я скопировал одну из стандартных, получился такой путь: ~/.kde/share/apps/kopete/styles/PXClear/Contents/Resources) ищем main.css и добавляем

.OutgoingMessage, .NextOutgoingMessage
{
            height: 40px;
            overflow:hidden;
}

.OutgoingMessage:hover.NextOutgoingMessage:hover
{
            height:auto;
}

.IncomingMessage, .NextIncomingMessage
{
            height: 40px;
            overflow:hidden;
}

.IncomingMessage:hover.NextIncomingMessage:hover
{
            height:auto;
}


посты длиннее двух строчек (с моим размером шрифта) отображаются полностью только при наведении на них мышки.

28 Февраль 2009

О web-based IDE и тонких клиентах вообще

Вся эта шумиха вокруг web-based IDE(bespin, heroku) и тонких клиентах для веб-сервисов вообще (google mail, docs) останется шумихой до тех пор, пока тонкий клиент (ноутбук, MID, телефон etc. + браузер) не будет считаться неработоспособным, если он не в состоянии функционировать в течении всего периода бодрствования человека без подзарядки (скажем 20 часов - в случае более длительного периода без доступа к розетке вам скорее нужно ружьё, нож и палатка) и обеспечить доступ в сеть из любой точки земного шара, включая метро, самолёт, глухую тайгу и дикие горы.

08 Февраль 2009

Improving KDE4.2 taskbar plasmoid

Захотелось мне удобства дополнительного в вышеозначенном плазмоиде, а именно - знакомого по браузерным вкладкам поведения, когда шелчок по заголовку вкладки средней кнопкой закрывает её. Так и тут захотел закрывать окна шелчком колеса на соотв. кнопке таскбара (важно - при этом не затрагиваются окна, бывшие ранее в группе - я не использую группировку). В общем-то, всё просто, хотя пришлось вспомнить великий могучий цпп и поползать по иерархии классов:

 1 diff --git a/plasma/applets/tasks/windowtaskitem.cpp b/plasma/applets/tasks/windowtaskitem.cpp
 2 index aaaabbd..d4adaa4 100644
 3 --- a/plasma/applets/tasks/windowtaskitem.cpp
 4 +++ b/plasma/applets/tasks/windowtaskitem.cpp
 5 @@ -84,6 +84,10 @@ void WindowTaskItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
 6          if (isGrouped()) {
 7              parentGroup()->collapse();
 8          }
 9 +       else{
10 +           m_task->close();
11 +           close();
12 +       }
13      } else {
14          AbstractTaskItem::mousePressEvent(event);
15      }


В связи с чем вопрос - кому-то интересно такое поведение плазмоида?

02 Февраль 2009

gentoo, kdeprefix useflag, KDE 4.2, Phonon and backends

Ну в общем в курсе все, что 4.2 вышел, он крут и наступило щастье. Так что это пока не обсуждаем.
А вот то, что поломался звук - предмет нашего разговора.
Поломался звук, amarok не играет, а всё потому что phonon не видит свои backend'ы, ибо всё раскидано в разных местах, понеже кто-то на useflag kdeprefix внимание обращает, а кто-то нет и кладёт всё по FHS.
Варианта, как водится, два.
1. Отмержить к чёрту все версии KDE ниже 4.2, отключить kdeprefix, только тогда ставить 4.2. Более правильный на мой взгляд. В воздухе повисшим оставим тот вопрос, что же делать с k3b и прочим антиквариатом.
2. Помочь найти потерянные backends.

ln -s /usr/share/kde4/services/phononbackends/ /usr/kde/4.2/share/kde4/services/phononbackends

Костыль, но быстрый и действенный.

31 Январь 2009

Escaping Unicode in Ruby

Ещё одна крупица мудрости и благодати позволит преобразовывать non-ASCII символы в строке в их экранированный Unicode эквивалент вроде \u0444:

1 class String
2   def escape_unicode
3     unpack('U*').map {|c| c < 0x80 ? c.chr : '\u%04x' % c}.join
4   end
5 end


>> puts "фывыфdd".escape_unicode
\u0444\u044b\u0432\u044b\u0444dd

Работает и в 1.8 и в 1.9.
Воистину, Ruby велик и Hal Fulton его пророк.
По мотивам одного перлового модуля. Короче в 5 раз.

29 Январь 2009

Midori, Mer, Nokia Internet Tablets, webkit.



Это именно то, о чём я так долго мечтал и считал единственно приемлемым для NIT - легковесный webkit-based браузер вместо того убожества, которое есть сейчас. Его ещё конечно нужно допиливать, в частности хилдонизировать, но это уже мелочи.
Собственно сама основная новость - выход Mer - не менее важна, читать рукоммендую тут.

26 Январь 2009

Дата в maemo

Приложение "Часы" в ITOS, скажем так, несколько странное, и при установке даты заставляет устанавливать не часовой пояс, а город, в списке доступных городов моего города нет, более того, города, по которому назван мой часовой пояс, там тоже нет! Такого бредового подхода я нигде не видел, да везде можно установить свой пояс в Asia/Yekaterinburg! Так что открываем рутову консоль и колдуем стандартное

echo "Asia/Yekaterinburg">/etc/timezone
date 01252055 (см. UPD)

Доступные временные зоны можно поглядеть так: ls -R /usr/share/zoneinfo/, а время записывать в формате ММДДЧЧмм.
Ещё +1 к карме и +5 к кошерности девайса.
UPD: я тут сам был и других ввёл в заблуждение. Оказывается, maemo не сохраняет системное время в аппаратные часы, что приводит к тому, что после перезагрузки время опять возвращается на круги своя. Из используемого в maemo busybox стандартная утилита для синхронизации системного и аппаратного времени hwclock была вырезана. Установить аппаратные часы можно так:
/mnt/initfs/usr/bin/retutime -T 2009-01-25/20:04:36

При этом время нужно указывать UTC (или гринвическое, как удобнее называйте).