No module named ‘apt_pkg’

Всё началось неплохо (с)… А именно захотел я обновить apache на одном из серверов, Ubuntu на «наисвежайший». Сначала попытался собрать из исходных кодов, но как-то не срослось, а потому чуть погуглив, нашел что в репозитарии ondrej/apache2 всегда лежат уже собраные пакеты самой свежей версии. Казалось бы дело простое:

sudo add-apt-repository ppa:ondrej/apache2
sudo apt update
sudo apt upgrade apache2

Но не тут то было..Получил ошибку «No module named ‘apt_pkg'»:

Traceback (most recent call last):
  File "/usr/bin/add-apt-repository", line 5, in <module>
    import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'

При попытке доустановить пакет через pip3… вышло сообщение, что пакета то такого и нет..

pip install apt_pkg
ERROR: Could not find a version that satisfies the requirement apt_pkg (from versions: none)
ERROR: No matching distribution found for apt_pkg

Долго гуглил почему так, выяснить так и не смог. Единственное что удалось выяснить, что если запускать pip3 для python3.10, то пакет ищется и устанавливается. Возможно дело в как-то криво установленном python3.11 В результате, пришлось перейти обратно на python3.10

update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 2
update-alternatives --list python3

После чего всё штатно обновилось и установилось.

No module named 'apt_pkg'

RedOS 7.3: установка apache (httpd) из исходников

Задача: установить наисвежайшую версию веб сервера apache (установка apache из исходников). В репозитарии, версия довольно старая. Поэтому единственное решение — ставить apache из исходных кодов.

Сначала подготовлю ОС, для возможности компиляции (инструментарий):

dnf install libtool svn expat-devel pcre pcre-devel openssl-devel -y

Далее необходимо зайти на сайт https://httpd.apache.org/download.cgi и скачать необходимую версию с исходниками httpd и APR (https://apr.apache.org/download.cgi) и APR-UTIL

Распакуем их:

tar xfvj *.bz2

Далее необходимо переместить исходники APR в папку используемых библиотек httpd:

mv apr-1.7.4 httpd-2.4.59/srclib/apr
mv apr-util-1.6.3 httpd-2.4.59/srclib/apr-util

Теперь зайдём в получившуюся папку (например httpd-2.4.59), и попробуем собрать конфигурацию для компиляции:

./buildconf

И далее сконфигурируем установку:

./configure --enable-ssl --enable-so --with-mpm=event --with-included-apr --prefix=/usr/local/apache2

И наконец собираем бинарник и установим его по указанным выше путям:

make
make install
установка apache из исходников

Файл docx на основе шаблона при помощи PHP

Довольно часто встречается задача автоматизировать заполнение всяческих заявлений..ну например в бухгалтерию. Это вполне можно сделать и на PHP, позволив пользователю на форме веб страницы заполнить основные данные, а затем отдав ему уже сформированный на основе шаблона файл формата docx (файл docx на основе шаблона).

HTML часть может выглядеть примерно так:

<div class="rendered-form">
    <div class="formbuilder-text form-group field-position_at_work">
        <label for="position_at_work" class="formbuilder-text-label">Ваша должность
            <br>
        </label>
        <input type="text" placeholder="Наиглавнейший церемонимейстер" class="form-control" name="position_at_work" access="false" id="position_at_work">
    </div>
    <div class="formbuilder-text form-group field-me_unit">
        <label for="me_unit" class="formbuilder-text-label">Подразделение</label>
        <input type="text" placeholder="Отдел развития и автоматизации" class="form-control" name="me_unit" access="false" id="me_unit">
    </div>
    <div class="formbuilder-text form-group field-me_name">
        <label for="me_name" class="formbuilder-text-label">Ваше ФИО
            <br>
        </label>
        <input type="text" placeholder="Иванов Иван Иванович" class="form-control" name="me_name" access="false" id="me_name">
    </div>
    <div class="formbuilder-date form-group field-date_start">
        <label for="date_start" class="formbuilder-date-label">Дата начала отпуска
            <br>
        </label>
        <input type="date" class="form-control" name="date_start" access="false" id="date_start">
    </div>
    <div class="formbuilder-number form-group field-long_vacation">
        <label for="long_vacation" class="formbuilder-number-label">Продолжительность отпуска
            <br>
        </label>
        <input type="number" class="form-control" name="long_vacation" access="false" value="14" min="1" max="31" id="long_vacation">
    </div>
    <div class="formbuilder-button form-group field-button-1714717346219">
        <button onclick="CreateZay()" type="button" class="btn-success btn" name="button-1714717346219" access="false" style="success" id="button-1714717346219">Сформировать заявление
            <br>
        </button>
    </div>
</div>

На странице увидим что-то вроде:

файл docx на основе шаблона

На JavaScript создам функцию — обработчик нажатия на кнопку «Сформировать заявление». Функция делает запрос на сервер, а в ответ получает сформированный файл. Браузер автоматически предложит его сохранить.

function CreateZay(){
  console.log("--создаётся заявление..");  
  
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/sever/zayav.php', true);
        
        xhr.responseType = 'blob';     
        xhr.onload = function(e) {
            if (this.status == 200) {
                var link=document.createElement('a');
                link.href=window.URL.createObjectURL(this.response);                
                link.download="result.docx";
                link.click();
            }
            else {
                console.log(e);
            }
        };     
        var form_data = new FormData();        
        form_data.append("position_at_work", position_at_work.value);
        form_data.append("me_unit", me_unit.value);
        form_data.append("me_name", me_name.value);
        form_data.append("date_start", date_start.value);
        form_data.append("long_vacation", long_vacation.value);
        xhr.send(form_data);                 
};  

С клиентской частью (ну которая в браузере) разобрались. Теперь займемся сервером. Чтобы ничего не изобретать, воспользуемся пакетом phpoffice/phpword:

composer require phpoffice/phpword

Далее подготовим файл-шаблон. Можно в любом редакторе, который поддерживает расширение docx. В файле , те части которые мы хотим заменить, обрамляем ${имя_переменноя}, чтобы получилось например что-то вроде:

Далее, серверная часть, которая заполняет непосредственно сам шаблон:

<?php
$dt_start=strtotime($_POST["date_start"]);
$dt_end=strtotime($_POST["date_start"]." ".$_POST["long_vacation"]." day");

$newformat_start = date('d.m.Y',$dt_start);
$newformat_end = date('d.m.Y',$dt_end);

//var_dump($_POST);
//die();

require $_SERVER["DOCUMENT_ROOT"].'/sever/phpword/autoload.php';
//создаем класс
$phpWord = new  \PhpOffice\PhpWord\PhpWord(); 
$_doc = new \PhpOffice\PhpWord\TemplateProcessor('templates/template_1.docx');


$_doc->setValue('position_at_work', $_POST["position_at_work"]); 
$_doc->setValue('me_unit', $_POST["me_unit"]); 
$_doc->setValue('me_name', $_POST["me_name"]); 
$_doc->setValue('long_vacation', $_POST["long_vacation"]); 
$_doc->setValue('date_start', $newformat_start); 
$_doc->setValue('date_end', $newformat_end); 

$res=$_doc->saveAs($_SERVER["DOCUMENT_ROOT"]."/sever/tmp.docx");

$fil=file_get_contents($_SERVER["DOCUMENT_ROOT"]."/sever/tmp.docx");
echo $fil;

В результате мы получили файл docx. Другие статьи по PHP можете почитать здесь

Текущая дата в input

Задача: Необходимо чтобы при отображении на HTML странице поля input с типом дата, автоматически подставлялась определенная дата (заполнение текущей датой поля input). Ну например текущая+14 дней.

Решение: собственно без javascript тут не обойтись (ну если исключить вариант, что html генерируется на сервере, и соответственно заполняется поле value. Но это не наш метод (с)

HTML:

    <div class="formbuilder-date form-group field-date_start">
        <label for="date_start" class="formbuilder-date-label">Дата начала отпуска
            <br>
        </label>
        <input type="date" class="form-control" name="date_start" access="false" id="date_start">
    </div>

JavaScript:

<script>
    var date = new Date(Date.now());
    date.setDate(date.getDate() + 14);    
    date_start.value=date.toISOString().split("T")[0];
</script>    

Что тут интересного? Ну фактически мы пользуемся тем, что value у тега input с типом даты обязательно должно быть в формате гггг-мм-дд, т.е. ISO формат, а в ISO формат мы можем пере конвертировать дату полученную при помощи функции Date. Время нам не нужно, поэтому отсекаем его, разделив дату по разделителю «Т», и взяв первый элемент массива.

заполнение текущей датой поля input

Дата истечения сертификата

Неожиданно задался вопросом как проверить дату истечения сертификата сайта (дата истечения сертификата сайта), если нет возможности воспользоваться для этого онлайн-сервисами, а еще коварный AVP Kaspersky на ПК в браузере подменяет сертификат на свой. В самих файлах *.key *.crt визуально даты не наблюдаются.. Остаётся несколько вариантов: посмотреть по дате создания файла, и прибавить год ;). Ну так себе вариант. Второй, правильный — воспользоваться утилитой командной строки openssl. Примерно так:

openssl x509 -enddate -noout -in wiiudhioweu_2023.crt

Ну или если используете letsencrypt,то файл с расширением pem:

openssl x509 -enddate -noout -in fullchain3.pem

На выходе будет примерно так:

дата истечения сертификата сайта
1 2 3 4 5 6 56