Example #1
0
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    """
    now = timezone.now()
    if not days:
        days = (now - get_last_updated_date()).days + 1

    for component in COMPONENTS:
        url = URL.format(username=settings.REMOZILLA_USERNAME,
                         password=settings.REMOZILLA_PASSWORD,
                         component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timedelta=days)
        response = requests.get(url)

        if response.status_code != 200:
            raise ValueError('Invalid response from server.')

        bugs = json.loads(response.text)

        for bdata in bugs['bugs']:
            bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

            bug.summary = bdata.get('summary', '')
            bug.creator = get_object_or_none(User,
                                             email=bdata['creator']['name'])

            bug.bug_creation_time = datetime.strptime(bdata['creation_time'],
                                                      '%Y-%m-%dT%H:%M:%SZ')
            bug.component = bdata['component']
            bug.whiteboard = bdata.get('whiteboard', '')

            bug.cc.clear()
            for person in bdata.get('cc', []):
                cc_user = get_object_or_none(User, email=person['name'])
                if cc_user:
                    bug.cc.add(cc_user)

            bug.assigned_to = get_object_or_none(User,
                                                 email=(bdata['assigned_to']\
                                                        ['name']))
            bug.status = bdata['status']
            bug.resolution = bdata.get('resolution', '')
            bug.due_date = bdata.get('cf_due_date', None)
            if 'last_change_time' in bdata:
                bug.bug_last_change_time = datetime.strptime(
                    bdata['last_change_time'], '%Y-%m-%dT%H:%M:%SZ')
            bug.save()

    set_last_updated_date(now)
Example #2
0
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    """
    now = timezone.now()
    if not days:
        days = (now - get_last_updated_date()).days + 1

    for component in COMPONENTS:
        url = URL.format(username=settings.REMOZILLA_USERNAME,
                         password=settings.REMOZILLA_PASSWORD,
                         component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timedelta=days)
        response = requests.get(url)

        if response.status_code != 200:
            raise ValueError('Invalid response from server.')

        bugs = json.loads(response.text)

        for bdata in bugs['bugs']:
            bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

            bug.summary = bdata.get('summary', '')
            bug.creator = get_object_or_none(User,
                                             email=bdata['creator']['name'])

            bug.bug_creation_time = datetime.strptime(bdata['creation_time'],
                                                      '%Y-%m-%dT%H:%M:%SZ')
            bug.component = bdata['component']
            bug.whiteboard = bdata.get('whiteboard', '')

            bug.cc.clear()
            for person in bdata.get('cc', []):
                cc_user = get_object_or_none(User, email=person['name'])
                if cc_user:
                    bug.cc.add(cc_user)

            bug.assigned_to = get_object_or_none(User,
                                                 email=(bdata['assigned_to']\
                                                        ['name']))
            bug.status = bdata['status']
            bug.resolution = bdata.get('resolution', '')
            bug.due_date = bdata.get('cf_due_date', None)
            if 'last_change_time' in bdata:
                bug.bug_last_change_time = datetime.strptime(
                    bdata['last_change_time'], '%Y-%m-%dT%H:%M:%SZ')
            bug.save()

    set_last_updated_date(now)
Example #3
0
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    """
    login_url = LOGIN_URL.format(username=settings.REMOZILLA_USERNAME,
                                 password=settings.REMOZILLA_PASSWORD)
    response = requests.get(login_url).json()
    error = response.get('error')

    # Check the server response and get the token
    if error:
        raise ValueError('Invalid response from server, {0}.'.format(
            response['error']))
    token = response['token']

    now = timezone.now()
    if not days:
        changed_date = get_last_updated_date()
    else:
        changed_date = now - timedelta(int(days))

    for component in components:
        offset = 0
        url = URL.format(token=token,
                         component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timestamp=changed_date,
                         offset=offset,
                         limit=LIMIT)

        while True:
            bugs = requests.get(url).json()
            error = bugs.get('error')

            # Check the server response and get the token
            if error:
                raise ValueError('Invalid response from server, {0}.'.format(
                    bugs['message']))

            remo_bugs = bugs.get('bugs', [])
            if not remo_bugs:
                break

            for bdata in remo_bugs:
                # Get comments for current bug
                comment_url = COMMENT_URL.format(id=bdata['id'], token=token)
                comments = requests.get(comment_url).json()
                error = comments.get('error')

                if error:
                    raise ValueError(
                        'Invalid response from server, {0}.'.format(
                            comments['message']))

                bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

                bug.summary = unicode(bdata.get('summary', ''))
                creator_email = bdata['creator']
                bug.creator = get_object_or_none(User, email=creator_email)
                bug.bug_creation_time = (parse_bugzilla_time(
                    bdata['creation_time']))
                bug.component = bdata['component']
                bug.whiteboard = bdata.get('whiteboard', '')

                bug.cc.clear()
                for email in bdata.get('cc', []):
                    cc_user = get_object_or_none(User, email=email)
                    if cc_user:
                        bug.cc.add(cc_user)

                bug.assigned_to = get_object_or_none(
                    User, email=bdata['assigned_to'])
                bug.status = bdata['status']
                bug.resolution = bdata.get('resolution', '')
                bug.bug_last_change_time = parse_bugzilla_time(
                    bdata.get('last_change_time'))

                automated_voting_trigger = 0
                bug.budget_needinfo.clear()
                bug.council_member_assigned = False
                bug.pending_mentor_validation = False
                for flag in bdata.get('flags', []):
                    if ((flag['status'] == '?'
                         and flag['name'] == 'remo-approval')):
                        automated_voting_trigger += 1
                        if 'Council Reviewer Assigned' in bug.whiteboard:
                            bug.council_member_assigned = True
                    if ((flag['status'] == '?' and flag['name'] == 'needinfo'
                         and 'requestee' in flag and flag['requestee']
                         == (settings.REPS_COUNCIL_ALIAS))):
                        automated_voting_trigger += 1
                    if flag['status'] == '?' and flag['name'] == 'remo-review':
                        bug.pending_mentor_validation = True
                    if (flag['status'] == '?' and flag['name'] == 'needinfo'
                            and 'requestee' in flag):
                        email = flag['requestee']
                        user = get_object_or_none(User, email=email)
                        if user:
                            bug.budget_needinfo.add(user)

                if ((automated_voting_trigger == 2
                     and waffle.switch_is_active('automated_polls'))):
                    bug.council_vote_requested = True

                unicode_id = unicode(bdata['id'])
                bug_comments = comments['bugs'][unicode_id]['comments']
                if bug_comments and bug_comments[0].get('text', ''):
                    # Enforce unicode encoding.
                    bug.first_comment = unicode(bug_comments[0]['text'])

                bug.save()

            offset += LIMIT
            url = urlparams(url, offset=offset)

    set_last_updated_date(now)
Example #4
0
File: tasks.py Project: giallu/remo
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    """
    now = timezone.now()
    if not days:
        days = (now - get_last_updated_date()).days + 1

    for component in components:
        offset = 0
        url = URL.format(username=settings.REMOZILLA_USERNAME,
                         password=settings.REMOZILLA_PASSWORD,
                         component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timedelta=days, offset=offset, limit=LIMIT)
        while True:
            response = requests.get(url)
            if response.status_code != 200:
                raise ValueError('Invalid response from server.')

            bugs = json.loads(response.text)

            if not bugs['bugs']:
                break

            for bdata in bugs['bugs']:
                bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

                bug.summary = bdata.get('summary', '')
                creator_name = bdata['creator']['name']
                bug.creator = get_object_or_none(User, email=creator_name)
                creation_time = datetime.strptime(bdata['creation_time'],
                                                  '%Y-%m-%dT%H:%M:%SZ')
                bug.bug_creation_time = creation_time
                bug.component = bdata['component']
                bug.whiteboard = bdata.get('whiteboard', '')

                bug.cc.clear()
                for person in bdata.get('cc', []):
                    cc_user = get_object_or_none(User, email=person['name'])
                    if cc_user:
                        bug.cc.add(cc_user)

                bug.assigned_to = (
                    get_object_or_none(User,
                                       email=(bdata['assigned_to']['name'])))
                bug.status = bdata['status']
                bug.resolution = bdata.get('resolution', '')
                bug.due_date = bdata.get('cf_due_date', None)
                if 'last_change_time' in bdata:
                    bug.bug_last_change_time = datetime.strptime(
                        bdata['last_change_time'], '%Y-%m-%dT%H:%M:%SZ')
                flags = bdata.get('flags', [])

                bug.flag_status = next((item['status'] for item in flags
                                        if item['status'] == '?'), '')
                bug.flag_name = next((item['name'] for item in flags
                                      if item['name'] == 'remo-review'), '')

                comments = bdata.get('comments', [])
                if comments and comments[0].get('text', ''):
                    bug.first_comment = comments[0]['text']

                bug.save()

            offset += LIMIT
            url = urlparams(url, offset=offset)

    set_last_updated_date(now)
Example #5
0
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    """
    now = timezone.now()
    if not days:
        days = (now - get_last_updated_date()).days + 1

    for component in components:
        offset = 0
        url = URL.format(username=settings.REMOZILLA_USERNAME,
                         password=settings.REMOZILLA_PASSWORD,
                         component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timedelta=days, offset=offset, limit=LIMIT)

        while True:
            response = requests.get(url)
            if response.status_code != 200:
                raise ValueError('Invalid response from server.')

            bugs = json.loads(response.text)

            if not bugs['bugs']:
                break

            for bdata in bugs['bugs']:
                bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

                bug.summary = bdata.get('summary', '')
                creator_name = bdata['creator']['name']
                bug.creator = get_object_or_none(User, email=creator_name)
                bug.bug_creation_time = (
                    parse_bugzilla_time(bdata['creation_time']))
                bug.component = bdata['component']
                bug.whiteboard = bdata.get('whiteboard', '')

                bug.cc.clear()
                for person in bdata.get('cc', []):
                    cc_user = get_object_or_none(User, email=person['name'])
                    if cc_user:
                        bug.cc.add(cc_user)

                bug.assigned_to = get_object_or_none(
                    User, email=bdata['assigned_to']['name'])
                bug.status = bdata['status']
                bug.resolution = bdata.get('resolution', '')
                bug.bug_last_change_time = parse_bugzilla_time(
                    bdata.get('last_change_time'))

                automated_voting_trigger = 0
                for flag in bdata.get('flags', []):
                    if ((flag['status'] == '?'
                         and flag['name'] == 'remo-approval')):
                        automated_voting_trigger += 1
                    if ((flag['status'] == '?'
                         and flag['name'] == 'needinfo'
                         and 'requestee' in flag
                         and flag['requestee']['name'] == (
                             settings.REPS_COUNCIL_ALIAS))):
                        automated_voting_trigger += 1

                if ((automated_voting_trigger == 2
                     and waffle.switch_is_active('automated_polls'))):
                    bug.council_vote_requested = True

                comments = bdata.get('comments', [])
                if comments and comments[0].get('text', ''):
                    bug.first_comment = comments[0]['text']

                bug.save()

            offset += LIMIT
            url = urlparams(url, offset=offset)

    set_last_updated_date(now)
Example #6
0
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    """
    now = timezone.now()
    if not days:
        days = (now - get_last_updated_date()).days + 1

    for component in components:
        offset = 0
        url = URL.format(username=settings.REMOZILLA_USERNAME,
                         password=settings.REMOZILLA_PASSWORD,
                         component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timedelta=days, offset=offset, limit=LIMIT)

        while True:
            response = requests.get(url)
            if response.status_code != 200:
                raise ValueError('Invalid response from server.')

            bugs = json.loads(response.text)

            if not bugs['bugs']:
                break

            for bdata in bugs['bugs']:
                bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

                bug.summary = bdata.get('summary', '')
                creator_name = bdata['creator']['name']
                bug.creator = get_object_or_none(User, email=creator_name)
                bug.bug_creation_time = (
                    parse_bugzilla_time(bdata['creation_time']))
                bug.component = bdata['component']
                bug.whiteboard = bdata.get('whiteboard', '')

                bug.cc.clear()
                for person in bdata.get('cc', []):
                    cc_user = get_object_or_none(User, email=person['name'])
                    if cc_user:
                        bug.cc.add(cc_user)

                bug.assigned_to = get_object_or_none(
                    User, email=bdata['assigned_to']['name'])
                bug.status = bdata['status']
                bug.resolution = bdata.get('resolution', '')
                bug.bug_last_change_time = parse_bugzilla_time(
                    bdata.get('last_change_time'))

                automated_voting_trigger = 0
                bug.budget_needinfo.clear()
                bug.council_member_assigned = False
                bug.pending_mentor_validation = False
                for flag in bdata.get('flags', []):
                    if ((flag['status'] == '?'
                         and flag['name'] == 'remo-approval')):
                        automated_voting_trigger += 1
                        if 'Council Reviewer Assigned' in bug.whiteboard:
                            bug.council_member_assigned = True
                    if ((flag['status'] == '?'
                         and flag['name'] == 'needinfo'
                         and 'requestee' in flag
                         and flag['requestee']['name'] == (
                             settings.REPS_COUNCIL_ALIAS))):
                        automated_voting_trigger += 1
                    if ((flag['status'] == '?'
                         and flag['name'] == 'remo-review')):
                        bug.pending_mentor_validation = True
                    if ((flag['status'] == '?'
                         and flag['name'] == 'needinfo'
                         and 'requestee' in flag
                         and bug.component == 'Budget Requests')):
                        email = flag['requestee']['name']
                        user = get_object_or_none(User, email=email)
                        if user:
                            bug.budget_needinfo.add(user)

                if ((automated_voting_trigger == 2
                     and waffle.switch_is_active('automated_polls'))):
                    bug.council_vote_requested = True

                comments = bdata.get('comments', [])
                if comments and comments[0].get('text', ''):
                    bug.first_comment = comments[0]['text']

                bug.save()

            offset += LIMIT
            url = urlparams(url, offset=offset)

    set_last_updated_date(now)
Example #7
0
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    # TODO: This can trigger a does not exist error because the task was picked
    # by the worker before the transaction was complete. Needs fixing after the
    # upgrade to a Django version > 1.8
    """
    now = timezone.now()
    if not days:
        changed_date = get_last_updated_date()
    else:
        changed_date = now - timedelta(int(days))

    for component in components:
        offset = 0
        url = URL.format(api_key=settings.REMOZILLA_API_KEY,
                         component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timestamp=changed_date,
                         offset=offset,
                         limit=LIMIT)

        while True:
            bugs = requests.get(url).json()
            error = bugs.get('error')

            # Check the server response for errors
            if error:
                raise ValueError('Invalid response from server, {0}.'.format(
                    bugs['message']))

            remo_bugs = bugs.get('bugs', [])
            if not remo_bugs:
                break

            for bdata in remo_bugs:
                # Get comments for current bug
                comment_url = COMMENT_URL.format(
                    id=bdata['id'], api_key=settings.REMOZILLA_API_KEY)
                comments = requests.get(comment_url).json()
                error = comments.get('error')

                if error:
                    raise ValueError(
                        'Invalid response from server, {0}.'.format(
                            comments['message']))

                bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

                bug.summary = bdata.get('summary', '')
                creator_email = bdata['creator']
                bug.creator = get_object_or_none(User, email=creator_email)
                bug.bug_creation_time = parse_bugzilla_time(
                    bdata['creation_time'])
                bug.component = bdata['component']
                bug.whiteboard = bdata.get('whiteboard', '')

                bug.cc.clear()
                for email in bdata.get('cc', []):
                    cc_user = get_object_or_none(User, email=email)
                    if cc_user:
                        bug.cc.add(cc_user)

                bug.assigned_to = get_object_or_none(
                    User, email=bdata['assigned_to'])
                bug.status = bdata['status']
                bug.resolution = bdata.get('resolution', '')
                bug.bug_last_change_time = parse_bugzilla_time(
                    bdata.get('last_change_time'))

                automated_voting_trigger = 0
                bug.budget_needinfo.clear()
                bug.council_member_assigned = False
                bug.pending_mentor_validation = False
                for flag in bdata.get('flags', []):
                    if flag['status'] == '?' and flag['name'] == BUG_APPROVAL:
                        automated_voting_trigger += 1
                        if BUG_WHITEBOARD in bug.whiteboard:
                            bug.council_member_assigned = True
                    if ((flag['status'] == '?' and flag['name'] == 'needinfo'
                         and 'requestee' in flag and flag['requestee']
                         == (settings.REPS_REVIEW_ALIAS))):
                        automated_voting_trigger += 1
                    if flag['status'] == '?' and flag['name'] == BUG_REVIEW:
                        bug.pending_mentor_validation = True
                    if (flag['status'] == '?' and flag['name'] == 'needinfo'
                            and 'requestee' in flag):
                        email = flag['requestee']
                        user = get_object_or_none(User, email=email)
                        if user:
                            bug.budget_needinfo.add(user)

                if automated_voting_trigger == 2 and waffle.switch_is_active(
                        'automated_polls'):
                    bug.council_vote_requested = True

                unicode_id = str(bdata['id'])
                bug_comments = comments['bugs'][unicode_id]['comments']
                if bug_comments and bug_comments[0].get('text', ''):
                    # Enforce unicode encoding.
                    bug.first_comment = bug_comments[0]['text']

                bug.save()

            offset += LIMIT
            url = urlparams(url, offset=offset)

    set_last_updated_date(now)
Example #8
0
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    """
    login_url = LOGIN_URL.format(username=settings.REMOZILLA_USERNAME,
                                 password=settings.REMOZILLA_PASSWORD)
    response = requests.get(login_url).json()
    error = response.get('error')

    # Check the server response and get the token
    if error:
        raise ValueError('Invalid response from server, {0}.'
                         .format(response['error']))
    token = response['token']

    now = timezone.now()
    if not days:
        changed_date = get_last_updated_date()
    else:
        changed_date = now - timedelta(int(days))

    for component in components:
        offset = 0
        url = URL.format(token=token, component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timestamp=changed_date, offset=offset, limit=LIMIT)

        while True:
            bugs = requests.get(url).json()
            error = bugs.get('error')

            # Check the server response and get the token
            if error:
                raise ValueError('Invalid response from server, {0}.'
                                 .format(bugs['message']))

            remo_bugs = bugs.get('bugs', [])
            if not remo_bugs:
                break

            for bdata in remo_bugs:
                # Get comments for current bug
                comment_url = COMMENT_URL.format(id=bdata['id'], token=token)
                comments = requests.get(comment_url).json()
                error = comments.get('error')

                if error:
                    raise ValueError('Invalid response from server, {0}.'
                                     .format(comments['message']))

                bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

                bug.summary = unicode(bdata.get('summary', ''))
                creator_email = bdata['creator']
                bug.creator = get_object_or_none(User, email=creator_email)
                bug.bug_creation_time = (
                    parse_bugzilla_time(bdata['creation_time']))
                bug.component = bdata['component']
                bug.whiteboard = bdata.get('whiteboard', '')

                bug.cc.clear()
                for email in bdata.get('cc', []):
                    cc_user = get_object_or_none(User, email=email)
                    if cc_user:
                        bug.cc.add(cc_user)

                bug.assigned_to = get_object_or_none(
                    User, email=bdata['assigned_to'])
                bug.status = bdata['status']
                bug.resolution = bdata.get('resolution', '')
                bug.bug_last_change_time = parse_bugzilla_time(
                    bdata.get('last_change_time'))

                automated_voting_trigger = 0
                bug.budget_needinfo.clear()
                bug.council_member_assigned = False
                bug.pending_mentor_validation = False
                for flag in bdata.get('flags', []):
                    if ((flag['status'] == '?' and
                         flag['name'] == 'remo-approval')):
                        automated_voting_trigger += 1
                        if 'Council Reviewer Assigned' in bug.whiteboard:
                            bug.council_member_assigned = True
                    if ((flag['status'] == '?' and
                         flag['name'] == 'needinfo' and 'requestee' in flag and
                         flag['requestee'] == (settings.REPS_COUNCIL_ALIAS))):
                        automated_voting_trigger += 1
                    if flag['status'] == '?' and flag['name'] == 'remo-review':
                        bug.pending_mentor_validation = True
                    if (flag['status'] == '?' and flag['name'] == 'needinfo'
                            and 'requestee' in flag):
                        email = flag['requestee']
                        user = get_object_or_none(User, email=email)
                        if user:
                            bug.budget_needinfo.add(user)

                if ((automated_voting_trigger == 2 and
                     waffle.switch_is_active('automated_polls'))):
                    bug.council_vote_requested = True

                unicode_id = unicode(bdata['id'])
                bug_comments = comments['bugs'][unicode_id]['comments']
                if bug_comments and bug_comments[0].get('text', ''):
                    # Enforce unicode encoding.
                    bug.first_comment = unicode(bug_comments[0]['text'])

                bug.save()

            offset += LIMIT
            url = urlparams(url, offset=offset)

    set_last_updated_date(now)
Example #9
0
def fetch_bugs(components=COMPONENTS, days=None):
    """Fetch all bugs from Bugzilla.

    Loop over components and fetch bugs updated the last days. Link
    Bugzilla users with users on this website, when possible.

    """
    now = timezone.now()
    if not days:
        days = (now - get_last_updated_date()).days + 1

    for component in components:
        offset = 0
        url = URL.format(username=settings.REMOZILLA_USERNAME,
                         password=settings.REMOZILLA_PASSWORD,
                         component=quote(component),
                         fields=','.join(BUGZILLA_FIELDS),
                         timedelta=days,
                         offset=offset,
                         limit=LIMIT)
        while True:
            response = requests.get(url)
            if response.status_code != 200:
                raise ValueError('Invalid response from server.')

            bugs = json.loads(response.text)

            if not bugs['bugs']:
                break

            for bdata in bugs['bugs']:
                bug, created = Bug.objects.get_or_create(bug_id=bdata['id'])

                bug.summary = bdata.get('summary', '')
                creator_name = bdata['creator']['name']
                bug.creator = get_object_or_none(User, email=creator_name)
                creation_time = datetime.strptime(bdata['creation_time'],
                                                  '%Y-%m-%dT%H:%M:%SZ')
                bug.bug_creation_time = creation_time
                bug.component = bdata['component']
                bug.whiteboard = bdata.get('whiteboard', '')

                bug.cc.clear()
                for person in bdata.get('cc', []):
                    cc_user = get_object_or_none(User, email=person['name'])
                    if cc_user:
                        bug.cc.add(cc_user)

                bug.assigned_to = (get_object_or_none(
                    User, email=(bdata['assigned_to']['name'])))
                bug.status = bdata['status']
                bug.resolution = bdata.get('resolution', '')
                bug.due_date = bdata.get('cf_due_date', None)
                if 'last_change_time' in bdata:
                    bug.bug_last_change_time = datetime.strptime(
                        bdata['last_change_time'], '%Y-%m-%dT%H:%M:%SZ')
                flags = bdata.get('flags', [])

                bug.flag_status = next(
                    (item['status']
                     for item in flags if item['status'] == '?'), '')
                bug.flag_name = next(
                    (item['name']
                     for item in flags if item['name'] == 'remo-review'), '')

                comments = bdata.get('comments', [])
                if comments and comments[0].get('text', ''):
                    bug.first_comment = comments[0]['text']

                bug.save()

            offset += LIMIT
            url = urlparams(url, offset=offset)

    set_last_updated_date(now)