Mercurial > traipse_dev
view orpg/mapper/images.py @ 76:37a11fea3304 ornery-dev
More clean up. Images now posts a Chat Info post if image doesn't load.
author | sirebral |
---|---|
date | Sat, 22 Aug 2009 04:02:14 -0500 |
parents | 449a8900f9ac |
children | 6226a5f9a4b3 |
line wrap: on
line source
# Copyright (C) 2000-2001 The OpenRPG Project # # openrpg-dev@lists.sourceforge.net # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -- # # File: mapper/images.py # Author: OpenRPG # Maintainer: # Version: # $Id: images.py,v 1.21 2007/12/11 04:07:15 digitalxero Exp $ # # Description: # __version__ = "$Id: images.py,v 1.21 2007/12/11 04:07:15 digitalxero Exp $" import urllib import Queue import thread from threading import Lock import time from orpg.orpg_wx import * from orpg.orpgCore import component from orpg.dirpath import dir_struct from orpg.tools.orpg_log import logger def singleton(cls): instances = {} def getinstance(): if cls not in instances: instances[cls] = cls() return instances[cls] return getinstance() class ImageHandlerClass(object): __cache = {} __fetching = {} __queue = Queue.Queue(0) __lock = Lock() chat = component.get("chat") def load(self, path, image_type, imageId): """Load an image, with a intermideary fetching image shown while it loads in a background thread""" if self.__cache.has_key(path): return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2]).ConvertToBitmap() if not self.__fetching.has_key(path): self.__fetching[path] = True """Start Image Loading Thread""" thread.start_new_thread(self.__loadThread, (path, image_type, imageId)) else: if self.__fetching[path] is True: thread.start_new_thread(self.__loadCacheThread, (path, image_type, imageId)) return wx.Bitmap(dir_struct["icon"] + "fetching.png", wx.BITMAP_TYPE_PNG) def directLoad(self, path): """Directly load an image, no threads""" if self.__cache.has_key(path): return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2]).ConvertToBitmap() uriPath = urllib.unquote(path) try: d = urllib.urlretrieve(uriPath) """We have to make sure that not only did we fetch something, but that it was an image that we got back.""" if d[0] and d[1].getmaintype() == "image": self.__cache[path] = (path, d[0], d[1].gettype(), None) return wx.ImageFromMime(self.__cache[path][1], self.__cache[path][2]).ConvertToBitmap() else: logger.general("Image refused to load or URI did not reference a valid image: " + path) component.get('chat').InfoPost("<font color='#FF0000'>Image refused to load or URI did not reference a valid image: " + path + "</font>") return None except IOError: logger.general("Unable to resolve/open the specified URI; image was NOT loaded: " + path) component.get('chat').InfoPost("<font color='#FF0000'>Unable to resolve/open the specified URI; image was NOT loaded: " + path + "</font>") return None def cleanCache(self): """Shrinks the Cache down to the proper size""" try: cacheSize = int(component.get('settings').get_setting("ImageCacheSize")) except: cacheSize = 32 cache = self.__cache.keys() cache.sort() for key in cache[cacheSize:]: del self.__cache[key] def flushCache(self): """This function will flush all images contained within the image cache.""" self.__lock.acquire() try: keyList = self.__cache.keys() for key in keyList: del self.__cache[key] finally: self.__lock.release() urllib.urlcleanup() """Private Methods""" def __loadThread(self, path, image_type, imageId): uriPath = urllib.unquote(path) self.__lock.acquire() try: d = urllib.urlretrieve(uriPath) """We have to make sure that not only did we fetch something, but that it was an image that we got back.""" if d[0] and d[1].getmaintype() == "image": self.__cache[path] = (path, d[0], d[1].gettype(), imageId) self.__queue.put((self.__cache[path], image_type, imageId)) if self.__fetching.has_key(path): self.__fetching[path] = False #Fix for failed multi-load? else: logger.general("Image refused to load or URI did not reference a valid image: " + path) component.get('chat').InfoPost("<font color='#FF0000'>Image refused to load or URI did not reference a valid image: " + path +"</font>") del self.__fetching[path] except IOError: del self.__fetching[path] logger.general("Unable to resolve/open the specified URI; image was NOT loaded: " + path) component.get('chat').InfoPost("<font color='#FF0000'> Unable to resolve/open the specified URI; image was NOT loaded: " + path + "</font>") finally: self.__lock.release() def __loadCacheThread(self, path, image_type, imageId): if self.__cache.has_key(path): try: st = time.time() while self.__fetching.has_key(path) and self.__fetching[path] is not False: time.sleep(0.025) if (time.time()-st) > 120: logger.general("Timeout: " + path) break except: del self.__fetching[path] logger.general("Unable to resolve/open the specified URI; image was NOT loaded: " + path) component.get('chat').InfoPost("<font color='#FF0000'>Unable to resolve/open the specified URI; image was NOT loaded: " + path + "</font>") return self.__lock.acquire() try: logger.debug("Adding Image to Queue from Cache: " + str(self.__cache[path])) component.debug('chat').InfoPost("<font color='#FF0000'>Adding Image to Queue from Cache: " + str(self.__cache[path]) + "</font>) self.__queue.put((self.__cache[path], image_type, imageId)) finally: self.__lock.release() """Property Methods""" def _getCache(self): return self.__cache def _getQueue(self): return self.__queue """Properties""" Cache = property(_getCache) Queue = property(_getQueue) ImageHandler = singleton(ImageHandlerClass)