<s> from __future__ import absolute_import , print_function , unicode_literals , division <EOL> from collections import defaultdict <EOL> from io import BytesIO <EOL> import os <EOL> import sys <EOL> try : <EOL> unicode <EOL> except NameError : <EOL> basestring = unicode = str <EOL> if sys . version_info [ <NUM_LIT:0> ] < <NUM_LIT:3> : <EOL> from urllib2 import urlopen <EOL> from urlparse import urlparse <EOL> else : <EOL> from urllib . request import urlopen <EOL> from urllib . parse import urlparse <EOL> import re <EOL> import time <EOL> from sc2reader import utils <EOL> from sc2reader import log_utils <EOL> from sc2reader . resources import Resource , Replay , Map , GameSummary , Localization <EOL> @ log_utils . loggable <EOL> class SC2Factory ( object ) : <EOL> """<STR_LIT>""" <EOL> _resource_name_map = dict ( replay = Replay , map = Map ) <EOL> default_options = { <EOL> Resource : { '<STR_LIT>' : False } , <EOL> Replay : { '<STR_LIT>' : <NUM_LIT:4> , '<STR_LIT>' : False } , <EOL> } <EOL> def __init__ ( self , ** options ) : <EOL> self . plugins = list ( ) <EOL> self . options = defaultdict ( dict ) <EOL> for cls , options in self . default_options . items ( ) : <EOL> self . options [ cls ] = options . copy ( ) <EOL> self . configure ( ** options ) <EOL> def load_replay ( self , source , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> return self . load ( Replay , source , options , ** new_options ) <EOL> def load_replays ( self , sources , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> return self . load_all ( Replay , sources , options , extension = '<STR_LIT>' , ** new_options ) <EOL> def load_localization ( self , source , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> return self . load ( Localization , source , options , ** new_options ) <EOL> def load_localizations ( self , sources , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> return self . load_all ( Localization , sources , options , extension = '<STR_LIT>' , ** new_options ) <EOL> def load_map ( self , source , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> return self . load ( Map , source , options , ** new_options ) <EOL> def load_maps ( self , sources , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> return self . load_all ( Map , sources , options , extension = '<STR_LIT>' , ** new_options ) <EOL> def load_game_summary ( self , source , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> return self . load ( GameSummary , source , options , ** new_options ) <EOL> def load_game_summaries ( self , sources , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> return self . load_all ( GameSummary , sources , options , extension = '<STR_LIT>' , ** new_options ) <EOL> def configure ( self , cls = None , ** options ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( cls , basestring ) : <EOL> cls = self . _resource_name_map . get [ cls . lower ( ) ] <EOL> cls = cls or Resource <EOL> self . options [ cls ] . update ( options ) <EOL> def reset ( self ) : <EOL> "<STR_LIT>" <EOL> self . options = defaultdict ( dict ) <EOL> def register_plugin ( self , cls , plugin ) : <EOL> "<STR_LIT>" <EOL> if isinstance ( cls , basestring ) : <EOL> cls = self . _resource_name_map . get ( cls . lower ( ) , Resource ) <EOL> self . plugins . append ( ( cls , plugin ) ) <EOL> def load ( self , cls , source , options = None , ** new_options ) : <EOL> options = options or self . _get_options ( cls , ** new_options ) <EOL> resource , filename = self . _load_resource ( source , options = options ) <EOL> return self . _load ( cls , resource , filename = filename , options = options ) <EOL> def load_all ( self , cls , sources , options = None , ** new_options ) : <EOL> options = options or self . _get_options ( cls , ** new_options ) <EOL> for resource , filename in self . _load_resources ( sources , options = options ) : <EOL> yield self . _load ( cls , resource , filename = filename , options = options ) <EOL> def _load ( self , cls , resource , filename , options ) : <EOL> obj = cls ( resource , filename = filename , factory = self , ** options ) <EOL> for plugin in options . get ( '<STR_LIT>' , self . _get_plugins ( cls ) ) : <EOL> obj = plugin ( obj ) <EOL> return obj <EOL> def _get_plugins ( self , cls ) : <EOL> plugins = list ( ) <EOL> for ext_cls , plugin in self . plugins : <EOL> if issubclass ( cls , ext_cls ) : <EOL> plugins . append ( plugin ) <EOL> return plugins <EOL> def _get_options ( self , cls , ** new_options ) : <EOL> options = dict ( ) <EOL> for opt_cls , cls_options in self . options . items ( ) : <EOL> if issubclass ( cls , opt_cls ) : <EOL> options . update ( cls_options ) <EOL> options . update ( new_options ) <EOL> return options <EOL> def _load_resources ( self , resources , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> options = options or self . _get_options ( Resource , ** new_options ) <EOL> if isinstance ( resources , basestring ) : <EOL> resources = utils . get_files ( resources , ** options ) <EOL> for resource in resources : <EOL> yield self . _load_resource ( resource , options = options ) <EOL> def load_remote_resource_contents ( self , resource , ** options ) : <EOL> self . logger . info ( "<STR_LIT>" + resource ) <EOL> return urlopen ( resource ) . read ( ) <EOL> def load_local_resource_contents ( self , location , ** options ) : <EOL> with open ( location , '<STR_LIT:rb>' ) as resource_file : <EOL> return resource_file . read ( ) <EOL> def _load_resource ( self , resource , options = None , ** new_options ) : <EOL> """<STR_LIT>""" <EOL> options = options or self . _get_options ( Resource , ** new_options ) <EOL> if isinstance ( resource , utils . DepotFile ) : <EOL> resource = resource . url <EOL> if isinstance ( resource , basestring ) : <EOL> if re . match ( r'<STR_LIT>' , resource ) : <EOL> contents = self . load_remote_resource_contents ( resource , ** options ) <EOL> else : <EOL> directory = options . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> location = os . path . join ( directory , resource ) <EOL> contents = self . load_local_resource_contents ( location , ** options ) <EOL> resource_name = resource <EOL> resource = BytesIO ( contents ) <EOL> else : <EOL> if not hasattr ( resource , '<STR_LIT>' ) : <EOL> resource = BytesIO ( resource . read ( ) ) <EOL> resource_name = getattr ( resource , '<STR_LIT:name>' , '<STR_LIT>' ) <EOL> if options . get ( '<STR_LIT>' , None ) : <EOL> print ( resource_name ) <EOL> return ( resource , resource_name ) <EOL> class CachedSC2Factory ( SC2Factory ) : <EOL> def get_remote_cache_key ( self , remote_resource ) : <EOL> parseresult = urlparse ( remote_resource ) <EOL> bucket = re . sub ( r'<STR_LIT>' , '<STR_LIT>' , parseresult . netloc ) <EOL> key = parseresult . path . strip ( '<STR_LIT:/>' ) <EOL> return ( bucket , key ) <EOL> def load_remote_resource_contents ( self , remote_resource , ** options ) : <EOL> cache_key = self . get_remote_cache_key ( remote_resource ) <EOL> if not self . cache_has ( cache_key ) : <EOL> resource = super ( CachedSC2Factory , self ) . load_remote_resource_contents ( remote_resource , ** options ) <EOL> self . cache_set ( cache_key , resource ) <EOL> else : <EOL> resource = self . cache_get ( cache_key ) <EOL> return resource <EOL> def cache_has ( self , cache_key ) : <EOL> raise NotImplemented ( ) <EOL> def cache_get ( self , cache_key ) : <EOL> raise NotImplemented ( ) <EOL> def cache_set ( self , cache_key , value ) : <EOL> raise NotImplemented ( ) <EOL> class FileCachedSC2Factory ( CachedSC2Factory ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , cache_dir , ** options ) : <EOL> super ( FileCachedSC2Factory , self ) . __init__ ( ** options ) <EOL> self . cache_dir = os . path . abspath ( cache_dir ) <EOL> if not os . path . isdir ( self . cache_dir ) : <EOL> raise ValueError ( "<STR_LIT>" . format ( self . cache_dir ) ) <EOL> elif not os . access ( self . cache_dir , os . F_OK | os . W_OK | os . R_OK ) : <EOL> raise ValueError ( "<STR_LIT>" . format ( self . cache_dir ) ) <EOL> def cache_has ( self , cache_key ) : <EOL> return os . path . exists ( self . cache_path ( cache_key ) ) <EOL> def cache_get ( self , cache_key , ** options ) : <EOL> return self . load_local_resource_contents ( self . cache_path ( cache_key ) , ** options ) <EOL> def cache_set ( self , cache_key , value ) : <EOL> cache_path = self . cache_path ( cache_key ) <EOL> bucket_dir = os . path . dirname ( cache_path ) <EOL> if not os . path . exists ( bucket_dir ) : <EOL> os . makedirs ( bucket_dir ) <EOL> with open ( cache_path , '<STR_LIT:wb>' ) as out : <EOL> out . write ( value ) <EOL> def cache_path ( self , cache_key ) : <EOL> return os . path . join ( self . cache_dir , * ( cache_key ) ) <EOL> class DictCachedSC2Factory ( CachedSC2Factory ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , cache_max_size = <NUM_LIT:0> , ** options ) : <EOL> super ( DictCachedSC2Factory , self ) . __init__ ( ** options ) <EOL> self . cache_dict = dict ( ) <EOL> self . cache_used = dict ( ) <EOL> self . cache_max_size = cache_max_size <EOL> def cache_set ( self , cache_key , value ) : <EOL> if self . cache_max_size and len ( self . cache_dict ) >= self . cache_max_size : <EOL> oldest_cache_key = min ( self . cache_used . items ( ) , key = lambda e : e [ <NUM_LIT:1> ] ) [ <NUM_LIT:0> ] <EOL> del self . cache_used [ oldest_cache_key ] <EOL> del self . cache_dict [ oldest_cache_key ] <EOL> self . cache_dict [ cache_key ] = value <EOL> self . cache_used [ cache_key ] = time . time ( ) <EOL> def cache_get ( self , cache_key ) : <EOL> self . cache_used [ cache_key ] = time . time ( ) <EOL> return self . cache_dict [ cache_key ] <EOL> def cache_has ( self , cache_key ) : <EOL> return cache_key in self . cache_dict <EOL> class DoubleCachedSC2Factory ( DictCachedSC2Factory , FileCachedSC2Factory ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , cache_dir , cache_max_size = <NUM_LIT:0> , ** options ) : <EOL> super ( DoubleCachedSC2Factory , self ) . __init__ ( cache_max_size , cache_dir = cache_dir , ** options ) <EOL> def load_remote_resource_contents ( self , remote_resource , ** options ) : <EOL> cache_key = self . get_remote_cache_key ( remote_resource ) <EOL> if DictCachedSC2Factory . cache_has ( self , cache_key ) : <EOL> return DictCachedSC2Factory . cache_get ( self , cache_key ) <EOL> if not FileCachedSC2Factory . cache_has ( self , cache_key ) : <EOL> resource = SC2Factory . load_remote_resource_contents ( self , remote_resource , ** options ) <EOL> FileCachedSC2Factory . cache_set ( self , cache_key , resource ) <EOL> else : <EOL> resource = FileCachedSC2Factory . cache_get ( self , cache_key ) <EOL> DictCachedSC2Factory . cache_set ( self , cache_key , resource ) <EOL> return resource </s>
