Spaces:
Sleeping
Sleeping
Enhance topic detail view by prefetching author yearly stats and update footer styling for improved layout
0f380ab
| from BridgeMentor.utils import refresh_author_db | |
| from django.db import transaction | |
| from django.core.cache import cache | |
| from django.shortcuts import render, get_object_or_404 | |
| # Import Author model | |
| from .models import Domain, Field, Subfield, Topic, AuthorTopic, Author, Institution | |
| from django.http import JsonResponse, HttpResponse | |
| from django.db.models import Q | |
| from django.core.management import call_command | |
| from io import StringIO | |
| from difflib import get_close_matches | |
| import unicodedata | |
| def unaccent(text): | |
| return ''.join( | |
| c for c in unicodedata.normalize('NFKD', text) | |
| if not unicodedata.combining(c) | |
| ) | |
| with transaction.atomic(): | |
| author_data = cache.get('author_data') | |
| if not author_data: | |
| author_dict = { | |
| unaccent(author.name.lower()): author for author in Author.objects.all()} | |
| author_names = list(author_dict.keys()) | |
| cache.set('author_data', {'dict': author_dict, | |
| 'names': author_names}, timeout=None) | |
| else: | |
| author_dict, author_names = author_data['dict'], author_data['names'] | |
| def home_page(request): | |
| if request.user.is_authenticated: | |
| user_full_name = f"{request.user.first_name} {request.user.last_name}" | |
| search_ascii = unaccent(user_full_name.lower()) | |
| best_match = get_close_matches( | |
| search_ascii, author_names, n=5, cutoff=0.8) | |
| print(f"Best match: {best_match}") | |
| matched_author = None | |
| if best_match: | |
| matched_author = max( | |
| (author_dict[name] for name in best_match), key=lambda a: a.cited_by_count) | |
| return render(request, 'home.html', {"user": request.user, "author": matched_author}) | |
| else: | |
| return render(request, "must_login.html") | |
| def refresh_author_db_view(request): | |
| # check if admin | |
| if not request.user.is_superuser: | |
| return JsonResponse({"error": "Permission denied"}, status=403) | |
| refresh_author_db(check_time=False) | |
| return HttpResponse("Database refreshed successfully. <a href='/'>Go Home</a>", status=200) | |
| def collect_static_view(request): | |
| if not request.user.is_superuser: | |
| return JsonResponse({"error": "Permission denied"}, status=403) | |
| # Capture the output of the collectstatic command | |
| output = StringIO() | |
| call_command('collectstatic', interactive=False, stdout=output) | |
| output.seek(0) # Reset the pointer to the beginning of the output | |
| return HttpResponse(output.read(), content_type='text/plain') | |
| def search_hierarchy(request): | |
| q = request.GET.get("q", "").strip() | |
| if not q: | |
| return JsonResponse({"results": []}) | |
| results = [] | |
| results += [{"id": d.id, "text": d.name, "type": "Domain"} | |
| for d in Domain.objects.filter(name__icontains=q)] | |
| results += [{"id": f.id, "text": f"{f.domain.name} > {f.name}", "type": "Field"} | |
| for f in Field.objects.select_related("domain").filter(name__icontains=q)] | |
| results += [{"id": s.id, "text": f"{s.field.domain.name} > {s.field.name} > {s.name}", "type": "Subfield"} | |
| for s in Subfield.objects.select_related("field__domain").filter(name__icontains=q)] | |
| results += [{"id": t.id, "text": f"{t.subfield.field.domain.name} > {t.subfield.field.name} > {t.subfield.name} > {t.name}", "type": "Topic"} | |
| for t in Topic.objects.select_related("subfield__field__domain").filter(name__icontains=q)] | |
| return JsonResponse({"results": sorted(results, key=lambda x: x["text"].lower())[:10]}) | |
| def search_author(request): | |
| q = request.GET.get("q", "").strip() | |
| if not q: | |
| return JsonResponse({"results": []}) | |
| q_unaccented = unaccent(q.lower()) | |
| close_matches = get_close_matches( | |
| q_unaccented, author_names, n=10, cutoff=0.5) | |
| results = [] | |
| for name_key in close_matches: | |
| author = author_dict[name_key] | |
| last_affiliation = author.latest_affiliation() | |
| affiliation = last_affiliation.institution.name if last_affiliation else "No affiliation" | |
| results.append( | |
| {"id": author.id, "text": f"{author.name} ({affiliation})"}) | |
| return JsonResponse({"results": results}) | |
| # Domain views | |
| def domain_list(request): | |
| domains = Domain.objects.all() | |
| return render(request, "domain/list.html", {"items": domains}) | |
| def domain_detail(request, pk): | |
| domain = get_object_or_404(Domain, pk=pk) | |
| # Get all fields under this domain | |
| fields = Field.objects.filter(domain=domain) | |
| return render(request, "domain/detail.html", {"item": domain, "fields": fields}) | |
| # Field views | |
| def field_list(request): | |
| fields = Field.objects.select_related("domain").all() | |
| return render(request, "field/list.html", {"items": fields}) | |
| def field_detail(request, pk): | |
| field = get_object_or_404(Field.objects.select_related("domain"), pk=pk) | |
| # Get all subfields under this field | |
| subfields = Subfield.objects.filter(field=field) | |
| return render(request, "field/detail.html", {"item": field, "subfields": subfields}) | |
| # Subfield views | |
| def subfield_list(request): | |
| subfields = Subfield.objects.select_related("field__domain").all() | |
| return render(request, "subfield/list.html", {"items": subfields}) | |
| def subfield_detail(request, pk): | |
| subfield = get_object_or_404( | |
| Subfield.objects.select_related("field__domain"), pk=pk) | |
| # Get all topics under this subfield | |
| topics = Topic.objects.filter(subfield=subfield) | |
| return render(request, "subfield/detail.html", {"item": subfield, "topics": topics}) | |
| # Topic views | |
| def topic_list(request): | |
| topics = Topic.objects.select_related("subfield__field__domain").all() | |
| return render(request, "topic/list.html", {"items": topics}) | |
| def topic_detail(request, pk): | |
| topic = get_object_or_404(Topic, id=pk) | |
| authors = AuthorTopic.objects.filter(topic=topic).select_related( | |
| 'author').prefetch_related('author__yearly_stats') | |
| return render(request, 'topic/detail.html', {'item': topic, 'authors': authors}) | |
| # Author views | |
| def author_detail(request, pk): | |
| author = get_object_or_404(Author, pk=pk) | |
| topics = AuthorTopic.objects.filter(author=author).select_related('topic') | |
| affiliations = Institution.objects.filter( | |
| affiliation__author=author).distinct() | |
| return render(request, 'author/detail.html', {'item': author, | |
| 'affiliations': affiliations, | |
| 'topics': topics}) | |