internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: kartoza/prj.app

Issue:
Sponsors map should be switchable between sponsor count per country and income per country
See also #264



Discussion:

Resolving patch:
diff --git a/django_project/changes/views/sponsor.py b/django_project/changes/views/sponsor.py
--- a/django_project/changes/views/sponsor.py
+++ b/django_project/changes/views/sponsor.py
@@ -19,6 +19,7 @@
 from django.http import HttpResponseRedirect, Http404
 from django.db import IntegrityError
 from django.core.exceptions import ValidationError
+from django.core import serializers
 from braces.views import LoginRequiredMixin, StaffuserRequiredMixin
 from pure_pagination.mixins import PaginationMixin
 
@@ -163,6 +164,26 @@ class SponsorWorldMapView(SponsorMixin, ListView):
     context_object_name = 'sponsors'
     template_name = 'sponsor/world-map.html'
 
+    def get_context_data(self, **kwargs):
+        """Get the context data which is passed to a template.
+
+        :param kwargs: Any arguments to pass to the superclass.
+        :type kwargs: dict
+
+        :returns: Context data which will be passed to the template.
+        :rtype: dict
+        """
+        project_slug = self.kwargs.get('project_slug', None)
+        context = super(SponsorWorldMapView, self).get_context_data(**kwargs)
+        if project_slug:
+            project = Project.objects.get(slug=project_slug)
+            levels = SponsorshipLevel.objects.filter(project=project)
+            context['levels'] = serializers.serialize(
+                "json",
+                levels
+            )
+        return context
+
     def get_queryset(self, queryset=None):
         """Get the queryset for this view.
 


Test patch:
diff --git a/django_project/changes/tests/test_views.py b/django_project/changes/tests/test_views.py
--- a/django_project/changes/tests/test_views.py
+++ b/django_project/changes/tests/test_views.py
@@ -790,7 +790,7 @@ def test_SponsorListView(self):
         }))
         self.assertEqual(response.status_code, 200)
 
-    def test_SponsorListView(self):
+    def test_SponsorWorldMapView(self):
 
         response = self.client.get(reverse('sponsor-world-map', kwargs={
             'project_slug': self.project.slug
Repository: kartoza/prj.app

Issue:
Sponsors world map should be navigable via Project menu
See also #264 



Discussion:

Resolving patch:
diff --git a/django_project/changes/views/sponsor.py b/django_project/changes/views/sponsor.py
--- a/django_project/changes/views/sponsor.py
+++ b/django_project/changes/views/sponsor.py
@@ -163,6 +163,21 @@ class SponsorWorldMapView(SponsorMixin, ListView):
     context_object_name = 'sponsors'
     template_name = 'sponsor/world-map.html'
 
+    def get_context_data(self, **kwargs):
+        """Get the context data which is passed to a template.
+
+        :param kwargs: Any arguments to pass to the superclass.
+        :type kwargs: dict
+
+        :returns: Context data which will be passed to the template.
+        :rtype: dict
+        """
+        context = super(SponsorWorldMapView, self).get_context_data(**kwargs)
+        project_slug = self.kwargs.get('project_slug', None)
+        if project_slug:
+            context['the_project'] = Project.objects.get(slug=project_slug)
+        return context
+
     def get_queryset(self, queryset=None):
         """Get the queryset for this view.
 


Test patch:
Repository: kartoza/prj.app

Issue:
Sponsor urls should be plural
<project>/sponsor/??? should be <project>/sponsors/??? except in cases where the view references a single sponsor



Discussion:

Resolving patch:
diff --git a/django_project/changes/urls.py b/django_project/changes/urls.py
--- a/django_project/changes/urls.py
+++ b/django_project/changes/urls.py
@@ -196,16 +196,16 @@
     url(regex='^json-sponsor/list/(?P<version>\d+)/$',
         view=JSONSponsorListView.as_view(),
         name='json-sponsor-list'),
-    url(regex='^(?P<project_slug>[\w-]+)/pending-sponsor/list/$',
+    url(regex='^(?P<project_slug>[\w-]+)/pending-sponsors/list/$',
         view=PendingSponsorListView.as_view(),
         name='pending-sponsor-list'),
     url(regex='^(?P<project_slug>[\w-]+)/approve-sponsor/(?P<slug>[\w-]+)/$',
         view=ApproveSponsorView.as_view(),
         name='sponsor-approve'),
-    url(regex='^(?P<project_slug>[\w-]+)/sponsor/list/$',
+    url(regex='^(?P<project_slug>[\w-]+)/sponsors/list/$',
         view=SponsorListView.as_view(),
         name='sponsor-list'),
-    url(regex='^(?P<project_slug>[\w-]+)/sponsor/world-map/$',
+    url(regex='^(?P<project_slug>[\w-]+)/sponsors/world-map/$',
         view=SponsorWorldMapView.as_view(),
         name='sponsor-world-map'),
     url(regex='^(?P<project_slug>[\w-]+)/sponsor/(?P<slug>[\w-]+)/$',


Test patch:
Repository: kartoza/prj.app

Issue:
We need to support animated GIF's
Using licecap or silentcast it is easy to make animated GIF's. When images are uploaded to django though they are resized and converted to PNG. We need to update the logic so thumbs etc. can be created for animate GIF's without losing the animation. 



Discussion:

Resolving patch:
diff --git a/django_project/base/templatetags/custom_markup.py b/django_project/base/templatetags/custom_markup.py
--- a/django_project/base/templatetags/custom_markup.py
+++ b/django_project/base/templatetags/custom_markup.py
@@ -16,3 +16,9 @@ def base_markdown(value):
                                        extensions,
                                        safe_mode=True,
                                        enable_attributes=False))
+
+
+@register.filter(name='is_gif', is_safe=True)
+@stringfilter
+def is_gif(value):
+    return value[-4:] == '.gif'


Test patch:
Repository: kartoza/prj.app

Issue:
In the pending approval menu, only show menu items that have pending approvals
The **Pending approval** menu should be filtered to show only items in the active project where there are pending approvals.



Discussion:

Resolving patch:
diff --git a/django_project/core/custom_middleware.py b/django_project/core/custom_middleware.py
--- a/django_project/core/custom_middleware.py
+++ b/django_project/core/custom_middleware.py
@@ -3,7 +3,8 @@
 """
 core.custom_middleware
 """
-from base.models import Project
+from base.models import Project, Version
+from changes.models import Category, SponsorshipLevel, SponsorshipPeriod
 
 
 class NavContextMiddleware(object):
@@ -34,6 +35,15 @@ def process_template_response(request, response):
 
         if context.get('project', None):
             context['the_project'] = context.get('project')
+            context['has_pending_versions'] = Version.unapproved_objects.filter(
+                project=context.get('project')).exists()
+            context['has_pending_categories'] = Category.unapproved_objects.filter(
+                project=context.get('project')).exists()
+            context['has_pending_sponsor_lvl'] = SponsorshipLevel.unapproved_objects.filter(
+                project=context.get('project')).exists()
+            context['has_pending_sponsor_period'] = SponsorshipPeriod.unapproved_objects.filter(
+                project=context.get('project')).exists()
+
         else:
             if request.user.is_staff:
                 context['the_projects'] = Project.objects.all()


Test patch:
Repository: kartoza/prj.app

Issue:
More menu navigation cleanups
<img width="834" alt="screen shot 2016-06-22 at 00 00 38" src="https://cloud.githubusercontent.com/assets/178003/16247917/6d784382-380c-11e6-91f6-29423d263b8c.png">
- [ ] Make project icon and name clickable - click should take you to e.g. /en/qgis/
- [ ] Changelogs -> Changelog
- [ ] Remove version entries item
- [ ] Remove version thumbnails item
- [ ] Remove add entry item



Discussion:

Resolving patch:
diff --git a/django_project/base/templatetags/custom_markup.py b/django_project/base/templatetags/custom_markup.py
--- a/django_project/base/templatetags/custom_markup.py
+++ b/django_project/base/templatetags/custom_markup.py
@@ -22,3 +22,17 @@ def base_markdown(value):
 @stringfilter
 def is_gif(value):
     return value[-4:] == '.gif'
+
+
+@register.inclusion_tag('button_span.html', takes_context=True)
+def show_button_icon(context, value):
+
+    context_icon = {
+        'add': 'glyphicon glyphicon-asterisk',
+        'update': 'glyphicon glyphicon-pencil',
+        'delete': 'glyphicon glyphicon-minus'
+    }
+
+    return {
+        'button_icon': context_icon[value]
+    }


Test patch:
Repository: kartoza/prj.app

Issue:
Order sponsors in their groups
From @andreasneumann: 

```For the sponsors listing - is there a clear order within the same level at http://changelog.qgis.org/en/qgis/version/2.16.0/ ?

In my opinion, it should either be ordered alphabetically or by date. Neither seems to be the case. I would prefer alphabetic ordering with in each sponsorship level.```

I think it is actually better to order them with most recently added sponsors first to oldest sponsors last. That we they get the most visibility when they are new, degrading over time to the bottom of the list. What do you think @andreasneumann ?



Discussion:
I had a look at the code - we are already wording sponsors by date they became sponsors which seems the most logical to me. Maybe we should add a sort button to let you sort it according to your preferred criteria?

Really?

I don't think that http://changelog.qgis.org/en/qgis/version/2.16.0/ does match a date order. In what order? Rows first, or columns first? Or vice versa? Oldest or newest? By renewal date or first registration date? I can't see any logical temporal order there.

I would just do alphabetical order - seems more logical to me than date orders.

@andreasneumann hoo sorry you are right - I looked again at the code:

https://github.com/kartoza/projecta/blob/develop/django_project/changes/models/version.py#L205

I will fix it. 

Ok how does this look?

![screen shot 2016-07-07 at 10 20 00 am](https://cloud.githubusercontent.com/assets/178003/16646798/70afc56c-442c-11e6-86dc-158ecb1ba8ec.png)

By the way I removed a lot of the detail around each sponsor so the sponsor cloud is less cluttered and fits in a smaller space...(done in a previous commit)


Resolving patch:
diff --git a/django_project/changes/models/version.py b/django_project/changes/models/version.py
--- a/django_project/changes/models/version.py
+++ b/django_project/changes/models/version.py
@@ -202,7 +202,7 @@ def sponsors(self):
                 start_date__lte=self.release_date).filter(
                 project=self.project).order_by(
             'start_date').order_by(
-            '-sponsorship_level__value')
+            '-sponsorship_level__value', 'sponsor__name')
         return sponsors
 
     def formatted_release_date(self):


Test patch:
Repository: kartoza/prj.app

Issue:
Display thumbnails in a modal window when we click on fullscreen
We can see a lot of GIF in the QGIS changelog. These thumbnails are too small to see so I have to click on the button to see it fullscreen. For now, it redirects to the GIF url like http://changelog.qgis.org/media/images/entries/53f72a9cf1bf32d73eb5174c37e54c60002b9707.gif
The user needs to use the "previous" button in the web browser to come back to the changelog.

It would be better to implement a javascript modal window to show the GIF and to stay on the URL http://changelog.qgis.org/en/qgis/version/2.16.0/



Discussion:
Yes good idea. Maybe you would like to make a patch yourself using this:

http://www.w3schools.com/bootstrap/bootstrap_modal.asp

Here is the place to add logic:

https://github.com/kartoza/projecta/blob/develop/django_project/changes/templates/entry/includes/entry_detail.html#L37

I guess we should do it not only for GIF's but for any image....


Resolving patch:
diff --git a/django_project/core/settings/project.py b/django_project/core/settings/project.py
--- a/django_project/core/settings/project.py
+++ b/django_project/core/settings/project.py
@@ -55,7 +55,8 @@
     'source_filenames': (
         'js/csrf-ajax.js',
         'js/changelog.js',
-        'js/github-issue.js'
+        'js/github-issue.js',
+        'js/entry.js',
     ),
     'output_filename': 'js/project.js',
 }


Test patch:
Repository: kartoza/prj.app

Issue:
Projecta reveals personal data without login
I noticed that one can view personal data on Projecta without logging in - see f.e. http://changelog.qgis.org/en/qgis/sponsor/uhcnwf/ which reveals person names and E-Mail addresses without a Login. I think this should be avoided and should only be viewed after  #login.



Discussion:
@dimasciput can you fix this with highest priority?


Resolving patch:
diff --git a/django_project/changes/views/sponsor.py b/django_project/changes/views/sponsor.py
--- a/django_project/changes/views/sponsor.py
+++ b/django_project/changes/views/sponsor.py
@@ -212,6 +212,22 @@ class SponsorDetailView(SponsorMixin, DetailView):
     context_object_name = 'sponsor'
     template_name = 'sponsor/detail.html'
 
+    def get_context_data(self, **kwargs):
+        """Get the context data which is passed to a template.
+
+        :param kwargs: Any arguments to pass to the superclass.
+        :type kwargs: dict
+
+        :returns: Context data which will be passed to the template.
+        :rtype: dict
+        """
+        context = super(SponsorDetailView, self).get_context_data(**kwargs)
+        project_slug = self.kwargs.get('project_slug', None)
+        context['project_slug'] = project_slug
+        if project_slug:
+            context['the_project'] = Project.objects.get(slug=project_slug)
+        return context
+
     def get_queryset(self):
         """Get the queryset for this view.
 
diff --git a/django_project/changes/views/version.py b/django_project/changes/views/version.py
--- a/django_project/changes/views/version.py
+++ b/django_project/changes/views/version.py
@@ -131,7 +131,6 @@ def get_context_data(self, **kwargs):
         context['project_slug'] = project_slug
         if project_slug:
             context['project'] = Project.objects.get(slug=project_slug)
-            
         return context
 
     def get_queryset(self):


Test patch:
Repository: kartoza/prj.app

Issue:
Redundant text in categories list
We can remove the project name above each category since it is a list that is filtered by the project. And we can make the text of the categories a little smaller...

![screen shot 2016-07-22 at 12 09 13 am](https://cloud.githubusercontent.com/assets/178003/17031883/9e0ca9a6-4fa0-11e6-8b0d-74e40ee8d4d6.png)



Discussion:

Resolving patch:
diff --git a/django_project/changes/views/category.py b/django_project/changes/views/category.py
--- a/django_project/changes/views/category.py
+++ b/django_project/changes/views/category.py
@@ -127,7 +127,7 @@ def get_queryset(self):
         return qs
 
 
-class CategoryListView(CategoryMixin, ListView):
+class CategoryListView(CategoryMixin, StaffuserRequiredMixin, ListView):
     """List view for Category."""
     context_object_name = 'categories'
     template_name = 'category/list.html'
diff --git a/django_project/core/settings/project.py b/django_project/core/settings/project.py
--- a/django_project/core/settings/project.py
+++ b/django_project/core/settings/project.py
@@ -57,6 +57,7 @@
         'js/changelog.js',
         'js/github-issue.js',
         'js/entry.js',
+        'js/category.js',
     ),
     'output_filename': 'js/project.js',
 }


Test patch:
diff --git a/django_project/changes/tests/test_views.py b/django_project/changes/tests/test_views.py
--- a/django_project/changes/tests/test_views.py
+++ b/django_project/changes/tests/test_views.py
@@ -58,13 +58,7 @@ def test_CategoryListView(self):
         response = self.client.get(reverse('category-list', kwargs={
             'project_slug': self.project.slug
         }))
-        self.assertEqual(response.status_code, 200)
-        expected_templates = [
-            'category/list.html', u'changes/category_list.html'
-        ]
-        self.assertEqual(response.template_name, expected_templates)
-        self.assertEqual(response.context_data['object_list'][0],
-                         self.category)
+        self.assertEqual(response.status_code, 302)
 
     def test_CategoryCreateView_with_login(self):
Repository: kartoza/prj.app

Issue:
Error download sponsor and rst for authenticated but non staff user
When I try to download sponsor as an authenticated but not staff user I got this error : 
`Failed to load resource: net::ERR_TOO_MANY_REDIRECTS`



Discussion:

Resolving patch:
diff --git a/django_project/changes/views/version.py b/django_project/changes/views/version.py
--- a/django_project/changes/views/version.py
+++ b/django_project/changes/views/version.py
@@ -43,6 +43,19 @@ class VersionMixin(object):
     form_class = VersionForm
 
 
+class CustomStaffuserRequiredMixin(StaffuserRequiredMixin):
+    """Fix redirect loop when user is already authenticated but non staff"""
+
+    def no_permissions_fail(self, request=None):
+        """
+        Called when the user has no permissions and no exception was raised.
+        """
+        if not request.user.is_authenticated():
+            return super(CustomStaffuserRequiredMixin, self).no_permissions_fail(request)
+
+        raise Http404('Sorry! You have to be staff to open this page.')
+
+
 class VersionListView(VersionMixin, PaginationMixin, ListView):
     """List view for Version."""
     context_object_name = 'versions'
@@ -562,7 +575,7 @@ def get_redirect_url(self, project_slug, slug):
         })
 
 
-class VersionDownload(VersionMixin, StaffuserRequiredMixin, DetailView):
+class VersionDownload(VersionMixin, CustomStaffuserRequiredMixin, DetailView):
     """View to allow staff users to download Version page in RST format"""
     template_name = 'version/detail-content.html'
 
@@ -733,7 +746,7 @@ def get(self, request, *args, **kwargs):
             content_type="text/plain; charset=utf-8")
 
 
-class VersionSponsorDownload(VersionMixin, StaffuserRequiredMixin, DetailView):
+class VersionSponsorDownload(VersionMixin, CustomStaffuserRequiredMixin, DetailView):
     """View to allow staff users to download Version page in html format"""
     template_name = 'version/includes/version-sponsors.html'
 


Test patch:
Repository: kartoza/prj.app

Issue:
Accepting the last entry in the pending list should redirect you to the version page

Order sponsors in their groups
From @andreasneumann: 

```For the sponsors listing - is there a clear order within the same level at http://changelog.qgis.org/en/qgis/version/2.16.0/ ?

In my opinion, it should either be ordered alphabetically or by date. Neither seems to be the case. I would prefer alphabetic ordering with in each sponsorship level.```

I think it is actually better to order them with most recently added sponsors first to oldest sponsors last. That we they get the most visibility when they are new, degrading over time to the bottom of the list. What do you think @andreasneumann ?



Discussion:

Resolving patch:
diff --git a/django_project/changes/views/version.py b/django_project/changes/views/version.py
--- a/django_project/changes/views/version.py
+++ b/django_project/changes/views/version.py
@@ -627,8 +627,8 @@ def render_to_response(self, context, **response_kwargs):
         )
         # convert the html to rst
         converted_doc = pypandoc.convert(
-            document.rendered_content.encode(
-                'utf8', 'ignore'), 'rst', format='html', extra_args=['--no-wrap'])
+            document.rendered_content.encode('utf8', 'ignore'),
+            'rst', format='html', extra_args=['--no-wrap'])
         converted_doc = converted_doc.replace('/media/images/', 'images/')
 
         # prepare the ZIP file
@@ -648,6 +648,7 @@ def render_to_response(self, context, **response_kwargs):
     # noinspection PyMethodMayBeStatic
     def _prepare_zip_archive(self, document, version_obj):
         """Prepare a ZIP file with the document and referenced images.
+
         :param document:
         :param version_obj: Instance of a version object.
 


Test patch:
Repository: kartoza/prj.app

Issue:
Cannot add new sponsor
I tried adding new sponsors to the QGIS sponsors list, but got the following error:

500
Ooops. Something broke....

The powers that be have been informed.
In the meantime, please form an orderly queue and head to the home page.

If you need assistance, you may reference this error as 1f96dfdab8c642789dcb40867a97e90d.

I used foreign characters, f.e. "ü" and "é" in the contact names, if that matters.



Discussion:

Resolving patch:
diff --git a/django_project/base/models/project.py b/django_project/base/models/project.py
--- a/django_project/base/models/project.py
+++ b/django_project/base/models/project.py
@@ -14,6 +14,7 @@
 from django.contrib.auth.models import User
 from django.conf import settings
 from django.core.exceptions import ValidationError
+from unidecode import unidecode
 
 logger = logging.getLogger(__name__)
 
@@ -128,7 +129,8 @@ def save(self, *args, **kwargs):
         if not self.pk:
             words = self.name.split()
             filtered_words = [t for t in words if t.lower() not in STOP_WORDS]
-            new_list = unicode(' '.join(filtered_words))
+            # unidecode() represents special characters (unicode data) in ASCII
+            new_list = unidecode(' '.join(filtered_words))
             self.slug = slugify(new_list)[:50]
 
         super(Project, self).save(*args, **kwargs)
diff --git a/django_project/changes/models/sponsor.py b/django_project/changes/models/sponsor.py
--- a/django_project/changes/models/sponsor.py
+++ b/django_project/changes/models/sponsor.py
@@ -10,6 +10,8 @@
 from django.utils.translation import ugettext_lazy as _
 from django.contrib.auth.models import User
 from django_countries.fields import CountryField
+from unidecode import unidecode
+
 
 __author__ = 'rischan'
 
@@ -120,7 +122,8 @@ def save(self, *args, **kwargs):
         if not self.pk:
             words = self.name.split()
             filtered_words = [t for t in words if t.lower() not in STOP_WORDS]
-            new_list = ' '.join(filtered_words)
+            # unidecode() represents special characters (unicode data) in ASCII
+            new_list = unidecode(' '.join(filtered_words))
             self.slug = slugify(new_list)[:50]
         super(Sponsor, self).save(*args, **kwargs)
 


Test patch:
diff --git a/django_project/base/tests/test_models.py b/django_project/base/tests/test_models.py
--- a/django_project/base/tests/test_models.py
+++ b/django_project/base/tests/test_models.py
@@ -92,3 +92,14 @@ def test_gitter_validation(self):
                 model.save()
 
         self.assertEqual(Project.objects.filter(gitter_room='invalid').count(), 0)
+
+    def test_unidecode(self):
+        """
+        Tests unidecode() to represent special characters into ASCII
+        """
+        model = ProjectF.create(
+            name = u'straße',
+        )
+
+        # check if properly decoded into ASCII
+        self.assertTrue(model.slug == "strasse")