We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
dc-volumes.yml:27-28: Repair npm container reusing at...
The puzzle `449-27d8c19e` from #449 has to be resolved:

https://github.com/fidals/shopelectro/blob/f8ce85246c00411fcb21d025b0fb42abab81c7d5/docker/dc-volumes.yml#L27-L28

The puzzle was created by duker33 on 28-Jul-18. 

Estimate: 60 minutes,     

If you have any technical questions, don't ask me, submit new tickets instead. The task will be "done" when the problem is fixed and the text of the puzzle is _removed_ from the source code. Here is more about [PDD](http://www.yegor256.com/2009/03/04/pdd.html) and [about me](http://www.yegor256.com/2017/04/05/pdd-in-action.html).
В Firefox не поставить оценку товару
Не нажимаются звездочки, когда хочешь оставить отзыв о товаре

Firefox 58.0.2, чистый профиль. В Chromium работают

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `shopelectro/management/commands/_update_catalog/utils.py`
Content:
```
1 import glob
2 import logging
3 import math
4 import os
5 import shutil
6 import subprocess
7 import time
8 from contextlib import contextmanager
9 from itertools import chain
10 from typing import Iterator, Dict
11 from uuid import UUID
12 from xml.etree import ElementTree
13 
14 import requests
15 from django.conf import settings
16 
17 from shopelectro.exception import DownloadFilesError
18 
19 logger = logging.getLogger(__name__)
20 DOWNLOAD_FILES_TIMEOUT = 15.0
21 UUID_TYPE = str
22 Data = Dict[str, Dict[str, dict]]
23 NOT_SAVE_TEMPLATE = '{entity} with name="{name}" has no {field}. It\'ll not be' \
24                     ' saved'
25 
26 
27 def floor(x: float, precision=0) -> float:
28     """
29     The same behaviour as `math.floor`, but with precision.
30 
31     >>> floor(1.234, precision=2)  # result: 1.23
32     """
33     k = 10**precision
34     return math.floor(x * k) / k
35 
36 
37 def is_correct_uuid(uuid_):
38     try:
39         val = UUID(uuid_)
40     except (ValueError, TypeError):
41         return False
42     return str(val) == uuid_
43 
44 
45 class XmlFile:
46 
47     namespace = '{urn:1C.ru:commerceml_2}'
48 
49     def __init__(self, fetch_callback, xml_path_pattern, xpath_queries,
50                  extra_options=None):
51         self.fetch_callback = fetch_callback
52         self.xml_path_pattern = xml_path_pattern
53         self.xpath_queries = xpath_queries
54         self.extra_options = extra_options or {}
55 
56     @property
57     def parsed_files(self):
58         """Get parsed xml files, that matched the path pattern."""
59         xml_files = glob.glob(os.path.join(
60             settings.ASSETS_DIR, self.xml_path_pattern
61         ))
62         assert xml_files, 'Files on path {} does not exist.'.format(
63             self.xml_path_pattern
64         )
65         return [ElementTree.parse(file) for file in xml_files]
66 
67     @property
68     def xpaths(self):
69         """Get xpath queries for xml."""
70         return {
71             name: query.format(self.namespace)
72             for name, query in self.xpath_queries.items()
73         }
74 
75     def get_data(self) -> Iterator:
76         """
77         Get data from xml files.
78 
79         Example files with products names or prices.
80         """
81         return chain.from_iterable(
82             self.fetch_callback(file, self)
83             for file in self.parsed_files
84         )
85 
86 
87 @contextmanager
88 def collect_errors(error_types: tuple):
89     errors = []
90 
91     @contextmanager
92     def collect():
93         try:
94             yield
95         except error_types as error:
96             errors.append(error)
97     yield collect
98     if errors:
99         raise errors[0]
100 
101 
102 @contextmanager
103 def download_catalog(destination):
104     """Download catalog's xml files and delete after handle them."""
105     wget_command = (
106         'wget -r -P {} ftp://{}:{}@{}/webdata/'
107         ' 2>&1 | grep "время\|time\|Downloaded"'.format(
108             destination,
109             settings.FTP_USER,
110             settings.FTP_PASS,
111             settings.FTP_IP,
112         )
113     )
114 
115     try:
116         subprocess.run(wget_command, timeout=DOWNLOAD_FILES_TIMEOUT, shell=True)
117     except subprocess.TimeoutExpired as e:
118         raise DownloadFilesError(str(e))
119 
120     assert os.path.exists(os.path.join(
121         destination, settings.FTP_IP)), 'Files do not downloaded...'
122     logger.info('Download catalog - completed...')
123 
124     try:
125         yield
126     finally:
127         # remove downloaded data
128         shutil.rmtree(os.path.join(destination, settings.FTP_IP))
129 
130 
131 def report(error):
132     report_url = getattr(settings, 'SLACK_REPORT_URL', None)
133     if report_url is not None:
134         requests.post(
135             url=report_url,
136             json={
137                 'text': '*Не удалось обновить каталог Shopelectro.*\n'
138                         '*Время*: {}\n'
139                         '*Ошибка*: {}'.format(time.ctime(), error),
140             }
141         )
142
```
--- 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/shopelectro/management/commands/_update_catalog/utils.py b/shopelectro/management/commands/_update_catalog/utils.py
--- a/shopelectro/management/commands/_update_catalog/utils.py
+++ b/shopelectro/management/commands/_update_catalog/utils.py
@@ -17,7 +17,7 @@
 from shopelectro.exception import DownloadFilesError
 
 logger = logging.getLogger(__name__)
-DOWNLOAD_FILES_TIMEOUT = 15.0
+DOWNLOAD_FILES_TIMEOUT = 40.0
 UUID_TYPE = str
 Data = Dict[str, Dict[str, dict]]
 NOT_SAVE_TEMPLATE = '{entity} with name="{name}" has no {field}. It\'ll not be' \

{"golden_diff": "diff --git a/shopelectro/management/commands/_update_catalog/utils.py b/shopelectro/management/commands/_update_catalog/utils.py\n--- a/shopelectro/management/commands/_update_catalog/utils.py\n+++ b/shopelectro/management/commands/_update_catalog/utils.py\n@@ -17,7 +17,7 @@\n from shopelectro.exception import DownloadFilesError\n \n logger = logging.getLogger(__name__)\n-DOWNLOAD_FILES_TIMEOUT = 15.0\n+DOWNLOAD_FILES_TIMEOUT = 40.0\n UUID_TYPE = str\n Data = Dict[str, Dict[str, dict]]\n NOT_SAVE_TEMPLATE = '{entity} with name=\"{name}\" has no {field}. It\\'ll not be' \\\n", "issue": "dc-volumes.yml:27-28: Repair npm container reusing at...\nThe puzzle `449-27d8c19e` from #449 has to be resolved:\n\nhttps://github.com/fidals/shopelectro/blob/f8ce85246c00411fcb21d025b0fb42abab81c7d5/docker/dc-volumes.yml#L27-L28\n\nThe puzzle was created by duker33 on 28-Jul-18. \n\nEstimate: 60 minutes,     \n\nIf you have any technical questions, don't ask me, submit new tickets instead. The task will be \"done\" when the problem is fixed and the text of the puzzle is _removed_ from the source code. Here is more about [PDD](http://www.yegor256.com/2009/03/04/pdd.html) and [about me](http://www.yegor256.com/2017/04/05/pdd-in-action.html).\n\u0412 Firefox \u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043e\u0446\u0435\u043d\u043a\u0443 \u0442\u043e\u0432\u0430\u0440\u0443\n\u041d\u0435 \u043d\u0430\u0436\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u0438, \u043a\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0448\u044c \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u0437\u044b\u0432 \u043e \u0442\u043e\u0432\u0430\u0440\u0435\r\n\r\nFirefox 58.0.2, \u0447\u0438\u0441\u0442\u044b\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c. \u0412 Chromium \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442\n", "before_files": [{"content": "import glob\nimport logging\nimport math\nimport os\nimport shutil\nimport subprocess\nimport time\nfrom contextlib import contextmanager\nfrom itertools import chain\nfrom typing import Iterator, Dict\nfrom uuid import UUID\nfrom xml.etree import ElementTree\n\nimport requests\nfrom django.conf import settings\n\nfrom shopelectro.exception import DownloadFilesError\n\nlogger = logging.getLogger(__name__)\nDOWNLOAD_FILES_TIMEOUT = 15.0\nUUID_TYPE = str\nData = Dict[str, Dict[str, dict]]\nNOT_SAVE_TEMPLATE = '{entity} with name=\"{name}\" has no {field}. It\\'ll not be' \\\n                    ' saved'\n\n\ndef floor(x: float, precision=0) -> float:\n    \"\"\"\n    The same behaviour as `math.floor`, but with precision.\n\n    >>> floor(1.234, precision=2)  # result: 1.23\n    \"\"\"\n    k = 10**precision\n    return math.floor(x * k) / k\n\n\ndef is_correct_uuid(uuid_):\n    try:\n        val = UUID(uuid_)\n    except (ValueError, TypeError):\n        return False\n    return str(val) == uuid_\n\n\nclass XmlFile:\n\n    namespace = '{urn:1C.ru:commerceml_2}'\n\n    def __init__(self, fetch_callback, xml_path_pattern, xpath_queries,\n                 extra_options=None):\n        self.fetch_callback = fetch_callback\n        self.xml_path_pattern = xml_path_pattern\n        self.xpath_queries = xpath_queries\n        self.extra_options = extra_options or {}\n\n    @property\n    def parsed_files(self):\n        \"\"\"Get parsed xml files, that matched the path pattern.\"\"\"\n        xml_files = glob.glob(os.path.join(\n            settings.ASSETS_DIR, self.xml_path_pattern\n        ))\n        assert xml_files, 'Files on path {} does not exist.'.format(\n            self.xml_path_pattern\n        )\n        return [ElementTree.parse(file) for file in xml_files]\n\n    @property\n    def xpaths(self):\n        \"\"\"Get xpath queries for xml.\"\"\"\n        return {\n            name: query.format(self.namespace)\n            for name, query in self.xpath_queries.items()\n        }\n\n    def get_data(self) -> Iterator:\n        \"\"\"\n        Get data from xml files.\n\n        Example files with products names or prices.\n        \"\"\"\n        return chain.from_iterable(\n            self.fetch_callback(file, self)\n            for file in self.parsed_files\n        )\n\n\n@contextmanager\ndef collect_errors(error_types: tuple):\n    errors = []\n\n    @contextmanager\n    def collect():\n        try:\n            yield\n        except error_types as error:\n            errors.append(error)\n    yield collect\n    if errors:\n        raise errors[0]\n\n\n@contextmanager\ndef download_catalog(destination):\n    \"\"\"Download catalog's xml files and delete after handle them.\"\"\"\n    wget_command = (\n        'wget -r -P {} ftp://{}:{}@{}/webdata/'\n        ' 2>&1 | grep \"\u0432\u0440\u0435\u043c\u044f\\|time\\|Downloaded\"'.format(\n            destination,\n            settings.FTP_USER,\n            settings.FTP_PASS,\n            settings.FTP_IP,\n        )\n    )\n\n    try:\n        subprocess.run(wget_command, timeout=DOWNLOAD_FILES_TIMEOUT, shell=True)\n    except subprocess.TimeoutExpired as e:\n        raise DownloadFilesError(str(e))\n\n    assert os.path.exists(os.path.join(\n        destination, settings.FTP_IP)), 'Files do not downloaded...'\n    logger.info('Download catalog - completed...')\n\n    try:\n        yield\n    finally:\n        # remove downloaded data\n        shutil.rmtree(os.path.join(destination, settings.FTP_IP))\n\n\ndef report(error):\n    report_url = getattr(settings, 'SLACK_REPORT_URL', None)\n    if report_url is not None:\n        requests.post(\n            url=report_url,\n            json={\n                'text': '*\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 Shopelectro.*\\n'\n                        '*\u0412\u0440\u0435\u043c\u044f*: {}\\n'\n                        '*\u041e\u0448\u0438\u0431\u043a\u0430*: {}'.format(time.ctime(), error),\n            }\n        )\n", "path": "shopelectro/management/commands/_update_catalog/utils.py"}], "after_files": [{"content": "import glob\nimport logging\nimport math\nimport os\nimport shutil\nimport subprocess\nimport time\nfrom contextlib import contextmanager\nfrom itertools import chain\nfrom typing import Iterator, Dict\nfrom uuid import UUID\nfrom xml.etree import ElementTree\n\nimport requests\nfrom django.conf import settings\n\nfrom shopelectro.exception import DownloadFilesError\n\nlogger = logging.getLogger(__name__)\nDOWNLOAD_FILES_TIMEOUT = 40.0\nUUID_TYPE = str\nData = Dict[str, Dict[str, dict]]\nNOT_SAVE_TEMPLATE = '{entity} with name=\"{name}\" has no {field}. It\\'ll not be' \\\n                    ' saved'\n\n\ndef floor(x: float, precision=0) -> float:\n    \"\"\"\n    The same behaviour as `math.floor`, but with precision.\n\n    >>> floor(1.234, precision=2)  # result: 1.23\n    \"\"\"\n    k = 10**precision\n    return math.floor(x * k) / k\n\n\ndef is_correct_uuid(uuid_):\n    try:\n        val = UUID(uuid_)\n    except (ValueError, TypeError):\n        return False\n    return str(val) == uuid_\n\n\nclass XmlFile:\n\n    namespace = '{urn:1C.ru:commerceml_2}'\n\n    def __init__(self, fetch_callback, xml_path_pattern, xpath_queries,\n                 extra_options=None):\n        self.fetch_callback = fetch_callback\n        self.xml_path_pattern = xml_path_pattern\n        self.xpath_queries = xpath_queries\n        self.extra_options = extra_options or {}\n\n    @property\n    def parsed_files(self):\n        \"\"\"Get parsed xml files, that matched the path pattern.\"\"\"\n        xml_files = glob.glob(os.path.join(\n            settings.ASSETS_DIR, self.xml_path_pattern\n        ))\n        assert xml_files, 'Files on path {} does not exist.'.format(\n            self.xml_path_pattern\n        )\n        return [ElementTree.parse(file) for file in xml_files]\n\n    @property\n    def xpaths(self):\n        \"\"\"Get xpath queries for xml.\"\"\"\n        return {\n            name: query.format(self.namespace)\n            for name, query in self.xpath_queries.items()\n        }\n\n    def get_data(self) -> Iterator:\n        \"\"\"\n        Get data from xml files.\n\n        Example files with products names or prices.\n        \"\"\"\n        return chain.from_iterable(\n            self.fetch_callback(file, self)\n            for file in self.parsed_files\n        )\n\n\n@contextmanager\ndef collect_errors(error_types: tuple):\n    errors = []\n\n    @contextmanager\n    def collect():\n        try:\n            yield\n        except error_types as error:\n            errors.append(error)\n    yield collect\n    if errors:\n        raise errors[0]\n\n\n@contextmanager\ndef download_catalog(destination):\n    \"\"\"Download catalog's xml files and delete after handle them.\"\"\"\n    wget_command = (\n        'wget -r -P {} ftp://{}:{}@{}/webdata/'\n        ' 2>&1 | grep \"\u0432\u0440\u0435\u043c\u044f\\|time\\|Downloaded\"'.format(\n            destination,\n            settings.FTP_USER,\n            settings.FTP_PASS,\n            settings.FTP_IP,\n        )\n    )\n\n    try:\n        subprocess.run(wget_command, timeout=DOWNLOAD_FILES_TIMEOUT, shell=True)\n    except subprocess.TimeoutExpired as e:\n        raise DownloadFilesError(str(e))\n\n    assert os.path.exists(os.path.join(\n        destination, settings.FTP_IP)), 'Files do not downloaded...'\n    logger.info('Download catalog - completed...')\n\n    try:\n        yield\n    finally:\n        # remove downloaded data\n        shutil.rmtree(os.path.join(destination, settings.FTP_IP))\n\n\ndef report(error):\n    report_url = getattr(settings, 'SLACK_REPORT_URL', None)\n    if report_url is not None:\n        requests.post(\n            url=report_url,\n            json={\n                'text': '*\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 Shopelectro.*\\n'\n                        '*\u0412\u0440\u0435\u043c\u044f*: {}\\n'\n                        '*\u041e\u0448\u0438\u0431\u043a\u0430*: {}'.format(time.ctime(), error),\n            }\n        )\n", "path": "shopelectro/management/commands/_update_catalog/utils.py"}]}