<s> import os <EOL> import re <EOL> import uuid <EOL> import copy <EOL> from functools import update_wrapper <EOL> import jinja2 <EOL> from babel import dates <EOL> from inifile import IniFile <EOL> from lektor . utils import tojson_filter , secure_url , format_lat_long , bool_from_string <EOL> from lektor . i18n import get_i18n_block <EOL> from lektor . context import url_to , get_asset_url , site_proxy , config_proxy , get_ctx , get_locale <EOL> from lektor . pluginsystem import PluginController <EOL> PRIMARY_ALT = '<STR_LIT>' <EOL> DEFAULT_CONFIG = { <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : <NUM_LIT> , <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : '<STR_LIT:image>' , <EOL> '<STR_LIT>' : '<STR_LIT:image>' , <EOL> '<STR_LIT>' : '<STR_LIT:image>' , <EOL> '<STR_LIT>' : '<STR_LIT:image>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT:text>' , <EOL> '<STR_LIT>' : '<STR_LIT:text>' , <EOL> } , <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT:name>' : None , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:url>' : None , <EOL> } , <EOL> '<STR_LIT>' : { } , <EOL> '<STR_LIT>' : { } , <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : { } , <EOL> } <EOL> def _pass_locale ( func ) : <EOL> def new_func ( * args , ** kwargs ) : <EOL> if kwargs . get ( '<STR_LIT>' , None ) is None : <EOL> kwargs [ '<STR_LIT>' ] = get_locale ( '<STR_LIT>' ) <EOL> return func ( * args , ** kwargs ) <EOL> return update_wrapper ( new_func , func ) <EOL> def update_config_from_ini ( config , inifile ) : <EOL> def set_simple ( target , source_path ) : <EOL> rv = config . get ( source_path ) <EOL> if rv is not None : <EOL> config [ target ] = rv <EOL> set_simple ( target = '<STR_LIT>' , <EOL> source_path = '<STR_LIT>' ) <EOL> set_simple ( target = '<STR_LIT>' , <EOL> source_path = '<STR_LIT>' ) <EOL> config [ '<STR_LIT>' ] . update ( <EOL> ( k . encode ( '<STR_LIT:ascii>' , '<STR_LIT:replace>' ) , v . encode ( '<STR_LIT:ascii>' , '<STR_LIT:replace>' ) ) <EOL> for k , v in inifile . section_as_dict ( '<STR_LIT>' ) ) <EOL> config [ '<STR_LIT>' ] . update ( inifile . section_as_dict ( '<STR_LIT>' ) ) <EOL> config [ '<STR_LIT>' ] . update ( inifile . section_as_dict ( '<STR_LIT>' ) ) <EOL> for sect in inifile . sections ( ) : <EOL> if sect . startswith ( '<STR_LIT>' ) : <EOL> server_id = sect . split ( '<STR_LIT:.>' ) [ <NUM_LIT:1> ] <EOL> config [ '<STR_LIT>' ] [ server_id ] = inifile . section_as_dict ( sect ) <EOL> elif sect . startswith ( '<STR_LIT>' ) : <EOL> alt = sect . split ( '<STR_LIT:.>' ) [ <NUM_LIT:1> ] <EOL> config [ '<STR_LIT>' ] [ alt ] = { <EOL> '<STR_LIT:name>' : get_i18n_block ( inifile , '<STR_LIT>' % alt ) , <EOL> '<STR_LIT>' : inifile . get ( '<STR_LIT>' % alt ) , <EOL> '<STR_LIT>' : inifile . get ( '<STR_LIT>' % alt ) , <EOL> '<STR_LIT>' : inifile . get_bool ( '<STR_LIT>' % alt ) , <EOL> '<STR_LIT>' : inifile . get ( '<STR_LIT>' % alt , '<STR_LIT>' ) , <EOL> } <EOL> for alt , alt_data in config [ '<STR_LIT>' ] . iteritems ( ) : <EOL> if alt_data [ '<STR_LIT>' ] : <EOL> config [ '<STR_LIT>' ] = alt <EOL> break <EOL> else : <EOL> if config [ '<STR_LIT>' ] : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> IGNORED_FILES = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> SPECIAL_ARTIFACTS = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> class ServerInfo ( object ) : <EOL> def __init__ ( self , id , name_i18n , target , enabled = True , default = False ) : <EOL> self . id = id <EOL> self . name_i18n = name_i18n <EOL> self . target = target <EOL> self . enabled = enabled <EOL> self . default = default <EOL> @ property <EOL> def name ( self ) : <EOL> return self . name_i18n . get ( '<STR_LIT>' ) or self . id <EOL> @ property <EOL> def short_target ( self ) : <EOL> match = re . match ( r'<STR_LIT>' , self . target ) <EOL> if match is not None : <EOL> protocol , server = match . groups ( ) <EOL> return '<STR_LIT>' % ( server , protocol ) <EOL> return self . target <EOL> def to_json ( self ) : <EOL> return { <EOL> '<STR_LIT:id>' : self . id , <EOL> '<STR_LIT:name>' : self . name , <EOL> '<STR_LIT>' : self . name_i18n , <EOL> '<STR_LIT:target>' : self . target , <EOL> '<STR_LIT>' : self . short_target , <EOL> '<STR_LIT>' : self . enabled , <EOL> '<STR_LIT:default>' : self . default , <EOL> } <EOL> class Expression ( object ) : <EOL> def __init__ ( self , env , expr ) : <EOL> self . env = env <EOL> self . tmpl = env . jinja_env . from_string ( '<STR_LIT>' % expr ) <EOL> def evaluate ( self , pad = None , this = None , values = None , alt = None ) : <EOL> result = [ ] <EOL> def result_func ( value ) : <EOL> result . append ( value ) <EOL> return u'<STR_LIT>' <EOL> values = self . env . make_default_tmpl_values ( pad , this , values , alt ) <EOL> values [ '<STR_LIT>' ] = result_func <EOL> self . tmpl . render ( values ) <EOL> return result [ <NUM_LIT:0> ] <EOL> class FormatExpression ( object ) : <EOL> def __init__ ( self , env , expr ) : <EOL> self . env = env <EOL> self . tmpl = env . jinja_env . from_string ( expr ) <EOL> def evaluate ( self , pad = None , this = None , values = None , alt = None ) : <EOL> values = self . env . make_default_tmpl_values ( pad , this , values , alt ) <EOL> return self . tmpl . render ( values ) <EOL> class CustomJinjaEnvironment ( jinja2 . Environment ) : <EOL> def _load_template ( self , name , globals ) : <EOL> rv = jinja2 . Environment . _load_template ( self , name , globals ) <EOL> ctx = get_ctx ( ) <EOL> if ctx is not None : <EOL> ctx . record_dependency ( rv . filename ) <EOL> return rv <EOL> class Config ( object ) : <EOL> def __init__ ( self , filename = None ) : <EOL> self . filename = filename <EOL> self . values = copy . deepcopy ( DEFAULT_CONFIG ) <EOL> if filename is not None and os . path . isfile ( filename ) : <EOL> inifile = IniFile ( filename ) <EOL> update_config_from_ini ( self . values , inifile ) <EOL> def __getitem__ ( self , name ) : <EOL> return self . values [ name ] <EOL> @ property <EOL> def site_locale ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . values [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> def get_servers ( self , public = False ) : <EOL> """<STR_LIT>""" <EOL> rv = { } <EOL> for server in self . values [ '<STR_LIT>' ] : <EOL> server_info = self . get_server ( server , public = public ) <EOL> if server_info is None : <EOL> continue <EOL> rv [ server ] = server_info <EOL> return rv <EOL> def get_default_server ( self , public = False ) : <EOL> """<STR_LIT>""" <EOL> choices = [ ] <EOL> for server in self . values [ '<STR_LIT>' ] : <EOL> server_info = self . get_server ( server , public = public ) <EOL> if server_info is not None : <EOL> if server_info . default : <EOL> return server_info <EOL> choices . append ( server_info ) <EOL> if len ( choices ) == <NUM_LIT:1> : <EOL> return choices [ <NUM_LIT:0> ] <EOL> def get_server ( self , name , public = False ) : <EOL> """<STR_LIT>""" <EOL> info = self . values [ '<STR_LIT>' ] . get ( name ) <EOL> if info is None : <EOL> return None <EOL> target = info . get ( '<STR_LIT:target>' ) <EOL> if target is None : <EOL> return None <EOL> if public : <EOL> target = secure_url ( target ) <EOL> return ServerInfo ( <EOL> id = name , <EOL> name_i18n = get_i18n_block ( info , '<STR_LIT:name>' ) , <EOL> target = target , <EOL> enabled = bool_from_string ( info . get ( '<STR_LIT>' ) , True ) , <EOL> default = bool_from_string ( info . get ( '<STR_LIT:default>' ) , False ) <EOL> ) <EOL> def is_valid_alternative ( self , alt ) : <EOL> """<STR_LIT>""" <EOL> if alt == PRIMARY_ALT : <EOL> return True <EOL> return alt in self . values [ '<STR_LIT>' ] <EOL> def list_alternatives ( self ) : <EOL> """<STR_LIT>""" <EOL> return sorted ( self . values [ '<STR_LIT>' ] ) <EOL> def iter_alternatives ( self ) : <EOL> """<STR_LIT>""" <EOL> found = False <EOL> for alt in self . values [ '<STR_LIT>' ] : <EOL> if alt != PRIMARY_ALT : <EOL> yield alt <EOL> found = True <EOL> if not found : <EOL> yield PRIMARY_ALT <EOL> def get_alternative ( self , alt ) : <EOL> """<STR_LIT>""" <EOL> if alt == PRIMARY_ALT : <EOL> alt = self . primary_alternative <EOL> return self . values [ '<STR_LIT>' ] . get ( alt ) <EOL> def get_alternative_url_prefixes ( self ) : <EOL> """<STR_LIT>""" <EOL> items = [ ( v [ '<STR_LIT>' ] . lstrip ( '<STR_LIT:/>' ) , k ) <EOL> for k , v in self . values [ '<STR_LIT>' ] . iteritems ( ) <EOL> if v [ '<STR_LIT>' ] ] <EOL> items . sort ( key = lambda x : - len ( x [ <NUM_LIT:0> ] ) ) <EOL> return items <EOL> def get_alternative_url_suffixes ( self ) : <EOL> """<STR_LIT>""" <EOL> items = [ ( v [ '<STR_LIT>' ] . rstrip ( '<STR_LIT:/>' ) , k ) <EOL> for k , v in self . values [ '<STR_LIT>' ] . iteritems ( ) <EOL> if v [ '<STR_LIT>' ] ] <EOL> items . sort ( key = lambda x : - len ( x [ <NUM_LIT:0> ] ) ) <EOL> return items <EOL> def get_alternative_url_span ( self , alt = PRIMARY_ALT ) : <EOL> """<STR_LIT>""" <EOL> if alt == PRIMARY_ALT : <EOL> alt = self . primary_alternative <EOL> cfg = self . values [ '<STR_LIT>' ] . get ( alt ) <EOL> if cfg is not None : <EOL> return cfg [ '<STR_LIT>' ] or '<STR_LIT>' , cfg [ '<STR_LIT>' ] or '<STR_LIT>' <EOL> return '<STR_LIT>' , '<STR_LIT>' <EOL> @ property <EOL> def primary_alternative_is_rooted ( self ) : <EOL> """<STR_LIT>""" <EOL> primary = self . primary_alternative <EOL> if primary is None : <EOL> return True <EOL> cfg = self . values [ '<STR_LIT>' ] . get ( primary ) <EOL> if not ( cfg [ '<STR_LIT>' ] or '<STR_LIT>' ) . lstrip ( '<STR_LIT:/>' ) and not ( cfg [ '<STR_LIT>' ] or '<STR_LIT>' ) . rstrip ( '<STR_LIT:/>' ) : <EOL> return True <EOL> return False <EOL> @ property <EOL> def primary_alternative ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . values [ '<STR_LIT>' ] <EOL> def lookup_from_bag ( * args ) : <EOL> pieces = '<STR_LIT:.>' . join ( x for x in args if x ) <EOL> return site_proxy . databags . lookup ( pieces ) <EOL> class Environment ( object ) : <EOL> def __init__ ( self , project , load_plugins = True ) : <EOL> self . project = project <EOL> self . root_path = os . path . abspath ( project . tree ) <EOL> self . jinja_env = CustomJinjaEnvironment ( <EOL> autoescape = self . select_jinja_autoescape , <EOL> extensions = [ '<STR_LIT>' , '<STR_LIT>' ] , <EOL> loader = jinja2 . FileSystemLoader ( <EOL> os . path . join ( self . root_path , '<STR_LIT>' ) ) <EOL> ) <EOL> from lektor . db import F <EOL> self . jinja_env . filters . update ( <EOL> tojson = tojson_filter , <EOL> latformat = lambda x , secs = True : format_lat_long ( lat = x , secs = secs ) , <EOL> longformat = lambda x , secs = True : format_lat_long ( long = x , secs = secs ) , <EOL> latlongformat = lambda x , secs = True : format_lat_long ( secs = secs , * x ) , <EOL> url = jinja2 . contextfilter ( <EOL> lambda ctx , * a , ** kw : url_to ( * a , ** kw ) ) , <EOL> asseturl = jinja2 . contextfilter ( <EOL> lambda ctx , * a , ** kw : get_asset_url ( * a , ** kw ) ) , <EOL> ) <EOL> self . jinja_env . globals . update ( <EOL> F = F , <EOL> url_to = url_to , <EOL> site = site_proxy , <EOL> config = config_proxy , <EOL> bag = lookup_from_bag , <EOL> get_random_id = lambda : uuid . uuid4 ( ) . hex , <EOL> ) <EOL> self . jinja_env . filters . update ( <EOL> datetimeformat = _pass_locale ( dates . format_datetime ) , <EOL> dateformat = _pass_locale ( dates . format_date ) , <EOL> timeformat = _pass_locale ( dates . format_time ) , <EOL> ) <EOL> from lektor . types import builtin_types <EOL> self . types = builtin_types . copy ( ) <EOL> self . plugin_controller = PluginController ( self ) <EOL> self . plugins = { } <EOL> self . plugin_ids_by_class = { } <EOL> self . build_programs = [ ] <EOL> self . special_file_assets = { } <EOL> self . special_file_suffixes = { } <EOL> self . custom_url_resolvers = [ ] <EOL> self . custom_generators = [ ] <EOL> if load_plugins : <EOL> self . load_plugins ( ) <EOL> @ property <EOL> def asset_path ( self ) : <EOL> return os . path . join ( self . root_path , '<STR_LIT>' ) <EOL> @ property <EOL> def temp_path ( self ) : <EOL> return os . path . join ( self . root_path , '<STR_LIT>' ) <EOL> def load_plugins ( self ) : <EOL> """<STR_LIT>""" <EOL> from . packages import load_packages <EOL> from . pluginsystem import initialize_plugins <EOL> load_packages ( self ) <EOL> initialize_plugins ( self ) <EOL> def load_config ( self ) : <EOL> """<STR_LIT>""" <EOL> return Config ( self . project . project_file ) <EOL> def new_pad ( self ) : <EOL> """<STR_LIT>""" <EOL> from lektor . db import Database <EOL> return Database ( self ) . new_pad ( ) <EOL> def is_uninteresting_source_name ( self , filename ) : <EOL> """<STR_LIT>""" <EOL> fn = filename . lower ( ) <EOL> if fn in SPECIAL_ARTIFACTS : <EOL> return False <EOL> return filename [ : <NUM_LIT:1> ] in '<STR_LIT>' or fn in IGNORED_FILES <EOL> def is_ignored_artifact ( self , asset_name ) : <EOL> """<STR_LIT>""" <EOL> fn = asset_name . lower ( ) <EOL> if fn in SPECIAL_ARTIFACTS : <EOL> return False <EOL> return fn [ : <NUM_LIT:1> ] == '<STR_LIT:.>' or fn in IGNORED_FILES <EOL> def render_template ( self , name , pad = None , this = None , values = None , alt = None ) : <EOL> ctx = self . make_default_tmpl_values ( pad , this , values , alt , <EOL> template = name ) <EOL> return self . jinja_env . get_or_select_template ( name ) . render ( ctx ) <EOL> def make_default_tmpl_values ( self , pad = None , this = None , values = None , alt = None , <EOL> template = None ) : <EOL> values = dict ( values or ( ) ) <EOL> if alt is None : <EOL> if this is not None : <EOL> alt = getattr ( this , '<STR_LIT>' , None ) <EOL> if not isinstance ( alt , basestring ) : <EOL> alt = None <EOL> if alt is None : <EOL> alt = PRIMARY_ALT <EOL> if pad is None : <EOL> ctx = get_ctx ( ) <EOL> if ctx is not None : <EOL> pad = ctx . pad <EOL> if pad is not None : <EOL> values [ '<STR_LIT>' ] = pad <EOL> if this is not None : <EOL> values [ '<STR_LIT>' ] = this <EOL> if alt is not None : <EOL> values [ '<STR_LIT>' ] = alt <EOL> self . plugin_controller . emit ( '<STR_LIT>' , <EOL> context = values , template = template ) <EOL> return values <EOL> def select_jinja_autoescape ( self , filename ) : <EOL> if filename is None : <EOL> return False <EOL> return filename . endswith ( ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> def resolve_custom_url_path ( self , obj , url_path ) : <EOL> for resolver in self . custom_url_resolvers : <EOL> rv = resolver ( obj , url_path ) <EOL> if rv is not None : <EOL> return rv <EOL> def add_build_program ( self , cls , program ) : <EOL> self . build_programs . append ( ( cls , program ) ) <EOL> def add_asset_type ( self , asset_cls , build_program ) : <EOL> self . build_programs . append ( ( asset_cls , build_program ) ) <EOL> self . special_file_assets [ asset_cls . source_extension ] = asset_cls <EOL> if asset_cls . artifact_extension : <EOL> cext = asset_cls . source_extension + asset_cls . artifact_extension <EOL> self . special_file_suffixes [ cext ] = asset_cls . source_extension <EOL> def urlresolver ( self , func ) : <EOL> self . custom_url_resolvers . append ( func ) <EOL> return func <EOL> def generator ( self , func ) : <EOL> self . custom_generators . append ( func ) <EOL> return func </s>
