• Как можно отследить отправку сообщения с изображением, аудио, стикером и видео?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    Для отслеживания сообщений с изображениями, аудио, стикерами и видео в VK, вы можете использовать метод vk.updates.on('message_new'), который срабатывает каждый раз, когда на страницу пользователя или группы приходит новое сообщение. Для определения типа сообщения и наличия прикрепленных файлов вы можете проверять содержимое объекта message в обработчике события.

    В приведенном вами примере, сообщение является обычным текстовым сообщением, однако имеет прикрепленное изображение в массиве attachments. Вы можете проверять наличие элементов в этом массиве и определять тип прикрепленного файла по полю type, которое указано в каждом элементе массива. Например, тип изображения будет указан как "type": "photo" , а тип аудиозаписи будет "type": "audio"
    Ответ написан
  • Не передаются данные eel, что делать?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    Проблема возникает из-за того, что вызов askdirectory() блокирует выполнение программы до тех пор, пока пользователь не выберет папку. Однако в вашем коде используется асинхронный JavaScript, поэтому нужно использовать асинхронную версию askdirectory().

    Для этого можно использовать библиотеку aioify для превращения синхронных функций в асинхронные. Также нужно обновить метод downdir() для использования асинхронной версии askdirectory().
    from tkinter.filedialog import askdirectory
    from getpass import getuser
    
    import eel
    from aioify import aioify
    
    
    eel.init("web")
    
    downloadsPath = f"C:/Users/{getuser()}/Downloads"
    
    # Превращаем функцию askdirectory() в асинхронную
    async_askdirectory = aioify(askdirectory)
    
    
    @eel.expose
    async def downdir():
        # Используем асинхронную версию askdirectory()
        path = await async_askdirectory()
        return path
    
    
    @eel.expose
    def defaultPath():
        return downloadsPath
    
    
    eel.start("index.html", size=(500, 800), mode="chrome")

    async function defaultPath(){
        let path = await eel.defaultPath()();
    
        document.getElementById('tpd').textContent = path;
    }
    
    defaultPath();
    
    
    async function downloadsDir(){
        let dpath = await eel.downdir()();
        return await dpath;
    }
    
    
    document.querySelector('#dl').onclick = async () => {
        let path = await downloadsDir();
        document.getElementById('tpd').textContent = path;
        console.log("+")
    }

    Теперь вызов askdirectory() не блокирует выполнение программы, и вы можете выбрать папку в диалоговом окне.
    Ответ написан
  • Почему не загружается страница React?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    Возможно, проблема заключается в необходимости оптимизации вашего кода. Например, при каждом изменении в любом компоненте вам нужно проверять, что компоненты, которые зависят от этой измененной переменной, должны перерендериваться или нет. Для того, чтобы сделать это эффективно, вам может понадобиться переместить свою функцию `getSourse` на уровень выше, чтобы она не вызывалась при каждом изменении состояний.

    Кроме того, вам необходимо учесть состояние компонента `PeoplePage` между переходами. Если вы вернетесь на страницу `PeoplePage`, то предыдущие данные будут сохранены, и при переходе на другой `PersonPage` без перезагрузки страницы они будут использоваться заново. Чтобы решить эту проблему, вы можете очистить данные в компоненте `PeoplePage` при каждом переходе на другой `PersonPage`.

    Например, это можно сделать, обнулив значения `prevPage`, `nextPage`, `people` и `counterPage` в компоненте `PeoplePage` с помощью вычисляемых свойств, и они будут автоматически обновляться при каждом переходе на другую страницу. Вот пример такого кода:

    const PeoplePage = () => {
      const query = useQueryParams()
      const queryPage = query.get('page')
    
      const [prevPage, setPrevPage] = React.useState(null)
      const [nextPage, setNextPage] = React.useState(null)
      const [people, setPeople] = React.useState([])
      const [counterPage, setCounterPage] = React.useState(parseInt(queryPage || "1"))
      const [error, setError] = React.useState(false)
    
      React.useEffect(() => {
        setPeople([])
        setError(false)
        const getSourse = async (url) => {
          const res = await getApiJson(url);
          if (res?.results) {
            const peopleList = res.results.map(({ name, url }) => {
              const id = getId(url)
              const img = getFullSourse(id)
              return ({ name, url, img })
            })
            setPrevPage(res.previous)
            setNextPage(res.next)
            setPeople(peopleList)
            setCounterPage(getPeoplePageId(url))
          } else {
            setError(true)
          }
        }
        getSourse(API_PEOPLE + queryPage)
      }, [queryPage])
    
      ...


    Это позволит вам сохранить текущие данные, необходимые для отображения на странице `PeoplePage`, и перейти на другую страницу `PersonPage` без проблем. Также будьте уверены, что вы используете ключи для каждого элемента, возвращаемого в компонентах, чтобы React мог инвалидировать этот элемент при его удалении.
    Ответ написан
  • Как решить проблему с fslightbox.js?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    Проблема, вероятно, связана с тем, что ресурсы не успевают загрузиться до инициализации библиотеки, из-за чего иногда фото открываются как ссылки. Попробуйте перенести инициализацию fslightbox.js в событие window.onload.
    Например:
    window.onload = function() {
      setTimeout(function() {
        const lightbox = new FsLightbox();
      }, 500);
    }

    Еще одна возможная причина проблемы - это конфликт с другими скриптами на странице. Проверьте, нет ли ошибок в консоли браузера и попробуйте отключить другие скрипты на странице, чтобы выяснить, не вызывает ли один из них конфликт.
    Если вы все еще столкнетесь с проблемой, то можете рассмотреть другие библиотеки, например, Magnific Popup, PhotoSwipe или LightGallery. Они поддерживают предварительную загрузку изображений и поддерживают видео в галерее.
    Ответ написан
    Комментировать
  • Как заставить ACF repeater работать в категории?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    У вас проблема с получением данных из повторителя ACF на странице категории товаров. Возможно, это связано с тем, что на странице категории переменная $post не определена корректно, поэтому `get_field()` получает неправильный идентификатор записи.
    Попробуйте передать в функцию `get_field()` правильный идентификатор категории, например используя функцию `get_queried_object_id()`, которая вернет ID текущей страницы категории.
    Вот пример:
    $category_id = get_queried_object_id();
    $anchors = get_field('anchors', 'product_cat_'.$category_id);
    Ответ написан
  • Как корректно запустить SocketIO + Django?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    Проблема с тем, что запросы по Rest API уходят в бесконечное ожидание может быть вызвана таймаутом воркера.

    Для устранения этой проблемы, можно увеличить таймаут воркера gunicorn до того времени, сколько он может выполнять запросы и ожидать ответы перед тем, как отвалиться.

    Для этого нужно добавить следующий параметр к команде запуска gunicorn:
    --timeout 600

    Это установит таймаут в 600 секунд (10 минут).

    Также, для предотвращения блокировки воркера gunicorn другими задачами, можно увеличить количество воркеров до нескольких.

    Как пример, можно выполнить команду запуска gunicorn следующим образом:
    gunicorn --workers 4 --timeout 600 --keep-alive 25 --reload -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 config.wsgi:application --bind 0.0.0.0:8000 --log-level debug

    В этой команде были добавлены опции для увеличения количества воркеров (--workers), установки времени ожидания ответа сервера (--keep-alive) и повторного запуска воркера при изменении кода приложения (--reload).

    Таким образом, после добавления этих настроек, воркеры gunicorn должны продолжать корректную работу с Socket.IO и Rest API.

    Для сброса диалога введите команду /context

    Jarvis IT Assistant, [14/03/23 18:53]
    Сообщение "Server initialized for gevent" означает, что сервер успешно проинициализирован с использованием gevent - библиотеки для сетевого программирования событийного типа в Python.

    Если вы запускаете как restapi, так и сокеты на одном и том же порту и в одном и том же процессе, то это может привести к ошибкам. Хотя Python может обрабатывать оба типа соединений, запуск веб-сервера для restapi и сокетов в одном процессе не является хорошей практикой.

    Рекомендуется запускать сервер для restapi и сервер для сокетов в отдельных процессах, используя разные порты для каждого из них. Также вы можете использовать различные фреймворки для создания рест-интерфейса и работы с сокетами.

    Если вы используете Flask, то вы можете использовать библиотеку Flask-SocketIO для работы с веб-сокетами. Эта библиотека позволяет запускать сервер для сокетов и сервер для rest api с использованием одного порта.

    Независимо от того, как вы реализуете свой сервер, важно понимать, что правильная настройка и использование механизмов управления соединениями является важной частью разработки веб-приложений. Таким образом, следует уделять внимание этой теме, чтобы обеспечить эффективную работу веб-сервера и избежать возможных ошибок и проблем на этапе эксплуатации.
    Ответ написан
    Комментировать
  • Здравствуйте! Надо вытянуть значение атрибута content в контейнере span по class="js-basket-total-cost" .,Как это вывести на стр.?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    Вам необходимо получить элемент с классом `js-basket-total-cost` и внутри него найти элемент с атрибутом `content`. Для этого можно использовать метод `querySelector` и `getAttribute`.

    Пример кода:

    const totalCostSpan = document.querySelector('.js-basket-total-cost span[itemprop="price"]');
    const totalCost = totalCostSpan.getAttribute('content');
    
    console.log(totalCost);


    В этом примере мы сначала получаем элемент `span` с классом `js-basket-total-cost`. Затем мы находим вложенный элемент `span` с атрибутом `itemprop="price"` и получаем значение его атрибута `content`, используя метод `getAttribute`. В итоге, в переменной `totalCost` будет содержаться "6130.00".
    Ответ написан
    Комментировать
  • Почему условие не работает?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    Вероятно, проблема заключается в том, что вы пытаетесь сравнивать строку, которая содержит и "pass=" и "123". Чтобы получить только значение пароля из запроса, вы можете использовать метод `FormValue` из `gin.Context`, который позволяет получить значение формы по имени поля:

    router.POST("/login", func(c *gin.Context) {
        pass := c.PostForm("pass")
    
        if pass != "123" {
            fmt.Println("Ошибка")
            return
        }
    })


    Теперь при получении значения пароля в переменную `pass` уже не будет содержаться "pass=" - будет только сам пароль.
    Ответ написан
    Комментировать
  • Как правильно расположить такие элементы?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    Самый простой способ. Вставь картинку
    Ответ написан
  • Как создать родительский массив объектов с определенными свойствами на основе другого массива объектов?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    // Исходный массив объектов
    const sourceArray = [
    {name: 'John', age: 25},
    {name: 'Jane', age: 30},
    {name: 'Bob', age: 20}
    ];

    // Создание родительского массива объектов с определенными свойствами
    const parentArray = sourceArray.map(item => ({ name: item.name, ageGroup: item.age > 25 ? 'adult' : 'young' }));

    во это проверь
    Ответ написан
    1 комментарий
  • Можно ли сделать интерфейс адаптивным, не переписывая весь CSS через media query's?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    вместо px ставь % и использую гриды или флексы. Я использую такой подходт :)
    Ответ написан