We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
App Generator creates faulty info.xml when using umlauts (special characters äöü)
Problem: nextcloud/apps/foo/appinfo/info.xml misses the closing **</info>** tag. Just generates **</**

## Details

* Browser and browser version: Firefox 55.0.3

## Steps to reproduce

Steps to reproduce:

- visit https://apps.nextcloud.com/developer/apps/generate
- enter the required information; in summary and description enter "This is a test app äöü"
- click generate and download.
- look at the generated info.xml


App Generator creates faulty info.xml when using umlauts (special characters äöü)
Problem: nextcloud/apps/foo/appinfo/info.xml misses the closing **</info>** tag. Just generates **</**

## Details

* Browser and browser version: Firefox 55.0.3

## Steps to reproduce

Steps to reproduce:

- visit https://apps.nextcloud.com/developer/apps/generate
- enter the required information; in summary and description enter "This is a test app äöü"
- click generate and download.
- look at the generated info.xml



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nextcloudappstore/scaffolding/archive.py`
Content:
```
1 import re
2 import tarfile
3 from io import BytesIO, StringIO
4 from typing import Dict
5 from os.path import join, isdir, relpath
6 from os import walk
7 
8 from django.template import Context
9 from django.template import Template
10 
11 from nextcloudappstore.core.facades import resolve_file_relative_path
12 from nextcloudappstore.settings.base import APP_SCAFFOLDING_PROFILES
13 
14 
15 def build_files(args: Dict[str, str]) -> Dict[str, str]:
16     platform = int(args['platform'])  # prevent path traversal
17     vars = {
18         'id': args['name'].lower(),
19         'summary': args['summary'],
20         'description': args['description'],
21         'name': ' '.join(re.findall(r'[A-Z][^A-Z]*', args['name'])),
22         'namespace': args['name'],
23         'author_name': args['author_name'],
24         'author_mail': args['author_email'],
25         'author_homepage': args['author_homepage'],
26         'issue_tracker': args['issue_tracker'],
27         'categories': args['categories'],
28         'nextcloud_version': platform
29     }
30     vars.update(APP_SCAFFOLDING_PROFILES.get(platform, {}))
31     relative_base = 'app-templates/%i/app/' % platform
32     base = resolve_file_relative_path(__file__, relative_base)
33 
34     context = Context({'app': vars})
35     result = {}
36     if isdir(base):
37         for root, dirs, files in walk(base):
38             for file in files:
39                 file_path = join(root, file)
40                 rel_file_path = '%s/%s' % (
41                     vars['id'], relpath(file_path, base)
42                 )
43                 with open(file_path) as f:
44                     t = Template(f.read())
45                     result[rel_file_path] = t.render(context)
46 
47     return result
48 
49 
50 def build_archive(parameters: Dict[str, str]) -> BytesIO:
51     buffer = BytesIO()
52     with tarfile.open(fileobj=buffer, mode='w:gz') as f:
53         files = build_files(parameters)
54         for path, contents in files.items():
55             info = tarfile.TarInfo(path)
56             info.size = len(contents)
57             f.addfile(info, BytesIO(contents.encode()))
58     buffer.seek(0)
59     return buffer
60
```
--- 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/nextcloudappstore/scaffolding/archive.py b/nextcloudappstore/scaffolding/archive.py
--- a/nextcloudappstore/scaffolding/archive.py
+++ b/nextcloudappstore/scaffolding/archive.py
@@ -1,9 +1,9 @@
 import re
 import tarfile
-from io import BytesIO, StringIO
-from typing import Dict
-from os.path import join, isdir, relpath
+from io import BytesIO
 from os import walk
+from os.path import join, isdir, relpath
+from typing import Dict
 
 from django.template import Context
 from django.template import Template
@@ -53,7 +53,8 @@
         files = build_files(parameters)
         for path, contents in files.items():
             info = tarfile.TarInfo(path)
-            info.size = len(contents)
-            f.addfile(info, BytesIO(contents.encode()))
+            encoded_content = contents.encode()
+            info.size = len(encoded_content)
+            f.addfile(info, BytesIO(encoded_content))
     buffer.seek(0)
     return buffer

{"golden_diff": "diff --git a/nextcloudappstore/scaffolding/archive.py b/nextcloudappstore/scaffolding/archive.py\n--- a/nextcloudappstore/scaffolding/archive.py\n+++ b/nextcloudappstore/scaffolding/archive.py\n@@ -1,9 +1,9 @@\n import re\n import tarfile\n-from io import BytesIO, StringIO\n-from typing import Dict\n-from os.path import join, isdir, relpath\n+from io import BytesIO\n from os import walk\n+from os.path import join, isdir, relpath\n+from typing import Dict\n \n from django.template import Context\n from django.template import Template\n@@ -53,7 +53,8 @@\n         files = build_files(parameters)\n         for path, contents in files.items():\n             info = tarfile.TarInfo(path)\n-            info.size = len(contents)\n-            f.addfile(info, BytesIO(contents.encode()))\n+            encoded_content = contents.encode()\n+            info.size = len(encoded_content)\n+            f.addfile(info, BytesIO(encoded_content))\n     buffer.seek(0)\n     return buffer\n", "issue": "App Generator creates faulty info.xml when using umlauts (special characters \u00e4\u00f6\u00fc)\nProblem: nextcloud/apps/foo/appinfo/info.xml misses the closing **</info>** tag. Just generates **</**\r\n\r\n## Details\r\n\r\n* Browser and browser version: Firefox 55.0.3\r\n\r\n## Steps to reproduce\r\n\r\nSteps to reproduce:\r\n\r\n- visit https://apps.nextcloud.com/developer/apps/generate\r\n- enter the required information; in summary and description enter \"This is a test app \u00e4\u00f6\u00fc\"\r\n- click generate and download.\r\n- look at the generated info.xml\r\n\r\n\nApp Generator creates faulty info.xml when using umlauts (special characters \u00e4\u00f6\u00fc)\nProblem: nextcloud/apps/foo/appinfo/info.xml misses the closing **</info>** tag. Just generates **</**\r\n\r\n## Details\r\n\r\n* Browser and browser version: Firefox 55.0.3\r\n\r\n## Steps to reproduce\r\n\r\nSteps to reproduce:\r\n\r\n- visit https://apps.nextcloud.com/developer/apps/generate\r\n- enter the required information; in summary and description enter \"This is a test app \u00e4\u00f6\u00fc\"\r\n- click generate and download.\r\n- look at the generated info.xml\r\n\r\n\n", "before_files": [{"content": "import re\nimport tarfile\nfrom io import BytesIO, StringIO\nfrom typing import Dict\nfrom os.path import join, isdir, relpath\nfrom os import walk\n\nfrom django.template import Context\nfrom django.template import Template\n\nfrom nextcloudappstore.core.facades import resolve_file_relative_path\nfrom nextcloudappstore.settings.base import APP_SCAFFOLDING_PROFILES\n\n\ndef build_files(args: Dict[str, str]) -> Dict[str, str]:\n    platform = int(args['platform'])  # prevent path traversal\n    vars = {\n        'id': args['name'].lower(),\n        'summary': args['summary'],\n        'description': args['description'],\n        'name': ' '.join(re.findall(r'[A-Z][^A-Z]*', args['name'])),\n        'namespace': args['name'],\n        'author_name': args['author_name'],\n        'author_mail': args['author_email'],\n        'author_homepage': args['author_homepage'],\n        'issue_tracker': args['issue_tracker'],\n        'categories': args['categories'],\n        'nextcloud_version': platform\n    }\n    vars.update(APP_SCAFFOLDING_PROFILES.get(platform, {}))\n    relative_base = 'app-templates/%i/app/' % platform\n    base = resolve_file_relative_path(__file__, relative_base)\n\n    context = Context({'app': vars})\n    result = {}\n    if isdir(base):\n        for root, dirs, files in walk(base):\n            for file in files:\n                file_path = join(root, file)\n                rel_file_path = '%s/%s' % (\n                    vars['id'], relpath(file_path, base)\n                )\n                with open(file_path) as f:\n                    t = Template(f.read())\n                    result[rel_file_path] = t.render(context)\n\n    return result\n\n\ndef build_archive(parameters: Dict[str, str]) -> BytesIO:\n    buffer = BytesIO()\n    with tarfile.open(fileobj=buffer, mode='w:gz') as f:\n        files = build_files(parameters)\n        for path, contents in files.items():\n            info = tarfile.TarInfo(path)\n            info.size = len(contents)\n            f.addfile(info, BytesIO(contents.encode()))\n    buffer.seek(0)\n    return buffer\n", "path": "nextcloudappstore/scaffolding/archive.py"}], "after_files": [{"content": "import re\nimport tarfile\nfrom io import BytesIO\nfrom os import walk\nfrom os.path import join, isdir, relpath\nfrom typing import Dict\n\nfrom django.template import Context\nfrom django.template import Template\n\nfrom nextcloudappstore.core.facades import resolve_file_relative_path\nfrom nextcloudappstore.settings.base import APP_SCAFFOLDING_PROFILES\n\n\ndef build_files(args: Dict[str, str]) -> Dict[str, str]:\n    platform = int(args['platform'])  # prevent path traversal\n    vars = {\n        'id': args['name'].lower(),\n        'summary': args['summary'],\n        'description': args['description'],\n        'name': ' '.join(re.findall(r'[A-Z][^A-Z]*', args['name'])),\n        'namespace': args['name'],\n        'author_name': args['author_name'],\n        'author_mail': args['author_email'],\n        'author_homepage': args['author_homepage'],\n        'issue_tracker': args['issue_tracker'],\n        'categories': args['categories'],\n        'nextcloud_version': platform\n    }\n    vars.update(APP_SCAFFOLDING_PROFILES.get(platform, {}))\n    relative_base = 'app-templates/%i/app/' % platform\n    base = resolve_file_relative_path(__file__, relative_base)\n\n    context = Context({'app': vars})\n    result = {}\n    if isdir(base):\n        for root, dirs, files in walk(base):\n            for file in files:\n                file_path = join(root, file)\n                rel_file_path = '%s/%s' % (\n                    vars['id'], relpath(file_path, base)\n                )\n                with open(file_path) as f:\n                    t = Template(f.read())\n                    result[rel_file_path] = t.render(context)\n\n    return result\n\n\ndef build_archive(parameters: Dict[str, str]) -> BytesIO:\n    buffer = BytesIO()\n    with tarfile.open(fileobj=buffer, mode='w:gz') as f:\n        files = build_files(parameters)\n        for path, contents in files.items():\n            info = tarfile.TarInfo(path)\n            encoded_content = contents.encode()\n            info.size = len(encoded_content)\n            f.addfile(info, BytesIO(encoded_content))\n    buffer.seek(0)\n    return buffer\n", "path": "nextcloudappstore/scaffolding/archive.py"}]}