#NEWLINE# def _GenerateMsuUserSummary( self , since_days = None , now = None ) : #NEWLINE# #INDENT# 'Generate summary of MSU user data.\n\n    Args:\n      since_days: int, optional, only report on the last x days\n      now: datetime.datetime, optional, supply an alternative\n        value for the current date/time\n    ' #NEWLINE# lock_name = 'msu_user_summary_lock' #NEWLINE# cursor_name = 'msu_user_summary_cursor' #NEWLINE# if ( since_days is None ) : #NEWLINE# #INDENT# since = None #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# since = ( '%dD' % since_days ) #NEWLINE# lock_name = ( '%s_%s' % ( lock_name , since ) ) #NEWLINE# cursor_name = ( '%s_%s' % ( cursor_name , since ) ) #NEWLINE# #UNINDENT# lock = gae_util . ObtainLock ( lock_name ) #NEWLINE# if ( not lock ) : #NEWLINE# #INDENT# logging . warning ( 'GenerateMsuUserSummary lock found; exiting.' ) #NEWLINE# return #NEWLINE# #UNINDENT# interested_events = self . USER_EVENTS #NEWLINE# lquery = models . ComputerMSULog . all ( ) #NEWLINE# cursor = models . KeyValueCache . MemcacheWrappedGet ( cursor_name , 'text_value' ) #NEWLINE# ( summary , unused_dt ) = models . ReportsCache . GetMsuUserSummary ( since = since , tmp = True ) #NEWLINE# if ( cursor and summary ) : #NEWLINE# #INDENT# lquery . with_cursor ( cursor ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# summary = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# for event in interested_events : #NEWLINE# #INDENT# summary [ event ] = 0 #NEWLINE# #UNINDENT# summary [ 'total_events' ] = 0 #NEWLINE# summary [ 'total_users' ] = 0 #NEWLINE# summary [ 'total_uuids' ] = 0 #NEWLINE# models . ReportsCache . SetMsuUserSummary ( summary , since = since , tmp = True ) #NEWLINE# #UNINDENT# begin = time . time ( ) #NEWLINE# if ( now is None ) : #NEWLINE# #INDENT# now = datetime . datetime . utcnow ( ) #NEWLINE# #UNINDENT# while True : #NEWLINE# #INDENT# reports = lquery . fetch ( self . FETCH_LIMIT ) #NEWLINE# if ( not reports ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# userdata = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# last_user = None #NEWLINE# last_user_cursor = None #NEWLINE# prev_user_cursor = None #NEWLINE# n = 0 #NEWLINE# for report in reports : #NEWLINE# #INDENT# userdata . setdefault ( report . user , { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } ) #NEWLINE# userdata [ report . user ] . setdefault ( report . uuid , { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } ) . update ( { #NEWLINE# #INDENT# report . event : report . mtime , #NEWLINE# #UNINDENT# } ) #NEWLINE# if ( last_user != report . user ) : #NEWLINE# #INDENT# last_user = report . user #NEWLINE# prev_user_cursor = last_user_cursor #NEWLINE# last_user_cursor = str ( lquery . cursor ( ) ) #NEWLINE# #UNINDENT# n += 1 #NEWLINE# #UNINDENT# if ( n == self . FETCH_LIMIT ) : #NEWLINE# #INDENT# del userdata [ last_user ] #NEWLINE# last_user_cursor = prev_user_cursor #NEWLINE# #UNINDENT# for user in userdata : #NEWLINE# #INDENT# events = 0 #NEWLINE# for uuid in userdata [ user ] : #NEWLINE# #INDENT# if ( 'launched' not in userdata [ user ] [ uuid ] ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# for event in userdata [ user ] [ uuid ] : #NEWLINE# #INDENT# if ( ( since_days is None ) or IsTimeDelta ( userdata [ user ] [ uuid ] [ event ] , now , days = since_days ) ) : #NEWLINE# #INDENT# summary . setdefault ( event , 0 ) #NEWLINE# summary [ event ] += 1 #NEWLINE# summary [ 'total_events' ] += 1 #NEWLINE# events += 1 #NEWLINE# #UNINDENT# #UNINDENT# if events : #NEWLINE# #INDENT# summary [ 'total_uuids' ] += 1 #NEWLINE# #UNINDENT# #UNINDENT# if events : #NEWLINE# #INDENT# summary [ 'total_users' ] += 1 #NEWLINE# summary . setdefault ( ( 'total_users_%d_events' % events ) , 0 ) #NEWLINE# summary [ ( 'total_users_%d_events' % events ) ] += 1 #NEWLINE# #UNINDENT# #UNINDENT# lquery = models . ComputerMSULog . all ( ) #NEWLINE# lquery . with_cursor ( last_user_cursor ) #NEWLINE# end = time . time ( ) #NEWLINE# if ( ( end - begin ) > RUNTIME_MAX_SECS ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# #UNINDENT# if reports : #NEWLINE# #INDENT# models . ReportsCache . SetMsuUserSummary ( summary , since = since , tmp = True ) #NEWLINE# models . KeyValueCache . MemcacheWrappedSet ( cursor_name , 'text_value' , last_user_cursor ) #NEWLINE# if since_days : #NEWLINE# #INDENT# args = ( '/%d' % since_days ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# args = '' #NEWLINE# #UNINDENT# taskqueue . add ( url = ( '/cron/reports_cache/msu_user_summary%s' % args ) , method = 'GET' , countdown = 5 ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# models . ReportsCache . SetMsuUserSummary ( summary , since = since ) #NEWLINE# models . KeyValueCache . DeleteMemcacheWrap ( cursor_name , prop_name = 'text_value' ) #NEWLINE# models . ReportsCache . DeleteMsuUserSummary ( since = since , tmp = True ) #NEWLINE# #UNINDENT# gae_util . ReleaseLock ( lock_name )