← на главную
24 заметки с тегом

КЭНК

Сервис isDayOff для нужд автоматизации

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

Я очень люблю автоматизацию, особенно — автоматический контроль за соблюдением правил и договоренностей в системах. Человеческий фактор невозможно полностью исключить, зато можно заставить дотошных и не устающих роботов контролировать, что человек сделал всё правильно. Однако, здесь кроется одна проблема — человеки, в отличие от роботов, уходят на выходные и государственные праздники. Согласно Первому закону робототехники, робот не может причинить вред человеку или своим бездействием допустить, чтобы человеку был причинён вред. А что может быть противней, чем тикет на исправление некритической проблемы, прилетевший в выходные? Да, можно запрограммировать, чтобы тикеты не прилетали в субботы и воскресенья — но что делать с праздниками и переносами выходных?

isDayOff простой как автомат Калашникова, и легко встраивается в скрипты и пайплайны автоматизации. В простейшем виде через https://isdayoff.ru/today можно узнать, является ли текущий день рабочим, ну а дополнительные параметры к запросу могут дать информацию о любой дате в прошлом и будущем (в разумных пределах) и даже о праздниках в соседних странах (поддерживаются Белоруссия, Казахстан и Украина).

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

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

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

Слава роботам!

 25   3 мес   PowerShell   КЭНК

Забрать своё из облаков: обновление вКачатора

Допилил небольшое, но важное дополнение для скрипта обогащения дампов профиля ВКонтакте. Эксплуатация предыдущей версии выявила существенный недостаток: видео с YouTube, импортированные в ВК, в разных разделах сайта фигурируют с разными ID (и разными URL). Выходит странненькое — по этим разным ссылкам открывается один и тот же объект (страницца) ВК, с теми же комментариями, лайками, и прочими атрибутами соцсети, и конечно же встроенный в объект ролик YouTube там тоже один и тот же, но ссылки на этот объект разные. И например, добавленное на стену видео, и то же видео, посланное в диалоге, будут иметь разные адреса. Поэтому старая версия скачивала, и складывала в папку видео несколько раз, что расходовало лишнее место (а у меня в избранные как-то попала даже девятичасовая прямая трансляция выхода в открытый космос с МКС).

Идеально было бы научить скрипт сразу узнавать такие дубликаты по адресам, и не скачивать повторы вовсе, но как это сделать я придумать не смог. Зато можно скачать через yt-dlp оригинал с ютуба, и по его метаданным распознать дубль, сравнив с метаданными уже скачанных видео. Так и поступил — теперь скрипт сохраняет в простой json информацию по всем уже скачанным файлам, и при закачке дубля не сохраняет его на диск, заменяя ссылки в дампе на уже скачанный экземпляр. На моем дампе это значительно сократило объём выгрузки.

Обновлённая версия уже на гитхабе: https://github.com/alexbatishchev/kenk-vk-enricher

Забрать своё из облаков: kenk-vk-enricher 1.4

Допилил скрипт обогащения дампа Вконтакте. Теперь скрипт качает видео в разделах Видеозаписи, Стена и Сообщения — закачка идет через yt-dlp, перед использованием желательно обновить его до свежей версии, и залогиниться в ВК в одном из бразуеров на машине, тогда yt-dlp сможет использовать куки и больше видео будет доступно для скачивания. Также скачиваются аттачменты типа «файл» на стене и в сообщениях (те, что доступны по прямым ссылкам).

Сейчас актуальной версией скрипта мой личный профиль выкачивается на почти 200 гб, сказываются видео файлы в переписке и на стене — часто репостились интересные чужие видосы, и всё вместе занимает прилично места. Ну да больше-не меньше.

Скрипт на гитхабе: https://github.com/alexbatishchev/kenk-vk-enricher

Слава роботам!

Забрать своё из облаков: важные видео из YouTube — 2

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

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

Во-вторых, всплыла интересная особенность этого вашего СЕО и кликбейт-традиций: авторы на ютубе нередко переименовывают ролики, иногда (как например вДудь) — после добавления субтитров и других изменений, а иногда — просто чтобы новые названия привлекали внимание зрителей и обманывали алгоритмы. Так как в шаблон именования файлов я внёс название ролика, это приводило к тому что часть роликов повторялась несколько раз — а видос с одного канала (крутой по содержанию документальный фильм про советскую мультипликацию, кстати), закачался аж 6 раз, в соответствии с каждым почти ежедневным переименованием.

К счастью, в шаблон имени файла я с самого начала добавил ID ролика, и по ним дубликаты можно легко находить. Добил скрипт закачки несколькими строками, находящими в архиве файлы с одинаковыми ID внутри имён и удаляющие самые старые файлы — и дело в шляпе

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

Машины работают, человек счастлив. Вернусь к вопросу через следующие полгода

Забрать своё из облаков: kenk-vk-enricher

Причесал и опубликовал скрипт, докачивающий в дамп официальной выгрузки из ВКонтакте картинки в переписку (сообщения) и фотоальбомы. Фотки выкачиваются и складываются заодно внутрь дампа в папки с именами, соответствующими оригинальным альбомам, а если они были опубликованы с подписью (как например часто было при параллельной публикации в ИГ) — подпись сохраняется в отдельный текстовой файл рядом.

В дампе переписке все файлы даются прямыми ссылками. А вот в дампе стены картинки прописаны ссылками вида https://vk.com/photoXXXXXXXXX_XXXXXXXXX — но тут был придуман хитрый ход, немного исправляющий ситуацию. Так как среди фотоальбомов есть «Фотографии на моей стене», то если сдампить их и из кода страницы выдернуть и прямые ссылки на файлы, и ссылки photoXXXXXXXXX_XXXXXXXXX (которые там есть), то можно закешировать это соответствие и подставить потом известные картинки в код выгрузки стены. К сожалению, так можно обойти только картинки, и только картинки ваши — репосты от других пользователей или групп так и останутся со ссылками на данные в серверах ВК. Как до них добраться без URL оригинальных файлов непонятно — с парсерами картинок ВК в интернете такая же беда как и с видео. Хотя жаль, стену со своими публикациями хотелось бы содрать в максимально полном виде, включая и репосты.

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

Забавное наблюдение — в дампе стены есть уже удалённые вами сообщения (с пометкой «Запись удалена»). Так приятно что заботливые товарищи всё хранят даже после удаления (евпочя).

КЭНК! Слава роботам!

Ёлочные игрушки: начало

Около полутора лет я плотно использую в работе ELK Stack. Хочу в серии постов рассказать о том, как можно применять Elasticsearch, Logstash, и Kibana для сбора и анализа информации в различных задачах системного администрирования и управления информационной безопасностью на предприятии.

Ложь, наглая ложь и статистика

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

Формулирование таких метрик и понимание их изменения помогает сразу по нескольким фронтам. Во-первых, исполнитель всегда может оценить прогресс и наглядно продемонстрировать руководству что и насколько улучшено (или ухудшено), с актуальными «здесь и сейчас» цифрами. Ура, нет больше ночных бдений «срочно предоставить к утру отчет о том что сделано по этой проблеме»

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

Предположим, внедряется процесс управления учетными записями в AD — настраиваются политики, вычищаются старые или ненужные записи, настраиваются параметры безопасности. Как оценить насколько сегодня ситуация лучше чем была месяц назад? Безопасник нашел и поставил задачу исправить N записей, за это время админы сделали M новых, что в целом по ситуации? Какова её оценка и как она изменилась?

Другой практический пример — управление обновлениями Windows хостов при помощи WSUS. Насколько сегодня уровень покрытия инфраструктуры апдейтами лучше чем два месяца назад? Не стало ли хуже из-за раздолбайства смежных подразделений, или выхода апдейта с ошибками установки? Ситуация в целом исправляется или наоборот, движется в ад?

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

Достаём подарки из-под ёлки

Основная идея этого kenk-велосипеда заключается в том, чтобы регулярно и автоматически собирать (или выгружать) из информационных систем данные, и после этого хранить и анализировать их с помощью ELK Stack.

При этом появляется возможность анализировать состояние систем в исторической перспективе, видеть тренды изменений и контролировать соблюдение заданных ключевых показателей. Кроме того, появляется возможность собирать или генерировать другую информацию, недоступную через штатные средства управления этими системами — потому что перед загрузкой в ELK, данные можно дополнительно обработать, обогатить сведениями из других систем и так далее. Например, можно дополнить статистику из WSUS данными из учетной системы предприятия об ответственных за сервера, и иметь возможность сразу видеть кого нужно пнуть за необновлённый сервер.

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

Картинки и примеры

Приведу пару визуальных примеров. В картинках ниже конкретные цифры (показатели) и временные отметки на скриншотах удалены по причине NDA

Пример 1. Графики изменения во времени на группе хостов метрик «процент обновлённых назначенными патчами машин» и «процент машин, требующих перезагрузки для завершения обновления». Вы никогда не получите эти данные из WSUS, потому что он не хранит историю состояний хостов

Пример 2. График изменения во времени на группе хостов количества установленных экземпляров Chrome разных версий. Здесь красиво видно, как по мере выпуска патчей одна версия Chrome сменяет на группе хостов другую. Вы не получите эти данные, если ваша система учёта ПО на хостах этого не умеет (данные для графика получены из отчетов Kaspersky Security Center)

kenk-дисклеймер

Внимание! Этот подход рожден и работоспособен в условиях, когда у вас есть набор информационных систем, возможности которых недостаточноы для решения озвученных задач. Если ваша система всё это может, и в условиях дивной новой реальности вы можете эту систему купить :), сий велосипед не для вас.

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

 52   9 мес   ELK   Ëлочные игрушки   КЭНК

КЭНК: безопасно храним секреты для скриптов PowerShell

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

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

К счастью, в Windows есть магическая штука на этот случай — Secure Strings — волшебство которых в данном случае заключается в том, что они работают с учетом контекста учетной записи, от которой запущены. Поэтому, если задать пароль ($pw = Read-Host -AsSecureString) прогнать его через ConvertFrom-SecureString ($pw | ConvertFrom-SecureString) и результат записать в файл, то на выходе будет чудесная буквенно-цифровая белиберда. А обратно эту белиберду можно превратить в пароль (Get-Content .\password.txt | ConvertFrom-SecureString), но только вот пароль правильным получится только если это преобразование работает от той же учетной записи, под которой шло прямое кодирование.

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

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

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

Пример кода, иллюстрирующий подход:

Ссылки по теме:

https://www.techtarget.com/searchitoperations/tutorial/How-to-secure-passwords-with-PowerShell
https://www.travisgan.com/2015/06/powershell-password-encryption.html

Слава Роботам! КЭНК!

 63   11 мес   PowerShell   КЭНК

КЭНК: тихое удаление обновления Windows по номеру KB

Задача: тихо удалить с хоста обновление Windows по номеру KB.

Какое-то время проблема легко решалась через wusa.exe /uninstall /kb:XXXXXX /quiet, но теперь в Windows 10 команда с ключом quiet просто игнорируется, а без ключа — задает много вопросов пользователю, что ожидаемо, но не подходит для решения задачи.

В интернетах быстро гуглится способ, который хорош, но не универсален. Способ рассчитывает на то что KB будет упомянута в имени пакета для DISM, а это бывает не всегда — в примере ниже у двух последних обновлений номера KB в имени пакета нет.

Ситуацию усложняет то, что в разных локалях ОС команда dism выдает информацию на разных языках, да к тому же не структурированным объектом — а строкой. К счастью, из строки все же можно выцепить имя пакета, а по нему — запросить подробную информацию (тоже строкой), где номер KB есть (судя по моим тестам) всегда:

Итоговое решение задачи такое:

  • смотрим список всех установленных обновлений и выдергиваем имена пакетов
  • по каждому пакету смотрим расширенное описание и ищем в нём искомый номер KB
  • если в описании найден нужный номер KB — пакет по его имени отправляется на деинсталляцию через DISM.exe /Online /Remove-Package /PackageName:$sFoundPackageName /quiet /norestart

Короткий сниппет, иллюстрирующий подход:

$sKBNumber = "4578968"
$aUpdts = dism /online /get-packages | ? {$_.Contains("Package_for")} | %{($_.Split(":"))[1].Trim()}
foreach ($sUpdate in $aUpdts) {
	$sInfo = (dism /online /get-packageinfo /packagename:$sUpdate) -join(", ")
	if ($sInfo.Contains($sKBNumber)) {
		write-host "Found package $sUpdate for KB number $sKBNumber"
		# uncomment below to uninstall package
		# DISM.exe /Online /Remove-Package /PackageName:$sUpdate /quiet /norestart
	}
}

КЭНК! Слава роботам!

 109   2021   PowerShell   WSUS   КЭНК

КЭНК: выгрузка фото из iCloud на Яндекс диск — 2

В прошлой серии велосипедостроения на тему переноса фоток в Яндекс.Диск была успешно решена проблема выгрузки и переименовывания файлов из iCloud в соответствии с датой. Однако, опыт эксплуатации процедуры показал её недостаток: перенесенные таким образом файлы *.heic Ядиском не располагались по альбомам в соответствии с датой, а сваливались в одну кучу дня импортирования.

Пара вечеров была потрачена на анализ и сравнение *.heic файлов, импортированных яндексом с телефона самостоятельно, и обработанных мной вручную. К сожалению, никакого способа поправить теги даты так, чтобы яндекс их воспринял, не нашлось: изменения внесенные exiftool или гуевыми программами типа XnView или FastStone результата не давали. Я заморочился, сравнил файлы преобразованные яндексом и свои, добился полного совпадения полей в выгрузке exiftool — и всё равно роботы яндекса делать красоту отказывались. Поэтому с *.heic файлами придуман обходной путь — конвертировать их в jpeg (те же теги, пробитые в jpeg, срабатывали отлично)

Заодно кстати выяснилось, что яндексу важны метаданные в поле DateTimeOriginal: файлы с корректно заполненными DateCreated но не заполненными DateTimeOriginal он также датировал неправильно.

Так вот, конвертация из heic в jpeg. Тут мне открылся неведомый мир цветовых профилей и прочих тонкостей. Оказалось что эппле пишет heic со своим чудо-профилем, который мало кто понимает и корректно показывает. Все распространённые свободные конверторы в джипег на выходе дают гораздо более бледные и светлые картинки, при этом встроенный просмотрщик macOS эти файлы показывает в исходном красивом цвете, а вот в других программах и на других платформах случается «ой». Перелопачена уйма форумов, нужное колдунство найдено — нужно не просто конвертировать heic в jpeg, но ещё и заменять цветовой профиль, а также корректировать гамму (значение корректировки я подобрал на глаз более-менее похожим, возможно тут будут нюансы на фотках разных насыщенностей)

Вот что выходит с разными конвертациями и (что важно) при разных программах просмотра:

оригинальный heic в Preview macOS, конверченный ImageMagick jpeg без коррекции цвета в Preview macOS, он же в XnView, jpeg с коррекцией цвета в Preview macOS и в XnView

Хорош рассусоливать, что вышло-то?

Итоговая на текущий момент процедура конвертации такова:

  • перегнать все heic в jpeg при помощи ImageMagick, заменяя цветовой профиль на sRGB.icc и цветовое пространство на sRGB и корректируя гамму, стереть оригиналы
  • пробить во все экспортированные файлы (и в том числе в джипеги, конвертированные из heic) метаданные из *.xmp
  • видосикам пробить FileModifyDate из TrackCreateDate и переименовать
  • там где у картинок DateTimeOriginal задан — переименовать файлы в соответствии с датой
  • там где у картинок DateTimeOriginal не задан — пробить его из DateCreated и переименовать файлы в соответствии с датой

Обработанные таким образом медиаматериалы корректно раскладываются яндекс диском в альбомы по времени и геолокации. Косяки и нюансы

  • не раскладываются по датам PNG (у меня это на 100% скриншоты) — ну да от них участия в генерации памятных сторис и прочей красоты не требуется.
  • heic с Live Photos внутри конвертируются в два файла: картинка с дефолтным кадром и микро-mp4 с полной анимацией. Не парит опять же.

В полном соответствии с методологией КЭНК и принципами Hobby-as-Code процедура собрана в shell скрипт, ознакомиться с которым можно на github (уберите от консоли беременных детей и женщин): https://github.com/alexbatishchev/kenk-yadisk-photomaster

КЭНК!
Слава роботам!

КЭНК: выгрузка фото из iCloud на Яндекс диск

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

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

Сегодняшний рассказ — о сервисе, который достался «забесплатно», но потом перестал работать, и о том как я добился получения привычного результата уже своими силами.

Что случилось и кто виноват

В мире победившей вычислительной фотографии я уже много лет снимаю на телефон и веду архив фото на телефоне. Это удобно, и всё связанное с повседневным фото завязано у меня на экосистему Apple. Однако, было бы глупо полагаться только на одного вендора, да и вручную выдёргивать фото из Apple для резервной копии не самый удобный вариант, поэтому как только Яндекс запустил фичу автоматической синхронизации фотографий на Яндекс.Диск, я сразу же начал ей пользоваться.

Вышло удобно:

  • фотографирую на телефон или планшет, имею синхронизированные фотки на всех личных устройствах и ноуте (на разных платформах приложение называется по разному, буду дальше использовать термин Айклауд как синоним определения «ну где там у эпплов всё лежит и красиво синхронизируется и показывается на всех девайсах»).
  • Сразу после съемки или по напоминанию отмечаю в Айклауде сердечком лучшие фото и удаляю откровенный брак и шлак, на телефоне остаются материалы лучшие и «пусть просто для архива»
  • Всё это время полное зеркало всех фото и видео с телефона автоматически синхронизируется с папкой Фотокамера в Яндекс диске (а она уже в свою очередь бэкапится как надо на NAS)
  • раз в 2-3 месяца провожу чистку:
  1. захожу в айклауд через приложение на ноуте или телефоне,

2. скрываю все избранные (Library — альбом Favourites — ⌘A — hide items),

  1. стираю все оставшиеся нескрытые (и не лайканые) фотки (Library — альбом photos — ⌘A — delete items),
  2. возвращаю все скрытые обратно (Library — альбом Hidden — ⌘A — unhide items)
  • переношу все фотки из папки Фотокамера Яндекс диска в долговременный архив, Яндекс на телефоне сам синхронизируется и обратно заливает в фотокамеру только избранные фотографии

Таким образом я всегда имею две копии актуальных фоток (избранные + недавно сделанные) на яндексе и в айклауде, а также легко регулярно очищаю хранилище на устройствах от ненужных данных, оставляя только лучшие. Также благодаря этому умные алгоритмы Apple и Яндекса генерят мне истории и ролики-воспоминания на основе лучших фото и видео из поездок, с важных событий и тому подобное.

Красиво переименованные и уложенные яндексдиском файлы

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

В принципе, потеря небольшая, просто весь 2020-й Яндекс диск скидывал мне напоминания о событиях 19-го. Тем не менее, это натолкнуло меня на мысль о том, что случись что — у меня есть полный архив всех фото включая самые свежие, но архива лучших нет! На отбор их потрачено время, и теперь сведения этого отбора не защищены от потери.

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

Айклауд (как и Яндекс) красиво показывает в ленте фото по датам и местам, умеет на основе этой метаинформации собирать истории и альбомы. При этом на уровне файлов творится дикая дичь — в зависимости от источника (фото сделано на телефон, сохранено из мессенджера, проявлено в Лайтруме на компе и прислано по почте, это скриншот экрана или сохранёнка с веб страницы), а также от типа файла (разные форматы видео и графики), метаданные о времени съемки, локации и другом хранятся в разных полях по разной логике. И вот выгруженные штатными средствами файлы именуются непонятно как, имеют странные даты съемки (ещё и отображаемые по-разному в зависимости от программы просмотра) — в общем никакой красоты, удобства и единообразия тут нет.

Выгрузка из Айклауда. Ад и мешанина в именах, атрибутах и метаданных файлов. Дата съемки видео якобы неизвестна (но она есть, просто зашита глубоко)

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

Что делать

Проводим НИР, применяем для решения задачи великий и могучий ExifTool. Общая схема такая:

  • экспортируем данные из macOS Photo в оригинальном качестве и с записью дополнительных файлов xmp
  • пробиваем с помощью ExifTool метаданные из xmp в медиафайлы
  • проходимся по файлам набором команд ExifTool с разными параметрами в зависимости от типа файла и сохранённых в нём данных, чтобы переименовать их по дате
  • раскладываем полученные файлы по каталогам дат (для удобства)

Собственно, на понимание того, в каких случаях как может храниться дата съемки, и экспериментальный подбор команд для третьего пункта, и ушло несколько часов этой субботы

Зато теперь есть способ выгрузить лучшие материалы из Айклауда и разложить их красиво с сохранением метаданных, в том числе и положить в Яндекс диск для бэкапа и красивостей. Вторичная выгода — прокачка скилла и овладение инструментом ExifTool и скриптования на bash под macOS, теперь эти ваши экзифы и переименования файлов можем делать с закрытыми глазами и одной левой

Итог

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

# экспортируем фотки из macOS Photo в оригинальном качестве и с записью xmp, открываем терминал в этот каталог

# далее пробиваем параметры из xmp в графические файлы
find . -maxdepth 1  -not -iname "*.xmp" -exec bash -c 'file="{}"; xmpname=${file%.*}.xmp; echo "$xmpname"; echo "$file"; exiftool -tagsfromfile "$xmpname" -xmp "$file" -overwrite_original' \;

# пробиваем атрибуты и переименовываем файлы по дате в зависимости от типа и содержимого

exiftool '-FileModifyDate<TrackCreateDate' '-FileName<TrackCreateDate' -d "%Y-%m-%d %H-%M-%S.%%f.%%e" *.mov -directory=out
exiftool '-FileModifyDate<TrackCreateDate' '-FileName<TrackCreateDate' -d "%Y-%m-%d %H-%M-%S.%%f.%%e" *.mp4 -directory=out

exiftool -v '-Filename<${datetimeoriginal}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.jpg -directory=out -if '($datetimeoriginal and (not ($datetimeoriginal eq "0000:00:00 00:00:00"))) and ($filetype eq "JPEG")' 
exiftool -v '-Filename<${datetimeoriginal}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.jpeg -directory=out -if '($datetimeoriginal and (not ($datetimeoriginal eq "0000:00:00 00:00:00"))) and ($filetype eq "JPEG")' 
exiftool -v '-Filename<${DateCreated}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.jpeg -directory=out -if '($DateCreated and (not ($DateCreated eq "0000:00:00 00:00:00"))) and ($filetype eq "JPEG")'
exiftool -v '-Filename<${DateCreated}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.jpg -directory=out -if '($DateCreated and (not ($DateCreated eq "0000:00:00 00:00:00"))) and ($filetype eq "JPEG")'


exiftool -v '-Filename<${datetimeoriginal}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.heic -directory=out -if '($datetimeoriginal and (not ($datetimeoriginal eq "0000:00:00 00:00:00")))'

exiftool -v '-Filename<${datetimeoriginal}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.png -directory=out -if '($datetimeoriginal and (not ($datetimeoriginal eq "0000:00:00 00:00:00")))'
exiftool -v '-Filename<${DateCreated}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.png -directory=out -if '($DateCreated and (not ($DateCreated eq "0000:00:00 00:00:00")))'

exiftool -v '-Filename<${datetimeoriginal}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.gif -directory=out -if '($datetimeoriginal and (not ($datetimeoriginal eq "0000:00:00 00:00:00"))) and ($filetype eq "GIF")' 
exiftool -v '-Filename<${DateCreated}.%f.%e' -d "%Y-%m-%d %H-%M-%S" *.gif -directory=out -if '($DateCreated and (not ($DateCreated eq "0000:00:00 00:00:00"))) and ($filetype eq "GIF")'

# Чистим xmp
rm -f ./*.xmp

# перекладываем файлы в папки YYYY/YYYY-MM/
cd out
find . -maxdepth 1  -type f -exec bash -c 'file=$(basename "{}"); yearname=${file:0:4}; monthname=${file:5:2}; pathname="$yearname/$yearname-$monthname"; mkdir -p "$pathname"; echo "$pathname"; mv "$file" "$pathname"/ ' \;

Полезные ссылки по теме

КЭНК!
Слава роботам!

 1436   2020   Linux   КЭНК   Яндекс.Диск
Ранее Ctrl + ↓