<s> import logging <EOL> import os <EOL> import posixpath <EOL> import django . core . exceptions <EOL> from django . contrib . staticfiles import finders <EOL> from django . utils import encoding , functional , six <EOL> from static_precompiler import models , settings , utils <EOL> logger = logging . getLogger ( "<STR_LIT>" ) <EOL> __all__ = ( <EOL> "<STR_LIT>" , <EOL> ) <EOL> class BaseCompiler ( object ) : <EOL> name = None <EOL> supports_dependencies = False <EOL> input_extension = None <EOL> output_extension = None <EOL> def is_supported ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> return os . path . splitext ( source_path ) [ <NUM_LIT:1> ] . lstrip ( "<STR_LIT:.>" ) == self . input_extension <EOL> def get_full_source_path ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> norm_source_path = utils . normalize_path ( source_path . lstrip ( "<STR_LIT:/>" ) ) <EOL> if settings . STATIC_ROOT : <EOL> full_path = os . path . join ( settings . STATIC_ROOT , norm_source_path ) <EOL> if os . path . exists ( full_path ) : <EOL> return full_path <EOL> try : <EOL> full_path = finders . find ( norm_source_path ) <EOL> except django . core . exceptions . SuspiciousOperation : <EOL> full_path = None <EOL> if full_path is None : <EOL> raise ValueError ( "<STR_LIT>" . format ( source_path ) ) <EOL> return full_path <EOL> def get_output_filename ( self , source_filename ) : <EOL> """<STR_LIT>""" <EOL> return "<STR_LIT>" . format ( os . path . splitext ( source_filename ) [ <NUM_LIT:0> ] , self . output_extension ) <EOL> def get_output_path ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> source_dir = os . path . dirname ( source_path ) <EOL> source_filename = os . path . basename ( source_path ) <EOL> output_filename = self . get_output_filename ( source_filename ) <EOL> return posixpath . join ( settings . OUTPUT_DIR , source_dir , output_filename ) <EOL> def get_full_output_path ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> return os . path . join ( settings . ROOT , utils . normalize_path ( self . get_output_path ( source_path . lstrip ( "<STR_LIT:/>" ) ) ) ) <EOL> def get_source_mtime ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> return utils . get_mtime ( self . get_full_source_path ( source_path ) ) <EOL> def get_output_mtime ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> full_output_path = self . get_full_output_path ( source_path ) <EOL> if not os . path . exists ( full_output_path ) : <EOL> return None <EOL> return utils . get_mtime ( full_output_path ) <EOL> def should_compile ( self , source_path , from_management = False ) : <EOL> """<STR_LIT>""" <EOL> if settings . DISABLE_AUTO_COMPILE and not from_management : <EOL> return False <EOL> compiled_mtime = self . get_output_mtime ( source_path ) <EOL> if compiled_mtime is None : <EOL> return True <EOL> if compiled_mtime <= self . get_source_mtime ( source_path ) : <EOL> return True <EOL> if self . supports_dependencies : <EOL> for dependency in self . get_dependencies ( source_path ) : <EOL> dependency_mtime = self . get_source_mtime ( dependency ) <EOL> if compiled_mtime <= dependency_mtime : <EOL> return True <EOL> return False <EOL> def get_source ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> with open ( self . get_full_source_path ( source_path ) ) as source : <EOL> return source . read ( ) <EOL> def compile ( self , source_path , from_management = False , verbosity = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> if not self . is_supported ( source_path ) : <EOL> raise ValueError ( "<STR_LIT>" . format ( <EOL> source_path , self . __class__ . __name__ <EOL> ) ) <EOL> compiled_path = self . get_output_path ( source_path ) <EOL> if self . should_compile ( source_path , from_management = from_management ) : <EOL> compiled_path = self . compile_file ( source_path ) <EOL> if self . supports_dependencies : <EOL> self . update_dependencies ( source_path , self . find_dependencies ( source_path ) ) <EOL> message = "<STR_LIT>" . format ( source_path , compiled_path ) <EOL> if from_management and verbosity >= <NUM_LIT:1> : <EOL> print ( message ) <EOL> else : <EOL> logging . info ( message ) <EOL> return compiled_path <EOL> def compile_lazy ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> return encoding . force_text ( self . compile ( source_path ) ) <EOL> compile_lazy = functional . lazy ( compile_lazy , six . text_type ) <EOL> def compile_file ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError <EOL> def compile_source ( self , source ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError <EOL> def find_dependencies ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> return [ ] <EOL> def get_dependencies ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> dependencies = [ ] <EOL> for dependency in models . Dependency . objects . filter ( source = source_path ) . order_by ( "<STR_LIT>" ) : <EOL> try : <EOL> self . get_full_source_path ( dependency . depends_on ) <EOL> except ValueError : <EOL> dependency . delete ( ) <EOL> else : <EOL> dependencies . append ( dependency . depends_on ) <EOL> return dependencies <EOL> def get_dependents ( self , source_path ) : <EOL> """<STR_LIT>""" <EOL> dependents = [ ] <EOL> for dependency in models . Dependency . objects . filter ( depends_on = source_path ) . order_by ( "<STR_LIT:source>" ) : <EOL> try : <EOL> self . get_full_source_path ( dependency . source ) <EOL> except ValueError : <EOL> dependency . delete ( ) <EOL> else : <EOL> dependents . append ( dependency . source ) <EOL> return dependents <EOL> def update_dependencies ( self , source_path , dependencies ) : <EOL> """<STR_LIT>""" <EOL> if not dependencies : <EOL> models . Dependency . objects . filter ( source = source_path ) . delete ( ) <EOL> else : <EOL> models . Dependency . objects . filter ( <EOL> source = source_path <EOL> ) . exclude ( <EOL> depends_on__in = dependencies , <EOL> ) . delete ( ) <EOL> for dependency in dependencies : <EOL> models . Dependency . objects . get_or_create ( <EOL> source = source_path , <EOL> depends_on = dependency , <EOL> ) <EOL> def handle_changed_file ( self , source_path , verbosity = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> self . compile ( source_path , from_management = True , verbosity = verbosity ) <EOL> for dependent in self . get_dependents ( source_path ) : <EOL> self . compile ( dependent , from_management = True , verbosity = verbosity ) </s>
