Exemple #1
0
class DingtalkRobot(object):
    """
    钉钉机器人类

    :param param1: this is a first param
    :param param2: this is a second param
    :returns: this is a description of what is returned
    :raises keyError: raises an exception
    @author: jhuang
    @time:02/04/2018
    """

    def __init__(self, access_token):
        self.access_token = access_token
        self.send_api = 'https://oapi.dingtalk.com/robot/send'
        self.ohttp = HttpClass(headers={"Content-Type": "application/json"})

    def send_text_msg(self, text):
        """
        钉钉机器人发送消息

        :param param1: this is a first param
        :param param2: this is a second param
        :returns: this is a description of what is returned
        :raises keyError: raises an exception
        @author: jhuang
        @time:02/04/2018
        """
        jsons = {"msgtype": "text", "text": {"content": text}}
        jsons = json.dumps(jsons)
        ret = self.ohttp.post('%s?access_token=%s' % (self.send_api, self.access_token), payload=jsons)
        api_ret_json = json.loads(ret[1])
        if int(api_ret_json['errcode']) > 0:
            raise Exception('接口返回错误:%s' % ret[1])
        return ret

    def send_link_msg(self, title, text, picUrl, messageUrl):
        jsons = {"msgtype": "link",
                 "link": {"text": text,
                          "title": title,
                          "picUrl": picUrl,
                          "messageUrl": messageUrl
                          }
                 }
        jsons = json.dumps(jsons)
        ret = self.ohttp.post('%s?access_token=%s' % (self.send_api, self.access_token), payload=jsons)
        api_ret_json = json.loads(ret[1])
        if int(api_ret_json['errcode']) > 0:
            raise Exception('接口返回错误:%s' % ret[1])
        return ret
Exemple #2
0
class Dingtalk(object):
    def __init__(self, corpid, corpsecret):
        self.corpid = corpid
        self.corpsecret = corpsecret
        self.access_token = ''
        self.http_obj = HttpClass(headers={"Content-Type": "application/json"})
        self.__gettoken()

    def get_data_by_get(self, api):
        try:
            res, res_text, res_time = self.http_obj.get(api)
            res_dict = json.loads(res_text)
            if res_dict['errcode'] == 0:
                return res_dict
            else:
                raise Exception('errcode: ' + str(res_dict['errcode']) +
                                res_dict['errmsg'].encode('utf8'))
        except Exception as e:
            logger.error(e)
            raise
            # logger.error("请求dingding API返回: " + e.message)
            # raise Exception("请求dingding API返回: " + e.message)

    def get_data_by_post(self, api, payload):
        try:
            res, res_text = self.http_obj.post(api, payload)
            res_dict = json.loads(res_text)
            if res_dict['errcode'] == 0:
                return res_dict
            else:
                raise Exception('errcode: ' + str(res_dict['errcode']) +
                                res_dict['errmsg'].encode('utf8'))
        except Exception as e:
            logger.error(e)
            raise
            # logger.error("请求dingding API返回: " + e.message)
            # raise Exception("请求dingding API返回: " + e.message)

    @retry(stop_max_attempt_number=20, wait_fixed=8000)
    def __gettoken(self):
        # api https://oapi.dingtalk.com/gettoken?corpid=id&corpsecret=secrect
        # 检查mysql 连接是否可用
        try:
            from django.db import connections
            for conn in connections.all():
                conn.close_if_unusable_or_obsolete()
        except Exception as e:
            logger.error(
                '关闭无效数据库连接失败 %s conn.close_if_unusable_or_obsolete()' % e)

        try:
            logger.info('从数据库获取dingtalk_token_info')
            obj_sysparam = SysParam.objects.get(
                param_name='dingtalk_token_info')
            dingtalk_token_info = obj_sysparam.param_value
        except ObjectDoesNotExist as e:
            dingtalk_token_info = None
        except Exception as e:
            logger.error(e)
            raise

        def __set_token():
            api = """{}/gettoken?corpid={}&corpsecret={}""".format(
                Dingtalk_API, self.corpid, self.corpsecret)
            res_dict = self.get_data_by_get(api)
            self.access_token = res_dict['access_token']
            dingtalk_token_info = "%s|%s|%s" % (
                time.time(), res_dict['expires_in'], res_dict['access_token'])
            obj_sysparam = SysParam.objects.get(
                param_name='dingtalk_token_info')
            obj_sysparam.param_value = dingtalk_token_info
            obj_sysparam.save()
            logger.info('dingtalk_token_info %s,获取dingtalk token' %
                        dingtalk_token_info)

        if dingtalk_token_info is None:
            logger.info('dingtalk_token_info not exists, 重新设置token')
            __set_token()
        else:
            get_time = float(dingtalk_token_info.split('|')[0])
            expires_in = float(dingtalk_token_info.split('|')[1])
            access_token = str(dingtalk_token_info.split('|')[2])
            now_time = time.time()
            if now_time - get_time >= expires_in:
                logger.info('dingtalk_token_info %s已经过期,重新获取' %
                            dingtalk_token_info)
                __set_token()
            else:
                self.access_token = access_token

    def get_all_department(self, only_get_id=True):
        """
        获取部门列表(非详情)
        @author: lanxiong
        @time:2018/8/15
        """
        dpt_list = list()
        api = """{}/department/list?access_token={}""".format(
            Dingtalk_API, self.access_token)
        res_dict = self.get_data_by_get(api)
        if only_get_id is True:
            for dpt in res_dict['department']:
                dpt_list.append(dpt['id'])
            return dpt_list
        else:
            return res_dict['department']

    def get_department_member_userids_list_by_dptid(self, department_id):
        """
        获取部门用户userid列表
        @author: lanxiong
        @time:2018/8/15
        """
        # https: //oapi.dingtalk.com/user/getDeptMember?access_token = ACCESS_TOKEN & deptId = 1
        api = """{}/user/getDeptMember?access_token={}&deptId={}""".format(
            Dingtalk_API, self.access_token, department_id)
        res_dict = self.get_data_by_get(api)
        return res_dict['userIds']

    def get_all_member(self, only_get_id=True):
        """
        获取所有员工
        @author: lanxiong
        @time:2018/8/16
        """
        all_user = list()
        all_user_id = list()
        dptid_list = self.get_all_department(only_get_id=True)

        for dptid in dptid_list:
            dept_users_list = self.get_department_member_userids_list_by_dptid(
                dptid)
            for i in dept_users_list:
                all_user_id.append(i)

        if only_get_id is True:
            return all_user_id
        else:
            for id in all_user_id:
                user = self.get_user_detail_by_userid(id)
                all_user.append(user)
            return all_user

    def get_user_detail_by_userid(self, userid):
        """
        获取员工详情
        @author: lanxiong
        @time:2018/8/15
        """
        api = """{}/user/get?access_token={}&userid={}""".format(
            Dingtalk_API, self.access_token, userid)
        res_dict = self.get_data_by_get(api)
        return res_dict

    def get_attendance_by_departmentid(self, department_id, checkDateFrom,
                                       checkDateTo):
        """
        获取部门考勤详细信息
        https://oapi.dingtalk.com/attendance/listRecord?access_token=ACCESS_TOKEN
        @author: lanxiong
        @time:2018/8/15
        """
        pass

    def get_attendance_by_userids_list(self, userids_list, checkDateFrom,
                                       checkDateTo):
        """
        获取员工详细考勤信息
        {
            "userIds": ["001","002"],
            "checkDateFrom": "yyyy-MM-dd hh:mm:ss",
            "checkDateTo": "yyyy-MM-dd hh:mm:ss",
            "isI18n":"false"
        }
        @author: lanxiong
        @time:2018/8/15
        """
        api = """{}/attendance/listRecord?access_token={}""".format(
            Dingtalk_API, self.access_token)
        payload = {
            "userIds": userids_list,
            "checkDateFrom": str(checkDateFrom),
            "checkDateTo": str(checkDateTo),
            "isI18n": "false"
        }
        res_dict = self.get_data_by_post(api, json.dumps(payload))
        return res_dict

    def get_attendance_by_userid(self, userid, checkDateFrom, checkDateTo):
        """
        获取员工详细考勤信息
        {
            "userIds": ["001"],
            "checkDateFrom": "yyyy-MM-dd hh:mm:ss",
            "checkDateTo": "yyyy-MM-dd hh:mm:ss",
            "isI18n":"false"
        }
        @author: lanxiong
        @time:2018/8/15
        """
        api = """{}/attendance/listRecord?access_token={}""".format(
            Dingtalk_API, self.access_token)
        payload = {
            "userIds": [userid],
            "checkDateFrom": str(checkDateFrom),
            "checkDateTo": str(checkDateTo),
            "isI18n": "false"
        }
        res_dict = self.get_data_by_post(api, json.dumps(payload))
        return res_dict

    def get_processinstance_by_id(self, process_instance_id):
        """
        获取单个审批实例
        Doc: https://open-doc.dingtalk.com/microapp/serverapi2/xgqkvx
        API: https://oapi.dingtalk.com/topapi/processinstance/get?access_token=ACCESS_TOKEN
        @author: lanxiong
        @time:2018/8/16
        """
        api = """{}/topapi/processinstance/get?access_token={}""".format(
            Dingtalk_API, self.access_token)
        payload = {"process_instance_id": process_instance_id}
        logger.info(self.access_token)
        res_dict = self.get_data_by_post(api, json.dumps(payload))
        return res_dict

    def get_processinstance_list(self, process_code, start_time, **kwargs):
        """
        批量获取审批实例
        Doc: https://open-doc.dingtalk.com/microapp/serverapi2/fpn98d
        API: https://oapi.dingtalk.com/topapi/processinstance/list?access_token=ACCESS_TOKEN
        process_code: 流程模板唯一标识
        start_time: 时间戳毫秒
        @author: lanxiong
        @time:2018/8/16
        """
        api = """{}/topapi/processinstance/list?access_token={}""".format(
            Dingtalk_API, self.access_token)
        payload = {
            "process_code": process_code,
            "start_time": start_time,
            "cursor": 0
        }
        payload.update(kwargs)
        processinstance_list = list()
        while True:
            res_dict = self.get_data_by_post(api, json.dumps(payload))
            if res_dict['result']['list']:
                processinstance_list.extend(res_dict['result']['list'])
            if 'next_cursor' in res_dict['result']:
                payload['cursor'] += 1
            else:
                break
        return processinstance_list

    def get_processinstance_list_all(self, start_time, **kwargs):
        """
        获取所有审批实例
        start_time 必填
        默认获取从指定日期到当前
        @author: lanxiong
        @time:2018/8/18
        """
        processinstance_all_list = list()
        for process_code in self.get_process_code_list():
            processinstance_list = self.get_processinstance_list(
                process_code, start_time, **kwargs)
            if processinstance_list:
                processinstance_all_list.append(processinstance_list)
        return processinstance_all_list

    def get_process_list(self, offset=0, size=100):
        """
        获取用户可见的审批模板
        https://open-doc.dingtalk.com/microapp/serverapi2/fpn98d
        API: https://oapi.dingtalk.com/topapi/process/listbyuserid?access_token=ACCESS_TOKEN
        @author: lanxiong
        @time:2018/8/16
        """
        # https://oapi.dingtalk.com/topapi/process/listbyuserid?access_token=ACCESS_TOKEN
        api = """{}/topapi/process/listbyuserid?access_token={}""".format(
            Dingtalk_API, self.access_token)
        process_list = list()
        payload = {"offset": offset, "size": size}
        while True:
            res_dict = self.get_data_by_post(api, json.dumps(payload))
            for proc in res_dict['result']['process_list']:
                process_list.append(proc)
            if 'next_cursor' in res_dict['result']:
                offset += 1
            else:
                break

        return process_list

    def get_process_code_list(self, proc_name_like=''):
        """
        获取用户可见的审批模板id
        @author: lanxiong
        @time:2018/8/16
        """
        process_code_list = list()
        for proc in self.get_process_list():
            process_code_list.append(proc['process_code'])
        return process_code_list

    def get_leave_approve_duration(self, userid, from_date, to_date):
        """
        获取请假时长 分钟
        Doc: https://open-doc.dingtalk.com/microapp/serverapi2/bdz3a3
        API: https://oapi.dingtalk.com/topapi/attendance/getleaveapproveduration?access_token=ACCESS_TOKEN
        @author: lanxiong
        @time:2018/8/17
        """
        api = """{}/topapi/attendance/getleaveapproveduration?access_token={}""".format(
            Dingtalk_API, self.access_token)
        payload = {
            "userid": userid,
            "from_date": from_date,
            "to_date": to_date
        }
        res_dict = self.get_data_by_post(api, json.dumps(payload))
        duration_in_minutes = res_dict['result']['duration_in_minutes']
        return duration_in_minutes

    def get_attendance_getsimplegroups(self, **payload):
        """
        获取考勤组详情
        Doc: https://open-doc.dingtalk.com/microapp/serverapi2/tc6f5p
        API: https://oapi.dingtalk.com/topapi/attendance/getsimplegroups?access_token=ACCESS_TOKEN
        @author: lanxiong
        @time:2018/8/20
        """
        api = """{}/topapi/attendance/getsimplegroups?access_token={}""".format(
            Dingtalk_API, self.access_token)
        res_dict = self.get_data_by_post(api, json.dumps(payload))
        return res_dict

    def get_no_attendance(self, userid, start_time, end_time):
        process_list = self.get_process_list()

    def get_checkin_by_dpt_id(self, department_id, start_time, end_time):
        """
        获取签到
        Doc: https://open-doc.dingtalk.com/microapp/serverapi2/xmfmlh
        API: https://oapi.dingtalk.com/checkin/record?access_token=ACCESS_TOKEN&department_id=1&start_time=1467707227000&end_time=1467707240000&offset=0&size=100&order=asc
        start_time 开始时间。Unix时间戳,如:1520956800000
        """
        api = """{Dingtalk_API}/checkin/record?access_token={access_token}&department_id={department_id}&start_time={start_time:}&end_time={end_time}""".format(
            Dingtalk_API=Dingtalk_API,
            access_token=self.access_token,
            department_id=department_id,
            start_time=start_time,
            end_time=end_time)
        res_dict = self.get_data_by_get(api)
        return res_dict['data']
Exemple #3
0
class JiraClass():
    def __init__(self):
        self.username = None
        self.password = None
        self.jira = None

        self.jira_server_url = None

    def web_login(self, url, username, password):
        """
        | ##@函数目的: 登录
        | ##@参数说明:
        | ##@返回值:登录句柄
        | ##@函数逻辑:
        | ##@开发人:jhuang
        | ##@时间:
        """
        self.jira_server_url = url
        if self.jira_server_url[-1] == '/':
            self.jira_server_url = self.jira_server_ur[:-1]
        data = {'login': '******',
                'os_username': username,
                'os_password': password,
                'os_destination': '',
                'atl_token': type
                }

        self.ohttp = HttpClass()
        logger.debug('登录Jira..user:%s,pwd:%s' % (username, '*'))
        ret, html = self.ohttp.post(self.jira_server_url + '/login.jsp', data)
        if not '登录' in html:
            logger.debug('登录JIRA成功!')
        else:
            logger.exception('登录JIRA失败!')

        return self.ohttp

    def connect(self, jira_server_url, username, password):
        '''
        [方法说明]
            初始化连接(认证,获取对象)
        [参数说明]
            server:服务器URL
            username:登陆用户名
            password:登陆密码    
        [实例]
            jira_connect('http://www.tjhcc.com.cn:91','jhuang', '****.')
        '''

        self.jira_server_url = jira_server_url
        if self.jira_server_url[-1] == '/':
            self.jira_server_url = self.jira_server_url[:-1]
        self.username = username
        self.password = password

        jira_options = {'server': jira_server_url, 'verify': False}

        logger.debug('连接Jira:%s (%s)' % (jira_server_url, username))
        jira = JIRA(options=jira_options, basic_auth=(username, password))
        self.jira = jira
        return self.jira

    def update_fields(self, issue_key, fields_dict):
        """
        更新jira自定义字段:https://jira.readthedocs.io/en/master/examples.html#fields

        :param fields_dict: {'customfield_11403': 1}
        :param issue_key: pms-299
        :returns: this is a description of what is returned
        :raises keyError: raises an exception
        @author: jhuang
        @time:10/10/2018
        """
        issue = self.jira.issue(issue_key)

        for idct_key in fields_dict:
            fields = idct_key

        all_fields_dict = issue.raw['fields']

        text = 0
        for all_fields_dict_one in all_fields_dict:
            if all_fields_dict_one.find(fields):
                text = 1
        if text == 0:
            return 0
        try:
            issue.update(fields=fields_dict)
        except Exception as e:
            return get_except(e)


    def comment(self, issueKey, comment):
        '''
        添加评论
        [参数说明]
            issuenum:issue号 
        '''
        # 解决命令行参数:中文问题.decode("GBK")
        logger.debug('提交jira备注:%s至:%s' % (comment, issueKey))
        # comment = self.jira.add_comment(issueKey, comment.decode("GBK"))
        comment = self.jira.add_comment(issueKey, comment)

    def resolve_issue(self, issueKey, resolution='6'):
        '''
        解决ISSUE
        [参数说明]
            issuenum:issue号 
        '''
        try:
            logger.debug('解决jira::%s' % (issueKey))
            self.jira.transition_issue(issueKey, '%s' % ('5'), None, resolution={'id': '%s' % resolution})
        except Exception as e:
            get_except(e)

    def queryIssueLink(self, issueKey):
        """查询关联的ISSUE"""
        oIssue = self.jira.issue('ZJYYXM-201')
        '''
In [2]: issue.
issue.delete  issue.fields  issue.id      issue.raw     issue.update
issue.expand  issue.find    issue.key     issue.self

In [2]: issue.fields.
issue.fields.aggregateprogress              issue.fields.customfield_11531
issue.fields.aggregatetimeestimate          issue.fields.customfield_11631
issue.fields.aggregatetimeoriginalestimate  issue.fields.customfield_11930
issue.fields.aggregatetimespent             issue.fields.customfield_12130
issue.fields.assignee                       issue.fields.customfield_12131
issue.fields.attachment                     issue.fields.description
issue.fields.comment                        issue.fields.environment
issue.fields.components                     issue.fields.fixVersions
issue.fields.created                        issue.fields.issuelinks
issue.fields.customfield_10150              issue.fields.issuetype
issue.fields.customfield_10160              issue.fields.labels
issue.fields.customfield_10161              issue.fields.mro
issue.fields.customfield_10180              issue.fields.progress
issue.fields.customfield_10230              issue.fields.project
issue.fields.customfield_10575              issue.fields.reporter
issue.fields.customfield_10610              issue.fields.resolution
issue.fields.customfield_10650              issue.fields.resolutiondate
issue.fields.customfield_10651              issue.fields.status
issue.fields.customfield_10680              issue.fields.subtasks
issue.fields.customfield_10723              issue.fields.summary
issue.fields.customfield_11130              issue.fields.timeestimate
issue.fields.customfield_11230              issue.fields.timeoriginalestimate
issue.fields.customfield_11431              issue.fields.timespent
issue.fields.customfield_11433              issue.fields.updated
issue.fields.customfield_11434              issue.fields.versions
issue.fields.customfield_11435              issue.fields.votes
issue.fields.customfield_11436              issue.fields.watches
issue.fields.customfield_11437              issue.fields.workratio'''
        #             logger.info ('关联的ISSUE:%s' %(oIssue.fields.attachment))
        for IssueLink in oIssue.fields.RemoteLinks:
            print IssueLink

    def _search_issue(self, searchText, childTask=False):
        """
        |##desc: 子函数  支持包含多个KEY的LIST 返回: list
        |##:param: None
        |##:return: None
        |##@author: jhuang
        |##@time:2017/8/22
        """
        if isinstance(searchText, list) is True:
            keys = ','.join(searchText)
            JiraList = []
            searchJQL = 'key in (%s)' % (keys)
            searchText = searchJQL
            logger.debug('jira搜索:%s' % (searchJQL))

        issues = self.jira.search_issues(searchText)

        arrays = []
        attachmentList = []
        for issue in issues:
            dic = {}
            dic['jira_name'] = issue.key
            dic['jira_summary'] = issue.fields.summary
            dic['environment'] = issue.fields.environment
            dic['jira_status'] = issue.fields.status.name
            dic['jira_status_id'] = issue.fields.status.id
            dic['description'] = issue.fields.description
            dic['issue_type'] = issue.fields.issuetype.name
            # 获取修复版本
            str_fix_version = ''
            for fixVersion in issue.fields.fixVersions:
                str_fix_version = str_fix_version + fixVersion.name + ','
            dic['str_fix_version'] = str_fix_version[:-1]
            dic['reporter'] = str(issue.fields.reporter)  # 报告人
            dic['reporter_email'] = str(issue.fields.reporter.emailAddress)  # 报告人邮箱
            dic['assignee_email'] = str(issue.fields.assignee.emailAddress)  # 经办人邮箱
            dic['assignee'] = str(issue.fields.assignee)  # 经办人

            dic['status'] = str(issue.fields.status)

            dic['issue_url'] = '%s/browse/%s' % (self.jira_server_url, issue.key)

            theIssue = self.jira.issue(issue.key)
            #               logger.info ('获取附件信息:%s' %(theIssue.fields.attachment))
            for attachment in theIssue.fields.attachment:
                attachmentDic = {}
                attachmentDic['id'] = attachment.id
                attachmentDic['filename'] = attachment.filename

                attachmentList.append(attachmentDic)
            logger.debug(attachmentList)
            dic['attachment'] = attachmentList

            arrays.append(dic)
        return arrays

    def jql_search_to_list(self, searchText, searchChildIssue=False, searchRelIssue=False, both=False, maxResult=500):
        """
        |##@函数目的:issue 的高级搜索 结果输出为LIST
        |##@参数说明:affectedVersion ='SRMC-15
        |##@返回值:
        |##@函数逻辑:
        |##@开发人:JHUANG
        |##@时间:
        """
        try:
            logger.debug(searchText)
            lists = []
            issues = self.jira.search_issues(searchText, 0, maxResult)
            n = 0

            for issue in issues:
                pdic = {}

                try:
                    customfield_10800 = issue.fields.customfield_10800
                except:
                    customfield_10800 = ''
                pdic['customfield_10800'] = customfield_10800
                pdic['index'] = n
                pdic['rel_type'] = 'parentIssue'
                pdic['parent_issue_key'] = ''
                pdic['rel_issues'] = ''
                pdic['jira_name'] = str(issue.key)
                parentKey = str(issue.key)
                pdic['jira_summary'] = issue.fields.summary
                pdic['environment'] = issue.fields.environment
                pdic['jira_status'] = issue.fields.status.name
                pdic['jira_statu_id'] = issue.fields.status.id

                pdic['description'] = issue.fields.description
                #                问题类型  缺陷/严重等
                pdic['issue_type'] = issue.fields.issuetype.name
                # 获取修复版本
                str_fix_version = ''
                for fixVersion in issue.fields.fixVersions:
                    str_fix_version = str_fix_version + fixVersion.name + ','
                pdic['str_fix_version'] = str_fix_version[:-1]
                pdic['reporter'] = str(issue.fields.reporter)  # 报告人
                pdic['assignee'] = str(issue.fields.assignee)  # 经办人
                pdic['reporter_email'] = str(issue.fields.reporter.emailAddress)  # 报告人邮箱
                pdic['assignee_email'] = str(issue.fields.assignee.emailAddress)  # 经办人邮箱
                # dic['status'] = str(issue.fields.status)
                #                 for issueLink in  issue.fields.linkedIssues:
                #                     print issueLink
                pdic['issue_url'] = '%s/browse/%s' % (self.jira_server_url, issue.key)
                pdic['created_time'] = str(issue.fields.created).replace('T', ' ')[0:19]
                pdic['updated_time'] = str(issue.fields.updated).replace('T', ' ')[0:19]
                pdic['duedate'] = str(issue.fields.duedate).replace('T', ' ')[0:19]
                pdic['resolution'] = str(issue.fields.resolution)
                pdic['resolutiondate'] = str(issue.fields.resolutiondate).replace('T', ' ')[0:19]

                n += 1

                relIssueList = []
                if both:
                    logger.debug('查询子任务+关联任务...%s' % parentKey)

                    childIssues = self.jira.search_issues(
                        'parent =%s or issue in linkedIssues(%s)' % (parentKey, parentKey))
                    for issue in childIssues:
                        dic = {}
                        dic['index'] = n
                        dic['rel_type'] = 'childIussue+relIssue'
                        dic['parent_issue_key'] = parentKey
                        dic['jira_name'] = str(issue.key)
                        relIssueList.append(str(issue.key))
                        dic['jira_summary'] = issue.fields.summary
                        dic['environment'] = issue.fields.environment
                        dic['jira_status'] = issue.fields.status.name
                        dic['jira_statu_id'] = issue.fields.status.id
                        dic['description'] = issue.fields.description
                        #                问题类型  缺陷/严重等
                        dic['issue_type'] = issue.fields.issuetype.name
                        # 获取修复版本
                        str_fix_version = ''
                        for fixVersion in issue.fields.fixVersions:
                            str_fix_version = str_fix_version + fixVersion.name + ','
                        dic['str_fix_version'] = str_fix_version[:-1]
                        dic['reporter'] = str(issue.fields.reporter)  # 报告人
                        dic['assignee'] = str(issue.fields.assignee)  # 经办人
                        dic['reporter_email'] = str(issue.fields.reporter.emailAddress)  # 报告人邮箱
                        dic['assignee_email'] = str(issue.fields.assignee.emailAddress)  # 经办人邮箱
                        # dic['status'] = str(issue.fields.status)
                        #                 for issueLink in  issue.fields.linkedIssues:
                        #                     print issueLink
                        dic['issue_url'] = '%s/browse/%s' % (self.jira_server_url, issue.key)
                        dic['createdTime'] = str(issue.fields.created).replace('T', ' ')[0:19]
                        dic['updated_time'] = str(issue.fields.updated).replace('T', ' ')[0:19]
                        dic['duedate'] = str(issue.fields.duedate).replace('T', ' ')[0:19]
                        dic['resolution'] = str(issue.fields.resolution)
                        dic['resolutiondate'] = str(issue.fields.resolutiondate).replace('T', ' ')[0:19]

                        n += 1
                        lists.append(dic)

                if searchChildIssue and both == False:

                    logger.debug('查询子任务...%s' % parentKey)
                    childIssues = self.jira.search_issues('parent = %s' % (parentKey))
                    for issue in childIssues:
                        dic = {}
                        dic['index'] = n
                        dic['rel_type'] = 'childIussue'
                        dic['parent_issue_key'] = parentKey
                        dic['jira_name'] = str(issue.key)
                        relIssueList.append(str(issue.key))
                        dic['jira_summary'] = issue.fields.summary
                        dic['environment'] = issue.fields.environment
                        dic['jira_status'] = issue.fields.status.name
                        dic['jira_statu_id'] = issue.fields.status.id
                        dic['description'] = issue.fields.description
                        #                问题类型  缺陷/严重等
                        dic['issue_type'] = issue.fields.issuetype.name
                        # 获取修复版本
                        str_fix_version = ''
                        for fixVersion in issue.fields.fixVersions:
                            str_fix_version = str_fix_version + fixVersion.name + ','
                        dic['str_fix_version'] = str_fix_version[:-1]
                        dic['reporter'] = str(issue.fields.reporter)  # 报告人
                        dic['assignee'] = str(issue.fields.assignee)  # 经办人
                        dic['reporter_email'] = str(issue.fields.reporter.emailAddress)  # 报告人邮箱
                        dic['assignee_email'] = str(issue.fields.assignee.emailAddress)  # 经办人邮箱
                        # dic['status'] = str(issue.fields.status)
                        #                 for issueLink in  issue.fields.linkedIssues:
                        #                     print issueLink
                        dic['issue_url'] = '%s/browse/%s' % (self.jira_server_url, issue.key)
                        dic['createdTime'] = str(issue.fields.created).replace('T', ' ')[0:19]
                        dic['updated_time'] = str(issue.fields.updated).replace('T', ' ')[0:19]
                        dic['duedate'] = str(issue.fields.duedate).replace('T', ' ')[0:19]
                        dic['resolution'] = str(issue.fields.resolution)
                        dic['resolutiondate'] = str(issue.fields.resolutiondate).replace('T', ' ')[0:19]

                        n += 1
                        lists.append(dic)

                if searchRelIssue and both == False:

                    logger.debug('查询相关任务...')
                    childIssues = self.jira.search_issues('issue in linkedIssues(%s)' % (parentKey))
                    for issue in childIssues:
                        dic = {}
                        dic['index'] = n
                        dic['rel_type'] = 'relIssue'
                        dic['parent_issue_key'] = parentKey
                        dic['jira_name'] = str(issue.key)
                        relIssueList.append(str(issue.key))
                        dic['jira_summary'] = issue.fields.summary
                        dic['environment'] = issue.fields.environment
                        dic['jira_status'] = issue.fields.status.name
                        dic['jira_statu_id'] = issue.fields.status.id
                        dic['description'] = issue.fields.description
                        #                问题类型  缺陷/严重等
                        dic['issue_type'] = issue.fields.issuetype.name
                        # 获取修复版本
                        str_fix_version = ''
                        for fixVersion in issue.fields.fixVersions:
                            str_fix_version = str_fix_version + fixVersion.name + ','
                        dic['str_fix_version'] = str_fix_version[:-1]
                        dic['reporter'] = str(issue.fields.reporter)  # 报告人
                        dic['assignee'] = str(issue.fields.assignee)  # 经办人
                        dic['reporter_email'] = str(issue.fields.reporter.emailAddress)  # 报告人邮箱
                        dic['assignee_email'] = str(issue.fields.assignee.emailAddress)  # 经办人邮箱
                        # dic['status'] = str(issue.fields.status)
                        #                 for issueLink in  issue.fields.linkedIssues:
                        #                     print issueLink
                        dic['issue_url'] = '%s/browse/%s' % (self.jira_server_url, issue.key)
                        dic['createdTime'] = str(issue.fields.created).replace('T', ' ')
                        dic['updated_time'] = str(issue.fields.updated).replace('T', ' ')
                        dic['duedate'] = str(issue.fields.duedate).replace('T', ' ')
                        dic['resolution'] = str(issue.fields.resolution)
                        dic['resolutiondate'] = str(issue.fields.resolutiondate).replace('T', ' ')

                        n += 1
                        lists.append(dic)

                pdic['relissues'] = relIssueList
                lists.append(pdic)
            return lists

        except Exception as e:
            logger.exception('异常信息')
            lists = []

    def search_issue(self, searchText):
        '''
        搜索issue列表
        返回结果是jira搜索结果数组
        '''
        searchText = str(searchText).replace(' ', '')
        str1 = 'key = "' + searchText + '" OR text ~ "' + searchText + '"'
        str1 = 'key = "' + searchText + '"'
        str2 = 'summary ~ ' + searchText
        try:
            arrays = self._search_issue(str1)
        except Exception as e:
            logger.exception('异常信息')
            try:
                arrays = self._search_issue(self, str2)
            except Exception as e:
                logger.exception('异常信息')
                arrays = []
                return arrays, str(e)
        return arrays, '1'

    def jql_search(self, searchText, type=0):
        """
        |##@函数目的:issue 的高级搜索
        |##@参数说明:affectedVersion ='SRMC-15
        |##@返回值:type =1 执行原生高级搜索
        |##@函数逻辑:
        |##@开发人:runksun
        |##@时间:2017年2月23日
        """
        r = re.findall('^\w+-\d+$', searchText)
        if r:
            logger.debug('用户输入的纯JIRA号,进行高级搜索格式化...')
            searchText = 'key = "' + r[0] + '" OR text ~ "' + r[0] + '"'
        else:

            logger.debug(searchText)
        try:
            if type == 0:
                arrays = self._search_issue(searchText)
            else:
                return self.jira.search_issues(searchText), type
        except Exception as e:
            logger.exception('异常信息')
            arrays = []
        return arrays, '1'

    def search_issue_status(self, jira_name):
        """
            |##@函数目的:查询issue的状态
            |##@参数说明:jira_name 支持 包含多个key 的list
            |##@返回值:list
            |##@函数逻辑:
            |##@开发人:runksun,jhuang
            |##@时间:2017年1月17日
            JQL高级搜索文档:https://confluence.atlassian.com/jira060/advanced-searching-370704913.html
        """
        # tstart=time.time()
        # 将多个KEY 进行高级搜索,一次查询,速度快
        if isinstance(jira_name, list) is True:
            if len(jira_name) <= 0:
                return None
            keys = ','.join(jira_name)
            JiraList = []
            searchJQL = 'key in (%s)' % (keys)
            print searchJQL

            issues = self.jira.search_issues(searchJQL, 0, 1000)

            for issue in issues:
                dic = {}
                # print issue.key
                dic['key'] = issue.key
                dic['statu'] = issue.fields.status.name
                dic['jira_statu_id'] = issue.fields.status.id

                dic['issuetype'] = issue.fields.issuetype
                dic['assignee'] = str(issue.fields.assignee)  # 经办人
                JiraList.append(dic)
            logger.debug('查询状态完成!')
            return JiraList

        else:
            jira_name = str(jira_name).replace(' ', '')
            str1 = 'key =' + jira_name
            try:
                issue = self.jira.search_issues(str1)
                jira_status = issue[0].fields.status.name
            except:
                jira_status = '状态未知'
            finally:
                return jira_status
Exemple #4
0
class Confluence(object):
    def __init__(self):
        self.username = None
        self.password = None
        self.ohttp = None
        self.confluence_server_url = None

    def login(self, url, username, password):
        """
        | ##@函数目的: 登录
        | ##@参数说明:
        | ##@返回值:登录句柄
        | ##@函数逻辑:
        | ##@开发人:jhuang
        | ##@时间:
        """
        self.confluence_server_url = url
        data = {'login': '******',
                'os_username': username,
                'os_password': password,
                'os_destination': '',
                'atl_token': type
                }
        #         if self.ohttp ==None:
        self.ohttp = HttpClass()
        logger.debug('登录Confluence...')
        ret, html = self.ohttp.post(self.confluence_server_url + '/login.jsp', data)
        #         else:
        #             logger.info  ( u'已登录Confluence,无需登录!')
        # logger.info  ( html)
        return self.ohttp

    def logout(self):
        self.ohttp.get('%s/logout.action' % (self.confluence_server_url))
        self.ohttp.close()

    def get_avatar(self, username):
        """
        | ##@函数目的: 获取用户头像
        | ##@参数说明:
        | ##@返回值:
        | ##@函数逻辑:
        | ##@开发人:jhuang
        | ##@时间:
        """
        ret, html,respone_time = self.ohttp.get(
            self.confluence_server_url + '/rest/spacedirectory/1/search?label=~' + username + '%3Afavourite&label=~' + username + '%3Afavorite&_=1483072547386')
        try:
            R = re.findall('"image/png" href="(http.*?(?:jpg|png))', html)
            if len(R) > 1:
                return R[1]
            else:
                return None
        except Exception as e:
            get_except(e)
            return None

    def get_page_title(self, pageid):
        """
        | ##@函数目的: 获取文档标题
        | ##@参数说明:
        | ##@返回值:
        | ##@函数逻辑:
        | ##@开发人:jhuang
        | ##@时间:
        """
        ret, html = self.ohttp.get('%s/pages/viewpage.action?pageId=%s' % (self.confluence_server_url, pageid))
        r = re.findall('<meta name="ajs-page-title" content="(.*?)">', html, re.M)
        if len(r) > 0:
            return r[0]
        else:
            return None