Overview

Path PyPoE/poe/file/ggpk.py
Version 1.0.0a0
Revision $Id: a3c76dfa17ccf43550a5e2ae1195a891d050c6a3 $
Author Omega_K2

Description

Support for reading .ggpk files.

A .ggpk file, namely content.ggpk, is a container containing a virtual directory and file contents. It is basically just packing the files together without compression.

Agreement

See PyPoE/LICENSE

Documentation

Public API

class PyPoE.poe.file.ggpk.GGPKFile(*args, **kwargs)[source]

Bases: PyPoE.poe.file.shared.AbstractFileReadOnly

Representation of a .ggpk file.

Variables:
__getitem__(item)[source]

Returns the specified node for the specified file path

Parameters:

item (str) – file path

Returns:

the DirectoryNode instance if found

Return type:

DirectoryNode

Raises:
__init__(*args, **kwargs)[source]

Initialize self. See help(type(self)) for accurate signature.

diff(other_ggpk, out_file=None)[source]

Creates a list of file paths that differ between this GGPKFile instance and another GGPKFile instance. This will take into account new, deleted and changed files.

Optionally writes this list to the specified out_file

Parameters:
  • other_ggpk (GGPKFile) – Other parsed GGPKFile instance to compare against
  • out_file (str or None) – File to optionally write the output to.
Returns:

  • list[str] – List of new file paths
  • list[str] – List of deleted file paths
  • list[str] – List of changed file paths (different hash)

Raises:
  • TypeError – if other_ggpk is not a GGPKFile instance
  • ValueError – if any of the GGPKFile instances are not parsed
  • ValueError – if any of the GGPKFile instances do not have their directory build
directory_build(parent=None)[source]

Rebuilds the directory or the specified DirectoryNode If the root directory is rebuild it will be stored in the directory object variable.

Parameters:parent (DirectoryNode or None) – parent DirectoryNode. If None generate the root directory
Returns:Returns the parent node or the root node if parent was None
Return type:DirectoryNode
Raises:ParserError – if performed without calling .read() first if offsets pointing to records types which are not FileRecord or DirectoryRecord
extract_dds(data, path_or_ggpk=None)[source]

Attempts to extract a .dds from the given data bytes.

.dds files in the content.ggpk may be compressed with brotli or may be a reference to another .dds file.

This function will take of those kind of files accordingly and try to return a file instead. If any problems arise an error will be raised instead.

Parameters:
  • data (bytes) – The raw data to extract the dds from.
  • path_or_ggpk (str or GGPKFile) – A str containing the path where the extracted content.ggpk is located or an GGPKFile instance
Returns:

the uncompressed, dereferenced .dds file data

Return type:

bytes

Raises:
  • ValueError – If the file data contains a reference, but path_or_ggpk is not specified
  • TypeError – If the file data contains a reference, but path_or_ggpk is of invalid type (i.e. not str or GGPKFile
  • ParserError – If the uncompressed size does not match the size in the header
  • brotli.error – If whatever bytes were read were not brotli compressed
get_read_buffer(file_path_or_raw, function, *args, **kwargs)

Will attempt to open the given file_path_or_raw in read mode and pass the buffer to the specified function. The function must accept at least one keyword argument called ‘buffer’.

Parameters:
  • file_path_or_raw (BytesIO | bytes | str) – file path, bytes or buffer to read from
  • args – Additional positional arguments to pass to the specified function
  • kwargs – Additional keyword arguments to pass to the specified function
Returns:

Result of the function

Return type:

object

Raises:

TypeError – if file_path_or_raw has an invalid type

is_parsed

Whether the directory has been built.

Returns:
Return type:bool
read(file_path_or_raw, *args, **kwargs)[source]

Reads the file contents into the specified path or buffer. This will also reset any existing contents of the file.

If a buffer or bytes was given, the data will be read from the buffer or bytes object.

If a file path was given, the resulting data will be read from the specified file.

Parameters:
  • file_path_or_raw (BytesIO | bytes | str) – file path, bytes or buffer to read from
  • args – Additional positional arguments
  • kwargs – Additional keyword arguments
Returns:

result of the read operation, if any

Return type:

object

Raises:

TypeError – if file_path_or_raw has an invalid type

PyPoE.poe.file.ggpk.extract_dds(data, path_or_ggpk=None)[source]

Attempts to extract a .dds from the given data bytes.

.dds files in the content.ggpk may be compressed with brotli or may be a reference to another .dds file.

This function will take of those kind of files accordingly and try to return a file instead. If any problems arise an error will be raised instead.

Parameters:
  • data (bytes) – The raw data to extract the dds from.
  • path_or_ggpk (str or GGPKFile) – A str containing the path where the extracted content.ggpk is located or an GGPKFile instance
Returns:

the uncompressed, dereferenced .dds file data

Return type:

bytes

Raises:
  • ValueError – If the file data contains a reference, but path_or_ggpk is not specified
  • TypeError – If the file data contains a reference, but path_or_ggpk is of invalid type (i.e. not str or GGPKFile
  • ParserError – If the uncompressed size does not match the size in the header
  • brotli.error – If whatever bytes were read were not brotli compressed

Internal API

General

class PyPoE.poe.file.ggpk.DirectoryNode(record, hash, parent)[source]

Bases: object

Variables:
__getitem__(item)[source]

Return the the specified file or directory path.

The path will accept valid paths for the current operating system, however I suggest using forward slashes ( / ) as they are supported on both Windows and Linux.

Since the each node supports the same syntax, all these calls are equivalent:

self['directory1']['directory2']['file.ext']
self['directory1']['directory2/file.ext']
self['directory1/directory2']['file.ext']
self['directory1/directory2/file.ext']
Parameters:item (str) – file path or file name
Returns:returns the DirectoryNode of the specified item
Return type:DirectoryNode
Raises:FileNotFoundError – if the specified item is not found
directories

Returns a list of nodes which belong to directories

Returns:list of DirectoryNode instances which contain a DirectoryRecord
Return type:list[DirectoryNode]
extract_to(target_directory)[source]

Extracts the node and its contents (including sub-directories) to the specified target directory.

Parameters:target_directory (str) – Path to directory where to extract to.
files

Returns a list of nodes which belong to files

Returns:list of DirectoryNode instances which contain a FileRecord
Return type:list[DirectoryNode]
get_parent(n=-1, stop_at=None, make_list=False)[source]

Gets the n-th parent or returns root parent if at top level. Negative values for n will iterate until the root is found.

If the make_list keyword is set to True, a list of Nodes in the following form will be returned:

[n-th parent, (n-1)-th parent, …, self]

Parameters:
Returns:

Returns parent or root DirectoryNode instance

Return type:

DirectoryNode

get_path()[source]

Returns the full path

Returns:Full path
Return type:str
name

Returns the name associated with the stored record.

Returns:name of the file/directory
Return type:str
search(regex, search_files=True, search_directories=True)[source]
Parameters:
  • regex (re.compile()) – compiled regular expression to use
  • search_files (bool) – Whether FileRecord instances should be searched
  • search_directories (bool) – Whether DirectoryRecord instances should be searched
Returns:

List of matching DirectoryNode instances

Return type:

list[DirectoryNode]

walk(function)[source]

Todo

function = None -> generator like os.walk (dir, [dirs], [files])

Walks over the nodes and it’s sub nodes and executes the specified function.

The function will be called with the following dictionary arguments:

Parameters:function (callable) – function to call when walking

Records

class PyPoE.poe.file.ggpk.GGPKRecord(container, length, offset)[source]

Bases: PyPoE.poe.file.ggpk.BaseRecord

The GGPKRecord is the master record of the file; it always contains two entries. First is the root directory, 2nd is a FreeRecord.

Variables:
  • offsets (list[int]) – List of offsets for records
  • _container (GGPKFile) – Parent GGPKFile
  • length (int) – Length
  • offset (int) – Starting offset in ggpk
read(ggpkfile)[source]

Read this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
write(ggpkfile)[source]

Write this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
class PyPoE.poe.file.ggpk.DirectoryRecord(*args, **kwargs)[source]

Bases: PyPoE.poe.file.ggpk.MixinRecord, PyPoE.poe.file.ggpk.BaseRecord

Represents a directory in the virtual GGPKFile file tree.

Variables:
  • _name (str) – Name of directory
  • _name_length (int) – Length of name
  • _entries_length (int) – Number of directory entries
  • hash (int) – SHA256 hash of file contents
  • _container (GGPKFile) – Parent GGPKFile
  • length (int) – Length
  • offset (int) – Starting offset in ggpk
name

Returns and sets the name of the file

If setting, it also takes care of adjusting name_length accordingly. Returns name of the file.

Returns:name of the file
Return type:str
read(ggpkfile)[source]

Read this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
write(ggpkfile)[source]

Write this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
class PyPoE.poe.file.ggpk.FileRecord(*args, **kwargs)[source]

Bases: PyPoE.poe.file.ggpk.MixinRecord, PyPoE.poe.file.ggpk.BaseRecord

Represents a file in the virtual GGPKFile file tree.

Variables:
  • _name (str) – Name of file
  • _name_length (int) – Length of name
  • hash (int) – SHA256 hash of file contents
  • data_start (int) – starting offset of data
  • data_length (int) – length of data
  • _container (GGPKFile) – Parent GGPKFile
  • length (int) – Length
  • offset (int) – Starting offset in ggpk
extract(buffer=None)[source]

Extracts this file contents into a memory file object.

Parameters:buffer (io.Bytes or None) – GGPKFile Buffer to use; if None, open the parent GGPKFile and use it as buffer.
Returns:memory file buffer object
Return type:io.BytesIO
extract_to(directory, name=None)[source]

Extracts the file to the given directory.

Parameters:
  • directory (str) – the directory to extract the file to
  • name (str or None) – the name of the file; if None use the file name as in the record.
name

Returns and sets the name of the file

If setting, it also takes care of adjusting name_length accordingly. Returns name of the file.

Returns:name of the file
Return type:str
read(ggpkfile)[source]

Read this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
write(ggpkfile)[source]

Write this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
class PyPoE.poe.file.ggpk.FreeRecord(container, length, offset)[source]

Bases: PyPoE.poe.file.ggpk.BaseRecord

Variables:
  • next_free (int) – offset of next FreeRecord
  • _container (GGPKFile) – Parent GGPKFile
  • length (int) – Length
  • offset (int) – Starting offset in ggpk
read(ggpkfile)[source]

Read this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
write(ggpkfile)[source]

Write this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance

Miscellaneous

class PyPoE.poe.file.ggpk.BaseRecord(container, length, offset)[source]

Bases: PyPoE.shared.mixins.ReprMixin

Variables:
  • _container (GGPKFile) – Parent GGPKFile
  • length (int) – Length
  • offset (int) – Starting offset in ggpk
read(ggpkfile)[source]

Read this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
write(ggpkfile)[source]

Write this record’s header for the given GGPKFile instance.

Parameters:ggpkfile (GGPKFile) – GGPKFile instance
class PyPoE.poe.file.ggpk.MixinRecord(*args, **kwargs)[source]

Bases: object

name

Returns and sets the name of the file

If setting, it also takes care of adjusting name_length accordingly. Returns name of the file.

Returns:name of the file
Return type:str
class PyPoE.poe.file.ggpk.DirectoryRecordEntry(hash, offset)[source]

Bases: PyPoE.shared.mixins.ReprMixin

Variables:
__init__(hash, offset)[source]
Parameters:
  • hash (int) – murmur2 32bit hash
  • offset (int) – offset in GGPKFile