<commit_before>"""Environment params and backend implementations."""

import json
import logging
import datetime

from rauth import OAuth2Service

from google.appengine.api import mail
from google.appengine.ext import deferred
from mailchimp import mailchimp
import stripe

import handlers
import model

def get_env():
  """Get environmental parameters."""
  j = json.load(open('config.json'))

  stripe_backend = None
  mailing_list_subscriber = None
  if j['appName'] == 'local':
    stripe_backend = ProdStripe(model.Config.get().stripe_private_key)
    mailing_list_subscriber = FakeSubscriber()
  else:
    stripe_backend = ProdStripe(model.Config.get().stripe_private_key)
    mailing_list_subscriber = MailchimpSubscriber()

  return handlers.Environment(
    app_name=j['appName'],
    stripe_public_key=model.Config.get().stripe_public_key,
    stripe_backend=stripe_backend,
    mailing_list_subscriber=mailing_list_subscriber,
    mail_sender=MailSender())

class ProdStripe(handlers.StripeBackend):
  def __init__(self, stripe_private_key):
    self.stripe_private_key = stripe_private_key

  def CreateCustomer(self, email, card_token):
    stripe.api_key = self.stripe_private_key
    customer = stripe.Customer.create(card=card_token, email=email)
    return customer

  def RetrieveCardData(self, customer_id):
    stripe.api_key = self.stripe_private_key
    cus = stripe.Customer.retrieve(customer_id)
    return cus.cards.data[0] if len(cus.cards.data) > 0 else {}

  def Charge(self, customer_id, amount_cents):
    stripe.api_key = self.stripe_private_key
    try:
      charge = stripe.Charge.create(
        amount=amount_cents,
        currency='usd',
        customer=customer_id,
        statement_descriptor="Lessig Equal Citizens"
      )
    except stripe.CardError, e:
      logging.info('Stripe returned error for customer: %s ' % customer_id)
      raise handlers.PaymentError(str(e))
    return charge.id

  def CreateCustomerWithPlan(self, email, card_token, amount_dollars,
    recurrence_period):
    stripe.api_key = self.stripe_private_key
    if recurrence_period == "monthly":
      plan = "one_dollar_monthly"
    elif recurrence_period == "weekly":
      plan = "one_dollar_weekly"
    else:
      plan = "one_dollar_monthly"

    customer = stripe.Customer.create(
      card=card_token,
      email=email,
      plan=plan,
      quantity=amount_dollars
    )

    return customer

class FakeStripe(handlers.StripeBackend):
  def CreateCustomer(self, email, card_token):
    logging.warning('USING FAKE STRIPE')
    cus = stripe.Customer()
    cus.cards = stripe.ListObject()
    if email == 'failure@failure.biz':
      cus.id = 'doomed_customer'
      cus.cards.data = []
    else:
      cus.id = 'fake_1234'
      cus.cards.data = [self.RetrieveCardData(id)]
    return cus

  def RetrieveCardData(self, customer_id):
    return {
      "address_city": "Washington",
      "address_country": "US",
      "address_line1": "1600 Pennsylvania Ave NW",
      "address_line1_check": "pass",
      "address_line2": "",
      "address_state": "DC",
      "address_zip": "20500",
      "address_zip_check": "pass",
      "brand": "Visa",
      "country": "US",
      "customer": customer_id,
      "cvc_check": "pass",
      "exp_month": 3,
      "exp_year": 2020,
      "fingerprint": "fakefingerprint",
      "funding": "debit",
      "id": "card_fakeid",
      "last4": "4242",
      "name": "Phillip Mamouf-Wifarts",
      "object": "card",
      "type": "Visa"
    }

  def Charge(self, customer_id, amount_cents):
    logging.error('USING FAKE STRIPE')
    if customer_id == 'doomed_customer':
      raise handlers.PaymentError(
        'You have no chance to survive make your time')
    logging.error('CHARGED CUSTOMER %s %d cents', customer_id, amount_cents)
    return 'fake_charge_1234'

  def CreateCustomerWithPlan(self, email, card_token, amount_dollars,
    recurrence_period):
    logging.warning('USING FAKE STRIPE')
    cus = stripe.Customer()
    cus.cards = stripe.ListObject()
    if email == 'failure@failure.biz':
      cus.id = 'doomed_customer'
      cus.cards.data = []
    else:
      cus.id = 'fake_1234'
      cus.cards.data = [self.RetrieveCardData(id)]
    return cus

class MailchimpSubscriber(handlers.MailingListSubscriber):
  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, otherVars = None,
		is_supporter=None, nationBuilderVars=None):
    deferred.defer(_subscribe_to_mailchimp,
                   email, first_name, last_name,
                   amount_cents, ip_addr, source, phone, zipcode,
                   volunteer, skills, rootstrikers,
                   nonce, pledgePageSlug, otherVars)

      deferred.defer(_subscribe_to_nationbuilder,
                     email, first_name, last_name,
                     amount_cents, ip_addr, source, phone, zipcode,
                     volunteer, skills, rootstrikers,
                     nonce, pledgePageSlug, otherVars,
                     is_supporter, nationBuilderVars)

class FakeSubscriber(handlers.MailingListSubscriber):
  def Subscribe(self, **kwargs):
    logging.info('Subscribing %s', kwargs)

class MailSender(object):
  def __init__(self, defer=True):
    # this can
    self.defer = defer

  def Send(self, to, subject, text_body, html_body, reply_to=None):
    if self.defer:
      deferred.defer(_send_mail, to, subject, text_body, html_body, reply_to)
    else:
      _send_mail(to, subject, text_body, html_body, reply_to)

def _send_mail(to, subject, text_body, html_body, reply_to=None):
  """Deferred email task"""
  sender = ('Team Lessig <noreply@%s.appspotmail.com>' %
            model.Config.get().app_name)
  message = mail.EmailMessage(sender=sender, subject=subject)
  message.to = to
  message.body = text_body
  message.html = html_body
  if reply_to:
    message.reply_to = reply_to
  else:
    message.reply_to = 'info@lessigforpresident.com'
  message.send()

def _subscribe_to_nationbuilder(email_to_subscribe, first_name, last_name,
                            amount, request_ip, source, phone=None, zipcode=None,
                            volunteer=None, skills=None, rootstrikers=None,
                            nonce=None, pledgePageSlug=None, otherVars=None,
			    is_supporter=None, nationBuilderVars=None):
  nationbuilder_token = model.Secrets.get().nationbuilder_token
  if nationbuilder_token == '':
    return

  nation_slug = "mayday"
  access_token_url = "http://" + nation_slug + ".nationbuilder.com/oauth/token"
  authorize_url = nation_slug + ".nationbuilder.com/oauth/authorize"
  service = OAuth2Service(
    client_id = "",
    client_secret = "",
    name = "anyname",
    authorize_url = authorize_url,
    access_token_url = access_token_url,
    base_url = nation_slug + ".nationbuilder.com")
  session = service.get_session(nationbuilder_token)
  person = {
    'email':email_to_subscribe
  }

  if first_name:
    person['first_name'] = first_name
  if last_name:
    person['last_name'] = last_name
  if request_ip:
    person['request_ip'] = request_ip

  if rootstrikers:
    if rootstrikers == "Yes":
	person["rootstrikers_subscription"] = True
    else:
	person["rootstrikers_subscription"] = False

  if is_supporter:
    person["is_supporter"] = True
    person["is_prospect"] = False

  if volunteer:
    if volunteer == "Yes":
	person["is_volunteer"] = True
    else:
	person["is_volunteer"] = False

  if phone:
    person["phone"] = phone

  if zipcode:
    person['home_address'] = {'zip':zipcode}
  if skills:
    person['skills'] = skills

  if nonce:
    person['uuid'] = nonce

  if pledgePageSlug:
    person['pledge_page_slug'] = pledgePageSlug

  if otherVars:
    merge13 = otherVars.get('MERGE13', '')
    if merge13 != '':
      person['fundraising_email_subscription'] = merge13
    else:
      person['fundraising_email_subscription'] = 'Yes'
  else:
    person['fundraising_email_subscription'] = 'Yes'

  if nationBuilderVars:
    for key in nationBuilderVars.keys():
      person[key] = nationBuilderVars[key]
  response = session.put('https://' + nation_slug +".nationbuilder.com/api/v1/people/push",
    data=json.dumps({'person':person}),
    headers={"content-type":"application/json"}
  )
  id = json.loads(response.content)["person"]["id"]
  response = session.put('https://' + nation_slug + ".nationbuilder.com/api/v1/people/" + str(id) + "/taggings",
    data=json.dumps({"tagging":{"tag":"source: " + source}}),
    headers={"content-type":"application/json"}
  )

def _subscribe_to_mailchimp(email_to_subscribe, first_name, last_name,
                            amount, request_ip, source, phone=None, zipcode=None,
                            volunteer=None, skills=None, rootstrikers=None,
                            nonce=None, pledgePageSlug=None, otherVars=None):
  mailchimp_api_key = model.Config.get().mailchimp_api_key
  mailchimp_list_id = model.Config.get().mailchimp_list_id

  mc = mailchimp.Mailchimp(mailchimp_api_key)
  merge_vars = {
    'FNAME': first_name,
    'LNAME': last_name,
    'optin_ip': request_ip,
    'optin_time': str(datetime.datetime.now())
  }

  if source:
    merge_vars['SOURCE'] = source

  if amount:
    amount_dollars = '{0:.02f}'.format(float(amount) / 100.0)
    merge_vars['LASTPLEDGE'] = amount_dollars

  if volunteer == 'Yes':
    merge_vars['VOLN'] = volunteer

  if nonce is not None:
    merge_vars['UUT'] = nonce

  if skills is not None and len(skills)>0:
    merge_vars['SKILLS'] = skills[0:255]

  if phone is not None:
    merge_vars['PHONE'] = phone

  if zipcode is not None:
    merge_vars['ZIP'] = zipcode

  if rootstrikers is not None:
    merge_vars['ROOTS'] = rootstrikers

  if pledgePageSlug is not None:
    merge_vars['PPURL'] = pledgePageSlug

  if otherVars is not None:
    merge_vars.update(otherVars)

  # list ID and email struct
  logging.info('Subscribing: %s. Merge_vars: %s', email_to_subscribe, str(merge_vars))
  try:
    mc.lists.subscribe(id=mailchimp_list_id,
                     email=dict(email=email_to_subscribe),
                     merge_vars=merge_vars,
                     double_optin=False,
                     update_existing=True,
                     send_welcome=False)
  except mailchimp.ListInvalidImportError as e:
    logging.info("ListInvalidImportError: %s", e.message)
<commit_msg>fixed indent<commit_after>"""Environment params and backend implementations."""

import json
import logging
import datetime

from rauth import OAuth2Service

from google.appengine.api import mail
from google.appengine.ext import deferred
from mailchimp import mailchimp
import stripe

import handlers
import model

def get_env():
  """Get environmental parameters."""
  j = json.load(open('config.json'))

  stripe_backend = None
  mailing_list_subscriber = None
  if j['appName'] == 'local':
    stripe_backend = ProdStripe(model.Config.get().stripe_private_key)
    mailing_list_subscriber = FakeSubscriber()
  else:
    stripe_backend = ProdStripe(model.Config.get().stripe_private_key)
    mailing_list_subscriber = MailchimpSubscriber()

  return handlers.Environment(
    app_name=j['appName'],
    stripe_public_key=model.Config.get().stripe_public_key,
    stripe_backend=stripe_backend,
    mailing_list_subscriber=mailing_list_subscriber,
    mail_sender=MailSender())

class ProdStripe(handlers.StripeBackend):
  def __init__(self, stripe_private_key):
    self.stripe_private_key = stripe_private_key

  def CreateCustomer(self, email, card_token):
    stripe.api_key = self.stripe_private_key
    customer = stripe.Customer.create(card=card_token, email=email)
    return customer

  def RetrieveCardData(self, customer_id):
    stripe.api_key = self.stripe_private_key
    cus = stripe.Customer.retrieve(customer_id)
    return cus.cards.data[0] if len(cus.cards.data) > 0 else {}

  def Charge(self, customer_id, amount_cents):
    stripe.api_key = self.stripe_private_key
    try:
      charge = stripe.Charge.create(
        amount=amount_cents,
        currency='usd',
        customer=customer_id,
        statement_descriptor="Lessig Equal Citizens"
      )
    except stripe.CardError, e:
      logging.info('Stripe returned error for customer: %s ' % customer_id)
      raise handlers.PaymentError(str(e))
    return charge.id

  def CreateCustomerWithPlan(self, email, card_token, amount_dollars,
    recurrence_period):
    stripe.api_key = self.stripe_private_key
    if recurrence_period == "monthly":
      plan = "one_dollar_monthly"
    elif recurrence_period == "weekly":
      plan = "one_dollar_weekly"
    else:
      plan = "one_dollar_monthly"

    customer = stripe.Customer.create(
      card=card_token,
      email=email,
      plan=plan,
      quantity=amount_dollars
    )

    return customer

class FakeStripe(handlers.StripeBackend):
  def CreateCustomer(self, email, card_token):
    logging.warning('USING FAKE STRIPE')
    cus = stripe.Customer()
    cus.cards = stripe.ListObject()
    if email == 'failure@failure.biz':
      cus.id = 'doomed_customer'
      cus.cards.data = []
    else:
      cus.id = 'fake_1234'
      cus.cards.data = [self.RetrieveCardData(id)]
    return cus

  def RetrieveCardData(self, customer_id):
    return {
      "address_city": "Washington",
      "address_country": "US",
      "address_line1": "1600 Pennsylvania Ave NW",
      "address_line1_check": "pass",
      "address_line2": "",
      "address_state": "DC",
      "address_zip": "20500",
      "address_zip_check": "pass",
      "brand": "Visa",
      "country": "US",
      "customer": customer_id,
      "cvc_check": "pass",
      "exp_month": 3,
      "exp_year": 2020,
      "fingerprint": "fakefingerprint",
      "funding": "debit",
      "id": "card_fakeid",
      "last4": "4242",
      "name": "Phillip Mamouf-Wifarts",
      "object": "card",
      "type": "Visa"
    }

  def Charge(self, customer_id, amount_cents):
    logging.error('USING FAKE STRIPE')
    if customer_id == 'doomed_customer':
      raise handlers.PaymentError(
        'You have no chance to survive make your time')
    logging.error('CHARGED CUSTOMER %s %d cents', customer_id, amount_cents)
    return 'fake_charge_1234'

  def CreateCustomerWithPlan(self, email, card_token, amount_dollars,
    recurrence_period):
    logging.warning('USING FAKE STRIPE')
    cus = stripe.Customer()
    cus.cards = stripe.ListObject()
    if email == 'failure@failure.biz':
      cus.id = 'doomed_customer'
      cus.cards.data = []
    else:
      cus.id = 'fake_1234'
      cus.cards.data = [self.RetrieveCardData(id)]
    return cus

class MailchimpSubscriber(handlers.MailingListSubscriber):
  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, otherVars = None,
		is_supporter=None, nationBuilderVars=None):
    deferred.defer(_subscribe_to_mailchimp,
                   email, first_name, last_name,
                   amount_cents, ip_addr, source, phone, zipcode,
                   volunteer, skills, rootstrikers,
                   nonce, pledgePageSlug, otherVars)

    deferred.defer(_subscribe_to_nationbuilder,
                   email, first_name, last_name,
                   amount_cents, ip_addr, source, phone, zipcode,
                   volunteer, skills, rootstrikers,
                   nonce, pledgePageSlug, otherVars,
                   is_supporter, nationBuilderVars)

class FakeSubscriber(handlers.MailingListSubscriber):
  def Subscribe(self, **kwargs):
    logging.info('Subscribing %s', kwargs)

class MailSender(object):
  def __init__(self, defer=True):
    # this can
    self.defer = defer

  def Send(self, to, subject, text_body, html_body, reply_to=None):
    if self.defer:
      deferred.defer(_send_mail, to, subject, text_body, html_body, reply_to)
    else:
      _send_mail(to, subject, text_body, html_body, reply_to)

def _send_mail(to, subject, text_body, html_body, reply_to=None):
  """Deferred email task"""
  sender = ('Team Lessig <noreply@%s.appspotmail.com>' %
            model.Config.get().app_name)
  message = mail.EmailMessage(sender=sender, subject=subject)
  message.to = to
  message.body = text_body
  message.html = html_body
  if reply_to:
    message.reply_to = reply_to
  else:
    message.reply_to = 'info@lessigforpresident.com'
  message.send()

def _subscribe_to_nationbuilder(email_to_subscribe, first_name, last_name,
                            amount, request_ip, source, phone=None, zipcode=None,
                            volunteer=None, skills=None, rootstrikers=None,
                            nonce=None, pledgePageSlug=None, otherVars=None,
			    is_supporter=None, nationBuilderVars=None):
  nationbuilder_token = model.Secrets.get().nationbuilder_token
  if nationbuilder_token == '':
    return

  nation_slug = "mayday"
  access_token_url = "http://" + nation_slug + ".nationbuilder.com/oauth/token"
  authorize_url = nation_slug + ".nationbuilder.com/oauth/authorize"
  service = OAuth2Service(
    client_id = "",
    client_secret = "",
    name = "anyname",
    authorize_url = authorize_url,
    access_token_url = access_token_url,
    base_url = nation_slug + ".nationbuilder.com")
  session = service.get_session(nationbuilder_token)
  person = {
    'email':email_to_subscribe
  }

  if first_name:
    person['first_name'] = first_name
  if last_name:
    person['last_name'] = last_name
  if request_ip:
    person['request_ip'] = request_ip

  if rootstrikers:
    if rootstrikers == "Yes":
	person["rootstrikers_subscription"] = True
    else:
	person["rootstrikers_subscription"] = False

  if is_supporter:
    person["is_supporter"] = True
    person["is_prospect"] = False

  if volunteer:
    if volunteer == "Yes":
	person["is_volunteer"] = True
    else:
	person["is_volunteer"] = False

  if phone:
    person["phone"] = phone

  if zipcode:
    person['home_address'] = {'zip':zipcode}
  if skills:
    person['skills'] = skills

  if nonce:
    person['uuid'] = nonce

  if pledgePageSlug:
    person['pledge_page_slug'] = pledgePageSlug

  if otherVars:
    merge13 = otherVars.get('MERGE13', '')
    if merge13 != '':
      person['fundraising_email_subscription'] = merge13
    else:
      person['fundraising_email_subscription'] = 'Yes'
  else:
    person['fundraising_email_subscription'] = 'Yes'

  if nationBuilderVars:
    for key in nationBuilderVars.keys():
      person[key] = nationBuilderVars[key]
  response = session.put('https://' + nation_slug +".nationbuilder.com/api/v1/people/push",
    data=json.dumps({'person':person}),
    headers={"content-type":"application/json"}
  )
  id = json.loads(response.content)["person"]["id"]
  response = session.put('https://' + nation_slug + ".nationbuilder.com/api/v1/people/" + str(id) + "/taggings",
    data=json.dumps({"tagging":{"tag":"source: " + source}}),
    headers={"content-type":"application/json"}
  )

def _subscribe_to_mailchimp(email_to_subscribe, first_name, last_name,
                            amount, request_ip, source, phone=None, zipcode=None,
                            volunteer=None, skills=None, rootstrikers=None,
                            nonce=None, pledgePageSlug=None, otherVars=None):
  mailchimp_api_key = model.Config.get().mailchimp_api_key
  mailchimp_list_id = model.Config.get().mailchimp_list_id

  mc = mailchimp.Mailchimp(mailchimp_api_key)
  merge_vars = {
    'FNAME': first_name,
    'LNAME': last_name,
    'optin_ip': request_ip,
    'optin_time': str(datetime.datetime.now())
  }

  if source:
    merge_vars['SOURCE'] = source

  if amount:
    amount_dollars = '{0:.02f}'.format(float(amount) / 100.0)
    merge_vars['LASTPLEDGE'] = amount_dollars

  if volunteer == 'Yes':
    merge_vars['VOLN'] = volunteer

  if nonce is not None:
    merge_vars['UUT'] = nonce

  if skills is not None and len(skills)>0:
    merge_vars['SKILLS'] = skills[0:255]

  if phone is not None:
    merge_vars['PHONE'] = phone

  if zipcode is not None:
    merge_vars['ZIP'] = zipcode

  if rootstrikers is not None:
    merge_vars['ROOTS'] = rootstrikers

  if pledgePageSlug is not None:
    merge_vars['PPURL'] = pledgePageSlug

  if otherVars is not None:
    merge_vars.update(otherVars)

  # list ID and email struct
  logging.info('Subscribing: %s. Merge_vars: %s', email_to_subscribe, str(merge_vars))
  try:
    mc.lists.subscribe(id=mailchimp_list_id,
                     email=dict(email=email_to_subscribe),
                     merge_vars=merge_vars,
                     double_optin=False,
                     update_existing=True,
                     send_welcome=False)
  except mailchimp.ListInvalidImportError as e:
    logging.info("ListInvalidImportError: %s", e.message)
<|endoftext|>


<commit_before>from django.apps import AppConfig
from django.conf import settings
from django.db.models import signals

def get_secret_attributes():
    if not settings.WALDUR_OPENSTACK['TENANT_CREDENTIALS_VISIBLE']:
        return 'user_username', 'user_password'

class MarketplaceOpenStackConfig(AppConfig):
    name = 'waldur_mastermind.marketplace_openstack'
    verbose_name = 'Marketplace OpenStack'

    def ready(self):
        from waldur_core.quotas import models as quota_models
        from waldur_core.structure import models as structure_models
        from waldur_core.structure import signals as structure_signals
        from waldur_openstack.openstack import models as openstack_models
        from waldur_openstack.openstack.apps import OpenStackConfig
        from waldur_openstack.openstack_tenant import models as tenant_models
        from waldur_mastermind.invoices import registrators
        from waldur_mastermind.marketplace import models as marketplace_models
        from waldur_mastermind.marketplace import filters as marketplace_filters
        from waldur_mastermind.marketplace import handlers as marketplace_handlers
        from waldur_mastermind.marketplace import signals as marketplace_signals
        from waldur_mastermind.marketplace.plugins import manager
        from waldur_mastermind.marketplace.plugins import Component
        from waldur_mastermind.marketplace_openstack.registrators import MarketplaceItemRegistrator
        from waldur_mastermind.packages import models as package_models

        from . import (
            filters, handlers, processors,
            INSTANCE_TYPE, VOLUME_TYPE, PACKAGE_TYPE,
            RAM_TYPE, CORES_TYPE, STORAGE_TYPE, AVAILABLE_LIMITS
        )

        marketplace_filters.ExternalOfferingFilterBackend.register(filters.VpcExternalFilter())

        signals.post_save.connect(
            handlers.create_offering_from_tenant,
            sender=openstack_models.Tenant,
            dispatch_uid='waldur_mastermind.marketpace_openstack.create_offering_from_tenant',
        )

        signals.pre_delete.connect(
            handlers.archive_offering,
            sender=structure_models.ServiceSettings,
            dispatch_uid='waldur_mastermind.marketpace_openstack.archive_offering',
        )

        resource_models = (tenant_models.Instance, tenant_models.Volume, openstack_models.Tenant)
        marketplace_handlers.connect_resource_metadata_handlers(*resource_models)
        marketplace_handlers.connect_resource_handlers(*resource_models)

        signals.post_save.connect(
            handlers.create_template_for_plan,
            sender=marketplace_models.Plan,
            dispatch_uid='waldur_mastermind.marketpace_openstack.create_template_for_plan',
        )

        signals.post_save.connect(
            handlers.update_template_for_plan,
            sender=marketplace_models.Plan,
            dispatch_uid='waldur_mastermind.marketpace_openstack.update_template_for_plan',
        )

        signals.post_save.connect(
            handlers.update_plan_for_template,
            sender=package_models.PackageTemplate,
            dispatch_uid='waldur_mastermind.marketpace_openstack.update_plan_for_template',
        )

        signals.post_save.connect(
            handlers.synchronize_plan_component,
            sender=marketplace_models.PlanComponent,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_plan_component',
        )

        FIXED = marketplace_models.OfferingComponent.BillingTypes.FIXED
        manager.register(offering_type=PACKAGE_TYPE,
                         create_resource_processor=processors.PackageCreateProcessor,
                         update_resource_processor=processors.PackageUpdateProcessor,
                         delete_resource_processor=processors.PackageDeleteProcessor,
                         components=(
                             Component(type=CORES_TYPE, name='Cores', measured_unit='cores', billing_type=FIXED),
                             # Price is stored per GiB but size is stored per MiB
                             # therefore we need to divide size by factor when price estimate is calculated.
                             Component(type=RAM_TYPE, name='RAM', measured_unit='GB', billing_type=FIXED, factor=1024),
                             Component(type=STORAGE_TYPE, name='Storage', measured_unit='GB', billing_type=FIXED, factor=1024),
                         ),
                         service_type=OpenStackConfig.service_name,
                         secret_attributes=get_secret_attributes,
                         available_limits=AVAILABLE_LIMITS,
                         resource_model=openstack_models.Tenant)

        manager.register(offering_type=INSTANCE_TYPE,
                         create_resource_processor=processors.InstanceCreateProcessor,
                         delete_resource_processor=processors.InstanceDeleteProcessor)

        manager.register(offering_type=VOLUME_TYPE,
                         create_resource_processor=processors.VolumeCreateProcessor,
                         delete_resource_processor=processors.VolumeDeleteProcessor)

        signals.post_save.connect(
            handlers.synchronize_volume_metadata,
            sender=tenant_models.Volume,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_volume_metadata',
        )

        signals.post_save.connect(
            handlers.synchronize_instance_metadata,
            sender=tenant_models.Instance,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_instance_metadata',
        )

        signals.post_save.connect(
            handlers.synchronize_internal_ips,
            sender=tenant_models.InternalIP,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_internal_ips',
        )

        signals.post_save.connect(
            handlers.synchronize_floating_ips,
            sender=tenant_models.FloatingIP,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_floating_ips',
        )

        signals.post_delete.connect(
            handlers.synchronize_internal_ips_on_delete,
            sender=tenant_models.InternalIP,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_internal_ips_on_delete',
        )

        signals.post_delete.connect(
            handlers.synchronize_floating_ips_on_delete,
            sender=tenant_models.FloatingIP,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_floating_ips_on_delete',
        )

        signals.post_save.connect(
            handlers.create_resource_of_volume_if_instance_created,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketpace_openstack.'
                         'create_resource_of_volume_if_instance_created',
        )

        for model in [tenant_models.Instance, tenant_models.Volume, openstack_models.Tenant]:
            structure_signals.resource_imported.connect(
                handlers.create_marketplace_resource_for_imported_resources,
                sender=model,
                dispatch_uid='waldur_mastermind.marketpace_openstack.'
                             'create_resource_for_imported_%s' % model,
            )

        signals.post_save.connect(
            handlers.import_resource_metadata_when_resource_is_created,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketpace_openstack.'
                         'import_resource_metadata_when_resource_is_created',
        )

        signals.post_save.connect(
            handlers.update_openstack_tenant_usages,
            sender=quota_models.Quota,
            dispatch_uid='waldur_mastermind.marketpace_openstack.'
                         'update_openstack_tenant_usages',
        )

        registrators.RegistrationManager.add_registrator(
            marketplace_models.Resource,
            MarketplaceItemRegistrator,
        )

        marketplace_signals.resource_creation_succeeded.connect(
            handlers.update_invoice_when_resource_is_created,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.'
                         'update_invoice_when_resource_is_created',
        )

        marketplace_signals.limit_update_succeeded.connect(
            handlers.update_invoice_when_resource_is_updated,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.'
                         'update_invoice_when_resource_is_updated',
        )

        marketplace_signals.resource_deletion_succeeded.connect(
            handlers.update_invoice_when_resource_is_deleted,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.'
                         'update_invoice_when_resource_is_deleted',
        )
<commit_msg>Fix import of volumes and instances via marketplace.<commit_after>from django.apps import AppConfig
from django.conf import settings
from django.db.models import signals

def get_secret_attributes():
    if not settings.WALDUR_OPENSTACK['TENANT_CREDENTIALS_VISIBLE']:
        return 'user_username', 'user_password'

class MarketplaceOpenStackConfig(AppConfig):
    name = 'waldur_mastermind.marketplace_openstack'
    verbose_name = 'Marketplace OpenStack'

    def ready(self):
        from waldur_core.quotas import models as quota_models
        from waldur_core.structure import models as structure_models
        from waldur_core.structure import signals as structure_signals
        from waldur_openstack.openstack import models as openstack_models
        from waldur_openstack.openstack.apps import OpenStackConfig
        from waldur_openstack.openstack_tenant import models as tenant_models
        from waldur_mastermind.invoices import registrators
        from waldur_mastermind.marketplace import models as marketplace_models
        from waldur_mastermind.marketplace import filters as marketplace_filters
        from waldur_mastermind.marketplace import handlers as marketplace_handlers
        from waldur_mastermind.marketplace import signals as marketplace_signals
        from waldur_mastermind.marketplace.plugins import manager
        from waldur_mastermind.marketplace.plugins import Component
        from waldur_mastermind.marketplace_openstack.registrators import MarketplaceItemRegistrator
        from waldur_mastermind.packages import models as package_models

        from . import (
            filters, handlers, processors,
            INSTANCE_TYPE, VOLUME_TYPE, PACKAGE_TYPE,
            RAM_TYPE, CORES_TYPE, STORAGE_TYPE, AVAILABLE_LIMITS
        )

        marketplace_filters.ExternalOfferingFilterBackend.register(filters.VpcExternalFilter())

        signals.post_save.connect(
            handlers.create_offering_from_tenant,
            sender=openstack_models.Tenant,
            dispatch_uid='waldur_mastermind.marketpace_openstack.create_offering_from_tenant',
        )

        signals.pre_delete.connect(
            handlers.archive_offering,
            sender=structure_models.ServiceSettings,
            dispatch_uid='waldur_mastermind.marketpace_openstack.archive_offering',
        )

        resource_models = (tenant_models.Instance, tenant_models.Volume, openstack_models.Tenant)
        marketplace_handlers.connect_resource_metadata_handlers(*resource_models)
        marketplace_handlers.connect_resource_handlers(*resource_models)

        signals.post_save.connect(
            handlers.create_template_for_plan,
            sender=marketplace_models.Plan,
            dispatch_uid='waldur_mastermind.marketpace_openstack.create_template_for_plan',
        )

        signals.post_save.connect(
            handlers.update_template_for_plan,
            sender=marketplace_models.Plan,
            dispatch_uid='waldur_mastermind.marketpace_openstack.update_template_for_plan',
        )

        signals.post_save.connect(
            handlers.update_plan_for_template,
            sender=package_models.PackageTemplate,
            dispatch_uid='waldur_mastermind.marketpace_openstack.update_plan_for_template',
        )

        signals.post_save.connect(
            handlers.synchronize_plan_component,
            sender=marketplace_models.PlanComponent,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_plan_component',
        )

        FIXED = marketplace_models.OfferingComponent.BillingTypes.FIXED
        manager.register(offering_type=PACKAGE_TYPE,
                         create_resource_processor=processors.PackageCreateProcessor,
                         update_resource_processor=processors.PackageUpdateProcessor,
                         delete_resource_processor=processors.PackageDeleteProcessor,
                         components=(
                             Component(type=CORES_TYPE, name='Cores', measured_unit='cores', billing_type=FIXED),
                             # Price is stored per GiB but size is stored per MiB
                             # therefore we need to divide size by factor when price estimate is calculated.
                             Component(type=RAM_TYPE, name='RAM', measured_unit='GB', billing_type=FIXED, factor=1024),
                             Component(type=STORAGE_TYPE, name='Storage', measured_unit='GB', billing_type=FIXED, factor=1024),
                         ),
                         service_type=OpenStackConfig.service_name,
                         secret_attributes=get_secret_attributes,
                         available_limits=AVAILABLE_LIMITS,
                         resource_model=openstack_models.Tenant)

        manager.register(offering_type=INSTANCE_TYPE,
                         create_resource_processor=processors.InstanceCreateProcessor,
                         delete_resource_processor=processors.InstanceDeleteProcessor,
                         resource_model=tenant_models.Instance)

        manager.register(offering_type=VOLUME_TYPE,
                         create_resource_processor=processors.VolumeCreateProcessor,
                         delete_resource_processor=processors.VolumeDeleteProcessor,
                         resource_model=tenant_models.Volume)

        signals.post_save.connect(
            handlers.synchronize_volume_metadata,
            sender=tenant_models.Volume,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_volume_metadata',
        )

        signals.post_save.connect(
            handlers.synchronize_instance_metadata,
            sender=tenant_models.Instance,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_instance_metadata',
        )

        signals.post_save.connect(
            handlers.synchronize_internal_ips,
            sender=tenant_models.InternalIP,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_internal_ips',
        )

        signals.post_save.connect(
            handlers.synchronize_floating_ips,
            sender=tenant_models.FloatingIP,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_floating_ips',
        )

        signals.post_delete.connect(
            handlers.synchronize_internal_ips_on_delete,
            sender=tenant_models.InternalIP,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_internal_ips_on_delete',
        )

        signals.post_delete.connect(
            handlers.synchronize_floating_ips_on_delete,
            sender=tenant_models.FloatingIP,
            dispatch_uid='waldur_mastermind.marketpace_openstack.synchronize_floating_ips_on_delete',
        )

        signals.post_save.connect(
            handlers.create_resource_of_volume_if_instance_created,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketpace_openstack.'
                         'create_resource_of_volume_if_instance_created',
        )

        for model in [tenant_models.Instance, tenant_models.Volume, openstack_models.Tenant]:
            structure_signals.resource_imported.connect(
                handlers.create_marketplace_resource_for_imported_resources,
                sender=model,
                dispatch_uid='waldur_mastermind.marketpace_openstack.'
                             'create_resource_for_imported_%s' % model,
            )

        signals.post_save.connect(
            handlers.import_resource_metadata_when_resource_is_created,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketpace_openstack.'
                         'import_resource_metadata_when_resource_is_created',
        )

        signals.post_save.connect(
            handlers.update_openstack_tenant_usages,
            sender=quota_models.Quota,
            dispatch_uid='waldur_mastermind.marketpace_openstack.'
                         'update_openstack_tenant_usages',
        )

        registrators.RegistrationManager.add_registrator(
            marketplace_models.Resource,
            MarketplaceItemRegistrator,
        )

        marketplace_signals.resource_creation_succeeded.connect(
            handlers.update_invoice_when_resource_is_created,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.'
                         'update_invoice_when_resource_is_created',
        )

        marketplace_signals.limit_update_succeeded.connect(
            handlers.update_invoice_when_resource_is_updated,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.'
                         'update_invoice_when_resource_is_updated',
        )

        marketplace_signals.resource_deletion_succeeded.connect(
            handlers.update_invoice_when_resource_is_deleted,
            sender=marketplace_models.Resource,
            dispatch_uid='waldur_mastermind.marketplace.'
                         'update_invoice_when_resource_is_deleted',
        )
<|endoftext|>


<commit_before>#####################################################################
#
# This file contains code relevant to the construction and use of
# an injection grid for Balrog objects (for now, likely just
# galaxies). Only rectangular and hexagonal grids currently
# supported.
#
#
# Spencer Everett
# UCSC
# 5/2/18
#####################################################################

import numpy as np
import matplotlib.pyplot as plt
# import pudb

class Grid(object):

    def __init__(self, grid_spacing, wcs, Npix_x=10000, Npix_y=10000, pixscale=0.2631,
                 rot_angle=None, pos_offset=None, angle_unit='rad'):
        self.grid_spacing = grid_spacing  # arcsec
        self.im_gs = grid_spacing * (1.0 / pixscale)  # pixels
        self.Npix_x, self.Npix_y = Npix_x, Npix_y
        self.pixscale = pixscale  # arcsec
        self.wcs = wcs
        self.rot_angle = rot_angle # rotation angle, in rad
        self.angle_unit = angle_unit

        if pos_offset:
            self.pos_offset = pos_offset
        else:
            self.pos_offset = [0., 0.]

        # May have to modify grid corners if there is a rotation
        if rot_angle:
            dx = Npix_x / 2.
            dy = Npix_y / 2.
            if angle_unit == 'deg':
                theta = np.deg2rad(rot_angle)
            else:
                theta = rot_angle
            self.startx = (0.-dx) * np.cos(theta) - (Npix_y-dy) * np.sin(theta) + dx
            self.endx = (Npix_x-dx) * np.cos(theta) - (0.-dy) * np.sin(theta) + dx
            self.starty = (0.-dx) * np.cos(theta) + (0.-dy) * np.sin(theta) + dx
            self.endy = (Npix_x-dx) * np.cos(theta) + (Npix_y-dy) * np.sin(theta) + dx
        else:
            self.startx, self.endx= 0., Npix_x
            self.starty, self.endy= 0., Npix_y

        return

    def rotate_grid(self, theta, offset=None, angle_unit='rad'):

        if angle_unit == 'rad': pass
        elif angle_unit == 'deg': theta = np.deg2rad(theta)
        else: raise ValueError('`angle_unit` can only be `deg` or `rad`! ' +
                               'Passed unit of {}'.format(angle_unit))

        if not offset: offset = [0., 0.]

        c, s = np.cos(theta), np.sin(theta)
        R = np.array(((c,-s), (s, c)))

        offset_grid = np.array([self.im_ra - offset[0], self.im_dec - offset[1]])
        translate = np.empty_like(offset_grid)
        translate[0,:] = offset[0]
        translate[1,:] = offset[1]

        rotated_grid = np.dot(R, offset_grid) + translate

        self.im_pos = rotated_grid.T
        self.im_ra, self.im_dec = self.im_pos[0,:], self.im_pos[1,:]

        return

    def cut2buffer(self):
        '''
        Remove objects outside of tile (and buffer).
        We must sample points in the buffer zone in the beginning due to
        possible rotations.
        '''
        b = self.im_gs
        in_region = np.where( (self.im_pos[:,0]>b) & (self.im_pos[:,0]<self.Npix_x-b) &
                              (self.im_pos[:,1]>b) & (self.im_pos[:,1]<self.Npix_y-b) )
        self.im_pos = self.im_pos[in_region]
        self.im_ra = self.im_pos[:,0]
        self.im_dec = self.im_pos[:,1]

        # Get all image coordinate pairs
        self.pos = self.wcs.wcs_pix2world(self.im_pos, 1)
        self.ra = self.pos[:,0]
        self.dec = self.pos[:,1]

        return

class RectGrid(Grid):
    def __init__(self, grid_spacing, wcs, Npix_x=10000, Npix_y=10000, pixscale=0.2631,
                 rot_angle=None, pos_offset=None, angle_unit='rad'):
        super(RectGrid, self).__init__(grid_spacing, wcs, Npix_x=Npix_x, Npix_y=Npix_y,
                                       pixscale=pixscale, rot_angle=rot_angle,
                                       pos_offset=pos_offset, angle_unit=angle_unit)
        self._create_grid()

        return

    def _create_grid(self):
        im_gs = self.im_gs

        po = self.pos_offset
        im_po = po / self.pixscale
        self.im_ra  = np.arange(self.startx, self.endx, im_gs)
        self.im_dec = np.arange(self.starty, self.endy, im_gs)

        # Get all image coordinate pairs
        self.im_pos = np.array(np.meshgrid(self.im_ra, self.im_dec)).T.reshape(
                -1, 2)
        self.im_ra  = self.im_pos[:,0]
        self.im_dec = self.im_pos[:,1]

        if self.rot_angle:
            self.rotate_grid(self.rot_angle, angle_unit=self.angle_unit,
                            offset=[(self.Npix_x+im_po[0])/2., (self.Npix_y+im_po[1])/2.])

        self.cut2buffer()

        return

class HexGrid(Grid):
    def __init__(self, grid_spacing, wcs, Npix_x=10000, Npix_y=10000, pixscale=0.2631,
                 rot_angle=None, pos_offset=None, angle_unit='rad'):
        super(HexGrid, self).__init__(grid_spacing, wcs, Npix_x=Npix_x, Npix_y=Npix_y,
                                       pixscale=pixscale, rot_angle=rot_angle,
                                       pos_offset=pos_offset, angle_unit=angle_unit)
        self._create_grid()

        return

    def _create_grid(self):
        im_gs = self.im_gs

        po = self.pos_offset
        im_po = [p / self.pixscale for p in po]
        self.im_pos = HexGrid.calc_hex_coords(self.startx, self.starty,
                                              self.endx, self.endy, im_gs)

        self.im_ra  = self.im_pos[:,0]
        self.im_dec = self.im_pos[:,1]

        if self.rot_angle:
            self.rotate_grid(self.rot_angle, angle_unit=self.angle_unit,
                            offset=[(self.Npix_x+im_po[0])/2., (self.Npix_y+im_po[1])/2.])

        self.cut2buffer()

        return

    @classmethod
    def calc_hex_coords(cls, startx, starty, endx, endy, radius):
        # Geoemtric factors of given hexagon
        r = radius
        p = r * np.tan(np.pi / 6.) # side length / 2
        h = 4. * p
        dx = 2. * r
        dy = 2. * p

        row = 1

        xs = []
        ys = []

        while startx < endx:
            x = [startx, startx, startx + r, startx + dx, startx + dx, startx + r, startx + r]
            xs.append(x)
            startx += dx

        while starty < endy:
            y = [starty + p, starty + 3*p, starty + h, starty + 3*p, starty + p, starty, starty + dy]
            ys.append(y)
            starty += 2*p
            row += 1

        polygons = [zip(x, y) for x in xs for y in ys]
        hexgrid = cls.polygons2coords(polygons)

        # Some hexagonal elements go beyond boundary; cut these out
        indx = np.where( (hexgrid[:,0]<endx) & (hexgrid[:,1]<endy) )
        return hexgrid[indx]

    @classmethod
    def polygons2coords(HexGrid, p):
        s = np.shape(p)
        L = s[0]*s[1]
        pp = np.array(p).reshape(L,2)
	return np.vstack({tuple(row) for row in pp})
        # NOTE: Requires numpy 1.3.3
        # return np.unique(pp, axis=0)

    def rotate_polygons():
        return

class FibonacciGrid(Grid):
    def __init__(self, wcs, N=1000000):
        pass

    def make_fib_grid(self, N=1000000):
        self.golden_angle = np.pi * (3 - np.sqrt(5))
        theta = self.golden_angle * np.arange(N)
        z = np.linspace(1 - 1.0 / N, 1.0 / N - 1, N)
        radius = np.sqrt(1 - z * z)

        points = np.zeros((N, 3))
        points[:, 0] = radius * np.cos(theta)  # rad
        points[:, 1] = radius * np.sin(theta)  # rad
        points[:, 2] = z

        return points

def plot_fib_grid(points):
    fig = plt.figure()
    fig.set_size_inches(10,10)
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(points[:,0], points[:,1], zs=points[:,2])
    return

def plot_sphere(points):
    fig = plt.figure()
    fig.set_size_inches(10, 10)
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(points[:,0], points[:,1], zs=points[:,2])
    return

def rotate_grid(self, theta, x, y, offset=[0., 0.]):

    c, s = np.cos(theta), np.sin(theta)
    R = np.array(((c,-s), (s, c)))

    offset_grid = np.array([x - offset[0], y - offset[1]])
    translate = np.empty_like(offset_grid)
    translate[0,:] = offset[0]
    translate[1,:] = offset[1]

    offset_grid = np.dot(R, offset_grid) + translate

    return
<commit_msg>Fixed `HexGrid` bug where redundant positions werent being caught due to some rounding on the order of ~1e-10 pixels.<commit_after>#####################################################################
#
# This file contains code relevant to the construction and use of
# an injection grid for Balrog objects (for now, likely just
# galaxies). Only rectangular and hexagonal grids currently
# supported.
#
#
# Spencer Everett
# UCSC
# 5/2/18
#####################################################################

import numpy as np
import matplotlib.pyplot as plt
import pudb

class Grid(object):

    def __init__(self, grid_spacing, wcs, Npix_x=10000, Npix_y=10000, pixscale=0.2631,
                 rot_angle=None, pos_offset=None, angle_unit='rad'):
        self.grid_spacing = grid_spacing  # arcsec
        self.im_gs = grid_spacing * (1.0 / pixscale)  # pixels
        self.Npix_x, self.Npix_y = Npix_x, Npix_y
        self.pixscale = pixscale  # arcsec
        self.wcs = wcs
        self.rot_angle = rot_angle # rotation angle, in rad
        self.angle_unit = angle_unit

        if pos_offset:
            self.pos_offset = pos_offset
        else:
            self.pos_offset = [0., 0.]

        # May have to modify grid corners if there is a rotation
        if rot_angle:
            dx = Npix_x / 2.
            dy = Npix_y / 2.
            if angle_unit == 'deg':
                theta = np.deg2rad(rot_angle)
            else:
                theta = rot_angle
            self.startx = (0.-dx) * np.cos(theta) - (Npix_y-dy) * np.sin(theta) + dx
            self.endx = (Npix_x-dx) * np.cos(theta) - (0.-dy) * np.sin(theta) + dx
            self.starty = (0.-dx) * np.cos(theta) + (0.-dy) * np.sin(theta) + dx
            self.endy = (Npix_x-dx) * np.cos(theta) + (Npix_y-dy) * np.sin(theta) + dx
        else:
            self.startx, self.endx= 0., Npix_x
            self.starty, self.endy= 0., Npix_y

        return

    def rotate_grid(self, theta, offset=None, angle_unit='rad'):

        if angle_unit == 'rad': pass
        elif angle_unit == 'deg': theta = np.deg2rad(theta)
        else: raise ValueError('`angle_unit` can only be `deg` or `rad`! ' +
                               'Passed unit of {}'.format(angle_unit))

        if not offset: offset = [0., 0.]

        c, s = np.cos(theta), np.sin(theta)
        R = np.array(((c,-s), (s, c)))

        offset_grid = np.array([self.im_ra - offset[0], self.im_dec - offset[1]])
        translate = np.empty_like(offset_grid)
        translate[0,:] = offset[0]
        translate[1,:] = offset[1]

        rotated_grid = np.dot(R, offset_grid) + translate

        self.im_pos = rotated_grid.T
        self.im_ra, self.im_dec = self.im_pos[0,:], self.im_pos[1,:]

        return

    def cut2buffer(self):
        '''
        Remove objects outside of tile (and buffer).
        We must sample points in the buffer zone in the beginning due to
        possible rotations.
        '''
        b = self.im_gs
        in_region = np.where( (self.im_pos[:,0]>b) & (self.im_pos[:,0]<self.Npix_x-b) &
                              (self.im_pos[:,1]>b) & (self.im_pos[:,1]<self.Npix_y-b) )
        self.im_pos = self.im_pos[in_region]
        self.im_ra = self.im_pos[:,0]
        self.im_dec = self.im_pos[:,1]

        # Get all image coordinate pairs
        self.pos = self.wcs.wcs_pix2world(self.im_pos, 1)
        self.ra = self.pos[:,0]
        self.dec = self.pos[:,1]

        return

class RectGrid(Grid):
    def __init__(self, grid_spacing, wcs, Npix_x=10000, Npix_y=10000, pixscale=0.2631,
                 rot_angle=None, pos_offset=None, angle_unit='rad'):
        super(RectGrid, self).__init__(grid_spacing, wcs, Npix_x=Npix_x, Npix_y=Npix_y,
                                       pixscale=pixscale, rot_angle=rot_angle,
                                       pos_offset=pos_offset, angle_unit=angle_unit)
        self._create_grid()

        return

    def _create_grid(self):
        im_gs = self.im_gs

        po = self.pos_offset
        im_po = po / self.pixscale
        self.im_ra  = np.arange(self.startx, self.endx, im_gs)
        self.im_dec = np.arange(self.starty, self.endy, im_gs)

        # Get all image coordinate pairs
        self.im_pos = np.array(np.meshgrid(self.im_ra, self.im_dec)).T.reshape(
                -1, 2)
        self.im_ra  = self.im_pos[:,0]
        self.im_dec = self.im_pos[:,1]

        if self.rot_angle:
            self.rotate_grid(self.rot_angle, angle_unit=self.angle_unit,
                            offset=[(self.Npix_x+im_po[0])/2., (self.Npix_y+im_po[1])/2.])

        self.cut2buffer()

        return

class HexGrid(Grid):
    def __init__(self, grid_spacing, wcs, Npix_x=10000, Npix_y=10000, pixscale=0.2631,
                 rot_angle=None, pos_offset=None, angle_unit='rad'):
        super(HexGrid, self).__init__(grid_spacing, wcs, Npix_x=Npix_x, Npix_y=Npix_y,
                                       pixscale=pixscale, rot_angle=rot_angle,
                                       pos_offset=pos_offset, angle_unit=angle_unit)
        self._create_grid()

        return

    def _create_grid(self):
        im_gs = self.im_gs

        po = self.pos_offset
        im_po = [p / self.pixscale for p in po]
        pudb.set_trace()
        self.im_pos = HexGrid.calc_hex_coords(self.startx, self.starty,
                                              self.endx, self.endy, im_gs)

        self.im_ra  = self.im_pos[:,0]
        self.im_dec = self.im_pos[:,1]

        if self.rot_angle:
            self.rotate_grid(self.rot_angle, angle_unit=self.angle_unit,
                            offset=[(self.Npix_x+im_po[0])/2., (self.Npix_y+im_po[1])/2.])

        self.cut2buffer()

        return

    @classmethod
    def calc_hex_coords(cls, startx, starty, endx, endy, radius):
        # Geoemtric factors of given hexagon
        r = radius
        p = r * np.tan(np.pi / 6.) # side length / 2
        h = 4. * p
        dx = 2. * r
        dy = 2. * p

        row = 1

        xs = []
        ys = []

        while startx < endx:
            x = [startx, startx, startx + r, startx + dx, startx + dx, startx + r, startx + r]
            xs.append(x)
            startx += dx

        while starty < endy:
            y = [starty + p, starty + 3*p, starty + h, starty + 3*p, starty + p, starty, starty + dy]
            ys.append(y)
            starty += 2*p
            row += 1

        polygons = [zip(x, y) for x in xs for y in ys]
        hexgrid = cls.polygons2coords(polygons)

        # Some hexagonal elements go beyond boundary; cut these out
        indx = np.where( (hexgrid[:,0]<endx) & (hexgrid[:,1]<endy) )
        return hexgrid[indx]

    @classmethod
    def polygons2coords(HexGrid, p):
        s = np.shape(p)
        L = s[0]*s[1]
        pp = np.array(p).reshape(L,2)
        c = np.vstack({tuple(row) for row in pp})
        # Some of the redundant coordinates are offset by ~1e-10 pixels
        return np.unique(c.round(decimals=6), axis=0)

    def rotate_polygons():
        return

class FibonacciGrid(Grid):
    def __init__(self, wcs, N=1000000):
        pass

    def make_fib_grid(self, N=1000000):
        self.golden_angle = np.pi * (3 - np.sqrt(5))
        theta = self.golden_angle * np.arange(N)
        z = np.linspace(1 - 1.0 / N, 1.0 / N - 1, N)
        radius = np.sqrt(1 - z * z)

        points = np.zeros((N, 3))
        points[:, 0] = radius * np.cos(theta)  # rad
        points[:, 1] = radius * np.sin(theta)  # rad
        points[:, 2] = z

        return points

def plot_fib_grid(points):
    fig = plt.figure()
    fig.set_size_inches(10,10)
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(points[:,0], points[:,1], zs=points[:,2])
    return

def plot_sphere(points):
    fig = plt.figure()
    fig.set_size_inches(10, 10)
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(points[:,0], points[:,1], zs=points[:,2])
    return

def rotate_grid(self, theta, x, y, offset=[0., 0.]):

    c, s = np.cos(theta), np.sin(theta)
    R = np.array(((c,-s), (s, c)))

    offset_grid = np.array([x - offset[0], y - offset[1]])
    translate = np.empty_like(offset_grid)
    translate[0,:] = offset[0]
    translate[1,:] = offset[1]

    offset_grid = np.dot(R, offset_grid) + translate

    return
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

from __future__ import with_statement

import codecs
import datetime
import os
import sys

from docutils.core import publish_parts
from jinja2 import Environment
from jinja2.loaders import FileSystemLoader
from jinja2.utils import open_if_exists

import conf

class Site(object):
    def __init__(self):
        self.url = conf.SITE_URL.rstrip('/')

        fs_loader = FileSystemLoader(conf.TEMPLATES_PATH, encoding="utf-8")
        self.env = Environment(loader=fs_loader)
        self.env.charset = 'utf-8'
        self.env.filters['rel_url'] = self.rel_url

    def rel_url(self, value):
        return value.split(self.url)[1]

    def render(self):
        for curr_path, dirs, files in os.walk(conf.INPUT_PATH):
            tgt_path = curr_path.replace(conf.INPUT_PATH, conf.OUTPUT_PATH)
            if not os.path.isdir(tgt_path):
                os.makedirs(tgt_path)
            self.process(files, curr_path, tgt_path)

    def process(self, files, curr_path, tgt_path):
        for f in files:
            page = Page(self, f, curr_path, tgt_path)
            if not page.needed():
                continue

            print "Page: %s" % page.source
            page.write()

    def get_template(self, name):
        return self.env.get_template(name)

class Page(object):

    def __init__(self, site, filename, curr_path, tgt_path):
        self.site = site
        self.filename = filename
        self.source = os.path.join(curr_path, filename)
        self.headers = {}
        self.body = ""

        with open(self.source, 'Ur') as handle:
            raw = handle.read()

        try:
            headers, body = raw.split("\n\n", 1)
        except ValueError:
            headers, body = "", raw

        try:
            for line in headers.splitlines():
                name, value = line.split(':', 1)
                self.headers[name.strip()] = value.strip()
        except ValueError:
            self.headers = {}
            body = "\n\n".join([headers, body])
        self.headers['pubDate'] = ctime = os.stat(self.source).st_ctime
        self.headers['published'] = datetime.datetime.fromtimestamp(ctime)

        basename, oldext = os.path.splitext(filename)
        oldext = oldext.lower()[1:]
        converter = getattr(self, "convert_%s" % oldext, lambda x: x)
        self.body = converter(body)

        newext = self.headers.get('ext', '.html')
        self.target = os.path.join(tgt_path, "%s%s" % (basename, newext))

    def url(self):
        path = self.target.split(conf.OUTPUT_PATH)[1].lstrip('/')
        return "/".join([self.site.url, path])

    def needed(self):
        for f in "force --force -f":
            if f in sys.argv[1:]:
                return True

        if not os.path.exists(self.target):
            return True

        smtime = os.stat(self.source).st_mtime
        tmtime = os.stat(self.target).st_mtime
        return smtime > tmtime

    def write(self):
        contents = self.render()
        with codecs.open(self.target, 'w', 'utf-8') as tgt:
            tgt.write(contents)

    def render(self):
        tmpl_name = self.headers.get('template')
        if not tmpl_name:
            return self.body

        kwargs = {"conf": conf, "body": self.body, "url": self.url()}
        kwargs.update(self.headers)
        return self.site.get_template(tmpl_name).render(kwargs)

    def convert_rst(self, body):
        parts = publish_parts(source=body, writer_name="html")
        return parts['html_body']

def main():
    Site().render()

if __name__ == "__main__":
    main()
<commit_msg>Fix forced builds.<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

from __future__ import with_statement

import codecs
import datetime
import os
import sys

from docutils.core import publish_parts
from jinja2 import Environment
from jinja2.loaders import FileSystemLoader
from jinja2.utils import open_if_exists

import conf

class Site(object):
    def __init__(self):
        self.url = conf.SITE_URL.rstrip('/')

        fs_loader = FileSystemLoader(conf.TEMPLATES_PATH, encoding="utf-8")
        self.env = Environment(loader=fs_loader)
        self.env.charset = 'utf-8'
        self.env.filters['rel_url'] = self.rel_url

    def rel_url(self, value):
        return value.split(self.url)[1]

    def render(self):
        for curr_path, dirs, files in os.walk(conf.INPUT_PATH):
            tgt_path = curr_path.replace(conf.INPUT_PATH, conf.OUTPUT_PATH)
            if not os.path.isdir(tgt_path):
                os.makedirs(tgt_path)
            self.process(files, curr_path, tgt_path)

    def process(self, files, curr_path, tgt_path):
        for f in files:
            page = Page(self, f, curr_path, tgt_path)
            if not page.needed():
                continue

            print "Page: %s" % page.source
            page.write()

    def get_template(self, name):
        return self.env.get_template(name)

class Page(object):

    def __init__(self, site, filename, curr_path, tgt_path):
        self.site = site
        self.filename = filename
        self.source = os.path.join(curr_path, filename)
        self.headers = {}
        self.body = ""

        with open(self.source, 'Ur') as handle:
            raw = handle.read()

        try:
            headers, body = raw.split("\n\n", 1)
        except ValueError:
            headers, body = "", raw

        try:
            for line in headers.splitlines():
                name, value = line.split(':', 1)
                self.headers[name.strip()] = value.strip()
        except ValueError:
            self.headers = {}
            body = "\n\n".join([headers, body])
        self.headers['pubDate'] = ctime = os.stat(self.source).st_ctime
        self.headers['published'] = datetime.datetime.fromtimestamp(ctime)

        basename, oldext = os.path.splitext(filename)
        oldext = oldext.lower()[1:]
        converter = getattr(self, "convert_%s" % oldext, lambda x: x)
        self.body = converter(body)

        newext = self.headers.get('ext', '.html')
        self.target = os.path.join(tgt_path, "%s%s" % (basename, newext))

    def url(self):
        path = self.target.split(conf.OUTPUT_PATH)[1].lstrip('/')
        return "/".join([self.site.url, path])

    def needed(self):
        for f in "force --force -f".split():
            if f in sys.argv[1:]:
                return True

        if not os.path.exists(self.target):
            return True

        smtime = os.stat(self.source).st_mtime
        tmtime = os.stat(self.target).st_mtime
        return smtime > tmtime

    def write(self):
        contents = self.render()
        with codecs.open(self.target, 'w', 'utf-8') as tgt:
            tgt.write(contents)

    def render(self):
        tmpl_name = self.headers.get('template')
        if not tmpl_name:
            return self.body

        kwargs = {"conf": conf, "body": self.body, "url": self.url()}
        kwargs.update(self.headers)
        return self.site.get_template(tmpl_name).render(kwargs)

    def convert_rst(self, body):
        parts = publish_parts(source=body, writer_name="html")
        return parts['html_body']

def main():
    Site().render()

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# ----------------------------------------------------------------------
# Numenta Platform for Intelligent Computing (NuPIC)
# Copyright (C) 2014, Numenta, Inc.  Unless you have an agreement
# with Numenta, Inc., for a separate license for this software code, the
# following terms and conditions apply:
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see http://www.gnu.org/licenses.
#
# http://numenta.org/licenses/
# ----------------------------------------------------------------------

import unittest2 as unittest

from nupic.regions.PyRegion import PyRegion
from nupic.engine import *

class PCANodeTest(unittest.TestCase):

  def testPCANode(self):
    rgen = numpy.random.RandomState(37)

    inputSize = 8

    net = Network()
    sensor = net.addRegion('sensor', 'py.ImageSensor' ,
          '{ width: %d, height: %d }' % (inputSize, inputSize))

    params = """{bottomUpCount: %d,
                SVDSampleCount: 5,
                SVDDimCount: 2}""" % inputSize

    pca = net.addRegion('pca', 'py.PCANode', params)

    #nodeAbove = CreateNode("py.ImageSensor", phase=0, categoryOut=1, dataOut=3,
    #                       width=3, height=1)
    #net.addElement('nodeAbove', nodeAbove)

    linkParams = '{ mapping: in, rfSize: [%d, %d] }' % (inputSize, inputSize)
    net.link('sensor', 'pca', 'UniformLink', linkParams, 'dataOut', 'bottomUpIn')

    net.initialize()

    for i in range(10):
      pca.getSelf()._testInputs = numpy.random.random([inputSize])
      net.run(1)
      #print s.sendRequest('nodeOPrint pca_node')

if __name__ == "__main__":
  unittest.main()
<commit_msg>PCA_Node test: some fixes, WIP<commit_after>#!/usr/bin/env python
# ----------------------------------------------------------------------
# Numenta Platform for Intelligent Computing (NuPIC)
# Copyright (C) 2015, Numenta, Inc.  Unless you have an agreement
# with Numenta, Inc., for a separate license for this software code, the
# following terms and conditions apply:
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see http://www.gnu.org/licenses.
#
# http://numenta.org/licenses/
# ----------------------------------------------------------------------

import unittest
import numpy

from nupic.regions.PyRegion import PyRegion
from nupic.engine import *

class PCANodeTest(unittest.TestCase):

  def testPCANode(self):
    rgen = numpy.random.RandomState(37)

    inputSize = 8

    net = Network()
    sensor = net.addRegion('sensor', 'py.ImageSensor' ,
          '{ width: %d, height: %d }' % (inputSize, inputSize))

    params = """{bottomUpCount: %d,
                SVDSampleCount: 5,
                SVDDimCount: 2}""" % inputSize

    pca = net.addRegion('pca', 'py.PCANode', params)

    #nodeAbove = CreateNode("py.ImageSensor", phase=0, categoryOut=1, dataOut=3,
    #                       width=3, height=1)
    #net.addElement('nodeAbove', nodeAbove)

    linkParams = '{ mapping: in, rfSize: [%d, %d] }' % (inputSize, inputSize)
    net.link('sensor', 'pca', 'UniformLink', linkParams, 'dataOut', 'bottomUpIn')

    net.initialize()

    for i in range(10):
      pca.getSelf()._testInputs = numpy.random.random([inputSize])
      net.run(1)
      print s.sendRequest('nodeOPrint pca_node')

if __name__ == "__main__":
  unittest.main()
<|endoftext|>


<commit_before>import unittest

from hecuba import config
from hecuba.hdict import StorageDict
from app.words import Words
import uuid

class StorageObjTest(unittest.TestCase):

    def test_init_empty(self):

        tablename = "tab1"
        tokens = [(1l, 2l), (2l, 3l), (3l, 4l)]
        nopars = StorageDict([('position', 'int')], [('value', 'int')], tablename, tokens)
        self.assertEqual("tab1", nopars._table)
        self.assertEqual(config.execution_name, nopars._ksp)

        res = ''
        res1 = config.session.execute(
            'SELECT storage_id, primary_keys, columns, class_name, name, tokens, istorage_props FROM hecuba.istorage WHERE storage_id = ' + str(nopars._storage_id) + '')
        for row in res1:
            res = row

        self.assertEqual(uuid.uuid3(uuid.NAMESPACE_DNS, config.execution_name + '.' + tablename), nopars._storage_id)
        self.assertEqual(nopars.__class__.__module__, 'hecuba.hdict')
        self.assertEqual(nopars.__class__.__name__, 'StorageDict')

        rebuild = StorageDict.build_remotely(res)
        self.assertEqual('tab1', rebuild._table)
        self.assertEqual(config.execution_name, rebuild._ksp)
        self.assertEqual(uuid.uuid3(uuid.NAMESPACE_DNS, config.execution_name + '.' + tablename), rebuild._storage_id)

        self.assertEqual(nopars._is_persistent, rebuild._is_persistent)

    def test_flush_items_cached(self):
        config.session.execute("CREATE TABLE IF NOT EXISTS hecuba.tab1(pk1 int, val1 text, PRIMARY KEY(pk1))")
        config.cache_activated = True
        tablename = "tab1"
        tokens = [(1l, 2l), (2l, 3l), (3l, 4l)]
        pd = StorageDict([('position', 'int')], [('value', 'int')], tablename, tokens)
        config.batch_size = 101
        for i in range(100):
            pd[int(i)] = 'ciao' + str(i)
        count, = config.session.execute('SELECT count(*) FROM ksp.tb1')[0]
        self.assertEqual(count, 0)
        pd._flush_items()
        count, = config.session.execute('SELECT count(*) FROM ksp.tb1')[0]
        self.assertEqual(count, 100)

    def test_make_persistent(self):
        config.session.execute("DROP TABLE IF EXISTS hecuba_app.words_de1b645ce2483509b58cbca4592c1430")
        nopars = Words()
        self.assertFalse(nopars._is_persistent)
        config.batch_size = 1
        config.cache_activated = False
        nopars.ciao = 1
        nopars.ciao2 = "1"
        nopars.ciao3 = [1, 2, 3]
        nopars.ciao4 = (1, 2, 3)
        for i in range(10):
            nopars.words[i] = 'ciao'+str(i)

        count, = config.session.execute("SELECT count(*) FROM system_schema.tables WHERE keyspace_name = 'hecuba_app' and table_name = 'words'")[0]
        self.assertEqual(0, count)

        nopars.make_persistent("hecuba_app.wordsso")

        count, = config.session.execute('SELECT count(*) FROM hecuba_app.words_de1b645ce2483509b58cbca4592c1430')[0]
        self.assertEqual(10, count)

    def test_empty_persistent(self):
        config.session.execute("DROP TABLE IF EXISTS hecuba_app.words_de1b645ce2483509b58cbca4592c1430")
        config.session.execute("DROP TABLE IF EXISTS hecuba_app.wordsso_6d5aff9e38263ef3b8b835464659d4ce")
        from app.words import Words
        so = Words()
        so.make_persistent("wordsso")
        so.ciao = "an attribute"
        so.another = 123
        config.batch_size = 1
        config.cache_activated = False
        for i in range(10):
            so.words[i] = str.join(',', map(lambda a: "ciao", range(i)))

        count, = config.session.execute('SELECT count(*) FROM hecuba_app.words_de1b645ce2483509b58cbca4592c1430')[0]
        self.assertEqual(10, count)

        so.delete_persistent()

        count, = config.session.execute('SELECT count(*) FROM hecuba_app.words_de1b645ce2483509b58cbca4592c1430')[0]
        self.assertEqual(0, count)

if __name__ == '__main__':
    unittest.main()
<commit_msg>Some more tests corrected<commit_after>import unittest

from hecuba import config
from hecuba.hdict import StorageDict
from app.words import Words
import uuid

class StorageObjTest(unittest.TestCase):

    def test_init_empty(self):
        # done
        tablename = "tab1"
        tokens = [(1l, 2l), (2l, 3l), (3l, 4l)]
        nopars = StorageDict([('position', 'int')], [('value', 'int')], tablename, tokens)
        self.assertEqual("tab1", nopars._table)
        self.assertEqual(config.execution_name, nopars._ksp)

        res = ''
        res1 = config.session.execute(
            'SELECT storage_id, primary_keys, columns, class_name, name, tokens, istorage_props FROM hecuba.istorage WHERE storage_id = ' + str(nopars._storage_id) + '')
        for row in res1:
            res = row

        self.assertEqual(uuid.uuid3(uuid.NAMESPACE_DNS, config.execution_name + '.' + tablename), nopars._storage_id)
        self.assertEqual(nopars.__class__.__module__, 'hecuba.hdict')
        self.assertEqual(nopars.__class__.__name__, 'StorageDict')

        rebuild = StorageDict.build_remotely(res)
        self.assertEqual('tab1', rebuild._table)
        self.assertEqual(config.execution_name, rebuild._ksp)
        self.assertEqual(uuid.uuid3(uuid.NAMESPACE_DNS, config.execution_name + '.' + tablename), rebuild._storage_id)

        self.assertEqual(nopars._is_persistent, rebuild._is_persistent)

    def test_flush_items_cached(self):
        # in process
        config.session.execute("CREATE TABLE IF NOT EXISTS hecuba.tab1(pk1 int, val1 text, PRIMARY KEY(pk1))")
        config.cache_activated = True
        tablename = "tab1"
        tokens = [(1l, 2l), (2l, 3l), (3l, 4l)]
        pd = StorageDict([('position', 'int')], [('value', 'int')], tablename, tokens)
        config.batch_size = 101
        for i in range(100):
            pd[int(i)] = 'ciao' + str(i)
        count, = config.session.execute('SELECT count(*) FROM ksp.tb1')[0]
        self.assertEqual(count, 0)
        pd._flush_items()
        count, = config.session.execute('SELECT count(*) FROM ksp.tb1')[0]
        self.assertEqual(count, 100)

    def test_make_persistent(self):
        # done
        config.session.execute("DROP TABLE IF EXISTS hecuba.text_7ac343c2eeb1360caae83c606d5da25c")
        nopars = Words()
        self.assertFalse(nopars._is_persistent)
        config.batch_size = 1
        config.cache_activated = False
        nopars.ciao = 1
        nopars.ciao2 = "1"
        nopars.ciao3 = [1, 2, 3]
        nopars.ciao4 = (1, 2, 3)
        for i in range(10):
            nopars.text[i] = 'ciao'+str(i)

        count, = config.session.execute("SELECT count(*) FROM system_schema.tables WHERE keyspace_name = 'hecuba' and table_name = 'text_7ac343c2eeb1360caae83c606d5da25c'")[0]
        self.assertEqual(0, count)

        nopars.make_persistent("wordsso")

        count, = config.session.execute('SELECT count(*) FROM hecuba.text_7ac343c2eeb1360caae83c606d5da25c')[0]
        self.assertEqual(10, count)

    def test_empty_persistent(self):
        # done
        config.session.execute("DROP TABLE IF EXISTS hecuba.wordsso_6d439fbe0b0334779ebc36da44f2e3b7")
        config.session.execute("DROP TABLE IF EXISTS hecuba.text_7ac343c2eeb1360caae83c606d5da25c")
        from app.words import Words
        so = Words()
        so.make_persistent("wordsso")
        so.ciao = "an attribute"
        so.another = 123
        config.batch_size = 1
        config.cache_activated = False
        for i in range(10):
            so.text[i] = str.join(',', map(lambda a: "ciao", range(i)))

        count, = config.session.execute('SELECT count(*) FROM hecuba.text_7ac343c2eeb1360caae83c606d5da25c')[0]
        self.assertEqual(10, count)

        so.delete_persistent()
        so.text.delete_persistent()

        count, = config.session.execute('SELECT count(*) FROM hecuba.text_7ac343c2eeb1360caae83c606d5da25c')[0]
        self.assertEqual(0, count)

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>import math
from interval_utils import *
import gui
import random

friendly_players=["Windfisch","windfisch","Cyanide","cyanide"] +\
    ["Midna","Nayru","Farore","Din","Ezelo","Navi","Zelda","Tetra","Link","Ciela","Linebeck","Salia","Epona","Shiek"] +\
    ["Vaati","Ganon","Ganondorf","Ghirahim","Agahnim"]

class Strategy:
    def __init__(self, c):
        self.target = (0,0)
        self.has_target = False
        self.target_cell = None
        self.color = (0,0,0)
        self.c = c
        self.do_approach_friends = True

    def get_my_smallest(self):
        return sorted(self.c.player.own_cells, key = lambda x: x.mass)[0]

    def dist(self, cell):
        return math.sqrt((cell.pos[0]-self.c.player.center[0])**2 + (cell.pos[1]-self.c.player.center[1])**2)

    def edible(self, cell):
        return ((cell.is_food) or (cell.mass <= self.get_my_smallest().mass * 0.75)) and not (cell.is_virus)

    def threat(self, cell):
        if cell.is_virus and (cell.mass <= self.get_my_smallest().mass * 0.75):
            return True
        elif (cell.mass <= self.get_my_smallest().mass * 1.25):
            return True
        else:
            return False

    def rival(self, cell, food):
        if cell.is_virus or cell.is_food: return False
        if cell.cid in self.c.player.own_ids: return False

        if cell.mass < 1.25*self.get_my_smallest().mass:
            return food.is_food or cell.size > 1.25*food.size
        else:
            return False

    def splitkiller(self, cell):
        return not cell.is_virus and not cell.is_food and cell.mass > 1.25*2*self.get_my_smallest().mass

    def nonsplitkiller(self, cell):
        return not cell.is_virus and not cell.is_food and 1.20*self.get_my_smallest().mass < cell.mass and cell.mass < 1.25*2*self.get_my_smallest().mass

    def quality(self, cell):
        dd_sq = max((cell.pos[0]-self.c.player.center[0])**2 + (cell.pos[1]-self.c.player.center[1])**2,0.001)
        sigma = 500
        dist_score = -math.exp(-dd_sq/(2*sigma**2))

        rivals = filter(lambda r : self.rival(r,cell), self.c.world.cells.values())
        splitkillers = filter(self.splitkiller, self.c.world.cells.values())
        nonsplitkillers = filter(self.nonsplitkiller, self.c.world.cells.values())

        rival_score = 0
        for r in rivals:
            dd_sq = max(0.001, (r.pos[0]-cell.pos[0])**2 + (r.pos[1]-cell.pos[1])**2)
            sigma = r.size + 100
            rival_score += math.exp(-dd_sq/(2*sigma**2))

        splitkill_score = 0
        for s in splitkillers:
            dd_sq = max(0.001, (s.pos[0]-cell.pos[0])**2 + (s.pos[1]-cell.pos[1])**2)
            sigma = (500+2*s.size)
            splitkill_score += math.exp(-dd_sq/(2*sigma**2))

        nonsplitkill_score = 0
        for s in nonsplitkillers:
            dd_sq = max(0.001, (s.pos[0]-cell.pos[0])**2 + (s.pos[1]-cell.pos[1])**2)
            sigma = (300+s.size)
            nonsplitkill_score += math.exp(-dd_sq/(2*sigma**2))

        density_score = 0
        sigma = 300
        for f in filter(lambda c : c.is_food and c!=cell, self.c.world.cells.values()):
            dd_sq = (f.pos[0]-cell.pos[0])**2 + (f.pos[1]-cell.pos[1])**2
            density_score -= math.exp(-dd_sq/(2*sigma**2))

        wall_score = 0
        wall_dist = min( cell.pos[0]-self.c.world.top_left[1], self.c.world.bottom_right[1]-cell.pos[0], cell.pos[1]-self.c.world.top_left[0], self.c.world.bottom_right[0]-cell.pos[1] )
        sigma = 100
        wall_score = math.exp(-wall_dist**2/(2*sigma**2))

        return 2.5*dist_score + 0.2*rival_score + nonsplitkill_score + 5*splitkill_score + 0.1*density_score + 5*wall_score
        ##print (density_score)
        #return density_score

    def weight_cell(self, cell):
        df = (10/self.dist(cell))
        if self.edible(cell):
            quality = self.quality(cell)
            if cell.is_food:
                return 1 + cell.mass * df * quality
            else:
                mf = 1 / ((self.get_my_smallest().mass * 0.75) + 1) - cell.mass
                return cell.mass * df * quality * mf
        elif self.threat(cell):
            if cell.is_virus:
                return -cell.mass * df * 100
            else:
                return -cell.mass * df
        else:
            return 0

    def process_frame(self):
        runaway = False

        my_smallest = min(self.c.player.own_cells, key=lambda cell : cell.mass)
        my_largest =  max(self.c.player.own_cells, key=lambda cell : cell.mass)

        friendly_cells = list(filter(lambda c : c.name in friendly_players, self.c.world.cells.values()))

        if friendly_cells:
            dist_to_friend = min(map(lambda c : (self.c.player.center-c.pos).len() - max(my_largest.size, c.size), friendly_cells))
        else:
            dist_to_friend = 99999999

        if dist_to_friend < 20 or my_largest.mass < 60:
            if self.do_approach_friends: print("not approaching friends")
            self.do_approach_friends = False
        elif dist_to_friend > 200 and my_largest.mass > 60 + 1*16:
            if not self.do_approach_friends: print("approaching friends")
            self.do_approach_friends = True

        if friendly_cells and self.do_approach_friends:
            friend_to_feed = max(friendly_cells, key=lambda c:c.mass)
            if friend_to_feed.mass < 1.25 * my_largest.mass:
                print("friend too small")
                friend_to_feed = None
            if friend_to_feed:
                gui.hilight_cell(friend_to_feed, (255,255,255),(255,127,127),30)

                self.target_cell = friend_to_feed
                self.has_target = True

        if self.do_approach_friends:
            for c in self.c.player.own_cells:
                gui.hilight_cell(c, (255,255,255), (255,127,127), 20)

        # can this cell feed that cell?
        # "False" means "No, definitely not"
        # "True" means "Maybe"
        def can_feed(this, that):
            if that.is_food or that.is_ejected_mass or that.size < 43: # too small cells cannot eat the ejected mass
                return False

            relpos = this.pos-that.pos
            dist = relpos.len()
            if dist == 0 or dist >= 700 + this.size + that.size:
                return False

            return check_cell_in_interval(this.pos, that, (this.movement_angle - 10*math.pi/180, this.movement_angle + 10*math.pi/180))

        success_rate = 0
        for my_cell in self.c.player.own_cells:
            try:
                my_cell.movement_angle
            except AttributeError:
                print("cannot calculate shoot angle, too few backlog")
                continue
            # check if ejecting mass would feed one friend
            possibly_feedable_cells = list(filter(lambda c : can_feed(my_cell, c), self.c.world.cells.values()))
            possibly_feedable_cells.sort(key = lambda c : (my_cell.pos - c.pos).len())

            good_intervals = []
            for feedable in possibly_feedable_cells:
                gui.hilight_cell(feedable, (255,192,127), (127,127,255))
                if feedable not in friendly_cells:
                    break

                good_intervals += canonicalize_angle_interval( interval_occupied_by_cell(my_cell.pos, feedable) )

            good_intervals = merge_intervals(good_intervals)
            area = interval_area( intersection(good_intervals, canonicalize_angle_interval((my_cell.movement_angle - 10*math.pi/180, my_cell.movement_angle + 10*math.pi/180))) )
            success_rate += area / (2*10*math.pi/180) / len(list(self.c.player.own_cells))

        gui.draw_bar(((100,40),(500,24)), success_rate, thresh=.98, color=(0,0,127))
        if success_rate >= 0.98:
            self.c.send_shoot()

        # enemy/virus avoidance
        forbidden_intervals = []
        for cell in self.c.world.cells.values():
            relpos = ((cell.pos[0]-self.c.player.center[0]),(cell.pos[1]-self.c.player.center[1]))
            dist = math.sqrt(relpos[0]**2+relpos[1]**2)

            if ( (not cell.is_virus and dist < ((500+2*cell.size) if cell.mass > 1.25*my_smallest.mass*2 else (300+cell.size)) and  cell.mass > 1.25 * my_smallest.mass) or (cell.is_virus and dist < my_largest.mass and cell.mass < my_largest.mass) ) and not (cell in friendly_cells) or (cell in friendly_cells) and dist < cell.size+10:
                try:
                    angle = math.atan2(relpos[1],relpos[0])
                    corridor_halfwidth = math.asin(cell.size / dist)
                    forbidden_intervals += canonicalize_angle_interval((angle-corridor_halfwidth, angle+corridor_halfwidth))
                    runaway = True
                except:
                    print("TODO FIXME: need to handle enemy cell which is in our centerpoint!")

        # wall avoidance
        if self.c.player.center[0] < self.c.world.top_left[1]+(self.c.player.total_size*2):
            forbidden_intervals += [(0.5*pi, 1.5*pi)]
        if self.c.player.center[0] > self.c.world.bottom_right[1]-(self.c.player.total_size*2):
            forbidden_intervals += [(0,0.5*pi), (1.5*pi, 2*pi)]
        if self.c.player.center[1] < self.c.world.top_left[0]+(self.c.player.total_size*2):
            forbidden_intervals += [(pi, 2*pi)]
        if self.c.player.center[1] > self.c.world.bottom_right[0]-(self.c.player.total_size*2):
            forbidden_intervals += [(0, pi)]

        # if there's actually an enemy to avoid:
        if (runaway):
            # find the largest non-forbidden interval, and run into this direction.

            forbidden_intervals = merge_intervals(forbidden_intervals)

            allowed_intervals = invert_angle_intervals(forbidden_intervals)

            (a,b) = find_largest_angle_interval(allowed_intervals)
            runaway_angle = (a+b)/2
            runaway_x, runaway_y = (self.c.player.center[0]+int(100*math.cos(runaway_angle))), (self.c.player.center[1]+int(100*math.sin(runaway_angle)))

            self.target = (runaway_x, runaway_y)
            self.has_target = False
            self.target_cell = None

            self.color = (255,0,0)

            # a bit of debugging information
            for i in forbidden_intervals:
                gui.draw_arc(self.c.player.center, self.c.player.total_size+10, i, (255,0,255))

        # if however there's no enemy to avoid, try to feed a friend. or chase food or jizz randomly around
        else:
            if self.target_cell != None:
                self.target = tuple(self.target_cell.pos)
                if self.target_cell not in self.c.world.cells.values() or (not self.edible(self.target_cell) and not self.target_cell in friendly_cells):
                    self.target_cell = None
                    self.has_target = False
            elif self.target == tuple(self.c.player.center):
                self.has_target = False
                print("Reached random destination")

            if not self.has_target:
                food = list(filter(self.edible, self.c.world.cells.values()))
                food = sorted(food, key = self.quality)

                if len(food) > 0:
                    self.target = (food[0].pos[0], food[0].pos[1])
                    self.target_cell = food[0]

                    self.has_target = True
                    self.color = (0,0,255)
                else:
                    rx = self.c.player.center[0] + random.randrange(-400, 401)
                    ry = self.c.player.center[1] + random.randrange(-400, 401)
                    self.target = (rx, ry)
                    self.has_target = True
                    self.color = (0,255,0)
                    print("Nothing to do, heading to random targetination: " + str((rx, ry)))

        # more debugging
        gui.draw_line(self.c.player.center, self.target, self.color)

        return self.target
<commit_msg>fix crash when no runaway interval is available<commit_after>import math
from interval_utils import *
import gui
import random

friendly_players=["Windfisch","windfisch","Cyanide","cyanide"] +\
    ["Midna","Nayru","Farore","Din","Ezelo","Navi","Zelda","Tetra","Link","Ciela","Linebeck","Salia","Epona","Shiek"] +\
    ["Vaati","Ganon","Ganondorf","Ghirahim","Agahnim"]

class Strategy:
    def __init__(self, c):
        self.target = (0,0)
        self.has_target = False
        self.target_cell = None
        self.color = (0,0,0)
        self.c = c
        self.do_approach_friends = True

    def get_my_smallest(self):
        return sorted(self.c.player.own_cells, key = lambda x: x.mass)[0]

    def dist(self, cell):
        return math.sqrt((cell.pos[0]-self.c.player.center[0])**2 + (cell.pos[1]-self.c.player.center[1])**2)

    def edible(self, cell):
        return ((cell.is_food) or (cell.mass <= self.get_my_smallest().mass * 0.75)) and not (cell.is_virus)

    def threat(self, cell):
        if cell.is_virus and (cell.mass <= self.get_my_smallest().mass * 0.75):
            return True
        elif (cell.mass <= self.get_my_smallest().mass * 1.25):
            return True
        else:
            return False

    def rival(self, cell, food):
        if cell.is_virus or cell.is_food: return False
        if cell.cid in self.c.player.own_ids: return False

        if cell.mass < 1.25*self.get_my_smallest().mass:
            return food.is_food or cell.size > 1.25*food.size
        else:
            return False

    def splitkiller(self, cell):
        return not cell.is_virus and not cell.is_food and cell.mass > 1.25*2*self.get_my_smallest().mass

    def nonsplitkiller(self, cell):
        return not cell.is_virus and not cell.is_food and 1.20*self.get_my_smallest().mass < cell.mass and cell.mass < 1.25*2*self.get_my_smallest().mass

    def quality(self, cell):
        dd_sq = max((cell.pos[0]-self.c.player.center[0])**2 + (cell.pos[1]-self.c.player.center[1])**2,0.001)
        sigma = 500
        dist_score = -math.exp(-dd_sq/(2*sigma**2))

        rivals = filter(lambda r : self.rival(r,cell), self.c.world.cells.values())
        splitkillers = filter(self.splitkiller, self.c.world.cells.values())
        nonsplitkillers = filter(self.nonsplitkiller, self.c.world.cells.values())

        rival_score = 0
        for r in rivals:
            dd_sq = max(0.001, (r.pos[0]-cell.pos[0])**2 + (r.pos[1]-cell.pos[1])**2)
            sigma = r.size + 100
            rival_score += math.exp(-dd_sq/(2*sigma**2))

        splitkill_score = 0
        for s in splitkillers:
            dd_sq = max(0.001, (s.pos[0]-cell.pos[0])**2 + (s.pos[1]-cell.pos[1])**2)
            sigma = (500+2*s.size)
            splitkill_score += math.exp(-dd_sq/(2*sigma**2))

        nonsplitkill_score = 0
        for s in nonsplitkillers:
            dd_sq = max(0.001, (s.pos[0]-cell.pos[0])**2 + (s.pos[1]-cell.pos[1])**2)
            sigma = (300+s.size)
            nonsplitkill_score += math.exp(-dd_sq/(2*sigma**2))

        density_score = 0
        sigma = 300
        for f in filter(lambda c : c.is_food and c!=cell, self.c.world.cells.values()):
            dd_sq = (f.pos[0]-cell.pos[0])**2 + (f.pos[1]-cell.pos[1])**2
            density_score -= math.exp(-dd_sq/(2*sigma**2))

        wall_score = 0
        wall_dist = min( cell.pos[0]-self.c.world.top_left[1], self.c.world.bottom_right[1]-cell.pos[0], cell.pos[1]-self.c.world.top_left[0], self.c.world.bottom_right[0]-cell.pos[1] )
        sigma = 100
        wall_score = math.exp(-wall_dist**2/(2*sigma**2))

        return 2.5*dist_score + 0.2*rival_score + nonsplitkill_score + 5*splitkill_score + 0.1*density_score + 5*wall_score
        ##print (density_score)
        #return density_score

    def weight_cell(self, cell):
        df = (10/self.dist(cell))
        if self.edible(cell):
            quality = self.quality(cell)
            if cell.is_food:
                return 1 + cell.mass * df * quality
            else:
                mf = 1 / ((self.get_my_smallest().mass * 0.75) + 1) - cell.mass
                return cell.mass * df * quality * mf
        elif self.threat(cell):
            if cell.is_virus:
                return -cell.mass * df * 100
            else:
                return -cell.mass * df
        else:
            return 0

    def process_frame(self):
        runaway = False

        my_smallest = min(self.c.player.own_cells, key=lambda cell : cell.mass)
        my_largest =  max(self.c.player.own_cells, key=lambda cell : cell.mass)

        friendly_cells = list(filter(lambda c : c.name in friendly_players, self.c.world.cells.values()))

        if friendly_cells:
            dist_to_friend = min(map(lambda c : (self.c.player.center-c.pos).len() - max(my_largest.size, c.size), friendly_cells))
        else:
            dist_to_friend = 99999999

        if dist_to_friend < 20 or my_largest.mass < 60:
            if self.do_approach_friends: print("not approaching friends")
            self.do_approach_friends = False
        elif dist_to_friend > 200 and my_largest.mass > 60 + 1*16:
            if not self.do_approach_friends: print("approaching friends")
            self.do_approach_friends = True

        if friendly_cells and self.do_approach_friends:
            friend_to_feed = max(friendly_cells, key=lambda c:c.mass)
            if friend_to_feed.mass < 1.25 * my_largest.mass:
                print("friend too small")
                friend_to_feed = None
            if friend_to_feed:
                gui.hilight_cell(friend_to_feed, (255,255,255),(255,127,127),30)

                self.target_cell = friend_to_feed
                self.has_target = True

        if self.do_approach_friends:
            for c in self.c.player.own_cells:
                gui.hilight_cell(c, (255,255,255), (255,127,127), 20)

        # can this cell feed that cell?
        # "False" means "No, definitely not"
        # "True" means "Maybe"
        def can_feed(this, that):
            if that.is_food or that.is_ejected_mass or that.size < 43: # too small cells cannot eat the ejected mass
                return False

            relpos = this.pos-that.pos
            dist = relpos.len()
            if dist == 0 or dist >= 700 + this.size + that.size:
                return False

            return check_cell_in_interval(this.pos, that, (this.movement_angle - 10*math.pi/180, this.movement_angle + 10*math.pi/180))

        success_rate = 0
        for my_cell in self.c.player.own_cells:
            try:
                my_cell.movement_angle
            except AttributeError:
                print("cannot calculate shoot angle, too few backlog")
                continue
            # check if ejecting mass would feed one friend
            possibly_feedable_cells = list(filter(lambda c : can_feed(my_cell, c), self.c.world.cells.values()))
            possibly_feedable_cells.sort(key = lambda c : (my_cell.pos - c.pos).len())

            good_intervals = []
            for feedable in possibly_feedable_cells:
                gui.hilight_cell(feedable, (255,192,127), (127,127,255))
                if feedable not in friendly_cells:
                    break

                good_intervals += canonicalize_angle_interval( interval_occupied_by_cell(my_cell.pos, feedable) )

            good_intervals = merge_intervals(good_intervals)
            area = interval_area( intersection(good_intervals, canonicalize_angle_interval((my_cell.movement_angle - 10*math.pi/180, my_cell.movement_angle + 10*math.pi/180))) )
            success_rate += area / (2*10*math.pi/180) / len(list(self.c.player.own_cells))

        gui.draw_bar(((100,40),(500,24)), success_rate, thresh=.98, color=(0,0,127))
        if success_rate >= 0.98:
            self.c.send_shoot()

        # enemy/virus avoidance
        forbidden_intervals = []
        for cell in self.c.world.cells.values():
            relpos = ((cell.pos[0]-self.c.player.center[0]),(cell.pos[1]-self.c.player.center[1]))
            dist = math.sqrt(relpos[0]**2+relpos[1]**2)

            if ( (not cell.is_virus and dist < ((500+2*cell.size) if cell.mass > 1.25*my_smallest.mass*2 else (300+cell.size)) and  cell.mass > 1.25 * my_smallest.mass) or (cell.is_virus and dist < my_largest.mass and cell.mass < my_largest.mass) ) and not (cell in friendly_cells) or (cell in friendly_cells) and dist < cell.size+10:
                try:
                    angle = math.atan2(relpos[1],relpos[0])
                    corridor_halfwidth = math.asin(cell.size / dist)
                    forbidden_intervals += canonicalize_angle_interval((angle-corridor_halfwidth, angle+corridor_halfwidth))
                    runaway = True
                except:
                    print("TODO FIXME: need to handle enemy cell which is in our centerpoint!")

        # wall avoidance
        if self.c.player.center[0] < self.c.world.top_left[1]+(self.c.player.total_size*2):
            forbidden_intervals += [(0.5*pi, 1.5*pi)]
        if self.c.player.center[0] > self.c.world.bottom_right[1]-(self.c.player.total_size*2):
            forbidden_intervals += [(0,0.5*pi), (1.5*pi, 2*pi)]
        if self.c.player.center[1] < self.c.world.top_left[0]+(self.c.player.total_size*2):
            forbidden_intervals += [(pi, 2*pi)]
        if self.c.player.center[1] > self.c.world.bottom_right[0]-(self.c.player.total_size*2):
            forbidden_intervals += [(0, pi)]

        # if there's actually an enemy to avoid:
        if (runaway):
            # find the largest non-forbidden interval, and run into this direction.

            forbidden_intervals = merge_intervals(forbidden_intervals)

            allowed_intervals = invert_angle_intervals(forbidden_intervals)

            try:
                (a,b) = find_largest_angle_interval(allowed_intervals)
            except:
                print("TODO FIXME: need to handle no runaway direction being available!")
                (a,b) = (0,0)

            runaway_angle = (a+b)/2
            runaway_x, runaway_y = (self.c.player.center[0]+int(100*math.cos(runaway_angle))), (self.c.player.center[1]+int(100*math.sin(runaway_angle)))

            self.target = (runaway_x, runaway_y)
            self.has_target = False
            self.target_cell = None

            self.color = (255,0,0)

            # a bit of debugging information
            for i in forbidden_intervals:
                gui.draw_arc(self.c.player.center, self.c.player.total_size+10, i, (255,0,255))

        # if however there's no enemy to avoid, try to feed a friend. or chase food or jizz randomly around
        else:
            if self.target_cell != None:
                self.target = tuple(self.target_cell.pos)
                if self.target_cell not in self.c.world.cells.values() or (not self.edible(self.target_cell) and not self.target_cell in friendly_cells):
                    self.target_cell = None
                    self.has_target = False
            elif self.target == tuple(self.c.player.center):
                self.has_target = False
                print("Reached random destination")

            if not self.has_target:
                food = list(filter(self.edible, self.c.world.cells.values()))
                food = sorted(food, key = self.quality)

                if len(food) > 0:
                    self.target = (food[0].pos[0], food[0].pos[1])
                    self.target_cell = food[0]

                    self.has_target = True
                    self.color = (0,0,255)
                else:
                    rx = self.c.player.center[0] + random.randrange(-400, 401)
                    ry = self.c.player.center[1] + random.randrange(-400, 401)
                    self.target = (rx, ry)
                    self.has_target = True
                    self.color = (0,255,0)
                    print("Nothing to do, heading to random targetination: " + str((rx, ry)))

        # more debugging
        gui.draw_line(self.c.player.center, self.target, self.color)

        return self.target
<|endoftext|>