Python and py2app help

Hi Folks,

I would like to use a python script from a xojo desktop app
so I thought of building an app from the python script and then call it from xojo.

the python script is here :

py2app asks for an entry point, and I can’t find it…
it should be somescript.py
and to use this script I must use : python -m extract_msg my_msg_document
so where is the entry point ? or how to fill the setpu.py file for py2app ?

thanks.

I do not know that this will help you, but I am throwing it out there on the off chance it might. Several years ago, I wrote various Xojo programs that called Python scripts. It worked beautifully. This is basically how I did it:

Const PATH_PYTHON3 = "/Users/koala/anaconda3/bin/python"
// get the path to the script that you want to run and place it in thePathname
Var thePathname As String 


Var pythonShell As New Shell
pythonShell.Mode = MODE_SYNCHRONOUS // the default anyway
pythonShell.Execute(PATH_PYTHON3, thePathname)

Var theAnswer As String
theAnswer = pythonShell.Result // Contains the contents of the output buffer
  1. PATH_PYTHON3 is just the path to where Python lives on your particular machine
  2. thePathname is just the full path to the Python script you want to run

You can pass string arguments to the Python script as in the below

Const SP As String = " "
Var argument1, argument2 As String
argument1 = "whatever"
argument2 = "somethingelse"
pythonShell.Execute(PATH_PYTHON3, thePathname  + SP + argument1 + SP + argument2)

Now my knowledge about all this is very rusty so I defer to others who might chime in. I am not confident that I actually understand your question since I do not know what py2app is. :woozy_face:

2 Likes

py2app is a mac application that converts a python script into a desktop app.
py2exe does the same on windows.

https://py2app.readthedocs.io/en/latest/

Have you tried Platypus?

1 Like

This looks interesting. But why not call the python script directly from Xojo with bundled Python framework, like Robert describes. What is the benefit of having an extra app doing (most likeley) the same?

1 Like

I want to have one app, with the python script inside, and not having the user to install scripts.

it seems to be the same problem: it asks for a python script to create the app, and I don’t know where the starting point is in all the folders…

well well, after a small hour with chatgpt, I have a working python script that calls the extract_msg library…

from extract_msg import Message
import os
import sys

def extract_msg_info(msg_file_path):
    msg = Message(msg_file_path)

    # Save the message as a text file
    save_text_path = os.path.splitext(msg_file_path)[0] + "_message.txt"
    with open(save_text_path, "w", encoding="utf-8") as text_file:
        text_file.write(f"Subject: {msg.subject}\n")
        text_file.write(f"Sender: {msg.sender}\n")
        text_file.write(f"Recipients: {msg.to}\n")
        text_file.write(f"CC: {msg.cc}\n")
        text_file.write(f"Date: {msg.date}\n")
        text_file.write(f"Body:\n{msg.body}\n")

    print("Message saved as text file:", save_text_path)

    # Save attachments in a folder
    save_attachments_path = os.path.splitext(msg_file_path)[0] + "_attachments"
    if not os.path.exists(save_attachments_path):
        os.makedirs(save_attachments_path)

    for attachment in msg.attachments:
        attachment_path = os.path.join(save_attachments_path, attachment.long_filename)
        with open(attachment_path, "wb") as f:
            f.write(attachment.data)

        print("Attachment saved:", attachment_path)

if __name__ == "__main__":
    # Check if at least one command line argument is provided
    if len(sys.argv) < 2:
        print("Usage: python script.py file1.msg file2.msg ...")
        sys.exit(1)

    # Extract information from each provided .msg file
    msg_files = sys.argv[1:]
    for msg_file_path in msg_files:
        extract_msg_info(msg_file_path)

and the setup.py file to make py2app work as I need !
impressive as I don’t know a lot of python …

from setuptools import setup

APP = ['extract_msg_script.py']
DATA_FILES = [
    ('extract_msg', ['extract_msg/__init__.py']),
]
OPTIONS = {
    'argv_emulation': True,
}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

So @Jean-Yves_Pochez this results then in a mac command line app that is installable and co tains the required python dependencies to (in your case) extract elements from Outlook messages - that correct ?

this makes a clickable desktop app with all needed inside, and it extracts .msg outlook files.
I still have a problem as the app looks universal, but only works on apple silicon
I have to fix that.
you drag msg files onto the app icon and it extracts the files.

you can also call the app using the command line with
name-of-the-app.app/Content/Macos/name-of-the-app

ok I’ve done the compil again, on an intel mac. and the compiled app now works on intel and silicon mac.