belkin_aa
@belkin_aa
Обо мне: https://clck.ru/ge9cs

Почему не отрабатывает субпроцесс?

Пытался запустить субпроцесс в скрипте:
path_ppt_file = '/home/...../3.pptx'
cmd = f'unoconv -v -f pdf {path_ppt_file}'
rezult = subprocess.run(shlex.split(cmd), stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT,
                                  shell=True, encoding='utf-8')
print(rezult )

Результат принта:
CompletedProcess(args=['unoconv', '-v', '-f', 'pdf', '/home/...../3.pptx'], returncode=127, stdout='-v: 1: -v: unoconv: not found\n')

причем, если самому выполнить команду в терминале:
unoconv -v -f pdf /home/..../3.pptx
То конвертация пройдет успешно. В чем может быть причина?

UPD:
Зашел в настройки сервиса приложения, закоментил:
Environment="PATH=/home/USER_FOLDER/APP_FOLDER/myprojectenv/bin"

Прописал:
Environment="PATH=/home/USER_FOLDER/APP_FOLDER/myprojectenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

Теперь стало такое выдавать:
'unoconv -v -f pdf /home/...../3.pptx', 'dop': (CompletedProcess(args=['unoconv', '-v', '-f', 'pdf', '/home/....../3.pptx'], returncode=1, stdout="unoconv: Cannot find a suitable pyuno library and python binary combination in /usr/lib/libreoffice\nERROR: No module named 'uno'\n\nunoconv: Cannot find a suitable office installation on your system.\nERROR: Please locate your office installation and send your feedback to:\n       http://github.com/dagwieers/unoconv/issues\n")


UPD:
1) Версия питона:
- вирт.окружения: 3.9.12 (не конвертирует)
- по умолчанию в системе: 3.9.15 (которая конвертирует)
2) Запустил скрипт с командой:
UNOPATH=/usr/bin/libreoffice /usr/bin/python3.9 /usr/bin/unoconv unoconv -v -f pdf /home/..../file.pptx

Переменная rezult вернула:
(CompletedProcess(args=['UNOPATH=/usr/bin/libreoffice', '/usr/bin/python3.9', '/usr/bin/unoconv', 'unoconv', '-v', '-f', 'pdf', '/home/..../file.pptx'], returncode=0, stdout='')

Файл не сконвертировался
3) Если активировать виртуальное окружение в консоли и запустить эту команду, то вернет:
unoconv: RuntimeException during import phase:
Office probably died. Unsupported URL <unoconv>: "type detection failed"

В итоге зависает и приходится нажимать Ctrl+Z и в каталоге создается файл: .~lock.file.pdf#

Что еще не так?
  • Вопрос задан
  • 345 просмотров
Решения вопроса 1
belkin_aa
@belkin_aa Автор вопроса
Обо мне: https://clck.ru/ge9cs
Спасибо всем кто отозвался, проблема решена. Оставлю обработчик конвертера, может кому пригодится. Да, может, он не идеален, но зато работает. Если кто предложит лучше, то я только за.

import os

def made_folder(verify_path):
    if os.path.exists(verify_path):
        pass
    else:
        os.mkdir(verify_path)
    return verify_path

class Convert_file():
    def __init__(self, name_file, ubuntu_pref, path_to_folder, exception='pdf'):
        # === У всех путей не указывать в конце слеш! ===
        # name_file = имя файла без расширения
        # exception - расширение файла
        # ubuntu_pref - путь Ubuntu до проекта
        # path_to_folder - расположение относительно проекта

        self.name_file = name_file
        self.exception = exception
        self.ubuntu_pref = ubuntu_pref
        self.path_to_folder = path_to_folder

        self.process_convert = []

        self.is_convert_pptx_in_pdf = False
        self.is_convert_pdf_in_png = False

        self.url_first_slide = f'{self.path_to_folder}/covers/slide-01.png'

        self.cover_presentation = 'static/wait.gif'

    def convert_pptx_to_pdf(self, exception_file='pptx'):
        # === КОНВЕРТАЦИЯ pptx  В pdf ===
        path_ppt_file = f'{self.path_to_folder}/{self.name_file}.{exception_file}'

        # -- Проверка есть ли PPTX-файл ---
        if self.is_file(path_ppt_file):
            # -- Проверка есть ли PDF-файл ---
            path_pdf = f'{self.path_to_folder}/{self.name_file}.pdf'
            if self.is_file(path_pdf):
                self.add_proc_conv(proc='conv ppt',
                                   rezult=False,
                                   cmd='pdf-file created')
            else:
                cmd = f'/usr/bin/soffice soffice --headless "-env:UserInstallation=file:///tmp/LibreOffice_Conversion_{self.name_file}" --convert-to pdf:writer_pdf_Export --outdir {self.path_to_folder} {self.ubuntu_pref}/{path_ppt_file}'
                child = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE,
                                        stderr=subprocess.STDOUT, encoding='utf-8', shell=False)
                start_time = datetime.datetime.now()
                while True:
                    curent_time = datetime.datetime.now()
                    if child.returncode == 0:
                        break
                    delta = curent_time - start_time
                    if delta.total_seconds() > 15:
                        break
                    if child.poll() == 0:
                        break
                if child.returncode == 0:
                    self.add_proc_conv(proc='conv ppt',
                                       rezult=True,
                                       cmd=cmd,
                                       dop=(child, child.returncode))
                    self.is_convert_pptx_in_pdf = True
                else:
                    self.add_proc_conv(proc='conv ppt',
                                       rezult=False,
                                       cmd=cmd)
        else:
            self.add_proc_conv(proc='conv ppt',
                           rezult=False,
                           cmd='no ppt-file',
                           dop=path_ppt_file)

    def convert_pdf_to_png(self):
        work_dir = f'{self.ubuntu_pref}/{self.path_to_folder}'

        path_pdf_file = f'{self.path_to_folder}/{self.name_file}.pdf'
        # --- ПРОВЕРКА есть ли PDF-файл ---
        if self.is_file(path_pdf_file):
            if self.is_file(self.url_first_slide):
                self.add_proc_conv(proc='conv pdf',
                                   rezult=False,
                                   cmd='first png-file created',
                                   dop=self.url_first_slide)
                self.cover_presentation = self.url_first_slide
            else:
                convert_dir_png = made_folder(verify_path=f'{work_dir}/covers')
                cmd = f'gs -sDEVICE=pngalpha -o {convert_dir_png}/slide-%02d.png -r96 {work_dir}/{self.name_file}.pdf'
                child = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT, encoding='utf-8',
                                     shell=False)
                start_time = datetime.datetime.now()
                while True:
                    curent_time = datetime.datetime.now()
                    if child.returncode == 0:
                        break
                    delta = curent_time - start_time
                    if delta.total_seconds() > 15:
                        break
                    if child.poll() == 0:
                        break
                if (child.returncode == 0) and (self.is_file(self.url_first_slide)):
                    self.add_proc_conv(proc='conv pdf',
                                       rezult=True,
                                       cmd=cmd,
                                       dop=child)
                    self.is_convert_pdf_in_png = True
                    self.cover_presentation = self.url_first_slide
                else:
                    self.add_proc_conv(proc='conv pdf',
                                       rezult=False,
                                       cmd=cmd)
        else:
            self.add_proc_conv(proc='conv pdf',
                               rezult=False,
                               cmd='no pdf-file')

    def add_proc_conv(self, proc, rezult, cmd, dop=None):
        self.process_convert.append(
            {proc: rezult,
             'cmd': cmd,
             'dop': dop
             }
        )

    def is_file(self, path_to_file_full):
        # == Проверяет есть ли файл ==
        return os.path.exists(path_to_file_full)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
hint000
@hint000
у админа три руки
попробуйте прописать полный путь, что-то типа
cmd = f'/usr/bin/unoconv -v -f pdf {path_ppt_file}'

ну или где у вас находится unoconv
Ответ написан
onegreyonewhite
@onegreyonewhite
Уберите shell=True. Если вам конкретно не нужен шелл, то уберите его.

UPD: просто shell оборачивает ваш вызов в условный /bin/sh -c ваши аргументы. В некоторых случаях, это добавляет боли. Если не работаете переменными окружения и условным bashrc, то это вам точно не нужно.

UPD2: Ну вам же пишет конкретные вещи сервис, что он ищет либру в конкретном месте. Сделайте линк.
Ответ написан
@DinoZavr2
Пропишите полный путь, а так же попробуйте изменить синтаксис значения переменной rezult.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
SpectrumData Екатеринбург
от 150 000 до 250 000 ₽
Гринатом Москва
от 150 000 ₽
DIGITAL SECTOR Краснодар
от 150 000 до 250 000 ₽
17 июл. 2024, в 17:54
30000 руб./за проект
17 июл. 2024, в 17:11
1200 руб./в час
17 июл. 2024, в 16:22
15000 руб./за проект