Как заменить табы, используя sed

Утилита командной строки sed (это потоковый редактор), как-то неочевидно работает с символом табуляции (tab). Выражения «\t», «\x09», «\011» не срабатывают даже в расширенном режиме регулярных выражений (включается флагами „-r“ или „-E“, в зависимости от системы).

Я немного поэксперементировал, оказалось, что sed вполне воспринимает этот символ как таковой, а все «магические выражения» не работают. Поскольку «таб» имеет специальное значение в командной строке, ввести его можно либо через комбинацию Ctrl+V, tab, либо Ctrl+V, Ctrl+I. Во многих шеллах (например, в bash, ksh, sh) сработает специальный синтаксис с долларом, как в примере ниже.

Например, если вам надо заменить последовательные «табы» на один, то это может выглядеть вот так:

sed $'s/\t\t*/\t/g' sample.txt # именно \t\t*, а не \t+

# или

sed -E $'s/\t+/\t/g' sample.txt # в Линуксе ключ „-r“

Если вы знаете как в sed можно работать с tab проще, расскажите, пожалуйста, в комментариях.

7 комментариев

Как отключить автообновление «Скайпа» пятой версии

Так как многие не могут найти как выключить в «Винде» автообновления Skype 5, вот рецепт ниже.

Надо поместить в реестр следующую информацию (сохранить в файл disableskypeupdate.reg и запустить его):

REGEDIT4 
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Skype\Phone] 
"DisableVersionCheck"=dword:00000001

Либо выполнить из командной строки вот это:

reg add HKLM\SOFTWARE\Policies\Skype\Phone /d DisableVersionCheck /t REG_DWORD /v 1

Должно помочь. В четвёртой версии «Скайпа» есть галочка в настройках для запрета автообновлений. На «Маках» она есть и в пятой версии.

5 комментариев

Канадское слоговое письмо (ᓀᐦᐃᔭᐍᐏᐣ)

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

Оно есть в Юникоде, но не знаю как оно отобразится в вашей операционной системе.

Разработано совсем недавно (1840 год) и устроено очень остроумно. Запись, в основном, идёт слогами, согласная-гласная.

Согласная буква определяется формой, а гласная — поворотом. Например, «ᑭ» — «ки», «ᑫ» — «ке», «ᒥ» — «ми», «ᒣ» — «ме» и так далее. Из знаков пунктуации присутствует только точка («᙮»). Письменность довольно широко используется и в наши дни.

Многих привычных нам букв там нехватает, так что записать мои имя и фамилию очень тяжело, разве что подобрать какие-то эквиваленты: «ᐁᐯᑫᓂ ᓭᑌᐸᓂᓭᑊ» («Епекени Сетепанисев»).

11 комментариев

К выходу новой версии «Скайпа»

Скажите, а все те люди, которые установив новую версию, пишут в твиттер «вышел новый скайп, верните старый интерфейс» не догадываются, что можно скачать и поставить предыдущую или что?

35 комментариев

Почему не следует расширять встроенные типы JavaScript

На Хабре хорошая статья — «Monkey-Patching, или Расширение Встроенных Типов: религия или осознанный выбор?».

Оставить комментарий

Зачем я учу языки программирования

Наверное многие заметили что время от времени я глубоко погружаюсь в какой-то язык программирования и ещё поверхностно смотрю на несколько других. Мне не раз задавали вопрос зачем я это делаю, отвечаю.

Во-первых, это отличная зарядка для ума. Тренируется память: ведь надо помнить новые конструкции, названия модулей, структуру и прочее. Тренируется способность адаптироваться: новый язык — новые сложности, новая, непривычная парадигма. Накапливается опыт: можно познакомиться с новыми вариантами решения старых проблем. И прочее, аспектов много, смысл один — тренировка.

Во-вторых, яркие, интересные языки программирования строятся вокруг какой-то парадигмы. Для проверки какой-то гипотезы или реализации интересной идеи. Эта идея в языке как бы «подсвечена», ярко сияет, хотя и не всегда объяснима. Иногда идея скучая и неинтересная (или сильно похожа на что-то знакомое), иногда непривычная и головоломная (например, Рефал мне сначала сломал мозг). В последнем случае язык я учу или смотрю, это зависит от богатства идеи. Эти новые идеи позволяют взглянуть на проблему с разных сторон, если посмотреть на одно и тоже невооружённым взглядом и через микроскоп, увидишь очень разную картину, но важны обе.

Недавно я написал, что поставил себе Кобол на Мак, у многих возник вполне закономерный вопрос — зачем?

Тут дело несколько в ином. Я хочу увидеть как всё начиналось, Кобол — один из первых языков с читаемым англоязычным синтаксисом, с революционными идеями, которые теперь кажутся очень странными. Есть и ещё причина. На Коболе до сих написано больше всего кода (по крайней мере в банковской сфере и правительственной), специалисты по Коболу стоят очень дорого (просто потому что их очень мало), и мне показалось забавным увеличить свою стоимость как программиста изучением Кобола. Это не значит, что я хотел бы программировать на этом языке профессионально. Упаси боже.

10 комментариев

Советские надписи на произодственной базе «Мелиты»

Сохранившиеся с советских времён таблички, надписи чем-то меня притягивают. Я их стараюсь фотографировать, если вижу. Буду выкладывать эти фотографии в блог.

Вот эти две — с заброшенной производственной базы фабрики «Мелита» (выпускает меховые изделия, существует с 60-х годов 19-го века), где мы в воскресенье в пейнтбол играли.

Пропуска предъявляйте в развёрнутом виде (52.50КиБ)
Вход на территорию фабрик строго запрещается с сумками узлами и чемодана (56.11КиБ)

6 комментариев

Заказали чай из Англии

Картонная коробка с наклейкой «SMALL PACKET» и таможенной декларацией, лежащая на деревянном полу.
Открытая картонная коробка на деревянном полу, внутри — каталог «The Kent & Sussex Tea & Coffee Company» за 2017 год, оранжевая упаковка и другие товары.
На деревянном столе разложены пакетики чая и кофе от компании "Bent & Sussman", включая сорта "Lapsang Souchong" и "Cinnamon", а также оранжевый пакет и брошюра.

Решили с женой попробовать заказать чай из Англии. Заказали месяц назад восемь сортов чая и один кофе в интернет-магазине компании «The Kent & Sussex Tea & Coffee Company». Вчера забрали посылку с почты и заварили первый чайник. Чай настолько ароматный, что чувствовался через коробку и упаковку, когда я его нёс с почты. Мне пока большего из заказанного понравился «Cinnamon», чай с пряностями.

Очень рекомендую, если кто-то из читателей любит хороший чай (и расскажите что вы заказываете, например, если вы нашли магазин с хорошим китайским чаем). Цены есть на сайте, чтобы можно было грубо прикинуть, у нас получился вес 1,25 кг за £40,84 (почти 2000 рублей).

39 комментариев

Удаление умершей ноды в кластере «Оракла»

Небольшой видеоурок по удалению умершей ноды из кластера «Оракла». В одном месте там требуется, чтобы на машине был своп не менее 500МБ, у нас не было (на машине 96ГБ памяти, зачем ей своп), мы его просто создали на диске в файле.

2 комментария

Как поставить Кобол на Мак

Пусть здесь полежит, чтобы я потом не искал.

Как поставить Кобол на Мак (при помощи «брю»):

curl http://www.sim-basis.de/open-cobol-1.1.tar.gz
tar xvfz open-cobol-1.1.tar.gz
cd open-cobol-1.1
brew install gmp
brew install berkeley-db

./configure --prefix=/usr/local/Cellar/open-cobol/1.1
make && make install
brew link open-cobol

9 комментариев

Всякая мелочь одним постом-4

Сегодня суббота, значит время для всякой мелочи одним постом.

Всем разработчикам знакома ситуация «ладно, потом переделаем». Такая и подобные ей ситуации называются «техническим долгом». Не забывайте отдавать технические долги, аукнется, мало не покажется!

Быстро научиться разговаривать с татарским акцентом поможет смешная статья «Изучаем татарский вместе», которую я вынес из «Вконтакте».

В Живом Журнале krascat можно увидеть цветные фотографии Англии 1928 года Клиффорда Адамса. Фотографии сделаны по  методу автохрома.

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

Новость на английском, но важная для всех, у кого есть смартфоны: компания Adobe прекращает разработку «Флеша» под мобильные платформы.

Про месть через 17 лет пишет mercylo в своём ЖЖ. Неприятная история — сына отомстившей, а скорее мелко подгадившей женщины когда-то mercylo не приняла в университет.

4 комментария

Будущее формата CSS image

Лого в CSS (38.79КиБ)

Мои эксперименты с картинками на чистом CSS внезапно дали следующий результат. Я взял для экспериментов логотип студии Лебедева в первом попавшемся цвете и перегнал его в CSS image при помощи своего конвертора, используя все префиксы браузеров: «webkit», «moz», «o» и «ms» («Конкерор» включать не стал, доля этого браузера исчезающе мала).

Оказалось, что если сжать получившийся файл (браузеры же понимают сжатый CSS), то получившийся файл будет размером меньше, чем та же картинка в формате PNG: 2,5КБ против 6,7. Файл с лого Студии я пропускал через онлайновый оптимизатор PNG (punypng), так что он вряд ли неоптимален.

Чем объяснить такой разврыв между форматом, предназначенном для эффективного сжатия графики, и неэффективным текстовым, с огромной избыточностью, сжатым обычным гзипом я не знаю.

Добавлено позднее: в комментариях картинку «утоптали» в 448 байт. Непонятно почему у меня такой плохой PNG получился.

23 комментария

Картинка на чистом CSS-2

Ещё картинка на чистом CSS (82.31КиБ)

Я тут всё это время думал как дёшево улучшить свой конвертор картинок в чистый CSS и придумал.

Выкинул «radial-gradient» и стал использовать «linear-gradient». Картинка, которая в прошлой версии занимала 164КБ, сейчас занимает 89 79. Это уже неплохо, в сжатом (gzip) виде этот код занимает 19КБ, что всего в два с половиной раза больше, чем исходное изображение в PNG. Результат можно сильно улучшить, если отказаться от повтора цвета, но изображения с мелкими деталями (с текстом, например) пострадают.

Кстати говоря, логотип студии Лебедева при конвертации из PNG (6,7КБ) уменьшился до 1,6КБ 1,3КБ. Это уже реальная экономия, если бы не префиксы браузеров.

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

Кстати этот раз «Опера», увы, не смогла показать картинку, так как, похоже, не поддерживает позиционирование для линейных градиентов.

Добавлено позднее: сделал оптимизацию, теперь конвертор делает два прогона: один просматривает пиксели по горизонтали, второй по вертикали. Выбирается тот, который даёт наименьший результат.

Ключи запуска те же.

<?
// ffccbb → fcb
// ff0000 → red
// abcdef → abcdef
function Bo_shortcolor($color) {
    static $shortnames = array(
        "c0c0c0" => "silver",
        "808080" => "gray",
        "800000" => "maroon",
        "ff0000" => "red",
        "800080" => "purple",
        "008000" => "green",
        "808000" => "olive",
        "000080" => "navy",
        "008080" => "teal",
        "f0ffff" => "azure",
        "f5f5dc" => "beige",
        "ffe4c4" => "bisque",
        "a52a2a" => "brown",
        "ff7f50" => "coral",
        "ffd700" => "gold",
        "808080" => "gray",
        "008000" => "green",
        "808080" => "grey",
        "4b0082" => "indigo",
        "fffff0" => "ivory",
        "f0e68c" => "khaki",
        "faf0e6" => "linen",
        "800000" => "maroon",
        "000080" => "navy",
        "808000" => "olive",
        "ffa500" => "orange",
        "da70d6" => "orchid",
        "cd853f" => "peru",
        "ffc0cb" => "pink",
        "dda0dd" => "plum",
        "800080" => "purple",
        "ff0000" => "red",
        "fa8072" => "salmon",
        "a0522d" => "sienna",
        "c0c0c0" => "silver",
        "fffafa" => "snow",
        "d2b48c" => "tan",
        "008080" => "teal",
        "ff6347" => "tomato",
        "ee82ee" => "violet",
        "f5deb3" => "wheat",
    );

    $c = strtolower($color);
    if (isset($shortnames[$c])) {
        return $shortnames[$c];
    }

    if ($c[0] == $c[1] && $c[2] == $c[3] && $c[4] == $c[5]) {
        return '#' . $c[1] . $c[3] . $c[5];
    }

    return '#' . $c;
}

class Bo {
    public function __get($num) {
        return $num ? $num . 'px' : 0;
    }
}

function Bo_convert_helper($im, $lim1, $lim2, $getpix, $dotmask, $z) {
    $end  = $lim1 - 1;
    $dots = array();

    for ($o1 = 0; $o1<$lim2; $o1++) {
        $coll = array();
        $prev    = null;
        $start   = 0;

        for ($o2 = 0; $o2<$lim1; $o2++) {
            $pixel = $getpix($im, $o2, $o1);

            if ($prev !== null && $prev !== $pixel || $o2 == $end) {
                if ($prev !== null) {
                    $color = Bo_shortcolor(vsprintf('%02x%02x%02x', $prev));

                    $coll[] = "$color {$z->$start},$color {$z->$o2}";
                }

                if ($o2 == $end && $prev != $pixel) {
                    $color = Bo_shortcolor(vsprintf('%02x%02x%02x', $pixel));
                    $cell[] = "$color {$z->$o2}";
                }

                $start = $o2;
            }

            $prev = $pixel;
        }

        $dots[] = sprintf($dotmask, implode(',', $coll), $z->$o1);
    }

    return $dots;
}


function Bo_convert($filename, $prefix = '') {
    $z = new Bo();

    if (!file_exists($filename) && !is_readable($filename)) {
        throw new Exception('File not found.');
    }

    $types = array(
        IMAGETYPE_JPG => 'jpeg',
        IMAGETYPE_PNG => 'png',
        IMAGETYPE_GIF => 'gif',
    );

    $imagedata = @getimagesize($filename);
    if (!is_array($imagedata) || !isset($imagedata[2]) || !isset($types[$imagedata[2]])) {
        throw new Exception('Unknown image format');
    }

    $im = call_user_func("imagecreatefrom" . $types[$imagedata[2]], $filename);
    $sw = $w = imagesx($im);
    $sh = $h = imagesy($im);

    $hfunc = create_function('$im, $x, $y', 'return imagecolorsforindex($im, imagecolorat($im, $x, $y));');
    $hmask = "{$prefix}linear-gradient(0,%s) 0 %s";

    $hdots = join(',', Bo_convert_helper($im, $w, $h, $hfunc, $hmask, $z));

    $vfunc = create_function('$im, $y, $x', 'return imagecolorsforindex($im, imagecolorat($im, $x, $y));');
    $vmask = "{$prefix}linear-gradient(90,%s) %s 0";

    $vdots = join(',', Bo_convert_helper($im, $h, $w, $vfunc, $vmask, $z));

    if (strlen($hdots) > strlen($vdots)) {
        $dots = $vdots;
        $sw = 1;
    } else {
        $dots = $hdots;
        $sh = 1;
    }

    return <<<HTML
<head>
<title>$filename converted in background by Evgeny Stepanischev //bolknote.ru</title>
<style text="text/css">
    div {
        background: $dots;
        background-repeat: no-repeat;
        {$prefix}background-size: {$sw}px {$sh}px;
        background-size: {$sw}px {$sh}px;
        width: {$w}px; height: {$h}px;
    }
</style>
<body>
<div></div>
</body>
HTML;
}

if ($_SERVER['argc'] < 2) {
    echo <<<HELP
Image to background CSS convertor v2 by Evgeny Stepanischev. //bolknote.ru Nov 2011

Usage: {$_SERVER['argv'][0]} filename [prefix]

filename  - image file name (PNG, JPEG or GIF)
prefix    - your browser name (Opera, IE, FF, Safari, Chrome)

HELP;
exit;
}

$browsers = array(
    'ie'     => '-ms-',
    'opera'  => '-o-',
    'safari' => '-webkit-',
    'chrome' => '-webkit-',
    'chromium' => '-webkit-',
    'ff' => '-moz-',
    'firefox' => '-moz-',
);

if (isset($_SERVER['argv'][2])) {
    $type = strtolower($_SERVER['argv'][2]);
    $prefix = isset($browsers[$type]) ? $browsers[$type] : '-' . $type . '-';
} else {
    $prefix = '';
}

try {
    echo Bo_convert($_SERVER['argv'][1], $prefix);
} catch (Exception $e) {
    echo "Error: ", $e->getMessage(), "\n";
    exit(1);
};

Оставить комментарий

Активность аудитории

Немного статистики.

В среднем на сайта в месяц бывает примерно 90 тысяч человек. Каждый месяц это число может быть меньше или больше. Например, в июне было 108 тысяч, а в августе — 77. Я недавно перелил большинство юзерпиков пользователей на «Яндекс.Фотки» и, делая скидку на людей с одинаковыми юзерпиками и именами (у меня для двух одинаковых имён сгенерируется один юзерпик), активная аудитория сайта порядка 1700 человек.

То есть более чем за 10 лет существования сайта (правда комментарии на сайте появились сильно позже) его посетила толпень народу, но комментрировали всего несколько тысяч. Похожая ситуация, судя по всему, у Экслера на его персональном блоге, в день его сайт посещает столько же народу, как меня за месяц, а комментариев в блоге — только несколько десятков к каждой записи.

Мне бы хотелось, чтобы читатели более активно высказывались, мне сейчас интереснее обсуждать мои мысли с читателями.

Причин низкой активности я вижу две: всё-таки мне не удалось научить читателей подписываться на комментарии через RSS (и надо думать о том, чтобы как-то корректно высылать их на почту), вторая — отсутствие древовидных комментариев (но их-то я вводить не хочу, они провоцируют уход от темы и читать их все у меня не получится и не интересно, тогда вопрос — зачем стимулировать дискуссии, в которых мне не хочется участвовать).

Надо думать в сторону почты. Проблема с почтой, что её надо как-то подтверждать. Устроить какому-нибудь ящику «сладкую жизнь» очень просто (у меня даже была программа «Shit Streamer» на Перле и ПХП для этого) — достаточно подписать ящик на комментарии на куче ресурсов, ведь сейчас мало кто озабочен подтверждением подлинности ящика.

Увы и подтверждение подлинности через письмо не очень-то хорошая идея — кого угодно можно засыпать по брови письмами с подтверждениями.

Идея, которую я сейчас обдумываю такова: пользователю для первого подтверждения адреса почты (что будет доступно только для пользователей, которые авторизовались через OpenID), предлагается нажать на ссылку, сформированную специально для него.

Что-то типа: mailto:bolknote-confirmation+dy43udsj36HdshddkjdDds@gmail.com?subject=http://someopenid.example.org

Пользователь жмёт на ссылку, отсылает пустое письмо на этот адрес, с этого момента считается, что он подтвердил свой адрес. «Гмэйл» устроен таким образом, что на часть после плюса он внимания не обращает и эти письма будут попадать на ящик «bolknote-confirmation». Мой скрипт время от времени будет заходить туда, прямо по протоколу POP3, это текстовый простой протокол, мне надо только научиться работать с ним через TSL, получать список писем, их заголовки, подверждать адреса и удалять обработанное.

Не слишком неудобно получается?

64 комментария

Запись в NTFS средствами Mac OS X

Как оказалось, использование этого небезопасно, используйте только если нет другого выхода.

Как известно пользователям «маков», Mac OS X умеет монтировать диски с файловой системой NTFS только на чтение. Обычно, чтобы писать скачивают сторонний драйвер NTFS — либо бесплатный NTFS-3G, либо какие-то платные драйвера (Tuxera или Парагон).

Ночью я случайно наткнулся на рецепт, позволяющий задействовать для записи на NTFS внутренний драйвер Mac OS X (рецепты немного различаются для «Снежного барса» и «Льва».

В сегодняшей утренней пробке я сделал программу, которая этот рецепт автоматизирует, листинг ниже, скачать можно с «Гитхаба» (запускать — через bash).

Плюсы следующие.

Во-первых, это высокая скорость записи (30МБ/сек). Во-вторых, с этим решением файл удаляется в корзину. В-третьих, никаких сторонних драйверов. Но надо быть аккурантым — диск обязательно нужно отмонтировать от «Винды» до отключения, иначе Mac OS смонтирует его в режиме только для чтения.

Добавлено позднее: Сергей Васильев предостерегает от использования родного драйвера для работы с NTFS: говорит, что можно разрушить файловую систему.

Листинг программы.

#!/bin/bash

ARCH=`uname -r | cut -d. -f1`
NMOUNT=/sbin/mount_ntfs
NLIBRA=/System/Library/Extensions/ntfs.kext/Contents/MacOS/ntfs

function usage {
    cat <<USAGE
NTFS writing enabler (//bolknote.ru Nov 2011)

usage: $0 <action>
  <action> - "enable" for enable NTFS write, "disable" otherwise.
USAGE
    exit
}

function ntfsdisable {
    if [ -e "${NMOUNT}_orig" ] && [[ -e "${NLIBRA}_orig" || $ARCH -eq 10 ]]; then
        sudo /bin/mv "${NMOUNT}_orig" "$NMOUNT"
        [ $ARCH -eq 11 ] && sudo mv "${NLIBRA}_orig" "$NLIBRA"

        echo Disabled
    else
        echo "Error: cannot disable NTFS. Already disabled?"
    fi
}

function ntfsenable {
    ntfsenable$ARCH
    echo Enabled
}

function ntfsenable10 {
    echo -n 'Please enter your administrator password. '

    sudo /bin/mv "$NMOUNT" "${NMOUNT}_orig"
    /bin/cat << MNT | sudo /usr/bin/tee "$NMOUNT" >/dev/null
#!/bin/sh
/sbin/mount_ntfs_orig -o rw "\$@"
MNT
    sudo /usr/sbin/chown root:wheel "$NMOUNT"
    sudo /bin/chmod 755 "$NMOUNT"
}

function ntfsenable11 {
    TEMP=`mktemp -d /tmp/ntfs$$.XXXXXX` || (
        echo 'Cannot create temporary directory.'
        exit
    )

    trap "/bin/rm -rf $TEMP" EXIT

    echo -n 'Please wait. Downloading...'

    curl -o "$TEMP/arch.zip" 'http://dl.dropbox.com/u/9349175/datahost-macdaily/NTFS_Enabler.zip' 2>&- 1>&- ||
    curl -o "$TEMP/arch.zip" 'http://ntfs_enabler.chat.ru/NTFS_Enabler.zip' 2>&- 1>&- || (
        echo 'Cannot download NTFS enabler bundle.'
        exit
    )

    echo ' done'

    unzip "$TEMP/arch.zip" -d "$TEMP" 2>&- 1>&-
    [ `md5 "$TEMP/NTFS_Enabler/ntfs"` == a88031b3257379257086af017891f229 ] || (
        echo "Error: invalid checksum NTFS enabler bundle"
        exit
    )
    ntfsenable10

    sudo /bin/mv "$NLIBRA" "${NLIBRA}_orig"
    sudo /bin/mv "$TEMP/NTFS_Enabler/ntfs" "$NLIBRA"
    sudo /usr/sbin/chown root:wheel "$NLIBRA"
    sudo /bin/chmod 755 "$NLIBRA"
}

if [[ $ARCH -lt 10 || $ARCH -gt 11 ]]; then
    echo 'Unknown Mac OS version (Snow Leopard or Lion required).'
    exit
fi

[ "$1" == "" ] && usage

case "$1" in
    enable)
        ntfsenable
        ;;
    disable)
        ntfsdisable
        ;;
esac

15 комментариев

Хочу поменять библиотеку для OpenID на сайте

Хочется поменять библиотеку, которую я использую для OpenID на сайте. Я сейчас использую Janrain OpenID, но она давно не обновлялась, генерирует варнинг и только с костылями и патчами работает с реализацией OpenID в ЖЖ (баг-репорт я писал в обе компании, бестолку).

Посоветуйте какие-нибуль альтернативы (на PHP). Я рассматриваю сейчас LightOpenID.

Требования — библиотека должна поддерживать OpenID 1.x и 2.x, SREG, предоставлять возможность хранить данные где я укажу (мне нужно на диске, а не в БД) и не должна использовать экзотические модули.

6 комментариев

Первый снег в Казани

Первый снег выпал, то есть тот, который ляжет хорошим слоем и уже вряд ли растает до весны. Хорошее время, ещё не слишком холодно (−4˚C сейчас на улице), не гоняет никто (зимние шины есть не у всех, да и непривычно ещё), от этого тихо вокруг и очень комфортно на дороге.

6 комментариев

Юзерпики на «Яндекс.Фотках»

Вчера в Татарстане был выходной, поэтому пока мы ехали на машине за город, я сделал заготовку для хранения юзерпиков на «Яндекс.Фотках», а вечером её доделал. Сейчас все юзерпики в фоне переливаются туда в порядке запроса пользователем в закрытый альбом специального пользователя, которого я завёл.

До этого юзерпики по сложным правилам (с использование адреса почты из SRE OpenID или vCard, favatar, gravatar, pavatar, юзерпиков из «Ярушки» и ЖЖ и т. д.) получались для каждого человека в комментариях и загружались каждый раз с совершенно разношёрстных ресурсов.

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

Есть и четвёртая причина, не знаю насколько она значимая. Некоторые юзерпики (побайтно) повторяются, но так как браузер не знает, что с двух разных УРЛов грузится та же картинка, он грузит её два раза. У меня сейчас не так — я хеширую картинку и по хешу ищу совпадение. Есть вероятность совпадения хеша, но юзерпики не слишком-то важные данные, чтобы бояться коллизий.

Сейчас юзерпики грузятся только в фоне, то есть какое-то время он грузится с «настоящего» адреса и только через какое-то время — с «Яндекс.Фоток». Так как запросов в стеке пока очень много (сейчас загружено 779 картинок и их число растёт очень быстро), процесс перекладывания может растянуться на часы. В будущем, когда бо́льшая часть будет уже лежать на «Фотках», этот процесс сократится до минут.

17 комментариев