def fetchPic(self, size=-1): if size == -1: size = self.picSize self.logs.info('Start Fetching Pic') #根据当前播放的歌曲,返回专辑图片的路径,有必要时下载 self.logs.info('picpath Format:' + self.picPathFormat) # self.logs.info('listFunc:%s', self.listFunc) # self.logs.info('songDict:%s', self.listdetail[self.songIndex]) picPath = self.picPathFormat % neapi.getItem( self.listFunc, self.listdetail[self.songIndex], "songAlbumID") picPath = os.path.abspath(picPath) if not os.path.exists(picPath): picUrl = neapi.getItem( self.listFunc, self.listdetail[self.songIndex], "songAlbumCoverURL") + '?param=%iy%i' % (size, size) self.logs.info('Start Downloading Pic at %s to %s' % (picUrl, picPath)) strList = [ s('下载专辑图片 ') + s( neapi.getItem(self.listFunc, self.listdetail[self.songIndex], "songAlbumName")), s('目标: ') + s(picPath.split('\\')[-1]) ] strList2 = [s('写入文件')] download(picUrl, picPath, self.downCallbackWrapper(strList), self.errCallback, self.writeCallbackWrapper(strList2)) self.logs.info('End Fetching Pic. picPath : %s' % picPath) return picPath
def errorAddFunc(sth): global continuousError if not continuousError: appuifw2.note(s("发生错误。若程序不能正常运行,请重新启动程序。")) appuifw2.note(s("查看文件夹E:\\NeteaseDebug2下的日志文件来排查错误。")) continuousError = True aoTErr.cancel() aoTErr.after(2, resetContinuousError)
def procTLyric(lrcDict, inTLyric, testParam=False): inTLyric = s(inTLyric) trimTLrc_findall = RE_LYRICLINE.findall('[mark]' + inTLyric) if trimTLrc_findall == []: return {} trimTLrc = trimTLrc_findall[0].split(u'\n') for lrcLine in trimTLrc: z = [] z = z + re.findall(RE_LYRICLINE_SPLITTING_TIME, lrcLine) z = z + re.findall(RE_LYRICLINE_SPLITTING_CONTENT, lrcLine) if len(z) > 1: for i in range(0, len(z) - 1): t = z[i] #处理时间,有00:00.920和00:00.92两种格式 t1 = t.split(u':') t2 = t1[1].split('.') min = int("0" + t1[0]) sec = int("0" + t2[0]) if (len(t2) > 1): msc = t2[1] if len(msc) == 2: msc = int("0" + msc) * 10 else: msc = int("0" + msc) else: msc = 0 totaltime = ((min * 60000) + (sec * 1000) + msc) if totaltime in lrcDict: lrcDict[totaltime][1] = z[len(z) - 1] return lrcDict
def procLyric(inLyric, testParam=False): #先用正则将没用的部分去掉,并用\n分割,留下纯歌词 #inLyric = re.sub(RE_LYRICLINE_PATCH_SQUARE_BRACKETS_TEXT, ("(\g<text>)"), inLyric) inLyric = s(inLyric) trimLrc_findall = RE_LYRICLINE.findall('[mark]' + inLyric) if trimLrc_findall == []: return [] trimLrc = trimLrc_findall[0].split(u'\n') lrcList = [] for lrcLine in trimLrc: z = [] z = z + re.findall(RE_LYRICLINE_SPLITTING_TIME, lrcLine) z = z + re.findall(RE_LYRICLINE_SPLITTING_CONTENT, lrcLine) if len(z) > 1: for i in range(0, len(z) - 1): t = z[i] #处理时间,有00:00.920和00:00.92两种格式 t1 = t.split(u':') t2 = t1[1].split('.') minute = int("0" + t1[0]) sec = int("0" + t2[0]) if (len(t2) > 1): msc = t2[1] if len(msc) == 2: msc = int("0" + msc) * 10 else: msc = int("0" + msc) else: msc = 0 totaltime = ((minute * 60000) + (sec * 1000) + msc) lrcList.append((totaltime, [z[len(z) - 1], ''])) return lrcList
def httpDownload(objUrl, objPath, callBack = None, writeCallBack = None, bs = 8*1024, writebs = 512 * 1024): try: while True: urlhost = objUrl.split('/')[2] conn1 = httplib.HTTPConnection(urlhost, 80) conn1.request('GET',objUrl,'',{}) responseIO = conn1.getresponse() utilLog.info('Downloading From ' + objUrl) if responseIO.status == 302 or bool(responseIO.getheader('Location')): conn1.close() objUrl = responseIO.getheader('Location') utilLog.info('Redirecting to ' + objUrl) continue elif responseIO.status == 200: break else: raise Exception, "STATUS %s" % responseIO.status responseData = StringIO.StringIO() totalSize = getIOLength(responseIO) utilLog.info(s('<FileSize> ') + unicode(totalSize)) fileIO = open(objPath, 'wb') # if totalSize < 4*1024*1024: if totalSize < 1: callbackWhenRead(responseIO, responseData, callBack, bs, totalSize) utilLog.info('Load Completed.') responseData.seek(0) utilLog.info('Start Write Progress.') callbackWhenRead(responseData, fileIO, writeCallBack, writebs, totalSize) utilLog.info('Write Completed.') else: #modify: force instant readwrite utilLog.info('Big File, Enable Instant ReadWrite') callbackWhenRead(responseIO, fileIO, callBack, bs * 16, totalSize) utilLog.info('ReadWrite Completed') fileIO.close() responseData.close() conn1.close() del responseData del fileIO del responseIO del conn1 except Exception, e: try: conn1.close() responseData.close() fileIO.close() except: pass try: del conn1 del responseIO del responseData del fileIO except: pass raise Exception, e
def errorDisplayFunc(): try: global bodyBack, exitBack, errStr, msgBody if id(appuifw2.app.body) != id(msgBody): bodyBack = appuifw2.app.body if id(appuifw2.app.exit_key_handler) != id(restoreError): exitBack = appuifw2.app.exit_key_handler appuifw2.app.body = msgBody try: msgBody.set(s("有错误发生:\n") + errStr + s("\n请造访e:\\neteaseDebug2查看详情。按“退出”减返回上一级。")) except: pass appuifw2.app.exit_key_handler = restoreError except Exception, e: appuifw2.note(s(repr(e)))
def fetchSong(self): #根据当前播放的歌曲,返回音频文件的路径,有必要时下载 self.logs.info( 'Start Fetching Song for %s , %s' % (neapi.getItem(self.listFunc, self.listdetail[self.songIndex], "songID"), neapi.getItem(self.listFunc, self.listdetail[self.songIndex], "songName"))) songPath = self.songPathFormat % (neapi.getItem( self.listFunc, self.listdetail[self.songIndex], "songID"), self.br) songPath = os.path.abspath(songPath) if not os.path.exists(songPath): #other sources? for letter, num in reversed(neapi.NEAPI_BRS): songPath = self.songPathFormat % (neapi.getItem( self.listFunc, self.listdetail[self.songIndex], "songID"), letter) songPath = os.path.abspath(songPath) if os.path.exists(songPath): self.logs.info( "Found a local alternative sound source : %s" % songPath) return songPath songPath = self.songPathFormat % (neapi.getItem( self.listFunc, self.listdetail[self.songIndex], "songID"), self.br) songPath = os.path.abspath(songPath) #no other sources, have to download strList = [ s('下载歌曲 ') + s( neapi.getItem(self.listFunc, self.listdetail[self.songIndex], "songName")), s('目标') + s(songPath.split('\\')[-1]) ] strList2 = [s('写入文件')] if self.listdown[self.songIndex] is None: raise Exception, "No URL for this Song" out("并没有获取到此曲的URL,可能是版权原因") download(self.listdown[self.songIndex], songPath, self.downCallbackWrapper(strList), self.errCallback, self.writeCallbackWrapper(strList2)) self.logs.info('End Fetching Song : %s' % songPath) return songPath
def __init__(self, playlist, apii, order=0, picsize=73, br='m', volume=1, debugMode=False, logH=None, lyricPathFormat="e:\\%s", picPathFormat="e:\\%s", songPathFormat="e:\\%s_%s", saveSongPathFormat="e:\\%s_%s", saveLyricPathFormat="e:\\%s_%s"): self.logs = logging.getLogger("Playlist_" + hex(id(self))) if logH is not None: self.logs.addHandler(logH) self.logs.setLevel(logging.WARNING) #该playlist用的api实例 self.api = apii if apii else neapi.NEApi({}) #0 - 列表循环 1 - 单曲循环 2 - 随机播放 self.order = order self.br = br self.volume = volume #将来可能要实现历史播放功能 self.historyList = [] #更新songList,同时获得其详细信息listDetail,并根据order生成playingList #若电台或稍后更新playlist,可设置为[] self.updateList(playlist) self.lyricPathFormat = lyricPathFormat self.picPathFormat = picPathFormat self.songPathFormat = songPathFormat self.saveSongPathFormat = saveSongPathFormat self.saveLyricPathFormat = saveLyricPathFormat #downCallback: 下载文件时候的callback #downCallbackWrapper: 下载文件时候的callback的Wrapper,在主程序中给其赋值一个函数,downCallbackWrapper('提示文字')(chunknum,chunksize,totalsize)为urlretreive的回调方式 #songCallback: self.player的播放状态发生变化时调用的callback self.downCallbackWrapper = lambda a: lambda b, c, d: None self.writeCallbackWrapper = lambda a: lambda b, c, d: None self.songCallback = lambda a, b, c: None #设置界面所需的专辑图片尺寸,默认为73 self.picSize = picsize self.isScroll = False self.logs.info('End Init Playlist') self.playCallback = lambda: None self.errCallback = lambda: None self.player = False self.playlistName = s('歌单') self.debugMode = debugMode
def createFolders(globalVars): dirList = [globalVars['MAIN_NETEASE_FOLDER'], os.path.join(globalVars['MAIN_NETEASE_FOLDER'], "cache"), os.path.join(globalVars['MAIN_NETEASE_FOLDER'], "playlist"), os.path.join(globalVars['MAIN_NETEASE_FOLDER'], "lyric"), os.path.join(globalVars['MAIN_NETEASE_FOLDER'], "pic"), os.path.join(globalVars['MAIN_NETEASE_FOLDER'], "data"), globalVars['MAIN_DEBUG_FOLDER'], globalVars['MAIN_NETEASE_MUSIC_FOLDER'], ] fileman = cfileman.FileMan() for x in dirList: x = s(x) if not os.path.isdir(x): os.makedirs(x) if x.find(globalVars['MAIN_NETEASE_MUSIC_FOLDER']) == -1: fileman.set_att(x, cfileman.EAttHidden)
def download(objUrl, objPath, callBack = None, errBack = lambda:None, writeCallBack = None): succeed = False retryCount = 0 # while((not succeed) and retryCount < 4): if True: try: utilLog.info(s('<Download> ') + s(objUrl) + s(' To: ') + s(objPath)) httpDownload(objUrl, objPath, callBack, writeCallBack) utilLog.info(u'Download Succeed') succeed = True except Exception, e: if os.path.exists(objPath): os.remove(objPath) errBack() utilLog.error(s('<Download Failure>x%s, %s: %s'), retryCount, e.__class__, e.args) utilLog.error(s(traceback.format_exc())) raise e
def saveSong(self): try: songDict = self.listdetail[self.songIndex] prompt = s('') f = False if not os.path.exists(self.songPath): self.songPath = self.fetchSong() songName = neapi.getItem(self.listFunc, songDict, "songName") songArtists = ','.join( neapi.getItem(self.listFunc, self.listdetail[self.songIndex], "songArtistsName")) songName = re.sub(RE_PATH_FILTER, "", songName) songArtists = re.sub(RE_PATH_FILTER, "", songArtists) if os.path.exists(self.songPath): desPath = self.saveSongPathFormat % (s(songName), s(songArtists)) desPath = s(desPath) orgPath = s(self.songPath) cfileman.FileMan().file_copy(orgPath, desPath, cfileman.EOverWrite) prompt += s('创建了') + s( os.path.abspath((desPath).encode("utf-8"))) + s('(') + s( str(dict(neapi.NEAPI_BRS)[self.br] / 1000)) + s('Kbps)') else: return False if self.lyric: desLyricPath = self.saveLyricPathFormat % (s(songName), s(songArtists)) desLyricPath = s(desLyricPath).encode("utf-8") f = os.open(desLyricPath, os.O_WRONLY | os.O_CREAT) os.write(f, STR_UTF8_BOM) os.write(f, s(self.lyric).encode("utf-8")) os.close(f) prompt += s('和') + s(os.path.basename(desLyricPath)) resp = out(prompt) self.logs.info(prompt) except Exception, e: import traceback self.logs.error(traceback.format_exc()) try: if f: f.close() os.remove(desPath) os.remove(desLyricPath) except: pass out("保存歌曲失败")
def nc(str1):return s(str1).encode('utf-8') def cnList(list1, toTuple=False):
def cn(str1): return s(str1)
def out(str1): appuifw.note(s(str1))