<s> import os <EOL> import shutil <EOL> from itertools import chain <EOL> from lektor . _compat import iteritems , range_type <EOL> from lektor . db import Page , Attachment <EOL> from lektor . assets import File , Directory <EOL> from lektor . environment import PRIMARY_ALT <EOL> from lektor . exception import LektorException <EOL> class BuildError ( LektorException ) : <EOL> pass <EOL> builtin_build_programs = [ ] <EOL> def buildprogram ( source_cls ) : <EOL> def decorator ( builder_cls ) : <EOL> builtin_build_programs . append ( ( source_cls , builder_cls ) ) <EOL> return builder_cls <EOL> return decorator <EOL> class SourceInfo ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , path , filename , alt = PRIMARY_ALT , <EOL> type = '<STR_LIT>' , title_i18n = None ) : <EOL> self . path = path <EOL> self . alt = alt <EOL> self . filename = filename <EOL> self . type = type <EOL> self . title_i18n = { } <EOL> en_title = self . path <EOL> if '<STR_LIT>' in title_i18n : <EOL> en_title = title_i18n [ '<STR_LIT>' ] <EOL> for key , value in iteritems ( title_i18n ) : <EOL> if key == '<STR_LIT>' : <EOL> continue <EOL> if value != en_title : <EOL> self . title_i18n [ key ] = value <EOL> self . title_i18n [ '<STR_LIT>' ] = en_title <EOL> class BuildProgram ( object ) : <EOL> def __init__ ( self , source , build_state ) : <EOL> self . source = source <EOL> self . build_state = build_state <EOL> self . artifacts = [ ] <EOL> self . _built = False <EOL> @ property <EOL> def primary_artifact ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return self . artifacts [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> return None <EOL> def describe_source_record ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def build ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _built : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> self . _built = True <EOL> self . produce_artifacts ( ) <EOL> sub_artifacts = [ ] <EOL> failures = [ ] <EOL> gen = self . build_state . builder <EOL> def _build ( artifact , build_func ) : <EOL> ctx = gen . build_artifact ( artifact , build_func ) <EOL> if ctx is not None : <EOL> if ctx . exc_info is not None : <EOL> failures . append ( ctx . exc_info ) <EOL> else : <EOL> sub_artifacts . extend ( ctx . sub_artifacts ) <EOL> for artifact in self . artifacts : <EOL> _build ( artifact , self . build_artifact ) <EOL> while sub_artifacts and not failures : <EOL> artifact , build_func = sub_artifacts . pop ( ) <EOL> _build ( artifact , build_func ) <EOL> if failures : <EOL> for artifact in self . artifacts : <EOL> artifact . set_dirty_flag ( ) <EOL> def produce_artifacts ( self ) : <EOL> """<STR_LIT>""" <EOL> def declare_artifact ( self , artifact_name , sources = None , extra = None ) : <EOL> """<STR_LIT>""" <EOL> self . artifacts . append ( self . build_state . new_artifact ( <EOL> artifact_name = artifact_name , <EOL> sources = sources , <EOL> source_obj = self . source , <EOL> extra = extra , <EOL> ) ) <EOL> def build_artifact ( self , artifact ) : <EOL> """<STR_LIT>""" <EOL> def iter_child_sources ( self ) : <EOL> """<STR_LIT>""" <EOL> return iter ( ( ) ) <EOL> @ buildprogram ( Page ) <EOL> class PageBuildProgram ( BuildProgram ) : <EOL> def describe_source_record ( self ) : <EOL> for filename in self . source . iter_source_filenames ( ) : <EOL> if os . path . isfile ( filename ) : <EOL> return SourceInfo ( <EOL> path = self . source . path , <EOL> alt = self . source [ '<STR_LIT>' ] , <EOL> filename = filename , <EOL> type = '<STR_LIT>' , <EOL> title_i18n = self . source . get_record_label_i18n ( ) <EOL> ) <EOL> def produce_artifacts ( self ) : <EOL> pagination_enabled = self . source . datamodel . pagination_config . enabled <EOL> if self . source . is_visible and ( self . source . page_num is not None or not pagination_enabled ) : <EOL> artifact_name = self . source . url_path <EOL> if artifact_name . endswith ( '<STR_LIT:/>' ) : <EOL> artifact_name += '<STR_LIT>' <EOL> self . declare_artifact ( <EOL> artifact_name , <EOL> sources = list ( self . source . iter_source_filenames ( ) ) ) <EOL> def build_artifact ( self , artifact ) : <EOL> try : <EOL> self . source . url_path . encode ( '<STR_LIT:ascii>' ) <EOL> except UnicodeError : <EOL> raise BuildError ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> self . source . url_path ) <EOL> artifact . render_template_into ( <EOL> self . source [ '<STR_LIT>' ] , this = self . source ) <EOL> def _iter_paginated_children ( self ) : <EOL> total = self . source . datamodel . pagination_config . count_pages ( self . source ) <EOL> for page_num in range_type ( <NUM_LIT:1> , total + <NUM_LIT:1> ) : <EOL> yield Page ( self . source . pad , self . source . _data , <EOL> page_num = page_num ) <EOL> def iter_child_sources ( self ) : <EOL> p_config = self . source . datamodel . pagination_config <EOL> pagination_enabled = p_config . enabled <EOL> child_sources = [ ] <EOL> all_children = self . source . children . include_undiscoverable ( True ) <EOL> if pagination_enabled : <EOL> if self . source . page_num is None : <EOL> child_sources . append ( self . _iter_paginated_children ( ) ) <EOL> pq = p_config . get_pagination_query ( self . source ) <EOL> child_sources . append ( set ( all_children ) - set ( pq ) ) <EOL> child_sources . append ( self . source . attachments ) <EOL> else : <EOL> child_sources . append ( self . source . pagination . items ) <EOL> else : <EOL> child_sources . append ( all_children ) <EOL> child_sources . append ( self . source . attachments ) <EOL> return chain ( * child_sources ) <EOL> @ buildprogram ( Attachment ) <EOL> class AttachmentBuildProgram ( BuildProgram ) : <EOL> def describe_source_record ( self ) : <EOL> return SourceInfo ( <EOL> path = self . source . path , <EOL> alt = self . source . alt , <EOL> filename = self . source . attachment_filename , <EOL> type = '<STR_LIT>' , <EOL> title_i18n = { '<STR_LIT>' : self . source [ '<STR_LIT>' ] } <EOL> ) <EOL> def produce_artifacts ( self ) : <EOL> if self . source . is_visible : <EOL> self . declare_artifact ( <EOL> self . source . url_path , <EOL> sources = list ( self . source . iter_source_filenames ( ) ) ) <EOL> def build_artifact ( self , artifact ) : <EOL> with artifact . open ( '<STR_LIT:wb>' ) as df : <EOL> with open ( self . source . attachment_filename , '<STR_LIT:rb>' ) as sf : <EOL> shutil . copyfileobj ( sf , df ) <EOL> @ buildprogram ( File ) <EOL> class FileAssetBuildProgram ( BuildProgram ) : <EOL> def produce_artifacts ( self ) : <EOL> self . declare_artifact ( <EOL> self . source . artifact_name , <EOL> sources = [ self . source . source_filename ] ) <EOL> def build_artifact ( self , artifact ) : <EOL> with artifact . open ( '<STR_LIT:wb>' ) as df : <EOL> with open ( self . source . source_filename , '<STR_LIT:rb>' ) as sf : <EOL> shutil . copyfileobj ( sf , df ) <EOL> @ buildprogram ( Directory ) <EOL> class DirectoryAssetBuildProgram ( BuildProgram ) : <EOL> def iter_child_sources ( self ) : <EOL> return self . source . children </s>
