<commit_before># -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from . import managers, querysets, settings, utils
from decimal import Decimal
from django.core.cache import cache
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.functional import cached_property
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.django_orm import CredentialsField, Storage
import json
import stripe


# South introspection rules for oauth2client's CredentialsField
try:
    from south.modelsinspector import add_introspection_rules
except ImportError:
    pass
else:
    add_introspection_rules(
        [], ['^oauth2client\.django_orm\.CredentialsField'])


class StripeAPIMixin(models.Model):

    _stripe = stripe

    class Meta(object):
        abstract = True

    def _construct_api_resource(self, cache_data):
        raise NotImplementedError('This method should be overridden.')

    @cached_property
    def _api_cache_name(self):
        return self.__class__.__name__

    def _get_api_resource(self):
        raise NotImplementedError('This method should be overridden.')

    def api(self, refresh=False, clear=False):
        key = 'thecut.stripe:{0}:{1}:api_data'.format(self._api_cache_name,
                                                      self.pk)
        if clear:
            return cache.delete(key)
        if not refresh:
            cache_data = cache.get(key)
            if cache_data:
                return self._construct_api_resource(cache_data)
        resource = self._get_api_resource()
        cache.set(key, json.dumps(resource))
        return resource


class AccountOAuth2Credentials(models.Model):
    """Stores OAuth2 credentials for an Account."""

    # Very yucky to use the id like this, but it is required by oauth2client's
    # django_orm Storage, which blindly created new instances without checking
    # to see if one already exists - with an id, it gets saved over the top).
    id = models.OneToOneField('stripe.Account',
                              related_name='_oauth2_credentials',
                              primary_key=True)

    credentials = CredentialsField()


@python_2_unicode_compatible
class Account(StripeAPIMixin, models.Model):
    """Stripe Account."""

    application = models.ForeignKey('stripe.Application', null=True,
                                    related_name='accounts',
                                    on_delete=models.PROTECT)

    _secret_key = models.TextField('secret key', blank=True, default='')

    _publishable_key = models.TextField('publishable key', blank=True,
                                        default='')

    def __str__(self):
        if self.secret_key:
            try:
                return self.api().get('display_name')
            except Exception as e:
                # This is to stop exception from Stripe breaking admin site.
                # See Note in `stripe_id`
                return "{}".format(e)
        else:
            return 'Disconnected'

    @cached_property
    def _api_cache_name(self):
        return 'Account'  # This is so proxy models share the same cache name.

    def _get_connect_credentials(self, code):
        flow = self.application._get_connect_flow()
        return flow.step2_exchange(code)

    def _get_oauth2_storage(self):
        return Storage(AccountOAuth2Credentials, 'id', self, 'credentials')

    def _construct_api_resource(self, cache_data):
        return self._stripe.Account.construct_from(json.loads(cache_data),
                                                   api_key=self.secret_key)

    def _get_api_resource(self):
        return self._stripe.Account.retrieve(api_key=self.secret_key)

    @property
    def oauth2_credentials(self):
        storage = self._get_oauth2_storage()
        return storage.get()

    @oauth2_credentials.setter
    def oauth2_credentials(self, credentials):<commit_msg>added stricter exception catching in Account.__str__<commit_after># -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from . import managers, querysets, settings, utils
from decimal import Decimal
from django.core.cache import cache
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.functional import cached_property
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.django_orm import CredentialsField, Storage
import json
import stripe


# South introspection rules for oauth2client's CredentialsField
try:
    from south.modelsinspector import add_introspection_rules
except ImportError:
    pass
else:
    add_introspection_rules(
        [], ['^oauth2client\.django_orm\.CredentialsField'])


class StripeAPIMixin(models.Model):

    _stripe = stripe

    class Meta(object):
        abstract = True

    def _construct_api_resource(self, cache_data):
        raise NotImplementedError('This method should be overridden.')

    @cached_property
    def _api_cache_name(self):
        return self.__class__.__name__

    def _get_api_resource(self):
        raise NotImplementedError('This method should be overridden.')

    def api(self, refresh=False, clear=False):
        key = 'thecut.stripe:{0}:{1}:api_data'.format(self._api_cache_name,
                                                      self.pk)
        if clear:
            return cache.delete(key)
        if not refresh:
            cache_data = cache.get(key)
            if cache_data:
                return self._construct_api_resource(cache_data)
        resource = self._get_api_resource()
        cache.set(key, json.dumps(resource))
        return resource


class AccountOAuth2Credentials(models.Model):
    """Stores OAuth2 credentials for an Account."""

    # Very yucky to use the id like this, but it is required by oauth2client's
    # django_orm Storage, which blindly created new instances without checking
    # to see if one already exists - with an id, it gets saved over the top).
    id = models.OneToOneField('stripe.Account',
                              related_name='_oauth2_credentials',
                              primary_key=True)

    credentials = CredentialsField()


@python_2_unicode_compatible
class Account(StripeAPIMixin, models.Model):
    """Stripe Account."""

    application = models.ForeignKey('stripe.Application', null=True,
                                    related_name='accounts',
                                    on_delete=models.PROTECT)

    _secret_key = models.TextField('secret key', blank=True, default='')

    _publishable_key = models.TextField('publishable key', blank=True,
                                        default='')

    def __str__(self):
        if self.secret_key:
            try:
                return self.api().get('display_name')
            except stripe.error.AuthenticationError:
                # This is to stop exception from Stripe breaking admin site.
                # See also Note in `stripe_id`
                return 'Authentication error'
        else:
            return 'Disconnected'

    @cached_property
    def _api_cache_name(self):
        return 'Account'  # This is so proxy models share the same cache name.

    def _get_connect_credentials(self, code):
        flow = self.application._get_connect_flow()
        return flow.step2_exchange(code)

    def _get_oauth2_storage(self):
        return Storage(AccountOAuth2Credentials, 'id', self, 'credentials')

    def _construct_api_resource(self, cache_data):
        return self._stripe.Account.construct_from(json.loads(cache_data),
                                                   api_key=self.secret_key)

    def _get_api_resource(self):
        return self._stripe.Account.retrieve(api_key=self.secret_key)

    @property
    def oauth2_credentials(self):
        storage = self._get_oauth2_storage()
        return storage.get()

    @oauth2_credentials.setter
    def oauth2_credentials(self, credentials):
{'fraction_non_alphanumeric': 0.07954262987820035, 'fraction_numerical': 0.005219985085756898, 'mean_word_length': 2.5988372093023258, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2724637', 'n_tokens_mistral': 2231, 'n_tokens_neox': 2142, 'n_words': 550}