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#

Что еще не так?
  • Вопрос задан
  • 284 просмотра
Решения вопроса 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.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы