Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Citations #1814

Merged
merged 4 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions peachjam/migrations/0129_work_citation_counts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Generated by Django 3.2.25 on 2024-05-14 06:18

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("peachjam", "0128_courtclass_show_listing_page"),
]

operations = [
migrations.AddField(
model_name="work",
name="n_cited_works",
field=models.IntegerField(default=0, verbose_name="number of cited works"),
),
migrations.AddField(
model_name="work",
name="n_citing_works",
field=models.IntegerField(
default=0, verbose_name="number of incoming citations"
),
),
migrations.AlterField(
model_name="extractedcitation",
name="citing_work",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="outgoing_citations",
to="peachjam.work",
verbose_name="citing work",
),
),
migrations.AlterField(
model_name="extractedcitation",
name="target_work",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="incoming_citations",
to="peachjam.work",
verbose_name="target work",
),
),
]
29 changes: 29 additions & 0 deletions peachjam/migrations/0130_backfill_citation_counts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.25 on 2024-05-14 06:19

from django.db import migrations
from django.db.models import Q


def backfill_citation_counts(apps, schema_editor):
Work = apps.get_model("peachjam", "Work")
ExtractedCitation = apps.get_model("peachjam", "ExtractedCitation")

qs = Work.objects.filter(
Q(outgoing_citations__isnull=False) | Q(incoming_citations__isnull=False)
)
for work in qs.order_by("-pk").distinct("pk").iterator(256):
work.n_cited_works = ExtractedCitation.objects.filter(citing_work=work).count()
work.n_citing_works = ExtractedCitation.objects.filter(target_work=work).count()
if work.n_cited_works or work.n_citing_works:
work.save(update_fields=["n_cited_works", "n_citing_works"])


class Migration(migrations.Migration):

dependencies = [
("peachjam", "0129_work_citation_counts"),
]

operations = [
migrations.RunPython(backfill_citation_counts, migrations.RunPython.noop)
]
10 changes: 8 additions & 2 deletions peachjam/models/citations.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ class ExtractedCitation(models.Model):
"peachjam.Work",
null=False,
on_delete=models.CASCADE,
related_name="citing_work",
related_name="outgoing_citations",
verbose_name=_("citing work"),
)
target_work = models.ForeignKey(
"peachjam.Work",
null=False,
on_delete=models.CASCADE,
related_name="target_work",
related_name="incoming_citations",
verbose_name=_("target work"),
)

Expand All @@ -100,6 +100,12 @@ def for_target_works(cls, work):
.order_by("citing_work__title")
)

@classmethod
def update_counts_for_work(cls, work):
work.n_cited_works = cls.for_citing_works(work).count()
work.n_citing_works = cls.for_target_works(work).count()
work.save(update_fields=["n_cited_works", "n_citing_works"])


class CitationProcessing(SingletonModel):
processing_date = models.DateField(_("processing date"), null=True, blank=True)
Expand Down
8 changes: 6 additions & 2 deletions peachjam/models/core_document_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ class Work(models.Model):
)
# the rank (weight) of this work in the graph network, computer by peachjam.graph.ranker
ranking = models.FloatField(_("ranking"), null=True, blank=False, default=0.0)
# number of outgoing citations
n_cited_works = models.IntegerField(_("number of cited works"), default=0)
# number of incoming citations
n_citing_works = models.IntegerField(_("number of incoming citations"), default=0)
Comment on lines +172 to +175
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was worried about this slowing down the pages with many citing documents but this solves that :)


class Meta:
verbose_name = _("work")
Expand Down Expand Up @@ -217,11 +221,11 @@ def fetch_cited_works_frbr_uris(self):
return work_frbr_uris

def cited_works(self):
"""Return Shows a list of works cited by the current work."""
"""Returns a list of works cited by the current work."""
return ExtractedCitation.for_citing_works(self).values("target_work")

def works_citing_current_work(self):
"""Shows a list of works that cite the current work."""
"""Returns a list of works that cite the current work."""
return ExtractedCitation.for_target_works(self).values("citing_work")

def save(self, *args, **kwargs):
Expand Down
16 changes: 15 additions & 1 deletion peachjam/signals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.db.models import signals
from django.dispatch import receiver

from peachjam.models import CoreDocument, SourceFile, Work
from peachjam.models import CoreDocument, ExtractedCitation, SourceFile, Work
from peachjam.tasks import update_extracted_citations_for_a_work


Expand Down Expand Up @@ -41,3 +41,17 @@ def convert_to_pdf(sender, instance, created, **kwargs):
"""Convert a source file to PDF when it's saved"""
if created:
instance.ensure_file_as_pdf()


@receiver(signals.post_save, sender=ExtractedCitation)
def extracted_citation_saved(sender, instance, **kwargs):
"""Update citation counts on works."""
ExtractedCitation.update_counts_for_work(instance.citing_work)
ExtractedCitation.update_counts_for_work(instance.target_work)


@receiver(signals.post_delete, sender=ExtractedCitation)
def extracted_citation_deleted(sender, instance, **kwargs):
"""Update citation counts on works."""
ExtractedCitation.update_counts_for_work(instance.citing_work)
ExtractedCitation.update_counts_for_work(instance.target_work)
8 changes: 4 additions & 4 deletions peachjam/templates/peachjam/_citations.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{% load peachjam i18n %}
<div class="container">
<div class="row">
<div class="col-sm mb-3">
<div class="col-lg mb-5">
<h4 class="mb-3">
<i class="bi bi-pj pj-citations"></i>
{% translate 'Cited documents' %} <span class="badge bg-secondary">{{ cited_documents_count }}</span>
{% translate 'Cited documents' %} <span class="badge bg-secondary">{{ document.work.n_cited_works }}</span>
</h4>
{% include 'peachjam/_citations_list.html' with citations=cited_documents group="outgoing" %}
</div>
<div class="col-sm">
<div class="col-lg">
<h4 class="mb-3">
{% translate 'Documents citing this one' %} <span class="badge bg-secondary">{{ documents_citing_current_doc_count }}</span>
{% translate 'Documents citing this one' %} <span class="badge bg-secondary">{{ document.work.n_citing_works }}</span>
</h4>
{% include 'peachjam/_citations_list.html' with citations=documents_citing_current_doc group="incoming" %}
</div>
Expand Down
27 changes: 14 additions & 13 deletions peachjam/templates/peachjam/_citations_list.html
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
{% load peachjam i18n %}
{% for item in citations %}
<h5 class="mt-3">
<h5 class="mt-4">
{{ item.doc_type }} <span class="badge bg-secondary">{{ item.docs|length }}</span>
</h5>
<ol class="mb-0">
{% for doc in item.docs|slice:":10" %}
<li class="{{ group }}">
<a href="{% url 'document_detail' frbr_uri=doc.work.frbr_uri|strip_first_character %}">{{ doc.title }}</a>
</li>
{% endfor %}
<table class="table table-striped table-borderless table-sm mb-0">
<colgroup>
<col />
<col style="width: 100%"/>
<col />
</colgroup>
<tbody>
{% include 'peachjam/_citations_list_items.html' with start=0 docs=item.docs|slice:":10" %}
</tbody>
{% if item.docs|length > 10 %}
{% for doc in item.docs|slice:"10:" %}
<li class="collapse {{ group }}-{{ forloop.parentloop.counter }}">
<a href="{% url 'document_detail' frbr_uri=doc.work.frbr_uri|strip_first_character %}">{{ doc.title }}</a>
</li>
{% endfor %}
<tbody class="collapse {{ group }}-{{ forloop.counter }}">
{% include 'peachjam/_citations_list_items.html' with start=10 docs=item.docs|slice:"10:" %}
</tbody>
{% endif %}
</ol>
</table>
{% if item.docs|length > 10 %}
<button class="btn btn-link"
data-bs-toggle="collapse"
Expand Down
18 changes: 18 additions & 0 deletions peachjam/templates/peachjam/_citations_list_items.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{% load peachjam i18n %}
{% for doc in docs %}
<tr>
<td>{{ start|add:forloop.counter }}.</td>
<td>
<a href="{% url 'document_detail' frbr_uri=doc.work.frbr_uri|strip_first_character %}">{{ doc.title }}</a>
</td>
<td class="text-nowrap">
{% if doc.work.n_citing_works %}
{% blocktrans trimmed count n=doc.work.n_citing_works %}
{{ n }} citation
{% plural %}
{{ n }} citations
{% endblocktrans %}
{% endif %}
</td>
</tr>
{% endfor %}
55 changes: 29 additions & 26 deletions peachjam/templates/peachjam/_related_documents.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,37 @@ <h4 class="mb-3">
{% trans "Related documents" %}
</h4>
<div class="row">
{% if relationships_as_subject %}
<div class="col-md">
<ul class="list-unstyled">
{% for rel in relationships_as_subject %}
{% if rel.object_work %}
<li>
{% translate rel.predicate.verb as verb %}
{{ verb|capfirst }}
<a href="{% url 'document_detail' frbr_uri=rel.object_work.frbr_uri|strip_first_character %}">{{ rel.object_work.title }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% if relationships_as_object %}
<div class="col-lg">
{% for verb, rels in relationships_as_object %}
<h4>{% translate verb as verb %}{{ verb|capfirst }}</h4>
<ol class="mb-4">
{% for rel in rels %}
{% if rel.subject_work %}
<li>
{% translate rel.predicate.reverse_verb as verb %}
<a href="{% url 'document_detail' frbr_uri=rel.subject_work.frbr_uri|strip_first_character %}">{{ rel.subject_work.title }}</a>
</li>
{% endif %}
{% endfor %}
</ol>
{% endfor %}
</div>
{% endif %}
{% if relationships_as_object %}
<div class="col-md">
<ul class="list-unstyled">
{% for rel in relationships_as_object %}
{% if rel.subject_work %}
<li>
{% translate rel.predicate.reverse_verb as verb %}
{{ verb|capfirst }}
<a href="{% url 'document_detail' frbr_uri=rel.subject_work.frbr_uri|strip_first_character %}">{{ rel.subject_work.title }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% if relationships_as_subject %}
<div class="col-lg mb-5">
{% for verb, rels in relationships_as_subject %}
<h4>{% translate verb as verb %}{{ verb|capfirst }}</h4>
<ol>
{% for rel in rels %}
{% if rel.object_work %}
<li>
<a href="{% url 'document_detail' frbr_uri=rel.object_work.frbr_uri|strip_first_character %}">{{ rel.object_work.title }}</a>
</li>
{% endif %}
{% endfor %}
</ol>
{% endfor %}
</div>
{% endif %}
</div>
2 changes: 1 addition & 1 deletion peachjam/templates/peachjam/layouts/document_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ <h1>{{ document.title }}</h1>
aria-selected="false">
<i class="bi bi-pj pj-citations"></i>
{% trans "Citations" %}
<span class="badge bg-secondary">{{ cited_documents_count|default:"-" }} / {{ documents_citing_current_doc_count|default:"-" }}</span>
<span class="badge bg-secondary">{{ document.work.n_cited_works|default:"-" }} / {{ document.work.n_citing_works|default:"-" }}</span>
</button>
</li>
{% endif %}
Expand Down
Loading
Loading