Initial Commit. Port from other project
189
cardvault/cardlist.py
Normal file
@@ -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
|
||||
|
||||
|
||||
22
cardvault/config.py
Normal file
@@ -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"
|
||||
13
cardvault/gui/cardList.glade
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkScrolledWindow" id="list_window">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
249
cardvault/gui/detailswindow.glade
Normal file
@@ -0,0 +1,249 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkWindow" id="cardDetails">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="bigCard">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixbuf">../resources/images/dummy_315x450.png</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="label" translatable="yes">Card Name:</property>
|
||||
<property name="justify">right</property>
|
||||
<property name="xalign">0.89999997615814209</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cardName">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Loading...</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.3"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="label" translatable="yes">Type:</property>
|
||||
<property name="justify">right</property>
|
||||
<property name="xalign">0.89999997615814209</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cardTypes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Loading...</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="label" translatable="yes">Rarity:</property>
|
||||
<property name="justify">right</property>
|
||||
<property name="xalign">0.89999997615814209</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cardRarity">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Loading...</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="label" translatable="yes">Release:</property>
|
||||
<property name="justify">right</property>
|
||||
<property name="xalign">0.89999997615814209</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cardReleaseDate">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Loading...</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="label" translatable="yes">Edition:</property>
|
||||
<property name="justify">right</property>
|
||||
<property name="xalign">0.89999997615814209</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cardSet">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Loading...</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="label" translatable="yes">Other Printings:</property>
|
||||
<property name="justify">right</property>
|
||||
<property name="xalign">0.89999997615814209</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cardPrintings">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Loading...</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Legalities:</property>
|
||||
<property name="justify">right</property>
|
||||
<property name="xalign">0.89999997615814209</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="cardLegalities">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Loading...</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
157
cardvault/gui/mainwindow.glade
Normal file
@@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkWindow" id="mainWindow">
|
||||
<property name="name">Card Vault</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Card Vault</property>
|
||||
<property name="default_width">800</property>
|
||||
<property name="default_height">600</property>
|
||||
<property name="icon_name">application-x-executable</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkMenuBar" id="menuBar">
|
||||
<property name="name">menuBar</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="Main">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Main</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="mainMenu">
|
||||
<property name="name">mainMenu</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem">
|
||||
<property name="label">gtk-quit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="View">
|
||||
<property name="name">View</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_View</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="viewMenu">
|
||||
<property name="name">viewMenu</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="searchViewItem">
|
||||
<property name="name">search</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_as_radio">True</property>
|
||||
<signal name="activate" handler="on_view_changed" swapped="no"/>
|
||||
<accelerator key="1" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="libraryViewItem">
|
||||
<property name="name">library</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Library</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_as_radio">True</property>
|
||||
<property name="group">searchViewItem</property>
|
||||
<signal name="activate" handler="on_view_changed" swapped="no"/>
|
||||
<accelerator key="2" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="decksViewItem">
|
||||
<property name="name">decks</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Decks</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_as_radio">True</property>
|
||||
<property name="group">searchViewItem</property>
|
||||
<signal name="activate" handler="on_view_changed" swapped="no"/>
|
||||
<accelerator key="3" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="contentPage">
|
||||
<property name="name">contentPage</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar" id="statusBar">
|
||||
<property name="name">statusBar</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_start">10</property>
|
||||
<property name="margin_end">10</property>
|
||||
<property name="margin_top">6</property>
|
||||
<property name="margin_bottom">6</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
122
cardvault/gui/overlays.glade
Normal file
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkGrid" id="imageLoding">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="row_spacing">10</property>
|
||||
<property name="row_homogeneous">True</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="label" translatable="yes">Loading Image</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinner">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="active">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkGrid" id="pageNotFound">
|
||||
<property name="name">Not Found</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="row_spacing">10</property>
|
||||
<property name="row_homogeneous">True</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="pixel_size">100</property>
|
||||
<property name="icon_name">edit-find-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="label" translatable="yes">Page not found</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkGrid" id="searchOverlay">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="row_spacing">10</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="pixel_size">100</property>
|
||||
<property name="icon_name">edit-find-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="2"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="label" translatable="yes">Use the entry on the left to search for cards</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
313
cardvault/gui/search.glade
Normal file
@@ -0,0 +1,313 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkGrid" id="searchView">
|
||||
<property name="name">Search</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkOverlay" id="searchResults">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="leftPane">
|
||||
<property name="name">leftPane</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="searchBox">
|
||||
<property name="name">searchBox</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="searchEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="activate" handler="do_search_cards" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="searchButton">
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="do_search_cards" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="filterGrid">
|
||||
<property name="name">filterGrid</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="row_spacing">2</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Filters</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Mana Color</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="manaFilterGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="whiteManaButton">
|
||||
<property name="name">W</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="blueManaButton">
|
||||
<property name="name">U</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="redManaButton">
|
||||
<property name="name">R</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="greenManaButton">
|
||||
<property name="name">G</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="blackManaButton">
|
||||
<property name="name">B</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="clearManaFilterButton">
|
||||
<property name="label">gtk-clear</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="do_clear_mana_filter" object="manaFilterGrid" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Rarity</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="rarityCombo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="active_id">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Type</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="typeCombo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="active_id">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Edition</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="setEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="secondary_icon_stock">gtk-clear</property>
|
||||
<signal name="icon-press" handler="do_clear_set_filter" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="height">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="selectionToolsBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="addRemoveButton">
|
||||
<property name="label" translatable="yes">Add Card to Library</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<signal name="clicked" handler="do_add_remove_clicked" object="searchResults" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
60
cardvault/handlers.py
Normal file
@@ -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)
|
||||
|
||||
|
||||
20
cardvault/mtgsdk/__init__.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
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
|
||||
67
cardvault/mtgsdk/card.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
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()
|
||||
25
cardvault/mtgsdk/changelog.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
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()
|
||||
15
cardvault/mtgsdk/config.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
__version__ = "1.2.0"
|
||||
__pypi_packagename__ = "mtgsdk"
|
||||
__github_username__ = "MagicTheGathering"
|
||||
__github_reponame__ = "mtg-sdk-python"
|
||||
__endpoint__ = "https://api.magicthegathering.io/v1"
|
||||
100
cardvault/mtgsdk/querybuilder.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
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]
|
||||
47
cardvault/mtgsdk/restclient.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
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
|
||||
49
cardvault/mtgsdk/set.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
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)
|
||||
19
cardvault/mtgsdk/subtype.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
from mtgsdk.querybuilder import QueryBuilder
|
||||
|
||||
|
||||
class Subtype(object):
|
||||
RESOURCE = 'subtypes'
|
||||
|
||||
@staticmethod
|
||||
def all():
|
||||
return QueryBuilder(Subtype).array()
|
||||
19
cardvault/mtgsdk/supertype.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
from mtgsdk.querybuilder import QueryBuilder
|
||||
|
||||
|
||||
class Supertype(object):
|
||||
RESOURCE = 'supertypes'
|
||||
|
||||
@staticmethod
|
||||
def all():
|
||||
return QueryBuilder(Supertype).array()
|
||||
19
cardvault/mtgsdk/type.py
Normal file
@@ -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 <backes.andrew@gmail.com>
|
||||
|
||||
from mtgsdk.querybuilder import QueryBuilder
|
||||
|
||||
|
||||
class Type(object):
|
||||
RESOURCE = 'types'
|
||||
|
||||
@staticmethod
|
||||
def all():
|
||||
return QueryBuilder(Type).array()
|
||||
11
cardvault/network.py
Normal file
@@ -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
|
||||
BIN
cardvault/resources/images/demo.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
cardvault/resources/images/dummy.jpg
Normal file
|
After Width: | Height: | Size: 147 KiB |
BIN
cardvault/resources/images/dummy_315x450.png
Normal file
|
After Width: | Height: | Size: 225 KiB |
BIN
cardvault/resources/mana/0.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
cardvault/resources/mana/1.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
cardvault/resources/mana/10.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
cardvault/resources/mana/11.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
cardvault/resources/mana/12.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
cardvault/resources/mana/13.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
cardvault/resources/mana/14.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
cardvault/resources/mana/15.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
cardvault/resources/mana/16.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
cardvault/resources/mana/17.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
cardvault/resources/mana/18.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
cardvault/resources/mana/19.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
cardvault/resources/mana/2.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
cardvault/resources/mana/20.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
cardvault/resources/mana/2b.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
cardvault/resources/mana/2g.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
cardvault/resources/mana/2r.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
cardvault/resources/mana/2u.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
cardvault/resources/mana/2w.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
cardvault/resources/mana/3.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
cardvault/resources/mana/4.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
cardvault/resources/mana/5.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
cardvault/resources/mana/6.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
cardvault/resources/mana/7.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
cardvault/resources/mana/8.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
cardvault/resources/mana/9.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
cardvault/resources/mana/B.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
cardvault/resources/mana/BG.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
cardvault/resources/mana/BP.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
cardvault/resources/mana/BR.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
cardvault/resources/mana/B_alt.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
cardvault/resources/mana/C.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
cardvault/resources/mana/C_alt.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
cardvault/resources/mana/G.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
cardvault/resources/mana/GP.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
cardvault/resources/mana/GU.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
cardvault/resources/mana/GW.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
cardvault/resources/mana/G_alt.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
cardvault/resources/mana/R.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
cardvault/resources/mana/RG.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
cardvault/resources/mana/RP.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
cardvault/resources/mana/RW.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
cardvault/resources/mana/R_alt.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
cardvault/resources/mana/S.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
cardvault/resources/mana/T.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
cardvault/resources/mana/U.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
cardvault/resources/mana/UB.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
cardvault/resources/mana/UP.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
cardvault/resources/mana/UR.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
cardvault/resources/mana/U_alt.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
cardvault/resources/mana/W.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
cardvault/resources/mana/WB.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
cardvault/resources/mana/WP.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
cardvault/resources/mana/WU.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
cardvault/resources/mana/W_alt.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
cardvault/resources/mana/X.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
cardvault/resources/mana/Y.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
cardvault/resources/mana/Z.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
cardvault/resources/mana/flip.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
cardvault/resources/mana/half.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
cardvault/resources/mana/infinite.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
cardvault/resources/mana/tap_old.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
cardvault/resources/mana/untap.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
135
cardvault/search_funct.py
Normal file
@@ -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)
|
||||
273
cardvault/util.py
Normal file
@@ -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
|
||||
61
cardvault/window.py
Normal file
@@ -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()
|
||||