PageRenderTime 93ms CodeModel.GetById 4ms RepoModel.GetById 7ms app.codeStats 0ms

/progenitus/updater/gui.py

https://github.com/TheGurke/Progenitus
Python | 245 lines | 244 code | 0 blank | 1 comment | 1 complexity | da254770ca63ae7846ece5c484729a71 MD5 | raw file
  1. # Written by TheGurke 2011
  2. """GUI for the database/image updater"""
  3. import os
  4. import datetime
  5. from gettext import gettext as _
  6. import logging
  7. import sqlite3
  8. import glib
  9. import gtk
  10. from progenitus import *
  11. from progenitus.db import *
  12. from progenitus.miner import *
  13. class Interface(uiloader.Interface):
  14. downloadlist = None
  15. def __init__(self):
  16. super(self.__class__, self).__init__()
  17. self.load(config.GTKBUILDER_UPDATER)
  18. # Check if another updater instance is running
  19. if not singleton.check(os.path.join(settings.cache_dir,
  20. config.LOCKFILE)):
  21. dialog = self.show_dialog(None,
  22. _("Another instance of the updater is running."), "error")
  23. dialog.connect("destroy", self.quit)
  24. return
  25. # Insert download servers
  26. self.liststore_data_servers.append(("magiccards.info",))
  27. self.combobox_data_servers.set_active(0)
  28. self.liststore_pic_servers.append(("magiccards.info",))
  29. self.combobox_pic_servers.set_active(0)
  30. self.liststore_price_servers.append(("tcgplayer.com",))
  31. self.combobox_price_servers.set_active(0)
  32. if not settings.disclaimer_agreed:
  33. self.disclaimer_win.show()
  34. self.checkbutton_confirm.grab_focus()
  35. else:
  36. self.main_win.show()
  37. self.button_start.grab_focus()
  38. def toggle_confirm(self, widget):
  39. """The user toggles the 'I confirm' checkbutton"""
  40. self.button_agree.set_sensitive(self.checkbutton_confirm.get_active())
  41. def agree(self, widget):
  42. """The user agreed to the disclaimer"""
  43. self.disclaimer_win.hide()
  44. self.main_win.show()
  45. # Save to settings
  46. settings.disclaimer_agreed = True
  47. glib.idle_add(settings.save)
  48. def toggle_download_pics(self, widget):
  49. self.combobox_pic_servers.set_sensitive(
  50. self.checkbutton_download_pics.get_active())
  51. def toggle_download_prices(self, widget):
  52. self.combobox_price_servers.set_sensitive(
  53. self.checkbutton_download_prices.get_active())
  54. def log(self, message):
  55. """Print a status log message"""
  56. buf = self.logview.get_buffer()
  57. if message[0] != "\n" and buf.get_char_count() > 0:
  58. message = "\n" + message
  59. buf.insert(buf.get_end_iter(), message, -1)
  60. mark = buf.get_mark("insert")
  61. self.logview.scroll_to_mark(mark, 0)
  62. def start_download(self, widget=None):
  63. """Interface callback to start the download"""
  64. self.vbox_settings.set_sensitive(False)
  65. self.hbox_progress.show()
  66. # self.expander_details.show() # currently broken in the ui
  67. self.button_start.hide()
  68. self.button_stop.show()
  69. async.run_threaded(self._run_download(), self.show_exception)
  70. # async.run(self._run_download()) # For debugging; prints traceback
  71. def _prepare_download(self):
  72. """Prepare everything for the download"""
  73. # Get download list
  74. self.log(_("Getting downloadlist..."))
  75. data = miner.fetch_downloadlist(settings.list_url)
  76. downloadlist = miner.parse_downloadlist(data)
  77. # Establish database access
  78. db_file = os.path.join(settings.cache_dir, config.DB_FILE)
  79. if not os.path.isfile(db_file):
  80. self.log(_("Creating a new database file..."))
  81. cards.create_db(db_file)
  82. cards.connect()
  83. self.sqlconn = sqlite3.connect(db_file)
  84. self.cursor = self.sqlconn.cursor()
  85. # Create directories
  86. if not os.path.exists(settings.cache_dir):
  87. os.mkdir(settings.cache_dir)
  88. if self.checkbutton_download_pics.get_active():
  89. if not os.path.exists(os.path.join(settings.cache_dir, "cards")):
  90. os.mkdir(os.path.join(settings.cache_dir, "cards"))
  91. self.log(_("Starting download."))
  92. return downloadlist
  93. def _run_download(self):
  94. """Threaded download function"""
  95. downloadlist = yield self._prepare_download()
  96. assert(downloadlist is not None)
  97. assert(len(downloadlist) > 0)
  98. # Download every card set
  99. for set_num in range(len(downloadlist)):
  100. setcode, releasedate, mcinfosetcode, setname, tcgplayersetname \
  101. = downloadlist[set_num]
  102. # Update gui
  103. self.progressbar1.set_fraction(float(set_num) / len(downloadlist))
  104. self.progressbar1.set_text(setname)
  105. self.progressbar2.set_fraction(0)
  106. self.progressbar2.set_text(" ")
  107. # Check if the set has already been downloaded
  108. self.cursor.execute('SELECT * FROM "sets" WHERE "id" = ?',
  109. (setcode,))
  110. cardlist = None
  111. if self.cursor.fetchone() is not None:
  112. cardlist = cards.search('"setid" = ?', (setcode,))
  113. else:
  114. self.log(_("Downloading '%s'...") % setname)
  115. self.progressbar2.set_text(_("Fetching card information..."))
  116. # Get full spoilers information
  117. setname, cardlist = yield magiccardsinfo.mine_set(
  118. *downloadlist[set_num][:3])
  119. # Insert into the database
  120. self.cursor.execute(u'INSERT INTO "sets" VALUES (?,?,?,?)',
  121. (setcode, setname, len(cardlist), releasedate.toordinal()))
  122. for i in range(len(cardlist)):
  123. self.progressbar2.set_fraction(float(i) / len(cardlist))
  124. self.cursor.execute(u'INSERT INTO "cards" VALUES (' +
  125. 23 * '?,' + '?)', cardlist[i].as_tuple())
  126. self.sqlconn.commit()
  127. assert(cardlist is not None)
  128. # Download pricing information
  129. if self.checkbutton_download_prices.get_active():
  130. self.progressbar2.set_fraction(0)
  131. self.progressbar2.set_text(_("Fetching pricing information..."))
  132. pricelist = yield tcgplayercom.mine_pricelist(tcgplayersetname)
  133. if pricelist == []:
  134. logging.warning(_("No pricing information for '%s'."),
  135. setname)
  136. for i in range(len(pricelist)):
  137. name, price = pricelist[i]
  138. self.progressbar2.set_fraction(float(i) / len(pricelist))
  139. self.cursor.execute('UPDATE "cards" SET "price" = ? '
  140. 'WHERE "name" = ? AND "setname" = ?',
  141. (price, name, setname)
  142. )
  143. self.sqlconn.commit()
  144. # Download card pictures
  145. if self.checkbutton_download_pics.get_active():
  146. self.progressbar2.set_fraction(0)
  147. self.progressbar2.set_text(_("Fetching card pictures..."))
  148. # Create picture directory
  149. pic_dir = os.path.dirname(pics._get_path(setcode + "." + "000"))
  150. if not os.path.exists(pic_dir):
  151. os.mkdir(pic_dir)
  152. # Get pics
  153. for i in range(len(cardlist)):
  154. self.progressbar2.set_fraction(float(i) / len(cardlist))
  155. card = cardlist[i]
  156. pic_filename = pics._get_path(card.id)
  157. if not os.path.exists(pic_filename):
  158. yield magiccardsinfo.mine_pic(magiccardsinfo.url_pic
  159. % (mcinfosetcode, card.collectorsid), pic_filename)
  160. # Download tokens
  161. if self.checkbutton_download_tokens.get_active():
  162. self.progressbar1.set_text(_("Tokens"))
  163. self.progressbar2.set_fraction(0)
  164. self.progressbar2.set_text(_("Fetching token information..."))
  165. self.log(_("Downloading tokens..."))
  166. # Create token pic directory
  167. if not os.path.exists(os.path.join(settings.cache_dir, "tokens")):
  168. os.mkdir(os.path.join(settings.cache_dir, "tokens"))
  169. # Get token information
  170. tokens = magiccardsinfo.mine_tokens()
  171. for i in range(len(tokens)):
  172. pic_url, token = tokens[i]
  173. self.progressbar2.set_fraction(float(i) / len(tokens))
  174. # Get token picture
  175. pic_filename = pics._get_path(token.id)
  176. if not os.path.exists(pic_filename):
  177. yield magiccardsinfo.mine_pic(pic_url, pic_filename)
  178. # Insert database entry
  179. try:
  180. yield cards.get(token.id)
  181. except RuntimeError:
  182. self.cursor.execute(u'INSERT INTO "tokens" VALUES (' +
  183. 17 * '?,' + '?)', token.as_tuple())
  184. self.sqlconn.commit()
  185. glib.idle_add(self.download_complete)
  186. def download_complete(self):
  187. self.progressbar1.set_fraction(1)
  188. self.progressbar2.set_fraction(1)
  189. self.log(_("Update complete."))
  190. md = gtk.MessageDialog(self.main_win, gtk.DIALOG_DESTROY_WITH_PARENT,
  191. gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE, _("Update complete."))
  192. md.connect("response", self.quit)
  193. md.show()
  194. def show_exception(self, exception):
  195. """Show the exception and then quit"""
  196. text = "An exception occured:\n%s" % str(exception)
  197. md = gtk.MessageDialog(self.main_win, gtk.DIALOG_DESTROY_WITH_PARENT,
  198. gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, text)
  199. md.connect("response", self.quit)
  200. md.show()