Задать вопрос
  • Долгая обработка SQL запроса?

    Lord_of_Rings
    @Lord_of_Rings Куратор тега Python
    Дунадан - северный странник. Злой, но очень добрый
    Можно использовать подзапрос вместо двух запросов и цикла, если я не ошибаюсь
    cur.execute('''DELETE FROM parsing
                   WHERE parsing_user_id IN (SELECT user_full_data_user_id FROM user_full_data)''')
    Ну и, конечно, sqlite - это не для таких БД

    P. S. Можно ещё индексы сделать к столбцам
    CREATE INDEX idx_user_full_data_user_id ON user_full_data(user_full_data_user_id);
    CREATE INDEX idx_parsing_user_id ON parsing(parsing_user_id);
    Ответ написан
    1 комментарий
  • Почему в параметр функции идёт только последний индекс?

    Vindicar
    @Vindicar
    RTFM!
    Поздравляю, ты попался на лямбду.
    Лямбды сохраняют ссылки на переменные, а не их значения.
    lambda _: set_default_microphone(index) сохранит ссылку на index, а потому все лямбды будут видеть одно и то же значение index, которое было установлено последним.
    Это можно обойти, сохранив ссылку при объявлении лямбды. Самый простой способ - засунуть сохраняемое значение в значение по умолчанию для неиспользуемого параметра. Значения по умолчанию для параметров вычисляются один раз при объявлении функции, в т.ч. лямбды.
    Например, так:
    lambda _, *, ind=index: set_default_microphone(ind)

    Ну или даже так:
    lambda _, *, index=index: set_default_microphone(index)
    Ответ написан
    2 комментария
  • Как избежать зависание textarea при обработке большого массива?

    @historydev Куратор тега JavaScript
    Редактирую файлы с непонятными расширениями
    <input type="text" id="textarea">

    // Код воркера в виде строки
    const workerCode = `
      self.onmessage = (event) => {
        const largeArray = event.data;
        
        // Выполнение тяжелой обработки массива
        for (let i = 0; i < largeArray.length; i++) {
          // Например: largeArray[i] = someProcessing(largeArray[i]);
          largeArray[i] *= 2; // Пример обработки: удваиваем каждый элемент
        }
    
        // Отправка обработанных данных обратно в главный поток
        self.postMessage(largeArray);
      };
    `;
    
    // Создание Blob из строки с кодом воркера
    const blob = new Blob([workerCode], { type: 'application/javascript' });
    // Создание объекта Worker из URL на Blob
    const worker = new Worker(URL.createObjectURL(blob));
    
    // Обработка сообщений от воркера
    worker.onmessage = (event) => {
      const processedArray = event.data;
      console.log('Обработанный массив:', processedArray);
      // Можно обновить интерфейс или использовать данные
    };
    
    // Пример массива для обработки
    const largeArray = new Array(1e6).fill(15);
    
    function debounce(func, delay) {
      let timeout;
      return function(...args) {
          clearTimeout(timeout);
          timeout = setTimeout(() => func.apply(this, args), delay);
      };
    }
    
    const handleInput = debounce(() => {
      worker.postMessage(largeArray);
    }, 300); // Вызываем через 300 мс после окончания ввода
    
    // Пример добавления обработчика для textarea
    textarea.addEventListener('input', (event) => {
      console.log(event.target.value);
      handleInput();
    });
    Ответ написан
    1 комментарий
  • Что пытается сделать злоумышленник на моем сайте?

    На первом скрине, похоже, атака через "Stacked Queries". Хацкер надеется, что вы не отфильтровали входящие данные.

    Допустим у вас из бройзера приходит ID товара. И в программе запрос:

    SELECT * FROM products WHERE productid={нефильтрованный ID};


    Хакер отправляет вместо ID товара следующее:

    1; SELECT pg_sleep(25)


    В результате получится запрос:

    SELECT * FROM products WHERE productid=1; SELECT pg_sleep(25);


    И ваш сервер при каждом таком запросе будет спать 25 секунд. И порядочное количество таких запросов в случае удачи атаки смогут повесить вам там всё.

    То, что он продолжает долбиться, ничего не значит. Он, наверняка, использует какого-то бота, где накиданы в кучу различные векторы атаки, и они все применяются, пока ваш сервер не упадёт в результате срабатывания какой-то из них.
    Ответ написан
    Комментировать
  • Клики по динамически созданным кнопкам в форме ajax?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    делегирование.
    +$(".form-submit").on("click", ".product__add", function () {
    -$(".product__add").on("click", function () {
    Ответ написан
    Комментировать
  • Как ускорить загрузку js?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    window.addEventListener('DOMContentLoaded', function() {
        let game = localStorage.getItem('game');
        document.getElementById('game').innerHTML = game;
    });
    Ответ написан
    7 комментариев
  • Почему не работает pattern на input?

    Elaryks
    @Elaryks
    Проверка с помощью атрибута pattern срабатывает непосредственно перед отправкой формы. Кроме того, это не запретит ввод символов, отличных от цифр, а лишь покажет уведомление в случае несоответствия. Вашу же задачу можно решить несколькими способами.
    Первый вариант: <input type="number" />. Из особенностей: он допускает ввод некоторых символов, отличающихся от цифр (например, "+" и "e").
    Второй вариант: перехватывать событие onChange у поля ввода:
    const [value, setValue] = useState('')
    
    const handleInputChange = (e) => {
      setValue(e.target.value.replace(/\D/g, ''))
    }
    
    <input value={value} onChange={handleInputChange} />
    Ответ написан
    Комментировать
  • Как отправить разные изображения для сообщений с одинаковым содержанием в Telebot?

    Vindicar
    @Vindicar
    RTFM!
    Тебе нужен автомат состояний (finite state machine, FSM). Не знаю, есть ли его реализация в комплекте с telebot, но идея простая: нужно помнить, что пользователь делал раньше, т.е. иметь хранилище ключ-значение вида "id пользователя -> состояние+доп. инфа". В простейшем варианте хватит и словаря (если тебе не критично, чтобы сведения переживали перезагрузку бота).
    Ответ написан
    Комментировать
  • Как на сайте отобразить MJPG поток, который требует digest авторизации?

    Anastasia2306
    @Anastasia2306
    PHP-разработчик.
    Это не будет работать в таком виде, потому что это на уровне браузера стоит защита от таких вот конструкций. Вы правильно указали, что без PHP тут не обойтись. Я бы как-то решила этот вопрос:

    <?php
    $url = 'http://192.168.1.8/cgi-bin/mjpg/video.cgi?channel=1&subtype=1';
    
    // Функция для digest-авторизации
    function digest_parse($txt)
    {
        $needed_parts = array('nonce'=>1, 'realm'=>1, 'qop'=>1);
        $data = array();
        $keys = implode('|', array_keys($needed_parts));
    
        preg_match_all('@('.$keys.')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
    
        foreach ($matches as $m) {
            $data[$m[1]] = $m[3] ? $m[3] : $m[4];
            unset($needed_parts[$m[1]]);
        }
    
        return $needed_parts ? false : $data;
    }
    
    // Инициализация cURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    
    // получения заголовков www-Authenticate
    $response = curl_exec($ch);
    
    // разбор заголовк а WWW-Authenticate
    if (preg_match('/^WWW-Authenticate: Digest (.*)$/im', $response, $matches)) {
        $digest_parts = digest_parse($matches[1]);
    
        // Создание заголовка Authorization
        // Здесь также надо сгенерить правильный ответ на основе полученных данных и вашего логина и пароля
        // наподобие этого
        $digest_response = ''; // ответ
    
        // Установка опций для cURL с заголовком Authorization
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Digest username="adminka", realm="'.$digest_parts['realm'].'", nonce="'.$digest_parts['nonce'].'", uri="/cgi-bin/mjpg/video.cgi?channel=1&subtype=1", response="'.$digest_response.'", qop='.$digest_parts['qop'].', nc=00000001, cnonce="d41d8cd98f00b204e9800998ecf8427e"'));
    }
    
    // Удаление предыдущих заголовков
    curl_setopt($ch, CURLOPT_HEADER, 0);
    
    // Передача потока клиенту
    curl_exec($ch);
    curl_close($ch);
    ?>


    Ну а потом уже смело в теге img можно сделать так:
    <img src="вашскрипт.php" width="720" height="480">

    Пример с PHP кодом не полный - я лишь натолкнула вас на мысль, как это может работать. Удачи!
    Ответ написан
    1 комментарий
  • Как ограничить количество подключений прокси в Pyrogram?

    Mike_Ro
    @Mike_Ro Куратор тега Python
    Python, JS, WordPress, SEO, Bots, Adversting
    в Pyrogram документации не нашел подобного

    Все верно, Pyrogram не настолько гибкий по прокси, в сравнение с Telethon. Используйте внешний менеджер подключений/проксей и не будите зависеть от конкретной библиотеки, например:
    import asyncio
    from pyrogram import Client
    from pyrogram.errors import PyrogramError
    
    class ProxyManager:
        def __init__(self, app, max_retries=5, retry_delay=1, proxy=None):
            self.app = app
            self.max_retries = max_retries
            self.retry_delay = retry_delay
            self.proxy = proxy
            self.client = None
    
        async def connect(self):
            for attempt in range(1, self.max_retries + 1):
                try:
                    print(f"Connection attempt #{attempt}")
                    self.client = Client(**self.app, proxy=self.proxy)
                    await self.client.start()
                    print("The connection was established successfully.")
    
                except PyrogramError as e:
                    print(f"Connection error: {e}")
                    if attempt == self.max_retries:
                        print("The maximum number of connection attempts has been reached, stop!")
                        break
    
                    await asyncio.sleep(self.retry_delay)
    
        async def disconnect(self):
            if self.client:
                await self.client.stop()
                print("Connection is closed.")
    
    app = {
        'api_id': 'YOUR_API_ID',
        'api_hash': 'YOUR_API_HASH',
        'session_name': 'your_session_name'
    }
    
    proxy = {
        'scheme': 'http',  # or 'socks5'
        'hostname': 'your.proxy.hostname',
        'port': 1080,
        'username': 'user',
        'password': 'password'
    }
    
    # test run
    async def main():
        manager = ProxyManager(app, max_retries=3, retry_delay=2, proxy=proxy)
        await manager.connect()
        await manager.disconnect()
    
    asyncio.run(main())
    Ответ написан
    1 комментарий
  • Ошибка 403 при парсинге сайта?

    Mike_Ro
    @Mike_Ro Куратор тега Python
    Python, JS, WordPress, SEO, Bots, Adversting
    Обнаружил некую защиту "на лоха", а значит request и обычный selenium не справятся, буду использовать selenium + selenium-stealth (пример от сюда) + chrome + socks5 (рабочий, на момент теста):
    import time
    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.chrome.options import Options
    from selenium_stealth import stealth
    
    proxy = '45.132.75.19:23820'
    
    options = Options()
    options.add_argument('--proxy-server=socks5://' + proxy)
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_argument("window-size=1920,1080")
    # options.add_argument("--incognito")
    options.add_argument("--disable-extensions")
    options.add_argument("--disable-plugins-discovery")
    options.add_argument("--start-maximized")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    
    executable_path = './chromedriver-121.0.6167.85.exe'
    
    service = Service(executable_path=executable_path)
    driver = webdriver.Chrome(service=service, options=options)
    
    stealth(driver,
            languages=["en-US", "en"],
            vendor="Google Inc.",
            platform="Win64",
            webgl_vendor="Intel Inc.",
            renderer="Intel Iris OpenGL Engine",
            fix_hairline=True,
            run_on_insecure_origins=True,
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.85 Safari/537.36',
            )
    
    try:
        driver.get('https://allegro.pl/kategoria/laptopy-491')
        time.sleep(30)
        print(driver.page_source)
    finally:
        driver.quit()

    Chromedriver качать здесь, он должен совпадать с мажорной версией Вашего Chrome браузера, который будет использовать Selenium.

    65c1e056ad6db620469150.png
    Ответ написан
    Комментировать
  • Как создавать, принимать и обрабатывать socket?

    1. Вебсокеты - это сложновато.
    2. Вебсокеты на PHP - вдвойне сложно. Проблема в том, что PHP задуман как скриптовый язык, т.е. скрипт выполняется заканчивает свою работу. А вебсокет - это постоянное соединение, т.е нам надо, чтобы программа постоянно крутилась в фоне. Вебсокеты можно реализовать на PHP, но, как персонально мне кажется, проще будет выучить Go )) , или же, как в ответе уважаемого Артём , сделать сервер на ноде.
    3. Если ваш чат не такой супер-функциональный, как чат в мессенджерах, то вместо вебсокетов можно обойтись SSE (Server Sent Events). SSE так же требует постоянного соединения, но всё работает через HTTP, и это ну прямо намного проще. Единственный недостаток - это то, что SSE работает только в одну сторону: от сервера в браузер. Т.е. запросы из браузера можно получать обычным POST запросом, а отдавать обратно информацию уже через SSE.

    С SSE есть два пути:
    1. Написать сервер самому, используя какую-то простую библиотеку вроде этой https://github.com/hhxsv5/php-sse
    2. Но я бы сделал ещё проще. Есть такой великолепный проект под названием Mercure https://mercure.rocks
    Это отдельный сервис на Go, задача которого как раз поддерживать SSE соединение и отправлять сообщения в браузеры. Сервис сидит в фоне, а браузеры подписываются на события через EventSource буквально в три строчки, как описано тут https://mercure.rocks/docs/getting-started
    Прелесть этого в том, что для того, чтобы отправить сообщение всем браузерам из кода на PHP, вам надо просто сделать обычный POST запрос на специальный адрес этого сервиса Mercure с телом самого сообщения и его id. Т.е. вам не надо делать никаких долгоживущих процессов на PHP, всё будет работать как раньше.

    Т.е. подытожим:
    - Браузеры пользователей подписываются на события в Mercure
    - Пользователь 1 отправляет текстовое сообщение обычным POST запросом на обычный PHP сайт.
    - PHP сайт получает этот POST запрос, определяет, что его надо отправить Пользователю 2, и отправляет соответствующее сообщение обычным POST запросом в сервис Mercure
    - Mercure отправляет сообщение Пользователю 2 через SSE, на которые он подписан.
    - Сообщение появляется у него на страничке
    Ответ написан
    5 комментариев
  • Как спарсить видео с whatsapp web?

    zkrvndm
    @zkrvndm
    Архитектор решений
    Сначала надо запустить видео, тогда вот эта ссылка заменится на blob и уже его качаешь.
    Ответ написан
    2 комментария
  • Держать громкость на одном уровне без изменения?

    Lastor
    @Lastor
    В чем сила, брат? В ньютонах.
    Главная сложность в том, что для каждого исходника требуются индивидуальные настройки.
    Амплитуда сигнала это одно, а воспринимаемая громкость - совсем другое.
    В индустрии это называют RMC, не понимая порой что это значит.
    Многие понимают RMS как воспринимаемую громкость в то время как это всего лишь среднеквадратичное значение уровня сигнала.
    Ухо (восприятие) работает несколько иначе. Как именно хорошо описано в учебнике Алдошиной
    А порой даже в рамках одного трека параметры требуется автоматизировать.
    В этом случае повезло. Получилось без автоматизации, но это просто случайность.
    Результат

    Я использовал плагины waves:
    Настройки
    Компрессор:
    64c6ff0ce3238046300781.png
    Лимитер:
    64c6ffb7d564f557449810.png
    Ответ написан
    Комментировать
  • Как сделать парсинг файла json средствами js?

    @Paramorez
    Fullstack Nodejs Developer
    В вашем JSON 'е нет ни поля id, ни Css стилей.

    А так, чтобы получить из них нужные вам поля. Достаточно просто импортировать файл JSON и пройтись по нему , допустим, через forEeach

    import myJson from './example.json'
    //Some code.....
    myJson.forEach(element => console.log(element.id));
    Ответ написан
    Комментировать
  • Как в Python получить список открытых позиций в Binance?

    Maksim_64
    @Maksim_64
    Data Analyst
    Обычно для работы с различными финансовыми данными используют такую структуру данных, как pandas датафрейм (некоторые api даже имеют параметр что то типа returned_type = 'dataframe' ). Там легко выбрать все что нужно, привести типы данных, ответить на любые вопросы например по какой монете самая большая открытая позиция и т.д, в общем все возможные манипуляции там есть + визуализации.

    Например представим нам прислали структуру как у тебя, я сократил (количество ключей для читабельности, а так не важно сколько их там)
    import pandas as pd
    import numpy as np
    data = [
        {'symbol': 'FTTBUSD', 'positionAmt': '0.001', 'entryPrice': '0.0', 'markPrice': '0.00000000'},
        {'symbol': 'ETHUSDT', 'positionAmt': '0.003', 'entryPrice': '1912.07', 'markPrice': '1911.37031373'},
        {'symbol': 'ALPHAUSDT', 'positionAmt': '0.002', 'entryPrice': '0.0', 'markPrice': '0.00000000'}
        ]
    df = pd.DataFrame(data=data, columns=['symbol','positionAmt'])
    df['positionAmt'] = df['positionAmt'].astype(float)
    print(df)

    Все мы выбрали только те ключи которые нам интересны параметр columns, если нужны все просто не указываем его. Теперь мы имеем таблицу с которой, мы можем делать все что угодно, начиная от любых расчетов, записей в различные форматы файлов или бд и даже визуализаций, например код df.plot(kind='bar', x='symbol', y='positionAmt'); Выведет вот такой график64b90126736ad454204003.png
    Это для демонстрации что всего в пару строк мы проходим путь от того что нам прислал binance до анализа.
    C датафреймом, будет легко и быстро задавать все интересующие вопросы.
    Ответ написан
    2 комментария
  • Как в Python получить список открытых позиций в Binance?

    dimonchik2013
    @dimonchik2013
    non progredi est regredi
    res = [x for x in getrisk if x['symbol'] in ('ETHUSDT', )]
    Ответ написан
    Комментировать
  • Как убрать воспроизведение нескольких аудио в html?

    Starina_js
    @Starina_js
    full-stack web dev
    Как-то так?
    Когда запускаем одно аудио, мы отключаем остальные, кроме текущего

    <audio id="audio1" src="music.mp3"></audio>
    <audio id="audio2" src="music2.mp3"></audio>

    const audioElements = Array.from(document.getElementsByTagName('audio'));
    
      const stopOtherAudio = (currentAudio) => {
        audioElements.forEach((audio) => {
          if (audio !== currentAudio) {
            audio.pause();
            audio.currentTime = 0;
          }
        });
      };
    
      audioElements.forEach((audio) => {
        audio.addEventListener('play', () => stopOtherAudio(audio));
      });
    Ответ написан
    1 комментарий
  • Не получается загрузить видео на VK через REST API и httpclient (java) - на POST сервер возвращает HTTP 406 Not Acceptable. В чем может быть проблема?

    @sherlock342342 Автор вопроса
    Проблема в неполной документации VK REST API. В ней ничего не сказано про то-что по каким-то причинам сервису по загрузке видео не нравится Transfer-Encoding: chunked

    Аналогичные сервисы VK по загрузке фото, аудио или документов пока не замечены в подобном.

    После модификации кода использующего java httpclient и указанием конкретного Content-Length (что выключает chunked режим) - все заработало.

    Надеюсь кому-то будет полезно.
    Ответ написан
    Комментировать
  • Верное у меня представление о разработке fullstack web приложений?

    AgentSmith72
    @AgentSmith72
    JS - это моё хобби
    Зависит от компании. бычно фронт занимается своими делами, а бэк своими.

    В лучшем случае, вы будете делать то, что говорит Тим-лид. Если нужно делать фронт на готовое от Бэка api, то значит в команде все хорошо. В редких случаях, фронту приходится мокать данные с Бэка, и работать со статичными данными.

    В худшем случае, это поддержка какого-нибудь сайта, где rest api и не пахнет.

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

    Проект по ссылке не столько не актуален, сколько ниже качества, чем нужно.

    Бэк часть:
    • Не рабочая концепция проекта.
    • Не профессиональная архитектура. Обычно используется архитектура вида валидатор-контроллер-сервис-репозиторий. В данном случае это был бы ProductsService (директория products + класс в ней ProductsService). Также в этом сервисе лежал бы класс репозитория этого сервиса, где хранились бы методы запросов к базе данных. Запрос бы попадал в валидатор, затем в контроллер, оттуда в сервис, а сервис бы вызывал соответствующий метод в репозитории.
    • База данных. Нет внешнего ключа у продукта к категориям.
    • Нет типизации. Это нужно для статичных анализаторов, проверяющих код на ошибки. Пример public string $name - как свойство класса. public function getById(int $id) - как метод класса
    • Нет валидации запроса. Например, что поля формы должны не содержать определённые символы, или быть конкретного типа. (Очистка от тэгов , используемая в модели, должна находится ещё до того как запрос попадёт в контроллер.)
    • Коды и текстовки раскиданы по разным файлам. Всё должно лежать в одном файле, классе, куда будут обращаться все классы за результатом.
    • Отсутствует MVC. В каждом файле создаётся новый класс, и дескриптор подключения, хотя это повторяющееся действие нужно вынести в отдельный класс.
    • Коды ответа. Не соответствуют действительности. При создании не нужно возвращать 200. 200 подразумевает, что в ответе есть дополнительные данные. Правильный вариант 201


    Фронт часть:
    • JQuery это рудимент.
    • Bootstrap не используется, если есть нормальный отдел разработки.
    • Стили страницы не разбиты на верхнюю и нижнюю части.
    • Не используется отложенная загрузка скриптов.
    • Вместо файлов JS для каждого типа CRUD достаточно одного JS файла
    • HTML код в JS. Загрузка JS это одна из самых затратных операций. Чем больше размер файла, тем выше время загрузки. Что сильно отщутимо на мобилке.
    • Везде используется POST запрос. В restfull api POST для создания, GET - для получения, DELETE - для удаления, Patch - для обновления части модели, PUT - Для обновления всех полей модели.

    Этого курса достаточно, чтобы сделать востребованный на рынке restfull api проект.
    Ответ написан
    6 комментариев