# Path: locksmith/common.py
# def enum(name, **enums):
#     def __iter__(self):
# def get_signature(params, signkey):
# def apicall(url, signkey, **params):
# def cache(seconds = 900):
#     def doCache(f):
#         def x(*args, **kwargs):
#     E = type(name or 'Enum', (), enums)
# API_OPERATING_STATUSES = (
#     (1, 'Normal'),
#     (2, 'Degraded Service'),
#     (3, 'Service Disruption'),
#     (4, 'Undergoing Maintenance')
# )
# API_STATUSES = enum('ApiStatuses',
#                     Stealth=0,
#                     Active=1,
#                     Deprecated=2,
#                     Disabled=3)
# KEY_STATUSES = (
#     ('U', 'Unactivated'),
#     ('A', 'Active'),
#     ('S', 'Suspended')
# )
# UNPUBLISHED, PUBLISHED, NEEDS_UPDATE = range(3)
# PUB_STATUSES = (
#     (UNPUBLISHED, 'Unpublished'),
#     (PUBLISHED, 'Published'),
#     (NEEDS_UPDATE, 'Needs Update'),
# )
# 
# Path: locksmith/hub/tasks.py
# @task(max_retries=5)
# def push_key(key, replicate_too=True):
#     if replicate_too:
#         for kps in key.pub_statuses.filter(api__push_enabled=True):
#             if kps.api.name in ReplicatedApiNames:
#                 replicate_key.delay(key, kps.api)
# 
#     endpoints = {UNPUBLISHED: 'create_key/', NEEDS_UPDATE: 'update_key/'}
#     dirty = key.pub_statuses.exclude(status=PUBLISHED).filter(
#               api__push_enabled=True).select_related()
#     if not dirty:
#         print u"Skipping push_key for {k} because all KeyPublicationStatus objects are PUBLISHED.".format(k=key.key)
# 
#     # Retrying immediately on failure would allow a broken or unresponsive
#     # api to prevent other, properly functioning apis from receiving the key.
#     # Thus we use retry_flag to delay the task retry until after attempting
#     # to push to all apis.
#     retry_flag = False
#     for kps in dirty:
#         if kps.api.name in ReplicatedApiNames:
#             # Skip this API because we've queued a replicate_key task above
#             print u"push_key for {k} ignoring {a} because it uses replicate_key.".format(k=key.key, a=kps.api.name)
#             continue
# 
#         endpoint = urljoin(kps.api.url, endpoints[kps.status])
#         try:
#             apicall(endpoint, kps.api.signing_key, api=kps.api.name,
#                     key=kps.key.key, email=kps.key.email, status=kps.key.status)
#             print 'sent key {k} to {a}'.format(k=key.key, a=kps.api.name)
#             kps.status = PUBLISHED
#             kps.save()
# 
#         except Exception as e:
#             ctx = {
#                 'a': str(kps.api.name),
#                 'k': str(key.key),
#                 'e': str(e.read()) if isinstance(e, urllib2.HTTPError) else str(e)
#             }
#             print 'Caught exception while pushing key {k} to {a}: {e}'.format(**ctx)
#             print 'Will retry'
#             retry_flag = True
# 
#     if retry_flag:
#         push_key.retry()


import datetime
from django.db import models
from django.db.models.signals import post_save
from django import forms
from django.contrib.auth.models import User
from locksmith.common import (KEY_STATUSES,
                              PUB_STATUSES,
                              UNPUBLISHED,
                              NEEDS_UPDATE,
                              API_OPERATING_STATUSES,
                              API_STATUSES)
from locksmith.hub.tasks import push_key
from taggit.managers import TaggableManager
    name = models.CharField('Name', max_length=100, blank=True, null=True,
                            db_index=True)
    org_name = models.CharField('Organization Name', max_length=100,
                                blank=True, null=True, db_index=True)
    org_url = models.CharField('Organization URL', blank=True, null=True,
                               max_length=200, db_index=True)
    usage = models.TextField('Intended Usage', blank=True, null=True)

    promotable = models.BooleanField(default=False)
    issued_on = models.DateTimeField(default=datetime.datetime.now, editable=False)

    def __unicode__(self):
        return '%s %s [%s]' % (self.key, self.email, self.status)

    def mark_for_update(self):
        '''
            Note that a change has been made so all Statuses need update
        '''
        self.pub_statuses.exclude(status=UNPUBLISHED).update(status=NEEDS_UPDATE)
        push_key.delay(self)

    class Meta:
        db_table = 'locksmith_hub_key'

class KeyPublicationStatus(models.Model):
    '''
        Status of Key with respect to an API
    '''
    key = models.ForeignKey(Key, related_name='pub_statuses')
    api = models.ForeignKey(Api, related_name='pub_statuses')

# Path: locksmith/common.py
# def enum(name, **enums):
#     def __iter__(self):
# def get_signature(params, signkey):
# def apicall(url, signkey, **params):
# def cache(seconds = 900):
#     def doCache(f):
#         def x(*args, **kwargs):
#     E = type(name or 'Enum', (), enums)
# API_OPERATING_STATUSES = (
#     (1, 'Normal'),
#     (2, 'Degraded Service'),
#     (3, 'Service Disruption'),
#     (4, 'Undergoing Maintenance')
# )
# API_STATUSES = enum('ApiStatuses',
#                     Stealth=0,
#                     Active=1,
#                     Deprecated=2,
#                     Disabled=3)
# KEY_STATUSES = (
#     ('U', 'Unactivated'),
#     ('A', 'Active'),
#     ('S', 'Suspended')
# )
# UNPUBLISHED, PUBLISHED, NEEDS_UPDATE = range(3)
# PUB_STATUSES = (
#     (UNPUBLISHED, 'Unpublished'),
#     (PUBLISHED, 'Published'),
#     (NEEDS_UPDATE, 'Needs Update'),
# )
# 
# Path: locksmith/hub/tasks.py
# @task(max_retries=5)
# def push_key(key, replicate_too=True):
#     if replicate_too:
#         for kps in key.pub_statuses.filter(api__push_enabled=True):
#             if kps.api.name in ReplicatedApiNames:
#                 replicate_key.delay(key, kps.api)
# 
#     endpoints = {UNPUBLISHED: 'create_key/', NEEDS_UPDATE: 'update_key/'}
#     dirty = key.pub_statuses.exclude(status=PUBLISHED).filter(
#               api__push_enabled=True).select_related()
#     if not dirty:
#         print u"Skipping push_key for {k} because all KeyPublicationStatus objects are PUBLISHED.".format(k=key.key)
# 
#     # Retrying immediately on failure would allow a broken or unresponsive
#     # api to prevent other, properly functioning apis from receiving the key.
#     # Thus we use retry_flag to delay the task retry until after attempting
#     # to push to all apis.
#     retry_flag = False
#     for kps in dirty:
#         if kps.api.name in ReplicatedApiNames:
#             # Skip this API because we've queued a replicate_key task above
#             print u"push_key for {k} ignoring {a} because it uses replicate_key.".format(k=key.key, a=kps.api.name)
#             continue
# 
#         endpoint = urljoin(kps.api.url, endpoints[kps.status])
#         try:
#             apicall(endpoint, kps.api.signing_key, api=kps.api.name,
#                     key=kps.key.key, email=kps.key.email, status=kps.key.status)
#             print 'sent key {k} to {a}'.format(k=key.key, a=kps.api.name)
#             kps.status = PUBLISHED
#             kps.save()
# 
#         except Exception as e:
#             ctx = {
#                 'a': str(kps.api.name),
#                 'k': str(key.key),
#                 'e': str(e.read()) if isinstance(e, urllib2.HTTPError) else str(e)
#             }
#             print 'Caught exception while pushing key {k} to {a}: {e}'.format(**ctx)
#             print 'Will retry'
#             retry_flag = True
# 
#     if retry_flag:
#         push_key.retry()


# Path: locksmith/hub/models.py
import datetime
from django.db import models
from django.db.models.signals import post_save
from django import forms
from django.contrib.auth.models import User
from locksmith.common import (KEY_STATUSES,
                              PUB_STATUSES,
                              UNPUBLISHED,
                              NEEDS_UPDATE,
                              API_OPERATING_STATUSES,
                              API_STATUSES)
from locksmith.hub.tasks import push_key
from taggit.managers import TaggableManager

    name = models.CharField('Name', max_length=100, blank=True, null=True,
                            db_index=True)
    org_name = models.CharField('Organization Name', max_length=100,
                                blank=True, null=True, db_index=True)
    org_url = models.CharField('Organization URL', blank=True, null=True,
                               max_length=200, db_index=True)
    usage = models.TextField('Intended Usage', blank=True, null=True)

    promotable = models.BooleanField(default=False)
    issued_on = models.DateTimeField(default=datetime.datetime.now, editable=False)

    def __unicode__(self):
        return '%s %s [%s]' % (self.key, self.email, self.status)

    def mark_for_update(self):
        '''
            Note that a change has been made so all Statuses need update
        '''
        self.pub_statuses.exclude(status=UNPUBLISHED).update(status=NEEDS_UPDATE)
        push_key.delay(self)

    class Meta:
        db_table = 'locksmith_hub_key'

class KeyPublicationStatus(models.Model):
    '''
        Status of Key with respect to an API
    '''
    key = models.ForeignKey(Key, related_name='pub_statuses')
    api = models.ForeignKey(Api, related_name='pub_statuses')

    status = models.IntegerField(default=UNPUBLISHED, choices=PUB_STATUSES)