Задать вопрос
  • Как сделать резервное копирование archlinux?

    @aleks-th
    Вы сначала делаете:
    1. Cписок то чего бекапим.
    2. Когда бекапим.
    3. С какой периодичностью бекапим.
    4. Как проверяем что бекап корректен.
    5. Определяем сколько времени должны хранится бэкапы.
    6. В боевом режиме бэкапим когда идет доступ к файлам или во время простоя.
    7. Какое время критично для развертывания этих бэкапов( примерное время которое может без потерь простаивать сервер пока идет восстановление данных)
    8. Чем бэкапим - базы данных свои инструмент, файлы можно просто tar архивировать и так далее.
    9. Сколько резервных копий и где храним.
    10. Обязательно оцениваем примерные обьемы, будет плохо если тупо на третьем бэкапе диск кончится или в облаке место....

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

    Но, если речь идет о том что тупо систему скопировать свою ни в чем не разбираясь, и после обновления откатится до предыдущей версии.
    Все что выше можно не читать, тупо взять какойнибудь Acronis и делать тупо копии всего диска перед тем как будешь делать какието глобальные изменения, ну или по расписанию.
    Ответ написан
    Комментировать
  • Как ускорить YouTube на OpenWRT?

    ValdikSS
    @ValdikSS
    Я установил на роутер zapret nfqws, не используя стандартные скрипты из поставки. Конфигурация такая, какая описана вот в этом баге:

    https://github.com/bol-van/zapret/discussions/262

    Взял бинарник из репозитория, написал простейший init-скрипт (/etc/init.d/nfqws) для openwrt с вшитыми параметрами, написал свои правила firewall’а. Оригинальные тоже хорошие (и обрабатывают разные конфигурации), но вот эти банально проще.

    # cat /etc/init.d/nfqws 
    #!/bin/sh /etc/rc.common
    
    USE_PROCD=1
    START=91
    
    PROG=/etc/zapret/nfqws/nfqws
    
    start_service() {
      procd_open_instance
      procd_set_param command "$PROG"
      procd_append_param command --dpi-desync=fake
      procd_append_param command --dpi-desync-fooling=md5sig,badseq
      procd_append_param command --dpi-desync-split-pos=1
      procd_append_param command --dpi-desync-repeats=12
      procd_append_param command --dpi-desync-ttl=4
      procd_append_param command --qnum=200
      procd_append_param command --hostlist=/etc/zapret/nfqws/youtube.txt
    #  procd_append_param command --hostlist=/tmp/domains-export.txt
      procd_set_param stdout 1 # forward stdout of the command to logd
      procd_set_param stderr 1 # same for stderr
      procd_close_instance
    }


    С моими правилами файрволла (connbytes) в nfqws копируются только первые 8 пакетов, а дальше всё маршрутизируется как обычно. /etc/zapret/zapret.nft:

    chain zapret_lan_hook {
        type filter hook forward priority mangle;
    
    #    iifname {"br-lan"} \
          ip daddr != {0.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 100.64.0.0/10, 169.254.0.0/16, 224.0.0.0/3, 255.255.255.255/32} \
          tcp dport {80, 443} ct original packets lt 8 counter queue flags bypass to 200 comment "zapret IPv4 443 tcp"
    
    #    iifname {"br-lan"} \
          ip6 daddr != {::ffff:0:0/96, fc00::/7, fe80::/10, ff00::/8} \
          tcp dport {80, 443} ct original packets lt 8 counter queue flags bypass to 200 comment "zapret IPv6 443 tcp"
    
    #    iifname {"br-lan"} \
          ip daddr != {0.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 100.64.0.0/10, 169.254.0.0/16, 224.0.0.0/3, 255.255.255.255/32} \
          udp dport 443 ct original packets lt 8 counter queue flags bypass to 200 comment "zapret IPv4 443 udp"
    
    #    iifname {"br-lan"} \
          ip6 daddr != {::ffff:0:0/96, fc00::/7, fe80::/10, ff00::/8} \
          udp dport 443 ct original packets lt 8 counter queue flags bypass to 200 comment "zapret IPv6 443 udp"
    }


    Нужно заinclude’ить скрипт в настройках firewall’а. /etc/config/firewall:

    config include 'zapret'
    	option type 'nftables'
    	option path '/etc/zapret/zapret.nft'
    	option position 'table-post'
    	option enabled '1'


    Необходимо отключить offloading, с ним, скорее всего, работать не будет (но я не проверял, оригинальные правила учитывают этот момент).

    В таком виде всё установить можно на ЛЮБОЙ роутер, даже на 4/32, при большом желании (скриптом скачивания бинарника в оперативную память, при необходимости).

    /etc/zapret/nfqws/youtube.txt:

    youtube.com
    youtu.be
    googlevideo.com
    googleapis.com
    gvt1.com
    ggpht.com
    ytimg.com
    youtube-nocookie.com
    play.google.com
    video.google.com
    youtube-ui.l.google.com
    youtubeeducation.com
    youtubekids.com
    Ответ написан
    2 комментария
  • Как вычислить количество записей?

    Vindicar
    @Vindicar
    RTFM!
    Прочитать все записи, разбить строку по разделителю, скормить всё в collections.Counter.
    С pandas не работал, вот пример для списков:
    from collections import Counter
    from itertools import chain
    data = [
      (1, 'old;white'),
      (2, 'old;green'),
      (3, 'old;brown'),
      (4, 'new;green'),
    ]
    # генерирует последовательность ['old', 'white'], ['old', 'green'], ...
    split_generator = (item[1].split(';') for item in data) 
    # генерирует последовательность 'old', 'white', 'old', 'green', ...
    property_generator = chain.from_iterable(split_generator)
    # исправляет регистр и удаляет пробелы - можно убрать, если не надо
    property_fixed_generator = (item.strip().lower() for item in property_generator)
    # поглощает данные из генераторов и считает вхождения
    count = Counter(property_fixed_generator)
    print(count)  # Counter({'old': 3, 'green': 2, 'white': 1, 'brown': 1, 'new': 1})
    Ответ написан
    Комментировать
  • Как выполнить относительный импорт библиотеки в Python?

    @o5a
    Можно добавить путь верхнего уровня (project_catalog) к pythonpath, тогда можно будет использовать относительный импорт. Например так
    import os
    
    # выходим на верхний уровень
    parentdir = os.path.dirname(os.path.dirname(__file__))
    # и добавляем его к путям поиска
    os.sys.path.insert(0,parentdir)
    # после чего можем использовать импорт по вложенному пути
    import module_name.module.ModuleFileOne
    Ответ написан
    1 комментарий
  • Как добавить класс js?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Используйте всплытие событий. Вешайте обработчик на постоянно присутствующий родительский элемент.
    Ответ написан
    2 комментария
  • Как получить высоту только видимой части блока?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    простая математика. исходные данные: координаты блока относительно окна браузера (elemtnt.getBoundingClientRect()) и высота окна (window.height).

    Если y_top <= 0 и y_bottom >= window.height То высота видимой части блока равна высоте экрана (первая ваша картинка).
    Если y_top > 0 и y_bottom < window.height То высота видимой части блока равна высоте это блока (весь виден).
    Если y_top > 0 и y_bottom > window.height То высота видимой части блока равна высоте экрана минус верхняя позиция (вторая картинка).
    Если y_top < 0 и y_bottom < window.height То высота видимой части блока равна значению нижней позиции (третья картинка).
    Ответ написан
    1 комментарий
  • Какую использовать утилиту на linux для создания waweform?

    Viktor_T2
    @Viktor_T2
    python developer
    Утилита для линукс bbc audiowaveform https://github.com/bbc/audiowaveform
    audiowaveform -i test.mp3 -o test.png -z 10000 --waveform-style bars --bar-width 3 --bar-gap 2 --bar-style rounded --no-axis-labels --amplitude-scale 1.25 --background-color 333333 --waveform-color BFBFBF

    654809df5e4da286885586.png
    Ответ написан
    Комментировать
  • Как ловить статус и от этого выводить результат?

    Vindicar
    @Vindicar
    RTFM!
    Вместо строки возвращай кортеж или словарь. Короче, структуру данных.
    from typing import NamedTuple
    
    class Result(NamedTuple):
        text: str  # текст запроса
        success: bool  # успешен ли запрос
        status: str  # статус
    
    async def check_text(text: str) -> Result:
        url = f'https://сайт.com/?query={text}'
    
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                if response.status != 200:
                    return Result(text=text, success=False, status='Не удалось определить результат')
                html = await response.text()
                soup = BeautifulSoup(html, 'html.parser')
                status_element = soup.find('div', class_='table-block')
                if not status_element:
                    return Result(text=text, success=False, status='Не удалось определить результат')
                status_text = status_element.get_text().strip()
                # тебе нужно будет решить, когда запрос был успешен (True), а когда нет (False)
                if "ok" in status_text:
                    return Result(text=text, success=True, status='Можно')
                elif "no" in status_text:
                    return Result(text=text, success=False, status='Данный вариант недоступен')
                elif "no1" in status_text:
                    return Result(text=text, success=True, status='Можно под заказ')
                else:
                    return Result(text=text, success=False, status='Неизвестно')

    Тогда можно будет анализировать результат просто:
    result = await check_text(text)
    if result.success:
        ...  # реагируем на успешный запрос
        logger.info('%s: %s', result.text, result.status)
    else:
        ...  # реагируем на неудачный запрос
        logger.info('%s: %s', result.text, result.status)
    Ответ написан
  • Как сделать автозапуск python программы с виртуальным окружением в фоновом режиме на линукс?

    drygdryg
    @drygdryg
    Python-разработчик
    Можно использовать систему инициализации Systemd. Напишите unit-файл такого вида:
    [Unit]
    Description=My Script Service
    After=multi-user.target
    
    [Service]
    User=user  # Имя пользователя, от имени которого будет запускаться команда, указанная в ExecStart
    WorkingDirectory=/home/user/program  # Директория, в которую будет осуществлён переход перед запуском
    ExecStart=/home/user/program/venv/bin/python /home/user/program/webui.py
    Restart=always  # Всегда перезапускать скрипт при его падениях
    
    [Install]
    WantedBy=multi-user.target

    и сохраните его в директории /etc/systemd/system с расширением .service, например, /etc/systemd/system/my_program.service.

    Здесь не используется скрипт activate для активации виртуального окружения, но вместо этого указывается полный путь к интерпретатору Python внутри этого виртуального окружения.
    Также важно указывать абсолютные пути к файлам и директориям, даже несмотря на то, что задана рабочая директория WorkingDirectory.
    Если ваш скрипт опирается на сетевые соединение, в секции Unit в качестве After задайте network-online.target вместо multi-user.target:
    After=network-online.target

    После этого перезагрузите конфигурацию Systemd:
    sudo systemctl daemon-reload
    И запустите сервис с добавлением в автозагрузку:
    sudo systemctl enable --now my_program.service
    Ответ написан
    2 комментария
  • Как исправить ошибку чтения аргумента?

    @va_k
    Вы потеряли в функции возвращаемое значение. Надо так
    def __getattribute__(self, name):
          print(name)
          return super().__getattribute__(name)
    Ответ написан
    3 комментария
  • Как заблокировать нежелательный dhcp сервер?

    @SunTechnik
    DHCP работает через broadcast: client dhcp шлет всем пакет с запросом на конфигурацию, в ответ dhcp сервер шлет конфиг.
    То-есть, что бы заблокировать dhcp сервер - он должен оказаться в отдельной физической подсети и нужен router, который обеспечит доступ для нлрмального трафика.
    Чем о делять и чем маршрутизировать - зависит от того, что у Вас есть.
    1. Можно использовать vlan и L3 коммутатор.

    2. Компьютер, в который поставить 2 сетевые карты. ( одна - поделбчена к принтеру, другая - в сеть. На компьютере настроен forward пакетов)

    3. Существующий роутер, у которого есть свободный порт.

    Но сама постановка задачи звучит странно. Что за модель принтера, может можно сбросить настройки и получить доступ к администрированию?
    Ответ написан
    4 комментария
  • Как исправить ошибку чтения аргумента?

    Vindicar
    @Vindicar
    RTFM!
    __getattribute__() вызывается ДО проверки содержимого __dict__. В большинстве случаев нужен __getattr__().
    А вообще, что ты пытаешься сделать?
    Ответ написан
    3 комментария
  • Почему aiogram не выводит фото?

    febday
    @febday
    Просмотри документацию одним глазком

    В твоём случае нужно использоваться FSInputFile
    Твой код будет примерно такой:
    @router.message(F.text == "/lesmat")
    async def lesmat(msg: Message):
        await msg.answer_photo(FSInputFile("lesmat/lit1.png"))
    Ответ написан
    Комментировать
  • Как web.telegram.org сделал, что не видно в Network запросов?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега Веб-разработка
    Он в websocket-соединении, которое было создано до открытия вами DevTools (или до удаления истории).
    Ответ написан
    Комментировать
  • Может ли роутер выступать в качестве ретранслятора внешнего трафика?

    @rPman
    так как роутеры это уже давно linux машина, почти полнофункциональная, из него можно сделать все что угодно.

    ищи статистику по трафику, сравнивай с такой же статистикой по машинам в сети, можешь даже специально время выделить для тестов и отключить все машины от роутера (или оставить одну с прогнозируемым трафиком)
    Ответ написан
    Комментировать
  • Почему браузеры и curl дают разные результаты?

    ValdikSS
    @ValdikSS
    На сайте используется TLS Fingerprint (вероятно, JA3) как один из индикаторов сессии в системе перед веб-сервером, вероятно, это анти-DDoS.
    Так как браузер и curl используют разные SSL-библиотеки и передают разные наборы шифров, сервер предлагает вам пройти challenge.
    Ответ написан
    5 комментариев
  • Как измерить площадь фигуры?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Есть алгоритм Монте-Карло. Ты просто кидаешь рандомные точки на экран и считаешь попадает ли точка в фигуру или нет. Соотношение попаданий к общему число бросков даст тебе соотношение площади фигуры и площади области бросков (экрана).

    Данный метод универсален. Быстр и позволяет аппроксимипровать площать (выдавать приближенное значение) еще до того как будут посчитаны все точки).

    Решение о попадании можно принимать по цвету пиксела.

    Если на экране находится несколько фигур одного цвета - то соотв будет посчитана их общая площать.
    Ответ написан
  • Как размыть фон под текстом?

    solotony
    @solotony
    покоряю пик Балмера
    from PIL import Image, ImageDraw, ImageFont, ImageFilter
    
    # Откройте исходное изображение
    img = Image.open('3.png')
    
    # Создайте копию изображения
    img_copy = img.copy()
    
    # Создайте изображение с текстом на черном фоне
    mask = Image.new('L', img.size, 0)
    draw = ImageDraw.Draw(mask)
    font = ImageFont.truetype('3.ttf', size=54)
    text_position = (297, 553)
    draw.text(text_position, 'Your Text', font=font, fill=255)
    
    # Размойте маску
    blurred_mask = mask.filter(ImageFilter.GaussianBlur(10))  # Измените радиус размытия по вашему усмотрению
    
    # Примените размытие к фону
    img_copy.paste(img_copy.filter(ImageFilter.GaussianBlur(10)), (0, 0), blurred_mask)
    
    # Наложите текст на размытый фон
    draw = ImageDraw.Draw(img_copy)
    draw.text(text_position, 'Your Text', font=font, fill=('#00bc44'))
    
    # Сохраните результат
    img_copy.save('output.png')
    Ответ написан
    Комментировать
  • Не могу изменить разрешение экрана на Ubuntu 22.04.03 LTS Как решить проблему?

    smorman
    @smorman
    When In Rome do as The Romans do...
    Используешь Wayland поди?
    С ним не дружат почти все железяки пока ещё.
    Перейти на Xorg и должно всё работать, тем паче с этой карточкой.
    У меня, ну почти такая и все параметры доступны.
    Ответ написан
    5 комментариев