internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: dotkom/onlineweb4

Issue:
Newly added "bio" fields have rendering issues
In the regular Profile "Overview", the Bio fields prints `None` if empty, when it should be an empty string.
Additionally, it repeats the contents of the bio fields 4x on this page. 

On the public profile page however, it renders the contents only one time, albeit only using 1/3 of the recommended page-width, as well as missing some row-spacing.



Discussion:
Also the Bio edit field in "Edit my profile" should be much more expanded by default.
A 10-row ish height set on the <textarea> should suffice.

```
{% if forloop.first %}
    <div class="col-md-8" id="bio">
        {% firstof user.bio|striptags 'Ikke tiljengelig...' %}
    </div>
{% endif %}
```

Kan nok være til hjelp forresten 


Resolving patch:
diff --git a/apps/authentication/migrations/0009_auto_20151016_2033.py b/apps/authentication/migrations/0009_auto_20151016_2033.py
new file mode 100644
--- /dev/null
+++ b/apps/authentication/migrations/0009_auto_20151016_2033.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('authentication', '0008_auto_20151014_2156'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='onlineuser',
+            name='bio',
+            field=models.TextField(default='', verbose_name='bio', blank=True),
+            preserve_default=False,
+        ),
+    ]
diff --git a/apps/authentication/models.py b/apps/authentication/models.py
--- a/apps/authentication/models.py
+++ b/apps/authentication/models.py
@@ -108,7 +108,7 @@ class OnlineUser(AbstractUser):
     nickname = models.CharField(_(u"nickname"), max_length=50, blank=True, null=True)
     website = models.URLField(_(u"hjemmeside"), blank=True, null=True)
     gender = models.CharField(_(u"kjønn"), max_length=10, choices=GENDER_CHOICES, default="male")
-    bio = models.TextField(_(u"bio"), blank=True, null=True)
+    bio = models.TextField(_(u"bio"), blank=True)
 
     # NTNU credentials
     ntnu_username = models.CharField(_(u"NTNU-brukernavn"), max_length=10, blank=True, null=True, unique=True)
diff --git a/apps/profiles/forms.py b/apps/profiles/forms.py
--- a/apps/profiles/forms.py
+++ b/apps/profiles/forms.py
@@ -16,6 +16,7 @@ class Meta:
         widgets = {
             'allergies' : forms.Textarea(attrs={'id' : 'allergies'}),
             'gender' : forms.Select(attrs={'class' : 'form-control'}),
+            'bio' : forms.Textarea(attrs={'id' : 'bio'}),
         }
 
     def clean(self):


Test patch:
Repository: dotkom/onlineweb4

Issue:
Users with many allergies or long text overflows their cell in the pdf
Example from prod can be seen on Immball 2015.



Discussion:

Resolving patch:
diff --git a/apps/events/pdf_generator.py b/apps/events/pdf_generator.py
--- a/apps/events/pdf_generator.py
+++ b/apps/events/pdf_generator.py
@@ -6,6 +6,8 @@
 from reportlab.lib import colors
 from reportlab.lib.styles import getSampleStyleSheet
 
+from textwrap import wrap
+
 class EventPDF(object):
 
     event = None
@@ -53,7 +55,9 @@ def create_attendees_table_data(self):
                 i += 1
                 self.full_span_attendee_lines.append(i) 
             if user.allergies:
-                self.allergies_table_data.append((user.allergies, user.get_full_name(),))
+                # Breaks the line every 60th character
+                allergies = "\n".join(wrap(user.allergies, width=60))
+                self.allergies_table_data.append((allergies, user.get_full_name(),))
 
             i += 1
 
@@ -75,7 +79,9 @@ def create_waiters_table_data(self):
                 i += 1
                 self.full_span_waiters_lines.append(i) 
             if user.allergies:
-                self.allergies_table_data.append((user.allergies, user.get_full_name(),))
+                # Breaks the line every 60th character
+                allergies = "\n".join(wrap(user.allergies, width=60))
+                self.allergies_table_data.append((allergies, user.get_full_name(),))
 
             i += 1
 


Test patch:
Repository: dotkom/onlineweb4

Issue:
Separate requirements in develop, testing and production
We should separate requirements for various environments. What sparked this was requiring some postgresql magic to install all requirements (`psycopg2`), and e.g. moonshine does not want postgres just for tests to pass (or run, for that matter).

Requirements that should be removed from `requirements.txt` and added to `requirements-<env>.txt`:
#### Production requirements [src](https://github.com/dotKom/onlineweb4/blob/develop/requirements.txt#L9):
- `psycopg2` (yes, some people use postgres in development. However, example-local.py uses sqlite and most people will therefore not need this package. *1)
#### Testing requirements [src](https://github.com/dotKom/onlineweb4/blob/develop/requirements.txt#L38):
- `cov-core`
- `coverage`
- `django-nose`
- `factory-boy`
- `lettuce`
- `nose` *2
- `nose-cov`
- `teamcity-messages`
#### Development requirements (these can be/should be fully optional)
- `django-debug-toolbar` (it's not in `requirements.txt` as of now, but maybe it should? [wiki](https://github.com/dotKom/onlineweb4/wiki/Django-debug-toolbar))

*1: It also fails to install and stops requirements.txt installation if people don't have postgresql dev headers ([ex.](https://online.ntnu.no/tc/viewLog.html?tab=buildLog&buildTypeId=Onlineweb4_Build&buildId=29))
*2: If we remove this one we have to change default runner class in base settings as the current testrunner is nose.



Discussion:
Good idea! :dancer: 

Move to production: 
- gunicorn (only used as a http server in production)
- python-memcached (only used in a management script I doubt anyone runs in development anyway). 

I think the following can be removed:
- wsgiref (old production http server?)
- werkzeug (why is this even in requirements?)


Resolving patch:
diff --git a/onlineweb4/settings/base.py b/onlineweb4/settings/base.py
--- a/onlineweb4/settings/base.py
+++ b/onlineweb4/settings/base.py
@@ -219,7 +219,6 @@
     'compressor',
     'pdfdocument',
     'watson',
-    'gunicorn',
     'markdown_deux',
     'djangoformsetjs',
     'reversion',


Test patch:
Repository: dotkom/onlineweb4

Issue:
Remove paymentrelation when a user is manually removed from an event.
Users that was booted by admins from an event got a mark and got removed from the waitinglist when the deadline of the paymentrelation object was reached.

The object needs to be removed when a user is manually removed from an event.



Discussion:

Resolving patch:
diff --git a/apps/events/models.py b/apps/events/models.py
--- a/apps/events/models.py
+++ b/apps/events/models.py
@@ -727,6 +727,17 @@ class Attendee(models.Model):
     def __unicode__(self):
         return self.user.get_full_name()
 
+    def delete(self):
+        #Importing here to prevent circular dependencies
+        from apps.payment.models import PaymentDelay
+        try:
+            PaymentDelay.objects.filter(user=self.user, payment=self.event.payment).delete()
+        except PaymentDelay.DoesNotExist:
+            #Do nothing
+            False
+
+        super(Attendee, self).delete()
+
     class Meta:
         ordering = ['timestamp']
         unique_together = (('event', 'user'),)


Test patch:
Repository: dotkom/onlineweb4

Issue:
Move bedkom / fagkom syncer logic to the dashboard
Trigger the sync code when a user adds or removes users from groups instead of using a mommy script.

The syncer mommy script clogs the loggs and makes it harder to debug other things



Discussion:
This could possibly be fixed by setting the level of syncer logs to WARN? https://github.com/dotKom/onlineweb4/blob/develop/onlineweb4/settings/example-local.py#L139

`Clogs the logs`. That is just silly. Log everything. Always.


Resolving patch:
diff --git a/apps/authentication/appconfig.py b/apps/authentication/appconfig.py
--- a/apps/authentication/appconfig.py
+++ b/apps/authentication/appconfig.py
@@ -4,3 +4,9 @@
 class AuthenticationConfig(AppConfig):
     name = 'apps.authentication'
     verbose_name = 'Authentication for OW4'
+
+    def ready(self):
+        super(AuthenticationConfig, self).ready()
+        # The following stops pycharm from nagging about unused import statement
+        # noinspection PyUnresolvedReferences
+        import apps.authentication.signals
diff --git a/apps/authentication/signals.py b/apps/authentication/signals.py
new file mode 100644
--- /dev/null
+++ b/apps/authentication/signals.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from django.conf import settings
+from django.contrib.auth.models import Group
+from django.db.models.signals import post_save
+from django.dispatch import receiver
+
+from apps.authentication.tasks import SynchronizeGroups
+
+
+@receiver(post_save, sender=Group)
+def trigger_group_syncer(sender, instance, created, **kwargs):
+    """
+    :param sender: The model that triggered this hook
+    :param instance: The model instance triggering this hook
+    :param created: True if the instance was created, False if the instance was updated
+
+    Calls the SynchronizeGroups Task if a group is updated. (Not if it's the initial creation of a group)
+    """
+
+    if created:
+        # If a new instance is created, we do not need to trigger group sync.
+        pass
+    else:
+        SynchronizeGroups.run()
diff --git a/apps/authentication/mommy.py b/apps/authentication/tasks.py
similarity index 93%
rename from apps/authentication/mommy.py
rename to apps/authentication/tasks.py
--- a/apps/authentication/mommy.py
+++ b/apps/authentication/tasks.py
@@ -15,9 +15,14 @@ class SynchronizeGroups(Task):
     @staticmethod
     def run():
         logger = logging.getLogger('syncer')
-        locale.setlocale(locale.LC_ALL, 'en_US.utf8')
 
-        SynchronizeGroups.do_sync(logger)
+        if not hasattr(settings, "GROUP_SYNCER"):
+            # Make sure to only run the group syncer if we have the settings for it
+            logger.info("GROUP_SYNCER setting not set, not syncing groups")
+        else:
+            locale.setlocale(locale.LC_ALL, 'en_US.utf8')
+
+            SynchronizeGroups.do_sync(logger)
 
     @staticmethod
     def do_sync(logger):
@@ -108,6 +113,3 @@ def do_sync(logger):
                         ' because they were not in the source group(s).'
                     )
 
-
-# Register scheduler
-schedule.register(SynchronizeGroups, day_of_week='mon-sun', minute='*/15')


Test patch:
Repository: dotkom/onlineweb4

Issue:
Users attending events that are group restricted should be able to see them
With closed events for groups (like julebord), some users may get added to them that are not specifically in the list of allowed groups. This can happen in many ways, but these users should also be able to see these events as if they were part of these groups while they are listed as attending.

Either that or allow them to pay for the events in some other way.



Discussion:

Resolving patch:
diff --git a/apps/events/views.py b/apps/events/views.py
--- a/apps/events/views.py
+++ b/apps/events/views.py
@@ -421,7 +421,8 @@ class EventViewSet(viewsets.GenericViewSet, mixins.RetrieveModelMixin, mixins.Li
 
     def get_queryset(self):
         return Event.objects.filter(
-            Q(group_restriction__isnull=True) | Q(group_restriction__groups__in=self.request.user.groups.all())).\
+            Q(group_restriction__isnull=True) | Q(group_restriction__groups__in=self.request.user.groups.all()) |
+            (Q(attendance_event__isnull=False) & Q(attendance_event__attendees__user=self.request.user))).\
             distinct()
 
 


Test patch:
Repository: dotkom/onlineweb4

Issue:
Option to post video in article
Make it possible to post video in article from dashboard.



Discussion:
Also add some help texts to explain the behaviour of images/video, since the image is still required if you wish to use video in the article.


Resolving patch:
diff --git a/apps/article/dashboard/forms.py b/apps/article/dashboard/forms.py
--- a/apps/article/dashboard/forms.py
+++ b/apps/article/dashboard/forms.py
@@ -22,6 +22,7 @@ class Meta(object):
             'ingress',
             'content',
             'image',
+            'video',
             'published_date',
             'authors',
             'tags',


Test patch:
Repository: dotkom/onlineweb4

Issue:
Users attending events that are group restricted should be able to see them
With closed events for groups (like julebord), some users may get added to them that are not specifically in the list of allowed groups. This can happen in many ways, but these users should also be able to see these events as if they were part of these groups while they are listed as attending.

Either that or allow them to pay for the events in some other way.



Discussion:

Resolving patch:
diff --git a/apps/events/views.py b/apps/events/views.py
--- a/apps/events/views.py
+++ b/apps/events/views.py
@@ -421,8 +421,7 @@ class EventViewSet(viewsets.GenericViewSet, mixins.RetrieveModelMixin, mixins.Li
 
     def get_queryset(self):
         return Event.objects.filter(
-            Q(group_restriction__isnull=True) | Q(group_restriction__groups__in=self.request.user.groups.all()) |
-            (Q(attendance_event__isnull=False) & Q(attendance_event__attendees__user=self.request.user))).\
+            Q(group_restriction__isnull=True) | Q(group_restriction__groups__in=self.request.user.groups.all())).\
             distinct()
 
 


Test patch:
Repository: dotkom/onlineweb4

Issue:
SplashYear matching query does not exist
https://github.com/dotKom/onlineweb4/blob/develop/apps/splash/models.py#L11 tries to get a SplashYear, but there are no objects matching the query, so it triggers an exception. 

> DoesNotExist: SplashYear matching query does not exist.

How to quick-fix: Create a SplashYear which satisfies the matching query.



Discussion:
IMO this should be properly fixed so we don't get the same errors next year.
Should be a pretty easy fix.


Resolving patch:
diff --git a/apps/events/utils.py b/apps/events/utils.py
--- a/apps/events/utils.py
+++ b/apps/events/utils.py
@@ -170,7 +170,7 @@ def add_event(self, event):
         self.cal.add_component(cal_event)
 
     def events(self):
-        self.add_events(SplashYear.objects.current().splash_events.all())
+        self.add_events(SplashYear.objects.current_events())
         self.filename = 'events'
 
 
diff --git a/apps/splash/models.py b/apps/splash/models.py
--- a/apps/splash/models.py
+++ b/apps/splash/models.py
@@ -8,7 +8,14 @@
 class SplashYearManager(models.Manager):
     def current(self):
         # I'm really sorry ...
-        return self.get(start_date__gt=str(datetime.date.today() - datetime.timedelta(180)))
+        half_a_year_ago = str(datetime.date.today() - datetime.timedelta(180))
+        return self.filter(start_date__gt=half_a_year_ago).first()
+
+    def current_events(self):
+        current_splash = self.current()
+        if current_splash:
+            return current_splash.events()
+        return self.none()
 
 
 class SplashYear(models.Model):
@@ -17,6 +24,9 @@ class SplashYear(models.Model):
 
     objects = SplashYearManager()
 
+    def events(self):
+        return self.splash_events.all()
+
     def __unicode__(self):
         return self.title
 
diff --git a/apps/splash/views.py b/apps/splash/views.py
--- a/apps/splash/views.py
+++ b/apps/splash/views.py
@@ -1,3 +1,4 @@
+from django.http import Http404
 from django.shortcuts import render
 from apps.splash.models import SplashYear
 
@@ -6,8 +7,10 @@
 
 def index(request):
     splash_year = SplashYear.objects.current()
+    if not splash_year:
+        raise Http404
 
-    splash_year.events = _merge_events(splash_year.splash_events.all())
+    splash_year.events = _merge_events(splash_year.events())
 
     return render(request, 'splash/base.html', {'splash_year': splash_year})
 


Test patch:
Repository: dotkom/onlineweb4

Issue:
Group Sync when changing a User
Currently the group syncer is only run when a group is updated (saved). If a user is added to (or removed from) a group, the syncer won't run. 

Fix:
Connect to the signal sent by User.groups m2m-relation when a user is saved, like described here: https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed

This is to be done in `apps/authentication/signals.py`.



Discussion:

Resolving patch:
diff --git a/apps/authentication/signals.py b/apps/authentication/signals.py
--- a/apps/authentication/signals.py
+++ b/apps/authentication/signals.py
@@ -1,13 +1,17 @@
 # -*- coding: utf-8 -*-
+from django.contrib.auth import get_user_model
 from django.contrib.auth.models import Group
-from django.db.models.signals import post_save
+from django.db.models.signals import m2m_changed, post_save
 from django.dispatch import receiver
 
 from apps.authentication.tasks import SynchronizeGroups
 
 
+User = get_user_model()
+
+
 @receiver(post_save, sender=Group)
-def trigger_group_syncer(sender, instance, created, **kwargs):
+def trigger_group_syncer(sender, instance, created=False, **kwargs):
     """
     :param sender: The model that triggered this hook
     :param instance: The model instance triggering this hook
@@ -21,3 +25,5 @@ def trigger_group_syncer(sender, instance, created, **kwargs):
         pass
     else:
         SynchronizeGroups.run()
+
+m2m_changed.connect(trigger_group_syncer, sender=User.groups.through)


Test patch:
Repository: dotkom/onlineweb4

Issue:
Deleted email address can't be added back
Deleting an email address from the user profile makes it impossible to add that same address back. Attempting to add it back gives a message saying a user with the NTNU-username is already registered. 

Problem persists weeks after the address was removed. 



Discussion:
For steps to resolve this issue, have a look at how the front-end view
handles removal of email addresses.

That workflow should be moved to signal handlers, so it will happen during
deletion in any way, not just the button click in front-end.

On Sun, Mar 13, 2016, 03:16 nornes notifications@github.com wrote:

> Deleting an email address from the user profile makes it impossible to add
> that same address back. Attempting to add it back gives a message saying
> the address is already in use.
> 
> Problem persists weeks after the address was removed.
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/dotKom/onlineweb4/issues/1480.


Resolving patch:
diff --git a/apps/profiles/views.py b/apps/profiles/views.py
--- a/apps/profiles/views.py
+++ b/apps/profiles/views.py
@@ -263,7 +263,7 @@ def add_email(request):
                 ntnu_username = email_string.split("@")[0]
                 user = User.objects.filter(ntnu_username=ntnu_username)
                 if user.count() == 1:
-                    if user != request.user:
+                    if user[0] != request.user:
                         messages.error(request, _("En bruker med dette NTNU-brukernavnet eksisterer allerede."))
                         return redirect('profiles')
 


Test patch:
Repository: dotkom/onlineweb4

Issue:
/api/v1/auth broke with django-oauth-toolkit 0.9.0
https://github.com/evonove/django-oauth-toolkit/compare/0.8.1...0.9.0



Discussion:

Resolving patch:
diff --git a/apps/sso/views.py b/apps/sso/views.py
--- a/apps/sso/views.py
+++ b/apps/sso/views.py
@@ -10,7 +10,6 @@
 from django.utils.decorators import method_decorator
 from django.views.decorators.debug import sensitive_post_parameters
 from django.views.generic import FormView, View
-from oauth2_provider.backends import OAuth2Backend
 from oauth2_provider.exceptions import OAuthToolkitError
 from oauth2_provider.forms import AllowForm
 from oauth2_provider.http import HttpResponseUriRedirect
@@ -85,7 +84,6 @@ class AuthorizationView(BaseAuthorizationView, FormView):
 
     server_class = Server
     validator_class = OAuth2Validator
-    oauthlib_backend_class = OAuth2Backend
 
     skip_authorization_completely = False
 
@@ -180,7 +178,6 @@ class TokenView(CsrfExemptMixin, OAuthLibMixin, View):
     """
     server_class = Server
     validator_class = OAuth2Validator
-    oauthlib_backend_class = OAuth2Backend
 
     @method_decorator(sensitive_post_parameters('password'))
     def post(self, request, *args, **kwargs):
@@ -198,7 +195,6 @@ class RevokeTokenView(CsrfExemptMixin, OAuthLibMixin, View):
     """
     server_class = Server
     validator_class = OAuth2Validator
-    oauthlib_backend_class = OAuth2Backend
 
     def post(self, request, *args, **kwargs):
         url, headers, body, status = self.create_revocation_response(request)


Test patch:
Repository: dotkom/onlineweb4

Issue:
Don't send additional 500 email if no useful information in it.
After the implementation if #1485 we get an additional email for _all_ 500 errors, even if there is no supplied information. Let's not send an email if there's no useful information in it.



Discussion:

Resolving patch:
diff --git a/onlineweb4/views.py b/onlineweb4/views.py
--- a/onlineweb4/views.py
+++ b/onlineweb4/views.py
@@ -1,21 +1,22 @@
 # -*- coding: utf-8 -*-
 import logging
-from smtplib import SMTPException
 
 from django.conf import settings
 from django.contrib import messages
 from django.core.mail import send_mail
 from django.shortcuts import redirect, render
 from onlineweb4.forms import ErrorForm
+from smtplib import SMTPException
 
 
 def server_error(request):
     log = logging.getLogger(__name__)
 
     if request.method == 'POST':
-        form = ErrorForm(request.POST)
-        message = request.POST.get('reason', 'Ingen forklaring oppgitt.')
-        try: 
+        message = request.POST.get('reason')
+        if not message:
+            return redirect('home')
+        try:
             log.error('%s triggered a 500 server error and provided the following description: %s' % (
                 request.user,
                 message
@@ -23,12 +24,9 @@ def server_error(request):
             send_mail('500error user-report', message,
                 settings.DEFAULT_FROM_EMAIL, [settings.EMAIL_DOTKOM])
             log.debug('Finished sending error email to %s' % settings.EMAIL_DOTKOM)
-
             messages.success(request, 'Feilmeldingen din ble sendt til %s' % settings.EMAIL_DOTKOM)
-
             return redirect('home')
         except SMTPException:
             messages.error(request, 'Det oppstod en uventet feil under sending av feilmeldingen')
             return redirect('home')
-
     return render(request, '500.html', {'error_form': ErrorForm})


Test patch:
Repository: dotkom/onlineweb4

Issue:
Mirror "only reveal winner when voting ends" functionality in admin panel as well
This is to prevent "tellekorps" from viewing the current standings before they themselves have casted a vote, allowing for potential bias.



Discussion:

Resolving patch:
diff --git a/apps/genfors/views.py b/apps/genfors/views.py
--- a/apps/genfors/views.py
+++ b/apps/genfors/views.py
@@ -91,10 +91,16 @@ def admin(request):
     if is_admin(request):
         meeting = get_next_meeting()
         if meeting:
+            aq = meeting.get_active_question()
+            a = anonymous_voter(request.COOKIES.get('anon_voter'), request.user.username)
+            r = RegisteredVoter.objects.filter(user=request.user, meeting=meeting).first()
+            v = a if aq.anonymous else r
+
             context['meeting'] = meeting
             context['question'] = meeting.get_active_question()
             context['questions'] = meeting.get_locked_questions()
             context['pin_code'] = meeting.get_pin_code()
+            context['already_voted'] = aq.already_voted(v)
         elif request.method == 'POST':
             form = MeetingForm(request.POST)
             context['form'] = form


Test patch: