Working with files, inside p3d and not

Here is a handy code snippet for dealing with files in a way that works both inside a p3d file, and not.

This code does not rely on an instance of ShowBase (base), and provides a fix (joining more than 2 parts of a path) to direct.stdpy.file.join.

Honestly though, direct.stdpy.file.join just sticks ‘/’ between the parts, so ‘/’.join(*paths) would do the same thing, but faster (maybe that should be put in direct.stdpy.file.join).
os.path.join is much smarter, so you have to be carful when switching over to this join. Mainly, os.path.join deals with trailing /s at the end where this approach does not.

This code works for me, though my use case is not too strict. I’ve tried it on my macs, and inside a p3d file on Windows. I’ll admit its not feature complete, or very tidy, but its exposes some hard to find panda internals in an easy to use way. Stick it in a module in your project and use it instead of the equivalent os and os.path methods and it will still work after being packed into a p3d file.

import os
from direct.showbase.AppRunnerGlobal import appRunner
from direct.stdpy import file
from panda3d.core import Filename

def join(*paths):
    return reduce(file.join,paths)
listdir=file.listdir
walk=file.walk

_vfs=file._vfs

def isdir(path):
    """ Implements os.path.isdir over vfs. """
    return _vfs.isDirectory(Filename(path))
def exists(path):
    """ Implements os.path.exists over vfs. """
    return _vfs.exists(Filename(path))
def pathPrefix():
    if appRunner:
        return appRunner.multifileRoot
    else:
        return os.curdir