[{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/tags/automation/","section":"Tags","summary":"","title":"Automation","type":"tags"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/categories/bash/","section":"Categories","summary":"","title":"Bash","type":"categories"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/tags/bash/","section":"Tags","summary":"","title":"Bash","type":"tags"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/tags/dpi/","section":"Tags","summary":"","title":"Dpi","type":"tags"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/tags/dpich/","section":"Tags","summary":"","title":"Dpich","type":"tags"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/categories/monitoring/","section":"Categories","summary":"","title":"Monitoring","type":"categories"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/tags/monitoring/","section":"Tags","summary":"","title":"Monitoring","type":"tags"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/categories/network/","section":"Categories","summary":"","title":"Network","type":"categories"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/categories/self-hosted/","section":"Categories","summary":"","title":"Self-Hosted","type":"categories"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/tags/ssh/","section":"Tags","summary":"","title":"Ssh","type":"tags"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"8 сентября 2026","externalUrl":null,"permalink":"/","section":"Tatarinov","summary":"","title":"Tatarinov","type":"page"},{"content":" dpich — это утилита из проекта dpi-checkers, которая запускает набор чекеров для анализа фильтрации трафика: определение IP и геолокации, проверку CIDR-шатдаунов, эвристику умных машинок (инжекты RST, сбросы TLS, подмены ответов) и диагностику DNS (спуфинг, leak, перехват DoH).\nПолучился checkdpi — один bash-файл, который сам подключается к серверам, проверяет, что там всё готово, запускает dpich --all и присылает отчёт обратно.\nЧто он делает # Скрипт работает с пулом удалённых серверов по SSH. Для каждого сервера он делает так:\nпроверяет, что SSH доступен; проверяет свободное место; смотрит, установлен ли dpich, и если нет — предлагает установить с официального репозитория; сверяет локальный и удалённый конфиг по версии или по md5, и если отличается — заливает новый; удаляет старые отчёты на сервере перед запуском; запускает dpich, ждёт завершения, скачивает результат и проверяет, что YAML валиден. Структура проекта # Всё кладите в одну папку:\ncheckdpi/ ├── checkdpi.sh # основной скрипт ├── config.example.yml # шаблон конфига для dpich └── dpi-ch-result_*.yaml # актуальные отчёты (по одному на сервер, будут после запуска скрипта) Шаблон конфига уже настроен на автоматический режим — auto-exit: true, формат YAML, вывод в /root/.local/dpi-ch/dpi-ch-result_.\nСерверы # Скрипт опрашивает список серверов, заданный в переменной DEFAULT_SERVERS в начале файла. Имена соответствуют алиасам из ~/.ssh/config:\nDEFAULT_SERVERS=(\u0026#34;thor\u0026#34; \u0026#34;loki\u0026#34; \u0026#34;wanda\u0026#34;) Список меняется прямо в скрипте или переопределяется через аргументы.\nЗапуск # По умолчанию — последовательно, интерактивно, с отображением TUI:\n./checkdpi.sh Параллельно — все серверы одновременно, быстрее:\n./checkdpi.sh -p Можно указать конкретные серверы:\n./checkdpi.sh -p thor wanda loki hulk В параллельном режиме каждый сервер запускается в фоне через script, чтобы обойти требование TTY, а логи пишутся во временные файлы /tmp/checkdpi_\u0026lt;server\u0026gt;.log. Если что-то падает, в конце выводится последний кусок лога.\nПредварительные проверки в скрипте # Перед запуском чекеров скрипт делает пять вещей:\nSSH connectivity. ssh -o BatchMode=yes -o ConnectTimeout=5 server \u0026quot;true\u0026quot;. Если не проходит — сервер исключается из запуска, и потом не надо отвлекаться на час.\nДисковое место. df -m в каталоге установки. Менее 100 МБ — пропуск.\ndpich. Проверяет, что бинарник есть в /root/.local/dpi-ch/dpich или в $PATH. Если нет — спрашивает, ставить ли, и запускает официальный скрипт установки.\nКонфиг. Скрипт читает версию из комментария # version: в локальном config.example.yml и сравнивает с удалённым. Если версии нет — fallback на md5sum. При несовпадении конфиг перезаливается через scp.\nПри этом если на сервере вообще нет конфига — скрипт сам заливает шаблон. Дополнительных ручных действий не требуется: достаточно положить config.example.yml в папку checkdpi/ локально, и скрипт скопирует его на все серверы при первом запуске.\nОчистка. Удаляет старые отчёты на сервере, чтобы не было путаницы.\nСинхронизация конфига # В начале config.example.yml есть строка:\n# version: 1.0 Если менять конфиг и увеличивать версию, при следующем запуске скрипт сам подтянет изменения на все серверы. Это удобно, когда меняются таймауты, добавляются хосты для проверки или меняются фингерпринты.\nЕсли версионности нет — скрипт сравнивает md5 локального и удалённого файла. Если различаются — обновляет.\nОтчёты # После запуска отчёт скачивается локально с именем вида:\ndpi-ch-result_\u0026lt;server\u0026gt;_\u0026lt;дата\u0026gt;.yaml Скрипт хранит только один последний отчёт на каждый сервер. Старый удаляется только после успешной валидации нового.\nЧто проверяет dpich # В конфиге включены четыре чекера:\nwhoami # Определяет публичный IP, ASN, провайдера и геолокацию. Нужно, чтобы сразу видеть, с какого адреса идет проверка, и не перепутать серверы.\ncidrwhitelist # Проверяет, не под шатдауном ли сервер. Если только белые доступны — фиксируется изоляция.\nwebhost # Основной чекер. Собирает пул хостов разных провайдеров (Akamai, Cloudflare, Hetzner, DigitalOcean, Vultr, OVH и другие), проверяет:\nдоступность (TCP connection) TLS-рукопожатие (версия, SAN, CN) эвристику умных машинок ведомства из 3 букв (tcp1620) пропускную способность (bursttxkbps, burstrxkbps) Эвристика умных машинок работает через несколько соединений с разными фингерпринтами. Если провайдер инжектит RST, сбрасывает TLS или подменяет ответы — отчёт показывает ERR или NOT_SUPPORTED_BY_HOST.\ndns # Проверяет DNS-спуфинг, leak и перехват DoH. Тестирует классические резолверы (AdGuard, Cloudflare, Google, Yandex, Quad9, MSK-IX и др.) по UDP/TCP, а также DoH-точки.\nКонфиг dpich # Шаблон config.example.yml выглядит так:\nall: format: yaml auto-exit: true prefix: /root/.local/dpi-ch/dpi-ch-result_ ts-format: 2006-01-02_15-04 checkers: - whoami - cidrwhitelist - webhost - dns checkers: cidrwhitelist: timeout: 7s whitelisted: - https://max.ru/ - https://ya.ru/ - https://vk.ru/ regular: - https://github.com/ - https://ru.wikipedia.org/ - https://www.google.com/ webhost: workers: 8 farm-timeout: 3m tcp-conn-timeout: 3s tls-handshake-timeout: 3s tcp-read-timeout: 10s tcp-write-timeout: 10s siberian-conn-count: 4 # Количество соединений для детекции эвристик умных машинок dns: resolve: plain-opt: timeout: 7s workers: 5 doh-opt: timeout: 7s workers: 5 inetutil: fingerprint: edge browser-headers: Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ... updater: enabled: true period: 24h root-dir: /root/.local/dpi-ch/data Фингерпринт выбран edge.\nУстановка dpich на серверах # Если dpich не установлен, скрипт ставит его через официальный инсталлятор:\nbash \u0026lt;(curl -Ls https://hyperion-cs.github.io/dpi-checkers/ru/dpi-ch/install/unix.sh) Как читать отчёт? # Отчёт представляет собой YAML-файл, разбитый по чекерам. Давайте разберём основные блоки на примере:\nwhoami: status: msg: Ok code: OK ip: 198.51.100.42 # Ваш публичный IP asn: AS0 org: \u0026#34;\u0026#34; location: \u0026#34;\u0026#34; whoami показывает, с какого IP и из какой сети был запущен скрипт. Полезно для уверенности, что тест прошёл именно с нужного сервера, а не через случайный VPN.\ncidrwhitelist: status: msg: You\u0026#39;re NOT under one code: NOT_DETECTED cidrwhitelist проверяет шатдаун. Если бы сервер был отрезан от мира и пускал только на легитимные внутренние ресурсы, статус был бы DETECTED.\ndns: leak: status: msg: Ok items: - ip: 2.200.XX.XX org: i3D.net B.V location: NL В dns.leak видно, от чьего имени идут запросы к корневым серверам. В данном случае DNS-резолвер физически ходит в интернет через Заковию.\nДалее идёт проверка классических (plain) DNS и DoH. Обратите внимание на перехваты и блокировки:\nplain: status: msg: Ok providers: Google DNS: - msg: Ok MSK-IX DNS: - msg: NXDOMAIN spoofing code: NXDOMAIN_SPOOFING NSDI: - msg: NXDOMAIN spoofing code: NXDOMAIN_SPOOFING doh: status: msg: Ok providers: Google DNS: - msg: Ok Mullvad DNS: - msg: \u0026#39;http: malformed response\u0026#39; code: INETUTIL_ERR Часть аномальных ответов (например, NXDOMAIN spoofing для MSK-IX или malformed response для DoH) прямо указывает на то, что умные машинки или провайдер вмешивается в DNS-трафик и подменяет ответы.\nwebhost — самый большой блок. Он делает запросы к популярным хостингам и сервисам (Cloudflare, DigitalOcean, VK, Yandex, Apple и др.) и проверяет, что с ними происходит.\nwebhost: Foreign Infrastructure Providers: items: - group: Cloudflare ip: 104.17.67.222 alive: msg: Ok tcp1620: msg: \u0026#34;No\u0026#34; siberian: msg: \u0026#34;No\u0026#34; bursttxkbps: 3.240756e+06 В результатах webhost важны два поля:\ntcp1620: Если здесь tcp: connection reset или ERR, значит по пути кто-то целенаправленно рубит нужное соединение RST-пакетом. siberian: Эвристика, проверяющая реакцию \u0026ldquo;умных машинок\u0026rdquo;. Если статус DETECTED, это значит, что DPI активно анализирует и ломает пакеты к этому хосту. Для bursttxkbps и burstrxkbps отображается пропускная способность при handshake и передаче данных. Если значения сильно отличаются в меньшую сторону, возможно, применяется шейпинг провайдером.\nА нафига это всё? # Когда серверов несколько, ручной процесс надоедает. Здесь всё в одном месте — несколько серверов, один запуск, отчёты лежат рядом, их можно сравнивать.\nБез скрипта для каждой проверки нужно заходить на каждый сервер по SSH, запускать dpich, копировать отчёт, сравнивать\u0026hellip;\nСсылки # dpich / dpi-checkers — утилита, которую запускает скрипт checkdpi.sh — сам скрипт config.example.yml — шаблон конфига ","date":"8 сентября 2026","externalUrl":null,"permalink":"/checkdpi/","section":"Posts","summary":"","title":"Скрипт с мониторингом фильтрации трафика на серверах","type":"posts"},{"content":"","date":"2 сентября 2026","externalUrl":null,"permalink":"/tags/clash/","section":"Tags","summary":"","title":"Clash","type":"tags"},{"content":"","date":"2 сентября 2026","externalUrl":null,"permalink":"/tags/geosite/","section":"Tags","summary":"","title":"Geosite","type":"tags"},{"content":"","date":"2 сентября 2026","externalUrl":null,"permalink":"/tags/github-actions/","section":"Tags","summary":"","title":"Github-Actions","type":"tags"},{"content":"","date":"2 сентября 2026","externalUrl":null,"permalink":"/categories/open-source/","section":"Categories","summary":"","title":"Open Source","type":"categories"},{"content":"","date":"2 сентября 2026","externalUrl":null,"permalink":"/categories/shadowrocket/","section":"Categories","summary":"","title":"Shadowrocket","type":"categories"},{"content":"","date":"2 сентября 2026","externalUrl":null,"permalink":"/tags/shadowrocket/","section":"Tags","summary":"","title":"Shadowrocket","type":"tags"},{"content":" В Shadowrocket Simple Config у меня лежат списки доменов для маршрутизации трафика. Но некоторые прокси-клиенты (Xray, Clash, Mihomo) работают не с текстовыми списками, а с бинарным форматом geosite.dat. Чтобы не конвертировать руками, сделал автоматический генератор.\nЧто такое geosite.dat? # geosite.dat — это protobuf-файл, который используется в ядрах Xray/v2Ray/Clash для компактного хранения и быстрого поиска доменов по категориям. Вместо правил в конфиге пишется что-то тип такого:\nrules: - GEOSITE,MAIN,PROXY - GEOSITE,RUDIRECT,DIRECT А маршрутизатор сам проверяет домен по базе.\nЗачем отдельный репозиторий? # Ручная конвертация — это Python, написать скрипт, запустить, проверить, загрузить куда-то. Кароче много дел.\nРешение: отдельный репозиторий srscdat, который:\nБерёт списки из ShadowRocketSimpleConfig Конвертирует в формат domain-list-community Генерирует geosite.dat через официальный инструмент v2fly Публикует как GitHub Release с постоянной ссылкой Как это работает # Всё построено на GitHub Actions:\non: workflow_dispatch: # только вручную, без расписания Процесс:\nCheckout srscdat и ShadowRocketSimpleConfig Клонирование domain-list-community (официальный генератор) Конвертация .list → формат нужный через convert.py Генерация geosite.dat через go run ./ Публикация в Releases через softprops/action-gh-release Структура проекта # srscdat/ ├── .github/workflows/generate.yml ← GitHub Actions ├── src/ │ ├── convert.py ← конвертер Shadowrocket → DLC │ └── check.py ← проверка geosite.dat ├── data/ ← промежуточные файлы (не коммитятся) └── output/ ← результат (не коммитится) Категории в geosite.dat # На данный момент файл содержит 13 категорий:\nКатегория Доменов Описание AI 97 ChatGPT, Claude, Gemini, Copilot FITNESS 4 Спорт и здоровье GAMES 22 Игровые платформы и CDN MAIN 254 Соцсети, медиа, инструменты MUSIC 12 Музыкальные стриминги NEVAMESSENGER 61 Мессенджер REDTUBE 16 RedTube и CDN RUADS 174 Российская реклама и трекинг RUBANKING 671 Российские банки RUDIRECT 337 Российские локальные сервисы RUIPCHECKER 9 Проверка IP VIDEO 41 Видео стриминги ZETASERVICES 107 Сервисы аналога ВК Итого: 1805 доменов, ~33 КБ.\nКак использовать # Постоянная ссылка (всегда ведёт на последнюю версию):\nhttps://github.com/tatarinovms/srscdat/releases/latest/download/geosite.dat В конфиге вашего клиента\\сервера:\n{ \u0026#34;Geositeurl\u0026#34;: \u0026#34;https://github.com/tatarinovms/srscdat/releases/latest/download/geosite.dat\u0026#34;, \u0026#34;DirectSites\u0026#34;: [\u0026#34;geosite:RUBANKING\u0026#34;, \u0026#34;geosite:RUDIRECT\u0026#34;], \u0026#34;ProxySites\u0026#34;: [\u0026#34;geosite:MAIN\u0026#34;, \u0026#34;geosite:AI\u0026#34;], \u0026#34;BlockSites\u0026#34;: [\u0026#34;geosite:RUADS\u0026#34;] } В Clash/Mihomo:\nrule-providers: geosite: type: http behavior: domain url: https://github.com/tatarinovms/srscdat/releases/latest/download/geosite.dat path: ./geosite.dat interval: 86400 rules: - RULE-SET,geosite,DIRECT Локальная генерация # Если не хочешь юзать GitHub Actions:\ngit clone https://github.com/tatarinovms/srscdat.git cd srscdat ./update-geosite.sh --check Требования: Python 3.6+, Go 1.21+, Git.\nРепозиторий # Всё открыто: github.com/tatarinovms/srscdat\nЕсли хочешь так же форкай и алга, поменяй ссылку на свои списки в generate.yml, запушъ. И теперь и у тебя есть автоматический генератор geosite.dat из любых списков Shadowrocket.\n","date":"2 сентября 2026","externalUrl":null,"permalink":"/srscdat/","section":"Posts","summary":"","title":"srscdat — генератор geosite.dat из списков Shadowrocket","type":"posts"},{"content":"","date":"2 сентября 2026","externalUrl":null,"permalink":"/tags/xray/","section":"Tags","summary":"","title":"Xray","type":"tags"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/tags/app-store/","section":"Tags","summary":"","title":"App-Store","type":"tags"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/tags/cli/","section":"Tags","summary":"","title":"Cli","type":"tags"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/categories/cli/","section":"Categories","summary":"","title":"CLI","type":"categories"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/tags/downloader/","section":"Tags","summary":"","title":"Downloader","type":"tags"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/tags/ipa/","section":"Tags","summary":"","title":"Ipa","type":"tags"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/tags/iphone/","section":"Tags","summary":"","title":"Iphone","type":"tags"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/tags/macos/","section":"Tags","summary":"","title":"Macos","type":"tags"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/categories/macos/","section":"Categories","summary":"","title":"MacOS","type":"categories"},{"content":"","date":"28 августа 2026","externalUrl":null,"permalink":"/tags/open-source/","section":"Tags","summary":"","title":"Open-Source","type":"tags"},{"content":" ⚠️ Установку и ковыряние во всём этом делаете с головой и прямыми руками, сей гайд для тех, кто и за безопасность своего аккаунта умеет думать и вообще на свой страх и риск, как говорится.\nipatool от majd — консольная утилита для поиска, просмотра покупок и скачивания зашифрованных .ipa пакетов из App Store. Ранее для обхода ошибки входа HTTP 403: empty or non-plist body приходилось ставить форк ipatool-sapfix, добавлявший обязательную SAP-подпись X-Apple-ActionSignature через CommerceKit. Начиная с релиза v2.4.0 и свежего v2.5.0 автор добавил нативную поддержку подписанных SAP-запросов прямо в апстрим и закрыл ошибку FailureType 5002. Форки больше не нужны — ставим оригинал. Утилита работает как на Apple Silicon, так и на Intel Mac.\nКак установить? # Самый удобный способ для macOS — через Homebrew:\nbrew install ipatool Либо вручную скачать бинарник со страницы релизов. Для Apple Silicon выбирайте arm64, для Intel Mac — amd64:\nVER=2.5.0 curl -LO https://github.com/majd/ipatool/releases/download/v${VER}/ipatool-${VER}-macos-arm64.tar.gz curl -LO https://github.com/majd/ipatool/releases/download/v${VER}/ipatool-${VER}-macos-arm64.tar.gz.sha256sum shasum -a 256 -c ipatool-${VER}-macos-arm64.tar.gz.sha256sum tar -xzf ipatool-${VER}-macos-arm64.tar.gz sudo install -m 0755 bin/ipatool-${VER}-macos-arm64 /usr/local/bin/ipatool ipatool --version Если macOS заблокирует запуск бинарника, снимите атрибут карантина:\nxattr -d com.apple.quarantine /usr/local/bin/ipatool Авторизация # Сначала входим в свой Apple ID:\nipatool auth login --email \u0026#34;beaver@ilovebeaver.com\u0026#34; Вводим пароль и код двухфакторной аутентификации (2FA). Успешный вход подтверждается строкой:\nemail=beaver@ilovebeaver.com name=\u0026#34;Beaver ClanLeaderovich\u0026#34; success=true Просмотр купленных приложений (list-purchases) # В актуальных версиях появилась аутентифицированная команда list-purchases, работающая через подписанные SAP-запросы к истории покупок App Store.\nОна возвращает список всех приложений, привязанных к вашему Apple ID, отсортированных по дате покупки (сначала самые свежие).\n# Вывести первые 10 купленных приложений (по умолчанию) ipatool list-purchases # Постраничная навигация (пагинация от 1 до 100 на страницу) ipatool list-purchases --page 1 --max-results 50 Доступные флаги:\n-l, --max-results \u0026lt;int\u0026gt; — количество приложений на страницу (по умолчанию 10, максимум 100). -p, --page \u0026lt;int\u0026gt; — номер страницы (по умолчанию 1). --format json — вывод в формате JSON (удобно для автоматизации и пайплайнов через jq). Пример вывода списка покупок в JSON:\nipatool list-purchases --page 1 --max-results 20 --format json Поиск и скачивание приложений # Поиск в App Store: ipatool search \u0026#34;WB Книги\u0026#34; 2:56PM INF apps=[{\u0026#34;bundleID\u0026#34;:\u0026#34;ru.wildberries.wbbooks\u0026#34;,\u0026#34;id\u0026#34;:6739949061,\u0026#34;name\u0026#34;:\u0026#34;WB Книги\u0026#34;,\u0026#34;price\u0026#34;:0,\u0026#34;version\u0026#34;:\u0026#34;2.12.0\u0026#34;},{\u0026#34;bundleID\u0026#34;:\u0026#34;ru.yandex.mobile.music\u0026#34;,\u0026#34;id\u0026#34;:520797969,\u0026#34;name\u0026#34;:\u0026#34;Yandex Music: музыка, книги\u0026#34;,\u0026#34;price\u0026#34;:0,\u0026#34;version\u0026#34;:\u0026#34;8.05\u0026#34;}] count=2 Привязка бесплатной лицензии к аккаунту (если приложение ещё не «купили»): ipatool purchase --bundle-identifier ru.wildberries.wbbooks Скачивание .ipa: ipatool download --bundle-identifier ru.wildberries.wbbooks --output ./ru.wildberries.wbbooks.ipa Важно: скачанные .ipa подписаны персональным сертификатом вашей учетной записи, поэтому установить их без переподписи можно только на устройства с этим же Apple ID.\nКак получить список Bundle ID? # Способ 1: Прямо из истории покупок Apple ID (без телефона) # Благодаря list-purchases и jq можно выгрузить bundleID ваших приложений прямо в файл:\nipatool list-purchases --page 1 --max-results 100 --format json | jq -r \u0026#39;.[].bundleID\u0026#39; \u0026gt; ~/Downloads/my_purchased_apps.txt Способ 2: С подключенного iPhone через USB # Если нужно вытащить идентификаторы только тех приложений, которые физически стоят на iPhone:\nbrew install libimobiledevice ideviceinstaller idevicepair pair # подтвердить «Доверять этому компьютеру» на экране ideviceinstaller list --user \u0026gt; /tmp/iphone_apps.csv # Очищаем CSV до списка Bundle ID: tail -n +2 /tmp/iphone_apps.csv | cut -d\u0026#39;,\u0026#39; -f1 | sed \u0026#39;s/^\u0026#34;//; s/\\\u0026#34;$//\u0026#39; \u0026gt; ~/Downloads/iphone_bundle_ids.txt Батч-скачивание всех приложений по списку # Берём полученный список bundleID и прогоняем через связку purchase + download:\n#!/usr/bin/env bash set -euo pipefail LIST=~/Downloads/my_purchased_apps.txt OUT=~/Downloads/ipas mkdir -p \u0026#34;$OUT\u0026#34; while read -r bid; do [ -z \u0026#34;$bid\u0026#34; ] \u0026amp;\u0026amp; continue echo \u0026#34;==\u0026gt; Обработка: $bid\u0026#34; ipatool purchase --bundle-identifier \u0026#34;$bid\u0026#34; || { echo \u0026#34;purchase failed: $bid\u0026#34;; } ipatool download --bundle-identifier \u0026#34;$bid\u0026#34; --output \u0026#34;$OUT/$bid.ipa\u0026#34; || { echo \u0026#34;download failed: $bid\u0026#34;; } done \u0026lt; \u0026#34;$LIST\u0026#34; Установка IPA на устройство # Скачанный файл .ipa можно установить обратно на телефон через Apple Configurator обычным перетаскиванием (drag-and-drop).\n","date":"28 августа 2026","externalUrl":null,"permalink":"/ipatool-sapfix/","section":"Posts","summary":"","title":"Качаем IPA из App Store","type":"posts"},{"content":"","date":"18 августа 2026","externalUrl":null,"permalink":"/tags/certbot/","section":"Tags","summary":"","title":"Certbot","type":"tags"},{"content":"","date":"18 августа 2026","externalUrl":null,"permalink":"/tags/dietpi/","section":"Tags","summary":"","title":"Dietpi","type":"tags"},{"content":"","date":"18 августа 2026","externalUrl":null,"permalink":"/tags/letsencrypt/","section":"Tags","summary":"","title":"Letsencrypt","type":"tags"},{"content":"","date":"18 августа 2026","externalUrl":null,"permalink":"/tags/nginx/","section":"Tags","summary":"","title":"Nginx","type":"tags"},{"content":"","date":"18 августа 2026","externalUrl":null,"permalink":"/tags/openwrt/","section":"Tags","summary":"","title":"Openwrt","type":"tags"},{"content":"","date":"18 августа 2026","externalUrl":null,"permalink":"/tags/selfhosted/","section":"Tags","summary":"","title":"Selfhosted","type":"tags"},{"content":"","date":"18 августа 2026","externalUrl":null,"permalink":"/tags/ssl/","section":"Tags","summary":"","title":"Ssl","type":"tags"},{"content":" Если вы выпускаете сертификаты Let\u0026rsquo;s Encrypt на сервере за домашним роутером, вам знакома ситуация: HTTP-01 challenge требует, чтобы порт 80 был доступен снаружи. Держать 80-й порт постоянно открытым очень плохая идея.\nРешение: открывать порт только на время самого продления, а сразу после - закрывать. И всё это автоматически, без участия человека.\nЗачем это вообще нужно # certbot с аутентификатором standalone поднимает свой веб-сервер на порту 80 и ждёт, пока Let\u0026rsquo;s Encrypt придёт по http://ваш-домен/.well-known/acme-challenge/.... Чтобы этот запрос дошёл:\nна роутере должен быть проброшен порт 80 (DNAT) на сервер; сам порт 80 на сервере должен быть свободен (иначе standalone не поднимется - Address already in use). В моём случае на сервере уже крутится nginx, который слушает 80-й. Поэтому в схему пришлось добавить ещё и остановку/запуск nginx вокруг продления.\nDietPi и certbot: что на самом деле делает скрипт # Кажется логичным: раз это DietPi, certbot автоматически продлит сертификат сам. Я заглянул в сам скрипт /boot/dietpi/dietpi-letsencrypt - и вот что там реально происходит.\nВо-первых, это не автоматика. dietpi-letsencrypt - интерактивный ручной инструмент. Он запускается вручную из меню, выпускает (или перевыпускает) сертификат один раз и выходит. Никакого cron-задания на переиздание DietPi не ставит - авто-продление целиком на совести certbot.timer.\nВо-вторых, метод выпуска зависит от того, что уже стоит на сервере:\nесть nginx → используется плагин --nginx (скрипт сам выбирает local aoptions=('--nginx')); есть lighttpd → --webroot -w /var/www; веб-сервер не обнаружен → fallback на --standalone, и вот тут DietPi сама останавливает занимающие :80 сервисы (fuser 80/tcp \u0026amp;\u0026amp; dietpi-services stop) перед challenge и поднимает их обратно (dietpi-services start) после. То есть при штатном сценарии с nginx certbot вообще не трогает работающий веб-сервер - плагин --nginx сам договаривается с ним и отдаёт challenge через него. Никакого стопа.\nПочему же у меня в renewal-conf написано authenticator = standalone? Потому что сертификат когда-то выпускался вручную в ситуации, когда либо nginx ещё не слушал 80-й. И вот тут - подвох: standalone и работающий nginx несовместимы. Certbot пытается открыть сокет на :80, порт уже занят nginx, и продление падает с Address already in use.\nА документация DietPi рекомендует:\nKeep port 80 open for Certbot renewal\nЭто справедливо для штатного пути (плагин веб-сервера): nginx сам слушает 80-й и сам отдаёт challenge, поэтому «держать порт открытым» означает просто не выключать проброс. Но это противоречит желанию не держать 80-й постоянно торчащим наружу. Наша схема с pre/post-hook - это ровно та же идея, но с закрытием порта, когда он не нужен: порт на роутере открывается на пару секунд только для HTTP-01 challenge и тут же закрывается.\nИдея # Certbot умеет выполнять скрипты до (pre-hook) и после (post-hook) попытки продления. post-hook вызывается всегда - даже при ошибке, - поэтому порт гарантированно закроется.\nПлан такой:\npre-hook - останавливаем nginx на сервере и открываем порт 80 на роутере. certbot делает свои дела. post-hook - запускаем nginx обратно и закрываем порт на роутере. SSH-доступ к роутеру # Скрипты управляют файрволом самого роутера — поэтому с сервера должен быть беспарольный SSH-доступ к нему. Обычный логин по паролю не подойдёт: в скриптах стоит ssh -o BatchMode=yes, и если ключ не настроен, соединение просто упадёт, а порт не откроется.\nЧто нужно сделать один раз:\nВключить SSH на роутере.\nЗакинуть публичный ключ сервера на роутер, чтобы вход был без пароля.\nПрописать алиас в ~/.ssh/config на сервере, чтобы скрипт не хранил ни IP, ни порт, ни имя пользователя:\nHost router Hostname 192.168.x.x Port \u0026lt;порт\u0026gt; User root IdentityFile ~/.ssh/id_bla_bla_bla Теперь ssh router \u0026quot;uci show firewall\u0026quot; из скрипта работает без дополнительных параметров, а в самих скриптах достаточно ssh -o BatchMode=yes router \u0026quot;...\u0026quot;.\nСкрипты на сервере # Кладём два скрипта, например, в /root/myscripts/. Путь до роутера настраиваем через ~/.ssh/config (отдельный Host), чтобы скрипт не содержал ни IP, ни ключей.\ncert-port-open.sh - открывает порт и освобождает :80:\n#!/bin/bash # pre-hook: открыть порт 80 на роутере, остановить nginx для standalone set -u ROUTER_HOST=\u0026#34;router\u0026#34; # алиас из ~/.ssh/config FW_RULE=\u0026#34;firewall.\u0026lt;cfg-id\u0026gt;\u0026#34; # uci-ид правила DNAT (см. ниже) systemctl stop nginx ssh -o StrictHostKeyChecking=no -o BatchMode=yes \u0026#34;$ROUTER_HOST\u0026#34; \u0026#34; uci set ${FW_RULE}.enabled=1 uci commit firewall fw4 reload \u0026#34; \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 exit 0 cert-port-close.sh - закрывает порт и поднимает nginx:\n#!/bin/bash # post-hook: закрыть порт 80 на роутере, запустить nginx set -u ROUTER_HOST=\u0026#34;router\u0026#34; FW_RULE=\u0026#34;firewall.\u0026lt;cfg-id\u0026gt;\u0026#34; systemctl start nginx ssh -o StrictHostKeyChecking=no -o BatchMode=yes \u0026#34;$ROUTER_HOST\u0026#34; \u0026#34; uci set ${FW_RULE}.enabled=0 uci commit firewall fw4 reload \u0026#34; \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 exit 0 Готовые версии скриптов можно скачать здесь: cert-port-open.sh и cert-port-close.sh.\nНастройка роутера # На роутере создаём (или находим) правило DNAT, которое внешний порт 80 шлёт на сервер. Через UCI:\n# один раз, на самом роутере (замените IP на адрес вашего сервера) uci add firewall redirect uci set firewall.@redirect[-1].enabled=\u0026#39;0\u0026#39; # по умолчанию ВЫКЛЮЧЕНО uci set firewall.@redirect[-1].dest=\u0026#39;lan\u0026#39; uci set firewall.@redirect[-1].target=\u0026#39;DNAT\u0026#39; uci set firewall.@redirect[-1].name=\u0026#39;LSEcrypt\u0026#39; uci set firewall.@redirect[-1].src=\u0026#39;wan\u0026#39; uci set firewall.@redirect[-1].src_dport=\u0026#39;80\u0026#39; uci set firewall.@redirect[-1].dest_ip=\u0026#39;192.168.x.x\u0026#39; uci set firewall.@redirect[-1].dest_port=\u0026#39;80\u0026#39; uci commit firewall fw4 reload Скрипты выше переключают enabled этого правила между 1 и 0. Чтобы узнать его cfg-ид, выполните на роутере uci show firewall | grep -B1 LSEcrypt и подставьте в FW_RULE.\nЧто такое \u0026lt;cfg-id\u0026gt;: в OpenWrt каждая секция конфига firewall при сохранении получает внутренний идентификатор вида cfgXXXXXX (набор букв и цифр, например cfg103837). Он уникален для каждой записи и используется в UCI для точного обращения к конкретному правилу, когда имя (name) неоднозначно или не задано. Именно поэтому в скриптах фигурирует firewall.\u0026lt;cfg-id\u0026gt;, а не человекочитаемое имя - чтобы команда uci set била точно в нужное правило. Вместо \u0026lt;cfg-id\u0026gt; подставьте свой реальный идентификатор (то, что показала команда выше).\nМой роутер - OpenWrt 24.10 с fw4; для старых версий на fw3 команда перезагрузки правил та же по смыслу (fw3 reload).\nПодключаем хуки в certbot # Прописываем хуки глобально, в /etc/letsencrypt/cli.ini:\npre-hook = /root/myscripts/cert-port-open.sh post-hook = /root/myscripts/cert-port-close.sh Теперь любой certbot renew (будь то по systemd-таймеру или вручную) откроет порт только на время выпуска и закроет сразу после.\nПроверка # Dry-run прогоняет хуки реально (не только симулирует challenge), так что это честная проверка:\ncertbot renew --dry-run --force-renewal В логе /var/log/letsencrypt/letsencrypt.log должны появиться строки:\nRunning pre-hook command: /root/myscripts/cert-port-open.sh Running post-hook command: /root/myscripts/cert-port-close.sh После прогона убедитесь, что порт на роутере снова закрыт (uci get firewall.\u0026lt;cfg\u0026gt;.enabled → 0), а nginx снова active.\nИтог # Порт 80 на роутере теперь открыт ровно на несколько секунд, пока идёт HTTP-01 challenge, и автоматически закрывается. Никакого постоянно торчащего 80-го порта, никаких ручных действий. Авто-обновление сертификатов работает само.\n","date":"18 августа 2026","externalUrl":null,"permalink":"/certbotopenwrtautoport/","section":"Posts","summary":"","title":"Авто-открытие порта 80 на OpenWrt для certbot","type":"posts"},{"content":"","date":"18 августа 2026","externalUrl":null,"permalink":"/categories/%D1%81%D0%B5%D1%82%D0%B8/","section":"Categories","summary":"","title":"Сети","type":"categories"},{"content":"","date":"17 августа 2026","externalUrl":null,"permalink":"/tags/bitwarden/","section":"Tags","summary":"","title":"Bitwarden","type":"tags"},{"content":"","date":"17 августа 2026","externalUrl":null,"permalink":"/tags/reverse-proxy/","section":"Tags","summary":"","title":"Reverse-Proxy","type":"tags"},{"content":"","date":"17 августа 2026","externalUrl":null,"permalink":"/categories/security/","section":"Categories","summary":"","title":"Security","type":"categories"},{"content":"","date":"17 августа 2026","externalUrl":null,"permalink":"/tags/security/","section":"Tags","summary":"","title":"Security","type":"tags"},{"content":"","date":"17 августа 2026","externalUrl":null,"permalink":"/tags/self-hosted/","section":"Tags","summary":"","title":"Self-Hosted","type":"tags"},{"content":"","date":"17 августа 2026","externalUrl":null,"permalink":"/tags/vaultwarden/","section":"Tags","summary":"","title":"Vaultwarden","type":"tags"},{"content":" В предыдущей заметке я описал, как поднять Vaultwarden (Bitwarden-совместимый сервер на Rust) на Docker Compose вместе с Caddy, чтобы последний автоматически получал TLS-сертификаты у Let\u0026rsquo;s Encrypt и проксировал запросы.\nТакая схема работала стабильно. Однако со временем появились причины заменить Caddy на nginx. В этой статье я расскажу, как выполнил миграцию.\nЗачем менять Caddy на nginx # Caddy — отличный инструмент, особенно для домашних серверов: минимальная конфигурация, автоматический TLS и мало зависимостей. Но у меня все завернуто через nginx все равно, лучше все в одном уж месте.\nАрхитектура после замены # Было:\nСеть → Caddy:443 (TLS + ACME) → Vaultwarden:80 (внутри Docker) Стало:\nСеть → Nginx:443 (TLS, Let\u0026#39;s Encrypt, статика) → Vaultwarden:8001 (HTTP) Vaultwarden больше не занимается терминацией TLS. Он обслуживает чистый HTTP на порту 8001, а nginx обеспечивает защищенное соединение. Это соответствует официальной рекомендации разработчиков Vaultwarden: использовать обратный прокси для TLS.\nТребования # Сервер с работающим Vaultwarden (в моем случае — нативная установка через DietPi). Установленный nginx. Доменное имя (например, vault.beaverbloger.com). Действующие сертификаты Let\u0026rsquo;s Encrypt, выпущенные через dietpi-letsencrypt. Открытые порты 80 и 443 на фаерволе/роутере (или использование Tailscale). Шаг 1. Отключаем встроенный TLS в Vaultwarden # Если ранее Vaultwarden работал по HTTPS, необходимо убрать эту настройку. Параметры хранятся в файле окружения (для DietPi это обычно /mnt/dietpi_userdata/vaultwarden/vaultwarden.env).\nНайдите и удалите или закомментируйте строку:\nROCKET_TLS={certs=\u0026#34;./fullchain.pem\u0026#34;,key=\u0026#34;./privkey.pem\u0026#34;} Убедитесь, что порт указан верно (по умолчанию 8001):\nROCKET_PORT=8001 Перезапустите сервис:\ndietpi-services restart vaultwarden Проверьте, что сервис слушает только HTTP:\ncurl http://127.0.0.1:8001 Шаг 2. Установка nginx # Если nginx еще не установлен, используйте DietPi Software:\ndietpi-software install 85 Проверьте версию и статус службы:\nnginx -v dietpi-services status nginx Убедитесь, что порты 80 и 443 свободны. Если вы ранее использовали Caddy, остановите и отключите его службу.\nШаг 3. Получение сертификатов через dietpi-letsencrypt # Вместо ручной настройки certbot используем штатную утилиту DietPi.\nЗапустите мастер настройки:\ndietpi-letsencrypt Укажите свой домен (например, vault.beaverbloger.com). Утилита предложит настроить nginx. Поскольку мы будем использовать кастомный конфиг, можно согласиться на базовую настройку. dietpi-letsencrypt использует certbot под капотом. Сертификаты будут обновляться автоматически по расписанию, но нам нужно научить nginx подхватывать новые файлы.\nШаг 4. Настройка nginx # Конфигурация состоит из upstream-блока и server-блоков\nUpstream и поддержка WebSocket # Vaultwarden использует WebSocket для push-уведомлений. Nginx должен корректно обрабатывать апгрейд соединения. Создайте файл /etc/nginx/conf.d/vaultwarden_upstream.conf:\nupstream vaultwarden { server 127.0.0.1:8001; keepalive 2; } map $http_upgrade $connection_upgrade { default upgrade; \u0026#34;\u0026#34; \u0026#34;\u0026#34;; } Виртуальный хост # Создайте файл /etc/nginx/sites-available/vaultwarden:\n# HTTP -\u0026gt; HTTPS редирект server { listen 80; listen [::]:80; server_name vault.beaverbloger.com; return 301 https://$host$request_uri; } # HTTPS server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name vault.beaverbloger.com; # Пути к сертификатам (копии для nginx) ssl_certificate /etc/ssl/vaultwarden/fullchain.pem; ssl_certificate_key /etc/ssl/vaultwarden/privkey.pem; # Безопасные настройки TLS ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers \u0026#34;ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384\u0026#34;; ssl_prefer_server_ciphers off; # HSTS add_header Strict-Transport-Security \u0026#34;max-age=604800; includeSubDomains\u0026#34; always; # Лимит размера загружаемых файлов (вложения) client_max_body_size 525M; location / { proxy_pass http://vaultwarden; proxy_http_version 1.1; # Заголовки для WebSocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # Стандартные прокси-заголовки proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } Активируйте конфиг и проверьте синтаксис:\nln -sf /etc/nginx/sites-available/vaultwarden /etc/nginx/sites-enabled/ nginx -t dietpi-services restart nginx Шаг 5. Автоматическое обновление сертификатов # Поскольку мы используем dietpi-letsencrypt, сертификаты обновляются автоматически. Однако nginx не увидит новые файлы, если они просто заменятся в папке /etc/letsencrypt/ (из-за прав доступа и символических ссылок).\nРешение ленивое: копировать сертификаты в отдельную директорию, доступную nginx, и перезагружать веб-сервер через deploy-хук.\nСоздайте скрипт /etc/letsencrypt/renewal-hooks/deploy/vaultwarden.sh:\n#!/bin/bash DOMAIN=\u0026#34;vault.beaverbloger.com\u0026#34; SSL_DEST=\u0026#34;/etc/ssl/vaultwarden\u0026#34; mkdir -p \u0026#34;$SSL_DEST\u0026#34; cp \u0026#34;/etc/letsencrypt/live/$DOMAIN/fullchain.pem\u0026#34; \u0026#34;$SSL_DEST/fullchain.pem\u0026#34; cp \u0026#34;/etc/letsencrypt/live/$DOMAIN/privkey.pem\u0026#34; \u0026#34;$SSL_DEST/privkey.pem\u0026#34; chown root:www-data \u0026#34;$SSL_DEST/privkey.pem\u0026#34; chmod 640 \u0026#34;$SSL_DEST/privkey.pem\u0026#34; chmod 644 \u0026#34;$SSL_DEST/fullchain.pem\u0026#34; dietpi-services restart nginx Сделайте скрипт исполняемым:\nchmod +x /etc/letsencrypt/renewal-hooks/deploy/vaultwarden.sh Теперь при каждом успешном обновлении сертификата через dietpi-letsencrypt (который вызывает certbot) этот скрипт выполнится автоматически, скопирует свежие ключи и мягко перезагрузит nginx.\nПроверка работы # TLS: echo | openssl s_client -connect vault.beaverbloger.com:443 2\u0026gt;/dev/null | openssl x509 -noout -subject Доступность API: curl https://vault.beaverbloger.com/api/config WebSocket: Откройте веб-интерфейс Vaultwarden в браузере Логи: tail -f /var/log/nginx/error.log Заключение # Миграция с Caddy на nginx в экосистеме DietPi требует немного больше ручной настройки, но дает полный контроль над параметрами. Использование штатной утилиты dietpi-letsencrypt для выпуска сертификатов и кастомного deploy-хука для их доставки в nginx позволяет сохранить автоматизацию обновлений, не жертвуя гибкостью конфигурации веб-сервера.\n","date":"17 августа 2026","externalUrl":null,"permalink":"/vaultwardennginx/","section":"Posts","summary":"","title":"Vaultwarden за nginx — меняем Caddy на nginx","type":"posts"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/categories/ai/","section":"Categories","summary":"","title":"AI","type":"categories"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/ai/","section":"Tags","summary":"","title":"AI","type":"tags"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/categories/automation/","section":"Categories","summary":"","title":"Automation","type":"categories"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/categories/cloud/","section":"Categories","summary":"","title":"Cloud","type":"categories"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/hermes/","section":"Tags","summary":"","title":"Hermes","type":"tags"},{"content":" Я использую rclone для работы с Яндекс.Диском уже давно: двусторонняя синхронизация скриптов, бэкап конфигов роутера и т.д. Команды простые, но иногда хочется их отдать отдать ИИ-агенту. Поэтому я сделал скилл для Hermes, который умеет управлять файлами на Яндекс.Диске через rclone.\nЧто умеет скилл # Скилл yandex-disk-rclone — это инструкция для ИИ-агента с набором команд. Теперь вместо того чтобы руками или скриптом что-то делать, я просто прошу по-русски агента: «залей это на яндекс диск» или «что лежит в папке X в облаке».\nОсновные операции:\nПросмотр: список директорий (rclone lsd), файлов с размером (rclone ls), имена файлов (rclone lsf), с датами (rclone lsl) Загрузка и скачивание: rclone copy в обе стороны, rclone move с удалением исходника Синхронизация: односторонняя rclone sync (с предупреждением о удалении лишних файлов) и двусторонняя rclone bisync — как в моём скрипте syncscript2yandexdisk.sh Удаление: rclone delete, rclone purge, rclone rmdir Служебное: создание папок, подсчёт размера, проверка целостности (rclone check) Правила безопасности # Самое важное в скилле — не навредить. Поэтому там прописаны жёсткие правила:\nПодтверждение перед опасными операциями — delete, purge, sync, move агент выполняет только после явного одобрения --dry-run для синхронизации — сначала показать, что будет удалено/изменено, и только потом делать Не выводить токен — в конфиге rclone хранится OAuth-токен, скилл запрещает его печатать Учтены конвенции машины — yandex:/scripts синхронизируется с ~/Documents/scripts, такие папки случайно перезаписывать нельзя Особенности Яндекс.Диска # У API Яндекс.Диска есть свои причуды, и скилл их учитывает:\nRate limit — примерно 90 запросов в минуту. Для массовых операций добавляется --tpslimit 10 --tpslimit-burst 20 --fast-list не поддерживается — при попытке использовать выдаст ошибку rclone about yandex: может не работать — API не отдаёт квоту надёжно purge удаляет безвозвратно — Яндекс держит файлы в своей корзине на стороне веб-интерфейса, но через rclone восстановить их нельзя Пример работы # Выглядит это так. Я пишу агенту:\nЗалей папку reports на яндекс диск\nАгент по скиллу выполняет:\n# 1. Смотрит, что уже есть в облаке rclone lsd yandex: # 2. Показывает, что будет загружено (dry run) rclone copy ~/reports/ yandex:/reports/ --dry-run # 3. Загружает rclone copy ~/reports/ yandex:/reports/ --progress # 4. Проверяет результат rclone lsf yandex:/reports/ --files-only | head Пример скилла # Скилл — это обычный Markdown-файл с YAML-шапкой, который лежит в ~/.hermes/skills/\u0026lt;категория\u0026gt;/\u0026lt;имя\u0026gt;/SKILL.md. Агент читает его перед выполнением задачи.\nСкачать готовый файл\nЗачем это нужно # У меня уже есть пост про настройку rclone для Яндекс.Диска, где разобраны команды вручную. Но когда работаешь с облаком часто, хочется иногда послать агента делать это.\nЕсли тоже пользуетесь Hermes или другим ИИ-агентом рекомендую оформлять повторяющиеся операции с облаком в скиллы. Это как шпаргалка, которую агент читает перед каждым действием.\n","date":"31 июля 2026","externalUrl":null,"permalink":"/hermesyandexdisk/","section":"Posts","summary":"","title":"Hermes: скилл для управления Яндекс.Диском через rclone","type":"posts"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/rclone/","section":"Tags","summary":"","title":"Rclone","type":"tags"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/yandex-disk/","section":"Tags","summary":"","title":"Yandex-Disk","type":"tags"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/apple/","section":"Tags","summary":"","title":"Apple","type":"tags"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/memo/","section":"Tags","summary":"","title":"Memo","type":"tags"},{"content":" Заметки Apple — это удобно: они синхронизируются через iCloud на все устройства, поддерживают вложения и быстрый поиск. Но у них есть один минус — ими сложно управлять программно. Нет API из коробки, нет командной строки. А как вы знаете мне иногда хочется автоматизации: сделать бэкап, перенести заметки в другой формат или дать ИИ-агенту доступ к своим заметкам.\nРешает эту проблему утилита memo — простая CLI для управления Notes.app прямо из терминала.\nУстановка # Утилита ставится через отдельный tap:\nbrew tap antoniorodr/memo brew install antoniorodr/memo/memo При первом запуске macOS может попросит разрешить управление Notes.app (Системные настройки → Конфиденциальность и безопасность → Автоматизация) — нужно нажать «Разрешить», иначе утилита не сможет получить доступ к заметкам.\nОсновные команды # Просмотр заметок:\nmemo notes # список всех заметок memo notes -f \u0026#34;Папка\u0026#34; # только заметки из конкретной папки memo notes -s \u0026#34;запрос\u0026#34; # поиск по тексту Создание:\nmemo notes -a # создать заметку (откроется ваш $EDITOR) memo notes -a -f \u0026#34;Папка\u0026#34; # создать заметку в конкретной папке Редактирование, удаление и перемещение — интерактивные команды, которые показывают список заметок для выбора:\nmemo notes -e # редактировать memo notes -d # удалить memo notes -m # переместить в другую папку Экспорт в Markdown или HTML:\nmemo notes -ex Зачем это нужно # Главный сценарий — автоматизация и моя любовь к CLI утилитам.\nЕщё один сценарий — интеграция с ИИ-ассистентами. Я, например сейчас пробую использовать memo вместе с Hermes: попросил «найди в заметках рецепт» — агент сам выполнил memo notes -s \u0026quot;рецепт\u0026quot; и вернул результат. Заметки остаются в привычном приложении и синхронизируются на iPhone, а агент при этом получает к ним доступ. Да, это бекап несмотря на наличие у меня основного Obsidian.\nОграничения # Заметки с изображениями и вложениями редактировать нельзя — только создавать и просматривать. Работает только на macOS. В остальном это аккуратная и полезная утилита, которая закрывает нишу программного доступа к Заметкам Apple. Если у вас накопилось много заметок и хочется над ними автоматизации — рекомендую попробовать.\n","date":"31 июля 2026","externalUrl":null,"permalink":"/memo/","section":"Posts","summary":"","title":"memo — Заметки Apple из терминала","type":"posts"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/notes/","section":"Tags","summary":"","title":"Notes","type":"tags"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/devops/","section":"Tags","summary":"","title":"Devops","type":"tags"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/launchd/","section":"Tags","summary":"","title":"Launchd","type":"tags"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/plist/","section":"Tags","summary":"","title":"Plist","type":"tags"},{"content":"","date":"31 июля 2026","externalUrl":null,"permalink":"/tags/systemd-alternative/","section":"Tags","summary":"","title":"Systemd-Alternative","type":"tags"},{"content":" На macOS часто хочется сделать то же, что на Linux делается через systemd: запустить скрипт как сервис, автоматически стартовать его при входе в систему или выполнять по расписанию. В macOS для этого есть launchd — встроенный менеджер процессов и задач.\nЕсли коротко: для пользовательских задач обычно нужен LaunchAgent, а для системных — LaunchDaemon. В этой статье разберём, как выбрать правильный вариант, как написать .plist и как убедиться, что всё работает.\nЧто такое launchd # launchd — это базовый механизм запуска сервисов в macOS. Он умеет:\nзапускать задачи при входе пользователя; держать процесс в фоне и перезапускать его при падении; запускать команды по расписанию; писать stdout/stderr в файлы; автоматически подхватывать конфигурацию из .plist. По сути, это не «отдельная утилита», а часть самой системы.\nLaunchAgent или LaunchDaemon # Самый важный выбор — где будет жить задача.\nLaunchAgent # Подходит, если скрипт:\nработает от имени текущего пользователя; должен иметь доступ к пользовательскому окружению; может открывать GUI-приложения; нужен только после логина. Типичный путь:\n~/Library/LaunchAgents/ LaunchDaemon # Подходит, если задача:\nдолжна работать без логина пользователя; запускается от root или системной учётки; обслуживает системный сервис; не должна зависеть от GUI. Типичный путь:\n/Library/LaunchDaemons/ Для большинства «домашних» автоматизаций на Mac — бэкапы, синхронизации, периодические скрипты — почти всегда нужен LaunchAgent.\nМинимальный пример # Допустим, у вас есть скрипт:\n/Users/beaverblogger/Documents/scripts/youtube-cookies/sync_yt_cookies.sh И вы хотите запускать его раз в сутки. Для этого создаём файл:\n~/Library/LaunchAgents/com.tatarinovms.youtube-cookies-sync.plist Пример содержимого:\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;!DOCTYPE plist PUBLIC \u0026#34;-//Apple//DTD PLIST 1.0//EN\u0026#34; \u0026#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd\u0026#34;\u0026gt; \u0026lt;plist version=\u0026#34;1.0\u0026#34;\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;Label\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;com.tatarinovms.youtube-cookies-sync\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;ProgramArguments\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;string\u0026gt;/Users/beaverblogger/Documents/scripts/youtube-cookies/sync_yt_cookies.sh\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt; \u0026lt;key\u0026gt;WorkingDirectory\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;/Users/beaverblogger/Documents/scripts/youtube-cookies\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;StartCalendarInterval\u0026lt;/key\u0026gt; \u0026lt;dict\u0026gt; \u0026lt;key\u0026gt;Hour\u0026lt;/key\u0026gt; \u0026lt;integer\u0026gt;9\u0026lt;/integer\u0026gt; \u0026lt;key\u0026gt;Minute\u0026lt;/key\u0026gt; \u0026lt;integer\u0026gt;0\u0026lt;/integer\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;key\u0026gt;StandardOutPath\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;/Users/tatarinovms/Library/Logs/youtube-cookies-sync.out.log\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;StandardErrorPath\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;/Users/tatarinovms/Library/Logs/youtube-cookies-sync.err.log\u0026lt;/string\u0026gt; \u0026lt;/dict\u0026gt; \u0026lt;/plist\u0026gt; Это уже полноценный сервис по расписанию.\nКакие ключи чаще всего нужны # Label # Уникальное имя сервиса. Обычно используют обратный DNS-стиль:\ncom.company.app-name ProgramArguments # Команда, которую нужно запустить. Лучше указывать полный путь к скрипту или бинарнику.\nWorkingDirectory # Полезно, если скрипт использует относительные пути.\nStartCalendarInterval # Запуск по времени. Можно указать:\nтолько Hour и Minute — каждый день в это время; Weekday — по дням недели; Day — по числам месяца; комбинации. RunAtLoad # Если поставить true, сервис запустится сразу после загрузки агента.\nKeepAlive # Если true, launchd будет пытаться держать процесс живым и перезапускать его. Для бесконечных демонов это удобно, но для одноразовых скриптов по расписанию обычно не нужно.\nStandardOutPath и StandardErrorPath # Очень полезно для отладки. Без логов легко потерять ошибку.\nКак установить сервис # После создания .plist нужно загрузить его в launchd:\nlaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.tatarinovms.youtube-cookies-sync.plist launchctl enable gui/$(id -u)/com.tatarinovms.youtube-cookies-sync Если конфиг уже был загружен и вы его меняете, обычно удобно сначала выгрузить старую версию:\nlaunchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.tatarinovms.youtube-cookies-sync.plist Потом снова выполнить bootstrap.\nКак проверить, что всё работает # Проверка plist # plutil -lint ~/Library/LaunchAgents/com.tatarinovms.youtube-cookies-sync.plist Если файл валидный, увидите OK.\nПроверка статуса # launchctl print gui/$(id -u)/com.tatarinovms.youtube-cookies-sync Там можно увидеть:\nпуть к plist; состояние агента; путь к stdout/stderr; последний код выхода. Ручной запуск # Для теста удобно временно выполнить сам скрипт руками:\n~/Documents/scripts/youtube-cookies/sync_yt_cookies.sh Это особенно полезно перед тем, как отдавать задачу launchd.\nПрактические советы # 1. Делайте скрипт идемпотентным # Сервис может запускаться повторно. Лучше, чтобы повторный запуск не ломал состояние.\n2. Не полагайтесь на интерактивную среду # В launchd обычно нет привычного shell-окружения из терминала. Поэтому:\nиспользуйте абсолютные пути; явно задавайте PATH, если он нужен; не рассчитывайте на alias и функции shell. 3. Логируйте в файл # Если задача не стартует, stdout/stderr в лог-файлы экономят много времени.\n4. Не quitiть чужой браузер или приложение без проверки # Если ваш скрипт запускает Firefox, Safari или другое GUI-приложение, сначала определите, запускали ли вы его сами. Иначе можно случайно закрыть то, что пользователь уже открыл вручную.\n5. Для фона и GUI — LaunchAgent # Если сервис должен открыть браузер, нажать что-то в UI или читать пользовательские cookies, LaunchAgent почти всегда правильнее LaunchDaemon.\nКогда лучше не использовать launchd # Иногда проще и честнее использовать:\nобычный cron, если задача очень простая и не зависит от GUI; at или одноразовый запуск, если нужен только разовый таймер; shortcuts или Automator, если задача чисто пользовательская и без сложной логики. Но если нужен нормальный сервис на macOS, launchd — стандартный путь.\nМой рабочий шаблон # Я обычно придерживаюсь такой схемы:\nСкрипт делает одну вещь. У него есть полный путь к интерпретатору или бинарнику. Есть отдельный лог-файл. Сервис оформлен через LaunchAgent. Конфиг проверяется через plutil -lint. После установки я смотрю launchctl print и тестирую вручную. Так проще отлаживать и проще поддерживать.\nВывод и финал # Если на macOS хочется «сделать сервис», почти всегда нужно идти через launchd.\nLaunchAgent — для пользовательских задач и GUI. LaunchDaemon — для системных фоновых сервисов. .plist — это конфигурация запуска. launchctl bootstrap и launchctl print — базовые команды для установки и проверки. ","date":"31 июля 2026","externalUrl":null,"permalink":"/servisynamacos/","section":"Posts","summary":"","title":"Как делать сервисы на macOS через launchd","type":"posts"},{"content":"","date":"25 июля 2026","externalUrl":null,"permalink":"/tags/homebrew/","section":"Tags","summary":"","title":"Homebrew","type":"tags"},{"content":"","date":"25 июля 2026","externalUrl":null,"permalink":"/tags/thunderbolt/","section":"Tags","summary":"","title":"Thunderbolt","type":"tags"},{"content":"","date":"25 июля 2026","externalUrl":null,"permalink":"/tags/usb-c/","section":"Tags","summary":"","title":"Usb-C","type":"tags"},{"content":"","date":"25 июля 2026","externalUrl":null,"permalink":"/tags/whatcable/","section":"Tags","summary":"","title":"Whatcable","type":"tags"},{"content":" USB-C кабели выглядят одинаково, но внутри могут сильно отличаться. Один кабель поддерживает только зарядку и USB 2.0, другой передаёт данные на скорости 40 Гбит/с, выводит изображение и заряжает ноутбук с мощностью до 240 Вт. По внешнему виду определить это практически невозможно.\nWhatCable GitHub — бесплатное приложение для macOS, которое показывает возможности вашего подключённого USB-C кабеля. Оно читает данные, уже доступные системе через IOKit, и помогает понять, что ограничивает соединение: порт Mac, кабель, зарядное устройство, переходник или подключённое устройство.\nЧто показывает WhatCable # В бесплатной версии можно посмотреть:\nтип соединения: USB 2, USB 3, USB4, Thunderbolt или DisplayPort; заявленную e-marker скорость кабеля и допустимую мощность; мощность зарядного устройства и выбранный профиль питания; скорость подключённого накопителя, хаба или другого устройства; компонент, который ограничивает скорость передачи данных или зарядку; предупреждения о сбоях соединения и превышении тока; данные производителя кабеля, если они доступны; подозрительные значения e-marker, не совпадающие со спецификацией USB Power Delivery. Приложение находится в строке меню и показывает информацию отдельно по каждому порту.\nУстановка # Устанавливаем WhatCable через Homebrew:\nbrew install --cask darrylmorley/whatcable/whatcable Важно: WhatCable работает только на Mac с Apple Silicon и требует macOS 14 Sonoma или новее. Intel Mac не поддерживаются, потому что macOS не предоставляет приложению необходимые данные контроллера USB-C портов.\nWhatCable Pro # Бесплатной версии хватает заглаза в общем и целом, но если у вас есть чем платить и не жалко £9.99, то велком на WhatCable Pro. Лицензия работает на двух Mac.\nPro добавляет:\nCable history — позволяет дать кабелю имя, узнать его при следующем подключении и сохранить историю работы; Negotiation Diagnostics — сравнивает возможности порта Mac, кабеля и устройства с фактическим соединением, выделяя ограничивающий компонент; Display Diagnostics — сравнивает лучший режим монитора с текущим DisplayPort-соединением и определяет переходники в цепочке; Live power metering — показывает мощность, ток и напряжение каждого порта в реальном времени с обновлением каждые две секунды; PD contract inspector — раскрывает текущий контракт USB Power Delivery, активные напряжение и ток, доступные PDO и найденные несовпадения; Cable resistance estimation — оценивает сопротивление кабеля в миллиомах по нескольким измерениям и помогает обнаружить изношенный или нестабильный кабель; Port health counters — показывает количество подключений, отключений, жёстких сбросов, коротких замыканий, ошибок I2C, смен ролей и отказов FET для каждого порта; PD event trace — выводит историю событий протокола USB Power Delivery: подключения, отключения, согласование питания и жёсткие сбросы. ","date":"25 июля 2026","externalUrl":null,"permalink":"/whatcable/","section":"Posts","summary":"","title":"WhatCable — проверяем возможности USB-C кабелей на Mac","type":"posts"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/tags/cookies/","section":"Tags","summary":"","title":"Cookies","type":"tags"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/tags/firefox/","section":"Tags","summary":"","title":"Firefox","type":"tags"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/categories/podcasts/","section":"Categories","summary":"","title":"Podcasts","type":"categories"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/categories/podsync/","section":"Categories","summary":"","title":"Podsync","type":"categories"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/tags/podsync/","section":"Tags","summary":"","title":"Podsync","type":"tags"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/tags/python/","section":"Tags","summary":"","title":"Python","type":"tags"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/tags/youtube/","section":"Tags","summary":"","title":"Youtube","type":"tags"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/categories/youtube/","section":"Categories","summary":"","title":"YouTube","type":"categories"},{"content":"","date":"21 июля 2026","externalUrl":null,"permalink":"/tags/%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F/","section":"Tags","summary":"","title":"Автоматизация","type":"tags"},{"content":" YouTube всё чаще требует авторизацию даже для обычного скачивания видео. У меня это проявилось в Podsync, про который я писал ранее: yt-dlp на сервере переставал получать ролики.\nРешение простое: забрать актуальные cookies из локального Firefox, перевести их в Netscape-формат, отправить на сервер и перезапустить Podsync. Чтобы не делать эти шаги вручную, я собрал маленький проект youtube-cookies.\nЧто получилось # Проект лежит в ~/Documents/scripts/youtube-cookies/:\nyoutube-cookies/ ├── .venv/ ├── extract_yt_cookies.py ├── requirements.txt ├── setup.sh └── sync_yt_cookies.sh extract_yt_cookies.py читает cookies из Firefox и сохраняет их в формате Mozilla/Netscape; sync_yt_cookies.sh отправляет файл на сервер, создаёт резервную копию и перезапускает Podsync; requirements.txt хранит список Python-зависимостей; setup.sh создаёт локальный .venv и устанавливает зависимости; .venv/ содержит установленную библиотеку rookiepy Готовые файлы # extract_yt_cookies.py requirements.txt setup.sh sync_yt_cookies.sh mkdir -p ~/Documents/scripts/youtube-cookies cd ~/Documents/scripts/youtube-cookies curl -O https://blog.tatarinovms.space/scripts/youtubecookies/extract_yt_cookies.py curl -O https://blog.tatarinovms.space/scripts/youtubecookies/requirements.txt curl -O https://blog.tatarinovms.space/scripts/youtubecookies/setup.sh curl -O https://blog.tatarinovms.space/scripts/youtubecookies/sync_yt_cookies.sh chmod +x setup.sh sync_yt_cookies.sh extract_yt_cookies.py После скачивания отредактируйте sync_yt_cookies.sh: замените SERVER=\u0026quot;homeserverbeaver\u0026quot; на ваш SSH-хост и проверьте путь к REMOTE_COOKIE_FILE на сервере.\nЧто понадобится # На Mac должны быть установлены Python 3.11 или 3.12 и Firefox с залогниненым Youtube. Для Python через Homebrew:\nbrew install python@3.12 Нужен настроенный SSH alias сервера. У меня он называется homeserverbeaver и описан в ~/.ssh/config:\nHost homeserverbeaver HostName 192.1.1.1 User root IdentityFile ~/.ssh/serverbeaverhome На сервере Podsync читает cookies из файла:\n/etc/podsync/youtube-cookies.txt Путь должен совпадать с настройкой Podsync или аргументами yt-dlp.\nНастройка Podsync # Одного файла /etc/podsync/youtube-cookies.txt мало. Podsync сам по себе не догадается его использовать: нужно передать путь в yt-dlp через youtube_dl_args в config.toml.\nУ меня конфиг лежит здесь:\n/mnt/dietpi_userdata/podsync/config.toml В каждом фиде добавлен аргумент --cookies:\n[feeds] [feeds.ChannelName] url = \u0026#34;https://www.youtube.com/@channel\u0026#34; format = \u0026#34;audio\u0026#34; update_period = \u0026#34;8h\u0026#34; youtube_dl_args = [ \u0026#34;--js-runtimes\u0026#34;, \u0026#34;deno:/root/.deno/bin/deno\u0026#34;, \u0026#34;--cookies\u0026#34;, \u0026#34;/etc/podsync/youtube-cookies.txt\u0026#34;, \u0026#34;--extractor-args\u0026#34;, \u0026#34;youtube:player_client=default\u0026#34; ] После правки конфига перезапускаем Podsync:\nsystemctl restart podsync А уже потом запускаем синхронизацию cookies с Mac. Скрипт обновит файл и ещё раз перезапустит сервис.\nЭкспорт cookies из Firefox # Для чтения cookies использую библиотеку rookiepy. Она достаёт данные из профиля браузера без ручного экспорта через расширение.\nЗависимость записана в requirements.txt:\nrookiepy Сам экспорт выглядит так:\nimport http.cookiejar import sys import rookiepy def export_cookies(output_file: str) -\u0026gt; None: raw = rookiepy.firefox( domains=[\u0026#34;.youtube.com\u0026#34;, \u0026#34;.google.com\u0026#34;, \u0026#34;.googlevideo.com\u0026#34;] ) if not raw: print(\u0026#34;ERROR: no YouTube cookies found\u0026#34;, file=sys.stderr) sys.exit(1) cookie_jar = http.cookiejar.MozillaCookieJar(output_file) for cookie in raw: cookie_jar.set_cookie( http.cookiejar.Cookie( version=0, name=cookie[\u0026#34;name\u0026#34;], value=cookie[\u0026#34;value\u0026#34;], port=None, port_specified=False, domain=cookie[\u0026#34;domain\u0026#34;], domain_specified=True, domain_initial_dot=cookie[\u0026#34;domain\u0026#34;].startswith(\u0026#34;.\u0026#34;), path=cookie[\u0026#34;path\u0026#34;], path_specified=True, secure=cookie[\u0026#34;secure\u0026#34;], expires=cookie[\u0026#34;expires\u0026#34;], discard=False, comment=None, comment_url=None, rest={}, rfc2109=False, ) ) cookie_jar.save(ignore_discard=True, ignore_expires=True) Я забираю только домены YouTube, Google и Google Video. На выходе получается обычный cookies-файл, который понимает yt-dlp.\nПри первом запуске macOS может запросить доступ Python или терминала к данным Firefox. Доступ нужно разрешить в системных настройках.\nСоздание Python-окружения # Устанавливать rookiepy глобально не хочется, поэтому зависимости живут в .venv. Скрипт setup.sh выбирает Python 3.12 или 3.11, пересоздаёт окружение и запускает pip:\n#!/bin/bash set -euo pipefail SCRIPT_DIR=\u0026#34;$(cd \u0026#34;$(dirname \u0026#34;$0\u0026#34;)\u0026#34; \u0026amp;\u0026amp; pwd)\u0026#34; VENV=\u0026#34;$SCRIPT_DIR/.venv\u0026#34; if command -v python3.12 \u0026gt;/dev/null 2\u0026gt;\u0026amp;1; then PYTHON=\u0026#34;python3.12\u0026#34; elif command -v python3.11 \u0026gt;/dev/null 2\u0026gt;\u0026amp;1; then PYTHON=\u0026#34;python3.11\u0026#34; else echo \u0026#34;Установите Python 3.11 или 3.12\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi rm -rf \u0026#34;$VENV\u0026#34; \u0026#34;$PYTHON\u0026#34; -m venv \u0026#34;$VENV\u0026#34; \u0026#34;$VENV/bin/python3\u0026#34; -m pip install --upgrade pip \u0026#34;$VENV/bin/python3\u0026#34; -m pip install -r \u0026#34;$SCRIPT_DIR/requirements.txt\u0026#34; Запуск:\ncd ~/Documents/scripts/youtube-cookies ./setup.sh В моём случае системный python3 уже был версии 3.14, но rookiepy 0.5.6 использует старую версию PyO3 и с Python 3.14 не собирается. Поэтому выбор 3.11/3.12 здесь не прихоть, а совместимость.\nОтправка cookies на сервер # Основной скрипт сначала проверяет окружение, извлекает cookies во временный файл и отправляет его через scp:\nSCRIPT_DIR=\u0026#34;$(cd \u0026#34;$(dirname \u0026#34;$0\u0026#34;)\u0026#34; \u0026amp;\u0026amp; pwd)\u0026#34; VENV_PYTHON=\u0026#34;$SCRIPT_DIR/.venv/bin/python3\u0026#34; LOCAL_COOKIE_FILE=\u0026#34;${TMPDIR:-/tmp}/yt_cookies.txt\u0026#34; SERVER=\u0026#34;homeserverbeaver\u0026#34; trap \u0026#39;rm -f \u0026#34;$LOCAL_COOKIE_FILE\u0026#34;\u0026#39; EXIT INT TERM umask 077 \u0026#34;$VENV_PYTHON\u0026#34; \u0026#34;$SCRIPT_DIR/extract_yt_cookies.py\u0026#34; \u0026#34;$LOCAL_COOKIE_FILE\u0026#34; scp \u0026#34;$LOCAL_COOKIE_FILE\u0026#34; \u0026#34;$SERVER:/tmp/yt_cookies_new.txt\u0026#34; umask 077 не даёт другим локальным пользователям прочитать новый файл. trap удаляет его после успешного запуска, ошибки или сигнала.\nНа сервере одна SSH-команда выполняет установку:\nssh \u0026#34;$SERVER\u0026#34; \u0026#34;if [ -f \u0026#39;/etc/podsync/youtube-cookies.txt\u0026#39; ]; then cp \u0026#39;/etc/podsync/youtube-cookies.txt\u0026#39; \u0026#39;/etc/podsync/youtube-cookies.txt.bak\u0026#39; fi mv /tmp/yt_cookies_new.txt \u0026#39;/etc/podsync/youtube-cookies.txt\u0026#39; \u0026amp;\u0026amp; chmod 600 \u0026#39;/etc/podsync/youtube-cookies.txt\u0026#39; \u0026amp;\u0026amp; systemctl restart podsync\u0026#34; Старый файл сохраняется как .bak, новый получает права 600, затем сервис перезапускается. Если любой шаг завершится ошибкой, shell не продолжит цепочку после \u0026amp;\u0026amp;.\nПолный запуск:\n~/Documents/scripts/youtube-cookies/sync_yt_cookies.sh Почему .venv не надо синхронизировать # Мои скрипты синхронизируются с Яндекс Диском и гитом через rclone bisync. Сначала туда хотел сунуть и virtualenv, но это плохая идея по нескольким причинам:\nв .venv тысячи мелких файлов; библиотеки занимают намного больше места, чем исходники; исполняемые файлы содержат абсолютные пути; бинарные модули зависят от версии Python, архитектуры и macOS; после переустановки скопированное окружение может не запуститься. В свой bisync скрипт добавил исключения:\n--exclude \u0026#34;**/.venv/**\u0026#34; --exclude \u0026#34;**/venv/**\u0026#34; --exclude \u0026#34;**/__pycache__/**\u0026#34; --exclude \u0026#34;**/*.pyc\u0026#34; --exclude \u0026#34;**/*.pyo\u0026#34; В облаке и гите остаются только исходники, requirements.txt и setup.sh. Это и есть переносимая часть проекта.\nВосстановление после переустановки # После чистой установки macOS порядок такой:\nУстановить Python 3.12: brew install python@3.12 Восстановить папку ~/Documents/scripts из Яндекс Диска или гита\nСоздать новое окружение:\ncd ~/Documents/scripts/youtube-cookies ./setup.sh Проверить SSH-подключение: ssh homeserverbeaver Отправить свежие cookies: ./sync_yt_cookies.sh Копировать старый .venv и вручную вспоминать команды pip install не требуется. requirements.txt описывает зависимости, а setup.sh полностью восстанавливает окружение.\nАвтоматический запуск # Скрипт можно запускать вручную после повторной авторизации YouTube или поставить в launchd. Я пока предпочитаю ручной запуск: cookies меняются не каждый день.\nЕсли нужна автоматизация, достаточно запускать эту команду по расписанию:\n~/Documents/scripts/youtube-cookies/sync_yt_cookies.sh Перед этим стоит убедиться, что SSH-ключ работает без интерактивного ввода пароля.\nВажный момент # Cookies дают доступ к авторизованной сессии YouTube. Их нельзя коммитить в git, складывать в общедоступное облако или отправлять в логи. В этой схеме файл существует локально только во время запуска, передаётся по SSH и хранится на сервере с правами 600.\nИтог # Получилась короткая цепочка: Firefox на Mac, rookiepy, временный Netscape cookies-файл, scp, backup на сервере и restart Podsync. Исходники спокойно синхронизируются через Яндекс Диск и гит, а тяжёлый и непереносимый .venv создаётся заново одной командой.\n","date":"21 июля 2026","externalUrl":null,"permalink":"/youtubecookies/","section":"Posts","summary":"","title":"Автоматическая синхронизация YouTube cookies с Podsync","type":"posts"},{"content":"","date":"18 июля 2026","externalUrl":null,"permalink":"/tags/hugo/","section":"Tags","summary":"","title":"Hugo","type":"tags"},{"content":"","date":"18 июля 2026","externalUrl":null,"permalink":"/tags/json-ld/","section":"Tags","summary":"","title":"Json-Ld","type":"tags"},{"content":"","date":"18 июля 2026","externalUrl":null,"permalink":"/categories/meta/","section":"Categories","summary":"","title":"Meta","type":"categories"},{"content":"","date":"18 июля 2026","externalUrl":null,"permalink":"/tags/open-graph/","section":"Tags","summary":"","title":"Open-Graph","type":"tags"},{"content":"","date":"18 июля 2026","externalUrl":null,"permalink":"/tags/schema-org/","section":"Tags","summary":"","title":"Schema-Org","type":"tags"},{"content":"","date":"18 июля 2026","externalUrl":null,"permalink":"/categories/seo/","section":"Categories","summary":"","title":"Seo","type":"categories"},{"content":"","date":"18 июля 2026","externalUrl":null,"permalink":"/tags/seo/","section":"Tags","summary":"","title":"Seo","type":"tags"},{"content":" Зачем это надо было # Блог — это не только для людей. Всё больше контента потребляют нейросети, поисковые боты и автономные агенты. Обычный блог им \u0026ldquo;читаем\u0026rdquo;, но без структуры теряется контекст: кто автор, когда опубликовано, о чём пост, есть ли превью-картинка да и для SEO говорят в наше время полезно.\nРаньше у меня в большинстве постов поле description было пустым, не было машинно-читаемой разметки. Агент, открывший страницу, видел кашу из заголовка и куска текста без понимания что это вообще статья.\nЧто сделано # 1. JSON-LD разметка (schema.org) # Добавил структурированные данные прямо в \u0026lt;head\u0026gt; каждой страницы. Для постов — тип BlogPosting (через layouts/posts/single.html, блок head), для страниц типа «О себе» и «CV» — WebPage (через layouts/partials/head/custom-icons.html).\nЧто внутри:\nheadline — заголовок description — описание (берётся из фронтматтера или автогенерится из текста) datePublished / dateModified — даты author / publisher — кто написал, кто публикует image — логотип поста url — каноническая ссылка Пример для поста:\n{ \u0026#34;@context\u0026#34;: \u0026#34;https://schema.org\u0026#34;, \u0026#34;@type\u0026#34;: \u0026#34;BlogPosting\u0026#34;, \u0026#34;headline\u0026#34;: \u0026#34;YouTube MCP: скачиваем видео и вшиваем субтитры\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Я запилил эмсипи-сервер для оупенкода...\u0026#34;, \u0026#34;datePublished\u0026#34;: \u0026#34;2026-07-01T18:00:00+05:00\u0026#34;, \u0026#34;author\u0026#34;: [{ \u0026#34;@type\u0026#34;: \u0026#34;Person\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Maxim S. Tatarinov\u0026#34; }] } 2. Open Graph и Twitter Cards # Раньше тема (hugo-coder) генерила базовые OG-теги, но с пустыми описаниями они были бесполезны. Теперь:\nog:title, og:description, og:type, og:image — заполняются автоматически article:published_time, article:author, article:tag — для статей twitter:card = summary_large_image с логотипом поста (крупная картинка-превью) Логотип поста (/images/posts/\u0026lt;slug\u0026gt;/logo.webp) подхватывается из контента автоматически через регулярку — руками ничего прописывать не надо.\n3. Чистка дублей # Тема дёргала внутренние шаблоны Hugo (_internal/opengraph.html, _internal/twitter_cards.html), которые дублировали мои OG-теги. Отключил их в override layouts/partials/head/meta-tags.html для постов (чтобы не было двух og:* подряд), а custom-icons.html генерирует OG/Twitter для всех страниц. JSON-LD для постов живёт в layouts/posts/single.html (блок head), для about/cv — в custom-icons.html.\n4. Архетип и контент # Обновил archetypes/default.md — новые посты сразу получают description, tags, categories по умолчанию Прогнал все ~70 старых постов и заполнил им description из первых абзацев Добавил описания на страницы about и cv Какие преимущества # Лучшее понимание агентами. Языковая модель, получившая ссылку на пост, видит чёткую структуру: что это статья, кто автор, о чём, когда вышла. Меньше галлюцинаций при пересказе. Красивые превью при шаринге. В чатах, соцсетях и MCP-инструментах посты теперь показывают картинку и описание, а не пустоту. SEO. JSON-LD — стандарт для поисковиков. Google и Bing лучше индексируют структурированный контент. Будущее-proof. Если завтра появится новый агент или протокол, читающий schema.org — блог уже готов. Единообразие. Все посты теперь имеют описания, картинки и метаданные по одному шаблону. Как проверить # Собрать и глянуть исходники:\nhugo --minify grep -A 20 \u0026#39;ld+json\u0026#39; public/posts/\u0026lt;slug\u0026gt;/index.html Или открыть любой пост и найти в \u0026lt;head\u0026gt; блок \u0026lt;script type=\u0026quot;application/ld+json\u0026quot;\u0026gt;.\nИтог # Блог стал не просто «сайтом для людей», а машинно-читаемым ресурсом. Агенты, боты и нейросети теперь получают контекст сразу.\n","date":"18 июля 2026","externalUrl":null,"permalink":"/agentreadableblog/","section":"Posts","summary":"","title":"Делаем блог удобным для ИИ-агентов","type":"posts"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/caveman/","section":"Tags","summary":"","title":"Caveman","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/git/","section":"Tags","summary":"","title":"Git","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/llm/","section":"Tags","summary":"","title":"Llm","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/mcp/","section":"Tags","summary":"","title":"Mcp","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/openchamber/","section":"Tags","summary":"","title":"Openchamber","type":"tags"},{"content":" OpenChamber — это веб-интерфейс для агента OpenCode. В этой заметке я опишу, как поднять его на домашнем сервере с DietPi и получить доступ к веб-морде из любой точки через Tailscale.\nЗачем это нужно # OpenCode из коробки — это терминальный агент, да у него есть своя мордашка, но она страшная. OpenChamber добавляет к нему веб-морду: удобный UI, управление сессиями и просмотр того, что делает агент, прямо из браузера. Также он дает например удобную консоль. Связка «DietPi-сервер + Tailscale» позволяет держать агента дома, не открывая порты в интернет.\nOpenChamber сам управляет OpenCode — то есть отдельно агента поднимать не нужно, веб-интерфейс запускает и контролирует его сам.\n1. Подготовка системы # OpenChamber — Node.js-приложение, а OpenCode — бинарь, который OpenChamber запускает.\n# обновляем систему sudo apt update \u0026amp;\u0026amp; sudo apt upgrade -y # Node.js + npm (на DietPi можно через dietpi-software или напрямую) curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt install -y nodejs node --version \u0026amp;\u0026amp; npm --version 2. Установка OpenCode # OpenChamber сам управляет OpenCode, но бинарь должен быть доступен в PATH. Официальный способ установки:\n# через curl-инсталлятор curl -fsSL https://opencode.ai/install | sh # либо через npm: npm install -g opencode-ai После установки убедитесь, что бинарь доступен и лежит в каталоге, который попадёт в PATH сервиса (в примере — /root/.opencode/bin/opencode). Проверка:\nopencode --version Обновление OpenCode в будущем:\nopencode upgrade 3. Установка OpenChamber # OpenChamber ставится глобально через npm:\nnpm install -g @openchamber/web После установки появляется команда openchamber:\nwhich openchamber # /usr/local/bin/openchamber openchamber --version # 1.16.2 Каталог данных OpenChamber по умолчанию: ~/.config/openchamber (в нашем случае /root/.config/openchamber).\nUI-пароль (обязателен для не-loopback привязки) # OpenChamber отказывается слушать не-loopback адрес** (например Tailscale-IP или 0.0.0.0), если не настроена UI-аутентификация.\nПоэтому пароль всегда передаётся при запуске через env-переменную или флаг. Придумайте свой пароль и используйте его далее (в примерах ниже — YOUR_UI_PASSWORD).\nДа, есть конечно OPENCHAMBER_ALLOW_UNAUTHENTICATED_LAN=true как обходной путь без пароля, но это сделает веб-интерфейс полностью открытым. Как-то не по христиански это.\n4. Определяем адрес для привязки # OpenChamber нужно привязать к IP, по которому вы будете заходить. Для доступа через Tailscale берём Tailscale-IP:\ntailscale ip Порт выбираем любой свободный (в примере — 8094).\n5. Автозапуск через systemd # На сервере без активной пользовательской сессии systemctl --user и loginctl enable-linger обычно недоступны (нет user D-Bus). Поэтому используем system-сервис (PID 1 systemd).\nСоздайте файл /etc/systemd/system/openchamber.service:\n[Unit] Description=OpenChamber Web interface for OpenCode After=network-online.target Wants=network-online.target [Service] Type=simple User=root Group=root WorkingDirectory=/root Environment=HOME=/root Environment=XDG_RUNTIME_DIR=/run/user/0 # ЗАМЕНИТЕ на свой пароль: Environment=OPENCHAMBER_UI_PASSWORD=YOUR_UI_PASSWORD Environment=PATH=/root/.opencode/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # ЗАМЕНИТЕ \u0026lt;TAILSCALE_IP\u0026gt; на ваш Tailscale-IP, порт — при необходимости: ExecStartPre=/usr/bin/mkdir -p /run/user/0 ExecStartPre=/usr/bin/chown root:root /run/user/0 ExecStart=/usr/local/bin/openchamber serve --foreground --host \u0026lt;TAILSCALE_IP\u0026gt; --port 8094 Restart=on-failure RestartSec=5 KillSignal=SIGTERM TimeoutStopSec=30 [Install] WantedBy=multi-user.target Пояснения:\nExecStart=/usr/local/bin/openchamber serve --foreground ... — ключ --foreground нужен для Type=simple, чтобы systemd держал процесс. OPENCHAMBER_UI_PASSWORD — обязателен для привязки к не-loopback IP. PATH явно включает /root/.opencode/bin, чтобы OpenChamber нашёл бинарь OpenCode (в системном сервисе PATH урезан). ExecStartPre создаёт /run/user/0, т.к. этот каталог не существует в system-сервисе по умолчанию и стирается при перезагрузке. Ограничьте права на файл (в нём лежит пароль):\nchmod 600 /etc/systemd/system/openchamber.service Активация:\nsudo systemctl daemon-reload sudo systemctl enable --now openchamber Проверка:\nsystemctl status openchamber --no-pager systemctl is-active openchamber # active systemctl is-enabled openchamber # enabled 6. Проверяем работоспособность # Health-эндпоинт (показывает, поднят ли managed OpenCode):\ncurl -s http://\u0026lt;TAILSCALE_IP\u0026gt;:8094/health | head -c 400; echo Ожидаемый результат: \u0026quot;status\u0026quot;:\u0026quot;ok\u0026quot; и openCodeRunning:true.\nСтатус самого OpenChamber:\nopenchamber status Откройте в браузере: http://\u0026lt;TAILSCALE_IP\u0026gt;:8094 и введите свой UI-пароль.\nУправление:\nsudo systemctl restart openchamber # перезапуск (также перезапускает OpenCode) sudo systemctl stop openchamber sudo systemctl start openchamber openchamber logs -p 8094 # логи (follow) Готово — веб-морда OpenCode крутится на домашнем сервере и доступна через Tailscale отовсюду.\nЕсли хочется пофлексить с телефона, то OpenChamber отлично работает на как PWA.\n","date":"17 июля 2026","externalUrl":null,"permalink":"/openchamber/","section":"Posts","summary":"","title":"OpenChamber: веб-морда для OpenCode на DietPi","type":"posts"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/opencode/","section":"Tags","summary":"","title":"Opencode","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/categories/opencode/","section":"Categories","summary":"","title":"OpenCode","type":"categories"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/server/","section":"Tags","summary":"","title":"Server","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/setup/","section":"Tags","summary":"","title":"Setup","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/skills/","section":"Tags","summary":"","title":"Skills","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/tailscale/","section":"Tags","summary":"","title":"Tailscale","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/tokens/","section":"Tags","summary":"","title":"Tokens","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0/","section":"Tags","summary":"","title":"Настройка","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/%D0%BE%D1%83%D0%BF%D0%B5%D0%BD%D0%BA%D0%BE%D0%B4/","section":"Tags","summary":"","title":"Оупенкод","type":"tags"},{"content":"","date":"17 июля 2026","externalUrl":null,"permalink":"/tags/%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F/","section":"Tags","summary":"","title":"Синхронизация","type":"tags"},{"content":" Зачем это нужно # У меня в opencode накопилось несколько скиллов и MCP-серверов: конвертер в маркдаун, поиск в duckduckgo, deepwiki и т.д Раньше они лежали где попало. Переезжаешь на другую машину или слетает конфиг — и всё, собирай заново.\nЗахотелось одного: чтобы всё было в git-репозиториях как единственный источник правды, а opencode просто читал оттуда. И чтобы обновление было в одну команду, а не ручной перенос файлов.\nЧто получилось # Два отдельных репозитория:\nskills — папки с SKILL.md, по одной на каждый скилл mcp — пайтон-скрипты MCP-серверов, opencode.jsonc и requirements.txt И два скрипта в ~/Documents/scripts/, которые «разворачивают» репозитории в нужные места opencode через symlink\u0026rsquo;и.\nКак это работает # Каждый скрипт сначала делает git pull, чтобы подтянуть свежие правки, а потом расставляет symlink\u0026rsquo;и.\nsync_skills.sh # Проходит по папкам репозитория, берёт только те, где есть SKILL.md, и симлинкует их в ~/.opencode/skills/. Если там уже лежит настоящая папка — заменяет её на symlink. Флаг --prune подчищает осиротевшие ссылки на удалённые скиллы.\nREPO_SKILLS=\u0026#34;~/Documents/project/skills\u0026#34; OPENCODE_SKILLS=\u0026#34;$HOME/.opencode/skills\u0026#34; git -C \u0026#34;$REPO_SKILLS\u0026#34; pull --ff-only mkdir -p \u0026#34;$OPENCODE_SKILLS\u0026#34; for dir in \u0026#34;$REPO_SKILLS\u0026#34;/*/; do name=$(basename \u0026#34;$dir\u0026#34;) [[ \u0026#34;$name\u0026#34; == \u0026#34;.git\u0026#34; ]] \u0026amp;\u0026amp; continue [[ -f \u0026#34;$dir/SKILL.md\u0026#34; ]] || continue target=\u0026#34;$OPENCODE_SKILLS/$name\u0026#34; ln -sfn \u0026#34;$dir\u0026#34; \u0026#34;$target\u0026#34; done sync_mcp.sh # С symlink\u0026rsquo;ами тут тоньше: сам конфиг opencode.jsonc и скрипты серверов симлинкуются в ~/.config/opencode/, а вот venv в git не кладём — он тяжёлый и генерится локально из requirements.txt.\nMCP_REPO=\u0026#34;~/Documents/project/mcp\u0026#34; MCP_DIR=\u0026#34;$HOME/.config/opencode/mcp\u0026#34; git -C \u0026#34;$MCP_REPO\u0026#34; pull --ff-only ln -sfn \u0026#34;$MCP_REPO\u0026#34;/*.py \u0026#34;$MCP_DIR/\u0026#34; ln -sfn \u0026#34;$MCP_REPO/opencode.jsonc\u0026#34; \u0026#34;$HOME/.config/opencode/opencode.jsonc\u0026#34; python3 -m venv \u0026#34;$MCP_DIR/venv\u0026#34; \u0026#34;$MCP_DIR/venv/bin/python3\u0026#34; -m pip install -r \u0026#34;$MCP_REPO/requirements.txt\u0026#34; После этого достаточно перезапустить opencode — и он видит и скиллы, и MCP-серверы.\nПочему symlink, а не копия # Правки в репозитории (новый скилл, правка промпта MCP) сразу видны opencode — никакого копирования. Коммитим в git, пушим в gitverse/github, и на другой машине git pull + запуск скрипта возвращают всю настройку.\nКак добавить новый скилл # Скилл — это папка с обязательным файлом SKILL.md (в нём front matter с полями name и description). Добавляется в три шага:\nСоздать папку в репо skills: mkdir -p ~/Documents/project/skills/my-new-skill # положить туда SKILL.md Закоммитить в репо skills (git add/commit, при желании push). Запустить sync — скрипт сам найдёт папку с SKILL.md и создаст symlink в ~/.opencode/skills/: bash ~/Documents/scripts/sync_skills.sh OpenCode подхватит скилл при следующем вызове (перезапуск не обязателен, но надёжнее). Удалить скилл так же просто: убрать папку из репо, закоммитить и вызвать sync_skills.sh --prune — он удалит осиротевший symlink.\nКак добавить новый MCP # Вся настройка MCP живёт в репо ~/Documents/project/mcp, а opencode читает её через symlink. Поэтому «добавить MCP» = пополнить репо и один раз запустить sync_mcp.sh. Править live-файлы в ~/.config/opencode/ напрямую не нужно — они перезапишутся симлинком.\nЛокальный python-сервер (как markitdown-mcp) # Допустим, новый сервер foobar_server.py:\nПоложить скрипт в репо: ~/Documents/project/mcp/foobar_server.py. Дописать его зависимости в ~/Documents/project/mcp/requirements.txt. Добавить блок в ~/Documents/project/mcp/opencode.jsonc: \u0026#34;foobar\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;local\u0026#34;, \u0026#34;command\u0026#34;: [ \u0026#34;/Users/tatarinovms/.config/opencode/mcp/venv/bin/python3\u0026#34;, \u0026#34;/Users/tatarinovms/.config/opencode/mcp/foobar_server.py\u0026#34; ] } Пути в command — live (~/.config/opencode/mcp/...), а не репо-пути. Sync сам симлинкует скрипт именно туда, так что они совпадут.\ngit add/commit в репо mcp. bash ~/Documents/scripts/sync_mcp.sh — симлинкует новый .py, обновит symlink opencode.jsonc и выполнит pip install -r requirements.txt, добавив зависимость в локальный venv. Перезапустить opencode. Remote / uvx (как deepwiki, ddg-search) # Без скрипта и без venv. Только:\nДобавить блок в репо-opencode.jsonc (type: \u0026quot;remote\u0026quot; с url либо type: \u0026quot;local\u0026quot; с uvx ...). git commit + sync_mcp.sh (обновит symlink конфига) + перезапуск opencode. Для uvx-серверов убедись, что uvx есть в PATH; для remote — что URL доступен.\nНюансы: не редактируй ~/.config/opencode/opencode.jsonc вручную (это symlink на репо, правки «провалятся» в репо, но потеряются при git pull без коммита — правь репо-файл); venv локальный и в git не ходит (новые python-зависимости = правка requirements.txt + перезапуск sync); после любой правки конфига обязателен перезапуск opencode.\nНастройка на новой инсталляции OpenCode # Переезд на чистую машину сводится к клонированию двух репозиториев и запуску пары скриптов:\nПоставить opencode, а также node и python3 (нужны для venv и MCP). Клонировать репозитории (куда удобно — пути должны совпадать с теми, что прописаны в скриптах, либо поправить пути в самих скриптах Перенести sync-скрипты в ~/Documents/scripts/ (они у меня синкаются тоже через Я.Диск): sync_skills.sh и sync_mcp.sh. Запустить синхронизацию — скрипты расставят symlink\u0026rsquo;и и создадут локальный venv из requirements.txt: bash ~/Documents/scripts/sync_skills.sh \u0026amp;\u0026amp; bash ~/Documents/scripts/sync_mcp.sh Перезапустить opencode — скиллы и MCP-серверы на месте. Если MCP-серверы используют внешние бинари (например, yt-dlp/ffmpeg для youtube), не забудь поставить и их.\nИтог # Пара скриптов и два репозитория — и вся настройка opencode теперь версионируется и переносится одной командой. Новый скилл добавляется как папка с SKILL.md в репо + sync_skills.sh, новый MCP — как скрипт + блок в opencode.jsonc + sync_mcp.sh. Полный перенос на новую машину — это git clone двух репозиториев, копия скриптов и один запуск синхронизации.\n","date":"17 июля 2026","externalUrl":null,"permalink":"/opencodeskillsmcpsync/","section":"Posts","summary":"","title":"Синхронизация скиллов и MCP opencode через git-репозитории","type":"posts"},{"content":" Зачем это нужно # Современные ИИ-агенты любят многословие. На каждый вопрос они выдают простыню текста с вежливыми вступлениями, пояснениями и повторами. Это тратит output-токены, а значит — деньги и время.\ncaveman — это скилл/плагин для Claude Code, Codex, Gemini, Cursor, opencode и 30+ других агентов. Он заставляет агента отвечать «по-пещерному»: коротко, фрагментами, без статей и воды. По замерам автора — в среднем 65% экономии output-токенов.\nПо итогу у нас будет:\nNew ref each render. Wrap object in useMemo.\nВместо:\nThe reason your React component is re-rendering is likely because you\u0026rsquo;re creating a new object reference on each render cycle. When you pass an inline object as a prop, React\u0026rsquo;s shallow comparison sees it as a different object every time, which triggers a re-render. I\u0026rsquo;d recommend using useMemo to memoize the object.\nУровни сжатия # Шесть уровней. Переключаются командой /caveman \u0026lt;level\u0026gt; и держатся до конца сессии:\nУровень Поведение lite Лёгкое сжатие, читается почти нормально full Дефолт. Короткие фразы-фрагменты ultra Максимальная рубленость wenyan Классический китайский, ещё плотнее по смыслу Язык ответа сохраняется: пишешь по-русски — агент рыкает по-русски.\nУстановка (универсальная) # Одна команда находит все агенты на машине и ставит под каждый:\n# macOS / Linux / WSL / Git Bash curl -fsSL https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.sh | bash # Windows (PowerShell 5.1+) irm https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.ps1 | iex Нужен Node ≥ 18. Установщик пропускает агентов, которых нет.\nУстановка под opencode # Для opencode есть нативный путь. Установщик сам детектит агента и прописывает плагин:\nnpx -y github:JuliusBrussee/caveman -- --only opencode Что он делает:\nкладёт плагин в ~/.config/opencode/plugins/caveman/ добавляет plugin в конфиг opencode прописывает команды, скиллы и агентов в ~/.config/opencode/{commands,skills,agents}/ вписывает блок caveman в AGENTS.md Тонкость с конфигом. Установщик правит opencode.json, но если ты пользуешься opencode.jsonc (например, через симлинк как я), плагин не подхватится. Нужно вручную добавить в .jsonc:\n\u0026#34;plugin\u0026#34;: [ \u0026#34;./plugins/caveman/plugin.js\u0026#34; ] и удалить созданный установщиком лишний opencode.json, чтобы не было конфликта.\nПосле правки — перезапусти opencode, плагин грузится на старте сессии.\nКак пользоваться # Включить: набери /caveman (или скажи «talk like caveman»). Для opencode режим уже активен с первого сообщения благодаря блоку в AGENTS.md.\nВыключить: «normal mode» или «stop caveman».\nПолезные команды:\n/caveman-stats — реальный расход токенов за сессию и накопленная экономия /caveman-commit — короткие commit-сообщения в формате Conventional Commits /caveman-review — однострочные комментарии к PR /caveman-compress \u0026lt;file\u0026gt; — переписывает memory-файл в пещерный стиль. Caveman режет только output-токены. Input и reasoning не трогаются, а сам скилл добавляет ~1–1.5k input-токенов на ход. На уже кратких задачах экономия может уйти в ноль.\nУдаление # npx -y github:JuliusBrussee/caveman -- --uninstall Скиллы, поставленные через npx skills add, удаляются отдельно: npx skills remove caveman.\nИтог # Поставил caveman под opencode. Агент стал отвечать короче, но вроде даже не потерял в удобстве. Понаблюдаем как наэкономит.\n","date":"17 июля 2026","externalUrl":null,"permalink":"/ustanovkacaveman/","section":"Posts","summary":"","title":"Установка caveman: говорим с ИИ по-пещерному и экономим токены","type":"posts"},{"content":"","date":"1 июля 2026","externalUrl":null,"permalink":"/tags/subtitles/","section":"Tags","summary":"","title":"Subtitles","type":"tags"},{"content":"","date":"1 июля 2026","externalUrl":null,"permalink":"/tags/video/","section":"Tags","summary":"","title":"Video","type":"tags"},{"content":" Зачем это нужно # Я часто скачиваю видео с ютуба, чтобы перекинуть в телеграм канал. В телеграме видео можно глянуть и без звука, да и принято щас так, как в рилсах кароче. Да и ролики бывают не на славянских языках, вшивать их каждый раз руками это эт лень.\nЯ запилил эмсипи-сервер для оупенкода, который делает всё одной командой: скачивает видео, достаёт субтитры (русские или английские), переводит их на русский прямо в чате и вшивает в видео. Никаких апи-ключей, никаких внешних сервисов — только yt-dlp, ffmpeg и сам оупенкод.\nКак это работает # Процесс выглядит так:\nСпрашиваю у оупенкода «скачай видос с ютуба, вшей субтитры» Оупенкод спрашивает у меня ссылку и куда сохранить Эмсипи сервер скачивает видео в 480p (для телеграма самое то) Сервер достаёт субтитры — сперва русские если есть, если нет — английские Если субтитры на английском, оупенкод переводит их на русский прямо в диалоге Ффмпег вшивает субтитры в видео Готовый файл лежит в ~/Downloads Всё это занимает пару минут и не требует ни одной команды в терминале.\nАрхитектура # Система состоит из трёх частей:\n1. Эмсипи-сервер # Пайтон-скрипт на FastMCP с четырьмя инструментами:\ndownload_video — скачивает 480p через yt-dlp extract_subs — достаёт субтитры (с авто-субтитрами как запасной вариант) save_subs — сохраняет переведённые субтитры burn_subs — вшивает субтитры через ffmpeg Сервер лежит в ~/.config/opencode/mcp/youtube_mcp_server.py:\nСкачать готовый файл\n2. Регистрация в оупенкод # Добавляем в ~/.config/opencode/opencode.jsonc:\n\u0026#34;youtube\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;local\u0026#34;, \u0026#34;command\u0026#34;: [ \u0026#34;/Users/ваш_юзер/.config/opencode/mcp/venv/bin/python3\u0026#34;, \u0026#34;/Users/ваш_юзер/.config/opencode/mcp/youtube_mcp_server.py\u0026#34; ] } 3. Скилл # Чтобы оупенкод сам понимал когда вызывать инструменты, создаём скилл в ~/.opencode/skills/youtube-processor/SKILL.md:\nСкачать готовый файл\nВ скилле описана последовательность: спросить ссылку и путь → скачать → достать субтитры → если английские — перевести → вшить → отдать результат.\nКак я перевожу субтитры без апи-ключей # Самый ленивый момент — перевод. Вместо того чтобы дёргать гугл-транслейт или оплачивать апи, я просто отдаю текст субтитров самому оупенкоду. Он переводит всё в диалоге, сохраняя таймкоды и структуру SRT, сохраняет обратно и передаёт на вшивание. Можно локально конечно, но не у всех есть. Да и в целом зачем лишний шаг.\nЧто получилось в итоге # Протестировал на видео со новостями на стопгейм, ютуб выдаёт автоматические русские субтитры, так что перевод не понадобился. Видео 8 минут скачалось за 10 секунд, субтитры за 3 секунды, вшивание заняло пару минут. На выходе — mp4 со встроенными субтитрами, готовый для телеграма.\nЕсли у видео нет русских субтитров, оупенкод скачает английские и переведёт их на русский прямо в диалоге — никаких лишних телодвижений.\nОсобенности # Для работы нужен FFMpeg с libass. Если subtitles фильтр не найден — brew install libass \u0026amp;\u0026amp; brew install homebrew-ffmpeg/ffmpeg/ffmpeg Если субтитров нет вообще — оупенкод спросит, сохранить видео без них или отменить Для \u0026ldquo;возрастных видео\u0026rdquo; может понадобиться куки браузера ","date":"1 июля 2026","externalUrl":null,"permalink":"/youtubemcp/","section":"Posts","summary":"","title":"YouTube MCP: скачиваем видео и вшиваем субтитры","type":"posts"},{"content":"","date":"27 июня 2026","externalUrl":null,"permalink":"/tags/deepwiki/","section":"Tags","summary":"","title":"Deepwiki","type":"tags"},{"content":" Зачем это нужно # В работе с опенсорсом постоянно возникает ситуация: нашёл интересный репозиторий, а документация — это просто README. Хочется быстро разобраться, как всё устроено, но читать исходники в лоб — долго и лениво.\nDeepWiki решает эту проблему: он анализирует код и README репозитория, и генерирует структурированную документацию с разделами, ссылками на исходники и с возможностью задавать вопросы.\nА через MCP (Model Context Protocol) это становится доступно прямо из оупенкод — агент может сам сходить в диипвики за документацией по любому репозиторию.\nЧто такое диипвики # DeepWiki — это AI-движок документации от Cognition Labs (те же ребята, что сделали Devin). Он берёт любой публичный GitHub-репозиторий, анализирует его код, README и файлы, и превращает всё это в удобную структурированную документацию.\nКаждая страница документации содержит:\nпояснения как работает тот или иной компонент ссылки на конкретные строки исходного кода (Sources) навигацию по разделам Диипвики в браузере # диипвики работает прямо в браузере. Просто замени github.com на deepwiki.com в URL любого публичного репозитория.\nВот так выглядит страница репозитория LOWERTOP/Shadowrocket на диипвики:\nСлева — навигация по разделам: Proxy Management, Traffic Routing, Rules System, Configuration Files и т.д. Справа — контент с пояснениями и ссылками на исходники. Гораздо удобнее, чем читать README в GitHub.\nРаботает почти для любого публичного репозитория: https://deepwiki.com/username/reponame.\nДиипвики эмсипи для оупенкод # Cognition Labs предоставляют официальный эмсипи-сервер DeepWiki. Это удалённый сервер, поэтому не нужно ничего устанавливать локально — никаких Python, venv, uvx. Просто URL в конфиге.\nДобавляем в ~/.config/opencode/opencode.jsonc:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;https://opencode.ai/config.json\u0026#34;, \u0026#34;mcp\u0026#34;: { \u0026#34;deepwiki\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;remote\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;https://mcp.deepwiki.com/mcp\u0026#34; } } } Готово. Никаких зависимостей, никаких API-ключей — сервер бесплатный и не требует аутентификации.\nИнструменты # Сервер предоставляет три инструмента:\nread_wiki_structure(repoName) # Возвращает структуру документации репозитория — список разделов и подразделов.\nread_wiki_contents(repoName) # Возвращает полное содержимое документации репозитория.\nask_question(repoName, question) # Задать вопрос по коду репозитория. DeepWiki отвечает с привязкой к конкретным строкам исходников.\nПроверка # Спрашиваю у оупенкод: \u0026ldquo;как устроена маршрутизация в ShadowRocket?\u0026rdquo;:\nОупенкод вызывает ask_question(\u0026quot;LOWERTOP/Shadowrocket\u0026quot;, \u0026quot;как устроена маршрутизация\u0026quot;), диипвики анализирует код и возвращает структурированный ответ: глобальные режимы (Configuration/Proxy/Direct/Scene), система правил, типы правил. Каждый пункт привязан к исходному коду.\nИтого # DeepWiki эмсипи — это документация для почти любого репозитория прямо из оупенкод.\nВместе с DuckDuckGo Search эмсипи получается идеальная пара: DuckDuckGo ищет в интернете, DeepWiki объясняет код репозиториев. Оупенкод наконец-то видит и интернет, и документацию.\n","date":"27 июня 2026","externalUrl":null,"permalink":"/deepwikimcp/","section":"Posts","summary":"","title":"DeepWiki MCP: AI-документация для любого репозитория","type":"posts"},{"content":"","date":"27 июня 2026","externalUrl":null,"permalink":"/tags/documentation/","section":"Tags","summary":"","title":"Documentation","type":"tags"},{"content":"","date":"26 июня 2026","externalUrl":null,"permalink":"/tags/duckduckgo/","section":"Tags","summary":"","title":"Duckduckgo","type":"tags"},{"content":" Зачем это нужно # Оупенкод хорош, но у него есть ограничение — он ничего не знает о мире за пределами того, что заложено в моделях которые ты юзаешь в агенте.\nDuckDuckGo Search MCP сервер решает эту проблему: он даёт оупенкод два инструмента — поиск в вебе и загрузку контента со страниц. Теперь агент может сам сходить в поисковик за актуальной информацией.\nЧем это отличается от встроенного WebFetch? WebFetch умеет только загружать контент по конкретному URL. Если агент не знает адрес — он бесполезен. А DuckDuckGo Search MCP добавляет поиск: агент сам находит нужные страницы по запросу, а потом может прочитать их через fetch_content. То есть это полноценный веб-сёрфинг, а не просто загрузка по известной ссылке.\nЧто такое MCP и как это работает # MCP (Model Context Protocol) — стандарт для подключения внешних инструментов к ИИ-ассистентам. Через эмсипи мы даём оупенкод доступ к произвольным действиям: поиск в интернете, чтение файлов, вызов API.\nМы устанавливаем DuckDuckGo эмсипи сервер, регистрируем его в конфиге оупенкод, и агент получает инструменты search и fetch_content. Дальше он сам решает, когда ими воспользоваться.\nУстановка # 1. Устанавливаем uv # uv — менеджер пакетов для Python, через него запускается сервер:\ncurl -LsSf https://astral.sh/uv/install.sh | sh После установки перезапустите терминал или добавьте ~/.local/bin в PATH.\n2. Регистрация в оупенкод # Добавляем сервер в ~/.config/opencode/opencode.jsonc:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;https://opencode.ai/config.json\u0026#34;, \u0026#34;mcp\u0026#34;: { \u0026#34;bb-browser\u0026#34;: { ... }, \u0026#34;markitdown\u0026#34;: { ... }, \u0026#34;ddg-search\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;local\u0026#34;, \u0026#34;command\u0026#34;: [\u0026#34;/Users/beaverbloger/.local/bin/uvx\u0026#34;, \u0026#34;duckduckgo-mcp-server\u0026#34;], \u0026#34;env\u0026#34;: { \u0026#34;DDG_SAFE_SEARCH\u0026#34;: \u0026#34;MODERATE\u0026#34;, \u0026#34;DDG_REGION\u0026#34;: \u0026#34;wt-wt\u0026#34; } } } } Параметры окружения:\nDDG_SAFE_SEARCH — уровень фильтрации контента: STRICT, MODERATE (по умолчанию), OFF DDG_REGION — регион по умолчанию: us-en, ru-ru, wt-wt (без региона) и т.д. Готово! После перезапуска оупенкод подхватит сервер.\nИнструменты # Сервер предоставляет два инструмента:\nsearch(query, max_results=10, region=\u0026quot;\u0026quot;) # Поиск в DuckDuckGo. Возвращает ссылки с заголовками и сниппетами. Можно указать регион для локализации результатов.\nfetch_content(url, start_index=0, max_length=8000) # Загрузка и очистка контента со страницы. Убирает навигацию, шапки, подвалы, скрипты — оставляет чистый текст. Поддерживает пагинацию для длинных страниц.\nПроверка # Проверим, как это работает. Прошу оупенкод найти рецепт курута:\nАгент вызывает search(\u0026quot;как готовить курут рецепт\u0026quot;), находит ссылки и краткие описания.\nА теперь попросим узнать погоду в Абзаково:\nРаботает! Агент сам решил, что ему не хватает данных, сходил в интернет и вернул актуальный ответ.\nКак это работает # Когда оупенкоду нужно найти что-то в интернете, он:\nВидит, что доступен инструмент search Формирует поисковый запрос Получает результаты Если нужно прочитать конкретную страницу — вызывает fetch_content Анализирует полученную информацию Всё прозрачно: агенту не нужно объяснять, как искать — он делает это сам, когда понимает, что ему не хватает знаний.\nОсобенности # Без API-ключей — DuckDuckGo не требует регистрации, всё бесплатно Rate limiting — 30 запросов в минуту для поиска, 20 для загрузки контента SafeSearch — настраиваемая фильтрация контента Регионы — можно локализовать поиск под нужную страну Итого # DuckDuckGo Search эмсипи — простой способ дать оупенкод доступ к веб-поиску. Без регистраций, без API-ключей, без смс. Поставил за минуту — и агент сам ходит в интернет за актуальной информацией.\n","date":"26 июня 2026","externalUrl":null,"permalink":"/duckduckgosearchmcp/","section":"Posts","summary":"","title":"DuckDuckGo Search MCP: веб-поиск для оупенкод","type":"posts"},{"content":"","date":"26 июня 2026","externalUrl":null,"permalink":"/tags/markitdown/","section":"Tags","summary":"","title":"Markitdown","type":"tags"},{"content":" Зачем это нужно # В работе с оупенкодом да и с агентами в целом, постоянно нужно читать документы, пдф файлы, эксель таблицы, презентации и прочие, не очень текстовые форматы. ЭЛЛ\u0026rsquo;мки хорошо понимают макрдаун, поэтому задача конвертации в маркдаун возникает постоянно. Также таким образом я — набиваю свое хранилище в обсидиан всякими гайдами.\nМайкрософт выпустила утилиту MarkItDown пайтон библиотеку, которая умеет конвертировать, практически, всё во что угодно в маркдаун:\n*.PDF *.DOCX *.XLSX *.PPTX HTML *.EPUB *.XML ну и так далее Что такое MCP и как это работает # MCP (Model Context Protocol) — это стандарт, который позволяет подключать внешние инструменты к эай-ассистентам (в нашем случае — к оупенкод). Через эмсипи мы даём оупенкод возможность выполнять произвольные действия: читать файлы, запускать команды, ходить в эпиай.\nМы создадим эмсипи сервер, который оборачивает MarkItDown в один простой инструмент convert_to_markdown. После этого оупенкод сможет сам сконвертировать файл в маркдаун, когда это понадобится.\nУстановка # 1. Виртуальное окружение и зависимости # Макось больше не разрешает ставить пакеты через pip глобально, поэтому создадим venv и установим всё туда:\npython3 -m venv ~/.config/opencode/mcp/venv ~/.config/opencode/mcp/venv/bin/pip3 install \u0026#39;markitdown[all]\u0026#39; \u0026#39;mcp[cli]\u0026#39; Разбиваем на составляющие: markitdown[all] сама библиотека конвертации со всеми опциональными зависимостями, mcp[cli] Python SDK для создания эмсипи-серверов.\n2. Скрипт эмсипи-сервера # Создаём файл ~/.config/opencode/mcp/markitdown_server.py:\nСкачать готовый файл\nfrom mcp.server.fastmcp import FastMCP from markitdown import MarkItDown import os mcp = FastMCP(\u0026#34;MarkItDown\u0026#34;) @mcp.tool() def convert_to_markdown(file_path: str) -\u0026gt; str: \u0026#34;\u0026#34;\u0026#34;Convert any supported file (PDF, DOCX, PPTX, XLSX, HTML, EPUB, XML) to Markdown.\u0026#34;\u0026#34;\u0026#34; file_path = os.path.expanduser(os.path.abspath(file_path)) if not os.path.exists(file_path): return f\u0026#34;Error: File not found: {file_path}\u0026#34; md = MarkItDown() result = md.convert(file_path) return result.text_content if __name__ == \u0026#34;__main__\u0026#34;: mcp.run(transport=\u0026#34;stdio\u0026#34;) Здесь мы используем FastMCP - фреймворк, который берёт на себя всю работу: парсинг JSON-RPC, логирование и т.д. Кароче способ для ленивых.\n3. Регистрация в оупенкод # Добавляем сервер в ~/.config/opencode/оупенкод.jsonc:\n{ \u0026#34;$schema\u0026#34;: \u0026#34;https://opencode.ai/config.json\u0026#34;, \u0026#34;mcp\u0026#34;: { \u0026#34;bb-browser\u0026#34;: { ... }, \u0026#34;markitdown\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;local\u0026#34;, \u0026#34;command\u0026#34;: [ \u0026#34;/Users/beaverbloger/.config/opencode/mcp/venv/bin/python3\u0026#34;, \u0026#34;/Users/beaverbloger/.config/opencode/mcp/markitdown_server.py\u0026#34; ] } } } Готово! оупенкод теперь знает про сервер и будет вызывать его автоматически.\n4. Скилл для оупенкод # Чтобы агент сам знал когда вызывать convert_to_markdown, создаём скилл. Он подскажет агенту какие форматы поддерживаются и как сохранять результат.\nСоздайте файл ~/.opencode/skills/markitdown-converter/SKILL.md:\nСкачать готовый файл\n--- name: markitdown-converter description: Convert files to Markdown using MCP tool --- When the user provides a file in a non-text format that needs to be read or converted to Markdown: 1. **Supported formats:** `.pdf`, `.docx`, `.xlsx`, `.pptx`, `.html`, `.epub`, `.xml` 2. **Use the `convert_to_markdown` MCP tool** with the file path. The path can be: - Absolute: `/Users/name/file.pdf` - With `~`: `~/Downloads/file.docx` - Relative: `./file.xlsx` 3. **Save the result** as `.md` file next to the original: - `~/Documents/doc.pdf` → `~/Documents/doc.md` - `~/Downloads/report.xlsx` → `~/Downloads/report.md` 4. **Return the path** to the saved `.md` file to the user. Теперь оупенкод сам понимает — файл не текстовый, надо конвертнуть.\nКак это работает # Когда оупенкоду нужно обработать документ, он:\nВидит, что есть инструмент convert_to_markdown Отправляет к эмсипи-запрос с путём к файлу Наш сервер запускает MarkItDown, конвертирует файл Возвращает готовый маркдаун Всё это происходит прозрачно. Оупенкод может вызвать этот инструмент самостоятельно, когда понимает, что файл нужно прочитать.\nПроверка # Перезапустим оупенкод чтобы эмсипи у нас подхватился и просим конвертировать файл пдф в маркдаун. Или просто скажи «прочитай этот файл» — скилл подскажет агенту что делать и тот сам вызовет convert_to_markdown:\nРезультат Особенности # Из коробки библиотека использует встроенные инструменты: pdfplumber для пдф, mammoth для DOCX, openpyxl для XLSX, python-pptx для PPTX, beautifulsoup4 для HTML и т.д.\nИтого # MarkItDown как эмсипи-сервер для оупенкод для меня это полезная комбинация. Юзайте для себя и вашего агента.\n","date":"26 июня 2026","externalUrl":null,"permalink":"/markitdownmcp/","section":"Posts","summary":"","title":"MarkItDown: конвертируем в макрдаун из оупенкод","type":"posts"},{"content":"","date":"26 июня 2026","externalUrl":null,"permalink":"/tags/pdf/","section":"Tags","summary":"","title":"Pdf","type":"tags"},{"content":"","date":"26 июня 2026","externalUrl":null,"permalink":"/tags/search/","section":"Tags","summary":"","title":"Search","type":"tags"},{"content":" Каждый, кто работал на Windows или Linux, привык к простой вещи: навёл курсор на иконку в панели задач - и увидел превью всех открытых окон приложения. На macOS этой фичи нет. DockDoor от ejbills возвращает эту фичу.\nЧто такое DockDoor # DockDoor - это бесплатное приложение с открытым исходным кодом, написанное на Swift. Что оно умеет?\nПревью окон при наведении на Dock - просто наведите курсор на иконку приложения и увидите все его окна. Alt+Tab переключатель - полноценный переключатель окон с превью Улучшенный Cmd+Tab - расширенная версия стандартного переключателя приложений с превью Блокировка Dock на мониторе - если у вас мультидисплейный сетап, Dock больше не будет прыгать между экранами. Календарь в Dock - интеграция с календарём прямо из панели. Компактный вид списка - альтернативный вид для переключения окон. Дополнительные кнопки - кнопки для управления окном приложения из меню Dock. Закрыть, свернуть, развернуть и закрыть прям настоящий закрыть, а не как в МакОси по дефолту. Как попробовать # Скачать DockDoor можно с GitHub или через сайт. Поставить Запустить Дать пару прав. ","date":"23 июня 2026","externalUrl":null,"permalink":"/ejbillsdockdoor/","section":"Posts","summary":"","title":"DockDoor - оконный превьюер для macOS","type":"posts"},{"content":"","date":"23 июня 2026","externalUrl":null,"permalink":"/tags/swift/","section":"Tags","summary":"","title":"Swift","type":"tags"},{"content":"","date":"23 июня 2026","externalUrl":null,"permalink":"/tags/%D1%83%D1%82%D0%B8%D0%BB%D0%B8%D1%82%D1%8B/","section":"Tags","summary":"","title":"Утилиты","type":"tags"},{"content":"","date":"12 июня 2026","externalUrl":null,"permalink":"/categories/blog/","section":"Categories","summary":"","title":"Blog","type":"categories"},{"content":"","date":"12 июня 2026","externalUrl":null,"permalink":"/tags/ci-cd/","section":"Tags","summary":"","title":"Ci-Cd","type":"tags"},{"content":"","date":"12 июня 2026","externalUrl":null,"permalink":"/tags/s3/","section":"Tags","summary":"","title":"S3","type":"tags"},{"content":"","date":"12 июня 2026","externalUrl":null,"permalink":"/tags/static-site/","section":"Tags","summary":"","title":"Static-Site","type":"tags"},{"content":"","date":"12 июня 2026","externalUrl":null,"permalink":"/tags/timeweb/","section":"Tags","summary":"","title":"Timeweb","type":"tags"},{"content":"","date":"12 июня 2026","externalUrl":null,"permalink":"/categories/web/","section":"Categories","summary":"","title":"Web","type":"categories"},{"content":" Долгое время мой блог жил на VDS — nginx, certbot, systemd-сервисы, бекапы, короче полноценный сервер. В какой-то момент стало лень следить за ещё одной машиной и особенно меня подтолкнули проблемы с разными хостингами и я решил переехать на статический S3-хостинг.\nПост про то — как я переехал, с какими граблями столкнулся и что в итоге получилось.\nПочему Timeweb S3 # Почему именно Timeweb, а не Яндекс Облако или Selectel? Тут всё просто: у меня уже были там аккаунты, а S3 у них стоит копейки. Для статики — идеально.\nИз коробки Timeweb S3 умеет раздавать статический сайт, выдаёт URL вида *.website.twcstorage.ru, поддерживает кастомные заголовки и политики.\nЧто нужно # Аккаунт в Timeweb (уже был) Hugo Репозиторий блога на GitHub (уже был) Домен (уже был) Шаг 1: Создание бакета # Заходим в панель Timeweb → S3 → Создать бакет Выбираем регион, имя бакета После создания открываем бакет → Настройки → Хостинг статического сайта → Включаем Получаем URL: https://\u0026lt;id\u0026gt;.website.twcstorage.ru Шаг 2: S3-ключи # В панели Timeweb идём в сервисные аккаунты → создаём ключ с доступом к бакету (на запись и чтение). Нам понадобятся:\nAWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_ENDPOINT_URL — https://s3.twcstorage.ru И имя бакета Шаг 3: GitHub Actions # Деплой настроил через GitHub Actions. Workflow выглядит так:\nname: Deploy blog to S3 on: push: branches: [main] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: peaceiris/actions-hugo@v3 with: extended: true - run: hugo --gc - uses: jakejarvis/s3-sync-action@master with: args: --delete env: AWS_S3_BUCKET: ${{ secrets.AWS_BUCKET_NAME }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_ENDPOINT_URL: ${{ secrets.AWS_ENDPOINT_URL }} Секреты (AWS_*) храню в настройках репозитория GitHub — Settings → Secrets and variables → Actions.\nШаг 4: Деплой # Пушим в main:\ngit push origin main GitHub Actions собирает сайт и синхронизирует с бакетом. Всё, сайт на S3, никаких ssh и ручных заливок.\nШаг 5: Домены (не так всё просто) # Настраиваем CNAME в DNS:\nblog.tatarinovms.ru → s3.twcstorage.ru blog.tatarinovms.space → s3.twcstorage.ru Ждём, пока DNS обновится, открываем браузер\u0026hellip; и получаем AccessDenied.\nПодводный камень: кастомные домены не работают # Как оказалось, Timeweb S3 не поддерживает кастомные домены. Вообще. Только их *.website.twcstorage.ru. На момент написания поста ответ поддержки это подтвердил.\nЕсть два пути:\nВариант 1: CloudFlare Меняем NS на CloudFlare, он проксирует запросы на S3-эндпоинт и выдаёт свой SSL. VDS не нужен. Бесплатно. Но мы знаем как в некоторых регионах работает CloudFlare, скажем мягко - с перебоями.\nВариант 2: nginx reverse proxy Пришла простая идея, так как есть в загашнике VDS, то мы ставим nginx на VDS, он проксирует кастомные домены на S3 URL. SSL через certbot. VDS всё равно есть под другие задачи. Конфиг nginx:\nserver { listen 80 default_server; server_name blog.tatarinovms.ru blog.tatarinovms.space; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name blog.tatarinovms.ru blog.tatarinovms.space; ssl_certificate /etc/letsencrypt/live/blog.tatarinovms.space/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/blog.tatarinovms.space/privkey.pem; location / { proxy_pass https://id.website.twcstorage.ru; proxy_ssl_verify off; proxy_ssl_server_name on; proxy_set_header Host id.website.twcstorage.ru; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } SSL получил через certbot:\ncertbot --nginx -d blog.tatarinovms.ru -d blog.tatarinovms.space Итоговая схема # Пуш в main → GitHub Actions → Hugo build → aws s3 sync → S3 бакет → DNS: blog.tatarinovms.ru / blog.tatarinovms.space → A → VDS → nginx reverse proxy → S3 (*.website.twcstorage.ru) При пуше в main GitHub Actions сам собирает Hugo и синхронизирует с S3 — nginx просто проксирует то, что уже лежит в бакете. Редеплой занимает меньше минуты.\nTimeweb S3 как хостинг статики — отличное решение. Но с кастомными доменами придётся извернуться. Надеюсь, когда-нибудь они добавят эту возможность, но пока — nginx.\n","date":"12 июня 2026","externalUrl":null,"permalink":"/blogontimewebs3/","section":"Posts","summary":"","title":"Хостинг Hugo-блога на S3 Timeweb","type":"posts"},{"content":"","date":"27 мая 2026","externalUrl":null,"permalink":"/tags/audio/","section":"Tags","summary":"","title":"Audio","type":"tags"},{"content":"","date":"27 мая 2026","externalUrl":null,"permalink":"/tags/finetune/","section":"Tags","summary":"","title":"Finetune","type":"tags"},{"content":" Что такое FineTune? # FineTune — это бесплатная open-source утилита для macOS, которая живёт в меню-баре и даёт полный контроль над аудио на системном уровне. Регулировка громкости каждого приложения независимо, маршрутизация звука на разные устройства, 10-полосный эквалайзер и коррекция АЧХ для наушников — всё в одном окне.\nДля перехвата аудиопотоков FineTune создаёт виртуальное аудиоустройство. Оно появляется в системных настройках звука и работает как прослойка между приложениями и вашими колонками/наушниками.\nНаписан на SwiftUI, требует macOS 15.0+.\nОсновные возможности # Управление громкостью # Per-app громкость — отдельный слайдер и mute для каждого приложения Pinned apps — закрепить приложение в меню-баре, даже когда оно не воспроизводит звук (удобно настроить EQ и маршрутизацию заранее) Ignore apps — полностью исключить приложение из управления FineTune Scroll-wheel — наведите курсор на любой слайдер и крутите колёсико Горячие клавиши # Глобальные хоткеи — назначьте свои комбинации на App Volume Up/Down и Mute. Работают даже когда приложение свёрнуто Toggle Popup — повесьте хоткей на открытие/закрытие окна FineTune, работает из полноэкранных приложений Навигация внутри попапа — стрелки ↑↓ между строками, ←→ регулировка громкости, M mute, Return/Space активация, Tab переключение вкладок устройств Маршрутизация # Multi-device output — вывод звука на несколько устройств одновременно Audio routing — отправлять разные приложения на разные устройства Device priority — автопереключение при подключении нового устройства Auto-restore — при переподключении устройства настройки (громкость, маршрут, EQ) восстанавливаются автоматически Эквалайзер # 10 полос, 20 готовых пресетов Пользовательские пресеты — сохраняйте свои настройки и применяйте к разным приложениям AutoEQ headphone correction — коррекция АЧХ под конкретную модель наушников из базы AutoEQ (тысячи профилей). Можно импортировать свои ParametricEQ.txt Загрузка пресета — выбрав пресет для своих наушников, FineTune запоминает его и применяет автоматически при каждом подключении этой модели Loudness compensation — автоматическая коррекция низких и высоких частот на малой громкости по стандарту ISO 226:2023 Системное # Input device control — уровень микрофона Alert volume — громкость системных уведомлений DDC — регулировка громкости внешних мониторов Volume HUD — встроенный индикатор громкости (Tahoe или Classic стиль) Медиа-клавиши F10-F12 — работают даже на USB DAC и HDMI, где штатные клавиши macOS бесполезны Bluetooth — подключение устройств прямо из меню-бара URL schemes — автоматизация через shell, Shortcuts или Raycast\u0026rsquo;о подобное Установка # brew install --cask finetune Или скачайте DMG с GitHub Releases.\nБыстрый старт # Запустите FineTune из папки Applications Разрешите Screen \u0026amp; System Audio Recording — это необходимо для перехвата аудиопотоков Нажмите на иконку FineTune в меню-баре — приложения, воспроизводящие звук, появятся автоматически Готово. Регулируйте громкость, маршрутизируйте звук, настраивайте EQ.\nПолезные фЫшки # Автопереключение на Bluetooth-гарнитуру: откройте edit mode (карандаш) и перетащите устройство выше встроенных динамиков — FineTune будет переключаться на него при подключении\nУправление с клавиатуры: откройте попап и пользуйтесь стрелками.\nURL schemes — automate volume, mute, device routing, and more from scripts\nFineTune понимает URL-команды формата finetune://.\nfinetune://set-volumes?app=com.spotify.client\u0026amp;volume=50 finetune://set-mute?app=com.spotify.client\u0026amp;muted=true finetune://toggle-mute?app=com.hnc.Discord finetune://set-device?app=com.apple.Music\u0026amp;device=DEVICE_UID finetune://reset ","date":"27 мая 2026","externalUrl":null,"permalink":"/finetune/","section":"Posts","summary":"","title":"FineTune — бесплатный аудио-микшер для macOS","type":"posts"},{"content":"","date":"27 мая 2026","externalUrl":null,"permalink":"/categories/media/","section":"Categories","summary":"","title":"Media","type":"categories"},{"content":"","date":"27 мая 2026","externalUrl":null,"permalink":"/tags/menu-bar/","section":"Tags","summary":"","title":"Menu-Bar","type":"tags"},{"content":"","date":"27 мая 2026","externalUrl":null,"permalink":"/tags/utility/","section":"Tags","summary":"","title":"Utility","type":"tags"},{"content":"","date":"23 мая 2026","externalUrl":null,"permalink":"/tags/brew/","section":"Tags","summary":"","title":"Brew","type":"tags"},{"content":"","date":"23 мая 2026","externalUrl":null,"permalink":"/tags/gui/","section":"Tags","summary":"","title":"Gui","type":"tags"},{"content":"","date":"23 мая 2026","externalUrl":null,"permalink":"/tags/react/","section":"Tags","summary":"","title":"React","type":"tags"},{"content":"","date":"23 мая 2026","externalUrl":null,"permalink":"/tags/wailbrew/","section":"Tags","summary":"","title":"Wailbrew","type":"tags"},{"content":" В прошлом я уже писал про Applite — графическую оболочку для Homebrew. Но недавно наткнулся на более интересный проект — WailBrew. Это минималистичный GUI для управления пакетами Homebrew, написанный на Go и React с использованием фреймворка Wails. Выглядит современно, работает быстро и, что приятно, имеет открытый исходный код.\nВозможности # Просмотр и управление установленными formula и cask Поиск пакетов с мгновенной фильтрацией Установка, удаление и обновление пакетов Проверка устаревших пакетов с возможностью обновить их по одному или все сразу Детальная информация о пакетах: зависимости, конфликты и прочее Управление репозиториями Homebrew (tap/untap) Локализация на 11 языках, включая русский Как установить? # Иронично, но также через brew:\nbrew install --cask wailbrew Либо скачать последний релиз с GitHub.\nЧем он лучше Applite? # WailBrew написан на Go + Wails + React, в то время как Applite — на SwiftUI. На практике WailBrew работает заметно шустрее, поиск практически мгновенный, а интерфейс напоминает нативный macOS-стиль. Плюс поддержка русского языка из коробки.\nПроект набрал уже более 2600 звезд на GitHub и активно развивается — на момент написания статьи последний релиз v0.9.20 от апреля 2026.\nЕсли вы пользуетесь Homebrew, но предпочитаете графический интерфейс — определённо рекомендую попробовать.\n(/images/posts/wailbrew/logo.webp)\n","date":"23 мая 2026","externalUrl":null,"permalink":"/wailbrew/","section":"Posts","summary":"","title":"WailBrew — минималистичный GUI для Homebrew","type":"posts"},{"content":"","date":"23 мая 2026","externalUrl":null,"permalink":"/tags/wails/","section":"Tags","summary":"","title":"Wails","type":"tags"},{"content":"","date":"2 мая 2026","externalUrl":null,"permalink":"/tags/asr/","section":"Tags","summary":"","title":"ASR","type":"tags"},{"content":"","date":"2 мая 2026","externalUrl":null,"permalink":"/tags/qwen/","section":"Tags","summary":"","title":"Qwen","type":"tags"},{"content":" В этом гайде я покажу, как развернуть и запустить модель распознавания речи Qwen3‑ASR через пакет mlx-qwen3-asr на macOS с M-чипом. Решение позволяет транскрибировать аудио из видеофайлов с поддержкой русского языка и сохранять результат в разных форматах: SRT, VTT, TXT, JSON.\nЧто такое mlx-qwen3-asr? # mlx-qwen3-asr - это Python‑пакет, предоставляющий удобный интерфейс к модели Qwen3‑ASR‑1.7B от Alibaba Cloud, оптимизированной для работы на чипах Apple Silicon через фреймворк MLX. Модель поддерживает несколько языков, включая наш родной русский, и позволяет получать транскрипцию с тайм‑кодами.\nТребования # macOS Установленный Python 3.11 Руки Свободное место на диске (модель ~3 ГБ) Установка и настройка # Подготовка директории проекта # Создайте отдельную папку для проекта и перейдите в неё, у меня будет так:\nmkdir -p ~/Documents/ai/asr cd ~/Documents/ai/asr Создание виртуального окружения # python3.11 -m venv venv Активация окружения # Активируйте виртуальное окружение:\nsource venv/bin/activate Обновление pip и установка пакета # Обновите менеджер пакетов и установите mlx-qwen3-asr:\npip install --upgrade pip pip install mlx-qwen3-asr Установка может занять несколько минут — загружаются зависимости и модель.\nСоздание скрипта автоматизации # Чтобы не вводить команды вручную каждый раз, создадим shell‑скрипт с небольшим интерактивным интерфейсом.\nСоздайте файл скрипта # Создадим скрипт в любимом текстовом редакторе: vim asr_process.sh Вставьте этот код\nУкажите настройку VENV_BIN=, где будет путь к созданной вами папке.\nСохраняем файл\nДелаем скрипт исполняемым\nchmod +x asr_process.sh Отправляем файл на распознавание # Запускаем скрипт ./asr_process.sh откроет диалоговое окно для выбора файла\nпотом скрипт предложит выбрать формат вывода\nпозволит указать папку для сохранения\nзапустится распознавание и покажет прогресс (при первом запуске модель скачается)\n","date":"2 мая 2026","externalUrl":null,"permalink":"/qwen3asronmacos/","section":"Posts","summary":"","title":"Qwen3 ASR на macOS","type":"posts"},{"content":"","date":"2 мая 2026","externalUrl":null,"permalink":"/tags/speech-recognition/","section":"Tags","summary":"","title":"Speech Recognition","type":"tags"},{"content":"","date":"21 апреля 2026","externalUrl":null,"permalink":"/categories/git/","section":"Categories","summary":"","title":"Git","type":"categories"},{"content":"","date":"21 апреля 2026","externalUrl":null,"permalink":"/tags/github/","section":"Tags","summary":"","title":"Github","type":"tags"},{"content":"","date":"21 апреля 2026","externalUrl":null,"permalink":"/tags/gitverse/","section":"Tags","summary":"","title":"Gitverse","type":"tags"},{"content":"","date":"21 апреля 2026","externalUrl":null,"permalink":"/tags/sync/","section":"Tags","summary":"","title":"Sync","type":"tags"},{"content":" Введение # В условиях турбулентной работы облачных сервисов (снова так скажем) вопрос избыточности хранения кода становится актуальным. Держать проект только на GitHub — это риск. Решением может стать зеркалирование кода в другой сервис, например, на GitVerse.\nОбычно мы привыкли, что один remote (например, origin) привязан к одному URL. Но Git позволяет добавить несколько URL для push-операций в один remote.\nКак это настроить # Если у вас уже есть основной репозиторий на GitHub, достаточно добавить второй URL для отправки данных:\ngit remote set-url --add --push origin git@gitverse.ru:tatarinovms/ShadowRocketSimpleConfig.git Теперь при выполнении команды git push origin ваши изменения полетят сразу в оба репозитория.\nНюансы с конфликтами # Главная проблема возникает, когда в одном из зеркал есть изменения, которых нет в другом (например, вы отредактировали README прямо в веб-интерфейсе GitVerse). В этом случае обычный push будет отклонен.\nРешить это можно через создание временного remote для «проблемного» зеркала и слияние веток:\nДобавляем зеркало как отдельный remote: git remote add gitverse git@gitverse.ru:tatarinovms/ShadowRocketSimpleConfig.git Подтягиваем изменения, разрешая несвязанные истории: git pull gitverse main --no-rebase --allow-unrelated-histories После разрешения конфликтов снова пушим всё в origin. Теперь код синхронизирован, а вы спите спокойно, зная, что копия вашего проекта лежит на разных площадках.\n","date":"21 апреля 2026","externalUrl":null,"permalink":"/synctogit/","section":"Posts","summary":"","title":"Синхронизация кода в два репозитория одновременно","type":"posts"},{"content":"","date":"12 апреля 2026","externalUrl":null,"permalink":"/tags/adtech/","section":"Tags","summary":"","title":"Adtech","type":"tags"},{"content":"","date":"12 апреля 2026","externalUrl":null,"permalink":"/tags/marketing/","section":"Tags","summary":"","title":"Marketing","type":"tags"},{"content":" Развёртывание VoxCPM на MacBook с чипом Apple Silicon # Данное руководство содержит пошаговые инструкции по установке и запуску VoxCPM на macOS с процессорами Apple Silicon. Игрался на своем ноуте.\nСкачиваем репозиторий проекта # Переходим в папку, где у вас всё будет аккуратно лежать и скачиваем репу:\ngit clone https://github.com/OpenBMB/VoxCPM.git cd VoxCPM Настройка доступа к Hugging Face # Для ускорения загрузки моделей и повышения лимитов запросов рекомендуется настроить токен доступа на Hugging Face\nПолучение токена # Перейдите на https://huggingface.co/settings/tokens Создайте новый токен с правами Read Скопируйте токен (формат: hf_...) Настройка токена # Способ 1: Через huggingface-cli\npip install -U huggingface_hub hf auth login # Вставьте токен при запросе Способ 2: Через переменную окружения\n# Временно для сессии export HF_TOKEN=\u0026#34;hf_ваш_токен_здесь\u0026#34; # Или навсегда (добавить в ~/.zshrc) echo \u0026#39;export HF_TOKEN=\u0026#34;hf_ваш_токен_здесь\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.zshrc source ~/.zshrc Установка Python 3.10+ через pyenv # Установка Homebrew (если не установлен, но навряд ли, конечно) # /bin/bash -c \u0026#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\u0026#34; Установка pyenv и зависимостей # brew install pyenv openssl readline sqlite3 xz zlib pkgconf autoconf Настройка окружения оболочки # Добавьте следующие строки в ~/.zshrc:\nexport PYENV_ROOT=\u0026#34;$HOME/.pyenv\u0026#34; export PATH=\u0026#34;$PYENV_ROOT/bin:$PATH\u0026#34; eval \u0026#34;$(pyenv init --path)\u0026#34; eval \u0026#34;$(pyenv init -)\u0026#34; Примените изменения:\nsource ~/.zshrc Установка Python 3.10.14 # pyenv install 3.10.14 Настройка версии для проекта # Перейдите в папку проекта, которую мы скачали ранее и указываем локальную версию Python:\ncd ~/Documents/ai/VoxCPM pyenv local 3.10.14 python --version # Должно вывести: Python 3.10.14 Настройка проекта и установка зависимостей # Создание виртуального окружения # # В папке проекта python -m venv venv source venv/bin/activate pip install --upgrade pip Установка проекта в режиме разработки # pip install -e . Проверка установки # which voxcpm # Должно указывать на путь внутри venv voxcpm --help # Должно отобразить справку по командам и доступным флагам Скачиваем модель в папку # Делаем папку для модели и качаем модель:\nmkdir -p models/VoxCPM-2B hf download openbmb/VoxCPM2 --local-dir ./models/VoxCPM2 Использование через CLI # Базовый синтаксис # В без все просто:\nvoxcpm \u0026lt;режим\u0026gt; [параметры] Но мы пойдём путём клонирования своего голоса для озвучки текста.\nГотовим файл для клонирования # Я просто записал аудиосообщение в одном голубом мессенджере, сохранил его и перекодировал через ffmpeg в wav. Текст сообщения был такой: Это образец моего голоса. Я говорю здесь целых пять секунд.\nФайл с текстом и аудио сохранил в папке ./ref. Т. е. ref.txt и ref.wav\nГотовим текст для озвучки # Создам папку output и inpit чтобы папку не замусоривать. Создаю текст для озвучки:\nvim ./inpit/anime.txt Накидал туда описание аниме - Ателье колдовских колпаков\nЗапускаем озвучку с клонированием нашего голоса # Запускаем озвучку нашего текста с клонированием голоса в папку output:\nvoxcpm clone --text \u0026#34;$(cat ./inpit/anime.txt)\u0026#34; --prompt-audio ./ref/ref.wav --prompt-text \u0026#34;$(cat ./ref/ref.txt)\u0026#34; --reference-audio ./ref/ref.wav --output ./output/anime_18.wav --model-path ./models/VoxCPM2 --device mps --no-optimize --cfg-value 1.8 --inference-timesteps 20 --normalize --no-denoiser Что у нас по параметрам? # Параметр Значение в команде Назначение voxcpm clone clone Активация режима клонирования голоса --text \u0026quot;$(cat ./inpit/anime.txt)\u0026quot; Целевой текст для генерации --prompt-audio ./ref/ref.wav Аудио-референс --prompt-text \u0026quot;$(cat ./ref/ref.txt)\u0026quot; Точная транскрипция prompt-audio --reference-audio ./ref/ref.wav Аудио-референс для тембральной идентичности --output ./output/anime_18.wav Путь к выходному файлу --model-path ./models/VoxCPM2 Локальный каталог с весами модели --device mps Платформа на которой мы играемся --no-optimize без значения Отключение torch.compile --cfg-value 1.8 Значение Classifier-Free Guidance --inference-timesteps 20 Количество шагов диффузионного декодера --normalize без значения Нормализация громкости выхода --no-denoiser без значения Отключение модуля ZipEnhancer Результат # На выходе получился файл 35.02. Послушать его можно ниже:\nВаш браузер не поддерживает воспроизведение аудиофайлов. Скачать запись\nПослушать на ютубе\nПослушать на рутубе\nПослушать на вквидео\nПослушать на дзене\nЛитература для изучения # GitHub репозиторий: https://github.com/OpenBMB/VoxCPM Страница модели на Hugging Face: https://huggingface.co/openbmb/VoxCPM2 ","date":"12 апреля 2026","externalUrl":null,"permalink":"/voxcpm/","section":"Posts","summary":"","title":"VoxCPM — клонирование вашего голоса через CLI","type":"posts"},{"content":"","date":"30 марта 2026","externalUrl":null,"permalink":"/tags/obsidian/","section":"Tags","summary":"","title":"Obsidian","type":"tags"},{"content":"","date":"30 марта 2026","externalUrl":null,"permalink":"/categories/productivity/","section":"Categories","summary":"","title":"Productivity","type":"categories"},{"content":" В условиях турбулентной схемы работы облачных сервисов (скажем это так) вопрос хранения и синхронизации личных заметок приобретает особую актуальность. Данная заметка посвящена настройке синхронизации заметок Obsidian между устройствами iOS (Android пока не пробовал) и MacOS с использованием приватного репозитория GitHub (пока как он ещё работает). Позже дополню с переходом на свой git-сервер, но это решение мне ещё надо обкатать.\nЧто у нас из плюсов? # Отсутствие зависимости от iCloud (есть только зависимость от GitHub); Бесплатность; Автоматическое копирование как содержимого заметок, так и истории их изменений; Есть и локальное хранение данных, мы же делаем git pull Краткое описание, что нам нужно # Приватный репозиторий GitHub в качестве центрального хранилища. Obsidian собственно. Для десктопных платформ: плагин Git для Obsidian. Для мобильных платформ: плагин Fit для Obsidian. Установка Obsidian на устройства # Все ссылки под все платформы:\nhttps://obsidian.md/download\nСоздание приватного репозитория на GitHub # Авторизуйтесь на github.com. Перейдите по ссылке https://github.com/new и укажите: Имя репозитория; Тип доступа: Private; Опция: Add a README file (репозиторий не должен быть пустым). Нажмите кнопку создания репозитория. В корне репозитория создайте файл .gitignore со следующим содержимым: .obsidian Файл .gitignore необходим для исключения папки .obsidian из синхронизации. В данной папке хранятся локальные настройки Obsidian, которые могут конфликтовать при синхронизации между разными устройствами.\nСоздание токена доступа # Перейдите по ссылке https://github.com/settings/personal-access-tokens. Укажите параметры токена: Token name (произвольное и понятное вам); Expiration: можно No expiration, но осторожно; Repository access: Выберите свой репозиторий, который создали ранее. Permissions: Выберите всё, что связано с репой, без всяких Copilot и пр. Создайте токен. Скопируйте и сохраните сгенерированный токен Настройка синхронизации на десктопной платформе # Клонирование репозитория # Убедитесь, что в системе установлен Git и он настроен Создайте папку для хранения хранилища Obsidian Откройте терминал, перейдите в созданную папку и выполните клонирование: cd ./OBSIDIANREPO git clone git@github.com:username/ObsidianRepo.git Создание хранилища в Obsidian # Запустите Obsidian. Выберите опцию Open folder as vault и укажите путь к клонированной папке репозитория. Теперь вы можете создавать и редактировать заметки в данном хранилище. Настройка плагина Git для автоматической синхронизации # В настройках Obsidian перейдите в раздел Community plugins, отключите Restricted mode (если активен), найдите и установите плагин Git. В настройках плагина укажите следующие параметры: Author name for commit: Ваше имя для коммитов Author email for commit: Ваша почта для коммитов Остальные параметры на ваш вкус.\nНастройка синхронизации на мобильных устройствах # Запустите приложение Obsidian на iOS. Создайте новое пустое хранилище (не добавляйте в него пока файлы). В настройках приложения перейдите в раздел Community plugins, найдите и установите плагин Fit. В настройках плагина укажите: Token: вставьте Personal Access Token, созданный ранее; Нажмите Authenticate user (она вверху) для авторизации; Github repository name: выберите ваш репозиторий; Branch name: main; Auto sync: Muted; Auto check interval: 5 minute; File change: отключите все визуальные уведомления. Особенности плагина Fit и вообще всей связки # Плагин не поддерживает автосинхронизацию при запуске приложения. Для немедленного получения изменений используйте кнопку Fit Sync (иконка с котиком в меню бургерном) сразу после запуска Obsidian. Не редактируйте один и тот же файл одновременно на двух устройствах, если не умеете разбираться с конфликтами в Git Итоги # Ну как-то так.\n","date":"30 марта 2026","externalUrl":null,"permalink":"/obsidiangit/","section":"Posts","summary":"","title":"Синхронизация заметок Obsidian через GitHub","type":"posts"},{"content":"","date":"6 марта 2026","externalUrl":null,"permalink":"/tags/go/","section":"Tags","summary":"","title":"Go","type":"tags"},{"content":"","date":"6 марта 2026","externalUrl":null,"permalink":"/tags/music/","section":"Tags","summary":"","title":"Music","type":"tags"},{"content":"","date":"6 марта 2026","externalUrl":null,"permalink":"/tags/navidrome/","section":"Tags","summary":"","title":"Navidrome","type":"tags"},{"content":" Ввиду недавних изменений на стриминговых платформах, давно хотел иметь свою собственную музыкальную библиотеку, к которой можно получить доступ с любого устройства. У меня конечно уже стоит Jellyfin, но хотелось отдельного решения для музыки. Остановился на Navidrome.\nПочему Navidrome? # Navidrome — это лёгкий и быстрый сервер для стриминга музыки с поддержкой Subsonic API. Написан на Go, использует SQLite в качестве базы данных и потребляет минимум ресурсов.\nИз плюсов:\nЛёгкость — написан на Go, потребляет мало RAM и CPU Subsonic API — совместим с большинством клиентов Subsonic Поддержка тегов — автоматически сканирует и индексирует метаданные Транскодинг — встроенная поддержка FFmpeg Веб-интерфейс и мобильные клиенты Мультипользовательский режим — можно создать аккаунты для семьи Что нам понадобится # Сервер с DietPi Домен (опционально, для удобного доступа извне) Nginx в качестве reverse proxy Установка Navidrome на DietPi # Шаг 1: Установка через dietpi-software # DietPi имеет встроенную поддержку Navidrome через dietpi-software. Запускаем:\ndietpi-software В меню выбираем Navidrome. Мастер автоматически:\nУстановит все зависимости Настроит сервис для автозапуска Создаст необходимые директории Шаг 2: Настройка после установки # После установки Navidrome будет доступен по адресу:\nhttp://\u0026lt;IP-сервера\u0026gt;:4533 Первый созданный пользователь автоматически получит права администратора.\nШаг 3: Добавление музыки # По умолчанию Navidrome ищет музыку в директории /mnt/dietpi_userdata/navidrome/music, но в интерфейсе можно будет добавить и свою библиотеку или в конфиге /mnt/dietpi_userdata/navidrome/navidrome.toml поменяйте путь:\nMusicFolder = \u0026#34;/mnt/external/music\u0026#34; на свою папку , она станет вашей основной библиотекой.\nПосле изменения конфига перезапустите сервис:\ndietpi-services restart navidrome Шаг 4: Проверка статуса # Проверяем что сервис запущен:\ndietpi-services status navidrome В ответе должно быть active (running).\nНастройка Nginx в качестве reverse proxy # Если вы хотите использовать доменное имя и HTTPS, нужно настроить reverse proxy. На DietPi это можно сделать через встроенную утилиту.\nШаг 1: Устанавливаем Nginx # dietpi-software Выбираем Nginx для установки.\nШаг 2: Получаем SSL сертификат # Для настройки HTTPS сначала нужно получить сертификат через встроенную утилиту dietpi-letsencrypt:\ndietpi-letsencrypt Следуем инструкциям мастера:\nВыбираем домен navidrome.yourdomain.com Указываем email для уведомлений Выбираем Nginx как веб-сервер После успешного выполнения сертификаты будут размещены в /etc/letsencrypt/live/navidrome.yourdomain.com/.\nШаг 3: Создаём конфиг для Navidrome # Создаём файл конфига:\nsudo nano /etc/nginx/sites-available/musicstream С таким содержимым:\nserver { listen 80; listen [::]:80; server_name navidrome.yourdomain.com; location / { proxy_pass http://localhost:4533; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; proxy_set_header Connection \u0026#34;\u0026#34;; proxy_read_timeout 90; } include /etc/nginx/sites-dietpi/*.conf; listen [::]:443 ssl; http2 on; listen 443 quic; listen [::]:443 quic; quic_retry on; quic_gso on; add_header Alt-Svc \u0026#39;h3=\u0026#34;:443\u0026#34;; ma=86400\u0026#39; always; ssl_certificate /etc/letsencrypt/live/navidrome.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/navidrome.yourdomain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } Пояснения # proxy_pass — перенаправляем запросы на Navidrome (порт 4533) proxy_set_header — передаём оригинальные заголовки клиента proxy_read_timeout — увеличиваем таймаут для стриминга include /etc/nginx/sites-dietpi/*.conf — подключаем дополнительные конфиги DietPi http2 on / quic — включаем HTTP/2 и HTTP/3 (QUIC) для лучшей производительности Alt-Svc — заголовок для поддержки HTTP/3 ssl_certificate — пути к сертификатам Let\u0026rsquo;s Encrypt Шаг 4: Включаем сайт # sudo ln -s /etc/nginx/sites-available/musicstream /etc/nginx/sites-enabled/musicstream sudo nginx -t dietpi-services restart nginx После перезагрузки Nginx ваш сервер будет доступен по HTTPS с поддержкой HTTP/2 и HTTP/3 (QUIC).\nТакже не забудьте открыть порт 443 в вашем фаерволле или роутере.\nКлиенты для Navidrome # Navidrome совместим с любым клиентом, поддерживающим Subsonic API. Вот некоторые из них:\nВеб # Встроенный веб-интерфейс Navidrome уже имеет полный функционал и адаптивный дизайн. Открыть его можно по адресу:\nЛокально: http://\u0026lt;IP-сервера\u0026gt;:4533 Через proxy: https://navidrome.yourdomain.com Мобильные # На телефоне я использую клиент Yuzic\nБекапы # Для резервного копирования достаточно сохранить директорию /mnt/dietpi_userdata/navidrome — там находится SQLite база и конфиги\nЗаключение # Navidrome — отличное решение для тех, кто хочет иметь свою музыкальную библиотеку с современным интерфейсом и минимальными затратами ресурсов. На DietPi разворачивается за 10 минут, а настройка Nginx proxy позволяет получить безопасный доступ по HTTPS с любого устройства.\n","date":"6 марта 2026","externalUrl":null,"permalink":"/navidrome/","section":"Posts","summary":"","title":"Navidrome — свой музыкальный стриминговый сервер на DietPi","type":"posts"},{"content":"","date":"6 марта 2026","externalUrl":null,"permalink":"/tags/streaming/","section":"Tags","summary":"","title":"Streaming","type":"tags"},{"content":"","date":"22 февраля 2026","externalUrl":null,"permalink":"/tags/agent/","section":"Tags","summary":"","title":"Agent","type":"tags"},{"content":" Предыстория # Долгое время хранил SSH-ключи в виде файлов на диске. Это неудобно и небезопасно: файлы могут быть украдены, забыты на разных устройствах, да и бэкапить их — отдельная головная боль.\nПользуюсь Bitwarden, а точнее Vaultwarden сервером с десктопным клиентом на компе. Через него храню пароли, TOTP и т.д. Но в Bitwarden можно хранить ещё и SSH-ключи, а встроенный SSH Agent позволяет использовать их без сохранения на диск.\nЗачем это нужно? # Безопасность — приватные ключи не лежат в файлах на диске Централизованное хранение — все ключи в одном месте, с доступом со всех устройств Автоматизация — SSH сам перебирает ключи, правда Bitwarden не сопоставляет ключи по имени хоста. Он просто предлагает все доступные ключи по очереди. Сервер сам выбирает подходящий. Синхронизация — добавил ключ в Bitwarden, и он доступен на всех устройствах Что понадобится # Bitwarden Desktop для macOS. Поставить его можно через Homebrew: brew install bitwarden Немного свободного времени Шаг 1: Включаем SSH Agent в Bitwarden # Открываем Bitwarden Desktop приложение Переходим в Settings → SSH Agent Включаем опцию \u0026ldquo;Enable SSH Agent\u0026rdquo; После включения Bitwarden создаст Unix-сокет для работы с SSH. На macOS путь к сокету:\n~/.bitwarden-ssh-agent.sock Шаг 2: Добавляем SSH-ключи в Bitwarden # В Bitwarden создаём новый элемент типа SSH Key Публичный ключ при этом должен быть добавлен на серверы в ~/.ssh/authorized_keys — как обычно.\nШаг 3: Настраиваем окружение # Теперь нужно указать системе использовать сокет Bitwarden вместо стандартного SSH-агента macOS.\nОткрываем ~/.zshrc и добавляем:\nexport SSH_AUTH_SOCK=\u0026#34;$HOME/.bitwarden-ssh-agent.sock\u0026#34; Применяем изменения:\nsource ~/.zshrc Шаг 4: Обновляем SSH config # Открываем ~/.ssh/config и убираем IdentityFile (если у вас были уже добавлены, если нет, добавляем с нуля) для хостов, которые будут использовать ключи из Bitwarden.\nБыло:\nHost LinuxServer Hostname 192.168.1.11 user root port 22 IdentityFile ~/LinuxServer.key Должно стать:\nHost LinuxServer Hostname 192.168.1.11 user root port 22 AddKeysToAgent yes Bitwarden SSH Agent сам предложит все доступные ключи при подключении.\nШаг 5: Проверяем работу # Перед проверкой убедитесь, что Bitwarden запущен и разблокирован. Ключи доступны только после разблокировки хранилища.\nПроверяем, что Bitwarden отдал ключи:\nssh-add -l Вывод должен показать ключи из Bitwarden:\n256 SHA256:i0DqblPzC/00lDAJzetqI53EYzzr+DF@#CDFDF@ LinuxServer (ED25519) 256 SHA256:uFCDz4H6b+dfYb+Od4VilIlOF7FZKCwNA99PgdXdyj0 LinuxServer2 (ED25519) Подключаемся к серверу:\nssh LinuxServer Примечание: После подключения в Bitwarden-клиенте появится запрос на разрешение использования ключа. Но если надоедает это, можно поставить настройку, чтобы не спрашивал, пока не будет заблокировано хранилище.\nКак это работает # При подключении SSH (ssh LinuxServer) сервер отправляет список допустимых ключей Bitwarden SSH Agent получает запрос и перебирает все разблокированные SSH-ключи Сервер принимает тот ключ, который есть в ~/.ssh/authorized_keys Важно: Bitwarden не сопоставляет ключи по имени хоста. Он просто предлагает все доступные ключи по очереди. Сервер сам выбирает подходящий.\nЗаключение # Теперь все SSH-ключи хранятся только в Bitwarden, без файлов на диске. Подключение происходит автоматически, без лишних действий.\nЭто безопаснее, удобнее и проще в управлении. Особенно если у вас много ключей для разных серверов.\n","date":"22 февраля 2026","externalUrl":null,"permalink":"/ssh2bwmacos/","section":"Posts","summary":"","title":"SSH-ключи из Bitwarden на macOS","type":"posts"},{"content":"","date":"2 февраля 2026","externalUrl":null,"permalink":"/categories/development/","section":"Categories","summary":"","title":"Development","type":"categories"},{"content":"","date":"2 февраля 2026","externalUrl":null,"permalink":"/tags/zed/","section":"Tags","summary":"","title":"Zed","type":"tags"},{"content":" Интеграция qwen-cli с редактором Zed # qwen-cli - это командная утилита, которая позволяет использовать возможности модели Qwen AI прямо из терминала. В этой статье я расскажу, как интегрировать qwen-cli с редактором Zed\nУстановка qwen-cli # Для начала установим qwen-cli. Установить его можно через Homebrew:\nbrew install qwen-code Для аутентификации используйте OAuth, указав тип аутентификации:\nqwen --auth-type qwen-oauth Настройка Zed # Zed поддерживает различные инструменты AI через протокол ACP (Agent Client Protocol). Чтобы подключить Qwen Code CLI, нужно воспользоваться встроенной возможностью Zed для добавления сторонних агентов.\nИнтеграция # Zed умеет в Agent Client Protocol (ACP), чтобы подключить Qwen Code CLI, нужно нажать \u0026ldquo;Add agent\u0026rdquo;, затем \u0026ldquo;Add Custom Agent\u0026rdquo; и добавьте следующую конфигурацию:\n{ \u0026#34;agent_servers\u0026#34;: { \u0026#34;Qwen Code\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;command\u0026#34;: \u0026#34;qwen\u0026#34;, \u0026#34;args\u0026#34;: [\u0026#34;--acp\u0026#34;], \u0026#34;env\u0026#34;: {}, }, }, После добавления этой конфигурации, Qwen Code станет доступен как AI агент в Zed, и вы сможете использовать его возможности в AI панельке в редакторе.\n","date":"2 февраля 2026","externalUrl":null,"permalink":"/qwenclizedintegration/","section":"Posts","summary":"","title":"Интеграция qwen-cli с редактором Zed","type":"posts"},{"content":"","date":"24 января 2026","externalUrl":null,"permalink":"/tags/clipboard/","section":"Tags","summary":"","title":"Clipboard","type":"tags"},{"content":"","date":"24 января 2026","externalUrl":null,"permalink":"/tags/flowclip/","section":"Tags","summary":"","title":"Flowclip","type":"tags"},{"content":" Что такое FlowClip? # FlowClip - это менеджер буфера обмена для macOS, созданный как форк проекта Maccy. FlowClip добавляет новую функцию - очередь буфера обмена, которая позволяет собирать несколько элементов и вставлять их вместе.\nОсновные возможности # Легковесность и скорость: Минимальное использование ресурсов Управление с клавиатуры: Создан для продвинутых пользователей Безопасность и конфиденциальность: История буфера обмена хранится локально Нативный интерфейс: Использует стандартные элементы интерфейса macOS Пакетное копирование: Копируйте несколько элементов последовательно для создания очереди Последовательная вставка: Вставляйте элементы в том порядке, в котором они были добавлены (FIFO - первый пришел, первый ушел) Пользовательские разделители: Выбирайте, как разделять вставляемые элементы (пробел, новая строка, запятая или пользовательские символы) Визуальная очередь: Выделенное всплывающее окно для просмотра и управления очередью Как использовать FlowClip # Общий доступ: Нажмите SHIFT + COMMAND + C чтобы открыть FlowClip Режим очереди: Переключить окно очереди: OPTION + SHIFT + V Копируйте элементы обычным способом с помощью COMMAND + C пока активен режим очереди Используйте окно очереди для управления или очистки элементов Выбор и вставка: Введите текст для поиска по истории буфера обмена ENTER чтобы скопировать выбранный элемент OPTION + ENTER чтобы вставить напрямую Как установить FlowClip? # brew tap gityeop/flowclip brew install --cask flowclip ","date":"24 января 2026","externalUrl":null,"permalink":"/flowclip/","section":"Posts","summary":"","title":"FlowClip - продвинутый менеджер буфера обмена для macOS","type":"posts"},{"content":"","date":"24 января 2026","externalUrl":null,"permalink":"/tags/productivity/","section":"Tags","summary":"","title":"Productivity","type":"tags"},{"content":"","date":"11 января 2026","externalUrl":null,"permalink":"/tags/aiogram/","section":"Tags","summary":"","title":"Aiogram","type":"tags"},{"content":"","date":"11 января 2026","externalUrl":null,"permalink":"/tags/bot/","section":"Tags","summary":"","title":"Bot","type":"tags"},{"content":"","date":"11 января 2026","externalUrl":null,"permalink":"/tags/iot/","section":"Tags","summary":"","title":"Iot","type":"tags"},{"content":"","date":"11 января 2026","externalUrl":null,"permalink":"/categories/python/","section":"Categories","summary":"","title":"Python","type":"categories"},{"content":"","date":"11 января 2026","externalUrl":null,"permalink":"/categories/telegram/","section":"Categories","summary":"","title":"Telegram","type":"categories"},{"content":"","date":"11 января 2026","externalUrl":null,"permalink":"/tags/telegram/","section":"Tags","summary":"","title":"Telegram","type":"tags"},{"content":" Введение # Потеря питомца — страшный сон любого владельца. Я решил подойти к вопросу технически и написал небольшой телеграм-бот, который будет круться на домашнем сервере, а на адреснике для своей собаки закажу QR-код, который ведет в персонального Telegram-бота.\nЗачем это нужно? # Геолокация в один клик: Нашедшему не нужно объяснять на словами, где он находится. Нажатие одной кнопки в боте отправляет мне точные координаты GPS.\nПрямая связь: Если человек не хочет делиться локацией, он может перейти в чат со мной.\nАктуальность данных: Если я поменяю номер телефона или акаунт в Telegram, мне не нужно переделывать жетон. Я просто обновлю ссылку в коде бота.\nТехнические детали # Бот написан на Python в 5 строчек кода с использованием библиотеки aiogram.\nПри сканировании QR-кода открывается чат.\nПо команде /start пользователь видит две опции: огромную кнопку «Отправить координаты» и кнопку «Связь с владельцем:».\nКак только нашедший подтверждает отправку локации, бот пересылает мне в личку карту с точкой, и логин владельца в Telegram.\nРазварачивать его буду у себя локально дома на dietpi.\nКак развернуть? # Создание Telegram Bot\u0026rsquo;а # Через @BotFather создайте бота и получите токен.\nЗапишите токен, он нам пригодится для запуска бота.\nОпционально: Сделайте красивую аватарку для бота и приветственное сообщение с картинкой и описание.\nРазварачивание на сервере # Проверяем, что у нас установлен Python и pip: python3 --version pip3 --version Если нет, то устанавливаем (в примере Ubuntu): sudo apt-get update sudo apt-get install python3 python3-pip Скачиваем файлы бота: git clone https://gitverse.ru/tatarinovms/finddogbot.git Переходим в директорию проекта и создаем виртуальное окружение: cd finddogbot python3 -m venv venv Активируем виртуальное окружение : source venv/bin/activate pip install aiogram Настраиваем бота: vim bot.py Введоим данные и сохраняем изменения: API_TOKEN = \u0026#34;ВАШ_ТОКЕН_ОТ_BOTFATHER\u0026#34; # Получите у @BotFather YOUR_CHAT_ID = 123456789 # Ваш Telegram ID YOUR_USERNAME = \u0026#34;ваш_username\u0026#34; # Ваш username без @ Создаем файл сервиса: vim /etc/systemd/system/finddogbot.service Вставьте в него следующее и сохраните: [Unit] Description=Telegram Dog Search Bot After=network.target [Service] Type=simple User=root WorkingDirectory=/root/finddogbot ExecStart=/root/finddogbot/venv/bin/python /root/finddogbot/bot.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target Запуск службы: sudo systemctl daemon-reload sudo systemctl enable finddogbot.service sudo systemctl start finddogbot.service QR-код # Нам необходимо создать QR-код, который будет открывать чат с ботом. Формат ссылки: https://t.me/usernameбота?start=1\nКак выглядит для пользователя? # Как выглдяит для владельца пса? # ","date":"11 января 2026","externalUrl":null,"permalink":"/findmydog/","section":"Posts","summary":"","title":"Telegram бот для собачего адресника","type":"posts"},{"content":"","date":"9 января 2026","externalUrl":null,"permalink":"/tags/comss/","section":"Tags","summary":"","title":"Comss","type":"tags"},{"content":"","date":"9 января 2026","externalUrl":null,"permalink":"/tags/dns/","section":"Tags","summary":"","title":"Dns","type":"tags"},{"content":"","date":"9 января 2026","externalUrl":null,"permalink":"/tags/networking/","section":"Tags","summary":"","title":"Networking","type":"tags"},{"content":"","date":"9 января 2026","externalUrl":null,"permalink":"/categories/openwrt/","section":"Categories","summary":"","title":"OpenWRT","type":"categories"},{"content":"","date":"9 января 2026","externalUrl":null,"permalink":"/tags/router/","section":"Tags","summary":"","title":"Router","type":"tags"},{"content":" Что такое Comss.one DNS? # Comss.one DNS — это бесплатный DNS-сервис от компании Comss.one. Сервис построен на базе PowerDNS и предлагает помощь в работе с играми и AI сервисами. Но как-то пускать весь трафик мне не хочется через этот DNS, так что расскажу как сделать Forward определенных доменов через DNS Comss.one на вашем роутере с OpenWRT.\nКак сделать? # Простите я любитель CLI, так что будем делать через консоль.\nНастройка DNS Comss.one на OpenWRT # Логинимся по ssh на роутер: ssh root@192.168.1.1 Вводим пароль и получаем доступ к консоли роутера.\nДелаем бекап нашего файла /etc/config/dhcp\ncp /etc/config/dhcp ~/dhcp.bak Открываем файл /etc/config/dhcp в редакторе: vim /etc/config/dhcp и в вашу секцию config dnsmasq добавляем список из файла list.txt\nт.е должно получиться что-то типо такого:\n... list server \u0026#39;/ab.chatgpt.com/195.133.25.16\u0026#39; list server \u0026#39;/ai.com/195.133.25.16\u0026#39; list server \u0026#39;/ai.google.dev/195.133.25.16\u0026#39; list server \u0026#39;/aistudio.google.com/195.133.25.16\u0026#39; ... сохраняем файл и перезагружаем dnsmasq: /etc/init.d/dnsmasq restart ","date":"9 января 2026","externalUrl":null,"permalink":"/commsdnsopenwrt/","section":"Posts","summary":"","title":"Настройка Comss.one DNS на OpenWRT","type":"posts"},{"content":"","date":"5 января 2026","externalUrl":null,"permalink":"/categories/backup/","section":"Categories","summary":"","title":"Backup","type":"categories"},{"content":"","date":"5 января 2026","externalUrl":null,"permalink":"/tags/backup/","section":"Tags","summary":"","title":"Backup","type":"tags"},{"content":"","date":"5 января 2026","externalUrl":null,"permalink":"/tags/shell/","section":"Tags","summary":"","title":"Shell","type":"tags"},{"content":" OpenWRT — мощная операционная система для роутеров, но её настройка требует времени. Чтобы не потерять конфигурацию при сбоях или обновлениях, написал скрипт для автоматического резервного копирования на Яндекс Диск с уведомлениями в Telegram.\nРепозиторий: OpenWRTBackupScript на GitVerse\nОписание проекта # OpenWRTBackupScript — shell-скрипт для автоматического создания бекапов конфигурации OpenWRT роутеров с загрузкой на Яндекс Диск.\nВозможности # Создание бекапов через sysupgrade -b Прямая загрузка на Яндекс Диск через rclone Хранение только последних 3 бекапов в облаке Уведомления в Telegram об успешности/ошибках Автоматическая очистка временных файлов Простая настройка прямо в скрипте Установка # Шаг 1: Установка rclone на OpenWRT # # Подключитесь к роутеру ssh root@192.168.1.1 # Обновите список пакетов opkg update # Установите rclone opkg install rclone # Проверьте установку rclone --version Шаг 2: Настройка rclone для Яндекс Диска # rclone config Следуйте инструкциям для настройки подключения к Яндекс Диску.\nШаг 3: Копирование скрипта на роутер # # Подключитесь к роутеру ssh root@192.168.1.1 # Создайте папку и скачайте скрипт mkdir -p /root/scripts curl -o /root/scripts/router-backup.sh https://gitverse.ru/api/repos/tatarinovms/OpenWRTBackupScript/raw/branch/master/router-backup.sh # Сделайте исполняемым chmod +x /root/scripts/router-backup.sh Шаг 4: Настройка Telegram (опционально) # Создание бота:\nНапишите @BotFather в Telegram Отправьте /newbot Введите имя и username бота Получите токен Получение Chat ID: Перейдите по ссылке: https://api.telegram.org/bot[ТОКЕН]/getUpdates и найдите поле \u0026quot;chat\u0026quot;:{\u0026quot;id\u0026quot;:\nШаг 5: Настройка скрипта # Отредактируйте конфигурацию в начале файла:\nvi /root/scripts/router-backup.sh # rclone settings RCLONE_SERVICE=\u0026#34;yandex\u0026#34; # Название вашего rclone сервиса YANDEX_PATH=\u0026#34;Backup/router\u0026#34; # Папка на Яндекс Диске # Telegram settings (опционально) TELEGRAM_BOT_TOKEN=\u0026#34;\u0026#34; # Токен бота (пусто — отключить уведомления) TELEGRAM_CHAT_ID=\u0026#34;\u0026#34; # Chat ID (пусто — отключить уведомления) Шаг 6: Ручной запуск # /root/scripts/router-backup.sh При успехе бекап появится на Яндекс Диске и придёт уведомление в Telegram.\nШаг 7: Автоматизация через cron # crontab -e # Добавьте строку (каждый понедельник в 10:00) 0 10 * * 1 /root/scripts/router-backup.sh \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 # Перезапустите cron /etc/init.d/cron enable /etc/init.d/cron restart Примеры уведомлений # ✅ Успешный бекап:\n✅ OpenWRT Backup Completed 📁 File: router-backup-2025-12-13-1430.tar.gz 📍 Location: yandex:Backup/router/router-backup-2025-12-13-1430.tar.gz 🕐 Time: 2025-12-13 14:30:00 ❌ Ошибка:\n❌ OpenWRT Backup Failed 🚫 Error: Failed to create backup 🕐 Time: 2025-12-13 14:30:00 ","date":"5 января 2026","externalUrl":null,"permalink":"/openwrtbackup/","section":"Posts","summary":"","title":"Автоматический бекап роутера на Яндекс Диск","type":"posts"},{"content":"","date":"5 января 2026","externalUrl":null,"permalink":"/tags/ip/","section":"Tags","summary":"","title":"Ip","type":"tags"},{"content":" Для удалённого доступа к домашнему серверу и сервисам на нем, важно знать текущий внешний IP-адрес. Решил написать простой бот, который отслеживает изменения и присылает уведомления в Telegram.\nОписание проекта # IPChecker — минималистичный Python-бот для мониторинга внешнего IP-адреса. При изменении IP отправляет уведомление в Telegram с указанием старого и нового адреса.\nВозможности # Автоматическая проверка внешнего IP через API ipify.org Уведомления в Telegram при изменении адреса Сохранение истории последнего IP в локальный файла Настраиваемая частота проверок Запуск как системная служба через systemd Автоматический перезапуск при сбоях Установка # 1. Клонирование репозитория # git clone https://gitverse.ru/tatarinovms/IPChecker.git cd IPChecker 2. Установка зависимостей # sudo apt update sudo apt install python3-requests 3. Настройка конфигурации # Скопируйте пример конфигурации и заполните своими данными:\ncp config.example.py config.py Отредактируйте файл config.py:\n# Токен вашего бота от BotFather TELEGRAM_TOKEN = \u0026#34;12345678:ABCDefGhIklMnOpQrStUvWxY\u0026#34; # Ваш ID пользователя (узнайте через @userinfobot) CHAT_ID = \u0026#34;123456789\u0026#34; # Количество проверок в сутки (24 — раз в час) CHECKS_PER_DAY = 24 # Файл для хранения последнего известного IP IP_STORAGE_FILE = \u0026#34;last_ip.txt\u0026#34; 4. Запуск как systemd-сервис # Отредактируйте файл ip_bot.service, указав правильные пути:\n[Unit] Description=Telegram IP Change Notifier After=network.target [Service] Type=simple User=root WorkingDirectory=/root/IPChecker/ ExecStart=/usr/bin/python3 /root/IPChecker/ip_notifier.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target Установите и запустите сервис:\nsudo cp ip_bot.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable ip_bot.service sudo systemctl start ip_bot.service Проверьте статус:\nsudo systemctl status ip_bot.service Как получить токен бота # Напишите @BotFather в Telegram Отправьте команду /newbot Следуйте инструкциям для создания бота Скопируйте полученный токен в TELEGRAM_TOKEN Как узнать свой Chat ID # Отправьте сообщение боту @userinfobot — он покажет ваш ID.\nПример работы # При первом запуске бот отправит:\n🚀 Бот запущен. Текущий IP: 95.165.xxx.xxx\nПри изменении IP:\n🔔 Внимание! Внешний IP изменился. Старый: 95.165.xxx.xxx Новый: 178.176.xxx.xxx\nЗаключение # Простой и надёжный инструмент для тех, кто держит домашний сервер и хочет всегда быть в курсе изменений внешнего IP. Минимальные зависимости и systemd-сервис обеспечивают стабильную работу в фоновом режиме.\nРепозиторий: IPChecker на GitVerse\n","date":"5 января 2026","externalUrl":null,"permalink":"/ipchecker/","section":"Posts","summary":"","title":"IPChecker — мониторинг внешнего IP с уведомлениями в Telegram","type":"posts"},{"content":"","date":"5 января 2026","externalUrl":null,"permalink":"/tags/systemd/","section":"Tags","summary":"","title":"Systemd","type":"tags"},{"content":"","date":"28 декабря 2025","externalUrl":null,"permalink":"/tags/cleaner/","section":"Tags","summary":"","title":"Cleaner","type":"tags"},{"content":"","date":"28 декабря 2025","externalUrl":null,"permalink":"/tags/mole/","section":"Tags","summary":"","title":"Mole","type":"tags"},{"content":" Mole — это универсальный инструмент для глубокой очистки и оптимизации macOS в одном бинарном файле. Он объединяет возможности CleanMyMac, AppCleaner, DaisyDisk и iStat.\nИнструмент умеет сканировать и удалять кэши, логи, остатки браузеров, освобождая гигабайты пространства. Есть умный деинсталлятор, который полностью удаляет приложения вместе с launch-агентами, настройками и скрытыми остатками. Также доступен анализ диска, мониторинг CPU, GPU, памяти, диска и сети в реальном времени.\nКак установить? # brew install tw93/tap/mole Или через скрипт:\ncurl -fsSL https://raw.githubusercontent.com/tw93/Mole/main/install.sh | bash Как использовать? # mo # Интерактивное меню mo clean # Глубокая очистка mo clean --dry-run # Предпросмотр плана очистки mo uninstall # Удаление приложений с остатками mo optimize # Обновление кэшей и сервисов mo analyze # Визуальный анализ диска mo status # Дашборд состояния системы mo purge # Очистка артефактов сборки mo touchid # Настройка Touch ID для sudo mo update # Обновление Mole mo remove # Удаление Mole из системы Полезные фишки # Предпросмотр изменений перед очисткой через --dry-run Управление белым списком защищённых путей через --whitelist Поддержка Vim-биндингов для навигации Интеграция с Raycast и Alfred для быстрого запуска Подробности и исходный код на GitHub проекта.\n","date":"28 декабря 2025","externalUrl":null,"permalink":"/mole/","section":"Posts","summary":"","title":"Mole — глубокая очистка и оптимизация macOS","type":"posts"},{"content":"","date":"28 декабря 2025","externalUrl":null,"permalink":"/tags/optimization/","section":"Tags","summary":"","title":"Optimization","type":"tags"},{"content":"","date":"16 ноября 2025","externalUrl":null,"permalink":"/tags/linux/","section":"Tags","summary":"","title":"Linux","type":"tags"},{"content":"","date":"16 ноября 2025","externalUrl":null,"permalink":"/tags/podcasts/","section":"Tags","summary":"","title":"Podcasts","type":"tags"},{"content":" Podsync — маленький проектик на go, который преобразует каналы с YouTube или Vimeo в обычные подкаст-фиды (RSS). Идея проста: у меня есть каналы, которые я больше слушаю, чем смотрю, и мне хотелось бы делать это в моём подкаст-приёмнике. Гайд будет на Debian-based системы.\nКак это работает # Принцип работы Podsync довольно простой:\nВ конфиге прописываем каналы Podsync по расписанию проверяет обновления Скачивает новые видео через yt-dlp и конвертирует их в аудио в MP3 через ffmpeg или оставляет видео. Тут уж как хотите. Генерирует RSS-фид, доступный по HTTP/HTTPS Вы просто добавляете ссылку вида https://your-domain.com/feed_id.xml в подкаст-клиент — и всё работает.\nУстановка зависимостей # Для работы Podsync нужны yt-dlp, ffmpeg и deno (как JS runtime для yt-dlp на всякий случай):\napt update \u0026amp;\u0026amp; apt install -y yt-dlp ffmpeg curl Deno устанавливается через официальный скрипт:\ncurl -fsSL https://deno.land/install.sh | sh Также понадобится Go, если планируете собирать из исходников:\napt install -y golang Установка Podsync # Вариант A: Сборка из исходников # git clone https://github.com/mxpv/podsync /mnt/dietpi_userdata/podsync cd /mnt/dietpi_userdata/podsync make Вариант Бэ: Готовый бинарь # Скачиваем с GitHub Releases:\ncd /mnt/dietpi_userdata/podsync curl -L -o podsync \u0026#34;https://github.com/mxpv/podsync/releases/download/v2.8.0/podsync-v2.8.0-linux-amd64\u0026#34; chmod +x podsync Вариант Цэ: Docker # Если предпочитаете контейнеры:\nservices: podsync: image: ghcr.io/mxpv/podsync container_name: podsync volumes: - ./data:/app/data/ - ./db:/app/db/ - ./config.toml:/app/config.toml ports: - 8181:8080 Запуск:\ndocker compose up -d YouTube Data API v3 ключ # Ключевой момент — для работы Podsync нужен YouTube Data API v3 ключ. Без него парсинг каналов не работает.\nПолучить ключ можно здесь: https://developers.google.com/youtube/registering_an_application\nВ конфиге нужно указать ключ в секции:\n[tokens] youtube = \u0026#34;YOUR_YOUTUBE_API_KEY\u0026#34; Или даже несколько для ротации:\nyoutube = [\u0026#34;KEY1\u0026#34;, \u0026#34;KEY2\u0026#34;, \u0026#34;KEY3\u0026#34;] Настройка конфигурации # Собственно и сам конфиг. Создаём файл config.toml на основе примера:\ncp /mnt/dietpi_userdata/podsync/config.toml.example /mnt/dietpi_userdata/podsync/config.toml nano /mnt/dietpi_userdata/podsync/config.toml Для примера:\n[server] port = 8181 hostname = \u0026#34;https://poddown.tatarinovlovesbeaver.su\u0026#34; [cleanup] keep_last = 2 [storage] [storage.local] data_dir = \u0026#34;/mnt/dietpi_userdata/podsync/data\u0026#34; [tokens] youtube = \u0026#34;тут ваш ключ из пункта выше\u0026#34; [feeds] [feeds.MaximTatarinov] url = \u0026#34;https://www.youtube.com/@MaximTatarinov\u0026#34; format = \u0026#34;video\u0026#34; update_period = \u0026#34;8h\u0026#34; page_size = 5 youtube_dl_args = [\u0026#34;--js-runtimes\u0026#34;, \u0026#34;deno:/root/.deno/bin/deno\u0026#34;] [log] filename = \u0026#34;podsync.log\u0026#34; max_size = 50 max_age = 30 max_backups = 1 compress = true debug = false Конфиг готов.\nЗапуск как systemd-сервис # Чтобы Podsync работал в фоне и запускался автоматически, создаём сервис:\nnano /etc/systemd/system/podsync.service [Unit] Description=Podsync After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/mnt/dietpi_userdata/podsync/bin/podsync WorkingDirectory=/mnt/dietpi_userdata/podsync Restart=on-failure RestartSec=10 StandardOutput=journal StandardError=journal Environment=\u0026#34;PATH=/root/.deno/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\u0026#34; [Install] WantedBy=multi-user.target Активируем и запускаем:\nsystemctl daemon-reload systemctl enable podsync systemctl start podsync Проверить статус:\nsystemctl status podsync journalctl -u podsync -f Reverse proxy через nginx # Podsync у меня работает без TLS, поэтому HTTPS у нас будет обрабатывать nginx. Конфиг для сайта:\nserver { listen 80; listen [::]:80; server_name poddown.tatarinovlovesbeaver.su; return 301 https://$host$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; http2 on; listen 443 quic; listen [::]:443 quic; quic_retry on; quic_gso on; add_header Alt-Svc \u0026#39;h3=\u0026#34;:443\u0026#34;; ma=86400\u0026#39; always; server_name poddown.tatarinovlovesbeaver.su; ssl_certificate /etc/letsencrypt/live/poddown.tatarinovlovesbeaver.su/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/poddown.tatarinovlovesbeaver.su/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://127.0.0.1:8181; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } Применить:\nnginx -t \u0026amp;\u0026amp; systemctl reload nginx Фильтры и тонкая настройка # Podsync позволяет не просто скачивать всё подряд, а выбирать контент по правилам. Например, скачивать только эпизоды, содержащие «обзор» и длительностью до 2 часов:\n[feeds] [feeds.ID1] url = \u0026#34;https://www.youtube.com/@channel\u0026#34; format = \u0026#34;audio\u0026#34; filters = { title = \u0026#34;обзор\u0026#34;, max_duration = 7200, max_age = 30 } Доступные фильтры:\nПараметр Описание title Regex для совпадения в заголовке not_title Regex для исключения по заголовку description Regex для совпадения в описании not_description Regex для исключения по описанию min_duration Минимальная длительность (секунды) max_duration Максимальная длительность (секунды) min_age Минимальный возраст (дни) max_age Максимальный возраст (дни) Также можно задать кастомный формат видео:\n[feeds] [feeds.MaximTatarinov] format = \u0026#34;custom\u0026#34; custom_format = { youtube_dl_format = \u0026#34;bestaudio[ext=m4a]\u0026#34;, extension = \u0026#34;m4a\u0026#34; } Итог # RSS-лента доступна по адресу:\nhttps://poddown.tatarinovlovesbeaver.su/MaximTatarinov.xml Подставляем её в ваш подкаст-клиент и вуаля!\nP.S еще рекомендую вам сделать перекидование Cookie для корректной работы yt-dlp. Про это можно почитать тут\n","date":"16 ноября 2025","externalUrl":null,"permalink":"/podsync/","section":"Posts","summary":"","title":"Podsync — скачивание подкастов из YouTube","type":"posts"},{"content":"","date":"22 октября 2025","externalUrl":null,"permalink":"/categories/linux/","section":"Categories","summary":"","title":"Linux","type":"categories"},{"content":"","date":"22 октября 2025","externalUrl":null,"permalink":"/tags/mtproto/","section":"Tags","summary":"","title":"Mtproto","type":"tags"},{"content":"","date":"22 октября 2025","externalUrl":null,"permalink":"/tags/proxy/","section":"Tags","summary":"","title":"Proxy","type":"tags"},{"content":"","date":"22 октября 2025","externalUrl":null,"permalink":"/tags/ubuntu/","section":"Tags","summary":"","title":"Ubuntu","type":"tags"},{"content":"","date":"22 октября 2025","externalUrl":null,"permalink":"/tags/vps/","section":"Tags","summary":"","title":"Vps","type":"tags"},{"content":" Установка MTProto Proxy на Ubuntu VPS # MTProto — это официальный протокол для Telegram, который обеспечивает безопасное подключение к мессенджеру. В этом руководстве рассмотрен полный процесс установки и настройки MTProxy на вашем сервере.\nТребования # Для запуска собственного прокси-сервера понадобится:\nVPS ну например с Ubuntu Root-доступ Открытый порт наружу Подключение и обновление системы # Подключаемся к серверу по SSH:\nssh root@your_server_ip Обновляем пакеты:\nsudo apt update -y sudo apt upgrade -y Установка зависимостей # sudo apt install git curl build-essential libssl-dev zlib1g-dev -y Клонирование репозитория # Рекомендуется использовать активный форк MTProxy:\ngit clone https://github.com/GetPageSpeed/MTProxy cd MTProxy Компиляция # make Если возникла ошибка, очистите сборку:\nmake clean и повторите команду make.\nКопирование бинарного файла # sudo mkdir -p /opt/MTProxy sudo cp objs/bin/mtproto-proxy /opt/MTProxy/ cd /opt/MTProxy Загрузка конфигураций # Скачиваем актуальные файлы конфигурации:\nsudo curl -s https://core.telegram.org/getProxySecret -o proxy-secret sudo curl -s https://core.telegram.org/getProxyConfig -o proxy-multi.conf Для автоматического обновления добавьте в cron:\nsudo crontab -e Строка для еженедельного обновления:\n0 3 * * 1 curl -s https://core.telegram.org/getProxyConfig -o /opt/MTProxy/proxy-multi.conf \u0026amp;\u0026amp; systemctl restart MTProxy.service Генерация секретного ключа # head -c 16 /dev/urandom | xxd -ps Запишите ключ куда нить — он понадобится для конфигурации службы и ваших клиентов.\nНастройка Firewall # Открываем порт для клиентов:\nsudo ufw allow 8443/tcp Для firewalld:\nsudo firewall-cmd --zone=public --permanent --add-port=8443/tcp sudo firewall-cmd --reload P.S На этот порт мы и будем подключаться с Telegram клиента\nНастройка службы systemd # Создаем службу:\nsudo nano /etc/systemd/system/MTProxy.service Пример конфигурации:\n[Unit] Description=MTProxy After=network.target [Service] Type=simple mtproxy WorkingDirectory=/opt/MTProxy ExecStart=/opt/MTProxy/mtproto-proxy -u mtproxy -p 8888 -H \u0026lt;MTPROXY_PORT\u0026gt; -S \u0026lt;YOUR_SECRET\u0026gt; --aes-pwd proxy-secret proxy-multi.conf -M 1 Restart=on-failure [Install] WantedBy=multi-user.target Параметры:\n-u mtproxy — пользователь для запуска -p 8888 — локальный порт статистики -H — порт подключения клиентов -S — секретный ключ -M 1 — число воркеров Если сервер за NAT, добавьте:\n--nat-info \u0026lt;внутренний_IP\u0026gt;:\u0026lt;внешний_IP\u0026gt; Запуск и автозагрузка # sudo systemctl daemon-reload sudo systemctl start MTProxy.service sudo systemctl enable MTProxy.service Проверяем статус службы:\nsudo systemctl status MTProxy.service Подключение клиентов Telegram # Добавьте прокси в Telegram по ссылке со своими параметрами:\ntg://proxy?server=\u0026lt;IP_сервера\u0026gt;\u0026amp;port=\u0026lt;ПОРТ\u0026gt;\u0026amp;secret=\u0026lt;СЕКРЕТ\u0026gt; P.S Для защиты от анализа трафика добавьте префикс dd к ключу на клиенте (random padding).\nИли вручную:\nНастройки → Данные и память → Настройки прокси → Добавить прокси → MTProto\nСервер: IP вашего VPS Порт: выбранный порт Секрет: ваш ключ Послесловие # Я оставил кучу всего за бортом: настройка промоканала в прокси, как сделать красивый домен и т.д. Но смысл гайда в простоте и пошаговости.\n","date":"22 октября 2025","externalUrl":null,"permalink":"/mtprx/","section":"Posts","summary":"","title":"Установка MTProto на Ubuntu VPS","type":"posts"},{"content":" Введение # Краткая заметка и дополнение к моему посту: rclone для Яндекс Диска. В Я.Диске есть папка Загрузки — в неё попадают файлы, если вы на каком-то сайте или сервисе нажали кнопку «Загрузить в Яндекс.Диск». Я решил использовать её как временное облачное хранилище для загрузки файлов прямо из терминала.\nДля этого напишем простую функцию для zsh.\nНастройка # Открываем удобным редактором файл ~/.zshrc и добавляем в него следующую функцию:\nyup() { if [[ $# -eq 0 ]]; then echo \u0026#34;Укажи файл или папку для копирования!\u0026#34; return 1 fi for item in \u0026#34;$@\u0026#34;; do if [[ -f \u0026#34;$item\u0026#34; ]]; then rclone copy \u0026#34;$item\u0026#34; yandex:Загрузки --progress echo \u0026#34;Файл \u0026#39;$item\u0026#39; успешно загружен.\u0026#34; elif [[ -d \u0026#34;$item\u0026#34; ]]; then folder_name=$(basename \u0026#34;$item\u0026#34;) rclone copy \u0026#34;$item\u0026#34; \u0026#34;yandex:Загрузки/$folder_name\u0026#34; --progress echo \u0026#34;Папка \u0026#39;$item\u0026#39; успешно загружена в подкаталог \u0026#39;$folder_name\u0026#39;.\u0026#34; else echo \u0026#34;Ошибка: \u0026#39;$item\u0026#39; не найден.\u0026#34; fi done } Как пользоваться # Для загрузки одного файла: yup путь/к/файлу Для загрузки нескольких файлов: yup файл1 файл2 файл3 Для загрузки папки со всем её содержимым (создаст подкаталог с именем папки): yup путь/к/папке Можно смешивать файлы и папки: yup файл1 путь/к/папке файл2 При загрузке будет показываться прогресс и подтверждение успешной операции.\n","date":"26 сентября 2025","externalUrl":null,"permalink":"/ydiskupload/","section":"Posts","summary":"","title":"Заметка про функцию для загрузки в Yandex Disk из zsh","type":"posts"},{"content":" Введение # Иногда хочется скачивать треки в автоматическом режиме прямо на домашний сервер. Для браузеров на базе Chromium есть удобное расширение Yandex Music Downloader V3, которое умеет загружать музыку в FLAC и пакетом, но гораздо удобнее иметь аналог в командной строке.\nУстановка и настройка # Установите утилиту:\npipx install git+https://github.com/llistochek/yandex-music-downloader.git Добавьте pipx в PATH:\npipx ensurepath Получите токен. Есть несколько способов получения токена — я использовал способ «для продвинутых».\nСохраните токен в файл:\nvim ~/.yandex_music_token chmod 600 ~/.yandex_music_token Сохранение токена в файле упростит дальнейший вызов утилиты.\nИспользование # Простейшая команда для скачивания одного трека выглядит так:\nyandex-music-downloader \\ --token \u0026#34;ваш_токен\u0026#34; \\ --quality 2 \\ --embed-cover \\ --cover-resolution original \\ --retry-delay 5 \\ --skip-existing \\ --only-music \\ --url https://music.yandex.ru/track/116054894 Чтобы не вводить всё это каждый раз, можно обернуть вызов в функцию вашей оболочки.\nОткройте файл ~/.bashrc или ~/.zshrc.\nДобавьте в конец или начало:\nymdl() { if [[ \u0026#34;$1\u0026#34; != --* ]]; then url=\u0026#34;$1\u0026#34; shift else url=\u0026#34;\u0026#34; fi yandex-music-downloader \\ --token \u0026#34;$(cat ~/.yandex_music_token)\u0026#34; \\ --quality 2 \\ --embed-cover \\ --cover-resolution original \\ --retry-delay 5 \\ --skip-existing \\ --only-music \\ ${url:+--url \u0026#34;$url\u0026#34;} \\ \u0026#34;$@\u0026#34; } Примените изменения:\nsource ~/.bashrc или\nsource ~/.zshrc Теперь можно скачивать треки, альбомы и плейлисты одной командой:\nymdl https://music.yandex.ru/album/18466774 ","date":"20 сентября 2025","externalUrl":null,"permalink":"/yandexmusicdownloadcli/","section":"Posts","summary":"","title":"CLI утилита для скачивания музыки","type":"posts"},{"content":"","date":"2 августа 2025","externalUrl":null,"permalink":"/tags/http/","section":"Tags","summary":"","title":"Http","type":"tags"},{"content":"","date":"2 августа 2025","externalUrl":null,"permalink":"/tags/ios/","section":"Tags","summary":"","title":"Ios","type":"tags"},{"content":"","date":"2 августа 2025","externalUrl":null,"permalink":"/tags/mitmproxy/","section":"Tags","summary":"","title":"Mitmproxy","type":"tags"},{"content":" Введение # mitmproxy — это интерактивный прокси-сервер, позволяющий перехватывать, анализировать и модифицировать HTTP, HTTPS и WebSocket-трафик «на лету». Название утилиты происходит от «man-in-the-middle proxy» — именно так она и работает: становится «посредником» между клиентом и сервером, что позволяет видеть всё, что передаётся между ними.\nОсновные возможности mitmproxy:\nПерехват и отображение HTTP/HTTPS-трафика в реальном времени; Интерактивная модификация запросов и ответов; Генерация SSL-сертификатов для HTTPS; Возможность сохранять и воспроизводить трафик; CLI-интерфейс; Удобный веб интерфейс для анализа и управления трафиком; Это отличный инструмент для тестирования API, анализа трафика мобильных приложений и поиска уязвимостей.\nУстановка # Самый простой способ установить mitmproxy на Mac, как всегда использовать Homebrew.\nbrew install mitmproxy Проверьте установку:\nmitmproxy --version Использование mitmproxy с iPhone # Рассмотрим пример: вы хотите проанализировать, какие запросы отправляет приложение на iPhone.\nЗапуск mitmproxy # В терминале на Mac запустите:\nmitmweb По умолчанию прокси запускается на порту 8080.\n➜ beaver mitmweb [16:00:08.620] HTTP(S) proxy listening at *:8080. [16:00:08.620] Web server listening at http://127.0.0.1:8081/?token=193beaverlovestree14 Как мы видем у вас запустился уже прокси и сразу открылась веб-страница с интерфейсом.\nНастройка сети на iPhone # Подключите iPhone к той же Wi-Fi сети, что и ваш Mac. Перейдите в настройки Wi-Fi → нажмите на значок (i) рядом с вашей сетью. Пролистайте до Configure Proxy и выберите Manual. В поле “Server” укажите IP-адрес вашего Mac. В поле “Port” укажите 8080. Нажмите Save. Теперь весь HTTP/HTTPS трафик с iPhone будет проходить через ваш Mac.\nНастройка SSL-сертификата на iPhone # Чтобы mitmproxy мог расшифровывать HTTPS, нужно установить его сертификат:\nВ Safari на iPhone откройте адрес: http://mitm.it Найдите пункт iOS и скачайте сертификат по нажатию на кнопку: Get mitmproxy-ca-cert.pem Перейдите в Настройки → Выберите «Профиль загружен» и установите его. Затем в Настройки → Основные → листаете в самый низ до пункта - Sertificate Trust Settings Находим mitmproxy и взводим крыжик в состоние On Запускаем приложение или сайт, которое мы \u0026ldquo;хотим послушать\u0026rdquo; Наблюдение за трафиком # Во вкладке браузера, которая открылась после запуска mitmweb, отображаются все запросы.\nВозможности интерфейса:\nПросмотр запросов и ответов; Редактирование и повторная отправка; Изменение заголовков и тел запросов; Сохранение и экспорт трафика; Изменение внешнего вида и фильтрация; Вкладка Options позволяет настраивать поведение прокси прямо в веб-интерфейсе, без использования флагов при запуске. Задача со * # mitmproxy умеет работать как WireGuard-сервер. Это означает, что на клиентском устройстве (например, iPhone) достаточно установить WireGuard и подключиться к туннелю — и весь трафик будет перехватываться без необходимости ручной настройки прокси в Wi-Fi. QR для подключения рисуется в веб-морде и конфиг выводится в консоль после запуска mitmproxy.\nЭто может быть особенно полезно в ограниченных или защищённых сетях.\nЗапускается mit такой коммандой:\nmitmweb --mode wireguard ","date":"2 августа 2025","externalUrl":null,"permalink":"/mitmproxy/","section":"Posts","summary":"","title":"mitmproxy: инструмент перехвата и анализа трафика","type":"posts"},{"content":"","date":"2 августа 2025","externalUrl":null,"permalink":"/tags/network/","section":"Tags","summary":"","title":"Network","type":"tags"},{"content":"","date":"19 июля 2025","externalUrl":null,"permalink":"/tags/docker/","section":"Tags","summary":"","title":"Docker","type":"tags"},{"content":"","date":"19 июля 2025","externalUrl":null,"permalink":"/tags/uptime-kuma/","section":"Tags","summary":"","title":"Uptime-Kuma","type":"tags"},{"content":" Введение # У меня уже есть серия постов про UptimeKuma: Uptime Kuma – мониторинг ваших сервисов, Uptime Kuma – добавляем мониторинг статуса systemd сервисов\nТеперь пришло время настроить бекап настроек этого сервиса. Новое ничего придумывать не будем, возьмем за основу проторенный путь из статьи: Делаем резервную копию базы Vaultwarden в DietPi\nОбщий план бэкапа # В теории процесс резервного копирования довольно прост:\n— Остановить сервис UptimeKuma\n— Скопировать папку с настройками\n— Заархивировать эти данные с паролем\n— Загрузить архив в облако с помощью rclone\n— Запустить UptimeKuma обратно\nПодготовка скрипта для бекапа # Как я говорил выше, мы будем использовать похожий скрипт из статьи Делаем резервную копию базы Vaultwarden в DietPi, так что нового ничего нового особо нет\n— создаем файл nano /root/scripts/uptimekumabackup.sh в вашем любимом редакторе и копируем в него содержание моего файла uptimekumabackup.sh\n— создаем файл с настройками работы скрипта nano /root/scripts/backups.env\nP.S. Если он у вас уже был, мы просто добавим в него новые переменные: OUTPUT_UPTIMEKUMA и RCLONE_FOLDER_UPTIMEKUMA\nSECRET_KEY=passwordqwerty123 OUTPUT_UPTIMEKUMA=vaultwarden_backup.zip RCLONE_SERVICES=yandex RCLONE_FOLDER_UPTIMEKUMA=backupdromserver/dbuptumekuma Пояснение к файлу настроек:\nSECRET_KEY = пароль для вашего архива с бекапами\nOUTPUT_UPTIMEKUMA = имя архива с вашим бекапом\nRCLONE_SERVICES = название облачного сервиса для бэкапа в rclone\nRCLONE_FOLDER_UPTIMEKUMA = Название папки в облачном сервисе\n— сохраняем файл настроек\nПроверка работы скрипта # — переходим в папку со скриптом cd /root/scripts/\n— запускаем скрипт bash ./uptimekumabackup.sh\nОтправка уведомлений в Telegram (опционально) # Скрипт может отправлять уведомления в Telegram. Для этого:\nСоздаём бота # Открываем @BotFather, создаём бота и сохраняем API Token.\nУзнаём chat_id # — Напишите боту /start\n— Перейдите по ссылке в браузере:\nhttps://api.telegram.org/bot\u0026lt;API_TOKEN\u0026gt;/getUpdates\n(замените \u0026lt;API_TOKEN\u0026gt; на свой токен бота, сохраненный ранее)\nВ ответе будет JSON, где ищем:\n\u0026#34;chat\u0026#34;: { \u0026#34;id\u0026#34;: 987654321, ... } Это и есть TELEGRAM_CHAT_ID.\n— Добавляем переменные TELEGRAM_BOT_TOKEN и TELEGRAM_CHAT_ID в /root/scripts/backups.env или используем те что у вас уже были.\nTELEGRAM_BOT_TOKEN=987654321:QWERTYUIO-ASDFGHJKlzx TELEGRAM_CHAT_ID=987654321 — сохраняем файл настроек\nДобавляем в cron ваш скрипт # — делаем скрипт исполняемым chmod +x /root/scripts/uptimekumabackup.sh\n— выполняем команду crontab -e\n— добавляем строку 0 8 * * * /root/scripts/uptimekumabackup.sh\n— сохраняем изменения\nДанный скрипт будет выполняется каждый день в 8 утра.\n","date":"19 июля 2025","externalUrl":null,"permalink":"/uptimekumabackup/","section":"Posts","summary":"","title":"Делаем резервную копию настроек UptimeKuma","type":"posts"},{"content":" Введение # Как вы знаете, я использую я использую DietPi и на нем у меня развернут Vaultwarden.\nВ той статье я описывал общий способ развёртывания Vaultwarden, не привязанный к DietPi. Однако в DietPi всё гораздо проще — Vaultwarden можно установить через официальный установщик.\nОбщий план бэкапа # В теории процесс резервного копирования довольно прост:\n— Остановить сервис Vaultwarden\n— Скопировать файл db.sqlite3\n— Скопировать папки attachments и sends (если используете вложения и отправку файлов)\n— Скопировать vaultwarden.env (на всякий случай)\n— Заархивировать эти данные с паролем\n— Загрузить архив в облако с помощью rclone\n— Запустить Vaultwarden обратно\nДанный пост буду писать про бекапирование на DietPi. Так как я ленив, скорее всего это будет просто и \u0026ldquo;в три строчки\u0026rdquo; (ну почти).\nПодготовка скрипта для бекапа # — создаем файл nano /root/scripts/vaultwardenbackup.sh в вашем любимом редакторе и копируем в него содержание моего файла vaultwardenbackup.sh\n— создаем файл с настройками работы скрипта nano /root/scripts/backups.env\nSECRET_KEY=passwordqwerty123 OUTPUT_VAULTWARDEN=vaultwarden_backup.zip RCLONE_SERVICES=yandex RCLONE_FOLDER_VAULTWARDEN=backupdromserver/dbvaultwarden Пояснение к файлу настроек:\nSECRET_KEY = пароль для вашего архива с бекапами\nOUTPUT_VAULTWARDEN = имя архива с вашим бекапом\nRCLONE_SERVICES = название облачного сервиса для бакапа в rclone\nRCLONE_FOLDER_VAULTWARDEN = Название папки в облачном сервисе\n— сохраняем файл настроек\nПроверка работы скрипта # — переходим в папку со скриптом cd /root/scripts/\n— запускаем скрипт bash ./vaultwardenbackup.sh\nОтправка уведомлений в Telegram (опционально) # Скрипт может отправлять уведомления в Telegram. Для этого:\nСоздаём бота # Открываем @BotFather, создаём бота и сохраняем API Token.\nУзнаём chat_id # — Напишите боту /start\n— Перейдите по ссылке в браузере:\nhttps://api.telegram.org/bot\u0026lt;API_TOKEN\u0026gt;/getUpdates\n(замените \u0026lt;API_TOKEN\u0026gt; на свой токен бота, сохраненный ранее)\nВ ответе будет JSON, где ищем:\n\u0026#34;chat\u0026#34;: { \u0026#34;id\u0026#34;: 987654321, ... } Это и есть TELEGRAM_CHAT_ID.\n— Добавляем переменные TELEGRAM_BOT_TOKEN и TELEGRAM_CHAT_ID в /root/scripts/backups.env\nTELEGRAM_BOT_TOKEN=987654321:QWERTYUIO-ASDFGHJKlzx TELEGRAM_CHAT_ID=987654321 — сохраняем файл настроек\nДобавляем в cron ваш скрипт # — делаем скрипт исполняемым chmod +x /root/scripts/vaultwardenbackup.sh\n— выполняем комманду crontab -e\n— добавляем строку 0 8 * * * /root/scripts/vaultwardenbackup.sh\n— сохраняем изменения\nДанный скрипт будет выполняется каждый день в 8 утра.\n","date":"19 июля 2025","externalUrl":null,"permalink":"/vaultwardenbackup/","section":"Posts","summary":"","title":"Делаем резервную копию настроек Vaultwarden","type":"posts"},{"content":"","date":"12 июля 2025","externalUrl":null,"permalink":"/categories/browser/","section":"Categories","summary":"","title":"Browser","type":"categories"},{"content":"","date":"12 июля 2025","externalUrl":null,"permalink":"/tags/browser/","section":"Tags","summary":"","title":"Browser","type":"tags"},{"content":"","date":"12 июля 2025","externalUrl":null,"permalink":"/tags/chromium/","section":"Tags","summary":"","title":"Chromium","type":"tags"},{"content":"","date":"12 июля 2025","externalUrl":null,"permalink":"/tags/dia/","section":"Tags","summary":"","title":"Dia","type":"tags"},{"content":" Dia - это новый веб-браузер, разработанный компанией The Browser Company, ранее известной по продукту Arc. В отличие от своего предшественника(который они закрыли), Dia ориентирован на максимально простое и привычное взаимодействие, но с интеграцией AI. Кстати данный браузер вы не установите на мак на процессоре Intel, только на M чипы. И браузер не работает из РФ. Вы просто не залогинились в аккаунт.\nДля проверки откуда вы его запускаете браузер использует сервис LaunchDarkly, который и дает комманду на установку флагов в браузере и проверяет запуск.\nЯ решил немного потрогать их алфа версию и отпишусь по особенностям и что нашел.\nНа чем основан? # Кратко:Chromium Engine Version 138.0.7204.101\nПодсмотрим в /Applications/Dia.app/Contents/Info.plist\nVersion: 0.37.1\nSDK Used: macOS 15.2 (macOS Sequoia beta)\nMinimum OS: macOS 14.0 (Sonoma)\nBuild Number: 65361\nТакже обновления с адреса https://releases.diabrowser.com/BoostBrowser-updates.xml проверяются каждые 8 часов.\nAI Ассистент # Встроенный ИИ-ассистент: Чат-бот интегрирован прямо в адресную строку Из РФ ассистент не работает корректно, мы получаем ошибку:\nauthenticationFailed(AuthClient.AccountServiceError (code: AuthClient.AccountServiceErrorCode.restrictedCountry, message: nil)) Но если вы не в РФ, то все работает отлично!\nAI ассисент на странице Ассистенту можно задать вопрос про контент на странице:\nВыбирать несколько элементов или несколько вкладок и уточнить необходимые вам детали, я вот попросил выбрать лучший роутер и сравнить их: Что под копотом? # Расширения и фреемворки # Посмотрим какие расширения у нас стоят из коробки в браузере. # Открываем страницу : chrome://extensions-internals, которая нас редектит на dia://extensions-internals/ и подсматриваем в json. Что у нас есть:\nРасширение Назначение Web Store Аналог Chrome Web Store, адаптирован под Arc/Dia Arc internal extension Внутренняя логика браузера Chromium PDF Viewer Просмотр PDF Google Hangouts Интеграция с Google Hangouts Посмотрим фреемворки приложении: # Переходим в папку:\ncd /Applications/Dia.app/Contents/Frameworks Смотрим что у нас есть:\nФреймворк Назначение ArcCore.framework Основное ядро браузера Arc - управление интерфейсом, вкладками, Spaces и т.д. GRDB.framework Локальное хранение данных через SQLite (история, закладки, настройки и т.п.). libAIInfra.dylib Внутренняя библиотека. libAIInfraTestBindings.dylib Судя по названию для отладки и тестирования либы libAIInfra. Lottie.framework Анимаций в интерфейсе (например, при переключении между вкладками). Sentry.framework Сбор краш-репортов Sparkle.framework Автоматическое обновление приложения на macOS. Содержимое ./Resources/ # Посмотрим что у нас по ресурсам? Что интересно бандлы до сих пор имеют преффиксы в названиях сторого творения компании ARC..\nЕсть такие бандлы как:\nADK_ADK.bundle и ARCClients_BlockListClient.bundle AdBlock встренный из интересного, есть вот такая структура: \u0026#34;id\u0026#34;: \u0026#34;ua\u0026#34;, \u0026#34;display_name\u0026#34;: \u0026#34;RU AdList\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;regional\u0026#34;, Большой список адресов. Я их себе скачал, засуну в свой AdGuard DNS\nARCClients_AppRestartClient.bundle Перезапускалка браузера. Внутри короткий sh скипт, который мониторит запуск браузера\nAIInfra_LocalClassification.bundle Модуль отвечающий за локальную классификацию данных с помощью искусственного интеллекта. У нас лежит файл vocab.txt в котором у нас словарь токенизатора возможно для DistilBERT. Интересно что есть слова: russia,russian\nswift-transformers_Hub.bundle Реализация Hugging Face Transformers на Swift.Для работы с NLP-моделями локально.\nOnDeviceLoRAadaptors.bundle LoRA - метод дообучения LLM,т.е есть возможность адаптировать модели под конкретные задачи без полного переобучения В директории OnDeviceLoRAadaptors.bundle конфигурационный файл модели DistilBERT - config.json:\n{ \u0026#34;_name_or_path\u0026#34;: \u0026#34;distilbert-base-uncased\u0026#34;, \u0026#34;activation\u0026#34;: \u0026#34;gelu\u0026#34;, \u0026#34;architectures\u0026#34;: [ \u0026#34;DistilBertForSequenceClassification\u0026#34; ], \u0026#34;attention_dropout\u0026#34;: 0.1, \u0026#34;dim\u0026#34;: 768, \u0026#34;dropout\u0026#34;: 0.1, \u0026#34;hidden_dim\u0026#34;: 3072, \u0026#34;id2label\u0026#34;: { \u0026#34;0\u0026#34;: \u0026#34;LABEL_0\u0026#34;, \u0026#34;1\u0026#34;: \u0026#34;LABEL_1\u0026#34;, \u0026#34;2\u0026#34;: \u0026#34;LABEL_2\u0026#34; }, \u0026#34;initializer_range\u0026#34;: 0.02, \u0026#34;label2id\u0026#34;: { \u0026#34;LABEL_0\u0026#34;: 0, \u0026#34;LABEL_1\u0026#34;: 1, \u0026#34;LABEL_2\u0026#34;: 2 }, \u0026#34;max_position_embeddings\u0026#34;: 512, \u0026#34;model_type\u0026#34;: \u0026#34;distilbert\u0026#34;, \u0026#34;n_heads\u0026#34;: 12, \u0026#34;n_layers\u0026#34;: 6, \u0026#34;pad_token_id\u0026#34;: 0, \u0026#34;qa_dropout\u0026#34;: 0.1, \u0026#34;seq_classif_dropout\u0026#34;: 0.2, \u0026#34;sinusoidal_pos_embds\u0026#34;: false, \u0026#34;tie_weights_\u0026#34;: true, \u0026#34;torch_dtype\u0026#34;: \u0026#34;float16\u0026#34;, \u0026#34;transformers_version\u0026#34;: \u0026#34;4.44.2\u0026#34;, \u0026#34;vocab_size\u0026#34;: 30522 } Немного его расшифруем:\nПараметр Значение/Тип Описание _name_or_path distilbert-base-uncased Имя предобученной модели. activation \u0026quot;gelu\u0026quot; Функция активации (GELU - Gaussian Error Linear Unit). architectures [\u0026quot;DistilBertForSequenceClassification\u0026quot;] Архитектура модели для классификации текста. attention_dropout 0.1 Вероятность dropout dim 768 Размерность эмбеддингов (векторное представление слов/токенов). dropout 0.1 Базовый уровень dropout для всех слоёв. hidden_dim 3072 Размерность скрытого слоя в feed-forward сети. id2label {\u0026quot;0\u0026quot;: \u0026quot;LABEL_0\u0026quot;, ...} Соответствие числовых ID меткам классов (3 класса в примере). label2id {\u0026quot;LABEL_0\u0026quot;: 0, ...} Обратное соответствие меток к ID. initializer_range 0.02 Диапазон инициализации весов. max_position_embeddings 512 Максимальная длина обрабатываемого текста (в токенах). model_type \u0026quot;distilbert\u0026quot; Тип модели (упрощённая версия BERT). n_heads 12 Количество голов в механизме \u0026ldquo;внимания\u0026rdquo;. n_layers 6 Количество трансформерных слоёв (у оригинального BERT - 12). pad_token_id 0 ID токена для дополнения текста. qa_dropout 0.1 Dropout для вопросно-ответных задач seq_classif_dropout 0.2 Специфичный dropout для слоя классификации. sinusoidal_pos_embds false Использование синусоидальных позиционных эмбеддингов (здесь отключено). tie_weights_ true Связывание весов между слоями (для эффективности). torch_dtype \u0026quot;float16\u0026quot; Тип данных PyTorch (половинная точность для экономии памяти). transformers_version \u0026quot;4.44.2\u0026quot; Версия библиотеки Hugging Face Transformers. vocab_size 30522 Размер словаря . Также рядом с конфигом у нас лежат и веса и LoRA-адаптеры:\nResources ls cmd_t_router_adapter_model_overrides.safetensors cmd_t_router_adapter_model.safetensors cmd_t_router_classification_head_overrides.safetensors cmd_t_router_classification_head.safetensors config.json distilBERTbase_part1.safetensors distilBERTbase_part2.safetensors sensitive_content_adapter_model.safetensors sensitive_content_classification_head.safetensors skills_adapter_model.safetensors skills_classifier_head.safetensors mlx-swift_Cmlx.bundle MLX - фреймворк для работы с машинным обучением на Apple Silicon, т.е он нужен для ускорения вычислений для AI-моделей на Mac.\nswift-transformers.Hub.resources Нужен для работы gpt2 и seq2seq моделями, об этом нам накают файлы: gpt2_tokenizer_config.json и t5_tokenizer_config.json\nARCClients_Integrations.bundle и ARCClients_LiveDataClient.bundle Интеграция с различными сервисами, а именно: Получение транскриптов и метаданных видео в Youtube, работа с Notion, Google Docs и т.д. Прям лежат скрипты, можно подсмотреть.\n","date":"12 июля 2025","externalUrl":null,"permalink":"/dia/","section":"Posts","summary":"","title":"Обзор Браузера Dia","type":"posts"},{"content":"","date":"20 июня 2025","externalUrl":null,"permalink":"/tags/3proxy/","section":"Tags","summary":"","title":"3proxy","type":"tags"},{"content":" Введение # 3proxy — это компактный и гибкий прокси-сервер с открытым исходным кодом, поддерживающий протоколы HTTP, HTTPS, SOCKS, FTP и другие. Он особенно популярен благодаря своей легкости, простоте настройки и широким возможностям по контролю доступа. Ниже в статье я расскажу как развернуть его на Ubuntu и примеры подключения.\nНастройка # Установка зависимостей # \u0026ndash; Установим необходимые пакеты для сборки\nsudo apt update \u0026amp;\u0026amp; sudo apt install build-essential make -y Клонирование репозитория # — Скачиваем исходный код 3proxy с GitHub:\ngit clone https://github.com/z3APA3A/3proxy.git cd 3proxy Сборка 3proxy # — Собираем прокси-сервер:\nmake -f Makefile.Linux — После сборки создаём директорию и копируем бинарник:\nsudo mkdir -p /usr/local/3proxy/bin sudo cp ./bin/* /usr/local/3proxy/bin/ Создание конфигурационного файла # Создаём директорию и файл конфигурации: sudo mkdir -p /etc/3proxy sudo nano /etc/3proxy/3proxy.cfg Пример конфигурации с поддержкой HTTP и SOCKS5 nscache 4000 timeouts 1 5 30 60 180 1800 15 60 users \u0026lt;имя_пользователя\u0026gt;:CL:\u0026lt;пароль\u0026gt; auth strong allow \u0026lt;имя_пользователя\u0026gt; proxy -p3128 socks -p1080 flush Замените \u0026lt;имя_пользователя\u0026gt; во всех местах конфига и \u0026lt;пароль\u0026gt; на свои значения.\nПо остальным значениям: nscache 4000 - Создаёт DNS-кэш на 4000 записей timeouts 1 5 30 60 180 1800 15 60 - Это по сути: timeouts \u0026lt;t1\u0026gt; \u0026lt;t2\u0026gt; \u0026lt;t3\u0026gt; \u0026lt;t4\u0026gt; \u0026lt;t5\u0026gt; \u0026lt;t6\u0026gt; \u0026lt;t7\u0026gt; \u0026lt;t8\u0026gt;\nКаждый параметр — это таймаут на определённый тип соединения:\nПараметр Назначение Значение t1 На соединение с клиентом 1 секунда t2 На соединение к удалённому хосту 5 секунд t3 Бездействие между чтением запроса 30 секунд t4 Ожидание ответа от удалённого хоста 60 секунд t5 Простой соединения 180 секунд t6 Keep-alive 1800 секунд t7 Макс. время ожидания запроса 15 секунд t8 Макс. время ответа 60 секунд auth strong — Указывает, что будет использоваться авторизация с логином и паролем.\nallow \u0026lt;имя_пользователя\u0026gt; — Разрешает доступ пользователю \u0026lt;имя_пользователя\u0026gt;, указанному выше в конфиге.\nproxy -p3128— Запускает HTTP-прокси на порту 3128.\nsocks -p1080 — Запускает SOCKS5-прокси на порту 1080.\nflush — Завершает конфигурацию.\nЗапуск прокси # Для проверки работы запустим сначала вручную:\n/usr/local/3proxy/bin/3proxy /etc/3proxy/3proxy.cfg Проверка через curl # Запускаем с другого ПК Curl, чтобы проверить работу прокси:\n— HTTP: curl -x http://\u0026lt;имя_пользователя\u0026gt;:\u0026lt;пароль\u0026gt;@\u0026lt;ваш_IP\u0026gt;:3128 https://ifconfig.me\n— SOCKS5: curl -x socks5h://\u0026lt;имя_пользователя\u0026gt;:\u0026lt;пароль\u0026gt;@\u0026lt;ваш_IP\u0026gt;:1080 https://ifconfig.me\nЕсли в ответ вернулся IP - значит все работает корректно.\nНастройка автозапуска через systemd # — Создаём systemd unit-файл:\nsudo nano /etc/systemd/system/3proxy.service\n— Добавляем содержимое:\n[Unit] Description=3proxy Proxy Server After=network.target [Service] ExecStart=/usr/local/3proxy/bin/3proxy /etc/3proxy/3proxy.cfg Restart=always User=nobody LimitNOFILE=512 [Install] WantedBy=multi-user.target — Активируем и запускаем:\nsudo systemctl daemon-reexec sudo systemctl enable 3proxy sudo systemctl start 3proxy — Проверяем что запустился сервис:\nsudo systemctl status 3proxy Использование # Теперь для вашего браузера, Телеграм клиента и другого софта можно использовать такие настройки:\nТип подключения Параметр Значение HTTP-прокси Сервер IP или домен вашего сервера Порт 3128 Логин и пароль Те же, что указаны в конфигурации SOCKS5-прокси Сервер IP или домен вашего сервера Порт 1080 Тип SOCKS5 Логин и пароль Те же, что указаны в конфигурации ","date":"20 июня 2025","externalUrl":null,"permalink":"/3proxy/","section":"Posts","summary":"","title":"Разворачиваем 3proxy на Ubuntu","type":"posts"},{"content":"","date":"16 июня 2025","externalUrl":null,"permalink":"/tags/development/","section":"Tags","summary":"","title":"Development","type":"tags"},{"content":"","date":"16 июня 2025","externalUrl":null,"permalink":"/tags/nodejs/","section":"Tags","summary":"","title":"Nodejs","type":"tags"},{"content":"","date":"16 июня 2025","externalUrl":null,"permalink":"/tags/nodenv/","section":"Tags","summary":"","title":"Nodenv","type":"tags"},{"content":" Если вы разрабатываете или как я тестируете по написанное на Node.js, то наверняка сталкивались с необходимостью управлять несколькими версиями Node.js. Для этих целей отлично подходит nodenv — легковесная утилита для управления версиями Node.js.\nКратко плюсы можно описать так:\nИзоляция версий Node.js для разных проектов. Легко устанавливать новые версии, без риска сломать старые. Простота и надёжность — nodenv работает быстро и стабильно. Интеграция с shell, автоматическое переключение версий при смене директории. Возможность временного изменения версии через nodenv shell. Установка # Для установки nodenv как всегда будем использовать Homebrew:\nbrew install nodenv После установки нужно добавить nodenv в ваш шел, в моем случае это zsh.\n— добавляем в файл ~/.zshrc:\neval \u0026#34;$(nodenv init -)\u0026#34; — теперь примените изменения:\nsource ~/.zshrc Просмотр и установка версий Node.js # Посмотреть последние стабильные версии для установки: # nodenv install --list Посмотреть все доступные версии для установки: # nodenv install --list-all Установить нужную версию, например, 22.16.0: # nodenv install 22.16.0 Переключение между версиями Node.js # Установить версию глобально, т.е по умолчанию: # nodenv global 22.16.0 Эта версия будет использоваться по умолчанию во всех проектах, если не указано иное.\nУстановить локальную версию (для конкретного проекта): # Перейдите в папку проекта и выполните:\ncd ../bla-bla/my-project/ nodenv local 24.2.0 Теперь при входе в эту директорию автоматически будет активироваться версия 24.2.0.\nИ например перейдем в другую директорию:\ncd ../bla-bla/my-other-project/ nodenv local 22.16.0 Теперь в этой директории будет использоваться версия 22.16.0.\nИспользование nodenv shell # Иногда бывает удобно временно изменить версию Node.js только для текущей сессии терминала, без изменения глобальной или локальной настроек. Для этого используется команда:\nnodenv shell 24.15.0 Теперь в текущей сессии терминала будет использоваться версия 16.15.0. Как только вы закроете терминал, эта настройка сбросится.\nУдаление ненужных версий # Если версия больше не нужна:\nnodenv uninstall 14.19.3 ","date":"16 июня 2025","externalUrl":null,"permalink":"/nodenv/","section":"Posts","summary":"","title":"Управление версиями Node.js с помощью nodenv","type":"posts"},{"content":"","date":"14 июня 2025","externalUrl":null,"permalink":"/categories/apple/","section":"Categories","summary":"","title":"Apple","type":"categories"},{"content":"","date":"14 июня 2025","externalUrl":null,"permalink":"/tags/apple-tv/","section":"Tags","summary":"","title":"Apple-Tv","type":"tags"},{"content":"","date":"14 июня 2025","externalUrl":null,"permalink":"/tags/quicktime/","section":"Tags","summary":"","title":"Quicktime","type":"tags"},{"content":"","date":"14 июня 2025","externalUrl":null,"permalink":"/tags/screen-recording/","section":"Tags","summary":"","title":"Screen-Recording","type":"tags"},{"content":" Как сделать скриншоты и записи экрана Apple TV ? # Apple TV не имеет встроенной функции скриншотов и записи экрана напрямую. По крайней мере я не знаю удобный способ. Однако есть способ сделать это через MacOS с помощью QuickTime Player.\nПодготовка # — Apple TV и ваш Mac должны быть подключены к той же Wi-Fi сети. Т.е быть в локальной сети. — Откройте QuickTime Player на Mac\nСоздание скриншота # — В QuickTime выберите «File» → «New Movie Recording» — Нажмите стрелку рядом с кнопкой записи и выберите ваш Apple TV в блоке «Экран» — Откройте нужный раздел на Apple TV\nТеперь уже можно делать скрины стандартными средствами MacOS — Cmd + Shift + 3 (полный экран) — Cmd + Shift + 4 (выборочная область)\nЗапись экрана # — Убедитесь, что экран Apple TV отображается в окне QuickTime — Нажмите стрелку рядом с кнопкой записи и выберите Apple TV в блоке «Звук» — Установите максимальную громкость в окне плеера — Нажмите кнопку записи для начала записи — Для завершения нажмите кнопку записи еще раз и закройте окно плеера — Сохраните ролик\n","date":"14 июня 2025","externalUrl":null,"permalink":"/appletvscreenshot/","section":"Posts","summary":"","title":"Снимаем скриншоты и видео с AppleTV на ПК","type":"posts"},{"content":"","date":"10 июня 2025","externalUrl":null,"permalink":"/tags/customization/","section":"Tags","summary":"","title":"Customization","type":"tags"},{"content":"","date":"10 июня 2025","externalUrl":null,"permalink":"/tags/karabiner/","section":"Tags","summary":"","title":"Karabiner","type":"tags"},{"content":" Что такое Karabiner-Elements? # Karabiner-Elements — это мощный инструмент для настройки клавиатуры и мыши в macOS, позволяющий полностью контролировать поведение клавиш. Принцип работы приложения прост: оно перехватывает сигналы от устройств и изменяет их перед отправкой в систему.\nЗачем мне это понадобилось? # Я случайно приобрёл клавиатуру RSQ-20052:\nЭта клавиатура имеет раскладку под Windows. Да, часть клавиш можно переназначить стандартными средствами системы или софта производителя, но функционал таких решений сильно ограничен. В настройках macOS можно поменять местами ⌘, ⌃ и ⌥, но мне хотелось более гибкой настройки.\nКроме того, у меня есть мышь Logitech с дополнительными кнопками, которые по умолчанию не работают на macOS. Их тоже хотелось бы задействовать.\nУстановка # Karabiner-Elements можно установить либо с официального сайта, либо через Homebrew — я выбрал второй способ:\nbrew install karabiner-elements После установки и первого запуска приложения необходимо дать разрешения на использование драйверов. Приложение само покажет, куда зайти и что нажать.\nПосле всех этих шагов у вас будут доступны два приложения:\nKarabiner-Elements — основное приложение для настройки клавиатуры и мыши. Karabiner-EventViewer — утилита для просмотра событий от ваших устройств, полезна для определения кодов нажимаемых клавиш. Настройка мыши # Открываем Karabiner-EventViewer и нажимаем нужные кнопки на мыши, чтобы узнать их точные идентификаторы. Переходим в Karabiner-Elements → Simple Modifications. Выбираем ваше устройство (мышь) из списка. Определить модель можно по названию. Назначаем новое действие для каждой кнопки по принципу: «Что заменить → Чем заменить». Пример моих настроек:\nНастройка клавиатуры # Для сложных переназначений используется раздел Complex Modifications. Он позволяет создавать комбинации и более тонко настраивать поведение клавиш.\nС помощью Karabiner-EventViewer узнаём точные названия клавиш. В Karabiner-Elements переходим в Complex Modifications → Add your own rule. Вставляем следующий JSON-конфиг: { \u0026#34;conditions\u0026#34;: [ { \u0026#34;identifiers\u0026#34;: [ { \u0026#34;manufacturer\u0026#34;: \u0026#34;GSKY\u0026#34;, \u0026#34;product\u0026#34;: \u0026#34;RSQ-20052\u0026#34;, \u0026#34;product_id\u0026#34;: 58383, \u0026#34;transport\u0026#34;: \u0026#34;USB\u0026#34;, \u0026#34;vendor_id\u0026#34;: 13357 } ], \u0026#34;type\u0026#34;: \u0026#34;device_if\u0026#34; } ], \u0026#34;description\u0026#34;: \u0026#34;Make RSQ-20052 for MacOS\u0026#34;, \u0026#34;manipulators\u0026#34;: [ { \u0026#34;description\u0026#34;: \u0026#34;Change Left Alt to Left ⌘\u0026#34;, \u0026#34;from\u0026#34;: { \u0026#34;key_code\u0026#34;: \u0026#34;left_option\u0026#34; }, \u0026#34;to\u0026#34;: [{ \u0026#34;key_code\u0026#34;: \u0026#34;left_command\u0026#34; }], \u0026#34;type\u0026#34;: \u0026#34;basic\u0026#34; }, { \u0026#34;description\u0026#34;: \u0026#34;Change Left ⊞ to Left Alt\u0026#34;, \u0026#34;from\u0026#34;: { \u0026#34;key_code\u0026#34;: \u0026#34;left_command\u0026#34; }, \u0026#34;to\u0026#34;: [{ \u0026#34;key_code\u0026#34;: \u0026#34;left_option\u0026#34; }], \u0026#34;type\u0026#34;: \u0026#34;basic\u0026#34; }, { \u0026#34;description\u0026#34;: \u0026#34;Change Right Alt to Right ⌘\u0026#34;, \u0026#34;from\u0026#34;: { \u0026#34;key_code\u0026#34;: \u0026#34;right_option\u0026#34; }, \u0026#34;to\u0026#34;: [{ \u0026#34;key_code\u0026#34;: \u0026#34;right_command\u0026#34; }], \u0026#34;type\u0026#34;: \u0026#34;basic\u0026#34; }, { \u0026#34;description\u0026#34;: \u0026#34;Change Print Screen to ⌘+⇧+5 (MacOS Screenshot menu)\u0026#34;, \u0026#34;from\u0026#34;: { \u0026#34;key_code\u0026#34;: \u0026#34;print_screen\u0026#34; }, \u0026#34;to\u0026#34;: [ { \u0026#34;key_code\u0026#34;: \u0026#34;5\u0026#34;, \u0026#34;modifiers\u0026#34;: [\u0026#34;left_command\u0026#34;, \u0026#34;left_shift\u0026#34;] } ], \u0026#34;type\u0026#34;: \u0026#34;basic\u0026#34; }, { \u0026#34;description\u0026#34;: \u0026#34;Change Pause to Lock Screen\u0026#34;, \u0026#34;from\u0026#34;: { \u0026#34;key_code\u0026#34;: \u0026#34;pause\u0026#34; }, \u0026#34;to\u0026#34;: [ { \u0026#34;key_code\u0026#34;: \u0026#34;q\u0026#34;, \u0026#34;modifiers\u0026#34;: [\u0026#34;left_control\u0026#34;, \u0026#34;left_command\u0026#34;] } ], \u0026#34;type\u0026#34;: \u0026#34;basic\u0026#34; }, { \u0026#34;description\u0026#34;: \u0026#34;Change Scroll lock to Mission Control\u0026#34;, \u0026#34;from\u0026#34;: { \u0026#34;key_code\u0026#34;: \u0026#34;scroll_lock\u0026#34; }, \u0026#34;to\u0026#34;: [{ \u0026#34;apple_vendor_keyboard_key_code\u0026#34;: \u0026#34;mission_control\u0026#34; }], \u0026#34;type\u0026#34;: \u0026#34;basic\u0026#34; }, { \u0026#34;description\u0026#34;: \u0026#34;Change Insert to ⌘+V\u0026#34;, \u0026#34;from\u0026#34;: { \u0026#34;key_code\u0026#34;: \u0026#34;insert\u0026#34; }, \u0026#34;to\u0026#34;: [ { \u0026#34;key_code\u0026#34;: \u0026#34;v\u0026#34;, \u0026#34;modifiers\u0026#34;: [\u0026#34;left_command\u0026#34;] } ], \u0026#34;type\u0026#34;: \u0026#34;basic\u0026#34; }, { \u0026#34;description\u0026#34;: \u0026#34;Change Caps to Change language\u0026#34;, \u0026#34;from\u0026#34;: { \u0026#34;key_code\u0026#34;: \u0026#34;caps_lock\u0026#34; }, \u0026#34;to\u0026#34;: [{ \u0026#34;apple_vendor_top_case_key_code\u0026#34;: \u0026#34;keyboard_fn\u0026#34; }], \u0026#34;type\u0026#34;: \u0026#34;basic\u0026#34; } ] } Нажимаем Save, затем активируем правило. Что делает этот конфиг? # Условие: только для клавиатуры GSKY RSQ-20052\nЛевый Alt (⌥) работает как Command (⌘) Левый Win (⊞) работает как Alt (⌥) Правый Alt (⌥) работает как Command (⌘) PrintScreen открывает встроенное меню скриншотов macOS (⌘+⇧+5) Pause блокирует экран (⌘+Ctrl+Q) ScrollLock вызывает Mission Control Insert работает как ⌘+V (вставка) CapsLock переключает язык (как Fn) ","date":"10 июня 2025","externalUrl":null,"permalink":"/karabiner/","section":"Posts","summary":"","title":"Karabiner-Elements: Полный контроль над клавиатурой и мышью на Mac","type":"posts"},{"content":"","date":"10 июня 2025","externalUrl":null,"permalink":"/tags/keyboard/","section":"Tags","summary":"","title":"Keyboard","type":"tags"},{"content":"","date":"10 июня 2025","externalUrl":null,"permalink":"/tags/mouse/","section":"Tags","summary":"","title":"Mouse","type":"tags"},{"content":"Uptime Kuma — отличный инструмент для мониторинга доступности сервисов, но в нем нет встроенной поддержки systemd. В этом посте я покажу, как с помощью простого bash-скрипта и Push отслеживать статус systemd сервисов и получать оповещения об изменнии их статуса.\nНастраиваем Uptime # Переходим в Uptime Kuma и логинимся Добавляем Группу (чтоб статистика была общая) Нажимаем +Add New monitor Выбираем тип мониторинга Group Настройки для Group такие: # Friendly Name: Server (Можете выбрать удобное вам) Heartbeat Interval: 300 Retries: 2 Heartbeat Retry Interval: 30 Resend Notification if Down X times consecutively: 5 Нажимаем Save Добавляем сервис из systemctl # Добавляем сервис. Нажимаем +Add New monitor Выбираем Monitoring Type: Push Friendly Name: rclone-yandex Push URL: Копируем в буфер и записываем, он нам позже пригодится. Heartbeat Interval: 300 Retries: 2 Heartbeat Retry Interval: 30 Resend Notification if Down X times consecutively: 5 Monitoring Group: Выбираем Server, или то что вы указали в Friendly Name на предыдущем шаге. Нажимаем Save Повторяем # Повторяем шаг для всех нужных вам сервисов. Можно через кнопку Clone в уже готовом сервисе. Так будет проще. У меня получились: unbound, rclone-yandex, qbittorrent,vaultwarden.\nСоздаем скрипт для отправки статуса сервисов # Создаем файл: /etc/sendstatus.sh nano /etc/sendstatus.sh Копируем текст в файл: #!/bin/bash # Название сервисов и их Push URL до символа ? # Например [\u0026#34;qbittorrent\u0026#34;]=http://10.1.0.12:3001/api/push/Qwerty declare -A SERVICES=( [\u0026#34;qbittorrent\u0026#34;]=\u0026#34;http://10.1.0.12:3001/api/push/zCDfxf232fds\u0026#34; [\u0026#34;vaultwarden\u0026#34;]=\u0026#34;http://10.1.0.12:3001/api/push/djfhDf23e12\u0026#34; [\u0026#34;unbound\u0026#34;]=\u0026#34;http://10.1.0.12:3001/api/push/df234SDd98Kdx\u0026#34; [\u0026#34;rclone-yandex\u0026#34;]=\u0026#34;http://10.1.0.12:3001/api/push/Df23cxsd2\u0026#34; ) # Перебираем сервисы и отправляем статус в Uptime for SERVICE in \u0026#34;${!SERVICES[@]}\u0026#34;; do URL=\u0026#34;${SERVICES[$SERVICE]}\u0026#34; if systemctl is-active --quiet \u0026#34;$SERVICE\u0026#34;; then # Сервис работает — отправляем UP curl -fsS -X GET \u0026#34;$URL?status=up\u0026amp;msg=$SERVICE%20is%20active\u0026#34; \u0026gt; /dev/null else # Сервис упал — отправляем DOWN curl -fsS -X GET \u0026#34;$URL?status=down\u0026amp;msg=$SERVICE%20is%20inactive\u0026#34; \u0026gt; /dev/null fi done В скрипте перечисляем сервисы и их Push URL в секции SERVICES. Т.е у вас должен быть сервис с названием qbittorent, vaultwarden, unbound, rclone-yandex и т.д. Через = указываем Push URL до ?status=up\u0026amp;msg=OK\u0026amp;ping= так как актуальный статус мы будем передавать самим скриптом. Чтобы проверить что у вас сервис присутвует можно выполнить комманду: systemctl list-unit-files | grep rclone. Т.е systemctl list-unit-files | grep \u0026lt;название сервиса\u0026gt;\nСохраняем файл /etc/sendstatus.sh\nПроверяем работу скрипта:\nbash /etc/sendstatus.sh Сервисы в Uptime должны сменить статус на UP Делаем файл скрипта исполняемым: chmod +x /etc/sendstatus.sh Добавляем в crontab crontab -e Добавляем строку для отправки статуса сервисов каждые 4 минуты */4 * * * * /etc/sendstatus.sh Сохраняем и выходим из редактора ","date":"2 июня 2025","externalUrl":null,"permalink":"/uptimesystemd/","section":"Posts","summary":"","title":"Uptime Kuma – добавляем мониторинг статуса systemd сервисов","type":"posts"},{"content":"","date":"31 мая 2025","externalUrl":null,"permalink":"/tags/unbound/","section":"Tags","summary":"","title":"Unbound","type":"tags"},{"content":" Что такое DNS-резолвер и зачем он нужен? # DNS-резолвер – это ПО, которое преобразует доменные имена в IP-адреса и наоборот. Локальный резолвер особенно полезен как на домашних серверах, и прям на самих рабочих машинах, поскольку ускорить процесс разрешения доменных имен или настроить форвардинг. Основные плюсы: — Кэширование запросов – мгновенные ответы на уже известные DNS-запросы — Защита конфиденциальности – провайдер не видит, какие сайты вы посещаете — Стабильность работы – минимизация влияния перегруженных публичных резолверов — Prefetch-механизм – автоматическое обновление записей в фоне — Безопасность – возможность настройки зашифрованного форвардинга — Форвардинг — Prefetch-механизм\nУстановка # У меня в диструбитве он уже был установлен по умолчанию. Но на debian based системах его можно установить с помощью пакетного менеджера:\nsudo apt update sudo apt install unbound Настройка # В основном конфиге /etc/unbound/unbound.conf у меня только одна настройка: include-toplevel: \u0026quot;/etc/unbound/unbound.conf.d/*.conf, т.е все настройки берутся из конфигов по пути: /etc/unbound/unbound.conf.d/ И в каталоге /etc/unbound/unbound.conf.d/ у меня несколько файлов с настройками. Перейдем к ним всем по очереди:\ndietpi.conf # Для моего сервера это деффолтный файл, он уже был. В нем живут все основные настройки. У вас это может быть и с другим именем или все настройки оставите в файле /etc/unbound/unbound.conf.\nОсновные пункты моих настроек:\nОсновные настройки # do-daemonize: no num-threads: 1 — do-daemonize: no — - запрещает демонизацию процесса для лучшего контроля через systemd, а именно им он и запускается. — num-threads: 1 - использует один поток, мне пока хватает\nЛогирование # verbosity: 0 log-queries: no log-replies: no — Минимальная детализация логов — Отключено логирование запросов и ответов\nСетевые настройки # interface: 0.0.0.0 port: 53 — Слушает на всех сетевых интерфейсах — Использует стандартный DNS-порт 53\nКонтроль доступа # access-control: 0.0.0.0/0 refuse access-control: 10.0.0.0/8 allow access-control: 127.0.0.1/8 allow access-control: 192.168.0.0/16 allow — Запрещает доступ всем, кроме этих локальных сетей\nНастройки протоколов # do-udp: yes do-tcp: yes do-ip4: yes do-ip6: no — Включает UDP и TCP протоколы — Отключаем IPv6\nБезопасность и защита # harden-glue: yes harden-dnssec-stripped: yes harden-algo-downgrade: yes harden-large-queries: yes harden-short-bufsize: yes — Набор настроек для \u0026ldquo;усиления\u0026rdquo; безопасности DNS-резолвера\nКонфиденциальность # use-caps-for-id: yes rrset-roundrobin: yes qname-minimisation: yes minimal-responses: yes hide-identity: yes identity: \u0026#34;Server\u0026#34; hide-version: yes — Минимизация информации, передаваемой в DNS-запросах\nКэширование # cache-min-ttl: 300 cache-max-ttl: 86400 serve-expired: yes neg-cache-size: 4M prefetch: yes prefetch-key: yes msg-cache-size: 50m rrset-cache-size: 100m — Минимальный и максимальный TTL для кэширования — Размер различных типов кэша\nОграничения и буферы # ratelimit: 1000 unwanted-reply-threshold: 10000 edns-buffer-size: 1232 so-rcvbuf: 4m so-sndbuf: 4m — Ограничение количества запросов в секунду — Защита от нежелательных ответов — Настройки буферов для оптимизации производительности\nДополнительные настройки # module-config: \u0026#34;validator iterator\u0026#34; — Активирует модуль DNSSEC\nroot-auto-trust-anchor-file.conf # auto-trust-anchor-file: \u0026#34;/var/lib/unbound/root.key\u0026#34; Это и есть сама настройка для работы DNSSEC (Domain Name System Security Extensions)\n— auto-trust-anchor-file - указывает путь к файлу, содержащему корневой ключ доверия (trust anchor)\n“/var/lib/unbound/root.key” - это сам файл, который содержит ключ корневой DNS-зоны\nforward-default.conf # forward-zone: name: \u0026#34;.\u0026#34; forward-addr: 8.8.8.8 forward-addr: 8.8.4.4 — forward-zone - определяет зону для форвардинга DNS-запросов — name: “.” - точка (.) указывает, что все DNS-запросы будут форвардиться — forward-addr - IP-адреса гугловых DNS-серверов, на которые будут перенаправляться запросы\nforward-ru.conf # forward-zone: name: \u0026#34;ru\u0026#34; forward-addr: 77.88.8.8 forward-addr: 77.88.8.1 — forward-zone - определяет зону для форвардинга DNS-запросов — name: “ru” - указывает, что эта конфигурация применяется только к доменам зоны .ru — forward-addr - IP-адреса Яндекс DNS-серверов, на которые будут перенаправляться запросы\nopenai.conf # forward-zone: name: \u0026#34;chatgpt.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;ab.chatgpt.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;api.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;arena.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;auth.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;auth0.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;beta.api.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;beta.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;blog.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;cdn.oaistatic.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;cdn.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;chat.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;community.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;contest.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;debate-game.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;discuss.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;files.oaiusercontent.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;gpt3-openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;gym.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;help.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;ios.chat.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;jukebox.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;labs.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;microscope.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;oaistatic.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;openai.fund\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;openai.org\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;platform.api.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;platform.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;spinningup.openai.com\u0026#34; forward-addr: 83.220.169.155 forward-zone: name: \u0026#34;universe.openai.com\u0026#34; forward-addr: 83.220.169.155 Настройка для форварда доменов ChatGPT от OpenAI через DNS от Comss.one чтобы работал ChatGPT на ПК и всех устройств в локалке.\nЗапускаем # sudo systemctl enable unbound sudo systemctl start unbound ","date":"31 мая 2025","externalUrl":null,"permalink":"/unbound/","section":"Posts","summary":"","title":"Unbound — рекурсивный, валидирующий и кэширующий DNS-резидент","type":"posts"},{"content":"","date":"26 мая 2025","externalUrl":null,"permalink":"/tags/oh-my-zsh/","section":"Tags","summary":"","title":"Oh-My-Zsh","type":"tags"},{"content":"","date":"26 мая 2025","externalUrl":null,"permalink":"/tags/zsh/","section":"Tags","summary":"","title":"Zsh","type":"tags"},{"content":" Если вы часто работаете в терминале вы часто привыкаете к вашему окружению. Я очень привык к Oh My Zsh. И так как мой \u0026ldquo;домашний\u0026rdquo; сервер живет на DietPi(https://blog.tatarinovms.space/dietpi), то мне захотелось его накатить на сервер. Да, хоть и в последней версии уже есть fish, но привычка есть привычка.\nЧто такое Oh My Zsh? # Oh My Zsh — это фреймворк для управления конфигурацией Z Shell (zsh). Он упрощает настройку оболочки, добавляет плагинов, тем, алиасов и пр\nТеперь давайте перейдем к практической части — установке Oh My Zsh на систему DietPi.\nШаг 1: Установка Z Shell (zsh) # По умолчанию, DietPi использует bash. Устанавливаем zsh:\nsudo apt update \u0026amp;\u0026amp; sudo apt install zsh -y Шаг 2: Установка Oh My Zsh # Для установки Oh My Zsh можно использовать самый официальный скрипт установки:\nsh -c \u0026#34;$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)\u0026#34; Во время установки система предложит сделать zsh вашей оболочкой по умолчанию — согласитесь\nШаг 3: Настройка Oh My Zsh # После установки основная конфигурация находится в файле ~/.zshrc.\nОткройте его в текстовом редакторе:\nvim ~/.zshrc Чтобы у нас работали все \u0026ldquo;фишки\u0026rdquo; и алиасы из dietpi. Нам надо их и прочие красоты перенести из bash в zsh. Для этого добавляем в открытый файл строчку:\nsource /etc/bashrc.d/dietpi.bash Сохраняем и выходим из редактора.\n","date":"26 мая 2025","externalUrl":null,"permalink":"/dietpizsh/","section":"Posts","summary":"","title":"Установка oh-my-zsh на dietpi","type":"posts"},{"content":"","date":"18 мая 2025","externalUrl":null,"permalink":"/tags/cloud/","section":"Tags","summary":"","title":"Cloud","type":"tags"},{"content":" Ранее я писал о том, как использовать Яндекс.Диск через WebDAV и как установить родной клиент Яндекс.Диска на Ubuntu Server. В этой статье расскажу о более «продвинутом» способе — с использованием утилиты rclone. Это простой, универсальный инструмент, который можно использовать в bash-скриптах, например. В гайде покажу, как настроить его на Ubuntu, но он подойдёт и для других систем. Например, на macOS я использую его точно так же.\nЧто нам понадобится? # rclone на сервере (Ubuntu) rclone на основной машине с браузером. Так как мой домашний сервер не имеет графической оболочке и браузера, я буду использовать rclone на macOS для получения токена. Установить его на macOS можно через brew Установка rclone на Ubuntu # sudo apt update Затем:\nsudo apt install rclone Настройка подключения к Яндекс.Диску # rclone config Далее следуйте этим шагам:\nНажмите n (новое удалённое хранилище). Введите имя (например, yandex). Выберите тип хранилища: yandex (у меня это номер 57). Оставьте поля client_id и client_secret пустыми (нажмите Enter). При запросе Edit advanced config? — выберите N. При запросе Use web browser to automatically authenticate rclone with remote? — если вы на сервере без GUI, ответьте n. Переходим на основную машину:\nЗапускаем команду: rclone authorize \u0026#34;yandex\u0026#34; Авторизуемся в Яндекс. После прохождения авторизации в консоли появится access_token, полностью скопируйте его (от { до }). Возвращаемся в консоль сервера и вставляем этот токен.\nПри запросе Keep this \u0026quot;yandex\u0026quot; remote? — нажимаем Y. Нажимаем q для выхода. ✅ Готово! Теперь Яндекс.Диск доступен через rclone.\nПримеры использования # Ниже приведены полезные команды:\nКопирование файла в корень Яндекс.Диска\nrclone copy ~/1.txt yandex: Показать содержимое папки \u0026ldquo;Фото\u0026rdquo; на Яндекс.Диске\nrclone ls yandex:/Фото Скачать файл reports_room.pdf из папки Documents на Яндекс.Диске в папку Downloads\nrclone copy yandex:/Documents/reports_room.pdf ~/Downloads/ Скачать всю папку Documents с Яндекс.Диска\nrclone copy yandex:/Documents/ ~/Downloads/Documents Синхронизация папки Backup с внешним HDD\nrclone sync yandex:/Backup /Volumes/HDD/Backup ⚠️ Важно: команда sync перезаписывает локальную папку, удаляя файлы, которых нет на удаленном диске.\nУдаление одного файла\nrclone delete yandex:/Temp/old.txt Очистка целой папки\nrclone purge yandex:/Temp Задача со звёздочкой: автоматический монтирование через systemd # Хочу заменить родное приложение Yandex.Disk и попробовать использовать rclone как сервис в связке с FUSE.\nУстановка FUSE (если ещё не установлен) # apt install -y fuse3 Самый “правильный” способ для DietPi — положить скрипт в специальную ежедневную папку, которая подхватывается местным cron.\nДелаем файл для запуска: # vim /etc/cron.hourly/rclone-yandex Вписываем ему такой вот код: # #!/bin/bash /usr/bin/rclone copy yandex: /mnt/HDD/YD \\ --config=/root/.config/rclone/rclone.conf \\ --log-file=/var/log/rclone-yandex.log \\ --log-level ERROR \\ --transfers=2 \\ --checkers=4 \\ --timeout=10m \\ --retries=3 \\ --retries-sleep=5s Сохраняем файл и делаем его исполняемым: # chmod +x /etc/cron.hourly/rclone-yandex Заключение # rclone — мощный и удобный инструмент для работы с облачными хранилищами, особенно если вам нужна автоматизация и работа из терминала. Он позволяет легко управлять Яндекс.Диском, создавать резервные копии, синхронизировать данные и даже монтировать диск как локальную файловую систему.\n","date":"18 мая 2025","externalUrl":null,"permalink":"/rclone4yd/","section":"Posts","summary":"","title":"rclone для Яндекс Диска","type":"posts"},{"content":" DietPi отличается крайне малым размером образа (менее 500 МБ) и низким использованием оперативной памяти и процессора. И что самое приятное с большим количеством \u0026ldquo;преднастроенных сервисов\u0026rdquo; и собственных CLI утилит.\nСписок предустановленных утилит:\nКоманда Назначение dietpi-launcher Единая точка входа в инструменты DietPi через меню dietpi-config Сетевые параметры, аудио, регион, CPU, журналирование и др. dietpi-software Установка и управление более чем 200 приложениями dietpi-update Обновление системы и утилит DietPi dietpi-backup Создание и восстановление резервных копий dietpi-sync Односторонняя синхронизация папок dietpi-cleaner Очистка системы от кэша и мусора dietpi-logclear Очистка логов системы dietpi-drive_manager Управление подключёнными накопителями dietpi-services Включение/отключение и перезапуск служб dietpi-autostart Настройка программ, запускаемых при старте системы dietpi-wifidb База данных известных Wi-Fi сетей (если используется Wi-Fi) dietpi-cron Упрощённое управление cron-заданиями dietpi-led_control Управление индикаторными LED (если поддерживаются устройством) dietpi-nordvpn Быстрая настройка VPN-клиента через NordVPN dietpi-vpn Поддержка других OpenVPN/WirGuard-клиентов dietpi-optimal_mtu Автоматический подбор оптимального MTU-сетевого значения dietpi-letsencrypt Настройка HTTPS-сертификатов через Let\u0026rsquo;s Encrypt dietpi-ddns Поддержка Dynamic DNS провайдеров dietpi-banner Настройка приветственного баннера в терминале dietpi-display Управление выводом на экран (если поддерживается) dietpi-justboom Настройка аудиоплат JustBoom и аналогичных DAC dietpi-benchmark Тестирование производительности CPU, RAM и накопителя dietpi-cloudshell Графическое отображение состояния системы в терминале dietpi-explorer Файловый менеджер на базе Midnight Commander dietpi-morsecode Световая передача IP-адреса устройства на LED (в виде азбуки Морзе) dietpi-survey Анонимная статистика использования (можно отключить) dietpi-bugreport Утилита для сбора и отправки отчётов о проблемах Почти все утилиты можно запускать как из dietpi-launcher, так и напрямую.\nПоддержка оборудования # DietPi поддерживает более 50 платформ, включая:\nRaspberry Pi (все модели), Odroid, NanoPi, Orange Pi, Banana Pi, ASUS Tinker Board, x86_64-системы Виртуальные машины: VMware, VirtualBox, Hyper-V, RISC-V и другие архитектуры. Установка и настройка # Установка # Скачайте нужный образ с официального сайта DietPi. Запишите его на карту памяти или флешку с помощью Balena Etcher или аналогичной утилиты. Подключите носитель к устройству и включите питание. Следуйте пошаговому мастеру установки, который появится при первом запуске. Первичная настройка # После загрузки DietPi предложит выбрать настройки локали, часового пояса, сетевых параметров, а затем — перейти к установке дополнительного ПО через dietpi-software.\nЗаключение # DietPi — это отличное решение для тех, кто хочет получить стабильную и лёгкую Linux-систему, быстро настраиваемую под любые задачи.\n","date":"13 мая 2025","externalUrl":null,"permalink":"/dietpi/","section":"Posts","summary":"","title":"DietPi - минималистичный Linux","type":"posts"},{"content":"","date":"13 мая 2025","externalUrl":null,"permalink":"/tags/ffmpeg/","section":"Tags","summary":"","title":"Ffmpeg","type":"tags"},{"content":" FFmpeg — это мощный и свободно распространяемый мультимедийный фреймворк, который позволяет конвертировать, редактировать, обрезать, склеивать, стримить см: Делаем свою радиостанцию в Telegram канале. Он работает на любом утюге.\nРешил в одном посте собрать комманды, которыми я часто пользуюсь и в \u0026ldquo;домашних делах\u0026rdquo; и в работе.\nУменьшение размера видео: # ffmpeg -i rec.mov -vcodec h264 -crf 23 -preset fast -acodec aac output.mp4 Делаем GIF из видео: # ffmpeg -i ./output.mp4 -t 10 -vf \u0026#34;fps=10,scale=320:-1\u0026#34; output.gif Удаляем аудио из видео: # ffmpeg -i ./output.mp4 -an -c:v copy output_noaudio.mp4 Извлечение аудио из видео # ffmpeg -i ./youtube.mp4 -acodec libmp3lame audio.mp3 Сохраняет один кадр на 10-й секунды как screen.jpg # ffmpeg -i ./youtube_VMuZuUjpGC0_1080x1920_h264.mp4 -ss 00:00:10 -vframes 1 screen.jpg Вырезает фрагмент с 15-й по 30-ю секунду # ffmpeg -i ./youtube_VMuZuUjpGC0_1080x1920_h264.mp4 -ss 00:00:15 -to 00:00:30 -c copy cut_output.mp4 Накладываем логотип на видео # ffmpeg -i ./youtube.mp4 -i ./logo.jpeg -filter_complex \u0026#34;[0:v][1:v]overlay=10:10\u0026#34; output.mp4 ","date":"13 мая 2025","externalUrl":null,"permalink":"/ffmpeg/","section":"Posts","summary":"","title":"ffmpeg — полезности","type":"posts"},{"content":"","date":"13 мая 2025","externalUrl":null,"permalink":"/tags/minimalist/","section":"Tags","summary":"","title":"Minimalist","type":"tags"},{"content":"","date":"13 мая 2025","externalUrl":null,"permalink":"/tags/multimedia/","section":"Tags","summary":"","title":"Multimedia","type":"tags"},{"content":"","date":"13 мая 2025","externalUrl":null,"permalink":"/tags/raspberry-pi/","section":"Tags","summary":"","title":"Raspberry-Pi","type":"tags"},{"content":"","date":"10 мая 2025","externalUrl":null,"permalink":"/tags/gatekeeper/","section":"Tags","summary":"","title":"Gatekeeper","type":"tags"},{"content":"","date":"10 мая 2025","externalUrl":null,"permalink":"/tags/terminal/","section":"Tags","summary":"","title":"Terminal","type":"tags"},{"content":"","date":"10 мая 2025","externalUrl":null,"permalink":"/tags/xattr/","section":"Tags","summary":"","title":"Xattr","type":"tags"},{"content":" Gatekeeper — это встроенная функция безопасности macOS, которая помогает защитить ваш компьютер от вредоносных программ, ограничивая установку приложений только из App Store и от идентифицированных разработчиков. Однако иногда пользователям может потребоваться установить приложения из других источников всяких \u0026ldquo;зеленых сайтов\u0026rdquo;. В этой статье представлено напишу руководство по обходу Gatekeeper.\n⚠️ Установка приложений из ненадежных источников может подвергнуть вашу систему повышенному риску заражения вредоносным ПО. Продолжайте только в том случае, если вы полностью уверены в безопасности источника приложения.\nОбход Gatekeeper для конкретного приложения # Откройте терминал Используйте команду xattr: Введите следующую команду в терминале: sudo xattr -r -c Перетащите приложение: Поставьте пробел после команды, затем перетащите значок приложения из Finder в окно терминала. Это автоматически заполнит путь к приложению. т.е комманда например выглядит так: sudo xattr -r -c /Applications/Raycast.app Перетащите приложение: Поставьте пробел после команды, затем перетащите значок приложения из Finder в окно терминала. Это автоматически заполнит путь к приложению. Важное замечание: Эта команда не работает напрямую с файлами образов (.dmg). Необходимо скопировать приложение из образа, например, в папку \u0026ldquo;Applications\u0026rdquo;\nВыполните команду: Нажмите клавишу Enter.\nВведите пароль администратора: Введите пароль своей учетной записи администратора и нажмите Enter. Обратите внимание, что символы пароля не будут отображаться в терминале во время ввода. Это нормальное поведение.\nЗапустите приложение\nОбъяснение # Команда xattr используется для управления расширенными атрибутами файлов. В данном случае мы используем ее для удаления атрибута com.apple.quarantine, который указывает macOS, что файл был загружен из Интернета и должен быть проверен Gatekeeper.\nsudo: Позволяет выполнять команду с правами суперпользователя (администратора).\nxattr: Утилита командной строки для просмотра, изменения и удаления расширенных атрибутов файлов.\n-r: Рекурсивно обрабатывает все вложенные файлы и каталоги.\n-c: Удаляет указанный расширенный атрибут.\ncom.apple.quarantine: Расширенный атрибут, который Gatekeeper использует для идентификации загруженных файлов.\nАльтернативные методы # Описанный выше метод избавляет вам ходить в настройки параметров безопасности в системных настройках и много кликать мышкой.\n","date":"10 мая 2025","externalUrl":null,"permalink":"/gatekeepermacos/","section":"Posts","summary":"","title":"Обход Gatekeeper в macOS","type":"posts"},{"content":"","date":"7 мая 2025","externalUrl":null,"permalink":"/tags/blog/","section":"Tags","summary":"","title":"Blog","type":"tags"},{"content":"","date":"7 мая 2025","externalUrl":null,"permalink":"/tags/miniapp/","section":"Tags","summary":"","title":"Miniapp","type":"tags"},{"content":"","date":"7 мая 2025","externalUrl":null,"permalink":"/tags/web-app/","section":"Tags","summary":"","title":"Web-App","type":"tags"},{"content":" Введение # Цель — сделать без лишних движений бота в Telegram, в котором будет базово открываться мой блог в мини-апп в Telegram. И чтобы был доступен мини-апп для чтения блога.\nКак делать? # Все действия будут делаться в боте @BotFather.\nСоздаем нового бота # Открываем бот @BotFather.\nПишем команду /newbot.\nУказываем имя вашего бота.\nглянуть в картинках\nСоздаем мини-апп # Пишем команду /newapp.\nВыбираем ранее созданного бота.\nУказываем тайтл для нашего мини-апп.\nУказываем краткое описание нашего мини-апп.\nЗагружаем картинку для мини-приложения. Картинки принимаются в размере 640x360.\nЗагрузку GIF — пока можно пропустить.\nОтправляем URL нашего сайта.\nВыбираем короткое имя для ссылки на мини-апп.\nглянуть в картинках\nДелаем кнопочку для открытия мини-апп в боте # Пишем команду /setmenubutton.\nВыбираем нашего бота.\nОтправляем URL на наш мини-апп.\nПишем название кнопки.\nглянуть в картинках\nЧто вышло в итоге? # У нас есть бот @blog_tatarinovms_bot с кнопкой «Почитать блог», которая ведет в наш мини-апп. Есть мини-апп, который открывается по ссылке: t.me/blog_tatarinovms_bot/blogtatarinovms. ","date":"7 мая 2025","externalUrl":null,"permalink":"/telegramniniapp/","section":"Posts","summary":"","title":"Блог как мини-апп в Telegram","type":"posts"},{"content":" Привет, я Максим. # Самые оперативные способы связи со мной: # Тэгешка: @tatarinovms Почта i@mtatarinov.ru *gram @tatarinovms О себе # Разбираюсь в *nix, веб‑сервисах, сетях и тестировании. Могу внедрить «не внедряемое» и настроить «настраиваемое». Работаю Senior QA Engineer в финтехе. Играю на PlayStation, на ПК — в Factorio и разное ретро. Могу подискутировать об истории мирового игростроя и геймдизайне. Читаю много всего: в основном фантастику Шарю за эйай Есть пёс и кот Активности # Блог про IT # blog.tatarinovms.space или blog.tatarinovms.ru Блог в телетайпе Проекты # Простой и эффективный набор правил маршрутизации для клиента ShadowRocket на iOS в GitHub Простой и эффективный набор правил маршрутизации для клиента ShadowRocket на iOS в GitVerse Репозитарий с ипа для айфона Корги Альфа в ТГ Клан Боевых Бобров в ТГ Клан Боевых Бобров в ВК Клан Боевых Бобров в Дзен Клан Боевых Бобров в Cетке Клан Боевых Бобров в mave.stream Социальщина # *gram WeChat ВК Тредс Linkedin Сетка Васкрик.Клуб OK Экс бывший твиттер FaceБook Pikabu Reddit Pinterest 4pda Gravatar DEV # Github GitVerse Games # PlayStation Steam Music # Apple Music Spotify Звук Видео # Twitch Youtube Рутуб ВКВидео НФТ # GetGems Донаты # Банковские и платежные сервисы # Банковская карта T-Bank СБП # CloudTips\nOzon Чаевые\nVK Донат\nБусти\n","date":"7 мая 2025","externalUrl":null,"permalink":"/about/","section":"Tatarinov","summary":"","title":"About","type":"page"},{"content":"📄 Скачать CV (PDF)\nMaxim Tatarinov # Senior QA Engineer | Mobile \u0026amp; Fintech Testing Specialist # Telegram: @tatarinovms\nEmail: i@mtatarinov.ru\nБлог: blog.tatarinovms.space\nTelegram-канал: @beaverclan\nО себе # Опытный инженер по тестированию с 10+ годами в IT и 8+ годами специализации на тестировании мобильных приложений и финтех-решений. Глубокая экспертиза в тестировании платёжных систем, процессинговых решений, хостовых приложений для электронной коммерции и ДБО. Владею полным циклом тестирования: от составления тест-документации до интеграционного тестирования и сопровождения продуктов в production.\nКлючевые компетенции # Тестирование мобильных приложений:\nПлатформы: iOS (Swift), Android (Kotlin), кроссплатформенные решения (React Native, .NET MAUI) Инструменты: Android Studio, Xcode, эмуляторы и реальные устройства Перехват и анализ трафика: Charles Proxy, Fiddler, Proxyman, mitmproxy Финтех и платёжные системы:\nТестирование платёжных страниц, процессинговых систем, интеграций с Visa, MasterCard, НСПК, Хостовые решения для электронной коммерции и дистанционного банковского обслуживания (ДБО) Знание специфики финтех-продуктов, требований безопасности и compliance API и базы данных:\nREST API тестирование: Postman, Swagger, автоматизация запросов SQL: Oracle, PostgreSQL — написание запросов, проверка данных, подготовка тестовых данных Тест-дизайн и документация:\nРазработка тест-стратегий, тест-планов, чек-листов, тест-кейсов Детальное описание баг-репортов с приложением логов, скриншотов, трафика Интеграционное, регрессионное, smoke-тестирование Инструменты и технологии:\nСистемы управления: Jira, Bugzilla, TestRail Версионный контроль: Git, SVN Администрирование: Linux (Ubuntu, RedHat, Astra Linux), macOS, Windows Серверные технологии: Tomcat, Node.js, навыки DevOps Автоматизация:\nМобильная автоматизация: Appium, (Android) Web/API автоматизация: Playwright, автотесты REST API Языки скриптинга: JavaScript/TypeScript CI/CD и DevOps:\nПайплайны: Jenkins, GitHub Actions Интеграция автотестов в CI, регрессия перед релизом Профессиональный опыт # Senior Testing Engineer QA # Апрель 2023 – настоящее время\nТестирование мобильных приложений на React Native, Swift, Kotlin, .NET MAUI для финтех-сектора REST API тестирование с использованием Postman и Swagger, валидация интеграций между системами Написание и выполнение SQL-запросов (Oracle, PostgreSQL) для проверки корректности данных и логики бэкенда Тестирование хостовых решений для электронной коммерции и процессинговых систем Разработка полного цикла тест-документации: чек-листы, тест-кейсы, баг-репорты, тест-планы Активное участие в выводе продуктов в production, мониторинг стабильности после релиза Сокращение post-release инцидентов Интеграционное тестирование сложных систем, проверка взаимодействия между микросервисами и внешними API Использование инструментов перехвата трафика для анализа безопасности и отладки проблем Участие во внедрении AI в процессы тестирования и разработки в продукты компании: LLM-ассистенты, генерация тест-кейсов, автоанализ баг-репортов, разработка. Head of Technical Support Bureau in Retail Business Management # Октябрь 2019 – Апрель 2023\nУправление командой технической поддержки обеспечение бесперебойной работы мобильного платёжного приложения и его сервера. Анализ и тестирование финтех-продуктов: платёжные системы, банковские приложения, процессинг Регламентные работы, восстановление после сбоев, оптимизация процессов поддержки Тесное взаимодействие с разработчиками, бизнес-аналитиками и продакт-менеджерами Участие в проектировании архитектуры решений с учётом требований надёжности и безопасности Testing Engineer QA # Октябрь 2015 – Октябрь 2019\nФункциональное и регрессионное тестирование мобильных (iOS, Android) и веб-приложений Управление дефектами через Jira, Trello, Bugzilla — от обнаружения до верификации исправлений Тестирование интеграций с платёжными системами (Visa, MasterCard, НСПК) Администрирование тестовых сред на Linux, Windows, macOS Участие в процессах CI/CD, тестирование перед развёртыванием Product Support Engineer / IT User Support Engineer # 2012 – 2015\nТехническая поддержка пользователей, диагностика и устранение инцидентов Администрирование серверов (Tomcat, Node.js), работа с системами контроля версий (Git/SVN) Обеспечение стабильности сетевой инфраструктуры и серверного окружения Образование # Российский Новый Университет (РосНОУ)\nПрикладная информатика в экономике (бакалавриат, 2011–2014)\n2011–2014\nФГОУ СПО Тамбовский бизнес-колледж\nАвтоматизированные системы обработки информации и управления\n2007–2011\nДополнительные активности # Технический блог: blog.tatarinovms.space — публикации о тестировании, DevOps, мобильной разработке Telegram-канал: @beaverclan — новости IT-индустрии и личные наблюдения Личные качества # Системное мышление, внимание к деталям, проактивный поиск дефектов Быстрая адаптация к новым технологиям, эффективная командная работа ","date":"7 мая 2025","externalUrl":null,"permalink":"/cv/","section":"Tatarinov","summary":"","title":"CV","type":"page"},{"content":"","date":"8 марта 2025","externalUrl":null,"permalink":"/tags/btop/","section":"Tags","summary":"","title":"Btop","type":"tags"},{"content":" Введение # Сегодня хочу рассказать вам об одной из утилит для мониторинга системы — btop++\nbtop++ — это усовершенствованная версия популярной утилиты btop, которая предоставляет детализированную информацию о состоянии вашей системы в реальном времени. Она отображает данные о процессоре, оперативной памяти, дисковом пространстве, сетевых соединениях и др..\nОсновные особенности: # Интуитивно понятный интерфейс: btop++ имеет красивый и настраиваемый интерфейс, который легко читается и позволяет быстро находить нужную информацию.\nПоддержка тем: Вы можете выбрать из нескольких встроенных тем или создать свою собственную\nДетализированные метрики: Утилита предоставляет подробные данные о каждом аспекте системы, включая использование ресурсов, температуру процессора, скорость сети и многое другое.\nИнтерактивность: btop++ позволяет взаимодействовать с процессами прямо из интерфейса. Вы можете завершать процессы, изменять их приоритеты и выполнять другие действия.\nКроссплатформенность: Утилита поддерживает различные операционные системы, включая Linux, macOS и Windows(да, не без особенностей)\nУстановка # brew install btop Использование # После установки вы можете запустить btop++ просто введя команду в терминале:\nbtop\nИнтерфейс # Основная панель: В верхней части окна отображается общая информация о системе, включая использование процессора, памяти, дискового пространства и сети.\nПроцессы: В нижней части окна отображается список запущенных процессов с информацией о их использовании ресурсов.\nУправление процессами # Выбор процесса: Используйте клавиши со стрелками для навигации по списку процессов.\nЗавершение процесса: Выберите процесс и нажмите k, чтобы завершить его.\nИзменение приоритета: Выберите процесс и используйте клавиши + и - для изменения его приоритета.\nФильтрация процессов: Вы можете фильтровать процессы по различным критериям, используя клавишу f.\nСортировка: Нажмите s, чтобы изменить порядок сортировки процессов.\nНастройки # Нажмите m, чтобы выбрать меню с настройками или help\u0026rsquo;ом Выход: Нажмите q, чтобы выйти из btop++. ","date":"8 марта 2025","externalUrl":null,"permalink":"/btopplus/","section":"Posts","summary":"","title":"btop++ — cовременный мониторинг системы","type":"posts"},{"content":"","date":"8 марта 2025","externalUrl":null,"permalink":"/tags/system-resources/","section":"Tags","summary":"","title":"System-Resources","type":"tags"},{"content":" Если вы ознакомитесь с содержимым моего блога, вы заметите довольно большое количество консольных инструментов. Консольный софт часто оказывается более удобным и быстрым решением по сравнению с приложениями с графическим интерфейсом (GUI). Сегодня я расскажу о самой фундаментальной утилите для macOS — менеджере пакетов brew. Через него можно управлять установкой практически всего остального ПО, будь то CLI-инструменты или полноценные GUI-приложения.\nЗачем нужен Brew? # Brew — это де-факто стандартный пакетный менеджер для macOS, который позволяет мне устанавливать и управлять огромным количеством полезного ПО, необходимого как в профессиональной работе, так и в повседневной жизни. В качестве оболочки (shell) я использую старый добрый oh-my-zsh.\nКак установить Brew? # Выполните следующую команду в терминале:\n/bin/bash -c \u0026#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\u0026#34; Ключевые утилиты, которые я регулярно устанавливаю: # Ниже список ПО, которое я устанавливаю через brew\nCLI-утилиты # openjdk # Реализация Java Development Kit с открытым исходным кодом.\nbrew install openjdk android-platform-tools # ADB-инструменты для работы с Android-устройствами.\nbrew install android-platform-tools aria2 # Многопоточная утилита для загрузки файлов по различным протоколам.\nbrew install aria2 asciinema # Запись терминальных сессий для документации и демонстраций.\nbrew install asciinema btop # Графический мониторинг системных ресурсов, удобная замена htop.\nbrew install btop bitwarden-cli # CLI-версия менеджера паролей BitWarden.\nbrew install bitwarden-cli curl # Командная утилита для передачи данных между сервером и клиентом.\nbrew install curl deno # Runtime для JavaScript и TypeScript.\nbrew install deno diffutils # Набор утилит для сравнения файлов.\nbrew install diffutils duck # FTP/SFTP клиент для скриптов и автоматизации.\nbrew install duck eza # Современная замена ls с более читабельным выводом (преемник exa).\nbrew install eza go # Открытый язык программирования для облачной и сетевой разработки.\nbrew install go htop # Интерактивный просмотрщик процессов.\nbrew install htop imagemagick # Инструмент для создания, редактирования и преобразования изображений.\nbrew install imagemagick ipatool # Поиск и загрузка iOS-приложений из App Store.\nbrew tap majd/repo brew install ipatool jq # Обработка JSON-данных в терминале.\nbrew install jq Midnight Commander (mc) # Текстовый файловый менеджер на манер Norton Commander.\nbrew install mc mole # Универсальный инструмент для глубокой очистки и оптимизации macOS. Удаляет кэши, логи, остатки приложений, анализирует диск и показывает live-статистику системы.\nbrew install tw93/tap/mole nmap # Сканер портов и инструмент сетевой разведки.\nbrew install nmap Newman # CLI-запуск Postman-коллекций для автоматизации тестирования API.\nbrew install newman node # Платформа выполнения JavaScript вне браузера.\nbrew install node nvm # Менеджер версий Node.js.\nbrew install nvm nodenv # Переключалка разных версий Node.js\nbrew install nodenv fastfetch # Отображает информацию о системе в красивом формате (преемник neofetch).\nbrew install fastfetch peco # Интерактивный фильтр для терминала.\nbrew install peco qrencode # Генератор QR-кодов из командной строки.\nbrew install qrencode lz4 # Утилита для сжатия и распаковки данных в формате LZ4.\nbrew install lz4 socat # Утилита для двусторонней передачи данных между различными типами соединений.\nbrew install socat SVN # Система контроля версий Apache Subversion.\nbrew install svn telnet # Протокол и клиент для удалённого подключения к другим компьютерам.\nbrew install telnet tmux # Мультиплексор терминалов, удобен с iTerm2.\nbrew install tmux unar # Утилита для извлечения архивов (CLI от The Unarchiver).\nbrew install unar wget # Утилита для загрузки файлов из сети через HTTP, HTTPS и FTP.\nbrew install wget yt-dlp # Инструмент для скачивания видео с YouTube и других платформ.\nbrew install yt-dlp uv # Очень быстрый пакетный менеджер для Python.\nbrew install uv killport # Завершает процессы, слушающие указанный порт.\nbrew tap jkfran/killport brew install killport ffmpeg # Мощный инструмент для работы с видео и аудио.\nbrew install ffmpeg pandoc # Универсальный конвертер документов.\nbrew install pandoc pyenv # Менеджер версий Python.\nbrew install pyenv tlrc # Упрощенные man-страницы (клиент tldr на Rust).\nbrew install tlrc yadm # Управление dotfiles с помощью git.\nbrew install yadm zsh-autosuggestions # Подсказки при вводе команд в zsh.\nbrew install zsh-autosuggestions zsh-syntax-highlighting # Подсветка синтаксиса команд в терминале.\nbrew install zsh-syntax-highlighting memo # CLI-утилита для управления Заметками Apple (Notes.app) из терминала: список, поиск, создание, экспорт в Markdown.\nbrew tap antoniorodr/memo brew install antoniorodr/memo/memo Подробнее — в отдельном посте.\nrclone # Утилита для синхронизации и управления файлами в облачных хранилищах (Яндекс.Диск, Google Drive и др.) из терминала.\nbrew install rclone Подробнее — в отдельном посте.\nGUI-приложения # Android Studio # Официальная IDE для разработки Android-приложений.\nbrew install --cask android-studio Audacity # Простой и мощный аудиоредактор.\nbrew install --cask audacity Bitwarden # GUI-версия менеджера паролей BitWarden.\nbrew install --cask bitwarden DBeaver Community # Универсальный SQL клиент для работы с различными СУБД.\nbrew install --cask dbeaver-community Firefox # Браузер Firefox.\nbrew install --cask firefox Google Chrome # Классика браузерного мира от Google.\nbrew install --cask google-chrome iTerm2 # Расширенный эмулятор терминала для macOS.\nbrew install --cask iterm2 Keystore Explorer # Инструмент для управления Java Keystore и цифровыми сертификатами.\nbrew install --cask keystore-explorer Mitmproxy # Перехват и анализ HTTP/HTTPS трафика.\nbrew install --cask mitmproxy Mockoon # Создание mock API для тестирования и прототипирования.\nbrew install --cask mockoon Obsidian # Приложение для создания заметок в формате Markdown.\nbrew install --cask obsidian ONLYOFFICE # Альтернатива Microsoft Office с поддержкой совместной работы над документами.\nbrew install --cask onlyoffice Postman # Инструмент для тестирования и разработки REST API.\nbrew install --cask postman Telegram # Быстрый и безопасный мессенджер с открытым API.\nbrew install --cask telegram Tunnelblick # OpenVPN клиент для macOS с графическим интерфейсом.\nbrew install --cask tunnelblick UTM # Виртуальная машина на базе QEMU для запуска различных операционных систем.\nbrew install --cask utm VLC # Универсальный медиаплеер, поддерживающий множество форматов.\nbrew install --cask vlc VMWare Fusion # Эмулятор операционных систем на Mac.\nbrew install --cask vmware-fusion Vivaldi # Настраиваемый браузер на движке Chromium.\nbrew install --cask vivaldi Visual Studio Code # Популярный текстовый редактор с мощными возможностями расширения.\nbrew install --cask visual-studio-code Yandex Browser # Браузер от Яндекса с поддержкой российских сервисов и сертификатов.\nbrew install --cask yandex zen # Firefox-подобный браузер в стиле закрытого ARC.\nbrew install --cask zen FlowClip # Утилита для работы с буфером обмена на macOS\nbrew tap gityeop/flowclip brew install --cask flowclip betterdisplay # Инструмент для улучшения отображения дисплеев на macOS.\nbrew install --cask betterdisplay balenaEtcher # Простая утилита для записи ISO-образов на флешки.\nbrew install --cask balenaetcher Docker Desktop # Платформа для разработки и запуска контейнеров.\nbrew install --cask docker-desktop Handbrake # Популярный транскодер видео.\nbrew install --cask handbrake-app Tabby # Современный и расширяемый терминал.\nbrew install --cask tabby Tailscale # Простая и безопасная VPN-сеть.\nbrew install --cask tailscale-app VSCodium # Свободная версия VS Code без телеметрии Microsoft.\nbrew install --cask vscodium WailBrew # Минималистичный GUI для управления Homebrew, написанный на Go, Wails и React.\nbrew install --cask wailbrew Zed # Сверхбыстрый редактор кода.\nbrew install --cask zed qlmarkdown # Плагин Quick Look для предпросмотра Markdown-файлов прямо в окне быстрого просмотра macOS (пробел по выделенному файлу в Finder).\nbrew install --cask qlmarkdown syntax-highlight # Плагин Quick Look для подсветки синтаксиса исходных кодов в окне быстрого просмотра macOS.\nbrew install --cask syntax-highlight Заключение # Таким образом, с помощью brew можно эффективно и удобно управлять всем программным обеспечением на вашей машине macOS. Это значительно упрощает рабочий процесс и повышает общую продуктивность.\n","date":"1 января 2025","externalUrl":null,"permalink":"/brew/","section":"Posts","summary":"","title":"Brew - хватит для всего","type":"posts"},{"content":"","date":"1 января 2025","externalUrl":null,"permalink":"/tags/package-manager/","section":"Tags","summary":"","title":"Package-Manager","type":"tags"},{"content":"","date":"25 декабря 2024","externalUrl":null,"permalink":"/tags/mks/","section":"Tags","summary":"","title":"Mks","type":"tags"},{"content":"","date":"25 декабря 2024","externalUrl":null,"permalink":"/tags/remote-control/","section":"Tags","summary":"","title":"Remote-Control","type":"tags"},{"content":"","date":"25 декабря 2024","externalUrl":null,"permalink":"/tags/simulator/","section":"Tags","summary":"","title":"Simulator","type":"tags"},{"content":" Введение # У меня есть друг, который использует Punto Switcher ради одной странной цели — ради звука набора. Для тех, кто не знаком с этой программой, поясняю: Punto Switcher — это популярная утилита для автоматической смены раскладки клавиатуры между русским и английским языками. Она помогает избегать ошибок при наборе текста, автоматически переключая язык ввода, когда вы начинаете печатать слово на другом языке.\nВ Telegram-канале @FixedOneNews вышел пост о программе MKS: Mechanical Keyboard Simulator. Эта программа добавляет звук нажатия клавиш клавиатуры и мыши. Причём присутствуют звуки не только нажатия клавиши, но и её отжатия, что делает звучание немного более естественным. Из обнаруженных мной недостатков этого ПО — отсутствие звукового сопровождения при нажатии клавиши Tab во время переключения программ (например, комбинация Cmd + Tab + Tab), начиная со второго и последующих нажатий на Tab.\nКак установить? # через старый добрый brew brew install --cask mks запускаем из папки Applications\nтак как программа не подписана, нужно выдать ей соответствующие права:\nНастройки # Настроек здесь немного: всего три профиля и возможность включения/отключения всех функций.\nЩелкайте, как на механической клавиатуре, но без неё.\n","date":"25 декабря 2024","externalUrl":null,"permalink":"/mks/","section":"Posts","summary":"","title":"Нет механики, но хочется така-така?","type":"posts"},{"content":" Введение # В результате непредвиденного инцидента, а именно случайного погружения пульта дистанционного управления Apple TV в жидкость (пиво), возникла необходимость поиска альтернативных методов взаимодействия с устройством. Хотя использование смартфона в качестве замены оказалось достаточно удобным\u0026hellip;\nЕсли бы телефонный пульт мог работать через iPhone Mirroring, я бы не стал искать альтернативные решения. Но проблема заключается в том, что при запуске пульта на телефоне приложение iPhone Mirroring автоматически закрывается.\nУстановка # Скачиваем готовую сборку с GitHub\nОткрываем DMG-файл и устанавливаем программу.\nЗапускаем приложение.\nНастройка # Запускаем проект.\nОжидаем завершения установки Python.\nВыбираем ваше устройство Apple TV по IP-адресу и вводим PIN-код c вашего TV. Использование # Вот кнопки, управляем. Сам пульт живет в \u0026ldquo;трее\u0026rdquo;\n","date":"25 декабря 2024","externalUrl":null,"permalink":"/appletvremoute/","section":"Posts","summary":"","title":"Управляем AppleTV c ПК","type":"posts"},{"content":"","date":"20 ноября 2024","externalUrl":null,"permalink":"/categories/mobile/","section":"Categories","summary":"","title":"Mobile","type":"categories"},{"content":"","date":"20 ноября 2024","externalUrl":null,"permalink":"/categories/windows/","section":"Categories","summary":"","title":"Windows","type":"categories"},{"content":" Введение # Данный пост расскажет о возможностях приложения Microsoft Phone Link в связке с iPhone.\nЧто у нас есть # iPhone на OC iOS 18.1\nWindows 11\nMicrosoft Phone Link\nLink to Windows (приложение для iPhone)\nУстановка приложения и настройка синхронизации # Установка приложения # Чтобы подключить iPhone к компьютеру на Windows, нам потребуется приложение Phone Link. На последних версиях Windows данное приложение уже предустановлено. Если же у вас его еще нет, то можно загрузить его из Microsoft Store.\nНастройка синхронизации # Установите на iPhone приложение Link to Windows из App Store\nЗапустите его на телефоне\nЗапустить приложение Microsoft Phone Link на вашем ПК\nВыберете iPhone\nОтсканируйте QR телефоном Спарьте по Bluetooth ваш телефон и ПК В настройках блютуз на телефоне разрешите доступ к контактам и Share system notification для синхронизации уведомлений между телефоном и ПК Настройка завершена!\nФункциональные возможности приложения Phone Link # Сообщения \\ iMessage # Внешний вид сообщений в приложении Phone Link # Плюсы и минусы функции сообщений # ➕ Получение уведомлений о сообщении на ПК. В том числе полученного по iMessage.\n➕ Возможность писать сообщение с ПК. Если у контакта которому вы отправляете сообщение имеется поддержка iMessage, сообщение отправится по данному протоколу. В противном случае в виде SMS.\n➕ Поддержка emoji.\n➖ Отсутствие поддержки групповых чатов в iMessage\n➖ Отсутствие поддержки фото и видео и изображений в сообщениях. Причем не только получение, но и отправка.\n➖ Отсутствие поддержки memoji и стикеров\n➖ Отсутствие поддержки голосовых сообщений\n➖ Отсутствие поддержки форматированных сообщений\n➖ Отсутствие поддержки ингерации с FaceTime\nВсе это вы не увидите на ПК:\nЗвонки # Если вы находитесь в поле действия Bluetooth, то ваш ПК может выступать в роли \u0026ldquo;гарнитуры\u0026rdquo; для совершаемых звонков. Позвонить можно выбрав контакт или введя номер телефона.\nУведомления # Уведомления показываются в левой стороне приложения и \u0026ldquo;улетают\u0026rdquo; в нотификатор ОС Windows:\nПри клике на пуш происходит редерект в браузер, а точнее переход через поисковик Bing.\nТ.е если кликнуть в пуш от приложения \u0026ldquo;Интерсвязь\u0026rdquo;, будет выполнил поиск слова Интерсвязь в Bing, если кникнуть в пуш от нельзяграмма, то будет выполнен переход просто на сайт ***gram.com.\nВ минусы также запишу отсутствие поддержки группированных отложенных уведомлений.\nИтоги # Возможности приложения Microsoft Phone Link даже не поддаются сравнению с возможностями интеграции iPhone и MacBook особенно в связке с приложением iPhone Mirroring.\nТехнически это больше похоже на то, что ваш ПК с Phone Link становится блютус гарнитурой с возможностями читать уведомления, прям как самый недорогой фитнес браслет и то на браслете фото из iMessage можно увидеть, даже хотябы текстом {images} и ответить можно в групповой чат iMessage. Написать текстовое сообщение и прочитать его - можно, но на этом все. Возможность звонить с ПК - удобно может быть, но какой в этом смысл, мне не очень понятно.\n🚩 На моих часах Casio и то больше возможностей по работе с уведомлениями от iPhone.\n","date":"20 ноября 2024","externalUrl":null,"permalink":"/windowslink/","section":"Posts","summary":"","title":"Возможности Microsoft Phone Link в связке Windows и iPhone","type":"posts"},{"content":"","date":"21 октября 2024","externalUrl":null,"permalink":"/tags/hack/","section":"Tags","summary":"","title":"Hack","type":"tags"},{"content":"","date":"21 октября 2024","externalUrl":null,"permalink":"/tags/sequoia/","section":"Tags","summary":"","title":"Sequoia","type":"tags"},{"content":" Вступление # Сегодня хочу поделиться с вами небольшим лайфхаком, который может пригодиться всем, кто пользуется на своём Mac нестандартными раскладками клавиатуры. Например, вы установили типографскую раскладку от Ильи Бирмана или любую другую. Возможно, вам захочется удалить стандартную английскую раскладку (ABC). Обычными способами сделать это на новых версиях macOS нельзя. Ниже расскажу вам о способе, который не требует использования терминалов, команд и СМС.\nКак сделать? # Переходим в System Setting - Keyboard - Text input Нажимаем Edit Нажимаем ➕ Выбираем раскладку Японский — ромадзи Переходим в него Ставим флаг Ромадзи Нажимаем ➖ выбрав стандартную английскую Нажимаем ➖ выбрав Японский — ромадзи Все! # Вы восхитительны!\n","date":"21 октября 2024","externalUrl":null,"permalink":"/removeabc/","section":"Posts","summary":"","title":"Как в macOS Sequoia удалить стандартную английскую раскладку клавиатуры","type":"posts"},{"content":"","date":"28 июля 2024","externalUrl":null,"permalink":"/tags/status/","section":"Tags","summary":"","title":"Status","type":"tags"},{"content":" Uptime Kuma — это легковесный open-source инструмент для отслеживания состояния сервисов, сайтов, Docker-контейнеров и даже домашних устройств. После тестирования в локальной среде могу сказать, что он отлично подходит как для небольших задач, так и для более сложных сценариев.\nИнтеграция с Telegram позволяет удобно получать уведомления при падении сервисов.\nПредварительные требования # Перед началом установки убедитесь, что на вашей системе установлены следующие компоненты:\ngit Node.js (версия 18.x или 20.x) npm (версия 9+) pm2 Установка на Ubuntu / Debian-подобную систему # Обновление системы # sudo apt update Установка Node.js и npm # sudo apt install nodejs -y sudo apt install npm -y Проверьте установленные версии:\nnode -v \u0026amp;\u0026amp; npm -v Установка PM2 # PM2 — это продвинутый процесс-менеджер для Node.js приложений.\nsudo npm install pm2 -g Клонирование репозитория и запуск Uptime Kuma # git clone https://github.com/louislam/uptime-kuma.git cd uptime-kuma Запустите приложение с помощью PM2:\npm2 start server/server.js --name uptime-kuma Настройте автозапуск после перезагрузки:\npm2 startup pm2 save Доступ к веб-интерфейсу # После запуска сервис будет доступен по адресу:\nhttp://localhost:3001 Откройте этот URL в браузере, пройдите начальную настройку (логин и пароль) и добавьте первый мониторинговый элемент.\nОсновные возможности # Uptime Kuma поддерживает широкий спектр проверок:\nHTTP(s) TCP Ping Docker Поиск ключевых слов в ответе Также реализована поддержка уведомлений через:\nTelegram Email Discord Pushover И другие каналы Заключение # Uptime Kuma — отличное решение для организации мониторинга сервисов в домашней или рабочей среде. Он прост в настройке, не требует больших ресурсов и имеет удобный интерфейс.\nP.S. Вы восхитительны! 💪\n","date":"28 июля 2024","externalUrl":null,"permalink":"/uptime/","section":"Posts","summary":"","title":"Uptime Kuma – мониторинг ваших сервисов","type":"posts"},{"content":" Вступление # Блог стал тяжеловат. Особенно картинки. Решил я привести их в порядок и перевести всё в формат WebP — он легче, быстрее грузится и поддерживается почти везде.\nЧто такое WebP? # WebP — это формат изображений от Google, созданный ещё в 2010 году. Основан на технологии сжатия без потерь. Позволяет уменьшить размер файла:\nдо ~26% меньше, чем PNG до ~30% меньше, чем JPEG** Сжимаем изображения # Для сжатия используем утилиту cwebp. У кого её нет — можно установить на macOS через Homebrew:\nbrew install webp Шаги # 1. Создаём скрипт # Вот базовый вариант скрипта для массового конвертирования:\n#!/bin/bash #путь к папке с картиночкой path=\u0026#34;./images\u0026#34; #Сам скрипт find \u0026#34;$path\u0026#34; -type d -exec bash -c \u0026#39; for dir in \u0026#34;$@\u0026#34;; do current_dir=\u0026#34;$(basename \u0026#34;$dir\u0026#34;)\u0026#34; echo \u0026#34;Processing directory: $current_dir\u0026#34; for file in \u0026#34;$dir\u0026#34;/*.{jpg,jpeg,png}; do output=\u0026#34;${file%.*}\u0026#34;.webp cwebp -q 80 \u0026#34;$file\u0026#34; -o \u0026#34;$output\u0026#34; rm \u0026#34;$file\u0026#34; done done \u0026#39; _ {} \\; Скачать скрипт: 👉 webpconvert.sh\n⚠️ Скрипт неидеальный, но работает. Доработаю позже, если будет время (или нужда).\n2. Запуск # Укажите путь к папке с изображениями в скрипте и запустите его:\nchmod +x webpconvert.sh ./webpconvert.sh 3. Ждём # Процесс может занять какое-то время, особенно если много картинок. Но результат того стоит.\nВы восхитительны! # ","date":"27 июля 2024","externalUrl":null,"permalink":"/webp/","section":"Posts","summary":"","title":"Пакетная конвертация в .webp","type":"posts"},{"content":"","date":"4 июля 2024","externalUrl":null,"permalink":"/tags/certificate/","section":"Tags","summary":"","title":"Certificate","type":"tags"},{"content":" В этой статье мы расскажем о двух удобных CLI-утилитах — showcert и gencert, которые помогут вам легко читать, проверять и генерировать SSL-сертификаты. Эти инструменты отлично подходят как для повседневного использования, так и для автоматизации задач в DevOps-окружении.\nОбзор утилит # showcert # Эта утилита предназначена для чтения и анализа существующих SSL-сертификатов. С её помощью вы можете быстро получить информацию о сертификате удалённого сервера или локального файла.\ngencert # Утилита gencert служит для генерации самоподписанных сертификатов. Она позволяет создавать ключи и сертификаты с гибкими настройками, включая возможность подписи через собственный центр сертификации (CA).\nУстановка # Для установки обеих утилит используется pipx, который позволяет запускать Python-приложения в изолированных окружениях:\npip install pipx После этого установите showcert следующей командой:\npipx install showcert Использование # showcert # Проверка сертификата сайта # Чтобы проверить сертификат сайта, просто передайте доменное имя в качестве аргумента:\nshowcert blog.tatarinovms.space Эта команда отобразит подробную информацию о сертификате указанного хоста.\nСохранение full chain в формате PEM # Если вы хотите сохранить полную цепочку сертификатов удалённого сервера в формате .pem, используйте флаг --chain и перенаправьте вывод в файл:\nshowcert --chain -o pem ya.ru \u0026gt; ya.ru.pem gencert # Генерация самоподписанного сертификата # Самый простой способ создать самоподписанный сертификат — указать доменное имя:\ngencert example.ru www.example.ru Это создаст ключ и сертификат для домена example.ru и его поддомена www.example.ru.\nРаздельное сохранение ключа и сертификата # Если вы предпочитаете иметь отдельные файлы для приватного ключа и сертификата, используйте опции --key и --cert:\ngencert example.ru --key example.ru.key --cert example.ru.pem Использование собственного CA # Если вы хотите подписать сертификат своим центром сертификации, выполните:\ngencert --ca \u0026#34;MyCA\u0026#34; Это создаст корневой CA с названием MyCA.\nСоздание сертификата с использованием существующего CA # Для выпуска сертификата, подписанного вашим собственным CA, используйте параметры --cacert и --cakey:\ngencert example.ru --key example.ru.key --cert example.ru.pem --cacert MyCA.pem --cakey MyCA.key Эта команда создаёт ключ и сертификат для example.ru, подписанные ранее созданным центром сертификации.\nЗаключение # showcert и gencert — это мощные и удобные инструменты для работы с SSL-сертификатами в командной строке. Они экономят время при тестировании, разработке и администрировании защищённых сервисов. Благодаря простому интерфейсу и гибким настройкам эти утилиты будут полезны как начинающим, так и опытным разработчикам и системным администраторам.\nЕсли вы работаете с TLS/SSL в своём проекте, обязательно попробуйте эти инструменты. Они помогут сделать управление сертификатами проще и быстрее.\n","date":"4 июля 2024","externalUrl":null,"permalink":"/showcert/","section":"Posts","summary":"","title":"showcert \u0026 gencert — удобный инструмент для работы с SSL-сертификатами","type":"posts"},{"content":"","date":"24 мая 2024","externalUrl":null,"permalink":"/tags/applite/","section":"Tags","summary":"","title":"Applite","type":"tags"},{"content":" Не многие умеют и любят использовать программы без GUI. Даже с тем же самым brew. Я очень много софта через него ставлю, но вдруг людям не удобно писать brew search, затем brew install bla-bla\u0026hellip;но для тех кто не любит кли, есть гуи к этим кли програмам. Сегодня посоветую вам Applite — гуй к brew.\nКак ставить? # иронично, но можно через через brew brew install --cask applite либо через dmg файл с оффициального сайта Запускаем # Отвечаем на базовые вопросы. Есть ли у вас brew, и где он стоит:\nПользуемся # Работает как обычный магазин приложений: Поиск, просмотр и обновление установленного софта, категории.\n","date":"24 мая 2024","externalUrl":null,"permalink":"/applite/","section":"Posts","summary":"","title":"Легкий гуй для брю","type":"posts"},{"content":"","date":"23 апреля 2024","externalUrl":null,"permalink":"/tags/rust/","section":"Tags","summary":"","title":"Rust","type":"tags"},{"content":" Предыстория # Давно уже не помню пароли для своих сервисов. И помог мне в этом освобождении памяти — Bitwarden. Битводен – это многофункциональный с открытым исходным кодом, менеджер паролей.\nИз плюсов этого решения:\nкроссплатформенность: МакОсь, Виндовс, Линукс, айОС, Андройд, екстешены для браузеров, и даже консольный клиент\nинтеграции с рейкастом и Альфредом\n2х факторка и для него и внутри можно TOTP хранить\nавтозаполнение форм\nгенерация паролей по правилам\nшаринг паролей\nсохранение данный платежных карт\nне тошнит от интерфейса клиента\nСоздание базового аккаунта битводен является бесплатным на их серверах и даже за подписку можно больше фич, но можно самостоятельно разместить и свой сервер, но официальный сервер говорят подтормаживает, да и еще надо поднимать Microsoft SQL сервер, да и не будет всех \u0026ldquo;платных\u0026rdquo; фич. Да и времена сейчас такие, что лучше иметь все свое и при себе.\nПоэтому навел резкость, своих прекрасных глаз на такое решение как vaultwarden\nВаултводен — ранее известный как \u0026ldquo;Bitwarden_RS\u0026rdquo;, написан на языке Rust и использует Sqlite в качестве базы данных. и обрантно совместим с Bitwarden API.\nКак будем разворачивать ? # Нам нужно:\nДомен, чтобы был SSl Сервер (свой или VPS) Docker с docker-compose Caddy Что такое випиэска и докеры\\шмокеры знает почти каждый, немного расскажу про кэдди.\nОчень часто, в последнее время, все больше использую его для простой раздачи статики или для проксирования. Очень лаконичные конфиги получаются и SSL делается в разы проще и автоматически. Честно для дома для семьи почти заменил энджинкс.\nНастраиваем домен # На вашем операторе доменных имен добавляете A запись для вашего домена, которая ведет на ваш сервер.\nСтавим docker-compose # Ставим, если еще нет. На убунту делается так:\napt install docker.io docker-compose Создаем docker-compose.yml файл # Делаем стильно, модно и микросервисно. Поднимаем ваултводен сразу вместе с кэдди.\nСоздаем docker-compose.yml в удобном вам месте в любимом вашем текстовом редакторе с таким содержимым:\nversion: \u0026#34;3\u0026#34; services: vaultwarden: image: vaultwarden/server:latest container_name: vaultwarden restart: always volumes: - /etc/localtime:/etc/localtime:ro - /srv/vaultwarden:/data caddy: image: caddy:2 container_name: caddy restart: always ports: - 80:80 - 443:443 volumes: - /srv/caddy/Caddyfile:/etc/caddy/Caddyfile:ro - /srv/caddy/config:/config - /srv/caddy/data:/data - /srv/caddy/logs:/logs environment: DOMAIN: \u0026#34;\u0026lt;yourdomain\u0026gt;\u0026#34; EMAIL: \u0026#34;\u0026lt;youremail\u0026gt;\u0026#34; LOG_FILE: /srv/caddy/logs/access.log Где DOMAIN и EMAIL вам надо заполнить, для выпуска сертификата. Указываем например так:\nDOMAIN: \u0026#34;notbitwarden.tatar.beaver\u0026#34; EMAIL: \u0026#34;noreplay@tatar.beaver\u0026#34; Немного поясню # Первый сервис, это и есть “vaultwarden”, он основан на последнем образе vaultwarden/server. Имя ему не будем выдумывать и наречем его — vaultwarden. Также назначим ему рестарт - всегда.\nТакже определили два монтирования (bind mounts):\nпервый из этих файлов – /etc/localtime: это для проверки часового пояса и времени между контейнером и хостовой машиной\nкаталог /data внутри контейнера с /srv/vaultwarden на хосте нужен для хранения базы данных и прочих кешей с аттачментами. Да и бекапить удобнее будет.\nВторой сервис это и есть сам кэдди. Из интересного для использования его в качестве реверс прокси и для работы его как ACME клиента для получения сертификата у Let’s Encrypt, мы также сопоставили порты 80 и 443 на хосте с теми же портами внутри контейнера. Тут мудрить не стал особо.\nМы определили четыре \u0026ldquo;монтирования\u0026rdquo;: с помощью первой мы привязали файл /etc/caddy/CaddyFile - это основной конфиг. Остальное - \u0026ldquo;системное\u0026rdquo; и логи.\nСоздаем Caddyfile # Создаем папку:\nsudo mkdir /srv/caddy создаем Caddyfile в вашем любимом текстовом редакторе:\nvim /srv/caddy/Caddyfile с таким содержимым:\n{$DOMAIN}:443 { log { output file {$LOG_FILE} { roll_size 10MB roll_keep 10 } } tls {$EMAIL} reverse_proxy /notifications/hub vaultwarden:3012 reverse_proxy vaultwarden:80 { header_up X-Real-IP {remote_host} } } Немного поясню # {$DOMAIN} и {$EMAIL} возмется из docker-compose.yml\nСделали логи цикличным и не очень большими и в правильное место их пишем в виде файла.\nreverse_proxy. У него синтаксис простой:\nreverse_proxy [чо][куда]:\n— \u0026ldquo;Чо\u0026rdquo; используется для ограничения применения. Мы использовали путь, начинающийся со /: запрос будет обработан только при его совпадении.\n\u0026ldquo;Куда\u0026rdquo; - это адрес, на который должен быть перенаправлен запрос. Т.е мы перенаправляем запросы с путем /notifications/hub в “vaultwarden” на порт 3012 (“vaultwarden” – это имя сервиса и имя хоста, которое мы определили в файле docker-compose.yml, а все остальное – в порт 80.\nheader_up в нем мы ставим “{remote_host}” в “X-Real-IP” Запускаем # в каталоге где у нас лежит docker-compose.yml выполняем: sudo docker-compose up -d ждем — проверяем что все работает, выполняем:\nsudo docker ps В ответе будут наши контейнерны с именами: caddy и vaultwarden\nТеперь открываем в браузере домен который вы указали ранее и выполняем регистрацию новой учетной записи. В клиентах битводен для ваших ОС указываем его как URL для self-hosted системы.\nВы супер! # ","date":"23 апреля 2024","externalUrl":null,"permalink":"/vaultwarden/","section":"Posts","summary":"","title":"Vaultwarden - свой сервер для Bitwarden клиента","type":"posts"},{"content":" Надо мне запустить консольную версию Яндекс Диска и иметь копию на внешнем HDD. Оффициальный гайд на сайте Yandex\nУстанавливаем Яндекс Диск на Ubuntu Server # добавляем ключ echo \u0026#34;deb http://repo.yandex.ru/yandex-disk/deb/ stable main\u0026#34; | sudo tee -a /etc/apt/sources.list.d/yandex-disk.list \u0026gt; /dev/null \u0026amp;\u0026amp; wget http://repo.yandex.ru/yandex-disk/YANDEX-DISK-KEY.GPG -O- | sudo apt-key add - обновляем репы: sudo apt update устанавливаем яндекс диск: sudo apt install yandex-disk запускаем настройку клиента: yandex-disk setup просто отвечаем на вопросы и активируем устройство по предоставленному коду и по указанному урлу: вводим путь для сохранения файлов с вашего Яндекс Диска, я указал путь до примаунтированного своего HDD: соглашаемся на автостарт сервиса: Вы восхитительны!\n","date":"11 марта 2024","externalUrl":null,"permalink":"/yadisk/","section":"Posts","summary":"","title":"Устанавливаем Яндекс Диск на Ubuntu Server","type":"posts"},{"content":"","date":"12 февраля 2024","externalUrl":null,"permalink":"/categories/gaming/","section":"Categories","summary":"","title":"Gaming","type":"categories"},{"content":" Внимание! Программа больше не поддерживается\nС выпуском MacOS 14 Sonoma, Apple интегрировала Game Porting Toolkit, который предназначен для упрощения запуска игр Windows на компьютерах с чипом Apple Sillicon М. Однако, первые пользователи, тестировавшие эту технологию, столкнулись с необходимостью использования сложных гайдов.\nWhisky — это инструмент, который позволяет запускать игры в привычном для пользователей окружении. Whisky построен на основе платного CrossOver 22.1.1, который основан на Wine и собственно самого Game Porting Toolkit от Apple.\nПодготовка # Устанавливаем Whiskey # Скачиваем программу с официального сайта и устанавливаем ее. Или можно воспользоваться brew\nbrew install --cask whisky Скачиваем Steam для Windows # Скачиваем Steam для Windows\nСоздаем \u0026ldquo;бутылку\u0026rdquo; # Нажимаем Create Bottle Задаем имя бутылки и выбираем ОС. Рекомендую оставить Windows 10 и нажимаем Create Ждем скачивание файлов Устанавливаем Steam и игру # Нажимаем Run Выбираем ранее скаченный Steam для Windows Устанавливаем Steam \u0026ldquo;нативно\u0026rdquo; как в Windows. Next-Next\u0026hellip; Запускаем Steam из Whisky Устанавливаем и ждем пока Play станет активной Запускаем игру # P.S Список совместимых игр # Список совместимых игр можно глянуть по ссылке и лайхаки для запуска популярных игр\n","date":"12 февраля 2024","externalUrl":null,"permalink":"/whisky/","section":"Posts","summary":"","title":"Запускаем Windows игры на Mac с чипом Apple Sillicon М","type":"posts"},{"content":" Давно писал такой пост Конвертация Youtube ролика в mp3 но Youtube-dl умер. Самый крутой и популярный сейчас проект это yt-dlp\nКак установить ? # brew install yt-dlp Как использовать ? # Скачать MP3 # yt-dlp https://youtu.be/ioxEuSpUMkQ -x --audio-format mp3 На выходе у вас будет сразу mp3 файл cо звуком из видео\nСкачать видео # Скачайте лучшее доступное видео в формате mp4, но если нет mp4, то в формате с самым лучшим качеством.\nyt-dlp -f \u0026#34;bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4] / bv*+ba/b\u0026#34; т.е\nyt-dlp https://youtu.be/_mFWtAo29MU -f \u0026#34;bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4] / bv*+ba/b\u0026#34; Плей листы качаются аналогично, просто указываете ссылку на плейлист\nСкачать субтитры из видео # Смотрим список доступных субтиров\nyt-dlp https://youtu.be/_mFWtAo29MU --list-subs так как у этого видео нет загруженных субтитров, скачаем автоматически сгенерированные субтитры:\nyt-dlp https://youtu.be/_mFWtAo29MU --write-auto-subs --sub-langs ru ","date":"8 августа 2023","externalUrl":null,"permalink":"/yt-dlp/","section":"Posts","summary":"","title":"Качаем видео и не только с YouTube с помощью yt-dlp","type":"posts"},{"content":" Иногда во время разработки или тестирования необходимо быстро убить процесс, но вы знаете только порт на котором сервис поднялся. Быстро убить процесс по порту вам поможет программа — killport\nУстановка # Linux # curl -sL https://bit.ly/killport | sh MacOS # brew tap jkfran/killport brew install killport Использование # Если порт один:\nkillport 8080 А если процессов несколько:\nkillport 443 8081 3001 ","date":"28 апреля 2023","externalUrl":null,"permalink":"/killbyport/","section":"Posts","summary":"","title":"killport - убиваем процесс по сетевому порту","type":"posts"},{"content":"","date":"28 апреля 2023","externalUrl":null,"permalink":"/tags/port/","section":"Tags","summary":"","title":"Port","type":"tags"},{"content":" Давно уже в телеграм каналах и чатах есть поддержка стриминга по протоколу rtmps, но стримить из OBS, как-то банально. Решил я замутить свою \u0026ldquo;радиостанцию\u0026rdquo;, которая всегда будет онлайн и будет стримиться с виртуальной машины.\nЧто нам нужно? # Linux машина (у меня VDS с Ubuntu)\nУстановленный ffmpeg\nКонтент для трансляции\nПодготовка # Устанавливаем FFMPEG # Если на вашей Linux машине еще нет ffmpeg, то нужно его поставить!\napt install ffmpeg Создаем канал в Telegram # Нажимаем создать Telegram канал, устанавливаем аватарку, даем имя Копируем ваш serverURL и stream Key # Для трансляции rtmps потока в стрим нам нужен ключ и сервер, забираем его из канала:\nПереходим в канал и нажимаем Live Stream Выбираем Start With\u0026hellip; Копируем ваши serverURL и stream key: Начинаем трансляцию # Я буду делать стриминг всех песен с радиостанции VRock из игры Grand Theft Auto: Vice City, но вы можете использовать и ваш файл(ы) или ре-стримить трансляцию чужую.\nЗапускаем трансляцию # Логинимся в вашу Linux машину\nГотовим команду для запуска ffmpeg и получается вот такая команда:\nffmpeg -nostdin -hide_banner -nostats -loglevel panic \\ -stream_loop -1 -re -i {путь к файлу для стриминга} \\ -c:v libx264 -preset veryfast -b:v 3500k -maxrate 3500k -bufsize 5000k -pix_fmt yuv420p -g 50 \\ -c:a aac -b:a 32k -ac 1 -ar 22050 \\ -f flv {serverURL из Telegram}{stream key из Telegram} Запускаем ffmpeg в фоне, чтобы он не выключился после закрытия консоли и работал в фоне, для этого просто добавим символ \u0026amp; Проверяем работу нашей трансляции # Переходим в созданный наш Telegram канал и нажимаем Join на Live Stream Слушаем станцию: Пробуем с ПК: ","date":"23 апреля 2023","externalUrl":null,"permalink":"/telegramradio/","section":"Posts","summary":"","title":"Делаем свою радиостанцию в Telegram канале","type":"posts"},{"content":"","date":"22 июня 2022","externalUrl":null,"permalink":"/tags/adb/","section":"Tags","summary":"","title":"Adb","type":"tags"},{"content":"","date":"22 июня 2022","externalUrl":null,"permalink":"/categories/android/","section":"Categories","summary":"","title":"Android","type":"categories"},{"content":"","date":"22 июня 2022","externalUrl":null,"permalink":"/tags/android/","section":"Tags","summary":"","title":"Android","type":"tags"},{"content":"","date":"22 июня 2022","externalUrl":null,"permalink":"/tags/scrcpy/","section":"Tags","summary":"","title":"Scrcpy","type":"tags"},{"content":" scrcpy – простое приложение, которое отображает экран вашего мобильного устройства и позволяет управлять мышкой с ПК, записывать экран, вводить текст с клавиатуры, буфера обмена и пр Поддерживает подключение по проводу или по сети. Бесплатно, без рекламы и смс, да и вообще OpenSource\nКак установить? # brew install scrcpy И также у вас должен быть ADB который есть в PATH, если у вас его нет. Установите:\nbrew install android-platform-tools Как запустить # Подрубаем телефон к ПК В консоли вводим scrcpy Пользуемся! Если нужно что-то больше, в помощь вам scrcpy \u0026ndash;help или GitHub проекта\n","date":"22 июня 2022","externalUrl":null,"permalink":"/scrcpy/","section":"Posts","summary":"","title":"Scrcpy - Управление вашим Android устройством с ПК","type":"posts"},{"content":" Краткий гайд, как подключить Яндекс Диск по протоколу WebDav.\nГенерация пароля для приложения # Yandex рекомендует создать отдельный пароль для каждого стороннего приложения, которым требуется ваш пароль на Яндексе:\nДля этого воспользуйтесь этим гайдом от Yandex\nПодключаем Yandex по WebDav в приложении # Запускаем приложение в котором есть WebDav клиент. В моем случае это Documents by Readdle для iPadOS\nВыбираем WebDav Server\nВводим параметры для подключения: Title: Название коннекта\nURL: https://webdav.yandex.ru\nLogin: ваш логин Yandex\nPassword: ваш сгенерированный пароль для приложения\n— Открываем созданное подключение\nГотово # ","date":"14 апреля 2022","externalUrl":null,"permalink":"/ydiskwebdav/","section":"Posts","summary":"","title":"Подключение Яндекс Диск по WebDav","type":"posts"},{"content":"","date":"19 февраля 2022","externalUrl":null,"permalink":"/tags/dock/","section":"Tags","summary":"","title":"Dock","type":"tags"},{"content":"","date":"19 февраля 2022","externalUrl":null,"permalink":"/tags/ui/","section":"Tags","summary":"","title":"Ui","type":"tags"},{"content":" Чтобы наглядно рассортировать ваши приложения в Dock можно добавить разделитель, по сути это будет пустой значок.\nДля добавление узкого разделителя выполните комманду:\ndefaults write com.apple.dock persistent-apps -array-add \u0026#39;{\u0026#34;tile-type\u0026#34;=\u0026#34;small-spacer-tile\u0026#34;;}\u0026#39; Перезагружаем док:\nkillall Dock Для добавления большого разделителя выполните комманду:\ndefaults write com.apple.dock persistent-apps -array-add \u0026#39;{\u0026#34;tile-type\u0026#34;=\u0026#34;spacer-tile\u0026#34;;}\u0026#39; Перезагружаем док:\nkillall Dock Разделители передвигаются и удаляются как обычные значки программ в dock,т.е двигаем мышкой, а если мешают перетаскиваем вверх.\n","date":"19 февраля 2022","externalUrl":null,"permalink":"/spaceindock/","section":"Posts","summary":"","title":"Как сделать пробелы в Dock?","type":"posts"},{"content":"","date":"7 августа 2021","externalUrl":null,"permalink":"/tags/exa/","section":"Tags","summary":"","title":"Exa","type":"tags"},{"content":"","date":"7 августа 2021","externalUrl":null,"permalink":"/tags/eza/","section":"Tags","summary":"","title":"Eza","type":"tags"},{"content":" Очередная CLI утилита!\nСегодня я вам кратко о более удобной версии ls, в чем преимущества eza над ls?\nПросто чуть удобнее: больше ключей, подсветка и удобные типы сортировок и т.д.\nО всех фичах можно почитать тут.\nИсходный проект exa был архивирован в 2023 году. Его развивает форк eza — тот же функционал, но с актуальной поддержкой и новыми фичами. Устанавливайте именно eza. На macOS ставится через brew:\nbrew install eza Есть версии под все дистрибутивы Linux, ищите в ваших репозиториях!\n","date":"7 августа 2021","externalUrl":null,"permalink":"/exa/","section":"Posts","summary":"","title":"eza – удобный ls","type":"posts"},{"content":"","date":"7 августа 2021","externalUrl":null,"permalink":"/tags/ls/","section":"Tags","summary":"","title":"Ls","type":"tags"},{"content":"","date":"8 марта 2021","externalUrl":null,"permalink":"/categories/hardware/","section":"Categories","summary":"","title":"Hardware","type":"categories"},{"content":" Увидел рекламу сервиса в сториз инстаграм, который продает клейкую NFC метку со ссылкой на вашу анкету и якобы она упростит способом делится вашим контактом с пользователями. Они просто сканируют вашу метку и вуаля..такая вот визитка 21ого века.\nТехнически сервис работает просто - вы заполняете ваши контакты, они формируют About страницу с вашими данными, записывают URL адрес данной страницы в NFC метку, присылают вам ее, вы наклеиваете его на телефон/чехол и профит. На данном сайте есть ссылки в формате tel:, mailto:, вашей аватаркой и ссылкой на контакт и т.д\nНо это слишком топорно, давайте сделаем дешевле, практичнее и гибче.\nP.S Конечно в NFC метку можно записать и контакт сразу, но это не так информативно, так как возможных полей будет меньше.\nНачинаем # Создаем страницу с вашими контактами и ссылками на ресурсы где вас можно найти. Например как моя about страница Покупаем на Ali самые дешевые перезаписываемые метки (можно \u0026ldquo;одноразовые\u0026rdquo;, так даже дешевле выйдет). Я брал такие Создаем vCard для удобства добавления вас в справочник. Можно воспользоваться экспортом из приложения Contacts на MacOS или сделать vCard на сайте, сделать экспорт из GMail, способов много, даже взять стандарт vCard и заполним все поля вручную. P.S Если делаете файл аватарки в Base64, то конвертируем нашу аватарку в можно на сайте base64-image.de\nСохраняем наш файл как name.vcf и размещаем его и добавляем ссылку на вашу about страницу Записываем данные на метки # Для iPhone использую утилиту NFC Tools\nДля метки на нашу about страничку: Для метки c ссылкой на vCard: Проверяем работу # Приклеиваем метки на чехол/телефон/визитку\nPROFFIT!\n","date":"8 марта 2021","externalUrl":null,"permalink":"/personal-about/","section":"Posts","summary":"","title":"Создание вашей визитки в NFC Tag","type":"posts"},{"content":" Приобрел себе роутер Yota 4G, который до брендирования компанией назывался ZTE MF922, но в админке компания Yota скрыла очень много нужных и полезных настроек для опытных пользователей (мы с вами такие же, правда?) как их открыть?\nОчень просто открываем в вашем любимом браузере админку роутера и запускаем DevTools\n— Находим фрейм с именем fremeNav\nПереключаемся в Console выбираем наш фрейм и вводим: json $(\u0026#39;#nav\u0026#39;).css(\u0026#39;display\u0026#39;, \u0026#39;block\u0026#39;) Все, теперь нам доступны все скрытые и полезные настройки: # Также опубликую сразу прямые ссылки чтобы вам не делать эти манипуляции: # Настройки перенаправления портов, APN\nСписок подключенных устройств\nWizard настройки роутера\nНастройки Wifi\nРасширенные настройки Wifi сети\nНастройка мощности Wifi и \u0026ldquo;засыпания\u0026rdquo; роутера\nСмена пароля на админку\nНастройка Firewall\nНастройка приоритетов GSM сети\nНастройка WPS\nНастройка Pin кода для SIM\nСброс роутера на заводские настройки\nПроброс портов\nНастройки UPnP\nНастройка DMZ\n","date":"17 февраля 2021","externalUrl":null,"permalink":"/yota4g/","section":"Posts","summary":"","title":"Разблокировка дополнительных настроек в Yota 4G Wifi Router без перепрошивки","type":"posts"},{"content":"","date":"23 мая 2020","externalUrl":null,"permalink":"/tags/curl/","section":"Tags","summary":"","title":"Curl","type":"tags"},{"content":" Иногда необходимо быстро узнать ваш внешний адрес, как это сделать?\nВоспользуемся сайтом ifconfig.me\ncurl ifconfig.me В ответ вам придет ваш внешний IP адрес.\n","date":"23 мая 2020","externalUrl":null,"permalink":"/externalip/","section":"Posts","summary":"","title":"Как просто узнать ваш внешний IP адрес?","type":"posts"},{"content":"","date":"3 июля 2019","externalUrl":null,"permalink":"/tags/defaults/","section":"Tags","summary":"","title":"Defaults","type":"tags"},{"content":"","date":"3 июля 2019","externalUrl":null,"permalink":"/tags/screenshots/","section":"Tags","summary":"","title":"Screenshots","type":"tags"},{"content":" Мне не нравится, что папка по умолчанию для скриншотов в МакОС это рабочий стол, после долго использования рабочий стол превращается в помойку. Путь папки можно изменить.\nКак это сделать? # Открываем терминал и вводим команду:\ndefaults write com.apple.screencapture location ~/Pictures/Screenshots вместо ~/Pictures/Screenshots вы можете ввести желаемый для вас путь для сохранения скриншотов.\nПерезагружаем UI.\nkillall SystemUIServer Теперь все скриншоты будут сохраняться в указанную вам папку\n","date":"3 июля 2019","externalUrl":null,"permalink":"/macosdefscrinshots/","section":"Posts","summary":"","title":"Изменение папки для скриншотов в МакОС","type":"posts"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]