Skip to content

Commit

Permalink
add manifest file creator for a modpack
Browse files Browse the repository at this point in the history
  • Loading branch information
drs-11 committed Oct 15, 2020
1 parent 3863e5e commit 1bb1a90
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 0 deletions.
1 change: 1 addition & 0 deletions copying.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ _the openage authors_ are:
| Merlin Stollenwerk | Mese96 | merlin-stollenwerk à past-development dawt de |
| 段清楠 Duan Qingnan | duanqn | duanqn_own_1 à yeah dawt net |
| Sean Ramey | SeanRamey | sramey40 à gmail dawt com |
| D R Siddhartha | drs-11 | siddharthadr11 à gmail dawt com |

If you're a first-time committer, add yourself to the above list. This is not
just for legal reasons, but also to keep an overview of all those nicknames.
Expand Down
4 changes: 4 additions & 0 deletions openage/convert/entity_object/conversion/modpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Defines a modpack that can be exported.
"""

from ...processor.export.modpack_manifest import ManifestFile
from ..export.data_definition import DataDefinition
from ..export.formats.modpack_info import ModpackInfo
from ..export.media_export_request import MediaExportRequest
Expand All @@ -22,6 +23,9 @@ def __init__(self, name):
# Definition file
self.info = ModpackInfo("", self.name + ".nfo", self.name)

# Manifest file
self.manifest = ManifestFile("", "manifest.toml")

# Data/media export
self.data_export_files = []
self.media_export_files = {}
Expand Down
4 changes: 4 additions & 0 deletions openage/convert/processor/export/modpack_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@ def export(modpack, args):

for metadata_file in metadata_files:
metadata_file.save(modpack_dir)

# Manifest file
modpack.manifest.save(modpack_dir)

109 changes: 109 additions & 0 deletions openage/convert/processor/export/modpack_manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Copyright 2020-2020 the openage authors. See copying.md for legal info.

"""
Create a manifest file for a modpack
"""
import hashlib
import os
import toml

from ....util.fslike.path import Path
from ...entity_object.export.data_definition import DataDefinition


class ManifestFile(DataDefinition):
"""
Used for creating a manifest file for a modpack.
"""

HASHING_FUNCTION = 'sha3_256'
BUF_SIZE = 32000

def __init__(self, targetdir, filename):
super().__init__(targetdir, filename)

def dump(self, exportdir):
"""
Returns the manifest file content in TOML format.
:param exportdir: directory which contains exported modpack
:type exportdir: ....util.fslike.path.Path
"""

output_dict = {}

info_table = {"info": {}}
info_table["info"].update({"hash": self.HASHING_FUNCTION})

output_dict.update(info_table)

hash_values_table = {'hash-values': {}}
for file in self._bfs_directory(exportdir):
hash_val = self._get_file_hash(file)
relative_path = os.path.relpath(str(file), str(exportdir))
hash_values_table['hash-values'].update({hash_val: relative_path})

output_dict.update(hash_values_table)

output_str = "# openage autogenerated modpack integrity check\n\n"
output_str += toml.dumps(output_dict)

return output_str

def save(self, exportdir):
"""
Saves the contents of the manifest file in the exported
directory containing the modpack.
:param exportdir: Relative path to the export directory.
:type exportdir: ....util.fslike.path.Path
"""
if not isinstance(exportdir, Path):
raise ValueError("util.fslike.path.Path expected as filename, not %s" %
type(exportdir))

output_dir = exportdir.joinpath(self.targetdir)
output_content = self.dump(exportdir)

# generate human-readable file
with output_dir[self.filename].open('wb') as outfile:
outfile.write(output_content.encode('utf-8'))

def _bfs_directory(self, root):
"""
Traverse the given directory in breadth-first way.
:param root: The directory to traverse.
:type root: ....util.fslike.path.Path
"""

dirs = [root]
while dirs:
next_level = []
for directory in dirs:
for item in directory.iterdir():
item_path = directory.joinpath(item)
if item_path.is_dir():
next_level.append(item_path)
else:
yield item_path
dirs = next_level

def _get_file_hash(self, file_path):
"""
Returns the hash value of a given file.
:param file_path: Path of the given file.
:type file_path: ....util.fslike.path
"""
# set the hashing algorithm
hashf = hashlib.new(self.HASHING_FUNCTION)

with file_path.open_r() as f_in:
while True:
data = f_in.read(self.BUF_SIZE)
if not data:
break
hashf.update(data)

return hashf.hexdigest()

0 comments on commit 1bb1a90

Please sign in to comment.