# encoding:utf-8

import csv
import re
import copy
import json
import time
import sys
import os
import argparse
import requests
from loguru import logger
from requests_toolbelt import MultipartEncoder
from xmindparser import xmind_to_dict

class Zentao:
    
    # 根据命名规则配置
    PRODUCTS_MAP = {
        "后台+店铺": ["油葱运营后台", "PC店铺", "APP店铺", "智能客服"],
        "商城前端": ["油葱PC", "油葱APP", "油葱小程序"],
        "健康前端": ["健康小程序"],
        "后台+门店": ["健康运营后台", "健康门店系统"]
    }
    
    SUBTASKNAME_MAP = {
        "油葱运营后台": "【后台】",
        "PC店铺": "【店铺】【PC】",
        "APP店铺": "【店铺】【APP】",
        "智能客服": "客服",
        "油葱PC": "【PC】",
        "油葱APP": "【APP】",
        "油葱小程序": "【MP】",
        "健康小程序": "【健康前端】",
        "健康运营后台": "【后台】",
        "健康门店系统": "【门店】"
    }
    # 获取产品别名
    pattern = re.compile(r"【测试】【(\S+)】【\S+】")
    
    def __init__(self, account, password, projectname):
        self.session = requests.session()
        self.base_url = BASE_URL
        self.account = account # 用户账号
        self.password = password # 密码
        self.projectname = projectname # 项目名称
        self.status = ["wait", "doing", "done"] # 任务状态
        self.cookies = self._login(self.account, self.password)
        self.project_id = self._get_project_id(self.projectname)
    
    def _get_session_id(self):
        "获取SessionID,登录要用"
        url = f"{self.base_url}/api-getSessionID.json"
        r = self.session.get(url)
        return json.loads(r.json()["data"])["sessionID"]
      
    def _login(self, account, password):
        "登录，获取token，后续接口要用"

        sessionID = self._get_session_id()
        data = {
            "account": account,
            "password": password,
            "zentaosid": sessionID
        }
        url = f"{self.base_url}/user-login.json"
        r = self.session.post(url, data)

        return r.json()

    def _get_project_id(self, productname):
        "获取项目"
        url = f"{self.base_url}/project-index-no.json"
        r= self.session.get(url)
        
        for k, v in json.loads(r.json()["data"])["projects"].items():
            if v == productname:
                self.project_id = k
        return self.project_id

    def _get_project_products_modules(self, project_id):
        "获取项目-产品模块"
        url = f"{self.base_url}/project-task-{project_id}.json"
        r= self.session.get(url)
        sproducts_dict = {} # 项目产品
        modules_dict = {} # 项目产品模块
        for k, v in json.loads(r.json()["data"]).items():
            # 项目产品信息
            if k == "products":
                for i in v.values():
                    sproducts_dict[i["id"]] = i["name"]
            # 项目模块信息
            elif k == "modules":
                modules_dict = v
             
        return sproducts_dict, modules_dict
                 
    def _get_project_stories(self, project_id):
        "获取项目-产品需求"
        url = f"{self.base_url}/project-story-{project_id}.json"
        r= self.session.get(url)
        stories = []
        for k, v in json.loads(r.json()["data"]).items():
            # 需求信息
            if k == "stories":
                for story in v.values():
                    if story["status"] == "active": # 激活的需求
                        stories.append({
                            'project': story['project'], # 需求所属项目编号
                            'product': story['product'], # 需求所属产品编号
                            'story': story['story'], # 需求编号
                            'parent': story['parent'], # 需求所属父需求编号，0表示没有父需求
                            'module': story['module'], # 需求所属模块编号
                            'title': story['title'], # 需求标题
                        })
        return stories

    def _parse_stories(self, project_id, nicknames=["后台+店铺", "商城前端"]):
        """
        解析项目-需求，找出目标产品列表所属需求，并解析字段
        需求所属项目编号,需求所属产品编号,需求所属模块编号,需求编号,需求所属父需求编号,需求标题,需求所属产品名称,需求所属模块名称
        """
        
        sproducts_dict, modules_dict = self._get_project_products_modules(project_id)
        stories_list = self._get_project_stories(project_id)
        # 解析目标产品
        productnames = []
        for nickname in nicknames:
            if self.PRODUCTS_MAP.get(nickname, None):
                productnames.extend(self.PRODUCTS_MAP.get(nickname, None))
            else:
                logger.error(f"{nickname} 不存在，请确认名称是否符合规范！")
        # 进保存目标产品名称: id        
        products = {}
        for id, name in sproducts_dict.items():
            if name in productnames:
                products[id] = name
        # 仅保存目标产品的需求,且加上所属产品名称,所属模块名称
        stories = []
        for nickname in range(len(stories_list)):
            if stories_list[nickname]['product'] in products.keys():
                stories_list[nickname]["productname"] = products[stories_list[nickname]['product']] # 需求所属产品名称
                stories_list[nickname]["modulename"] = modules_dict[stories_list[nickname]['module']] # 需求所属模块名称
                stories.append(stories_list[nickname])
                
        logger.debug(stories)
        return stories
              
    def _get_project_products_no(self, project_id, productname):
        "获取项目-产品编号"
        url = f"{self.base_url}/project-story-{project_id}.json"
        r = self.session.get(url)
        for k, v in json.loads(r.json()["data"])["products"].items():
            if v["name"] == productname:
                product_no = k
                
        return product_no

    def _get_products_tree_browse(self, product_no):
        "获取产品-模块"
        sons_dict = []
        url = f"{self.base_url}/tree-browse-{product_no}-story.json"
        r = self.session.get(url)
        for i in json.loads(r.json()["data"])["sons"]:
            sons_dict.append({"id": i["id"], "name": i["name"]})

        return sons_dict

    def _get_project_story(self, project_id, productname):
        """
        获取项目-产品-需求
        productname: 必须和禅道中的产品名称一致
        """
        product_no = self._get_project_products_no(project_id, productname)
        url = f"{self.base_url}/project-story-{project_id}--byProduct-{product_no}.json"
        r = self.session.get(url)
        # 遍历需求
        stories_dict = {}
        for k, v in json.loads(r.json()["data"])["stories"].items():
            stories_dict[k] = {"title": v["title"], "module": v["module"]}
        
        return stories_dict
       
    def _get_task(self, project_id, nicknames=["后台+店铺", "商城前端"]):
        "获取目标项目中，名称中包含nickname的test主任务"
        url = f"{self.base_url}/project-task-{project_id}.json"
        r = self.session.get(url)
        tasks_dict = {}
        tasks = json.loads(r.json()["data"])["tasks"]
        if tasks:
            for k, v in tasks.items():
                if v["type"] == "test" and (v["parent"] in ["0", "-1"]) and (v["status"] in self.status):
                    for nickname in nicknames:
                        if v["name"].find(nickname) > 0:
                            tasks_dict[v["name"]] = k
            return tasks_dict

        return tasks

    def _get_subtask(self, project_id, nicknames=["后台+店铺", "商城前端"]):
        "获取目标项目中，名称中包含nickname的test主任务下的子任务"
         
        url = f"{self.base_url}/project-task-{project_id}.json"
        r = self.session.get(url)
        subtasks_dict = {}
        tasks = json.loads(r.json()["data"])["tasks"]
        if tasks:
            for k, v in tasks.items():
                for nickname in nicknames:  
                    if v["name"].find(nickname) > 0 and v["type"] == "test" and (v["parent"] in ["0", "-1"]) and (v["status"] in self.status) and v.get("children", None):
                        for id, task_dict in v["children"].items():
                            if task_dict["type"] == "test" and task_dict["parent"] == k and (task_dict["status"] in self.status):
                                subtasks_dict[task_dict["name"]] = id
            return subtasks_dict

        return tasks

    def task_delete(self, project_id, taskid):
        "删除任务"
        url = f"{self.base_url}/task-delete-{project_id}-{taskid}-yes.json"
        r = self.session.get(url)
        logger.debug(r.json()["status"])
           
    def task_create(self, project_id, nicknames=["后台+店铺", "商城前端"]):
        """
        循环创建单个主任务
        project_id: 所属项目id
        productname: 产品平台名称，如 油葱运营后台
        """
        url = f"{self.base_url}/task-create-{project_id}--0.json"
        tasks_name = []
        for nickname in nicknames:
            tasks_name.extend([f"【测试】【{nickname}】【用例编写】", f"【测试】【{nickname}】【测试执行】"])
        tasks_dict = self._get_task(project_id)
        tasks = []
        if tasks_dict:
            for name in tasks_name:
                if name in [k for k in tasks_dict.keys()]:
                    logger.info(f"主任务已存在，无需新建：{name}")
                else:
                    tasks.append(name)
        else:
            tasks = tasks_name
        for task in tasks:
            m = MultipartEncoder(
                fields={
                "project": str(project_id), # 所属项目 *必填
                "type": "test", # 任务类型 取值范围： | design | devel | test | study | discuss | ui | affair | misc*必填
                "name": task, # 任务名称 *必填
                "module": "0", # 所属模块
                "assignedTo[]": self.account, # 指派给
                "pri": "1", # 优先级 取值范围：0 | 1 | 2 | 3 | 4
                "story": "", # 相关需求
                "color": "", # 标题颜色 颜色格式：#RGB，如：#3da7f5
                "desc": "", # 任务描述
                "mailto": "" # 抄送给 填写帐号，多个账号用','分隔。                    
                },
                boundary="----WebKitFormBoundaryIXlKvBV2kkJQ2g4E",
                encoding="utf-8"
            )
            r = self.session.post(url, data=m, headers={"Content-Type": m.content_type})
            logger.info(f"新建主任务：{task} {r.json()['message']}")
 
    def task_batch_create(self, project_id, nicknames=["后台+店铺", "商城前端"]):
        """
        批量创建主任务
        project_id: 所属项目id
        productnames: 产品平台名称，如 油葱运营后台
        """
        url = f"{self.base_url}/task-batchCreate-{project_id}--.json"
        tasks_name = []
        for name in nicknames:
            tasks_name.extend([f"【测试】【{name}】【用例编写】", f"【测试】【{name}】【测试执行】"])
            
        tasks_dict = self._get_task(project_id)
        tasks = []
        # 检测主任务是否已存在
        if tasks_dict:
            for name in tasks_name:
                if name in [k for k in tasks_dict.keys()]:
                    logger.info(f"主任务已存在，无需新建：{name}")
                else:
                    tasks.append(name)
        else:
            tasks = tasks_name
            
        fields = {}
        if tasks:
            for i in range(len(tasks)):
                fields[f"type[{i}]"] = "test" # 任务类型 取值范围： | design | devel | test | study | discuss | ui | affair | misc*必填
                fields[f"name[{i}]"] = tasks[i] # 任务名称 *必填
                fields[f"module[{i}]"] = "0" # 所属模块
                fields[f"story[{i}]"] = "0" # 关联需求
                fields[f"assignedTo[{i}]"] = self.account # 指派给
                fields[f"pri[{i}]"] = "1" # 优先级 取值范围：0 | 1 | 2 | 3 | 4
                
            m = MultipartEncoder(
                fields=fields,
                boundary="----WebKitFormBoundaryIXlKvBV2kkJQ2g4E",
                encoding="utf-8"
            )
            r = self.session.post(url, data=m, headers={"Content-Type": m.content_type})
            if r.json()["message"] == "保存成功":
                for task in tasks:
                    logger.info(f"新建主任务：{task} {r.json()['message']}")
            else:
                for task in tasks:
                    logger.error(f"新建主任务：{task} 失败！")                
        else:
            logger.debug(f"主任务都已存在，无需重复创建！")
                            
    def suubtask_to_csv(self, project_id, nicknames=["后台+店铺", "商城前端"], path="subtask.csv"):
        """
        获取项目-产品-需求，并导出子任务csv
        productnames: 必须和禅道中的产品名称一致
        """
        # # 获取需求
        # productnames = []
        # for nickname in nicknames:
        #     productnames.extend(self.PRODUCTS_MAP[nickname])
        # # 产品名称 去重
        # productnames = set(productnames)
        stories = self._parse_stories(project_id, nicknames)
                
        # 获取目标产品的，类型为test的主任务        
        tasks_dict = self._get_task(project_id, nicknames)
        if tasks_dict == {}:
            logger.error("请先创建主任务！")
            sys.exit(0)
        subtasks = []
        for taskname, taskid in tasks_dict.items(): # 遍历主任务
            for i in range(len(stories)): # 遍历需求
                if stories[i]["productname"] in self.PRODUCTS_MAP[self.pattern.search(taskname).group(1)]: # 该需求的测试子任务应建在该主任务下（根据需求所属产品判断）        
                    subtasks.append(copy.deepcopy(stories[i])) # 必须深复制
                    subtasks[-1]["taskid"] = taskid # 主任务id
                    subtasks[-1]["taskname"] = taskname # 主任务名称
                    subtasks[-1]["subtaskname"] = f"{self.SUBTASKNAME_MAP[stories[i]['productname']]}{stories[i]['modulename'][stories[i]['modulename'][1:].find('/')+2:].replace('/', '-').replace(' ', '')}{taskname[-6:]}" # 子任务名称
                    subtasks[-1]["type"] = "test" # 任务类型
                    subtasks[-1]["assignedTo"] = self.account # 指派给谁
                    subtasks[-1]["pri"] = 1 # 优先级
                    if "用例编写" in taskname:
                        subtasks[-1]["estimate"] = 4.5 # 预计工时
                    elif "测试执行" in taskname:                
                        subtasks[-1]["estimate"] = 7.5 # 预计工时                
                    else:
                        raise ValueError(f"主任务名称错误：{taskname}")
            
        # 清除不需要的键值对
        for i in range(len(subtasks)):
            subtasks[i].pop("product") # 产品编号
            subtasks[i].pop("parent") # 父需求id
            subtasks[i].pop("productname") # 产品名称
          
        try:
            with open(path, 'w', newline='', encoding='utf-8') as f:
                headline = ['project', 'story',  'module', 'title', 'modulename', 'taskid', 'taskname', 'subtaskname', 'type', 'assignedTo', 'pri', 'estimate']
                writer = csv.DictWriter(f, fieldnames=headline)
                writer.writeheader()
                for i in range(len(subtasks)):
                    writer.writerow(subtasks[i])
        except PermissionError:
            logger.error("请先关闭文件：{path}")
            sys.exit(0)
        else:
            logger.info("子任务已导出CSV文件，请自行修改重复的子任务名称！")

        return subtasks
                        
    def subtask_batch_create(self, path="subtask.csv"):
        """
        批量创建子任务
        project_id: 所属项目id
        name: 产品平台名称，如 油葱运营后台
        """
        try:
            with open(path, encoding="utf-8") as f:
                subtasks = f.readlines()
        except UnicodeDecodeError:
            with open(path, encoding="gbk") as f:
                subtasks = f.readlines()          
            
        # 检验子任务名称是否唯一, 是否已存在
        subtask_dict = self._get_subtask(self.project_id)
        tasksnames = []
        subtasks_02 = [] # 真正待创建的子任务清单
        reusable = False # 是否存在名称重复的子任务
        for i in range(len(subtasks)):
            tasksname = subtasks[i].split(",")[7]           
            if tasksnames.count(tasksname) > 0:
                reusable = True
                logger.error(f"子任务名称必须唯一：{i+1}:{tasksname}")
            if subtask_dict.get(tasksname, None):
                logger.warning(f"子任务已存在，无需新建：{tasksname}: {subtask_dict.get(tasksname, None)}")
            else:
                tasksnames.append(tasksname)
                subtasks_02.append(subtasks[i])
                
        if reusable: # 如果存在名称重复的子任务，则退出，等待修改
            sys.exit(0)
                
        tasks_list = []
        while len(subtasks_02) > 1:
            stk = subtasks_02.pop().strip()
            subtask = stk.split(",")
            if not tasks_list or (tasks_list and tasks_list[-1][5] == subtask[5]):
                 tasks_list.append(subtask)
            else:
                # 和前面主任务不同的子任务，要重新加入列表中
                subtasks_02.append(stk)                        
                url = f"{self.base_url}/task-batchCreate-{tasks_list[0][0]}-0-0-{tasks_list[0][5]}-0.json"                    
                fields = {}
                for i in range(len(tasks_list)):
                    fields[f"parent[{i}]"] = tasks_list[i][5] # 主任务
                    fields[f"type[{i}]"] = "test" # 任务类型 取值范围： | design | devel | test | study | discuss | ui | affair | misc*必填
                    fields[f"name[{i}]"] = tasks_list[i][7] # 任务名称 *必填
                    fields[f"module[{i}]"] = tasks_list[i][2] # 所属模块
                    fields[f"story[{i}]"] = tasks_list[i][1] # 关联需求
                    fields[f"assignedTo[{i}]"] = tasks_list[i][9] # 指派给
                    fields[f"pri[{i}]"] = tasks_list[i][10] # 优先级 取值范围：0 | 1 | 2 | 3 | 4
                    fields[f"estimate[{i}]"] = tasks_list[i][11] # 预计工时

                m = MultipartEncoder(
                    fields=fields,
                    boundary="----WebKitFormBoundaryIXlKvBV2kkJQ2g4E",
                    encoding="utf-8"
                )
                r = self.session.post(url, data=m, headers={"Content-Type": m.content_type})
                logger.debug(tasks_list)
                tasks_list = []
                
                logger.debug(r.json()["message"])
                time.sleep(2)
            if len(subtasks_02) <= 1 and tasks_list:
                url = f"{self.base_url}/task-batchCreate-{tasks_list[0][0]}-0-0-{tasks_list[0][5]}-0.json"                    
                fields = {}
                for i in range(len(tasks_list)):
                    fields[f"parent[{i}]"] = tasks_list[i][5] # 主任务
                    fields[f"type[{i}]"] = "test" # 任务类型 取值范围： | design | devel | test | study | discuss | ui | affair | misc*必填
                    fields[f"name[{i}]"] = tasks_list[i][7] # 任务名称 *必填
                    fields[f"module[{i}]"] = tasks_list[i][2] # 所属模块
                    fields[f"story[{i}]"] = tasks_list[i][1] # 关联需求
                    fields[f"assignedTo[{i}]"] = tasks_list[i][9] # 指派给
                    fields[f"pri[{i}]"] = tasks_list[i][10] # 优先级 取值范围：0 | 1 | 2 | 3 | 4
                    fields[f"estimate[{i}]"] = tasks_list[i][11] # 预计工时

                m = MultipartEncoder(
                    fields=fields,
                    boundary="----WebKitFormBoundaryIXlKvBV2kkJQ2g4E",
                    encoding="utf-8"
                )
                r = self.session.post(url, data=m, headers={"Content-Type": m.content_type})
                logger.debug(tasks_list)
                tasks_list = []
                
                logger.debug(r.json()["message"])
                time.sleep(2)                


class Xmind:

    pattern = re.compile(r"\(#(\d+)\)")
    
    def __init__(self, zentao, path):
        self.zentao = zentao
        self.path = path
        
    def xmind_to_tree(self, path):
        "把xmind文件解析成python dict,并返回xmind tree, onetitle"
        
        xmind = xmind_to_dict(path)
        tree = xmind[0]['topic']
        onetitle = tree['title']
        
        return tree, onetitle

    def parser_tree_to_list(self, tree, onetitle, titlelist=[]):
        "把xmind tree遍历成初始数据,并放到list中"
        
        if isinstance(tree, dict):
            if len(tree) >= 2:
                self.parser_tree_to_list(tree['topics'], str(onetitle), titlelist)
            if len(tree) == 1:
                self.parser_tree_to_list(tree['title'],str(onetitle), titlelist)

        elif isinstance(tree, list):
            for sontree in tree:
                self.parser_tree_to_list(sontree, str(onetitle)  + "_" + sontree['title'], titlelist)

        elif isinstance(tree,str):
            titlelist.append((str(onetitle) ))
                
        return titlelist
       
    def titlelist_delete_onetitle(self, titlelist):
        "删除titlelist中每个title中的第一个字段"
        
        caselist = []
        for title in titlelist:
            index = title.find("_")
            title = title[index + 1:]
            caselist.append(title)
                
        return caselist

    def find_step_and_expectation(self, caselist):
        "caselist 把测试步骤和期望拆解出来"
        
        # 把每条数据拆分成 标题 测试步骤 预期
        caselist02 = []
        for title in caselist:
            case = title.split("_")
            casetitle = "_".join(case[:-2])
            caselist02.append([casetitle, case[-2], case[-1]])
        
        # 把相同标题的数据中的 测试步骤 预期 合并, ['title', '步骤一\n步骤二', '预期一\n预期二']
        caselist03 = []   
        line = 1
        for case in caselist02:
            if caselist03:
                if case[0] == title:
                    caselist03[-1][1] += f"\n{line}.{case[1]}" # 禅道需要在步骤前面加序号
                    caselist03[-1][2] += f"\n{line}.{case[2]}" # 禅道需要在期望前面加序号
                    line += 1
                else:
                    line = 1 # 序号复原为1
                    caselist03.append(case)
                    title = caselist03[-1][0]
                    caselist03[-1][1] = f"{line}.{case[1]}" # 禅道需要在步骤前面加序号
                    caselist03[-1][2] = f"{line}.{case[2]}" # 禅道需要在期望前面加序号
                    line += 1
            else:
                caselist03.append(case)
                title = caselist03[-1][0]
                caselist03[-1][1] = f"{line}.{case[1]}" # 禅道需要在步骤前面加序号
                caselist03[-1][2] = f"{line}.{case[2]}" # 禅道需要在期望前面加序号
                line += 1
        
        return caselist03
           
    def testcaselist(self, caselist, tag):
        """
        ['title', '步骤一\n步骤二', '预期一\n预期二'] 
        调整成用例结构 
        ["所属模块", "相关需求", "优先级", "关键词", "前置条件","用例标题", "测试步骤", "预期结果"]
        
        """
        testcaselist = []
        for case in caselist:
            test = case[0].split("_")
            if case[0].find("_成功路径_") != -1:
                mudule = f'{case[0][:case[0].find("_成功路径_")]}'
                title = f'{case[0][:case[0].find("_成功路径_")+5]}: {test[-4]}'
            elif case[0].find("_失败路径_") != -1:
                mudule = f'{case[0][:case[0].find("_失败路径_")]}'
                title = f'{case[0][:case[0].find("_失败路径_")+5]}: {test[-4]}'
            else:
                raise Exception(f"{case[0]}: 没有找到对应的字段:成功路径&失败路径")
                
            testcaselist.append([mudule, f"(#{test[-2].upper()})", test[-3].upper(), tag.upper(), test[-1], title, case[1], case[2]])
        
        return testcaselist

    def parse_modules(self, caselist, nicknames=["后台+店铺", "商城前端"]):
        "把模块转成禅道上的模块id"
        stories = self.zentao._parse_stories(self.zentao.project_id, nicknames)
        exist = False # 是否有不存在的需求
        for case in caselist: # 遍历用例
            for storie in stories: # 遍历需求
                try:
                    if int(self.pattern.search(case[1]).group(1)) == int(storie["story"]):
                        logger.debug(f"{case[0]} : (#{storie['module']})")
                        case[0] = f"(#{storie['module']})"
                        break
                except AttributeError:
                    logger.error(f"{case[5]}:{case[1]} 用例所属需求编号不存在！")
            if case[0].find("#") < 0:
                logger.error(f"{case[5]}：{case[1]} 需求编号不存在！")
                exist = True
        if exist:
            sys.exit(0)
        
        return caselist
                               
    def to_csv(self, path, caselist):
        "导出csv文件,匹配禅道格式"
        
        csv_case_list = [[
            "所属模块", "相关需求", "优先级", "关键词", "前置条件",
            "用例标题", "步骤", "预期", "用例类型", "适用阶段"
        ]]
        for i in caselist:
            csv_case_list.append([
                i[0], 
                i[1], 
                i[2], 
                i[3],
                i[4], 
                i[5],
                i[6], 
                i[7], 
                "功能测试", 
                "功能测试阶段"])
        
        # 将用例写入csv文件
        
        try:
            with open(path, 'w', newline='', encoding='gbk') as csvfile:
                writer = csv.writer(csvfile)
                writer.writerows(csv_case_list)
        except PermissionError:
            logger.error("请先关闭文件：{path}")
            sys.exit(0)
        else:
            logger.info('用例xmind已成功导出csv文件,请自行导入禅道！')


def client(account, password, projectname, nicknames=["后台+店铺", "商城前端"]):
    """
    Args:
        account (str): 禅道账号
        password (str): 禅道密码
        projectname (str): 禅道项目名称
        nicknames (list, optional): 产品别名
    """
    
    parser = argparse.ArgumentParser(description="禅道python客户端")
    parser.add_argument('--do', action='store', choices=['subtaskout', 'subtaskint', 'taskint', 'xmindout'], 
                        help="导出或导入子任务，导出Xmind用例到CSV，新建主任务")
    parser.add_argument('-xmind-file', help="Xmind用例文件")
    parser.add_argument('-tag', type=str, help="关键词")
    
    args = parser.parse_args()
    if len(sys.argv) == 1:
        # no argument passed
        parser.print_help()
        sys.exit(0)
    zentao = Zentao(account, password, projectname)
    # 测试用例xmind文件导出为CSV格式
    if args.do == "xmindout":
        if not args.xmind_file:
            logger.error("请提供xmind文件，如：-xmind-file 测试用例-3.7.5.xmind")
            sys.exit(0)
        if not args.tag:
            logger.error("请提供用例关键词，如：-tag V3.7.5")
            sys.exit(0)            
        xmind = Xmind(zentao, args.xmind_file)
        csv_path = f"{args.xmind_file[:-6]}.csv" 
        if args.xmind_file[-6:] == '.xmind' and os.path.exists(args.xmind_file):  # 判断文件存在，格式是Xmind      
            tree, onetitle = xmind.xmind_to_tree(args.xmind_file)        
            titlelist = xmind.parser_tree_to_list(tree, onetitle)
            caselist = xmind.titlelist_delete_onetitle(titlelist)
            caselist = xmind.find_step_and_expectation(caselist)
            caselist = xmind.testcaselist(caselist, args.tag)
            caselist = xmind.parse_modules(caselist, nicknames)
            xmind.to_csv(csv_path, caselist)
        else:
            raise Exception(f'测试用例xmind文件不存在:{args.xmind_file}')
    # 导出子任务
    elif args.do == "subtaskout":
        zentao.suubtask_to_csv(zentao.project_id, nicknames)
    # 导入子任务
    elif args.do == "subtaskint":
        zentao.subtask_batch_create()
    # 批量新建主任务
    elif args.do == "taskint":
        zentao.task_batch_create(zentao.project_id, nicknames)
            
if __name__ == "__main__":
    logger.remove()
    logger.add(sys.stderr, level="DEBUG")
    """
    安装依赖：
    pip install xmindparser
    pip install loguru
    pip install request
    - 新建主任务命令：python testcase_xmind_to_csv_zengtao.py --do taskint
    - 导出子任务命令：python testcase_xmind_to_csv_zengtao.py --do subtaskout
    - 导入子任务命令：python testcase_xmind_to_csv_zengtao.py --do subtaskint
    - Xmind文件导出CSV命令：python testcase_xmind_to_csv_zengtao.py --do xmindout -xmind-file  完美运营后台-测试用例-3.7.5.xmind -tag V3.7.5
    """
    BASE_URL = "http://127.0.0.1/zentao" # 禅道路径
    client("ceshi01", "Test123456", "商城V3.7.5", ["后台+店铺", "商城前端"])


