internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: LibraryOfCongress/concordia

Issue:
Images in an item should be sorted sequentially not alphabetically
**What behavior did you observe? Please describe the bug**
Items with more than 10 or more than 100 images don't display in the correct order. They seem to be alphabetically sorted.  Images are displayed 1, 10, 100, etc. instead of 1, 2, 3.

**How can we reproduce the bug?**
Steps to reproduce the behavior:
1. Go to any item that has more than 10 or more than 100 items.
2. Click on the Next arrow after the first page.
3. Look at the image numbers displayed under each image.

**What is the expected behavior?**
Images should be displayed sequentially starting from 1. Image 100 should come after 99, Image 10 after 9, etc.




Discussion:

Resolving patch:
diff --git a/concordia/views.py b/concordia/views.py
--- a/concordia/views.py
+++ b/concordia/views.py
@@ -266,7 +266,7 @@ def get_queryset(self):
             slug=self.kwargs["slug"],
         )
 
-        asset_qs = self.item.asset_set.all()
+        asset_qs = self.item.asset_set.all().order_by("sequence")
         asset_qs = asset_qs.select_related(
             "item__project__campaign", "item__project", "item"
         )


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Link campaigns to project pages on the homepage
In the campaign section: 

- [x] Remove the get started button
- [x] link image to go to the projects page for that campaign


Discussion:

Resolving patch:
diff --git a/concordia/urls.py b/concordia/urls.py
--- a/concordia/urls.py
+++ b/concordia/urls.py
@@ -140,7 +140,7 @@
 )
 
 urlpatterns = [
-    re_path(r"^$", TemplateView.as_view(template_name="home.html"), name="homepage"),
+    re_path(r"^$", views.HomeView.as_view(), name="homepage"),
     path(r"healthz", views.healthz, name="health-check"),
     path("about/", views.static_page, name="about"),
     re_path(r"^contact/$", views.ContactUsView.as_view(), name="contact"),
diff --git a/concordia/views.py b/concordia/views.py
--- a/concordia/views.py
+++ b/concordia/views.py
@@ -145,6 +145,13 @@ def form_valid(self, form):
         return super().form_valid(form)
 
 
+class HomeView(ListView):
+    template_name = "home.html"
+
+    queryset = Campaign.objects.published().order_by("title")
+    context_object_name = "campaigns"
+
+
 class CampaignListView(ListView):
     template_name = "transcriptions/campaign_list.html"
     paginate_by = 10


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
MetricsModelMixin is missing from several models



Discussion:

Resolving patch:
diff --git a/concordia/models.py b/concordia/models.py
--- a/concordia/models.py
+++ b/concordia/models.py
@@ -84,7 +84,7 @@ def get_absolute_url(self):
         return reverse("transcriptions:campaign", args=(self.slug,))
 
 
-class Project(models.Model):
+class Project(MetricsModelMixin("project"), models.Model):
     objects = PublicationManager()
 
     campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE)
@@ -112,7 +112,7 @@ def get_absolute_url(self):
         )
 
 
-class Item(models.Model):
+class Item(MetricsModelMixin("item"), models.Model):
     objects = PublicationManager()
 
     project = models.ForeignKey(
@@ -155,7 +155,7 @@ def get_absolute_url(self):
         )
 
 
-class Asset(models.Model):
+class Asset(MetricsModelMixin("asset"), models.Model):
     item = models.ForeignKey(Item, on_delete=models.CASCADE)
 
     title = models.CharField(max_length=100)
@@ -199,7 +199,7 @@ def get_absolute_url(self):
         )
 
 
-class Tag(models.Model):
+class Tag(MetricsModelMixin("tag"), models.Model):
     TAG_VALIDATOR = RegexValidator(r"^[- _'\w]{1,50}$")
     value = models.CharField(max_length=50, validators=[TAG_VALIDATOR])
 
@@ -207,7 +207,9 @@ def __str__(self):
         return self.value
 
 
-class UserAssetTagCollection(models.Model):
+class UserAssetTagCollection(
+    MetricsModelMixin("user_asset_tag_collection"), models.Model
+):
     asset = models.ForeignKey(Asset, on_delete=models.CASCADE)
 
     user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
@@ -220,7 +222,7 @@ def __str__(self):
         return "{} - {}".format(self.asset, self.user)
 
 
-class Transcription(models.Model):
+class Transcription(MetricsModelMixin("transcription"), models.Model):
     asset = models.ForeignKey(Asset, on_delete=models.CASCADE)
 
     user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Change import duplicate item check to be global rather than per project
Following on from discussion between @vvh and @acdha 


Discussion:

Resolving patch:
diff --git a/importer/tasks.py b/importer/tasks.py
--- a/importer/tasks.py
+++ b/importer/tasks.py
@@ -16,7 +16,7 @@
 from django.utils.timezone import now
 from requests.exceptions import HTTPError
 
-from concordia.models import Asset, MediaType
+from concordia.models import Asset, Item, MediaType
 from concordia.storage import ASSET_STORAGE
 from importer.models import ImportItem, ImportItemAsset, ImportJob
 
@@ -259,10 +259,9 @@ def create_item_import_task(self, import_job_pk, item_url):
     resp.raise_for_status()
     item_data = resp.json()
 
-    item, item_created = import_job.project.item_set.get_or_create(
+    item, item_created = Item.objects.get_or_create(
         item_id=get_item_id_from_item_url(item_data["item"]["id"]),
-        item_url=item_url,
-        project=import_job.project,
+        defaults={"item_url": item_url, "project": import_job.project},
     )
 
     import_item, import_item_created = import_job.items.get_or_create(
@@ -272,7 +271,10 @@ def create_item_import_task(self, import_job_pk, item_url):
     if not item_created:
         logger.warning("Not reprocessing existing item %s", item)
         import_item.status = "Not reprocessing existing item %s" % item
-        import_item.completed = now()
+        import_item.completed = import_item.last_started = now()
+        import_item.task_id = self.request.id
+        import_item.full_clean()
+        import_item.save()
         return
 
     import_item.item.metadata.update(item_data)


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Refine Contact Us page
**What behavior did you observe? Please describe the bug**
- The language is very direct. Need to make it more user friendly. 
- Add content to get to History Hub
- Begin with options to self-service in Help Center or History Hub

**What is the expected behavior?**
As a user, I want to contact a community manager with a pressing question via the Contact Us form so that I can get a swift reply. It should also include: 
- Friendlier language for the different fields
- Contact Us form would autopopulate my email and tell CM what page they are referring to
- I should be able to categorize my question in the Contact Us form to best route the question.
- Some information telling me about History Hub

**Got screenshots? This helps us identify the issue**

![contact](https://user-images.githubusercontent.com/7362915/46110939-4114f780-c1b3-11e8-9504-3e9358f6cfcb.PNG)


**Additional context**
Add any other context about the problem here.



Discussion:
@elainekamlley you can send a pull request against https://github.com/LibraryOfCongress/concordia/blob/21bc9c11817cd95683f818e38cae7c6bac646b56/concordia/forms.py#L94-L130 with label changes.

Resolving patch:
diff --git a/concordia/forms.py b/concordia/forms.py
--- a/concordia/forms.py
+++ b/concordia/forms.py
@@ -42,27 +42,16 @@ def clean_email(self):
 class ContactUsForm(forms.Form):
     referrer = forms.CharField(label="Referring Page", widget=forms.HiddenInput())
 
-    email = forms.EmailField(label="Your email", required=True)
-    subject = forms.CharField(label="Subject", required=False)
+    email = forms.EmailField(label="Your email:", required=True)
+    subject = forms.CharField(label="Subject:", required=False)
 
-    category = forms.CharField(
-        label="Category",
-        required=True,
-        widget=forms.Select(
-            choices=(
-                ("General", "General"),
-                ("Campaign", "Question about campaign"),
-                ("Problem", "Something is not working"),
-            )
-        ),
-    )
 
     link = forms.URLField(
-        label="Link to the page you need support with", required=False
+        label="Have a specific page you need help with? Add the link below:", required=False
     )
 
     story = forms.CharField(
-        label="Why are you contacting us", required=True, widget=forms.Textarea
+        label="Let us know how we can help:", required=True, widget=forms.Textarea
     )
 
 


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Add tooltips to breadcrumbs
Currently we truncate the breadcrumb text to avoid wrapping but it would be nice to present the title as a tooltip on the link in case someone wants to see the full value.


Discussion:

Resolving patch:
diff --git a/concordia/views.py b/concordia/views.py
--- a/concordia/views.py
+++ b/concordia/views.py
@@ -23,7 +23,7 @@
 from django.utils.timezone import now
 from django.views.decorators.cache import never_cache
 from django.views.decorators.http import require_POST
-from django.views.generic import DetailView, FormView, ListView, TemplateView, View
+from django.views.generic import DetailView, FormView, ListView, TemplateView
 from django_registration.backends.activation.views import RegistrationView
 
 from concordia.forms import (
@@ -102,13 +102,19 @@ def static_page(request, base_name=None):
         html = md.convert(f.read())
 
     page_title = md.Meta.get("title")
-
     if page_title:
         page_title = "\n".join(i.strip() for i in page_title)
     else:
         page_title = base_name.replace("-", " ").replace("/", " — ").title()
 
-    ctx = {"body": html, "title": page_title}
+    breadcrumbs = []
+    path_components = request.path.strip("/").split("/")
+    for i, segment in enumerate(path_components, start=1):
+        breadcrumbs.append(
+            ("/%s/" % "/".join(path_components[0:i]), segment.replace("-", " ").title())
+        )
+
+    ctx = {"body": html, "title": page_title, "breadcrumbs": breadcrumbs}
 
     return render(request, "static-page.html", ctx)
 
@@ -321,8 +327,9 @@ def get_context_data(self, **kwargs):
         transcription = asset.transcription_set.order_by("-pk").first()
         ctx["transcription"] = transcription
 
-        # We'll handle the case where an item with no transcriptions should be shown as status=edit here
-        # so the logic doesn't need to be repeated in templates:
+        # We'll handle the case where an item with no transcriptions should be
+        # shown as status=edit here so the logic doesn't need to be repeated in
+        # templates:
         if transcription:
             transcription_status = transcription.status.lower()
         else:


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Add tooltips to breadcrumbs
Currently we truncate the breadcrumb text to avoid wrapping but it would be nice to present the title as a tooltip on the link in case someone wants to see the full value.


Discussion:

Resolving patch:
diff --git a/concordia/views.py b/concordia/views.py
--- a/concordia/views.py
+++ b/concordia/views.py
@@ -23,7 +23,7 @@
 from django.utils.timezone import now
 from django.views.decorators.cache import never_cache
 from django.views.decorators.http import require_POST
-from django.views.generic import DetailView, FormView, ListView, TemplateView, View
+from django.views.generic import DetailView, FormView, ListView, TemplateView
 from django_registration.backends.activation.views import RegistrationView
 
 from concordia.forms import (
@@ -108,7 +108,14 @@ def static_page(request, base_name=None):
     else:
         page_title = base_name.replace("-", " ").replace("/", " — ").title()
 
-    ctx = {"body": html, "title": page_title}
+    breadcrumbs = []
+    path_components = request.path.strip("/").split("/")
+    for i, segment in enumerate(path_components, start=1):
+        breadcrumbs.append(
+            ("/%s/" % "/".join(path_components[0:i]), segment.replace("-", " ").title())
+        )
+
+    ctx = {"body": html, "title": page_title, "breadcrumbs": breadcrumbs}
 
     return render(request, "static-page.html", ctx)
 
@@ -321,8 +328,9 @@ def get_context_data(self, **kwargs):
         transcription = asset.transcription_set.order_by("-pk").first()
         ctx["transcription"] = transcription
 
-        # We'll handle the case where an item with no transcriptions should be shown as status=edit here
-        # so the logic doesn't need to be repeated in templates:
+        # We'll handle the case where an item with no transcriptions should be
+        # shown as status=edit here so the logic doesn't need to be repeated in
+        # templates:
         if transcription:
             transcription_status = transcription.status.lower()
         else:


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Questions page to various help links
As a user, when I click `Questions?` button in the transcription, I am taken to a page where I am given choices based on what I need help with. I can see three boxes that link out to: 
- Discussion forum: I want to talk about what I am finding 
- Help Center: I want to know how to do something
- Contact Us: I have a specific question to a Community manager 

This is a self guided routing page for users to determine how they would like to get help. 
Acceptance criteria: 
- create a new static page title `questions.md`
- take the styling of the guide cards in the Help center and link out to: History Hub, Help Center,  contact us page 

![mymcards](https://user-images.githubusercontent.com/7362915/46969720-fa653f80-d084-11e8-8f2c-d89329169a77.PNG)




Discussion:

Resolving patch:
diff --git a/concordia/urls.py b/concordia/urls.py
--- a/concordia/urls.py
+++ b/concordia/urls.py
@@ -69,6 +69,7 @@
     path("help-center/how-to-tag/", views.static_page, name="how-to-tag"),
     path("for-educators/", views.static_page, name="for-educators"),
     path("latest/", views.static_page, name="latest"),
+    path("questions/", views.static_page, name="questions"),
     path("contact/", views.ContactUsView.as_view(), name="contact"),
     path("campaigns/", include(tx_urlpatterns, namespace="transcriptions")),
     path(


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Pagination and filtering don't work together
**What behavior did you observe? Please describe the bug**
The filter became unset and went to all images.

**How can we reproduce the bug?**
Steps to reproduce the behavior:
1. Go to an item that has several assets in open and submitted states.
2. Use the filter to only view submitted for review assets.
3. Scroll down and click page 2.

**What is the expected behavior?**
When I click page 2, the filter should be maintained.



Discussion:

Resolving patch:
diff --git a/concordia/settings_template.py b/concordia/settings_template.py
--- a/concordia/settings_template.py
+++ b/concordia/settings_template.py
@@ -78,6 +78,7 @@
     "raven.contrib.django.raven_compat",
     "maintenance_mode",
     "bootstrap4",
+    "bittersweet",
     "concordia.apps.ConcordiaAppConfig",
     "exporter",
     "importer",


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
As an admin, be able to sort users by recent of sign up and activity
User stories:
- As an admin, I would like to be able to sort users list by recency of joining crowd.loc.gov so that I can 
- As an admin, I would like to be able to sort users by activity
Make item on asset admin change form readonly
Currently this builds a giant select list and we never want to make assets movable anyway 


Discussion:

Resolving patch:
diff --git a/concordia/admin.py b/concordia/admin.py
--- a/concordia/admin.py
+++ b/concordia/admin.py
@@ -5,8 +5,11 @@
 from django.conf import settings
 from django.contrib import admin, messages
 from django.contrib.admin.views.decorators import staff_member_required
+from django.contrib.auth.admin import UserAdmin
 from django.contrib.auth.decorators import permission_required
+from django.contrib.auth.models import User
 from django.core.exceptions import ValidationError
+from django.db.models import Count
 from django.shortcuts import get_object_or_404, render
 from django.template.defaultfilters import slugify, truncatechars
 from django.urls import path
@@ -88,6 +91,24 @@ def unpublish_action(modeladmin, request, queryset):
 unpublish_action.short_description = "Unpublish selected"
 
 
+class ConcordiaUserAdmin(UserAdmin):
+    list_display = UserAdmin.list_display + ("date_joined", "transcription_count")
+
+    def get_queryset(self, request):
+        qs = super().get_queryset(request)
+        qs = qs.annotate(Count("transcription"))
+        return qs
+
+    def transcription_count(self, obj):
+        return obj.transcription__count
+
+    transcription_count.admin_order_field = "transcription__count"
+
+
+admin.site.unregister(User)
+admin.site.register(User, ConcordiaUserAdmin)
+
+
 @never_cache
 @staff_member_required
 @permission_required("concordia.add_campaign")
@@ -441,7 +462,7 @@ class AssetAdmin(admin.ModelAdmin, CustomListDisplayFieldsMixin):
         "transcription_status",
     )
     actions = (publish_action, unpublish_action)
-
+    autocomplete_fields = ("item",)
     ordering = ("item__item_id", "sequence")
 
     def get_queryset(self, request):
@@ -461,6 +482,11 @@ def truncated_media_url(self, obj):
     truncated_media_url.allow_tags = True
     truncated_media_url.short_description = "Media URL"
 
+    def get_readonly_fields(self, request, obj=None):
+        if obj:
+            return self.readonly_fields + ("item",)
+        return self.readonly_fields
+
     def change_view(self, request, object_id, extra_context=None, **kwargs):
         if object_id:
             if extra_context is None:
diff --git a/importer/admin.py b/importer/admin.py
--- a/importer/admin.py
+++ b/importer/admin.py
@@ -83,6 +83,7 @@ def inner(obj):
                 return value
 
         inner.short_description = field_name.replace("_", " ").title()
+        inner.admin_order_field = field_name
         return inner
 
     def __init__(self, *args, **kwargs):


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Set site time zone to US/Eastern
https://docs.djangoproject.com/en/2.1/ref/settings/#std:setting-TIME_ZONE

Use Django setting to change user-facing timestamps to use US/Eastern time zone.


Discussion:

Resolving patch:
diff --git a/concordia/settings_template.py b/concordia/settings_template.py
--- a/concordia/settings_template.py
+++ b/concordia/settings_template.py
@@ -41,7 +41,7 @@
     os.path.join(SITE_ROOT_DIR, "static"),
 ]
 TEMPLATE_DEBUG = False
-TIME_ZONE = "UTC"
+TIME_ZONE = "America/New_York"
 USE_I18N = True
 USE_L10N = True
 USE_TZ = True


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
"Images in this project" is incorrect on campaign report
**What behavior did you observe? Please describe the bug**
The number of Images in this project is incorrect. It doesn't match the actual number of published assets in the project.

**How can we reproduce the bug?**
Steps to reproduce the behavior:
1. Go to any campaign report.
2. In the django admin, filter the list of assets by projects in that campaign.
3. Check the control checkbox.

**What is the expected behavior?**
The "Images in this project" should accurately display the number of published assets per project.



Discussion:

Resolving patch:
diff --git a/concordia/views.py b/concordia/views.py
--- a/concordia/views.py
+++ b/concordia/views.py
@@ -822,6 +822,7 @@ def get(self, request, campaign_slug):
             asset_count=Count(
                 "item__asset",
                 filter=Q(item__published=True, item__asset__published=True),
+                distinct=True
             )
         )
         projects_qs = projects_qs.annotate(


Test patch:
Repository: LibraryOfCongress/concordia

Issue:
Admin export of users who signed up for newsletter
**Is your feature request related to a problem? Please describe.**
Admins need a way to export (in CSV format) a list of users sorted by date who opted in for the news letter when they registered.

**Describe the solution you'd like**
For admin export, we should test whether this requires changes for Django 2.x since it could be a simple option:

https://github.com/LibraryOfCongress/django-tabular-export#admin-integration




Discussion:
Related to #155 

Resolving patch:
diff --git a/concordia/admin.py b/concordia/admin.py
--- a/concordia/admin.py
+++ b/concordia/admin.py
@@ -16,6 +16,7 @@
 from django.utils.decorators import method_decorator
 from django.utils.html import format_html
 from django.views.decorators.cache import never_cache
+from tabular_export.admin import export_to_csv_action, export_to_excel_action
 
 from exporter import views as exporter_views
 from importer.tasks import import_items_into_project_from_url
@@ -103,6 +104,7 @@ def transcription_count(self, obj):
         return obj.transcription__count
 
     transcription_count.admin_order_field = "transcription__count"
+    actions = (export_to_excel_action, export_to_csv_action)
 
 
 admin.site.unregister(User)


Test patch: