Example #1
0
def handle_get(http_server, database_manager, session, account):
    subscription_plan_template = SubscriptionPlan(database_manager)
    subscription_conditions = [{
        "column": "is_active",
        "equivalence": "=",
        "value": 1
    }]
    subscription_plans = database_manager.fetch_by(subscription_plan_template,
                                                   subscription_conditions)
    billing_profiles = []
    for subscription_plan in subscription_plans:
        billing_profiles.append({
            "slug":
            subscription_plan.name,
            "name":
            subscription_plan.name.title(),
            "amount":
            subscription_plan.amount,
            "currency":
            subscription_plan.currency,
            "allowed_requests_per_month":
            subscription_plan.allowed_requests_per_month,
            "allowed_requests_per_month_printed":
            "{:,}".format(subscription_plan.allowed_requests_per_month),
        })

    template = fetch_template("account/register.jinja.htm")
    keys = {"billing_profiles": billing_profiles, "errors": [], "response": []}
    output = template.render(keys)
    http_server.print_headers()
    print(output)
Example #2
0
def handle_get(http_server, database_manager, ip, account, api_key):
    query_params = http_server.get_query_parameters()
    if "city" not in query_params:
        raise ApiParamNoCityProvidedError
    if "state" not in query_params:
        raise ApiParamNoStateCodeProvidedError

    raw_city_string = query_params["city"]
    raw_state_code_string = query_params["state"]
    city_string = raw_city_string.title()
    state_code_string = raw_state_code_string.upper()

    match = re.match(r'^[A-Z]{2}$', state_code_string)
    if match is None:
        raise ApiParamInvalidStateCodeError

    zip_conditions = [
        {
            'column': 'city',
            'equivalence': '=',
            'value': city_string.upper()
        },
        {
            'column': 'state_code',
            'equivalence': '=',
            'value': state_code_string
        }
    ]
    zip_codes = database_manager.fetch_by(
        ZipCode(database_manager),
        zip_conditions
    )
    if len(zip_codes) == 0:
        raise ApiParamInvalidStateCodeError

    state = UsState.fetch_by_code(database_manager, state_code_string)

    zip_code_counties_conditions = [{
        'column': 'zip',
        'equivalence': ' IN ',
        'value': [z.zip_code for z in zip_codes]
    }]
    county_percentages = database_manager.fetch_by(
        county2zipCode(database_manager),
        zip_code_counties_conditions
    )
    county_fips = []
    if len(county_percentages) > 0:
        county_fips = [c.get_state_county_fips() for c in county_percentages]
        county_fips = list(set(county_fips))

    subscription_plan = SubscriptionPlan.fetch_by_id(
        database_manager,
        account.subscription_plan_id
    )
    for header in eligible_headers:
        eligible_headers[header] = get_is_eligible(
            subscription_plan,
            header
        )

    zip_totals = {}
    if len(county_fips) > 0:
        voting_county_conditions = [{
            "column": "county_code",
            "equivalence": "IN",
            "value": county_fips
        }]
        county_totals = database_manager.fetch_by(
            VotesCounty(database_manager),
            voting_county_conditions
        )
    else:
        raise ApiParamInvalidStateCodeError

    for header, is_eligible in eligible_headers.items():
        if is_eligible is True:
            zip_totals[header] = 0
            for county_total in county_totals:
                for county_percentage in county_percentages:
                    if county_percentage.get_state_county_fips() == \
                            county_total.county_code:
                        total = getattr(
                                county_total,
                                header
                            )
                        if total is None:
                            total = 0
                        zip_totals[header] += (
                            round(
                                total * county_percentage.zip_population_percent
                            )
                        )
                        break

    years = [str(x) for x in range(1980, 2010)]
    raw_output_data = OrderedDict({})
    totals = {}
    for year in years:
        output_year = {}
        for header, value in zip_totals.items():
            if year in header:
                output_year[header[:-len(year)-1]] = value
            if len(output_year) > 0:
                raw_output_data[year] = output_year
        if year not in totals:
            if year in raw_output_data:
                totals[year] = raw_output_data[year]["total"]

    # get percentages
    output_data = OrderedDict({})
    notes = []
    for year in raw_output_data:
        output_data[year] = {"breakdown":{}}
        for key, value in raw_output_data[year].items():
            if key != "total":
                output_data[year]["breakdown"][key] = 100 * value / totals[year]
        if get_is_eligible(subscription_plan, "totals") is True:
            output_data[year]['total_votes'] = totals[year]
        else:
            notes.append("Upgrade to a paid plan for totals")

    if len(output_data) == 1:
        notes.append("Upgrade plan for historical data")

    notes = list(set(notes))

    state_name = ""
    state_code = ""
    if state.code is not None:
        state_code = state.code
    if state.name is not None:
        state_name = state.name
    output = OrderedDict({
        "voting_ranges": output_data,
        "units": "percent",
        "location": {
            "city": {
                "name": city_string,
            },
            "state": {
                "name": state_name,
                "code": state_code.upper(),
                "api_endpoint": '/v1/race/state?code={}'.format(state_code.upper()),
            },
            "country": {
                "name": "United States of America",
                "code": "US",
                "api_endpoint": '/v1/race/country?code=US',
            }
        },
        "notes": notes
    })
    http_server.print_headers()
    http_server.print_json(output)
Example #3
0
def handle_get(http_server, database_manager, ip, account, api_key):
    query_params = http_server.get_query_parameters()
    if "code" not in query_params:
        raise ApiParamNoCountryCodeProvidedError

    raw_country_code_string = query_params["code"]
    country_code_string = raw_country_code_string.upper()

    if country_code_string is None:
        raise ApiParamInvalidCountryCodeError

    match = re.match(r'^[A-Za-z]{2}$', country_code_string)
    if match is None:
        raise ApiParamInvalidCountryCodeError

    country = Country.fetch_by_code(database_manager, country_code_string)
    if country is None:
        raise ApiParamInvalidCountryCodeError

    country_name = country.name
    if country.code == "US":
        country_name = "United States"

    county_total = GenderCounty.fetch_by_country_name(database_manager,
                                                      country_name.upper())
    subscription_plan = SubscriptionPlan.fetch_by_id(
        database_manager, account.subscription_plan_id)
    for header in eligible_headers:
        eligible_headers[header] = get_is_eligible(subscription_plan, header)

    zip_totals = {}
    for header, is_eligible in eligible_headers.items():
        if is_eligible is True:
            zip_totals[header] = 0
            total = getattr(county_total, header)
            if total is None:
                total = 0
            zip_totals[header] = (round(total))

    years = [str(year) for year in range(2000, 2010)]
    raw_output_data = OrderedDict({})
    totals = {}
    for year in years:
        output_year = {}
        for header, value in zip_totals.items():
            if year in header:
                output_year[header[:-len(year) - 1]] = value
            if len(output_year) > 0:
                raw_output_data[year] = output_year
        if year not in totals:
            if year in raw_output_data:
                totals[year] = sum(
                    [v for k, v in raw_output_data[year].items()])

    # get percentages
    output_data = OrderedDict({})
    notes = []
    for year in raw_output_data:
        output_data[year] = {"breakdown": {}}
        for key, value in raw_output_data[year].items():
            output_data[year]["breakdown"][key] = 100 * value / totals[year]
        if get_is_eligible(subscription_plan, "totals") is True:
            output_data[year]['total'] = totals[year]
        else:
            notes.append("Upgrade to a paid plan for totals")

    if len(output_data) == 1:
        notes.append("Upgrade plan for historical data")

    notes = list(set(notes))

    output = OrderedDict({
        "gender_breakdown": output_data,
        "units": "percent",
        "location": {
            "country": {
                "name": "United States of America",
                "code": "US",
            }
        },
        "notes": notes
    })
    http_server.print_headers()
    http_server.print_json(output)
Example #4
0
def handle_get(http_server, database_manager, session, account):
    if account.is_phone_verified != 1:
        redirect_to_phone_confirmation(http_server, database_manager, session,
                                       account)
    else:
        keys = {'current_page': "billing"}
        template = fetch_template("account/billing.jinja.htm")
        # http_server.print_headers()
        # print(dict(account))

        subscription_plan_template = SubscriptionPlan(database_manager)
        subscription_conditions = [{
            "column": "is_active",
            "equivalence": "=",
            "value": 1
        }]
        subscription_plans = database_manager.fetch_by(
            subscription_plan_template, subscription_conditions)
        subscription_plan_name = None
        account_subscription_plan = None
        billing_profiles = []
        for subscription_plan in subscription_plans:
            if subscription_plan.id == account.subscription_plan_id:
                subscription_plan_name = subscription_plan.name
                account_subscription_plan = subscription_plan
            billing_profiles.append({
                "slug":
                subscription_plan.name,
                "name":
                subscription_plan.name.title(),
                "amount":
                subscription_plan.amount,
                "currency":
                subscription_plan.currency,
                "allowed_requests_per_month":
                subscription_plan.allowed_requests_per_month,
                "allowed_requests_per_month_printed":
                "{:,}".format(subscription_plan.allowed_requests_per_month),
            })

        next_billing_date = account.get_next_billing_date()
        if account.stripe_subscription_id is not None and \
                account.stripe_subscription_id != "":
            stripe.api_key = settings["stripe"]["secret_key"]
            stripe_subscription = stripe.Subscription.retrieve(
                account.stripe_subscription_id)
            next_billing_date = datetime.utcfromtimestamp(
                stripe_subscription.current_period_end)

        keys = {
            "current_page":
            "billing",
            "billing_profiles":
            billing_profiles,
            "current_plan_name":
            subscription_plan_name,
            "errors": [],
            "response": [],
            "billing_profile_name":
            account_subscription_plan.name.title(),
            "monthly_cost":
            "{:,.2f}".format(account_subscription_plan.amount),
            "currency":
            account_subscription_plan.currency,
            "billing_day":
            account.billing_day,
            "billing_day_ordinality":
            get_ordinality(account.billing_day),
            "next_billing_date":
            next_billing_date.strftime("%Y-%m-%d"),
            "max_api_calls":
            "{:,}".format(
                account_subscription_plan.allowed_requests_per_month),
            "selected_subscription_plan_name":
            account_subscription_plan.name
        }

        output = template.render(keys)
        http_server.print_headers()
        print(output)
Example #5
0
def handle_put_post(http_server, database_manager, session, account):
    if account.is_phone_verified != 1:
        redirect_to_phone_confirmation(http_server, database_manager, session,
                                       account)
    else:
        keys = {'current_page': "billing"}
        template = fetch_template("account/billing.jinja.htm")
        # http_server.print_headers()
        # print(dict(account))

        subscription_plan_template = SubscriptionPlan(database_manager)
        subscription_conditions = [{
            "column": "is_active",
            "equivalence": "=",
            "value": 1
        }]
        subscription_plans = database_manager.fetch_by(
            subscription_plan_template, subscription_conditions)
        subscription_plan_name = None
        account_subscription_plan = None
        billing_profiles = []
        for subscription_plan in subscription_plans:
            if subscription_plan.id == account.subscription_plan_id:
                subscription_plan_name = subscription_plan.name
                account_subscription_plan = subscription_plan
            billing_profiles.append({
                "slug":
                subscription_plan.name,
                "name":
                subscription_plan.name.title(),
                "amount":
                subscription_plan.amount,
                "currency":
                subscription_plan.currency,
                "allowed_requests_per_month":
                subscription_plan.allowed_requests_per_month,
                "allowed_requests_per_month_printed":
                "{:,}".format(subscription_plan.allowed_requests_per_month),
            })

        next_billing_date = account.get_next_billing_date()
        if account.stripe_subscription_id is not None and \
                account.stripe_subscription_id != "":
            stripe.api_key = settings["stripe"]["secret_key"]
            stripe_subscription = stripe.Subscription.retrieve(
                account.stripe_subscription_id)
            next_billing_date = datetime.utcfromtimestamp(
                stripe_subscription.current_period_end)

        keys = {
            "current_page":
            "billing",
            "billing_profiles":
            billing_profiles,
            "current_plan_name":
            subscription_plan_name,
            "errors": [],
            "response": [],
            "billing_profile_name":
            account_subscription_plan.name.title(),
            "monthly_cost":
            "{:,.2f}".format(account_subscription_plan.amount),
            "currency":
            account_subscription_plan.currency,
            "billing_day":
            account.billing_day,
            "billing_day_ordinality":
            get_ordinality(account.billing_day),
            "next_billing_date":
            next_billing_date.strftime("%Y-%m-%d"),
            "max_api_calls":
            "{:,}".format(
                account_subscription_plan.allowed_requests_per_month),
            "selected_subscription_plan_name":
            account_subscription_plan.name
        }

        # new get post info
        errors = []
        required_keys = [
            "billing_id",
        ]
        post_params = http_server.get_post_parameters()
        if "billing_id" in post_params:
            if post_params["billing_id"] != "free":
                required_keys += ["stripe_token"]

        keys["response"] = post_params

        for required_key in required_keys:
            if required_key not in post_params or post_params[
                    required_key] == "":
                errors.append(required_key)

        if len(errors) == 0:
            subscription_plan_name = post_params["billing_id"]
            subscription_plan = SubscriptionPlan.fetch_by_name(
                database_manager, subscription_plan_name)
            if subscription_plan is None:
                errors.append("billing_id")

        keys["errors"] = errors
        for error in errors:
            keys["error_{}".format(error)] = True

        if len(errors) > 0:
            output = template.render(keys)
            # http_server.set_status(400)
            http_server.print_headers()
            print(output)

        else:
            if account.stripe_customer_id:
                stripe_subscription_id = account.stripe_subscription_id
                if account.stripe_subscription_id:
                    try:
                        subscription = stripe.Subscription.retrieve(
                            account.stripe_subscription_id)
                        subscription.delete()
                    except:
                        pass

            stripe_source_token = None
            stripe_subscription_id = None
            if subscription_plan.amount > 0:
                stripe.api_key = settings["stripe"]["secret_key"]
                stripe_plan = stripe.Plan.retrieve(subscription_plan.stripe_id)
                # How to acquire stripe tokens
                # https://stripe.com/docs/sources/cards
                stripe_source_token = post_params["stripe_token"]

                stripe_customer_description = account.email

                # will throw an exception if it fails. Must catch
                subscription = stripe.Subscription.create(
                    customer=account.stripe_customer_id,
                    items=[{
                        "plan": stripe_plan.id
                    }])
                stripe_subscription_id = subscription.id

            billing_epoch = datetime.now()
            account.subscription_plan_id = subscription_plan.id
            account.stripe_source_id = stripe_source_token
            account.stripe_subscription_id = stripe_subscription_id
            account.billing_interval = "monthly"
            account.billing_year = billing_epoch.year
            account.billing_month = billing_epoch.month
            account.billing_day = billing_epoch.day

            account.update()
            #keys["update_succeeded"] = True

            # retrieve updated subscription plan info
            subscription_plan_name = None
            account_subscription_plan = None
            billing_profiles = []
            for subscription_plan in subscription_plans:
                if subscription_plan.id == account.subscription_plan_id:
                    subscription_plan_name = subscription_plan.name
                    account_subscription_plan = subscription_plan
                billing_profiles.append({
                    "slug":
                    subscription_plan.name,
                    "name":
                    subscription_plan.name.title(),
                    "amount":
                    subscription_plan.amount,
                    "currency":
                    subscription_plan.currency,
                    "allowed_requests_per_month":
                    subscription_plan.allowed_requests_per_month,
                    "allowed_requests_per_month_printed":
                    "{:,}".format(
                        subscription_plan.allowed_requests_per_month),
                })

            next_billing_date = account.get_next_billing_date()
            if account.stripe_subscription_id is not None and \
                    account.stripe_subscription_id != "":
                stripe.api_key = settings["stripe"]["secret_key"]
                stripe_subscription = stripe.Subscription.retrieve(
                    account.stripe_subscription_id)
                next_billing_date = datetime.utcfromtimestamp(
                    stripe_subscription.current_period_end)

            keys = {
                'current_page':
                "billing",
                "update_succeeded":
                True,
                "billing_profiles":
                billing_profiles,
                "current_plan_name":
                subscription_plan_name,
                "errors": [],
                "response": [],
                "billing_profile_name":
                account_subscription_plan.name.title(),
                "monthly_cost":
                "{:,.2f}".format(account_subscription_plan.amount),
                "currency":
                account_subscription_plan.currency,
                "billing_day":
                account.billing_day,
                "billing_day_ordinality":
                get_ordinality(account.billing_day),
                "next_billing_date":
                next_billing_date.strftime("%Y-%m-%d"),
                "max_api_calls":
                "{:,}".format(
                    account_subscription_plan.allowed_requests_per_month),
                "selected_subscription_plan_name":
                account_subscription_plan.name
            }

            http_server.set_status(200)
            http_server.print_headers()
            output = template.render(keys)
            print(output)
Example #6
0
def handle_get(http_server, database_manager, ip, account, api_key):
    query_params = http_server.get_query_parameters()
    if "zip" not in query_params:
        raise ApiParamNoZipCodeProvidedError

    raw_zip_code_string = query_params["zip"]
    zip_code_string = raw_zip_code_string
    if "-" in raw_zip_code_string:
        dash_position = raw_zip_code_string.find("-")
        zip_code_string = raw_zip_code_string[0:dash_position]

    match = re.match(r'^\d+$', zip_code_string)
    if match is None:
        raise ApiParamInvalidZipCodeError

    zip_code_int = int(zip_code_string)
    zip_code = ZipCode.fetch_by_zip_int(database_manager,
                                        zip_code_int,
                                        is_decommisioned=False)

    if zip_code is None:
        raise ApiParamInvalidZipCodeError

    state = UsState.fetch_by_id(database_manager, zip_code.state_id)
    city_name = zip_code.city
    if zip_code.city is not None:
        city_name = zip_code.city.title()

    county_percentages = zip_code.get_county_percentages()
    county_fips = []
    if len(county_percentages) > 0:
        county_fips = [c.get_state_county_fips() for c in county_percentages]
        county_fips = list(set(county_fips))

    subscription_plan = SubscriptionPlan.fetch_by_id(
        database_manager, account.subscription_plan_id)
    for header in eligible_headers:
        eligible_headers[header] = get_is_eligible(subscription_plan, header)

    zip_totals = {}
    if len(county_fips) > 0:
        population_county_conditions = [{
            "column": "county_code",
            "equivalence": "IN",
            "value": county_fips
        }]
        county_totals = database_manager.fetch_by(
            PopulationCounty(database_manager), population_county_conditions)
    else:
        raise ApiParamInvalidZipCodeError

    for header, is_eligible in eligible_headers.items():
        if is_eligible is True:
            zip_totals[header] = 0
            for county_total in county_totals:
                for county_percentage in county_percentages:
                    if county_percentage.get_state_county_fips() == \
                            county_total.county_code:
                        total = getattr(county_total, header)
                        if total is None:
                            total = 0
                        zip_totals[header] += (round(
                            total * county_percentage.zip_population_percent))
                        break

    years = [str(x) for x in range(1930, 2011)]
    raw_output_data = OrderedDict({})
    totals = {}
    for year in years:
        output_year = {}
        for header, value in zip_totals.items():
            if year in header:
                output_year[header[:-len(year) - 1]] = value
            if len(output_year) > 0:
                raw_output_data[year] = output_year

    # get percentages
    output_data = OrderedDict({})
    notes = []
    for year in raw_output_data:
        output_data[year] = None
        for key, value in raw_output_data[year].items():
            output_data[year] = value

    if len(output_data) == 1:
        notes.append("Upgrade plan for historical data")

    notes = list(set(notes))

    state_name = ""
    state_code = ""
    if state.code is not None:
        state_code = state.code
    if state.name is not None:
        state_name = state.name
    output = OrderedDict({
        "population_estimates": output_data,
        "units": "people",
        "location": {
            "city": {
                "name":
                city_name,
                "api_endpoint":
                '/v1/population/city?city={}&state={}'.format(
                    requote_uri(city_name), state_code.upper()),
            },
            "state": {
                "name":
                state_name,
                "code":
                state_code.upper(),
                "api_endpoint":
                '/v1/population/state?code={}'.format(state_code.upper()),
            },
            "country": {
                "name": "United States of America",
                "code": "US",
                "api_endpoint": '/v1/population/country?code=US',
            }
        },
        "notes": notes
    })
    http_server.print_headers()
    http_server.print_json(output)
Example #7
0
def handle_put_post(http_server, database_manager, session, account):
    subscription_plan_template = SubscriptionPlan(database_manager)
    subscription_conditions = [{
        "column": "is_active",
        "equivalence": "=",
        "value": 1
    }]
    subscription_plans = database_manager.fetch_by(subscription_plan_template,
                                                   subscription_conditions)
    billing_profiles = []
    for available_subscription_plan in subscription_plans:
        billing_profiles.append({
            "slug":
            available_subscription_plan.name,
            "name":
            available_subscription_plan.name.title(),
            "amount":
            available_subscription_plan.amount,
            "currency":
            available_subscription_plan.currency,
            "allowed_requests_per_month":
            available_subscription_plan.allowed_requests_per_month,
            "allowed_requests_per_month_printed":
            "{:,}".format(
                available_subscription_plan.allowed_requests_per_month),
        })
    template = fetch_template("account/register.jinja.htm")
    keys = {
        "current_page": "register",
        "billing_profiles": billing_profiles,
    }

    errors = []
    required_keys = [
        "billing_id",
        "email",
        "password",
        "verify_password",
        "phone",
        #"g-recaptcha-response"
    ]
    post_params = http_server.get_post_parameters()
    if "billing_id" in post_params:
        if post_params["billing_id"] != "free":
            required_keys += ["stripe_token"]

    keys["response"] = post_params

    for required_key in required_keys:
        if required_key not in post_params or post_params[required_key] == "":
            errors.append(required_key)

    if len(errors) == 0:
        email = post_params["email"]
        password = post_params["password"]
        verify_password = post_params["verify_password"]
        phone = post_params["phone"]
        formatted_number = phone
        if password != verify_password:
            errors.append("verify_password")
        #try:
        phone_details = phonenumbers.parse(phone, "US")
        if phonenumbers.is_valid_number(phone_details) is False:
            errors.append("phone")
        else:
            formatted_number = "+{} {}".format(
                phone_details.country_code,
                phonenumbers.format_number(
                    phone_details, phonenumbers.PhoneNumberFormat.NATIONAL))
            client = Client(settings["twilio"]["account_sid"],
                            settings["twilio"]["auth_token"])
            twilio_phone_details = client.lookups.phone_numbers(
                formatted_number).fetch(type='carrier')
            if twilio_phone_details.carrier["error_code"] is not None:
                errors.append("phone")
            else:
                if twilio_phone_details.carrier["type"] == "voip":
                    errors.append("phone_voip")
        #except:
        #    errors.append("phone")
        if validate_email(email) is False:
            errors.append("email")
        else:
            subscription_plan_name = post_params["billing_id"]
            subscription_plan = SubscriptionPlan.fetch_by_name(
                database_manager, subscription_plan_name)
            if subscription_plan is None:
                errors.append("billing_id")

    keys["errors"] = errors
    for error in errors:
        keys["error_{}".format(error)] = True

    if len(errors) > 0:
        output = template.render(keys)
        # http_server.set_status(400)
        http_server.print_headers()
        print(output)

    else:
        is_captcha_valid = True
        '''
        recaptcha_response = post_params['g-recaptcha-response']
        captcha_data = {
            "secret": settings["google_recaptcha3"]["secret_key"],
            "response": recaptcha_response
        }
        recaptcha_response = requests.post(
            settings["google_recaptcha3"],
            data=captcha_data
        )
        recapcha_json = recaptcha_response.json()

        is_captcha_valid = True
        if recapcha_json['success']:
            is_captcha_valid = True
        else:
            is_captcha_valid = False
        '''

        if is_captcha_valid is False:
            keys["error_invalid_captcha"] = True
            output = template.render(keys)
            # http_server.set_status(400)
            http_server.print_headers()
            print(output)
        else:
            is_marketing_ok = False
            if "subscribe" in post_params:
                if int(post_params["subscribe"]) == 1:
                    is_marketing_ok = True
                    keys["is_marketing_ok"] = True

            do_continue = True
            stripe_source_token = None
            stripe_customer_id = None
            stripe_subscription_id = None
            if subscription_plan.amount > 0:
                stripe.api_key = settings["stripe"]["secret_key"]

                discount_code = None
                stripe_coupon = None
                stripe_coupon_id = None
                if "discount_code" in post_params:
                    discount_code = post_params["discount_code"]
                    try:
                        stripe_coupon = stripe.Coupon.retrieve(discount_code)
                        do_continue = True
                        stripe_coupon_id = stripe_coupon.id
                    except Exception:
                        errors += ["discount_code"]
                        keys["errors"] = errors
                        for error in errors:
                            keys["error_{}".format(error)] = True
                        output = template.render(keys)
                        # http_server.set_status(400)
                        http_server.print_headers()
                        print(output)

                if do_continue is True:
                    stripe_plan = stripe.Plan.retrieve(
                        subscription_plan.stripe_id)
                    # How to acquire stripe tokens
                    # https://stripe.com/docs/sources/cards
                    # if "stripe_token" not in post_params:
                    #    raise ApiParamMissingStripeTokenError
                    stripe_source_token = post_params["stripe_token"]

                    stripe_customer_description = email
                    try:
                        customer = stripe.Customer.create(
                            description=stripe_customer_description,
                            source=stripe_source_token)
                        stripe_customer_id = customer.id

                        # will throw an exception if it fails. Must catch
                        subscription = stripe.Subscription.create(
                            customer=stripe_customer_id,
                            items=[{
                                "plan": stripe_plan.id
                            }],
                            coupon=stripe_coupon_id)
                        stripe_subscription_id = subscription.id
                    except Exception:
                        errors += ["duplicate_submission"]
                        keys["errors"] = errors
                        for error in errors:
                            keys["error_{}".format(error)] = True
                        output = template.render(keys)
                        # http_server.set_status(400)
                        http_server.print_headers()
                        print(output)
                        do_continue = False

            if do_continue is True:
                # verify email doesn't already exist
                account = Account.fetch_by_email(database_manager, email)
                if account is not None:
                    errors += ["email_taken"]
                    keys["errors"] = errors
                    for error in errors:
                        keys["error_{}".format(error)] = True
                    output = template.render(keys)
                    # http_server.set_status(400)
                    http_server.print_headers()
                    print(output)
                else:
                    registration = AccountRegistration.fetch_by_email(
                        database_manager, email)
                    if registration is not None:
                        errors += ["email_taken"]
                        keys["errors"] = errors
                        for error in errors:
                            keys["error_{}".format(error)] = True
                        output = template.render(keys)
                        # http_server.set_status(400)
                        http_server.print_headers()
                        print(output)
                    else:
                        registration_epoch = datetime.now()
                        registration = AccountRegistration(database_manager)
                        registration.email = post_params["email"]
                        registration.password = post_params["password"]
                        registration.phone = formatted_number
                        registration.subscription_plan_id = subscription_plan.id
                        registration.is_marketing_ok = is_marketing_ok
                        registration.stripe_source_id = stripe_source_token
                        registration.stripe_customer_id = stripe_customer_id
                        registration.stripe_subscription_id = stripe_subscription_id
                        registration.billing_interval = "monthly"
                        registration.billing_year = registration_epoch.year
                        registration.billing_month = registration_epoch.month
                        registration.billing_day = registration_epoch.day

                        confirmation_code = registration.generate_confirmation_code(
                        )
                        # send confirmation email
                        courier = Courier(settings["sendgrid"])
                        from_email = settings["email"]["from"]["email"]
                        subject = "Confirm your account"
                        template_id = "d-46d40e8316ba439095fdefb20b171a3e"
                        substitutions = {"confirm_code": confirmation_code}
                        response = courier.send_template_email(
                            email, from_email, subject, template_id,
                            substitutions)
                        if response.status_code != 202:
                            errors += ["email_delivery"]
                            keys["errors"] = errors
                            for error in errors:
                                keys["error_{}".format(error)] = True
                            output = template.render(keys)
                            # http_server.set_status(400)
                            http_server.print_headers()
                            print(output)
                        else:
                            registration.insert()
                            template = fetch_template(
                                "account/register-success.jinja.htm")
                            keys["email"] = post_params["email"]
                            http_server.set_status(200)
                            http_server.print_headers()
                            output = template.render(keys)
                            print(output)
Example #8
0
def handle_get(http_server, database_manager, ip, account, api_key):
    query_params = http_server.get_query_parameters()
    if "code" not in query_params:
        raise ApiParamNoStateCodeProvidedError

    raw_state_code_string = query_params["code"]
    state_code_string = raw_state_code_string.upper()

    match = re.match(r'^[A-Za-z]{2}$', state_code_string)
    if match is None:
        raise ApiParamInvalidStateCodeError

    state = UsState.fetch_by_code(database_manager, state_code_string)

    if state is None:
        raise ApiParamInvalidStateCodeError

    county_total = AncestryCounty.fetch_by_state_name(database_manager,
                                                      state.name.upper())
    subscription_plan = SubscriptionPlan.fetch_by_id(
        database_manager, account.subscription_plan_id)
    for header in eligible_headers:
        eligible_headers[header] = get_is_eligible(subscription_plan, header)

    zip_totals = {}
    for header, is_eligible in eligible_headers.items():
        if is_eligible is True:
            zip_totals[header] = 0
            total = getattr(county_total, header)
            if total is None:
                total = 0
            zip_totals[header] = (round(total))

    years = [str(x) for x in range(1980, 2010)]
    raw_output_data = OrderedDict({})
    totals = {}
    for year in years:
        output_year = {}
        for header, value in zip_totals.items():
            if year in header:
                output_year[header[:-len(year) - 1]] = value
            if len(output_year) > 0:
                raw_output_data[year] = output_year
                if year not in totals:
                    totals[year] = 0
                else:
                    totals[year] += value

    # get percentages
    output_data = OrderedDict({})
    notes = []
    for year in raw_output_data:
        output_data[year] = {"breakdown": {}}
        for key, value in raw_output_data[year].items():
            output_data[year]["breakdown"][key] = value / totals[year]
        if get_is_eligible(subscription_plan, "totals") is True:
            output_data[year]['total'] = totals[year]
        else:
            notes.append("Upgrade to a paid plan for totals")

    if len(output_data) == 1:
        notes.append("Upgrade plan for historical data")

    notes = list(set(notes))

    output = {
        "ancestry_ranges": output_data,
        "units": "percent",
        "location": {
            "state": {
                "name": state.name,
                "code": state.code.upper(),
            },
            "country": {
                "name": "United States of America",
                "code": "US",
                "api_endpoint": '/v1/ancestry/country?code=US',
            }
        },
        "notes": notes
    }
    http_server.print_headers()
    http_server.print_json(output)
Example #9
0
def handle_get(http_server, database_manager, session, account):
    keys = {
        "current_page": "register"
    }
    template = fetch_template("account/confirm.jinja.htm")
    query_parameters = http_server.get_query_parameters()

    if "code" not in query_parameters:
        keys["no_code_provided"] = True
        output = template.render(keys)
        # http_server.set_status(400)
        http_server.print_headers()
        print(output)

    else:
        code = query_parameters["code"]
        registration = AccountRegistration.fetch_by_confirmation_code(
            database_manager,
            code
        )
        if registration is None:
            keys["invalid_code"] = True
            output = template.render(keys)
            # http_server.set_status(400)
            http_server.print_headers()
            print(output)

        else:
            existing_account = Account.fetch_by_from_registration_id(
                database_manager,
                registration.id
            )
            if existing_account is not None:
                keys["already_confirmed"] = True
                output = template.render(keys)
                # http_server.set_status(400)
                http_server.print_headers()
                print(output)

            else:
                account = Account.from_registration(registration)
                account.insert()
                if account.id is None or account.id < 1:
                    account = Account.fetch_by_from_registration_id(
                        database_manager,
                        registration.id
                    )

                subscription = SubscriptionPlan.fetch_by_id(
                    database_manager,
                    account.subscription_plan_id
                )
                if subscription is None:
                    subscription = SubscriptionPlan.fetch_by_name(
                        database_manager,
                        "free"
                    )
                new_api_key = ApiKey(database_manager)
                new_api_key.generate_key()
                new_api_key.generate_secret()
                new_api_key.account_id = account.id
                new_api_key.update_plan(subscription)
                new_api_key.insert()

                # log in
                ip_string = http_server.get_remote_address()
                session = Session(database_manager)
                session.set_expiration_days_from_now(
                    settings["confirm_page"]["session_timeout_days"]
                )
                session_slug = session.generate_slug()
                session.account_id = account.id
                session.ip_address = ip_string
                session.slug = session_slug
                session.insert()
                http_server.set_cookie("session_id", session_slug)

                output = template.render(keys)
                http_server.print_headers()
                print(output)
Example #10
0
def handle_get(http_server, database_manager, ip, account, api_key):
    query_params = http_server.get_query_parameters()
    if "code" not in query_params:
        raise ApiParamNoStateCodeProvidedError

    raw_state_code_string = query_params["code"]
    state_code_string = raw_state_code_string.upper()

    match = re.match(r'^[A-Za-z]{2}$', state_code_string)
    if match is None:
        raise ApiParamInvalidStateCodeError

    state = UsState.fetch_by_code(database_manager, state_code_string)

    if state is None:
        raise ApiParamInvalidStateCodeError

    county_total = EducationCounty.fetch_by_state_name(database_manager,
                                                       state.name.upper())
    subscription_plan = SubscriptionPlan.fetch_by_id(
        database_manager, account.subscription_plan_id)
    for header in eligible_headers:
        eligible_headers[header] = get_is_eligible(subscription_plan, header)

    zip_totals = {}
    for header, is_eligible in eligible_headers.items():
        if is_eligible is True:
            zip_totals[header] = 0
            total = getattr(county_total, header)
            if total is None:
                total = 0
            zip_totals[header] = (round(total))

    years = ["1980", "1990", "2000", "2009"]
    raw_output_data = OrderedDict({})
    totals = {}
    for year in years:
        output_year = {}
        for header, value in zip_totals.items():
            if "num_adults" not in header:
                if year in header:
                    ending = year
                    end = len(ending) + 1
                    if "_2005_" in header:
                        ending = "2005_{}".format(year)
                        end = len(ending) + 1
                    output_year[header[:-end]] = 100 * value / zip_totals[
                        "num_adults_{}".format(ending)]
            if len(output_year) > 0:
                raw_output_data[year] = output_year
        if year not in totals:
            if year in raw_output_data:
                ending = year
                if year == "2009":
                    ending = "2005_2009"
                totals[year] = zip_totals["num_adults_{}".format(ending)]

    # get percentages
    output_data = OrderedDict({})
    notes = []
    for year in raw_output_data:
        output_data[year] = {"breakdown": {}}
        for key, value in raw_output_data[year].items():
            output_data[year]["breakdown"][key] = value
        if get_is_eligible(subscription_plan, "totals") is True:
            output_data[year]['total_adults'] = totals[year]
        else:
            notes.append("Upgrade to a paid plan for totals")

    notes = list(set(notes))

    state_name = ""
    state_code = ""
    if state.code is not None:
        state_code = state.code
    if state.name is not None:
        state_name = state.name
    output = {
        "education_ranges": output_data,
        "location": {
            "state": {
                "name": state.name,
                "code": state.code.upper(),
            },
            "country": {
                "name": "United States of America",
                "code": "US",
                "api_endpoint": '/v1/education/country?code=US',
            }
        },
        "notes": notes
    }
    http_server.print_headers()
    http_server.print_json(output)
Example #11
0
def handle_get(http_server, database_manager, ip, account, api_key):
    query_params = http_server.get_query_parameters()
    if "zip" not in query_params:
        raise ApiParamNoZipCodeProvidedError

    raw_zip_code_string = query_params["zip"]
    zip_code_string = raw_zip_code_string
    if "-" in raw_zip_code_string:
        dash_position = raw_zip_code_string.find("-")
        zip_code_string = raw_zip_code_string[0:dash_position]

    match = re.match(r'^\d+$', zip_code_string)
    if match is None:
        raise ApiParamInvalidZipCodeError

    zip_code_int = int(zip_code_string)
    zip_code = ZipCode.fetch_by_zip_int(
        database_manager,
        zip_code_int,
        is_decommisioned=False
    )

    if zip_code is None:
        raise ApiParamInvalidZipCodeError

    state = UsState.fetch_by_id(database_manager, zip_code.state_id)
    city_name = zip_code.city
    if zip_code.city is not None:
        city_name = zip_code.city.title()

    county_percentages = zip_code.get_county_percentages()
    county_fips = []
    if len(county_percentages) > 0:
        county_fips = [c.get_state_county_fips() for c in county_percentages]
        county_fips = list(set(county_fips))

    subscription_plan = SubscriptionPlan.fetch_by_id(
        database_manager,
        account.subscription_plan_id
    )
    for header in eligible_headers:
        eligible_headers[header] = get_is_eligible(
            subscription_plan,
            header
        )

    zip_totals = {}
    if len(county_fips) > 0:
        education_county_conditions = [{
            "column": "county_code",
            "equivalence": "IN",
            "value": county_fips
        }]
        county_totals = database_manager.fetch_by(
            EducationCounty(database_manager),
            education_county_conditions
        )
    else:
        raise ApiParamInvalidZipCodeError

    for header, is_eligible in eligible_headers.items():
        if is_eligible is True:
            zip_totals[header] = 0
            for county_total in county_totals:
                for county_percentage in county_percentages:
                    if county_percentage.get_state_county_fips() == \
                            county_total.county_code:
                        total = getattr(
                                county_total,
                                header
                            )
                        if total is None:
                            total = 0
                        zip_totals[header] = (
                            round(
                                total * county_percentage.zip_population_percent
                            )
                        )
                        break

    years = ["1980", "1990", "2000", "2009"]
    raw_output_data = OrderedDict({})
    totals = {}
    for year in years:
        output_year = {}
        for header, value in zip_totals.items():
            if "num_adults" not in header:
                if year in header:
                    ending = year
                    end = len(ending) + 1
                    if "_2005_" in header:
                        ending = "2005_{}".format(year)
                        end = len(ending) + 1
                    output_year[header[:-end]] = 100 * value / zip_totals[
                        "num_adults_{}".format(ending)
                    ]
            if len(output_year) > 0:
                raw_output_data[year] = output_year
        if year not in totals:
            if year in raw_output_data:
                ending = year
                if year == "2009":
                    ending = "2005_2009"
                totals[year] = zip_totals["num_adults_{}".format(ending)]

    # get percentages
    output_data = OrderedDict({})
    notes = []
    for year in raw_output_data:
        output_data[year] = {"breakdown":{}}
        for key, value in raw_output_data[year].items():
            output_data[year]["breakdown"][key] = value
        if get_is_eligible(subscription_plan, "totals") is True:
            output_data[year]['total_adults'] = totals[year]
        else:
            notes.append("Upgrade to a paid plan for totals")

    if len(output_data) == 1:
        notes.append("Upgrade plan for historical data")

    notes = list(set(notes))

    state_name = ""
    state_code = ""
    if state.code is not None:
        state_code = state.code
    if state.name is not None:
        state_name = state.name
    output = OrderedDict({
        "education_ranges": output_data,
        "city": {
            "name": city_name,
            "api_endpoint": '/v1/education/city?city={}&state={}'.format(
                requote_uri(city_name),
                state_code.upper()
            ),
        },
        "state": {
            "name": state_name,
            "code": state_code.upper(),
            "api_endpoint": '/v1/education/state?code={}'.format(state_code.upper()),
        },
        "country": {
            "name": "United States of America",
            "code": "US",
            "api_endpoint": '/v1/education/country?code=US',
        }
    })
    http_server.print_headers()
    http_server.print_json(output)