Monday, November 22, 2010

Японса развлекается

Mary had a little lambda, its syntax white as snow:

% tail -30 ~/.emacs.d/lisp/twittering-mode/twittering-mode.el

(provide 'twittering-mode)
;;; twittering.el ends here

         (progn  (when  (
          boundp  (  intern (
           mapconcat 'identity '
           ("twittering" "oauth"
             "consumer" "key" ) "-"
              )  )  )   (eval  ` (
               setq ,(intern (mapconcat
                (quote identity) (quote
                 ("twittering"    "oauth"
                  "consumer" "key")  )"-"
                  ))  (base64-decode-string
                (apply  'string  (mapcar   '1-
               (quote (83 88 75 114 88 73 79 117
             101 109 109 105 82 123 75 120 78 73
            105 122 83 69 67 78   98 49 75 109 101
          120 62 62))))))))(       when ( boundp  (
         intern (mapconcat '      identity'("twittering"
        "oauth" "consumer"         "secret") "-")))(eval `
       (setq  ,(intern   (         mapconcat 'identity '(
      "twittering" "oauth"          "consumer" "secret") "-"))
     (base64-decode-string          (apply 'string (mapcar '1-
    (quote   (91   70                    113 87 83 123 75 112
   87 123 75 117 87 50                109 50  102  85 83 91 101
  49 87 116 100 73 101                  106 82 107 67 113  90 49
 75 68  99  52  79 120                   80 89  91  51  79 85 71
110 101  110 91  49                      100 49   58  71)))))) )))

The remains of the day can be killed by reading (& using)
https://github.com/hayamiz/twittering-mode/.

Thursday, October 28, 2010

Patches for Claws Mail

Думал избавить claws mail от идиотской манеры гадить в ~/.claws-mail/newscache, а там оказалось не все так просто.

Оно сначала делает кэш, а потом читает с получившегося локального файла письмо. И точно также с imap. Пошуршал по плагинам--глухо. Зато обнаружил функцию folder_func_to_all_folders() и готовую функцию удаления кэша из 1 фолдера.

Тоскуя по mutt, нельзя не вспомнить как он дает прыгать к новому письму не открывая его и не трогая при этом флаги read/unread. Ужасно удобно, когда заходишь в newsgroup, где томятся 2584 старых письма и светятся 315 новых, раскиданных по 491 треду. В claws mail прыжок к новому письму всегда автоматически его (письмо) открывает, что иногда доводит меня до бешенства.

В общем, патчи для версии 3.7.6 лежат тут. Кто собирает порт в FreeBSD--просто киньте их в директорию files порта и собирайте порт как обычно. После инсталляции, в меню Tools появится пункт Purge Cache, а Go to Next/Previous Unread Message начнет работать правильно.

Tuesday, October 12, 2010

iTunes U RSS feeds

Часто, публичное в iTunes U которое читалось не last fall, а обновляется сейчас, хочется качать как подкаст без помощи толстопузого iTunes, что как бы официально нельзя. Ну, конечно, разумеется можно, только нужно для каждого курса знать URL секретной feed.

Если я правильно понял, университеты либо просто дают iTunes U свою feed (тогда URL ее, как правило, указан на сайте университета), либо закачивают файлы в эппловскую тучу, которая генерирует RSS сама. То есть, в любом случаи iTunes U сперва тянет feed и ничем это от обычного подкастинга не отличается.

Например, на talks в Yale Entrepreneurial Institute, подписаться никак, кроме как через благодаря посредством iTunes не дают. Но если посмотреть, например, wireshark'ом, куда iTunes незаметно лезет за файлами, то мы видим вот такую URL:

http://deimos3.apple.com/WebObjects/Core.woa/Feed/yale.edu-dz.4357409176.04357409178

Content-Type у нее почему-то text/html, но эта обычная, скучная rss 2.0. Проблемы начинаются, если скачать несколько (например, 4) enlosures одну за другой. В зависимости от степени тупости вашего podcacher'а, можно получить 1 (один) файл enclosure.mp3 содержащий либо 1-ю по списку enlosure либо 4-ю, но не все 4 файла по отдельности.

Почему? URL на mp3 файлы в у iTunes U вот такой:

http://deimos3.apple.com/WebObjects/[всякое].4721501315/enclosure.mp3

где изменяется только набор цифр, а предполагаемое имя для файла дается всегда одинаковое enclosure.mp3--что привело предыдущую версию uraniacast в тихое помешательство. Впрочем, в хедерах той URL стоит Content-Disposition: inline; filename=2001_conde.mp3, что дает некоторую надежду, если попытаться сказать podcacher'у: "смотри на Content-Disposition, а не на URL".

To make long story short. Теперь в uraniacast 0.16 можно указывать feed-specific downloader, а не только глобальный для всех. Для замученного Yale Entrepreneurial Institute получилось так:

# a crappy link from itunes
set feed(biz.yale.entrepreneurial_institute) {
    url {http://deimos3.apple.com/WebObjects/Core.woa/Feed/yale.edu-dz.4357409176.04357409178}
    sort decreasing
    fetch {curl -OJ --noproxy * %u}
}

Huzza!

Friday, October 1, 2010

A Horror Story From z1

Date: Tue, 28 Sep 2010 19:49:27 -0700
From: Ilya L <lvi123@yahoo.com>
Newsgroups: alt.russian.z1
Subject: Re: Chase online

On 9/28/10 5:52 PM, Sol Windborn wrote:

>> Только для чего-то наколенного, наверное. В нетривиальном коде
>> найдется кусочек, который на stdout вывалит debug message и кранты.
>
> Если что-то плюется отладкой на консоль, то это, скорее, наколенное.
> Ненавижу. Убивать сразу.

        У меня был чрезвычайно печальный опыт с приложением, которое с какой-то
забытой целью закрывало свой stderr. Наверное, чтобы ничего на консоль
не лезло. Наш код открывал /dev/sda. И так как descriptor #2 был unused,
этот /dev/sda туда и попадал. И отладка, которая печаталась once in a
blue moon, писалась в master boot record. Application занимался backup-ом :)

Saturday, September 4, 2010

Левая сторона---правая сторона

UI вопрос, который гложет немногих: почему абсолютно все ставят scrollbar справа?

Ответы какие-то скучные: "исторически" или потому, что якобы когда пользователь заканчивает читать абзац, это случается у правого края окна или потому что курсор мыши мерещится мозолистой рукой, которая бы закрывала собой текст, если бы тот scrollbar был слева.

Разумеется, все эти аргументы (кроме "исторического")--полная чепуха. Кто-то в майкросовте в 1987 году спросонья засунул scrollbar и кнопочки закрытия окошка справа, а как виндюк захватил все, дизайнеры интерфейсов, кивая друг другу, тонкою мыслью сплели себе на несчастных головах паранджу.

  1. Современный пользователь не читает внимательно страницу от корки до корки: он прыгает по абзацам, ищет глазами списки, короткие предложения и картинки. Если он смотрит на страницу на left-to-right языке, его глаза натыкаются на углы абзацев слева.

  2. Когда пользователь просмотревший все абзацы, хочет проскролить ниже или узнать свою текущую позицию на странице, ему приходится двигать глазами вправо--прямо к scrollbar, то есть в противоположном направлении. Чем шире окно, в которое он пялится, тем мучительнее для него это действие.

    Примером клинического маразма тут является броузеры у которых кнопки назад/вперед расположены слева вверху, а scrollbar, разумеется, на другой стороне экрана. Хотел бы я знать, какой идиот это первым придумал (у Бернереса-Ли на скриншоте его первого броузера scrollbar слева, потому что а) он писал его под NeXT, где scrollbar везде слева по умолчанию, б) у него есть мозг).

  3. Если пользователь таки допустим читает абзац целиком и этот абзац оказывается в самом низу страницы, то глаза пользователя будут в правом углу только тогда, когда конец последнего предложения абзаца заканчивается ближе к правой стороне.

    Всегда ли это верно? В каких случаях абзацы идеально подогнаны в идеальные прямоугольники? Возможно ли вообще это реализовать, если страница растягивается/сжимается динамически в зависимости от размеров окна, а не прибита гвоздями в свои n пикселов шириной? Как абзацы будут себя вести, если пользователь изменил масштаб шрифта в броузере?

    По контрасту, левый угол заполнен всегда, вне зависимости от длины абзаца, даже если абзац состоит из 1 буквы и 1 точки.

  4. Некоторые говорят, что курсор мыши им визуально мешает, когда он слева от текста, тогда когда справа обычно посвободнее, поэтому им более комфортно тыкать в scrollbar справа.

    Это тот случай, когда дизайнеры наперед зная то, что scrollbar всегда будет справа, экономят место и специально убирают поле слева, а потом храбро приводят такие страницы в доказательство.

    Это как если ввести левостороннее движение, но машины делать только с левым рулем и громко возмущаются до чего же не комфортно стало ездить.

    Кто сомневается, рекомендую взять вот этот Tk скрипт и попробовать поскролить в ситуации, когда поля у текста одинаковы.

    http://lh6.ggpht.com/_W-OHaMHyRAE/TIGK59o9PzI/AAAAAAAAAIw/omC9l2fvNeo/s400/scrollbar_test.png

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

Monday, August 23, 2010

Minimal open-vm-tools for FreeBSD 8.1

(For newcomers: есть предыдущие серии.)

Обновленный package для 8.1 лежит вот тут. Это версия от 2010.04.25; в более новых грохнули vmware-user, а все его функции перенесли в плагины для vmtoolsd, что означает то, что мне нужно читать код vmtoolsd заново. До выхода 8.2 делать я этого не буду, хотя там много интересного, если верить анонсам.

Friday, May 28, 2010

О горькой судьбе математишанс

A joke from mathoverflow:

A mathematician who studied a very abstract topic was annoyed that his peers in more applied fields always made fun of him.

One day he saw a sign "talk today on the theory of gears", and said to himself "I'll go to that! What could be more practical than a talk on gears?".

He arrives at the talk, eager to learn applicable knowledge. The speaker goes up to the podium and addresses the crowd: "Welcome to this talk on the theory of gear. Today I will be speaking about gears with an irrational number of teeth".

Sunday, April 4, 2010

A Simple FVWM Vector Buttons Viewer

Говорят, когда-то в Киеве жил человек, который мог глядя на

ButtonStyle 6 Vector 13 60x20@0 60x40@0 80x40@1 80x60@0 60x60@0 60x80@0 \
                        40x80@0 40x60@1 20x60@0 20x40@1 40x40@1 40x20@1 \
                        60x20@1

через 15 секунд сказать, что это стрелочка:

1 KB

Тому, кто такими способностями не обладал, оставалось 2 варианта: наплевать (популярный) или пользовать готовые кнопки из коллекции на fvwm.org.

Но теперь, в наши светлые времена, можно пойти на вот эту страничку, и не мучительно визуализировать the spec в голове, а вставить его в textarea и нажать кнопошку Draw. (Для рисования оно использует canvas, поэтому в IE тестировать бесполезно.)

Отправил ссылку в fvwm mail list, надеясь получить комментарии "ага!", "наконец-то", "эх, уж теперича мы!", и шо вы думаете? За полтора дня ее в совершеннейшем молчании посмотрели ажно 10 человек, а так--нуль внимания, those bastards.

Friday, March 12, 2010

Quotes from 97 Things Every Programmer Should Know

I thought it would be a collection of super-duper, mega wise unpalatable truth, but in reality it was the set of truisms, cliches and platitudes. In brief, I'm disappointed. There of course exists some interesting advices (<20), mostly applicable for very young developers.

Here are examples of the most useful:

Giles Colborne

When you get stuck, you look around. When users get stuck, they narrow their focus. [...] It becomes harder for them to see solutions elsewhere on the screen. It's one reason why help text is a poor solution to poor user interface design. If you must have instructions or help text, make sure to locate it right next to your problem areas. A user's narrow focus of attention is why tool tips are more useful than help menus.

[...] Spending an hour watching users is more informative than spending a day guessing what they want.

Filip van Laenen

  • Make sure code formatting is part of the build process, so that everybody runs it automatically every time they compile the code.
  • Use static code analysis tools to scan the code for unwanted antipatterns. If any are found, break the build.

Rajith Attapattu

Many incremental changes are better than one massive change. [...] It is no fun to see a hundred test failures after you make a change. This can lead to frustration and pressure that can in turn result in bad decisions. A couple of test failures at a time is easier to deal with, leading to a more manageable approach.

Mattias Karlsson

Be gentle during code reviews. Ensure that comments are constructive, not caustic.

[...] Code reviews will flow more easily if the team has coding conventions that are checked by tools. That way, code formatting will never be discussed during the code review meeting.

Jon Jagger

Deliberate practice means repetition. It means performing the task with the aim of increasing your mastery of one or more aspects of the task. It means repeating the repetition.

[...] Ask yourself, how much of your time do you spend developing someone else's product? How much developing yourself?

[...] Deliberate practice is about learning--learning that changes you, learning that changes your behavior.

Mike Lewis

Don't be afraid of your code. Who cares if something gets temporarily broken while you move things around? A paralyzing fear of change is what got your project into this state to begin with. Investing the time to refactor will pay for itself several times over the lifecycle of your project.

Alan Griffiths

[...] the hard part [of the programming]--the thinking--is the least visible and least appreciated by the uninitiated.

Johannes Brodwall

When I start a new project from scratch, there are no [compiler] warnings, no clutter, no problems. But as the codebase grows, if I don't pay attention, the clutter, the cruft, the warnings, and the problems can start piling up. [...] If I leave the warnings, someone else will have to wade through what is relevant and what is not. Or more likely, that person will just ignore all the warnings, including the significant ones.

Warnings from your build are useful. You just need to get rid of the noise to start noticing them.

Dan Bergh Johnsson

Know your next commit. If you cannot finish, throw away your changes, then define a new task you believe in with the insights you have gained. Do speculative experimentation whenever needed, but do not let yourself slip into speculative mode without noticing. Do not commit guesswork into your repository.

Daniel Lindner

You need to give your project a voice. [...] The idea of XFDs [Extreme Feedback Device] is to drive a physical device such as a lamp, a portable fountain, a toy robot, or even a USB rocket launcher, based on the results of the automatic analysis. Whenever your limits are broken, the device alters its state. In case of a lamp, it will light up, bright and obvious. You can't miss the message even if you're hurrying out the door to get home.

Jon Jagger

Lack of visible progress is synonymous with lack of progress. [...] It's best to develop software with plenty of regular visible evidence. Visibility gives confidence that progress is genuine and not an illusion, deliberate and not unintentional, repeatable and not accidental.

Linda Rising

[...] in all the years I've taught and worked side by side with programmers, it seems that most of them thought that since the problems they were struggling with were difficult, the solutions should be just as difficult for everyone.

Giles Colborne

Another way of avoiding formatting errors is to offer cues--for instance, with a label within the field showing the desired format ("DD/MM/YYYY").

[...] Cues are different from instructions: cues tend to be hints; instructions are verbose. Cues occur at the point of interaction; instructions appear before the point of interaction. Cues provide context; instructions dictate use. In general, instructions are ineffective at preventing error.

Uncle Bob

A professional programmer does not pass that responsibility off on others.

[Professionals] take responsibility for their own careers. They take responsibility for making sure their code works properly. They take responsibility for the quality of their workmanship. They do not abandon their principles when deadlines loom. Indeed, when the pressure mounts, professionals hold ever tighter to the disciplines they know are right.

Alex Miller

When I was first placed in a technical leadership role, I felt that my job was to protect my beautiful software from the ridiculous stream of demands coming from product managers and business analysts. I started most conversations seeing a request as something to defeat, not something to grant.

At some point, I had an epiphany that maybe there was a different way to work that merely involved shifting my perspective from starting at no to starting at yes. In fact, I've come to believe that starting from yes is actually an essential part of being a technical leader.

Wednesday, March 10, 2010

gem 1.3.6, Ruby 1.9 and FreeBSD

Кстати о rubygems. Для несчастных владельцев gem'ов, кои требуется тихо класть на rubygems.org, версия gem, которая идет в комплекте с ruby 1.9.1 лишена команды push. А без нее

% gem push pkg/глюкало-0.1.3.gem

не скажешь. Чтобы эта счастье там появилось, требуется обновить rubygems командочкой gem update --system. Это все не является тайной, но выполнивши указанную командочку под FreeBSD и набрав gem list, мы получим:

*** LOCAL GEMS ***

(пустой список)

Караул! Куда делись все мои инсталлированные gems?

В начале этого года в freebsd-ruby мяли неверность gem path выглядевшую как /usr/local/lib/ruby19/gems/1.9. В порту появился патч, исправлявший ее на "правильную" /usr/local/lib/ruby/gems/1.9. После ручного обновления rubygems, gem path снова сбрасывается на кривую /usr/local/lib/ruby19/gems/1.9. Именно ее пытается прочесть новая версия и, конечно, не находит там ни единого установленного gem'а.

То есть, чтобы направить rubygems на истинный путь, вам придется руками подредактировать файл /usr/local/lib/ruby/site_ruby/1.9/rubygems/defaults.rb. Патч:

--- defaults.rb.orig  2010-03-01 14:13:23.000000000 +0200
+++ defaults.rb       2010-03-01 14:13:38.000000000 +0200
@@ -20,10 +20,6 @@
         if defined? RUBY_FRAMEWORK_VERSION then
               File.join File.dirname(ConfigMap[:sitedir]), 'Gems',
                                 ConfigMap[:ruby_version]
-    # 1.9.2dev reverted to 1.8 style path
-    elsif RUBY_VERSION > '1.9' and RUBY_VERSION < '1.9.2' then
-      File.join(ConfigMap[:libdir], ConfigMap[:ruby_install_name], 'gems',
-                ConfigMap[:ruby_version])
         else
               File.join(ConfigMap[:libdir], ruby_engine, 'gems',
                                 ConfigMap[:ruby_version])

Теперь наберите:

% gem env | grep -A2 PATH

и убедитесь что все работает как надо.

podgraph

If you are like me--a person who hates to fire up wysiwyg editors (or even worse--an editor in a browser) to make a blog post, then you may like a tiny Ruby program called podgraph.

It parses an XHTML file and creates a proper MIME mail from it. "Proper" means that if you have included some local images in your html, they will be encoded and bundled with the mail as inline images (see RFC2387).

After creating the mail, podgraph can automatically send it somewhere, probably to your mail-to-blog gateway.

To install podgraph 0.0.1, make sure that you have Ruby 1.9 on your machine and type as root:

# gem install podgraph

For the help, type:

% ri Podgraph

History

As starting a brand new blog at posterous.com, I came up with an old problem: how to post to <my lousy blog> from Emacs? There is no working posterous client for Emacs (at least I don't know any), but thank g-d we can use just html emails for simulating that.

A long time ago before joining to Ruby camp, I fell in love with python's reStructuredText. It gives me an ability not to struggle with damn html tags but to write blog posts in (more or less) human readable text and then convert it to lame html.

So, at the present time any posting to posterous looks like this:

  1. Editing (in Emacs) file.rest.

  2. Typing gmake in the directory with file.rest. Makefile:

    PODGRAPH := ~/lib/software/alex/podgraph/trunk/bin/podgraph
    #PODGRAPH := podgraph
    
    .PHONY : clean html
    
    XHTML := $(addsuffix .html,$(basename $(wildcard *.rest)))
    
    all: html
    
    .SUFFIXES: .rest .html .sent
    
    .rest.html:
       rst2html -o koi8-r < $< > $@
    
    .html.sent:
       $(PODGRAPH) $<
       touch $@
    
    html: $(XHTML)
    
    clean:
       rm -f *.html
    

    Which brings to me file.html.

  3. Previewing in the browser the result: firefox3 file.html.

  4. Typing gmake file.sent--and podgraph suddenly creates the MIME mail and delivers it to posterous.

Btw, the whole process tested only on FreeBSD. I don't see any possible Linux quirks here, but if you'll find some, don't forget to tell me.

Wednesday, February 10, 2010

List installed packages sorted by date/size in FreeBSD

For tcsh:

alias pkg.size 'pkg_info | awk '\''{print $1}'\'' | xargs pkg_info -sQ | sort -n -t: -k2 -r | awk -F: '\''{printf("%12s\t%s\n", $2, $1)}'\'' '
alias pkg.date 'ls -ltT /var/db/pkg/*/+CONTENTS | sed -E "s/.*(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(.+)\/var\/db\/pkg\/(.+)\/\+CONTENTS/\1\2\3/"'

Resize your browser window if you can't see the end of the lines. Pay attention to all quotes in 2 lines above, otherwise aliases may not work.

Then, for example, you can print package list sorted by size:

% pkg.size
   277980976    jdk-doc-1.6.0.10
   158015255    diablo-jdk-1.6.0.07.02
         ...
        2226    bigreqsproto-1.0.2
        1815    font-micro-misc-1.0.0

Or print package list sorted by installed date:

% pkg.date
Feb  9 10:46:06 2010 firefox-3.6,1
Feb  9 08:35:54 2010 inn-2.4.6_1
...
Jan  8 04:48:58 2009 pkg-config-0.23_1
Jan  8 04:48:57 2009 kbproto-1.0.3

Not a big deal but still useful.

Friday, February 5, 2010

The answer to The Quiz from PragPub #8

Зашифрованный код на ст. 37 журнала--кусок программы ELIZA переписанной на Lua.

Расшифровщик на Ruby 1.9 можно взять отсюда.

Картинка процесса:

687 KB