From 77e1e126c309fcc4df2700f2834eddd1c98186c4 Mon Sep 17 00:00:00 2001 From: roseva1 Date: Mon, 13 Nov 2023 15:00:56 -0500 Subject: [PATCH 01/14] batch bookmark model added --- turkle/admin.py | 1 - turkle/models.py | 5 ++++ turkle/templates/turkle/base.html | 5 +++- turkle/templates/turkle/index.html | 40 +++++++++++++++++++++++++++ turkle/views.py | 44 +++++++++++++++++++++++++++--- 5 files changed, 89 insertions(+), 6 deletions(-) diff --git a/turkle/admin.py b/turkle/admin.py index 146e413..3464758 100644 --- a/turkle/admin.py +++ b/turkle/admin.py @@ -27,7 +27,6 @@ from django.urls import path, reverse from django.utils import timezone from django.utils.html import format_html, format_html_join -from django.utils.translation import ngettext from guardian.admin import GuardedModelAdmin from guardian.shortcuts import (assign_perm, get_groups_with_perms, get_users_with_perms, remove_perm) diff --git a/turkle/models.py b/turkle/models.py index 089fb74..e97b0b0 100644 --- a/turkle/models.py +++ b/turkle/models.py @@ -938,3 +938,8 @@ def completed_assignments(self): def most_recent(self): return self.last_finished_time most_recent.admin_order_field = 'last_finished_time' + +class Bookmark(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE) + batch = models.ForeignKey(Batch, on_delete=models.CASCADE) + bookmarked = models.BooleanField(default=False) \ No newline at end of file diff --git a/turkle/templates/turkle/base.html b/turkle/templates/turkle/base.html index 25e0067..c43b602 100644 --- a/turkle/templates/turkle/base.html +++ b/turkle/templates/turkle/base.html @@ -62,5 +62,8 @@ {% block footer %} {% endblock %} + + {% block script %} + {% endblock %} - + \ No newline at end of file diff --git a/turkle/templates/turkle/index.html b/turkle/templates/turkle/index.html index 06dd2a4..699f0b9 100644 --- a/turkle/templates/turkle/index.html +++ b/turkle/templates/turkle/index.html @@ -39,6 +39,7 @@ Project Batch Batch Published + Batch Bookmarked Tasks Available @@ -48,6 +49,9 @@ {{ batch_row.project_name }} {{ batch_row.batch_name }} {{ batch_row.batch_published }} + + + {{ batch_row.assignments_available }} @@ -74,3 +78,39 @@

{% endblock %} + +{% block script %} + + +{% endblock %} \ No newline at end of file diff --git a/turkle/views.py b/turkle/views.py index 7e74c36..36290e1 100644 --- a/turkle/views.py +++ b/turkle/views.py @@ -5,7 +5,7 @@ import urllib from django.conf import settings -from django.contrib import messages +from django.contrib import messages, auth from django.contrib.auth import get_user_model from django.core.exceptions import ObjectDoesNotExist from django.db import connection, transaction @@ -17,13 +17,12 @@ from django.utils.dateparse import parse_date from django.utils.datastructures import MultiValueDictKeyError -from .models import Task, TaskAssignment, Batch, Project +from .models import Task, TaskAssignment, Batch, Project, Bookmark, User User = get_user_model() logger = logging.getLogger(__name__) - def handle_db_lock(func): """Decorator that catches database lock errors from sqlite""" @wraps(func) @@ -41,6 +40,12 @@ def wrapper(request, *args, **kwargs): return wrapper +def get_user(request): + if not hasattr(request, '_cached_user'): + request._cached_user = auth.get_user(request) + return request._cached_user + + def index(request): """ Security behavior: @@ -63,21 +68,52 @@ def index(request): available_task_counts = Batch.available_task_counts_for(batch_query, request.user) + if request.POST: + def process_bookmark(query_dict): + """Create or update bookmark status for a batch & user + """ + batch_name = query_dict.get('rowId') + bookmark_status = query_dict.get('bookmarked') == 'true' + batch = Batch.objects.get(name=batch_name) + bookmark, created = Bookmark.objects.get_or_create( + user=get_user(request), + batch=batch, + defaults={'bookmarked': bookmark_status} + ) + if not created: + bookmark.bookmarked = bookmark_status + bookmark.save() + + if request.POST: + print(request.POST) + if 'bookmarking' in request.POST.get('action'): + process_bookmark(request.POST) + batch_rows = [] for batch in batch_query.values('created_at', 'id', 'name', 'project__name'): - total_tasks_available = available_task_counts[batch['id']] + def get_bookmark_status(batch): + """Access batch bookmark status for a user + """ + bookmark = Bookmark.objects.filter( + user=get_user(request), + batch__name=batch['name'] + ).values_list('bookmarked', flat=True).first() + return 'checked' if bookmark else '' + total_tasks_available = available_task_counts[batch['id']] if total_tasks_available > 0: batch_rows.append({ 'project_name': batch['project__name'], 'batch_name': batch['name'], 'batch_published': batch['created_at'], 'assignments_available': total_tasks_available, + 'selected': get_bookmark_status(batch), 'preview_next_task_url': reverse('preview_next_task', kwargs={'batch_id': batch['id']}), 'accept_next_task_url': reverse('accept_next_task', kwargs={'batch_id': batch['id']}) }) + return render(request, 'turkle/index.html', { 'abandoned_assignments': abandoned_assignments, 'batch_rows': batch_rows From ca9c9d15b9e0f4ab1fec85fcb6ee4e6c0fb95eb7 Mon Sep 17 00:00:00 2001 From: roseva1 Date: Mon, 13 Nov 2023 15:13:55 -0500 Subject: [PATCH 02/14] linting --- turkle/admin.py | 1 + turkle/models.py | 3 ++- turkle/views.py | 9 +++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/turkle/admin.py b/turkle/admin.py index 3464758..146e413 100644 --- a/turkle/admin.py +++ b/turkle/admin.py @@ -27,6 +27,7 @@ from django.urls import path, reverse from django.utils import timezone from django.utils.html import format_html, format_html_join +from django.utils.translation import ngettext from guardian.admin import GuardedModelAdmin from guardian.shortcuts import (assign_perm, get_groups_with_perms, get_users_with_perms, remove_perm) diff --git a/turkle/models.py b/turkle/models.py index e97b0b0..e8b56db 100644 --- a/turkle/models.py +++ b/turkle/models.py @@ -939,7 +939,8 @@ def most_recent(self): return self.last_finished_time most_recent.admin_order_field = 'last_finished_time' + class Bookmark(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) batch = models.ForeignKey(Batch, on_delete=models.CASCADE) - bookmarked = models.BooleanField(default=False) \ No newline at end of file + bookmarked = models.BooleanField(default=False) diff --git a/turkle/views.py b/turkle/views.py index 36290e1..d606dcc 100644 --- a/turkle/views.py +++ b/turkle/views.py @@ -17,12 +17,13 @@ from django.utils.dateparse import parse_date from django.utils.datastructures import MultiValueDictKeyError -from .models import Task, TaskAssignment, Batch, Project, Bookmark, User +from .models import Task, TaskAssignment, Batch, Project, Bookmark User = get_user_model() logger = logging.getLogger(__name__) + def handle_db_lock(func): """Decorator that catches database lock errors from sqlite""" @wraps(func) @@ -76,8 +77,8 @@ def process_bookmark(query_dict): bookmark_status = query_dict.get('bookmarked') == 'true' batch = Batch.objects.get(name=batch_name) bookmark, created = Bookmark.objects.get_or_create( - user=get_user(request), - batch=batch, + user=get_user(request), + batch=batch, defaults={'bookmarked': bookmark_status} ) if not created: @@ -95,7 +96,7 @@ def get_bookmark_status(batch): """Access batch bookmark status for a user """ bookmark = Bookmark.objects.filter( - user=get_user(request), + user=get_user(request), batch__name=batch['name'] ).values_list('bookmarked', flat=True).first() return 'checked' if bookmark else '' From b22d6da666affd31a3371b9f232bf6c3a670ef07 Mon Sep 17 00:00:00 2001 From: roseva1 Date: Tue, 14 Nov 2023 08:42:30 -0500 Subject: [PATCH 03/14] migration file --- turkle/migrations/0014_bookmark.py | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 turkle/migrations/0014_bookmark.py diff --git a/turkle/migrations/0014_bookmark.py b/turkle/migrations/0014_bookmark.py new file mode 100644 index 0000000..18e373f --- /dev/null +++ b/turkle/migrations/0014_bookmark.py @@ -0,0 +1,44 @@ +# Generated by Django 4.2.6 on 2023-11-14 13:41 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("turkle", "0013_activeproject_activeuser"), + ] + + operations = [ + migrations.CreateModel( + name="Bookmark", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("bookmarked", models.BooleanField(default=False)), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="turkle.batch" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] From a5b456098a1bffbe795e1fe438b0fe147482009d Mon Sep 17 00:00:00 2001 From: roseva1 Date: Tue, 14 Nov 2023 08:48:37 -0500 Subject: [PATCH 04/14] catch case of anonymous user --- turkle/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/turkle/views.py b/turkle/views.py index d606dcc..e2775bd 100644 --- a/turkle/views.py +++ b/turkle/views.py @@ -86,7 +86,6 @@ def process_bookmark(query_dict): bookmark.save() if request.POST: - print(request.POST) if 'bookmarking' in request.POST.get('action'): process_bookmark(request.POST) @@ -100,6 +99,8 @@ def get_bookmark_status(batch): batch__name=batch['name'] ).values_list('bookmarked', flat=True).first() return 'checked' if bookmark else '' + + bookmark_status = get_bookmark_status(batch) if request.user.is_authenticated else '' total_tasks_available = available_task_counts[batch['id']] if total_tasks_available > 0: @@ -108,7 +109,7 @@ def get_bookmark_status(batch): 'batch_name': batch['name'], 'batch_published': batch['created_at'], 'assignments_available': total_tasks_available, - 'selected': get_bookmark_status(batch), + 'selected': bookmark_status, 'preview_next_task_url': reverse('preview_next_task', kwargs={'batch_id': batch['id']}), 'accept_next_task_url': reverse('accept_next_task', From 6a79ae1e8eeb061551d1d38de911f32bbb63b7a3 Mon Sep 17 00:00:00 2001 From: roseva1 Date: Tue, 14 Nov 2023 08:53:12 -0500 Subject: [PATCH 05/14] flake8 tab removal --- turkle/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/turkle/views.py b/turkle/views.py index e2775bd..d3b61d1 100644 --- a/turkle/views.py +++ b/turkle/views.py @@ -99,9 +99,8 @@ def get_bookmark_status(batch): batch__name=batch['name'] ).values_list('bookmarked', flat=True).first() return 'checked' if bookmark else '' - - bookmark_status = get_bookmark_status(batch) if request.user.is_authenticated else '' + bookmark_status = get_bookmark_status(batch) if request.user.is_authenticated else '' total_tasks_available = available_task_counts[batch['id']] if total_tasks_available > 0: batch_rows.append({ From 749129022d91937c3007c7fcd973eb7aa6505a6a Mon Sep 17 00:00:00 2001 From: roseva1 Date: Thu, 29 Feb 2024 11:18:08 -0500 Subject: [PATCH 06/14] inclusion of abandoned and bookmark tables --- turkle/migrations/0014_bookmark.py | 2 +- turkle/static/turkle/css/turkle.css | 27 +++ turkle/templates/turkle/base.html | 6 +- turkle/templates/turkle/index.html | 319 ++++++++++++++++++++-------- turkle/views.py | 2 +- 5 files changed, 263 insertions(+), 93 deletions(-) diff --git a/turkle/migrations/0014_bookmark.py b/turkle/migrations/0014_bookmark.py index 18e373f..a10c66a 100644 --- a/turkle/migrations/0014_bookmark.py +++ b/turkle/migrations/0014_bookmark.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.6 on 2023-11-14 13:41 +# Generated by Django 4.2.6 on 2024-02-08 15:16 from django.conf import settings from django.db import migrations, models diff --git a/turkle/static/turkle/css/turkle.css b/turkle/static/turkle/css/turkle.css index e85366f..37a53a8 100644 --- a/turkle/static/turkle/css/turkle.css +++ b/turkle/static/turkle/css/turkle.css @@ -62,3 +62,30 @@ div.task-preview { background: #fff; opacity: 0.8; } +.table-alert{ + margin-bottom: 0; + height: 100%; +} +.column-div { + float: left; + width: 50%; + border-radius: 5px; + padding: 5pt; + position: relative; + overflow: hidden; + height: 100%; +} + +.table-header, .table-body { + width: 100%; + table-layout: fixed; + border-collapse: collapse; +} +.table-body-container { + height: 12vh; + overflow-y: auto; +} +.column-div th, td { + text-align: left; + padding: 8px; +} diff --git a/turkle/templates/turkle/base.html b/turkle/templates/turkle/base.html index c43b602..11f33de 100644 --- a/turkle/templates/turkle/base.html +++ b/turkle/templates/turkle/base.html @@ -8,9 +8,11 @@ {% load turkle_tags %}{% for tag in turkle_meta_tags %}{{ tag|meta_tag }}{% endfor %} - - + + + + {% block head %} {% endblock %} diff --git a/turkle/templates/turkle/index.html b/turkle/templates/turkle/index.html index 699f0b9..30ac5f0 100644 --- a/turkle/templates/turkle/index.html +++ b/turkle/templates/turkle/index.html @@ -2,115 +2,256 @@ {% load static %} {% block body %} +{% if batch_rows %} + +
+