Commit ca468826 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch '930-i18n-fixes' into 'develop'

Resolve "i18n fixes for 0.20"

Closes #930

See merge request funkwhale/funkwhale!912
parents 6cee5463 2cdc8fa6
......@@ -4,7 +4,7 @@ locales_dir="locales"
sources=$(find src -name '*.vue' -o -name '*.html' 2> /dev/null)
js_sources=$(find src -name '*.vue' -o -name '*.js')
touch $locales_dir/app.pot
GENERATE=${GENERATE-true}
# Create a main .pot template, then generate .po files for each available language.
# Extract gettext strings from templates files and create a POT dictionary template.
$(yarn bin)/gettext-extract --attribute v-translate --quiet --output $locales_dir/app.pot $sources
......@@ -18,12 +18,14 @@ xgettext --language=JavaScript --keyword=npgettext:1c,2,3 \
# Fix broken files path/lines in pot
sed -e 's|#: src/|#: front/src/|' -i $locales_dir/app.pot
# Generate .po files for each available language.
echo $locales
for lang in $locales; do \
po_file=$locales_dir/$lang/LC_MESSAGES/app.po; \
echo "msgmerge --update $po_file "; \
mkdir -p $(dirname $po_file); \
[ -f $po_file ] && msgmerge --lang=$lang --update $po_file $locales_dir/app.pot --no-wrap || msginit --no-wrap --no-translator --locale=$lang --input=$locales_dir/app.pot --output-file=$po_file; \
msgattrib --no-wrap --no-obsolete -o $po_file $po_file; \
done;
if [ $GENERATE = 'true' ]; then
# Generate .po files for each available language.
echo $locales
for lang in $locales; do \
po_file=$locales_dir/$lang/LC_MESSAGES/app.po; \
echo "msgmerge --update $po_file "; \
mkdir -p $(dirname $po_file); \
[ -f $po_file ] && msgmerge --lang=$lang --update $po_file $locales_dir/app.pot --no-wrap || msginit --no-wrap --no-translator --locale=$lang --input=$locales_dir/app.pot --output-file=$po_file; \
msgattrib --no-wrap --no-obsolete -o $po_file $po_file; \
done;
fi
import argparse
import collections
import polib
def print_duplicates(path):
pofile = polib.pofile(path)
contexts_by_id = collections.defaultdict(list)
for e in pofile:
contexts_by_id[e.msgid].append(e.msgctxt)
count = collections.Counter(
[e.msgid for e in pofile]
)
duplicates = [
(k, v) for k, v in count.items()
if v > 1
]
for k, v in sorted(duplicates, key=lambda r: r[1], reverse=True):
print('{} entries - {}:'.format(v, k))
for ctx in contexts_by_id[k]:
print(' - {}'.format(ctx))
print()
total_duplicates = sum([v - 1 for _, v in duplicates])
print('{} total duplicates'.format(total_duplicates))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("po", help="Path of the po file to use as a source")
args = parser.parse_args()
print_duplicates(path=args.po)
......@@ -83,7 +83,7 @@
<div class="ui stackable grid">
<div class="four wide column">
<h3 class="header">
<translate translate-context="Content/Home/Header">About Funkwhale</translate>
<translate translate-context="Footer/*/Title/Short">About Funkwhale</translate>
</h3>
<p v-translate translate-context="Content/Home/Paragraph">This pod runs Funkwhale, a community-driven project that lets you listen and share music and audio within a decentralized, open network.</p>
<p v-translate translate-context="Content/Home/Paragraph">Funkwhale is free and developped by a friendly community of volunteers.</p>
......
......@@ -36,7 +36,7 @@
</div>
</section>
<footer class="actions">
<div class="ui cancel button"><translate translate-context="Popup/Keyboard shortcuts/Button.Label/Verb">Close</translate></div>
<div class="ui cancel button"><translate translate-context="*/*/Button.Label/Verb">Close</translate></div>
</footer>
</modal>
</template>
......
......@@ -83,7 +83,7 @@
v-if="$store.state.auth.availablePermissions['library']"
class="item"
:to="{name: 'manage.library.edits', query: {q: 'is_approved:null'}}">
<i class="book icon"></i><translate translate-context="*/*/*">Library</translate>
<i class="book icon"></i><translate translate-context="*/*/*/Noun">Library</translate>
<div
v-if="$store.state.ui.notifications.pendingReviewEdits > 0"
:title="labels.pendingReviewEdits"
......
......@@ -3,7 +3,7 @@
<div class="ui divider" />
<h3 class="ui header">{{ group.label }}</h3>
<div v-if="errors.length > 0" class="ui negative message">
<div class="header"><translate translate-context="Content/Settings/Error message.Title">Error while saving settings</translate></div>
<div class="header"><translate translate-context="Content/*/Error message.Title">Error while saving settings</translate></div>
<ul class="list">
<li v-for="error in errors">{{ error }}</li>
</ul>
......
......@@ -97,7 +97,7 @@ export default {
},
title () {
if (this.playable) {
return this.$pgettext('*/Queue/Button/Title', 'More…')
return this.$pgettext('*/*/Button.Label/Noun', 'More…')
} else {
if (this.track) {
return this.$pgettext('*/Queue/Button/Title', 'This track is not available in any library you have access to')
......
......@@ -39,7 +39,7 @@
<translate translate-context="Content/Album/Card.Link/Verb" :translate-params="{count: album.tracks.length - initialTracks}" :translate-n="album.tracks.length - initialTracks" translate-plural="Show %{ count } more tracks">Show %{ count } more track</translate>
</em>
<em v-else @click="showAllTracks = false" class="expand">
<translate translate-context="Content/*/Card.Link/Verb">Collapse</translate>
<translate translate-context="*/*/Button,Label">Collapse</translate>
</em>
</div>
</div>
......
......@@ -5,7 +5,7 @@
<tr>
<th></th>
<th></th>
<th colspan="6"><translate translate-context="Content/Track/*/Noun">Title</translate></th>
<th colspan="6"><translate translate-context="*/*/*/Noun">Title</translate></th>
<th colspan="4"><translate translate-context="*/*/*/Noun">Artist</translate></th>
<th colspan="4"><translate translate-context="*/*/*">Album</translate></th>
<th colspan="4"><translate translate-context="Content/*/*">Duration</translate></th>
......
......@@ -8,7 +8,7 @@
</ul>
</div>
<div class="ui field">
<label><translate translate-context="Content/Applications/Input.Label/Noun">Name</translate></label>
<label><translate translate-context="*/*/*/Noun">Name</translate></label>
<input name="name" required type="text" v-model="fields.name" />
</div>
<div class="ui field">
......@@ -21,7 +21,7 @@
</p>
</div>
<div class="ui field">
<label><translate translate-context="Content/Applications/Input.Label/Noun">Scopes</translate></label>
<label><translate translate-context="Content/*/*/Noun">Scopes</translate></label>
<p>
<translate translate-context="Content/Applications/Paragraph/">
Checking the parent "Read" or "Write" scopes implies access to all the corresponding children scopes.
......
......@@ -6,7 +6,7 @@
<translate translate-context="Content/Applications/Link">Back to settings</translate>
</router-link>
<h2 class="ui header">
<translate translate-context="Content/Applications/Title">Create a new application</translate>
<translate translate-context="Content/Settings/Button.Label">Create a new application</translate>
</h2>
<application-form
:defaults="defaults"
......@@ -38,7 +38,7 @@ export default {
computed: {
labels() {
return {
title: this.$pgettext('Content/Applications/Title', "Create a new application")
title: this.$pgettext('Content/Settings/Button.Label', "Create a new application")
}
},
}
......
......@@ -30,7 +30,7 @@
</div>
<div class="field">
<label>
<translate translate-context="Content/*/Input.Label">Password</translate> |
<translate translate-context="*/*/*">Password</translate> |
<router-link :to="{name: 'auth.password-reset', query: {email: credentials.username}}">
<translate translate-context="*/Login/*/Verb">Reset your password</translate>
</router-link>
......
......@@ -244,7 +244,7 @@
</td>
<td>
<router-link class="ui basic tiny green button" :to="{name: 'settings.applications.edit', params: {id: app.client_id}}">
<translate translate-context="Content/Settings/Button.Label">Edit</translate>
<translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
</router-link>
<dangerous-button
class="ui tiny basic button"
......@@ -272,7 +272,7 @@
<h2 class="ui header">
<i class="trash icon"></i>
<div class="content">
<translate translate-context="Content/Settings/Title/Verb">Delete my account</translate>
<translate translate-context="*/*/Button.Label">Delete my account</translate>
</div>
</h2>
<p>
......@@ -300,7 +300,7 @@
<div slot="modal-content">
<p><translate translate-context="Popup/Settings/Paragraph">This is irreversible and will permanently remove your data from our servers. You will we immediatly logged out.</translate></p>
</div>
<div slot="modal-confirm"><translate translate-context="Popup/Settings/Button.Label">Delete my account</translate></div>
<div slot="modal-confirm"><translate translate-context="*/*/Button.Label">Delete my account</translate></div>
</dangerous-button>
</div>
</section>
......
......@@ -34,7 +34,7 @@
v-model="email">
</div>
<div class="field">
<label><translate translate-context="Content/*/Input.Label">Password</translate></label>
<label><translate translate-context="*/*/*">Password</translate></label>
<password-input v-model="password" />
</div>
<div class="field" v-if="!$store.state.instance.settings.users.registration_enabled.value">
......
......@@ -17,7 +17,7 @@
<template v-else>
<section class="ui vertical stripe segment">
<h2>
<translate translate-context="*/*/*/Noun">Tracks</translate>
<translate translate-context="*/*/*">Tracks</translate>
</h2>
<track-table v-if="object" :artist="object.artist" :display-position="true" :tracks="object.tracks"></track-table>
</section>
......
......@@ -92,8 +92,8 @@
<thead>
<tr>
<th><translate translate-context="Content/Library/Table.Label">Filename</translate></th>
<th><translate translate-context="Content/Library/*/in MB">Size</translate></th>
<th><translate translate-context="Content/Library/Table.Label (Value is Uploading/Uploaded/Error)">Status</translate></th>
<th><translate translate-context="Content/*/*/Noun">Size</translate></th>
<th><translate translate-context="*/*/*">Status</translate></th>
</tr>
</thead>
<tbody>
......
......@@ -44,7 +44,7 @@
</tr>
<tr>
<td>
<translate translate-context="Popup/Import/Table.Label/Noun">Getting help</translate>
<translate translate-context="Footer/*/Link">Getting help</translate>
</td>
<td>
<ul>
......@@ -141,7 +141,7 @@ export default {
let detail = payload.detail || {}
d.errorRows = getErrors(detail)
} else {
d.label = this.$pgettext('Popup/Import/Error.Label', 'Unknown error')
d.label = this.$pgettext('*/*/Error', 'Unknown error')
d.detail = this.$pgettext('Popup/Import/Error.Label', 'An unknown error occurred')
}
let debugInfo = {
......
......@@ -17,7 +17,7 @@
<artist-widget :controls="false" :filters="{playable: true, ordering: '-creation_date', tag: id}">
<template slot="title">
<router-link :to="{name: 'library.artists.browse', query: {tag: id}}">
<translate translate-context="*/*/*">Artists</translate>
<translate translate-context="*/*/*/Noun">Artists</translate>
</router-link>
</template>
</artist-widget>
......
......@@ -9,7 +9,7 @@
<tbody>
<tr>
<td>
<translate translate-context="Content/Track/Table.Label/Noun">Copyright</translate>
<translate translate-context="Content/Track/*/Noun">Copyright</translate>
</td>
<td v-if="track.copyright" :title="track.copyright">{{ track.copyright|truncate(50) }}</td>
<td v-else>
......@@ -38,7 +38,7 @@
</tr>
<tr>
<td>
<translate translate-context="Content/Library/*/in MB">Size</translate>
<translate translate-context="Content/*/*/Noun">Size</translate>
</td>
<td v-if="upload && upload.size">{{ upload.size | humanSize }}</td>
<td v-else>
......
......@@ -23,7 +23,7 @@
<input id="name" name="name" type="text" v-model="radioName" :placeholder="labels.placeholder.name" />
</div>
<div class="field">
<label for="description"><translate translate-context="Content/*/Input.Label/Noun">Description</translate></label>
<label for="description"><translate translate-context="*/*/*/Noun">Description</translate></label>
<textarea rows="2" id="description" type="text" v-model="radioDesc" :placeholder="labels.placeholder.description" />
</div>
<div class="ui toggle checkbox">
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment