python tornado 实现类禅道系统
最近楼主加班 喽, 好久没有更新我的博客了,哎,一言难尽,废话我就不说了,来开始上精华。
背景:目前市面上有很多bug管理工具,但是各有各的特点,最著名,最流行的就是禅道,一个偶然的机会接触到了python ,学到tornado后,就想着去怎么去用到实处,后来发现自己公司的除了禅道就记录bug没有什么可以用的工具了。
语言:python3 第三库 :tornado,qiniu(用于云存储文件),数据库用sqlite
why use tornado?很多人其实会这么问我,我感觉tornado可以实现异步,虽然现在代码还没有用到异步,我感觉还是很不错的框架,值得学习,现在很多公司都在用,个人感觉这是一个不错的,值得我们大家去学习的框架。
来看看我的需求文档
大题是这么的轮廓,那么拿到这个的时候,我会进行需求分析,
需要什么样的数据库, 数据模型之间的关系,虽然现在还是有很多地方是写死的还没有进行搜索功能的设置,但是我相信,有了现在这个demo
那么我开始来设计下我主要会结构
handlsers 存放类似flask的views
models存数据库相关的,
static存放静态
template存放模板
untils存放公共库
setting 配置文件
urls url地址映射
run 运行文件。
那么我来开始设计我的数据,其实我的数据模型也是一波三折的。
选择用了sqlalchemy,之前用过flask的sqlalchemy感觉不错
from models.dataconfig import db_session,Base,create_all
from sqlalchemy import Column,Integer,DateTime,Boolean,String,ForeignKey,desc,asc,Text
from sqlalchemy.orm import relationship,backref
from untils.common import encrypt
import datetime
class User(Base):
__tablename__='users'
id=Column(Integer(),primary_key=True)
username=Column(String(64),unique=True,index=True)
email=Column(String(64))
password=Column(String(64))
last_logtime=Column(DateTime())
status=Column(Integer())
leves=Column(Integer())
iphone=Column(Integer())
Projects=relationship('Project',backref='users')
shebei=relationship('Shebei',backref='users')
file=relationship('FilePan',backref='users')
banben=relationship('BanbenWrite',backref='users')
testresult=relationship('TestResult',backref='users')
testcase=relationship('TestCase',backref='users')
buglog=relationship('BugLog',backref='users')
def __repr__(self):
return self.username
@classmethod
def get_by_id(cls, id):
item = db_session.query(User).filter(User.id==id).first()
return item
@classmethod
def get_by_username(cls, username):
item = db_session.query(User).filter(User.username== username).first()
return item
@classmethod
def get_count(cls):
return db_session.query(Shebei).count()
@classmethod
def add_new(cls,username,password,iphone,email,leves):
new=User(username=username,iphone=iphone,email=email,leves=leves)
new.password=encrypt(password)
new.status=0
db_session.add(new)
try:
db_session.commit()
except:
db_session.rollback()
class Shebei(Base):
__tablename__='shebeis'
id=Column(Integer(),primary_key=True)
shebei_id=Column(String(32),unique=True)
shebei_name=Column(String(64))
shebei_xitong=Column(String(64))
shebei_xinghao=Column(String(255))
shebei_jiage=Column(Integer())
shebei_fapiaobianhao=Column(String(64))
shebei_quanxian=Column(Boolean())
shebei_jie=Column(Boolean())
shebei_shuyu=Column(String())
shebei_date=Column(DateTime())
shebei_user=Column(String())
gou_date=Column(DateTime())
shebei_status=Column(String(16))
she_sta=Column(Integer(),default=0)
ruku_user=Column(Integer(),ForeignKey('users.id'))
def __repr__(self):
return self.shebei_name
@classmethod
def get_by_name(cls,name):
item=db_session.query(Shebei).filter(Shebei.shebei_name==name).first()
return item
@classmethod
def get_by_id(cls,id):
item=db_session.query(Shebei).filter(Shebei.id==id).first()
return item
@classmethod
def get_count(cls):
return db_session.query(Shebei).count()
class TestResult(Base):
__tablename__='testresults'
id=Column(Integer(),primary_key=True)
porject_id=Column(Integer(),ForeignKey('projects.id'))
creat_time=Column(DateTime())
bug_first=Column(Integer())
ceshirenyuan=Column(String(255))
is_send=Column(Boolean(),default=True)
filepath=Column(String(64))
status=Column(Integer(),default=0)
user_id=Column(Integer(),ForeignKey('users.id'))
def __repr__(self):
return self.porject_name
@classmethod
def get_by_name(cls,name):
item=db_session.query(TestResult).filter(TestResult.porject_name==name).first()
return item
@classmethod
def get_by_id(cls,id):
item=db_session.query(TestResult).filter(TestResult.id==id).first()
return item
@classmethod
def get_by_user_id(cls,user_id):
item=db_session.query(TestResult).filter(TestResult.user_id==user_id).first()
return item
@classmethod
def get_count(cls):
return db_session.query(TestResult).count()
class BanbenWrite(Base):
__tablename__='banbens'
id=Column(Integer(),primary_key=True)
porject_id=Column(Integer(),ForeignKey('projects.id'))
creat_time=Column(DateTime(),default=datetime.datetime.now())
banbenhao=Column(String(32))
is_xian=Column(Boolean(),default=False)
is_test=Column(Boolean(),default=False)
status=Column(Integer())
user_id=Column(Integer(),ForeignKey('users.id'))
bugadmin=relationship('BugAdmin',backref='banbens')
def __repr__(self):
return self.banbenhao
@classmethod
def get_by_name(cls,name):
item=db_session.query(BanbenWrite).filter(BanbenWrite.porject_name==name).first()
return item
@classmethod
def get_by_id(cls,id):
item=db_session.query(BanbenWrite).filter(BanbenWrite.id==id).first()
return item
@classmethod
def get_by_user_id(cls,user_id):
item=db_session.query(BanbenWrite).filter(BanbenWrite.user_id==user_id).first()
return item
@classmethod
def get_count(cls):
return db_session.query(BanbenWrite).count()
class FilePan(Base):
__tablename__='files'
id=Column(Integer(),primary_key=True)
file_fenlei=Column(String(64))
file_name=Column(String(64))
down_count=Column(Integer(),default=0)
creat_time=Column(DateTime(),default=datetime.datetime.now())
status=Column(Integer(),default=0)
down_url=Column(String(64))
is_tui=Column(Boolean(),default=False)
user_id=Column(Integer(),ForeignKey('users.id'))
def __repr__(self):
return self.file_name
@classmethod
def get_by_file_name(cls,name):
item=db_session.query(FilePan).filter(FilePan.file_name==name).first()
return item
@classmethod
def get_by_id(cls,id):
item=db_session.query(FilePan).filter(FilePan.id==id).first()
return item
@classmethod
def get_by_user_id(cls,user_id):
item=db_session.query(FilePan).filter(FilePan.user_id==user_id).first()
return item
@classmethod
def get_count(cls):
return db_session.query(FilePan).count()
class BugAdmin(Base):
__tablename__='bugadmins'
id=Column(Integer(),primary_key=True)
porject_id=Column(Integer(),ForeignKey('projects.id'))
bugname=Column(String(64))
bugdengji=Column(String(64))
bugtime=Column(DateTime(),default=datetime.datetime.now())
bug_miaoshu=Column(String(255))
ban_id=Column(Integer(),ForeignKey('banbens.id'))
fujian=Column(String(64))
is_que=Column(Boolean())
bug_status=Column(String(64))
bug_jiejuefangan=Column(String(64))
bug_send=Column(String(64))
status=Column(Integer(),default=0)
bug_log=relationship('BugLog',backref='bugadmins')
user_id=Column(Integer(),ForeignKey('users.id'))
def __repr__(self):
return self.bugname
@classmethod
def get_by_bugname(cls,bugname):
item=db_session.query(BugAdmin).filter(BugAdmin.bugname==bugname).first()
return item
@classmethod
def get_by_id(cls,id):
item=db_session.query(BugAdmin).filter(BugAdmin.id==id).first()
return item
@classmethod
def get_by_porject_name(cls,porject_name):
item=db_session.query(BugAdmin).filter(BugAdmin.porject_name==porject_name).first()
return item
@classmethod
def get_count(cls):
return db_session.query(BugAdmin).count()
class TestCase(Base):
__tablename__='testcases'
id=Column(Integer(),primary_key=True)
porject_id=Column(Integer(),ForeignKey('projects.id'))
casename=Column(String(64))
case_qianzhi=Column(String())
case_buzhou=Column(String())
case_yuqi=Column(String())
status=Column(Integer(),default=0)
case_crea_time=Column(DateTime(),default=datetime.datetime.now())
user_id=Column(Integer(),ForeignKey('users.id'))
def __repr__(self):
return self.casename
@classmethod
def get_by_project_name(Cls,project_name):
item=db_session.query(TestCase).filter(TestCase.project_name==project_name).first()
return item
@classmethod
def get_by_casename(Cls,casename):
item=db_session.query(TestCase).filter(TestCase.casename==casename).first()
return item
@classmethod
def get_by_id(cls,id):
item=db_session.query(TestCase).filter(TestCase.id==id).first()
return item
@classmethod
def get_count(cls):
return db_session.query(TestCase).count()
class BugLog(Base):
__tablename__='buglogs'
id=Column(Integer(),primary_key=True)
bug_id=Column(Integer(),ForeignKey('bugadmins.id'))
caozuo=Column(String())
caozuo_time=Column(DateTime())
user_id=Column(Integer(),ForeignKey('users.id'))
def __repr__(self):
return self.caozuo
@classmethod
def get_by_id(Cls,id):
item=db_session.query(BugLog).filter(BugLog.id==id).first()
return item
@classmethod
def get_by_user_id(Cls,user_id):
item=db_session.query(BugLog).filter(BugLog.user_id==user_id).first()
return item
@classmethod
def get_by_bug_id(Cls,bug_id):
item=db_session.query(BugLog).filter(BugLog.bug_id==bug_id).first()
return item
class Project(Base):
__tablename__='projects'
id=Column(Integer(),primary_key=True)
name=Column(String(64))
user_id=Column(Integer(),ForeignKey('users.id'))
bug_log=relationship('BugAdmin',backref='projects')
banben=relationship('BanbenWrite',backref='projects')
testresult=relationship('TestResult',backref='projects')
testcase=relationship('TestCase',backref='projects')
def __repr__(self):
return self.name
@classmethod
def get_by_id(cls,id):
item=db_session.query(Project).filter(Project.id==id).first()
return item
@classmethod
def get_by_name(cls,name):
item=db_session.query(Project).filter(Project.name==name).first()
return item
这是数据库相关的,
数据库配置相关的 from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session,sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine=create_engine('sqlite:///shebei.db',convert_unicode=True)
Base=declarative_base()
db_session=scoped_session(sessionmaker(bind=engine))
def create_all():
Base.metadata.create_all(engine)
def drop_all():
Base.metadata.drop_all(engine)
其实在开发的过程中,也遇到了很多阻力,比如下载一直实现不好,比如分页,也是参照别人的实现的,
分页公共模块
class Pagination:
def __init__(self, current_page, all_item):
try:
page = int(current_page)
except:
page = 1
if page < 1:
page = 1
all_pager, c = divmod(all_item, 10)
if int(c) > 0:
all_pager += 1
self.current_page = page
self.all_pager = all_pager
@property
def start(self):
return (self.current_page - 1) * 10
@property
def end(self):
return self.current_page * 10
def string_pager(self, base_url="/index/"):
if self.current_page == 1:
prev = '<li><a href="javascript:void(0);">上一页</a></li>'
else:
prev = '<li><a href="%s%s">上一页</a></li>' % (base_url, self.current_page - 1,)
if self.current_page == self.all_pager:
nex = '<li><a href="javascript:void(0);">下一页</a></li>'
else:
nex = '<li><a href="%s%s">下一页</a></li>' % (base_url, self.current_page + 1,)
last = '<li><a href="%s%s">尾页</a></li>' % (base_url, self.all_pager,)
str_page = "".join((prev,nex,last))
return str_page
在上传文件的时候,原来存放在本地,结果呢,下载处理不好,于是乎选择了七牛,需要到七牛的官网去注册自己的账号
from qiniu import Auth,put_file,etag,urlsafe_base64_encode
import qiniu.config
access_key='uVxowDUcYx641ivtUb111WBEI4112L3D117JHNM_AOtskRh4'
secret_key='PdXU9XrXTLtp1N21bhU1Frm1FDZqE1qhjkEaE9d1xVLZ5C'
def sendfile(key,file):
q=Auth(access_key,secret_key)
bucket_name='leilei22'
token = q.upload_token(bucket_name, key)
ret, info = put_file(token, key, file)
me= ret['hash']
f=etag(file)
if me==f:
assert_t=True
else:
assert_t=False
return assert_t
解析Excel,主要用于上传测试用例
import xlrd,xlwt
from xlutils.copy import copy
def datacel(filepath):
file=xlrd.open_workbook(filepath)
me=file.sheets()[0]
nrows=me.nrows
porject_id_list=[]
casename_list=[]
case_qianzhi_list=[]
case_buzhou_list=[]
case_yuqi_list=[]
for i in range(1,nrows):
porject_id_list.append(me.cell(i,0).value)
casename_list.append(me.cell(i,2).value)
case_qianzhi_list.append(me.cell(i,3).value)
case_buzhou_list.append(me.cell(i,4).value)
case_yuqi_list.append(me.cell(i,1).value)
return porject_id_list,casename_list,case_qianzhi_list,case_buzhou_list,case_yuqi_list
其实这么现在公共模块完毕了,其实现在可以着手去开始写我们的代码了,主要的代码,还有静态界面,因为前后端都是我自己,我的前端其实还是从网上找来的模板,
学习的道路是痛苦的,但是我相信我是可以成功的,
from tornado.web import RequestHandler
from models.model_py import User
class BaseHandler(RequestHandler):
@property
def db(self):
return self.application.db
def get_current_user(self):
user_id = self.get_secure_cookie('user_id')
if not user_id:
return None
return User.get_by_id(int(user_id))
基础的类集成了RequestHandler的类,,进行了一些简单的自定义,然后后续可以用这个,
进过两周的开发,已经形成了成熟的,
python tornado 实现类禅道系统的更多相关文章
- 用python实现自动化登录禅道系统 设置定时器自动执行脚本
由于各种原因,我想试下用python实现自动登录禅道系统,并且每天定时执行.(本人第一次接触自动化,在大佬眼中门槛都没摸到的类型) 首先缕清思路: 1.实现自动登录禅道系统,用selenium实现2. ...
- Linux下禅道系统的搭建
说明: 禅道系统的搭建,分两大部分 1.xampp环境的搭建 2.禅道系统的搭建 *********************************************************** ...
- python数据统计之禅道bug统计
背景 通过定期输出 每条产品的 BUG 情况,以此来反馈开发解决问题.测试跟进问题的情况:钉钉群推送提醒开发及时解决 以此我这边开始着手准备编写一个小工具,最终达到目的:自动定期发送统计报告,报告维度 ...
- windows系统搭建禅道系统(BUG管理工具)
我也呆过三家公司了,用过的BUG管理工具也是五花八门的,常见的一般有禅道,bugzilla,jira等 个人比较推荐禅道,功能强大,主页的说明文档也是相当详细,最主要的是,用的人比较多,出现使用问题一 ...
- 腾讯云服务器ubuntu18.04部署禅道系统
踩了不少坑,记录一下. 基于ubuntu18.04 一开始按照网上的攻略下载安装包 ZenTaoPMS.9.8.3.zbox_64.tar.gz,通过FileZilla传到linux的/opt下面,解 ...
- Jmeter跨线程组传递cookie,以禅道系统为例;BeanShell的存取数据的使用
先看下脚本结构: 思路:将登陆请求放在setUp Thread Group中:把登陆后的cookie通过正则提取出来,然后存为全局变量,传递到下一个线程组中: 第一步:添加setUp Thread G ...
- 20181017 work - Inno Setup 禅道 xp系统 楷体字体 win10倒计时 nwjs chosen
win10 闹钟和时钟 用个倒计时 Inno Setup 编译器 把应用程序打包成安装程序 nwjs-v0.14.7-win-ia32 XP专用 chrome用的49的版本 作用是把浏览器地址的程序打 ...
- 禅道 Rest API 开发
在老的 PHP 系统中使用 PHP 5.3以后的库 所谓老的系统,是指没有使用PHP 5.3以上命名空间(namespace)特性编码的系统. 但是,只要你的系统运行在 PHP 5.3及以上的环境,在 ...
- 禅道PMS兼容redmine用户认证接口
项目地址:https://github.com/web3d/zentao-redmine-userauth zentao-redmine-userauth 做了一个基本的用户认证接口,兼容redmin ...
随机推荐
- HTML <hr>标签
HTML的<hr>标签用来插入一个水平分割线以把文档分成几部分. 水平线通常显示为一条突出的或者凹下去的线条. 在页面中特定的位置插入水平线,既能使页面的结构清晰,又能使整个页面显得美观, ...
- 利用Java随机,生成随机学生数据
为模拟向数据库中大量插入学生数据(注:此处应该用PreparedStatement.batchUpdate等批处理提高效率)的情形,通过Java随机来生成学生数据. 一.要生成的学生数据 studen ...
- macOS Sierra Version 10.12.6 环境下Tomcat的下载与安装以及InterlliJ IDEA 2017.2 环境下配置Tomcat 与创建Web项目
一.Tomcat的下载与安装 1.官网(http://tomcat.apache.org/)下载Tomcat 9.0 Core:zip包: 2.解压到指定的文件夹即可安装完成: 3.测试是否安装成功 ...
- 【二次开发jumpserver】——整合jumpserver与zabbix推送主机功能
jasset/forms.py "ip", "other_ip", "hostname", "port", " ...
- adb不是内部或外部命令
1.安卓环境没配好, 2.tools下面没有adb.exe这个程序 3.2.3以后,adb.exe这个程序在platform-tools下而不是在tools下,所有环境变量的tools改成platfo ...
- HTK语音识别示例(Ubuntu)
一.简介 HTK(Hidden Markov Model Toolkit)是一款语音识别工具包,诞生于Cambridge University Engineering Department (CUED ...
- css的颜色表示,与透明度
今天是第一天开始写博客.主要还是想着好记性不如烂笔头.每天学点什么就记下来,也防止以后再去百度. 今天主要是一些旧知识的整理,整理中看到原来写的代码对颜色的表示有用rgb的,有用rega的,有用# ...
- 【Centos7】安装memcached
1.Linux系统安装memcached,首先要先安装libevent库. 安装libevent库有两种方式 (1)rpm安装 yum install libevent libdeve (2)源码包安 ...
- Win10各版本区别
Win10各版本之间的区别.. ------------------- =============================================功能最强大的,不是日后绝大多数中国用户 ...
- face ++ 人脸识别技术初步
网站地址: https://console.faceplusplus.com.cn/documents/5671791主要有 1 人脸识别技术 2 人体识别技术 ...