Недавно мне понадобилось добавить в некоторые материалы на сайте под управлением Joomla дополнительный текст — ссылку на Яндекс Диск с файлами. Ручное редактирование заняло бы слишком много времени, поэтому я решил автоматизировать задачу с помощью Python. В этой статье я расскажу, как это сделал.

Задача

Нужно было добавить в конец материалов из категории с ID 14 текст:

Текст для добавления:

<div class="yadisk">
    Файлы, связанные с материалом, перемещены на Яндекс Диск по ссылке <a href="https://disk.yandex.com/d/Y07UWUtIk5PE2w" target="_blank">https://disk.yandex.com/d/Y07UWUtIk5PE2w</a>
</div>

Но не во все материалы, а только в те, чьи заголовки содержат слова "landrover", "defender" или "td5". Например, статья "Land Rover Defender Td5 Maintenance" должна получить этот текст, а "General Car Tips" — нет.

Решение

Я написал простой скрипт на Python, который подключается к базе данных Joomla, проверяет заголовки и обновляет поле fulltext нужных материалов. Вот как это выглядело.

Шаг 1: Подготовка

Сначала я настроил подключение к базе данных Joomla через библиотеку pymysql. Конфигурацию (хост, пользователь, пароль, имя базы) я вынес в файл .env для безопасности:

import pymysql
import os
from dotenv import load_dotenv
import logging

load_dotenv()
logging.basicConfig(level=logging.INFO, format='%(asctime)s:%(levelname)s:%(message)s')

jedig_db_config = {
    'host': os.getenv('JEDIG_MYSQL_HOST'),
    'user': os.getenv('JEDIG_MYSQL_USER'),
    'password': os.getenv('JEDIG_MYSQL_PASSWORD'),
    'db': os.getenv('JEDIG_MYSQL_DATABASE'),
    'charset': 'utf8mb4',
    'cursorclass': pymysql.cursors.DictCursor
}

Префикс таблицы у меня был dyutb_, так как это Joomla на сайте jedig.ru.

Шаг 2: Определение текста

Я создал переменную с HTML-текстом, который нужно добавить:

yadisk_text = '''
<div class="yadisk">
    Файлы, связанные с материалом, перемещены на Яндекс Диск по ссылке <a href="https://disk.yandex.com/d/Y07UWUtIk5PE2w" target="_blank">https://disk.yandex.com/d/Y07UWUtIk5PE2w</a>
</div>
'''

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

Шаг 3: Основная функция

Вот сама функция, которая делает всю работу:

def append_yadisk_text():
    jedig_connection = pymysql.connect(**jedig_db_config)
    try:
        with jedig_connection.cursor() as jedig_cursor:
            jedig_cursor.execute("""
                SELECT `id`, `title`, `fulltext`
                FROM `dyutb_content`
                WHERE `catid` = 14
            """)
            items = jedig_cursor.fetchall()

            for item in items:
                title_lower = item['title'].lower()
                keywords = ['landrover', 'defender', 'td5']
                matches_keywords = any(keyword in title_lower for keyword in keywords)

                if matches_keywords:
                    current_fulltext = item['fulltext'] or ""
                    if not current_fulltext.strip().endswith(yadisk_text.strip()):
                        updated_fulltext = current_fulltext + yadisk_text
                        jedig_cursor.execute("""
                            UPDATE `dyutb_content`
                            SET `fulltext` = %s
                            WHERE `id` = %s
                        """, (updated_fulltext, item['id']))
                        logging.info(f"Добавлен текст в материал ID: {item['id']}, Заголовок: {item['title']}")

            jedig_connection.commit()
            logging.info("Обработка завершена.")
    except Exception as e:
        logging.error(f"Ошибка: {e}")
    finally:
        jedig_connection.close()

append_yadisk_text()

Что тут происходит:

  • Выбираю материалы из категории 14 с помощью SQL-запроса.
  • Для каждого материала проверяю заголовок на наличие ключевых слов.
  • Если заголовок подходит, добавляю текст в конец fulltext, но только если его там ещё нет (проверка через endswith).
  • Обновляю базу и логирую изменения.

Шаг 4: Запуск

Я сохранил скрипт в файл, например, add_yadisk.py, и запустил его:

python add_yadisk.py

В логах увидел, какие материалы обновились, например:

2025-03-11 10:15:23,456:INFO:Добавлен текст в материал ID: 123, Заголовок: Land Rover Defender Td5 Maintenance
2025-03-11 10:15:23,789:INFO:Обработка завершена.

Результат

Теперь в конце нужных материалов появился блок со ссылкой на Яндекс Диск. Например, если открыть статью "Land Rover Defender Td5 Maintenance" в админке Joomla или на сайте, внизу будет:

Файлы, связанные с материалом, перемещены на Яндекс Диск по ссылке https://disk.yandex.com/d/Y07UWUtIk5PE2w

При этом материалы без ключевых слов остались нетронутыми.

Вывод

Python оказался отличным инструментом для автоматизации работы с Joomla. Скрипт сэкономил мне часы ручного труда, а логи помогли убедиться, что всё прошло как надо. Если нужно будет что-то подобное сделать снова, я просто адаптирую этот код под новую задачу.

Полный код:

import pymysql
import os
from dotenv import load_dotenv
import logging

load_dotenv()
logging.basicConfig(level=logging.INFO, format='%(asctime)s:%(levelname)s:%(message)s')

jedig_db_config = {
    'host': os.getenv('JEDIG_MYSQL_HOST'),
    'user': os.getenv('JEDIG_MYSQL_USER'),
    'password': os.getenv('JEDIG_MYSQL_PASSWORD'),
    'db': os.getenv('JEDIG_MYSQL_DATABASE'),
    'charset': 'utf8mb4',
    'cursorclass': pymysql.cursors.DictCursor
}

jedig_table_prefix = 'dyutb_'

# Текст для добавления в конец материалов
yadisk_text = '''
<div class="yadisk">
    Файлы, связанные с материалом, перемещены на Яндекс Диск по ссылке <a href="https://disk.yandex.com/d/Y07UWUtIk5PE2w" target="_blank">https://disk.yandex.com/d/Y07UWUtIk5PE2w</a>
</div>
'''

def append_yadisk_text():
    jedig_connection = None
    try:
        jedig_connection = pymysql.connect(**jedig_db_config)
        with jedig_connection.cursor() as jedig_cursor:
            # Выбираем материалы из категории 14
            jedig_cursor.execute(f"""
                SELECT `id`, `title`, `fulltext`
                FROM `{jedig_table_prefix}content`
                WHERE `catid` = 14
            """)
            items = jedig_cursor.fetchall()

            for item in items:
                title_lower = item['title'].lower()
                keywords = ['landrover', 'defender', 'td5']
                matches_keywords = any(keyword in title_lower for keyword in keywords)

                if matches_keywords:
                    current_fulltext = item['fulltext'] or ""
                    # Проверяем, нет ли уже этого текста в конце
                    if not current_fulltext.strip().endswith(yadisk_text.strip()):
                        updated_fulltext = current_fulltext + yadisk_text
                        jedig_cursor.execute(f"""
                            UPDATE `{jedig_table_prefix}content`
                            SET `fulltext` = %s
                            WHERE `id` = %s
                        """, (updated_fulltext, item['id']))
                        logging.info(f"Добавлен текст Яндекс Диска в материал ID: {item['id']}, Заголовок: {item['title']}")
                    else:
                        logging.info(f"Текст Яндекс Диска уже присутствует в материале ID: {item['id']}, Заголовок: {item['title']}")

            jedig_connection.commit()
            logging.info("Обработка завершена.")

    except Exception as e:
        logging.error(f"Ошибка при выполнении скрипта: {e}")
    finally:
        if jedig_connection:
            jedig_connection.close()

if __name__ == "__main__":
    append_yadisk_text()