images.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. ########################################################################
  2. # Wiizard - A Wii games manager
  3. # Copyright (C) 2023 CYBERDEViL
  4. #
  5. # This file is part of Wiizard.
  6. #
  7. # Wiizard is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # Wiizard is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  19. #
  20. ########################################################################
  21. from PyQt5.QtWidgets import (
  22. QDialog,
  23. QGridLayout,
  24. QProgressBar,
  25. QPushButton,
  26. QMessageBox,
  27. QLabel,
  28. QCheckBox
  29. )
  30. from PyQt5.QtCore import Qt
  31. from wiizard import globals as Global
  32. from wiizard.images import DlImagesThread
  33. from wiizard.const import (
  34. IMG_FRONT_COVER,
  35. IMG_FRONT_3D_COVER,
  36. IMG_DISC,
  37. IMG_FULL
  38. )
  39. from wiizard.models.settings import GameImageSettings
  40. from wiizard.widgets.line import HLine
  41. from wiizard.translations import _
  42. """ This dialog will start the thread for downloading images
  43. """
  44. class DlImagesProgressDialog(QDialog):
  45. def __init__(self, dlList, requestHandler, scraper, parent=None):
  46. QDialog.__init__(self, parent, Qt.Dialog)
  47. self.setWindowTitle(_("Download progress"))
  48. self.setModal(False)
  49. layout = QGridLayout(self)
  50. self.progressBar = QProgressBar(self)
  51. self.cancelButton = QPushButton(_("Cancel"), self)
  52. maxi = 0
  53. for idv6Str in dlList:
  54. maxi += len(dlList[idv6Str])
  55. self.progressBar.setMaximum(maxi)
  56. self.progressBar.setFormat("%v / %m")
  57. self.progressBar.setValue(0)
  58. layout.addWidget(self.progressBar, 0, 0)
  59. layout.addWidget(self.cancelButton, 1, 0)
  60. self.thread = DlImagesThread(dlList, requestHandler, scraper)
  61. self.thread.progress.connect(self.updateProgress)
  62. self.thread.completed.connect(self.onCompleted)
  63. self.cancelButton.clicked.connect(self.cancel)
  64. def run(self):
  65. Global.ActiveThreads.append(self.thread)
  66. self.thread.start()
  67. self.show()
  68. def cancel(self):
  69. self.progressBar.setFormat(_("Cancelling.."))
  70. self.progressBar.setValue(0)
  71. self.cancelButton.setEnabled(False)
  72. self.thread.cancel()
  73. def updateProgress(self, value):
  74. self.progressBar.setValue(value)
  75. def onCompleted(self):
  76. self.thread.wait()
  77. Global.ActiveThreads.remove(self.thread)
  78. failed = self.thread.failed
  79. if failed:
  80. print("FAILED!")
  81. failedStr = ""
  82. for fail in failed:
  83. failedStr += fail + "\n"
  84. QMessageBox(0, _("Failed downloads"), failedStr).exec()
  85. self.thread.quit()
  86. self.close()
  87. Global.SharedGameImages.remakePixmaps()
  88. print("Done")
  89. class DlImagesDialog(QDialog):
  90. def __init__(self, requestHandler, scraper, parent=None):
  91. QDialog.__init__(self, parent, Qt.Dialog)
  92. self.__requestHandler = requestHandler
  93. self.__scraper = scraper
  94. self.__missing = {
  95. IMG_FRONT_COVER : [],
  96. IMG_FRONT_3D_COVER: [],
  97. IMG_FULL : [],
  98. IMG_DISC : []
  99. }
  100. for sourceName, source in Global.Sources.localDirectories.items():
  101. missing = source.findMissingImages()
  102. self.__missing[IMG_FRONT_COVER] += missing[IMG_FRONT_COVER]
  103. self.__missing[IMG_FRONT_3D_COVER] += missing[IMG_FRONT_3D_COVER]
  104. self.__missing[IMG_FULL] += missing[IMG_FULL]
  105. self.__missing[IMG_DISC] += missing[IMG_DISC]
  106. for sourceName, source in Global.Sources.devicePartitions.items():
  107. missing = source.findMissingImages()
  108. self.__missing[IMG_FRONT_COVER] += missing[IMG_FRONT_COVER]
  109. self.__missing[IMG_FRONT_3D_COVER] += missing[IMG_FRONT_3D_COVER]
  110. self.__missing[IMG_FULL] += missing[IMG_FULL]
  111. self.__missing[IMG_DISC] += missing[IMG_DISC]
  112. for sourceName, source in Global.Sources.filePartitions.items():
  113. missing = source.findMissingImages()
  114. self.__missing[IMG_FRONT_COVER] += missing[IMG_FRONT_COVER]
  115. self.__missing[IMG_FRONT_3D_COVER] += missing[IMG_FRONT_3D_COVER]
  116. self.__missing[IMG_FULL] += missing[IMG_FULL]
  117. self.__missing[IMG_DISC] += missing[IMG_DISC]
  118. frontMissingCount = 0
  119. front3dMissingCount = 0
  120. missingFront = 0
  121. missingFront3d = 0
  122. missingFull = 0
  123. missingDisc = 0
  124. missingCount = 0
  125. if IMG_FRONT_COVER in self.__missing:
  126. missingFront += len(self.__missing[IMG_FRONT_COVER])
  127. if IMG_FRONT_3D_COVER in self.__missing:
  128. missingFront3d += len(self.__missing[IMG_FRONT_3D_COVER])
  129. if IMG_FULL in self.__missing:
  130. missingFull += len(self.__missing[IMG_FULL])
  131. if IMG_DISC in self.__missing:
  132. missingDisc += len(self.__missing[IMG_DISC])
  133. missingCount += missingFront
  134. missingCount += missingFront3d
  135. missingCount += missingFull
  136. missingCount += missingDisc
  137. self.setWindowTitle(_("Download images"))
  138. self.setModal(False)
  139. layout = QGridLayout(self)
  140. layout.addWidget(QLabel(_("<b>Download missing {} images</b>")
  141. .format(missingCount), self), 0, 0, 1, 3, Qt.AlignCenter)
  142. layout.addWidget(HLine(self) , 1, 0, 1, 3)
  143. layout.addWidget(QLabel(_("<b>Type</b>"), self) , 2, 0)
  144. layout.addWidget(QLabel(_("<b>Missing</b>"), self) , 2, 1)
  145. layout.addWidget(QLabel(_("<b>Download</b>"), self) , 2, 2)
  146. self.dlFrontCb = QCheckBox(self)
  147. layout.addWidget(QLabel(_("Front 2D"), self) , 3, 0)
  148. layout.addWidget(QLabel(str(missingFront), self) , 3, 1)
  149. layout.addWidget(self.dlFrontCb , 3, 2, Qt.AlignRight)
  150. self.dlFront3dCb = QCheckBox(self)
  151. layout.addWidget(QLabel(_("Front 3D"), self) , 4, 0)
  152. layout.addWidget(QLabel(str(missingFront3d), self) , 4, 1)
  153. layout.addWidget(self.dlFront3dCb , 4, 2, Qt.AlignRight)
  154. self.dlFullCb = QCheckBox(self)
  155. layout.addWidget(QLabel(_("Full"), self) , 5, 0)
  156. layout.addWidget(QLabel(str(missingFull), self) , 5, 1)
  157. layout.addWidget(self.dlFullCb , 5, 2, Qt.AlignRight)
  158. self.dlDiscCb = QCheckBox(self)
  159. layout.addWidget(QLabel(_("Disc"), self) , 6, 0)
  160. layout.addWidget(QLabel(str(missingDisc), self) , 6, 1)
  161. layout.addWidget(self.dlDiscCb , 6, 2, Qt.AlignRight)
  162. layout.addWidget(HLine(self) , 7, 0, 1, 3)
  163. langInfoLabel = QLabel(_(f"Preferred language is "
  164. f"<b>{GameImageSettings.PreferredLang}</b>, "
  165. f"fallback language is "
  166. f"<b>{GameImageSettings.FallbackLang}</b> and "
  167. f"any fallback is set to "
  168. f"<b>{GameImageSettings.AnyFallback}</b>"), self)
  169. langInfoLabel.setToolTip(_("Preferred image language and fallback "
  170. "language can be set from Settings."))
  171. langInfoLabel.setWordWrap(True)
  172. layout.addWidget(langInfoLabel , 8, 0, 1, 3)
  173. self.dlButton = QPushButton(_("Download"), self)
  174. if not missingCount:
  175. self.dlButton.setEnabled(False)
  176. layout.addWidget(self.dlButton , 9, 0, 1, 3, Qt.AlignCenter)
  177. self.dlButton.clicked.connect(self.__dlClicked)
  178. def __dlClicked(self):
  179. self.setEnabled(False)
  180. # Generate image type flags from checkboxes
  181. imgTypeFlags = 0
  182. if self.dlFrontCb.isChecked():
  183. imgTypeFlags |= IMG_FRONT_COVER
  184. if self.dlFront3dCb.isChecked():
  185. imgTypeFlags |= IMG_FRONT_3D_COVER
  186. if self.dlFullCb.isChecked():
  187. imgTypeFlags |= IMG_FULL
  188. if self.dlDiscCb.isChecked():
  189. imgTypeFlags |= IMG_DISC
  190. # create a download list with as primary key the id6 and as value the image
  191. # types to download
  192. dlList = {}
  193. for imgType in self.__missing:
  194. if not (imgType & imgTypeFlags):
  195. continue
  196. for idv6Str in self.__missing[imgType]:
  197. if idv6Str not in dlList:
  198. dlList.update({idv6Str: []})
  199. dlList[idv6Str].append(imgType)
  200. dlDialog = DlImagesProgressDialog(dlList, self.__requestHandler, self.__scraper, parent=self)
  201. dlDialog.finished.connect(self.__dlFinished)
  202. dlDialog.run()
  203. #self.close()
  204. def __dlFinished(self):
  205. self.close()