<s> """<STR_LIT>""" <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> VERSION = '<STR_LIT>' <EOL> import os . path <EOL> import mimetypes <EOL> import warnings <EOL> import collections <EOL> import posixpath <EOL> from fnmatch import fnmatch <EOL> from unicodedata import normalize <EOL> from threading import Lock <EOL> from contextlib import contextmanager <EOL> from collections import Mapping <EOL> from posixpath import relpath as posix_relpath <EOL> try : <EOL> from urllib import unquote <EOL> from urlparse import urlsplit <EOL> except ImportError : <EOL> from urllib . parse import urlsplit , unquote <EOL> from werkzeug . exceptions import HTTPException <EOL> from flask import ( Flask , Blueprint , url_for , request , send_from_directory , <EOL> redirect ) <EOL> try : <EOL> unicode <EOL> except NameError : <EOL> unicode = str <EOL> basestring = str <EOL> class MissingURLGeneratorWarning ( Warning ) : <EOL> pass <EOL> class MimetypeMismatchWarning ( Warning ) : <EOL> pass <EOL> class NotFoundWarning ( Warning ) : <EOL> pass <EOL> class Freezer ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , app = None , with_static_files = True , <EOL> with_no_argument_rules = True , log_url_for = True ) : <EOL> self . url_generators = [ ] <EOL> self . log_url_for = log_url_for <EOL> if with_static_files : <EOL> self . register_generator ( self . static_files_urls ) <EOL> if with_no_argument_rules : <EOL> self . register_generator ( self . no_argument_rules_urls ) <EOL> self . init_app ( app ) <EOL> def init_app ( self , app ) : <EOL> """<STR_LIT>""" <EOL> self . app = app <EOL> if app : <EOL> self . url_for_logger = UrlForLogger ( app ) <EOL> app . config . setdefault ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> app . config . setdefault ( '<STR_LIT>' , [ ] ) <EOL> app . config . setdefault ( '<STR_LIT>' , [ ] ) <EOL> app . config . setdefault ( '<STR_LIT>' , None ) <EOL> app . config . setdefault ( '<STR_LIT>' , True ) <EOL> app . config . setdefault ( '<STR_LIT>' , <EOL> '<STR_LIT>' ) <EOL> app . config . setdefault ( '<STR_LIT>' , False ) <EOL> app . config . setdefault ( '<STR_LIT>' , False ) <EOL> app . config . setdefault ( '<STR_LIT>' , False ) <EOL> def register_generator ( self , function ) : <EOL> """<STR_LIT>""" <EOL> self . url_generators . append ( function ) <EOL> return function <EOL> @ property <EOL> def root ( self ) : <EOL> """<STR_LIT>""" <EOL> return os . path . join ( <EOL> unicode ( self . app . root_path ) , <EOL> unicode ( self . app . config [ '<STR_LIT>' ] ) <EOL> ) <EOL> def freeze ( self ) : <EOL> """<STR_LIT>""" <EOL> remove_extra = self . app . config [ '<STR_LIT>' ] <EOL> if not os . path . isdir ( self . root ) : <EOL> os . makedirs ( self . root ) <EOL> if remove_extra : <EOL> ignore = self . app . config [ '<STR_LIT>' ] <EOL> previous_files = set ( <EOL> normalize ( '<STR_LIT>' , os . path . join ( self . root , * name . split ( '<STR_LIT:/>' ) ) ) <EOL> for name in walk_directory ( self . root , ignore = ignore ) ) <EOL> seen_urls = set ( ) <EOL> seen_endpoints = set ( ) <EOL> built_files = set ( ) <EOL> for url , endpoint in self . _generate_all_urls ( ) : <EOL> seen_endpoints . add ( endpoint ) <EOL> if url in seen_urls : <EOL> continue <EOL> seen_urls . add ( url ) <EOL> new_filename = self . _build_one ( url ) <EOL> built_files . add ( normalize ( '<STR_LIT>' , new_filename ) ) <EOL> self . _check_endpoints ( seen_endpoints ) <EOL> if remove_extra : <EOL> for extra_file in previous_files - built_files : <EOL> os . remove ( extra_file ) <EOL> parent = os . path . dirname ( extra_file ) <EOL> if not os . listdir ( parent ) : <EOL> os . removedirs ( parent ) <EOL> return seen_urls <EOL> def all_urls ( self ) : <EOL> """<STR_LIT>""" <EOL> for url , _endpoint in self . _generate_all_urls ( ) : <EOL> yield url <EOL> def _script_name ( self ) : <EOL> """<STR_LIT>""" <EOL> base_url = self . app . config [ '<STR_LIT>' ] <EOL> return urlsplit ( base_url or '<STR_LIT>' ) . path . rstrip ( '<STR_LIT:/>' ) <EOL> def _generate_all_urls ( self ) : <EOL> """<STR_LIT>""" <EOL> script_name = self . _script_name ( ) <EOL> url_encoding = self . app . url_map . charset <EOL> url_generators = list ( self . url_generators ) <EOL> url_generators += [ self . url_for_logger . iter_calls ] <EOL> with self . app . test_request_context ( base_url = script_name or None ) : <EOL> for generator in url_generators : <EOL> for generated in generator ( ) : <EOL> if isinstance ( generated , basestring ) : <EOL> url = generated <EOL> endpoint = None <EOL> else : <EOL> if isinstance ( generated , Mapping ) : <EOL> values = generated <EOL> endpoint = generator . __name__ <EOL> else : <EOL> endpoint , values = generated <EOL> url = url_for ( endpoint , ** values ) <EOL> assert url . startswith ( script_name ) , ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> % ( url , script_name ) <EOL> ) <EOL> url = url [ len ( script_name ) : ] <EOL> url = unquote ( url ) <EOL> parsed_url = urlsplit ( url ) <EOL> if parsed_url . scheme or parsed_url . netloc : <EOL> raise ValueError ( '<STR_LIT>' + url ) <EOL> url = parsed_url . path <EOL> if not isinstance ( url , unicode ) : <EOL> url = url . decode ( url_encoding ) <EOL> yield url , endpoint <EOL> def _check_endpoints ( self , seen_endpoints ) : <EOL> """<STR_LIT>""" <EOL> get_endpoints = set ( <EOL> rule . endpoint for rule in self . app . url_map . iter_rules ( ) <EOL> if '<STR_LIT:GET>' in rule . methods ) <EOL> not_generated_endpoints = get_endpoints - seen_endpoints <EOL> if self . static_files_urls in self . url_generators : <EOL> not_generated_endpoints -= set ( self . _static_rules_endpoints ( ) ) <EOL> if not_generated_endpoints : <EOL> warnings . warn ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % '<STR_LIT:U+002CU+0020>' . join ( <EOL> unicode ( e ) for e in not_generated_endpoints ) , <EOL> MissingURLGeneratorWarning , <EOL> stacklevel = <NUM_LIT:3> ) <EOL> def _build_one ( self , url ) : <EOL> """<STR_LIT>""" <EOL> client = self . app . test_client ( ) <EOL> base_url = self . app . config [ '<STR_LIT>' ] <EOL> with conditional_context ( self . url_for_logger , self . log_url_for ) : <EOL> with conditional_context ( patch_url_for ( self . app ) , <EOL> self . app . config [ '<STR_LIT>' ] ) : <EOL> response = client . get ( url , follow_redirects = True , <EOL> base_url = base_url ) <EOL> ignore_404 = self . app . config [ '<STR_LIT>' ] <EOL> if response . status_code != <NUM_LIT:200> : <EOL> if response . status_code == <NUM_LIT> and ignore_404 : <EOL> warnings . warn ( '<STR_LIT>' % ( response . status , url ) , <EOL> NotFoundWarning , <EOL> stacklevel = <NUM_LIT:3> ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' % ( response . status , url ) ) <EOL> destination_path = self . urlpath_to_filepath ( url ) <EOL> filename = os . path . join ( self . root , * destination_path . split ( '<STR_LIT:/>' ) ) <EOL> if not self . app . config [ '<STR_LIT>' ] : <EOL> basename = os . path . basename ( filename ) <EOL> guessed_type , guessed_encoding = mimetypes . guess_type ( basename ) <EOL> if not guessed_type : <EOL> guessed_type = self . app . config [ '<STR_LIT>' ] <EOL> if not guessed_type == response . mimetype : <EOL> warnings . warn ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % ( basename , guessed_type , response . content_type ) , <EOL> MimetypeMismatchWarning , <EOL> stacklevel = <NUM_LIT:3> ) <EOL> dirname = os . path . dirname ( filename ) <EOL> if not os . path . isdir ( dirname ) : <EOL> os . makedirs ( dirname ) <EOL> content = response . data <EOL> if os . path . isfile ( filename ) : <EOL> with open ( filename , '<STR_LIT:rb>' ) as fd : <EOL> previous_content = fd . read ( ) <EOL> else : <EOL> previous_content = None <EOL> if content != previous_content : <EOL> with open ( filename , '<STR_LIT:wb>' ) as fd : <EOL> fd . write ( content ) <EOL> response . close ( ) <EOL> return filename <EOL> def urlpath_to_filepath ( self , path ) : <EOL> """<STR_LIT>""" <EOL> if path . endswith ( '<STR_LIT:/>' ) : <EOL> path += '<STR_LIT>' <EOL> assert path . startswith ( '<STR_LIT:/>' ) <EOL> return path [ <NUM_LIT:1> : ] <EOL> def serve ( self , ** options ) : <EOL> """<STR_LIT>""" <EOL> app = self . make_static_app ( ) <EOL> script_name = self . _script_name ( ) <EOL> app . wsgi_app = script_name_middleware ( app . wsgi_app , script_name ) <EOL> app . run ( ** options ) <EOL> def run ( self , ** options ) : <EOL> """<STR_LIT>""" <EOL> self . freeze ( ) <EOL> self . serve ( ** options ) <EOL> def make_static_app ( self ) : <EOL> """<STR_LIT>""" <EOL> root = os . path . join ( <EOL> self . app . root_path , <EOL> self . app . config [ '<STR_LIT>' ] <EOL> ) <EOL> def dispatch_request ( ) : <EOL> filename = self . urlpath_to_filepath ( request . path ) <EOL> guessed_type , guessed_encoding = mimetypes . guess_type ( filename ) <EOL> if not guessed_type : <EOL> guessed_type = self . app . config [ '<STR_LIT>' ] <EOL> return send_from_directory ( root , filename , mimetype = guessed_type ) <EOL> app = Flask ( __name__ ) <EOL> app . dispatch_request = dispatch_request <EOL> return app <EOL> def _static_rules_endpoints ( self ) : <EOL> """<STR_LIT>""" <EOL> send_static_file = unwrap_method ( Flask . send_static_file ) <EOL> assert unwrap_method ( Blueprint . send_static_file ) is send_static_file <EOL> for rule in self . app . url_map . iter_rules ( ) : <EOL> view = self . app . view_functions [ rule . endpoint ] <EOL> if unwrap_method ( view ) is send_static_file : <EOL> yield rule . endpoint <EOL> def static_files_urls ( self ) : <EOL> """<STR_LIT>""" <EOL> for endpoint in self . _static_rules_endpoints ( ) : <EOL> view = self . app . view_functions [ endpoint ] <EOL> app_or_blueprint = method_self ( view ) <EOL> root = app_or_blueprint . static_folder <EOL> ignore = self . app . config [ '<STR_LIT>' ] <EOL> if root is None or not os . path . isdir ( root ) : <EOL> continue <EOL> for filename in walk_directory ( root , ignore = ignore ) : <EOL> yield endpoint , { '<STR_LIT:filename>' : filename } <EOL> def no_argument_rules_urls ( self ) : <EOL> """<STR_LIT>""" <EOL> for rule in self . app . url_map . iter_rules ( ) : <EOL> if not rule . arguments and '<STR_LIT:GET>' in rule . methods : <EOL> yield rule . endpoint , { } <EOL> def walk_directory ( root , ignore = ( ) ) : <EOL> """<STR_LIT>""" <EOL> path_ignore = [ n . strip ( '<STR_LIT:/>' ) for n in ignore if '<STR_LIT:/>' in n ] <EOL> basename_ignore = [ n for n in ignore if '<STR_LIT:/>' not in n ] <EOL> def walk ( directory , path_so_far ) : <EOL> for name in sorted ( os . listdir ( directory ) ) : <EOL> if any ( fnmatch ( name , pattern ) for pattern in basename_ignore ) : <EOL> continue <EOL> path = path_so_far + '<STR_LIT:/>' + name if path_so_far else name <EOL> if any ( fnmatch ( path , pattern ) for pattern in path_ignore ) : <EOL> continue <EOL> full_name = os . path . join ( directory , name ) <EOL> if os . path . isdir ( full_name ) : <EOL> for file_path in walk ( full_name , path ) : <EOL> yield file_path <EOL> elif os . path . isfile ( full_name ) : <EOL> yield path <EOL> return walk ( root , '<STR_LIT>' ) <EOL> @ contextmanager <EOL> def patch_url_for ( app ) : <EOL> """<STR_LIT>""" <EOL> previous_url_for = app . jinja_env . globals [ '<STR_LIT>' ] <EOL> app . jinja_env . globals [ '<STR_LIT>' ] = relative_url_for <EOL> try : <EOL> yield <EOL> finally : <EOL> app . jinja_env . globals [ '<STR_LIT>' ] = previous_url_for <EOL> def relative_url_for ( endpoint , ** values ) : <EOL> """<STR_LIT>""" <EOL> url = url_for ( endpoint , ** values ) <EOL> if not url . startswith ( '<STR_LIT:/>' ) : <EOL> return url <EOL> url , fragment_sep , fragment = url . partition ( '<STR_LIT:#>' ) <EOL> url , query_sep , query = url . partition ( '<STR_LIT:?>' ) <EOL> if url . endswith ( '<STR_LIT:/>' ) : <EOL> url += '<STR_LIT>' <EOL> url += query_sep + query + fragment_sep + fragment <EOL> request_path = request . path <EOL> if not request_path . endswith ( '<STR_LIT:/>' ) : <EOL> request_path = posixpath . dirname ( request_path ) <EOL> return posix_relpath ( url , request_path ) <EOL> def unwrap_method ( method ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return method . im_func <EOL> except AttributeError : <EOL> try : <EOL> return method . __func__ <EOL> except AttributeError : <EOL> return method <EOL> def method_self ( method ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return method . im_self <EOL> except AttributeError : <EOL> return method . __self__ <EOL> @ contextmanager <EOL> def conditional_context ( context , condition ) : <EOL> """<STR_LIT>""" <EOL> if condition : <EOL> with context : <EOL> yield <EOL> else : <EOL> yield <EOL> class UrlForLogger ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , app ) : <EOL> self . app = app <EOL> self . logged_calls = collections . deque ( ) <EOL> self . _enabled = False <EOL> self . _lock = Lock ( ) <EOL> def logger ( endpoint , values ) : <EOL> if self . _enabled : <EOL> self . logged_calls . append ( ( endpoint , values . copy ( ) ) ) <EOL> self . app . url_default_functions . setdefault ( None , [ ] ) . insert ( <NUM_LIT:0> , logger ) <EOL> def __enter__ ( self ) : <EOL> self . _lock . acquire ( ) <EOL> self . _enabled = True <EOL> def __exit__ ( self , exc_type , exc_value , traceback ) : <EOL> self . _enabled = False <EOL> self . _lock . release ( ) <EOL> def iter_calls ( self ) : <EOL> """<STR_LIT>""" <EOL> while self . logged_calls : <EOL> yield self . logged_calls . popleft ( ) <EOL> def script_name_middleware ( application , script_name ) : <EOL> """<STR_LIT>""" <EOL> def new_application ( environ , start_response ) : <EOL> path_info = environ [ '<STR_LIT>' ] <EOL> if path_info . startswith ( script_name ) : <EOL> environ [ '<STR_LIT>' ] += script_name <EOL> environ [ '<STR_LIT>' ] = path_info [ len ( script_name ) : ] <EOL> next = application <EOL> else : <EOL> next = redirect ( script_name + '<STR_LIT:/>' ) <EOL> return next ( environ , start_response ) <EOL> return new_application </s>
