# vim: set et sta sw=4 ts=4 : # # This module exposes an "embeddedFs" object, that can # return file handles for either native use (extracted on first run) # or wasm (via preload-files). import std/os, std/files, std/paths, std/strformat, std/tempfiles type EmbeddedFS* = object EmbeddedFSError* = object of CatchableError let embeddedFs* = EmbeddedFS() when not defined( emscripten ): import zippy/tarballs const ROOT = Path( currentSourcePath() ).parentDir.parentDir.parentDir const RESOURCES = staticRead( $(ROOT / Path("resources.tgz")) ) let appname = extractFilename( getAppFileName() ) let dataDir = Path(getDataDir()) / Path( appname ) let confDir = Path(getConfigDir()) / Path( appname ) let confFile* = confDir / Path("config.ini") else: let dataDir = Path( "resources" ) let confDir = Path( "resources" ) let confFile* = confDir / Path("config.ini") proc path*( data: EmbeddedFS, path: string ): Path = ## Returns the path of an embedded file. return dataDir / Path( path ) proc `[]`*( data: EmbeddedFS, path: string ): string = ## Returns the contents of an embedded file. if not fileExists( data.path(path) ): raise newException( EmbeddedFSError, "No such file: {path}".fmt ) let f = open( $data.path(path) ) defer: f.close return f.readAll # TODO: version check, extract over old stuff # no-op if versions match # proc update*( e: EmbeddedFS ) = when not defined( emscripten ): createDir( getDataDir() ) createDir( $confDir ) # check existing path / version let ( tarball, path ) = createTempFile( "{appname}_resources_".fmt, ".tgz" ) tarball.write( RESOURCES ) tarball.close extractAll( path, $dataDir ) removeFile( path ) let source = dataDir / Path( "config.ini" ) if not fileExists( confFile ): moveFile( source, confFile )