<s> """<STR_LIT>""" <EOL> import datetime <EOL> import logging <EOL> import re <EOL> import xml <EOL> from xml . dom import minidom <EOL> from google . appengine . api import taskqueue <EOL> from google . appengine . ext import deferred <EOL> from simian import settings <EOL> from simian . mac import common <EOL> from simian . mac import models <EOL> from simian . mac . common import gae_util <EOL> from simian . mac . models import constants <EOL> from simian . mac . munki import plist <EOL> OS_VERSIONS = frozenset ( <EOL> [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> CATALOG_REGENERATION_LOCK_NAME = '<STR_LIT>' <EOL> MON , TUE , WED , THU , FRI , SAT , SUN = range ( <NUM_LIT:0> , <NUM_LIT:7> ) <EOL> class Error ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class DocumentFormatError ( Error ) : <EOL> """<STR_LIT>""" <EOL> class DistFileDocument ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> """<STR_LIT>""" <EOL> self . Reset ( ) <EOL> def Reset ( self ) : <EOL> """<STR_LIT>""" <EOL> self . description = None <EOL> self . restart_required = None <EOL> self . server_comment = None <EOL> self . softwareupdate_name = None <EOL> self . title = None <EOL> self . version = None <EOL> self . _installer_script = { } <EOL> def _ParseInstallerScriptString ( self , istr ) : <EOL> """<STR_LIT>""" <EOL> installer_script = { } <EOL> kv_split = re . compile ( <EOL> ( r'<STR_LIT>' <EOL> '<STR_LIT>' ) , <EOL> re . MULTILINE | re . DOTALL ) <EOL> for i in re . finditer ( kv_split , istr ) : <EOL> if i . group ( <NUM_LIT:1> ) : <EOL> installer_script [ i . group ( <NUM_LIT:1> ) ] = i . group ( <NUM_LIT:3> ) <EOL> return installer_script <EOL> def LoadDocument ( self , distfile_xml ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> p = minidom . parseString ( distfile_xml ) <EOL> except xml . parsers . expat . ExpatError , e : <EOL> raise DocumentFormatError ( str ( e ) ) <EOL> try : <EOL> l = p . getElementsByTagName ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> s = p . getElementsByTagName ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> cdata = [ ] <EOL> for cn in s . childNodes : <EOL> cdata . append ( cn . nodeValue ) <EOL> cdata = '<STR_LIT>' . join ( cdata ) <EOL> except IndexError : <EOL> raise DocumentFormatError <EOL> self . restart_required = re . search ( <EOL> r'<STR_LIT>' , distfile_xml ) is not None <EOL> swupd_name_match = re . search ( <EOL> r'<STR_LIT>' , distfile_xml ) <EOL> if swupd_name_match : <EOL> self . softwareupdate_name = swupd_name_match . group ( <NUM_LIT:2> ) <EOL> self . _installer_script = self . _ParseInstallerScriptString ( cdata ) <EOL> self . description = self . _installer_script . get ( '<STR_LIT>' ) <EOL> self . server_comment = self . _installer_script . get ( '<STR_LIT>' ) <EOL> self . title = self . _installer_script . get ( '<STR_LIT>' ) <EOL> self . version = ( self . _installer_script . get ( '<STR_LIT>' ) or <EOL> self . _installer_script . get ( '<STR_LIT>' ) ) <EOL> def GenerateAppleSUSCatalogs ( track = None , tracks = None , delay = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> if track and tracks : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> elif not tracks and not track : <EOL> tracks = common . TRACKS <EOL> elif track : <EOL> tracks = [ track ] <EOL> for track in tracks : <EOL> for os_version in OS_VERSIONS : <EOL> if delay : <EOL> now_str = datetime . datetime . utcnow ( ) . strftime ( '<STR_LIT>' ) <EOL> deferred_name = '<STR_LIT>' % ( <EOL> os_version , track , now_str ) <EOL> deferred_name = re . sub ( r'<STR_LIT>' , '<STR_LIT>' , deferred_name ) <EOL> try : <EOL> deferred . defer ( <EOL> GenerateAppleSUSCatalog , os_version , track , <EOL> _countdown = delay , _name = deferred_name ) <EOL> except taskqueue . TaskAlreadyExistsError : <EOL> logging . info ( '<STR_LIT>' ) <EOL> else : <EOL> GenerateAppleSUSCatalog ( os_version , track ) <EOL> if delay : <EOL> now_str = datetime . datetime . utcnow ( ) . strftime ( '<STR_LIT>' ) <EOL> deferred_name = '<STR_LIT>' % now_str <EOL> deferred_name = re . sub ( r'<STR_LIT>' , '<STR_LIT>' , deferred_name ) <EOL> try : <EOL> deferred . defer ( <EOL> GenerateAppleSUSMetadataCatalog , _name = deferred_name ) <EOL> except taskqueue . TaskAlreadyExistsError : <EOL> logging . info ( '<STR_LIT>' ) <EOL> else : <EOL> GenerateAppleSUSMetadataCatalog ( ) <EOL> def GenerateAppleSUSCatalog ( os_version , track , _datetime = datetime . datetime ) : <EOL> """<STR_LIT>""" <EOL> logging . info ( '<STR_LIT>' , os_version , track ) <EOL> gae_util . ReleaseLock ( CATALOG_REGENERATION_LOCK_NAME % track ) <EOL> catalog_key = '<STR_LIT>' % os_version <EOL> untouched_catalog_obj = models . AppleSUSCatalog . get_by_key_name ( catalog_key ) <EOL> if not untouched_catalog_obj : <EOL> logging . warning ( '<STR_LIT>' , catalog_key ) <EOL> return None , None <EOL> untouched_catalog_plist = plist . ApplePlist ( untouched_catalog_obj . plist ) <EOL> untouched_catalog_plist . Parse ( ) <EOL> approved_product_ids = set ( ) <EOL> products_query = models . AppleSUSProduct . AllActive ( ) . filter ( '<STR_LIT>' , track ) <EOL> for product in products_query : <EOL> approved_product_ids . add ( product . product_id ) <EOL> product_ids = untouched_catalog_plist . get ( '<STR_LIT>' , { } ) . keys ( ) <EOL> new_plist = untouched_catalog_plist <EOL> for product_id in product_ids : <EOL> if product_id not in approved_product_ids : <EOL> del new_plist [ '<STR_LIT>' ] [ product_id ] <EOL> catalog_plist_xml = new_plist . GetXml ( ) <EOL> now = _datetime . utcnow ( ) <EOL> now_str = now . strftime ( '<STR_LIT>' ) <EOL> backup = models . AppleSUSCatalog ( <EOL> key_name = '<STR_LIT>' % ( os_version , track , now_str ) ) <EOL> backup . plist = catalog_plist_xml <EOL> backup . put ( ) <EOL> c = models . AppleSUSCatalog ( key_name = '<STR_LIT>' % ( os_version , track ) ) <EOL> c . plist = catalog_plist_xml <EOL> c . put ( ) <EOL> return c , new_plist <EOL> def GenerateAppleSUSMetadataCatalog ( ) : <EOL> """<STR_LIT>""" <EOL> logging . info ( '<STR_LIT>' ) <EOL> products = { } <EOL> unattended = models . AppleSUSProduct . AllActive ( ) . filter ( '<STR_LIT>' , True ) <EOL> force_install_after_date = models . AppleSUSProduct . AllActive ( ) . filter ( <EOL> '<STR_LIT>' , None ) <EOL> for p in unattended : <EOL> products [ p . product_id ] = p <EOL> for p in force_install_after_date : <EOL> products [ p . product_id ] = p <EOL> catalog_plist_xml_fragments = [ <EOL> p . plist . GetXmlContent ( ) for p in products . values ( ) ] <EOL> catalog_plist_xml = constants . CATALOG_PLIST_XML % ( <EOL> '<STR_LIT:\n>' . join ( catalog_plist_xml_fragments ) ) <EOL> c = models . Catalog ( key_name = '<STR_LIT>' ) <EOL> c . plist = catalog_plist_xml <EOL> c . put ( ) <EOL> models . Catalog . DeleteMemcacheWrap ( <EOL> '<STR_LIT>' , prop_name = '<STR_LIT>' ) <EOL> return c <EOL> def GetAutoPromoteDate ( track , applesus_product ) : <EOL> """<STR_LIT>""" <EOL> if not settings . APPLE_AUTO_PROMOTE_ENABLED : <EOL> return None <EOL> if applesus_product . manual_override : <EOL> return None <EOL> elif common . UNSTABLE not in applesus_product . tracks : <EOL> return None <EOL> if track == common . TESTING : <EOL> days = settings . APPLE_UNSTABLE_GRACE_PERIOD_DAYS <EOL> elif track == common . STABLE : <EOL> days = settings . APPLE_TESTING_GRACE_PERIOD_DAYS <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' % track ) <EOL> auto_promote_offset = datetime . timedelta ( days = days ) <EOL> previous_track_date = applesus_product . mtime . date ( ) <EOL> if track == common . TESTING : <EOL> auto_promote_date = previous_track_date + auto_promote_offset <EOL> if auto_promote_date . weekday ( ) >= SAT : <EOL> auto_promote_date = _GetNextWeekdayDate ( <EOL> weekday = MON , min_date = auto_promote_date ) <EOL> return auto_promote_date <EOL> if common . TESTING not in applesus_product . tracks : <EOL> previous_track_date = GetAutoPromoteDate ( '<STR_LIT>' , applesus_product ) <EOL> min_auto_promote_date = previous_track_date + auto_promote_offset <EOL> return _GetNextWeekdayDate ( <EOL> weekday = settings . APPLE_AUTO_PROMOTE_STABLE_WEEKDAY , <EOL> min_date = min_auto_promote_date ) <EOL> def _GetNextWeekdayDate ( weekday , min_date = None ) : <EOL> """<STR_LIT>""" <EOL> if min_date is None : <EOL> min_date = datetime . datetime . utcnow ( ) . date ( ) <EOL> next_date = min_date <EOL> if min_date . weekday ( ) > weekday : <EOL> next_date += datetime . timedelta ( <NUM_LIT:7> - min_date . weekday ( ) + weekday ) <EOL> else : <EOL> next_date += datetime . timedelta ( weekday - min_date . weekday ( ) ) <EOL> return next_date </s>
