prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Print progress bar while downloading bugs
  Similar to what we're doing for commits data: 28b83c12c29185c52afb58d94a533a9448969a8a.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `bugbug/bugzilla.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 # This Source Code Form is subject to the terms of the Mozilla Public
  3 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4 # You can obtain one at http://mozilla.org/MPL/2.0/.
  5 
  6 import json
  7 import os
  8 
  9 import requests
  10 from libmozdata import bugzilla
  11 
  12 from bugbug import db
  13 
  14 BUGS_DB = 'data/bugs.json'
  15 db.register(BUGS_DB, 'https://www.dropbox.com/s/xm6wzac9jl81irz/bugs.json.xz?dl=1')
  16 
  17 ATTACHMENT_INCLUDE_FIELDS = [
  18     'id', 'is_obsolete', 'flags', 'is_patch', 'creator', 'content_type', 'creation_time',
  19 ]
  20 
  21 COMMENT_INCLUDE_FIELDS = [
  22     'id', 'text', 'author', 'creation_time',
  23 ]
  24 
  25 
  26 def get_bug_fields():
  27     os.makedirs('data', exist_ok=True)
  28 
  29     try:
  30         with open('data/bug_fields.json', 'r') as f:
  31             return json.load(f)
  32     except IOError:
  33         pass
  34 
  35     r = requests.get('https://bugzilla.mozilla.org/rest/field/bug')
  36     r.raise_for_status()
  37     return r.json()['fields']
  38 
  39 
  40 def get_bugs():
  41     return db.read(BUGS_DB)
  42 
  43 
  44 def set_token(token):
  45     bugzilla.Bugzilla.TOKEN = token
  46 
  47 
  48 def _download(ids_or_query):
  49     new_bugs = {}
  50 
  51     def bughandler(bug):
  52         bug_id = int(bug['id'])
  53 
  54         if bug_id not in new_bugs:
  55             new_bugs[bug_id] = dict()
  56 
  57         new_bugs[bug_id].update(bug)
  58 
  59     def commenthandler(bug, bug_id):
  60         bug_id = int(bug_id)
  61 
  62         if bug_id not in new_bugs:
  63             new_bugs[bug_id] = dict()
  64 
  65         new_bugs[bug_id]['comments'] = bug['comments']
  66 
  67     def attachmenthandler(bug, bug_id):
  68         bug_id = int(bug_id)
  69 
  70         if bug_id not in new_bugs:
  71             new_bugs[bug_id] = dict()
  72 
  73         new_bugs[bug_id]['attachments'] = bug
  74 
  75     def historyhandler(bug):
  76         bug_id = int(bug['id'])
  77 
  78         if bug_id not in new_bugs:
  79             new_bugs[bug_id] = dict()
  80 
  81         new_bugs[bug_id]['history'] = bug['history']
  82 
  83     bugzilla.Bugzilla(ids_or_query, bughandler=bughandler, commenthandler=commenthandler, comment_include_fields=COMMENT_INCLUDE_FIELDS, attachmenthandler=attachmenthandler, attachment_include_fields=ATTACHMENT_INCLUDE_FIELDS, historyhandler=historyhandler).get_data().wait()
  84 
  85     return new_bugs
  86 
  87 
  88 def download_bugs_between(date_from, date_to, security=False):
  89     products = set([
  90         'Add-on SDK',
  91         'Android Background Services',
  92         'Core',
  93         'DevTools',
  94         'External Software Affecting Firefox',
  95         'Firefox',
  96         'Firefox for Android',
  97         # 'Firefox for iOS',
  98         'Firefox Graveyard',
  99         'Firefox Health Report',
  100         # 'Focus',
  101         # 'Hello (Loop)',
  102         'NSPR',
  103         'NSS',
  104         'Toolkit',
  105         'WebExtensions',
  106     ])
  107 
  108     r = requests.get(f'https://bugzilla.mozilla.org/rest/bug?include_fields=id&f1=creation_ts&o1=greaterthan&v1={date_from.strftime("%Y-%m-%d")}&limit=1&order=bug_id')
  109     r.raise_for_status()
  110     first_id = r.json()['bugs'][0]['id']
  111 
  112     r = requests.get(f'https://bugzilla.mozilla.org/rest/bug?include_fields=id&f1=creation_ts&o1=lessthan&v1={date_to.strftime("%Y-%m-%d")}&limit=1&order=bug_id%20desc')
  113     r.raise_for_status()
  114     last_id = r.json()['bugs'][0]['id']
  115 
  116     assert first_id < last_id
  117 
  118     all_ids = range(first_id, last_id + 1)
  119 
  120     download_bugs(all_ids, security=security, products=products)
  121 
  122     return all_ids
  123 
  124 
  125 def download_bugs(bug_ids, products=None, security=False):
  126     old_bug_count = 0
  127     old_bugs = []
  128     new_bug_ids = set(int(bug_id) for bug_id in bug_ids)
  129     for bug in get_bugs():
  130         old_bug_count += 1
  131         if int(bug['id']) in new_bug_ids:
  132             old_bugs.append(bug)
  133             new_bug_ids.remove(bug['id'])
  134 
  135     print(f'Loaded {old_bug_count} bugs.')
  136 
  137     new_bug_ids = sorted(list(new_bug_ids))
  138 
  139     total_downloaded = 0
  140     chunks = (new_bug_ids[i:(i + 500)] for i in range(0, len(new_bug_ids), 500))
  141     for chunk in chunks:
  142         new_bugs = _download(chunk)
  143 
  144         total_downloaded += len(new_bugs)
  145 
  146         print(f'Downloaded {total_downloaded} out of {len(new_bug_ids)} bugs')
  147 
  148         if not security:
  149             new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if len(bug['groups']) == 0}
  150 
  151         if products is not None:
  152             new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if bug['product'] in products}
  153 
  154         db.append(BUGS_DB, new_bugs.values())
  155
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/bugbug/bugzilla.py b/bugbug/bugzilla.py
  --- a/bugbug/bugzilla.py
  +++ b/bugbug/bugzilla.py
  @@ -8,6 +8,7 @@
   
   import requests
   from libmozdata import bugzilla
  +from tqdm import tqdm
   
   from bugbug import db
   
  @@ -136,19 +137,17 @@
   
       new_bug_ids = sorted(list(new_bug_ids))
   
  -    total_downloaded = 0
       chunks = (new_bug_ids[i:(i + 500)] for i in range(0, len(new_bug_ids), 500))
  -    for chunk in chunks:
  -        new_bugs = _download(chunk)
  +    with tqdm(total=len(new_bug_ids)) as progress_bar:
  +        for chunk in chunks:
  +            new_bugs = _download(chunk)
   
  -        total_downloaded += len(new_bugs)
  +            progress_bar.update(len(chunk))
   
  -        print(f'Downloaded {total_downloaded} out of {len(new_bug_ids)} bugs')
  +            if not security:
  +                new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if len(bug['groups']) == 0}
   
  -        if not security:
  -            new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if len(bug['groups']) == 0}
  +            if products is not None:
  +                new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if bug['product'] in products}
   
  -        if products is not None:
  -            new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if bug['product'] in products}
  -
  -        db.append(BUGS_DB, new_bugs.values())
  +            db.append(BUGS_DB, new_bugs.values())
  
verification_info: {"golden_diff": "diff --git a/bugbug/bugzilla.py b/bugbug/bugzilla.py\n--- a/bugbug/bugzilla.py\n+++ b/bugbug/bugzilla.py\n@@ -8,6 +8,7 @@\n \n import requests\n from libmozdata import bugzilla\n+from tqdm import tqdm\n \n from bugbug import db\n \n@@ -136,19 +137,17 @@\n \n     new_bug_ids = sorted(list(new_bug_ids))\n \n-    total_downloaded = 0\n     chunks = (new_bug_ids[i:(i + 500)] for i in range(0, len(new_bug_ids), 500))\n-    for chunk in chunks:\n-        new_bugs = _download(chunk)\n+    with tqdm(total=len(new_bug_ids)) as progress_bar:\n+        for chunk in chunks:\n+            new_bugs = _download(chunk)\n \n-        total_downloaded += len(new_bugs)\n+            progress_bar.update(len(chunk))\n \n-        print(f'Downloaded {total_downloaded} out of {len(new_bug_ids)} bugs')\n+            if not security:\n+                new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if len(bug['groups']) == 0}\n \n-        if not security:\n-            new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if len(bug['groups']) == 0}\n+            if products is not None:\n+                new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if bug['product'] in products}\n \n-        if products is not None:\n-            new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if bug['product'] in products}\n-\n-        db.append(BUGS_DB, new_bugs.values())\n+            db.append(BUGS_DB, new_bugs.values())\n", "issue": "Print progress bar while downloading bugs\nSimilar to what we're doing for commits data: 28b83c12c29185c52afb58d94a533a9448969a8a.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this file,\n# You can obtain one at http://mozilla.org/MPL/2.0/.\n\nimport json\nimport os\n\nimport requests\nfrom libmozdata import bugzilla\n\nfrom bugbug import db\n\nBUGS_DB = 'data/bugs.json'\ndb.register(BUGS_DB, 'https://www.dropbox.com/s/xm6wzac9jl81irz/bugs.json.xz?dl=1')\n\nATTACHMENT_INCLUDE_FIELDS = [\n    'id', 'is_obsolete', 'flags', 'is_patch', 'creator', 'content_type', 'creation_time',\n]\n\nCOMMENT_INCLUDE_FIELDS = [\n    'id', 'text', 'author', 'creation_time',\n]\n\n\ndef get_bug_fields():\n    os.makedirs('data', exist_ok=True)\n\n    try:\n        with open('data/bug_fields.json', 'r') as f:\n            return json.load(f)\n    except IOError:\n        pass\n\n    r = requests.get('https://bugzilla.mozilla.org/rest/field/bug')\n    r.raise_for_status()\n    return r.json()['fields']\n\n\ndef get_bugs():\n    return db.read(BUGS_DB)\n\n\ndef set_token(token):\n    bugzilla.Bugzilla.TOKEN = token\n\n\ndef _download(ids_or_query):\n    new_bugs = {}\n\n    def bughandler(bug):\n        bug_id = int(bug['id'])\n\n        if bug_id not in new_bugs:\n            new_bugs[bug_id] = dict()\n\n        new_bugs[bug_id].update(bug)\n\n    def commenthandler(bug, bug_id):\n        bug_id = int(bug_id)\n\n        if bug_id not in new_bugs:\n            new_bugs[bug_id] = dict()\n\n        new_bugs[bug_id]['comments'] = bug['comments']\n\n    def attachmenthandler(bug, bug_id):\n        bug_id = int(bug_id)\n\n        if bug_id not in new_bugs:\n            new_bugs[bug_id] = dict()\n\n        new_bugs[bug_id]['attachments'] = bug\n\n    def historyhandler(bug):\n        bug_id = int(bug['id'])\n\n        if bug_id not in new_bugs:\n            new_bugs[bug_id] = dict()\n\n        new_bugs[bug_id]['history'] = bug['history']\n\n    bugzilla.Bugzilla(ids_or_query, bughandler=bughandler, commenthandler=commenthandler, comment_include_fields=COMMENT_INCLUDE_FIELDS, attachmenthandler=attachmenthandler, attachment_include_fields=ATTACHMENT_INCLUDE_FIELDS, historyhandler=historyhandler).get_data().wait()\n\n    return new_bugs\n\n\ndef download_bugs_between(date_from, date_to, security=False):\n    products = set([\n        'Add-on SDK',\n        'Android Background Services',\n        'Core',\n        'DevTools',\n        'External Software Affecting Firefox',\n        'Firefox',\n        'Firefox for Android',\n        # 'Firefox for iOS',\n        'Firefox Graveyard',\n        'Firefox Health Report',\n        # 'Focus',\n        # 'Hello (Loop)',\n        'NSPR',\n        'NSS',\n        'Toolkit',\n        'WebExtensions',\n    ])\n\n    r = requests.get(f'https://bugzilla.mozilla.org/rest/bug?include_fields=id&f1=creation_ts&o1=greaterthan&v1={date_from.strftime(\"%Y-%m-%d\")}&limit=1&order=bug_id')\n    r.raise_for_status()\n    first_id = r.json()['bugs'][0]['id']\n\n    r = requests.get(f'https://bugzilla.mozilla.org/rest/bug?include_fields=id&f1=creation_ts&o1=lessthan&v1={date_to.strftime(\"%Y-%m-%d\")}&limit=1&order=bug_id%20desc')\n    r.raise_for_status()\n    last_id = r.json()['bugs'][0]['id']\n\n    assert first_id < last_id\n\n    all_ids = range(first_id, last_id + 1)\n\n    download_bugs(all_ids, security=security, products=products)\n\n    return all_ids\n\n\ndef download_bugs(bug_ids, products=None, security=False):\n    old_bug_count = 0\n    old_bugs = []\n    new_bug_ids = set(int(bug_id) for bug_id in bug_ids)\n    for bug in get_bugs():\n        old_bug_count += 1\n        if int(bug['id']) in new_bug_ids:\n            old_bugs.append(bug)\n            new_bug_ids.remove(bug['id'])\n\n    print(f'Loaded {old_bug_count} bugs.')\n\n    new_bug_ids = sorted(list(new_bug_ids))\n\n    total_downloaded = 0\n    chunks = (new_bug_ids[i:(i + 500)] for i in range(0, len(new_bug_ids), 500))\n    for chunk in chunks:\n        new_bugs = _download(chunk)\n\n        total_downloaded += len(new_bugs)\n\n        print(f'Downloaded {total_downloaded} out of {len(new_bug_ids)} bugs')\n\n        if not security:\n            new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if len(bug['groups']) == 0}\n\n        if products is not None:\n            new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if bug['product'] in products}\n\n        db.append(BUGS_DB, new_bugs.values())\n", "path": "bugbug/bugzilla.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this file,\n# You can obtain one at http://mozilla.org/MPL/2.0/.\n\nimport json\nimport os\n\nimport requests\nfrom libmozdata import bugzilla\nfrom tqdm import tqdm\n\nfrom bugbug import db\n\nBUGS_DB = 'data/bugs.json'\ndb.register(BUGS_DB, 'https://www.dropbox.com/s/xm6wzac9jl81irz/bugs.json.xz?dl=1')\n\nATTACHMENT_INCLUDE_FIELDS = [\n    'id', 'is_obsolete', 'flags', 'is_patch', 'creator', 'content_type', 'creation_time',\n]\n\nCOMMENT_INCLUDE_FIELDS = [\n    'id', 'text', 'author', 'creation_time',\n]\n\n\ndef get_bug_fields():\n    os.makedirs('data', exist_ok=True)\n\n    try:\n        with open('data/bug_fields.json', 'r') as f:\n            return json.load(f)\n    except IOError:\n        pass\n\n    r = requests.get('https://bugzilla.mozilla.org/rest/field/bug')\n    r.raise_for_status()\n    return r.json()['fields']\n\n\ndef get_bugs():\n    return db.read(BUGS_DB)\n\n\ndef set_token(token):\n    bugzilla.Bugzilla.TOKEN = token\n\n\ndef _download(ids_or_query):\n    new_bugs = {}\n\n    def bughandler(bug):\n        bug_id = int(bug['id'])\n\n        if bug_id not in new_bugs:\n            new_bugs[bug_id] = dict()\n\n        new_bugs[bug_id].update(bug)\n\n    def commenthandler(bug, bug_id):\n        bug_id = int(bug_id)\n\n        if bug_id not in new_bugs:\n            new_bugs[bug_id] = dict()\n\n        new_bugs[bug_id]['comments'] = bug['comments']\n\n    def attachmenthandler(bug, bug_id):\n        bug_id = int(bug_id)\n\n        if bug_id not in new_bugs:\n            new_bugs[bug_id] = dict()\n\n        new_bugs[bug_id]['attachments'] = bug\n\n    def historyhandler(bug):\n        bug_id = int(bug['id'])\n\n        if bug_id not in new_bugs:\n            new_bugs[bug_id] = dict()\n\n        new_bugs[bug_id]['history'] = bug['history']\n\n    bugzilla.Bugzilla(ids_or_query, bughandler=bughandler, commenthandler=commenthandler, comment_include_fields=COMMENT_INCLUDE_FIELDS, attachmenthandler=attachmenthandler, attachment_include_fields=ATTACHMENT_INCLUDE_FIELDS, historyhandler=historyhandler).get_data().wait()\n\n    return new_bugs\n\n\ndef download_bugs_between(date_from, date_to, security=False):\n    products = set([\n        'Add-on SDK',\n        'Android Background Services',\n        'Core',\n        'DevTools',\n        'External Software Affecting Firefox',\n        'Firefox',\n        'Firefox for Android',\n        # 'Firefox for iOS',\n        'Firefox Graveyard',\n        'Firefox Health Report',\n        # 'Focus',\n        # 'Hello (Loop)',\n        'NSPR',\n        'NSS',\n        'Toolkit',\n        'WebExtensions',\n    ])\n\n    r = requests.get(f'https://bugzilla.mozilla.org/rest/bug?include_fields=id&f1=creation_ts&o1=greaterthan&v1={date_from.strftime(\"%Y-%m-%d\")}&limit=1&order=bug_id')\n    r.raise_for_status()\n    first_id = r.json()['bugs'][0]['id']\n\n    r = requests.get(f'https://bugzilla.mozilla.org/rest/bug?include_fields=id&f1=creation_ts&o1=lessthan&v1={date_to.strftime(\"%Y-%m-%d\")}&limit=1&order=bug_id%20desc')\n    r.raise_for_status()\n    last_id = r.json()['bugs'][0]['id']\n\n    assert first_id < last_id\n\n    all_ids = range(first_id, last_id + 1)\n\n    download_bugs(all_ids, security=security, products=products)\n\n    return all_ids\n\n\ndef download_bugs(bug_ids, products=None, security=False):\n    old_bug_count = 0\n    old_bugs = []\n    new_bug_ids = set(int(bug_id) for bug_id in bug_ids)\n    for bug in get_bugs():\n        old_bug_count += 1\n        if int(bug['id']) in new_bug_ids:\n            old_bugs.append(bug)\n            new_bug_ids.remove(bug['id'])\n\n    print(f'Loaded {old_bug_count} bugs.')\n\n    new_bug_ids = sorted(list(new_bug_ids))\n\n    chunks = (new_bug_ids[i:(i + 500)] for i in range(0, len(new_bug_ids), 500))\n    with tqdm(total=len(new_bug_ids)) as progress_bar:\n        for chunk in chunks:\n            new_bugs = _download(chunk)\n\n            progress_bar.update(len(chunk))\n\n            if not security:\n                new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if len(bug['groups']) == 0}\n\n            if products is not None:\n                new_bugs = {bug_id: bug for bug_id, bug in new_bugs.items() if bug['product'] in products}\n\n            db.append(BUGS_DB, new_bugs.values())\n", "path": "bugbug/bugzilla.py"}]}