Skip to content
Snippets Groups Projects
Verified Commit e587e5ae authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch 'master' into develop

parents 9a162c57 78734a86
No related branches found
Tags 0.18.3
No related merge requests found
Showing
with 90 additions and 355 deletions
......@@ -10,6 +10,57 @@ This changelog is viewable on the web at https://docs.funkwhale.audio/changelog.
.. towncrier
0.18.3 (2019-03-21)
-------------------
Upgrade instructions are available at
https://docs.funkwhale.audio/index.html
Avoid mixed content when deploying mono-container behind proxy [Manual action required]
---------------------------------------------------------------------------------------
*You are only concerned if you use the mono-container docker deployment behind a reverse proxy*
Because of `an issue in our mono-container configuration <https://github.com/thetarkus/docker-funkwhale/issues/19>`_, users deploying Funkwhale via docker
using our `funkwhale/all-in-one` image could face some mixed content warnings (and possibly other troubles)
when browsing the Web UI.
This is fixed in this release, but on existing deployments, you'll need to add ``NESTED_PROXY=1`` in your container
environment (either in your ``.env`` file, or via your container management tool), then recreate your funkwhale container.
Enhancements:
- Added title on hover for truncated content (#766)
- Ask for confirmation before leaving upload page if there is a an upload in process (#630)
- Exclude in-place imported files from quota computation (#570)
- Truncate filename in library file table to ensure correct display of the table. (#735)
Bugfixes:
- Avoid mixed content when deploying mono-container behind HTTPS proxy (thetarkus/docker-funkwhale#19)
- Display new notifications immediatly on notifications page (#729)
- Ensure cover art from uploaded files is picked up properly on existing albums (#757)
- Fixed a crash when federating a track with unspecified position
- Fixed broken Activity and Actor modules in django admin (#767)
- Fixed broken sample apache configuration (#764)
- Fixed constant and unpredictable reordering during file upload (#716)
- Fixed delivering of local activities causing unintended side effects, such as rollbacking changes (#737)
- Fixed escaping issues in translated strings (#652)
- Fixed saving moderation policy when clicking on "Cancel" (#751)
- i18n: Update page title when changing the App's language. (#511)
- Include disc number in Subsonic responses (#765)
- Do not send notification when rejecting a follow on a local library (#743)
Documentation:
- Added documentation on mono-container docker upgrade (#713)
- Added documentation to set up let's encrypt certificate (#745)
0.18.2 (2019-02-13)
-------------------
......
......@@ -358,343 +358,6 @@ Internationalization
--------------------
We're using https://github.com/Polyconseil/vue-gettext to manage i18n in the project.
<<<<<<< HEAD
When working on the front-end, any end-user string should be marked as a translatable string,
with the proper context, as described below.
Translations in HTML
^^^^^^^^^^^^^^^^^^^^
Translations in HTML use the ``<translate>`` tag::
<template>
<div>
<h1><translate translate-context="Content/Profile/Header">User profile</translate></h1>
<p>
<translate
translate-context="Content/Profile/Paragraph"
:translate-params="{username: 'alice'}">
You are logged in as %{ username }
</translate>
</p>
<p>
<translate
translate-context="Content/Profile/Paragraph"
translate-plural="You have %{ count } new messages, that's a lot!"
:translate-n="unreadMessagesCount"
:translate-params="{count: unreadMessagesCount}">
You have 1 new message
</translate>
</p>
</div>
</template>
Anything between the `<translate>` and `</translate>` delimiters will be considered as a translatable string.
You can use variables in the translated string via the ``:translate-params="{var: 'value'}"`` directive, and reference them like this:
``val value is %{ value }``.
For pluralization, you need to use ``translate-params`` in conjunction with ``translate-plural`` and ``translate-n``:
- ``translate-params`` should contain the variable you're using for pluralization (which is usually shown to the user)
- ``translate-n`` should match the same variable
- The ``<translate>`` delimiters contain the non-pluralized version of your string
- The ``translate-plural`` directive contains the pluralized version of your string
Translations in javascript
^^^^^^^^^^^^^^^^^^^^^^^^^^
Translations in javascript work by calling the ``this.$*gettext`` functions::
export default {
computed: {
strings () {
let tracksCount = 42
let playButton = this.$pgettext('Sidebar/Player/Button/Verb, Short', 'Play')
let loginMessage = this.$pgettext('*/Login/Message', 'Welcome back %{ username }')
let addedMessage = this.$npgettext('*/Player/Message', 'One track was queued', '%{ count } tracks were queued', tracksCount)
console.log(this.$gettextInterpolate(addedMessage, {count: tracksCount}))
console.log(this.$gettextInterpolate(loginMessage, {username: 'alice'}))
}
}
}
The first argument of the ``$pgettext`` and ``$npgettext`` functions is the string context.
Contextualization
^^^^^^^^^^^^^^^^^
Translation contexts provided via the ``translate-context`` directive and the ``$pgettext`` and ``$npgettext`` are never shown to end users
but visible by Funkwhale translators. They help translators where and how the strings are used,
especially with short or ambiguous strings, like ``May``, which can refer a month or a verb.
While we could in theory use free form context, like ``This string is inside a button, in the main page, and is a call to action``,
Funkwhale use a hierarchical structure to write contexts and keep them short and consistents accross the app. The previous context,
rewritten correctly would be: ``Content/Home/Button/Call to action``.
This hierarchical structure is made of several parts:
- The location part, which is required and refers to the big blocks found in Funkwhale UI where the translated string is displayed:
- ``Content``
- ``Footer``
- ``Head``
- ``Menu``
- ``Popup``
- ``Sidebar``
- ``*`` for strings that are not tied to a specific location
- The feature part, which is required, and refers to the feature associated with the translated string:
- ``About``
- ``Admin``
- ``Album``
- ``Artist``
- ``Embed``
- ``Home``
- ``Login``
- ``Library``
- ``Moderation``
- ``Player``
- ``Playlist``
- ``Profile``
- ``Favorites``
- ``Notifications``
- ``Radio``
- ``Search``
- ``Settings``
- ``Signup``
- ``Track``
- ``Queue``
- ``*`` for strings that are not tied to a specific feature
- The component part, which is required and refers to the type of element that contain the string:
- ``Button``
- ``Card``
- ``Checkbox``
- ``Dropdown``
- ``Error message``
- ``Form``
- ``Header``
- ``Help text``
- ``Hidden text``
- ``Icon``
- ``Input``
- ``Image``
- ``Label``
- ``Link``
- ``List item``
- ``Menu``
- ``Message``
- ``Paragraph``
- ``Placeholder``
- ``Tab``
- ``Table``
- ``Title``
- ``Tooltip``
- ``*`` for strings that are not tied to a specific component
The detail part, which is optional and refers to the contents of the string itself, such as:
- ``Adjective``
- ``Call to action``
- ``Noun``
- ``Short``
- ``Unit``
- ``Verb``
Here are a few examples of valid context hierarchies:
- ``Sidebar/Player/Button``
- ``Content/Home/Button/Call to action``
- ``Footer/*/Help text``
- ``*/*/*/Verb, Short``
- ``Popup/Playlist/Button``
- ``Content/Admin/Table.Label/Short, Noun (Value is a date)``
It's possible to nest multiple component parts to reach a higher level of detail. The component parts are then separated by a dot:
- ``Sidebar/Queue/Tab.Title``
- ``Content/*/Button.Title``
- ``Content/*/Table.Header``
- ``Footer/*/List item.Link``
- ``Content/*/Form.Help text``
Collecting translatable strings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you want to ensure your translatable strings are correctly marked for translation,
you can try to extract them.
||||||| merged common ancestors
When working on the front-end, any end-user string should be translated
using either ``<translate>yourstring</translate>`` or ``$gettext('yourstring')``
function.
=======
<<<<<<< HEAD
When working on the front-end, any end-user string should be translated
using either ``<translate>yourstring</translate>`` or ``$gettext('yourstring')``
function.
||||||| parent of 21fb39dd... Update docs/developers/index.rst, docs/developers/subsonic.rst files
When working on the front-end, any end-user string should be marked as a translatable string,
with the proper context, as described below.
Translations in HTML
^^^^^^^^^^^^^^^^^^^^
Translations in HTML use the ``<translate>`` tag::
<template>
<div>
<h1><translate translate-context="Content/Profile/Header">User profile</translate></h1>
<p>
<translate
translate-context="Content/Profile/Paragraph"
:translate-params="{username: 'alice'}">
You are logged in as %{ username }
</translate>
</p>
<p>
<translate
translate-context="Content/Profile/Paragraph"
translate-plural="You have %{ count } new messages, that's a lot!"
:translate-n="unreadMessagesCount"
:translate-params="{count: unreadMessagesCount}">
You have 1 new message
</translate>
</p>
</div>
</template>
Anything between the `<translate>` and `</translate>` delimiters will be considered as a translatable string.
You can use variables in the translated string via the ``:translate-params="{var: 'value'}"`` directive, and reference them like this:
``val value is %{ value }``.
For pluralization, you need to use ``translate-params`` in conjunction with ``translate-plural`` and ``translate-n``:
- ``translate-params`` should contain the variable you're using for pluralization (which is usually shown to the user)
- ``translate-n`` should match the same variable
- The ``<translate>`` delimiters contain the non-pluralized version of your string
- The ``translate-plural`` directive contains the pluralized version of your string
Translations in javascript
^^^^^^^^^^^^^^^^^^^^^^^^^^
Translations in javascript work by calling the ``this.$*gettext`` functions::
export default {
computed: {
strings () {
let tracksCount = 42
let playButton = this.$pgettext('Sidebar/Player/Button/Verb, Short', 'Play')
let loginMessage = this.$pgettext('*/Login/Message', 'Welcome back %{ username }')
let addedMessage = this.$npgettext('*/Player/Message', 'One track was queued', '%{ count } tracks were queued', tracksCount)
console.log(this.$gettextInterpolate(addedMessage, {count: tracksCount}))
console.log(this.$gettextInterpolate(loginMessage, {username: 'alice'}))
}
}
}
The first argument of the ``$pgettext`` and ``$npgettext`` functions is the string context.
Contextualization
^^^^^^^^^^^^^^^^^
Translation contexts provided via the ``translate-context`` directive and the ``$pgettext`` and ``$npgettext`` are never shown to end users
but visible by Funkwhale translators. They help translators where and how the strings are used,
especially with short or ambiguous strings, like ``May``, which can refer a month or a verb.
While we could in theory use free form context, like ``This string is inside a button, in the main page, and is a call to action``,
Funkwhale use a hierarchical structure to write contexts and keep them short and consistents accross the app. The previous context,
rewritten correctly would be: ``Content/Home/Button/Call to action``.
This hierarchical structure is made of several parts:
- The location part, which is required and refers to the big blocks found in Funkwhale UI where the translated string is displayed:
- ``Content``
- ``Footer``
- ``Head``
- ``Menu``
- ``Popup``
- ``Sidebar``
- ``*`` for strings that are not tied to a specific location
- The feature part, which is required, and refers to the feature associated with the translated string:
- ``About``
- ``Admin``
- ``Album``
- ``Artist``
- ``Embed``
- ``Home``
- ``Login``
- ``Library``
- ``Moderation``
- ``Player``
- ``Playlist``
- ``Profile``
- ``Favorites``
- ``Notifications``
- ``Radio``
- ``Search``
- ``Settings``
- ``Signup``
- ``Track``
- ``Queue``
- ``*`` for strings that are not tied to a specific feature
- The component part, which is required and refers to the type of element that contain the string:
- ``Button``
- ``Card``
- ``Checkbox``
- ``Dropdown``
- ``Error message``
- ``Form``
- ``Header``
- ``Help text``
- ``Hidden text``
- ``Icon``
- ``Input``
- ``Image``
- ``Label``
- ``Link``
- ``List item``
- ``Menu``
- ``Message``
- ``Paragraph``
- ``Placeholder``
- ``Tab``
- ``Table``
- ``Title``
- ``Tooltip``
- ``*`` for strings that are not tied to a specific component
The detail part, which is optional and refers to the contents of the string itself, such as:
- ``Adjective``
- ``Call to action``
- ``Noun``
- ``Short``
- ``Unit``
- ``Verb``
Here are a few examples of valid context hierarchies:
- ``Sidebar/Player/Button``
- ``Content/Home/Button/Call to action``
- ``Footer/*/Help text``
- ``*/*/*/Verb, Short``
- ``Popup/Playlist/Button``
- ``Content/Admin/Table.Label/Short, Noun (Value is a date)``
It's possible to nest multiple component parts to reach a higher level of detail. The component parts are then separated by a dot:
- ``Sidebar/Queue/Tab.Title``
- ``Content/*/Button.Title``
- ``Content/*/Table.Header``
- ``Footer/*/List item.Link``
- ``Content/*/Form.Help text``
Collecting translatable strings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you want to ensure your translatable strings are correctly marked for translation,
you can try to extract them.
When working on the front-end, any end-user string should be marked as a translatable string,
with the proper context, as described below.
......
# -*- coding: utf-8 -*-
__version__ = "0.18.2"
__version__ = "0.18.3"
__version_info__ = tuple(
[
int(num) if num.isdigit() else num
......
......@@ -5,12 +5,25 @@ from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
from django.db import models, transaction
from django.db.models import Lookup
from django.db.models.fields import Field
from django.utils import timezone
from django.urls import reverse
from funkwhale_api.federation import utils as federation_utils
@Field.register_lookup
class NotEqual(Lookup):
lookup_name = "ne"
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return "%s <> %s" % (lhs, rhs), params
class LocalFromFidQuerySet:
def local(self, include=True):
host = settings.FEDERATION_HOSTNAME
......
......@@ -53,11 +53,15 @@ class ActorQuerySet(models.QuerySet):
def with_current_usage(self):
qs = self
for s in ["pending", "skipped", "errored", "finished"]:
uploads_query = models.Q(
libraries__uploads__import_status=s,
libraries__uploads__audio_file__isnull=False,
libraries__uploads__audio_file__ne="",
)
qs = qs.annotate(
**{
"_usage_{}".format(s): models.Sum(
"libraries__uploads__size",
filter=models.Q(libraries__uploads__import_status=s),
"libraries__uploads__size", filter=uploads_query
)
}
)
......
......@@ -53,7 +53,25 @@ def test_actor_get_quota(factories):
audio_file__from_path=None,
audio_file__data=b"aaaa",
)
expected = {"total": 10, "pending": 1, "skipped": 2, "errored": 3, "finished": 4}
# this one is imported in place and don't count
factories["music.Upload"](
library=library,
import_status="finished",
source="file://test",
audio_file=None,
size=42,
)
# this one is imported in place but count because there is a mapped file
factories["music.Upload"](
library=library,
import_status="finished",
source="file://test2",
audio_file__from_path=None,
audio_file__data=b"aaaa",
)
expected = {"total": 14, "pending": 1, "skipped": 2, "errored": 3, "finished": 8}
assert library.actor.get_current_usage() == expected
......
i18n: Update page title when changing the App's language. (#511)
Ask for confirmation before leaving upload page if there is a an upload in process (#630)
\ No newline at end of file
Fixed escaping issues in translated strings (#652)
Added documentation on mono-container docker upgrade (#713)
Fixed constant and unpredictable reordering during file upload (#716)
Display new notifications immediatly on notifications page (#729)
Truncate filename in library file table to ensure correct display of the table. (#735)
Fixed delivering of local activities causing unintended side effects, such as rollbacking changes (#737)
Do not send notification when rejecting a follow on a local library (#743)
Added documentation to set up let's encrypt certificate (#745)
Fixed saving moderation policy when clicking on "Cancel" (#751)
Ensure cover art from uploaded files is picked up properly on existing albums (#757)
Fixed broken sample apache configuration (#764)
Include disc number in Subsonic responses (#765)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment