Skip to content

Instantly share code, notes, and snippets.

@blackboxoperations
Last active October 17, 2019 13:15
Show Gist options
  • Save blackboxoperations/23b95ed8c78227b7b8501b75cd064d20 to your computer and use it in GitHub Desktop.
Save blackboxoperations/23b95ed8c78227b7b8501b75cd064d20 to your computer and use it in GitHub Desktop.
Sync Command for pending dj-stripe release
import datetime
import json
import multiprocessing
import stripe
import sys
import threading
import time
from pprint import pprint
from stripe.error import InvalidRequestError
from django.conf import settings
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from djstripe.models import Card
from djstripe.models import Charge
from djstripe.models import Coupon
from djstripe.models import Customer
from djstripe.models import Invoice
from djstripe.models import PaymentMethod
from djstripe.models import Plan
from djstripe.models import Subscription
from djstripe.settings import get_subscriber_model
stripe.api_key = settings.STRIPE_TEST_SECRET_KEY
stripe.api_version = "2018-05-21"
def handed_threadler(customer):
dj_subscriber = get_subscriber_model().objects.get(email=customer.email)
if dj_subscriber:
customer.metadata = {} or customer.metadata
customer.metadata['djstripe_subscriber'] = dj_subscriber.id
customer.metadata['updated'] = datetime.datetime.now()
customer.save()
def threaded_handler(customer):
print("Handling %s/%s" % (customer.id, customer.email))
try:
customer.sync_from_stripe_data(customer.api_retrieve())
customer._sync_subscriptions()
customer._sync_invoices()
customer._sync_cards()
customer._sync_charges()
except InvalidRequestError as e:
print("ERROR: " + str(e))
def sync_up_with_remote():
custs = Customer.objects.all()
newpeeps = []
for subscriber in User.objects.all():
found = False
for c in custs:
if subscriber == c.subscriber:
found = True
print("found customer %s" % subscriber.email)
break
if not found:
print("couldn't find %s/%d" % (subscriber.email, subscriber.id))
newpeeps.append(subscriber)
for cust in Customer.api_list():
for np in newpeeps:
if 'djstripe_subscriber' not in cust.metadata:
if cust.email == np.email:
pprint("%s %s %s %d" % (cust.id, cust.email, np.email, np.id))
handed_threadler(cust)
class Command(BaseCommand):
"""Sync like you mean it, and make sure to put on your cereal face and get cereal with it"""
help = "Sync stripe data to local data repository"
def weave(self, threads, threshold = 0):
if len(threads) > threshold:
for thread in threads:
thread.join()
threads = []
return threads
def handle(self, *args, **options):
# because no no no until you know know know
return
threads = []
threshold = multiprocessing.cpu_count()
# 1. Things have happened as you've been developing, and there's simply no way
# you've managed to remain in perfect harmony with production databases and datasets,
# because you're not that bright, and I question your dedication to Sparkle Motion
sync_up_with_remote()
# 2. Things have also happened remotely, because you ain't special, and neither is
# your local development environment, snowflake
for customer in Customer.api_list():
print("Annotating Customer: %s " % customer.id)
try:
thread = threading.Thread(target=handed_threadler, args=(customer,))
thread.start()
threads.append(thread)
threads = self.weave(threads=threads, threshold=multiprocessing.cpu_count())
except ObjectDoesNotExist as e:
# these will be created by the djstripe_init_customers command
print("%s %s" % (customer.email, e))
pass
# 2.end You won't always have a number of customers that is perfectly and consistently
# divisible by the number of processes you happen to have on whatever machine you're
# currently on, so address the stragglers
self.weave(threads)
# 3. Finally, with a local development environment that won't throw DoesNotExist or
# OopsYouJustMadeThatCustomer19MoreTimesGoodJob or WowYouJustChargedThemAgainDidntYou
# error, let's knuckle down and bring allllll the content down into our awesome
# Celeron development machine equipped with a whole GB of DDR2 Memory, because
# we live life dangerously, and on the edge, and eat mayonnaise - whole jars at a time
for customer in Customer.objects.all():
thread = threading.Thread(target=threaded_handler, args=(customer,))
thread.start()
threads.append(thread)
threads = self.weave(threads=threads, threshold=multiprocessing.cpu_count())
self.weave(threads)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment