python 配置钉钉机器人,推送禅道bug统计

禅道11.7版本开始,webhook支持集成钉钉工作消息通知。具体设置见禅道开源版使用手册
因为公司的禅道版本较低,升级或迁移又比较麻烦。为了方便统计bug信息并自动通知到钉钉群,写了一个脚本用来获取当前项目的bug列表,然后统计待解决的、待回归的bug,以及具体bug信息,最后通过钉钉机器人,以markdown的方式发送到群里。代码参考python 爬虫禅道任务自动推送到钉钉

效果展示.png


2021.05.28更新说明
公司将禅道升级至15.0版本后,原代码已再不适用。以下为新版本的爬虫代码。

一、配置钉钉群机器人

群设置-群智能助手--添加机器人


群机器人.png

安全设置我设置的是加签,webhook和密钥待会代码里会用到。

二、python代码

# run.py
# !/usr/bin/env python
# _*_ coding: utf-8 _*_

import config,my_task

if __name__ == '__main__':

    config = config.Config()
    task = my_task.MyTask(config)
    task.request()
# config.json
{
 "host": "http://X.X.X.X",
 "account": "username",
 "password": "pwd",
 "webhook": "钉钉机器人webhook",
 "secret": "钉钉机器人secret",
 "page_path": "要爬虫的禅道buglist页面地址,格式如/zentao/bug-browse-40.html"
}
# config.py
#!/usr/bin/env python
# _*_ coding: utf-8 _*_
# @Time : 2021/5/28 10:53 
# @Author : Renyjenny 
# @desc : 读取配置文件

import json
import os


class Config:
    def __init__(self):
        config_path = "config.json"
        if not os.path.exists(config_path):
            print("config.json文件不存在")
        else:
            with open(config_path, 'r') as configFile:
                table = json.load(configFile)
                self._host = table["host"]
                self._account = table["account"]
                self._pwd = table["password"]
                self._webhook = table["webhook"]
                self._secret = table["secret"]
                self._pagepath = table["page_path"]

    def get_host(self):
        return self._host

    def get_account(self):
        print(f"account:{self._account}")
        return self._account

    def get_password(self):
        print(f"pwd:{self._pwd}")
        return self._pwd

    def get_webhook(self):
        return self._webhook

    def get_secret(self):
        return self._secret

    def get_pagepath(self):
        return self._pagepath

# my_zentao.py
#!/usr/bin/env python
# _*_ coding: utf-8 _*_
# @Time : 2021/5/28 11:01 
# @Author : Renyjenny 
# @desc : 登录、获取session

import requests
from dingtalkchatbot.chatbot import DingtalkChatbot
import random
from hashlib import md5
import json


class MyZentao:
    def __init__(self, config):
        self._config = config
        self._loginurl = config.get_host() + "/zentao/user-login.html"
        self._session = requests.session()

        # 钉钉机器人
        webhook = config.get_webhook()
        secret = config.get_secret()
        self._robot = DingtalkChatbot(webhook, secret=secret)

    # pwd加密计算
    def computePasswordStrength(self, pwd):
        if len(pwd) == 0:
            return 0

        h = 0
        e = len(pwd)
        c = ""
        a = [0] * 3
        for i in pwd:
            letter = ord(str(i))
            if letter >= 48 and letter <= 57:
                a[2] = 2
            elif letter >= 65 and letter <= 90:
                a[1] = 2
            elif letter >= 97 and letter <= 122:
                a[0] = 1
            else:
                a[3] = 3
            if c != i:
                c += i
        if len(c) > 4:
            h += len(c) - 4
        g = f = 0
        for i in a:
            f += 1
            g += i
        h += g + (2 * (f - 2))
        if e < 6 and h >= 10:
            h = 9
        h = min(h, 29)
        h = h // 10
        return h

    def get_rank(self):
        url = self._config.get_host() + "/zentao/user-refreshRandom.html"
        res = self._session.get(url)
        res = res.text
        return res

    def login(self):
        password = str(self._config.get_password())
        rank = str(self.get_rank())

        body = {
            "account": self._config.get_account(),
            "password": md5((md5(password.encode('utf8')).hexdigest() + rank).encode('utf8')).hexdigest(),
            "passwordStrength": self.computePasswordStrength(password),
            "referer": "/zentao/",
            "verifyRand": rank,
            "keepLogin": 1,
            "captcha": ""
        }
        body_str = json.dumps(body)
        print(body_str)

        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"
        }

        response = self._session.post(self._loginurl, headers=headers, data=body)

        with response:
            content = response.text
            if "self.location=" in content:
                print(" login success")
                return True
            elif "登录失败,请检查您的用户名或密码是否填写正确" in content:
                print("登录失败,请检查您的用户名或密码是否填写正确")
                return False
            else:
                print("login fail")
                return False

    def send_markdown(self, title, text):
        self._robot.send_markdown(title, text, is_at_all=True)

# my_task.py
#!/usr/bin/env python
# _*_ coding: utf-8 _*_
# @Time : 2021/5/28 13:45 
# @Author : Renyjenny 
# @desc : 爬虫

import my_zentao
from lxml import etree
import datetime


class MyTask(my_zentao.MyZentao):
    def request(self):
        url = self._config.get_host() + self._config.get_pagepath()

        success = self.login()
        if success:
            response = self._session.get(url)
            with response:
                content = response.text
                html = etree.HTML(content)

                tasks = html.xpath("//table[@id='bugList']//tbody/tr")
                count = todo_num = 0
                bug_list = []

                for i,task in enumerate(tasks):
                    # 任务id
                    id = task.xpath("./@data-id")
                    id_str = str(id[0])
                    count += 1

                    # 状态
                    status = task.xpath("./td[contains(@class, 'c-status')]/@title")
                    if status[0] != '激活':
                        continue
                    todo_num += 1

                    # 组合bug list
                    content = task.xpath("./td[@class='c-title text-left']/@title")
                    content_str = str(content[0])

                    assigned_to = task.xpath("./td[contains(@class, 'c-assignedTo')]//text()")
                    assigned_to_str = str(assigned_to[1])

                    bug_list_item = "{0} {1}===>{2}".format(id_str, content_str, assigned_to_str)
                    bug_list.append(bug_list_item)

                # 组合markdown格式
                msg = "### [截止{},共有{}个bug未解决,{}个bug待回归。](禅道地址)".format(
                    datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), todo_num, count - todo_num)
                msg = msg + "\n\n* * *\n"
                for i in bug_list:
                    msg = msg + '\n- ' + str(i)

                print(msg)
                # self.send_markdown("禅道提醒", msg)

三、配置定时任务

# 每周一到周五,下午4点执行
crontab -e
0 16 * * 2-6 python /root/chandao/run.py
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容