Позднее Ctrl + ↑

Передача большого количества картинок между серверами

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

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

Какой есть выход из этой ситуации? Верно, создать архив без сжатия:

Вот так, если предпочитаете tar:

tar -cf ./archive.tar /path/to/folder

И так, если больше нравится zip:

zip -qq -0 -r ./archive.zip /path/to/folder

Но как показывают замеры времени, tar справляется с задачей простой сборки файлов в один в разы быстрее.

После передачи файла по сети распаковать его можно так:

Для tar архива:

tar -xf ./archive.tar

И для zip архива:

unzip -qq ./archive.zip

Обрабатываем некорректно сохраненные в лог JSON данные

С месяц назад, при записи JSON данных в лог, забыл отформатировать их json.dumps из питоновского dict’a в нормальный вид, а просто записал его при форматной печатью, преобразовав dict в str. Само собой, получил кучу данных в неудобоваримом виде, эх.

Как исправить? Стандартный json.loads теперь не воспримет такую строку как корректный JSON, т. к. с точки зрения формата она не валидна. Можно решить эту проблему при помощи функции ast.literal_eval.

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

Пример работы:


import ast
import json

# Наш преобразованный в строку dict()
s = "{'a': 'Text with \\'quotes\\''}"
j = json.loads(s)
# Получаем ошибку парсинга из-за одинарных кавычек
>> json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

# Парсим строку в dict
j = ast.literal_eval(s)
print(j)
>> {'a': "Text with 'quotes'"}
# Теперь уже дампим данные корректно
print(json.dumps(j))
>>{"a": "Text with 'quotes'"}

Слив данных ИПшников в ВТБ?

Знакомые часто говорят, что налоговая, якобы, «сливает» данные новых ИПшников, т. к. им сразу же после регистрации начинают обрывать телефон банки, предлагая подключить у них услугу РКО. Я вот, несколько лет назад, вообще узнал об успешности регистрации своего ИП не из налоговой, а от колл-центра Тинькова, хехе.

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

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

BCO плагин для ВТБ Бизнес Онлайн на macOS Catalina

Вляпался вот в BCO System Cryptographic Plugin на macOS Catalina, в процессе подключения к РКО ВТБ. Оценки и комментарии к этому плагину сразу внушили уважение и обещали приятный вечер, полный изысканных речевых оборотов.

Без этого ПО у вас не получится создать себе ключ доступа для пользователя ВТБ Бизнес Онлайн, а значит и не даст завершить процедуру открытия расчетного счета.

После установки плагина, важно перезапускать браузер иначе не заработает вообще ничего. Инструкция по установке говорит, что плагин на macOS может работать в Safari и Chrome. Но, по факту, в Safari 13 он вообще не завелся, как я не старался, видел надпись «Unsupported Plug-in». В Chrome 87 сам плагин завелся, но отказалась работать криптографическая часть, то бишь, не генерировались ключи доступа.

Решение оказалось довольно простым: надо следовать инструкции дословно. Во время установки предложенного на сайте pkg файла, нужно выбирать опцию «Установить только для меня».

Если установить для всех, как сделал я (ачотакова, да?), то ничего работать не будет. По какой причине — не ясно.

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

P.S. А публичную часть созданного ключа, вам придется распечатать на бумажке в двух экземплярах и отнести ногами в офис...

Шпаргалка по формам/алгоритмам нормализации Unicode текста

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

Всего есть четыре таких алгоритма: NFD, NFC, NFKD, NFKC. Каждый в отдельности можно запускать на одной и той же строке много раз, и результат от этого никак не изменится. То есть они идемпотентны.

Работать с Unicode текстом будем при помощи страндартной Python библиотеки unicodedata.

1. NFD (Normalization Form Canonical Decomposition) или форма нормализации D.

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

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

for c in unicodedata.normalize("NFD", "ё"):
    print("'%s': %s" % (c, unicodedata.name(c)))

>> 'е': CYRILLIC SMALL LETTER IE
>> '̈': COMBINING DIAERESIS

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

2. NFC (Normalization Form Canonical Composition) или форма нормализации C.

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

for c in unicodedata.normalize("NFC", "ё"):
    print("'%s': %s" % (c, unicodedata.name(c)))

>> 'ё': CYRILLIC SMALL LETTER IO

Так можно быстро «приклеить» всю диакритику к буквам и получить из двух символов CYRILLIC SMALL LETTER IE и COMBINING DIAERESIS один CYRILLIC SMALL LETTER IO.

3. NFKD (Normalization Form Compatibility Decomposition) или форма нормализации KD.

Алгоритм, который выполняет NFD декомпозицию и заменяет похожие символы совместимыми аналогами, например, дробь ’¼’ заменяется на строку символов «1/4».

s = '⑲ ⁹ ¼'
print(unicodedata.normalize("NFKD", s))

>> 1 19 9 1/4

for c in list(s):
    print("'%s': %s - '%s'" % (c, unicodedata.name(c), unicodedata.normalize("NFKD", c)))

>> '⑲': CIRCLED NUMBER NINETEEN - '19'
>> ' ': SPACE - ' '
>> '⁹': SUPERSCRIPT NINE - '9'
>> ' ': SPACE - ' '
>> '¼': VULGAR FRACTION ONE QUARTER - '1⁄4'

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

4. NFKC (Normalization Form Compatibility Composition) или форма нормализации KC.

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

Проблемы NFKD и NFKC

При всем удобстве алгоритмов NFKD и NFKC, они не приводят некоторую часть визуально похожих символов к совместимым аналогам. Например, группу Negative Circled Number * из блока Enclosed Alphanumerics вполне можно привести к числам, но этого не происходит:

unicodedata.normalize("NFKC", "⓫ ⓯")

>> '⓫ ⓯'

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

Ранее Ctrl + ↓