1529291b by 周伟奇

add field order & add RP

1 parent cc0dc16d
...@@ -79,7 +79,7 @@ META_SHEET_TITLE = '关键信息提取和展示' ...@@ -79,7 +79,7 @@ META_SHEET_TITLE = '关键信息提取和展示'
79 FIXED_HEADERS = ('记账日期', '记账时间', '金额', '余额', '交易名称', '附言', '对方账户名', '对方卡号/账号', 79 FIXED_HEADERS = ('记账日期', '记账时间', '金额', '余额', '交易名称', '附言', '对方账户名', '对方卡号/账号',
80 '对方开户行', '核对结果', '借贷', '收入', '支出') 80 '对方开户行', '核对结果', '借贷', '收入', '支出')
81 FIXED_COL_AMOUNT = len(FIXED_HEADERS) 81 FIXED_COL_AMOUNT = len(FIXED_HEADERS)
82 BASE_HEADERS_MAPPING = {label: idx+1 for idx, label in enumerate(FIXED_HEADERS)} 82 BASE_HEADERS_MAPPING = {label: idx + 1 for idx, label in enumerate(FIXED_HEADERS)}
83 BORROW_HEADER_COL = BASE_HEADERS_MAPPING['借贷'] 83 BORROW_HEADER_COL = BASE_HEADERS_MAPPING['借贷']
84 INCOME_HEADER_COL = BASE_HEADERS_MAPPING['收入'] 84 INCOME_HEADER_COL = BASE_HEADERS_MAPPING['收入']
85 OUTLAY_HEADER_COL = BASE_HEADERS_MAPPING['支出'] 85 OUTLAY_HEADER_COL = BASE_HEADERS_MAPPING['支出']
...@@ -583,47 +583,238 @@ OTHER_CLASSIFY = 2 ...@@ -583,47 +583,238 @@ OTHER_CLASSIFY = 2
583 # 身份证 583 # 身份证
584 IC_CN_NAME = '身份证' 584 IC_CN_NAME = '身份证'
585 IC_CLASSIFY = 33 585 IC_CLASSIFY = 33
586 IC_FIELD_ORDER = () 586 IC_FIELD_ORDER_0 = (('姓名', '姓名'),
587 ('公民身份号码', '公民身份号码'),
588 ('出生年月', '出生年月'),
589 ('住址', '住址'),
590 ('性别', '性别'),
591 ('民族', '民族'),)
592 IC_FIELD_ORDER_1 = (('有效期限', '有效期限'), ('签发机关', '签发机关'),)
593 # 居住证
594 RP_CN_NAME = '身份证'
595 RP_CLASSIFY = 10087
596 RP_FIELD_ORDER_0 = (('姓名', '姓名'),
597 ('公民身份号码', '公民身份号码'),
598 ('出生年月', '出生年月'),
599 ('住址', '住址'),
600 ('性别', '性别'),)
601 RP_FIELD_ORDER_1 = IC_FIELD_ORDER_1
587 # 增值税发票 602 # 增值税发票
588 VAT_CN_NAME = '增值税发票' 603 VAT_CN_NAME = 'VAT普票'
589 VAT_CLASSIFY = 0 604 VAT_CLASSIFY = 0
590 VAT_FIELD_ORDER = () 605 VAT_FIELD_ORDER = (('发票代码', '发票代码'),
606 ('发票代码(开具)', '发票代码(开具)'),
607 ('发票号码', '发票号码'),
608 ('发票号码(开具)', '发票号码(开具)'),
609 ('开票日期', '开票日期'),
610 ('校验码', '校验码'),
611 ('货物或应税劳务、服务名称', '货物或应税劳务、服务名称'),
612 ('金额合计', '开具金额合计(不含税)'),
613 ('税率', '税率'),
614 ('税额合计', '税额合计'),
615 ('价税合计小写', '价税合计(小写)'),
616 ('价税合计大写', '价税合计(大写)'),
617 ('购方名称', '购买方名称'),
618 ('购方纳税人识别号', '购买方纳税人识别号'),
619 ('购方地址、电话', '购买方地址、电话'),
620 ('购方开户行及账号', '购买方开户行及账号'),
621 ('销方名称', '销售方名称'),
622 ('销方纳税人识别号', '销售方纳税人识别号'),
623 ('销方地址、电话', '销售方地址、电话'),
624 ('销方开户行及账号', '销售方开户行及账号'),
625 ('销售方:(章)', '销售方:(章)'),
626 ('备注', '备注'),)
591 # 机动车登记证书 627 # 机动车登记证书
592 MVC_CN_NAME = '机动车登记证书' 628 MVC_CN_NAME = '机动车登记证书'
593 MVC_CLASSIFY = 28 629 MVC_CLASSIFY = 28
594 MVC_FIELD_ORDER = () 630 MVC_CLASSIFY_SE = 10086
595 MVC_SE_FIELD_ORDER = () 631 MVC_FIELD_ORDER_1_2 = (('1.机动车所有人/身份证名称/号码', '机动车所有人/身份证明名称/号码'),
632 ('3.登记日期', '登记日期'),
633 ('9.车辆识别代号/车架号', '车辆识别代号/车架号'),
634 ('32.车辆出厂日期', '车辆出厂日期'),
635 ('34.发证日期', '发证日期'),
636 ('30.使用性质', '使用性质'),
637 ('31.车辆获得方式', '车辆获得方式'),
638 ('4.机动车登记编号', '机动车登记编号'),
639 ('空行占位', None),
640 ('5.车辆类型', '车辆类型'),
641 ('6.车辆品牌', '车辆品牌'),
642 ('7.车辆型号', '车辆型号'),
643 ('8.车身颜色', '车身颜色'),
644 ('10.国产/进口', '国产/进口'),
645 ('11.发动机号', '发动机号'),
646 ('12.发动机型号', '发动机型号'),
647 ('15.制造厂名称', '制造厂名称'),
648 ('2.登记机关', '登记机关'),
649 ('编号', '机动车登记证书编号'),)
650 MVC_FIELD_ORDER_3_4 = (
651 ('姓名/名称', '姓名/名称'),
652 ('身份证明名称/号码', '身份证明名称/号码'),
653 ('转移登记日期', '转移登记日期'),
654 )
655 MVC_SE_FIELD_ORDER_1_2 = (('9.车辆识别代号/车架号', '车辆识别代号/车架号'),
656 ('1.机动车所有人/身份证名称/号码', '机动车所有人/身份证明名称/号码'),
657 ('空行占位', None),
658 ('3.登记日期', '登记日期'),
659 ('32.车辆出厂日期', '车辆出厂日期'),
660 ('34.发证日期', '发证日期'),
661 ('30.使用性质', '使用性质'),
662 ('31.车辆获得方式', '车辆获得方式'),
663 ('5.车辆类型', '车辆类型'),
664 ('6.车辆品牌', '车辆品牌'),
665 ('7.车辆型号', '车辆型号'),
666 ('8.车身颜色', '车身颜色'),
667 ('10.国产/进口', '国产/进口'),
668 ('11.发动机号', '发动机号'),
669 ('12.发动机型号', '发动机型号'),
670 ('13.燃料种类', '燃料种类'),
671 ('14.排量/功率', '排量/功率'),
672 ('15.制造厂名称', '制造厂名称'),
673 ('16.转向形式', '转向形式'),
674 ('17.轮距', '轮距'),
675 ('18.轮胎数', '轮胎数'),
676 ('19.轮胎规格', '轮胎规格'),
677 ('20.钢板弹簧片数', '钢板弹簧片数'),
678 ('21.轴距', '轴距'),
679 ('22.轴数', '轴数'),
680 ('23.外廓尺寸', ''),
681 ('24.货厢内部尺寸', ''),
682 ('25.总质量', ''),
683 ('26.核定载质量', ''),
684 ('27.核定载客', ''),
685 ('28.准牵引总质量', ''),
686 ('29.驾驶室载客', ''),
687 ('2.登记机关', '登记机关'),
688 ('4.机动车登记编号', '机动车登记编号'),
689 ('编号', '机动车登记证书编号'),)
690 MVC_SE_FIELD_ORDER_3_4 = (
691 ('姓名/名称', '姓名/名称'),
692 ('身份证明名称/号码', '身份证明名称/号码'),
693 ('转移登记日期', '转移登记日期'),
694 )
596 # 机动车销售统一发票 695 # 机动车销售统一发票
597 MVI_CN_NAME = '机动车销售统一发票' 696 MVI_CN_NAME = '机动车销售统一发票'
598 MVI_CLASSIFY = 29 697 MVI_CLASSIFY = 29
599 MVI_FIELD_ORDER = () 698 MVI_FIELD_ORDER = (('发票代码', '发票代码'),
699 ('发票号码', '发票号码'),
700 ('开票日期', '开票日期'),
701 ('不含税价', '不含税价'),
702 ('发票类型', '发票联'),
703 ('购方名称', '购买方名称'),
704 ('购买方身份证号或组织机构代码', '购买方证件号码'),
705 ('纳税人识别号', '纳税人识别号'), # nodo
706 ('车辆识别代码', '车架号'),
707 ('价税合计小写', '价税合计小写'),
708 ('销方名称', '销货单位名称'),
709 ('增值税税额', '增值税税额'),
710 ('增值税税率', '增值税税率'), # nodo
711 ('发票章有无', '发票章有无'), # nodo 全国统一发票监制章 销售单位章
712 ('价税合计大写', '价税合计大写'), # nodo
713 ('', None),
714 ('发动机号码', '发动机号'),
715 ('车辆类型', '车辆类型'), # nodo
716 ('厂牌型号', '厂牌型号'), # nodo
717 ('产地', '产地'), # nodo
718 ('合格证号', '合格证号'), # nodo
719 ('进口证明书号', '进口证明书号'), # nodo
720 ('商检单号', '商检单号'), # nodo
721 ('电话', '电话'), # nodo
722 ('销方纳税人识别号', '销货方纳税人识别号'),
723 ('账号', '账号'), # nodo
724 ('地址', '地址'), # nodo
725 ('开户银行', '开户银行'), # nodo
726 ('主管税务机关及代码', '主管税务机关及代码'), # nodo
727 ('吨位', '吨位'), # nodo
728 ('限乘人数', '限乘人数'),) # nodo
600 IC_PID = VAT_PID = MVC_PID = MVI_PID = None 729 IC_PID = VAT_PID = MVC_PID = MVI_PID = None
601 730
602 # 营业执照 731 # 营业执照
603 BL_CN_NAME = '营业执照' 732 BL_CN_NAME = '营业执照'
604 BL_CLASSIFY = 31 733 BL_CLASSIFY = 31
605 BL_PID = 41 734 BL_PID = 41
606 BL_FIELD_ORDER = () 735 BL_FIELD_ORDER = (('注册号', '统一社会信用代码'),
736 ('企业名称', '名称'),
737 ('企业类型', '类型'),
738 ('经营者姓名', '法定代表人'),
739 ('成立日期', '成立日期'),
740 ('营业期限', '营业期限'),
741 ('注册资本', '注册资本'),
742 ('地址', '住所'),
743 ('经营范围', '经营范围'),)
607 # 二手车发票 744 # 二手车发票
608 UCI_CN_NAME = '二手车发票' 745 UCI_CN_NAME = '二手车发票'
609 UCI_CLASSIFY = 1 746 UCI_CLASSIFY = 1
610 UCI_PID = 60 747 UCI_PID = 60
611 UCI_FIELD_ORDER = () 748 UCI_FIELD_ORDER = (('发票代码', '发票代码'),
749 ('发票号码', '发票号码'),
750 ('开票日期', '开票日期'),
751 ('车价合计', '车价合计小写'),
752 ('发票联', '发票联'),
753 ('购方单位', '买方单位/个人'),
754 ('购方号码', '买方单位代码/身份证号码'),
755 ('车架号码', '车架号'),
756 ('车价合计大写', '车价合计大写'),
757 ('二手车市场', '二手车市场'),
758 ('发票章有无', '发票章有无'),
759 ('空行占位', None),
760 ('车牌照号', '车牌照号'),
761 ('登记证号', '登记证号'),
762 ('购方地址', '买方单位/住址'),
763 ('车辆类型', '车辆类型'),
764 ('厂牌型号', '厂牌型号'),
765 ('车管所名称', '转入地车辆管理所名称'),
766 ('销方名称', '卖方单位/个人'),
767 ('销方号码', '卖方单位代码/身份证号码'),
768 ('销方地址', '卖方单位/个人住址'),)
612 # 港澳台通行证 769 # 港澳台通行证
613 EEP_CN_NAME = '港澳台通行证' 770 EEP_CN_NAME = '港澳台通行证'
614 EEP_CLASSIFY = 30 771 EEP_CLASSIFY = 30
615 EEP_PID = 1018 772 EEP_PID = 1018
616 EEP_FIELD_ORDER = () 773 EEP_FIELD_ORDER = (('中文名', '姓名'), # 英文名
774 ('证件号码', '证件号码'),
775 ('签发次数', '换证次数(签发次数)'),
776 ('有效期限', '有效期限'),
777 ('出生日期', '出生日期'),
778 ('性别', '性别'),
779 ('签发机关', '签发机关'),
780 ('签发地点', '签发地点'),)
617 # 行驶证 781 # 行驶证
618 DL_CN_NAME = '行驶证' 782 DL_CN_NAME = '行驶证'
619 DL_CLASSIFY = 32 783 DL_CLASSIFY = 32
620 DL_PID = 5 784 DL_PID = 5
621 DL_FIELD_ORDER = () 785 DL_FIELD_ORDER_0 = (('号牌号码', '1 号牌号码'),
786 ('所有人', '3 所有人'),
787 ('使用性质', '5 使用性质'),
788 ('车辆识别代码', '7 车辆识别代号'),
789 ('注册日期', '9 注册日期'),
790 ('发证日期', '10 发证日期'),
791 ('车辆类型', '2 车辆类型'),
792 ('地址', '4 住址'),
793 ('品牌型号', '6 品牌型号'),
794 ('发动机号', '8 发动机号码'),)
795 DL_FIELD_ORDER_1 = (('号牌号码', '1 号牌号码'),
796 ('档案编号', '11 档案编号'),
797 ('核定载人数', '12 核定载人数'),
798 ('总质量', '13 总质量'),
799 ('整备质量', '14 整备质量'),
800 ('核定载质量', '15 核对载质量'),
801 ('外廓尺寸', '16 外廓尺寸'),
802 ('准牵引总质量', '17 准牵引总质量'),)
622 # 护照 803 # 护照
623 PP_CN_NAME = '护照' 804 PP_CN_NAME = '护照'
624 PP_CLASSIFY = 3 805 PP_CLASSIFY = 3
625 PP_PID = 8 806 PP_PID = 8
626 PP_FIELD_ORDER = () 807 PP_FIELD_ORDER = (('类型', '类型/Type'),
808 ('英文姓名', '姓名/Name'),
809 ('护照号码', '护照号码/Passport No'),
810 ('有效期至', '有效期至/Date of expiry'),
811 ('签发日期', '签发日期/Date of issue'),
812 ('国家码', '国家码/Country Code'),
813 ('性别', '性别/Sex'),
814 ('国籍', '国籍/Nationality'),
815 ('出生日期', '出生日期/Date of birth'),
816 ('出生地点', '出生地点/Place of birth'),
817 ('签发地点', '签发地点/Place of issue'),)
627 # 银行卡 818 # 银行卡
628 BC_CN_NAME = '银行卡' 819 BC_CN_NAME = '银行卡'
629 BC_CLASSIFY = 37 820 BC_CLASSIFY = 37
...@@ -640,16 +831,25 @@ BC_FIELD_ORDER = (('BankName', '发卡行名称'), ...@@ -640,16 +831,25 @@ BC_FIELD_ORDER = (('BankName', '发卡行名称'),
640 831
641 SUCCESS_CODE_SET = {'0', 0} 832 SUCCESS_CODE_SET = {'0', 0}
642 833
643 LICENSE_ORDER = ((MVI_CLASSIFY, (MVI_PID, MVI_CN_NAME, MVI_FIELD_ORDER)), 834 FIELD_ORDER_MAP = {
644 (IC_CLASSIFY, (IC_PID, IC_CN_NAME, IC_FIELD_ORDER)), 835 IC_CLASSIFY: ('有效期限', IC_FIELD_ORDER_1, IC_FIELD_ORDER_0),
645 (BC_CLASSIFY, (BC_PID, BC_CN_NAME, BC_FIELD_ORDER)), 836 RP_CLASSIFY: ('有效期限', RP_FIELD_ORDER_1, RP_FIELD_ORDER_0),
646 (BL_CLASSIFY, (BL_PID, BL_CN_NAME, BL_FIELD_ORDER)), 837 DL_CLASSIFY: ('档案编号', DL_FIELD_ORDER_1, DL_FIELD_ORDER_0),
647 (UCI_CLASSIFY, (UCI_PID, UCI_CN_NAME, UCI_FIELD_ORDER)), 838 MVC_CLASSIFY: ('转移登记日期', MVC_FIELD_ORDER_3_4, MVC_FIELD_ORDER_1_2),
648 (EEP_CLASSIFY, (EEP_PID, EEP_CN_NAME, EEP_FIELD_ORDER)), 839 MVC_CLASSIFY_SE: ('转移登记日期', MVC_SE_FIELD_ORDER_3_4, MVC_SE_FIELD_ORDER_1_2)
649 (DL_CLASSIFY, (DL_PID, DL_CN_NAME, DL_FIELD_ORDER)), 840 }
650 (PP_CLASSIFY, (PP_PID, PP_CN_NAME, PP_FIELD_ORDER)), 841
651 (MVC_CLASSIFY, (MVC_PID, MVC_CN_NAME, MVC_FIELD_ORDER)), 842 LICENSE_ORDER = ((MVI_CLASSIFY, (MVI_PID, MVI_CN_NAME, MVI_FIELD_ORDER, False, False)),
652 (VAT_CLASSIFY, (VAT_PID, VAT_CN_NAME, VAT_FIELD_ORDER))) 843 (IC_CLASSIFY, (IC_PID, IC_CN_NAME, None, True, False)),
844 (RP_CLASSIFY, (None, RP_CN_NAME, None, True, False)),
845 (BC_CLASSIFY, (BC_PID, BC_CN_NAME, BC_FIELD_ORDER, False, False)),
846 (BL_CLASSIFY, (BL_PID, BL_CN_NAME, BL_FIELD_ORDER, False, False)),
847 (UCI_CLASSIFY, (UCI_PID, UCI_CN_NAME, UCI_FIELD_ORDER, False, False)),
848 (EEP_CLASSIFY, (EEP_PID, EEP_CN_NAME, EEP_FIELD_ORDER, False, False)),
849 (DL_CLASSIFY, (DL_PID, DL_CN_NAME, None, True, False)),
850 (PP_CLASSIFY, (PP_PID, PP_CN_NAME, PP_FIELD_ORDER, False, False)),
851 (MVC_CLASSIFY, (MVC_PID, MVC_CN_NAME, None, True, True)),
852 (VAT_CLASSIFY, (VAT_PID, VAT_CN_NAME, VAT_FIELD_ORDER, False, False)))
653 853
654 LICENSE_CLASSIFY_MAPPING = dict(LICENSE_ORDER) 854 LICENSE_CLASSIFY_MAPPING = dict(LICENSE_ORDER)
655 855
......
...@@ -159,6 +159,7 @@ class Command(BaseCommand, LoggerMixin): ...@@ -159,6 +159,7 @@ class Command(BaseCommand, LoggerMixin):
159 ed_list.append(summary[6]) 159 ed_list.append(summary[6])
160 160
161 def license1_process(self, ocr_data, license_summary, classify, skip_img, img_path): 161 def license1_process(self, ocr_data, license_summary, classify, skip_img, img_path):
162 # 类别:'0'身份证, '1'居住证
162 license_data = ocr_data.get('data', []) 163 license_data = ocr_data.get('data', [])
163 if not license_data: 164 if not license_data:
164 skip_img.append(self.parse_img_path(img_path)) 165 skip_img.append(self.parse_img_path(img_path))
...@@ -174,7 +175,7 @@ class Command(BaseCommand, LoggerMixin): ...@@ -174,7 +175,7 @@ class Command(BaseCommand, LoggerMixin):
174 # res_dict[chn_key] = ocr_res_2.get(en_key, '') 175 # res_dict[chn_key] = ocr_res_2.get(en_key, '')
175 license_summary.setdefault(classify, []).append(ocr_res_2) 176 license_summary.setdefault(classify, []).append(ocr_res_2)
176 else: 177 else:
177 # 营业执照、行驶证 178 # 营业执照等
178 for result_dict in ocr_res_2.get('ResultList', []): 179 for result_dict in ocr_res_2.get('ResultList', []):
179 res_dict = {} 180 res_dict = {}
180 for field_dict in result_dict.get('FieldList', []): 181 for field_dict in result_dict.get('FieldList', []):
...@@ -224,7 +225,7 @@ class Command(BaseCommand, LoggerMixin): ...@@ -224,7 +225,7 @@ class Command(BaseCommand, LoggerMixin):
224 elif classify in consts.LICENSE_CLASSIFY_SET_1: # 证件1 225 elif classify in consts.LICENSE_CLASSIFY_SET_1: # 证件1
225 self.license1_process(ocr_data, license_summary, classify, skip_img, img_path) 226 self.license1_process(ocr_data, license_summary, classify, skip_img, img_path)
226 elif classify in consts.LICENSE_CLASSIFY_SET_2: # 证件2 227 elif classify in consts.LICENSE_CLASSIFY_SET_2: # 证件2
227 pid, _, _ = consts.LICENSE_CLASSIFY_MAPPING.get(classify) 228 pid, _, _, _, _ = consts.LICENSE_CLASSIFY_MAPPING.get(classify)
228 json_data_2 = { 229 json_data_2 = {
229 "pid": str(pid), 230 "pid": str(pid),
230 "key": conf.OCR_KEY, 231 "key": conf.OCR_KEY,
...@@ -490,8 +491,7 @@ class Command(BaseCommand, LoggerMixin): ...@@ -490,8 +491,7 @@ class Command(BaseCommand, LoggerMixin):
490 # 识别失败:普通异常,如PDF异常、构建过程异常 491 # 识别失败:普通异常,如PDF异常、构建过程异常
491 # EDMS异常:下载异常-->回队列-->邮件;上传异常-->重新上传队列-->邮件 492 # EDMS异常:下载异常-->回队列-->邮件;上传异常-->重新上传队列-->邮件
492 # 算法异常:第一道异常-->识别失败-->邮件;第二道异常-->识别失败-->邮件 493 # 算法异常:第一道异常-->识别失败-->邮件;第二道异常-->识别失败-->邮件
493 # TODO 协程异步发送OCR请求 494 # TODO OCR接口调用重试
494 # TODO 调用接口重试
495 # TODO 数据库断联问题 495 # TODO 数据库断联问题
496 def handle(self, *args, **kwargs): 496 def handle(self, *args, **kwargs):
497 sleep_second = int(conf.SLEEP_SECOND) 497 sleep_second = int(conf.SLEEP_SECOND)
......
...@@ -360,15 +360,20 @@ class BSWorkbook(Workbook): ...@@ -360,15 +360,20 @@ class BSWorkbook(Workbook):
360 self.remove(self.get_sheet_by_name(sheet)) 360 self.remove(self.get_sheet_by_name(sheet))
361 361
362 def license_rebuild(self, license_summary, document_scheme): 362 def license_rebuild(self, license_summary, document_scheme):
363 for classify, (_, name, field_order) in consts.LICENSE_ORDER: 363 for classify, (_, name, field_order, side_diff, scheme_diff) in consts.LICENSE_ORDER:
364 # 机动车登记证:CA和SE不同顺序
365 if classify == consts.MVC_CLASSIFY and document_scheme == consts.DOC_SCHEME_LIST[1]:
366 field_order = consts.MVC_SE_FIELD_ORDER
367 license_list = license_summary.get(classify) 364 license_list = license_summary.get(classify)
368 if license_list is None: 365 if not license_list:
369 continue 366 continue
370 ws = self.create_sheet(name) 367 ws = self.create_sheet(name)
368 if scheme_diff and document_scheme == consts.DOC_SCHEME_LIST[1]:
369 classify = consts.MVC_CLASSIFY_SE
371 for license_dict in license_list: 370 for license_dict in license_list:
371 if classify == consts.IC_CLASSIFY and license_dict.get('类别') == '1':
372 license_summary.setdefault(consts.RP_CLASSIFY, []).append(license_dict)
373 continue
374 if side_diff:
375 key, field_order_yes, field_order_no = consts.FIELD_ORDER_MAP.get(classify)
376 field_order = field_order_yes if key in license_dict else field_order_no
372 for search_field, write_field in field_order: 377 for search_field, write_field in field_order:
373 ws.append((write_field, license_dict.get(search_field, ''))) 378 ws.append((write_field, license_dict.get(search_field, '')))
374 ws.append((None, )) 379 ws.append((None, ))
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!