Display online mode in statusbar.
Save set data in sqlite.
This commit is contained in:
@@ -2,9 +2,7 @@ import sys
|
||||
try:
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Pango
|
||||
from gi.repository import GdkPixbuf
|
||||
from gi.repository import Gtk, GObject, Pango, GdkPixbuf
|
||||
except ImportError as ex:
|
||||
print("Couldn't import GTK dependencies. Make sure you "
|
||||
"installed the PyGTK package and %s module." % ex.name)
|
||||
@@ -22,6 +20,8 @@ from cardvault import util
|
||||
from cardvault import database
|
||||
|
||||
|
||||
|
||||
|
||||
class Application:
|
||||
# ---------------------------------Initialize the Application----------------------------------------------
|
||||
def __init__(self):
|
||||
@@ -32,7 +32,6 @@ class Application:
|
||||
util.LOG_LEVEL = self.config["log_level"]
|
||||
util.log("Start using config file: '{}'".format(self.configfile), util.LogLevel.Info)
|
||||
|
||||
# Load ui files
|
||||
self.ui = Gtk.Builder()
|
||||
self.ui.add_from_file(util.get_ui_filename("mainwindow.glade"))
|
||||
self.ui.add_from_file(util.get_ui_filename("overlays.glade"))
|
||||
@@ -64,14 +63,14 @@ class Application:
|
||||
self.precon_icons = util.reload_preconstructed_icons(util.CACHE_PATH + "icons/")
|
||||
self.mana_icons = util.load_mana_icons(os.path.dirname(__file__) + "/resources/mana/")
|
||||
|
||||
util.log("Loading set list...", util.LogLevel.Info)
|
||||
self.sets = util.load_sets(util.get_root_filename("sets"))
|
||||
|
||||
self.library = Dict[str, Type[mtgsdk.Card]]
|
||||
self.tags = Dict[str, str]
|
||||
self.wants = Dict[str, List[Type[mtgsdk.Card]]]
|
||||
self.load_user_data()
|
||||
|
||||
self.load_data()
|
||||
self.ui.get_object('statusbar_icon').set_from_icon_name(
|
||||
util.online_icons[self.is_online()], Gtk.IconSize.BUTTON)
|
||||
self.ui.get_object('statusbar_icon').set_tooltip_text(util.online_tooltips[self.is_online()])
|
||||
|
||||
self.handlers = handlers.Handlers(self)
|
||||
self.ui.connect_signals(self.handlers)
|
||||
@@ -119,7 +118,7 @@ class Application:
|
||||
# Printings
|
||||
prints = []
|
||||
for set in card.printings:
|
||||
prints.append(self.sets[set].name)
|
||||
prints.append(self.get_all_sets()[set].name)
|
||||
builder.get_object("cardPrintings").set_text(", ".join(prints))
|
||||
# Legalities
|
||||
grid = builder.get_object("legalitiesGrid")
|
||||
@@ -219,7 +218,7 @@ class Application:
|
||||
# self.push_status("All data saved.")
|
||||
pass
|
||||
|
||||
def load_data(self):
|
||||
def load_user_data(self):
|
||||
util.log("Loading Data from database", util.LogLevel.Info)
|
||||
start = time.time()
|
||||
self.library = self.db.lib_get_all()
|
||||
@@ -229,6 +228,17 @@ class Application:
|
||||
util.log("Finished in {}s".format(str(round(end-start, 3))), util.LogLevel.Info)
|
||||
self.push_status("All data loaded.")
|
||||
|
||||
def set_online(self, status: bool):
|
||||
"""Online status of the application. True if no local card data is present."""
|
||||
self.ui.get_object('statusbar_icon').set_from_icon_name(util.online_icons[status], Gtk.IconSize.BUTTON)
|
||||
self.ui.get_object('statusbar_icon').set_tooltip_text(util.online_tooltips[status])
|
||||
self.config['local_db'] = not status
|
||||
self.save_config()
|
||||
|
||||
def is_online(self) -> bool:
|
||||
"""Return the online status of the application. True if no local data present."""
|
||||
return not self.config['local_db']
|
||||
|
||||
def get_untagged_cards(self):
|
||||
lib = copy.copy(self.library)
|
||||
for ids in self.tags.values():
|
||||
@@ -384,8 +394,19 @@ class Application:
|
||||
"""Called before before rebuilding local data storage"""
|
||||
util.log("Clearing local card data", util.LogLevel.Info)
|
||||
self.db.db_clear_data_card()
|
||||
self.set_online(True)
|
||||
util.log("Done", util.LogLevel.Info)
|
||||
|
||||
def get_all_sets(self) -> dict:
|
||||
if not self.is_online ():
|
||||
l = self.db.set_get_all()
|
||||
out = {}
|
||||
for s in l:
|
||||
out[s.code] = s
|
||||
else:
|
||||
out = util.load_sets(util.get_root_filename('sets'))
|
||||
return out
|
||||
|
||||
def get_mana_icons(self, mana_string):
|
||||
if not mana_string:
|
||||
util.log("No mana string provided", util.LogLevel.Info)
|
||||
@@ -408,5 +429,6 @@ class Application:
|
||||
|
||||
|
||||
def main():
|
||||
GObject.threads_init()
|
||||
Application()
|
||||
Gtk.main()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import sqlite3
|
||||
import ast
|
||||
|
||||
from mtgsdk import Card
|
||||
from mtgsdk import Card, Set
|
||||
from cardvault import util
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ class CardVaultDB:
|
||||
con.execute("CREATE TABLE IF NOT EXISTS library ( multiverseid INT PRIMARY KEY, copies INT )")
|
||||
con.execute("CREATE TABLE IF NOT EXISTS tags ( tag TEXT, multiverseid INT )")
|
||||
con.execute("CREATE TABLE IF NOT EXISTS wants ( listName TEXT, multiverseid INT )")
|
||||
con.execute("CREATE TABLE IF NOT EXISTS sets ( code TEXT PRIMARY KEY , name TEXT, type TEXT, border TEXT, "
|
||||
"mkmid INT, mkmname TEXT, releasedate TEXT, gatherercode TEXT, magiccardsinfocode TEXT, "
|
||||
"booster TEXT, oldcode TEXT)")
|
||||
|
||||
def db_card_insert(self, card: Card):
|
||||
# Connect to database
|
||||
@@ -66,7 +69,8 @@ class CardVaultDB:
|
||||
|
||||
def db_insert_data_card(self, cards_json):
|
||||
"""Insert download from mtgjson"""
|
||||
rows = []
|
||||
c_rows = []
|
||||
s_rows = []
|
||||
for data in cards_json.values():
|
||||
cards = []
|
||||
for raw in data["cards"]:
|
||||
@@ -77,14 +81,20 @@ class CardVaultDB:
|
||||
cards.append(c)
|
||||
|
||||
for c in cards:
|
||||
rows.append(self.card_to_table_mapping(c))
|
||||
c_rows.append(self.card_to_table_mapping(c))
|
||||
set = Set(data)
|
||||
s_rows.append(self.set_to_table_mapping(set))
|
||||
|
||||
# Connect to database
|
||||
con = sqlite3.connect(self.db_file)
|
||||
try:
|
||||
with con:
|
||||
sql_string = "INSERT INTO `cards` VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," \
|
||||
"?,?,?,?,?,?,?,?,?,?,?)"
|
||||
con.executemany(sql_string, rows)
|
||||
con.executemany(sql_string, c_rows)
|
||||
sql_string = "INSERT INTO `sets` VALUES (?,?,?,?,?,?,?,?,?,?,?)"
|
||||
con.executemany(sql_string, s_rows)
|
||||
|
||||
except sqlite3.OperationalError as err:
|
||||
util.log("Database Error", util.LogLevel.Error)
|
||||
util.log(str(err), util.LogLevel.Error)
|
||||
@@ -95,6 +105,7 @@ class CardVaultDB:
|
||||
def db_clear_data_card(self):
|
||||
"""Delete all resource data from database"""
|
||||
self.db_operation("DELETE FROM cards")
|
||||
self.db_operation("DELETE FROM sets")
|
||||
|
||||
def db_clear_data_user(self):
|
||||
"""Delete all user data from database"""
|
||||
@@ -278,6 +289,20 @@ class CardVaultDB:
|
||||
|
||||
return self.rows_to_card_dict(rows)
|
||||
|
||||
def set_get_all(self):
|
||||
con = sqlite3.connect(self.db_file)
|
||||
cur = con.cursor()
|
||||
cur.row_factory = sqlite3.Row
|
||||
|
||||
# First load all tags
|
||||
cur.execute("SELECT * FROM sets")
|
||||
rows = cur.fetchall()
|
||||
sets = []
|
||||
for row in rows:
|
||||
sets.append(self.table_to_set_mapping(row))
|
||||
|
||||
return sets
|
||||
|
||||
# DB internal functions ############################################################################################
|
||||
|
||||
def rows_to_card_dict(self, rows):
|
||||
@@ -383,3 +408,27 @@ class CardVaultDB:
|
||||
card.foreign_names = ast.literal_eval(row["foreignNames"])
|
||||
|
||||
return card
|
||||
|
||||
@staticmethod
|
||||
def set_to_table_mapping(set: Set):
|
||||
"""Convert Set object to a table row"""
|
||||
return (set.code, set.name, set.type, set.border, set.mkm_id, set.mkm_name, set.release_date, set.gatherer_code,
|
||||
set.magic_cards_info_code, str(set.booster), set.old_code)
|
||||
|
||||
@staticmethod
|
||||
def table_to_set_mapping(row):
|
||||
"""Return Set object representation of a table row"""
|
||||
set = Set()
|
||||
set.code = row['code']
|
||||
set.name = row['name']
|
||||
set.type = row['type']
|
||||
set.border = row['border']
|
||||
set.mkm_id = row['mkmid']
|
||||
set.mkm_name = row['mkmname']
|
||||
set.release_date = row['releasedate']
|
||||
set.gatherer_code = row['gatherercode']
|
||||
set.magic_cards_info_code = row['magiccardsinfocode']
|
||||
set.booster = ast.literal_eval(row['booster'])
|
||||
set.old_code = row['oldcode']
|
||||
|
||||
return set
|
||||
|
||||
@@ -264,10 +264,9 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<object class="GtkLabel" id="statusbar_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Online</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
@@ -276,10 +275,9 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<object class="GtkImage" id="statusbar_icon">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">network-idle</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
||||
@@ -122,8 +122,7 @@ class Handlers(SearchHandlers, LibraryHandlers, WantsHandlers):
|
||||
def download_finished(self):
|
||||
"""Download thread finished without errors"""
|
||||
self.cancel_token = False
|
||||
self.app.config["local_db"] = True
|
||||
self.app.save_config()
|
||||
self.app.set_online(False)
|
||||
self.app.ui.get_object("loadDataDialog").hide()
|
||||
self.app.push_status("Card data downloaded")
|
||||
util.log("Card data download finished", util.LogLevel.Info)
|
||||
@@ -238,6 +237,7 @@ class Handlers(SearchHandlers, LibraryHandlers, WantsHandlers):
|
||||
def do_clear_card_data(self, menu_item):
|
||||
util.log("Deleting all local card data", util.LogLevel.Info)
|
||||
self.app.db.db_clear_data_card()
|
||||
self.app.set_online(True)
|
||||
util.log("Done", util.LogLevel.Info)
|
||||
|
||||
def do_clear_data(self, item):
|
||||
|
||||
@@ -195,7 +195,7 @@ class SearchHandlers:
|
||||
# Set
|
||||
name = self.app.ui.get_object("setEntry").get_text()
|
||||
output["set"] = ""
|
||||
for mtgset in self.app.sets.values():
|
||||
for mtgset in self.app.get_all_sets().values():
|
||||
if mtgset.name == name:
|
||||
output["set"] = mtgset.code
|
||||
return output
|
||||
@@ -343,7 +343,7 @@ class SearchHandlers:
|
||||
def _init_set_entry(self, entry):
|
||||
""" Initialize model for set entry """
|
||||
set_store = Gtk.ListStore(str, str)
|
||||
for mtgset in self.app.sets.values():
|
||||
for mtgset in self.app.get_all_sets().values():
|
||||
set_store.append([mtgset.name, mtgset.code])
|
||||
completer = Gtk.EntryCompletion()
|
||||
completer.set_model(set_store)
|
||||
|
||||
@@ -106,6 +106,16 @@ rarity_dict = {
|
||||
}
|
||||
card_types = ["Creature", "Artifact", "Instant", "Enchantment", "Sorcery", "Land", "Planeswalker"]
|
||||
|
||||
online_icons = {
|
||||
True: 'network-wired',
|
||||
False: 'drive-harddisk'
|
||||
}
|
||||
|
||||
online_tooltips = {
|
||||
True: 'Using online card data',
|
||||
False: 'Using card data from local database.'
|
||||
}
|
||||
|
||||
|
||||
class LogLevel(enum.Enum):
|
||||
Error = 1
|
||||
@@ -258,7 +268,10 @@ def net_load_set_list() -> dict:
|
||||
|
||||
|
||||
def load_sets(filename: str) -> dict:
|
||||
# TODO Update Data function
|
||||
"""
|
||||
Load sets from local file if possible.
|
||||
Called by: Application if in online mode
|
||||
"""
|
||||
if not os.path.isfile(filename):
|
||||
# use mtgsdk api to retrieve al list of all sets
|
||||
sets = net_load_set_list()
|
||||
|
||||
Reference in New Issue
Block a user