views:

378

answers:

3

Hi all,

I found a solution to add files in library.zip via: Extend py2exe to copy files to the zipfile where pkg_resources can load them.

I can access to my file when library.zip is not include the exe.

I add a file : text.txt in directory: foo/media in library.zip. And I use this code:

import pkg_resources
import zipfile
from cStringIO import StringIO

my_data = pkg_resources.resource_string(__name__,"library.zip")

filezip = StringIO(my_data)
zip = zipfile.ZipFile(filezip)
data = zip.read("foo/media/text.txt")

I try to use pkg_resources but I think that I don't understand something because I could open directly "library.zip".

My question is how can I do this when library.zip is embed in exe?

Best Regards

Jean-Michel

A: 

You shouldn't be using pkg_resources to retrieve the library.zip file. You should use it to retrieve the added resource.

Suppose you have the following project structure:

setup.py
foo/
    __init__.py
    bar.py
    media/
        image.jpg

You would use resource_string (or, preferably, resource_stream) to access image.jpg:

img = pkg_resources.resource_string(__name__, 'media/image.jpg')

That should "just work". At least it did when I bundled my media files in the EXE. (Sorry, I've since left the company where I was using py2exe, so don't have a working example to draw on.)

You could also try using pkg_resources.resource_filename(), but I don't think that works under py2exe.

Ian Stevens
A: 

Thank you but I found the solution

my_data = pkg_resources.resource_stream("__main__",sys.executable) # get lib.zip file
zip = zipfile.ZipFile(my_data)
data = zip.read("foo/media/doc.pdf") # get my data on lib.zip
file = open(output_name, 'wb')
file.write(data) # write it on a file
file.close()

Best Regards

jean-michel
A: 

I cobbled together a reasonably neat solution to this, but it doesn't use pkg_resources.

I need to distribute productivity tools as standalone EXEs, that is, all bundled into the one .exe file. I also need to send out notifications when these tools are used, which I do via the Logging API, using file-based configuration. I emded the logging.cfg fileto make it harder to effectively switch-off these notifications i.e. by deleting the loose file... which would probably break the app anyway.

So the following is the interesting bits from my setup.py:

LOGGING_CFG = open('main/resources/logging.cfg').read()

setup(
    name='productivity-tool',
    ...

    # py2exe extras
    console=[{'script': productivity_tool.__file__.replace('.pyc', '.py'),
              'other_resources': [(u'LOGGINGCFG', 1, LOGGING_CFG)]}],
    zipfile=None,
    options={'py2exe': {'bundle_files': 1, 'dll_excludes': ['w9xpopen.exe']}},
)

Then in the startup code for productivity_tool.py:

from win32api import LoadResource
from StringIO import StringIO
from logging.config import fileConfig
...

if __name__ == '__main__':
    if is_exe():
        logging_cfg = StringIO(LoadResource(0, u'LOGGINGCFG', 1))
    else:
        logging_cfg = 'main/resources/logging.cfg'
    fileConfig(logging_cfg)
    ...

Works a treat!!!

Darren