<commit_before>"""Handlers for MayOne.US."""

from collections import namedtuple, defaultdict
import datetime
import json
import logging
import cgi
import base64
import urllib
import datetime

from google.appengine.api import mail
from google.appengine.ext import db
from google.appengine.ext import deferred
from google.appengine.api import urlfetch
from google.appengine.api import memcache

import validictory
import webapp2


import cache
import model
from model import StretchCheckTotal
import templates
import util

import pprint
import urlparse
import paypal
from rauth import OAuth2Service

# Immutable environment with both configuration variables, and backends to be
# mocked out in tests.
Environment = namedtuple(
  'Environment',
  [
    # App engine app name, or 'local' for dev_appserver, or 'unittest' for unit
    # tests.
    'app_name',

    'stripe_public_key',

    # StripeBackend
    'stripe_backend',

    # MailingListSubscriber
    'mailing_list_subscriber',

    # MailSender
    'mail_sender',
  ])


class PaymentError(Exception):
  pass


class StripeBackend(object):
  """Interface which contacts stripe."""

  def CreateCustomer(self, email, card_token):
    """Creates a stripe customer so we can charge them later.

    Returns: A string customer id.
    """
    raise NotImplementedError()

  def RetrieveCardData(self, customer_id):
    """Retrieves a stripe customer's card data, given the id.

    Returns: A card dictionary
    """
    raise NotImplementedError()

  def Charge(self, customer_id, amount_cents):
    """Charges a customer and returns an identifier for the charge."""
    raise NotImplementedError()


class MailingListSubscriber(object):
  """Interface which signs folks up for emails."""
  def Subscribe(self, email, first_name, last_name, amount_cents, ip_addr, time,
                source, phone=None, zipcode=None, volunteer=None, skills=None,
                rootstrikers=None, nonce=None, pledgePageSlug=None, recurring=None):
    raise NotImplementedError()


_STR = dict(type='string')
_STR_optional = dict(type='string', required=False)

valid_recurrence_periods = ["monthly", "weekly", ""]
PLEDGE_SCHEMA = dict(
  type='object',
  properties=dict(
    email=_STR,
    phone=dict(type='string', blank=True),
    name=_STR,
    occupation=_STR,
    employer=_STR,
    target=_STR,
    surveyResult=_STR_optional,
    subscribe=dict(type='boolean'),
    anonymous=dict(type='boolean', required=False),
    amountCents=dict(type='integer', minimum=100, maximum=540000),
    pledgeType=dict(enum=model.Pledge.TYPE_VALUES, required=False),
    team=dict(type='string', blank=True),
    recurrence_period=dict(type='string', required=False, enum=valid_recurrence_periods),
    payment=dict(type='object',
                 properties=dict(
                   STRIPE=dict(type='object',
                               required=False,
                               properties=dict(token=_STR)),
                   PAYPAL=dict(type='object',
                               required=False,
                               properties=dict(step=_STR_optional)),
                 )
               ),
  )
)


def pledge_helper(handler, data, stripe_customer_id, stripe_charge_id, paypal_payer_id, paypal_txn_id):
    env = handler.app.config['env']

    if 'last_name' in data:
      last_name = data['last_name']
      if 'first_name' in data:
        first_name = data['first_name']
      else:
        first_name = ''
    else:
      # Split apart the name into first and last. Yes, this sucks, but adding the
      # name fields makes the form look way more daunting. We may reconsider this.
      name_parts = data['name'].split(None, 1)
      first_name = name_parts[0]
      if len(name_parts) == 1:
        last_name = ''
        logging.warning('Could not determine last name: %s', data['name'])
      else:
        last_name = name_parts[1]

    if not 'surveyResult' in data:
      data['surveyResult'] = ''

    if not 'city' in data:
      data['city'] = None

    if not 'address' in data:
      data['address'] = None
    else:
      logging.info('Address was: ' + str( data['address']))

    if not 'state' in data:
      data['state'] = None

    if not 'zipCode' in data:
      data['zipCode'] = None

    if not 'bitpay_invoice_id' in data:
      data['bitpay_invoice_id'] = None
    print data
    if not 'recurring' in data:
      data['recurring'] = False
    if not 'enddate' in data:
      data['enddate'] = ''
    if not 'recurrence_period' in data:
      data['recurrence_period'] = ''
    if not 'nationBuilderVars' in data:
      data['nationBuilderVars'] = None
    if not 'keep_donation' in data:
      data['keep_donation'] = False
    if not 'pledge_fulfillment' in data:
      data['pledge_fulfillment'] = False    

    amountCents = data['amountCents']

    user, pledge = model.addPledge(email=data['email'],
                             stripe_customer_id=stripe_customer_id,
                             stripe_charge_id=stripe_charge_id,
                             paypal_payer_id=paypal_payer_id,
                             paypal_txn_id=paypal_txn_id,
                             amount_cents=amountCents,
                             first_name=first_name,
                             last_name=last_name,
                             occupation=data['occupation'],
                             employer=data['employer'],
                             phone=data['phone'],
                             target=data['target'],
                             surveyResult=data['surveyResult'],
                             pledge_type=data.get(
                               'pledgeType', model.Pledge.TYPE_CONDITIONAL),
                             team=data['team'],
                             mail_list_optin=data['subscribe'],
                             anonymous=data.get('anonymous', False),
                             address=str(data['address']),
                             city=data['city'],
                             state=data['state'],
                             zipCode=data['zipCode'],
                             bitpay_invoice_id = data['bitpay_invoice_id'],
                             recurring=data['recurring'],
                             recurrence_period=data['recurrence_period'],
                             enddate=data['enddate'],
                             keep_donation=data['keep_donation']
                             )
    logging.info('Added pledge to database')                         
    if data['subscribe']:
      env.mailing_list_subscriber.Subscribe(
        email=data['email'],
        first_name=first_name, last_name=last_name,
        amount_cents=amountCents,
        ip_addr=handler.request.remote_addr,
        time=datetime.datetime.now(),
        source='pledge',
        phone=data['phone'],
        nonce=user.url_nonce,
        recurring=data['recurring'],
        zipcode=data['zipCode']
      )
        
    if False:
        model.addNationBuilderDonation(email=data['email'],
                             stripe_customer_id=stripe_customer_id,
                             stripe_charge_id=stripe_charge_id,
                             paypal_payer_id=paypal_payer_id,
                             paypal_txn_id=paypal_txn_id,
                             amount_cents=amountCents,
                             first_name=first_name,
                             last_name=last_name,
                             occupation=data['occupation'],
                             employer=data['employer'],
                             phone=data['phone'],
                             target=data['target'],
                             surveyResult=data['surveyResult'],
                             pledge_type=data.get(
                               'pledgeType', model.Pledge.TYPE_CONDITIONAL),
                             team=data['team'],
                             mail_list_optin=data['subscribe'],
                             anonymous=data.get('anonymous', False),
                             address=str(data['address']),
                             city=data['city'],
                             state=data['state'],
                             zipCode=data['zipCode'],
                             bitpay_invoice_id = data['bitpay_invoice_id'],
			                 recurring = data['recurring'],
			                 enddate = data['enddate'],
			                 recurrence_period = data['recurrence_period'],
			                 nationBuilderVars = data['nationBuilderVars']
                             )
        
            
    
    if data['pledge_fulfillment']: # Remove from stretch total.
      logging.info('Removing from stretch total: $%d' % int(amountCents / 100))
      stretchTotal = StretchCheckTotal.get()
      StretchCheckTotal.update( stretchTotal - amountCents)
    
    # Add to the total, adjusting 6x for recurring    
    amountRecurring = amountCents
    if data['recurring'] == True:    
      amountRecurring = amountCents * 6
      
    model.ShardedCounter.increment('TOTAL-5', amountRecurring)
    

    if data['team']:
      cache.IncrementTeamPledgeCount(data['team'], 1)
      cache.IncrementTeamTotal(data['team'], amountRecurring)

    totalStr = '$%d' % int(amountCents / 100)
    format_kwargs = {
      'name': data['name'].encode('utf-8'),
      'url_nonce': pledge.url_nonce,
      'total': totalStr,
      'user_url_nonce': user.url_nonce
    }
    if data['recurring'] == True:
      text_body = open('email/thank-you-recurring.txt').read().format(**format_kwargs)
      html_body = open('email/thank-you-recurring.html').read().format(**format_kwargs)
    else:
      text_body = open('email/thank-you.txt').read().format(**format_kwargs)
      html_body = open('email/thank-you.html').read().format(**format_kwargs)

    env.mail_sender.Send(to=data['email'].encode('utf-8'),
                         subject='Thank you for your pledge',
                         text_body=text_body,
                         html_body=html_body)
   
    id = str(pledge.key())
    receipt_url = '?receipt=%s&auth_token=%s&uut=%s' % (id, pledge.url_nonce, user.url_nonce)

    return id, pledge.url_nonce, user.url_nonce, receipt_url<commit_msg>addresses unicode issue<commit_after>"""Handlers for MayOne.US."""

from collections import namedtuple, defaultdict
import datetime
import json
import logging
import cgi
import base64
import urllib
import datetime

from google.appengine.api import mail
from google.appengine.ext import db
from google.appengine.ext import deferred
from google.appengine.api import urlfetch
from google.appengine.api import memcache

import validictory
import webapp2


import cache
import model
from model import StretchCheckTotal
import templates
import util

import pprint
import urlparse
import paypal
from rauth import OAuth2Service

# Immutable environment with both configuration variables, and backends to be
# mocked out in tests.
Environment = namedtuple(
  'Environment',
  [
    # App engine app name, or 'local' for dev_appserver, or 'unittest' for unit
    # tests.
    'app_name',

    'stripe_public_key',

    # StripeBackend
    'stripe_backend',

    # MailingListSubscriber
    'mailing_list_subscriber',

    # MailSender
    'mail_sender',
  ])


class PaymentError(Exception):
  pass


class StripeBackend(object):
  """Interface which contacts stripe."""

  def CreateCustomer(self, email, card_token):
    """Creates a stripe customer so we can charge them later.

    Returns: A string customer id.
    """
    raise NotImplementedError()

  def RetrieveCardData(self, customer_id):
    """Retrieves a stripe customer's card data, given the id.

    Returns: A card dictionary
    """
    raise NotImplementedError()

  def Charge(self, customer_id, amount_cents):
    """Charges a customer and returns an identifier for the charge."""
    raise NotImplementedError()


class MailingListSubscriber(object):
  """Interface which signs folks up for emails."""
  def Subscribe(self, email, first_name, last_name, amount_cents, ip_addr, time,
                source, phone=None, zipcode=None, volunteer=None, skills=None,
                rootstrikers=None, nonce=None, pledgePageSlug=None, recurring=None):
    raise NotImplementedError()


_STR = dict(type='string')
_STR_optional = dict(type='string', required=False)

valid_recurrence_periods = ["monthly", "weekly", ""]
PLEDGE_SCHEMA = dict(
  type='object',
  properties=dict(
    email=_STR,
    phone=dict(type='string', blank=True),
    name=_STR,
    occupation=_STR,
    employer=_STR,
    target=_STR,
    surveyResult=_STR_optional,
    subscribe=dict(type='boolean'),
    anonymous=dict(type='boolean', required=False),
    amountCents=dict(type='integer', minimum=100, maximum=540000),
    pledgeType=dict(enum=model.Pledge.TYPE_VALUES, required=False),
    team=dict(type='string', blank=True),
    recurrence_period=dict(type='string', required=False, enum=valid_recurrence_periods),
    payment=dict(type='object',
                 properties=dict(
                   STRIPE=dict(type='object',
                               required=False,
                               properties=dict(token=_STR)),
                   PAYPAL=dict(type='object',
                               required=False,
                               properties=dict(step=_STR_optional)),
                 )
               ),
  )
)


def pledge_helper(handler, data, stripe_customer_id, stripe_charge_id, paypal_payer_id, paypal_txn_id):
    env = handler.app.config['env']

    if 'last_name' in data:
      last_name = data['last_name']
      if 'first_name' in data:
        first_name = data['first_name']
      else:
        first_name = ''
    else:
      # Split apart the name into first and last. Yes, this sucks, but adding the
      # name fields makes the form look way more daunting. We may reconsider this.
      name_parts = data['name'].split(None, 1)
      first_name = name_parts[0]
      if len(name_parts) == 1:
        last_name = ''
        logging.warning('Could not determine last name: %s', data['name'])
      else:
        last_name = name_parts[1]

    if not 'surveyResult' in data:
      data['surveyResult'] = ''

    if not 'city' in data:
      data['city'] = None

    if not 'address' in data:
      data['address'] = None
    else:
      logging.info('Address was: ' + str( data['address']))

    if not 'state' in data:
      data['state'] = None

    if not 'zipCode' in data:
      data['zipCode'] = None

    if not 'bitpay_invoice_id' in data:
      data['bitpay_invoice_id'] = None
    print data
    if not 'recurring' in data:
      data['recurring'] = False
    if not 'enddate' in data:
      data['enddate'] = ''
    if not 'recurrence_period' in data:
      data['recurrence_period'] = ''
    if not 'nationBuilderVars' in data:
      data['nationBuilderVars'] = None
    if not 'keep_donation' in data:
      data['keep_donation'] = False
    if not 'pledge_fulfillment' in data:
      data['pledge_fulfillment'] = False    

    amountCents = data['amountCents']

    user, pledge = model.addPledge(email=data['email'],
                             stripe_customer_id=stripe_customer_id,
                             stripe_charge_id=stripe_charge_id,
                             paypal_payer_id=paypal_payer_id,
                             paypal_txn_id=paypal_txn_id,
                             amount_cents=amountCents,
                             first_name=first_name,
                             last_name=last_name,
                             occupation=data['occupation'],
                             employer=data['employer'],
                             phone=data['phone'],
                             target=data['target'],
                             surveyResult=data['surveyResult'],
                             pledge_type=data.get(
                               'pledgeType', model.Pledge.TYPE_CONDITIONAL),
                             team=data['team'],
                             mail_list_optin=data['subscribe'],
                             anonymous=data.get('anonymous', False),
                             address=str(data['address']),
                             city=data['city'],
                             state=data['state'],
                             zipCode=data['zipCode'],
                             bitpay_invoice_id = data['bitpay_invoice_id'],
                             recurring=data['recurring'],
                             recurrence_period=data['recurrence_period'],
                             enddate=data['enddate'],
                             keep_donation=data['keep_donation']
                             )
    logging.info('Added pledge to database')                         
    if data['subscribe']:
      env.mailing_list_subscriber.Subscribe(
        email=data['email'],
        first_name=first_name, last_name=last_name,
        amount_cents=amountCents,
        ip_addr=handler.request.remote_addr,
        time=datetime.datetime.now(),
        source='pledge',
        phone=data['phone'],
        nonce=user.url_nonce,
        recurring=data['recurring'],
        zipcode=data['zipCode']
      )
        
    if False:
        model.addNationBuilderDonation(email=data['email'],
                             stripe_customer_id=stripe_customer_id,
                             stripe_charge_id=stripe_charge_id,
                             paypal_payer_id=paypal_payer_id,
                             paypal_txn_id=paypal_txn_id,
                             amount_cents=amountCents,
                             first_name=first_name,
                             last_name=last_name,
                             occupation=data['occupation'],
                             employer=data['employer'],
                             phone=data['phone'],
                             target=data['target'],
                             surveyResult=data['surveyResult'],
                             pledge_type=data.get(
                               'pledgeType', model.Pledge.TYPE_CONDITIONAL),
                             team=data['team'],
                             mail_list_optin=data['subscribe'],
                             anonymous=data.get('anonymous', False),
                             address=str(data['address']),
                             city=data['city'],
                             state=data['state'],
                             zipCode=data['zipCode'],
                             bitpay_invoice_id = data['bitpay_invoice_id'],
			                 recurring = data['recurring'],
			                 enddate = data['enddate'],
			                 recurrence_period = data['recurrence_period'],
			                 nationBuilderVars = data['nationBuilderVars']
                             )
        
            
    
    if data['pledge_fulfillment']: # Remove from stretch total.
      logging.info('Removing from stretch total: $%d' % int(amountCents / 100))
      stretchTotal = StretchCheckTotal.get()
      StretchCheckTotal.update( stretchTotal - amountCents)
    
    # Add to the total, adjusting 6x for recurring    
    amountRecurring = amountCents
    if data['recurring'] == True:    
      amountRecurring = amountCents * 6
      
    model.ShardedCounter.increment('TOTAL-5', amountRecurring)
    

    if data['team']:
      cache.IncrementTeamPledgeCount(data['team'], 1)
      cache.IncrementTeamTotal(data['team'], amountRecurring)

    totalStr = '$%d' % int(amountCents / 100)
    format_kwargs = {
      'name': data['name'].encode('utf-8'),
      'url_nonce': pledge.url_nonce,
      'total': totalStr,
      'user_url_nonce': user.url_nonce
    }
    if data['recurring'] == True:
      text_body = open('email/thank-you-recurring.txt').read().format(**format_kwargs)
      html_body = open('email/thank-you-recurring.html').read().format(**format_kwargs)
    else:
      text_body = open('email/thank-you.txt').read().format(**format_kwargs)
      html_body = open('email/thank-you.html').read().format(**format_kwargs)

    env.mail_sender.Send(to=data['email'].encode('utf-8'),
                         subject='Thank you for your pledge',
                         text_body=text_body,
                         html_body=html_body)
   
    id = str(pledge.key())
    receipt_url = '?receipt=%s&auth_token=%s&uut=%s' % (id, str(pledge.url_nonce), str(user.url_nonce))

    return id, pledge.url_nonce, user.url_nonce, receipt_url
{'fraction_non_alphanumeric': 0.10551932249586295, 'fraction_numerical': 0.0028229339044096176, 'mean_word_length': 2.013198416190057, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6844054', 'n_tokens_mistral': 5883, 'n_tokens_neox': 5714, 'n_words': 1145}