Example #1
0
 def create(cls, table_name: str, key_name: str, data: dict, master_loader):
     try:
         type = data['type']
         return cls._type_table[type](table_name, key_name, data, master_loader)
     except Exception as e:
         ToolOutput.out_error(f'columnの生成に失敗 table={table_name}, key={key_name}')
         raise e
Example #2
0
 def render_enum_python(self, out_python_path: Path, enum_loader: EnumLoader):
     ToolOutput.anchor('generate python enum code...')
     out_enum_path = out_python_path / 'def_enum.py'
     pr = PythonEnumRenderer()
     for p, d in enum_loader.iter():
         pr.add_unit(PythonEnumRenderUnit(d))
     write_file(out_enum_path, pr.render())
     ToolOutput.pop('OK')
Example #3
0
    def render_units(self):
        ToolOutput.anchor('Wiki出力を開始')
        u = IndentString()
        for k, table in self.master_loader.iter():
            un = MasterDataWikiRenderUnit(table).render()
            u.add(un)
        ToolOutput.pop('OK')

        return u
Example #4
0
    def setup(self, dir_name=''):
        super().setup(dir_name)

        ToolOutput.anchor('MasterExcelを準備します')
        d = defaultdict(dict)
        for k, v in self.iter():
            self.ref_table_name[v.table_name] = v
            d[v.excel_name][v.excel_sheet_name] = v
        self.ref_excel_name = dict(d)
        ToolOutput.pop()
Example #5
0
    async def handle(self, *args, **options):
        ToolOutput.anchor('Generate Excel...')
        in_path = Path(options['dsl_path'])
        out_path = Path(options['out'])

        in_master_path = in_path / 'master'
        in_enum_path = in_path / 'enum'
        in_dynamo_path = in_path / 'dynamo'

        out_excel_path = out_path / 'excel'
        out_python_path = out_path / 'python'

        if options['clean']:
            self.clean(out_excel_path, out_python_path)

        enum_loader = self.load_enum_yaml(in_enum_path)
        master_loader = self.load_master_yaml(in_master_path, enum_loader)

        self.render_master_excel(out_excel_path, master_loader)

        # CSモデルの書き出し
        # out_cs_path = options.get('out_cs_path', None)
        # if out_cs_path:
        #     cs_model_path = Path(out_cs_path)
        #     ToolOutput.anchor('generate cs model...')
        #     for name, table in master_loader.iter():
        #         if not table.is_out_pack:
        #             continue
        #         p = cs_model_path / (table.class_name + '.cs')
        #         r = MasterCSModelRenderer()
        #         r.add_unit(MasterCSModelRenderUnit(table))
        #         write_file(p, r.render())
        #     ToolOutput.pop('OK')

        self.render_enum_excel(out_excel_path, enum_loader, master_loader)

        # pythonモデル&データストアの書き出し
        self.render_master_python(out_python_path, master_loader)

        # generate python master models.
        self.render_enum_python(out_python_path, enum_loader)

        self.render_dynamo(in_dynamo_path, out_python_path)

        # generate cs master models.
        # if out_cs_path:
        #     ToolOutput.anchor('generate cs master models...')
        #     out_cs_enum_path = Path(out_cs_path) / 'enums'
        #     for p, d in enum_loader.iter():
        #         cs = CSEnumRenderer()
        #         cs.add_unit(CSEnumRenderUnit(d))
        #         write_file(out_cs_enum_path / ('Enum' + d.full_classname + '.cs'), cs.render())
        #     ToolOutput.pop('OK')
        ToolOutput.pop('all done!')
Example #6
0
    def __init__(self, book: 'MasterExcel', sheet: Worksheet,
                 formula_sheet: Worksheet, table: MasterTable, loader):
        from hatsudenki.packages.command.master.exporter.loader import MasterExcelLoader
        self.sheet = sheet
        self.formula_sheet = formula_sheet
        self.table = table
        self.loader: MasterExcelLoader = loader
        ToolOutput.out(
            f'[MasterExcel]Sheet準備 {self.sheet.title} = {table.table_name}')
        self.book = book

        self.resolved_headers = self._resolve_headers()
        self.datas: Dict[str, Dict[str, Tuple[MasterColumn,
                                              any]]] = self._resolve()
Example #7
0
 def __init__(self, base_path: Path, full_path: Path,
              table_data: Dict[str, MasterTable], loader, *args, **kwargs):
     from hatsudenki.packages.command.master.exporter.loader import MasterExcelLoader
     super().__init__(base_path, full_path, *args, **kwargs)
     self.data = MasterExcelData(Path(full_path))
     self.table = table_data
     self.loader: MasterExcelLoader = loader
     self.table_sheets: Dict[str, MasterExcelSheet] = {}
     ToolOutput.anchor(f'{self.data.name} をよみこみます')
     for sheet in self.data.iter_table_sheet():
         if sheet.title not in self.table:
             continue
         self.table_sheets[sheet.title] = self._create_sheet(sheet)
     ToolOutput.pop('OK')
Example #8
0
 def render_master_excel(self, out_excel_path: Path, master_loader: MasterTableLoader):
     ToolOutput.anchor('generate excel books...')
     for excel_name, sheet_list in master_loader.ref_excel_name.items():
         ToolOutput.anchor(f'{excel_name}')
         book = MasterExcelBook(out_excel_path / (excel_name + '.xlsx'), sheet_list)
         ToolOutput.pop()
         book.save_file()
     ToolOutput.pop('OK')
Example #9
0
    def add_table(self, table_data: List[dict]):
        ToolOutput.anchor(f'{self.book.path.name} {self.sheet.title}にレストア')
        r = self.sheet.rows
        headers = next(r)
        idxes = [h.value for h in headers]

        self.sheet.delete_rows(2, self.sheet.max_row - 1)

        for d in table_data:
            dd = []
            for idx in idxes:
                if idx == 'TAG':
                    # TAGは出力されないので強制的に0入れる
                    dd.append(0)
                    continue
                dd.append(d.get(idx, None))
            self.sheet.append(dd)
        ToolOutput.pop('OK')
Example #10
0
    def render(self):
        ToolOutput.anchor(f'{self.data.label} をMarkdownに変換')
        u = IndentString()
        u.add(f'# {self.data.excel_sheet_name}')
        u.add(f'## 情報')
        u.add(self.data.description if self.data.
              description else '*!! descriptionが設定されていません !!*')
        u.blank_line()

        u.add(self._gen_info().render())

        u.add(f'## 担当者')
        u.add(self._gen_assigner().render())

        u.add(f'## スキーマ情報')
        u.add(self._column().render())

        ToolOutput.pop('OK')
        return u
Example #11
0
def cli():
    # 引数の処理
    parser = get_args()
    args = parser.parse_args()
    if hasattr(args, 'handler'):
        s = vars(args)

        # quietがセットされていない場合はToolのロガーをセットアップする
        if not s.get('quiet'):
            ToolOutput.setup()

        acv = asyncio.get_event_loop()
        try:
            # commandの実行
            acv.run_until_complete(args.handler(*sys.argv, **s))
        except:
            print_exc()
    else:
        # helpの表示(一応)
        parser.print_help()
Example #12
0
    def _load(self, path: Path):
        tbl_name = path.name.replace('.yml', '')
        ToolOutput.anchor(f'"{path}:1" をロード')
        table = self.master_loader.get_by_table_name(tbl_name)
        if table is None:
            ToolOutput.pop(f'みつからない {tbl_name}')
            return None

        a = MasterDataYaml(self.base_path, path, table, self)
        ToolOutput.pop('OK')
        return a
Example #13
0
    def clean(self, excel_path: Path, python_path: Path):
        ToolOutput.anchor('出力フォルダをクリア')
        ToolOutput.anchor('cleaning excel directory...')
        for book_file in excel_path.glob('*.xlsx'):
            ToolOutput.out(str(book_file))
            book_file.unlink()
        ToolOutput.pop('OK')

        ToolOutput.anchor('cleaning output python directory...')
        p = python_path / 'def_enum.py'
        if p.exists():
            p.unlink()
        p = python_path / 'masters.py'
        if p.exists():
            p.unlink()
        ToolOutput.pop('OK')
        ToolOutput.print_with_pop('OK')
Example #14
0
 def setup(self, dir_name=''):
     ToolOutput.out(f'[{self.__class__.__name__}] setup...')
     self.datas = {
         Path(unicodedata.normalize('NFC', str(path))): None
         for path in (self.base_path / dir_name).glob('**/*' + self.ext)
     }
Example #15
0
    def _generate_table_sheets(self):
        """
        マスターテーブルに対応するシートを生成
        """
        origin = 0
        self.sort_dict = {}
        # 所属するテーブルでループ
        for idx, (sheet_name, table) in enumerate(self.table_infos.items()):
            ToolOutput.anchor(f'[{sheet_name}]シート作成開始...')

            if sheet_name in self.book.sheetnames:
                # すでに対応するシートが存在する
                sheet = self.book[sheet_name]
                old_header = self.get_header_values(sheet_name)
                self.sort_dict[sheet_name] = table.data[
                    'priority'] if 'priority' in table.data else 0
            else:
                sheet = self.book.create_sheet(sheet_name, origin + idx)
                ToolOutput.out(f'[{sheet_name}]シート を追加します')
                old_header = {}
                self.sort_dict[sheet_name] = table.data[
                    'priority'] if 'priority' in table.data else 0
            tail_coord = old_header.get('TAG', 'A1')

            # カラム列の生成
            for idx_2, (k, c) in enumerate(table.columns.items()):
                # すでに列が存在するか?
                coord = old_header.get(c.excel_raw_header_name, None)
                if coord is None:
                    # 新規に追加された列である
                    ToolOutput.out(
                        f'{c.excel_raw_header_name} 列が[{tail_coord}]に追加されました')

                    row_idx, col_idx = coordinate_to_tuple(tail_coord)
                    sheet.insert_cols(col_idx, 1)
                    cell = sheet[tail_coord]
                    tail_coord = cell.offset(row=0, column=1).coordinate
                else:
                    cell = sheet[coord]

                cell.style = CellStyle.RED.name
                # 特殊なカラムの処理
                if c.is_no_pack:
                    # packに出力しない列
                    cell.style = CellStyle.GREEN.name
                if c.is_relation:
                    # 参照が設定されている列
                    cell.value = c.excel_header_name
                    cell.font = Font(name="Meiryo UI",
                                     size=10,
                                     underline="single",
                                     color=Color(rgb=None,
                                                 indexed=None,
                                                 auto=None,
                                                 theme=10,
                                                 tint=0.0,
                                                 type="theme"))
                else:
                    # 普通の列
                    cell.value = c.excel_header_name
            ToolOutput.pop('OK')

            cell = sheet[tail_coord]
            cell.style = CellStyle.BLUE.name
            cell.value = 'TAG'
Example #16
0
 def render_master_python(self, out_python_path: Path, master_loader: MasterTableLoader):
     ToolOutput.anchor('generate master python code...')
     model_renderer = MasterModelRenderer(master_loader)
     write_file(out_python_path / 'masters.py', model_renderer.render())
     ToolOutput.pop()
Example #17
0
 def render_enum_excel(self, out_excel_path: Path, enum_loader: EnumLoader, master_loader: MasterTableLoader):
     ToolOutput.anchor('generate enum excel...')
     enum_book = EnumExcelBook(out_excel_path / 'pg_excel' / '定義タイプ.xlsx', enum_loader, master_loader)
     enum_book.save_file()
     ToolOutput.pop('OK')
Example #18
0
    async def handle(self, *args, **options):
        # 引数解析
        in_path = Path(options.get('in'))
        out_path = Path(options.get('out'))
        dsl_path = Path(options.get('dsl_path'))
        target_tag: str = options.get('tag')
        enable_debug = options.get('debug', False)
        ToolOutput.print(
            f'dump master yaml... tag={target_tag} debug={enable_debug}',
            False)
        ToolOutput.out(f'parameter {in_path}, {out_path}, tag={target_tag}')

        # 出力TAG
        tag_loader = MasterTagLoader(dsl_path / 'define' / 'master_tag.yml')
        tag_loader.load()

        # TAG情報を取得
        out_tag = tag_loader.get_tag(target_tag)

        if out_tag is None:
            raise Exception(f'出力タグ {target_tag} は定義されていません!')

        if out_tag.is_only:
            ToolOutput.out(f'onlyモードで出力します include={out_tag.include}')

        enum_path = dsl_path / 'enum'
        master_schema_path = dsl_path / 'master'
        master_excel_path = in_path

        out_raw_yaml_path = out_path / 'raw_yaml'

        # Enum準備
        ToolOutput.print_with_anchor('enum準備')
        enum_loader = EnumLoader(enum_path)
        enum_loader.setup()
        ToolOutput.print_with_pop('OK')

        # スキーマパース
        ToolOutput.print_with_anchor('masterスキーマ準備')
        master_loader = MasterTableLoader(master_schema_path, enum_loader)
        master_loader.setup()
        ToolOutput.print_with_pop('OK')

        # Excel読み込み
        ToolOutput.print_with_anchor('excel準備')
        excel_loader = MasterExcelLoader(master_excel_path, master_loader,
                                         tag_loader)
        excel_loader.set_out_level(out_tag)
        excel_loader.set_debug_flg(enable_debug)
        excel_loader.setup()
        ToolOutput.print_with_pop('OK')

        # cleanフラグが設定されている場合は掃除する
        if options.get('clean', False):
            recreate_dir(out_raw_yaml_path)

        # YAML書き出し
        self.generate_yaml(excel_loader, out_raw_yaml_path, out_tag)
Example #19
0
    async def render_to_wiki(self, base_url, token_str):
        ToolOutput.anchor('Wiki出力を開始')

        wiki = GitWikiUploader(base_url, token_str)

        page_list = await wiki.get_page_list()
        page_slug_list = [v['slug'] for v in page_list]

        d: DefaultDict[str, List[MasterDataWikiRenderUnit]] = defaultdict(list)
        ToolOutput.anchor('YAML読み込み')
        for k, table in self.master_loader.iter():
            ru = MasterDataWikiRenderUnit(table)
            ToolOutput.out(f'{ru.page_name} # {ru.data.excel_sheet_name}')
            d[ru.page_name].append(ru)
        ToolOutput.pop('OK')

        ToolOutput.anchor('書き出し')
        num = 1
        index = MarkdownTableRenderer(
            ['ID', 'Book', 'Client', 'Server', 'Planner', 'Table'])
        for p, rus in d.items():
            ToolOutput.anchor(p)
            u = IndentString()
            for r in rus:
                u.add(r.render())
                idx = r.render_index()
                idx['ID'] = str(num)
                num += 1
                index.append(idx)

            if p in page_slug_list:
                ToolOutput.print(f'{p}更新します')
                await wiki.update_page(content=u.render(), page_name=p)
            else:
                ToolOutput.print(f'{p}作成します')
                await wiki.create_page(content=u.render(), page_name=p)
            ToolOutput.pop('OK')

        ix = self.render_index(index)

        index_title = 'MasterData/☆INDEX☆'
        if index_title in page_slug_list:
            ToolOutput.print(f'{index_title}更新します')
            await wiki.update_page(content=ix.render(), page_name=index_title)
        else:
            ToolOutput.print(f'{index_title}作成します')
            await wiki.create_page(content=ix.render(), page_name=index_title)

        ToolOutput.pop('OK')
Example #20
0
 def render_index(self, index: MarkdownTableRenderer):
     ToolOutput.anchor('目次')
     u = IndentString()
     u.add('# MasterData目次')
     u.add(index.render())
     return u
Example #21
0
 def load_enum_yaml(self, in_enum_path: Path):
     ToolOutput.anchor('loading enum yaml files...')
     enum_loader = EnumLoader(in_enum_path)
     enum_loader.setup()
     ToolOutput.pop('OK')
     return enum_loader
Example #22
0
 def load_master_yaml(self, in_master_path: Path, enum_loader: EnumLoader):
     ToolOutput.anchor('loading master yaml files...')
     master_loader = MasterTableLoader(in_master_path, enum_loader)
     master_loader.setup()
     ToolOutput.pop('OK')
     return master_loader
Example #23
0
def write_file(out_path: Path, data: str, mode: str = 'w'):
    ToolOutput.print(f'write to {out_path}', False)
    out_path.parent.mkdir(parents=True, exist_ok=True)
    with out_path.open(mode=mode, encoding='utf-8') as file:
        file.write(data)