Техническое

Подписаться на эту рубрику по RSS

Описание всяческих софтовых и железячных решений.

Шпаргалка для себя, а может и еще кому понадобится. В силу странного поведения k3b, решил от него отказаться.

1 Создаем образ файловой системы для записи:

$ mkisofs -V label -r -R -l -J -o file1.iso ./files_for_burn

-r, -R - RockRidge (технология позволяет несколько расширить возможности ISO9660 fs)

-J - Joliet позволяет делать длинные имена и имена с пробелами на болванке

-l - имена длиннее 31ого символа

2 Прожигаем образ:

$ sudo cdrecord -v speed=8 dev=/dev/cdrw -multi file1.iso

3 Для следующей сессии узнаем где закончилась предыдущая:

$ cdrecord -msinfo dev=/dev/cdrw

4 Создаем образ следующей сессии в соответствии с завершением предыдущей:

$ mkisofs -V label2 -r -R -l -J -C `cdrecord -msinfo dev=/dev/cdrw` -M /dev/cdrw -o file2.iso -multi ./files_for_burn2

5 Для закрытия болванки от дальнейшей записи, последнюю сессию записываем без -multi:

$ sudo cdrecord -v speed=8 dev=/dev/cdrw file2.iso

Обладателей кард-ридеров или фотиков, определяющихся как mass-storage, вряд ли взволнует нижеследующий материал. А вот владельцы Canon`ов да и просто ленивцы, которым проще вставить USB-хвост в камеру, нежели вытащить SD-шку из нее и возиться с кард-ридером, возможно заинтересуются.

И так, скрипт.

#!/bin/bash
# title: PHotoGET
# desc: Retrieve photos from camera
# uses: ap/gphoto2
# by Alexander (su6s) Polyakhov
# Tue Dec 1 23:15:21 MSK 2009
# apolyakhov@gmail.com
# su6s@jabber.ru
# http://juick.com/su6s
# http://blog.su6s.me
# Зададим формат имени каталога для изображений
DIR_NAME="$(date +%Y%m%d)";
#######################################
# Все, что ниже трогать не обязательно#
#######################################
# Переменная NNNN задает начало диапозона
#+ MMMM задает конец диапозона фоток.
#+ Последовательность из четырех цифр —
#+ уникальная часть имени изображения.
#+ Справедливо для камер Canon, Pentax
NNNN="$(echo $1 | grep -E "^[0-9]{4}$")";
MMMM="$(echo $2 | grep -E "^[0-9]{4}$")";
# Убедимся, что диапозон задан верно
if [ -z "$NNNN" ]; then
echo "Bad parameters";
exit 1;
fi
if [ -z "$MMMM" ]; then
echo "Bad parameters";
exit 1;
fi
# Убедимся, что каталог DIR_NAME еще не создан
if [ -d "$DIR_NAME" ]; then
echo "dir ${DIR_NAME}/ exists";
exit 1;
fi
# Создадим каталог DIR_NAME для изображений
mkdir "$DIR_NAME";
# Скачаем изображения от NNNN до MMMM
cd "$DIR_NAME";
FIRST_NAME="$(gphoto2 -L |grep "$NNNN" |tr -d '\#'|awk '{print $1}')";
LAST_NAME="$(gphoto2 -L |grep "$MMMM" |tr -d '\#'|awk '{print $1}')";
gphoto2 -p ${FIRST_NAME}-${LAST_NAME};
exit 0;

Как работает?

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

После запуска скрипт создает каталог для фоток и копирует их в него.

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

Поиск, как в RL, так и в гугле увенчался успехом. Вариантов приобретения T39 на текущий момент есть три: либо это ref на Ebay по цене менее 1K руб., либо тот же ref на Савеловском за 3K руб., либо в каком-то "эксклюзивном" месте рунета за $238. Refurbished в переводе на русский означает обновленный, восстановленный. Эти трубки собирают в Гонконге. Корпус неоригинальный, внутренности (по легенде, пкм) оригинальные. Про савеловских барыг даже и говорить ничего не хочется, а вот про цену $238 думаю, что это либо тот же ref (но для покупателя барабана Страдивари), либо просто цена по состоянию на 2001 год. По причинам, полагаю, понятным я выбрал для себя первый вариант.

И так, лот обсужден с продавцом, условия оговорены, лот выигран, платеж выполнен, ждем. До моего замкадья посылка добиралась ровно месяц, каким-либо отслеживаением ее движения по территории необъятной я не интересовался, более того, даже не пробовал получить номер идентификатора посылки от продавца. Настал момент получения, я держу в руках коробку. Она из обычного упаковочного картона, никаких намеков на содержимое. And what`s in the box? Сначала посмотрите на саму коробку, обратите внимание на гонконговскую газету — в нее было завернуто все содержимое коробки.

transport box for phone

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

phone bodyphone bodyphone body

Пластик корпуса приятен на ощупь и напоминает "фирменный эриксоновский". Ну что ж, первый небольшой шок от упаковки (все-таки я ожидал увидеть более презентабельный бокс) прошел. Достаю аккумулятор. Он неоригинальный, на нижней части ни слова по-английски. За исключением нескольких маркировок: T28, 3.7V, 650mAH, Li-ion, загадочное GB/T18287-2000, 2009.07, 4.2V, ISO 9001, QC1, все остальное предлагается понимать путем чтения иероглифов.batterybatterybattery

Что сразу огорчило, так то, что аккум оказался толстым. Во время переговоров с продавцом я отдельно отметил, что мне нужен тонкий аккум. Он меньшей емкости, но зато сохраняет плоскость тыльной стороны телефона. И продавец обещал мне именно тонкий вариант. Но увы. Зато я порадовался, что заказал лот без дополнительного аккума. Следующее огорчение затмило первое — аккумулятор не фиксировался в корпусе телефона. Именно в этот момент я мобилизовал все силы и решил, что так или иначе, но заведу весь этот "конструктор". Даже и мысли не было о возврате товара на родину. Во-первых, не те деньги, во-вторых, ехать на савеловский за тем же самым смысла немного, а хочется именно t39. Пока я пытался вставить аккум, отскочила лицевая накладка.

face part of phone bodyface part of phone body

Первая новость хорошая — накладка металлическая, вторая хуже — накладка посажена на обычный силиконовый клей и дополнительно на китайский "суперхреноддерешь". Сразу после этой метаморфозы трубка приобрела такой вид:

phone body without face part

Насколько сильно икал продавец и сборщик моего комплекта затрудняюсь предположить, подозреваю, что они уже привыкли к постоянной икоте. А впереди еще много любопытного. Достаем из коробки зарядник. Сразу замечу, что а) я оговаривал с продавцом соответствие зарядника российским стандартам (как минимум евро-вилка, ~220 50Hz входных) и б) коробка еще не пуста. Слайды:

charger

Евро-вилку пока что не заметно, а с входным напряжением, глядя на маркировки, вроде бы порядок. Посмотрим в коробку и увидим внутри последний оставшийся предмет.

adapter

Да, вот она евро-вилка. Честно говоря, когда я увидел этот переходник, мне стало очень смешно, позднее стало смешно вдвойне — я попробовал им воспользоваться. Этот переходник — воплощение памятника бессмысленности или бесполезности. Габариты переходника просто не позволяют воткнуть его ни в одну из евро-розеток моей квартиры, а также в пару оставшихся розеток советских времен. Еще немного изображений на тему "памятника бесполезности":

adapteradapter

Теперь перед нами почти полная картина: комплектация полная, аккумулятор не фиксируется в корпусе, зарядник+переходник использовать крайне затруднительно. Хотелось бы еще выяснить принципиальную работоспособность аппарата, аккума и зарядника.

Терять нечего — применим хирургию. Являясь обладателем нескольких зарядок для сонериков, я решил распотрошить одну и припаять ей хвост от комплектной зарядки. Для начала я разобрал последнюю, удивился "простоте" устройства (конечно же, от слова "опрощать", ни в коем случае не "упрощать").

chargercharger

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

Беглый осмотр показал, что каких-либо саморезов или защелок фирменная зарядка лишена, а шов по образующей корпуса намекал на то, что последний цельнолитой. Несколько ударов молотком по стамеске, установленной аккурат на шов, помогли установить истину. Корпус состоит из двух частей, применена пайка пластиком. В общем "из того же материала". Если пройтись несколько раз обычным ножом для резки бумаги по краям шва, то разъединить соединение будет значительно проще.

charger

Взгляните на внутренности фирменной зарядки

chargercharger

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

chargercharger

Паяльник разогрет, перепаиваю хвост.

charger

Собираю все в корпус, вставляю штекер в гнездо телефона, прижимаю пальцем аккумдля обеспечения контакта, втыкаю зарядник в розетку. Клюет!

charging testcharging test

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

Для успешной фиксации аккума нужно утопить его еще на миллиметр или полтора вглубь корпуса. Исхожу из размера текущего зазора.

play between battery and phone body

Однако сделать это не удается, жать сильнее уже не кажется перспективным. Немного снял пластика по краям корпуса аккумулятора все тем же ножом для бумаги — хотелось убедиться, что дело в избыточной толщине. Тогда я извлек аккумулятор из телефона и нажал на него где-то посередине — прогибается, значит есть свободное место. Разбираю аккум. Соединение двух частей его корпуса "проектировалось" как неразъемное, попросту половинки склеены. Внутри видим рабочий блок и управляющую микросхему

disassembled batterydisassembled battery

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

no play between battery and phone body

Теперь я включил телефон, начал "исследовать" (знакомое до мелочей) меню, играть в Erix и Tennis, и был "абсолютно счастлив" (с)Д.Гайдук. Вот с чем не обманул продавец, так это с поддержкой английского и русского языков как в интерфейсе, так и в режиме набора текста. Причем, баг в поиске по телефонной книге, наблюдаемый во всех мной виденных сонериках, здесь не обнаружился. То есть я могу пользоваться английским интерфейсом и при этом нормально пользоваться поиском контактов, записанных по-русски.

Оставалась единственная мелочь. Вернуть на место алюминиевую накладку. Для начала я убрал с нее клей, а также зачистил корпус телефона от клея. Замешивать ипоксидку в половине пятого утра было очень лень да и не оказалось у меня нужных ингридиентов, также не оказалось ни момента, ни китайского суперклея. Я решился на костыльное временное решение. Двухсторонний скоч.

twin-sided scotch

Нарезал тонкие полоски и расположил их на корпусе телефона.

twin-sided scotch

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

assembled phone bodyassembled phone body

В заключение скажу, что телефоном доволен, а покупкой нет. Хотя, не скрою, получил отдельное удовльствие от "рукоприкладства", но изначально на него не расчитывал. Поэтому отзыв продавцу на ebaye склонен поставить отрицательный. Просто как представлю, что такой комплект приехал бы человеку, не готовому поковыряться, взять в руки паяльник. К тому же пришлось привлечь дополнительную зарядку.

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

assembled phone body

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

Нужно:

  • Независимость от настроек почтового клиента
  • Централизация места описания правил
  • Возможность оперировать временем поступления письма
  • Поддержка флагов к письму
  • Поддержка регулярных выражений при обработке полей письма
Проще говоря, захотелось реализовать конвейер, в котором одна утилита фильтрует почту, другая просматривает уже отфильтрованное. В этом случае неважно, читаю ли я почту из WEB-, GUI- или CLI-интерфейса.

Задачу фильтрации, с выполнением всех пунктов списка выше, решает утилита imapfilter.

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

Так вот, чтобы отфильтровать почту, нам потребуется настроить imapfilter. Конфигурационный файл этой утилиты представляет собой программу на языке lua.

Lua — язык несложный, пришлось, конечно, полистать документацию, отработать примеры, поэкспериментировать.

Imapfilter же обеспечивает интерфейс доступа к вашему imap-ящику, лишая нас необходимости вникать в тонкости работы протокола IMAP, предоставляя набор методов для манипуляции почтой. Например, метод list_all() позволяет посмотреть список папок и боксов вашего аккаунта, а move_messages() используется для перемещения писем, is_seen() поможет проверить было ли прочитано письмо, is_older() дает возможность управлять письмами определенного возраста.

А как же практика? Начнем!

Открываем в редакторе файл ~/.imapfilter/config.lua, если нет такого файла, то создаем. По тексту придерживаемся правила, что все зеленое идет в конфиг, синее - заметки по lua.


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

options.timeout = 120

options.namespace = false

Добавим логины

gmail = {username1, username2}
yandex = {username3, username4}

То есть мы определили две таблицы, — gmail и yandex с соответствующими элементами.

На основе таблиц с логинами заполним информацию об аккаунтах

gmail.username1 = IMAP {
    server = 'imap.gmail.com',
    username = 'username1@gmail.com',
    password = 'pass1',
    ssl = 'ssl3'
}

gmail.username2 = IMAP {
    server = 'imap.gmail.com',
    username = 'username2@gmail.com',
    password = 'pass2',
    ssl = 'ssl3'
}

yandex.username3 = IMAP {
    server = 'imap.yandex.ru',
    username = 'username3',
    password = 'pass3',
    ssl = 'ssl3'
}

yandex.username4 = IMAP {
    server = 'imap.yandex.ru',
    username = 'username4',
    password = 'pass4',
    ssl = 'ssl3'
}

Добавим подписки на мейл-листы

Lists = {
        '@bazar2.conectiva.com.br',
        '@lists.hellug.gr'
}

Добавим мейлбоксы, в которые будут раскладываться письма из мейл-листов

(Порядок мейлбоксов должен соответствовать порядку мейл-листов)

Mailboxes = {
        'lua',
        'imapfilter'
}

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

gmail.username1.INBOX:check_status()
gmail.username2.INBOX:check_status()
yandex.username3.INBOX:check_status()
yandex.username4.INBOX:check_status()

Сохраним в переменную result письма, в теме которых находится выражение, и письма уже просмотрены

result = yandex.username4.INBOX:contain_subject('выражение') *
        yandex.username4.INBOX:is_seen()

Основной момент здесь — звездочка (*), которая играет роль логического "И"

Перемещаем письма, удовлетворяющие условию result, в мейлбокс MAILBOX

Тут стоит обратить внимание, что запись yandex.username4.MAILBOX эквивалентна
yandex.username4['MAILBOX']

yandex.username4.INBOX:move_messages(yandex.username4['MAILBOX'],result)

Работаем с мейл-листами. Рассылки будем обрабатывать пачкой. Для начала выясним количество элементов в таблице Lists

Lcount = # Lists

Теперь перебираем в цикле наши подписки, выделяем просмотренные письма

for i=1,Lcount do
result = (
                gmail.username1.INBOX:contain_from("'"..Lists[i].."'") +
                gmail.username1.INBOX:contain_to("'"..Lists[i].."'")
        ) *
       
        gmail.username1.INBOX:is_seen()

Как видно выше, правила можно группировать скобками, знак плюс (+) играет роль логического "ИЛИ". Конструкция что-то_..еще_..что-то - конкатенация, результат — что-то_еще_что-то


Раскладываем по мейлбоксам (таблица Mailboxes). Мейлбокс будет создан, если не существует
gmail.username1.INBOX:move_messages(gmail.username1["lists/"..Mailboxes[i]], result)
end

Запустить фильтр легко — достаточно выполнить команду imapfilter.

Не забудем установить права 700 на каталог ~/.imapfilter и 600 на файлы в нем.

При первом старте imapfilter скорее всего предложит сохранить сертификаты для доступа к серверу через протокол ssl, я согласился и сохранил.

В заключение замечу, что imapfilter умеет работать в режиме демона и поддерживает пайпы.

Берегите свое время.