#NEWLINE# def ReadData( self , source ) : #NEWLINE# #INDENT# 'Parses source option and reads appropriate data source.\n\n    Args:\n      source: Source of Appstats data. Either filename if being read from\n        a file or MEMCACHE if being read from memcache.\n    Returns:\n      errormessage: An error message to display to the user if an error occured\n        while reading data, None if no error occured.\n      recordlist: A list of Appstats records in RequestStatProto protobuf format\n        in reverse chronological order (i.e. most recent first).\n    ' #NEWLINE# errormessage = None #NEWLINE# recordlist = None #NEWLINE# if ( source == 'MEMCACHE' ) : #NEWLINE# #INDENT# recordlist = loader . FromMemcache ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# rootdir = self . GetRoot ( ) #NEWLINE# if ( rootdir is None ) : #NEWLINE# #INDENT# errormessage = 'No parent directory has app.yaml!' #NEWLINE# return ( errormessage , recordlist ) #NEWLINE# #UNINDENT# source_root = os . path . join ( rootdir , source ) #NEWLINE# try : #NEWLINE# #INDENT# outfile = mockable_open ( source_root , 'rb' ) #NEWLINE# #UNINDENT# except IOError : #NEWLINE# #INDENT# logging . error ( 'Cannot open %s' , source ) #NEWLINE# errormessage = 'Unable to open file!' #NEWLINE# return ( errormessage , recordlist ) #NEWLINE# #UNINDENT# mtime = os . path . getmtime ( source_root ) #NEWLINE# if cache . IsCached ( source , mtime ) : #NEWLINE# #INDENT# logging . info ( 'Using cached records from %s' , source ) #NEWLINE# recordlist = cache . recordlist #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# logging . info ( 'Reading fresh records from %s' , source ) #NEWLINE# recordlist = loader . UnpickleFromFile ( outfile ) #NEWLINE# cache . Insert ( source , mtime , recordlist ) #NEWLINE# #UNINDENT# #UNINDENT# return ( errormessage , recordlist )