main.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import base64
  2. import datetime
  3. import os
  4. import threading
  5. from PyQt5.QtWidgets import *
  6. from PyQt5.QtGui import *
  7. import FileOperator
  8. from MainWindow import Ui_MainWindow
  9. from icon import img
  10. import TitleSpider
  11. def GetSeries(dataList):
  12. return int(dataList.split('_')[1])
  13. class MainApp(QMainWindow, Ui_MainWindow):
  14. def __init__(self):
  15. QMainWindow.__init__(self)
  16. self.setupUi(self)
  17. self.SetBaseInfo()
  18. self.InitMenuBar()
  19. self.HandleButtons()
  20. self.SetUI()
  21. self.setFixedSize(self.width(), self.height())
  22. self.SetLogText()
  23. self.progressBar.setValue(0)
  24. self.InitCheckBox()
  25. def InitCheckBox(self):
  26. # self.txtFileCheckBox.setChecked(True) # 默认保存Txt
  27. # self.deleteFileCheckBox.setChecked(False) # 默认保留源目录
  28. # self.copyToOutput.setChecked(True) # 默认使用复制的方式
  29. self.txtFileCheckBox.setChecked(False) # 默认不保存Txt
  30. self.deleteFileCheckBox.setChecked(True) # 默认不保留源目录
  31. self.moveToOutput.setChecked(True) # 默认不使用复制的方式
  32. def MutiThreadCopy(self, mp4List, outputPath):
  33. t = threading.Thread(target=FileOperator.CopyFile, args=(mp4List, outputPath))
  34. t.start()
  35. t.join()
  36. def MutiThreadMove(self, mp4List, outputPath):
  37. t = threading.Thread(target=FileOperator.MoveFile, args=(mp4List, outputPath))
  38. t.start()
  39. t.join()
  40. def CheckIsChecked(self):
  41. self.isSaveTxt = self.txtFileCheckBox.isChecked()
  42. self.isDeleteDir = self.deleteFileCheckBox.isChecked()
  43. if self.copyToOutput.isChecked() or self.moveToOutput.isChecked():
  44. pass
  45. else:
  46. QMessageBox.critical(self, "错误", "请至少勾选一种输出方式!")
  47. if self.copyToOutput.isChecked():
  48. self.isCopyOutput = True
  49. else:
  50. self.isCopyOutput = False
  51. if self.moveToOutput.isChecked():
  52. self.isMoveOutput = True
  53. else:
  54. self.isMoveOutput = False
  55. def SetLogText(self):
  56. self.activityLogEdit.setReadOnly(True)
  57. def Log(self, msg):
  58. self.statusbar.showMessage(msg)
  59. self.activityLogEdit.appendPlainText('[{0}]'.format(str(datetime.datetime.now())[0:19]))
  60. self.activityLogEdit.appendPlainText(msg)
  61. self.activityLogEdit.appendPlainText('')
  62. def LogOnBar(self, msg):
  63. self.statusbar.showMessage(msg)
  64. def HandleButtons(self):
  65. self.downloadDirButton.clicked.connect(self.OpenDownloadDir)
  66. self.outputDirButton.clicked.connect(self.OpenOutputDir)
  67. self.renameButton.clicked.connect(self.RenameFile)
  68. self.copyToOutput.clicked.connect(self.DisableMove)
  69. self.moveToOutput.clicked.connect(self.DisableCopy)
  70. def DisableCopy(self):
  71. if self.copyToOutput.isChecked():
  72. self.copyToOutput.setChecked(False)
  73. def DisableMove(self):
  74. if self.moveToOutput.isChecked():
  75. self.moveToOutput.setChecked(False)
  76. def InitMenuBar(self):
  77. # 添加menu“帮助”的事件
  78. aboutAction = QAction('&关于', self)
  79. # aboutAction.setStatusTip('关于')
  80. aboutAction.triggered.connect(self.ShowAboutDialog)
  81. # 已有菜单栏,此处只需要添加菜单
  82. mainPageMenu = self.menubar.addMenu('&主页')
  83. helpMenu = self.menubar.addMenu('&帮助')
  84. # 菜单绑定之前添加的事件
  85. helpMenu.addAction(aboutAction)
  86. # 设置UI
  87. def SetUI(self):
  88. tmp = open('tmp.png', "wb+")
  89. tmp.write(base64.b64decode(img))
  90. tmp.close()
  91. icon = QIcon('tmp.png')
  92. os.remove("tmp.png")
  93. self.setWindowIcon(icon)
  94. def ShowAboutDialog(self):
  95. about_text = "<p>描述:这是一个致力于解决BiliBiLi UWP版下载视频的名称十分反人类的痛点的软件</p><p>版本:1.0</p><p>@Author:LZY</p><p>@github:love" \
  96. "-in-cpp</p> "
  97. QMessageBox.about(self, '说明', about_text)
  98. def OpenDownloadDir(self):
  99. dName = QFileDialog.getExistingDirectory(self, '选择文件夹', '/')
  100. self.downloadDirEdit.setText(dName)
  101. def OpenOutputDir(self):
  102. dName = QFileDialog.getExistingDirectory(self, '选择文件夹', '/')
  103. self.outputDirEdit.setText(dName)
  104. def SetBaseInfo(self):
  105. self.setWindowTitle('BiliBili UWP版视频下载整理工具')
  106. self.downloadDirEdit.setToolTip(r"例如:E:\BiliDownload\44938322")
  107. self.downloadDirEdit.setPlaceholderText("路径请具体到下载的视频对应的单个文件夹,暂不支持批量处理")
  108. self.outputDirEdit.setPlaceholderText("您希望处理后的文件被保存到的地方")
  109. # def FindFiles(self,downloadPath):
  110. def RenameFile(self):
  111. self.CheckIsChecked()
  112. # 进入目录查找dvi文件
  113. downloadPath = self.downloadDirEdit.toPlainText()
  114. if os.path.isdir(downloadPath) is False:
  115. self.Log('UWP下载目录的路径存在非法输入!')
  116. else:
  117. self.Log("进入目录:{0}".format(downloadPath))
  118. dviInfoList = FileOperator.GetDviInfo(downloadPath) # 获取dvi文件信息
  119. if dviInfoList[0] is False:
  120. self.Log('没有找到.dvi文件!请检查下载目录后重试!')
  121. else:
  122. self.Log("开始爬取BV:{0}, 标题:{1} 的所有视频标题,请稍后...".format(dviInfoList[1], dviInfoList[3]))
  123. TitleSpider.GetTxt(dviInfoList[1]) # 调用爬虫
  124. global fileName
  125. fileName = TitleSpider.fileName
  126. self.LogOnBar('已成功爬取文件: {0} ! 注:只显示部分文件名'.format(fileName[0:35]))
  127. self.Log('已成功爬取文件: {0} !'.format(fileName))
  128. # 找到所有downloadPath的.mp4文件
  129. mp4List = FileOperator.FindAllMp4Files(downloadPath)[0] # mp4真正在的地方
  130. # Log
  131. mp4nameList = FileOperator.FindAllMp4Files(downloadPath)[1]
  132. mp4nameList.sort(key=GetSeries)
  133. s = "查询到以下mp4文件:\n"
  134. for item in mp4nameList:
  135. s += (item + '\n')
  136. self.Log(s)
  137. # 复制
  138. outputPath = self.outputDirEdit.toPlainText()
  139. if os.path.isdir(outputPath) is False:
  140. self.Log('输出目录的路径存在非法输入!')
  141. else:
  142. self.CopyOrMove(self.isCopyOutput, mp4List, outputPath)
  143. # 重命名
  144. self.Log("开始重命名...")
  145. FileOperator.DoRename(outputPath, fileName)
  146. self.Log("重命名完毕!")
  147. # 进度条100%
  148. self.progressBar.setValue(100)
  149. # 是否保存.txt文件
  150. if self.isSaveTxt is True:
  151. pass
  152. else:
  153. self.Log("正在删除程序运行过程中产生的.txt文件")
  154. FileOperator.DeleteTxt(os.getcwd(), fileName)
  155. self.Log("删除.txt文件成功!")
  156. # 是否删除源文件夹
  157. if self.isDeleteDir is True:
  158. self.Log("正在删除源文件夹")
  159. FileOperator.DeleteDir(downloadPath)
  160. self.Log("删除源文件夹成功!")
  161. else:
  162. pass
  163. # 重命名输出文件夹 搁置
  164. # 输出方式:复制或移动
  165. def CopyOrMove(self, isCopyTo, mp4List, outputPath):
  166. if isCopyTo is True:
  167. self.Log("进入目录:{0}".format(outputPath))
  168. self.Log("开始复制... 这可能需要一段时间...")
  169. self.MutiThreadCopy(mp4List, outputPath) # 多线程复制
  170. self.Log("复制完毕!")
  171. else:
  172. self.Log("进入目录:{0}".format(outputPath))
  173. self.Log("开始移动... 这可能需要一段时间...")
  174. self.MutiThreadMove(mp4List, outputPath) # 多线程移动
  175. self.Log("移动完毕!")
  176. if __name__ == '__main__':
  177. app = QApplication([])
  178. window = MainApp()
  179. window.show()
  180. app.exec_()