• Как удалить библиотеку с Python?

    Vindicar
    @Vindicar
    RTFM!
    Конечно, команды UNISTALL нету.
    Есть команда UNINSTALL.
    Ответ написан
    2 комментария
  • Почему перестает работать приложение на VPS после закрытия SSH?

    Vindicar
    @Vindicar
    RTFM!
    Я исхожу из того, что VPS под линуксом.
    Потому что когда ты закрываешь соединение, SSH-демон завершает процесс оболочки, который он запустил для его обслуживания (скорее всего это bash), посылая ему сигнал HUP. А твой сервис запущен как дочерний процесс из этой оболочки, и потому тоже получает сигнал HUP. Так как он этот сигнал не обрабатывает, он завершается.

    Если тебе нужно запустить процесс сервиса разово, и больше его не трогать, запускай его такой командой:
    nohup /путь/до/сервиса --параметры --сервиса &
    & позволит оболочке продолжить работу (запустит твою программу "в фоне"), а nohup "проглотит" сигнал HUP и тем самым не даст завершиться твоему сервису, когда ты отключишь сессию SSH. Но если сервис "упадёт", то запускать его придётся снова.

    Если для тебя допустимо запускать сервис вручную, и тебе нужно взаимодействие с сервисом через консоль (ну скажем, прочитать что он туда пишет), используй программу screen (может потребоваться её установить). Что это за программа, погугли сам, но вкратце, она позволяет создать сессию оболочки, которая переживёт отключение. Однако опять же, если сервис упал, screen его обратно не поднимет.

    Предыдущие варианты сойдут для отладки. А если на постоянку, то тебе нужно запускать сервис как демон, при старте VPS (ну мало ли хостер её перезагрузит), так что разбирайся с автозагрузкой. В зависимости от установленного на VPS дистрибутива это может быть скрипт init.d (смотри скрипты в каталоге /etc/init.d), модуль systemd или что-то ещё. Разбирайся, гугли, по этому материалов в сети полно.
    Ответ написан
    3 комментария
  • Как с помощью python вызвать функцию другой программы по ее адресу в памяти?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, получить ее возвращаемое значение - это слишком обще. Одно дело - получить целое число, другое дело - получить объект или строку.
    Во-вторых, речь про программу или про библиотеку? Всё-таки есть разница.

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

    Без ответов на эти вопросы детали предоставить трудно.

    Ты можешь посмотреть библиотеку Detours, она вроде многие вещи автоматизирует, но она для C++. Pymem может помочь, но нужно посмотреть, получится ли подружить его с ctypes.
    Но общий алгоритм и используемые winapi-функции я опишу.
    1. CreateProcess() для запуска целевого процесса как дочернего. Это самый простой способ получить права на его изменение.
    2. VirtualAllocEx(), чтобы выделить память в адресном пространстве этого процесса. Память может быть нужна как для данных, так и для исполняемого кода (нагрузки).
    3. Сформировать нагрузку в машинном коде, которая бы выполняла вызов требуемой функции. Может потребоваться знание соглашения о вызове целевой функции, чтобы подготовить регистры и стек перед вызовом, и корректно очистить их после вызова.
    4а. Если хочешь создавать поток, то твоя нагрузка должна быть функцией с сигнатурой вида:
    int __stdcall payload(LPVOID param)
    читай про конвенцию stdcall, чтобы понять, как это должно выглядеть в машинном коде на целевой платформе. Создав такую функцию, передаёшь её в CreateRemoteThread() для запуска потока.
    4б. Если хочешь вызвать целевую функцию в главном потоке, тебе еще придётся почитать про SuspendThread(), ResumeThread(), GetThreadContext() и SetThreadContext(). Грубо говоря, останавливаешь поток, запоминаешь его контекст (где он сейчас находится), перенастраиваешь контекст так, чтобы выполнение продолжилось с твоей нагрузки (меняешь регистр EIP/RIP), и возобновляешь поток. Твоя нагрузка, в свою очередь, должна просигналить твоему внешнему коду, что она завершила работу, и уйти в вечный цикл. Тогда внешний код должен снова остановить поток, вернуть старый контекст, и возобновить поток. В этом случае твоя нагрузка может быть просто кодом, а не функцией.
    4в. Ещё можно выполнить код при инъекции библиотеки в процесс, в рамках DLLMain(), но этот код, ЕМНИП, сильно ограничен в том, что он может делать. Хотя он наверняка сможет запустить новый поток, а тот поток уже будет делать что сочтёт нужным.

    В любом случае это всё куда проще сделать на C/C++ чем на питоне. Можно ли провернуть такой фокус только через pymem и ctypes, я не знаю. Насколько я знаю, pymem делает вариант 4a чтобы засунуть интерпретатор питона внутрь целевого процесса, и выполнять код в контексте этого процесса. Так что может и прокатит.
    Ответ написан
    1 комментарий
  • Не понимаю, почему код где-то застревает и не выполняется?

    Vindicar
    @Vindicar
    RTFM!
    sock.listen(1)
    listen() достаточно сделать 1 раз, чтобы переключить сокет в слушающий режим.
    Параметр указывает, сколько клиентов могут одновременно ожидать ответа на попытку соединения. Если эта очередь переполнится (клиенты подключаются, а твоё приложение их не успевает принимать), то последующие клиенты автоматически получат отлуп вместо ожидания.

    thread_listen_client = Thread(target=listen_client())
    Ты запускаешь поток, телом которого является значение, возвращаемое функцией listen_client(). Т.е. функция listen_client() выполняется сразу же, а поток уже не запускается, так как возвращённый listen_client() None - это не функция. Осознай разницу между ссылкой на функцию (listen_client) и вызовом функции (listen_client()).

    Ну и наконец, у тебя listen_client() обслуживает клиента, и только потом пытается принять следующее подключение. Как следствие, клиенты будут обслуживаться только по одному (хотя в твоём случае обслуживание очень быстрое и это будет незаметно). Смысл вообще городить потоки?
    Ответ написан
  • Как вывести все из скобок, но внутри них могут имеется и другие?

    Vindicar
    @Vindicar
    RTFM!
    В общем надо выводить весь текст из скобок с соблюдений вложений.

    В общем случае невозможно. Всегда можно составить такую строку, на которой твоя регулярка споткнётся.
    Нужно идти по строке и считать уровень сложенности скобок.
    Ответ написан
    Комментировать
  • Как исправить "pymysql.err.ProgrammingError: Cursor closed"?

    Vindicar
    @Vindicar
    RTFM!
    async with conn.cursor() as cur:
    По выходу из with курсор будет гарантированно закрыт, независимо от способа выхода. А у тебя дальше идёт
    await cur.execute(f'INSERT INTO profile(uid) VALUES(uid)')

    Либо внеси эту операцию внутрь with, либо создай под неё новый курсор.
    Ответ написан
    6 комментариев
  • Замена вхождений regex, разбирая каждое вхождение в Python?

    Vindicar
    @Vindicar
    RTFM!
    Читаем доку.
    The sub() method takes a replacement value, which can be either a string or a function, and the string to be processed.
    replacement can also be a function, which gives you even more control. If replacement is a function, the function is called for every non-overlapping occurrence of pattern. On each call, the function is passed a match object argument for the match and can use this information to compute the desired replacement string and return it.


    Т.е. пишешь функцию, которая обрабатывает одиночную замену желаемым образом, и передаёшь её в метод sub() регулярки.
    Ответ написан
    Комментировать
  • Как сделать умный запрос в sqllite на Python?

    Vindicar
    @Vindicar
    RTFM!
    Ну разве что синтезировать текст запроса - проходить по списку полей, если поле задано, прописываем его с плейсхолдером в секцию SET, а в список передаваемых значений добавляем подставляемое значение.
    Иначе никак - насколько я знаю, SQL подразумевает что если ты не хочешь изменять значение поля в UPDATE, ты его просто не указываешь.
    Ответ написан
    Комментировать
  • Как правильно создать признаки Хаара?

    Vindicar
    @Vindicar
    RTFM!
    Без кода дать ответ сложно. Вообще выглядит как проблема с non-maximum suppression - грубо говоря, у тебя несколько соседних перекрывающихся окон дают отклик, так как они все содержат лицо. Нужно выбирать окно с самым сильным откликом, и либо отбрасывать, либо объединять сильно пересекающиеся с ним. Кроме того, можно пробовать отсекать те окна, у которых соседей слишком мало.

    Кроме того, признак Хаара всегда состоит из черных И белых прямоугольников равной суммарной площади. Это связано с тем, что он оперирует суммарной яркостью в той или иной области окна. Так что признак с одним чёрным прямоугольником - это не признак. Что-то ты странно сформулировал.

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

    Vindicar
    @Vindicar
    RTFM!
    Igor Pecherskih, читай документацию. Достаточно проверить, есть ли у целевого пользователя некоторый минимальный набор прав модера - и тогда будет непринципиально, как роль модератора называется да и есть ли она вообще.
    Ответ написан
  • Как получить код страницы?

    Vindicar
    @Vindicar
    RTFM!
    Прямо через селениум и ищи, он это позволяет.
    Ответ написан
  • Возможно ли окно у окна отключить взаимодействие?

    Vindicar
    @Vindicar
    RTFM!
    Не знаю, есть ли решение через PyQT, но точно есть решение через WinAPI.
    SetWindowRgn() позволяет задать активный регион для окна. Точки, не входящие в этот регион, не будут обрабатываться ни при рисовании, ни при кликах.

    Пример

    import ctypes
    import ctypes.wintypes as w
    
    def ErrorIfZero(result, func, args):
        if not result:
            raise ctypes.WinError(ctypes.get_last_error())
        return result
    
    # используем user32.dll и kernel32.dll
    kernel32 = ctypes.windll.kernel32
    user32 = ctypes.windll.user32
    gdi32 = ctypes.windll.gdi32
    # описываем используемые функции, типы и константы 
    kernel32.GetConsoleWindow.argtypes = []
    kernel32.GetConsoleWindow.restype = w.HWND
    kernel32.GetConsoleWindow.check = ErrorIfZero
    
    user32.GetWindowRect.argtypes = [w.HWND, w.LPRECT]
    user32.GetWindowRect.restype = w.BOOL
    user32.GetWindowRect.check = ErrorIfZero
    
    user32.SetWindowRgn.argtypes = [w.HWND, w.HRGN, w.BOOL]
    user32.SetWindowRgn.restype = w.INT
    user32.SetWindowRgn.check = ErrorIfZero
    
    gdi32.DeleteObject.argtypes = [w.HANDLE]
    gdi32.DeleteObject.restype = w.BOOL
    gdi32.DeleteObject.check = ErrorIfZero
    
    gdi32.CreateRectRgnIndirect.argtypes = [w.LPRECT]
    gdi32.CreateRectRgnIndirect.restype = w.HRGN
    gdi32.CreateRectRgnIndirect.check = ErrorIfZero
    
    gdi32.CombineRgn.argtypes = [w.HRGN, w.HRGN, w.HRGN, w.INT]
    gdi32.CombineRgn.restype = w.INT
    gdi32.CombineRgn.check = ErrorIfZero
    RGN_AND  = 1
    RGN_OR   = 2
    RGN_XOR  = 3
    RGN_DIFF = 4
    RGN_COPY = 5
    
    
    hWnd = kernel32.GetConsoleWindow()
    r = w.RECT()
    user32.GetWindowRect(hWnd, ctypes.byref(r))
    r.left, r.right = 0, r.right - r.left
    r.top, r.bottom = -50, r.bottom - r.top #почему-то есть косяк с заголовком окна
    hole = w.RECT(r.right // 4, r.bottom // 4, 3 * r.right // 4, 3 * r.bottom // 4)
    
    hRgn = gdi32.CreateRectRgnIndirect(ctypes.byref(r))
    hHole = gdi32.CreateRectRgnIndirect(ctypes.byref(hole))
    gdi32.CombineRgn(hRgn, hRgn, hHole, RGN_DIFF)
    gdi32.DeleteObject(hHole)
    
    user32.SetWindowRgn(hWnd, hRgn, True)
    
    input('Press Enter to fix the hole.')
    
    user32.SetWindowRgn(hWnd, 0, True)
    gdi32.DeleteObject(hRgn)

    Ответ написан
    Комментировать
  • Как сделать динамическую slash команду disnake?

    Vindicar
    @Vindicar
    RTFM!
    Т.е. ты хочешь чтобы в команде автоматически предлагался список доступных серверов и т.п.?
    Никак. Особенно с учётом того что команда (а значит, и её параметры) регистрируется при старте бота, а со временем этот список всё равно может измениться и потерять актуальность.
    Ответ написан
    4 комментария
  • Как сделать ответ на "/start" на aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Ответ написан
    Комментировать
  • Как купить роль по "айди"?

    Vindicar
    @Vindicar
    RTFM!
    У тебя противоречия в запросах к БД. Для начала ответь на такие вопросы:
    1. Сколько серверов будет обслуживать бот - один или несколько?
    2. Сколько ролей можно покупать на сервере?
    3. Баланс пользователя будет свой на каждом сервере или общий?
    Исходя из этого и нужно проектировать БД.
    Ответ написан
  • Как один цикл прерывает другой цикл?

    Vindicar
    @Vindicar
    RTFM!
    А что тут непонятного?

    Внешний цикл выполняет своё тело раз за разом. При этом пока тело не выполнится до конца, новое выполнение тела не начнётся.
    Соответственно, внутренний цикл задерживает выполнение кода в теле внешнего цикла, и тем самым задерживает весь внешний цикл.
    Ответ написан
    Комментировать
  • Как по написанной функции в python отобразить ее на графике с помощью matplotlib.pyplot, установив при этом шаг по оси х 0.1?

    Vindicar
    @Vindicar
    RTFM!
    Если в arange() не указать третий параметр, то она вернёт значения в указанном интервале от a до b с шагом 1.
    Если указать, то этот параметр будет желаемым значением шага.
    Так что просто генерируй массивы x с другим шагом, и всё.
    Ответ написан
    3 комментария
  • Получение текста между заголовкми?

    Vindicar
    @Vindicar
    RTFM!
    Тривиально. Держи в памяти буфер строк и переменную для текущего заголовка.
    Если строка является заголовком - отправляешь на вывод текущий заголовок и текущее содержимое буфера строк, потом очищаешь буфер и запоминаешь текущую строку как заголовок.
    Если строка не является заголовком - добавляешь её в буфер строк.
    Когда перебрал все строки, отправляешь на вывод последний заголовок и то, что сейчас в буфере.
    Ответ написан
    Комментировать