We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Microsoft automatic translation fails for Serbian ("sr")
### Describe the issue

For the locale Serbian - "sr" the automatic translation with Microsoft Translator does not work. There are no "Automatic suggestions" and the "Automatic translation" tool does not get any texts.

### I already tried

- [X] I've read and searched [the documentation](https://docs.weblate.org/).
- [X] I've searched for similar issues in this repository.

### Steps to reproduce the behavior

1. Add Microsoft Translator to Weblate
2. Create a project and component with the language "Serbian" - "sr"
3. Go to `/translate/{project}/{component}/sr/?q=state:<translated` and see that no texts are suggested

### Expected behavior

Automatic suggestions should be shown for Serbian.

### Screenshots

_No response_

### Exception traceback

_No response_

### How do you run Weblate?

Docker container

### Weblate versions

 * Weblate: 4.18.2
 * Django: 4.2.2
 * siphashc: 2.1
 * translate-toolkit: 3.9.2
 * lxml: 4.9.2
 * Pillow: 9.5.0
 * nh3: 0.2.13
 * python-dateutil: 2.8.2
 * social-auth-core: 4.4.2
 * social-auth-app-django: 5.2.0
 * django-crispy-forms: 2.0
 * oauthlib: 3.2.2
 * django-compressor: 4.4
 * djangorestframework: 3.14.0
 * django-filter: 23.2
 * django-appconf: 1.0.5
 * user-agents: 2.2.0
 * filelock: 3.12.2
 * rapidfuzz: 3.1.1
 * openpyxl: 3.1.2
 * celery: 5.3.1
 * django-celery-beat: 2.5.0
 * kombu: 5.3.1
 * translation-finder: 2.15
 * weblate-language-data: 2023.5
 * html2text: 2020.1.16
 * pycairo: 1.24.0
 * PyGObject: 3.44.1
 * diff-match-patch: 20230430
 * requests: 2.31.0
 * django-redis: 5.3.0
 * hiredis: 2.2.3
 * sentry-sdk: 1.26.0
 * Cython: 0.29.35
 * misaka: 2.1.1
 * GitPython: 3.1.31
 * borgbackup: 1.2.4
 * pyparsing: 3.0.9
 * pyahocorasick: 2.0.0
 * python-redis-lock: 4.0.0
 * charset-normalizer: 3.1.0
 * Python: 3.11.4
 * Git: 2.30.2
 * psycopg2: 2.9.6
 * phply: 1.2.6
 * ruamel.yaml: 0.17.32
 * tesserocr: 2.6.0
 * boto3: 1.26.164
 * zeep: 4.2.1
 * aeidon: 1.12
 * iniparse: 0.5
 * mysqlclient: 2.2.0
 * Mercurial: 6.4.5
 * git-svn: 2.30.2
 * git-review: 2.3.1
 * Redis server: 6.2.12
 * PostgreSQL server: 13.10
 * Database backends: django.db.backends.postgresql
 * Cache backends: default:RedisCache, avatar:FileBasedCache
 * Email setup: django.core.mail.backends.smtp.EmailBackend: mailz.porsche.co.at
 * OS encoding: filesystem=utf-8, default=utf-8
 * Celery: redis://localhost:6379/1, redis://localhost:6379/1, regular
 * Platform: Linux 3.10.0-1160.90.1.el7.x86_64 (x86_64)

### Weblate deploy checks

```shell
System check identified some issues:

INFOS:
?: (weblate.I021) Error collection is not set up, it is highly recommended for production use
        HINT: https://docs.weblate.org/en/latest/admin/install.html#collecting-errors

System check identified 1 issue (1 silenced).
```


### Additional context

It seems that Microsoft translator treats "sr" as "sr-Latn".

For example:
``` 
POST https://api-eur.cognitive.microsofttranslator.com/translate?api-version=3.0&from=en&to=sr
Content-Type: application/json

[{"Text":"Hello World!"}]
```

gets the answer
```
[
  {
    "translations": [
      {
        "text": "Zdravo svete!",
        "to": "sr-Latn"
      }
    ]
  }
]
```

I think this has to be added to the `language_map`: https://github.com/WeblateOrg/weblate/blob/5674acc39e21ea092c0d2fba89569b802315595a/weblate/machinery/microsoft.py#L26

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `weblate/machinery/microsoft.py`
Content:
```
1 # Copyright © Michal Čihař <michal@weblate.org>
2 #
3 # SPDX-License-Identifier: GPL-3.0-or-later
4 
5 from __future__ import annotations
6 
7 from datetime import timedelta
8 
9 from django.conf import settings
10 from django.utils import timezone
11 
12 from .base import MachineTranslation, MachineTranslationError
13 from .forms import MicrosoftMachineryForm
14 
15 TOKEN_URL = "https://{0}{1}/sts/v1.0/issueToken?Subscription-Key={2}"
16 TOKEN_EXPIRY = timedelta(minutes=9)
17 
18 
19 class MicrosoftCognitiveTranslation(MachineTranslation):
20     """Microsoft Cognitive Services Translator API support."""
21 
22     name = "Microsoft Translator"
23     max_score = 90
24     settings_form = MicrosoftMachineryForm
25 
26     language_map = {
27         "zh-hant": "zh-Hant",
28         "zh-hans": "zh-Hans",
29         "zh-tw": "zh-Hant",
30         "zh-cn": "zh-Hans",
31         "tlh": "tlh-Latn",
32         "tlh-qaak": "tlh-Piqd",
33         "nb": "no",
34         "bs-latn": "bs-Latn",
35         "sr-latn": "sr-Latn",
36         "sr-cyrl": "sr-Cyrl",
37         "mn": "mn-Mong",
38     }
39 
40     def __init__(self, settings: dict[str, str]):
41         """Check configuration."""
42         super().__init__(settings)
43         self._access_token = None
44         self._token_expiry = None
45 
46         # check settings for Microsoft region prefix
47         region = "" if not self.settings["region"] else f"{self.settings['region']}."
48 
49         self._cognitive_token_url = TOKEN_URL.format(
50             region,
51             self.settings["endpoint_url"],
52             self.settings["key"],
53         )
54 
55     @staticmethod
56     def migrate_settings():
57         return {
58             "region": settings.MT_MICROSOFT_REGION,
59             "endpoint_url": settings.MT_MICROSOFT_ENDPOINT_URL,
60             "base_url": settings.MT_MICROSOFT_BASE_URL,
61             "key": settings.MT_MICROSOFT_COGNITIVE_KEY,
62         }
63 
64     def get_url(self, suffix):
65         return f"https://{self.settings['base_url']}/{suffix}"
66 
67     def is_token_expired(self):
68         """Check whether token is about to expire."""
69         return self._token_expiry <= timezone.now()
70 
71     def get_authentication(self):
72         """Hook for backends to allow add authentication headers to request."""
73         return {"Authorization": f"Bearer {self.access_token}"}
74 
75     @property
76     def access_token(self):
77         """Obtain and caches access token."""
78         if self._access_token is None or self.is_token_expired():
79             self._access_token = self.request(
80                 "post", self._cognitive_token_url, skip_auth=True
81             ).text
82             self._token_expiry = timezone.now() + TOKEN_EXPIRY
83 
84         return self._access_token
85 
86     def map_language_code(self, code):
87         """Convert language to service specific code."""
88         return super().map_language_code(code).replace("_", "-")
89 
90     def download_languages(self):
91         """
92         Download list of supported languages from a service.
93 
94         Example of the response:
95 
96         ['af', 'ar', 'bs-Latn', 'bg', 'ca', 'zh-CHS', 'zh-CHT', 'yue', 'hr', 'cs', 'da',
97         'nl', 'en', 'et', 'fj', 'fil', 'fi', 'fr', 'de', 'el', 'ht', 'he', 'hi', 'mww',
98         'h', 'id', 'it', 'ja', 'sw', 'tlh', 'tlh-Qaak', 'ko', 'lv', 'lt', 'mg', 'ms',
99         'mt', 'yua', 'no', 'otq', 'fa', 'pl', 'pt', 'ro', 'r', 'sm', 'sr-Cyrl',
100         'sr-Latn', 'sk', 'sl', 'es', 'sv', 'ty', 'th', 'to', 'tr', 'uk', 'ur', 'vi',
101         'cy']
102         """
103         response = self.request(
104             "get", self.get_url("languages"), params={"api-version": "3.0"}
105         )
106         # Microsoft tends to use utf-8-sig instead of plain utf-8
107         response.encoding = response.apparent_encoding
108         payload = response.json()
109 
110         # We should get an object, string usually means an error
111         if isinstance(payload, str):
112             raise MachineTranslationError(payload)
113 
114         return payload["translation"].keys()
115 
116     def download_translations(
117         self,
118         source,
119         language,
120         text: str,
121         unit,
122         user,
123         threshold: int = 75,
124     ):
125         """Download list of possible translations from a service."""
126         args = {
127             "api-version": "3.0",
128             "from": source,
129             "to": language,
130             "category": "general",
131         }
132         response = self.request(
133             "post", self.get_url("translate"), params=args, json=[{"Text": text[:5000]}]
134         )
135         # Microsoft tends to use utf-8-sig instead of plain utf-8
136         response.encoding = "utf-8-sig"
137         payload = response.json()
138         yield {
139             "text": payload[0]["translations"][0]["text"],
140             "quality": self.max_score,
141             "service": self.name,
142             "source": text,
143         }
144
```
--- 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/weblate/machinery/microsoft.py b/weblate/machinery/microsoft.py
--- a/weblate/machinery/microsoft.py
+++ b/weblate/machinery/microsoft.py
@@ -32,6 +32,7 @@
         "tlh-qaak": "tlh-Piqd",
         "nb": "no",
         "bs-latn": "bs-Latn",
+        "sr": "sr-Latn",
         "sr-latn": "sr-Latn",
         "sr-cyrl": "sr-Cyrl",
         "mn": "mn-Mong",

{"golden_diff": "diff --git a/weblate/machinery/microsoft.py b/weblate/machinery/microsoft.py\n--- a/weblate/machinery/microsoft.py\n+++ b/weblate/machinery/microsoft.py\n@@ -32,6 +32,7 @@\n         \"tlh-qaak\": \"tlh-Piqd\",\n         \"nb\": \"no\",\n         \"bs-latn\": \"bs-Latn\",\n+        \"sr\": \"sr-Latn\",\n         \"sr-latn\": \"sr-Latn\",\n         \"sr-cyrl\": \"sr-Cyrl\",\n         \"mn\": \"mn-Mong\",\n", "issue": "Microsoft automatic translation fails for Serbian (\"sr\")\n### Describe the issue\n\nFor the locale Serbian - \"sr\" the automatic translation with Microsoft Translator does not work. There are no \"Automatic suggestions\" and the \"Automatic translation\" tool does not get any texts.\n\n### I already tried\n\n- [X] I've read and searched [the documentation](https://docs.weblate.org/).\n- [X] I've searched for similar issues in this repository.\n\n### Steps to reproduce the behavior\n\n1. Add Microsoft Translator to Weblate\r\n2. Create a project and component with the language \"Serbian\" - \"sr\"\r\n3. Go to `/translate/{project}/{component}/sr/?q=state:<translated` and see that no texts are suggested\n\n### Expected behavior\n\nAutomatic suggestions should be shown for Serbian.\n\n### Screenshots\n\n_No response_\n\n### Exception traceback\n\n_No response_\n\n### How do you run Weblate?\n\nDocker container\n\n### Weblate versions\n\n * Weblate: 4.18.2\r\n * Django: 4.2.2\r\n * siphashc: 2.1\r\n * translate-toolkit: 3.9.2\r\n * lxml: 4.9.2\r\n * Pillow: 9.5.0\r\n * nh3: 0.2.13\r\n * python-dateutil: 2.8.2\r\n * social-auth-core: 4.4.2\r\n * social-auth-app-django: 5.2.0\r\n * django-crispy-forms: 2.0\r\n * oauthlib: 3.2.2\r\n * django-compressor: 4.4\r\n * djangorestframework: 3.14.0\r\n * django-filter: 23.2\r\n * django-appconf: 1.0.5\r\n * user-agents: 2.2.0\r\n * filelock: 3.12.2\r\n * rapidfuzz: 3.1.1\r\n * openpyxl: 3.1.2\r\n * celery: 5.3.1\r\n * django-celery-beat: 2.5.0\r\n * kombu: 5.3.1\r\n * translation-finder: 2.15\r\n * weblate-language-data: 2023.5\r\n * html2text: 2020.1.16\r\n * pycairo: 1.24.0\r\n * PyGObject: 3.44.1\r\n * diff-match-patch: 20230430\r\n * requests: 2.31.0\r\n * django-redis: 5.3.0\r\n * hiredis: 2.2.3\r\n * sentry-sdk: 1.26.0\r\n * Cython: 0.29.35\r\n * misaka: 2.1.1\r\n * GitPython: 3.1.31\r\n * borgbackup: 1.2.4\r\n * pyparsing: 3.0.9\r\n * pyahocorasick: 2.0.0\r\n * python-redis-lock: 4.0.0\r\n * charset-normalizer: 3.1.0\r\n * Python: 3.11.4\r\n * Git: 2.30.2\r\n * psycopg2: 2.9.6\r\n * phply: 1.2.6\r\n * ruamel.yaml: 0.17.32\r\n * tesserocr: 2.6.0\r\n * boto3: 1.26.164\r\n * zeep: 4.2.1\r\n * aeidon: 1.12\r\n * iniparse: 0.5\r\n * mysqlclient: 2.2.0\r\n * Mercurial: 6.4.5\r\n * git-svn: 2.30.2\r\n * git-review: 2.3.1\r\n * Redis server: 6.2.12\r\n * PostgreSQL server: 13.10\r\n * Database backends: django.db.backends.postgresql\r\n * Cache backends: default:RedisCache, avatar:FileBasedCache\r\n * Email setup: django.core.mail.backends.smtp.EmailBackend: mailz.porsche.co.at\r\n * OS encoding: filesystem=utf-8, default=utf-8\r\n * Celery: redis://localhost:6379/1, redis://localhost:6379/1, regular\r\n * Platform: Linux 3.10.0-1160.90.1.el7.x86_64 (x86_64)\n\n### Weblate deploy checks\n\n```shell\nSystem check identified some issues:\r\n\r\nINFOS:\r\n?: (weblate.I021) Error collection is not set up, it is highly recommended for production use\r\n        HINT: https://docs.weblate.org/en/latest/admin/install.html#collecting-errors\r\n\r\nSystem check identified 1 issue (1 silenced).\n```\n\n\n### Additional context\n\nIt seems that Microsoft translator treats \"sr\" as \"sr-Latn\".\r\n\r\nFor example:\r\n``` \r\nPOST https://api-eur.cognitive.microsofttranslator.com/translate?api-version=3.0&from=en&to=sr\r\nContent-Type: application/json\r\n\r\n[{\"Text\":\"Hello World!\"}]\r\n```\r\n\r\ngets the answer\r\n```\r\n[\r\n  {\r\n    \"translations\": [\r\n      {\r\n        \"text\": \"Zdravo svete!\",\r\n        \"to\": \"sr-Latn\"\r\n      }\r\n    ]\r\n  }\r\n]\r\n```\r\n\r\nI think this has to be added to the `language_map`: https://github.com/WeblateOrg/weblate/blob/5674acc39e21ea092c0d2fba89569b802315595a/weblate/machinery/microsoft.py#L26\n", "before_files": [{"content": "# Copyright \u00a9 Michal \u010ciha\u0159 <michal@weblate.org>\n#\n# SPDX-License-Identifier: GPL-3.0-or-later\n\nfrom __future__ import annotations\n\nfrom datetime import timedelta\n\nfrom django.conf import settings\nfrom django.utils import timezone\n\nfrom .base import MachineTranslation, MachineTranslationError\nfrom .forms import MicrosoftMachineryForm\n\nTOKEN_URL = \"https://{0}{1}/sts/v1.0/issueToken?Subscription-Key={2}\"\nTOKEN_EXPIRY = timedelta(minutes=9)\n\n\nclass MicrosoftCognitiveTranslation(MachineTranslation):\n    \"\"\"Microsoft Cognitive Services Translator API support.\"\"\"\n\n    name = \"Microsoft Translator\"\n    max_score = 90\n    settings_form = MicrosoftMachineryForm\n\n    language_map = {\n        \"zh-hant\": \"zh-Hant\",\n        \"zh-hans\": \"zh-Hans\",\n        \"zh-tw\": \"zh-Hant\",\n        \"zh-cn\": \"zh-Hans\",\n        \"tlh\": \"tlh-Latn\",\n        \"tlh-qaak\": \"tlh-Piqd\",\n        \"nb\": \"no\",\n        \"bs-latn\": \"bs-Latn\",\n        \"sr-latn\": \"sr-Latn\",\n        \"sr-cyrl\": \"sr-Cyrl\",\n        \"mn\": \"mn-Mong\",\n    }\n\n    def __init__(self, settings: dict[str, str]):\n        \"\"\"Check configuration.\"\"\"\n        super().__init__(settings)\n        self._access_token = None\n        self._token_expiry = None\n\n        # check settings for Microsoft region prefix\n        region = \"\" if not self.settings[\"region\"] else f\"{self.settings['region']}.\"\n\n        self._cognitive_token_url = TOKEN_URL.format(\n            region,\n            self.settings[\"endpoint_url\"],\n            self.settings[\"key\"],\n        )\n\n    @staticmethod\n    def migrate_settings():\n        return {\n            \"region\": settings.MT_MICROSOFT_REGION,\n            \"endpoint_url\": settings.MT_MICROSOFT_ENDPOINT_URL,\n            \"base_url\": settings.MT_MICROSOFT_BASE_URL,\n            \"key\": settings.MT_MICROSOFT_COGNITIVE_KEY,\n        }\n\n    def get_url(self, suffix):\n        return f\"https://{self.settings['base_url']}/{suffix}\"\n\n    def is_token_expired(self):\n        \"\"\"Check whether token is about to expire.\"\"\"\n        return self._token_expiry <= timezone.now()\n\n    def get_authentication(self):\n        \"\"\"Hook for backends to allow add authentication headers to request.\"\"\"\n        return {\"Authorization\": f\"Bearer {self.access_token}\"}\n\n    @property\n    def access_token(self):\n        \"\"\"Obtain and caches access token.\"\"\"\n        if self._access_token is None or self.is_token_expired():\n            self._access_token = self.request(\n                \"post\", self._cognitive_token_url, skip_auth=True\n            ).text\n            self._token_expiry = timezone.now() + TOKEN_EXPIRY\n\n        return self._access_token\n\n    def map_language_code(self, code):\n        \"\"\"Convert language to service specific code.\"\"\"\n        return super().map_language_code(code).replace(\"_\", \"-\")\n\n    def download_languages(self):\n        \"\"\"\n        Download list of supported languages from a service.\n\n        Example of the response:\n\n        ['af', 'ar', 'bs-Latn', 'bg', 'ca', 'zh-CHS', 'zh-CHT', 'yue', 'hr', 'cs', 'da',\n        'nl', 'en', 'et', 'fj', 'fil', 'fi', 'fr', 'de', 'el', 'ht', 'he', 'hi', 'mww',\n        'h', 'id', 'it', 'ja', 'sw', 'tlh', 'tlh-Qaak', 'ko', 'lv', 'lt', 'mg', 'ms',\n        'mt', 'yua', 'no', 'otq', 'fa', 'pl', 'pt', 'ro', 'r', 'sm', 'sr-Cyrl',\n        'sr-Latn', 'sk', 'sl', 'es', 'sv', 'ty', 'th', 'to', 'tr', 'uk', 'ur', 'vi',\n        'cy']\n        \"\"\"\n        response = self.request(\n            \"get\", self.get_url(\"languages\"), params={\"api-version\": \"3.0\"}\n        )\n        # Microsoft tends to use utf-8-sig instead of plain utf-8\n        response.encoding = response.apparent_encoding\n        payload = response.json()\n\n        # We should get an object, string usually means an error\n        if isinstance(payload, str):\n            raise MachineTranslationError(payload)\n\n        return payload[\"translation\"].keys()\n\n    def download_translations(\n        self,\n        source,\n        language,\n        text: str,\n        unit,\n        user,\n        threshold: int = 75,\n    ):\n        \"\"\"Download list of possible translations from a service.\"\"\"\n        args = {\n            \"api-version\": \"3.0\",\n            \"from\": source,\n            \"to\": language,\n            \"category\": \"general\",\n        }\n        response = self.request(\n            \"post\", self.get_url(\"translate\"), params=args, json=[{\"Text\": text[:5000]}]\n        )\n        # Microsoft tends to use utf-8-sig instead of plain utf-8\n        response.encoding = \"utf-8-sig\"\n        payload = response.json()\n        yield {\n            \"text\": payload[0][\"translations\"][0][\"text\"],\n            \"quality\": self.max_score,\n            \"service\": self.name,\n            \"source\": text,\n        }\n", "path": "weblate/machinery/microsoft.py"}], "after_files": [{"content": "# Copyright \u00a9 Michal \u010ciha\u0159 <michal@weblate.org>\n#\n# SPDX-License-Identifier: GPL-3.0-or-later\n\nfrom __future__ import annotations\n\nfrom datetime import timedelta\n\nfrom django.conf import settings\nfrom django.utils import timezone\n\nfrom .base import MachineTranslation, MachineTranslationError\nfrom .forms import MicrosoftMachineryForm\n\nTOKEN_URL = \"https://{0}{1}/sts/v1.0/issueToken?Subscription-Key={2}\"\nTOKEN_EXPIRY = timedelta(minutes=9)\n\n\nclass MicrosoftCognitiveTranslation(MachineTranslation):\n    \"\"\"Microsoft Cognitive Services Translator API support.\"\"\"\n\n    name = \"Microsoft Translator\"\n    max_score = 90\n    settings_form = MicrosoftMachineryForm\n\n    language_map = {\n        \"zh-hant\": \"zh-Hant\",\n        \"zh-hans\": \"zh-Hans\",\n        \"zh-tw\": \"zh-Hant\",\n        \"zh-cn\": \"zh-Hans\",\n        \"tlh\": \"tlh-Latn\",\n        \"tlh-qaak\": \"tlh-Piqd\",\n        \"nb\": \"no\",\n        \"bs-latn\": \"bs-Latn\",\n        \"sr\": \"sr-Latn\",\n        \"sr-latn\": \"sr-Latn\",\n        \"sr-cyrl\": \"sr-Cyrl\",\n        \"mn\": \"mn-Mong\",\n    }\n\n    def __init__(self, settings: dict[str, str]):\n        \"\"\"Check configuration.\"\"\"\n        super().__init__(settings)\n        self._access_token = None\n        self._token_expiry = None\n\n        # check settings for Microsoft region prefix\n        region = \"\" if not self.settings[\"region\"] else f\"{self.settings['region']}.\"\n\n        self._cognitive_token_url = TOKEN_URL.format(\n            region,\n            self.settings[\"endpoint_url\"],\n            self.settings[\"key\"],\n        )\n\n    @staticmethod\n    def migrate_settings():\n        return {\n            \"region\": settings.MT_MICROSOFT_REGION,\n            \"endpoint_url\": settings.MT_MICROSOFT_ENDPOINT_URL,\n            \"base_url\": settings.MT_MICROSOFT_BASE_URL,\n            \"key\": settings.MT_MICROSOFT_COGNITIVE_KEY,\n        }\n\n    def get_url(self, suffix):\n        return f\"https://{self.settings['base_url']}/{suffix}\"\n\n    def is_token_expired(self):\n        \"\"\"Check whether token is about to expire.\"\"\"\n        return self._token_expiry <= timezone.now()\n\n    def get_authentication(self):\n        \"\"\"Hook for backends to allow add authentication headers to request.\"\"\"\n        return {\"Authorization\": f\"Bearer {self.access_token}\"}\n\n    @property\n    def access_token(self):\n        \"\"\"Obtain and caches access token.\"\"\"\n        if self._access_token is None or self.is_token_expired():\n            self._access_token = self.request(\n                \"post\", self._cognitive_token_url, skip_auth=True\n            ).text\n            self._token_expiry = timezone.now() + TOKEN_EXPIRY\n\n        return self._access_token\n\n    def map_language_code(self, code):\n        \"\"\"Convert language to service specific code.\"\"\"\n        return super().map_language_code(code).replace(\"_\", \"-\")\n\n    def download_languages(self):\n        \"\"\"\n        Download list of supported languages from a service.\n\n        Example of the response:\n\n        ['af', 'ar', 'bs-Latn', 'bg', 'ca', 'zh-CHS', 'zh-CHT', 'yue', 'hr', 'cs', 'da',\n        'nl', 'en', 'et', 'fj', 'fil', 'fi', 'fr', 'de', 'el', 'ht', 'he', 'hi', 'mww',\n        'h', 'id', 'it', 'ja', 'sw', 'tlh', 'tlh-Qaak', 'ko', 'lv', 'lt', 'mg', 'ms',\n        'mt', 'yua', 'no', 'otq', 'fa', 'pl', 'pt', 'ro', 'r', 'sm', 'sr-Cyrl',\n        'sr-Latn', 'sk', 'sl', 'es', 'sv', 'ty', 'th', 'to', 'tr', 'uk', 'ur', 'vi',\n        'cy']\n        \"\"\"\n        response = self.request(\n            \"get\", self.get_url(\"languages\"), params={\"api-version\": \"3.0\"}\n        )\n        # Microsoft tends to use utf-8-sig instead of plain utf-8\n        response.encoding = response.apparent_encoding\n        payload = response.json()\n\n        # We should get an object, string usually means an error\n        if isinstance(payload, str):\n            raise MachineTranslationError(payload)\n\n        return payload[\"translation\"].keys()\n\n    def download_translations(\n        self,\n        source,\n        language,\n        text: str,\n        unit,\n        user,\n        threshold: int = 75,\n    ):\n        \"\"\"Download list of possible translations from a service.\"\"\"\n        args = {\n            \"api-version\": \"3.0\",\n            \"from\": source,\n            \"to\": language,\n            \"category\": \"general\",\n        }\n        response = self.request(\n            \"post\", self.get_url(\"translate\"), params=args, json=[{\"Text\": text[:5000]}]\n        )\n        # Microsoft tends to use utf-8-sig instead of plain utf-8\n        response.encoding = \"utf-8-sig\"\n        payload = response.json()\n        yield {\n            \"text\": payload[0][\"translations\"][0][\"text\"],\n            \"quality\": self.max_score,\n            \"service\": self.name,\n            \"source\": text,\n        }\n", "path": "weblate/machinery/microsoft.py"}]}