mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-20 15:04:54 +02:00
- a press on the mast of a selected signal grabbed the gizmo, whose up axis runs along the mast, and lifted the signal instead of moving it along the track; the gizmo gives way over a signal and while one is dragged - dragged beside its track, off every track, the signal follows the nearest place of the track it stands by instead of staying put - a drop away from any track, and a signal in a file the editor doesn't change, say so instead of doing nothing - a template without a //$e description of its own takes it from editor/templates/<its path in the scenery folder>; the header scripts write there with --sidecar, leaving the templates alone, so a check of the game files by the store doesn't take the descriptions away (the descriptions written into the templates on 8.10 and 11.10 were gone, and with them every signal and drive the editor knew)
92 lines
3.2 KiB
Python
92 lines
3.2 KiB
Python
"""Shared parts of the scripts writing //$e descriptions into the templates of the scenery."""
|
||
|
||
import os
|
||
import tarfile
|
||
import time
|
||
import zipfile
|
||
|
||
LINEMARK = '//$e'
|
||
BOM = ''
|
||
|
||
|
||
def load(path):
|
||
with open(path, 'rb') as source: # NOSONAR
|
||
return source.read()
|
||
|
||
|
||
def decode(raw, plain='cp1250'):
|
||
try:
|
||
text = raw.decode('utf-8')
|
||
encoding = 'utf-8' if raw.startswith(b'\xef\xbb\xbf') or max(raw, default=0) > 127 else plain
|
||
except UnicodeDecodeError:
|
||
text = raw.decode('cp1250')
|
||
encoding = 'cp1250'
|
||
return text, encoding
|
||
|
||
|
||
def body_lines(text):
|
||
return [line for line in text.splitlines() if not line.startswith(LINEMARK)]
|
||
|
||
|
||
def rewrite(info):
|
||
if info.get('header') is None:
|
||
return info['raw']
|
||
text = info['text']
|
||
eol = '\r\n' if '\r\n' in text else '\n'
|
||
bom = text.startswith(BOM)
|
||
if bom:
|
||
text = text[1:]
|
||
kept = [line for line in text.split(eol) if not line.startswith(LINEMARK)]
|
||
block = [LINEMARK + ' ' + line for line in info['header']]
|
||
out = eol.join(block + kept)
|
||
return ((BOM if bom else '') + out).encode(info['encoding'])
|
||
|
||
|
||
def options(argv, usage):
|
||
if len(argv) < 2:
|
||
print(usage)
|
||
return None
|
||
pack = argv[argv.index('--zip') + 1] if '--zip' in argv else None
|
||
return argv[1], '--write' in argv, pack
|
||
|
||
|
||
def sidecar(data, folder, entries):
|
||
"""the descriptions next to the game data instead of in the templates: <data>/editor/templates/<the path of the
|
||
template in the scenery folder>, the lines without the marks, which the editor reads for a template without its own;
|
||
the templates stay as they are, so a check of the game files by the store doesn't take the descriptions away"""
|
||
root = os.path.join(data, 'editor', 'templates', os.path.relpath(folder, 'scenery'))
|
||
written = 0
|
||
for file, info in entries:
|
||
if info.get('header') is None:
|
||
continue
|
||
target = os.path.normpath(os.path.join(root, file))
|
||
os.makedirs(os.path.dirname(target), exist_ok=True) # NOSONAR
|
||
with open(target, 'w', encoding='utf-8', newline='\n') as out: # NOSONAR
|
||
out.write('\n'.join(info['header']) + '\n')
|
||
written += 1
|
||
print('%d descriptions written beside the data in %s' % (written, root))
|
||
|
||
|
||
def write(data, folder, name, entries):
|
||
backup = os.path.join(data, 'editor_backup')
|
||
os.makedirs(backup, exist_ok=True) # NOSONAR
|
||
archive = os.path.join(backup, time.strftime(name + '_%Y%m%d_%H%M%S.tar'))
|
||
root = os.path.join(data, folder)
|
||
with tarfile.open(archive, 'w') as tar: # NOSONAR
|
||
for file, _ in entries:
|
||
tar.add(os.path.join(root, file), arcname=folder + '/' + file) # NOSONAR
|
||
for file, info in entries:
|
||
content = rewrite(info)
|
||
if content != info['raw']:
|
||
with open(os.path.join(root, file), 'wb') as out: # NOSONAR
|
||
out.write(content)
|
||
print('written, originals in', archive)
|
||
|
||
|
||
def pack(target, folder, entries):
|
||
with zipfile.ZipFile(target, 'w', zipfile.ZIP_DEFLATED) as out: # NOSONAR
|
||
for file, info in entries:
|
||
out.writestr(folder + '/' + file, rewrite(info))
|
||
print('packed into ' + target)
|
||
|