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. Go Home", 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})