Commit 0b4da71c authored by Weblate's avatar Weblate

Merge remote-tracking branch 'origin/master'

parents 54747c90 fdba5971
...@@ -248,6 +248,8 @@ Projects ...@@ -248,6 +248,8 @@ Projects
:>json string slug: project slug :>json string slug: project slug
:>json object source_language: source language object, see :http:get:`/api/languages/(string:language)/` :>json object source_language: source language object, see :http:get:`/api/languages/(string:language)/`
:>json string web: project website :>json string web: project website
:>json string components_list_url: URL to components list, see :http:get:`/api/projects/(string:project)/components/`
:>json string repository_url: URL to repository status, see :http:get:`/api/projects/(string:project)/repository/`
.. seealso:: .. seealso::
...@@ -398,6 +400,9 @@ Components ...@@ -398,6 +400,9 @@ Components
:>json string template: base file for monolingual translations :>json string template: base file for monolingual translations
:>json string new_base: base file for adding new translations :>json string new_base: base file for adding new translations
:>json string vcs: version control system :>json string vcs: version control system
:>json string repository_url: URL to repository status, see :http:get:`/api/components/(string:project)/(string:component)/repository/`
:>json string translations_url: URL to translations list, see :http:get:`/api/components/(string:project)/(string:component)/translations/`
:>json string lock_url: URL to lock statuc, see :http:get:`/api/components/(string:project)/(string:component)/lock/`
.. seealso:: .. seealso::
...@@ -598,6 +603,8 @@ Translations ...@@ -598,6 +603,8 @@ Translations
:>json int translated: number of translated units :>json int translated: number of translated units
:>json float translated_percent: percentage of translated units :>json float translated_percent: percentage of translated units
:>json int translated_words: number of translated words :>json int translated_words: number of translated words
:>json string repository_url: URL to repository status, see :http:get:`/api/translations/(string:project)/(string:component)/(string:language)/repository/`
:>json string file_url: URL to file object, see :http:get:`/api/translations/(string:project)/(string:component)/(string:language)/file/`
.. seealso:: .. seealso::
......
...@@ -79,23 +79,44 @@ class LanguageSerializer(serializers.ModelSerializer): ...@@ -79,23 +79,44 @@ class LanguageSerializer(serializers.ModelSerializer):
class ProjectSerializer(serializers.ModelSerializer): class ProjectSerializer(serializers.ModelSerializer):
web_url = serializers.CharField(source='get_absolute_url', read_only=True) web_url = serializers.CharField(source='get_absolute_url', read_only=True)
source_language = LanguageSerializer(read_only=True) source_language = LanguageSerializer(read_only=True)
components_list_url = serializers.HyperlinkedIdentityField(
view_name='api:project-components',
lookup_field='slug',
)
repository_url = serializers.HyperlinkedIdentityField(
view_name='api:project-repository',
lookup_field='slug',
)
class Meta(object): class Meta(object):
model = Project model = Project
fields = ( fields = (
'name', 'slug', 'web', 'source_language', 'web_url', 'url', 'name', 'slug', 'web', 'source_language', 'web_url', 'url',
'components_list_url', 'repository_url',
) )
extra_kwargs = { extra_kwargs = {
'url': { 'url': {
'view_name': 'api:project-detail', 'view_name': 'api:project-detail',
'lookup_field': 'slug' 'lookup_field': 'slug'
} },
} }
class ComponentSerializer(RemovableSerializer): class ComponentSerializer(RemovableSerializer):
web_url = serializers.CharField(source='get_absolute_url', read_only=True) web_url = serializers.CharField(source='get_absolute_url', read_only=True)
project = ProjectSerializer(read_only=True) project = ProjectSerializer(read_only=True)
repository_url = MultiFieldHyperlinkedIdentityField(
view_name='api:component-repository',
lookup_field=('project__slug', 'slug'),
)
translations_url = MultiFieldHyperlinkedIdentityField(
view_name='api:component-translations',
lookup_field=('project__slug', 'slug'),
)
lock_url = MultiFieldHyperlinkedIdentityField(
view_name='api:component-lock',
lookup_field=('project__slug', 'slug'),
)
serializer_url_field = MultiFieldHyperlinkedIdentityField serializer_url_field = MultiFieldHyperlinkedIdentityField
...@@ -105,6 +126,8 @@ class ComponentSerializer(RemovableSerializer): ...@@ -105,6 +126,8 @@ class ComponentSerializer(RemovableSerializer):
'name', 'slug', 'project', 'vcs', 'repo', 'git_export', 'name', 'slug', 'project', 'vcs', 'repo', 'git_export',
'branch', 'filemask', 'template', 'new_base', 'file_format', 'branch', 'filemask', 'template', 'new_base', 'file_format',
'license', 'license_url', 'web_url', 'url', 'license', 'license_url', 'web_url', 'url',
'repository_url', 'translations_url',
'lock_url',
) )
extra_kwargs = { extra_kwargs = {
'url': { 'url': {
...@@ -145,6 +168,22 @@ class TranslationSerializer(RemovableSerializer): ...@@ -145,6 +168,22 @@ class TranslationSerializer(RemovableSerializer):
last_author = serializers.CharField( last_author = serializers.CharField(
source='get_last_author', read_only=True, source='get_last_author', read_only=True,
) )
repository_url = MultiFieldHyperlinkedIdentityField(
view_name='api:translation-repository',
lookup_field=(
'subproject__project__slug',
'subproject__slug',
'language__code',
),
)
file_url = MultiFieldHyperlinkedIdentityField(
view_name='api:translation-file',
lookup_field=(
'subproject__project__slug',
'subproject__slug',
'language__code',
),
)
serializer_url_field = MultiFieldHyperlinkedIdentityField serializer_url_field = MultiFieldHyperlinkedIdentityField
...@@ -162,6 +201,7 @@ class TranslationSerializer(RemovableSerializer): ...@@ -162,6 +201,7 @@ class TranslationSerializer(RemovableSerializer):
'fuzzy', 'fuzzy_percent', 'fuzzy', 'fuzzy_percent',
'failing_checks_percent', 'failing_checks_percent',
'last_change', 'last_author', 'last_change', 'last_author',
'repository_url', 'file_url',
) )
extra_kwargs = { extra_kwargs = {
'url': { 'url': {
......
...@@ -23,10 +23,12 @@ import os.path ...@@ -23,10 +23,12 @@ import os.path
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.utils.encoding import smart_text
from rest_framework import parsers, viewsets from rest_framework import parsers, viewsets
from rest_framework.decorators import detail_route from rest_framework.decorators import detail_route
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.utils import formatting
from weblate.api.serializers import ( from weblate.api.serializers import (
ProjectSerializer, ComponentSerializer, TranslationSerializer, ProjectSerializer, ComponentSerializer, TranslationSerializer,
...@@ -42,6 +44,7 @@ from weblate.trans.permissions import ( ...@@ -42,6 +44,7 @@ from weblate.trans.permissions import (
) )
from weblate.lang.models import Language from weblate.lang.models import Language
from weblate.trans.views.helper import download_translation_file from weblate.trans.views.helper import download_translation_file
from weblate import get_doc_url
OPERATIONS = { OPERATIONS = {
'push': (can_push_translation, 'do_push'), 'push': (can_push_translation, 'do_push'),
...@@ -50,6 +53,40 @@ OPERATIONS = { ...@@ -50,6 +53,40 @@ OPERATIONS = {
'commit': (can_commit_translation, 'commit_pending'), 'commit': (can_commit_translation, 'commit_pending'),
} }
DOC_TEXT = """
See <a href="{0}">the Weblate's Web API documentation</a> for detailed description of the API.
"""
def get_view_description(view_cls, html=False):
"""
Given a view class, return a textual description to represent the view.
This name is used in the browsable API, and in OPTIONS responses.
This function is the default for the `VIEW_DESCRIPTION_FUNCTION` setting.
"""
description = view_cls.__doc__ or ''
description = formatting.dedent(smart_text(description))
if hasattr(view_cls, 'serializer_class'):
doc_url = get_doc_url(
'api'
'{0}s'.format(
view_cls.serializer_class.Meta.model.__name__.lower()
)
)
else:
doc_url = get_doc_url('api')
description = '\n\n'.join((
description,
DOC_TEXT.format(doc_url)
))
if html:
return formatting.markup_description(description)
return description
class MultipleFieldMixin(object): class MultipleFieldMixin(object):
""" """
...@@ -137,6 +174,7 @@ class WeblateViewSet(viewsets.ReadOnlyModelViewSet): ...@@ -137,6 +174,7 @@ class WeblateViewSet(viewsets.ReadOnlyModelViewSet):
class ProjectViewSet(WeblateViewSet): class ProjectViewSet(WeblateViewSet):
"""Translation projects API. """Translation projects API.
""" """
queryset = Project.objects.none() queryset = Project.objects.none()
serializer_class = ProjectSerializer serializer_class = ProjectSerializer
lookup_field = 'slug' lookup_field = 'slug'
......
...@@ -579,6 +579,7 @@ REST_FRAMEWORK = { ...@@ -579,6 +579,7 @@ REST_FRAMEWORK = {
'rest_framework.pagination.PageNumberPagination' 'rest_framework.pagination.PageNumberPagination'
), ),
'PAGE_SIZE': 20, 'PAGE_SIZE': 20,
'VIEW_DESCRIPTION_FUNCTION': 'weblate.api.views.get_view_description',
} }
# Example for restricting access to logged in users # Example for restricting access to logged in users
......
Markdown is supported
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