<s> import json <EOL> import operator <EOL> from datetime import datetime , date , timedelta <EOL> from functools import reduce <EOL> from django . conf import settings <EOL> from django . db . models import Count , F , Q <EOL> import cronjobs <EOL> import requests <EOL> from statsd import statsd <EOL> from kitsune . customercare . models import Reply <EOL> from kitsune . dashboards import LAST_90_DAYS <EOL> from kitsune . dashboards . models import WikiDocumentVisits <EOL> from kitsune . kpi . models import ( <EOL> Metric , MetricKind , CohortKind , Cohort , RetentionMetric , AOA_CONTRIBUTORS_METRIC_CODE , <EOL> KB_ENUS_CONTRIBUTORS_METRIC_CODE , KB_L10N_CONTRIBUTORS_METRIC_CODE , L10N_METRIC_CODE , <EOL> SUPPORT_FORUM_CONTRIBUTORS_METRIC_CODE , VISITORS_METRIC_CODE , SEARCH_SEARCHES_METRIC_CODE , <EOL> SEARCH_CLICKS_METRIC_CODE , EXIT_SURVEY_YES_CODE , EXIT_SURVEY_NO_CODE , <EOL> EXIT_SURVEY_DONT_KNOW_CODE , CONTRIBUTOR_COHORT_CODE , KB_ENUS_CONTRIBUTOR_COHORT_CODE , <EOL> KB_L10N_CONTRIBUTOR_COHORT_CODE , SUPPORT_FORUM_HELPER_COHORT_CODE , AOA_CONTRIBUTOR_COHORT_CODE , <EOL> CONTRIBUTORS_CSAT_METRIC_CODE , AOA_CONTRIBUTORS_CSAT_METRIC_CODE , <EOL> KB_ENUS_CONTRIBUTORS_CSAT_METRIC_CODE , KB_L10N_CONTRIBUTORS_CSAT_METRIC_CODE , <EOL> SUPPORT_FORUM_CONTRIBUTORS_CSAT_METRIC_CODE ) <EOL> from kitsune . kpi . surveygizmo_utils import ( <EOL> get_email_addresses , add_email_to_campaign , get_exit_survey_results , <EOL> SURVEYS ) <EOL> from kitsune . questions . models import Answer , Question <EOL> from kitsune . sumo import googleanalytics <EOL> from kitsune . wiki . config import TYPO_SIGNIFICANCE , MEDIUM_SIGNIFICANCE <EOL> from kitsune . wiki . models import Revision <EOL> @ cronjobs . register <EOL> def update_visitors_metric ( ) : <EOL> """<STR_LIT>""" <EOL> if settings . STAGE : <EOL> return <EOL> latest_metric = _get_latest_metric ( VISITORS_METRIC_CODE ) <EOL> if latest_metric is not None : <EOL> latest_metric_date = latest_metric . start <EOL> else : <EOL> latest_metric_date = date ( <NUM_LIT> , <NUM_LIT:0> <NUM_LIT:1> , <NUM_LIT:0> <NUM_LIT:1> ) <EOL> start = latest_metric_date + timedelta ( days = <NUM_LIT:1> ) <EOL> end = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> visitors = googleanalytics . visitors ( start , end ) <EOL> metric_kind = MetricKind . objects . get ( code = VISITORS_METRIC_CODE ) <EOL> for date_str , visits in visitors . items ( ) : <EOL> day = datetime . strptime ( date_str , '<STR_LIT>' ) . date ( ) <EOL> Metric . objects . create ( <EOL> kind = metric_kind , <EOL> start = day , <EOL> end = day + timedelta ( days = <NUM_LIT:1> ) , <EOL> value = visits ) <EOL> MAX_DOCS_UP_TO_DATE = <NUM_LIT:50> <EOL> @ cronjobs . register <EOL> def update_l10n_metric ( ) : <EOL> """<STR_LIT>""" <EOL> if settings . STAGE : <EOL> return <EOL> top_60_docs = _get_top_docs ( <NUM_LIT> ) <EOL> end = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> start = end - timedelta ( days = <NUM_LIT:30> ) <EOL> locale_visits = googleanalytics . visitors_by_locale ( start , end ) <EOL> total_visits = sum ( locale_visits . itervalues ( ) ) <EOL> coverage = <NUM_LIT:0> <EOL> for locale , visits in locale_visits . iteritems ( ) : <EOL> if locale == settings . WIKI_DEFAULT_LANGUAGE : <EOL> num_docs = MAX_DOCS_UP_TO_DATE <EOL> up_to_date_docs = MAX_DOCS_UP_TO_DATE <EOL> else : <EOL> up_to_date_docs , num_docs = _get_up_to_date_count ( <EOL> top_60_docs , locale ) <EOL> if num_docs and total_visits : <EOL> coverage += ( ( float ( up_to_date_docs ) / num_docs ) * <EOL> ( float ( visits ) / total_visits ) ) <EOL> metric_kind = MetricKind . objects . get ( code = L10N_METRIC_CODE ) <EOL> day = date . today ( ) <EOL> Metric . objects . create ( <EOL> kind = metric_kind , <EOL> start = day , <EOL> end = day + timedelta ( days = <NUM_LIT:1> ) , <EOL> value = int ( coverage * <NUM_LIT:100> ) ) <EOL> @ cronjobs . register <EOL> def update_contributor_metrics ( day = None ) : <EOL> """<STR_LIT>""" <EOL> if settings . STAGE : <EOL> return <EOL> update_support_forum_contributors_metric ( day ) <EOL> update_kb_contributors_metric ( day ) <EOL> update_aoa_contributors_metric ( day ) <EOL> def update_support_forum_contributors_metric ( day = None ) : <EOL> """<STR_LIT>""" <EOL> if day : <EOL> start = end = day <EOL> else : <EOL> latest_metric = _get_latest_metric ( <EOL> SUPPORT_FORUM_CONTRIBUTORS_METRIC_CODE ) <EOL> if latest_metric is not None : <EOL> start = latest_metric . end + timedelta ( days = <NUM_LIT:1> ) <EOL> else : <EOL> start = date ( <NUM_LIT> , <NUM_LIT:0> <NUM_LIT:1> , <NUM_LIT:0> <NUM_LIT:1> ) <EOL> end = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> day = start <EOL> while day <= end : <EOL> thirty_days_back = day - timedelta ( days = <NUM_LIT:30> ) <EOL> contributors = ( <EOL> Answer . objects . exclude ( creator = F ( '<STR_LIT>' ) ) <EOL> . filter ( created__gte = thirty_days_back , <EOL> created__lt = day ) <EOL> . values ( '<STR_LIT>' ) <EOL> . annotate ( count = Count ( '<STR_LIT>' ) ) <EOL> . filter ( count__gte = <NUM_LIT:10> ) ) <EOL> count = contributors . count ( ) <EOL> metric_kind = MetricKind . objects . get ( <EOL> code = SUPPORT_FORUM_CONTRIBUTORS_METRIC_CODE ) <EOL> Metric . objects . create ( <EOL> kind = metric_kind , <EOL> start = thirty_days_back , <EOL> end = day , <EOL> value = count ) <EOL> day = day + timedelta ( days = <NUM_LIT:1> ) <EOL> def update_kb_contributors_metric ( day = None ) : <EOL> """<STR_LIT>""" <EOL> if day : <EOL> start = end = day <EOL> else : <EOL> latest_metric = _get_latest_metric ( KB_ENUS_CONTRIBUTORS_METRIC_CODE ) <EOL> if latest_metric is not None : <EOL> start = latest_metric . end + timedelta ( days = <NUM_LIT:1> ) <EOL> else : <EOL> start = date ( <NUM_LIT> , <NUM_LIT:0> <NUM_LIT:1> , <NUM_LIT:0> <NUM_LIT:1> ) <EOL> end = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> day = start <EOL> while day <= end : <EOL> thirty_days_back = day - timedelta ( days = <NUM_LIT:30> ) <EOL> editors = ( <EOL> Revision . objects . filter ( <EOL> created__gte = thirty_days_back , <EOL> created__lt = day ) <EOL> . values_list ( '<STR_LIT>' , flat = True ) . distinct ( ) ) <EOL> reviewers = ( <EOL> Revision . objects . filter ( <EOL> reviewed__gte = thirty_days_back , <EOL> reviewed__lt = day ) <EOL> . values_list ( '<STR_LIT>' , flat = True ) . distinct ( ) ) <EOL> en_us_count = len ( set ( <EOL> list ( editors . filter ( document__locale = '<STR_LIT>' ) ) + <EOL> list ( reviewers . filter ( document__locale = '<STR_LIT>' ) ) <EOL> ) ) <EOL> l10n_count = len ( set ( <EOL> list ( editors . exclude ( document__locale = '<STR_LIT>' ) ) + <EOL> list ( reviewers . exclude ( document__locale = '<STR_LIT>' ) ) <EOL> ) ) <EOL> metric_kind = MetricKind . objects . get ( <EOL> code = KB_ENUS_CONTRIBUTORS_METRIC_CODE ) <EOL> Metric . objects . create ( <EOL> kind = metric_kind , <EOL> start = thirty_days_back , <EOL> end = day , <EOL> value = en_us_count ) <EOL> metric_kind = MetricKind . objects . get ( <EOL> code = KB_L10N_CONTRIBUTORS_METRIC_CODE ) <EOL> Metric . objects . create ( <EOL> kind = metric_kind , <EOL> start = thirty_days_back , <EOL> end = day , <EOL> value = l10n_count ) <EOL> day = day + timedelta ( days = <NUM_LIT:1> ) <EOL> def update_aoa_contributors_metric ( day = None ) : <EOL> """<STR_LIT>""" <EOL> if day : <EOL> start = end = day <EOL> else : <EOL> latest_metric = _get_latest_metric ( AOA_CONTRIBUTORS_METRIC_CODE ) <EOL> if latest_metric is not None : <EOL> start = latest_metric . end + timedelta ( days = <NUM_LIT:1> ) <EOL> else : <EOL> try : <EOL> first_reply = Reply . objects . order_by ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> start = first_reply . created . date ( ) + timedelta ( days = <NUM_LIT:30> ) <EOL> except IndexError : <EOL> return <EOL> end = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> day = start <EOL> while day <= end : <EOL> thirty_days_back = day - timedelta ( days = <NUM_LIT:30> ) <EOL> contributors = ( <EOL> Reply . objects . filter ( <EOL> created__gte = thirty_days_back , <EOL> created__lt = day ) <EOL> . values_list ( '<STR_LIT>' ) . distinct ( ) ) <EOL> count = contributors . count ( ) <EOL> metric_kind = MetricKind . objects . get ( code = AOA_CONTRIBUTORS_METRIC_CODE ) <EOL> Metric . objects . create ( <EOL> kind = metric_kind , <EOL> start = thirty_days_back , <EOL> end = day , <EOL> value = count ) <EOL> day = day + timedelta ( days = <NUM_LIT:1> ) <EOL> @ cronjobs . register <EOL> def update_search_ctr_metric ( ) : <EOL> """<STR_LIT>""" <EOL> if settings . STAGE : <EOL> return <EOL> latest_metric = _get_latest_metric ( SEARCH_CLICKS_METRIC_CODE ) <EOL> if latest_metric is not None : <EOL> latest_metric_date = latest_metric . start <EOL> else : <EOL> latest_metric_date = date ( <NUM_LIT> , <NUM_LIT:0> <NUM_LIT:1> , <NUM_LIT:0> <NUM_LIT:1> ) <EOL> start = latest_metric_date + timedelta ( days = <NUM_LIT:1> ) <EOL> end = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> ctr_data = googleanalytics . search_ctr ( start , end ) <EOL> clicks_kind = MetricKind . objects . get ( code = SEARCH_CLICKS_METRIC_CODE ) <EOL> searches_kind = MetricKind . objects . get ( code = SEARCH_SEARCHES_METRIC_CODE ) <EOL> for date_str , ctr in ctr_data . items ( ) : <EOL> day = datetime . strptime ( date_str , '<STR_LIT>' ) . date ( ) <EOL> Metric . objects . create ( <EOL> kind = searches_kind , <EOL> start = day , <EOL> end = day + timedelta ( days = <NUM_LIT:1> ) , <EOL> value = <NUM_LIT:1000> ) <EOL> Metric . objects . create ( <EOL> kind = clicks_kind , <EOL> start = day , <EOL> end = day + timedelta ( days = <NUM_LIT:1> ) , <EOL> value = round ( ctr , <NUM_LIT:1> ) * <NUM_LIT:10> ) <EOL> def _get_latest_metric ( metric_code ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> last_metric = Metric . objects . filter ( <EOL> kind__code = metric_code ) . order_by ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> return last_metric <EOL> except IndexError : <EOL> return None <EOL> def _get_top_docs ( count ) : <EOL> """<STR_LIT>""" <EOL> top_qs = WikiDocumentVisits . objects . select_related ( '<STR_LIT>' ) . filter ( <EOL> period = LAST_90_DAYS ) . order_by ( '<STR_LIT>' ) [ : count ] <EOL> return [ v . document for v in top_qs ] <EOL> def _get_up_to_date_count ( top_60_docs , locale ) : <EOL> up_to_date_docs = <NUM_LIT:0> <EOL> num_docs = <NUM_LIT:0> <EOL> for doc in top_60_docs : <EOL> if num_docs == MAX_DOCS_UP_TO_DATE : <EOL> break <EOL> if not doc . is_localizable : <EOL> continue <EOL> num_docs += <NUM_LIT:1> <EOL> cur_rev_id = doc . latest_localizable_revision_id <EOL> translation = doc . translated_to ( locale ) <EOL> if not translation or not translation . current_revision_id : <EOL> continue <EOL> if translation . current_revision . based_on_id >= cur_rev_id : <EOL> up_to_date_docs += <NUM_LIT:1> <EOL> else : <EOL> revs = doc . revisions . filter ( <EOL> id__gt = translation . current_revision . based_on_id , <EOL> is_approved = True , <EOL> id__lte = cur_rev_id ) . exclude ( significance = TYPO_SIGNIFICANCE ) <EOL> if not revs . exists ( ) : <EOL> up_to_date_docs += <NUM_LIT:1> <EOL> elif ( len ( revs ) == <NUM_LIT:1> and <EOL> revs [ <NUM_LIT:0> ] . significance == MEDIUM_SIGNIFICANCE ) : <EOL> up_to_date_docs += <NUM_LIT:0.5> <EOL> return up_to_date_docs , num_docs <EOL> @ cronjobs . register <EOL> def process_exit_surveys ( ) : <EOL> """<STR_LIT>""" <EOL> _process_exit_survey_results ( ) <EOL> if settings . STAGE : <EOL> return <EOL> startdate = date . today ( ) - timedelta ( days = <NUM_LIT:2> ) <EOL> enddate = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> for survey in SURVEYS . keys ( ) : <EOL> if '<STR_LIT>' not in SURVEYS [ survey ] : <EOL> continue <EOL> emails = get_email_addresses ( survey , startdate , enddate ) <EOL> for email in emails : <EOL> add_email_to_campaign ( survey , email ) <EOL> statsd . gauge ( '<STR_LIT>' . format ( survey ) , len ( emails ) ) <EOL> def _process_exit_survey_results ( ) : <EOL> """<STR_LIT>""" <EOL> yes_kind , _ = MetricKind . objects . get_or_create ( code = EXIT_SURVEY_YES_CODE ) <EOL> no_kind , _ = MetricKind . objects . get_or_create ( code = EXIT_SURVEY_NO_CODE ) <EOL> dunno_kind , _ = MetricKind . objects . get_or_create ( <EOL> code = EXIT_SURVEY_DONT_KNOW_CODE ) <EOL> latest_metric = _get_latest_metric ( EXIT_SURVEY_YES_CODE ) <EOL> if latest_metric is not None : <EOL> latest_metric_date = latest_metric . start <EOL> else : <EOL> latest_metric_date = date ( <NUM_LIT> , <NUM_LIT:0> <NUM_LIT:7> , <NUM_LIT:0> <NUM_LIT:1> ) <EOL> day = latest_metric_date + timedelta ( days = <NUM_LIT:1> ) <EOL> today = date . today ( ) <EOL> while day < today : <EOL> results = get_exit_survey_results ( '<STR_LIT>' , day ) <EOL> Metric . objects . create ( <EOL> kind = yes_kind , <EOL> start = day , <EOL> end = day + timedelta ( days = <NUM_LIT:1> ) , <EOL> value = results [ '<STR_LIT:yes>' ] ) <EOL> Metric . objects . create ( <EOL> kind = no_kind , <EOL> start = day , <EOL> end = day + timedelta ( days = <NUM_LIT:1> ) , <EOL> value = results [ '<STR_LIT>' ] ) <EOL> Metric . objects . create ( <EOL> kind = dunno_kind , <EOL> start = day , <EOL> end = day + timedelta ( days = <NUM_LIT:1> ) , <EOL> value = results [ '<STR_LIT>' ] ) <EOL> day += timedelta ( days = <NUM_LIT:1> ) <EOL> @ cronjobs . register <EOL> def survey_recent_askers ( ) : <EOL> """<STR_LIT>""" <EOL> if settings . STAGE : <EOL> return <EOL> two_days_ago = date . today ( ) - timedelta ( days = <NUM_LIT:2> ) <EOL> yesterday = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> emails = ( <EOL> Question . objects <EOL> . filter ( created__gte = two_days_ago , created__lt = yesterday ) <EOL> . values_list ( '<STR_LIT>' , flat = True ) ) <EOL> for email in emails : <EOL> add_email_to_campaign ( '<STR_LIT>' , email ) <EOL> statsd . gauge ( '<STR_LIT>' , len ( emails ) ) <EOL> @ cronjobs . register <EOL> def cohort_analysis ( ) : <EOL> today = datetime . today ( ) . replace ( hour = <NUM_LIT:0> , minute = <NUM_LIT:0> , second = <NUM_LIT:0> , microsecond = <NUM_LIT:0> ) <EOL> boundaries = [ today - timedelta ( days = today . weekday ( ) ) ] <EOL> for _ in range ( <NUM_LIT:12> ) : <EOL> previous_week = boundaries [ - <NUM_LIT:1> ] - timedelta ( weeks = <NUM_LIT:1> ) <EOL> boundaries . append ( previous_week ) <EOL> boundaries . reverse ( ) <EOL> ranges = zip ( boundaries [ : - <NUM_LIT:1> ] , boundaries [ <NUM_LIT:1> : ] ) <EOL> reports = [ <EOL> ( CONTRIBUTOR_COHORT_CODE , [ <EOL> ( Revision . objects . all ( ) , ( '<STR_LIT>' , '<STR_LIT>' , ) ) , <EOL> ( Answer . objects . not_by_asker ( ) , ( '<STR_LIT>' , ) ) , <EOL> ( Reply . objects . all ( ) , ( '<STR_LIT:user>' , ) ) ] ) , <EOL> ( KB_ENUS_CONTRIBUTOR_COHORT_CODE , [ <EOL> ( Revision . objects . filter ( document__locale = '<STR_LIT>' ) , ( '<STR_LIT>' , '<STR_LIT>' , ) ) ] ) , <EOL> ( KB_L10N_CONTRIBUTOR_COHORT_CODE , [ <EOL> ( Revision . objects . exclude ( document__locale = '<STR_LIT>' ) , ( '<STR_LIT>' , '<STR_LIT>' , ) ) ] ) , <EOL> ( SUPPORT_FORUM_HELPER_COHORT_CODE , [ <EOL> ( Answer . objects . not_by_asker ( ) , ( '<STR_LIT>' , ) ) ] ) , <EOL> ( AOA_CONTRIBUTOR_COHORT_CODE , [ <EOL> ( Reply . objects . all ( ) , ( '<STR_LIT:user>' , ) ) ] ) <EOL> ] <EOL> for kind , querysets in reports : <EOL> cohort_kind , _ = CohortKind . objects . get_or_create ( code = kind ) <EOL> for i , cohort_range in enumerate ( ranges ) : <EOL> cohort_users = _get_cohort ( querysets , cohort_range ) <EOL> if None in cohort_users : <EOL> cohort_users . remove ( None ) <EOL> cohort , _ = Cohort . objects . update_or_create ( <EOL> kind = cohort_kind , start = cohort_range [ <NUM_LIT:0> ] , end = cohort_range [ <NUM_LIT:1> ] , <EOL> defaults = { '<STR_LIT:size>' : len ( cohort_users ) } ) <EOL> for retention_range in ranges [ i : ] : <EOL> retained_user_count = _count_contributors_in_range ( querysets , cohort_users , <EOL> retention_range ) <EOL> RetentionMetric . objects . update_or_create ( <EOL> cohort = cohort , start = retention_range [ <NUM_LIT:0> ] , end = retention_range [ <NUM_LIT:1> ] , <EOL> defaults = { '<STR_LIT:size>' : retained_user_count } ) <EOL> def _count_contributors_in_range ( querysets , users , date_range ) : <EOL> """<STR_LIT>""" <EOL> start , end = date_range <EOL> retained_users = set ( ) <EOL> for queryset , fields in querysets : <EOL> for field in fields : <EOL> filters = { '<STR_LIT>' % field : users , '<STR_LIT>' : start , '<STR_LIT>' : end } <EOL> retained_users |= set ( getattr ( o , field ) for o in queryset . filter ( ** filters ) ) <EOL> return len ( retained_users ) <EOL> def _get_cohort ( querysets , date_range ) : <EOL> start , end = date_range <EOL> cohort = set ( ) <EOL> for queryset , fields in querysets : <EOL> contributions_in_range = queryset . filter ( created__gte = start , created__lt = end ) <EOL> potential_users = set ( ) <EOL> for field in fields : <EOL> potential_users |= set ( getattr ( cont , field ) for cont in contributions_in_range ) <EOL> def is_in_cohort ( u ) : <EOL> qs = [ Q ( ** { field : u } ) for field in fields ] <EOL> filters = reduce ( operator . or_ , qs ) <EOL> first_contrib = queryset . filter ( filters ) . order_by ( '<STR_LIT:id>' ) [ <NUM_LIT:0> ] <EOL> return start <= first_contrib . created < end <EOL> cohort |= set ( filter ( is_in_cohort , potential_users ) ) <EOL> return cohort <EOL> @ cronjobs . register <EOL> def calculate_csat_metrics ( ) : <EOL> user = settings . SURVEYGIZMO_USER <EOL> password = settings . SURVEYGIZMO_PASSWORD <EOL> startdate = date . today ( ) - timedelta ( days = <NUM_LIT:2> ) <EOL> enddate = date . today ( ) - timedelta ( days = <NUM_LIT:1> ) <EOL> page = <NUM_LIT:1> <EOL> more_pages = True <EOL> survey_id = SURVEYS [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> csat = { <EOL> CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> SUPPORT_FORUM_CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> AOA_CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> KB_ENUS_CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> KB_L10N_CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> } <EOL> counts = { <EOL> CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> SUPPORT_FORUM_CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> AOA_CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> KB_ENUS_CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> KB_L10N_CONTRIBUTORS_CSAT_METRIC_CODE : <NUM_LIT:0> , <EOL> } <EOL> while more_pages : <EOL> response = requests . get ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( <EOL> survey = survey_id , start = startdate , <EOL> end = enddate , page = page , user = user , password = password ) , <EOL> timeout = <NUM_LIT> ) <EOL> results = json . loads ( response . content ) <EOL> total_pages = results . get ( '<STR_LIT>' , <NUM_LIT:1> ) <EOL> more_pages = page < total_pages <EOL> if '<STR_LIT:data>' in results : <EOL> for r in results [ '<STR_LIT:data>' ] : <EOL> try : <EOL> rating = int ( r [ '<STR_LIT>' ] ) <EOL> except ValueError : <EOL> pass <EOL> else : <EOL> csat [ CONTRIBUTORS_CSAT_METRIC_CODE ] += rating <EOL> counts [ CONTRIBUTORS_CSAT_METRIC_CODE ] += <NUM_LIT:1> <EOL> if len ( r [ '<STR_LIT>' ] ) : <EOL> csat [ AOA_CONTRIBUTORS_CSAT_METRIC_CODE ] += rating <EOL> counts [ AOA_CONTRIBUTORS_CSAT_METRIC_CODE ] += <NUM_LIT:1> <EOL> if len ( r [ '<STR_LIT>' ] ) : <EOL> csat [ SUPPORT_FORUM_CONTRIBUTORS_CSAT_METRIC_CODE ] += rating <EOL> counts [ SUPPORT_FORUM_CONTRIBUTORS_CSAT_METRIC_CODE ] += <NUM_LIT:1> <EOL> if len ( r [ '<STR_LIT>' ] ) : <EOL> csat [ KB_ENUS_CONTRIBUTORS_CSAT_METRIC_CODE ] += rating <EOL> counts [ KB_ENUS_CONTRIBUTORS_CSAT_METRIC_CODE ] += <NUM_LIT:1> <EOL> if len ( r [ '<STR_LIT>' ] ) : <EOL> csat [ KB_L10N_CONTRIBUTORS_CSAT_METRIC_CODE ] += rating <EOL> counts [ KB_L10N_CONTRIBUTORS_CSAT_METRIC_CODE ] += <NUM_LIT:1> <EOL> page += <NUM_LIT:1> <EOL> for code in csat : <EOL> metric_kind , _ = MetricKind . objects . get_or_create ( code = code ) <EOL> value = csat [ code ] / counts [ code ] if counts [ code ] else <NUM_LIT:50> <EOL> Metric . objects . update_or_create ( kind = metric_kind , start = startdate , end = enddate , <EOL> defaults = { '<STR_LIT:value>' : value } ) <EOL> @ cronjobs . register <EOL> def csat_survey_emails ( ) : <EOL> querysets = [ ( Revision . objects . all ( ) , ( '<STR_LIT>' , '<STR_LIT>' , ) ) , <EOL> ( Answer . objects . not_by_asker ( ) , ( '<STR_LIT>' , ) ) , <EOL> ( Reply . objects . all ( ) , ( '<STR_LIT:user>' , ) ) ] <EOL> end = datetime . today ( ) . replace ( hour = <NUM_LIT:0> , minute = <NUM_LIT:0> , second = <NUM_LIT:0> , microsecond = <NUM_LIT:0> ) <EOL> start = end - timedelta ( days = <NUM_LIT:30> ) <EOL> users = _get_cohort ( querysets , ( start , end ) ) <EOL> for u in users : <EOL> p = u . profile <EOL> if p . csat_email_sent is None or p . csat_email_sent < start : <EOL> survey_id = SURVEYS [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> campaign_id = SURVEYS [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> try : <EOL> requests . put ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( <EOL> survey = survey_id , campaign = campaign_id , email = u . email , <EOL> token = settings . SURVEYGIZMO_API_TOKEN , <EOL> secret = settings . SURVEYGIZMO_API_TOKEN_SECRET ) , <EOL> timeout = <NUM_LIT:30> ) <EOL> except requests . exceptions . Timeout : <EOL> print '<STR_LIT>' % u . email <EOL> else : <EOL> p . csat_email_sent = datetime . now ( ) <EOL> p . save ( ) </s>
