def refresh_file_list(self, dir_path): novel_file_list = scan(unicode(dir_path)) self.treeView.setModel(ProcessModel(self.treeView, novel_file_list)) self.treeView.connect(self.treeView.selectionModel(), SIGNAL("currentRowChanged(QModelIndex, QModelIndex)"), self.save_and_load_novel_info) Log.info(u'加载小说目录[%s]完成'%dir_path)
def navigate(url, locatorExpress): try: KeyWordsAction.driver.get(url) Log.info("访问URL:%s" % (url)) except Exception, e: KeyWordsAction.testResult = False Log.info("访问URL:%s异常" % (url)) print str(e)
def close_browser(value, elementExpress): try: KeyWordsAction.driver.quit() Log.info("关闭浏览器") except Exception, e: KeyWordsAction.testResult = False Log.info("关闭浏览器y异常") print str(e)
def sleep(second, elementExpress): try: time.sleep(second) Log.info("睡觉%d秒" % (second)) except Exception, e: KeyWordsAction.testResult = False Log.info("睡觉%d秒异常" % (second)) print str(e)
def refresh_image_list(self, dir_path): for novel in self.treeView.model().novels(): desc, portrait = self.db.query_novel_info(novel.title) if not os.path.exists(portrait): portrait = os.path.join(str(self.imageFilePath.text()), novel.title+'.jpg') if not os.path.exists(portrait): portrait = os.path.join(str(self.imageFilePath.text()), novel.title+'.png') self.db.save_novel_info(novel.title, desc, portrait) Log.info(u'加载封面目录[%s]完成'%dir_path)
class NewHtmlReport(object): def __init__(self): self.log = Log() def html(self, testSystem, caseSum, testPass, testFail, start_time, end_time, casePass, caseFail, id, step, motion, locatorExpression, value, expect, getText, locatorExpressionResult, runResult): table_tr2 = "" a = [ "id", "step", "motion", "locatorExpression", "value", "expect", "getText", "locatorExpressionResult", "runResult" ] if type(id) == list: for i in range(len(id)): results = [] results += [ id[i], step[i], motion[i], locatorExpression[i], value[i], expect[i], getText[i], locatorExpressionResult[i], runResult[i] ] b = results c = zip(a, b) d = dict(c) table_td_case = REPORT_TMPL_CASE % dict( id=d["id"], step=d["step"], motion=d["motion"], locatorExpression=d["locatorExpression"], value=d["value"], expect=d["expect"], getText=d["getText"], locatorExpressionResult=d["locatorExpressionResult"], runResult=d["runResult"], detail_id=d["id"], hiddenRow_id=d["id"]) table_tr2 += table_td_case table_td = html_template % dict(testSystem=testSystem, caseSum=caseSum, testPass=testPass, testFail=testFail, start_time=start_time, end_time=end_time, casePass=casePass, caseFail=caseFail, table_try=table_tr2) filename = '{name}测试报告.html'.format(name=testSystem) dir = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'report') filename = os.path.join(dir, filename) # print(filename) self.log.info("用例执行完成请查看测试报告:" + filename) with open(filename, 'wb') as f: f.write(table_td.encode('utf8'))
def click(value, locatorExpress): try: KeyWordsAction.driver.find_element( by=KeyWordsAction.objectMap.getLocator("baidu", locatorExpress)[0], value=KeyWordsAction.objectMap.getLocator( "baidu", locatorExpress)[1]).click() Log.info("点击搜索按钮") except Exception, e: KeyWordsAction.testResult = False Log.info("点击搜索按钮异常") print str(e)
def waitfor(value, elementExpress): try: KeyWordsAction.driver.implicitly_wait(10) KeyWordsAction.driver.find_element( by=KeyWordsAction.objectMap.getLocator("baidu", elementExpress)[0], value=KeyWordsAction.objectMap.getLocator( "baidu", elementExpress)[1]) Log.info("智能等待") except Exception, e: KeyWordsAction.testResult = False Log.info("智能等待异常") print str(e)
def input(value, locatorExpress): try: KeyWordsAction.driver.find_element( by=KeyWordsAction.objectMap.getLocator("baidu", locatorExpress)[0], value=KeyWordsAction.objectMap.getLocator( "baidu", locatorExpress)[1]).clear() KeyWordsAction.driver.find_element( by=KeyWordsAction.objectMap.getLocator("baidu", locatorExpress)[0], value=KeyWordsAction.objectMap.getLocator( "baidu", locatorExpress)[1]).send_keys(value) Log.info("在输入框输入%s" % (value)) except Exception, e: KeyWordsAction.testResult = False Log.info("在输入框输入%s异常" % (value)) print str(e)
def __init__(self): super(MainWindow, self).__init__() # uic.loadUi('ui/MainWindow.ui', self) self.setupUi(self) self.db = DB() self.timer = QtCore.QTimer() self.thread_pool = ThreadPool(1) self.portraitView.setScene(PortraitDisplayScene()) # 选择小说内容所在目录 self.novelFileSelector.connect(self.novelFileSelector, SIGNAL("clicked()"), lambda: self.update_input_text(self.novelFilePath)) # 选择小说封面所在目录 self.imageFileSelector.connect(self.imageFileSelector, SIGNAL("clicked()"), lambda: self.update_input_text(self.imageFilePath)) # 内容目录更改后同步更新左面列表 self.novelFilePath.connect(self.novelFilePath, SIGNAL("textChanged(QString)"), self.refresh_file_list) self.imageFilePath.connect(self.imageFilePath, SIGNAL("textChanged(QString)"), self.refresh_image_list) # 内容目录更改后保存到历史记录 self.novelFilePath.connect(self.novelFilePath, SIGNAL("textChanged(QString)"), lambda x: self.db.save_param('LAST_NOVEL_PATH', str(x))) # 图片目录更改后保存到历史记录 self.imageFilePath.connect(self.imageFilePath, SIGNAL("textChanged(QString)"), lambda x: self.db.save_param('LAST_IMAGE_PATH', str(x))) # 开始转换 self.startConvert.connect(self.startConvert, SIGNAL("clicked()"), lambda: self.thread_pool.add_task(self.start_convert)) # 日志定时刷新 self.timer.connect(self.timer, SIGNAL("timeout()"), self.showLog) self.novelFilePath.setText(self.db.get_param('LAST_NOVEL_PATH')) self.imageFilePath.setText(self.db.get_param('LAST_IMAGE_PATH')) self.timer.start(100) Log.info(u'系统初始化完成...')
class DownloadService(Service): def __init__(self): self.danmu = Danmu() self.log = Log('Download Service') self.musicDownloader = NeteaseMusic() # 获取下载队列 分发至下载函数 def run(self): try: # 判断队列是否为空 if DownloadQueue.empty(): return # 获取新的下载任务 task = DownloadQueue.get() if task and 'type' in task: if task['type'] == 'music': self.musicDownload(task) elif task['type'] == 'vedio': pass except Exception as e: self.log.error(e) pass def musicDownload(self, song): # 搜索歌曲并下载 self.danmu.send('正在下载%s' % song['name']) filename = self.musicDownloader.download(song['id']) if filename: self.log.info('歌曲下载完毕 %s - %s' % (song['name'], song['singer'])) # 加入播放队列 PlayQueue.put({ 'type': 'music', 'filename': filename, 'name': song['name'], 'singer': song['singer'], 'username': song['username'] }) else: pass
def genAll(novels, target_html_dir): db = DB() for novel in novels: Log.info(u'处理文件[%s]' % novel.file_name) novel_cur_dir = os.path.join(target_html_dir, novel.safe_title) if not os.path.exists(novel_cur_dir): os.mkdir(novel_cur_dir) write(novel_cur_dir, 'index.html', genNovelIndex(novel)) desc, portrait = db.query_novel_info(novel.title) if portrait: shutil.copy(portrait, os.path.join(novel_cur_dir, 'post.jpg')) else: Log.warn(u'小说[%s]未找到封面图片' % novel.title) for volume in novel.volumes: if volume.content: write(novel_cur_dir, volume.safe_name + '.html', genChapter(volume, volume)) for chapter in volume.sub_chapters: write(novel_cur_dir, volume.safe_name + '-' + chapter.safe_name + '.html', genChapter(volume, chapter)) write(target_html_dir, 'index.html', genIndex(novels))
def start_convert(self): Log.info(u'-------------------------开始生成 HTML-------------------------') novel_root_dir = unicode(self.novelFilePath.text()) target_html_dir = os.path.join(novel_root_dir, 'html') if not os.path.exists(target_html_dir): os.makedirs(target_html_dir) Log.info(u'输出目录定位到:%s'%target_html_dir) HtmlGenerator.genAll(self.treeView.model().novels(), target_html_dir) Log.info(u'--------------------------任-务-完-成--------------------------')
def open_browser(browserName, locatorExpress): try: if str(browserName).lower() == "ie": #或许还要指定驱动 KeyWordsAction.driver = webdriver.Ie() Log.info("IE 实例已经声明") elif str(browserName).lower() == "chrome": #或许还要指定驱动 KeyWordsAction.driver = webdriver.Chrome() Log.info("Chorme 实例已经声明") elif str(browserName).lower() == "firefox": #或许还要指定驱动 KeyWordsAction.driver = webdriver.Firefox() Log.info("Firefox 实例已经声明") except Exception, e: KeyWordsAction.testResult = False Log.info("浏览器实例已经声明异常") print str(e)
def test_suiteByExcel(self): try: testCaseCount = ExcelUtil.getRowCount(Constants.Sheet_TestSuite) for i in range(1,testCaseCount): testCaseId = ExcelUtil.getCellData(Constants.Sheet_TestSuite,i,Constants.Col_TestCaseID) testCaseRunFlag = ExcelUtil.getCellData(Constants.Sheet_TestSuite,i,Constants.Col_RunFlag) if str(testCaseRunFlag).lower() == "y": Log.startTestCase(testCaseId) TestSuiteByExcel.testResult = True testStep = ExcelUtil.getFirstRowContainsTestCaseId(Constants.Sheet_TestSteps,testCaseId,Constants.Col_TestCaseID) testLastStep = ExcelUtil.getTestCaseLastStepRow(Constants.Sheet_TestSteps,testCaseId,testStep) for j in range(testStep,testLastStep): keyWord = ExcelUtil.getCellData(Constants.Sheet_TestSteps,j,Constants.Col_KeyWordAction) Log.info("从excel读取的关键词为:%s" %(keyWord)) value = ExcelUtil.getCellData(Constants.Sheet_TestSteps,j,Constants.Col_ActionValue) Log.info("从excel读取的value为:%s" %(value)) locatorExpress = ExcelUtil.getCellData(Constants.Sheet_TestSteps,j,Constants.Col_locatorExpression) Log.info("从excel读取的locator表达式为%s" %(locatorExpress)) if hasattr(KeyWordsAction,str(keyWord)): func = getattr(KeyWordsAction,str(keyWord)) if(str(keyWord).startswith("assert")): func(self,value) else: func(value,locatorExpress) if KeyWordsAction.testResult == False: #ExcelUtil.setCellData() 在step中写入结果信息 TestSuiteByExcel.testResult = False Log.endTestCase(testCaseId) break if KeyWordsAction.testResult == True: pass #ExcelUtil.setCellData() 写step中入结果信息 else: print '没有找到相应的方法' if TestSuiteByExcel.testResult == True: #ExcelUtil.setCellData() 在suit中写入结果信息 Log.endTestCase(testCaseId) except Exception,e: if (type(e) is AssertionError): Log.info(str(e)) self.assertTrue(1==2)
class SelectTheSorting(object): # 构造函数 def __init__(self): self.login = Login() self.pa = PageAction() self.pj = ParseJson() self.log = Log() def selectSort(self, area, branch): # 登录 self.login.loginMethod() # 选择区域 # if area == "北京区域": # 选择区域 self.pa.pageMotion(motion='click', locatorExpression="//input[@placeholder='请选择二级组织']") self.pa.pageMotion(motion='click', locatorExpression="//span[contains(text()," + "'" + area + "' " + ")]") self.log.info("选择" + area) if branch != None: self.pa.pageMotion(motion='click', locatorExpression="//input[@placeholder='请选择三级组织']") self.pa.pageMotion(motion='click', locatorExpression="//span[contains(text()," + "'" + branch + "' " + ")]") self.log.info("选择" + branch) else: pass # print("//span[contains(text(),"+"'"+area+"' " +")]") # 选择角色 self.pa.pageMotion(motion='click', locatorExpression="//input[@placeholder='请选择角色']") self.pa.pageMotion(motion='click', locatorExpression="//span[contains(text(), '分院IT')]") self.log.info("选择分院IT角色") self.pa.pageMotion(motion='click_sleep', locatorExpression="//button[@type='button']") self.log.info("点击进入") def role(self): # print(self.pj.getRoleData("area")) # print() self.pa.pageMotion(motion='click', locatorExpression="//input[@placeholder='请选择二级组织']") self.pa.pageMotion(motion='click', locatorExpression="//span[contains(text()," + "'" + self.pj.getRoleData( "area") + "' " + ")]") self.pa.pageMotion(motion='click', locatorExpression="//input[@placeholder='请选择三级组织']") self.pa.pageMotion(motion='click', locatorExpression="//span[contains(text()," + "'" + self.pj.getRoleData( "branch") + "' " + ")]")
class _Operation(object): def __init__(self): self.danmu = Danmu() self.log = Log('Danmu Service') self.downloader = NeteaseMusic() def order_song(self, danmu): """点歌台""" # 如果命令全为数字,跳转到id点歌 if danmu['command'].isdigit(): song = self._order_song_id(danmu) # 否则按照歌名点歌 else: song = self._order_song_name(danmu) if song: self.danmu.send('%s 点歌成功' % song['name']) DownloadQueue.put({ 'type': 'music', 'id': song['id'], 'name': song['name'], 'singer': song['ar'][0]['name'], 'username': danmu['name'] }) else: self.danmu.send('找不到%s' % danmu['command']) self.log.info('找不到%s' % danmu['command']) def _order_song_name(self, danmu): """通过歌名点歌""" self.log.info('%s 点歌 [%s]' % (danmu['name'], danmu['command'])) detail = danmu['command'].split('-') if len(detail) == 1: # 按歌曲名点歌 song = self.downloader.search_single(danmu['command'].strip()) elif len(detail) == 2: # 按歌曲名-歌手点歌 song = self.downloader.search_single(detail[0].strip(), detail[1].strip()) else: # 无效命令 song = {} return song def _order_song_id(self, danmu): """通过id点歌""" self.log.info('%s id点歌 [%s]' % (danmu['name'], danmu['command'])) song = self.downloader.get_info(danmu['command'].strip()) return song
class Login(object): # 构造函数 def __init__(self): self.pa = PageAction() self.pc = ParseConfig() self.log = Log() # 登录方法 def loginMethod(self): # 打开浏览器 self.pa.openBrowser(self.pc.getValue("addres", "url")) self.log.info("打开浏览器") # 输入用户名 self.pa.pageMotion(motion="input", locatorExpression="//input[@placeholder='请输入账号']", value=self.pc.getValue("login", "username")) self.log.info("输入用户名") # 输入密码 self.pa.pageMotion(motion="input", locatorExpression="//input[@placeholder='请输入密码']", value=self.pc.getValue("login", "password")) self.log.info("输入密码") # 点击登录 self.pa.pageMotion(motion="click", locatorExpression="//button[@type='button']") self.log.info("点击登录")
class RequestMethod(object): def __init__(self): self.pj = ParseJson() self.log = Log() def runMethod(self, caseCount, startTime, casePresent): testPlanId = self.pj.gettestPlanId('testPlanId') if testPlanId == "0": header = {"Content-Type": "application/json"} data = { "baseSchemeId": self.pj.getbaseSchemeId('baseSchemeId'), "caseCount": caseCount, "startTime": startTime, "casePresent": casePresent, "testPlanId": "" } try: res = requests.post( url="http://uat.atp.ikang.com/atp-api/report/testing", data=json.dumps(data), headers=header).json() time.sleep(2) self.log.info("进度条接口返回:" + json.dumps(res, ensure_ascii=False)) except Exception as e: self.log.info("接口请求失败: %s" % e) else: header = {"Content-Type": "application/json"} data = { "baseSchemeId": self.pj.getbaseSchemeId('baseSchemeId'), "caseCount": caseCount, "startTime": startTime, "casePresent": casePresent, "testPlanId": testPlanId } try: res = requests.post( url="http://uat.atp.ikang.com/atp-api/report/testing", data=json.dumps(data), headers=header).json() time.sleep(2) self.log.info("进度条接口返回:" + json.dumps(res, ensure_ascii=False)) except Exception as e: self.log.info("接口请求失败: %s" % e) def uploading(self, caseCount, endTime, failureRate, systemName, passingRate, startTime, message): testPlanId = str(self.pj.gettestPlanId("testPlanId")) if testPlanId == "0": data = MultipartEncoder({ "baseSchemeId": str(self.pj.getbaseSchemeId("baseSchemeId")), "caseCount": str(caseCount), "endTime": str(endTime), "failRate": str(failureRate), "file": (systemName, open(report + systemName + "测试报告.html", 'rb'), 'text/plain'), "passRate": str(passingRate), "startTime": str(startTime), "testResult": str(message), "testPlanId": "" }) try: res = requests.post( url='http://uat.atp.ikang.com/atp-api/report/upload', data=data, headers={ 'Content-Type': data.content_type }).json() time.sleep(2) self.log.info("上传接口返回:" + json.dumps(res, ensure_ascii=False)) except Exception as e: self.log.info("请求接口失败:%s" % e) else: data = MultipartEncoder({ "baseSchemeId": str(self.pj.getbaseSchemeId("baseSchemeId")), "caseCount": str(caseCount), "endTime": str(endTime), "failRate": str(failureRate), "file": (systemName, open(report + systemName + "测试报告.html", 'rb'), 'text/plain'), "passRate": str(passingRate), "startTime": str(startTime), "testResult": str(message), "testPlanId": "" }) try: res = requests.post( url='http://uat.atp.ikang.com/atp-api/report/upload', data=data, headers={ 'Content-Type': data.content_type }).json() time.sleep(2) self.log.info("上传接口返回:" + json.dumps(res, ensure_ascii=False)) except Exception as e: self.log.info("请求接口失败:%s" % e)
class DanmuService(Service): def __init__(self): self.danmu = Danmu() self.musicDownloader = NeteaseMusic() self.log = Log('Danmu Service') self.commandMap = { '点歌': 'selectSongAction', 'id': 'selectSongByIdAction' } pass def run(self): try: self.parseDanmu() time.sleep(1.5) except Exception as e: self.log.error(e) # 解析弹幕 def parseDanmu(self): danmuList = self.danmu.get() if danmuList: for danmu in danmuList: self.log.debug('%s: %s' % (danmu['name'], danmu['text'])) self.danmuStateMachine(danmu) # 将对应的指令映射到对应的Action上 def danmuStateMachine(self, danmu): text = danmu['text'] commandAction = '' for key in self.commandMap: # 遍历查询comand是否存在 若存在则反射到对应的Action if text.find(key) == 0 and hasattr(self, self.commandMap[key]): danmu['command'] = danmu['text'][len(key) : len(danmu['text'])] getattr(self, self.commandMap[key])(danmu) break pass # 歌曲名点歌 def selectSongAction(self, danmu): self.log.info('%s 点歌 [%s]' % (danmu['name'], danmu['command'])) command = danmu['command'] song = [] # 按歌曲名-歌手点歌 if command.find('-') != -1: detail = command.split('-') if len(detail) == 2: song = self.musicDownloader.searchSingle(detail[0], detail[1]) else: # 查询失败 song = {} pass # 直接按歌曲名点歌 else: song = self.musicDownloader.searchSingle(danmu['command']) if song: self.danmu.send('%s点歌成功' % song['name']) DownloadQueue.put({ 'type': 'music', 'id': song['id'], 'name': song['name'], 'singer': song['singer'], 'username': danmu['name'] }) else: # 未找到歌曲 self.danmu.send('找不到%s' % danmu['command']) self.log.info('找不到%s' % danmu['command']) pass # 通过Id点歌 def selectSongByIdAction(self, danmu): command = danmu['command'] try: song = self.musicDownloader.getInfo(command) if song: self.danmu.send('%s点歌成功' % song['name']) DownloadQueue.put({ 'type': 'music', 'id': song['id'], 'name': song['name'], 'singer': song['singer'], 'username': danmu['name'] }) else: # 未找到歌曲 raise Exception('未找到歌曲') except Exception as e: self.danmu.send('找不到%s' % danmu['command']) self.log.info('找不到%s' % danmu['command'])
class MediaService(Service): def __init__(self): self.danmu = Danmu() self.log = Log('Media Service') self.config = Config() def run(self): try: # 判断队列是否为空 if PlayQueue.empty(): # 获取随机文件,播放 musicPath = './resource/music/' randomMusic = self.getRandomFile(musicPath) musicName = os.path.basename(randomMusic) musicName = musicName.replace(os.path.splitext(randomMusic)[1], '') self.playMusic({ 'username': '******', 'name': musicName, 'filename': musicPath + randomMusic }, True) return # 获取新的下载任务 task = PlayQueue.get() if task and 'type' in task: if task['type'] == 'music': self.playMusic(task) elif task['type'] == 'vedio': pass except Exception as e: self.log.error(e) # 播放音乐 def playMusic(self, music, autoPlay=False): imagePath = './resource/img/' randomImage = imagePath + self.getRandomFile(imagePath) self.log.info('[Music] 开始播放[%s]点播的[%s]' % (music['username'], music['name'])) self.danmu.send('正在播放 %s' % music['name']) # 获取歌词 assPath = './resource/lrc/default.ass' if 'lrc' in music: assPath = music['lrc'] # 开始播放 command = ffmpeg().getMusic(music=music['filename'], output=self.getRTMPUrl(), image=randomImage, ass=assPath) command = "%s 2>> ./log/ffmpeg.log" % command self.log.debug(command) process = subprocess.Popen(args=command, cwd=os.getcwd(), shell=True) process.wait() # 播放完毕 if not autoPlay: os.remove(path=music['filename']) self.log.info('[Music] [%s]播放结束' % music['name']) # 获取推流地址 def getRTMPUrl(self): url = self.config.get(module='rtmp', key='url') code = self.config.get(module='rtmp', key='code') return url + code # 获取随机文件 def getRandomFile(self, path): fileList = os.listdir(path) if len(fileList) == 0: raise Exception('无法获取随机文件,%s为空' % path) index = random.randint(0, len(fileList) - 1) return fileList[index]
class KuwoDownloader: def __init__(self): self.log = Log('KuwoDownloader Service') # 取第一个 def search(self, key): #搜索歌曲爬虫 search_url = 'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36 Edg/84.0.522.63", "Cookie": "_ga=GA1.2.1083049585.1590317697; _gid=GA1.2.2053211683.1598526974; _gat=1; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1597491567,1598094297,1598096480,1598526974; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1598526974; kw_token=HYZQI4KPK3P", "Referer": "http://www.kuwo.cn/search/list?key=%E5%91%A8%E6%9D%B0%E4%BC%A6", "csrf": "HYZQI4KPK3P", } params = { "key": key, # 页数 "pn": "1", # 音乐数 "rn": "10", "httpsStatus": "1", "reqId": "cc337fa0-e856-11ea-8e2d-ab61b365fb50", } resp = requests.get(search_url, params=params, headers=headers) # print(resp.text) json_string = json.loads(resp.text) song_list = json_string["data"]["list"] for song in song_list: print(song) songid = song_list[0]["musicrid"] return songid #拼接下载链接 def get_song(self, musicrid): return 'http://antiserver.kuwo.cn/anti.s?useless=/resource/&format=mp3&rid=%s&response=res&type=convert_url&' % musicrid # 解析下载链接 def get_download_url(self, musicrid): headers2 = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', # 'Connection': 'keep-alive', 'Host': 'antiserver.kuwo.cn', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36' } resp = requests.get(self.get_song(musicrid), headers=headers2, allow_redirects=False) download_url = resp.headers['Location'] self.log.info('解析链接 %s' % download_url) return download_url def download(self, musicname=None, musicrid=None): if musicrid: if 'MUSIC' not in musicrid: musicrid = 'MUSIC_' + musicrid return self.__download__(musicrid) else: musicrid = self.search(musicname) return self.__download__(musicrid) #下载歌曲到本地 def __download__(self, musicrid): filename = './downloader/download/%s.mp3' % musicrid if not os.path.exists(filename): resp = requests.get(self.get_download_url(musicrid)) with open(filename, "wb") as file: file.write(resp.content) else: self.log.info("使用缓存的音乐%s" % filename) return filename #获得歌曲信息 包括歌词 def get_song_info(self, musicrid): musicrid = musicrid.replace('MUSIC_', '') url = 'http://m.kuwo.cn/newh5/singles/songinfoandlrc' params = { 'musicId': musicrid, "httpsStatus": "1", "reqId": "cc337fa0-e856-11ea-8e2d-ab61b365fb50" } resp = requests.get(url, params=params) return json.loads(resp.text)['data'] #获得歌曲信息 def getInfo(self, musicrid): info = self.get_song_info(musicrid)["songinfo"] return { 'id': musicrid, 'name': info['songName'], 'singer': info['artist'], } #获得歌词 def getLyric(self, musicrid): info = self.get_song_info(musicrid)['lrclist'] #如果是纯音乐不传歌词 if not info: return '[00:00.000] 纯音乐,请您欣赏\n[10:00.000] ' lyric = "" for lineLyric in info: lyric = lyric + '[' + self.convert_time( lineLyric['time']) + ']' + lineLyric['lineLyric'] + '\n' return lyric #将酷我歌词时间格式转换为网易云格式 def convert_time(self, timeStr): time = float(timeStr) sec = int(time) ms = str(time).split('.')[1] m, s = divmod(sec, 60) return "{0:02d}:{1:02d}.{2:03d}".format(m, s, int(ms))
class MediaService(Service): def __init__(self): self.danmu = Danmu() self.log = Log('Media Service') self.config = Config() self.ass = AssMaker() def run(self): try: # 判断队列是否为空 if PlayQueue.empty(): time.sleep(3) # 获取随机文件,播放 musicPath = './resource/music/' musicName = self.getRandomFile(musicPath, '.mp3') # musicName = os.path.basename(musicName) musicName = os.path.splitext(musicName)[0] task = {} # 存在详情文件 if os.path.isfile('%s%s.mp3.json' % (musicPath, musicName)): f = open('%s%s.mp3.json' % (musicPath, musicName), 'rt') task = json.loads(f.read()) f.close() else: pass self.playMusic(task) else: # 获取新的下载任务 task = PlayQueue.get() if task and 'type' in task: if task['type'] == 'id': self.playMusic(task) elif task['type'] == 'mv': self.playVedio(task) pass except Exception as e: self.log.error(e) # 播放音乐 def playMusic(self, music): self.log.info('[Music] 开始播放[%s]点播的[%s]' % (music['username'], music['info']['name'])) self.danmu.send('正在播放%s' % music['info']['name']) # 生成背景字幕 self.ass.make_ass(music, './resource/bak.ass') # 处理图片 imagePath = './resource/img/' randomImage = imagePath + self.getRandomFile(imagePath) command = ffmpeg().getImage(image=randomImage, output='./resource/bak.jpg', ass='./resource/bak.ass') command = "%s 2>> ./log/ffmpeg_img.log" % command self.log.debug(command) process = subprocess.Popen(args=command, cwd=os.getcwd(), shell=True) process.wait() # 获取歌词 assPath = '' if 'lrc' in music['info']: assPath = './resource/music/%s.mp3.ass' % music['info']['id'] # 开始播放 mp3Path = './resource/music/%s.mp3' % music['info']['id'] command = ffmpeg().getMusic(music=mp3Path, output=self.getRTMPUrl(), image='./resource/bak.jpg', ass=assPath) command = "%s 2>> ./log/ffmpeg.log" % command self.log.debug(command) process = subprocess.Popen(args=command, cwd=os.getcwd(), shell=True) process.wait() self.log.info('[Music] [%s]播放结束' % music['info']['name']) # 播放视频 def playVedio(self, music): self.log.info('[Music] 开始播放[%s]点播的[%s]' % (music['username'], music['info']['name'])) self.danmu.send('正在播放%s' % music['info']['name']) # 开始播放 vedioPath = './resource/video/%s_mv.flv' % music['info']['id'] command = ffmpeg().getVedio(vedio=vedioPath, output=self.getRTMPUrl()) command = "%s 2>> ./log/ffmpeg.log" % command self.log.debug(command) process = subprocess.Popen(args=command, cwd=os.getcwd(), shell=True) process.wait() self.log.info('[Music] [%s]播放结束' % music['info']['name']) # 获取推流地址 def getRTMPUrl(self): url = self.config.get(module='rtmp', key='url') code = self.config.get(module='rtmp', key='code') return url + code # 获取随机文件 def getRandomFile(self, path, type=None): fileList = [] if type: for filename in os.listdir(path): if os.path.splitext(filename)[1] == type: fileList.append(filename) else: fileList = os.listdir(path) if len(fileList) == 0: raise Exception('无法获取随机文件,%s为空' % path) index = random.randint(0, len(fileList) - 1) return fileList[index]
class DownloadService(Service): def __init__(self): self.danmu = Danmu() self.log = Log('Download Service') self.musicDownloader = NeteaseMusic() self.kuwoDownloader = KuwoDownloader() # 获取下载队列 分发至下载函数 def run(self): try: # 判断队列是否为空 if DownloadQueue.empty(): return # 获取新的下载任务 task = DownloadQueue.get() if task and 'type' in task: if task['type'] == 'music': self.musicDownload(task) elif task['type'] == 'vedio': pass #酷我音乐 elif task['type'] == 'kuwo': self.kuwoMusicDownload(task) except Exception as e: self.log.error(e) traceback.print_exc() pass def musicDownload(self, song): # 搜索歌曲并下载 #发送弹幕 self.danmu.send('正在下载%s' % song['name']) filename = self.musicDownloader.download(song['id']) headers = { 'authority': 'music.163.com', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36', 'content-type': 'application/x-www-form-urlencoded', 'accept': '*/*', 'origin': 'https://music.163.com', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://music.163.com/search/', 'accept-language': 'zh-CN,zh;q=0.9', } url = 'http://music.163.com/api/song/lyric?' + 'id=' + str( song['id']) + '&lv=1&kv=1&tv=-1' resp = requests.get(url, headers=headers) resjson = json.loads(resp.text) #左下角info信息 info = '当前网易云id:' + str( song['id'] ) + "\\N当前播放的歌曲:" + song['name'] + "\\N点播人:" + song['username'] #生成ass文件 lrc = "" tlrc = "" #如果是纯音乐不传歌词 if not "nolyric" in resjson: lrc = resjson["lrc"]["lyric"] tlrc = resjson["tlyric"]["lyric"] else: lrc = '[00:00.000] 纯音乐,请您欣赏\n[10:00.000] ' self.musicDownloader.make_ass(song['name'], info, lrc_to_ass(lrc), tlrc_to_ass(tlrc)) if filename: self.log.info('歌曲下载完毕 %s - %s' % (song['name'], song['singer'])) # 加入播放队列 PlayQueue.put({ 'type': 'music', 'filename': filename, 'name': song['name'], 'singer': song['singer'], 'username': song['username'], 'lrc': './resource/lrc/' + song['name'] + '.ass' }) else: pass def kuwoMusicDownload(self, song): # 搜索歌曲并下载 #发送弹幕 self.danmu.send('正在下载%s' % song['name']) filename = self.kuwoDownloader.download(musicrid=song['id']) self.log.info("下载成功,文件 " + filename) #左下角info信息 info = '当前酷我歌曲id:' + str( song['id'] ) + "\\N当前播放的歌曲:" + song['name'] + "\\N点播人:" + song['username'] #生成ass文件 lrc = self.kuwoDownloader.getLyric(song['id']) tlrc = "" self.musicDownloader.make_ass(song['name'], info, lrc_to_ass(lrc), tlrc_to_ass(tlrc)) if filename: self.log.info('歌曲下载完毕 %s - %s' % (song['name'], song['singer'])) # 加入播放队列 PlayQueue.put({ 'type': 'music', 'filename': filename, 'name': song['name'], 'singer': song['singer'], 'username': song['username'], 'lrc': './resource/lrc/' + song['name'] + '.ass' }) else: pass
class PageAction(object): def __init__(self): self.log = Log() self.key = KeyboardKeys() self.rv = ReplaceValue() def openBrowser(self, url): ''' :param url: 输入的地址 :return: 打开浏览器 ''' global driver try: # option = webdriver.ChromeOptions() # option.add_argument('--headless') # driver = webdriver.Chrome(chrome_options=option) driver = webdriver.Chrome() driver.maximize_window() except Exception as e: raise e try: driver.get(url) driver.implicitly_wait(10) except Exception as e: raise e def pageMotion(self, motion=None, locatorExpression=None, hoverLocator=None, value=None, table=None): ''' :param motion: 动作指令 :param locatorExpression: 操作元素定位表达式 :param hoverLocator:悬浮点击位置定位表达式 :param value: :return: ''' global driver if motion == "click": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: # 点击事件 driver.find_element_by_xpath(locatorExpression).click() time.sleep(4) except: # print("未找到" + locatorExpression + "点击事件的元素") self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') elif motion == "click_bottom": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: # 点击事件 js = "var q=getElementByXPath(//div[@class='slider-bar']).scrollTop=0" driver.execute_script(js) time.sleep(2) driver.find_element_by_xpath(locatorExpression).click() time.sleep(4) except: # print("未找到" + locatorExpression + "点击事件的元素") self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') elif motion == "click_top": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: # 点击事件 js = "var q=getElementByXPath('//div[@class='slider-bar']').scrollTop=100000" driver.execute_script(js) time.sleep(2) driver.find_element_by_xpath(locatorExpression).click() time.sleep(4) except: # print("未找到" + locatorExpression + "点击事件的元素") self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') elif motion == "input": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: # 清除输入框 driver.find_element_by_xpath(locatorExpression).clear() # 输入值 driver.find_element_by_xpath(locatorExpression).send_keys( value) time.sleep(2) except: # print("未找到" + locatorExpression + "输入事件的元素") self.log.info('未找到"' + locatorExpression + '"输入事件的定位元素') elif motion == "double_click": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: double = driver.find_element_by_xpath(locatorExpression) ActionChains(driver).double_click(double).perform() time.sleep(4) except: # print("未找到" + locatorExpression + "双击事件的元素") self.log.info('未找到' + locatorExpression + '双击事件的定位元素') elif motion == "double_click_esc": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: double = driver.find_element_by_xpath(locatorExpression) ActionChains(driver).double_click(double).perform() time.sleep(4) ActionChains(driver).send_keys(Keys.ESCAPE).perform() time.sleep(2) except: # print("未找到" + locatorExpression + "双击事件的元素") self.log.info('未找到' + locatorExpression + '双击事件的定位元素') elif motion == "hover": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: ydong = driver.find_element_by_xpath(locatorExpression) ActionChains(driver).move_to_element(ydong).perform() time.sleep(2) except: self.log.info('未找到"' + locatorExpression + '"鼠标悬浮事件的定位元素') # try: # driver.find_element_by_xpath(hoverLocator).click() # time.sleep(3) # except: # self.log.info('未找到"' + hoverLocator + '"鼠标悬浮后点击事件的定位元素') # elif motion == "enter": # try: # self.key.oneKey("enter") # time.sleep(8) # except Exception as e: # self.log.info("模拟enter报错: %s" %e) elif motion == "enter": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: driver.find_element_by_xpath(locatorExpression).send_keys( Keys.ENTER) time.sleep(5) except: self.log.info('未找到"' + locatorExpression + '"回车键事件的定位元素') elif motion == "esc": try: self.key.oneKey("esc") time.sleep(2) except Exception as e: self.log.info("模拟esc报错: %s" % e) elif motion == "top": try: js = "var q=document.getElementById('main-scroll').scrollTop = 0" driver.execute_script(js) time.sleep(2) except Exception as e: self.log.info("页面置顶报错: %s" % e) # try: # driver.find_element_by_xpath(locatorExpression).click() # time.sleep(3) # except: # self.log.info('未找到"' + locatorExpression + '"置顶后点击事件的定位元素') elif motion == "click_esc": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: # 点击事件 driver.find_element_by_xpath(locatorExpression).click() time.sleep(9) ActionChains(driver).send_keys(Keys.ESCAPE).perform() time.sleep(2) except: # print("未找到" + locatorExpression + "点击事件的元素") self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') # try: # self.key.oneKey("esc") # time.sleep(2) # except Exception as e: # self.log.info("模拟esc报错: %s" %e) elif motion == "quit": try: driver.quit() except Exception as e: self.log.info("退出浏览器失败: %s" % e) elif motion == "text": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: text = driver.find_element_by_xpath(locatorExpression).text time.sleep(2) # print(text) return text except: self.log.info('未找到"' + locatorExpression + '"定位的元素文本信息') # driver.quit() elif motion == "attribute": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: text = driver.find_element_by_xpath( locatorExpression).get_attribute('value') time.sleep(2) # print(text) return text except: self.log.info('未找到"' + locatorExpression + '"定位的元素文本信息') elif motion == "table_cell": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: webTable = driver.find_element_by_xpath(locatorExpression) # listData = webTable.text tableMessage = Table(webTable) text = tableMessage.getCell(0, 5).text workNo = tableMessage.getCell(0, 4).text self.rv.keepValue(workNo) time.sleep(2) return text except: self.log.info('未找到"' + locatorExpression + '"定位的元素table表格信息') elif motion == "click_role": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: # 点击事件 driver.find_element_by_xpath(locatorExpression).click() time.sleep(5) except: # print("未找到" + locatorExpression + "点击事件的元素") self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') elif motion == "click_sleep": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: # 点击事件 driver.find_element_by_xpath(locatorExpression).click() time.sleep(10) except: # print("未找到" + locatorExpression + "点击事件的元素") self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') elif motion == "click_await": locator = (By.XPATH, locatorExpression) try: WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located(locator)) except: self.log.info('未找到"' + locatorExpression + '"点击事件的定位元素') try: text = driver.find_element_by_xpath(locatorExpression).text if "等待汇总" not in text: while True: driver.refresh() time.sleep(10) text = driver.find_element_by_xpath( locatorExpression).text if "等待汇总" in text: locator = ( By.XPATH, "//i[@class='icon ikcon ikcon-iconfont iconpick-up']" ) WebDriverWait(driver, 15).until( EC.presence_of_all_elements_located(locator)) driver.find_element_by_xpath( "//i[@class='icon ikcon ikcon-iconfont iconpick-up']" ).click() time.sleep(3) locator = ( By.XPATH, "//i[@class='icon ikcon ikcon-iconfont iconexpand']" ) WebDriverWait(driver, 15).until( EC.presence_of_all_elements_located(locator)) driver.find_element_by_xpath( "//i[@class='icon ikcon ikcon-iconfont iconexpand']" ).click() time.sleep(3) break except: self.log.info('未找到"' + locatorExpression + '"定位的元素文本信息') else: driver.quit() self.log.info("请检查excel'动作'列是否书写正确")
class TestCase(object): # 构造函数 def __init__(self): self.parseExcel = ParseExcel() self.log = Log() self.select = SelectTheSorting() self.pa = PageAction() self.pj = ParseJson() self.rm = RequestMethod() # 加载测试用例 # @app.task def ruCase(self, area, branch): ''' :return: 运行测试用例 ''' # select = SelectTheSorting() self.select.selectSort(area, branch) startTime, excel_id, excel_step, excel_motion, excel_locatorExpression, \ excel_hoverLocator, excel_value, excel_expect, excel_getText, \ excel_locatorExpressionResult, excel_runResult = self.parseExcel.getCaseData() self.log.info("用例开始时间:" + startTime) # print(excel_id) # print(excel_step) # print(excel_motion) # print(len(excel_id)) # print(excel_getText) caseNum = len(excel_id) - 1 pass_count = [] fail_count = [] exception = [] for i in range(len(excel_id)): # print(i) id = str(excel_id[i]) step = excel_step[i] motion = excel_motion[i] # print(motion) locatorExpression = excel_locatorExpression[i] hoverLocator = excel_hoverLocator[i] value = excel_value[i] getText = excel_getText[i] # print(getText) expect = excel_expect[i] locatorExpressionResult = excel_locatorExpressionResult[i] # print(locatorExpressionResult) if motion == "click": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "click_bottom": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "click_top": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "input": if value == 'number': self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression, value=self.pj.getJsonData(value)) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if self.pj.getJsonData(value) in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) else: self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression, value=value) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) if isinstance(expect, int): expect = str(expect) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) else: try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "hover": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "double_click": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "double_click_esc": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "enter": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "top": self.pa.pageMotion(motion=motion) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "click_esc": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "click_role": self.select.role() self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "步" + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "click_sleep": self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "click_await": self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) self.pa.pageMotion(motion=motion, locatorExpression=locatorExpression) result = self.pa.pageMotion(motion=getText, locatorExpression=locatorExpressionResult) try: if expect in result: self.parseExcel.writeCell(i + 2, 10, "pass") self.log.info("第" + id + "步:" + step + "-----pass") pass_count.append(i) else: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----fail") fail_count.append(i) self.pa.pageMotion(motion='quit') break except: self.parseExcel.writeCell(i + 2, 10, "fail") self.log.info("第" + id + "步:" + step + "-----exception") exception.append(i) self.pa.pageMotion(motion='quit') break self.rm.runMethod(caseCount=caseNum, startTime=startTime, casePresent=id) elif motion == "quit": self.parseExcel.writeCell(i + 2, 10, "pass") self.pa.pageMotion(motion=motion) excelstartTime, excelid, excelstep, excelmotion, excellocatorExpression, \ excelhoverLocator, excelvalue, excelexpect, excelgetText, \ excellocatorExpressionResult, runResult = self.parseExcel.getCaseData() # endTime = datetime.datetime.now() endTime = time.strftime('%Y-%m-%d %H:%M:%S') self.log.info("用例结束时间:" + endTime) # sumCase = len(pass_count) + len(fail_count) pr = len(pass_count) / caseNum # passingRate = '{:.0%}'.format(pr) passingRate = "%.2f" % pr fr = len(fail_count) / caseNum # failureRate = '{:.0%}'.format(fr) failureRate = "%.2f" % fr print(failureRate) self.log.info("用例通过条数" + str(len(pass_count))) self.log.info("用例失败条数:" + str(len(fail_count))) self.log.info("xpath定位失败:" + str(len(exception))) message = None if len(pass_count) == caseNum: message = 1 # 1代表成功 if len(fail_count) > 0: message = 2 # 2代表失败 if len(exception) > 0: message = 3 # 3代表未找到定位元素 # print(message) return startTime, endTime, caseNum, len(pass_count), len(fail_count), passingRate, failureRate, \ excel_id, excel_step, excel_motion, excel_locatorExpression, excel_value, excel_expect, excel_getText, \ excel_locatorExpressionResult, runResult, message
class DownloadService(Service): def __init__(self): self.danmu = Danmu() self.ass = AssMaker() self.log = Log('Download Service') self.neteaseMusic = NeteaseMusic() # 获取下载队列 分发至下载函数 def run(self): try: # 判断队列是否为空 if DownloadQueue.empty(): return # 获取新的下载任务 task = DownloadQueue.get() if task and 'type' in task: self.download(task) PlayQueue.put(task) self.log.info('播放列表+1') except Exception as e: self.log.error(e) # 下载媒体 def download(self, info, filename=None, callback=None): self.danmu.send('正在下载%s' % info['info']['name']) # 名称处理 if not filename: filename = info['info']['id'] if info['type'] == 'id': songId = info['info']['id'] # 本地不存在此歌曲 if (str(songId) + '.mp3') not in os.listdir('./resource/music/'): # 下载歌曲 musicUrl = self.neteaseMusic.getSingleUrl(songId) mp3_filename = './resource/music/%s.mp3' % filename Request.download(musicUrl, mp3_filename, callback) # 获取歌词文件 lyric = self.neteaseMusic.getLyric(songId) if lyric: ass_filename = '%s.ass' % mp3_filename self.ass.make_lrc_ass(ass_filename, lyric['lyric'], lyric['tlyric']) info['info']['lrc'] = True else: info['info']['lrc'] = False # 保存点歌信息 file = open('%s.json' % mp3_filename, 'w') file.write(json.dumps(info, ensure_ascii=False)) file.close() self.log.info('歌曲下载完毕 %s - %s' % (info['info']['name'], info['info']['singer'])) else: # 更新点歌信息 pass return filename elif info['type'] == 'mv': mvId = info['info']['id'] # 本地不存在此mv if (str(mvId) + '_mv.flv') not in os.listdir('./resource/video/'): # 下载mv mvUrl = '' if '720' in info['info']['brs']: mvUrl = info['info']['brs']['720'] elif '480' in info['info']['brs']: mvUrl = info['info']['brs']['480'] else: return None downPath = './resource/video/%s_mv.down' % filename Request.download(mvUrl, downPath, callback) self.log.info('MV下载完毕 %s - %s' % (info['info']['name'], info['info']['singer'])) # 生成背景字幕 self.ass.make_ass(info, './resource/video/bak.ass') # 渲染MV renderPath = './resource/video/%s_mv.render' % filename command = ffmpeg().renderVedio(vedio=downPath, output=renderPath, ass='./resource/video/bak.ass') command = "%s 2>> ./log/ffmpeg.log" % command self.log.debug(command) process = subprocess.Popen(args=command, cwd=os.getcwd(), shell=True) process.wait() # 渲染完成,修改文件名 os.remove(downPath) mp4Path = './resource/video/%s_mv.flv' % filename os.rename(renderPath, mp4Path) # 保存点歌信息 file = open('%s.json' % mp4Path, 'w') file.write(json.dumps(info, ensure_ascii=False)) file.close() self.log.info('MV渲染完毕 %s - %s' % (info['info']['name'], info['info']['singer'])) else: # 更新点歌信息 pass return filename
class DanmuService(Service): def __init__(self): self.danmu = Danmu() self.config = Config() self.neteaseMusic = NeteaseMusic() self.log = Log('Danmu Service') self.commandMap = { '点歌=': 'selectSongAction', 'id=': 'selectSongByIdAction', 'mv=': 'selectMvByIdAction', '切歌': 'DebugAction' } pass def run(self): try: self.parseDanmu() time.sleep(1.5) except Exception as e: self.log.error(e) # 解析弹幕 def parseDanmu(self): danmuList = self.danmu.get() if danmuList: for danmu in danmuList: self.log.debug('%s: %s' % (danmu['name'], danmu['text'])) if danmu['name'] != self.config.get('miaoUser'): # 不响应弹幕姬的弹幕 danmu['text'] = danmu['text'].replace(' ', '') # 删除空格防和谐 self.danmuStateMachine(danmu) pass # 将对应的指令映射到对应的Action上 def danmuStateMachine(self, danmu): text = danmu['text'] commandAction = '' for key in self.commandMap: # 遍历查询comand是否存在 若存在则反射到对应的Action if text.find(key) == 0 and hasattr(self, self.commandMap[key]): danmu['command'] = danmu['text'][len(key):len(danmu['text'])] getattr(self, self.commandMap[key])(danmu) break pass # 歌曲名点歌 def selectSongAction(self, danmu): self.log.info('%s 点歌 [%s]' % (danmu['name'], danmu['command'])) command = danmu['command'] song = [] # 按歌曲名-歌手点歌 if command.find('-') != -1: detail = command.split('-') if len(detail) == 2: song = self.neteaseMusic.searchSingle(detail[0], detail[1]) else: # 查询失败 song = {} # 直接按歌曲名点歌 else: song = self.neteaseMusic.searchSingle(danmu['command']) if song: self.danmu.send('%s点歌成功' % song['name']) DownloadQueue.put({ 'type': 'id', 'info': song, 'username': danmu['name'], 'time': danmu['time'] }) else: # 未找到歌曲 self.danmu.send('找不到%s' % danmu['command']) self.log.info('找不到%s' % danmu['command']) # 通过Id点歌 def selectSongByIdAction(self, danmu): self.log.info('%s ID [%s]' % (danmu['name'], danmu['command'])) command = danmu['command'] try: song = self.neteaseMusic.getInfo(command) if song: self.danmu.send('%s点歌成功' % song['name']) DownloadQueue.put({ 'type': 'id', 'info': song, 'username': danmu['name'], 'time': danmu['time'] }) else: # 未找到歌曲 raise Exception('未找到歌曲') except Exception as e: self.danmu.send('找不到%s' % danmu['command']) self.log.info('找不到%s' % danmu['command']) # 通过Id点Mv def selectMvByIdAction(self, danmu): self.log.info('%s MV [%s]' % (danmu['name'], danmu['command'])) command = danmu['command'] try: mv = self.neteaseMusic.getMv(command) if mv: self.danmu.send('%s点播成功' % mv['name']) DownloadQueue.put({ 'type': 'mv', 'info': mv, 'username': danmu['name'], 'time': danmu['time'] }) else: # 未找到歌曲 raise Exception('未找到MV') except Exception as e: self.danmu.send('找不到%s' % danmu['command']) self.log.info('找不到%s' % danmu['command']) def DebugAction(self, danmu): if danmu['name'] in self.config.get('adminUser'): if danmu['text'] == '切歌': os.system( "kill `ps a|grep 'ffmpeg -re'|grep -v 'sh'|grep -v 'grep'|awk '{print $1}'`" ) self.danmu.send('切歌成功')