Заметки
Внешний вид Фастаймера
Завернул отрисовку Фастаймера через выноски: это механика Obsidian, позволяющая превращать обычную цитату в оформленный блок текста, привлекающий внимание читателя. Вы наверняка видели блоки в духе «совет» и «обрати внимание» — вот это и есть выноски.
Подробнее можно прочитать в справке Obsidian.
В общем, теперь таймер принимает разный цвет в зависимости от состояния (активный интервал — голубой, успех — зеленый, провал — красный). Кроме того, я немного уплотнил текст и отточил формулировки:
Получилось компактнее и симпатичнее простого блока текста, который я использовал до этого.
2024-03-09 17:44:32 Obsidian TypeScript
Маленькие радости
Скучаю в очереди на кассу супермаркета: вечер, покупателей уже не очень много, но пожилая кассирша явно устала и не слишком торопится. Стоящий впереди высокий, седой мужчина с роскошной бородой коротает время, изучая стойку с шоколадками рядом с кассой.
Наконец, берет «Сникерс», задумчиво крутит его в руках. Пододвигает себе ещё два и широко, с видимым удовольствием улыбается в усы :)
2024-03-06 21:22:43 тем временем Грузия
Не только лишь все
Завидной глубины комментарий из документации к методу WriteJSON() XDTOSerializer'а:
Ну да, метод дампит данные в JSON, а не в XML. Так что поспорить сложно, не все типы данных можно упаковать в XML с его помощью (если быть точным — никакие). Если бы дальше не пошла очевидная копипаста из справки к WriteXML() — счёл бы пасхалкой от разработчиков :)
2024-02-25 22:49:48 1С
Фастаймер для Обсидиана
Разработчики Obsidian на днях заапрувили один из моих пет-плагинов на TypeScript — Фастаймер, трекер интервального голодания. Он добавляет в хранилище новый блок кода: вводишь в него дату начала окна голодания и получаешь дату завершения, время до этого момента и раскладку по зонам, которые предстоит пройти.
Блок показывает актуальную картину каждый раз, когда Obsidian его отрисовывает — то есть, можно следить за своим прогрессом в реальном времени. Когда окно голодания закончится, можно ввести дату завершения и блок покажет результат: получилось ли выполнить цель, сколько времени сверх плана вы голодали и так далее.
Думаю немного доработать визуальную часть (сейчас всё выводится текстом без какого-либо оформления). А ещё — прикрутить функции расчета статистики, чтобы можно было на ходу рисовать красивые графики в духе Charts и показывать ачивки. У меня была эта механика в реализации этого же приложения на Python, но я вряд ли к ней вернусь — в хранилище Obsidian эту задачу решать проще, чем раскатывать на компьютер дополнительную утилиту.
Короче, зацените плагин! :) В библиотеке Обсидиана его можно найти по имени (Fastimer). Или, при желании, установить вручную из репозитория.
2024-02-13 01:08:58 готово TypeScript Obsidian
Do? Do Not?
На одном из проектов у нас есть две общающиеся друг с другом системы: ERP и CRM. Обмен данными сделан по-взрослому: поднят push'n'pull сервер, прописаны подписки на события, подняты REST API и много другой интересной технической обвязки, но я сейчас не про неё.
Среди прочей логики, там так: если в CRM появляется новый контрагент — его данные отправляются в ERP. На днях с этим возникла проблема: один из контрагентов не отправлялся из CRM ну вот вообще никак, сколько его не записывай. Полезли разбираться, подозревая худшее: CRM написана на PHP (ничего личного, просто это не наш технический стек) и там много разного легаси. Выстрелить себе в ногу проще, чем высморкаться.
Однако особенно долго копаться не понадобилось. Открыли страницу контрагента в CRM и увидели, что у него стоит галка «Do Not Export To ERP», которая, собственно, блокирует отправку. Короче, очевидная ошибка какого-то менеджера.
Убираем галку, закрываем тикет?
Это решит проблему с этим конкретным контрагентом, но не причину, по которой она возникла. А она в интерфейсе, конкретно — в названии опции: используется «do not», которого желательно избегать из-за того, что пользователям сложнее правильно считать формулировку. К простому «do» это, кстати, тоже относится.
Программистам часто непросто понять, почему так: мы привыкли мгновенно рассчитывать в уме булевые выражения и вариации в духе «не (не истина)» для нас — обычное дело. А вот люди с другим бэкграундом могут путаться. Совсем чуточку, но иногда и этого достаточно, чтобы в горячке дня воспринять «do not export» как «do export», ткнуть опцию и побежать дальше.
Отсюда выводим правильное решение: переименовать галку. Подойдёт «Disable Export» или «Stop Export». В голову ещё приходит «Prohibit Export», но это скорее про межличностные отношения и вообще, запрет что-то делать не означает, что это что-то не будет сделано :)
2024-01-14 22:25:45 работа английский
Последний мет
Роюсь в коде внешней компоненты 1С, опубликованный разработчиками платформы как пример у себя на сайте. Из хорошего: ну, она компилируется и, если немного допилить — действительно работает.
В остальном хватает bruh moments: например, проект не открывается в современной Visual Studio (нужно указывать CMake вручную). Код довольно небрежный, документации нет, комментариев и оформления по большому счёту тоже. Разработчику без опыта в С++ может быть непросто вкатиться.
Позабавил нейминг:
long CAddInNative::FindMethod(const WCHAR_T* wsMethodName)
{
long plMethodNum = -1;
wchar_t* name = 0;
::convFromShortWchar(&name, wsMethodName);
plMethodNum = findName(g_MethodNames, name, eMethLast);
if (plMethodNum == -1)
plMethodNum = findName(g_MethodNamesRu, name, eMethLast);
delete[] name;
return plMethodNum;
}
Со строк выше на нас смотрит необъяснимая любовь автора кода к сокращениям: вот что ему мешало назвать переменную "eMethodLast", а не "eMethLast"? В конце концов, у нас уже есть "wsMethodName" и "plMethodNum".
Возможно, это такая пасхалка с отсылкой на Breaking Bad. Тогда, конечно, уверенный лайк :)
2023-12-17 19:34:42 1С
Пропущенный съезд
Вы когда-нибудь пропускали свой съезд с шоссе? Нужно всего лишь доехать до следующего, чтобы развернуться, но каждый дюйм дороги вызывает отвращение, потому что ты удаляешься от цели.
― Энди Вейер, «Марсианин»
У программистов бывают ровно те же эмоции, когда они долго пилят какую-то систему и внезапно осознают, что один из её компонентов стоит задизайнить иначе. В этот момент рождается технический долг: понимаешь, что именно так и придется поступить, так как это разом закроет несколько проблем.
Однако прямо сейчас, в моменте, не меняется ничего: ты продолжаешь пилить код вокруг того компонента, что есть. Ведь у тебя есть сроки на разработку, и ты профессионал! Нужно всего лишь выпустить релиз, чтобы вернуться к техдолгу, но каждый дюйм написанного кода вызывает отвращение, потому что ты удаляешься от цели.
2023-11-14 09:34:10 код с запашком
Бытовой героизм
Поднимал какое-то время назад Swagger для внутренней API-шки. Пока возился — стало понятно, что часть функционала в документацию включать не нужно. Поискал способ, как это сделать без костылей — наткнулся на забавный вопрос на GitHub'е.
Чем забавный? Ну, невольно вспомнил про Мисту. В среде 1С-разработчиков это синоним слова "токсичность": мол, спросишь там что-нибудь — получишь ушат помоев за шиворот вместо ответа. Здесь, конечно, не так всё запущено, но ребята, с завидным упорством ссылающиеся на 14-и страничный мануал, здорово рассмешили.
Одно радует: к концу треда всё же нашёлся отважный повстанец, который просто взял и запостил нужный параметр для декоратора.
Не все герои носят плащи, ей-богу.
Румынская фича
Делаю для нашего клиентского портала функцию восстановления пароля через SMS. Добрался до документации Twilio о поддержке буквенно-цифрового ID отправителя в разных странах; эта фича позволяет отправлять сообщения так, чтобы получатель видел не номер отправителя, а что-то осмысленное (название компании, например).
При этом фича везде зарегулирована по-своему: где-то просто работает, где-то нужна регистрация.
Читаю:
🤔
- Португалия: да
- Пуэрто-Рико: нет
- Катар: да (с регистрацией)
- Реюньон: да
- Румыния: да (с регистрацией) (но бойтесь Дракулы)
Не знаю, как ещё объяснить это кладбище.
UPD: Нашёл разгадку. Могильные кресты означают, что за регистрацию нужно заплатить 700 баксов.
Объяснение про Дракулу мне нравилось больше.
2023-08-30 01:02:24 тем временем работа
Новый Фастаймер
Выпустил новую версию своего консольного таймера для интервального голодания. Сам таймер я написал где-то год назад, когда меня в очередной раз расстроило приложение Zero для Android: в нём не работала какая-то совсем примитивная функция вроде просмотра конкретного интервала.
Основное отличие 1.3.1 от 1.2.3 — выпилил к черту консольное меню в пользу старых-добрых аргументов и опций. Концепция меню выглядит удобной, пока фич у приложения мало, но как только их число растёт — необходимость протыкивать каждое действие начинает напрягать.
Таков путь
Немного экзистенциальной безысходности от СП (на случай, если вам её почему-то не хватало):
Это справка для метода УдалитьСообщения() менеджера канала сервиса интеграции. Если серьёзно, я понимаю, что тут имеется в виду: дело в том, что все методы сервисов интеграции швыряются исключениями, если их вызвать в сеансе со включенными разделителями. Авторы документации педантично сообщают об этом в справке по любому из них, так что здесь, видимо, просто почему-то кусок отвалился. В английской документации к этому методу, например, всё нормально.
Но все равно, забавно смотрится. Напомнило старый мем:
2023-07-17 00:46:01 1С
Реостат для запросов
Забыл написать: пару месяцев назад выложил на GitHub пример кода, ограничивающего количество запросов в секунду, которое может быть отправлено к какому-то стороннему ресурсу из информационной базы 1С:Предприятия.
Задача решена через константу, которая хранит дату текущей секунды и количество запросов, которые уже были отправлены. Клиенты, которые утыкаются в ограничение — ждут. Очередь не гарантируется, но плюс-минус соблюдается.
Может пригодиться для управления нагрузкой на внешнюю систему. Например, облачный Битрикс24 прямо требует не отправлять ему запросы чаще, чем два раза в секунду, и за превышение выдает бан.
Ду ю спик инглиш?
Диалог входа в хранилище конфигурации актуальной версии платформы (8.3.22.1923, если быть точным), запущенной с английским интерфейсом:
Слышал, что развитие Конфигуратора остановилось во многом из-за чудовищного количества технического долга, тормозящего любые новые фичи. Но тут интерфейс поехал прямо на одном из первых окон приложения! Любопытно, как это пролезло через тесты.
Может, их и вовсе нет.
2023-05-14 10:15:16 1С
Опочтовиться
Пополнял словарь в попытках описать англоговорящему приятелю свои последние приключения и вычитал про красочную идиому «to go postal». Означает что-то вроде «рехнуться от злости»; появилась где-то между 80-и и 90-и годами в Штатах после серии довольно безумных инцидентов, в которых работники почты ехали крышей и нападали на всех подряд, включая коллег и посетителей.
В общем, выражение на первый взгляд звучит забавно, но уж больно мрачная история за кулисами. Думаю, продолжу применять старое-доброе «to go ballistic». Буквально «разозлиться так, что стать похожим на ракету, потерявшей управление», «взорваться от гнева».
В русском языке, кстати, есть похожие «ракетные» коннотации, но они почему-то про более управляемую или полезную, что ли, историю. Типа, пожар в заднице был настолько силён, что бедняга покинул Землю и успешно приземлился на Марсе (а не просто взорвался) :-)
2023-05-08 09:12:34 английский
Пауза()
Важная особенность: метод ВызватьПаузу недоступен в клиент-серверном вызове; при вызове с клиента серверного метода, в котором вызывается ВызватьПаузу, будет сгенерировано исключение «Нельзя вызвать метод ВызватьПаузу в клиент-серверном вызове».
Странное ограничение, если честно. С одной стороны, адекватный разработчик и так не будет в клиент-серверном вызове делать искусственную паузу, с другой — кому чешется, всё равно её там сделает (через проверку времени в цикле, например). Стоило ради security by obscurity огород городить?
В лучшем случае какой-нибудь джун схватит это исключение, подумает "похоже, я что-то не так делаю" и двинется в правильном направлении. Однако закладывать в платформу ограничение ради этого кейса — как из пушки по воробьям палить. Давайте ещё лимит по количеству прикрутим — мол, не больше 1000 пауз на сеанс, а то вдруг пользователи подумают, что программа работает слишком медленно :-)
2023-04-30 14:30:43 1С
Сделай это педантично
Ежедневная пальма первенства в номинации «самый философский код» уходит автору этого элегантного способа проверить, что две булевые переменные не равны друг другу:
If DataStructure.Property("AmountVATIn")
And ((DataStructure.AmountVATIn And NOT SearchPriceIncludesVAT)
OR (NOT DataStructure.AmountVATIn And SearchPriceIncludesVAT)) Then
Price = RecalculateAmountOnVATFlagsChange(Price, DataStructure.AmountVATIn, TabSectionLine.VATRate);
EndIf;
Думаю дописать сюда что-нибудь вроде «And Not (DataStructure.AmountVATIn = SearchPriceIncludesVAT)», чтобы придать происходящему тонкую нотку безумия.
2023-03-21 20:26:43 1С работа код с запашком
Повествование через окружение
Люблю замечать в окружающем мире штуки, за которыми явно стоит какая-то история. В видеоиграх это называют "повествованием через окружение": напрямую тебе историю не рассказывают, но если посмотреть по сторонам — можно догадаться, какое ружье висело на стенке и кто из него пальнул.
Например, недавно отмечал с коллегами десятилетие компании в местном гольф-клубе. Шары нужно было отправлять в полет со второго этажа; перил там по понятным причинам нет, но натянута сетка на случай, если кто-то потеряет равновесие.
Рядом висят предупреждения: прыгнете в сетку своим хотением — заплатите десять тысяч дирхам. Запишете этот прыжок веры на камеру — готовьте ещё пять тысяч.
Чувствуется история за кулисами, да?
Или, скажем, летал как-то в Турцию отдыхать и решил на всякий случай полистать правила авиакомпании (что можно брать на борт, чего нельзя). Среди списка запрещенных к проносу на борт предметов нашёл пункты «стальное копье» и «стальной кистень» 😬
UPD: Ещё один отличный пример откуда-то из сети.
2023-03-19 15:51:48 тем временем работа
Помедленнее, я записываю
Обычно при разработке исходишь из простой формулы: чем быстрее работает — тем лучше. Например, чем больше запросов приложение успеет выполнить за единицу времени — тем быстрее решится задача, ради которой эти запросы нужны.
Однако бывает наоборот: нужно снизить количество операций, которые программа способна выполнить. Допустим, мы дергаем внешний сервис и он банит, если делать это слишком часто. Пример — облако Битрикс24, которое требует отправлять не больше двух запросов в секунду.
Вот реализация такой замедлялки, которую я написал на прошлой неделе. Поддержки очередности в ней нет; основная решенная задача — выполнить как можно больше запросов, не выходя за лимит (с учётом того, что запросы могут делаться из разных сеансов).
REST-сервис для Service Manager
На этой неделе написал REST-сервис для настройки к нашему сервис-менеджеру (это такая конфигурация для управления инстансом 1cFresh). Развернуть контур разработки у нас — задача регулярная, и базу менеджера каждый раз приходилось тюнить руками: подкручивать витрину, менять адреса приложений, перезаписывать регламентные задания и так далее.
Реализация была проста. Придумай структуру JSON, напиши парсер, найди подходящий код в конфигурации, обеспечь его вызов извне и убедись, что ничего не сломал. Рутинная работа, в общем-то, но я люблю время от времени делать такие штуки: смотреть вокруг и пытаться сообразить, какая из ежедневных задач раздражает достаточно сильно.
Эта — хороший пример. Настройка сервис-менеджера не была проблемой (запустить приложение и покрутить настройки), но о ней нужно было думать и её нужно было делать. А теперь — нет:
- Есть JSON-файл со всеми настройками;
- Есть REST-сервис для его обработки;
- Есть скрипт, который засунет первый во второй;
- Есть пайплайн, который сделает всё это сам.
Короче, ботинок тёр ногу, а теперь перестал. Йаху!
Карьерные самосвалы
Коллега проворчал, что если продолжать эту логическую цепочку, то конфигуратор будет «Жигулями», а EDT — «Кама1» (это такой электрокар, который много лет пилят где-то в недрах КАМАЗа и всё никак не могут собраться с силами и, наконец, допилить).
Ну а я стараюсь смотреть на вещи с оптимизмом. Думаю, платформа и её IDE — это такие карьерные самосвалы. Никто в здравом уме на них по домашним делам не катает, но на разрезе эти звери незаменимы!
2023-02-20 09:00:00 1С
Ранее Ctrl + ↓