Как стать автором
Поиск
Написать публикацию
Обновить

Борьба с IE6 — ценовая политика

Уважаемые хабровчане! Это мой первый пост на Хабре, потому не судите строго. Хотел бы предложить для кого-то возможно новый способ решения старой проблемы, опробованный в моем маленьком бизнесе. Речь пойдет о борьбе с уже порядком всем надоевшем IE6.

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

IE6 стал для многих веб-разработчиков головной болью по множеству причин. Но давайте немного отвлечемся от технических деталей и переключимся на язык денег. Вёрстка как техпроцесс требует затрат времени соответствующего специалиста. Ценообразование соответственно напрямую связано с ценой единицы времени работы этого специалиста помноженной на время работы. В моем случае расчет производится таким образом: норма времени на работу верстальщика (речь о множестве проектов, определены нормы расхода времени на верстку в зависимости от технических условий) множится на стоимость часа его работы, затем полученная сумма (по сути — себестоимость) умножается на (100+X) % (где X — желаемая маржа), сверху это обременяется налогами (тут у каждого свое — варианты УСН, НДС, НДФЛ, налогов.нет и т. п.) и получается строка для сметы затрат по вёрстке.

Как-то раз я взялся понаблюдать за особенностями расхода времени на вёрстку. И у меня получилась интересная картинка: если взять время, необходимое для получения законченного варианта валидной вёрстки за N, то для того, чтобы адаптировать результат таким образом, чтобы он был по зубам еще и IE6 требовалось от 1,5N до 2,8N. В среднем получилось 2,38N (тут речь не о среднем арифметическом, а с учетом количественного распределения).

Вспомнив о том, что 20 % усилий приносят 80 % результата, я задумался — а имеет ли процесс адаптации вёрстки для IE6 экономическую целесообразность и как вообще ее обрести, если тут не все так прозрачно? На дворе уже почти 2010 год, и, как показывают статистические данные — доля использования злополучного браузера сейчас составляет от 15 до 25 %. Возник вопрос: кто из нас больше обманут — я, потому что делаю не особенно востребованную работу за те же деньги или клиент, потому что платит за то, что ему с высокой вероятностью не требуется? Я принял решение предлагать такие варианты клиенту: платить только за валидную вёрстку или за вёрстку, которая еще и адаптирована для IE6. И это дает очень забавные результаты — в 80 % случаев люди готовы платить только за валидную верстку.

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

Надеюсь кто-то сочтёт мой метод жизнеспособным и примет на вооружение.

P. S.: Я использую коэффициент наценки на вёрстку для IE6 2,5. Это с одной стороны облегчило ценник для вёрстки без поддержки IE6 и утяжелило с ней.

Кому на Руси жить хорошо? (Или давайте уже сделаем что-нибудь...)

Здравствуй, Песочница.
Ты не та, которой я хотел посвятить этот пост, но более некому, ибо инвайта на до-дыр-читаемом-мною Хабре у меня нет.

Всем остальным — тоже привет.
Этот пост и не пост вовсе, а, скорее попытка ответить на пост о наших проблемах и иже с ним.

Посему прошу его воспринимать далее в соответствующем ключе, не судить строго [и, в конце концов, дать инвайт ;) ].
Очень рекомендую ознакомиться с оригинальным постом, прежде чем читать мои «сопли».

Так вот. Господа, мои хорошие. (Здесь уместнее сказать: «Сами мы не местные» ;).
Да… Да. ДА!
У нас есть проблемы. И проблемы большие.
Да, у нас нет «Гражданских технологий» в американском их понимании.
Да, большинство величайших изобретений и проектов современности принадлежит русским, не принадлежащим России: вертолёты Сикорского, кинематограф Вороновых, видеозапись Понятова (AMPEX), Google Брина, ABBYY Яна и Москалёва, AVP Касперского, Тетрис Пажитного и Герасимова (хоть и написан он был в СССР), наши дирижабли для перевозки грузов (целая команда наших), система сейсмолокации Баласаняна, и так далее.

Но! Неужели можно так легко утверждать, что русский народ безыдеен и безынициативен?

Господа! Во-первых, давайте делать скидку на то, что «новое» государство молодо и глупо, как и положено отроку.
У нас БЫЛ отличный базис, как теоретический, так и практический.
Лучший космический проект века «Буран» был тупо погребён под крышей ангара, в котором доживал свой век.
Гибель технологии — первая жертва любой революции, после искусства.
(То же самое было и в 1917-м, но об этом позже).

Во-вторых, у нас немало базовых технологий, которые легко можно применить и сейчас: троичная система счисления (триты и трайты) системы «Сетунь»; процессоры «Эльбрус», развивающиеся по сей день, рекордсмены Гиннеса диктофоны «Эдик»… Список, пожалуй, бесконечен. О скольких разработках мы ещё не знаем: из Дубны и Новосибирска, Рязани и Красноярска, Волгограда и Читы…

У человека стороннего возникает закономерный вопрос: так в чём проблема?
Проблема, на мой взгляд, в системе.
В системе оценки собственных усилий, полезности, коммерческой привлекательности, системе взглядов, в конце концов.
Кто-то списывает это на власть, кто-то на менталитет, кто-то честно заявляет, что просто «лень».

Дорогие мои, у нас есть всё чтобы реализовать свои дерзкие идеи.
Нужно только СОБРАТЬСЯ ВСЕМ ВМЕСТЕ.
Александр Дмитриевич Засядько продирался чрез такие тернии, что нам с вами и не снились.
Хотя его после 1917 года и все забыли (только американцы назвали в его честь кратер на Луне).
Над Циолковским многие просто откровенно смеялись. МЦСТ Бабаяна Ельцин в своё время вообще «закрыл».
А результат?..

У каждого из нас с вами (в том числе у вашего покорного слуги) в головах есть десятки проектов нужных стране, или, как минимум, нам с вами, читателям Хабра. Так что же мешает ним реализовать их, когда всё расписано и разложено по полкам?

СТРАХ!

Вдруг никому это не нужно? Вдруг все вокруг сочтут меня безумным? А что если это уже есть?..
Мы с вами учимся/учились не в MIT и не в Беркли. Кто-то в МИЭМ, кто-то в «Рязанке», кто-то в «Бауманке»…
Совсем маргиналы, типа меня, в РУДН, РГГУ, МГИМО…
Большинство из нас, глядя на собственные кафедры, чётко поняли, что здесь никому ничего не надо…

Ошибка.

Надо! НАМ! Самим!

К примеру, я, до появления iPhone уже имел представление о том, каким должен быть современный телефон/коммуникатор, теперь думаю о том, как вернуть к истокам видеомонтаж и нелинейку сделать такой же шустрой, как линейку, прилепить к ней системы «перчаточной» манипуляции в пространстве; планирую увязку «настольников», нетбуков на базе «Эльбруса» с портативными устройствами на базе SPARC (или, в худшем раскладе, ARM); в общем, много о чём мечтаю.

— Реализую ли я всё это (хотя там много ещё чего)?
— КОНЕЧНО!

Иначе, смысл?

Хабр давно рассматривается как обменник ИДЕЙ. Но, в последнее время, он скорее рассадник МНЕНИЙ.
Нам с вами необходимо просто организоваться вместе и делать НАШЕ общее дело, независимо от властей, экономики и прочей стихии.

В конце концов, на Хабре «скользит» множество стартапов, а независимого «Национального Технологического Портала», как хаба идей не видать…
Может пора, а?

Шаблоны в ASP.NET MVC 2.

Читать дальше →

про русских ученых.

Хочу ответить на этот пост: habrahabr.ru/blogs/the_future_is_here/76992/#habracut

Изобретателей в России много. Изобретений — еще больше. Но общество изначально пропитано негативным отношением к тому, что придумано здесь. При этом общество восторженно относится к тому, что пришло с Запада.

Хотите пример? Пожалуйста! Прямо сейчас из моей жизни.

Я изобрел способ мгновенной шнуровки обуви. Подробно здесь: www.asder.ru/invention/russian.html

Вы думаете — кто-то хоть раз сказал, что это круто? Ничего подобного! На ходу сочиняли, что так способом шнуровались еще деды, что шнурков хватит на два раза, что… ну, не знаю, много глупостей можно придумать. И почему-то они придумываются именно в России. И почему-то именно в России полезные изобретения оказывается никому не нужны.

ЗЫ. Патенту десять лет. Никому не нужен даже бесплатно.

Divine Project — рассказ разработчиков (на русском)

Divine
Divine — это plug-in для Adobe Photoshop разработанный для тех, кто имеет представление о Photoshop и создании сайтов, но не желает тратить свое драгоценное время на кодирование сайта. Divine позволяет из PSD макета сверстать оптимизированный, кроссбраузерный HTML+CSS+PHP код, и отгрузить его в Интернет в виде готовой темы для Wordpress'a. И на данный момент это все совершенно бесплатно.
Но, часть землян это уже знает, поэтому сделаем гипер-прыжок к более интересным сущностям.

Проблема
Если хронологически, то человечество вот-вот отпразднует 2010 год, в фильмах это эпоха нано-технологий, могучих корпораций и персональных блогов. У кого-то даже есть свои роботы! Но со времен сайтов-динозавров процесс кодирования в HTML упрямо не претерпевает революционных изменений.

Вот уравнение, которое нужно упростить:

  1. Создаем/получаем уникальный макет в граф. формате (Photoshop и т.п.)
  2. Нарезаем картинки для элементов сайта (~10-60мин)
  3. Кодируем дизайн-макет в HTML (~1-8ч)
  4. Адаптируем под CMS (~1-2ч):
    • Готовый HTML код дробим на необходимые секции
    • Подставляем их в нужные PHP файлы
    • Загружаем картинки и все файлы на сервер
    • Активируем тему в CMS
  5. Тестируем (~1-8ч)
    • Выверяем динамические элементы CMS (snippets / widgets)
    • Проверяем все мелочи во всех браузерах
    • Оптимизируем скорости загрузки страницы и т.п.

В этой последовательности больше всего вопросов к пунктам 2-5, а точнее к инструментарию:
  • Почему мы должны кодировать и отлаживать html, css, php код дизайн-макета вручную?
  • Почему заказчик сайта должен мириться с некачественным (но дешевым) кодом нерадивых верстальщиков и программистов?
  • Можем ли мы закодировать сайт, создав уникальный дизайн, но исключив пункты 2-5 из процесса?
  • Можно ли приобрести финансовые выгоды, упрощая пункты 2-5?

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

Инструментарий
И что же делать? Пожаловаться на отсутствие инструментов, вас «отминусуют» по полной. ДА, существует множество качественных инструментов, но на поставленный вопрос:

Каким одним инструментом вы пользуетесь для кодирования дизайна под CMS?
Мы получили ответ: Вручную 76% (опрос есть на нашем сайте)


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

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

История
В конце апреля 2008 для очередного Web 2.0 сервиса нам (тогда еще дизайн студии) удалось в кратчайшие сроки сверстать несколько десятков страниц, с приоритетом на качестве кода. Т.к. заказчик вносил коррективы в сверстанные страницы в режиме нон-стоп, то немало времени тратилось на отладку кода.

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

Процесс
Прошло чуть больше года титанических усилий, споров, безумных идей… (будет время, выпустим книгу «Стартап из ....»)
До официального релиза мы решили создать некую демонстрацию возможностей — бесплатную версию, выполняющую заявленные функции без водных знаков и т.п., присущих некоторым shareware продуктам. В рамках данной статьи мы и рассмотрели историю бесплатной версии с «насадкой» на Wordpress — Divine Free Edition

Статья
Уважаемые верстальщики / дизайнеры / программисты! Мы прилетели к вам с миром. И написали на родном языке статью (для части нашей команды), чтобы вы знали — наш проект создан для облегчения в первую очередь вашего труда, многоуважаемые коллеги по цеху.
Все вопросы по качеству верстки / методах / способах мы выслушаем и сделаем ее безукоризненной.

Спасибо
Огромное, преогромное за участие в жизни нашего проекта.

Официальный сайт программы (на не русском):
www.divine-project.com

Расскажите нам, как улучшить продукт (на не русском):
www.ideastrunk.com/divine

p.s. И немного информации закоренелым скептикам — создать качественную верстку для типовых элементов это одна из относительно легких задач в нашем проекте.

Есть ли будущее у отечественной индустрии разработки ПО?

В преддверии нового 2010 года задумался о будущем ИТ-отрасли, в которой работаю сам, а также трудятся мои друзья, знакомые, коллеги.

Поводов для этого было несколько.

Во-первых, кризисная обстановка в мировой и российской экономике по-прежнему сохраняется. Судя по собственным ощущениям и наблюдениям со стороны, до сих пор многие ИТ-компании не только не преодолели спад, но и вступили в затяжную фазу балансирования бизнеса на грани закрытия. Убытки не покрываются выручкой, что в краткосрочном периоде не смертельно, но нельзя же так жить годами! Докризисный высокий спрос резко сменился так называемыми кост каттингами (сокращением затрат) на стороне клиентов и внутри самих компаний. Очевидно, что ИТ-компании, которые сами являются потребителями высокотехнологичных услуг и оборудования также сократили закупки. На лицо общее «сдутие» спроса как на ИТ, так и ИТ-специалистов.

Во-вторых, с января 2010 года государство решило поменять важный элемент налоговой системы – сбор средств на социальное обеспечение населения. Единый социальный налог. (ЕСН), который сейчас уплачивается организациями, будет заменен повышенными страховыми сборами, что несомненно еще более ухудшит положение ИТ-компаний, особенно разработчиков ПО, где заработная плата составляет до 70-80% от общего бюджета расходов. Правительство уже несколько раз объявляло о том, что для разработчиков софта будет введен специальный режим, или частично переплата страховых взносов будет компенсироваться из федерального бюджета, но деталей пока нет. И если основываться на опыте прежних лет, то от момента выхода поправок до момента претворения их в жизнь может пройти до 1,5 лет (на примере введения льгот на ЕСН для ИТ-компаний). Казалось бы, стимулирование развития высокотехнологичной продукции – удачный способ диверсифицировать экономику, отойти от сырьевой модели, но… вероятно, эти инициативы будут успешно погребены бюрократической машиной.

В-третьих, сложилась парадоксальная ситуация на рынке труда. С одной стороны, высвободилась огромная масса специалистов (до 20-30% от штата), которых набирали под будущий рост, вкладывая средства в их обучение и развитие. А с другой, требования работодателей повысились, в то время как зарплатные предложения заметно уменьшились. Нашлись и такие компании, которые рассчитывали снять сливки с этой массы безработных за относительно небольшие деньги. Конкуренция среди кандидатов на позиции рядовых сотрудников выросла, а спрос среди компаний на них снизился. Ведь намного удобнее нанять одного более опытного и лояльного сотрудника, чем держать троих и тратить время на их координацию. Множество выпускников этого года так и не смогли найти себе работу, никому не нужны «зеленые» специалисты на обучение.

Какие можно сделать выводы из всего этого?

Наверное, стоит вспомнить более ранние кризисные периоды, в частности кризис 98 года в России и повсеместный крах доткомов в 2000 году. С тех пор ИТ-бизнес конечно же видоизменился, появилось множество новых технологий и направлений. Но это как раз таки и усугубляет ситуацию, ибо все эти новые направления развивались вслед за развитием экономики. Получается, что все инновационные проекты, которые не приносят очевидных результатов в крактосрочном периоде замораживаются.

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

Удар для региональных компаний будет очень даже ощутимый, т.к. в провинции ниже зарплаты. Простой пример, предел для начисления налога 415 тыс.руб., чтобы в провинции пройти порог и после него не платить налог, сотрудник с зарплатой в 35 тыс.руб. должен отработать в компании целый год. А если учесть, что в столице оплата примерно в 2 раза выше, то столичная компания получит освобождение от уплаты налога уже через полгода.

Единственная приятная новость – правительство сделает переходный период для ИТ-компаний, видимо, чтобы сотрудники сумели переквалифицироваться и найти себе работу. В школах явно не хватает толковых учителей информатики…Напоследок приведу слова знакомого, который пережил все прошлые кризисы: «Ну не будет работы, тогда все пойдем в дворники» :-)

От «А» до первого офиса

sites
Не так давно, в феврале этого года, я с другом ехал в машине, и разговор наш зашёл о планах на будущее. Знакомы мы уже давно, вместе учились в школе, но если раньше вопросы карьеры ставились в будущем времени, то теперь, после окончания университета, они стали настоящим.
Читать дальше →

Место не мейстриновых языков программирования.

Я последнее время интересуюсь языками программирования, требования знаний которых трудно найти в вакансиях. Поиск выдает только вакансии в которых находится графа по типу: «Mastery of some number of interesting languages (e.g. Lisp, Smalltalk, OCaml, Haskell, Perl, Python, Ruby)» или «REQUIREMENTS: Experience with Lisp and ARX is a plus.», «Distributed hashing storage experience / Erlang is a plus» и т.д…
А мне очень интересны такие языки, и время им я уделяю больше чем Джаве или Си-шарпу. Но иногда меня терзают смутные сомнения что я занимаюсь не тем чтем надо. Я конечно получаю эстетическое удовольствие от изучения Лиспа или Хаскелла, мысли о том что через несколько лет придется искать работу, и мне, на собеседовании, придется блистать знаниями по современным технологиям(java, c#, etc.) – пугают меня, и заставляют бросить изучение этих языков.
Сейчас, я в процессе изучения такой книги как СИКП(конец 4-й главы). Мне она показалась фундаментальной и очень полезной. Но опять, меня высмеюют мои однокурсники, и старшекурсники тоже. Они семеются надо мной, мол я изучаю никому не нужный материал на примере древнего языка Scheme, и что это бесполезная трата времени.
Также меня пугает сообщество этих языков, они себя называют «Элитой», но при этом ведут себя как дети. Неоднократно подымаются обсуждения по типу «Хаскелл vs. С++» на ЛОРе. Но с этих «срачей», наполненных тролингом и неадекватом, трудно выяснить истину. Мне трудном понять, почему адепты всяких Хаскеллей так сильно отличаются от остальных программистов своей грубостью и странностью.
Поэтому обращаюсь к Хабру, по моему, одному из самых адекватных сообществ в рунете, за советом и разъяснением. Стоит ли продолжать изучать эти языки, не как хобби, а с мыслью, что это мне пригодиться в профессиональной деятельности. Или эти знания, только ухудшат понимание ООП и испортят мою карьеру как программиста.
Если эти языки действительно хороши, а мне так показалось, то меня удивляет столь невнимательное к ним отношение со стороны работодателя. И меня не покидает вопрос: «Возможно ли устроится на работу, не зная, например, полной спецификации джавы, нескольких фреймворков, но хорошо владея приемами программирования?.» Я думаю на Хабре много работодателей, и они дали бы мне искренний ответ.
У меня получилась не статья а вопрос. Прошу в форумы не посылать, так как там полно неадеквата, а как я уже упоминал, аудиторию Хабра я уважаю и надеюсь на дельные советы в комментариях.

Комплексная модель производительности и зрелости (CMMI — Capability Maturity Model Integration)

Краткое описание из википедии


Capability Maturity Model Integration (CMMI) — набор моделей (методологий) совершенствования процессов в организациях разных размеров и видов деятельности. CMMI содержит набор рекомендаций в виде практик, реализация которых, по мнению разработчиков модели, позволяет реализовать цели, необходимые для полной реализации определенных областей деятельности.

Набор моделей CMMI включает три модели: CMMI for Development (CMMI-DEV), CMMI for Services (CMMI-SVC) и CMMI for Acquisition (CMMI-ACQ). Наиболее известной является модель CMMI for Development, ориентированная на организации, занимающиеся разработкой программного обеспечения, аппаратного обеспечения, а также комплексных систем. Все действующие версии моделей имеют номер 1.2. Модель CMMI-DEV была опубликована в августе 2006 года, CMMI-ACQ — в ноябре 2007-го, CMMI-SVC — в феврале 2009-го.

CMMI является развитием методологии CMM, которая разрабатывалась со второй половины 1980-х годов Software Engineering Institute (SEI) в университете Карнеги-Меллона (Carnegie Mellon University).

А теперь подробнее…
Читать дальше →

TorrentFlux+cyrillic encoding – выходим из положения

Пользователям TorrentFlux (http://www.torrentflux.com/) приходилось сталкиватся с тем, что при скачивании .torrent-файлов, которые содержали в себе названия файлов и папок кириллицей, с неправильным отображением кодировки при старте загрузки, а также при создании torrentflux этих папок и файлов на разделе жесткого диска. Но ситуацию возможно исправить, внеся несколько изменений в исходный код.
Для начала, займемся фронт-эндом (собственно torrentflux), для приемлемого отображения кириллицы.
Для корректного отображения достаточно строки:
define("_CHARSET","windows-1251");

в файле /language/lang-russian.php и нескольких правок в файле metaInfo.php, а именно:
заменим
$this->name на iconv(«UTF-8»,«WINDOWS-1251»,$this->name)

в строке
echo(«d.add(».$this->num.",".$parent.",\"".$this->name."\",".$this->prio.",0);\n")

и
$v->name

на
iconv("UTF-8","WINDOWS-1251",$v->name)

в строке
echo("d.add(".$v->num.",".$this->num.",\"".$v->name."\",".$v->prio.",".$v->size.");\n");

После чего в строке
echo htmlentities($btmeta['info']['name'].$torrent_size." (".formatBytesToKBMGGB($torrent_size).")", ENT_QUOTES);

заменяем
htmlentities($btmeta['info']['name'].$torrent_size

на
htmlspecialchars(iconv("UTF-8","WINDOWS-1251",$btmeta['info']['name']).$torrent_size <br/>

И, наконец, в строке
echo "<tr><td>Directory Name:</td><td>".htmlentities($btmeta['info']['name'], ENT_QUOTES)."</td></tr>"; <br/>

заменяем
htmlentities($btmeta['info']['name'] <br/>

на
htmlspecialchars(iconv("UTF-8","WINDOWS-1251",$btmeta['info']['name']) <br/>

Так, как bittornado создает названия файлов и каталогов в кодировке utf-8, внесем несколько изменений в исходный код для создания файловой структуры в нужной нам кодировке.
Проверяем наличие нужной локали:
#locale –a | grep koi8-r
Для того, чтобы сгенерировать файлы локали, нужно добавить строку:
ru_RU KOI8-R
в файл /etc/locale.gen (в качестве дистрибутива используется Gentoo Linux) и выполнить команду:
#locale-gen
Текущую локаль можно не изменять, достаточно того, чтобы были сгенерированы файлы нужной локали.
Открываем файл TF_BitTornado/BitTornado/download_bt1.py, добавляем в конце строки:
f = path.split(f)[ 0] <br/>

строку
decode('utf-8').encode('koi8-r') <br/>

В результате чего получим строку:
f = path.split(f)[ 0].decode('utf-8').encode('koi8-r') <br/>

Затем, перед строкой:
if f != '' and not path.exists(f): <br/>

вставляем строку:
if forcedir: f = f.decode('utf-8').encode('koi8-r') <br/>

Открываем файл TF_BitTornado/BitTornado/BT1/Storage.py, ищем строку:
file, length = files[i] <br/>

и заменяем ее на строки:
utf_file, length = files[i]<br/>file = utf_file.decode('utf-8').encode('koi8-r') <br/>


После этого Torrentflux будет нормально работать с кириллическими кодировками.
Видоизмененные файлы находятся тут: http://dl.dropbox.com/u/3248658/tf_modified.tar.gz

Оптимизация «ORDER BY RAND() LIMIT 1» — не абсолют, но намного проще

Недавно был впечатлён размышлениями людей на тему оптимизации выборки произвольной записи из таблицы MySQL.

Конечно, выполненная работа впечатляет, но оправданы-ли такие трудозатраты на написание многострочного кода одним человеком, а затем, возможно, попытки понять его другим, причём часто без комментариев автора?

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

Поэтому хочу предложить простейшую альтернативу оптимизации запроса "… ORDER BY RAND() LIMIT 1;" вставкой в код условия «WHERE RAND()>0.9».

Вот результаты теста (взято две таблицы, каждый запрос выполнялся по два раза, результаты не кешировались):

таблица jos_squeezimages, 12804 записей, два поля: id (INT(11)) и fullname (VARCHAR(255))

SELECT fullname FROM `jos_squeezimages` ORDER BY RAND() LIMIT 1;
запрос выполнялся 0,0324 сек первый раз и 0,0317 сек второй раз

SELECT fullname FROM `jos_squeezimages` WHERE RAND()>0.9 ORDER BY RAND() LIMIT 1;
0,0130 секунды, 0,0134 секунды

SELECT fullname FROM `jos_squeezimages` WHERE RAND()>0.999 ORDER BY RAND() LIMIT 1;
0,0112 секунды, 0,0111 секунды

таблица t_tovars, 20212 записей, 25 полей, по большей части varchar
SELECT * FROM `t_tovars` ORDER BY RAND() LIMIT 1;
0,1717 секунды, 0,1816 секунды

SELECT * FROM `t_tovars` WHERE RAND()>0.9 ORDER BY RAND() LIMIT 1;
0,0735 секунды, 0,0642 секунды

SELECT * FROM `t_tovars` WHERE RAND()>0.999 ORDER BY RAND() LIMIT 1;
0,0455 секунды, 0,0447 секунды

Вуаля!
Добавить условие в запрос очень просто, и времени на оптимизацию ушло немного, а скорость увеличилась в три раза.

А главное — не надо много думать :)

Ruby Enterprise Edition, Nginx и заморозка

Затюнинговал я свой web-сервер, чтобы летал побыстрей. Для этого перенес MYSQL в tmpfs с синхронизацией на диск каждые 10 минут, наложил на него патчи от гугла, поставил в роли фронтэнда nginx, приделал к wordpress’у плагины кэширования. Радость то какая! Стал мой сервачок гораздо шустрее. Счастью не было предела. Но продолжалось, как всегда, не долго…

PHP – это отлично, но есть еще проектики, которые на Ruby On Rails крутятся у меня. Стоял Passanger, прикрученный к apache. Но из-за жутко медленной работы и граблей с одновременной работой в связке с PHP я его отключил, чтобы нервы не портил. Отложил до «хорошего настроения». И вот пришла муза.

Нашел отличную статейку на хабре и понеслась… Поставил Enterprise-версию рельсов, пассажира прикрутил. Nginx удалил, который до этого ставился из репозитория debian. Перенес нужные мне строчки из старого конфига в /opt/nginx/conf/nginx.conf. Замечательно! Теперь PHP и RoR дружат и все работает как надо (читайте, «летает»). Но, как всегда, вылез трабл. Не будь надобности запустить Redmine, я бы и не заметил. Проблемы были две. Вторая выявилась благодаря первой.
  • Redmine работает только с Rails 2.2.2 и не выше. А у меня стоит 2.3.5 (зачем нам барахло?)
  • gem install ставил пакеты в места, которые были определены до этого старыми дебиановскими скриптами, так как до этого описываемый софт ставился из репозитариев Debian.

Теперь по порядку. Трабл №1. Я подумал:»Заморожу версию рельсов с помощью команды rake rails:freeze:gems». Откатываю rails до нужной версии, захожу в директорию Redmine’а, замораживаю. Но копируются либы свежей версии рельсов. Выяснилось, что в /opt/ruby-enterprise/ рельсы не откатились. Вот и Трабл №2…

Замечу, что в статье, по которой все настраивал, сделаны симлинки в директорию /usr/bin/ из /opt/ruby-enterprise/bin/

Обе проблемы решил. Сначала вторую, чтобы все нужные бинарники и либы находились системой там, где нужно (/opt/ruby-enterprise/), потом первую, чтобы заморозить Redmine. Что я сделал:

aptitude purge rubygems rails, ruby
Удаляем пакеты, что ставились не из исходников

rm -f /usr/bin/gem /usr/bin/rails /usr/bin/ruby /usr/bin/rake
Удаляем симлинки, которые создавали

export PATH=/opt/ruby-enterprise/bin:$PATH
Говорим, где искать все это удаленное добро

gem uninstall rails -v=2.3.5
Удаляем старые рельсы. Вам может и не понадобится. У меня стояли обе версии (думается, что из-за MultiRails ). Как сказать фризу, чтобы он страую себе копировал, я не нашел.

gem install rails -v=2.2.2
Ставим старичка

cd /var/www/redmine/
rake rails:freeze:gems
gem uninstall rails -v=2.2.2
gem install rails

Перешли в директорию проекта, заморозили, удалили старичка, поставили свежачек

Все работает! Может кому пригодится.

Использованный материал:
Установка nginx и Ruby Enterprise
http://habrahabr.ru/blogs/ror/64295/
Заморозка проектов на RoR
http://www.softiesonrails.com/2008/1/3/freezing-your-rails-application
Решение с export PATH и удалением пакетов с симлинками
/dev/my_mind

Пишем оболочку для управления маршрутизатором ASUS WL-520GU.

Здравствуйте, уже как два года являюсь счастливым обладателем домашнего маршрутизатора фирмы ASUS, куплен он был потому как в семье начали появляться ноутбуки а провода это очень не удобно хотя быстро и безопасно. Перепрошивался аппарат только двумя прошивками это DD-WRT и OLEG firmware ставил я их для того что бы быть в курсе и может быть заменить оригинальную прошивку, но выбор пал на последнюю а проблема банальна настройка принтера легче и быстрее на оригинальной прошивке нежили на DD-WRT или OLEG, принтер у меня оказался очень капризный зовут его HP Deskjet D1300 настройка через RAW метод не удалась а LPR сервера на последних прошивках (DD-WRT) не было. И так девайс был прошит официальной прошивкой версии 3.0.0.8 дизайн в ней на много лучше чем у DD-WRT и OLEG но и она оказалась не без проблем подглючивает определение рабочих станции в прошивке 3.1.0.9 вроде бы убрали этот глюк

image

Так же тут нет теленета для удаленного управления. Скажите почему не обновил до последней беты, ответ прост лень которая управляется не хваткой времени. По умолчанию шифрование локальной сети было выставлено на Open system и тому есть причина, первая и основная причина фанатичные друзья линуксоиды у которых на то время были проблемы с установкой беспроводной сети, вторая причина это то что шифрование забирает часть полосы для пакетов безопасности по внутреннему убеждению я не хотел терять 10% производительности да и кто в маленьком городе будет воровать Wi Fi многие и интернета не видели но это было на тот момент. Спустя год я заметил визитеров в моей сети, часто замечал падение скорости интернета, снифер показал что качали с файловых обменников, акт вторжения быстро и жестоко пресекался :). Случаи вторжения были не частыми и узнавал я о них совсем случайно без обновления все станции что были подключены показывались в настройках так как лазить на маршрутизатор было не удобно я подумал о такой утилите которая управляет всем добром быстро и удобно а именно меня интересовали такие функции:

1. Просмотр клиентов подключенных к сети по Wi-Fi
2. Перезагрузка маршрутизатора
3. Смена IP адреса по возможности без перезагрузки

Хотелось не темного экрана а много кнопочек и что бы не пришлось устанавливать библиотеки размером 100 мегабайт, ноутбук то у меня слабый. И был еще один нюанс на ADSL модеме Callisto 821+ сгорели кондеры и теперь при выключение света он намертво вис помогал только сброс до заводских настроек пока электрики не выключали еще раз свет, раньше для быстрой смены IP я переводил модем в режим Роутера и скриптом быстро менял адрес, но когда появилась проблема с кондерами настраивать маршрутизатор оказалось накладно и нудно и так я стал жить без смены быстрого IP. Время шло и наконец прорвало, твердо решив довести все дело до конца я поспрашивал у Гугла что это и как реализовать нашел очень мало информации из этих крупиц я понял что писать придется на Delphi используя библиотеку Indi в которой я не очень разбирался, и еще проблема была в исходных кодах их нельзя было найти без проблем, на одном форуме добыл исходник регера почтовых ящиков, посмотрев на код понял что там полная жопа, в понимании библиотеки я знал что мне поможет книга а вот как быть с запросами GET и POST я не знал. После долгих поисков установил в Firefox два плагина Live Http Headers и Firebug и понял с индии все туго потому как нашел я конструктор программ под названием Hiasm

image

Для достижение цели тут нужно два компонента плюс запрос, да многие скажу что это не есть хорошо ламеризм и.т.д. но хочу не согласиться главное выбирать правильный инструмент к тому же программы на Hiasm имеют маленький размер что очень радует. После выбора инструмента взор пал на форум и его файлообменник быстро были найдены пару примеров, самый яркий из них это наверное выдирание ссылок из депозит-файлс =). С начала хотелось написать полноценную оболочку ну что бы вообще забыть за маршрутизатор но эта идея быстро отвалилась потому как долго это все будет происходить, решил выделить пару пунктов которые озвучены в верху. Самое интересно это запросы, ну вот например:

GET / HTTP/1.1
Host: 192.168.2.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; uk; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.2 YB/3.5.1 (.NET CLR 2.0.50727)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Authorization: Basic 9/LuIPXu9+X4/CDz5+3g8vwg7O7pIO/g8O7r/Dr18+kg8uXh5Q==

Для посылки запроса хватит первой(GET / HTTP/1.1) второй(Host: 192.168.2.1) и последней строчки, 9/LuIPXu9+X4/CDz5+3g8vwg7O7pIO/g8O7r/Dr18+kg8uXh5Q== непонятные символы это логин и пароль закодированные по алгоритму base64 но тут есть подводный камень этот запрос останется без ответа сервера если в конце запроса не вставить пустую строку, так делаются почти все GET запросы в двух случаях параметры передаются прямо в запросе в случае с перезагрузкой соединения WAN первая строка будет похожа на вот это GET /device-map/wan_action.asp?wanaction=Disconnect HTTP/1.1. Остальные запросы которые будут изменять разные настройки будут посылаться POST запросами эти запросы не намного отличаются в нашем случае их нужно правильно составить а именно не пропустить пустую строку только она теперь находится не в конце запроса а отделяет заголовок от тела запроса например вот так:

POST /start_apply.htm HTTP/1.1
Host: 192.168.2.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; uk; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.2 YB/3.5.1 (.NET CLR 2.0.50727)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: 192.168.2.1/device-map/clients.asp
Authorization: Basic 9/LuIPXu9+X4/CDz5+3g8vwg7O7pIO/g8O7r/Dr18+kg8uXh5Q==
Content-Type: application/x-www-form-urlencoded
Content-Length: 174

sid_list=LANHostConfig%3B&group_id=&action_mode=&action_script=networkmap_refresh¤t_page=%2Fdevice-map%2Fclients.asp&next_page=%2Fdevice-map%2Fclients.asp&flag=nodetect

В этом запросе нужно обратить внимание на Content-Length: 174 после этого блока идет разделитель и переменные которые мы передаем разделяются они знаком &, можно передавать не всю стопку а только маленькую часть но при этом нужно изменить Content-Length на число равное количеству букв в теле запроса в нашем случае их 174. Собственно этой простой техникой делаются регеры мыл и разные программы такого рода. Что бы не превращать эту статью в занудную статью предлагаю посмотреть исходный код программы по это му адресу www.wuala.com/Hort/Soft/WWW/520GU в архиве лежат исполняемый файл, ини-файл (в нем пропишите логин пароль и адрес маршрутизатора) и сам исходный код или схема так будет точнее звучать. Для компиляции схемы понадобится сам Hiasm и желательно компилятор Delphi который лежит по ссылке выше но стандартный фрипаскаль идущий в комплекте тоже будет работать =) но весить на 10% больше. Эту схему можно переделать и под другой тип маршрутизатора хотя глядя на нее можно запутаться

image

Программку малость глючит в плане обновления данных но кнопка обновить должна избавить вас от проблем =), ну если не исправит можете с этим мирится. В данном случае программа умеет выводить список подключенных ПК, выключать соединение с модемом (менять IP пез перезагрузки), перезагружать девайс, показывает и копирует в буфер обмена WAN IP, показывает принтер его можно тоже включать и выключать правда в прошивке глюк который не дает произвести эту операцию. Не откажусь от инвайта если кому понравилась эта статья.

PyQt4 — простейшее рисование

Отрисовка текста


#!/usr/bin/python

# drawtext.py

import sys
from PyQt4 import QtGui, QtCore

class DrawText(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)

self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Draw Text')

self.text = u'Hello from Python'

def paintEvent(self, event):
paint = QtGui.QPainter()
paint.begin(self)
paint.setPen(QtGui.QColor(168, 34, 3))
paint.setFont(QtGui.QFont('Decorative', 10))
paint.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)
paint.end()

app = QtGui.QApplication(sys.argv)
dt = DrawText()
dt.show()
app.exec_()


Текст выровнен по вертикали и горизонтали.

def paintEvent(self, event):
Для прорисовки создали функцию

paint = QtGui.QPainter()
paint.begin(self)
...
paint.end()

Класс QPainter отвечает за всю прорисовку. Все рисование должно быть между методами begin() и end().

paint.setPen(QtGui.QColor(168, 34, 3))
paint.setFont(QtGui.QFont('Decorative', 10))

Здесь мы определяем тип пера и шрифт, который мы используем, чтобы сделать текст.

paint.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)
Метод drawText() рисует текст в окне
image

Рисование точек


#!/usr/bin/python

# points.py

import sys, random
from PyQt4 import QtGui, QtCore

class Points(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)

self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Points')

def paintEvent(self, event):
paint = QtGui.QPainter()
paint.begin(self)
paint.setPen(QtCore.Qt.red)
size = self.size()
for i in range(1000):
x = random.randint(1, size.width()-1)
y = random.randint(1, size.height()-1)
paint.drawPoint(x, y)
paint.end()

app = QtGui.QApplication(sys.argv)
dt = Points()
dt.show()
app.exec_()

В нашем примере мы рисуем случайно 1000 красных точек.

paint.setPen(QtCore.Qt.red)
Устанавливаем перо в красный цвет

size = self.size()
Генерируется каждый раз, когда мы изменяем размер окна

paint.drawPoint(x, y)
Рисуем точки методом drawPoint()
image

Цвета


Цвета мы можем задать в виде значения RGB (в диапозоне от 0 до 255), в шестнадцатеричной системе, ну или же в RGBA (red, green, blue, alpha). Значение alpha 255 определяет полную не прозрачность, 0 для полной прозрачности.

#!/usr/bin/python

# colors.py

import sys, random
from PyQt4 import QtGui, QtCore

class Colors(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)

self.setGeometry(300, 300, 350, 280)
self.setWindowTitle('Colors')

def paintEvent(self, event):
paint = QtGui.QPainter()
paint.begin(self)

color = QtGui.QColor(0, 0, 0)
color.setNamedColor('#d4d4d4')
paint.setPen(color)

paint.setBrush(QtGui.QColor(255, 0, 0, 80))
paint.drawRect(10, 15, 90, 60)

paint.setBrush(QtGui.QColor(255, 0, 0, 160))
paint.drawRect(130, 15, 90, 60)

paint.setBrush(QtGui.QColor(255, 0, 0, 255))
paint.drawRect(250, 15, 90, 60)

paint.setBrush(QtGui.QColor(10, 163, 2, 55))
paint.drawRect(10, 105, 90, 60)

paint.setBrush(QtGui.QColor(160, 100, 0, 255))
paint.drawRect(130, 105, 90, 60)

paint.setBrush(QtGui.QColor(60, 100, 60, 255))
paint.drawRect(250, 105, 90, 60)

paint.setBrush(QtGui.QColor(50, 50, 50, 255))
paint.drawRect(10, 195, 90, 60)

paint.setBrush(QtGui.QColor(50, 150, 50, 255))
paint.drawRect(130, 195, 90, 60)

paint.setBrush(QtGui.QColor(223, 135, 19, 255))
paint.drawRect(250, 195, 90, 60)

paint.end()

app = QtGui.QApplication(sys.argv)
dt = Colors()
dt.show()
app.exec_()


image

color = QtGui.QColor(0, 0, 0)
color.setNamedColor('#d4d4d4')

Здесь мы определяем цвет, используя шестнадцатеричное представление

paint.setBrush(QtGui.QColor(255, 0, 0, 80));
paint.drawRect(10, 15, 90, 60)

Здесь определяем кисть, и рисуем прямоугольник. Метод drawRect () рисует прямоугольник, первые два параметра координаты X и Y, третий и четвертый — ширина и высота.

Линии


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

#!/usr/bin/python

# penstyles.py

import sys
from PyQt4 import QtGui, QtCore

class PenStyles(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)

self.setGeometry(300, 300, 280, 270)
self.setWindowTitle('penstyles')

def paintEvent(self, event):
paint = QtGui.QPainter()

paint.begin(self)

pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)

paint.setPen(pen)
paint.drawLine(20, 40, 250, 40)

pen.setStyle(QtCore.Qt.DashLine)
paint.setPen(pen)
paint.drawLine(20, 80, 250, 80)

pen.setStyle(QtCore.Qt.DashDotLine)
paint.setPen(pen)
paint.drawLine(20, 120, 250, 120)

pen.setStyle(QtCore.Qt.DotLine)
paint.setPen(pen)
paint.drawLine(20, 160, 250, 160)

pen.setStyle(QtCore.Qt.DashDotDotLine)
paint.setPen(pen)
paint.drawLine(20, 200, 250, 200)

pen.setStyle(QtCore.Qt.CustomDashLine)
pen.setDashPattern([1, 4, 5, 4])
paint.setPen(pen)
paint.drawLine(20, 240, 250, 240)

paint.end()

app = QtGui.QApplication(sys.argv)
dt = PenStyles()
dt.show()
app.exec_()


В этом примере мы рисуем шесть линий. Линии проведены в шести различных стилях.

pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
Создали QPen объект, цвет черный, толщина 2, QtCore.Qt.SolidLine является одним из предопределенных стилей пера.

pen.setStyle(QtCore.Qt.CustomDashLine)
pen.setDashPattern([1, 4, 5, 4])
paint.setPen(pen)

Здесь мы определяем пользовательский стиль пера. Список цифр определяет стиль пера. В нашем примере. Чем больше число тем больше пространство или тире. У нас: 1px заполнено, 4px пустота, 5px заполнено, 4px пустота, и т.д.
image

QBrush


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

#!/usr/bin/python

# brushes.py

import sys
from PyQt4 import QtGui, QtCore

class Brushes(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)

self.setGeometry(300, 300, 355, 280)
self.setWindowTitle('Brushes')

def paintEvent(self, event):
paint = QtGui.QPainter()

paint.begin(self)

brush = QtGui.QBrush(QtCore.Qt.SolidPattern)
paint.setBrush(brush)
paint.drawRect(10, 15, 90, 60)

brush.setStyle(QtCore.Qt.Dense1Pattern)
paint.setBrush(brush)
paint.drawRect(130, 15, 90, 60)

brush.setStyle(QtCore.Qt.Dense2Pattern)
paint.setBrush(brush)
paint.drawRect(250, 15, 90, 60)

brush.setStyle(QtCore.Qt.Dense3Pattern)
paint.setBrush(brush)
paint.drawRect(10, 105, 90, 60)

brush.setStyle(QtCore.Qt.DiagCrossPattern)
paint.setBrush(brush)
paint.drawRect(10, 105, 90, 60)

brush.setStyle(QtCore.Qt.Dense5Pattern)
paint.setBrush(brush)
paint.drawRect(130, 105, 90, 60)

brush.setStyle(QtCore.Qt.Dense6Pattern)
paint.setBrush(brush)
paint.drawRect(250, 105, 90, 60)

brush.setStyle(QtCore.Qt.HorPattern)
paint.setBrush(brush)
paint.drawRect(10, 195, 90, 60)

brush.setStyle(QtCore.Qt.VerPattern)
paint.setBrush(brush)
paint.drawRect(130, 195, 90, 60)

brush.setStyle(QtCore.Qt.BDiagPattern)
paint.setBrush(brush)
paint.drawRect(250, 195, 90, 60)

paint.end()

app = QtGui.QApplication(sys.argv)
dt = Brushes()
dt.show()
app.exec_()

В нашем примере мы рисуем 6 различных прямоугольников.

brush = QtGui.QBrush(QtCore.Qt.SolidPattern)
paint.setBrush(brush)
paint.drawRect(10, 15, 90, 60)


Определяем тип кисти, и рисуем прямоугольник, с помощью метода drawRect()
image

Антиспам для Skype

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

Нет — будет. На сайте обнаружился какой-никакой, а ассортимент wrapper'ов к API. Выбор пал на Python, ибо ничего масштабного не требовалось, а «import antigravity» только радовало. В процессе отладки скрипта было замечено несколько косяков в API. Оные были заботливо подпёрты костылями. Итак:

import Skype4Py
from time import sleep
skype = Skype4Py.Skype()
TRYING = 1
TEXT = {
¬'QUESTION':"Hello. It's antispam bot. Answer, 2+2=? One figure, please. You have %i trying." % (TRYING),
¬'ANSWER':"4",
¬'WIN':"Right. I'll write you soon.",
¬'AGAIN':"Try one more time.",
¬'FAIL':"Autoignoring.",
¬'INSTANT_BAN':"Autoignoring due to banned word in the authorization request or in the name."
}
BANNED = {
¬'WORDS':("http", "www"),
¬'NAMES':("")
}
HIDE_MESSAGES_AFTER_WRONG_ANSWER = True # True may cause loss of the new answers
REFRESH_DELAY = 30 # in seconds
GET_NAME_DELAY = 1.5
queue = {}

def answer_received(msg, status):
¬username = msg._GetSender()._GetHandle()
¬if username in queue.keys():
¬¬if status==Skype4Py.cmsReceived:
¬¬¬if msg._GetBody()!=TEXT['ANSWER']:
¬¬¬¬if HIDE_MESSAGES_AFTER_WRONG_ANSWER:
¬¬¬¬¬skype.UnregisterEventHandler('MessageStatus', answer_received)
¬¬¬¬¬for eachMsg in msg._GetChat()._GetRecentMessages():
¬¬¬¬¬¬try:
¬¬¬¬¬¬¬eachMsg.MarkAsSeen()
¬¬¬¬¬¬except:
¬¬¬¬¬¬¬continue
¬¬¬¬¬skype.RegisterEventHandler('MessageStatus', answer_received)
¬¬¬¬queue[username] = queue[username]-1
¬¬¬¬if queue[username]:
¬¬¬¬¬skype.SendMessage(username, TEXT['AGAIN'])
¬¬¬¬¬return
¬¬¬¬else:
¬¬¬¬¬del queue[username]
¬¬¬¬¬skype.SendMessage(username, TEXT['FAIL'])
¬¬¬¬¬msg._GetSender()._SetIsBlocked(True)
¬¬¬else:
¬¬¬¬del queue[username]
¬¬¬¬skype.SendMessage(username, TEXT['WIN'])
¬¬¬if len(queue)==0:
¬¬¬¬skype.UnregisterEventHandler('MessageStatus', answer_received)

def hasBanned(txtstr, target):
¬for word in BANNED[target]:
¬¬if word in txtstr:
¬¬¬return True
¬return False

def auth_received(from_user):
¬newUsers = skype._GetUsersWaitingAuthorization()
¬if not newUsers:
¬¬for key in queue.keys():
¬¬¬del queue[key]
¬¬return
¬for user in newUsers:
¬¬username = user._GetHandle()
¬¬if not (username in queue.keys()):
¬¬¬if TRYING < 1:
¬¬¬¬skype.SendMessage(username, TEXT['FAIL'])
¬¬¬¬user._SetIsBlocked(True)
¬¬¬¬continue
¬¬¬if hasBanned(user._GetReceivedAuthRequest(), 'WORDS'):
¬¬¬¬skype.SendMessage(username, TEXT['INSTANT_BAN'])
¬¬¬¬user._SetIsBlocked(True)
¬¬¬¬continue
¬¬¬skype.RegisterEventHandler('MessageStatus', answer_received)
¬¬¬skype.SendMessage(username, TEXT['QUESTION'])
¬¬¬queue[username] = TRYING
¬¬¬sleep(GET_NAME_DELAY)
¬¬¬if hasBanned(user._GetFullName(), 'NAMES'): # Skype's bug: full name is available only after message sending
¬¬¬¬del queue[username]
¬¬¬¬skype.SendMessage(username, TEXT['INSTANT_BAN'])
¬¬¬¬user._SetIsBlocked(True)
¬¬¬¬if len(queue)==0:
¬¬¬¬¬skype.UnregisterEventHandler('MessageStatus', answer_received)
¬¬¬¬continue

skype.RegisterEventHandler('UserAuthorizationRequestReceived', auth_received)
# В принципе следующий цикл не обязателен, но тогда при перезапуске скайпа придётся перезапускать и скрипт. И именно в такой последовательности.
while True:
¬skype.Attach()
¬auth_received(None)
¬sleep(REFRESH_DELAY)


¬ следует автозаменить на табуляцию, так вот глупо и неудобно определяется вложенность...
Затем сие сохраняется в файл с расширением .pyw и крутится в фоне.

P.S. К счастью, волна спама давно поутихла, но вдруг кому-то пригодится.

CodeIgniter — роутинг через базу данных

Возникла необходимость сделать так, чтобы можно было выбирать какой URL на какой контроллер ведет. Каждый раз лазить в файлы и править правила роутинга не есть правильное решение. Кроме того, в основном на сайте будут расположены страницы, и хотелось бы чтобы был ЧПУ из названия раздела и страницы. Особо гуглить я на эту тему не стал и придумал своё решение.

Принцип действия следующий:
1. В базе содержатся alias'ы страниц, к примеру '/it' и '/it/articles'. Последнему соответствует определенный контроллер и метод, допустим 'pages' и 'showList' соответственно.
2. Роутинг CodeIgniter'a смотрит куда обращаться по query_string или path_info. Эту строку мы и будем сравнивать с alias'ом в базе.
3. После сравнения, мы находим самое большое вхождение имеющейся строки. Допустим, если мы введем в строке '/it/test', то результатом будет алиас '/it', а если '/it/articles/param1' — '/it/articles' (все это делается одним запросом)
4. Для передачи параметров, мы из исходной строки удаляем alias, тем самым получается остаток от URI и являющийся параметрами, которые передадутся методу.

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

Манифест к хабросообществу, как самой многочисленной аудитории IT специалистов в России

Мы стоим на пороге новых открытий, технологий и продуктов для широкого использования. Информационные технологии, компьютеры, телефоны, портативные устройства, навигаторы стали частью нашей жизни и мы используем их каждый день в нашей деятельности. Область IT самая быстроразвивающаяся во всем мире. Посмотрите, что было достигнуто за поледние 20 лет, 10 лет и 5 лет. Каждый год появляются новые технологии, устройства, продукты, которые делают будущее уже сейчас. И благодаря кому это происходит? Благодаря нам, конечно! За всем этим стоят специалисты IT, которые претворяют, порой, даже самые невероятные идеи в жизнь. В 80-х годах началась эра информационных компьютеров. Они прошли путь от огромных вычислительных машин, но с маленькой мощностью для научных институтов до высокопроизводительных систем и портативных устройств, которые умещаются в вашем кармане и востребованы обывателями. Скорость обмена информацией возрасла на порядки за эти годы.
Настало время для нового продукта, который пройдет похожий путь. Роботы. Роботы от программируемых сварочных аппаратов на автозаводах, до неуклюжих конструкций, иммитирующих походку животных и действия человека, вперед к полноценным роботам, которые будут нужны каждому человеку в каждом доме. Роботов, которые не выходят из строя от воды, слабых источников питания, роботов, способных принимать решения на основе прошлого опыта, роботов, которые будут помогать человеку в его повседневных делах.
Читать дальше →

VDPAU или смотрим HD фильмы на Ubuntu

image

Тут товарищ hosco говорит, цитирую:
«Блин, перешёл бы на Линукс (именно этот дистрибутив покорил меня своей простотой в красоте и красотой в простоте), если бы не прошлый печальный опыт с 7-кой. Всё вроде заработало «из коробки», но отказывалось нормально проигрываться HD-видео. После волшебных пассов напильником оно проигрывалось, но после оказалось, что не передаётся звук по HDMI. Полазив по форумам, выяснилось, что сотворить звук по HDMI сродни только человеку с возможностями Нео :) Это мы хотели из Acer Revo сделать медиа-центр. Надеюсь 8-ка избавит многих от никчёмных страданий :)»
Тема — habrahabr.ru/blogs/ubuntu/75144

Ведь хочется помочь этому конкретному человеку, да и чёрт возьми многим другим, но инвайта мне никто не даёт, так что… =ъ «помогите люди добрые, сами мы не местные». Авансом я вам расскажу, как прикрутить VDPAU к SMplayer и XBMC Media Center, для комфортного просмотра HD видео.

Заранее предупреждаю, в линуксе я всего 2 года, так что многие советы могут показаться чересчур… ламерскими? Что я в связи с этим предлагаю, дорогие мои профи, если во-время прочтения у вас что-то и где-то сильно засвербит, кожа покраснеет, а глаза начнут выползать из орбит — не мучайте себя, перестаньте читать немедленно.
По-моему для %username% важнее то, что в итоге всё будет работать, а не трушность подхода. Всё проверенно на себе, на Acer Aspire Revo 3600.
С другой стороны, я должным образом приму любую критику и советы, дабы придать данному мануалу должный вид.

Со вступлением разобрались, и так начнём.
Читать дальше →