コード例 #1
0
ファイル: git.py プロジェクト: wylee/arctasks
def version(short=True):
    """Get tag associated with HEAD; fall back to SHA1.

    If HEAD is tagged, return the tag name; otherwise fall back to
    HEAD's SHA1, shortened by default.

    .. note:: Only annotated tags are considered.

    TODO: Support non-annotated tags?

    Args:
        short: When falling back to SHA1, this indicates whether to
            return the shortened unique SHA1 (typically 7 characters but
            not always)

    """
    try:
        value = run(["describe", "--exact-match"], return_output=True, stderr=subprocess.DEVNULL)
    except subprocess.CalledProcessError:
        print_warning("HEAD is not tagged; falling back to SHA1")
        value = run(["rev-parse", "--short" if short else "", "HEAD"], return_output=True)
    return value
コード例 #2
0
def remove_duplicate_users(ctx):
    setup()
    from django.apps import apps
    from django.contrib.auth import get_user_model
    from arcutils.db import will_be_deleted_with

    Comment = apps.get_model('comments', 'Comment')
    Image = apps.get_model('images', 'Image')
    Notification = apps.get_model('notifications', 'Notification')
    UserNotificationQuery = apps.get_model('notifications', 'UserNotificationQuery')
    Invite = apps.get_model('reports', 'Invite')
    Report = apps.get_model('reports', 'Report')

    user_model = get_user_model()
    dupes = user_model.objects.raw(
        'SELECT * from "user" u1 '
        'WHERE ('
        '    SELECT count(*) FROM "user" u2 WHERE lower(u2.email) = lower(u1.email )'
        ') > 1 '
        'ORDER BY lower(email)'
    )
    dupes = [d for d in dupes]

    print_info('Found {n} duplicates'.format(n=len(dupes)))

    # Delete any dupes we can.
    # Active and staff users are never deleted.
    # Public users with no associated records will be deleted.
    for user in dupes:
        email = user.email
        objects = list(will_be_deleted_with(user))
        num_objects = len(objects)
        f = locals()
        if user.is_active:
            print('Skipping active user: {email}.'.format_map(f))
        elif user.is_staff:
            print('Skipping inactive staff user: {email}.'.format_map(f))
        elif num_objects == 0:
            print_warning('Deleting {email} will *not* cascade.'.format_map(f))
            if confirm(ctx, 'Delete {email}?'.format_map(f), yes_values=('yes',)):
                print('Okay, deleting {email}...'.format_map(f), end='')
                user.delete()
                dupes.remove(user)
                print('Deleted')
        else:
            print(
                'Deleting {email} would cascade to {num_objects} objects. Skipping.'.format_map(f))

    # Group the remaining duplicates by email address
    grouped_dupes = defaultdict(list)
    for user in dupes:
        email = user.email.lower()
        grouped_dupes[email].append(user)
    grouped_dupes = {email: users for (email, users) in grouped_dupes.items() if len(users) > 1}

    # For each group, find the "best" user (staff > active > inactive).
    # The other users' associated records will be associated with this
    # "winner".
    for email, users in grouped_dupes.items():
        winner = None
        for user in users:
            if user.is_staff:
                winner = user
                break
        if winner is None:
            for user in users:
                if user.is_active:
                    winner = user
                    break
        if winner is None:
            for user in users:
                if user.full_name:
                    winner = user
        if winner is None:
            winner = users[0]
        losers = [user for user in users if user != winner]
        print('Winner:', winner.full_name, '<{0.email}>'.format(winner))
        for loser in losers:
            print('Loser:', loser.full_name, '<{0.email}>'.format(loser))
            print('Re-associating loser objects...', end='')
            Comment.objects.filter(created_by=loser).update(created_by=winner)
            Image.objects.filter(created_by=loser).update(created_by=winner)
            Invite.objects.filter(user=loser).update(user=winner)
            Invite.objects.filter(created_by=loser).update(created_by=winner)
            Notification.objects.filter(user=loser).update(user=winner)
            Report.objects.filter(claimed_by=loser).update(claimed_by=winner)
            Report.objects.filter(created_by=loser).update(created_by=winner)
            UserNotificationQuery.objects.filter(user=loser).update(user=winner)
            print('Done')