1#!/usr/bin/env python 2# -*- mode: python; coding: utf-8; -*- 3# ---------------------------------------------------------------------------## 4# 5# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer 6# Copyright (C) 2003 Mt. Hood Playing Card Co. 7# Copyright (C) 2005-2009 Skomoroh 8# 9# This program is free software: you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation, either version 3 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with this program. If not, see <http://www.gnu.org/licenses/>. 21# 22# ---------------------------------------------------------------------------## 23 24# imports 25import os 26try: 27 import site 28except Exception: 29 class Dummy: 30 def __init__(self): 31 self.PREFIXES = [] 32 site = Dummy() 33import sys 34 35# PySol imports 36from pysollib.mfxutil import Image 37from pysollib.mygettext import _ 38from pysollib.settings import DATA_DIRS, TOOLKIT 39 40# ************************************************************************ 41# * constants 42# ************************************************************************ 43 44# Suits values are 0-3. This maps to colors 0-1. 45SUITS = (_("Club"), _("Spade"), _("Heart"), _("Diamond")) 46SUITS_PL = (_("Clubs"), _("Spades"), _("Hearts"), _("Diamonds")) 47COLORS = (_("black"), _("red")) 48 49# Specific suits 50CLUB = 0 51SPADE = 1 52HEART = 2 53DIAMOND = 3 54 55# Card ranks are 0-12. We also define symbolic names for the picture cards. 56RANKS = (_("Ace"), "2", "3", "4", "5", "6", "7", "8", "9", "10", 57 _("Jack"), _("Queen"), _("King")) 58ACE = 0 59JACK = 10 60QUEEN = 11 61KING = 12 62 63# Special values for Stack.cap: 64ANY_SUIT = -1 65ANY_COLOR = -1 66ANY_RANK = -1 67NO_SUIT = 999999 # no card can ever match this suit 68NO_COLOR = 999999 # no card can ever match this color 69NO_RANK = 999999 # no card can ever match this rank 70UNLIMITED_MOVES = 999999 # for max_move 71UNLIMITED_ACCEPTS = 999999 # for max_accept 72UNLIMITED_CARDS = 999999 # for max_cards 73# 74NO_REDEAL = 0 75UNLIMITED_REDEALS = -1 76VARIABLE_REDEALS = -2 77 78CARDSET = _("cardset") 79 80IMAGE_EXTENSIONS = (".gif", ".ppm", ".png") 81if 1 and os.name == "nt": 82 IMAGE_EXTENSIONS = (".png", ".gif", ".ppm", ".jpg",) 83 pass 84 85if Image: 86 IMAGE_EXTENSIONS = (".png", ".gif", ".jpg", ".ppm", ".bmp") 87 88if TOOLKIT == 'kivy': 89 IMAGE_EXTENSIONS = (".png", ".bmp", ".ppm", ".jpg", ".tiff") 90 91# ************************************************************************ 92# * DataLoader 93# ************************************************************************ 94 95 96class DataLoader: 97 def __init__(self, argv0, filenames, path=[]): 98 self.dir = None 99 if isinstance(filenames, str): 100 filenames = (filenames,) 101 assert isinstance(filenames, (tuple, list)) 102 # init path 103 path = path[:] 104 head, tail = os.path.split(argv0) 105 if not head: 106 head = os.curdir 107 # dir where placed startup script 108 path.append(head) 109 path.append(os.path.join(head, "data")) 110 path.append(os.path.join(head, os.pardir, "data")) 111 # dir where placed pysol package 112 path.append(os.path.join(sys.path[0], "data")) 113 path.append(os.path.join(sys.path[0], "pysollib", "data")) 114 # from settings.py 115 path.extend(DATA_DIRS) 116 # py2app compatibility, see 117 # https://github.com/shlomif/PySolFC/issues/100 118 _prefixes = [] 119 try: 120 _prefixes = site.PREFIXES 121 except Exception: 122 _prefixes = [] 123 # itz 2018-10-21 in case of venv installation 124 # (or even homedir installation), path[0] will be quite wrong. 125 # Just directly use the location where setup.py puts the data. 126 for pref in _prefixes: 127 path.append(os.path.join(pref, 'share', 'PySolFC')) 128 # check path for valid directories 129 self.path = [] 130 for p in path: 131 if not p: 132 continue 133 np = os.path.abspath(p) 134 if np and (np not in self.path) and os.path.isdir(np): 135 self.path.append(np) 136 # now try to find all filenames along path 137 for p in self.path: 138 if all(os.path.isfile(os.path.join(p, fn)) for fn in filenames): 139 self.dir = p 140 break 141 else: 142 raise OSError(str(argv0)+": DataLoader could not find " + 143 str(filenames)) 144 145 def __findFile(self, func, filename, subdirs=None, do_raise=1): 146 if subdirs is None: 147 subdirs = ("",) 148 elif isinstance(subdirs, str): 149 subdirs = (subdirs,) 150 for dir in subdirs: 151 f = os.path.join(self.dir, dir, filename) 152 f = os.path.normpath(f) 153 if func(f): 154 return f 155 if do_raise: 156 raise OSError("DataLoader could not find "+filename+" in " + 157 self.dir+" "+str(subdirs)) 158 return None 159 160 def findFile(self, filename, subdirs=None): 161 return self.__findFile(os.path.isfile, filename, subdirs) 162 163 def findImage(self, filename, subdirs=None): 164 for ext in IMAGE_EXTENSIONS: 165 f = self.__findFile(os.path.isfile, filename+ext, subdirs, 0) 166 if f: 167 return f 168 raise OSError("DataLoader could not find image "+filename + 169 " in "+self.dir+" "+str(subdirs)) 170 171 def findAllIconSizes(self, filename='pysol.png'): 172 try: 173 icondir = self.findDir(os.path.join('images', 'icons')) 174 icons = [os.path.join(icondir, subdir, filename) for subdir in 175 os.listdir(icondir)] 176 except OSError: 177 try: 178 # pysol06.png is known to have transparent borders around it 179 # which is unsuitable for a window icon 180 icon_blacklist = ('pysol06.png',) 181 miscdir = self.findDir(os.path.join('images', 'misc')) 182 icons = [os.path.join(miscdir, f) for f in os.listdir(miscdir) 183 if f not in icon_blacklist] 184 except OSError: 185 icons = [] 186 return filter(os.path.isfile, icons) 187 188 def findDir(self, filename, subdirs=None): 189 return self.__findFile(os.path.isdir, filename, subdirs) 190