<s> try : <EOL> from StringIO import StringIO as BytesIO <EOL> except ImportError : <EOL> from io import BytesIO <EOL> import gc <EOL> import hashlib <EOL> import json <EOL> import mimetypes <EOL> import os <EOL> import re <EOL> import time <EOL> try : <EOL> from urllib import quote as urllib_quote <EOL> except ImportError : <EOL> from urllib . parse import quote as urllib_quote <EOL> from klein import Klein <EOL> from redis import Redis <EOL> import requests <EOL> from yarg . package import json2package <EOL> PYPI_URL = "<STR_LIT>" <EOL> SHIELD_URL = "<STR_LIT>" <EOL> FILE_CACHE = "<STR_LIT>" <EOL> CACHE_TIME = ( <NUM_LIT> * <NUM_LIT> ) * <NUM_LIT> <EOL> REDIS_EXPIRE = <NUM_LIT> * <NUM_LIT:10> <EOL> app = Klein ( ) <EOL> redis = Redis ( ) <EOL> def format_number ( singular , number ) : <EOL> value = singular % { '<STR_LIT:value>' : number } <EOL> return value . replace ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def escape_shield_query ( text ) : <EOL> """<STR_LIT>""" <EOL> text = urllib_quote ( text , safe = '<STR_LIT:U+0020>' ) <EOL> text = text . replace ( '<STR_LIT:_>' , '<STR_LIT>' ) <EOL> text = text . replace ( '<STR_LIT:U+0020>' , '<STR_LIT:_>' ) <EOL> text = text . replace ( '<STR_LIT:->' , '<STR_LIT>' ) <EOL> return text <EOL> intword_converters = ( <EOL> ( <NUM_LIT:3> , lambda number : format_number ( '<STR_LIT>' , number ) ) , <EOL> ( <NUM_LIT:6> , lambda number : format_number ( '<STR_LIT>' , number ) ) , <EOL> ( <NUM_LIT:9> , lambda number : format_number ( '<STR_LIT>' , number ) ) , <EOL> ) <EOL> class PypiHandler ( object ) : <EOL> '''<STR_LIT>''' <EOL> shield_subject = None <EOL> request = None <EOL> format = '<STR_LIT>' <EOL> cacheable = False <EOL> def get ( self , request , package , format , * args , ** kwargs ) : <EOL> self . request = request <EOL> self . format = format <EOL> url = PYPI_URL % package <EOL> r_data = redis . get ( package ) <EOL> if r_data : <EOL> self . package = json2package ( r_data ) <EOL> return self . handle_package_data ( ) <EOL> try : <EOL> response = requests . get ( url ) <EOL> response . raise_for_status ( ) <EOL> except requests . exceptions . HTTPError as e : <EOL> self . shield_subject = '<STR_LIT:error>' <EOL> return self . write_shield ( '<STR_LIT:error>' , '<STR_LIT>' ) <EOL> else : <EOL> redis . set ( package , response . content ) <EOL> redis . expire ( package , REDIS_EXPIRE ) <EOL> self . package = json2package ( response . content ) <EOL> return self . handle_package_data ( ) <EOL> def handle_package_data ( self ) : <EOL> '''<STR_LIT>''' <EOL> raise NotImplementedError <EOL> def hash ( self , url ) : <EOL> return hashlib . md5 ( url ) . hexdigest ( ) <EOL> def write_shield ( self , status , colour = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> shield_url = SHIELD_URL % ( <EOL> self . shield_subject , <EOL> status , <EOL> colour , <EOL> self . format , <EOL> ) <EOL> style = self . request . args . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> if style is not None and style [ <NUM_LIT:0> ] in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> style = style [ <NUM_LIT:0> ] <EOL> shield_url += "<STR_LIT>" . format ( style ) <EOL> shield_url = shield_url . replace ( "<STR_LIT:U+0020>" , "<STR_LIT:_>" ) <EOL> ihash = self . hash ( shield_url ) <EOL> cache = os . path . join ( FILE_CACHE , ihash ) <EOL> if os . path . exists ( cache ) and self . cacheable : <EOL> mtime = os . stat ( cache ) . st_mtime + CACHE_TIME <EOL> if mtime > time . time ( ) : <EOL> return open ( cache ) . read ( ) <EOL> shield_response = requests . get ( shield_url , stream = True ) <EOL> img = BytesIO ( ) <EOL> for chunk in shield_response . iter_content ( <NUM_LIT> ) : <EOL> if not chunk : <EOL> break <EOL> img . write ( chunk ) <EOL> if self . cacheable : <EOL> with open ( cache , '<STR_LIT:w>' ) as ifile : <EOL> img . seek ( <NUM_LIT:0> ) <EOL> ifile . write ( img . read ( ) ) <EOL> img . seek ( <NUM_LIT:0> ) <EOL> return img . read ( ) <EOL> class DownloadHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT>' <EOL> def intword ( self , value ) : <EOL> try : <EOL> value = int ( value ) <EOL> except ( TypeError , ValueError ) : <EOL> return value <EOL> if value < <NUM_LIT:1000> : <EOL> return str ( value ) <EOL> for exponent , converters in intword_converters : <EOL> large_number = <NUM_LIT:10> ** exponent <EOL> if value < large_number * <NUM_LIT:1000> : <EOL> new_value = value / float ( large_number ) <EOL> return converters ( new_value ) <EOL> def handle_package_data ( self ) : <EOL> period = self . request . args . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> if isinstance ( period , list ) : <EOL> period = period [ <NUM_LIT:0> ] <EOL> if period not in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> period = '<STR_LIT>' <EOL> downloads = getattr ( self . package . downloads , period ) <EOL> downloads = self . intword ( downloads ) <EOL> pperiod = "<STR_LIT>" % ( downloads , period ) <EOL> return self . write_shield ( pperiod ) <EOL> class VersionHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT>' <EOL> def handle_package_data ( self ) : <EOL> text = self . request . args . get ( '<STR_LIT:text>' , '<STR_LIT>' ) <EOL> if text [ <NUM_LIT:0> ] in ( '<STR_LIT>' , '<STR_LIT:version>' ) : <EOL> self . shield_subject = text [ <NUM_LIT:0> ] <EOL> return self . write_shield ( self . package . latest_release_id . replace ( '<STR_LIT:->' , '<STR_LIT>' ) ) <EOL> class WheelHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT>' <EOL> cacheable = True <EOL> def handle_package_data ( self ) : <EOL> has_wheel = self . package . has_wheel <EOL> wheel_text = "<STR_LIT:yes>" if has_wheel else "<STR_LIT>" <EOL> colour = "<STR_LIT>" if has_wheel else "<STR_LIT>" <EOL> return self . write_shield ( wheel_text , colour ) <EOL> class EggHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT>' <EOL> cacheable = True <EOL> def handle_package_data ( self , ) : <EOL> has_egg = self . package . has_egg <EOL> egg_text = "<STR_LIT:yes>" if has_egg else "<STR_LIT>" <EOL> colour = "<STR_LIT>" if has_egg else "<STR_LIT>" <EOL> return self . write_shield ( egg_text , colour ) <EOL> class FormatHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT>' <EOL> cacheable = True <EOL> def handle_package_data ( self ) : <EOL> has_egg = self . package . has_egg <EOL> colour = "<STR_LIT>" <EOL> text = "<STR_LIT:source>" <EOL> text = "<STR_LIT>" if has_egg else text <EOL> colour = "<STR_LIT>" if has_egg else colour <EOL> has_wheel = self . package . has_wheel <EOL> text = "<STR_LIT>" if has_wheel else text <EOL> colour = "<STR_LIT>" if has_wheel else colour <EOL> return self . write_shield ( text , colour ) <EOL> class LicenseHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT>' <EOL> cacheable = True <EOL> def get_license ( self ) : <EOL> '''<STR_LIT>''' <EOL> if self . package . license and '<STR_LIT:\n>' not in self . package . license and self . package . license . upper ( ) != '<STR_LIT>' : <EOL> return self . package . license <EOL> if self . package . license_from_classifiers : <EOL> return self . package . license_from_classifiers <EOL> return "<STR_LIT>" <EOL> def handle_package_data ( self ) : <EOL> license = self . get_license ( ) <EOL> license = escape_shield_query ( license ) <EOL> colour = "<STR_LIT>" if license != "<STR_LIT>" else "<STR_LIT>" <EOL> return self . write_shield ( license , colour ) <EOL> class PythonVersionsHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT>' <EOL> cacheable = True <EOL> def get_versions ( self ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( self . package . classifiers , list ) and not len ( self . package . classifiers ) > <NUM_LIT:0> : <EOL> return "<STR_LIT>" <EOL> cs = self . package . python_versions <EOL> cs = sorted ( set ( cs ) ) <EOL> if not len ( cs ) > <NUM_LIT:0> : <EOL> return "<STR_LIT>" <EOL> return cs <EOL> def handle_package_data ( self ) : <EOL> versions = self . get_versions ( ) <EOL> if not isinstance ( versions , list ) : <EOL> return self . write_shield ( versions , '<STR_LIT>' ) <EOL> return self . write_shield ( "<STR_LIT:U+002CU+0020>" . join ( versions ) , '<STR_LIT>' ) <EOL> class ImplementationHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT>' <EOL> cacheable = True <EOL> def get_implementations ( self ) : <EOL> """<STR_LIT>""" <EOL> cs = self . package . python_implementations <EOL> cs = [ c . lower ( ) for c in cs ] <EOL> if not len ( cs ) > <NUM_LIT:0> : <EOL> return '<STR_LIT>' <EOL> return cs <EOL> def handle_package_data ( self ) : <EOL> versions = self . get_implementations ( ) <EOL> if not isinstance ( versions , list ) : <EOL> return self . write_shield ( versions , '<STR_LIT>' ) <EOL> return self . write_shield ( "<STR_LIT:U+002CU+0020>" . join ( versions ) , '<STR_LIT>' ) <EOL> class StatusHandler ( PypiHandler ) : <EOL> shield_subject = '<STR_LIT:status>' <EOL> cacheable = True <EOL> def get_status ( self ) : <EOL> if not isinstance ( self . package . classifiers , list ) and not len ( self . package . classifiers ) > <NUM_LIT:0> : <EOL> return "<STR_LIT>" <EOL> for classifier in self . package . classifiers : <EOL> if classifier . startswith ( "<STR_LIT>" ) : <EOL> bits = classifier . split ( '<STR_LIT>' ) <EOL> return bits [ <NUM_LIT:1> ] . split ( '<STR_LIT>' ) <EOL> return "<STR_LIT:1>" , "<STR_LIT>" <EOL> def handle_package_data ( self ) : <EOL> statuses = { '<STR_LIT:1>' : '<STR_LIT>' , '<STR_LIT:2>' : '<STR_LIT>' , '<STR_LIT:3>' : '<STR_LIT>' , '<STR_LIT:4>' : '<STR_LIT>' , <EOL> '<STR_LIT:5>' : '<STR_LIT>' , '<STR_LIT>' : '<STR_LIT>' , '<STR_LIT>' : '<STR_LIT>' } <EOL> code , status = self . get_status ( ) <EOL> status = status . lower ( ) . replace ( '<STR_LIT:->' , '<STR_LIT>' ) <EOL> status = "<STR_LIT>" if status == "<STR_LIT>" else status <EOL> return self . write_shield ( status , statuses [ code ] ) <EOL> generators = { <EOL> '<STR_LIT:d>' : DownloadHandler , <EOL> '<STR_LIT>' : DownloadHandler , <EOL> '<STR_LIT:v>' : VersionHandler , <EOL> '<STR_LIT:version>' : VersionHandler , <EOL> '<STR_LIT>' : WheelHandler , <EOL> '<STR_LIT>' : EggHandler , <EOL> '<STR_LIT>' : LicenseHandler , <EOL> '<STR_LIT>' : FormatHandler , <EOL> '<STR_LIT>' : PythonVersionsHandler , <EOL> '<STR_LIT>' : ImplementationHandler , <EOL> '<STR_LIT:status>' : StatusHandler , <EOL> } <EOL> @ app . route ( '<STR_LIT>' ) <EOL> def shield ( request , generator , package , extension ) : <EOL> gc . collect ( ) <EOL> ext = mimetypes . types_map [ "<STR_LIT>" . format ( extension ) ] <EOL> request . headers . update ( { '<STR_LIT>' : ext } ) <EOL> klass = generators [ generator ] ( ) <EOL> img = klass . get ( request , package , extension ) <EOL> return img <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> if not os . path . exists ( FILE_CACHE ) : <EOL> os . mkdir ( FILE_CACHE ) <EOL> if '<STR_LIT>' not in mimetypes . types_map : <EOL> mimetypes . add_type ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> app . run ( "<STR_LIT:localhost>" , <NUM_LIT> ) </s>
