furmeet_events_self/timetable_parser/cli.py

113 lines
4.0 KiB
Python

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
import argparse
import sys
from datetime import datetime
from enum import Enum
from typing import List, Type
import pytz
from .reader import (AbstractReader, FileReader, HttpReader, KnownReader,
StdioReader)
from .tableparser import (AbstractTableParser, CsvTableParser,
HtmlMultiTableParser, HtmlTableParser)
PROG_ARGS = sys.argv[1:]
class Source(Enum):
url = 'url'
arg = 'arg'
file = 'file'
stdio = 'stdio'
def __str__(self):
return self.value
def as_type(self) -> Type[AbstractReader]:
return {
type(self).url: HttpReader,
type(self).arg: KnownReader,
type(self).file: FileReader,
type(self).stdio: StdioReader,
}[self]
def __getitem__(self, path: str) -> AbstractReader:
return self.as_type()(path)
class Format(Enum):
html_multi_table = 'html_multi_table'
html_table = 'html_table'
csv = 'csv'
def __str__(self):
return self.value
def as_type(self) -> Type[AbstractTableParser]:
return {
type(self).html_multi_table: HtmlMultiTableParser,
type(self).html_table: HtmlTableParser,
type(self).csv: CsvTableParser,
}[self]
def __getitem__(self, ar: AbstractReader) -> AbstractTableParser:
return self.as_type()(ar)
class AxisMeaning(Enum):
time = 'time'
place = 'place'
def __str__(self):
return self.value
class ContentMeaning(Enum):
name = 'name'
lang_name = 'lang_name'
name_lang = 'name_lang'
def __str__(self):
return self.value
def as_index(self) -> int:
return {
type(self).name: 0,
type(self).lang_name: 1,
type(self).name_lang: -1,
}[self]
def parseArguments(args: List[str] = PROG_ARGS) -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Transforms a data source into ICS")
parser.add_argument('origin', metavar='ORIGIN', type=Source, choices=list(Source),
help=f'The source type ({",".join(list(map(str, Source)))})')
parser.add_argument('path', metavar='PATH', type=str,
help='The source specification (anything typed here will be ignored if origin is stdio)')
parser.add_argument('format', metavar='FORMAT', type=Format, choices=list(Format),
help=f'The input format ({",".join(list(map(str, Format)))})')
parser.add_argument('line', metavar='LINE', type=AxisMeaning, choices=list(AxisMeaning),
help=f'The line meaning ({",".join(list(map(str, AxisMeaning)))})')
parser.add_argument('column', metavar='COLUMN', type=AxisMeaning, choices=list(AxisMeaning),
help=f'The column meaning ({",".join(list(map(str, AxisMeaning)))})')
parser.add_argument('content', metavar='CONTENT', type=ContentMeaning, choices=list(ContentMeaning),
help=f'The content meaning ({",".join(list(map(str, ContentMeaning)))})')
parser.add_argument('--year', metavar='YEAR', type=int, default=datetime.now().year,
help='The year, if absent')
parser.add_argument('--month', metavar='MONTH', type=int, choices=list(range(1, 13)), default=datetime.now().month,
help='The month, if absent')
parser.add_argument('--day', metavar='DAY', type=int, choices=list(range(1, 32)), default=datetime.now().day,
help='The day, if absent')
parser.add_argument('--lang', metavar='LANG', type=str, choices='EN,ES,PT'.split(','), default='EN',
help='The language, if absent (EN,ES,PT)')
parser.add_argument('timezone', metavar='TIMEZONE', type=pytz.timezone, default='UTC',
help='The output timezone')
pa = parser.parse_args(args)
if pa.line == pa.column:
raise ValueError('Line and column meanings must be different')
return pa