Позволяет ли Nautilus – настраиватель файлового менеджера – щелкнуть правой кнопкой и передать щелкнутый файл в функцию Python в качестве аргумента без ошибки?

Вопрос или проблема

Я работаю над созданием способа щелкнуть правой кнопкой мыши на файле .eml, запустить python для извлечения двух данных из него и вставки их в новый файл xlsx, а затем автоматически открыть этот файл xlsx.

Я бы попробовал этот код на Linux, но не знаю, выдаст ли он ошибку, которую я не смогу исправить.


Я сделал следующее на Mac, но выполнение прошло некорректно.

Один из методов заключается в том, чтобы использовать shell-скрипт в Automator, чтобы вызвать .py файл, который вызывает .ipynb файл.

Действие “Run Shell Script” вызвало ошибку: Когда я запускаю его на файле .eml, я вижу, “/Applications/Xcode.app/Contents/Developer/usr/bin/python3: can't open file '/users///Documents/run_notebook1.py': [Errno 1] Operation not permitted”

Когда я использую automator для тестирования скрипта с “get specified finder items”

Действие “Run Shell Script” вызвало ошибку: “Python path configuration:
PYTHONHOME = (не установлено)
PYTHONPATH = (не установлено)
program name="/Users//opt/anaconda3/bin/python"
isolated = 0
environment = 1
user site = 1
import site = 1
sys._base_executable="/Users//opt/anaconda3/bin/python"
sys.base_prefix = '/Users//opt/anaconda3'
sys.base_exec_prefix = '/Users//opt/anaconda3'
sys.platlibdir="lib"
sys.executable="/Users//opt/anaconda3/bin/python"
sys.prefix = '/Users//opt/anaconda3'
sys.exec_prefix = '/Users//opt/anaconda3'
sys.path = [
'/Users//opt/anaconda3/lib/python39.zip',
'/Users//opt/anaconda3/lib/python3.9',
'/Users//opt/anaconda3/lib/python3.9/lib-dynload',
]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

>Current thread 0x00000001ef41cc00 (most recent call first):
<no Python frame>
Traceback (most recent call last):
File "/users//Documents/run_notebook1.py", line 27, in <module>
run_notebook(eml_file)
File "/users//Documents/run_notebook1.py", line 16, in run_notebook
subprocess.run(command, shell=True,check=True)
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 528, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '/Users//opt/anaconda3/bin/jupyter nbconvert --to notebook --execute --inplace --ExecutePreprocessor.timeout=-1 /Users//Documents/process_email1.ipynb' returned non-zero exit status 1.

Является ли решение нахождение python39.zip?

sys.path = [
'/Users//opt/anaconda3/lib/python39.zip',
'/Users//opt/anaconda3/lib/python3.9',
'/Users//opt/anaconda3/lib/python3.9/lib-dynload'

Я запускал .py файл в терминале используя python3 file.py без проблем.

Shellscript в Automator (xcode установлен, поэтому я не нуждаюсь в указании директории python):

python3 /users//Documents/run_notebook1.py "$1"

Файл .py:

import sys
import subprocess
import os

def run_notebook(eml_file):
    # Путь к ноутбуку
    notebook_path="/Users//Documents/process_email1.ipynb"

    # Установить переменную окружения
    os.environ['EML_FILE_PATH'] = eml_file

    # Команда для запуска ноутбука с nbconvert
    command = f'/Users//opt/anaconda3/bin/jupyter nbconvert --to notebook --execute --inplace --ExecutePreprocessor.timeout=-1 {notebook_path}'

    # Запуск команды
    subprocess.run(command, shell=True,check=True)

# Убедиться, что путь к файлу передан как аргумент
if len(sys.argv) != 2:
    print("Использование: python run_notebook.py <path_to_eml_file>")
    sys.exit(1)

# Получить путь к EML файлу
eml_file = sys.argv[1]

# Запуск ноутбука с путем к EML файлу
run_notebook(eml_file)

Файл .ipynb

import email
import pandas as pd
import os
from email import policy
from email.parser import BytesParser
from datetime import datetime
import subprocess

# Получить путь к EML файлу из переменной окружения
eml_file = os.getenv('EML_FILE_PATH')

# Проверить, установлена ли переменная окружения
if not eml_file:
    raise ValueError("EML_FILE_PATH environment variable not set. Please pass the file path.")

# Функция для извлечения информации из файла email
def extract_eml_info(eml_file):
    # Разбор .eml файла
    with open(eml_file, 'rb') as f:
        msg = BytesParser(policy=policy.default).parse(f)

    # Извлечение имени файла (без расширения)
    file_name = os.path.splitext(os.path.basename(eml_file))[0]

    # Извлечение наиболее поздней даты переписки
    date_str = msg['date']
    if date_str:
        try:
            email_date = email.utils.parsedate_to_datetime(date_str)
        except Exception as e:
            email_date = None
    else:
        email_date = None

    return file_name, email_date

# Функция удаления информации о временной зоне из DataFrame
def remove_timezone_from_df(df):
    # Перебрать все столбцы
    for col in df.columns:
        if pd.api.types.is_datetime64_any_dtype(df[col]):
            # Удалить информацию о временной зоне, если это столбец даты
            df[col] = df[col].dt.tz_localize(None)
    return df

# Функция обработки EML файлов
def process_eml_files(eml_files):
    # Список для хранения извлеченных данных
    data = []

    for eml_file in eml_files:
        file_name, email_date = extract_eml_info(eml_file)
        data.append([file_name, email_date])

    # Создание DataFrame
    df = pd.DataFrame(data, columns=['File Name', 'Most Recent Date'])
    df = remove_timezone_from_df(df)

    # Запись в Excel
    output_file="output_eml_data.xlsx"
    df.to_excel(output_file, index=False, engine="openpyxl")
    print(f"Данные записаны в {output_file}")

    # Открытие вновь созданного Excel файла
    if os.name == 'nt':  # Для Windows
        os.startfile(output_file)
    elif os.name == 'posix':  # Для macOS/Linux
        subprocess.call(['open', output_file])

    return output_file

# Обработка указанного EML файла
process_eml_files([eml_file])

Ответ или решение

Чтобы определить, предоставляет ли файловый менеджер Nautilus возможность передавать файл в качестве аргумента в Python-функцию путем щелчка правой кнопкой мыши, необходимо рассмотреть возможности Nautilus, а также проблемы, с которыми вы столкнулись на macOS, запуская аналогичную задачу.

Возможности Nautilus

Nautilus (теперь известный как GNOME Files) предоставляет поддержку «сценариев», которые позволяют пользователям добавлять пользовательские действия для файлов через контекстное меню. Это означает, что вы можете создать скрипт, который выполнит Python-скрипт, передав ему путь к файлу в качестве аргумента. Чтобы реализовать это, вам следует выполнить следующие шаги:

  1. Создание скрипта: Создайте bash-скрипт, который будет вызываться при щелчке правой кнопкой на файл. Этот скрипт будет принимать путь к файлу в качестве аргумента и использовать его для вызова Python-скрипта.

    #!/bin/bash
    python3 /path/to/your_script.py "$1"
  2. Размещение скрипта: Поместите этот скрипт в папку ~/.local/share/nautilus/scripts/. После этого он будет доступен в меню «Scripts» при щелчке правой кнопкой мыши на файле.

  3. Запуск Python-скрипта: В Python-скрипте реализуйте необходимую логику обработки .eml файла и его последующей записи в Excel.

Решение проблем на платформе macOS

В проблемах, описанных вами, ошибка возникает из-за отсутствия разрешений на выполнение файлов или неверной конфигурации Python окружения. Чтобы устранить подобные ошибки:

  • Проверка прав доступа: Убедитесь, что вы предоставили достаточно прав доступа для выполнения ваших скриптов.
  • Корректная настройка PYTHONPATH: Убедитесь, что переменная окружения PYTHONPATH настроена правильно, чтобы система могла найти все необходимые модули, включая ‘encodings’.

Итог

Подводя итог, Nautilus действительно поддерживает возможность добавления пользовательского поведения через скрипты, что позволяет передавать файлы в Python-скрипт с контекстного меню без ошибок. Также важно тщательно настроить каждую деталь, связанную с правами доступа и путями в окружении, как на Linux, так и на macOS. Оптимально тестировать скрипты на платформе, для которой они предназначены, чтобы избежать несоответствий, связанных с различиями в операционных системах.

Оцените материал
Добавить комментарий

Капча загружается...