Use local database over internet for card searches.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import sqlite3
|
||||
import ast
|
||||
from mtgsdk import Card
|
||||
|
||||
from cardvault import util
|
||||
@@ -58,6 +59,59 @@ class CardVaultDB:
|
||||
util.log("Database Error", util.LogLevel.Error)
|
||||
util.log(str(err), util.LogLevel.Error)
|
||||
|
||||
def search_cards_by_name_filtered(self, term: str, filters: dict, list_size: int) -> dict:
|
||||
"""Search for cards based on the cards name with filter constrains"""
|
||||
filter_rarity = filters["rarity"]
|
||||
filer_type = filters["type"]
|
||||
filter_set = filters["set"]
|
||||
filter_mana = filters["mana"].split(',')
|
||||
|
||||
sql = 'SELECT * FROM cards WHERE `name` LIKE ?'
|
||||
parameters = ['%' + term + '%']
|
||||
if filter_rarity != "":
|
||||
sql += ' AND `rarity` = ?'
|
||||
parameters.append(filter_rarity)
|
||||
if filer_type != "":
|
||||
sql += ' AND `types` LIKE ?'
|
||||
parameters.append(filer_type)
|
||||
if filter_set != "":
|
||||
sql += ' AND `set` = ?'
|
||||
parameters.append(filter_set)
|
||||
if len(filter_mana) != 0:
|
||||
for color in filter_mana:
|
||||
sql += ' AND `manaCost` LIKE ?'
|
||||
parameters.append('%'+color+'%')
|
||||
sql += ' LIMIT ?'
|
||||
parameters.append(list_size)
|
||||
|
||||
con = sqlite3.connect(self.db_file)
|
||||
cur = con.cursor()
|
||||
cur.row_factory = sqlite3.Row
|
||||
cur.execute(sql, parameters)
|
||||
rows = cur.fetchall()
|
||||
con.close()
|
||||
|
||||
output = {}
|
||||
for row in rows:
|
||||
card = self.table_to_card_mapping(row)
|
||||
output[card.multiverse_id] = card
|
||||
return output
|
||||
|
||||
def search_cards_by_name(self, term: str) -> dict:
|
||||
"""Search for cards based on the cards name"""
|
||||
con = sqlite3.connect(self.db_file)
|
||||
cur = con.cursor()
|
||||
cur.row_factory = sqlite3.Row
|
||||
cur.execute("SELECT * FROM cards WHERE `name` LIKE ? LIMIT 50", ('%'+term+'%', ))
|
||||
rows = cur.fetchall()
|
||||
con.close()
|
||||
|
||||
output = {}
|
||||
for row in rows:
|
||||
card = self.table_to_card_mapping(row)
|
||||
output[card.multiverse_id] = card
|
||||
return output
|
||||
|
||||
@staticmethod
|
||||
def card_to_table_mapping(card: Card):
|
||||
"""Return the database representation of a card object"""
|
||||
@@ -73,3 +127,56 @@ class CardVaultDB:
|
||||
str(card.original_type), str(card.source), str(card.image_url), str(card.set), str(card.set_name),
|
||||
str(card.id),
|
||||
str(card.legalities), str(card.rulings), str(card.foreign_names))
|
||||
|
||||
@staticmethod
|
||||
def table_to_card_mapping(row: sqlite3.Row):
|
||||
"""Return card object representation of a table row"""
|
||||
card = Card()
|
||||
card.multiverse_id = row["multiverseid"]
|
||||
tmp = row["name"]
|
||||
card.name = tmp
|
||||
card.layout = row["layout"]
|
||||
card.mana_cost = row["manacost"]
|
||||
card.cmc = row["cmc"]
|
||||
card.colors = row["colors"]
|
||||
card.type = row["type"]
|
||||
card.rarity = row["rarity"]
|
||||
card.text = row["text"]
|
||||
card.flavor = row["flavor"]
|
||||
card.artist = row["artist"]
|
||||
card.number = row["number"]
|
||||
card.power = row["power"]
|
||||
card.toughness = row["toughness"]
|
||||
card.loyalty = row["loyalty"]
|
||||
card.watermark = row["watermark"]
|
||||
card.border = row["border"]
|
||||
card.hand = row["hand"]
|
||||
card.life = row["life"]
|
||||
card.release_date = row["releaseDate"]
|
||||
card.starter = row["starter"]
|
||||
card.original_text = row["originalText"]
|
||||
card.original_type = row["originalType"]
|
||||
card.source = row["source"]
|
||||
card.image_url = row["imageUrl"]
|
||||
card.set = row["set"]
|
||||
card.set_name = row["setName"]
|
||||
card.id = row["id"]
|
||||
|
||||
# Bool attributes
|
||||
card.timeshifted = ast.literal_eval(row["timeshifted"])
|
||||
|
||||
# List attributes
|
||||
card.names = ast.literal_eval(row["names"])
|
||||
card.supertypes = ast.literal_eval(row["supertypes"])
|
||||
card.subtypes = ast.literal_eval(row["subtypes"])
|
||||
card.types = ast.literal_eval(row["types"])
|
||||
card.printings = ast.literal_eval(row["printings"])
|
||||
card.variations = ast.literal_eval(row["variations"])
|
||||
|
||||
# Dict attributes
|
||||
card.legalities = ast.literal_eval(row["legalities"])
|
||||
card.rulings = ast.literal_eval(row["rulings"])
|
||||
card.foreign_names = ast.literal_eval(row["foreignNames"])
|
||||
|
||||
return card
|
||||
|
||||
|
||||
@@ -205,6 +205,18 @@ class SearchHandlers:
|
||||
return output
|
||||
|
||||
def search_cards(self, term: str, filters: dict) -> dict:
|
||||
"""Return a dict of cards based on a search term and filters"""
|
||||
# Check if a local database can be used for searching
|
||||
if self.app.config["local_db"]:
|
||||
util.log("Starting local search for '" + term + "'", util.LogLevel.Info)
|
||||
start = time.time()
|
||||
|
||||
cards = self.app.db.search_cards_by_name_filtered(term, filters, 100)
|
||||
|
||||
end = time.time()
|
||||
util.log("Card info fetched in {}s".format(round(end - start, 3)), util.LogLevel.Info)
|
||||
|
||||
else:
|
||||
util.log("Starting online search for '" + term + "'", util.LogLevel.Info)
|
||||
util.log("Used Filters: " + str(filters), util.LogLevel.Info)
|
||||
|
||||
@@ -212,7 +224,7 @@ class SearchHandlers:
|
||||
try:
|
||||
util.log("Fetching card info ...", util.LogLevel.Info)
|
||||
start = time.time()
|
||||
cards = Card.where(name=term) \
|
||||
data = Card.where(name=term) \
|
||||
.where(colorIdentity=filters["mana"]) \
|
||||
.where(types=filters["type"]) \
|
||||
.where(set=filters["set"]) \
|
||||
@@ -225,22 +237,21 @@ class SearchHandlers:
|
||||
util.log(err, util.LogLevel.Error)
|
||||
return {}
|
||||
|
||||
# Remove duplicate entries
|
||||
if util.SHOW_FROM_ALL_SETS is False:
|
||||
data = self._remove_duplicates(data)
|
||||
# Pack results in a dictionary
|
||||
cards = {}
|
||||
for card in data:
|
||||
cards[card.multiverse_id] = card
|
||||
|
||||
# Check if results were found
|
||||
if len(cards) == 0:
|
||||
# TODO UI show no cards found
|
||||
util.log("No Cards found", util.LogLevel.Info)
|
||||
return {}
|
||||
|
||||
util.log("Found " + str(len(cards)) + " cards", util.LogLevel.Info)
|
||||
# Remove duplicate entries
|
||||
if util.SHOW_FROM_ALL_SETS is False:
|
||||
cards = self._remove_duplicates(cards)
|
||||
|
||||
# Pack results in a dictionary
|
||||
lib = {}
|
||||
for card in cards:
|
||||
lib[card.multiverse_id] = card
|
||||
return lib
|
||||
return cards
|
||||
|
||||
# ---------------------------------Search Tree----------------------------------------------
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ GENERIC_TREE_COLORS ={
|
||||
default_config = {
|
||||
"hide_duplicates_in_search": False,
|
||||
"start_page": "search",
|
||||
"local_db": False,
|
||||
"log_level": 3,
|
||||
"legality_colors": {
|
||||
"Banned": "#C65642",
|
||||
|
||||
Reference in New Issue
Block a user