Стек для реестра отечественного ПО
Рекомендованный технологический стек для включения вашего софта в реестр отечественного ПО:
Telegram: @aagasiev
Рекомендованный технологический стек для включения вашего софта в реестр отечественного ПО:
Ура, в release notes к go 1.21:
The new functions min and max compute the smallest (or largest, for max) value of a fixed number of given arguments.
Хвала богам, не прошло и 10 лет, как в Go завезли такие нужные функции — min и max.
Потребовалось сейчас сделать быструю проверку того, что тип скачиваемого программой файла — картинка в формате webp, а если это не она, то не качать ее вовсе, ну или хотя бы не полностью.
Самый быстрый способ — сделать HEAD запрос и проверить content-type, например, с помощью питоновской библиотеки mimetypes:
import requests
import mimetypes
r = requests.head("https://.../image.webp")
file_ext = mimetypes.guess_extension(r.headers.get("content-type"), strict=False)
if file_ext == "webp":
pass
Можно ли точно полагаться на ответ сервера? В целом, нет, ведь даже если этот заголовок с виду корректен, то в тело ответа сервер может запихнуть что угодно. Однако, можно отсеивать очевидно ненужные варианты типа text/plain или чего-то подобного.
А еще бывает так, что нужный файл отдается с не тем типом контента. Например, в моем случае нужное хранилище AWS S3 грешило тем, что отдавало файл картинки с заголовком binary/octet-stream.
А еще HEAD запрос может не поддерживаться веб-сервером.
И что делать-то? Будем использовать обертку над libmagic, библиотеку python-magic. Она позволит нам по небольшому чанку данных узнать mime тип получаемого контента.
import os
import magic
import requests
import mimetypes
local_filename = "/local/file/name.webp"
r = requests.get("https://.../image.webp", stream=True)
f = open(local_filename, "wb")
for chunk in r.iter_content(1024):
mime = magic.from_buffer(chunk, mime=True)
file_ext = mimetypes.guess_extension(mime, strict=False)
if new_file_ext != "webp":
f.close()
os.remove(local_filename)
break
f.write(chunk)
else:
f.close()
# Тут уже что-то можем делать с полученным файлом.
Вроде, выглядит норм. Ну, еще обработку ошибок добавить бы не помешало, да.
Но вот с точки зрения работы с сетью есть некоторые сомнения, что в случае вызова break, requests реально считает только 1 кб данных. Беглое гугление скорее усугубило мои сомнения. Надо иметь это в виду и как-нибудь на досуге реально протестировать.
В общем, все.
P.S. Если mimetypes не смогла определить расширение файла webp по типу контента image/webp, то его стоит добавить вручную в один из файлов mime.types вашей системы. Например, для Ubuntu это файл /etc/mime.types, в который надо добавить строку:
image/webp webp
Другие файлики, откуда mimetypes может загружать себе данные, прописаны в самой библиотеке в массиве knownfiles:
knownfiles = [
"/etc/mime.types",
"/etc/httpd/mime.types", # Mac OS X
"/etc/httpd/conf/mime.types", # Apache
"/etc/apache/mime.types", # Apache 1
"/etc/apache2/mime.types", # Apache 2
"/usr/local/etc/httpd/conf/mime.types",
"/usr/local/lib/netscape/mime.types",
"/usr/local/etc/httpd/conf/mime.types", # Apache 1.2
"/usr/local/etc/mime.types", # Apache 1.3
]
Оказывается, единственная работающая WebP энкодер библиотека go-webp не умеет писать в bytes.Buffer через bufio.NewWriter() картинки маленького размера.
То есть, у меня кропы пользовательских аватарок разрешением меньше 200х200 пикселей стабильно получались весом в ноль байт. Это разрешение может немного меняться, в зависимости от картинки.
Однако, происходит это только в Lossy энкодере, Lossless работает нормально. Но кому он нужен, с его гигантскими файлами.
Выход, внезапно, прост и банален: делать надо 1 в 1 как в официальном примере, то бишь, писать все сразу в файл. Тогда картинка получится нормального размера и все будет хорошо.
Почему так происходит разбираться, если честно, лень. Если кто-то докопается до истины, отпишитесь пожалуйста.
Забавный факт, который мало кто учитывает при написании кода регистрации юзеров: точки в почтовом адресе Gmail не имеют значения.
То есть, с точки зрения гуглопочты, эти адреса равны между собой:
Этим хаком часто пользуются спамеры, которые могут зарегистрировать на одну почту кучу аккаунтов и атаковать с них ваш сервис.
Так что, для внутреннего поиска/индексации все точки в gmail.com адресах лучше удалить. Главное, самому пользователю показывать почту в том виде, в котором он ее ввел, а то испугается и побежит в саппорт.