def generate_survey_csv(brand): try: out=cStringIO.StringIO() surveyProps = configparsers.loadPropertyFile('survey_'+brand) """ Generate CSV file output VALUES """ surveys = datastore.get_surveys_by_brand(brand) # [ST] DEBUG: Returning just the first Survey, to test the Admin mail.send_to_admins() service # due to quota size exception on the attachment # surveys = [surveys.get()] sortedSections = None counter = 0 for survey in surveys: sections = dict() surveyResults = list() descendants = db.query_descendants(survey) for descendant in descendants: section = descendant _id = section.kind() # If the Section Model has properties, and it exists in the Survey Properties ConfigParser file (e.g. is not the User model)... if hasattr(section, 'properties') and surveyProps.has_section(_id): sections[_id] = dict() sections[_id]['index'] = surveyProps.getint(_id, 'index') sections[_id]['section'] = section surveyResults.append(sections[_id]) sortedSections = sorted(surveyResults, key=itemgetter('index'), reverse=False) if counter == 0: # for each section within the survey out.write('Created,Client,Account,') for section in sortedSections: for question, data in section['section'].properties().items(): out.write('\"'+str(surveyProps.get(section['section'].kind(), 'name')+' : '+data.verbose_name)+'\",') out.write('\n') out.write(str(survey.created.date().isoformat())+',') out.write(str(survey.user_id.name)+',') out.write(str(survey.user_id.account)+',') for section in sortedSections: for question, data in section['section'].properties().items(): answer = getattr(section['section'], question) # CGI Escape the output of the answer, in case there are '<', '>', '&' or '"' characters in there. The double quote will break the CSV formatting out.write('\"'+cgi.escape(str(answer), quote=True)+'\",') out.write('\n') counter += 1 return out except (Exception), e: logging.error(e) raise e
def action_get_survey_sections_by_brand(brand): try: memcache_key = 'survey:sections:'+str(brand) memcache_result = memcache.get(memcache_key, namespace=brand) if memcache_result is not None: logging.debug('action_get_survey_sections_by_brand() : Returning processed Survey Section results from MEMCACHE') return memcache_result else: logging.debug('action_get_survey_sections_by_brand() : Returning processed Survey Section results from DATASTORE') # Get the Surveys from the Datastore by Brand surveys = datastore.get_surveys_by_brand(brand) # Load the Survey Properties, for Content iteration in the HTML Template surveyProps = configparsers.loadPropertyFile('survey_'+brand) # Create an empty dict for Survey Sections sections = dict() # Create an empty list for all section results section_results = list() # For each Survey in the Datastore Query result for survey in surveys: # Get the Survey descendats survey_descendants = db.query_descendants(survey) for descendant in survey_descendants: # Set the Sections dict key to be the Kind (lowercase) _id = descendant.kind().lower() # Create a Section dict if _id not in sections: sections[_id] = dict( id=_id, created=survey.created, index=surveyProps.get(descendant.kind(), 'index'), name=surveyProps.get(descendant.kind(), 'name'), results = dict() ) section_results.append(sections[_id]) # for question name and value in the descendant section for question, prop in descendant.properties().items(): # If the Property is of type Integer (Long returned from Datastore, actually) if type(prop) == db.IntegerProperty: answer = getattr(descendant, question) # If we have not yet created a dict entry for this question in this section, then do so if question not in sections[_id]['results']: sections[_id]['results'][question] = dict( id=question, name=prop.verbose_name, raw=list(), count=dict(), percentage=dict(), options_length=len(prop.choices), type='multi' ) # Add the answer to the question list sections[_id]['results'][question]['raw'].append(answer) # If the Property is of type Text: if type(prop) == db.TextProperty: answer = getattr(descendant, question) # If we have not yet created a dict entry for this question in this section, then do so if question not in sections[_id]['results']: sections[_id]['results'][question] = dict( id=question, name=prop.verbose_name, answers=list(), type='single' ) # If an answer exists, include this as a tuple with the User model object as the first argument and the answer Text value as the second argument if answer != '': sections[_id]['results'][question]['answers'].append({ 'user':getattr(survey, 'user_id'), 'answer':answer, 'date':survey.created }) # Once we have iterated through all resuts, we need further processing. # This calculates the percentages of answers for multiple choice questions for section, questionSet in sections.items(): for question, data in questionSet['results'].items(): # If we have a multiple choice question we need to process the results #logging.debug(question) #logging.debug(data) if data.has_key('raw') and type(data['raw']) is list: base = {} if brand == 'razorfish': base[0]=0 base[1]=0 base[2]=0 base[3]=0 base[4]=0 base[5]=0 elif brand == 'mcdonalds': base[0]=0 base[1]=0 base[2]=0 base[3]=0 base[4]=0 counted = utils.count_unsorted_list_items(data['raw']) #logging.debug('counted') #logging.debug(counted) data['count'] = dict(base.items() + counted.items()) sorted(data['count'], reverse=False) data['percentage'] = utils.get_percentage(data['count']) # Finally, we sort our Section Results list, using the index of the section as the sort key section_results = sorted(section_results, key=itemgetter('index'), reverse=False) # Add the result to Memcache, to expire in 5 minutes if len(section_results) > 0: memcache_stored = memcache.set(memcache_key, value=section_results, time=360, namespace=brand) return section_results except Exception, e: logging.error(type(e)) logging.error(e) raise e