예제 #1
0
def main():
    # argparse:只需传入path,无其他开关
    parser = argparse.ArgumentParser(
        prog='AppScan',
        description='读取AppScan的XML文件,转换成测评能手标准格式,转换结果分别保存至每个原始文件的同目录下。')
    parser.add_argument('path', nargs='+', help='file path or dir path')
    args = parser.parse_args()
    _LOGGER.info('[AppScan] Started.')

    # 过滤xml并去重
    _LOGGER.debug('[AppScan] arg_paths = "{}".'.format(args.path))
    target_paths = set()
    for arg_path in args.path:
        target_paths = target_paths.union(
            set(Converter.walk.file(arg_path, ['.xml'])))
    _LOGGER.debug('[AppScan] target_paths = "{}".'.format(target_paths))

    # 调用Converter.xml处理
    count = 0
    for target_path in target_paths:
        try:
            new_root = Converter.xml.read_AppScan(target_path)
            Converter.xml.write(
                new_root,
                os.path.splitext(target_path)[0] + '_converted.xml')
            count += 1
        except Exception as err:
            _LOGGER.warning(
                '[AppScan] Conversion failure due to "{}"'.format(err))

    _LOGGER.info('[AppScan] Finished with {} converted.'.format(count))
예제 #2
0
def convert_PDF(src_file_path:str) -> str:
    ''' 调用Word,将{src_file_path}转换为PDF并存放在同目录。

    Args:
        src_file_path(str): 需转换的文件

    Returns:
        str: 转换完成的文件路径
    
    Raises:
        ValueError: 如果{src_file_path}不存在或格式非法
        OSError: 如果调用Word程序失败
    '''
    # 校验src_file_path的格式是否有效
    if os.path.isfile(src_file_path) and os.path.splitext(src_file_path)[1].lower() == '.pdf':
        return src_file_path
    if not os.path.isfile(src_file_path) or os.path.splitext(src_file_path)[1].lower() not in ['.doc', '.docx']:
        raise ValueError('Invalid word file.')
    dst_file_path = os.path.splitext(src_file_path)[0] + '.pdf'

    # 打开并关联Word,处理结束后放在后台不管,必要时会自动复用
    _LOGGER.debug('[Converter/document/convert_PDF] Dispatching Word.Application.')
    try:
        word = win32com.client.gencache.EnsureDispatch('Word.Application')
    except:
        _LOGGER.error('[Converter/document/convert_PDF] Failed to dispatch Word.Application.')
        raise OSError('Failed to dispatch Word.Application.')
    # 转换doc文件
    _LOGGER.info('[Converter/document/convert_PDF] Converting "{}"'.format(src_file_path))
    document = word.Documents.Open(FileName=src_file_path, ReadOnly=True)
    document.SaveAs2(FileName=dst_file_path, FileFormat=17) # wdFormatPDF=17
    document.Close(SaveChanges=0)
    return dst_file_path
예제 #3
0
def convert_latest(src_file_path:str) -> str:
    ''' 调用Word,将{src_file_path}转换最新格式。

    Args:
        src_file_path(str): 需转换的文件

    Returns:
        str: 转换完成的文件路径
    
    Raises:
        ValueError: 如果{src_file_path}不存在或格式非法
        OSError: 如果调用Word程序失败
    '''
    # 校验src_file_path的格式是否有效
    if not os.path.isfile(src_file_path) or os.path.splitext(src_file_path)[1].lower() not in ['.doc', '.docx']:
        raise ValueError('Invalid word file.')
    dst_file_path = os.path.splitext(src_file_path)[0] + '.docx'

    # 打开并关联Word,处理结束后放在后台不管,必要时会自动复用
    _LOGGER.debug('[Converter/document/convert_latest] Dispatching Word.Application.')
    try:
        word = win32com.client.gencache.EnsureDispatch('Word.Application')
    except:
        _LOGGER.error('[Converter/document/convert_latest] Failed to dispatch Word.Application.')
        raise OSError('Failed to dispatch Word.Application.')
    # 打开并关联文档
    document = word.Documents.Open(FileName=src_file_path)
    _LOGGER.info('[Converter/document/convert_latest] CompatibilityMode = {}.'.format(document.CompatibilityMode))
    # 将word转换为最新文件格式
    if document.CompatibilityMode < 15: # CompatibilityMode=11-14(旧版)
        _LOGGER.info('[Converter/document/convert_latest] Converting "{}".'.format(dst_file_path))
        document.Convert()
        document.Save()
    document.Close()
    return dst_file_path
예제 #4
0
def read_XT17(src_file_path:str) -> dict:
    ''' 读取{src_file_path}文件,获取项目编号、项目名称、方案日期、撰写人。

    Args:
        src_file_path(str): 读取的文件

    Returns:
        dict: {'code': (str), 'name': (str),'date': (str),'leader': (str)}

    Raises:
        ValueError: 如果{src_file_path}不存在或格式非法
    '''
    # 校验src_file_path的格式是否有效
    if not os.path.isfile(src_file_path) or os.path.splitext(src_file_path)[1].lower() not in ['.doc', '.docx']:
        raise ValueError('Invalid word file.')
    # 自动转换doc,失败时由convert_latest()抛出异常
    if os.path.splitext(src_file_path)[1].lower() == '.doc':
        src_file_path = convert_latest(src_file_path)

    ret = {'code': '', 'name': '','date': '','leader': ''}
    document = Document(src_file_path)
    # 读项目编号
    ## 印象中所有项目编号都能在前几行读到
    for paragraph in document.paragraphs[0:5]:
        re_result = re.search('SHTEC20[0-9]{2}DSYS[0-9]{4}', paragraph.text)
        if re_result:
            ret['code'] = re_result[0]
            break
    ret['name'] = document.tables[0].cell(0, 1).text.strip()
    ret['date'] = document.tables[0].cell(3, 1).text.strip()
    ret['leader'] = document.tables[-5].cell(0, 1).text.strip()
    _LOGGER.debug('[Converter/document/read_XT17] ret = "{}"'.format(ret))

    return ret
예제 #5
0
파일: XT09.py 프로젝트: ale10bb/Converter
def main():
    # argparse:传入path
    parser = argparse.ArgumentParser(
        prog='XT09',
        description='读取等保方案文件XT17,根据其中信息自动生成方案审核意见单XT09,并尝试转换PDF。')
    # 传入no-pdf,关闭自动生成PDF
    parser.add_argument('-np',
                        '--no-pdf',
                        default=False,
                        action='store_true',
                        help='disable PDF generation')
    parser.add_argument('path', nargs='+', help='file path or dir path')
    args = parser.parse_args()
    _LOGGER.info('[XT09] Started.')

    # 过滤doc/docx并去重
    _LOGGER.debug('[XT09] arg_paths = "{}".'.format(args.path))
    target_paths = set()
    for arg_path in args.path:
        target_paths = target_paths.union(
            set(Converter.walk.file(arg_path, ['.doc', '.docx'])))
    _LOGGER.debug('[XT09] target_paths = "{}".'.format(target_paths))

    # 读取自定义字典
    customized_advices = []
    try:
        # 字典文件不存在时释放res资源
        if not os.path.exists(
                os.path.join(os.path.dirname(sys.argv[0]), 'AdviceList.txt')):
            shutil.copy(_RESOURCE_PATH(os.path.join('res', 'AdviceList.txt')),
                        os.path.dirname(sys.argv[0]))
        # 尝试读取自定义字典文件
        with open(os.path.join(os.path.dirname(sys.argv[0]), 'AdviceList.txt'),
                  encoding='utf-8') as f:
            raw_lines = f.readlines()
        for raw_line in raw_lines:
            if not raw_line.lstrip().startswith('#'):
                customized_advices.append(raw_line.strip())
    except:
        _LOGGER.warning('[XT09] Fail to read "AdviceList.txt".')

    # 调用Converter.document处理
    count = 0
    for target_path in target_paths:
        try:
            # 读取基本信息,并写入随机审核意见
            info = Converter.document.read_XT17(target_path)
            info['advices'] = Converter.walk.XT09_advices(customized_advices)
            # 根据读取的信息生成审核意见单,并转换成PDF
            XT09_file_path = Converter.document.make_XT09(
                os.path.dirname(target_path), info)
            if not args.no_pdf:
                Converter.document.convert_PDF(XT09_file_path)
            count += 1
        except Exception as err:
            _LOGGER.warning(
                '[XT09] Generation failure due to "{}"'.format(err))

    _LOGGER.info('[XT09] Finished with {} generated.'.format(count))
예제 #6
0
파일: walk.py 프로젝트: ale10bb/Converter
def XT09_advices(customized_advices: list = []) -> str:
    ''' 生成XT09的建议。如果自定义建议数量少于四个,则使用内置字典。

    Args:
        customized_advices(list): 自定义建议列表

    Returns:
        str: 生成的建议(按\n换行)
    '''

    # 内置建议字典
    advices = [
        '封面的项目编号有误。', '方案中的被测单位名称可能有误,请与用户方充分沟通并确认。', '方案页脚的页码和总页码处不正确。',
        '方案中1.4、4.2等相关章节的段落缩进、字体大小等格式方面有不一致等问题,请通篇查找并修订。',
        '图1.1的图题描述错误,应为“等级保护测评工作流程图”。', '1.3章节测评过程中的个别年份存在笔误。', '2.2章节内容缺失。',
        '2.2章节“承载业务情况”的个别信息资产描述与2.4章节相关信息资产表的内容不一致。',
        '2.4章节信息资产表中个别信息资产的版本及型号未描述完善。', '2.4章节信息资产表中个别栏目为空,且未阐明原因或加以注销。',
        '3.1.1章节关注的抽选信息资产类别,未在3.1.2章节予以体现完整,例如终端这类信息资产。',
        '3.1.2章节抽选的信息资产列表中的个别信息资产类别,未在3.1.1章节中体现,存在上下文不一致的情况。', '3.3章节内容缺失。',
        '4.1章节内容有误。', '5.2章节,应对测试工具的接入点加以补充和完善,并与用户方做充分的沟通,确保扫描和渗透性测试的顺利实施。',
        '6.2章节扩展安全要求中个别栏目为空,且未阐明原因或加以注销。', '8.1章节“项目组织”中表格内的个别栏目未填写内容,请补充完善。'
    ]

    if len(customized_advices) >= 4:
        advices = customized_advices
        _LOGGER.info('[Converter/word/get_advices] Using customized advices.')
    else:
        _LOGGER.info('[Converter/word/get_advices] Using bulitin advices.')

    # 随机取2-4个索引
    chosen_indexs = random.sample(range(0, len(advices)), random.randint(2, 4))
    # 拼接审核意见字符串
    seq = 1
    chosen_advices = []
    for chosen_index in chosen_indexs:
        chosen_advices.append('{}、{}'.format(seq, advices[chosen_index]))
        seq += 1
    _LOGGER.debug('[Converter/word/get_advices] chosen_advices = "{}".'.format(
        chosen_advices))
    return '\n'.join(chosen_advices)
예제 #7
0
def merge_PDF(src_file_paths:list=[], dst_dir_path:str='') -> str:
    ''' 调用PyPDF2,将{src_file_paths}合并,输出到{dst_dir_path}下的output.pdf。

    Args:
        src_file_paths(list): 需合并的文件;
        dst_dir_path(str): 输出文件的目录,缺省时或目录无效时输出到第一个有效文件所在的目录;

    Returns:
        str: 合并完成的文件路径
    
    Raises:
        ValueError: 如果{src_file_paths}中没有任何有效文件
    '''
    # 校验src_file_paths中的文件是否有效
    valid_file_paths = []
    for src_file_path in src_file_paths:
        if os.path.isfile(src_file_path) and os.path.splitext(src_file_path)[1].lower() == '.pdf':
            valid_file_paths.append(src_file_path)
    _LOGGER.debug('[Converter/document/merge_PDF] valid_file_paths = "{}".'.format(valid_file_paths))
    # 校验dst_dir_path是否有效
    if not dst_dir_path or not os.path.isdir(dst_dir_path):
        dst_dir_path = os.path.dirname(valid_file_paths[0])
    dst_file_path = os.path.join(dst_dir_path, 'output.pdf')
    
    # 合并PDF
    if len(valid_file_paths) == 0:
        raise ValueError('Not enough PDFs.')
    elif len(valid_file_paths) == 1:
        shutil.copy(valid_file_paths[0], dst_file_path)
    else:
        merger = PdfFileMerger() 
        for src_file_path in valid_file_paths: 
            _LOGGER.debug('[Converter/document/merge_PDF] Reading "{}".'.format(src_file_path))
            with open(src_file_path, 'rb') as f: 
                merger.append(PdfFileReader(f), 'rb') 
        _LOGGER.info('[Converter/document/merge_PDF] Writing "{}".'.format(dst_file_path))
        with open(dst_file_path, 'wb') as f: 
            merger.write(f) 

    return dst_file_path
예제 #8
0
파일: Merge.py 프로젝트: ale10bb/Converter
def main():
    # argparse:传入path
    parser = argparse.ArgumentParser(prog='Merge',
                                     description='读取所有输入的Word文件,转换后合并PDF。')
    # 传入preserve,保留合并时产生的临时文件
    parser.add_argument('-p',
                        '--preserve',
                        default=False,
                        action='store_true',
                        help='preserve temp PDF')
    parser.add_argument('path', nargs='+', help='file path or dir path')
    args = parser.parse_args()
    preserve = args.preserve
    _LOGGER.info('[Merge] Started.')

    # 过滤doc/docx/pdf
    _LOGGER.debug('[Merge] arg_paths = "{}".'.format(args.path))
    # 传入的参数有顺序要求,不能使用set
    target_paths = []
    for arg_path in args.path:
        target_paths.extend(
            Converter.walk.file(arg_path, ['.doc', '.docx', '.pdf']))
    _LOGGER.debug('[Merge] target_paths = "{}".'.format(target_paths))

    # 调用Converter.document处理
    temp_PDF_paths = []
    try:
        for target_path in target_paths:
            temp_PDF_paths.append(Converter.document.convert_PDF(target_path))
        Converter.document.merge_PDF(temp_PDF_paths)
        if not preserve:
            for temp_PDF_path in set(temp_PDF_paths).difference(target_paths):
                os.remove(temp_PDF_path)
    except Exception as err:
        _LOGGER.warning('[Merge] Merge failure due to "{}"'.format(err))

    _LOGGER.info('[Merge] Finished.')
예제 #9
0
def main():
    # 目前本地数据库文件必须位于可执行文件的同目录下
    db_file_path = os.path.join(os.path.dirname(sys.argv[0]), 'vulns.sqlite3')
    # argparse:传入path
    parser = argparse.ArgumentParser(
        prog='Nessus',
        description='读取Nessus的CSV文件,将描述文字翻译成中文,转换结果分别保存至每个原始文件的同目录下。')
    parser.add_argument('path', nargs='+', help='file path or dir path')
    args = parser.parse_args()

    _LOGGER.info('[Nessus] Started.')
    # 本地数据库无效时,使用服务器版本强制覆盖
    if not Converter.sqlite.isvalid_Nessus(db_file_path):
        _LOGGER.warning('[Nessus] Invalid local DB. Downloading...')
        Converter.sqlite.update_Nessus(db_file_path)
    # 过滤csv并去重
    _LOGGER.debug('[Nessus] arg_paths = "{}".'.format(args.path))
    target_paths = set()
    for arg_path in args.path:
        target_paths = target_paths.union(
            set(Converter.walk.file(arg_path, ['.csv'])))
    _LOGGER.debug('[Nessus] target_paths = "{}".'.format(target_paths))

    # 调用Converter.csv处理
    count = 0
    for target_path in target_paths:
        try:
            rows = Converter.csv.read_Nessus(target_path, db_file_path)
            Converter.csv.write(
                rows,
                os.path.splitext(target_path)[0] + '_converted.csv')
            count += 1
        except Exception as err:
            _LOGGER.warning(
                '[Nessus] Conversion failure due to "{}"'.format(err))

    _LOGGER.info('[Nessus] Finished with {} converted.'.format(count))