Показаны сообщения с ярлыком программирование. Показать все сообщения
Показаны сообщения с ярлыком программирование. Показать все сообщения

вторник, мая 21, 2019

Жаркий день в аду

ИЛИ

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

В каждом сервере торчит флешка, на которую еженощно бэкапится база данных.

Был один зияющий пробел, который меня беспокоил: однажды в одной из точек вылетит сервер. Это неизбежно случится. Что я буду делать?



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

automysqlbackup создаёт бэкап базы в каталоге latest (при включенной опции latest), это хардлинк на последний файл в каталоге daily. Файл содержит в имени дату. Это неудобно, его надо переименовать (это значит, что файловая система должна поддерживать хардлинки, поэтому бэкапные флешки отформатированы в ext4).

Алгоритм:

1) монтируем флешку (на случай, если не);

2) бэкапим базу;

3) если удачно, удаляем daily.sql.qz в latest

4) переименовываем дамп базы в daily.sql.qz (в старых версиях дамп начинается с имени базы, в новых - с daily; соответственно, переименовываем файл, начинающийся на p или на d);

5) чмодим daily.sql.qz для чтения всеми (новая версия automysqlbackup создаёт его rw----).

Для этого создаём /root/backup с содержимым:

#!/bin/bash
mount /dev/sdb1 /mnt/backupflash; /usr/sbin/automysqlbackup && rm /mnt/backupflash/sql/latest/daily.sql.qz; mv $(ls /mnt/backupflash/sql/latest/p*) /mnt/backupflash/sql/latest/daily.sql.qz && chmod a+r /mnt/backupflash/sql/latest/daily.sql.qz

Выделено жирным: 1) automysqlbackup старых версий находится в /usr/local/bin, новых - в /usr/sbin; сделать whereis automysqlbackup от рута, чтобы узнать. 2) см. разницу p/d выше.

Делаем исполняемым chmod +x /root/backup и ставим в крон рута на ночное время.

0 3 * * * /root/backup >/dev/null 2>&1

Теперь на принимающей стороне. Здесь мы обходимся rsync в crontab:

0 7 * * * sshpass -p "PASSWORD" rsync LOGIN@HOST:/mnt/backupflash/sql/latest/daily.sql.gz /SOMEWHERE/HOST/ >/dev/null 2>&1

Чтобы это работало, надо предварительно соединиться по ssh с источником, чтобы сохранился ключ соединения. rsync должен иметься на обеих сторонах, конечно.

И копия рабочей системы:

5 7 * * * sshpass -p "PASSWORD" rsync -az LOGIN@HOST:/SOMEPATH /var/www/HOST >/dev/null 2>&1 

И резервные базы-то обновить, опустим подробности, это zcat и mysqladmin нужных файлов в нужные базы (их надо сперва создать).

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

Дальше нам надо создать виртуальные серверы для каждой системы, я их делал на основе ip-адреса.

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

Во вторник с утра вылетает один из серверов во Владивостоке.

Сука, едва успел пригнуться, а то бы убило.

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

воскресенье, октября 22, 2017

Программируемый калькулятор: мой первый плагин WordPress



Задача: расставить на страницах сайта калькуляторы расчёта стоимости потолка, балкона, окна, кондиционирования.

Параметры должны быть настраиваемыми.

Сайт на WordPress. Соответственно, настройка в админке.

Яваскриптить четыре калькулятора было в лом, поэтому от себя добавил условие: один универсальный скрипт на все калькуляторы, расчёты программируются параметрами полей ввода.

Загуглил, как устроен плагин WP (и сам WP заодно). На Хабре хорошие примеры. Немного поковырял, получил страницу в админке.

Сохранять и получать массив параметров удобно через вордпрессовские  get_option() / update_option().

Вставлять калькулятор в страницу - через shortcode с параметром.

Перешёл к самому интересному: скриптингу расчётов.

Всё, что участвует в расчёте, обозначим классом factor.

Калькуляторы не отнимают и не делят. Только два действия. Соответственно, нужны поля двух классов: add и mul. Первое прибавляет к итогу, второе - умножает итог.

При событиях change, keyup со всем, имеющим класс factor, вызывается пересчёт.

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

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

Покрутил так и эдак, пришёл к схеме: если среди $('.factor') есть что-то с классом freeze, запомнить итог на этот момент. Если дальше что-то имеет класс use-frozen, оперировать не итогом, а его замороженным значением.

Всё гениальное frozen.

Заодно добавим класс cm2m, значения этих полей при пересчёте переводим из сантиметров в метры на лету.

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

Если это хорошо упаковать (встроенный редактор калькуляторов, шаблоны внешнего вида, адаптив, i18n), годится как самостоятельный товар.

понедельник, августа 08, 2016

Ушёл на базу. Через шифрованную дырку.

С открытием второй пиццерии (с моей точки зрения - с развёртыванием второй системы управления производством) возникли вопросы взаимодействия:

Как дать возможность оператору отправить заказ на нужную пиццерию?

Как формировать консолидированные отчёты по двум точкам?

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

Вариант master/slave в MySQL сразу не рассматривал, потому что схема должна быть такой, чтобы пережить атомную бомбардировку: уцелевшие пиццерии должны продолжить автономную работу несмотря на оборванные провода и исчезнувшие соединения.

Это можно сделать через REST: куча писанины и куча новых ошибок.

Либо обращаться к базе удалённо.

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

Немножко почитал интернеты и понял, что понадобится:

autossh - надстройка над ssh, поддерживающая соединение в рабочем состоянии, пока это возможно;


И всё.

К слову, Гугл по поиску autossh в третьей позиции даёт ветку под названием "Чтоб вы знали: autossh - полное дерьмо". Я её внимательно изучил. Она меня не убедила.

Ещё нужен скрипт для управления autossh как службой, он находится здесь и отлично встраивается в Debian.

Смотав это всё синей изолентой, получаем на сервере А новый порт MySQL, открытый в тьму внешн базу данных сервера Б, без создания новых дырок, через зашифрованное, автоматически устанавливающееся и магически восстанавливающееся соединение.

Дальше - с отвёрткой в зубах - в PHP-класс работы с SQL. Здесь делаем выбор параметров соединения из массива предопределённых вариантов. Важно: если сервером указывать localhost, запрос такого-то порта будет проигнорирован. Поэтому указываем 127.0.0.1. Вроде хрен и редька, а вот хрен.

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

Холишыт, это действительно работает!

Дальше так: в интерфейс операторов, принимающих заказы с доставкой, добавляем выбор пиццерии:


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

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

Дальше надо поэкспериментировать и понять, как лучше строить консолидированные отчёты: federated table?

Ну и автоматические обновление настроечных данных: надо переписать методы класса работы с БД, чтобы запросы можно было автоматически проигрывать на выбранном или всех доступных соединениях.

четверг, августа 04, 2016

Печать чеков на Posiflex Aura: траблшутинг

Как уже сообщалось, произошло обарывание принтера Posiflex Aura для печати из-под CUPS; как оказалось, не окончательное.

При попытке перехода на новую схему оказалось, что некоторые чеки выходят в виде вертикальных полос либо просто чёрным листом с обрывком контента внизу. Их PDF выглядят такими же, как и нормально печатающиеся. Загадка? Загадка.

Надо думать. Теорию суперструн вон придумали, а ср@ные полоски на бумаге не осмыслим? Так не бывает.

Вот драйвер принтера переварил PDF и выдал растровую страницу. Вот она пошла в принтер. Может переполниться память? Если она есть, то может.

Посмотрел спецификацию принтера. Памяти страниц нет. Есть входной буфер размером 10К.

Значит, принтер не запоминает всё задание перед печатью. Выводит поток на ленту и тут же забывает. Логично: все нелазерные принтеры так работают.

Очевидно, размер буфера рассчитан так, чтобы в нём поместились данные, втекающие в трубу одного диаметра и вытекающие из трубы другого. В нормальных условиях.

Теперь смотрим на PDF, который мы печатаем. Начало.


Что, если жирный логотип сразу забивает буфер и не успевает утечь в дренаж? Buffer overrun. Скорее всего, часть данных будет потеряна; затем напечатается обрывок нижней части. Размер чека будет таким, будто всё напечатано правильно: скорее всего, он передаётся в задании.

Это именно то, что мы имеем.

Проверяем. Открываем шаблон PDF и комментим лого. Надо же - всё печатается хорошо.

Исправляем в стиле логотипа ширину: 40 мм вместо 70. Полёт нормальный.

Ставим 50 мм. Нормально.

Где-то между 50 и 70 находится критический размер, дающий битмап под 10К. Я не стал его выяснять: 5-сантиметровое лого ОК.

Если всё верно, теперь при любом размере чека печать будет происходить правильно. Для проверки лезем в базу данных:

select count(ID) as c, order_id 
from ########## 
group by order_id order by c desc limit 1

Получаем заказ из 52 позиций, это исторический максимум со среза базы в январе.

Печатаем его чек. Две 32-сантиметровые страницы, всё чётко. С логотипом.

Последнее: уменьшенный логотип имеет некрасивые края: dithering. Открываем Gimp, меняем печатный размер лого: 50 мм при разрешении 8 dpmm (из спецификации). Переводим в 1-битный битмап и сохраняем. О, печатается намного лучше!

Последнее. Открываем скрипт печати и переключаем вывод сокета TCP на очередь CUPS.

Трибуны беснуются.

вторник, июля 19, 2016

Чековый принтер Posiflex AURA 6900 + Linux

Более двух лет назад пришлось подключать чековые принтеры Posiflex 6900 к производственной системе, построенной на LAMP. Тогда я решил эту задачу минималистично: обнаружил, что принтер тупо выводит на ленту всё, что приходит на порт TCP 9100 (обнаружил случайно: попытался открыть порт 9100 браузером и увидел на ленте заголовки HTTP-запроса). Русские буквы выходили двухбайтными; установить, что встроенный шрифт использует codepage 866, было просто. Написал вывод текстовых чеков на порты нужных принтеров, и больше двух лет так и работало.

Сейчас возникло желание поиметь красивые чеки с картинками и шлюхами. Для этого надо подключить принтер через CUPS. Исследование инета показало. что: 1) драйверов для CUPS нет ни у производителя, ни у вендоров; 2) в инете есть 2 (две) релевантные темы на форумах, ни в одной нет решения. Но! В одной из тем топикстартер приложил файл 6800.zip. Внутри обнаружился PPD для этого типа принтеров и - бааааа! - файл rastertopp7, который, ясное дело, представляет собой принтер-специфический фильтр CUPS. Файл оказался 32-bit ELF binary. Система 64-битная. Хьюстон, у нас тово.

Положил фильтр в /usr/lib/cups/filter. Добавил принтер, подключение: socket://xxx.xxx.xxx.xxx:9100, скормил найденный PPD. Попробовал напечатать тестовую страницу, получил сообщение "Filter failed". Естественно: рыба-то пресноводная, а водоём-от солёный.

Я поискал исходники и почти нашёл. На тайваньском сервере. С китайским интерфейсом. За скачивание попросили 50 юаней. Я пожопился из-за отчётливого ощущения разводилова. Адрес пользователя, разместившего архив, был в mail.ru.

Остался план Б: мультиархитектура. Добавил архитектуру i386 в систему:

dpkg --add-architecture i386

добавил 32-битные библиотеки:

apt-get update

apt-get install ia32-libs

Повторил пробную печать. Filter failed. Недодавил где-то.

ldd /usr/lib/cups/filter/rastertopp7 | grep found

Выхватил сообщение о не найденной libcupsimage.so.2

apt-get install libcupsimage2:i386

Повторил печать. Из принтера вылезла пробная страница с пингвином.

Теперь всё просто:  1) чек рисуется в HTML; 2) пропускается через mPDF, получается PDF; 3) отправляем его на принтер, ждём несколько секунд и удаляем файл. Несколько уродски, но просто и работает, а простые фокусы - самые надёжные.




воскресенье, апреля 06, 2014

Ещё одна причина, почему надо избегать кириллических доменов

Подключал сайт к эквайрингу Сбербанка. Всё как по писаному, кроме последнего этапа: возврат пользователя из банка в магазин. Не происходит. Пустой экран. Уже написал письмо в саппорт, но что-то дёрнуло. Чисто для эксперимента заменил в адресе возврата блаблабла.рф на xn--blahblahblah.xn--p1ai

Ну ёёёлы-палы :-)

понедельник, марта 24, 2014

DLE: я упал об стол

Есть такой чудо-движок невероятной уродливости.

Тем не менее, иногда приходится по мелочи подшаманивать сайты, имевшие несчастье на нём быть сделанными.

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

Оказалось, что статья отнесена в 2 категории. Но системная переменная, хранящая категорию,  скалярная.

Полез посмотреть таблицы напрямую.

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

Уже тип поля category в dle_post (VARCHAR(200)) внушил худшие опасения.

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

*HEADSHOT.JPG*

среда, февраля 12, 2014

Сказ о том, как платёжная система с хостингом не подружилась

Злободневное, и может сэкономить кому-то время и мозг.

Подключал платёжную систему PayAnyWay (Монета.Ру) к сайту на Фабрике Хостинга (hostfabrica.ru). Всё нормально, но не доставляется техническое уведомление о прохождении платежа. Оно происходит невидимо для пользователя. Пользователь получает своё спасибо, деньги поступают, но на технический е-мейл начинают десятками идти сообщения от Монеты.Ру о невозможности передать уведомление.

Техподдержка Монеты.Ру поясняет, что их сервер по адресу Pay URL получает 403.

Делаю запрос из браузера руками: всё работает.

Техподдержка Фабрики Хостинга предполагает, что Монета.Ру не передаёт user-agent, и такие запросы получают 403.

Монета.Ру отвечает, что user-agent передаётся.

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

Можно было попробовать ввести их в диалог друг с другом, но - время. Поэтому просто перевёл сайт на другую площадку (hostline.ru). Всё работает.

Итоги:

1) если непонятно не работает уведомление на Pay URL от Монеты.Ру, причина может быть в блокировании их робота хостером.

2) до решения этой проблемы сайты с подключенной Монетой.Ру не будут полноценно работать на Фабрике Хостинга. Вряд ли их конфигурация в этом уникальна. То есть нестыковка может происходить и на других площадках.

воскресенье, мая 19, 2013

Идентификация от Google: стоп машина

Взяли и сменились идентификаторы пользователей, возвращаемые Гуглем после аутентификации.

Взяли и отвалились юзерские аккаунты, связанные с этими идентификаторами.

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

Я за Стабильность потому что.

среда, апреля 24, 2013

Краткая сводка спусков на воду

Запущен довольно давно, но не упомянут в личной истории туристический сайт Находки. Проект издательства "Тихоокеанский горизонт".

Пока не сильно богат контентом, но, если нужен путеводитель по городским кафешантанам, это лучший ресурс, я гарантирую это :-)

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

Из занимательного, во-первых, 3D-туры по заведениям (на сегодня один, но люди работают), во-вторых, некоторая интеграция с всеми нами тут любимым nakhodka.info: прологинившись на tur-n.ru через социальные сервисы (проще говоря - через Логинзу), можно в пару кликов перетянуть с Находки.Инфо свой ник и аватар и в будущем их синхронизировать. Тут я немного приподнял портьеру, но всё уже работает и будет открыто посетителям сегодня, так что приподнял совсем немного.

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

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

четверг, декабря 20, 2012

Тик-так часики... вечером в Техасике...

...Приехав в "Техас" пообщаться совершенно по другому поводу, уехал с данным обещанием подумать, что бы такого им демонстрировать на сцене с проектора. К примеру, часики.

Flash исключается, 3D - я и подзабыл порядком Блендер, и использовал его только для статичных картинок.

Осталось прибегнуть к тому, что хорошо знакомо: HTML + CSS + Javascript.

Нашёл в инете вот это.

Изучил. Первое, графику надо прорисовывать заново. Второе, Яваскрипт, который всем этим заправляет, конечно, как это - sophisticated, - но это же полный, как это - overkill. В общем, Яваскрипт решил тоже сделать свой. В итоге от оригинальных часиков осталась идея указания времени посредством трёх стрелок - по одной для часов, минут и секунд, что тоже не вполне оригинально.

Часики нарисовал в Инкскейпе в виде черыёх объектов: фон и три стрелки, всё тщательно выровнено относительно, как это - bounding box, - затем этот квадрат размножен на четыре, и каждый объект с ним сгруппирован. Таким образом, при экспорте в растр все объекты гарантированно имеют общий центр. Экспортировал с большим, даже огромным запасом разрешения, чтобы даже на проекторе Full HD было эротишненько.

Собирается в HTML внутри квадратного блока: три блока для графики стрелок, абсолютно позиционированы и равны контейнеру.

Стрелки крутятся путём CSS Transitions, что оставляет за бортом всякие там недобраузеры, благо это делается для одного-единственного клиента.

Для транзишнов использован jquery.transit.js.

Итоговый Яваскрипт, в отличие от оригинального (кому лень смотреть - там два экрана мелким почерком), следующий:

$(document).ready(function(){
                
   var Now = new Date();
   var Hour = Now.getHours();
   var Minute = Now.getMinutes();
   var Second = Now.getSeconds();
                
   Hour=(Hour > 12)? Hour-12 : Hour;
                
   var angleSecond = Second * 6;
   var angleMinute = Minute * 6 + Second*.1;
   var angleHour = Hour * 30 + Minute*.5;
                
   $('#analogHour').transition({rotate: angleHour});
   $('#analogMinute').transition({rotate: angleMinute});
   $('#analogSecond').transition({rotate: angleSecond});
                
   setInterval(function() {
      doAnimation($('#analogSecond'), 6, 500);
      doAnimation($('#analogMinute'), .1, 500);
   }, 1000);
                
   setInterval(function() {
      doAnimation($('#analogHour'), .5, 500);
      }, 60000);
                
});
            
function doAnimation(obj, angle, timing){
   obj.transition({rotate: '+='+angle}, timing);
}

Попробовал - тикает, зараза! Для проверки накопления ошибки (всё-таки вращение, а часики выставляются только в момент запуска и далее тикают независимо от часов компьютера) оставил на ночь. Утром увидел опережение на минуту: 9:05 на компьютере, шесть минут десятого в браузере. Не успел сказать "тваюжтымать", как часы компьютера перескочили на шесть минут: они ж дискретные, ёлы-палы.

Осталось проверить в деле, для чего поехал в "Техас" с флешкой. Запустили в Chrome, вывели на проектор - ну прямо мняшка.

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



четверг, ноября 08, 2012

Конструктор дымоходов - теперь и на планшетах

Пропатчил свой констуктор:
  1. добавил Mobile_Detect.php для распознавания планшетов;
  2. для планшетов дополнительно подгружается jQuery UI Touch Punch;
  3. тап-драг работает!
Для телефонов решил оставить констуктор view-only, без конструкторской части, потому что на телефоне любого размера это всё равно нереально.

Мой Acer A701 не определялся как планшет, пока не исправил Mobile_Detect.php:

строка 74
'AcerTablet'        => 'Android.*\b(A100|A101|A200|A500|A501|A510|W500|W500P|W501|W501P)\b',

на

строка 74
'AcerTablet'        => 'Android.*\b(A100|A101|A200|A500|A501|A510|A700|A701|W500|W500P|W501|W501P)\b',

Разработчик уведомлен.

понедельник, октября 29, 2012

Манипуляции ротацией

Потратил день на прокачку конструктора дымоходов для Dymunet.ru

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

Прорисовывать в Инкскейпе было и в лом, и показалось неумным. Ведь под это дело можно задействовать конструктор дымоходов. Надо только приделать к нему сохранение схем. Помимо элегантности, этот подход принесёт ведь и кучку нового функционала. Можно сделать галерею юзерских дизайнов, например.

Все объекты в конструкторе представлены двумя тегами - div и img с общим классом, то есть не сложно вытащить их из DOM, убрать все другие теги и включенные в div/img яваскрипты (других тегов конструктор не использует и яваскриптов не включает, но кулхацкеры-то на выдумки хитры). Вытащить их из базы и внедрить снова в страницу - тоже не проблема... как казалось.

Когда я открыл Хромом схему, сделанную в Фоксе, детали с вращением это вращение потеряли.

При написании конструктора вращение через назначение класса оказалось неудобным. Вместо этого используется плагин jquery.rotate.3. Он назначает повёрнутому элементу один из вариантов CSS transform: transform, -moz-transform, -o-..., -ms-... Естественно, transform: rotate() из схемы, сделанной Фоксом, не работает в Хроме: там нужен -webkit-transform: rotate().

Ну ё-моё.

Дурной путь состоял в том, чтобы в Яваскрипте находить transform регекспом, вытаскивать значение, удалять transform и применять его заново вызовом .rotate() - и я этот путь прошёл. Во-первых, оказалось, что transform:  rotate() в браузере немедленно превращается в matrix(.....), и восстанавливать угол поворота приходится хитрым исчислением со всякими синусами. Это ладно, это полбеды. Беда в том, что это свойство просто оказывается none, если браузер его сразу не понял. Круг замкнулся.

Не может быть всё так безысходно, подумал я, и это было правильно.

Всё решение заключалось в создании у вращаемого объекта одновременно с браузер-специфическим свойством CSS абстрактного атрибута data-rotate="n". При сохранении свойство в любом его варианте на стороне сервера вырезается регекспом:

 /\s(-.*)?transform:\srotate\(.*\);/

При загрузке/внедрении в DOM надо просто сделать:

$('.canvas_element[data-rotation]').each(function(){
      $(this).rotate(parseInt($(this).attr('data-rotation')));
});

Проверка:

  1. Схема, сделанная в Фоксе, правильно открывается Хромом:  http://dymunet.ru/?constructor,load,id=11
  2. Схема, сделанная в Хроме, правильно открывается Фоксом:  http://dymunet.ru/?constructor,load,id=14
Остальные браузеры: надо проверить.

вторник, октября 23, 2012

Прокачал свою типа-CMS: опросы и голосования

Потратил день, чтобы написать для сайта ДКМ комбинированный модуль опросов и голосований, который теперь можно втыкать, где понадобится.

Прототипами послужили опросы, сделанные когда-то для «Вирго», и процедура голосования, сделанная менее чем когда-то (но тоже давно) для «Златы».

Опросы: всё просто, один раз выбираешь вариант, потом видишь результаты.

Голосования: требуется e-mail, для подтверждения переход по ссылке в письме.

Блокируются одноразовые ящики (по опыту «Златы», это один из самых распространённых способов злоупотребить).

У «Златы» всё сделано на PHP. В новом варианте PHP выполняет только абсолютно необходимую серверную работу, многое переложено на Яваскрипт.

Времени ушёл почти день, вдвое больше, чем рассчитывал.

По-хорошему, надо ещё дописать сюда кэширование. Управляемый кэш входит в типа-CMS, то есть напо просто дописать несколько строк тут и там.

понедельник, июля 02, 2012

Оптимистическое правило веб-разработки

Любая проблема решается с помощью jQuery, PHP и SQL, кроме проблемы физической смерти (но, говорят, есть воркэраунды).

понедельник, июня 04, 2012

Лего-трубное глюкало своими руками за день из jQuery и всякой фигни

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

Сам сайт, понятное дело, тоже о дымоходах.

Не имея понятия, как это реализовать (но понимая, что Flash исключается, во-первых, потому что он Зло, а во-вторых, по ряду причин — например, не знаю я его), сел и нарисовал детальки. Смешные.


Рисовал в Inkscape, не заморачиваясь масштабом, но так, чтобы детали стыковались хотя бы. Основных деталей порядка 30.

Дальше стал вникать в jQuery UI, конкретно — примочки draggable и droppable. Это заработало из бокса. Изобрести пришлось только клонирование детали, взятой с палитры. Примеры из интернета не годились.

Больше всего времени ушло на допиливание бульдозера до самолёта.

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

Проверил на четвёрке браузеров, в одном обнаружился косяк. Угадайте, в каком. Ага, хрен там. Опера. Детали частично не прорисовываются при перетаскивании, оставляют призраков. Убрал со страницы анимированный гиф (мало ли?), обновил Оперу до последней. Не-а. Надо ещё попробовать самую последнюю версию jQuery/jQueryUI, а если не стрельнет — считать это багом Оперы. Жалко. IE, и тот осилил задачу.

Поигрался немного, нарисовал схему дымохода на даче, какой он есть, потом — каким он будет, потом — каким я его хотел бы. Ну прикольно же!

понедельник, января 09, 2012

Bitrix: подтверждение теоремы

теорема

Пиша написая занимаясь написанием многострадального сайта под Битриксом, дошёл до точки, когда война с ограничениями системы закончилась моим поражением :-)

Вариантов, как всегда, не меньше двух.

Первый: бросить всё.

Второй: бросить всё остальное и засесть на две недели за изучение внутренностей совершенно не нужной мне системы.

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

Быдло с былдом встретилось, короче, и тут уже не до изяществ.

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

вторник, декабря 27, 2011

мой вклад в законы Мэрфи

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

пятница, декабря 23, 2011

Битрикс: ощущения

Попроникал немного в Битрикс, в нутре ейное.

Главное ощущение: эта система очень похожа на российские законы. Если делать всё как положено, то никогда ничего не сделаешь как надо. Поэтому делай сразу как не надо, но чтобы поменьше последствий.

Попользовался API, поделал кое-какие выборки осторожненько. Главным образом модифицированной копипастой из документации. Попутно постоянно нарываясь на дописки: этот интерфейс оставлен для совместимости. Пользуйтесь новым интерфейсом... и ссылка. Ну йо-майо - и давай переписывать.

Заглянул в базу данных через phpMyADmin, перекрестился и сказал: «Чур меня» :) Каталог товаров, справочные подсказки из стандартной инсталляции, введённые мною записи инфоблоков ― всё хранится в одной таблице. Это, чтобы достать запись об адресе офиса, сервер будет лопатить таблицу, где заодно несколько десятков тысяч записей о товарных позициях? Экхм...

Одновременно начал испытывать и некоторое удовольствие наконец.

Узелок на память: не пользоваться встроенным редактором PHP, бо он сохатит код. Вставляет какие-то нелепые кавычки и отсебятину, которой я отродясь там не писал. Обновившись, страница говорит: пунтакс еррор, баран! :Е Грррррр.

понедельник, декабря 19, 2011

Bitrix: осторожность необходима.

Давненько не писал в блог: некогда было.

Впервые связался с Битриксом.

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

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

print_r($arResult);

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

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

Погуглил: ************** (я не вандал, поэтому звёздочки). Это поле, присутствующее в самой стрёмной части результата.

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

Ребят, ну что же вы творите. Ваши сайты очень часто хостятся на коммерческих площадках. Хостеры очень часто предоставляют phpMyAdmin. Достаточно ведь просто туда прологиниться, чтобы слить ваши данные, или подменить их своими, или продублировать админский аккаунт, или просто вывести сайт из строя.

Аналогично и к разработчикам Битрикса. О таких подлянках надо предупреждать большими красными надписями поперёк всей документации :)

Поиск по этому блогу