公司利用免费bug管理系统mantis来进行镜头管理,当然这个系统是经过二次开发的,表格字段都替换过了,所以进行简单的镜头管理是没有问题的。但美中不足是该系统基于web端,artist要查看提交自己的镜头任务都需要打开浏览器,这就降低了artist查看自己工作进度的积极性。于是决定开发一个集成在制作软件nuke中的小工具来解决这个问题。
姑且称呼这个工具为Nuke_Mantis吧。
总结起来就是需要这个工具能够能网站进行交互。
python语言无疑是一种非常优秀的语言,提供了urllib及urllib2两个库来处理表单提交以及获取页面的工作。
nuke支持的嵌入式语言中最简易的也就是python。所以我考虑采用python来完成这个项目。
这个工具要求具有以下三个基本特性:
1.该工具需要有一个ui页面
2.该工具需要有一个爬虫程序来获取数据提交表单
3.该工具还需要有一个类来处理硬盘数据,比如某个镜头在硬盘中的哪个地方
显然这三个特性之间是存在数据交互的,所以我决定首先构建一个父类,再分别为这三个特性构建子类,子类继承已有父类。
父类中存放需要交互的数据参数,子类继承父类后可以在内部实例化父类,这样三个子类之间就建立起一个数据交互体系了。
简单放出这四个类的不完整代码:
class ParentWindow(QtGui.QWidget): def __init__(self , parent=None ): QtGui.QWidget.__init__(self, parent) self.rownumber = 0 self.shotslist = [] self.status_time = 0 self.shot_time = 0 self.subshotslist = [] self.submitdata = {} self.newstream = None class MantisStream(ParentWindow): #the object must include username,password. def __init__(self,username,password,parent=None): ParentWindow.__init__(self, parent) class MantinsWindow( ParentWindow ): def __init__(self , parent=None ): #super(MantinsWindow, self).__init__( parent=None ) ParentWindow.__init__(self, parent) class Update_Version_Comment( ParentWindow ): def __init__(self , n , parent=None ): #super(Update_Version_Comment, self).__init__( parent ) ParentWindow.__init__(self, parent) #global versionValue,commentValue self.versionValue_b = None self.commentValue_b = None self.index = n ParentWindow.submitdata = {}
通过这种结构就非常轻松的解决了程序架构问题。
下一步就是写子类中具体的方法了:
简单提一下爬虫程序中的表单构建问题和书写ui界面时遇到的一些小问题和解决办法。
爬虫程序中如何构建表单:
首先我们需要分析网站结构,火狐浏览器按f12打开在‘网络’页面中分析php页面调用顺序非常简单,同时你点击相关页面也可以查看提交的表单,获取表单结构。了解php页面的调用顺序后,你就可以开始写请求了。以下是我的一个不完整请求:
# -*- coding: utf-8 -*- import urllib import urllib2 import cookielib cookie = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) postdata = urllib.urlencode({ 'return':'index.php', 'username':'Comp_hejian', 'password':'12345678', 'secure_session':'on' }) #define a requests req = urllib2.Request( url = 'http://website/mantisbt/login.php', data = postdata ) result = opener.open(req) print result.read()
按照这种方式就很轻松的获取到了页面源代码,之后就是分析页面源代码中的关键字。
当然你也可以在‘响应’页面中查看获取到的数据。
按照这种方式你可以很轻松的获取到你想要的数据。
书写ui界面时遇到的一些小问题和解决办法:
1.Nuke只支持PySide,不支持PyQt,但两种库其实几乎一样,代码都是通用的,如果要使用PyQt库,那么每台机器还要安装PyQt,很麻烦。为了省事起见,我还是使用了PySide来生成UI页面。
2.显示某个用户下的镜头最简单的办法就是使用表格工具,即QtGui.QTableWidget()对象,但该对象存在一个问题:
如果你使用setItem将QtGui.QTableWidgetItem()对象添加到表格中某个位置时,用户点击表头是可以对该列排序的,
如果使用setCellWidget将QtGui.QLabel()这类对象添加到表格中的某个位置时,用户点击表头就无法排序了。
解决这个问题的办法很简单,对需要排序的某一个列再建一个新列出来,原列用setCellWidget的方式来添加元素,新列用setItem的方式来添加元素,然后表头的点击事件建立一个信号:
self.myTable.horizontalHeader().sectionClicked.connect(self.sortByCol)
每当点击表头的时候,就会传递表头列的索引给sortByCol方法
在该方法中我们只需要做一个简单的判定即可:
def sortByCol(self,num): #print num if num == 1: self.myTable.sortByColumn( 5 , QtCore.Qt.AscendingOrder )
上面代码的意思就是如果点击表头列的索引num值是1的时候,就会对索引值为5的列进行降序排列。
通过这种简单的方式就可以实现我们想要的效果了,点击原列的表头,对新列进行排序。
3.在当前页面中点击一个按钮后会弹出一个新的子页面,该页面与主页面之间需要建立一个数据交互机制。
解决办法其实上文已经提到了,就是将主页面和子页面都继承到ParentWindow类中,这样就可以自由交换数据了。
以上就是这次项目开发的小结,希望自己在新年能更进一步吧!
(对现有mantis提个建议,sql数据结构太乱,需要调整,一些调用方式都需要改进)