prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Link to open an issue from a failed Build with pre-filled details
  There are several issues that are reported where there are missing information in the details section.
  
  To solve this I was thinking on generating a link inside this message that could contain all the information pre-filled:
  
  ![captura de pantalla_2018-01-22_15-07-15](https://user-images.githubusercontent.com/244656/35242041-6ed4e288-ff86-11e7-9b89-c69a45505318.png)
  
  
  I found that github supports _some_ query arguments in the URL but I didn't found a way to use those key/args inside the template itself.
  
  https://help.github.com/articles/about-automation-for-issues-and-pull-requests-with-query-parameters/
  
  I think it would be awesome if the user can just click a link and the username, project url, etc could be pre-filled automatically.
  
  </issue>
  <code>
  [start of readthedocs/builds/views.py]
  1 # -*- coding: utf-8 -*-
  2 
  3 """Views for builds app."""
  4 
  5 import logging
  6 
  7 from django.contrib import messages
  8 from django.contrib.auth.decorators import login_required
  9 from django.http import (
  10     HttpResponseForbidden,
  11     HttpResponsePermanentRedirect,
  12     HttpResponseRedirect,
  13 )
  14 from django.shortcuts import get_object_or_404
  15 from django.urls import reverse
  16 from django.utils.decorators import method_decorator
  17 from django.views.generic import DetailView, ListView
  18 
  19 from readthedocs.builds.models import Build, Version
  20 from readthedocs.core.permissions import AdminPermission
  21 from readthedocs.core.utils import trigger_build
  22 from readthedocs.projects.models import Project
  23 
  24 
  25 log = logging.getLogger(__name__)
  26 
  27 
  28 class BuildBase:
  29     model = Build
  30 
  31     def get_queryset(self):
  32         self.project_slug = self.kwargs.get('project_slug', None)
  33         self.project = get_object_or_404(
  34             Project.objects.protected(self.request.user),
  35             slug=self.project_slug,
  36         )
  37         queryset = Build.objects.public(
  38             user=self.request.user,
  39             project=self.project,
  40         )
  41 
  42         return queryset
  43 
  44 
  45 class BuildTriggerMixin:
  46 
  47     @method_decorator(login_required)
  48     def post(self, request, project_slug):
  49         project = get_object_or_404(Project, slug=project_slug)
  50 
  51         if not AdminPermission.is_admin(request.user, project):
  52             return HttpResponseForbidden()
  53 
  54         version_slug = request.POST.get('version_slug')
  55         version = get_object_or_404(
  56             Version,
  57             project=project,
  58             slug=version_slug,
  59         )
  60 
  61         update_docs_task, build = trigger_build(
  62             project=project,
  63             version=version,
  64         )
  65         if (update_docs_task, build) == (None, None):
  66             # Build was skipped
  67             messages.add_message(
  68                 request,
  69                 messages.WARNING,
  70                 "This project is currently disabled and can't trigger new builds.",
  71             )
  72             return HttpResponseRedirect(
  73                 reverse('builds_project_list', args=[project.slug]),
  74             )
  75 
  76         return HttpResponseRedirect(
  77             reverse('builds_detail', args=[project.slug, build.pk]),
  78         )
  79 
  80 
  81 class BuildList(BuildBase, BuildTriggerMixin, ListView):
  82 
  83     def get_context_data(self, **kwargs):
  84         context = super().get_context_data(**kwargs)
  85 
  86         active_builds = self.get_queryset().exclude(
  87             state='finished',
  88         ).values('id')
  89 
  90         context['project'] = self.project
  91         context['active_builds'] = active_builds
  92         context['versions'] = Version.objects.public(
  93             user=self.request.user,
  94             project=self.project,
  95         )
  96         context['build_qs'] = self.get_queryset()
  97 
  98         return context
  99 
  100 
  101 class BuildDetail(BuildBase, DetailView):
  102     pk_url_kwarg = 'build_pk'
  103 
  104     def get_context_data(self, **kwargs):
  105         context = super().get_context_data(**kwargs)
  106         context['project'] = self.project
  107         return context
  108 
  109 
  110 # Old build view redirects
  111 
  112 
  113 def builds_redirect_list(request, project_slug):  # pylint: disable=unused-argument
  114     return HttpResponsePermanentRedirect(
  115         reverse('builds_project_list', args=[project_slug]),
  116     )
  117 
  118 
  119 def builds_redirect_detail(request, project_slug, pk):  # pylint: disable=unused-argument
  120     return HttpResponsePermanentRedirect(
  121         reverse('builds_detail', args=[project_slug, pk]),
  122     )
  123
  [end of readthedocs/builds/views.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/readthedocs/builds/views.py b/readthedocs/builds/views.py
  --- a/readthedocs/builds/views.py
  +++ b/readthedocs/builds/views.py
  @@ -3,6 +3,7 @@
   """Views for builds app."""
   
   import logging
  +import textwrap
   
   from django.contrib import messages
   from django.contrib.auth.decorators import login_required
  @@ -15,7 +16,10 @@
   from django.urls import reverse
   from django.utils.decorators import method_decorator
   from django.views.generic import DetailView, ListView
  +from requests.utils import quote
  +from urllib.parse import urlparse
   
  +from readthedocs.doc_builder.exceptions import BuildEnvironmentError
   from readthedocs.builds.models import Build, Version
   from readthedocs.core.permissions import AdminPermission
   from readthedocs.core.utils import trigger_build
  @@ -104,6 +108,49 @@
       def get_context_data(self, **kwargs):
           context = super().get_context_data(**kwargs)
           context['project'] = self.project
  +
  +        build = self.get_object()
  +        if build.error != BuildEnvironmentError.GENERIC_WITH_BUILD_ID.format(build_id=build.pk):
  +            # Do not suggest to open an issue if the error is not generic
  +            return context
  +
  +        scheme = (
  +            'https://github.com/rtfd/readthedocs.org/issues/new'
  +            '?title={title}{build_id}'
  +            '&body={body}'
  +        )
  +
  +        # TODO: we could use ``.github/ISSUE_TEMPLATE.md`` here, but we would
  +        # need to add some variables to it which could impact in the UX when
  +        # filling an issue from the web
  +        body = """
  +        ## Details:
  +
  +        * Project URL: https://readthedocs.org/projects/{project_slug}/
  +        * Build URL(if applicable): https://readthedocs.org{build_path}
  +        * Read the Docs username(if applicable): {username}
  +
  +        ## Expected Result
  +
  +        *A description of what you wanted to happen*
  +
  +        ## Actual Result
  +
  +        *A description of what actually happened*""".format(
  +            project_slug=self.project,
  +            build_path=self.request.path,
  +            username=self.request.user,
  +        )
  +
  +        scheme_dict = {
  +            'title': quote('Build error with build id #'),
  +            'build_id': context['build'].id,
  +            'body': quote(textwrap.dedent(body)),
  +        }
  +
  +        issue_url = scheme.format(**scheme_dict)
  +        issue_url = urlparse(issue_url).geturl()
  +        context['issue_url'] = issue_url
           return context
  
verification_info: {"golden_diff": "diff --git a/readthedocs/builds/views.py b/readthedocs/builds/views.py\n--- a/readthedocs/builds/views.py\n+++ b/readthedocs/builds/views.py\n@@ -3,6 +3,7 @@\n \"\"\"Views for builds app.\"\"\"\n \n import logging\n+import textwrap\n \n from django.contrib import messages\n from django.contrib.auth.decorators import login_required\n@@ -15,7 +16,10 @@\n from django.urls import reverse\n from django.utils.decorators import method_decorator\n from django.views.generic import DetailView, ListView\n+from requests.utils import quote\n+from urllib.parse import urlparse\n \n+from readthedocs.doc_builder.exceptions import BuildEnvironmentError\n from readthedocs.builds.models import Build, Version\n from readthedocs.core.permissions import AdminPermission\n from readthedocs.core.utils import trigger_build\n@@ -104,6 +108,49 @@\n     def get_context_data(self, **kwargs):\n         context = super().get_context_data(**kwargs)\n         context['project'] = self.project\n+\n+        build = self.get_object()\n+        if build.error != BuildEnvironmentError.GENERIC_WITH_BUILD_ID.format(build_id=build.pk):\n+            # Do not suggest to open an issue if the error is not generic\n+            return context\n+\n+        scheme = (\n+            'https://github.com/rtfd/readthedocs.org/issues/new'\n+            '?title={title}{build_id}'\n+            '&body={body}'\n+        )\n+\n+        # TODO: we could use ``.github/ISSUE_TEMPLATE.md`` here, but we would\n+        # need to add some variables to it which could impact in the UX when\n+        # filling an issue from the web\n+        body = \"\"\"\n+        ## Details:\n+\n+        * Project URL: https://readthedocs.org/projects/{project_slug}/\n+        * Build URL(if applicable): https://readthedocs.org{build_path}\n+        * Read the Docs username(if applicable): {username}\n+\n+        ## Expected Result\n+\n+        *A description of what you wanted to happen*\n+\n+        ## Actual Result\n+\n+        *A description of what actually happened*\"\"\".format(\n+            project_slug=self.project,\n+            build_path=self.request.path,\n+            username=self.request.user,\n+        )\n+\n+        scheme_dict = {\n+            'title': quote('Build error with build id #'),\n+            'build_id': context['build'].id,\n+            'body': quote(textwrap.dedent(body)),\n+        }\n+\n+        issue_url = scheme.format(**scheme_dict)\n+        issue_url = urlparse(issue_url).geturl()\n+        context['issue_url'] = issue_url\n         return context\n", "issue": "Link to open an issue from a failed Build with pre-filled details\nThere are several issues that are reported where there are missing information in the details section.\r\n\r\nTo solve this I was thinking on generating a link inside this message that could contain all the information pre-filled:\r\n\r\n![captura de pantalla_2018-01-22_15-07-15](https://user-images.githubusercontent.com/244656/35242041-6ed4e288-ff86-11e7-9b89-c69a45505318.png)\r\n\r\n\r\nI found that github supports _some_ query arguments in the URL but I didn't found a way to use those key/args inside the template itself.\r\n\r\nhttps://help.github.com/articles/about-automation-for-issues-and-pull-requests-with-query-parameters/\r\n\r\nI think it would be awesome if the user can just click a link and the username, project url, etc could be pre-filled automatically.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"Views for builds app.\"\"\"\n\nimport logging\n\nfrom django.contrib import messages\nfrom django.contrib.auth.decorators import login_required\nfrom django.http import (\n    HttpResponseForbidden,\n    HttpResponsePermanentRedirect,\n    HttpResponseRedirect,\n)\nfrom django.shortcuts import get_object_or_404\nfrom django.urls import reverse\nfrom django.utils.decorators import method_decorator\nfrom django.views.generic import DetailView, ListView\n\nfrom readthedocs.builds.models import Build, Version\nfrom readthedocs.core.permissions import AdminPermission\nfrom readthedocs.core.utils import trigger_build\nfrom readthedocs.projects.models import Project\n\n\nlog = logging.getLogger(__name__)\n\n\nclass BuildBase:\n    model = Build\n\n    def get_queryset(self):\n        self.project_slug = self.kwargs.get('project_slug', None)\n        self.project = get_object_or_404(\n            Project.objects.protected(self.request.user),\n            slug=self.project_slug,\n        )\n        queryset = Build.objects.public(\n            user=self.request.user,\n            project=self.project,\n        )\n\n        return queryset\n\n\nclass BuildTriggerMixin:\n\n    @method_decorator(login_required)\n    def post(self, request, project_slug):\n        project = get_object_or_404(Project, slug=project_slug)\n\n        if not AdminPermission.is_admin(request.user, project):\n            return HttpResponseForbidden()\n\n        version_slug = request.POST.get('version_slug')\n        version = get_object_or_404(\n            Version,\n            project=project,\n            slug=version_slug,\n        )\n\n        update_docs_task, build = trigger_build(\n            project=project,\n            version=version,\n        )\n        if (update_docs_task, build) == (None, None):\n            # Build was skipped\n            messages.add_message(\n                request,\n                messages.WARNING,\n                \"This project is currently disabled and can't trigger new builds.\",\n            )\n            return HttpResponseRedirect(\n                reverse('builds_project_list', args=[project.slug]),\n            )\n\n        return HttpResponseRedirect(\n            reverse('builds_detail', args=[project.slug, build.pk]),\n        )\n\n\nclass BuildList(BuildBase, BuildTriggerMixin, ListView):\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n\n        active_builds = self.get_queryset().exclude(\n            state='finished',\n        ).values('id')\n\n        context['project'] = self.project\n        context['active_builds'] = active_builds\n        context['versions'] = Version.objects.public(\n            user=self.request.user,\n            project=self.project,\n        )\n        context['build_qs'] = self.get_queryset()\n\n        return context\n\n\nclass BuildDetail(BuildBase, DetailView):\n    pk_url_kwarg = 'build_pk'\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n        context['project'] = self.project\n        return context\n\n\n# Old build view redirects\n\n\ndef builds_redirect_list(request, project_slug):  # pylint: disable=unused-argument\n    return HttpResponsePermanentRedirect(\n        reverse('builds_project_list', args=[project_slug]),\n    )\n\n\ndef builds_redirect_detail(request, project_slug, pk):  # pylint: disable=unused-argument\n    return HttpResponsePermanentRedirect(\n        reverse('builds_detail', args=[project_slug, pk]),\n    )\n", "path": "readthedocs/builds/views.py"}]}