We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Running update_tmserver with --dry-run but no existing LocalTM will fail
If we try to build the LocalTM but don't specify `--rebuild` our initial import will fail because the revision counter does not exist.

``` pytb
$ pootle update_tmserver -v 3 --dry-run 
2015-09-30 10:55:33,485 INFO Loading custom settings from '/root/.pootle/pootle.conf'...
2015-09-30 13:55:33,704 INFO Using Python PO
System check identified some issues:

WARNINGS:
?: (pootle.W017) There are user accounts with duplicate emails. This will not be allowed in Pootle 2.8.
        HINT: Try using 'pootle find_duplicate_emails', and then update user emails with 'pootle update_user_email username email'. You might also want to consider using pootle merge_user or purge_user commands
Traceback (most recent call last):
  File "/var/www/pootle/env/bin/pootle", line 11, in <module>
    sys.exit(main())
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/pootle/runner.py", line 309, in main
    django_settings_module='pootle.settings')
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/pootle/runner.py", line 289, in run_app
    management.execute_from_command_line(command)
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/pootle/apps/pootle_app/management/commands/update_tmserver.py", line 152, in handle
    'field': 'revision'
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/client/utils.py", line 69, in _wrapped
    return func(*args, params=params, **kwargs)
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/client/__init__.py", line 506, in search
    params=params, body=body)
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/transport.py", line 307, in perform_request
    status, headers, data = connection.perform_request(method, url, params, body, ignore=ignore, timeout=timeout)
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/connection/http_urllib3.py", line 89, in perform_request
    self._raise_error(response.status, raw_data)
  File "/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/connection/base.py", line 105, in _raise_error
    raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)
elasticsearch.exceptions.RequestError: TransportError(400, u'SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][0]: SearchParseException[[translations][0]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"match_all": {}}, "facets": {"stat1": {"statistical": {"field": "revision"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }{[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][1]: SearchParseException[[translations][1]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"match_all": {}}, "facets": {"stat1": {"statistical": {"field": "revision"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }{[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][2]: SearchParseException[[translations][2]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"match_all": {}}, "facets": {"stat1": {"statistical": {"field": "revision"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }{[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][3]: SearchParseException[[translations][3]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"match_all": {}}, "facets": {"stat1": {"statistical": {"field": "revision"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }{[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][4]: SearchParseException[[translations][4]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"match_all": {}}, "facets": {"stat1": {"statistical": {"field": "revision"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }]')
```


--- 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['rebuild'] and
141             not options['overwrite'] and
142             es.indices.exists(self.INDEX_NAME)):
143             result = es.search(
144                 index=self.INDEX_NAME,
145                 body={
146                     'query': {
147                         'match_all': {}
148                     },
149                     'facets': {
150                         'stat1': {
151                             'statistical': {
152                                 'field': 'revision'
153                             }
154                         }
155                     }
156                 }
157             )
158             self.last_indexed_revision = result['facets']['stat1']['max']
159 
160         self.stdout.write("Last indexed revision = %s" % self.last_indexed_revision)
161 
162         success, _ = helpers.bulk(es, self._parse_translations(**options))
163
```
--- 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
@@ -137,6 +137,9 @@
             if es.indices.exists(self.INDEX_NAME):
                 es.indices.delete(index=self.INDEX_NAME)
 
+        if not options['dry_run'] and not es.indices.exists(self.INDEX_NAME):
+            es.indices.create(index=self.INDEX_NAME)
+
         if (not options['rebuild'] and
             not options['overwrite'] and
             es.indices.exists(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@@ -137,6 +137,9 @@\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", "issue": "Running update_tmserver with --dry-run but no existing LocalTM will fail\nIf we try to build the LocalTM but don't specify `--rebuild` our initial import will fail because the revision counter does not exist.\n\n``` pytb\n$ pootle update_tmserver -v 3 --dry-run \n2015-09-30 10:55:33,485 INFO Loading custom settings from '/root/.pootle/pootle.conf'...\n2015-09-30 13:55:33,704 INFO Using Python PO\nSystem check identified some issues:\n\nWARNINGS:\n?: (pootle.W017) There are user accounts with duplicate emails. This will not be allowed in Pootle 2.8.\n        HINT: Try using 'pootle find_duplicate_emails', and then update user emails with 'pootle update_user_email username email'. You might also want to consider using pootle merge_user or purge_user commands\nTraceback (most recent call last):\n  File \"/var/www/pootle/env/bin/pootle\", line 11, in <module>\n    sys.exit(main())\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/pootle/runner.py\", line 309, in main\n    django_settings_module='pootle.settings')\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/pootle/runner.py\", line 289, in run_app\n    management.execute_from_command_line(command)\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/django/core/management/__init__.py\", line 385, in execute_from_command_line\n    utility.execute()\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/django/core/management/__init__.py\", line 377, in execute\n    self.fetch_command(subcommand).run_from_argv(self.argv)\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/django/core/management/base.py\", line 288, in run_from_argv\n    self.execute(*args, **options.__dict__)\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/django/core/management/base.py\", line 338, in execute\n    output = self.handle(*args, **options)\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/pootle/apps/pootle_app/management/commands/update_tmserver.py\", line 152, in handle\n    'field': 'revision'\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/client/utils.py\", line 69, in _wrapped\n    return func(*args, params=params, **kwargs)\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/client/__init__.py\", line 506, in search\n    params=params, body=body)\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/transport.py\", line 307, in perform_request\n    status, headers, data = connection.perform_request(method, url, params, body, ignore=ignore, timeout=timeout)\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/connection/http_urllib3.py\", line 89, in perform_request\n    self._raise_error(response.status, raw_data)\n  File \"/var/www/pootle/env/local/lib/python2.7/site-packages/elasticsearch/connection/base.py\", line 105, in _raise_error\n    raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)\nelasticsearch.exceptions.RequestError: TransportError(400, u'SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][0]: SearchParseException[[translations][0]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": {\"match_all\": {}}, \"facets\": {\"stat1\": {\"statistical\": {\"field\": \"revision\"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }{[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][1]: SearchParseException[[translations][1]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": {\"match_all\": {}}, \"facets\": {\"stat1\": {\"statistical\": {\"field\": \"revision\"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }{[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][2]: SearchParseException[[translations][2]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": {\"match_all\": {}}, \"facets\": {\"stat1\": {\"statistical\": {\"field\": \"revision\"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }{[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][3]: SearchParseException[[translations][3]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": {\"match_all\": {}}, \"facets\": {\"stat1\": {\"statistical\": {\"field\": \"revision\"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }{[aQHk0CPtT1K_ZZ2YJG8rjQ][translations][4]: SearchParseException[[translations][4]: query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\": {\"match_all\": {}}, \"facets\": {\"stat1\": {\"statistical\": {\"field\": \"revision\"}}}}]]]; nested: FacetPhaseExecutionException[Facet [stat1]: No mapping found for field [revision]]; }]')\n```\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['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('--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"}]}