Skip to content

Commit

Permalink
Add a simple CSV export
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiask committed Aug 26, 2024
1 parent 5e58e72 commit 7eb10ae
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
5 changes: 5 additions & 0 deletions app/templates/projects/project.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ <h2>{% translate 'catalogs'|capfirst %}</h2>
{% endfor %}
</ul>

<h2>{% translate 'Export' %}</h2>
<p>
<a href="{% url 'projects:messages_csv' slug=project.slug %}">{% translate 'Export messages as CSV' %}</a>
</p>

<h2>{% translate 'users'|capfirst %}</h2>
<p>
{% for user in project.all_users %}<a href="mailto:{{ user.email }}">{{ user.get_full_name }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}
Expand Down
65 changes: 65 additions & 0 deletions projects/foreign.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from collections import defaultdict
from itertools import chain


def msg_key(entry):
return (entry.msgid, entry.msgid_plural, entry.msgctxt)


def merge_catalogs(project):
"""
Return a nested dictionary of the form:
``messages[msg_key][language, domain] = entry``
"""

messages = defaultdict(dict)

for catalog in project.catalogs.all():
for entry in catalog.po:
messages[msg_key(entry)][catalog.language_code, catalog.domain] = entry

return messages


def messages_as_table(project):
merged = merge_catalogs(project)
language_domain_combinations = sorted(
set(chain.from_iterable(thing.keys() for thing in merged.values()))
)

header = [
"msgctxt",
"msgid",
"msgid_plural",
"comment",
"tcomment",
"flags",
*(
f"{language_code}:{domain}"
for language_code, domain in language_domain_combinations
),
]
data = []

for entries in merged.values():
any_entry = next(iter(entries.values()))

row = [
any_entry.msgctxt,
any_entry.msgid,
any_entry.msgid_plural,
any_entry.comment,
any_entry.tcomment,
", ".join(any_entry.flags),
]

for language_code_domain in language_domain_combinations:
if entry := entries.get(language_code_domain):
row.append(entry.msgstr)
else:
row.append("")

data.append(row)

return [header, *data]
3 changes: 3 additions & 0 deletions projects/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ def test_project_access(self):
r = su_client.get("/traduire.toml")
self.assertContains(r, f'token = "{superuser.token}"')

r = su_client.get("/test/messages.csv")
self.assertContains(r, ",Continue,")

r = u_client.get(p.get_absolute_url(), headers={"accept-language": "en"})
self.assertEqual(r.status_code, 404)

Expand Down
1 change: 1 addition & 0 deletions projects/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@
views.traduire_toml,
name="traduire_toml",
),
path("<slug:slug>/messages.csv", views.messages_csv, name="messages_csv"),
]
14 changes: 14 additions & 0 deletions projects/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import csv

import polib
from django import http
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from django.template.defaulttags import querystring
from django.views.decorators.csrf import csrf_exempt
Expand All @@ -10,6 +13,7 @@
from accounts.models import User
from form_rendering import adapt_rendering
from projects import translators
from projects.foreign import messages_as_table
from projects.forms import EntriesForm, FilterForm, SuggestForm
from projects.models import Catalog, Event, Project

Expand Down Expand Up @@ -211,3 +215,13 @@ def traduire_toml(request):
for project in Project.objects.for_user(request.user)
)
return http.HttpResponse(toml, content_type="text/plain; charset=utf-8")


@login_required
def messages_csv(request, slug):
project = get_object_or_404(Project.objects.for_user(request.user), slug=slug)

response = HttpResponse(content_type="text/csv")
csv.writer(response).writerows(messages_as_table(project))

return response

2 comments on commit 7eb10ae

@nada
Copy link

@nada nada commented on 7eb10ae Aug 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merci!

@matthiask
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nada msgstr_plural fehlt noch, aber wir brauchen ngettext() im entsprechenden Projekt nicht (aber in anderen Projekten schon...!)

poxls ignoriert die *_plural Varianten aber auch. D.h. ist kein Rückschritt, abgesehen vom fehlenden Import.

Please sign in to comment.