Skip to content

Commit

Permalink
Preserve non-ASCII characters when downloading a zip (#342)
Browse files Browse the repository at this point in the history
* Preserve non-ASCII characters when downloading a zip

* Add test for style with ascii name download
  • Loading branch information
Xpirix authored Jan 31, 2024
1 parent fe8b04d commit a881607
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 4 deletions.
6 changes: 3 additions & 3 deletions qgis-app/base/views/processing_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
View,
)
from django.views.generic.base import ContextMixin
from django.utils.encoding import escape_uri_path

GROUP_NAME = "Style Managers"

Expand Down Expand Up @@ -484,9 +485,8 @@ def get(self, request, *args, **kwargs):
response = HttpResponse(
zipfile.getvalue(), content_type="application/x-zip-compressed"
)
response["Content-Disposition"] = "attachment; filename=%s.zip" % (
slugify(object.name, allow_unicode=True)
)
zip_name = slugify(object.name, allow_unicode=True)
response["Content-Disposition"] = f"attachment; filename*=utf-8''{escape_uri_path(zip_name)}.zip"
return response


Expand Down
17 changes: 17 additions & 0 deletions qgis-app/styles/tests/stylefiles/三调符号库.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE qgis_style>
<qgis_style version="2">
<symbols/>
<colorramps>
<colorramp name="Blues" type="gradient">
<prop k="color1" v="247,251,255,255"/>
<prop k="color2" v="8,48,107,255"/>
<prop k="discrete" v="0"/>
<prop k="rampType" v="gradient"/>
<prop k="stops" v="0.13;222,235,247,255:0.26;198,219,239,255:0.39;158,202,225,255:0.52;107,174,214,255:0.65;66,146,198,255:0.78;33,113,181,255:0.9;8,81,156,255"/>
</colorramp>
</colorramps>
<textformats/>
<labelsettings/>
<legendpatchshapes/>
<symbols3d/>
</qgis_style>
36 changes: 36 additions & 0 deletions qgis-app/styles/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from django.test import Client, TestCase, override_settings
from django.urls import reverse
from styles.models import Style, StyleType
from django.utils.text import slugify
from django.utils.encoding import escape_uri_path


STYLE_DIR = os.path.join(os.path.dirname(__file__), "stylefiles")

Expand Down Expand Up @@ -274,6 +277,18 @@ def setUp(self):
approved=True,
)

self.newstyle_non_ascii = Style.objects.create(
pk=2,
creator=User.objects.get(pk=2),
style_type=StyleType.objects.get(pk=1),
name="三调符号库",
description="This file is saved in styles/tests/stylefiles folder",
thumbnail_image="thumbnail.png",
file="三调符号库.xml",
download_count=0,
approved=True,
)

@override_settings(MEDIA_ROOT="styles/tests/stylefiles/")
def test_anonymous_user_download(self):
style = Style.objects.get(pk=1)
Expand All @@ -286,6 +301,27 @@ def test_anonymous_user_download(self):
style = Style.objects.get(pk=1)
self.assertEqual(style.download_count, 1)

@override_settings(MEDIA_ROOT="styles/tests/stylefiles/")
def test_non_ascii_name_download(self):
style = Style.objects.get(pk=2)
self.assertEqual(style.download_count, 0)
self.client.logout()
url = reverse("style_download", kwargs={"pk": 2})
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

# Check if the Content-Disposition header is present in the response
self.assertTrue('Content-Disposition' in response)

style_name = escape_uri_path(slugify(style.name, allow_unicode=True))
# Extract the filename from the Content-Disposition header
content_disposition = response['Content-Disposition']
_, params = content_disposition.split(';')
downloaded_filename = params.split('=')[1].strip(' "').split("utf-8''")[1]

# Check if the downloaded filename matches the original filename
self.assertEqual(downloaded_filename, f"{style_name}.zip")


class TestStyleApprovalNotify(TestCase):
fixtures = [
Expand Down
2 changes: 1 addition & 1 deletion qgis-app/styles/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class StyleReviewView(ResourceMixin, ResourceBaseReviewView):


class StyleDownloadView(ResourceMixin, ResourceBaseDownload):
"""Download a GeoPackage"""
"""Download a style"""


def style_nav_content(request):
Expand Down

0 comments on commit a881607

Please sign in to comment.