Задать вопрос
  • Как в Obsidian увеличть ширину заметки?

    @oghmios
    Можно не править CSS, а просто отключить конфигурационный параметр "Ограничить максимальную длину строки":

    Настройки (иконка "шестерёнка" внизу слева) -> Редактор -> Отображение -> выключить переключатель "Ограничить максимальную длину строки"

    На английском это "Readable file length", эта настройка появилась ещё в версии 0.7.0: https://obsidian.md/changelog/2020-06-09-desktop-v...
    https://readmedium.com/obsidian-editor-settings-fo...
    Ответ написан
    2 комментария
  • Как с помощью JS организовать запись и чтение данных?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    GM_setValue GM_getValue - будут храниться в сторе самого расширения.

    Всякие куки, localStorage, indexedDb - всё может почитститься самом сайтом или случайно тобой.

    Надёжнее - только свой сервак завести и к нему запросами отправлять-получать.:)
    Ответ написан
    Комментировать
  • Почему все говорят что писать ботов это сложно?

    Vindicar
    @Vindicar
    RTFM!
    А сложность начинается, как только задачи, стоящие перед ботом, перерастают уровень примера в документации видеотуториале пятилетней давности.

    Нужно сделать несколько под-команд у команды. Напишу цепочку if-elif-else, делов то. Ой, а теперь простыня кода на пять экранов, в которой фиг чего найдёшь. Потому что нет привычки структурировать код.

    Нужно, чтобы несколько команд/событий формировали цепочку (сценарий). Например, пользователь отправил тре сообщения, первое с именем, второе с возрастом, третье с адресом. Ой, а как это сделать вообще? Не зная понятия "конечный автомат" (finite state machine, FSM), очень трудно догадаться, как тут поступить.

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

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

    Нужно добавить боту графический интерфейс - админку. Ой, а работает или интерфейс, или сам бот! Потому что нужно представлять, как устроено большинство GUI-фреймворков, и как устроена асинхронное приложение. А заодно понимать многопоточность, вопросы синхронизации действий между двумя потоками, и особенности работы с asyncio в многопоточных приложениях. Потому что одним потоком тут обойтись будет очень непросто.

    Нужно хранить данные в БД. Ой, а почему у меня проблемы при записи в БД имени пользователя? А потому что погромист собирает SQL-запрос через форматирование строк. Надо было почитать доки, чтобы наткнуться на prepared statements, они же parameterized queries.

    Нужно хранить данные в БД. Вот только данные имеют связи многие-ко-многим. Я знаю! Я буду просто добавлять или удалять столбцы в таблицу! Потому что не освоены даже азы проектирования БД. Тут уже nuff said. И да, я такое видел на этом сайте.

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

    @Zzzz9
    Ответ написан
    Комментировать
  • Как сделать резервное копирование 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 комментариев