Skip to content

Instantly share code, notes, and snippets.

@xfxf
Last active June 6, 2017 03:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xfxf/f5b5875f7fb4c063adcd6be12e6edfbe to your computer and use it in GitHub Desktop.
Save xfxf/f5b5875f7fb4c063adcd6be12e6edfbe to your computer and use it in GitHub Desktop.
"""
Converts users/tokens from python-social-auth to django-allauth
Makes some assumptions (i.e. single SocialApp of 'facebook' already added)
"""
from django.core.management.base import NoArgsCommand
from django.db import connection, IntegrityError
from allauth.socialaccount.models import SocialAccount, SocialToken
from users.models import User
import json
# social_auth_usersocialauth.provider: socialaccount_socialapp.id
SOCIAL_MAPPINGS = {
'facebook': '1',
}
class Command(NoArgsCommand):
"""Converts python-social-auth database tokens to allauth ones"""
help = __doc__
def dictfetchall(self, cursor):
"""Return all rows from a cursor as a dict"""
columns = [col[0] for col in cursor.description]
return [
dict(zip(columns, row))
for row in cursor.fetchall()
]
def handle_noargs(self, **options):
errors = 0 # counter for errors encountered (script will convert what it can)
skipped = 0 # counter for known issues we skip past
with connection.cursor() as cursor:
cursor.execute("SELECT * from social_auth_usersocialauth ORDER BY id DESC") # recent first
usersocialauth = self.dictfetchall(cursor)
for line in usersocialauth:
if not line.get('uid'):
print("Skipping, no UID")
skipped += 1
continue
if line.get('provider') not in SOCIAL_MAPPINGS:
print("Skipping %s, no valid social mapping for %s" % (line['uid'], line['provider']))
skipped += 1
continue
if line.get('user_id') in [None or '' or ' ']:
print("Skipping %s, no user id" % line['uid'])
skipped += 1
continue
extra_data = line.get('extra_data')
if extra_data:
extra_data_json = json.loads(extra_data)
(last_login, date_joined) = User.objects\
.values_list('last_login', 'date_joined')\
.get(id=line['user_id'])
print("Adding SocialAccount for %s (%s)" % (line['uid'], errors))
try:
# We create/overwrite records always; assume a prior run may have failed.
s, _ = SocialAccount.objects.get_or_create(
provider=line['provider'],
uid=line['uid'],
user_id=line['user_id'],
)
except IntegrityError as e:
print(e)
errors += 1
continue
s.last_login = last_login
s.extra_data = {} # this was used for token information, not relevant in this context
s.date_joined = date_joined
s.save()
if extra_data_json:
access_token = extra_data_json.get('access_token')
if not access_token:
continue
print("Adding SocialToken for %s" % line['uid'])
t, _ = SocialToken.objects.get_or_create(
account_id=s.id,
app_id=SOCIAL_MAPPINGS[line.get('provider')],
)
t.token = access_token
t.expires_at = extra_data_json.get('expires_at')
t.save()
print("Errors: %s, Skipped Records: %s" % (errors, skipped))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment