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