commit 66c57b54523de4b50491733c66077a122a2cc7be Author: luxick Date: Wed Apr 12 14:47:17 2017 +0200 Initial Commit. Port from other project diff --git a/cardvault/cardlist.py b/cardvault/cardlist.py new file mode 100644 index 0000000..351bfd8 --- /dev/null +++ b/cardvault/cardlist.py @@ -0,0 +1,189 @@ +import gi +import util + +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk, GdkPixbuf, GObject + + +class CardList(Gtk.ScrolledWindow): + def __init__(self, tree, with_filter): + Gtk.ScrolledWindow.__init__(self) + self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + self.set_hexpand(True) + self.set_vexpand(True) + + self.filtered = with_filter + self.list = tree + + self.lib = {} + + # Columns are these: + # 0 Multiverse ID + # 1 Card Name + # 2 Card Supertypes (Legendary,..) + # 3 Card types (Creature, etc) + # 4 Rarity + # 5 Power + # 6 Toughness + # 7 Printings (Sets with this card in it) + # 8 Mana Cost(Form: {G}{2}) + # 9 CMC + # 10 Edition + self.store = Gtk.ListStore(int, str, str, str, str, str, str, str, GdkPixbuf.Pixbuf, int, str) + if self.filtered: + self.filter = self.store.filter_new() + self.filter_and_sort = Gtk.TreeModelSort(self.filter) + self.filter_and_sort.set_sort_func(4, self.compare_rarity, None) + self.list = Gtk.TreeView(self.filter_and_sort) + else: + self.store.set_sort_func(4, self.compare_rarity, None) + self.list = Gtk.TreeView(self.store) + self.add(self.list) + + self.list.set_rules_hint(True) + self.selection = self.list.get_selection() + + bold_renderer = Gtk.CellRendererText(xalign=0.5, yalign=0.5) + bold_renderer.set_property("weight", 800) + + text_renderer = Gtk.CellRendererText(xalign=0.5, yalign=0.5) + text_renderer.set_property("weight", 500) + image_renderer = Gtk.CellRendererPixbuf() + + col_id = Gtk.TreeViewColumn(title="Multiverse ID", cell_renderer=text_renderer, text=0) + col_id.set_visible(False) + + col_title = Gtk.TreeViewColumn(title="Name", cell_renderer=bold_renderer, text=1) + col_title.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) + col_title.set_expand(True) + col_title.set_sort_column_id(1) + + col_supertypes = Gtk.TreeViewColumn(title="Supertypes", cell_renderer=text_renderer, text=2) + col_supertypes.set_sort_column_id(2) + col_supertypes.set_visible(False) + + col_types = Gtk.TreeViewColumn(title="Types", cell_renderer=text_renderer, text=3) + col_types.set_sort_column_id(3) + + col_rarity = Gtk.TreeViewColumn(title="Rarity", cell_renderer=text_renderer, text=4) + col_rarity.set_sort_column_id(4) + + col_power = Gtk.TreeViewColumn(title="Power", cell_renderer=text_renderer, text=5) + col_power.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + col_power.set_fixed_width(50) + col_power.set_sort_column_id(5) + col_power.set_visible(False) + + col_thoughness = Gtk.TreeViewColumn(title="Toughness", cell_renderer=text_renderer, text=6) + col_thoughness.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + col_thoughness.set_fixed_width(50) + col_thoughness.set_sort_column_id(6) + col_thoughness.set_visible(False) + + col_printings = Gtk.TreeViewColumn(title="Printings", cell_renderer=text_renderer, text=7) + col_printings.set_sort_column_id(7) + col_printings.set_visible(False) + + col_mana = Gtk.TreeViewColumn(title="Mana Cost", cell_renderer=image_renderer, pixbuf=8) + col_mana.set_expand(False) + col_mana.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) + col_mana.set_sort_column_id(9) + + col_cmc = Gtk.TreeViewColumn(title="CMC", cell_renderer=text_renderer, text=9) + col_cmc.set_visible(False) + + col_set_name = Gtk.TreeViewColumn(title="Edition", cell_renderer=text_renderer, text=10) + col_set_name.set_expand(False) + col_set_name.set_sort_column_id(10) + + self.list.append_column(col_id) + self.list.append_column(col_title) + self.list.append_column(col_supertypes) + self.list.append_column(col_types) + self.list.append_column(col_rarity) + self.list.append_column(col_set_name) + self.list.append_column(col_power) + self.list.append_column(col_thoughness) + self.list.append_column(col_printings) + self.list.append_column(col_mana) + self.list.append_column(col_cmc) + + def update(self, library): + self.store.clear() + + if library is None: + return + + self.lib = library + + if self.filtered: + self.list.freeze_child_notify() + self.list.set_model(None) + + for multiverse_id, card in library.items(): + if card.multiverse_id is not None: + if card.supertypes is None: + card.supertypes = "" + item =[ + card.multiverse_id, + card.name, + " ".join(card.supertypes), + " ".join(card.types), + card.rarity, + card.power, + card.toughness, + ", ".join(card.printings), + util.create_mana_icons(card.mana_cost), + card.cmc, + card.set_name] + self.store.append(item) + + if self.filtered: + self.list.set_model(self.filter_and_sort) + self.list.thaw_child_notify() + + def update_generate(self, library, step=128): + n = 0 + self.store.clear() + self.list.freeze_child_notify() + for multiverse_id, card in library.items(): + if card.multiverse_id is not None: + if card.supertypes is None: + card.supertypes = "" + item =[ + card.multiverse_id, + card.name, + " ".join(card.supertypes), + " ".join(card.types), + card.rarity, + card.power, + card.toughness, + ", ".join(card.printings), + util.create_mana_icons(card.mana_cost), + card.cmc, + card.set_name] + self.store.append(item) + + n += 1 + if (n % step) == 0: + self.list.thaw_child_notify() + yield True + self.list.freeze_child_notify() + + self.list.thaw_child_notify() + # stop idle_add() + yield False + + def compare_rarity(self, model, row1, row2, user_data): + # Column for rarity + sort_column = 4 + value1 = model.get_value(row1, sort_column) + value2 = model.get_value(row2, sort_column) + if util.rarity_dict[value1.lower()] < util.rarity_dict[value2.lower()]: + return -1 + elif value1 == value2: + return 0 + else: + return 1 + + diff --git a/cardvault/config.py b/cardvault/config.py new file mode 100644 index 0000000..c8fbd12 --- /dev/null +++ b/cardvault/config.py @@ -0,0 +1,22 @@ +import gi +import os +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +from gi.repository import Gdk + + +# Title of the Program Window +application_title = "Card Vault v0.5" + +# Path of image cache +cache_path = os.path.dirname(__file__) + "/.cache/" +image_cache_path = os.path.dirname(__file__) + "/.cache/images/" + +# Colors to use in the Application +green_color = Gdk.color_parse('#87ff89') +red_color = Gdk.color_parse('#ff6d6d') + +# When True Search view will list a card multiple times for each set they appear in +show_from_all_sets = True + +start_page = "search" diff --git a/cardvault/gui/cardList.glade b/cardvault/gui/cardList.glade new file mode 100644 index 0000000..a511136 --- /dev/null +++ b/cardvault/gui/cardList.glade @@ -0,0 +1,13 @@ + + + + + + True + True + in + + + + + diff --git a/cardvault/gui/detailswindow.glade b/cardvault/gui/detailswindow.glade new file mode 100644 index 0000000..22f575d --- /dev/null +++ b/cardvault/gui/detailswindow.glade @@ -0,0 +1,249 @@ + + + + + + False + + + True + False + + + True + False + ../resources/images/dummy_315x450.png + + + 0 + 0 + + + + + True + False + True + + + True + False + end + 2 + Card Name: + right + 0.89999997615814209 + + + 0 + 0 + + + + + True + False + Loading... + 0.10000000149011612 + + + + + + + 1 + 0 + + + + + True + False + end + 2 + Type: + right + 0.89999997615814209 + + + 0 + 1 + + + + + True + False + Loading... + 0.10000000149011612 + + + 1 + 1 + + + + + True + False + end + 2 + Rarity: + right + 0.89999997615814209 + + + 0 + 2 + + + + + True + False + Loading... + 0.10000000149011612 + + + 1 + 2 + + + + + True + False + end + 2 + Release: + right + 0.89999997615814209 + + + 0 + 3 + + + + + True + False + Loading... + 0.10000000149011612 + + + 1 + 3 + + + + + True + False + end + 2 + Edition: + right + 0.89999997615814209 + + + 0 + 4 + + + + + True + False + Loading... + 0.10000000149011612 + + + 1 + 4 + + + + + True + False + end + 2 + Other Printings: + right + 0.89999997615814209 + + + 0 + 5 + + + + + True + False + Loading... + 0.10000000149011612 + + + 1 + 5 + + + + + True + False + end + Legalities: + right + 0.89999997615814209 + + + 0 + 6 + + + + + True + False + Loading... + 0.10000000149011612 + + + 1 + 6 + + + + + + + + + + + + + + + + + 1 + 0 + + + + + + + + + + + + + + + diff --git a/cardvault/gui/mainwindow.glade b/cardvault/gui/mainwindow.glade new file mode 100644 index 0000000..d7e4961 --- /dev/null +++ b/cardvault/gui/mainwindow.glade @@ -0,0 +1,157 @@ + + + + + + Card Vault + False + Card Vault + 800 + 600 + application-x-executable + + + True + False + 5 + 5 + vertical + + + menuBar + True + False + + + True + False + _Main + True + + + mainMenu + True + False + + + True + False + + + + + gtk-quit + True + False + True + True + + + + + + + + + View + True + False + _View + True + + + viewMenu + True + False + + + search + True + False + Search + True + True + + + + + + + library + True + False + Library + True + True + searchViewItem + + + + + + + decks + True + False + Decks + True + True + searchViewItem + + + + + + + + + + + False + True + 0 + + + + + contentPage + True + False + vertical + + + + + + True + True + 1 + + + + + statusBar + True + False + 10 + 10 + 10 + 10 + 6 + 6 + vertical + 2 + + + False + True + 2 + + + + + + + + + diff --git a/cardvault/gui/overlays.glade b/cardvault/gui/overlays.glade new file mode 100644 index 0000000..ddb7a29 --- /dev/null +++ b/cardvault/gui/overlays.glade @@ -0,0 +1,122 @@ + + + + + + True + False + 10 + True + True + + + True + False + start + Loading Image + True + + + 0 + 1 + + + + + True + False + center + end + True + + + 0 + 0 + + + + + Not Found + True + False + center + center + 10 + True + True + + + True + False + end + 100 + edit-find-symbolic + + + 0 + 0 + + + + + True + False + start + Page not found + + + 0 + 1 + + + + + True + False + center + center + 10 + True + + + True + False + end + 100 + edit-find-symbolic + + + 0 + 0 + + + + + True + False + center + Search + + + + + + + 0 + 1 + + + + + True + False + start + Use the entry on the left to search for cards + + + 0 + 2 + + + + diff --git a/cardvault/gui/search.glade b/cardvault/gui/search.glade new file mode 100644 index 0000000..5d5e99d --- /dev/null +++ b/cardvault/gui/search.glade @@ -0,0 +1,313 @@ + + + + + + Search + True + False + True + True + 2 + + + True + False + True + True + + + + + + 1 + 1 + + + + + leftPane + True + False + vertical + 2 + + + searchBox + True + False + vertical + 2 + + + True + True + + + + False + True + 1 + + + + + Search + True + True + True + + + + False + True + 2 + + + + + False + True + 0 + + + + + True + False + + + False + True + 5 + 1 + + + + + filterGrid + True + False + 2 + 2 + + + True + False + Filters + + + 0 + 0 + 2 + + + + + True + False + Mana Color + + + 0 + 1 + + + + + True + False + + + W + True + True + True + True + + + 0 + 0 + + + + + U + True + True + True + + + 1 + 0 + + + + + R + True + True + True + + + 0 + 1 + + + + + G + True + True + True + + + 1 + 1 + + + + + B + True + True + True + + + 2 + 0 + + + + + gtk-clear + True + True + True + True + + + + 2 + 1 + + + + + 1 + 1 + + + + + True + False + Rarity + + + 0 + 2 + + + + + True + False + 0 + + + 1 + 2 + + + + + True + False + Type + + + 0 + 3 + + + + + True + False + 0 + + + 1 + 3 + + + + + True + False + Edition + + + 0 + 4 + + + + + True + True + gtk-clear + + + + 1 + 4 + + + + + False + True + 2 + + + + + 0 + 0 + 2 + + + + + True + False + + + Add Card to Library + True + True + True + + + + False + True + 0 + + + + + + + + + + + 1 + 0 + + + + diff --git a/cardvault/handlers.py b/cardvault/handlers.py new file mode 100644 index 0000000..a6f5bdd --- /dev/null +++ b/cardvault/handlers.py @@ -0,0 +1,60 @@ +import gi +import config +import util +import search_funct +from mtgsdk import Card +from gi.repository import Gtk +gi.require_version('Gtk', '3.0') + + +class Handlers: + def __init__(self, app): + self.app = app + + def do_search_cards(self, sender): + search_term = self.app.ui.get_object("searchEntry").get_text() + + results = search_funct.search_cards(search_term) + + card_list = self.app.ui.get_object("searchResults").get_child() + card_list.update(results) + + self.app.ui.get_object("searchOverlay").set_visible(False) + + def on_view_changed(self, item): + if item.get_active(): + container = self.app.ui.get_object("contentPage") + new_page = self.app.pages[item.get_name()] + if self.app.current_page: + container.remove(self.app.current_page) + self.app.current_page = new_page + container.pack_start(self.app.current_page, True, True, 0) + container.show_all() + + app_title = new_page.get_name() + " - " + config.application_title + self.app.ui.get_object("mainWindow").set_title(app_title) + + def do_clear_mana_filter(self, mana_filter_grid): + for toggle_button in mana_filter_grid.get_children(): + if isinstance(toggle_button, Gtk.ToggleButton): + toggle_button.set_active(False) + + def do_clear_set_filter(self, entry, icon_pos, button): + entry.set_text("") + + def do_add_remove_clicked(self, button): + pass + + # Handlers for TreeViews etc. wich have been not added by Glade + + def on_search_card_selected(self, tree, row_no, column): + (model, path_list) = tree.get_selection().get_selected_rows() + + for path in path_list: + tree_iter = model.get_iter(path) + card_id = model.get_value(tree_iter, 0) + card_list = self.app.ui.get_object("searchResults").get_child() + card = card_list.lib[card_id] + self.app.show_card_details(card) + + diff --git a/cardvault/mtgsdk/__init__.py b/cardvault/mtgsdk/__init__.py new file mode 100644 index 0000000..dd18ad6 --- /dev/null +++ b/cardvault/mtgsdk/__init__.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +from mtgsdk.config import __version__, __pypi_packagename__, __github_username__, __github_reponame__, __endpoint__ +from mtgsdk.card import Card +from mtgsdk.set import Set +from mtgsdk.supertype import Supertype +from mtgsdk.subtype import Subtype +from mtgsdk.type import Type +from mtgsdk.changelog import Changelog +from mtgsdk.restclient import RestClient +from mtgsdk.restclient import MtgException +from mtgsdk.querybuilder import QueryBuilder \ No newline at end of file diff --git a/cardvault/mtgsdk/card.py b/cardvault/mtgsdk/card.py new file mode 100644 index 0000000..b45f311 --- /dev/null +++ b/cardvault/mtgsdk/card.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +from mtgsdk.querybuilder import QueryBuilder + + +class Card(object): + RESOURCE = 'cards' + + def __init__(self, response_dict={}): + self.name = response_dict.get('name') + self.layout = response_dict.get('layout') + self.mana_cost = response_dict.get('manaCost') + self.cmc = response_dict.get('cmc') + self.colors = response_dict.get('colors') + self.names = response_dict.get('names') + self.type = response_dict.get('type') + self.supertypes = response_dict.get('supertypes') + self.subtypes = response_dict.get('subtypes') + self.types = response_dict.get('types') + self.rarity = response_dict.get('rarity') + self.text = response_dict.get('text') + self.flavor = response_dict.get('flavor') + self.artist = response_dict.get('artist') + self.number = response_dict.get('number') + self.power = response_dict.get('power') + self.toughness = response_dict.get('toughness') + self.loyalty = response_dict.get('loyalty') + self.multiverse_id = response_dict.get('multiverseid') + self.variations = response_dict.get('variations') + self.watermark = response_dict.get('watermark') + self.border = response_dict.get('border') + self.timeshifted = response_dict.get('timeshifted') + self.hand = response_dict.get('hand') + self.life = response_dict.get('life') + self.release_date = response_dict.get('releaseDate') + self.starter = response_dict.get('starter') + self.printings = response_dict.get('printings') + self.original_text = response_dict.get('originalText') + self.original_type = response_dict.get('originalType') + self.source = response_dict.get('source') + self.image_url = response_dict.get('imageUrl') + self.set = response_dict.get('set') + self.set_name = response_dict.get('setName') + self.id = response_dict.get('id') + self.legalities = response_dict.get('legalities') + self.rulings = response_dict.get('rulings') + self.foreign_names = response_dict.get('foreignNames') + + @staticmethod + def find(id): + return QueryBuilder(Card).find(id) + + @staticmethod + def where(**kwargs): + return QueryBuilder(Card).where(**kwargs) + + @staticmethod + def all(): + return QueryBuilder(Card).all() diff --git a/cardvault/mtgsdk/changelog.py b/cardvault/mtgsdk/changelog.py new file mode 100644 index 0000000..ce419c8 --- /dev/null +++ b/cardvault/mtgsdk/changelog.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +from mtgsdk.querybuilder import QueryBuilder + + +class Changelog(object): + RESOURCE = 'changelogs' + + def __init__(self, response_dict={}): + self.id = response_dict.get('id') + self.version = response_dict.get('version') + self.details = response_dict.get('details') + self.release_date = response_dict.get('releaseDate') + + @staticmethod + def all(): + return QueryBuilder(Changelog).all() diff --git a/cardvault/mtgsdk/config.py b/cardvault/mtgsdk/config.py new file mode 100644 index 0000000..066a7d8 --- /dev/null +++ b/cardvault/mtgsdk/config.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +__version__ = "1.2.0" +__pypi_packagename__ = "mtgsdk" +__github_username__ = "MagicTheGathering" +__github_reponame__ = "mtg-sdk-python" +__endpoint__ = "https://api.magicthegathering.io/v1" diff --git a/cardvault/mtgsdk/querybuilder.py b/cardvault/mtgsdk/querybuilder.py new file mode 100644 index 0000000..b602259 --- /dev/null +++ b/cardvault/mtgsdk/querybuilder.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes +from mtgsdk.restclient import RestClient +from mtgsdk.config import __endpoint__ + + +class QueryBuilder(object): + def __init__(self, type): + self.params = {} + self.type = type + + def find(self, id): + """Get a resource by its id + + Args: + id (string): Resource id + Returns: + object: Instance of the resource type + """ + url = "{}/{}/{}".format(__endpoint__, self.type.RESOURCE, id) + response = RestClient.get(url)[self.type.RESOURCE[:-1]] + return self.type(response) + + def find_many(self, url, type, resource): + """Get a list of resources + + Args: + url (string): URL to invoke + type (class): Class type + resource (string): The REST Resource + Returns: + list of object: List of resource instances + """ + list = [] + response = RestClient.get(url)[resource] + if len(response) > 0: + for item in response: + list.append(type(item)) + + return list + + def where(self, **kwargs): + """Adds a parameter to the dictionary of query parameters + + Args: + **kwargs: Arbitrary keyword arguments. + Returns: + QueryBuilder: Instance of the QueryBuilder + """ + for key, value in kwargs.items(): + self.params[key] = value + + return self + + def all(self): + """Get all resources, automatically paging through data + + Returns: + list of object: List of resource objects + """ + list = [] + page = 1 + fetch_all = True + url = "{}/{}".format(__endpoint__, self.type.RESOURCE) + + if 'page' in self.params: + page = self.params['page'] + fetch_all = False + + while True: + response = RestClient.get(url, self.params)[self.type.RESOURCE] + if len(response) > 0: + for item in response: + list.append(self.type(item)) + + if not fetch_all: + break + else: + page += 1 + self.where(page=page) + else: + break + + return list + + def array(self): + """Get all resources and return the result as an array + + Returns: + array of str: Array of resources + """ + url = "{}/{}".format(__endpoint__, self.type.RESOURCE) + return RestClient.get(url, self.params)[self.type.RESOURCE] diff --git a/cardvault/mtgsdk/restclient.py b/cardvault/mtgsdk/restclient.py new file mode 100644 index 0000000..9a7da11 --- /dev/null +++ b/cardvault/mtgsdk/restclient.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +import json +from urllib.request import Request, urlopen +from urllib.error import HTTPError +from urllib.parse import urlencode + + +class RestClient(object): + @staticmethod + def get(url, params={}): + """Invoke an HTTP GET request on a url + + Args: + url (string): URL endpoint to request + params (dict): Dictionary of url parameters + Returns: + dict: JSON response as a dictionary + """ + request_url = url + + if len(params) > 0: + request_url = "{}?{}".format(url, urlencode(params)) + + try: + req = Request(request_url, headers={'User-Agent': 'Mozilla/5.0'}) + response = json.loads(urlopen(req).read().decode("utf-8")) + + return response + except HTTPError as err: + raise MtgException(err.read()) + + +class MtgException(Exception): + def __init__(self, description): + self.description = description + + def __str__(self): + return self.description diff --git a/cardvault/mtgsdk/set.py b/cardvault/mtgsdk/set.py new file mode 100644 index 0000000..228ee33 --- /dev/null +++ b/cardvault/mtgsdk/set.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +from mtgsdk.querybuilder import QueryBuilder +from mtgsdk.config import __endpoint__ +from mtgsdk.card import Card + + +class Set(object): + RESOURCE = 'sets' + + def __init__(self, response_dict={}): + self.code = response_dict.get('code') + self.name = response_dict.get('name') + self.type = response_dict.get('type') + self.border = response_dict.get('border') + self.mkm_id = response_dict.get('mkm_id') + self.mkm_name = response_dict.get('mkm_name') + self.release_date = response_dict.get('releaseDate') + self.gatherer_code = response_dict.get('gathererCode') + self.magic_cards_info_code = response_dict.get('magicCardsInfoCode') + self.booster = response_dict.get('booster') + self.old_code = response_dict.get('oldCode') + self.block = response_dict.get('block') + self.online_only = response_dict.get('onlineOnly') + + @staticmethod + def find(id): + return QueryBuilder(Set).find(id) + + @staticmethod + def where(**kwargs): + return QueryBuilder(Set).where(**kwargs) + + @staticmethod + def all(): + return QueryBuilder(Set).all() + + @staticmethod + def generate_booster(code): + url = "{}/{}/{}/booster".format(__endpoint__, Set.RESOURCE, code) + return QueryBuilder(Set).find_many(url, Card, Card.RESOURCE) diff --git a/cardvault/mtgsdk/subtype.py b/cardvault/mtgsdk/subtype.py new file mode 100644 index 0000000..757ed69 --- /dev/null +++ b/cardvault/mtgsdk/subtype.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +from mtgsdk.querybuilder import QueryBuilder + + +class Subtype(object): + RESOURCE = 'subtypes' + + @staticmethod + def all(): + return QueryBuilder(Subtype).array() diff --git a/cardvault/mtgsdk/supertype.py b/cardvault/mtgsdk/supertype.py new file mode 100644 index 0000000..3301711 --- /dev/null +++ b/cardvault/mtgsdk/supertype.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +from mtgsdk.querybuilder import QueryBuilder + + +class Supertype(object): + RESOURCE = 'supertypes' + + @staticmethod + def all(): + return QueryBuilder(Supertype).array() diff --git a/cardvault/mtgsdk/type.py b/cardvault/mtgsdk/type.py new file mode 100644 index 0000000..ef4c4cc --- /dev/null +++ b/cardvault/mtgsdk/type.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of mtgsdk. +# https://github.com/MagicTheGathering/mtg-sdk-python + +# Licensed under the MIT license: +# http://www.opensource.org/licenses/MIT-license +# Copyright (c) 2016, Andrew Backes + +from mtgsdk.querybuilder import QueryBuilder + + +class Type(object): + RESOURCE = 'types' + + @staticmethod + def all(): + return QueryBuilder(Type).array() diff --git a/cardvault/network.py b/cardvault/network.py new file mode 100644 index 0000000..ffd3cf7 --- /dev/null +++ b/cardvault/network.py @@ -0,0 +1,11 @@ +from urllib import request +from urllib.error import URLError, HTTPError +from mtgsdk import Set + + +def net_load_sets(): + try: + sets = Set.all() + except: + return "" + return sets diff --git a/cardvault/resources/images/demo.jpg b/cardvault/resources/images/demo.jpg new file mode 100644 index 0000000..8770dcf Binary files /dev/null and b/cardvault/resources/images/demo.jpg differ diff --git a/cardvault/resources/images/dummy.jpg b/cardvault/resources/images/dummy.jpg new file mode 100644 index 0000000..db96d70 Binary files /dev/null and b/cardvault/resources/images/dummy.jpg differ diff --git a/cardvault/resources/images/dummy_315x450.png b/cardvault/resources/images/dummy_315x450.png new file mode 100644 index 0000000..4c2170c Binary files /dev/null and b/cardvault/resources/images/dummy_315x450.png differ diff --git a/cardvault/resources/mana/0.png b/cardvault/resources/mana/0.png new file mode 100644 index 0000000..ccf4745 Binary files /dev/null and b/cardvault/resources/mana/0.png differ diff --git a/cardvault/resources/mana/1.png b/cardvault/resources/mana/1.png new file mode 100644 index 0000000..25910d5 Binary files /dev/null and b/cardvault/resources/mana/1.png differ diff --git a/cardvault/resources/mana/10.png b/cardvault/resources/mana/10.png new file mode 100644 index 0000000..0c7df91 Binary files /dev/null and b/cardvault/resources/mana/10.png differ diff --git a/cardvault/resources/mana/11.png b/cardvault/resources/mana/11.png new file mode 100644 index 0000000..8981a63 Binary files /dev/null and b/cardvault/resources/mana/11.png differ diff --git a/cardvault/resources/mana/12.png b/cardvault/resources/mana/12.png new file mode 100644 index 0000000..491f57c Binary files /dev/null and b/cardvault/resources/mana/12.png differ diff --git a/cardvault/resources/mana/13.png b/cardvault/resources/mana/13.png new file mode 100644 index 0000000..9bf560d Binary files /dev/null and b/cardvault/resources/mana/13.png differ diff --git a/cardvault/resources/mana/14.png b/cardvault/resources/mana/14.png new file mode 100644 index 0000000..5b3d3e1 Binary files /dev/null and b/cardvault/resources/mana/14.png differ diff --git a/cardvault/resources/mana/15.png b/cardvault/resources/mana/15.png new file mode 100644 index 0000000..c141fc1 Binary files /dev/null and b/cardvault/resources/mana/15.png differ diff --git a/cardvault/resources/mana/16.png b/cardvault/resources/mana/16.png new file mode 100644 index 0000000..9cedaab Binary files /dev/null and b/cardvault/resources/mana/16.png differ diff --git a/cardvault/resources/mana/17.png b/cardvault/resources/mana/17.png new file mode 100644 index 0000000..151ed3b Binary files /dev/null and b/cardvault/resources/mana/17.png differ diff --git a/cardvault/resources/mana/18.png b/cardvault/resources/mana/18.png new file mode 100644 index 0000000..3570589 Binary files /dev/null and b/cardvault/resources/mana/18.png differ diff --git a/cardvault/resources/mana/19.png b/cardvault/resources/mana/19.png new file mode 100644 index 0000000..03a11f8 Binary files /dev/null and b/cardvault/resources/mana/19.png differ diff --git a/cardvault/resources/mana/2.png b/cardvault/resources/mana/2.png new file mode 100644 index 0000000..ba97c06 Binary files /dev/null and b/cardvault/resources/mana/2.png differ diff --git a/cardvault/resources/mana/20.png b/cardvault/resources/mana/20.png new file mode 100644 index 0000000..d26b949 Binary files /dev/null and b/cardvault/resources/mana/20.png differ diff --git a/cardvault/resources/mana/2b.png b/cardvault/resources/mana/2b.png new file mode 100644 index 0000000..d43c422 Binary files /dev/null and b/cardvault/resources/mana/2b.png differ diff --git a/cardvault/resources/mana/2g.png b/cardvault/resources/mana/2g.png new file mode 100644 index 0000000..dfb55de Binary files /dev/null and b/cardvault/resources/mana/2g.png differ diff --git a/cardvault/resources/mana/2r.png b/cardvault/resources/mana/2r.png new file mode 100644 index 0000000..d96ae08 Binary files /dev/null and b/cardvault/resources/mana/2r.png differ diff --git a/cardvault/resources/mana/2u.png b/cardvault/resources/mana/2u.png new file mode 100644 index 0000000..139cd80 Binary files /dev/null and b/cardvault/resources/mana/2u.png differ diff --git a/cardvault/resources/mana/2w.png b/cardvault/resources/mana/2w.png new file mode 100644 index 0000000..cc94187 Binary files /dev/null and b/cardvault/resources/mana/2w.png differ diff --git a/cardvault/resources/mana/3.png b/cardvault/resources/mana/3.png new file mode 100644 index 0000000..e17feb1 Binary files /dev/null and b/cardvault/resources/mana/3.png differ diff --git a/cardvault/resources/mana/4.png b/cardvault/resources/mana/4.png new file mode 100644 index 0000000..5c0ff85 Binary files /dev/null and b/cardvault/resources/mana/4.png differ diff --git a/cardvault/resources/mana/5.png b/cardvault/resources/mana/5.png new file mode 100644 index 0000000..fbaaea9 Binary files /dev/null and b/cardvault/resources/mana/5.png differ diff --git a/cardvault/resources/mana/6.png b/cardvault/resources/mana/6.png new file mode 100644 index 0000000..44685bd Binary files /dev/null and b/cardvault/resources/mana/6.png differ diff --git a/cardvault/resources/mana/7.png b/cardvault/resources/mana/7.png new file mode 100644 index 0000000..65ceb52 Binary files /dev/null and b/cardvault/resources/mana/7.png differ diff --git a/cardvault/resources/mana/8.png b/cardvault/resources/mana/8.png new file mode 100644 index 0000000..81817e5 Binary files /dev/null and b/cardvault/resources/mana/8.png differ diff --git a/cardvault/resources/mana/9.png b/cardvault/resources/mana/9.png new file mode 100644 index 0000000..33cd6df Binary files /dev/null and b/cardvault/resources/mana/9.png differ diff --git a/cardvault/resources/mana/B.png b/cardvault/resources/mana/B.png new file mode 100644 index 0000000..9bdeb95 Binary files /dev/null and b/cardvault/resources/mana/B.png differ diff --git a/cardvault/resources/mana/BG.png b/cardvault/resources/mana/BG.png new file mode 100644 index 0000000..16ff5a1 Binary files /dev/null and b/cardvault/resources/mana/BG.png differ diff --git a/cardvault/resources/mana/BP.png b/cardvault/resources/mana/BP.png new file mode 100644 index 0000000..b8a95ab Binary files /dev/null and b/cardvault/resources/mana/BP.png differ diff --git a/cardvault/resources/mana/BR.png b/cardvault/resources/mana/BR.png new file mode 100644 index 0000000..9206ae0 Binary files /dev/null and b/cardvault/resources/mana/BR.png differ diff --git a/cardvault/resources/mana/B_alt.png b/cardvault/resources/mana/B_alt.png new file mode 100644 index 0000000..245051e Binary files /dev/null and b/cardvault/resources/mana/B_alt.png differ diff --git a/cardvault/resources/mana/C.png b/cardvault/resources/mana/C.png new file mode 100644 index 0000000..2694fd8 Binary files /dev/null and b/cardvault/resources/mana/C.png differ diff --git a/cardvault/resources/mana/C_alt.png b/cardvault/resources/mana/C_alt.png new file mode 100644 index 0000000..b60f4a8 Binary files /dev/null and b/cardvault/resources/mana/C_alt.png differ diff --git a/cardvault/resources/mana/G.png b/cardvault/resources/mana/G.png new file mode 100644 index 0000000..0b9de84 Binary files /dev/null and b/cardvault/resources/mana/G.png differ diff --git a/cardvault/resources/mana/GP.png b/cardvault/resources/mana/GP.png new file mode 100644 index 0000000..6505e9d Binary files /dev/null and b/cardvault/resources/mana/GP.png differ diff --git a/cardvault/resources/mana/GU.png b/cardvault/resources/mana/GU.png new file mode 100644 index 0000000..d5534df Binary files /dev/null and b/cardvault/resources/mana/GU.png differ diff --git a/cardvault/resources/mana/GW.png b/cardvault/resources/mana/GW.png new file mode 100644 index 0000000..58ecb1b Binary files /dev/null and b/cardvault/resources/mana/GW.png differ diff --git a/cardvault/resources/mana/G_alt.png b/cardvault/resources/mana/G_alt.png new file mode 100644 index 0000000..b41ccd9 Binary files /dev/null and b/cardvault/resources/mana/G_alt.png differ diff --git a/cardvault/resources/mana/R.png b/cardvault/resources/mana/R.png new file mode 100644 index 0000000..aae184b Binary files /dev/null and b/cardvault/resources/mana/R.png differ diff --git a/cardvault/resources/mana/RG.png b/cardvault/resources/mana/RG.png new file mode 100644 index 0000000..28352fc Binary files /dev/null and b/cardvault/resources/mana/RG.png differ diff --git a/cardvault/resources/mana/RP.png b/cardvault/resources/mana/RP.png new file mode 100644 index 0000000..a4c609f Binary files /dev/null and b/cardvault/resources/mana/RP.png differ diff --git a/cardvault/resources/mana/RW.png b/cardvault/resources/mana/RW.png new file mode 100644 index 0000000..299bae4 Binary files /dev/null and b/cardvault/resources/mana/RW.png differ diff --git a/cardvault/resources/mana/R_alt.png b/cardvault/resources/mana/R_alt.png new file mode 100644 index 0000000..5263bd1 Binary files /dev/null and b/cardvault/resources/mana/R_alt.png differ diff --git a/cardvault/resources/mana/S.png b/cardvault/resources/mana/S.png new file mode 100644 index 0000000..6800592 Binary files /dev/null and b/cardvault/resources/mana/S.png differ diff --git a/cardvault/resources/mana/T.png b/cardvault/resources/mana/T.png new file mode 100644 index 0000000..4237b55 Binary files /dev/null and b/cardvault/resources/mana/T.png differ diff --git a/cardvault/resources/mana/U.png b/cardvault/resources/mana/U.png new file mode 100644 index 0000000..add2250 Binary files /dev/null and b/cardvault/resources/mana/U.png differ diff --git a/cardvault/resources/mana/UB.png b/cardvault/resources/mana/UB.png new file mode 100644 index 0000000..a51d5c8 Binary files /dev/null and b/cardvault/resources/mana/UB.png differ diff --git a/cardvault/resources/mana/UP.png b/cardvault/resources/mana/UP.png new file mode 100644 index 0000000..8305d69 Binary files /dev/null and b/cardvault/resources/mana/UP.png differ diff --git a/cardvault/resources/mana/UR.png b/cardvault/resources/mana/UR.png new file mode 100644 index 0000000..97042c2 Binary files /dev/null and b/cardvault/resources/mana/UR.png differ diff --git a/cardvault/resources/mana/U_alt.png b/cardvault/resources/mana/U_alt.png new file mode 100644 index 0000000..a0ccba1 Binary files /dev/null and b/cardvault/resources/mana/U_alt.png differ diff --git a/cardvault/resources/mana/W.png b/cardvault/resources/mana/W.png new file mode 100644 index 0000000..2c84442 Binary files /dev/null and b/cardvault/resources/mana/W.png differ diff --git a/cardvault/resources/mana/WB.png b/cardvault/resources/mana/WB.png new file mode 100644 index 0000000..921efb0 Binary files /dev/null and b/cardvault/resources/mana/WB.png differ diff --git a/cardvault/resources/mana/WP.png b/cardvault/resources/mana/WP.png new file mode 100644 index 0000000..b9530f1 Binary files /dev/null and b/cardvault/resources/mana/WP.png differ diff --git a/cardvault/resources/mana/WU.png b/cardvault/resources/mana/WU.png new file mode 100644 index 0000000..59afef4 Binary files /dev/null and b/cardvault/resources/mana/WU.png differ diff --git a/cardvault/resources/mana/W_alt.png b/cardvault/resources/mana/W_alt.png new file mode 100644 index 0000000..4ff6c41 Binary files /dev/null and b/cardvault/resources/mana/W_alt.png differ diff --git a/cardvault/resources/mana/X.png b/cardvault/resources/mana/X.png new file mode 100644 index 0000000..1be868c Binary files /dev/null and b/cardvault/resources/mana/X.png differ diff --git a/cardvault/resources/mana/Y.png b/cardvault/resources/mana/Y.png new file mode 100644 index 0000000..53e453b Binary files /dev/null and b/cardvault/resources/mana/Y.png differ diff --git a/cardvault/resources/mana/Z.png b/cardvault/resources/mana/Z.png new file mode 100644 index 0000000..d0f1963 Binary files /dev/null and b/cardvault/resources/mana/Z.png differ diff --git a/cardvault/resources/mana/flip.png b/cardvault/resources/mana/flip.png new file mode 100644 index 0000000..cacd12f Binary files /dev/null and b/cardvault/resources/mana/flip.png differ diff --git a/cardvault/resources/mana/half.png b/cardvault/resources/mana/half.png new file mode 100644 index 0000000..89a03ba Binary files /dev/null and b/cardvault/resources/mana/half.png differ diff --git a/cardvault/resources/mana/infinite.png b/cardvault/resources/mana/infinite.png new file mode 100644 index 0000000..963d7fa Binary files /dev/null and b/cardvault/resources/mana/infinite.png differ diff --git a/cardvault/resources/mana/tap_old.png b/cardvault/resources/mana/tap_old.png new file mode 100644 index 0000000..1ab17d4 Binary files /dev/null and b/cardvault/resources/mana/tap_old.png differ diff --git a/cardvault/resources/mana/untap.png b/cardvault/resources/mana/untap.png new file mode 100644 index 0000000..7dc4008 Binary files /dev/null and b/cardvault/resources/mana/untap.png differ diff --git a/cardvault/search_funct.py b/cardvault/search_funct.py new file mode 100644 index 0000000..01fc53a --- /dev/null +++ b/cardvault/search_funct.py @@ -0,0 +1,135 @@ +import gi +import util +import config +import cardlist +import handlers +from gi.repository import Gtk +from mtgsdk import Card +from urllib.error import URLError, HTTPError +gi.require_version('Gtk', '3.0') + + +def init_search_view(app): + # set mana icons on filter buttons + buttons = [x for x in app.ui.get_object("manaFilterGrid").get_children() + if isinstance(x, Gtk.ToggleButton)] + _init_mana_buttons(buttons) + # set auto completion for filter entry + _init_set_entry(app.ui.get_object("setEntry")) + # Fill rarity box + _init_combo_box(app.ui.get_object("rarityCombo"), util.rarity_dict.keys()) + # Fill type box + _init_combo_box(app.ui.get_object("typeCombo"), util.card_types) + # Create Model for search results + _init_results_tree(app.ui.get_object("cardTree"), app) + + +def search_cards(term): + # Load filters from UI + filters = _get_filters(util.app) + + # Load card info from internet + try: + cards = Card.where(name=term) \ + .where(colorIdentity=filters["mana"]) \ + .where(types=filters["type"]) \ + .where(set=filters["set"]) \ + .where(rarity=filters["rarity"]) \ + .where(pageSize=50) \ + .where(page=1).all() + except (URLError, HTTPError) as err: + print("Error connecting to the internet") + return + + if len(cards) == 0: + # TODO UI show no cards found + return + + # Remove duplicate entries + if config.show_from_all_sets is False: + cards = _remove_duplicates(cards) + + # Pack results in a dictionary + lib = {} + for card in cards: + lib[card.multiverse_id] = card + return lib + + +def _init_results_tree(tree_view, app): + overlay = app.ui.get_object("searchResults") + card_list = cardlist.CardList(tree_view, False) + card_list.set_name("resultsScroller") + card_list.list.connect("row-activated", app.handlers.on_search_card_selected) + overlay.add(card_list) + overlay.add_overlay(app.ui.get_object("searchOverlay")) + overlay.show_all() + + +def _init_combo_box(combo, list): + model = Gtk.ListStore(str) + model.append(["All"]) + for entry in list: + model.append([entry.title()]) + combo.set_model(model) + cell = Gtk.CellRendererText() + combo.pack_start(cell, True) + combo.add_attribute(cell, "text", 0) + combo.set_active(0) + + +def _get_filters(app): + output = {} + # Mana colors + color_list = [] + # Go through mana color buttons an get the active filters + for button in app.ui.get_object("manaFilterGrid").get_children(): + if isinstance(button, Gtk.ToggleButton): + if button.get_active(): + color_list.append(button.get_name()) + output["mana"] = ",".join(color_list) + # Rarity + combo = app.ui.get_object("rarityCombo") + output["rarity"] = _get_combo_value(combo) + # Type + combo = app.ui.get_object("typeCombo") + output["type"] = _get_combo_value(combo) + # Set + name = app.ui.get_object("setEntry").get_text() + for set in util.set_list: + if set.name == name: + output["set"] = set.code + return output + + +def _remove_duplicates(cards): + unique_cards = [] + unique_names = [] + # Reverse cardlist so we get the version with the most modern art + for card in reversed(cards): + if card.name not in unique_names: + unique_names.append(card.name) + unique_cards.append(card) + return unique_cards + + +def _get_combo_value(combo): + tree_iter = combo.get_active_iter() + value = combo.get_model().get_value(tree_iter, 0) + return value.replace("All", "") + + +def _init_mana_buttons(button_list): + for button in button_list: + image = Gtk.Image.new_from_pixbuf(util.create_mana_icons("{" + button.get_name() + "}")) + button.set_image(image) + + +def _init_set_entry(entry): + set_store = Gtk.ListStore(str, str) + for set in util.set_list: + set_store.append([set.name, set.code]) + completer = Gtk.EntryCompletion() + completer.set_model(set_store) + completer.set_text_column(0) + entry.set_completion(completer) diff --git a/cardvault/util.py b/cardvault/util.py new file mode 100644 index 0000000..0558ec1 --- /dev/null +++ b/cardvault/util.py @@ -0,0 +1,273 @@ +import os +import datetime +import gi +import re +import config +import network +from gi.repository import GdkPixbuf, Gtk +from PIL import Image as PImage +from urllib import request +import six.moves.cPickle as pickle +gi.require_version('Gtk', '3.0') + + +# Locally stored images for faster loading times +imagecache = {} +manaicons = {} +set_list = [] + +# Card library object +library = {} +# Dictionary for tagged cards +tags = {} + +status_bar = None +app = None +unsaved_changes = False + +rarity_dict = { + "special": 0, + "common": 1, + "uncommon": 2, + "rare": 3, + "mythic rare": 4 +} +card_types = ["Creature", "Artifact", "Instant", "Enchantment", "Sorcery", "Land", "Planeswalker"] + +def export_library(): + dialog = Gtk.FileChooserDialog("Export Library", app.ui.get_object("mainWindow"), + Gtk.FileChooserAction.SAVE, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) + dialog.set_current_name("mtg_export-" + datetime.datetime.now().strftime("%Y-%m-%d")) + dialog.set_current_folder(os.path.expanduser("~")) + response = dialog.run() + if response == Gtk.ResponseType.OK: + try: + pickle.dump(library, open(dialog.get_filename(), 'wb')) + except: + show_message("Error", "Error while saving library to disk") + app.push_status("Library exported to \"" + dialog.get_filename() + "\"") + print("Library exported to \"", dialog.get_filename() + "\"") + dialog.destroy() + + +def import_library(): + dialog = Gtk.FileChooserDialog("Import Library", app.ui.get_object("mainWindow"), + Gtk.FileChooserAction.OPEN, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) + dialog.set_current_folder(os.path.expanduser("~")) + response = dialog.run() + if response == Gtk.ResponseType.OK: + override_question = show_question_dialog("Import Library", + "Importing a library will override your current library. " + "Proceed?") + if override_question == Gtk.ResponseType.YES: + imported = pickle.load(open(dialog.get_filename(), 'rb')) + library.clear() + for id, card in imported.items(): + library[id] = card + save_library() + app.push_status("Library imported") + print("Library imported") + dialog.destroy() + + +def save_library(): + if not os.path.exists(config.cache_path): + os.makedirs(config.cache_path) + lib_path = config.cache_path + "library" + tag_path = config.cache_path + "tags" + + # Serialize library object using pickle + try: + pickle.dump(library, open(lib_path, 'wb')) + pickle.dump(tags, open(tag_path, 'wb')) + except: + show_message("Error", "Error while saving library to disk") + return + + global unsaved_changes + unsaved_changes = False + app.push_status("Library saved.") + + +def load_library(): + lib_path = config.cache_path + "library" + library.clear() + + if os.path.isfile(lib_path): + # Deserialize using pickle + try: + library_loaded = pickle.load(open(lib_path, 'rb')) + for id, card in library_loaded.items(): + library[id] = card + except : + show_message("Error", "Error while loading library from disk") + else: + save_library() + print("No library file found, created new one") + + +def load_tags(): + tag_path = config.cache_path + "tags" + tags.clear() + if not os.path.isfile(tag_path): + save_library() + print("No tags file found, created new one") + try: + tags_loaded = pickle.load(open(tag_path, 'rb')) + for tag, ids in tags_loaded.items(): + tags[tag] = ids + except: + show_message("Error", "Error while loading library from disk") + + +def load_sets(): + path = config.cache_path + "sets" + if not os.path.isfile(path): + # use mtgsdk api to retrieve al list of all sets + new_sets = network.net_load_sets() + if new_sets == "": + show_message("API Error", "Could not retrieve Set infos") + return + # Serialize the loaded data to a file + pickle.dump(new_sets, open(path, 'wb')) + # Deserialize set data from local file + sets = pickle.load(open(path, 'rb')) + # Sort the loaded sets based on the sets name + for set in sorted(sets, key=lambda x: x.name): + set_list.append(set) + + +def reload_image_cache(): + if not os.path.exists(config.image_cache_path): + os.makedirs(config.image_cache_path) + + # return array of images + imageslist = os.listdir(config.image_cache_path) + imagecache.clear() + for image in imageslist: + try: + pixbuf = GdkPixbuf.Pixbuf.new_from_file(config.image_cache_path + image) + imagecache[image] = pixbuf + except OSError as err: + print("Error loading image: " + str(err)) + +# endregion + + +def add_tag(tag): + tags[tag] = {} + app.push_status("Added Tag \"" + tag + "\"") + global unsaved_changes + unsaved_changes = True + + +def remove_tag(tag): + tags[tag] = None + app.push_status("Removed Tag \"" + tag + "\"") + global unsaved_changes + unsaved_changes = True + + +def add_card_to_lib(card): + library[card.multiverse_id] = card + app.push_status(card.name + " added to library") + global unsaved_changes + unsaved_changes = True + + +def remove_card_from_lib(card): + del library[card.multiverse_id] + app.push_status(card.name + " removed from library") + global unsaved_changes + unsaved_changes = True + +def show_question_dialog(title, message): + dialog = Gtk.MessageDialog(app.ui.get_object("mainWindow"), 0, Gtk.MessageType.QUESTION, + Gtk.ButtonsType.YES_NO, title) + dialog.format_secondary_text(message) + response = dialog.run() + dialog.destroy() + return response + + +def show_message(title, message): + dialog = Gtk.MessageDialog(app.ui.get_object("mainWindow"), 0, Gtk.MessageType.INFO, + Gtk.ButtonsType.OK, title) + dialog.format_secondary_text(message) + dialog.run() + dialog.destroy() + + +def load_mana_icons(): + path = os.path.dirname(__file__) + "/resources/mana/" + if not os.path.exists(path): + print("ERROR: Directory for mana icons not found") + return + # return array of icons + imagelist = os.listdir(path) + manaicons.clear() + for image in imagelist: + img = PImage.open(path + image) + manaicons[os.path.splitext(image)[0]] = img + + +def load_dummy_image(sizex, sizey): + return GdkPixbuf.Pixbuf.new_from_file_at_size(os.path.dirname(__file__) + + '/resources/images/dummy.jpg', sizex, sizey) + + +def load_card_image_online(card, sizex, sizey): + url = card.image_url + if url is None: + print("No Image URL provided") + return load_dummy_image(sizex, sizey) + filename = config.image_cache_path + card.multiverse_id.__str__() + ".PNG" + print("Loading image for " + card.name + "from: " + url) + request.urlretrieve(url, filename) + reload_image_cache() + return GdkPixbuf.Pixbuf.new_from_file_at_size(filename, sizex, sizey) + + +def load_card_image(card, sizex, sizey): + # Try loading from disk, if file exists + filename = str(card.multiverse_id) + ".PNG" + if imagecache.__contains__(filename): + pixbuf = imagecache[filename] + return pixbuf.scale_simple(sizex, sizey, GdkPixbuf.InterpType.BILINEAR) + else: + return load_card_image_online(card, sizex, sizey) + + +def create_mana_icons(mana_string): + # Convert the string to a List + list = re.findall("{(.*?)}", str(mana_string)) + if len(list) == 0: + return + # Compute horizontal size for the final image + imagesize = len(list) * 105 + image = PImage.new("RGBA", (imagesize, 105)) + # incerment for each position of an icon (Workaround: 2 or more of the same icon will be rendered in the same poisition) + poscounter = 0 + # Go through all entries an add the correspondent icon to the final image + for icon in list: + xpos = poscounter * 105 + loaded = manaicons.get(icon.replace("/", "")) + if loaded is None: + print("ERROR: No icon file named \"" + icon + "\" found.") + else: + image.paste(loaded, (xpos, 0)) + poscounter += 1 + filename = "icon.png" + path = config.cache_path + filename + image.save(path) + try: + pixbuf = GdkPixbuf.Pixbuf.new_from_file(path) + pixbuf = pixbuf.scale_simple(image.width / 5, image.height / 5, GdkPixbuf.InterpType.HYPER) + except: + return + # os.remove(path) + return pixbuf diff --git a/cardvault/window.py b/cardvault/window.py new file mode 100644 index 0000000..d123f62 --- /dev/null +++ b/cardvault/window.py @@ -0,0 +1,61 @@ +import config +import handlers +import util +import search_funct +import gi +from gi.repository import Gtk +gi.require_version('Gtk', '3.0') + + +class MainWindow: + def __init__(self): + + self.ui = Gtk.Builder() + self.ui.add_from_file("gui/mainwindow.glade") + self.ui.add_from_file("gui/overlays.glade") + self.ui.add_from_file("gui/search.glade") + self.ui.add_from_file("gui/detailswindow.glade") + window = self.ui.get_object("mainWindow") + self.current_page = None + util.app = self + not_found = self.ui.get_object("pageNotFound") + + self.pages = { + "search": self.ui.get_object("searchView"), + "library": not_found, + "decks": not_found + } + + # Load local image Data + util.reload_image_cache() + util.load_mana_icons() + + util.load_sets() + util.load_library() + util.load_tags() + + self.handlers = handlers.Handlers(self) + self.ui.connect_signals(self.handlers) + + search_funct.init_search_view(self) + + window.connect('delete-event', Gtk.main_quit) + window.show_all() + self.push_status("Card Vault ready.") + + view_menu = self.ui.get_object("viewMenu") + start_page = [page for page in view_menu.get_children() if page.get_name() == config.start_page] + start_page[0].activate() + + def push_status(self, msg): + status_bar = self.ui.get_object("statusBar") + status_bar.pop(0) + status_bar.push(0, msg) + + def show_card_details(self, card): + print("Show", card.name) + pass + + +win = MainWindow() +Gtk.main()