From ae036326b62a58c8e99a4ccde84f4155166b8cf3 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 7 Feb 2018 14:41:07 -0500 Subject: [PATCH 01/44] Add raw_log property --- readthedocs/builds/models.py | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/readthedocs/builds/models.py b/readthedocs/builds/models.py index 973097249e1..77ce7f98102 100644 --- a/readthedocs/builds/models.py +++ b/readthedocs/builds/models.py @@ -466,6 +466,44 @@ def finished(self): """Return if build has a finished state.""" return self.state == BUILD_STATE_FINISHED + @property + def raw_log(self): + raw_log_template = '''RTD build information start +Build: {build} +Project: {project} +Version: {version} ({commit}) +Date: {date} +Success: {succes} +RTD build information end +''' + raw_log = raw_log_template.format( + build=self.pk, + project=self.project.slug, + version=self.version.verbose_name, + commit=self.commit, + date=self.date, + succes=self.success, + ) + + command_log_template = '''[rtd-command-info] start-time: {start_time}, end-time: {end_time}, duration: {duration}, exit-code: {exit_code} +{command} +{output} +''' + commands_log = ( + command_log_template.format( + start_time=command.start_time, + end_time=command.end_time, + duration=command.run_time, + exit_code=command.exit_code, + command=command.command, + output=command.output, + ) + for command in self.commands.all() + ) + + raw_log += '\n' + '\n'.join(commands_log) + return raw_log + class BuildCommandResultMixin(object): From fea2137240e627a48f049b6b8115fb1ecca30bfe Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 7 Feb 2018 20:04:37 -0500 Subject: [PATCH 02/44] Move log to separate template --- readthedocs/builds/models.py | 36 ++----------------- readthedocs/restapi/templates/restapi/log.txt | 13 +++++++ 2 files changed, 16 insertions(+), 33 deletions(-) create mode 100644 readthedocs/restapi/templates/restapi/log.txt diff --git a/readthedocs/builds/models.py b/readthedocs/builds/models.py index 77ce7f98102..0069c4cf55b 100644 --- a/readthedocs/builds/models.py +++ b/readthedocs/builds/models.py @@ -10,6 +10,7 @@ from builtins import object from shutil import rmtree +from django.template import loader from django.conf import settings from django.core.urlresolvers import reverse from django.db import models @@ -468,40 +469,9 @@ def finished(self): @property def raw_log(self): - raw_log_template = '''RTD build information start -Build: {build} -Project: {project} -Version: {version} ({commit}) -Date: {date} -Success: {succes} -RTD build information end -''' - raw_log = raw_log_template.format( - build=self.pk, - project=self.project.slug, - version=self.version.verbose_name, - commit=self.commit, - date=self.date, - succes=self.success, + raw_log = loader.get_template('restapi/log.txt').render( + {'build': self} ) - - command_log_template = '''[rtd-command-info] start-time: {start_time}, end-time: {end_time}, duration: {duration}, exit-code: {exit_code} -{command} -{output} -''' - commands_log = ( - command_log_template.format( - start_time=command.start_time, - end_time=command.end_time, - duration=command.run_time, - exit_code=command.exit_code, - command=command.command, - output=command.output, - ) - for command in self.commands.all() - ) - - raw_log += '\n' + '\n'.join(commands_log) return raw_log diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt new file mode 100644 index 00000000000..ffe31709ce6 --- /dev/null +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -0,0 +1,13 @@ +RTD build information start +Build: {{ build.pk }} +Project: {{ build.project.slug }} +Version: {{ build.version.verbose_name }} ({{ build.commit }}) +Date: {{ build.date }} +Success: {{ build.succes }} +RTD build information end + +{% for command in build.commands.all %} +[rtd-command-info] start-time: {{ command.start_time }}, end-time: {{ command.end_time }}, duration: {{ command.run_time }}, exit-code: {{ command.exit_code }} +{{ command.command }} +{{ command.output }} +{% endfor %} From 200b358bf7941bb9172afcba6a76922eb87ee299 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 7 Feb 2018 20:06:19 -0500 Subject: [PATCH 03/44] Add renderer for text/plain media type Taken from http://www.django-rest-framework.org/api-guide/renderers/#setting-the-character-set --- readthedocs/restapi/views/model_views.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index 0daf74409d4..9825f40b3d1 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -10,7 +10,7 @@ from django.shortcuts import get_object_or_404 from rest_framework import decorators, permissions, status, viewsets from rest_framework.decorators import detail_route -from rest_framework.renderers import JSONRenderer +from rest_framework.renderers import JSONRenderer, BaseRenderer from rest_framework.response import Response from readthedocs.builds.constants import BRANCH, TAG @@ -34,6 +34,19 @@ log = logging.getLogger(__name__) +class PlainTextRenderer(BaseRenderer): + """Custom renderer for text/plain format. + + charset is 'utf-8' by default. + """ + + media_type = 'text/plain' + format = 'txt' + + def render(self, data, media_type=None, renderer_context=None): + return data.encode(self.charset) + + class UserSelectViewSet(viewsets.ModelViewSet): """ From a7cfd4580c4ca77d02d44f3643b3221e27dc3f08 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 7 Feb 2018 20:07:27 -0500 Subject: [PATCH 04/44] Add endpoint /log for getting raw log --- readthedocs/restapi/views/model_views.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index 9825f40b3d1..f94e2d26694 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -231,6 +231,11 @@ class BuildViewSetBase(UserSelectViewSet): admin_serializer_class = BuildAdminSerializer model = Build + @detail_route(renderer_classes=[PlainTextRenderer]) + def log(self, request, *args, **kwargs): + build = self.get_object() + return Response(build.raw_log) + class BuildViewSet(SettingsOverrideObject): From 717d70ea37758e989b2210e2a72bafe3e2d22bfe Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 7 Feb 2018 20:13:11 -0500 Subject: [PATCH 05/44] Add suggestion for raw log link --- readthedocs/templates/builds/build_detail.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/readthedocs/templates/builds/build_detail.html b/readthedocs/templates/builds/build_detail.html index 9b07479a795..430f087ea81 100644 --- a/readthedocs/templates/builds/build_detail.html +++ b/readthedocs/templates/builds/build_detail.html @@ -61,6 +61,14 @@ + +
From a414abb015eca59a544cb7916dc22f584d2f788f Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 7 Feb 2018 20:28:10 -0500 Subject: [PATCH 06/44] Fix linter issue --- readthedocs/restapi/views/model_views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index f94e2d26694..0b02535475f 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -35,7 +35,9 @@ class PlainTextRenderer(BaseRenderer): - """Custom renderer for text/plain format. + + """ + Custom renderer for text/plain format. charset is 'utf-8' by default. """ From 8b6e2662554af3e5ed0f23031fab4606f1de24f4 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 7 Feb 2018 20:36:45 -0500 Subject: [PATCH 07/44] Linter --- readthedocs/restapi/views/model_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index 0b02535475f..72fac4af4e0 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -45,7 +45,7 @@ class PlainTextRenderer(BaseRenderer): media_type = 'text/plain' format = 'txt' - def render(self, data, media_type=None, renderer_context=None): + def render(self, data, accepted_media_type=None, renderer_context=None): return data.encode(self.charset) From 33af7f257907aa16c84a933f3111daa198e5bf16 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 9 Feb 2018 21:46:40 -0500 Subject: [PATCH 08/44] Fix typo --- readthedocs/restapi/templates/restapi/log.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt index ffe31709ce6..0abe0aad9e5 100644 --- a/readthedocs/restapi/templates/restapi/log.txt +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -3,7 +3,7 @@ Build: {{ build.pk }} Project: {{ build.project.slug }} Version: {{ build.version.verbose_name }} ({{ build.commit }}) Date: {{ build.date }} -Success: {{ build.succes }} +Success: {{ build.success }} RTD build information end {% for command in build.commands.all %} From 18545db3e53efbd9446c03663f7c0d9c7bb36aa4 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 9 Feb 2018 21:47:22 -0500 Subject: [PATCH 09/44] Fix method inside BuildViewSet --- readthedocs/restapi/views/model_views.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index 72fac4af4e0..aba6e9b819b 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -233,7 +233,6 @@ class BuildViewSetBase(UserSelectViewSet): admin_serializer_class = BuildAdminSerializer model = Build - @detail_route(renderer_classes=[PlainTextRenderer]) def log(self, request, *args, **kwargs): build = self.get_object() return Response(build.raw_log) @@ -245,6 +244,12 @@ class BuildViewSet(SettingsOverrideObject): _default_class = BuildViewSetBase + @detail_route(renderer_classes=[PlainTextRenderer]) + def log(self, request, *args, **kwargs): + # This meethod is defined on BuildViewSetBase + # because of SettingsOverrideObject. + pass + class BuildCommandViewSet(UserSelectViewSet): permission_classes = [APIRestrictedPermission] From 9f6da49205824e998306a87092f93375caef50b7 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 9 Feb 2018 21:48:38 -0500 Subject: [PATCH 10/44] Change Raw log to View raw --- readthedocs/templates/builds/build_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/templates/builds/build_detail.html b/readthedocs/templates/builds/build_detail.html index 430f087ea81..c23eeb2bd80 100644 --- a/readthedocs/templates/builds/build_detail.html +++ b/readthedocs/templates/builds/build_detail.html @@ -65,7 +65,7 @@ From a1f22a73c0b684689dd731832ac7713a847fcdb0 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 9 Feb 2018 21:52:38 -0500 Subject: [PATCH 11/44] Add url for view raw --- readthedocs/templates/builds/build_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/templates/builds/build_detail.html b/readthedocs/templates/builds/build_detail.html index c23eeb2bd80..14127da031d 100644 --- a/readthedocs/templates/builds/build_detail.html +++ b/readthedocs/templates/builds/build_detail.html @@ -64,7 +64,7 @@
  • - + {% trans "View raw" %}
  • From 1c46ce0c88632edef45e1e867d3324343447e653 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 9 Feb 2018 23:31:40 -0500 Subject: [PATCH 12/44] Check for valiud format before renderer --- readthedocs/restapi/views/model_views.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index aba6e9b819b..06853b76ed3 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -7,10 +7,11 @@ import logging from allauth.socialaccount.models import SocialAccount +from django.http import Http404 from django.shortcuts import get_object_or_404 from rest_framework import decorators, permissions, status, viewsets from rest_framework.decorators import detail_route -from rest_framework.renderers import JSONRenderer, BaseRenderer +from rest_framework.renderers import BaseRenderer, JSONRenderer from rest_framework.response import Response from readthedocs.builds.constants import BRANCH, TAG @@ -46,7 +47,11 @@ class PlainTextRenderer(BaseRenderer): format = 'txt' def render(self, data, accepted_media_type=None, renderer_context=None): - return data.encode(self.charset) + kwargs = renderer_context.get('kwargs', {}) + if kwargs.get('format', self.format) == self.format: + return data.encode(self.charset) + else: + raise Http404 class UserSelectViewSet(viewsets.ModelViewSet): From d4eaa37bb3ba73906b28669c5e47dc3945a6a97c Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 9 Feb 2018 23:33:13 -0500 Subject: [PATCH 13/44] Fix test --- readthedocs/rtd_tests/tests/test_privacy_urls.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readthedocs/rtd_tests/tests/test_privacy_urls.py b/readthedocs/rtd_tests/tests/test_privacy_urls.py index 761a2eedc75..cf7c582f580 100644 --- a/readthedocs/rtd_tests/tests/test_privacy_urls.py +++ b/readthedocs/rtd_tests/tests/test_privacy_urls.py @@ -336,6 +336,8 @@ def setUp(self): 'remoteorganization-detail': {'status_code': 404}, 'remoterepository-detail': {'status_code': 404}, 'remoteaccount-detail': {'status_code': 404}, + # This isn't a valid media type + '/api/v2/build/1/log.json': {'status_code': 404}, } From 31d39997d8cc0009564e827160eb3b4c137b4683 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Sat, 10 Feb 2018 00:10:33 -0500 Subject: [PATCH 14/44] Mark command and output as safe We don't want to escape characters here. --- readthedocs/restapi/templates/restapi/log.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt index 0abe0aad9e5..a2ac15f4211 100644 --- a/readthedocs/restapi/templates/restapi/log.txt +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -8,6 +8,6 @@ RTD build information end {% for command in build.commands.all %} [rtd-command-info] start-time: {{ command.start_time }}, end-time: {{ command.end_time }}, duration: {{ command.run_time }}, exit-code: {{ command.exit_code }} -{{ command.command }} -{{ command.output }} +{{ command.command|safe }} +{{ command.output|safe }} {% endfor %} From 73b7a12485a3197b2aa4654307ed951fcc6dae5c Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Sat, 10 Feb 2018 00:10:58 -0500 Subject: [PATCH 15/44] Add test --- readthedocs/rtd_tests/tests/test_api.py | 40 ++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index 726ec8b06fc..bb2f739f931 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -17,7 +17,7 @@ from rest_framework import status from rest_framework.test import APIClient -from readthedocs.builds.models import Build, Version +from readthedocs.builds.models import Build, BuildCommandResult, Version from readthedocs.integrations.models import Integration from readthedocs.oauth.models import RemoteOrganization, RemoteRepository from readthedocs.projects.models import Feature, Project @@ -277,6 +277,44 @@ def test_make_build_commands(self): self.assertEqual(build['commands'][0]['run_time'], 5) self.assertEqual(build['commands'][0]['description'], 'foo') + def test_get_raw_log(self): + build = get(Build, project_id=1, version_id=1, builder='foo') + get( + BuildCommandResult, + build=build, + command='python setup.py install', + output='Installing dependencies...' + ) + get( + BuildCommandResult, + build=build, + command='git checkout master', + output='Switched to branch "master"' + ) + client = APIClient() + + api_user = get(User, user='test', password='test') + client.force_authenticate(user=api_user) + resp = client.get('/api/v2/build/{0}/log.txt'.format(build.pk)) + self.assertEqual(resp.status_code, 200) + resp = client.get( + '/api/v2/build/{0}/log/'.format(build.pk), + format='txt' + ) + self.assertEqual(resp.status_code, 200) + + self.assertIn('RTD build information start', resp.data) + self.assertIn('RTD build information end', resp.data) + self.assertIn('[rtd-command-info]', resp.data) + self.assertIn( + 'python setup.py install\nInstalling dependencies...', + resp.data + ) + self.assertIn( + 'git checkout master\nSwitched to branch "master"', + resp.data + ) + class APITests(TestCase): fixtures = ['eric.json', 'test_data.json'] From 9be631d4041197a60073941428292ad758c24a7d Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Sat, 10 Feb 2018 00:15:43 -0500 Subject: [PATCH 16/44] Isort --- readthedocs/builds/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/builds/models.py b/readthedocs/builds/models.py index 0069c4cf55b..a38a09aa18e 100644 --- a/readthedocs/builds/models.py +++ b/readthedocs/builds/models.py @@ -10,10 +10,10 @@ from builtins import object from shutil import rmtree -from django.template import loader from django.conf import settings from django.core.urlresolvers import reverse from django.db import models +from django.template import loader from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext From 16aa10b99d92d48f8a09bbd0d7d40cee06b443af Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Thu, 15 Feb 2018 22:14:01 -0500 Subject: [PATCH 17/44] Use render_to_string --- readthedocs/builds/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readthedocs/builds/models.py b/readthedocs/builds/models.py index a38a09aa18e..0c5d400cedb 100644 --- a/readthedocs/builds/models.py +++ b/readthedocs/builds/models.py @@ -13,7 +13,7 @@ from django.conf import settings from django.core.urlresolvers import reverse from django.db import models -from django.template import loader +from django.template.loader import render_to_string from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext @@ -469,8 +469,8 @@ def finished(self): @property def raw_log(self): - raw_log = loader.get_template('restapi/log.txt').render( - {'build': self} + raw_log = render_to_string( + 'restapi/log.txt', {'build': self} ) return raw_log From 3cd340d2497dee33e250617525e7b78b37996ec5 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Thu, 15 Feb 2018 22:32:56 -0500 Subject: [PATCH 18/44] Update log template --- readthedocs/restapi/templates/restapi/log.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt index a2ac15f4211..5f1b8234dbc 100644 --- a/readthedocs/restapi/templates/restapi/log.txt +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -1,10 +1,9 @@ -RTD build information start +RTD build information Build: {{ build.pk }} Project: {{ build.project.slug }} Version: {{ build.version.verbose_name }} ({{ build.commit }}) Date: {{ build.date }} Success: {{ build.success }} -RTD build information end {% for command in build.commands.all %} [rtd-command-info] start-time: {{ command.start_time }}, end-time: {{ command.end_time }}, duration: {{ command.run_time }}, exit-code: {{ command.exit_code }} From d91dd60127130ed4ee854a2e7ec7ee243614b7c4 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Thu, 15 Feb 2018 22:33:24 -0500 Subject: [PATCH 19/44] Update tests --- readthedocs/rtd_tests/tests/test_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index bb2f739f931..8b78073c953 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -303,8 +303,8 @@ def test_get_raw_log(self): ) self.assertEqual(resp.status_code, 200) - self.assertIn('RTD build information start', resp.data) - self.assertIn('RTD build information end', resp.data) + self.assertEqual(resp.data, build.raw_log) + self.assertIn('RTD build information', resp.data) self.assertIn('[rtd-command-info]', resp.data) self.assertIn( 'python setup.py install\nInstalling dependencies...', From 4ca3c47314aa7628cd4b7081b87deacdf32d4c64 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 16 Feb 2018 15:15:34 -0500 Subject: [PATCH 20/44] Improve renderer class --- readthedocs/restapi/views/model_views.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index 06853b76ed3..00448e12081 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -7,7 +7,6 @@ import logging from allauth.socialaccount.models import SocialAccount -from django.http import Http404 from django.shortcuts import get_object_or_404 from rest_framework import decorators, permissions, status, viewsets from rest_framework.decorators import detail_route @@ -47,11 +46,10 @@ class PlainTextRenderer(BaseRenderer): format = 'txt' def render(self, data, accepted_media_type=None, renderer_context=None): - kwargs = renderer_context.get('kwargs', {}) - if kwargs.get('format', self.format) == self.format: - return data.encode(self.charset) - else: - raise Http404 + response = renderer_context.get('response') + if response.status_code != status.HTTP_200_OK: + return data['detail'].encode(self.charset) + return data.encode(self.charset) class UserSelectViewSet(viewsets.ModelViewSet): From 47315c8024ab2c83f3550468c7ec9d47c528d01e Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 16 Feb 2018 15:16:39 -0500 Subject: [PATCH 21/44] Remove black listed url --- readthedocs/rtd_tests/tests/test_privacy_urls.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/readthedocs/rtd_tests/tests/test_privacy_urls.py b/readthedocs/rtd_tests/tests/test_privacy_urls.py index cf7c582f580..761a2eedc75 100644 --- a/readthedocs/rtd_tests/tests/test_privacy_urls.py +++ b/readthedocs/rtd_tests/tests/test_privacy_urls.py @@ -336,8 +336,6 @@ def setUp(self): 'remoteorganization-detail': {'status_code': 404}, 'remoterepository-detail': {'status_code': 404}, 'remoteaccount-detail': {'status_code': 404}, - # This isn't a valid media type - '/api/v2/build/1/log.json': {'status_code': 404}, } From aca0ef8fbcbb4830031e25b5fb9cad79f63a834d Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 16 Feb 2018 15:27:57 -0500 Subject: [PATCH 22/44] Add black listed url again --- readthedocs/rtd_tests/tests/test_privacy_urls.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readthedocs/rtd_tests/tests/test_privacy_urls.py b/readthedocs/rtd_tests/tests/test_privacy_urls.py index 761a2eedc75..cf7c582f580 100644 --- a/readthedocs/rtd_tests/tests/test_privacy_urls.py +++ b/readthedocs/rtd_tests/tests/test_privacy_urls.py @@ -336,6 +336,8 @@ def setUp(self): 'remoteorganization-detail': {'status_code': 404}, 'remoterepository-detail': {'status_code': 404}, 'remoteaccount-detail': {'status_code': 404}, + # This isn't a valid media type + '/api/v2/build/1/log.json': {'status_code': 404}, } From 75a8042a71d2681cde83c2b8dfdf065a41b5609e Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 16 Feb 2018 15:34:54 -0500 Subject: [PATCH 23/44] Show view raw only to staff users --- readthedocs/templates/builds/build_detail.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readthedocs/templates/builds/build_detail.html b/readthedocs/templates/builds/build_detail.html index 14127da031d..f1c0b3cc980 100644 --- a/readthedocs/templates/builds/build_detail.html +++ b/readthedocs/templates/builds/build_detail.html @@ -62,13 +62,15 @@
    + {% if request.user.is_staff %} +
    + {% endif %}
    From 5c7629c9c19bbc91dd34e9f1b9b4a4eb8e1f615d Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Fri, 16 Feb 2018 16:05:42 -0500 Subject: [PATCH 24/44] Try ro reuse previous endpoint --- readthedocs/restapi/templates/restapi/log.txt | 2 +- readthedocs/restapi/views/model_views.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt index 5f1b8234dbc..c231fb06505 100644 --- a/readthedocs/restapi/templates/restapi/log.txt +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -5,7 +5,7 @@ Version: {{ build.version.verbose_name }} ({{ build.commit }}) Date: {{ build.date }} Success: {{ build.success }} -{% for command in build.commands.all %} +{% for command in build.commands %} [rtd-command-info] start-time: {{ command.start_time }}, end-time: {{ command.end_time }}, duration: {{ command.run_time }}, exit-code: {{ command.exit_code }} {{ command.command|safe }} {{ command.output|safe }} diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index 00448e12081..a69618ca271 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -9,6 +9,7 @@ from allauth.socialaccount.models import SocialAccount from django.shortcuts import get_object_or_404 from rest_framework import decorators, permissions, status, viewsets +from django.template.loader import render_to_string from rest_framework.decorators import detail_route from rest_framework.renderers import BaseRenderer, JSONRenderer from rest_framework.response import Response @@ -49,6 +50,9 @@ def render(self, data, accepted_media_type=None, renderer_context=None): response = renderer_context.get('response') if response.status_code != status.HTTP_200_OK: return data['detail'].encode(self.charset) + data = render_to_string( + 'restapi/log.txt', {'build': data} + ) return data.encode(self.charset) @@ -231,7 +235,7 @@ class VersionViewSet(UserSelectViewSet): class BuildViewSetBase(UserSelectViewSet): permission_classes = [APIRestrictedPermission] - renderer_classes = (JSONRenderer,) + renderer_classes = (JSONRenderer, PlainTextRenderer) serializer_class = BuildSerializer admin_serializer_class = BuildAdminSerializer model = Build From 949b42dc2a60ca38d63f3efebff70fccc35e9eeb Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 18:16:12 -0500 Subject: [PATCH 25/44] Check against None value --- readthedocs/restapi/views/model_views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index a69618ca271..b216feb39e0 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -47,6 +47,7 @@ class PlainTextRenderer(BaseRenderer): format = 'txt' def render(self, data, accepted_media_type=None, renderer_context=None): + renderer_context = renderer_context or {} response = renderer_context.get('response') if response.status_code != status.HTTP_200_OK: return data['detail'].encode(self.charset) From d9f229f2a9f8591d0543cba6a6696666e1c390bd Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 18:16:49 -0500 Subject: [PATCH 26/44] Rename renderer --- readthedocs/restapi/views/model_views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index b216feb39e0..73f3957a28b 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -35,7 +35,7 @@ log = logging.getLogger(__name__) -class PlainTextRenderer(BaseRenderer): +class PlainTextBuildRenderer(BaseRenderer): """ Custom renderer for text/plain format. @@ -236,7 +236,7 @@ class VersionViewSet(UserSelectViewSet): class BuildViewSetBase(UserSelectViewSet): permission_classes = [APIRestrictedPermission] - renderer_classes = (JSONRenderer, PlainTextRenderer) + renderer_classes = (JSONRenderer, PlainTextBuildRenderer) serializer_class = BuildSerializer admin_serializer_class = BuildAdminSerializer model = Build From ce7e16cab68dc337e33317567bfe762ef17f19b4 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 18:17:09 -0500 Subject: [PATCH 27/44] Remove old code --- readthedocs/restapi/views/model_views.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index 73f3957a28b..bb4e9178c05 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -241,10 +241,6 @@ class BuildViewSetBase(UserSelectViewSet): admin_serializer_class = BuildAdminSerializer model = Build - def log(self, request, *args, **kwargs): - build = self.get_object() - return Response(build.raw_log) - class BuildViewSet(SettingsOverrideObject): @@ -252,12 +248,6 @@ class BuildViewSet(SettingsOverrideObject): _default_class = BuildViewSetBase - @detail_route(renderer_classes=[PlainTextRenderer]) - def log(self, request, *args, **kwargs): - # This meethod is defined on BuildViewSetBase - # because of SettingsOverrideObject. - pass - class BuildCommandViewSet(UserSelectViewSet): permission_classes = [APIRestrictedPermission] From 40f259d49e3d07ee6964e4e09db2c33a3452140a Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 18:33:49 -0500 Subject: [PATCH 28/44] Show build state --- readthedocs/restapi/templates/restapi/log.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt index c231fb06505..f1745a044bc 100644 --- a/readthedocs/restapi/templates/restapi/log.txt +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -3,7 +3,10 @@ Build: {{ build.pk }} Project: {{ build.project.slug }} Version: {{ build.version.verbose_name }} ({{ build.commit }}) Date: {{ build.date }} +State: {{ build.state }} +{% if build.state == 'finished' %} Success: {{ build.success }} +{% endif %} {% for command in build.commands %} [rtd-command-info] start-time: {{ command.start_time }}, end-time: {{ command.end_time }}, duration: {{ command.run_time }}, exit-code: {{ command.exit_code }} From a029a08d737ff59b2b86124ae281a1cc9e3b3909 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 18:35:00 -0500 Subject: [PATCH 29/44] Update tests --- readthedocs/rtd_tests/tests/test_api.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index 8b78073c953..cd812b7b3b4 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -295,15 +295,9 @@ def test_get_raw_log(self): api_user = get(User, user='test', password='test') client.force_authenticate(user=api_user) - resp = client.get('/api/v2/build/{0}/log.txt'.format(build.pk)) - self.assertEqual(resp.status_code, 200) - resp = client.get( - '/api/v2/build/{0}/log/'.format(build.pk), - format='txt' - ) + resp = client.get('/api/v2/build/{0}.txt'.format(build.pk)) self.assertEqual(resp.status_code, 200) - self.assertEqual(resp.data, build.raw_log) self.assertIn('RTD build information', resp.data) self.assertIn('[rtd-command-info]', resp.data) self.assertIn( From c3b02f4a58a84044cda4eb21911f02fb73a94513 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 18:36:18 -0500 Subject: [PATCH 30/44] Remove raw_log property --- readthedocs/builds/models.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/readthedocs/builds/models.py b/readthedocs/builds/models.py index 0c5d400cedb..973097249e1 100644 --- a/readthedocs/builds/models.py +++ b/readthedocs/builds/models.py @@ -13,7 +13,6 @@ from django.conf import settings from django.core.urlresolvers import reverse from django.db import models -from django.template.loader import render_to_string from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext @@ -467,13 +466,6 @@ def finished(self): """Return if build has a finished state.""" return self.state == BUILD_STATE_FINISHED - @property - def raw_log(self): - raw_log = render_to_string( - 'restapi/log.txt', {'build': self} - ) - return raw_log - class BuildCommandResultMixin(object): From 03e642b8fc67c9dcd39c530098d702a35871accf Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 18:50:48 -0500 Subject: [PATCH 31/44] New url --- readthedocs/templates/builds/build_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/templates/builds/build_detail.html b/readthedocs/templates/builds/build_detail.html index f1c0b3cc980..f9284f3f9f7 100644 --- a/readthedocs/templates/builds/build_detail.html +++ b/readthedocs/templates/builds/build_detail.html @@ -65,7 +65,7 @@ {% if request.user.is_staff %}
  • - + {% trans "View raw" %}
  • From 39b3607b5c56d2960e2d43cc67f40cf268cf591e Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 19:07:15 -0500 Subject: [PATCH 32/44] Update tests --- readthedocs/rtd_tests/tests/test_api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index cd812b7b3b4..d9b34a3ab62 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -298,15 +298,15 @@ def test_get_raw_log(self): resp = client.get('/api/v2/build/{0}.txt'.format(build.pk)) self.assertEqual(resp.status_code, 200) - self.assertIn('RTD build information', resp.data) - self.assertIn('[rtd-command-info]', resp.data) + self.assertIn('RTD build information', resp.content) + self.assertIn('[rtd-command-info]', resp.content) self.assertIn( 'python setup.py install\nInstalling dependencies...', - resp.data + resp.content ) self.assertIn( 'git checkout master\nSwitched to branch "master"', - resp.data + resp.content ) From 7bfd92cc2d471be2a22aa60ab265af60cda69fc8 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 19:40:45 -0500 Subject: [PATCH 33/44] Fix tests --- readthedocs/rtd_tests/tests/test_api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index d9b34a3ab62..b9c10b7a616 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -298,14 +298,14 @@ def test_get_raw_log(self): resp = client.get('/api/v2/build/{0}.txt'.format(build.pk)) self.assertEqual(resp.status_code, 200) - self.assertIn('RTD build information', resp.content) - self.assertIn('[rtd-command-info]', resp.content) + self.assertIn(b'RTD build information', resp.content) + self.assertIn(b'[rtd-command-info]', resp.content) self.assertIn( - 'python setup.py install\nInstalling dependencies...', + b'python setup.py install\nInstalling dependencies...', resp.content ) self.assertIn( - 'git checkout master\nSwitched to branch "master"', + b'git checkout master\nSwitched to branch "master"', resp.content ) From 2af04a8e827d0eb9f06a7681dbac00e32021c60a Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Mon, 19 Feb 2018 19:58:42 -0500 Subject: [PATCH 34/44] Fix newline --- readthedocs/restapi/templates/restapi/log.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt index f1745a044bc..9bf1046e78e 100644 --- a/readthedocs/restapi/templates/restapi/log.txt +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -4,9 +4,7 @@ Project: {{ build.project.slug }} Version: {{ build.version.verbose_name }} ({{ build.commit }}) Date: {{ build.date }} State: {{ build.state }} -{% if build.state == 'finished' %} -Success: {{ build.success }} -{% endif %} +{% if build.state == 'finished' %}Success: {{ build.success }}{% endif %} {% for command in build.commands %} [rtd-command-info] start-time: {{ command.start_time }}, end-time: {{ command.end_time }}, duration: {{ command.run_time }}, exit-code: {{ command.exit_code }} From 59af03ab2786032a0f051987e9923d2df4e54c81 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Tue, 20 Feb 2018 12:04:07 -0500 Subject: [PATCH 35/44] Better status check --- readthedocs/restapi/views/model_views.py | 2 +- readthedocs/rtd_tests/tests/test_api.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index bb4e9178c05..febb5aef98b 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -49,7 +49,7 @@ class PlainTextBuildRenderer(BaseRenderer): def render(self, data, accepted_media_type=None, renderer_context=None): renderer_context = renderer_context or {} response = renderer_context.get('response') - if response.status_code != status.HTTP_200_OK: + if response.exception: return data['detail'].encode(self.charset) data = render_to_string( 'restapi/log.txt', {'build': data} diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index b9c10b7a616..2de62c98944 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -309,6 +309,14 @@ def test_get_raw_log(self): resp.content ) + def test_get_invalid_raw_log(self): + client = APIClient() + + api_user = get(User, user='test', password='test') + client.force_authenticate(user=api_user) + resp = client.get('/api/v2/build/{0}.txt'.format(404)) + self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND) + class APITests(TestCase): fixtures = ['eric.json', 'test_data.json'] From 990145cc665d06b95f0490ddf624b89e1d70c109 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Tue, 20 Feb 2018 12:04:23 -0500 Subject: [PATCH 36/44] Decode strings --- readthedocs/rtd_tests/tests/test_api.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index 2de62c98944..371c85082a2 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -298,15 +298,15 @@ def test_get_raw_log(self): resp = client.get('/api/v2/build/{0}.txt'.format(build.pk)) self.assertEqual(resp.status_code, 200) - self.assertIn(b'RTD build information', resp.content) - self.assertIn(b'[rtd-command-info]', resp.content) + self.assertIn('RTD build information', resp.content.decode()) + self.assertIn('[rtd-command-info]', resp.content.decode()) self.assertIn( - b'python setup.py install\nInstalling dependencies...', - resp.content + 'python setup.py install\nInstalling dependencies...', + resp.content.decode() ) self.assertIn( - b'git checkout master\nSwitched to branch "master"', - resp.content + 'git checkout master\nSwitched to branch "master"', + resp.content.decode() ) def test_get_invalid_raw_log(self): From 52aafc5c9e59f0bff71229fe5f68d1dfde356c92 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Tue, 20 Feb 2018 12:07:43 -0500 Subject: [PATCH 37/44] Better protection for None --- readthedocs/restapi/views/model_views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readthedocs/restapi/views/model_views.py b/readthedocs/restapi/views/model_views.py index febb5aef98b..fee6153091f 100644 --- a/readthedocs/restapi/views/model_views.py +++ b/readthedocs/restapi/views/model_views.py @@ -49,8 +49,8 @@ class PlainTextBuildRenderer(BaseRenderer): def render(self, data, accepted_media_type=None, renderer_context=None): renderer_context = renderer_context or {} response = renderer_context.get('response') - if response.exception: - return data['detail'].encode(self.charset) + if not response or response.exception: + return data.get('detail', '').encode(self.charset) data = render_to_string( 'restapi/log.txt', {'build': data} ) From dc2cbdd67d3d633d4cdeb56a740a47764d4118b0 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 21 Feb 2018 16:47:23 -0500 Subject: [PATCH 38/44] Fix information provided by data --- readthedocs/restapi/templates/restapi/log.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt index 9bf1046e78e..6eb9140f2a0 100644 --- a/readthedocs/restapi/templates/restapi/log.txt +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -1,7 +1,7 @@ RTD build information -Build: {{ build.pk }} -Project: {{ build.project.slug }} -Version: {{ build.version.verbose_name }} ({{ build.commit }}) +Build: {{ build.id }} +Project: {{ build.project }} +Version: {{ build.commit }} Date: {{ build.date }} State: {{ build.state }} {% if build.state == 'finished' %}Success: {{ build.success }}{% endif %} From 86d7bde1dfdb180d191a255f13127415f48bc43d Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 21 Feb 2018 17:06:52 -0500 Subject: [PATCH 39/44] More tests --- readthedocs/rtd_tests/tests/test_api.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index 371c85082a2..beb1261265f 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -299,6 +299,11 @@ def test_get_raw_log(self): self.assertEqual(resp.status_code, 200) self.assertIn('RTD build information', resp.content.decode()) + self.assertIn('Build: {}'.format(build.id), resp.content.decode()) + self.assertIn('Project: {}'.format(build.project.id), resp.content.decode()) + self.assertIn('Version: {}'.format(build.commit), resp.content.decode()) + self.assertIn('State: {}'.format(build.state), resp.content.decode()) + self.assertIn('Success: {}'.format(build.success), resp.content.decode()) self.assertIn('[rtd-command-info]', resp.content.decode()) self.assertIn( 'python setup.py install\nInstalling dependencies...', From 29696ed777ce1bb00e1c6492361f22f37625ea4e Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 23 May 2018 22:37:08 -0500 Subject: [PATCH 40/44] Remove trash from rebase --- readthedocs/rtd_tests/tests/test_privacy_urls.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/readthedocs/rtd_tests/tests/test_privacy_urls.py b/readthedocs/rtd_tests/tests/test_privacy_urls.py index cf7c582f580..761a2eedc75 100644 --- a/readthedocs/rtd_tests/tests/test_privacy_urls.py +++ b/readthedocs/rtd_tests/tests/test_privacy_urls.py @@ -336,8 +336,6 @@ def setUp(self): 'remoteorganization-detail': {'status_code': 404}, 'remoterepository-detail': {'status_code': 404}, 'remoteaccount-detail': {'status_code': 404}, - # This isn't a valid media type - '/api/v2/build/1/log.json': {'status_code': 404}, } From c8dc50611944e3af3535cf14e9ad11fa48a72ff7 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 23 May 2018 23:18:24 -0500 Subject: [PATCH 41/44] Improve log format --- readthedocs/restapi/templates/restapi/log.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/readthedocs/restapi/templates/restapi/log.txt b/readthedocs/restapi/templates/restapi/log.txt index 6eb9140f2a0..dda62a6e8e7 100644 --- a/readthedocs/restapi/templates/restapi/log.txt +++ b/readthedocs/restapi/templates/restapi/log.txt @@ -1,10 +1,11 @@ -RTD build information -Build: {{ build.id }} -Project: {{ build.project }} -Version: {{ build.commit }} +Read the Docs build information +Build id: {{ build.id }} +Project: {{ build.project_slug }} +Version: {{ build.version_slug }} +Commit: {{ build.commit }} Date: {{ build.date }} State: {{ build.state }} -{% if build.state == 'finished' %}Success: {{ build.success }}{% endif %} +Success: {% if build.state == 'finished' %}{{ build.success }}{% else %}Unknown{% endif %} {% for command in build.commands %} [rtd-command-info] start-time: {{ command.start_time }}, end-time: {{ command.end_time }}, duration: {{ command.run_time }}, exit-code: {{ command.exit_code }} From a0370624bca12640d580febc6d7dd2439ab890eb Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 23 May 2018 23:18:53 -0500 Subject: [PATCH 42/44] Add slugs to api response --- readthedocs/restapi/serializers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readthedocs/restapi/serializers.py b/readthedocs/restapi/serializers.py index b4d8b2b9b16..606f444496b 100644 --- a/readthedocs/restapi/serializers.py +++ b/readthedocs/restapi/serializers.py @@ -100,6 +100,8 @@ class BuildSerializer(serializers.ModelSerializer): """Build serializer for user display, doesn't display internal fields.""" commands = BuildCommandSerializer(many=True, read_only=True) + project_slug = serializers.ReadOnlyField(source='project.slug') + version_slug = serializers.ReadOnlyField(source='version.slug') docs_url = serializers.ReadOnlyField(source='version.get_absolute_url') state_display = serializers.ReadOnlyField(source='get_state_display') From bd03a78a18e72ce78b1d5d87aecc34ea82f870ba Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 23 May 2018 23:19:13 -0500 Subject: [PATCH 43/44] Show link to everyone --- readthedocs/templates/builds/build_detail.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/readthedocs/templates/builds/build_detail.html b/readthedocs/templates/builds/build_detail.html index f9284f3f9f7..0111805741e 100644 --- a/readthedocs/templates/builds/build_detail.html +++ b/readthedocs/templates/builds/build_detail.html @@ -62,7 +62,6 @@
    - {% if request.user.is_staff %} - {% endif %}
    From 1415270caed4e9c1b426ba218babd24844b02548 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Wed, 23 May 2018 23:45:15 -0500 Subject: [PATCH 44/44] More tests --- readthedocs/rtd_tests/tests/test_api.py | 103 ++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 7 deletions(-) diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index beb1261265f..365dfff61c3 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -277,7 +277,7 @@ def test_make_build_commands(self): self.assertEqual(build['commands'][0]['run_time'], 5) self.assertEqual(build['commands'][0]['description'], 'foo') - def test_get_raw_log(self): + def test_get_raw_log_success(self): build = get(Build, project_id=1, version_id=1, builder='foo') get( BuildCommandResult, @@ -298,12 +298,101 @@ def test_get_raw_log(self): resp = client.get('/api/v2/build/{0}.txt'.format(build.pk)) self.assertEqual(resp.status_code, 200) - self.assertIn('RTD build information', resp.content.decode()) - self.assertIn('Build: {}'.format(build.id), resp.content.decode()) - self.assertIn('Project: {}'.format(build.project.id), resp.content.decode()) - self.assertIn('Version: {}'.format(build.commit), resp.content.decode()) - self.assertIn('State: {}'.format(build.state), resp.content.decode()) - self.assertIn('Success: {}'.format(build.success), resp.content.decode()) + self.assertIn('Read the Docs build information', resp.content.decode()) + self.assertIn('Build id: {}'.format(build.id), resp.content.decode()) + self.assertIn('Project: {}'.format(build.project.slug), resp.content.decode()) + self.assertIn('Version: {}'.format(build.version.slug), resp.content.decode()) + self.assertIn('Commit: {}'.format(build.commit), resp.content.decode()) + self.assertIn('Date: ', resp.content.decode()) + self.assertIn('State: finished', resp.content.decode()) + self.assertIn('Success: True', resp.content.decode()) + self.assertIn('[rtd-command-info]', resp.content.decode()) + self.assertIn( + 'python setup.py install\nInstalling dependencies...', + resp.content.decode() + ) + self.assertIn( + 'git checkout master\nSwitched to branch "master"', + resp.content.decode() + ) + + def test_get_raw_log_building(self): + build = get( + Build, project_id=1, version_id=1, + builder='foo', success=False, + exit_code=1, state='building', + ) + get( + BuildCommandResult, + build=build, + command='python setup.py install', + output='Installing dependencies...', + exit_code=1, + ) + get( + BuildCommandResult, + build=build, + command='git checkout master', + output='Switched to branch "master"' + ) + client = APIClient() + + api_user = get(User, user='test', password='test') + client.force_authenticate(user=api_user) + resp = client.get('/api/v2/build/{0}.txt'.format(build.pk)) + self.assertEqual(resp.status_code, 200) + + self.assertIn('Read the Docs build information', resp.content.decode()) + self.assertIn('Build id: {}'.format(build.id), resp.content.decode()) + self.assertIn('Project: {}'.format(build.project.slug), resp.content.decode()) + self.assertIn('Version: {}'.format(build.version.slug), resp.content.decode()) + self.assertIn('Commit: {}'.format(build.commit), resp.content.decode()) + self.assertIn('Date: ', resp.content.decode()) + self.assertIn('State: building', resp.content.decode()) + self.assertIn('Success: Unknow', resp.content.decode()) + self.assertIn('[rtd-command-info]', resp.content.decode()) + self.assertIn( + 'python setup.py install\nInstalling dependencies...', + resp.content.decode() + ) + self.assertIn( + 'git checkout master\nSwitched to branch "master"', + resp.content.decode() + ) + + def test_get_raw_log_failure(self): + build = get( + Build, project_id=1, version_id=1, + builder='foo', success=False, exit_code=1 + ) + get( + BuildCommandResult, + build=build, + command='python setup.py install', + output='Installing dependencies...', + exit_code=1, + ) + get( + BuildCommandResult, + build=build, + command='git checkout master', + output='Switched to branch "master"' + ) + client = APIClient() + + api_user = get(User, user='test', password='test') + client.force_authenticate(user=api_user) + resp = client.get('/api/v2/build/{0}.txt'.format(build.pk)) + self.assertEqual(resp.status_code, 200) + + self.assertIn('Read the Docs build information', resp.content.decode()) + self.assertIn('Build id: {}'.format(build.id), resp.content.decode()) + self.assertIn('Project: {}'.format(build.project.slug), resp.content.decode()) + self.assertIn('Version: {}'.format(build.version.slug), resp.content.decode()) + self.assertIn('Commit: {}'.format(build.commit), resp.content.decode()) + self.assertIn('Date: ', resp.content.decode()) + self.assertIn('State: finished', resp.content.decode()) + self.assertIn('Success: False', resp.content.decode()) self.assertIn('[rtd-command-info]', resp.content.decode()) self.assertIn( 'python setup.py install\nInstalling dependencies...',