コード例 #1
0
    def _output(self, src: list, config: StoryConfig) -> ResultData:
        LOG.info('RUN: OUTPUT: start')
        assertion.is_instance(config, StoryConfig)

        result = ResultData(src, True, None)
        prefixs = assertion.is_valid_length(
            ['', '_p', '', '_data', '_sc', '_ad'], len(CompileMode.get_all()))
        extentions = assertion.is_valid_length(
            ['md', 'md', 'txt', 'md', 'md', 'md'], len(CompileMode.get_all()))
        fmt_idx = 0
        outputter = Outputter()

        for fmt_data in assertion.is_listlike(src):
            if fmt_data:
                LOG.info(f'RUN: START: Outputter [{fmt_idx}]')
                result = assertion.is_instance(
                    outputter.execute(fmt_data, config.output_mode,
                                      config.filename, prefixs[fmt_idx],
                                      extentions[fmt_idx], config.builddir),
                    ResultData)
                if not result.is_succeeded:
                    LOG.error(f'Failure in Outputter [{fmt_idx}]!!')
                    return result
                LOG.info(f'... SUCCESS: Outputter [{fmt_idx}]')
            fmt_idx += 1

        return result
コード例 #2
0
 def times_in_scene(self, src: Scene) -> list:
     tmp = []
     for child in assertion.is_instance(src, Scene).children:
         if isinstance(child, SCode):
             if child.cmd is SCmd.CHANGE_TIME:
                 tmp.append(assertion.is_instance(child.src, Time))
     return tmp
コード例 #3
0
    def execute(self, src: RawData, mode: FormatMode) -> ResultData:
        LOG.info(f'FORMATTER: start exec on [{mode}] mode')
        LOG.debug(f'-- src: {src}')

        is_succeeded = True
        tmp = []
        error = None

        if mode is FormatMode.DEFAULT:
            tmp = assertion.is_instance(self._to_default(src), TextList)
        elif mode is FormatMode.PLAIN:
            tmp = src
        elif mode is FormatMode.WEB:
            tmp = assertion.is_instance(self._to_web(src), TextList)
        elif mode is FormatMode.SMARTPHONE:
            tmp = src
        else:
            msg = f'Invalid format-mode! {mode}'
            LOG.critical(msg)
            is_succeeded = False
            error = FormatModeError(msg)
        return ResultData(
                tmp,
                is_succeeded,
                error)
コード例 #4
0
 def cameras_in_scene(self, src: Scene) -> list:
     tmp = []
     for child in assertion.is_instance(src, Scene).children:
         if isinstance(child, SCode):
             if child.cmd is SCmd.CHANGE_CAMEARA:
                 tmp.append(assertion.is_instance(child.src, Person))
     return tmp
コード例 #5
0
    def _dialogue_percents(self, src: TextList) -> list:
        assertion.is_instance(src, TextList)
        tmp = []

        def _is_desc(val):
            return val.startswith(' ')

        def _is_dialogue(val):
            return val.startswith(('「', '『'))

        totals = len([line for line in src.data])
        total_chars = sum([len(self._rid_topspace(line)) for line in src.data])
        descriptions = len([line for line in src.data if _is_desc(line)])
        desc_chars = sum([
            len(self._rid_topspace(line)) for line in src.data
            if _is_desc(line)
        ])
        dialogues = len([line for line in src.data if _is_dialogue(line)])
        dial_chars = sum(
            [len(line) for line in src.data if _is_dialogue(line)])
        desc_per = safe_divided(desc_chars, total_chars) * 100
        dial_per = safe_divided(dial_chars, total_chars) * 100
        tmp.append('## 台詞\n')
        tmp.append(f'- Total      : {total_chars}c / {totals}line')
        tmp.append(
            f'- Description: {desc_per:.2f}% [{desc_chars}c / {descriptions}line]'
        )
        tmp.append(
            f'- Dialogue   : {dial_per:.2f}% [{dial_chars}c / {dialogues}line]'
        )
        return tmp
コード例 #6
0
    def _update_container_info(
            self, src: (Chapter, Episode, Scene, Material), columns: int,
            rows: int) -> (Chapter, Episode, Scene, Material):
        LOG.info('HEAD_UPDATER: update_container_info')
        LOG.debug(f'-- src: {src}')
        LOG.debug(f'-- columns/rows: {columns}/{rows}')

        assertion.is_instance(src, (Chapter, Episode, Scene, Material))

        tmp = []
        tmp.append(self._containerhead_of(src))
        tmp.append(self._collect_header_info(src, columns, rows))
        tmp.append(self._title_of(src))
        if isinstance(src, Scene):
            tmp.append(self._collect_scene_info(src))
        if src.outline:
            tmp.append(self._outline_of(src))
        for child in src.children:
            if isinstance(child, (Chapter, Episode, Scene)):
                tmp.append(self._update_container_info(child, columns, rows))
            elif isinstance(child, SCode):
                if Checker().has_then(child):
                    tmp.append(SCode(None, SCmd.THEN, (), ''))
                tmp.append(child)
            elif isinstance(child, Material):
                tmp.append(self._update_container_info(child, columns, rows))
            else:
                LOG.error(f'Invalid child value!: {type(child)} | {child}')
        tmp.append(self._end_of(src))
        return src.inherited(*tmp)
コード例 #7
0
    def _exec_internal(
            self, src: Story) -> Tuple[Story, bool, (SceneUpdaterError, None)]:
        assertion.is_instance(src, Story)

        tmp = []
        is_succeeded = True
        error = None
        camera = None
        stage = None
        day = None
        time = None

        for child in src.children:
            if isinstance(child, (Chapter, Episode, Scene)):
                LOG.debug(
                    f'>> {camera.name if camera else camera}/{stage.name if stage else stage}/{day.name if day else day}/{time.name if time else time}'
                )
                ret, camera, stage, day, time = self._updated_scene_info(
                    child, camera, stage, day, time)
                tmp.append(ret)
            elif isinstance(child, SCode):
                tmp.append(child)
            elif isinstance(child, Material):
                tmp.append(child)
            else:
                msg = f'Invalid a child value in scene_update_exec!: {type(child)}: {child}'
                LOG.error(msg)
                error = SceneUpdaterError(msg)
        return src.inherited(*tmp), is_succeeded, error
コード例 #8
0
    def _add_rubi_on_novel(self, src: RawData, rubis: dict) -> RawData:
        LOG.info('COMP: add_rubi_on_novel start')

        tmp = []
        discards = []
        checker = Checker()
        conv = Converter()

        for line in assertion.is_instance(src, RawData).data:
            if isinstance(line, FormatTag) \
                    or checker.has_tag_top(assertion.is_str(line)) \
                    or checker.is_breakline(line) \
                    or checker.has_tag_comment(line):
                tmp.append(line)
            else:
                for key, rubi in rubis.items():
                    if key in discards:
                        continue
                    elif checker.has_rubi_key(line, key):
                        if checker.has_rubi_exclusions(
                                line,
                                assertion.is_instance(rubi, Rubi).exclusions):
                            continue
                        line = conv.add_rubi(line, key, rubi.rubi)
                        if not rubi.is_always:
                            discards.append(key)
                tmp.append(line)
        return RawData(*tmp)
コード例 #9
0
 def _updated_plot_info(self, src: Story, title: str) -> list:
     assertion.is_instance(src, Story)
     tmp = []
     for child in src.children:
         ret = self._updated_plot_info_internal(child, title)
         if ret:
             tmp.extend(ret)
     return tmp
コード例 #10
0
 def _get_sceneinfo(self, code: SCode) -> str:
     data = assertion.is_instance(
         assertion.is_instance(code, SCode).script[0], SceneInfo)
     camera = data.camera.name if data.camera else "第三者"
     stage = data.stage.name if data.stage else "どこか"
     day = data.day.daystring if data.day else "某月某日/某年"
     time = data.time.name if data.time else "不詳"
     return f"○{stage}({time}) - {day}【{camera}】\n"
コード例 #11
0
    def execute(self, src: (str, list, TextList),
            person_names: list,
            is_debug: bool=False) -> ResultData: # pragma: no cover
        LOG.info('ANALYZER: start exec')
        is_succeeded = True
        error = None
        basesrc = None
        result = ResultData([], is_succeeded, error)

        if isinstance(src, str):
            basesrc = TextList(*get_content_from_text_file(src))
        elif isinstance(src, TextList):
            basesrc = src
        elif isinstance(src, (list, tuple)):
            basesrc = TextList(*src)
        else:
            msg = f'Invalid analyze source!: {src}'
            LOG.critical(msg)
            return ResultData(result, False, AnalyzerError(msg))

        tmp = self._rid_tag(basesrc)

        LOG.info('TOKENIZER: call')
        result = assertion.is_instance(Tokenizer().execute(tmp, person_names), ResultData)
        if not result.is_succeeded:
            return result
        tokens = assertion.is_instance(result.data, TokenList)

        LOG.info('WORD_ANALYZER: call')
        result = assertion.is_instance(WordAnalyzer().execute(tokens), ResultData)
        if not result.is_succeeded:
            return result
        word_data = assertion.is_listlike(result.data)

        LOG.info('PERCENT_ANALYZER: call')
        result = assertion.is_instance(PercentAnalyzer().execute(tmp), ResultData)
        if not result.is_succeeded:
            return result
        percent_data = assertion.is_listlike(result.data)

        LOG.info('FREQUENCY_ANALYZER: call')
        result = assertion.is_instance(FrequencyAnalyzer().execute(tokens), ResultData)
        if not result.is_succeeded:
            return result
        freq_data = assertion.is_listlike(result.data)

        LOG.info('Analyzer result output')
        result_data = percent_data + ['\n---\n'] \
                + word_data + ['\n---\n'] \
                + freq_data
        fname = 'result'
        suffix = ''
        extention = 'md'
        builddir = 'build/results'
        mode = OutputMode.CONSOLE if is_debug else OutputMode.FILE
        data = TextList(*[f'{line}\n' for line in result_data])
        Outputter().execute(data, mode, fname, suffix, extention, builddir)
        return result
コード例 #12
0
    def _config_data_replaced(self, config: StoryConfig, tags: dict) -> bool:
        assertion.is_instance(config, StoryConfig)

        is_succeeded = True

        config.set_title(string_replaced_by_tag(config.title, tags))
        config.set_copy(string_replaced_by_tag(config.copy, tags))
        config.set_oneline(string_replaced_by_tag(config.oneline, tags))
        config.set_outline(string_replaced_by_tag(config.outline, tags))

        return is_succeeded
コード例 #13
0
 def __init__(
     self,
     camera: Person,
     stage: Stage,
     day: Day,
     time: Time,
 ):
     self._camera = assertion.is_instance(camera,
                                          Person) if camera else None
     self._stage = assertion.is_instance(stage, Stage) if stage else None
     self._day = assertion.is_instance(day, Day) if day else None
     self._time = assertion.is_instance(time, Time) if time else None
コード例 #14
0
 def __init__(
     self,
     src: SObject,
     cmd: SCmd,
     script: tuple,
     option: (int, str) = '',
 ):
     super().__init__('__scode__')
     self._src = assertion.is_instance(src, SObject) if src else None
     self._cmd = assertion.is_instance(cmd, SCmd)
     self._script = assertion.is_tuple(script)
     self._option = assertion.is_int_or_str(option)
コード例 #15
0
    def execute(
        self,
        src: Story,
        config: StoryConfig,
        db: Database,
    ) -> ResultData:  # pragma: no cover
        ''' Exec story building, compiling and outputting.

        NOTE: Compile option
            1. normal: output `story.md`
            2. plot: output `plot.md`
            3. text: output `story.txt`
            4. scenario: output `sc_story.md`
        '''
        LOG.info('RUN: == START EXEC ==')
        LOG.info('RUN: START-PHASE: Preparation')

        tmp = assertion.is_instance(src, Story)
        is_succeeded = True
        result = None
        error = None

        is_succeeded = self._build_options(config)
        if not is_succeeded:
            msg = 'Cannot build option arguments!!'
            error = RunnerError(msg)
            LOG.error(msg)
            return ResultData([], is_succeeded, error)
        LOG.info('... SUCCESS: Preparation')

        LOG.info('RUN: START-PHASE: Pre-Compile')
        result = self._pre_compile(src, config, db)
        if not result.is_succeeded:
            return result
        tmp = assertion.is_instance(result.data, Story)
        LOG.info('... SUCCESS: Finish: Pre-Compile')

        LOG.info('RUN: START-PHASE: Compile and Output')
        result = assertion.is_instance(self._compile(tmp, config, db),
                                       ResultData)
        LOG.info('... SUCCESS: Finish: Compile and Output')

        self._output_storyinfo(config)

        LOG.info('RUN: analyzer check')
        if self._is_analyzed:
            result = assertion.is_instance(
                self._analyze_and_output(tmp, db.get_person_names(),
                                         self._is_debug), ResultData)

        LOG.info('RUN: == ALL SUCCEEDED ==')
        return result
コード例 #16
0
 def _wordclass_counts(self, src: TokenList) -> list:
     assertion.is_instance(src, TokenList)
     tmp = []
     counter = WordCounter()
     # 品詞数
     total = len(src.data)
     each_nums = [(wcls, counter.word_classes_of(src, wcls))
                  for wcls in WordClass.get_all()]
     tmp.append('# 品詞分析\n')
     tmp.append(f'- Total: {total}')
     for val in each_nums:
         tmp.append(f'- {val[0].conv_str()}: {val[1]}')
     return tmp
コード例 #17
0
    def _inserted_after_storyinfo(self, src: Story, infos: list) -> Story:
        assertion.is_instance(src, Story)
        LOG.debug(f'- info in inserted_after_storyinfo:{infos}')

        tmp = []
        for child in src.children:
            if isinstance(child, SCode) and child.cmd is SCmd.INFO_STORY:
                tmp.append(child)
                for info in infos:
                    tmp.append(SCode(None, SCmd.INFO_DATA, (info,), ""))
            else:
                tmp.append(child)
        return src.inherited(*tmp)
コード例 #18
0
    def _analyze_and_output(self, src: Story, person_names: list,
                            is_debug: bool) -> ResultData:
        # serialize and compile as text
        mode = CompileMode.NOVEL_TEXT
        fmode = FormatMode.DEFAULT
        LOG.info('Serialize for Analyzer')
        result = assertion.is_instance(Serializer().execute(src, mode),
                                       ResultData)
        if not result.is_succeeded:
            return result
        tmp = assertion.is_instance(result.data, CodeList)
        LOG.info('Validate for Analyzer')
        result = assertion.is_instance(Validater().execute(tmp), ResultData)
        if not result.is_succeeded:
            return result
        tmp = assertion.is_instance(result.data, CodeList)
        LOG.info('Compile for Analyzer')
        result = assertion.is_instance(
            Compiler().execute(tmp, mode, {}, False, False), ResultData)
        if not result.is_succeeded:
            return result
        tmp = assertion.is_instance(result.data, RawData)
        LOG.info('Format for Analyzer')
        result = assertion.is_instance(Formatter().execute(tmp, fmode),
                                       ResultData)
        if not result.is_succeeded:
            return result
        tmp = assertion.is_instance(result.data, TextList)

        LOG.info('RUN: call Analyzer')
        result = Analyzer().execute(tmp, person_names, is_debug)
        return ResultData([], True, None)
コード例 #19
0
 def execute(self, src: Story, config: StoryConfig) -> ResultData:
     LOG.info('REDUCER: start exec')
     is_succeeded = True
     error = None
     tmp = assertion.is_instance(
         self._exec_internal(src, config.start, config.end), Story)
     return ResultData(tmp, is_succeeded, error)
コード例 #20
0
    def _to_web(self, src: RawData) -> TextList:
        LOG.info('FORMAT: to_web')

        tmp = []
        in_dialogue = False

        for line in assertion.is_instance(src, RawData).data:
            if isinstance(line, FormatTag):
                if line is FormatTag.DESCRIPTION_HEAD:
                    if in_dialogue:
                        tmp.append('\n')
                        in_dialogue = False
                elif line is FormatTag.DIALOGUE_HEAD:
                    if not in_dialogue:
                        tmp.append('\n')
                        in_dialogue = True
                elif line is FormatTag.SYMBOL_HEAD:
                    pass
                elif line is FormatTag.TAG_HEAD:
                    pass
                else:
                    pass
            else:
                assertion.is_str(line)
                tmp.append(line)
        return TextList(*tmp)
コード例 #21
0
 def execute(self, src: Story) -> ResultData:
     LOG.info('PLOT_UPDATER: start exec')
     tmp, is_succeeded, error = assertion.is_tuple(self._exec_internal(src))
     return ResultData(
             assertion.is_instance(tmp, Story),
             is_succeeded,
             error)
コード例 #22
0
 def __init__(self,
              mate_type: MaterialType,
              title: str,
              *args: Any,
              outline: str = ''):
     super().__init__(title, *args, outline=outline)
     self._mate_type = assertion.is_instance(mate_type, MaterialType)
コード例 #23
0
 def __init__(self, title: str):
     LOG.info('CONFIG: initialize')
     LOG.debug(f'-- title: {title}')
     # for specific
     self._title = assertion.is_str(title)
     self._copy = assertion.is_str('__catch_copy__')
     self._oneline = assertion.is_str('__one_line__')
     self._outline = assertion.is_str('__story_outline__')
     self._theme = assertion.is_str('__theme__')
     self._genre = assertion.is_str('__genre__')
     self._target = assertion.is_str('__target_age__')
     self._size = assertion.is_str('__size__')
     self._desc_size = assertion.is_int(0)
     self._total_size = assertion.is_int(0)
     self._desc_papers = assertion.is_int_or_float(0)
     self._total_papers = assertion.is_int_or_float(0)
     # for story
     self._priority = assertion.is_int(__PRIORITY_DEFAULT__)
     self._start = assertion.is_int(0)
     self._end = assertion.is_int(-1)
     self._base_date = datetime.date(2020, 1, 1)
     self._base_time = datetime.time(12, 00)
     self._version = assertion.is_tuple((0, 0, 1))
     self._columns = assertion.is_int(20)
     self._rows = assertion.is_int(20)
     self._contest_info = assertion.is_str('')
     self._caution = assertion.is_str('')
     self._note = assertion.is_str('')
     self._sites = assertion.is_listlike([])
     self._taginfos = assertion.is_listlike([])
     self._modified = datetime.date.today()
     self._released = datetime.date(2020, 1, 1)
     # for compile
     self._is_data = assertion.is_bool(False)
     self._is_plot = assertion.is_bool(False)
     self._is_text = assertion.is_bool(False)
     self._is_scenario = assertion.is_bool(False)
     self._is_audiodrama = assertion.is_bool(False)
     self._is_rubi = assertion.is_bool(False)
     self._is_comment = assertion.is_bool(False)
     self._is_console = assertion.is_bool(False)
     self._format_mode = assertion.is_instance(FormatMode.DEFAULT,
                                               FormatMode)
     self._output_mode = assertion.is_instance(OutputMode.FILE, OutputMode)
     self._filename = assertion.is_str('story')
     self._builddir = assertion.is_str('build')
     self._log_level = assertion.is_str('warn')
コード例 #24
0
    def _out_to_console(self, src: TextList) -> bool:
        LOG.info('OUTPUT: out to console')

        is_succeeded = True
        for line in assertion.is_instance(src, TextList).data:
            print(line, end='')
        print(datetime.datetime.now())
        return is_succeeded
コード例 #25
0
    def _exec_internal(self, src: Story) -> Tuple[Story, bool, (PlotUpdaterError, None)]:
        assertion.is_instance(src, Story)

        tmp = []
        is_succeeded = True
        error = None

        titles = self._collect_plot_title(src)

        infos = []
        for title in titles:
            ret = self._updated_plot_info(src, title)
            if ret:
                infos.append(PlotInfo(title, *ret))

        ret = self._inserted_after_storyinfo(src, infos)
        return ret, is_succeeded, error
コード例 #26
0
 def _to_default(self, src: RawData) -> TextList:
     LOG.info('FORMAT: to_default')
     tmp = []
     for line in assertion.is_instance(src, RawData).data:
         if isinstance(line, FormatTag):
             continue
         else:
             tmp.append(line)
     return TextList(*tmp)
コード例 #27
0
 def _exec_internal(self, src: Story, mode: CompileMode) -> list:
     ret = []
     assertion.is_instance(src, Story)
     if assertion.is_instance(mode,
                              CompileMode) in (CompileMode.NORMAL,
                                               CompileMode.NOVEL_TEXT):
         ret = self._novel_serialized(src)
     elif mode is CompileMode.PLOT:
         ret = self._plot_serialized(src)
     elif mode is CompileMode.STORY_DATA:
         ret = self._storydata_serialized(src)
     elif mode is CompileMode.SCENARIO:
         ret = []
     elif mode is CompileMode.AUDIODRAMA:
         ret = []
     else:
         LOG.error(f'Invalid story object![1]: {type(child)}: {child}')
     return ret
コード例 #28
0
 def _conv_from_end_container(self, src: SCode) -> str:
     if assertion.is_instance(src, SCode).cmd is SCmd.END_CHAPTER:
         return '\n--------\n'
     elif src.cmd is SCmd.END_EPISODE:
         return '\n\n'
     elif src.cmd is SCmd.END_SCENE:
         return '\n'
     else:
         return ''
コード例 #29
0
    def _has_invalid_symbol(self, src: CodeList) -> Tuple[list, bool]:
        tmp = []
        invalids = []
        checker = Checker()

        for child in assertion.is_instance(src, CodeList).data:
            assertion.is_instance(child, SCode)
            if child.cmd in SCmd.get_all_actions():
                for line in child.script:
                    if checker.has_tag_symbol(line):
                        invalids.append(line)
                tmp.append(child)
            else:
                # NOTE: それ以外をどうするか。ここはスルーか
                tmp.append(child)
        if invalids:
            return (invalids, False)
        else:
            return (CodeList(*tmp), True)
コード例 #30
0
 def _updated_scene_info(
     self,
     src: (Chapter, Episode, Scene, SCode),
     camera: Person = None,
     stage: Stage = None,
     day: Day = None,
     time: Time = None
 ) -> Tuple[(Chapter, Episode, Scene), (Person, None), (Stage, None), (
         Day, None), (Time, None)]:
     if isinstance(src, (Chapter, Episode)):
         tmp = []
         for child in src.children:
             ret, camera, stage, day, time = self._updated_scene_info(
                 child, camera, stage, day, time)
             tmp.append(ret)
         return src.inherited(*tmp), camera, stage, day, time
     elif isinstance(src, Scene):
         ret = self._get_scene_info(src)
         if not ret:
             LOG.error(f'Not found a SceneInfo!: in {src.title} scene')
             return src, camera, stage, day, time
         else:
             assertion.is_instance(ret, SCode)
             info = assertion.is_instance(ret.script[0], SceneInfo)
             camera = info.camera if info.camera else camera
             stage = info.stage if info.stage else stage
             day = info.day if info.day else day
             time = info.time if info.time else time
             codes = []
             for child in src.children:
                 if self._is_scene_info(child):
                     codes.append(
                         child.inherited(script=(
                             SceneInfo(camera, stage, day, time), )))
                 else:
                     codes.append(child)
         return src.inherited(*codes), camera, stage, day, time
     elif isinstance(src, SCode):
         return src, camera, stage, day, time
     else:
         LOG.error(f'Invalid value in updated_scene_info: {src}')
         return src, camera, stage, day, time