• Как через window сделать глобальную переменную const?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Через defineProperty()
    Object.defineProperty(window, "test", {
      value: "QnA"
    });
    Присвоение нового значения ошибки не вызовет, но и не сработает: сохранится указанное значение.
    проверки
    test = "X"; 
    test // "QnA"
    
    var test = "Y";
    test // "QnA"
    
    window.test = "Habr";
    test // "QnA"
    
    const test = "Z" // Uncaught SyntaxError: redeclaration of var test

    Тут не указано writable: false – оно и так по умолчанию false. И именно это свойство дескриптора определяет, можно ли назначить новое значение.

    Если переменная/свойство уже были декларированы ранее, то надо явно указать writable: false, чтобы свойство стало «константным».
    var test = "Habr";
    
    Object.defineProperty(window, "test", {
      value: "QnA",
      writable: false,
    });
    Ответ написан
    Комментировать
  • Как вывести строку по id php ?id=1?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Вопрос хороший, но здесь мы упираемся в главную беду пхп - ВСЕ учебники в интернете, и особенно видео - показывают как писать адов говнокод из прошлого века.

    1. Получение значения из адресной строки

    Чтобы получить значение переменной, которую передали в строке запроса (это то что после знака вопроса), надо обратиться к переменной $_GET

    То есть в данном случае можно написать $id = $_GET['id']. Имя получаемой переменной ($id) может быть любым и не обязательно совпадать с переданным значением. А вот в индекс массива $_GET разумеется надо писать именно то имя, которое в адресной строке. То есть если site.com/?id=1 то в $_GET['id'] будет значение 1.

    2. Валидация данных

    Далее очень желательно проверить, что мы в переменной получили то что хотели, а так же что мы вообще хоть что-то получили.

    Сначала надо проверить наличие в массиве $_GET нужного ключа. В данном случае это можно сделать с помощью оператора isset() (хотя вообще она для проверки наличия ключей в массивах не рекомендуется)
    Если для показа информации используем отдельную, специальную страницу, которая только занимается показом данных по айди, то после проверки на существование надо выдать ошибку.

    Затем, поскольку id может быть только целым числом больше нуля, то лучше проверить и это тоже и тоже выдать ошибку.

    3. Соединение с БД.

    в "config.php" должно быть написано не то что там сейчас а вот это (со своими параметрами подключения разумеется)
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $link = mysqli_connect($host, $user, $pass, $db_name);
    $link->set_charset("utf8mb4");


    4. SQL

    Запрос, который нам нужен, выглядит так:
    SELECT * FROM `product` WHERE id=1

    5. Выполнение запроса в РНР

    Но разумеется вместо 1 надо подставить значение переменной.
    Это самое сложное. Но надо один раз выучить и потом везде применять

    Важно, чтобы данные в БД всегда попадали отдельно от самого запроса. Это непреложное правило, которое надо соблюдать всегда.
    Для этого надо
    1. Заменить все переменные в запросе на специальные маркеры, которые называются плейсхолдеры или параметры, а по сути - просто знаки вопроса
    2. Подготовить запрос к исполнению с помощью функции prepare(). Эта функция принимает строку запроса и возвращает экземпляр специального класса stmt, с которым в дальнейшем и производятся все манипуляции
    3. Привязать переменные к запросу.
    4. Выполнить подготовленный ранее запрос с помощью с помощью execute()
    5. Получить результат запроса через get_result()
    6. и дальше конкретную строку из БД с помощью уже знакомой fetch_assoc


    В коде это будет так
    $sql = "SELECT * FROM `product` WHERE id=?";
    $stmt = $link->prepare($sql);
    $stmt->bind_param("s", $id);
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc();


    bind_param() принимает в качестве параметров все переменные, которые должны попасть в запрос, в том же самом порядке, в котором стоят плейсхолдеры в запросе. Но кроме того, сначала в этой функции должны быть указаны типы для всех переменных, в виде строки, где тип переменной обозначается одной буквой. То есть букв в этой строке должно быть ровно столько, сколько дальше будет переменных. К счастью, можно особо не париться с типами и для всех переменных указывать тип "s".

    6. Вывод данных.

    Важно понимать, что в момент вывода данных никакой работы с БД уже быть не должно!
    Должны быть только переменные РНР с уже полученными данными.
    Ответ написан
    1 комментарий
  • Как обработать двухфакторную аутентификацию Google?

    SoreMix
    @SoreMix
    yellow
    2fa гугла (да и не только) по сути является просто секретной строкой, на основе которой генерируются коды. Установите библиотеку pyotp, достаньте вашу секретную строку (обычно либо сайт ее даёт в чистом виде, для использования в других приложениях, либо даёт хотя бы возможность сгенерировать QR код, который можно прочитать камерой и из него достать строку; альтернативный вариант - открыть логи запросов в браузере и сгенерировать новый 2fa код, он где нибудь отразиться в истории), далее просто делаете
    import pyotp
    code = pyotp.TOTP(secret_line).now()

    И отправляете этот код через requests, точно так же как и отправляет обычный браузер
    Ответ написан
    1 комментарий
  • Сайт возвращает 404 при отправке запроса requests?

    delvin-fil
    @delvin-fil
    Crazy Linux-admin
    import requests
    
    headers = {
        'User-Agent': ('Mozilla/5.0 (Windows NT 6.0; rv:14.0) Gecko/20100101 '
                       'Firefox/14.0.1'),
        'Accept':
        'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language':
        'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3',
        'Accept-Encoding':
        'gzip, deflate',
        'Connection':
        'keep-alive',
        'DNT':
        '1'
    }
    
    url = f'https://subtitry.ru/'
    response = requests.post(url, headers=headers).text
    print(response)
    Ответ написан
    Комментировать
  • Как извлечь get параметр с url?

    @yaroslav1996
    Можно так.

    const query = new URLSearchParams(window.location.search);
    const {lpkay1, lpkay2} = Object.fromEntires(query.entries());
    Ответ написан
    Комментировать
  • Как дать боту возможность одновременно ждать сообщения от пользователя и проверять время для запланированного вывода сообщения?

    @Nameisconfidentialinfo
    За что-то даже платят
    посмотри в сторону apscheduler и celery.
    Apscheduler проще для бота, сам юзаю.
    Используй таски по-расписанию. Каждый день в 12 например, собирай инфу о погоде. В остальное время общайся с юзером
    Ответ написан
    Комментировать
  • Спавн бесконечного количества воркеров CELERY?

    @reqww Автор вопроса
    celery -A your_app_name worker --pool=solo -l info
    Ответ написан
    Комментировать
  • Как развернуть сайт на django?

    @pyHammer
    Очень вас понимаю, сам мучился неделю, когда только начал изучать.
    Но на самом деле ничего сложно тут нет, вот вам пошаговая инструкция:
    C на сайте хостера, услугам которого я пользуюсь и у меня там крутится около 5 проектов все на Django
    Но если что-то будет там не понятно, то вот кратное изложение:
    1. Подключаемся к хостингу по SSH
    2. Входим в контейнер Docker (пароль тот же что и для авторизации в ssh)
    $ ssh localhost -p222
    3. Создаем виртуальное окружение
    $ virtualenv --no-site-packages --python=/usr/bin/python3.6 --prompt="(env)" .env

    4. Активируем виртуальное окружение
    $ source .env/bin/activate
    5. Устанавливаем зависимости
    pip install -r requirements.txt
    Конечно у вас должен быть файл с зависимостями requirements.txt
    6. Создаем файл passenger_wsgi.py рядом с manage.py со следующим содержимыым
    # -*- coding: utf-8 -*-
    import os, sys
    sys.path.insert(0, '/home/u/username/username.beget.tech/project')
    sys.path.insert(1, '/home/u/username/username.beget.tech/.env/lib/python3.6/site-packages')
    os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings'
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()

    Тут нужно пояснить, путь /home/u/username/ формируется так /home/ первая буква имени вашего пользователя на beget / имя вашего пользователя на beget/.
    Домен username.beget.tech у вас будет доступен по умолчанию, его для тестов можно заюзать.
    7. Добавить домен в ALLOWED_HOSTS
    ALLOWED_HOSTS = ['username.beget.tech', ]
    8. Создаем файл .htaccess следующего содержания
    PassengerEnabled On
    PassengerPython /home/u/username/username.beget.tech/.env/bin/python

    9. Создаем папку tmp и в нем файл restart.txt
    $ mkdir tmp
    $ touch tmp/restart.txt

    Собственно после этих действий сайт должен завестись. Но не буду большим оптимистом, будут вылазить ошибки, так всегда когда что-то делаешь в первый раз. Но служба тех поддержки beget официально поддерживает сайты на python и вполне может помочь вам в развертывании сайта, а еще ответит на вопросы)
    Но если будут вопросы, можете и у меня спросить))
    Ответ написан
    4 комментария
  • Что такое Mixins?

    @kyern
    Быдлокодер без стажа
    Вот довольно хорошее объяснение mixin "на пальцах".
    Ответ написан
    Комментировать
  • Cмысл декоратора property?

    AtomKrieg
    @AtomKrieg
    Давай я поищу в Google за тебя
    "чем отличается первый метод от второго?"
    первый метод нужно вызывать без скобок и он прикидывается обычной переменной-членом класса, хотя внутри может быть спрятана весьма замысловатая логика. Обычный геттер, только более удобный.
    Ответ написан
    1 комментарий
  • Cмысл декоратора property?

    zymanch
    @zymanch
    python/django web-developer
    что, вкратце, делает декоратор property:
    class property(object):
        def __init__(self, fget):
            self.fget = fget
    
        def __get__(self, obj, type = None):
            return self.fget(obj)

    т.о., property реализован через дескриптор, в котором есть только getter
    в случае вашего примера, с точки зрения внутренней архитектуры python, разница будет такова:
    obj = Person()
    # obj.full_name_2()
    Person.__dict__['full_name_2'](obj)
    # obj.full_name_1
    Person.__dict__['full_name_1'].__get__(obj)

    зачем это нужно? для себя я вижу пока что только одну причину - отделить свойства класса от методов, позволив обращаться к "вычисляемым" свойствам не как к функциям, а как к атрибутам
    Ответ написан
    Комментировать
  • Cмысл декоратора property?

    @abcd0x00
    >>> class Person:
    ...     first_name = 'First'
    ...     last_name = 'Last'
    ...     
    ...     @property
    ...     def full_name_1(self):
    ...         return ' '.join([self.first_name, self.last_name])
    ...     
    ...     def full_name_2(self):
    ...         return ' '.join([self.first_name, self.last_name])
    ... 
    >>> p = Person()
    >>> p.full_name_1
    'First Last'
    >>> p.full_name_2()
    'First Last'
    >>> p.full_name_2
    <bound method Person.full_name_2 of <__main__.Person object at 0xb739a5ec>>
    >>>
    Ответ написан
    1 комментарий
  • Как в Notepad++ с помощью регулярных выражений выполнить замену?

    ForestAndGarden
    @ForestAndGarden
    Совершенствовать среду обитания.
    Найти: <param name=\"Диаметр колес\">(.*?)<\/param>

    Заменить на: <diametr>$1</diametr>
    Ответ написан
    Комментировать
  • Как взять значение из URL и запустить отсчёт от значения этого число до 0 (c помощью JS)?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Получить из адресной строки значение параметра sec см. URL.searchParams:
    const params = (new URL(document.location)).searchParams;
    const sec = Number(params.get('sec')) || 5; // или 5 по умолчанию

    Для обратного отсчёта лучше не вычитать раз в секунду единицу из счётчика, а сразу отметить момент в будущем, до которого в любой момент времени показывать оставшиеся секунды:
    const future = new Date();
    future.setTime(future.getTime() + 1000 * sec);

    Запустите таймер раз, скажем, в 200мс, и смотрите, сколько там осталось времени до момента future.
    const update = () => {
      const diff = future.getTime() - Date.now(); // сколько осталось, в миллисекундах
      const secondsLeft = Math.round(diff / 1000); // сколько осталось секунд
      if (diff <= 0) {
        // время прошло
      } else {
        // обновить в кнопке число оставшихся секунд
        // и вызвать это обновление снова через чуть-чуть:
        setTimeout(update, 200);
      }
    }
    
    update();
    Ответ написан
    2 комментария
  • Как в Notepad++ сгенерировать числа от 1 до 100 через python скрипт?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    editor.addText('\n'.join([str(x) for x in range(1,101)]))
    Ответ написан
    3 комментария
  • Как написать POST запрос с JSON и авторизацией на JavaScript?

    Seasle
    @Seasle Куратор тега JavaScript
    \( ゚ヮ゚)/
    Например так
    fetch(YOUR_URL, {
        method: 'POST',
        headers: {
            'Client-Id': YOUR_CLIENT_ID,
            'Api-Key': YOUR_API_KEY,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            offer_id: YOUR_OFFER_ID,
            product_id: YOUR_PRODUCT_ID,
            sku: YOUR_SKU
        })
    }).then(response => response.json()).then(data => {
        console.log(data);
    });
    Ответ написан
  • Фоновый импорт товаров из csv?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    Здравствуйте!
    Попробуйте следующее:
    Wp ALL Import + Woocommerce Addon
    Далее там есть возможность создавать крон задачу и тем самым выполнять импорт в "фоне"
    Ответ написан
    1 комментарий
  • Как вернуть SSL контекст по умолчанию?

    Ternick
    @Ternick
    По стандарту переменная ssl._create_default_https_context хранит в себе адрес функции create_default_context из того же модуля.

    Если я всё правильно понял, вопрос решается одной строчкой кода:
    ssl._create_default_https_context =  ssl.create_default_context
    Ответ написан
    Комментировать
  • Как сделать буквенные ID?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Просто 62-ричная позиционная система счисления с алфавитом 0-9a-zA-Z.
    <?php
    $alphabet62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    function toAlphabet(int $decimal, string $alphabet) : string
    {
      $base = mb_strlen($alphabet);
      $result = '';
      do {
        $pos = $decimal % $base;
        $result  = mb_substr($alphabet, $pos, 1) . $result;
        $decimal = intdiv($decimal, $base);
      } while ($decimal > 0);
      return $result;
    }
    var_dump(toAlphabet(12345678, $alphabet62));
    // string(4) "PNFQ"
    var_dump(toAlphabet(12345678, '0aA'));
    // string(15) "AaA0A00A000Aa00"
    Ответ написан
    1 комментарий
  • Как сделать буквенные ID?

    dyuriev
    @dyuriev
    A posteriori
    Не совсем понятно причем тут MySQL)

    10 цифр + 26 букв нижнего регистра + 26 букв вернего регистра - это 62 ричная система счисления.

    через php-gmp можно:

    <?php
      $id = '8472076875';
      echo 'original ' . $id . PHP_EOL;
    
      $id62 = gmp_strval(gmp_init($id, 10),62); // преобразовываем из 10-чной в 62-ричную
      echo '10to62   ' . $id62 . PHP_EOL;
    
      $id2 = gmp_strval(gmp_init($id62, 62),10); // преобразовываем из 62-ричной обратно в 10-чную
      echo '62to10   ' . $id2 . PHP_EOL;
    ?>
    результат:
    original 8472076875
    10to62   9FLyDD
    62to10   8472076875


    если буквы верхнего регистра не очень нужны, то можно через base_convert(); в 36-ричную для этой функции предел как раз 36)

    PS: преимущество gmp над реализацией метода через чистый php - феноменальная скорость. Тот же код что и в моем примере выше с 80-значным числом отработал на мобильно i5 меньше чем за пол секунды:
    $ time php test.php 
    original 23401823413248776823465324564823758974652738496528934652984564235623845698234763
    10to62   3BshjdyAzgaTxTiw0zqLRs58vHoKHBrnQmTdcE9NCRiEl
    62to10   23401823413248776823465324564823758974652738496528934652984564235623845698234763
    
    
    real	0m0.493s
    user	0m0.106s
    sys	0m0.108
    Ответ написан
    4 комментария