From 89fb49d37d1d5763b231eb312cd640daa7cbc591 Mon Sep 17 00:00:00 2001 From: emkael Date: Wed, 17 Jan 2024 23:25:23 +0100 Subject: Bringing Python port up to date with original interface in 2.x version: - generate SQK only on publish - do not explicitly mark SQD as published - separate field for DI value The SquareDeal and SquareDealPhase objects are now also mostly DTO, without complex modifications through internal methods, only input/output operations are their internal methods. --- pysquaredeal.py | 43 ++++++++++++++++++------ squaredeal/__init__.py | 90 ++++++++++++++++++++++++-------------------------- 2 files changed, 76 insertions(+), 57 deletions(-) diff --git a/pysquaredeal.py b/pysquaredeal.py index 7630772..a81e16f 100644 --- a/pysquaredeal.py +++ b/pysquaredeal.py @@ -1,6 +1,6 @@ import argparse, os, sys -from squaredeal import SquareDeal, SquareDealError +from squaredeal import SquareDeal, SquareDealError, SquareDealPhase, generate_session_key argparser = argparse.ArgumentParser(prog='pysquaredeal.py') @@ -19,8 +19,8 @@ argparser_create.add_argument('--delayed-information', required=False, metavar=' argparser_name = subparsers.add_parser('set_name', help='edit event name') argparser_name.add_argument('event_name', metavar='EVENT_NAME', help='event name (description)') -argparser_di = subparsers.add_parser('set_di', help='edit event delayed information (or its value)') -argparser_di.add_argument('delayed_information', metavar='DELAYED_INFO', help='(description of) delayed information') +argparser_di = subparsers.add_parser('set_di', help='edit event delayed information (its description ahead of time)') +argparser_di.add_argument('delayed_information', metavar='DELAYED_INFO', help='description of delayed information') argparser_phase = subparsers.add_parser('add_phase', help='add event phase') argparser_phase.add_argument('sessions', metavar='NO_SESSIONS', help='number of sessions in phase', type=int) @@ -30,6 +30,9 @@ argparser_phase.add_argument('description', nargs='?', metavar='DESCRIPTION', he argparser_publish = subparsers.add_parser('publish', help='mark SQD as published') +argparser_di = subparsers.add_parser('set_dv', help='edit event delayed information (its value)') +argparser_di.add_argument('delayed_information', metavar='DELAYED_INFO', help='value of delayed information') + argparser_generate = subparsers.add_parser('generate', help='generate PBN') argparser_generate.add_argument('phase', nargs='?', type=int, metavar='PHASE', help='phase number, if empty, all phases will be generated') argparser_generate.add_argument('session', nargs='?', type=int, metavar='SESSION', help='session number, if empty, all sessions will be generated') @@ -41,36 +44,54 @@ if arguments.command == 'create': sd = SquareDeal() sd.name = arguments.event_name sd.delayed_info = arguments.delayed_information - sd.tofile(arguments.sqd_file, sqkpath=arguments.sqk_file) + sd.tofile(arguments.sqd_file) elif arguments.command == 'set_name': sd = SquareDeal() sd.fromfile(arguments.sqd_file, sqkpath=arguments.sqk_file) if sd.published: raise SquareDealError('Cannot change name: event already published') sd.name = arguments.event_name - sd.tofile(arguments.sqd_file, sqkpath=arguments.sqk_file) + sd.tofile(arguments.sqd_file) elif arguments.command == 'set_di': sd = SquareDeal() sd.fromfile(arguments.sqd_file, sqkpath=arguments.sqk_file) + if sd.published: + raise SquareDealError('Cannot change delayed information description: event already published') sd.delayed_info = arguments.delayed_information - sd.tofile(arguments.sqd_file, sqkpath=arguments.sqk_file) + sd.tofile(arguments.sqd_file) +elif arguments.command == 'add_phase': + sd = SquareDeal() + sd.fromfile(arguments.sqd_file, sqkpath=arguments.sqk_file) + if sd.published: + raise SquareDealError('Cannot add phase: event already published') + sdphase = SquareDealPhase() + sdphase.sessions = arguments.sessions + sdphase.boards = arguments.boards + sdphase.prefix = arguments.prefix + sdphase.info = arguments.description + sd.phases.append(sdphase) + sd.tofile(arguments.sqd_file) elif arguments.command == 'publish': sd = SquareDeal() sd.fromfile(arguments.sqd_file, sqkpath=arguments.sqk_file) + if sd.published: + raise SquareDealError('Cannot mark as published: event already published') if not sd.name: raise SquareDealError('Cannot mark as published: event name is not set') if not sd.delayed_info: raise SquareDealError('Cannot mark as published: delayed information is not set') if not sd.phases: raise SquareDealError('Cannot mark as published: no phases are defined') + for sdphase in sd.phases: + sdphase.s_keys = [generate_session_key() for s in range(0, sdphase.sessions)] sd.published = True sd.tofile(arguments.sqd_file, sqkpath=arguments.sqk_file) -elif arguments.command == 'add_phase': +elif arguments.command == 'set_dv': sd = SquareDeal() sd.fromfile(arguments.sqd_file, sqkpath=arguments.sqk_file) - if sd.published: - raise SquareDealError('Cannot add phase: event already published') - sd.add_phase(arguments.sessions, arguments.boards, arguments.prefix, description=arguments.description) + if not sd.published: + raise SquareDealError('Cannot set delayed information value: event not published') + sd.delayed_value = arguments.delayed_information sd.tofile(arguments.sqd_file, sqkpath=arguments.sqk_file) elif arguments.command == 'generate': if arguments.bigdealx_path is None: @@ -80,4 +101,6 @@ elif arguments.command == 'generate': sd.fromfile(arguments.sqd_file, sqkpath=arguments.sqk_file) if not sd.published: raise SquareDealError('Cannot generate PBN files: event info is not marked as published') + if not sd.delayed_value: + raise SquareDealError('Cannot generate PBN files: delayed information value not set') sd.generate(arguments.phase, arguments.session, reserve=arguments.reserve) diff --git a/squaredeal/__init__.py b/squaredeal/__init__.py index 0e445f6..e44f780 100644 --- a/squaredeal/__init__.py +++ b/squaredeal/__init__.py @@ -1,6 +1,9 @@ import base64, hashlib, os, random, shutil, string, subprocess +def generate_session_key(): + return ''.join(random.choices(string.ascii_letters + string.digits, k=60)) + class SquareDealError(Exception): pass @@ -21,7 +24,6 @@ class SquareDealPhase(object): self.boards = int(parts[1]) self.prefix = parts[2] self.info = parts[3] - self.s_keys = [None] * self.sessions def tostring(self): return ':'.join([str(self.sessions), str(self.boards), self.prefix, self.info or '']) @@ -47,7 +49,7 @@ class SquareDealPhase(object): '-e', reserve_info, '-p', self._output_file_name(session+1, reserve), '-n', str(self.boards)] - subprocess.run(args, cwd=os.path.realpath(SquareDeal.BIGDEALX_PATH)) + subprocess.run(args) class SquareDeal(object): @@ -57,6 +59,7 @@ class SquareDeal(object): def __init__(self): self.name = '' self.delayed_info = '' + self.delayed_value = '' self.hash = '' self.phases = [] self.published = False @@ -72,9 +75,10 @@ class SquareDeal(object): self.name = linecontents elif linetype == 'DI': self.delayed_info = linecontents + elif linetype == 'DV': + self.delayed_value = linecontents elif linetype == 'KH': self.hash = linecontents - elif linetype == 'PU': self.published = True elif linetype == 'SN': phase = SquareDealPhase() @@ -82,35 +86,38 @@ class SquareDeal(object): self.phases.append(phase) else: raise SquareDealError('Unrecognized tag %s on line %d' % (linetype, idx)) - if sqkpath is None: - sqkpath = self._deduce_sqk_path(sqdpath) - try: - with open(sqkpath, encoding=encoding) as sqkfile: - contents = [line.strip() for line in sqkfile.readlines()] - except FileNotFoundError: - raise SquareDealError('Unable to locate SQK file for %s' % (sqdpath)) - for line in contents: - if not line.strip(): - continue - lineparts = line.split(':') - if len(lineparts) != 2: - raise SquareDealError('Malformed SQK line: %s' % (line)) - session = lineparts[0].split(',') - if len(session) != 2: - raise SquareDealError('Malformed SQK line: %s' % (line)) - phase_no = int(session[0]) - session_no = int(session[1]) + if self.published: + for phase in self.phases: + phase.s_keys = [None] * phase.sessions + if sqkpath is None: + sqkpath = self._deduce_sqk_path(sqdpath) try: - self.phases[phase_no-1].s_keys[session_no-1] = lineparts[1] - except IndexError: - raise SquareDealError('Session %s from SQK not declared in SQD' % (lineparts[0])) - for ph_idx, phase in enumerate(self.phases): - for s_idx, s_key in enumerate(phase.s_keys): - if s_key is None: - raise SquareDealError('Session %d,%d missing a key in SQK' % (ph_idx+1, s_idx+1)) - sqk_hash = self._get_file_hash(sqkpath) - if sqk_hash != self.hash: - raise SquareDealError('SQK hash mismtach: %s in SQD, % actual' % (self.hash, sqk_hash)) + with open(sqkpath, encoding=encoding) as sqkfile: + contents = [line.strip() for line in sqkfile.readlines()] + except FileNotFoundError: + raise SquareDealError('Unable to locate SQK file for %s' % (sqdpath)) + for line in contents: + if not line.strip(): + continue + lineparts = line.split(':') + if len(lineparts) != 2: + raise SquareDealError('Malformed SQK line: %s' % (line)) + session = lineparts[0].split(',') + if len(session) != 2: + raise SquareDealError('Malformed SQK line: %s' % (line)) + phase_no = int(session[0]) + session_no = int(session[1]) + try: + self.phases[phase_no-1].s_keys[session_no-1] = lineparts[1] + except IndexError: + raise SquareDealError('Session %s from SQK not declared in SQD' % (lineparts[0])) + for ph_idx, phase in enumerate(self.phases): + for s_idx, s_key in enumerate(phase.s_keys): + if s_key is None: + raise SquareDealError('Session %d,%d missing a key in SQK' % (ph_idx+1, s_idx+1)) + sqk_hash = self._get_file_hash(sqkpath) + if sqk_hash != self.hash: + raise SquareDealError('SQK hash mismtach: %s in SQD, % actual' % (self.hash, sqk_hash)) def _deduce_sqk_path(self, sqdpath): sqkpath = list(os.path.splitext(sqdpath)) @@ -146,31 +153,20 @@ class SquareDeal(object): sqkpath = self._deduce_sqk_path(sqdpath) if make_backups: self._make_backups(sqdpath, sqkpath) - self._write_session_keys(sqkpath) + if self.published: + self._write_session_keys(sqkpath) sqd_contents = [] sqd_contents.append('TN %s\n' % (self.name or '')) - sqd_contents.append('KH %s\n' % (self.hash)) sqd_contents.append('DI %s\n' % (self.delayed_info or '')) + if self.published: + sqd_contents.append('DV %s\n' % (self.delayed_value or '')) for phase in self.phases: sqd_contents.append('SN %s\n' % (phase.tostring())) if self.published: - sqd_contents.append('PU\n') + sqd_contents.append('KH %s\n' % (self.hash)) with open(sqdpath, 'w') as sqdfile: sqdfile.writelines(sqd_contents) - def _generate_session_key(self): - return ''.join(random.choices(string.ascii_letters + string.digits, k=60)) - - def add_phase(self, session_count, board_count, file_prefix, description=None): - phase = SquareDealPhase() - phase.sessions = session_count - phase.boards = board_count - phase.prefix = file_prefix - phase.info = description - for i in range(0, phase.sessions): - phase.s_keys.append(self._generate_session_key()) - self.phases.append(phase) - def generate(self, phase, session, reserve=False): phases_to_generate = range(0, len(self.phases)) if phase is None else [phase-1] for phase in phases_to_generate: -- cgit v1.2.3