Issues with file copy from p3d to disk

I’ve got some code that copies a file from my application directory to a user’s home directory using shutil.copy():

if base.appRunner:
      self.appFolder = base.appRunner.multifileRoot
    else:
      self.appFolder = os.path.dirname(__file__)
    self.dataFolder = os.path.join(Filename.getHomeDirectory().toOsSpecific(), 'Library', 'Application Support', 'BOT')
    self.sourceFile = os.path.join(self.appFolder, 'models.zip')
    self.destFile = os.path.join(self.dataFolder, 'models.zip')
    shutil.copy(self.sourceFile, self.destFile)

When I run using python, everything works, but when the application is packaged in a p3d it gives an IOError:

Traceback (most recent call last):
  File "/Users/rdb/pandaworker/panda3d-1.7.0/built_cmu/direct/p3d/AppRunner.py", line 411, in run
  File "/Users/rdb/pandaworker/panda3d-1.7.0/built_cmu/direct/task/Task.py", line 496, in run
  File "/Users/rdb/pandaworker/panda3d-1.7.0/built_cmu/direct/task/Task.py", line 454, in step
  File "/Users/rdb/pandaworker/panda3d-1.7.0/built_cmu/direct/showbase/Messenger.py", line 352, in __taskChainDispatch
  File "/Users/rdb/pandaworker/panda3d-1.7.0/built_cmu/direct/showbase/Messenger.py", line 410, in __dispatch
  File "/Users/rdb/pandaworker/panda3d-1.7.0/built_cmu/direct/p3d/AppRunner.py", line 493, in __startIfReady
  File "VFSImporter", line 153, in load_module
  File "/Users/aaron/Projects/MAW/BOT/BOTApps/test/ziptest.py", line 67, in <module>
    app = MyApp()
  File "/Users/aaron/Projects/MAW/BOT/BOTApps/test/ziptest.py", line 27, in __init__
    shutil.copy(self.sourceFile, self.destFile)
  File "/Users/rdb/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/shutil.py", line 88, in copy
  File "/Users/rdb/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/shutil.py", line 52, in copyfile
  File "/Users/rdb/pandaworker/panda3d-1.7.0/built_cmu/direct/stdpy/file.py", line 132, in __init__
IOError
:TaskManager: TaskManager.destroy()
:display: Closing osxGraphicsWindow
Successfully joined thread: 0
Failure on startup.

I’m assuming that this is an issue with copying a file from the virtual file system (reported as /mf on my machine). Is there a preferred panda method for copying files from the vfs?

I think it’s more likely that Filename.getHomeDirectory() returns a different value in the p3d environment. It should, because the p3d environment is primarily intended for use on web pages, where it is designed to be a special sandboxed environment that doesn’t normally interact with the wider directory structure.

If you really want to use the user’s actual home directory in your p3d file, you can try -c ‘keep_user_env=1’ on the packp3d command line.

David

The directory prints out the same whether the app is packed or not. Also, I can make this directory when the app is packed. Same IOError whether or not I use the keep_user_env setting and whether I use getHomeDirectory or another base directory like base.appRunner.rootDir.

Also, I tried opening the file and then writing it out, to avoid using shutil.copy:

    source_file = open(os.path.join(self.appFolder, 'models.zip'), 'r')
    dest_file = open(os.path.join(self.dataFolder, 'models.zip'), 'w')
    dest_file.write(source_file.read())
    source_file.close()
    dest_file.close()

This throws an IOError as well on the first open statement. (self.appFolder is the multifile root) Whether using shutil.copy or this method the IOError is generated in file.py (direct.stdpy.file).

Well, an IOError on open sure does sound like the path doesn’t exist, or it’s not readable for some reason.

Try:
print Filename(self.appFolder, ‘models.zip’).exists()
print vfs.exists(Filename(self.appFolder, ‘models.zip’))

The first line ought to print 0, because it checks only the actual hard disk, not the vfs, and presumably /mf doesn’t exist on your actual hard disk. But the second line ought to print 1, if the file is indeed within that folder on the vfs.

David

Ah, thanks, both are 0. Maybe my zip file isn’t getting included in the p3d? Is there a way to make that happen?

Note that you can use multify to inspect the contents of your p3d file. Zip files are not packaged by default, but you can add them with “-n zip” on the packp3d command line.

David

That worked. Thanks.