예제 #1
0
 def regist_subcommand(self, command):
     """
 sub_commandsの型に依存させないためのIF
 型変更の必要がでたら、局所的に操作を書き換える
 """
     from sub_command_core.sub_command import SubCommands
     Hoare.P(issubclass(command.__class__, SubCommands))
     # 衝突注意
     for name in command.command_names:
         Hoare.P(not (name in self.sub_commands.keys()),\
           '"{}" collision were detected in {}'.format(name, self.sub_commands.keys()))
         # NOTE: commandは参照であること。tupleへのrefactoring注意
         self.sub_commands.update({name: command})
예제 #2
0
 def renew_acc(cls, schema):
   Hoare.P(isinstance(schema, dict))
   _type = XLSX.__get_type(schema)
   if _type == TypeSign.ARRAY:
     return []
   elif _type == TypeSign.OBJ:
     return {}
   else:
     errorout(4, _type)
예제 #3
0
 def regist_command(cls, exchanger):
     """
 subcommand 登録
 **dont call from exchanger.__init__()**
 """
     command = cls.__init__()
     from jsonica import Jsonica
     Hoare.P(isinstance(exchanger, Jsonica))
     exchanger.regist_command(command)
예제 #4
0
 def validate(self, evl, desc):
     """
 _validateに流す
 成功すればスルー、失敗したらその場でcommand error / 判定値は返さない
 NOTE: 具体的なerrorハンドリングは_validate内で処理すること
 """
     Hoare.P(isinstance(evl, list) or isinstance(evl, dict))
     self.schema._validate(evl, self.make_schema(desc))
     Util.sprint(
         'i\'m {} \nNow I have -> {}'.format(self, self.schema_collection),
         self.DEBUG)
예제 #5
0
 def generate_json(self, sheet_name, acc=None):
   """
   sheet_nameが指すsheetのJSONをaccに追加する
   """
   sheets = self.__name_to_sheets()
   # pyxl...Workbookで[sheet名]を持っているが、あまり高速処理向けではないため
   sheet_names = list(sheets.keys())
   Util.sprint('in process %s'%sheet_name, self.DEBUG)
   Hoare.P(sheet_name in sheet_names, '"%s" not found in %s'%(sheet_name ,sheet_names))
   root_sheet = sheets[sheet_name]
   self.check_charcode(root_sheet)
   columns = []
   acc = [] if not acc else acc
   Util.sprint('I\'ll update {}'.format(acc), self.DEBUG)
   # COMBAK: 処理速度に問題が出るようであれば分散処理検討
   # A1, B1...で場所を特定するか、indexで回すか
   for i, row in enumerate(root_sheet.iter_rows()):
     subacc = {}
     if self.format:
       self.__output_to_csv(self.format_output, root_sheet, self.char_encode)
     for j, cell in enumerate(row):
       v = cell.value # off-by-oneを気にしないといけなくなるので、col_idxではなくenumerate使う
       if v is None: continue # cell check
       if i == 0: # 初行 column check
         # cell.commentは必ずつくが、中身がない場合はNone
         if hasattr(cell, "comment") and cell.comment:
           # column 準備 / schemaは遅延せずこの時点で辞書として成立している事を保証
           columns.append((v, Util.runtime_dict(cell.comment.text)))
         else:
           self.errorout(2, 'sheet = {}, col = {}, row = {}'.format(sheet_name, j, i))
       else:
         # TODO: 関数へ置き換え type = array, objectのケース をカバー
         # 別sheet評価
         if isinstance(v, str) and v.startswith(XLSX.sheet_link_sign):
           # COMBAK: sheetであることがarray, objectの必要条件になってしまっている
           # primitive配列をどう表現するかによって改修が必要 __storeに包含させる?
           link = v.lstrip(XLSX.sheet_link_sign)
           if link in sheet_names:
             col_name, col_schema = columns[j]
             Util.sprint('process %s -> %s'%(col_name, link), self.DEBUG)
             Util.sprint('current acc = %s'%acc, self.DEBUG)
             # recursive seed
             XLSX.__store(
               self.generate_leaf(root_sheet.title, col_name, link, col_schema),
               subacc)
           else:
             errorout(1, 'sheet = from %s to %s, col = %d, row = %d'%(sheet_name, link, j, i))
         else:
           XLSX.__store(self.type_validator(sheet_name, v, columns[j]), subacc)
       # pass columns
     Util.check_emptyOR(lambda x: XLSX.__store(x, acc), subacc)
     # pass a row
   return acc
예제 #6
0
 def __output_to_csv(self, base_path, sheet, enc):
   """
   CSV, TSV出力
   """
   if not self.format: return
   Hoare.P(self.format in output_formats)
   xdest = os.path.join(base_path, self.filename)
   os.makedirs(xdest, exist_ok=True)
   xdest_path = os.path.join(xdest, '%s.%s'%(sheet.title ,self.format))
   Util.sprint(' > %s'%xdest_path, self.DEBUG)
   with open(xdest_path, 'w', encoding=enc) as f:
     writer = csv.writer(f, delimiter=self.format_delimiter)
     for cols in sheet.rows:
       writer.writerow([str(col.value or '') for col in cols])
예제 #7
0
 def type_validator(self, sheet_name, value, type_desc, validator=Validator.jsonschema):
   """
   Validator switcher
   validation を passしたら成功した**評価値のみ**を返す
   失敗したら、その場でcommand errorとする
   """
   self.schema = Schema(validator)
   raw = Util.conv_escapedKV(XLSX.__get_type(type_desc[1]), type_desc[0], value)
   instance = Util.runtime_dict('{%s}'%raw)
   Util.sprint('i\'m %s. call validator'%self, self.DEBUG)
   self.piled_schema = (sheet_name, type_desc[0], {type_desc[0]:type_desc[1]})
   Util.sprint('>> %s -> type: %s\n%s'%(sheet_name, type_desc, instance), self.DEBUG)
   Hoare.P(instance is not None)
   self.schema.validate(instance, type_desc)
   return instance
예제 #8
0
def errorout(e, additonal=''):
    """ 強制的に止める sys.stderr へ出力 """
    errors = [
        'OK',
        'sheets link not found.',
        'schema not found.',  # 1, 2
        'root sheet not found.',
        'Unrecognized item type were found.',  # 3, 4
        'Unknown accumulator!',
        'Output json has failed.',  # 5, 6
        'Unsupported table filetype found.',
        'setting yaml file not found'
    ]
    Hoare.P(e < len(errors) and e >= 0)
    print('%s : %s' % (errors[e], additonal), file=sys.stderr)
    sys.exit(e)
예제 #9
0
 def check_charcode(self, item, valid_enc=None):
   Hoare.P(isinstance(item, openpyxl.workbook.workbook.Workbook) or \
           isinstance(item, openpyxl.worksheet.Worksheet) or \
           isinstance(item, openpyxl.cell.Cell))
   enc = valid_enc if bool(valid_enc) else self.char_encode
   Util.sprint(enc, self.DEBUG)
   if not (item.encoding == enc):
     # TODO: sheet, cellごとにエラーを上げる場合の処理
     if isinstance(item, openpyxl.workbook.workbook.Workbook):
       add = 'sheet_names = %s'%item.sheet_names
     elif isinstance(item, openpyxl.worksheet.Worksheet):
       add = 'sheet_name = %s'%item.title
     else: # Cell
       add = 'parent = {} index = {}'.format(item.parent ,item.cordinate)
     print('*'*50)
     print(add)
     print('*'*50)
     # TODO: excel rw 状態チェック
     item.encoding = enc
예제 #10
0
 def __run__(self, **kwargs):
     Hoare.P(False)
예제 #11
0
 def help(self):
     Hoare.P(False)
예제 #12
0
 def aliases(self):
     Hoare.P(False)
예제 #13
0
 def command_names(self):
     Hoare.P(False)
예제 #14
0
def refactor_check(validation):
    Hoare.P(validation, 'Have you made refactor??')
예제 #15
0
 def __get_type(cls, schema):
   Hoare.P('type' in schema.keys())
   return schema['type']
예제 #16
0
 def make_schema(self, desc):
     """ 一項目ずつの定義であることに留意 """
     Hoare.P(isinstance(desc[0], str) and isinstance(desc[1], dict))
     # TEMP: failfastとして小粒度で都度Errorを上げるか、reduceしたあと最後にvalidationをかけるか
     self.schema_collection.append(self.schema._make_schema(desc))
     return self.schema_collection[-1]
예제 #17
0
 def save(self):
     Hoare.P(self.out.endswith('.xlsx'))
     output = self.out
     print(r'generate template to {}'.format(output))
     self.processor.book.save(output)
예제 #18
0
 def check_settingfile(self):
     with open(self.settings, 'r') as f:
         self.setting_data = yaml.safe_load(f)
     if self.setting_data[ATTACH[0]] == ATTACH[1][0]:
         self.processor = XLSX(self.settings, self.enc)
     Hoare.P(self.processor)