We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
update_tmserver: Refactor options
Right now `update_tmserver` accepts several options (`--rebuild`, `--overwrite`) but it is not clear what they are for. After a discussion with @dwaynebailey we outlined three scenarios:

1) Add translations added since last indexed revision. This creates the index if missing, and adds translations from start if there is no last indexed revision. This is just calling `update_tmserver`.
2) Destroy index if it exists, create the index, and add all translations. This is calling `update_tmserver --rebuild`.
3) Add all translations from start, regardless of if there is last indexed revision, so this updates previously indexed translations in case they were changed afterwards and keeps previously indexed translations that are now gone (e.g. translations from removed projects). This creates the index if missing (this is scenario 1) with no previous index). What makes this scenario different from scenario 2) is that the index is not destroyed. This is calling `update_tmserver --refresh`.

Note that `--dry-run` can also be used for any of those three scenarios. In this case no changes to the index are done (no destroy, no create, no update).


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pootle/apps/pootle_app/management/commands/update_tmserver.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright (C) Pootle contributors.
5 #
6 # This file is a part of the Pootle project. It is distributed under the GPL3
7 # or later license. See the LICENSE file for a copy of the license and the
8 # AUTHORS file for copyright and authorship information.
9 
10 from hashlib import md5
11 from optparse import make_option
12 import os
13 import sys
14 
15 # This must be run before importing Django.
16 os.environ['DJANGO_SETTINGS_MODULE'] = 'pootle.settings'
17 
18 from elasticsearch import helpers, Elasticsearch
19 
20 from django.conf import settings
21 from django.core.management.base import BaseCommand, CommandError
22 
23 from pootle_store.models import Unit
24 
25 
26 BULK_CHUNK_SIZE = 5000
27 
28 
29 class Command(BaseCommand):
30     help = "Load Local Translation Memory"
31     option_list = BaseCommand.option_list + (
32         make_option('--overwrite',
33                     action="store_true",
34                     dest='overwrite',
35                     default=False,
36                     help='Process all items, not just the new ones (useful to '
37                          'overwrite properties while keeping the index in a '
38                          'working condition)'),
39         make_option('--rebuild',
40                     action="store_true",
41                     dest='rebuild',
42                     default=False,
43                     help='Drop the entire index on start and update '
44                          'everything from scratch'),
45         make_option('--dry-run',
46                     action="store_true",
47                     dest='dry_run',
48                     default=False,
49                     help='Report only the number of translations to index '
50                          'and quit'),
51     )
52 
53     def _parse_translations(self, **options):
54 
55         units_qs = Unit.simple_objects \
56             .exclude(target_f__isnull=True) \
57             .exclude(target_f__exact='') \
58             .filter(revision__gt=self.last_indexed_revision) \
59             .select_related(
60                 'submitted_by',
61                 'store',
62                 'store__translation_project__project',
63                 'store__translation_project__language'
64             ).values(
65                 'id',
66                 'revision',
67                 'source_f',
68                 'target_f',
69                 'submitted_by__username',
70                 'submitted_by__full_name',
71                 'submitted_by__email',
72                 'store__translation_project__project__fullname',
73                 'store__pootle_path',
74                 'store__translation_project__language__code'
75             ).order_by()
76 
77         total = units_qs.count()
78 
79         if total == 0:
80             self.stdout.write("No translations to index")
81             sys.exit()
82 
83         self.stdout.write("%s translations to index" % total)
84 
85         if options['dry_run']:
86             sys.exit()
87 
88         self.stdout.write("")
89 
90         for i, unit in enumerate(units_qs.iterator(), start=1):
91             fullname = (unit['submitted_by__full_name'] or
92                         unit['submitted_by__username'])
93             project = unit['store__translation_project__project__fullname']
94 
95             email_md5 = None
96             if unit['submitted_by__email']:
97                 email_md5 = md5(unit['submitted_by__email']).hexdigest()
98 
99             if (i % 1000 == 0) or (i == total):
100                 percent = "%.1f" % (i * 100.0 / total)
101                 self.stdout.write("%s (%s%%)" % (i, percent), ending='\r')
102                 self.stdout.flush()
103 
104             yield {
105                 "_index": self.INDEX_NAME,
106                 "_type": unit['store__translation_project__language__code'],
107                 "_id": unit['id'],
108                 'revision': int(unit['revision']),
109                 'project': project,
110                 'path': unit['store__pootle_path'],
111                 'username': unit['submitted_by__username'],
112                 'fullname': fullname,
113                 'email_md5': email_md5,
114                 'source': unit['source_f'],
115                 'target': unit['target_f'],
116             }
117 
118         if i != total:
119             self.stdout.write("Expected %d, loaded %d." % (total, i))
120 
121 
122     def handle(self, *args, **options):
123         if not getattr(settings, 'POOTLE_TM_SERVER', False):
124             raise CommandError("POOTLE_TM_SERVER is missing from your settings.")
125 
126         self.INDEX_NAME = settings.POOTLE_TM_SERVER['default']['INDEX_NAME']
127         es = Elasticsearch([{
128                 'host': settings.POOTLE_TM_SERVER['default']['HOST'],
129                 'port': settings.POOTLE_TM_SERVER['default']['PORT']
130             }],
131             retry_on_timeout=True
132         )
133 
134         self.last_indexed_revision = -1
135 
136         if options['rebuild'] and not options['dry_run']:
137             if es.indices.exists(self.INDEX_NAME):
138                 es.indices.delete(index=self.INDEX_NAME)
139 
140         if not options['dry_run'] and not es.indices.exists(self.INDEX_NAME):
141             es.indices.create(index=self.INDEX_NAME)
142 
143         if (not options['rebuild'] and
144             not options['overwrite'] and
145             es.indices.exists(self.INDEX_NAME)):
146             result = es.search(
147                 index=self.INDEX_NAME,
148                 body={
149                     'query': {
150                         'match_all': {}
151                     },
152                     'facets': {
153                         'stat1': {
154                             'statistical': {
155                                 'field': 'revision'
156                             }
157                         }
158                     }
159                 }
160             )
161             self.last_indexed_revision = result['facets']['stat1']['max']
162 
163         self.stdout.write("Last indexed revision = %s" % self.last_indexed_revision)
164 
165         success, _ = helpers.bulk(es, self._parse_translations(**options))
166
```
--- 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()

```

diff --git a/pootle/apps/pootle_app/management/commands/update_tmserver.py b/pootle/apps/pootle_app/management/commands/update_tmserver.py
--- a/pootle/apps/pootle_app/management/commands/update_tmserver.py
+++ b/pootle/apps/pootle_app/management/commands/update_tmserver.py
@@ -29,13 +29,12 @@
 class Command(BaseCommand):
     help = "Load Local Translation Memory"
     option_list = BaseCommand.option_list + (
-        make_option('--overwrite',
+        make_option('--refresh',
                     action="store_true",
-                    dest='overwrite',
+                    dest='refresh',
                     default=False,
-                    help='Process all items, not just the new ones (useful to '
-                         'overwrite properties while keeping the index in a '
-                         'working condition)'),
+                    help='Process all items, not just the new ones, so '
+                         'existing translations are refreshed'),
         make_option('--rebuild',
                     action="store_true",
                     dest='rebuild',
@@ -141,7 +140,7 @@
             es.indices.create(index=self.INDEX_NAME)
 
         if (not options['rebuild'] and
-            not options['overwrite'] and
+            not options['refresh'] and
             es.indices.exists(self.INDEX_NAME)):
             result = es.search(
                 index=self.INDEX_NAME,

{"golden_diff": "diff --git a/pootle/apps/pootle_app/management/commands/update_tmserver.py b/pootle/apps/pootle_app/management/commands/update_tmserver.py\n--- a/pootle/apps/pootle_app/management/commands/update_tmserver.py\n+++ b/pootle/apps/pootle_app/management/commands/update_tmserver.py\n@@ -29,13 +29,12 @@\n class Command(BaseCommand):\n     help = \"Load Local Translation Memory\"\n     option_list = BaseCommand.option_list + (\n-        make_option('--overwrite',\n+        make_option('--refresh',\n                     action=\"store_true\",\n-                    dest='overwrite',\n+                    dest='refresh',\n                     default=False,\n-                    help='Process all items, not just the new ones (useful to '\n-                         'overwrite properties while keeping the index in a '\n-                         'working condition)'),\n+                    help='Process all items, not just the new ones, so '\n+                         'existing translations are refreshed'),\n         make_option('--rebuild',\n                     action=\"store_true\",\n                     dest='rebuild',\n@@ -141,7 +140,7 @@\n             es.indices.create(index=self.INDEX_NAME)\n \n         if (not options['rebuild'] and\n-            not options['overwrite'] and\n+            not options['refresh'] and\n             es.indices.exists(self.INDEX_NAME)):\n             result = es.search(\n                 index=self.INDEX_NAME,\n", "issue": "update_tmserver: Refactor options\nRight now `update_tmserver` accepts several options (`--rebuild`, `--overwrite`) but it is not clear what they are for. After a discussion with @dwaynebailey we outlined three scenarios:\n\n1) Add translations added since last indexed revision. This creates the index if missing, and adds translations from start if there is no last indexed revision. This is just calling `update_tmserver`.\n2) Destroy index if it exists, create the index, and add all translations. This is calling `update_tmserver --rebuild`.\n3) Add all translations from start, regardless of if there is last indexed revision, so this updates previously indexed translations in case they were changed afterwards and keeps previously indexed translations that are now gone (e.g. translations from removed projects). This creates the index if missing (this is scenario 1) with no previous index). What makes this scenario different from scenario 2) is that the index is not destroyed. This is calling `update_tmserver --refresh`.\n\nNote that `--dry-run` can also be used for any of those three scenarios. In this case no changes to the index are done (no destroy, no create, no update).\n\n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nfrom hashlib import md5\nfrom optparse import make_option\nimport os\nimport sys\n\n# This must be run before importing Django.\nos.environ['DJANGO_SETTINGS_MODULE'] = 'pootle.settings'\n\nfrom elasticsearch import helpers, Elasticsearch\n\nfrom django.conf import settings\nfrom django.core.management.base import BaseCommand, CommandError\n\nfrom pootle_store.models import Unit\n\n\nBULK_CHUNK_SIZE = 5000\n\n\nclass Command(BaseCommand):\n    help = \"Load Local Translation Memory\"\n    option_list = BaseCommand.option_list + (\n        make_option('--overwrite',\n                    action=\"store_true\",\n                    dest='overwrite',\n                    default=False,\n                    help='Process all items, not just the new ones (useful to '\n                         'overwrite properties while keeping the index in a '\n                         'working condition)'),\n        make_option('--rebuild',\n                    action=\"store_true\",\n                    dest='rebuild',\n                    default=False,\n                    help='Drop the entire index on start and update '\n                         'everything from scratch'),\n        make_option('--dry-run',\n                    action=\"store_true\",\n                    dest='dry_run',\n                    default=False,\n                    help='Report only the number of translations to index '\n                         'and quit'),\n    )\n\n    def _parse_translations(self, **options):\n\n        units_qs = Unit.simple_objects \\\n            .exclude(target_f__isnull=True) \\\n            .exclude(target_f__exact='') \\\n            .filter(revision__gt=self.last_indexed_revision) \\\n            .select_related(\n                'submitted_by',\n                'store',\n                'store__translation_project__project',\n                'store__translation_project__language'\n            ).values(\n                'id',\n                'revision',\n                'source_f',\n                'target_f',\n                'submitted_by__username',\n                'submitted_by__full_name',\n                'submitted_by__email',\n                'store__translation_project__project__fullname',\n                'store__pootle_path',\n                'store__translation_project__language__code'\n            ).order_by()\n\n        total = units_qs.count()\n\n        if total == 0:\n            self.stdout.write(\"No translations to index\")\n            sys.exit()\n\n        self.stdout.write(\"%s translations to index\" % total)\n\n        if options['dry_run']:\n            sys.exit()\n\n        self.stdout.write(\"\")\n\n        for i, unit in enumerate(units_qs.iterator(), start=1):\n            fullname = (unit['submitted_by__full_name'] or\n                        unit['submitted_by__username'])\n            project = unit['store__translation_project__project__fullname']\n\n            email_md5 = None\n            if unit['submitted_by__email']:\n                email_md5 = md5(unit['submitted_by__email']).hexdigest()\n\n            if (i % 1000 == 0) or (i == total):\n                percent = \"%.1f\" % (i * 100.0 / total)\n                self.stdout.write(\"%s (%s%%)\" % (i, percent), ending='\\r')\n                self.stdout.flush()\n\n            yield {\n                \"_index\": self.INDEX_NAME,\n                \"_type\": unit['store__translation_project__language__code'],\n                \"_id\": unit['id'],\n                'revision': int(unit['revision']),\n                'project': project,\n                'path': unit['store__pootle_path'],\n                'username': unit['submitted_by__username'],\n                'fullname': fullname,\n                'email_md5': email_md5,\n                'source': unit['source_f'],\n                'target': unit['target_f'],\n            }\n\n        if i != total:\n            self.stdout.write(\"Expected %d, loaded %d.\" % (total, i))\n\n\n    def handle(self, *args, **options):\n        if not getattr(settings, 'POOTLE_TM_SERVER', False):\n            raise CommandError(\"POOTLE_TM_SERVER is missing from your settings.\")\n\n        self.INDEX_NAME = settings.POOTLE_TM_SERVER['default']['INDEX_NAME']\n        es = Elasticsearch([{\n                'host': settings.POOTLE_TM_SERVER['default']['HOST'],\n                'port': settings.POOTLE_TM_SERVER['default']['PORT']\n            }],\n            retry_on_timeout=True\n        )\n\n        self.last_indexed_revision = -1\n\n        if options['rebuild'] and not options['dry_run']:\n            if es.indices.exists(self.INDEX_NAME):\n                es.indices.delete(index=self.INDEX_NAME)\n\n        if not options['dry_run'] and not es.indices.exists(self.INDEX_NAME):\n            es.indices.create(index=self.INDEX_NAME)\n\n        if (not options['rebuild'] and\n            not options['overwrite'] and\n            es.indices.exists(self.INDEX_NAME)):\n            result = es.search(\n                index=self.INDEX_NAME,\n                body={\n                    'query': {\n                        'match_all': {}\n                    },\n                    'facets': {\n                        'stat1': {\n                            'statistical': {\n                                'field': 'revision'\n                            }\n                        }\n                    }\n                }\n            )\n            self.last_indexed_revision = result['facets']['stat1']['max']\n\n        self.stdout.write(\"Last indexed revision = %s\" % self.last_indexed_revision)\n\n        success, _ = helpers.bulk(es, self._parse_translations(**options))\n", "path": "pootle/apps/pootle_app/management/commands/update_tmserver.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nfrom hashlib import md5\nfrom optparse import make_option\nimport os\nimport sys\n\n# This must be run before importing Django.\nos.environ['DJANGO_SETTINGS_MODULE'] = 'pootle.settings'\n\nfrom elasticsearch import helpers, Elasticsearch\n\nfrom django.conf import settings\nfrom django.core.management.base import BaseCommand, CommandError\n\nfrom pootle_store.models import Unit\n\n\nBULK_CHUNK_SIZE = 5000\n\n\nclass Command(BaseCommand):\n    help = \"Load Local Translation Memory\"\n    option_list = BaseCommand.option_list + (\n        make_option('--refresh',\n                    action=\"store_true\",\n                    dest='refresh',\n                    default=False,\n                    help='Process all items, not just the new ones, so '\n                         'existing translations are refreshed'),\n        make_option('--rebuild',\n                    action=\"store_true\",\n                    dest='rebuild',\n                    default=False,\n                    help='Drop the entire index on start and update '\n                         'everything from scratch'),\n        make_option('--dry-run',\n                    action=\"store_true\",\n                    dest='dry_run',\n                    default=False,\n                    help='Report only the number of translations to index '\n                         'and quit'),\n    )\n\n    def _parse_translations(self, **options):\n\n        units_qs = Unit.simple_objects \\\n            .exclude(target_f__isnull=True) \\\n            .exclude(target_f__exact='') \\\n            .filter(revision__gt=self.last_indexed_revision) \\\n            .select_related(\n                'submitted_by',\n                'store',\n                'store__translation_project__project',\n                'store__translation_project__language'\n            ).values(\n                'id',\n                'revision',\n                'source_f',\n                'target_f',\n                'submitted_by__username',\n                'submitted_by__full_name',\n                'submitted_by__email',\n                'store__translation_project__project__fullname',\n                'store__pootle_path',\n                'store__translation_project__language__code'\n            ).order_by()\n\n        total = units_qs.count()\n\n        if total == 0:\n            self.stdout.write(\"No translations to index\")\n            sys.exit()\n\n        self.stdout.write(\"%s translations to index\" % total)\n\n        if options['dry_run']:\n            sys.exit()\n\n        self.stdout.write(\"\")\n\n        for i, unit in enumerate(units_qs.iterator(), start=1):\n            fullname = (unit['submitted_by__full_name'] or\n                        unit['submitted_by__username'])\n            project = unit['store__translation_project__project__fullname']\n\n            email_md5 = None\n            if unit['submitted_by__email']:\n                email_md5 = md5(unit['submitted_by__email']).hexdigest()\n\n            if (i % 1000 == 0) or (i == total):\n                percent = \"%.1f\" % (i * 100.0 / total)\n                self.stdout.write(\"%s (%s%%)\" % (i, percent), ending='\\r')\n                self.stdout.flush()\n\n            yield {\n                \"_index\": self.INDEX_NAME,\n                \"_type\": unit['store__translation_project__language__code'],\n                \"_id\": unit['id'],\n                'revision': int(unit['revision']),\n                'project': project,\n                'path': unit['store__pootle_path'],\n                'username': unit['submitted_by__username'],\n                'fullname': fullname,\n                'email_md5': email_md5,\n                'source': unit['source_f'],\n                'target': unit['target_f'],\n            }\n\n        if i != total:\n            self.stdout.write(\"Expected %d, loaded %d.\" % (total, i))\n\n\n    def handle(self, *args, **options):\n        if not getattr(settings, 'POOTLE_TM_SERVER', False):\n            raise CommandError(\"POOTLE_TM_SERVER is missing from your settings.\")\n\n        self.INDEX_NAME = settings.POOTLE_TM_SERVER['default']['INDEX_NAME']\n        es = Elasticsearch([{\n                'host': settings.POOTLE_TM_SERVER['default']['HOST'],\n                'port': settings.POOTLE_TM_SERVER['default']['PORT']\n            }],\n            retry_on_timeout=True\n        )\n\n        self.last_indexed_revision = -1\n\n        if options['rebuild'] and not options['dry_run']:\n            if es.indices.exists(self.INDEX_NAME):\n                es.indices.delete(index=self.INDEX_NAME)\n\n        if not options['dry_run'] and not es.indices.exists(self.INDEX_NAME):\n            es.indices.create(index=self.INDEX_NAME)\n\n        if (not options['rebuild'] and\n            not options['refresh'] and\n            es.indices.exists(self.INDEX_NAME)):\n            result = es.search(\n                index=self.INDEX_NAME,\n                body={\n                    'query': {\n                        'match_all': {}\n                    },\n                    'facets': {\n                        'stat1': {\n                            'statistical': {\n                                'field': 'revision'\n                            }\n                        }\n                    }\n                }\n            )\n            self.last_indexed_revision = result['facets']['stat1']['max']\n\n        self.stdout.write(\"Last indexed revision = %s\" % self.last_indexed_revision)\n\n        success, _ = helpers.bulk(es, self._parse_translations(**options))\n", "path": "pootle/apps/pootle_app/management/commands/update_tmserver.py"}]}