diff options
-rw-r--r-- | pysquaredeal.py | 19 | ||||
-rw-r--r-- | squaredeal/__init__.py | 24 |
2 files changed, 37 insertions, 6 deletions
diff --git a/pysquaredeal.py b/pysquaredeal.py index 346e1a6..5d3fbc4 100644 --- a/pysquaredeal.py +++ b/pysquaredeal.py @@ -1,6 +1,18 @@ -import argparse, os, sys +import argparse, os, re, sys -from squaredeal import SquareDeal, SquareDealError, SquareDealPhase, generate_session_key +from squaredeal import SquareDeal, SquareDealError, SquareDealPhase, generate_session_key, validate_board_range_str + + +def board_range(arg_str): + ranges = [] + for range_str in arg_str.split(','): + range_match = re.match(r'^([0-9]+)x([0-9]+)$', range_str) + if range_match: + subrange_count = int(range_match.group(2)) + ranges += ['%d-%d' % (i*subrange_count+1, (i+1)*subrange_count) for i in range(0, int(range_match.group(1)))] + continue + ranges += [validate_board_range_str(range_str)] + return ','.join(ranges) argparser = argparse.ArgumentParser(prog='pysquaredeal.py') @@ -24,7 +36,7 @@ argparser_di.add_argument('delayed_information', metavar='DELAYED_INFO', help='d 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) -argparser_phase.add_argument('boards', metavar='NO_BOARDS', help='number of boards in each session', type=int) +argparser_phase.add_argument('boards', metavar='NO_BOARDS', help='number of boards in each session, also accepts syntax like "1-10,11-20,21-30", "3x7" is expanded to "1-7,8-14,15-21"', type=board_range) argparser_phase.add_argument('prefix', metavar='PREFIX', help='ouput file prefix ("#" will be replaced by session number)') argparser_phase.add_argument('description', nargs='?', metavar='DESCRIPTION', help='phase description') @@ -40,6 +52,7 @@ argparser_generate.add_argument('--reserve', action='store_true', help='generate arguments = argparser.parse_args() + # TODO: this should be an interface class, also rename SquareDeal to SQD or sth and this to SquareDeal if arguments.command == 'create': sd = SquareDeal() diff --git a/squaredeal/__init__.py b/squaredeal/__init__.py index 90f5f4f..1163bea 100644 --- a/squaredeal/__init__.py +++ b/squaredeal/__init__.py @@ -24,6 +24,15 @@ def parse_range_str(range_str, max_count): raise ValueError('Value out of range: %d' % (range_end)) return range(range_start, range_end) + +def validate_board_range_str(range_str): + if range_str.isdigit(): + return range_str + if re.match(r'^[0-9]+-[0-9]+$', range_str): + return range_str + raise ValueError('Invalid board range definition: %s' % (range_str)) + + class SquareDealError(Exception): pass @@ -41,8 +50,7 @@ class SquareDealPhase(object): if len(parts) != 4: raise SquareDealError('Malformed phase definition: %s' % (phasestr)) self.sessions = int(parts[0]) - # TODO: parse the funky a-b,c-d,e-f and NxM syntax - self.boards = int(parts[1]) + self.boards = parts[1] self.prefix = parts[2] self.info = parts[3] @@ -59,11 +67,21 @@ class SquareDealPhase(object): prefix += 'reserve' return prefix + def _parse_board_ranges(self, range_def): + ranges = [range_str.strip() for range_str in range_def.split(',')] + for range_str in ranges: + validate_board_range_str(range_str) + output_ranges = [] + while len(output_ranges) < self.sessions: + output_ranges += ranges + return output_ranges[0:self.sessions] + def generate(self, session, delayed_info, reserve=False): if not SquareDeal.BIGDEALX_PATH: raise SquareDealError('Path to BigDeal is not set, initialize SquareDeal.BIGDEALX_PATH value') delayed_info = base64.b64encode(delayed_info.encode('utf-8')).decode() sessions_to_generate = parse_range_str(session, self.sessions) + board_ranges = self._parse_board_ranges(self.boards) for session in sessions_to_generate: session_key = self.s_keys[session] session_key_len = int(len(session_key)/2) @@ -76,7 +94,7 @@ class SquareDealPhase(object): '-e', delayed_info, '-e', reserve_info, '-p', self._output_file_name(session+1, reserve), - '-n', str(self.boards)] + '-n', board_ranges[session]] subprocess.run(args) |