Skip to content

Commit

Permalink
Merge pull request #387 from jacobdgm/develop
Browse files Browse the repository at this point in the history
Merge changes from develop into stag
  • Loading branch information
jacobdgm authored Oct 17, 2022
2 parents 51777f6 + 8df8191 commit 73a6cb2
Show file tree
Hide file tree
Showing 54 changed files with 926 additions and 259 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# CantusDB
Documentation for Cantus Database, including documentation on its APIs, can be found in the [Wiki](https://github.com/DDMAL/CantusDB/wiki).

Discrepancies between text stored in the CantusDB database and the manuscript text are compiled by testers in the following Google Spreadsheet: https://docs.google.com/spreadsheets/d/133lVOVM15l7a6bQKIQije4op363ragG4OXewYop_cbQ/edit#gid=0
## OldCantus vs. NewCantus

# OldCantus vs. NewCantus
This repository contains code for "NewCantus," an updated version of Cantus Database built in Django. "OldCantus", built in Drupal, can be accessed at https://cantus.uwaterloo.ca.

Known Differences in functionality/behavior between OldCantus and NewCantus
Discrepancies between text stored in the CantusDB database and the manuscript text are compiled by testers in the following Google Spreadsheet: https://docs.google.com/spreadsheets/d/133lVOVM15l7a6bQKIQije4op363ragG4OXewYop_cbQ/edit#gid=0

## Visible to All Users (Logged-In and Anonymous)
### Differences in functionality/behavior:
#### Visible to All Users (Logged-In and Anonymous)
- Several of the APIs from OldCantus are not implemented in NewCantus, or are implemented differently:
- json-activity (accessed via https://cantus.uwaterloo.ca/json-activity and https://cantus.uwaterloo.ca/json-activity?all) is not implemented in NewCantus ([Discussion](https://github.com/DDMAL/CantusDB/issues/126))
- json-analysis-export (accessed, we think, via [https://cantus.uwaterloo.ca/json-analysis-export/?src=\<source id\>](https://cantus.uwaterloo.ca/json-analysis-export/?src=123591)) is not implemented in NewCantus ([Discussion](https://github.com/DDMAL/CantusDB/issues/124))
- some of the keys in the json generated by json-node (accessed via [https://cantus.uwaterloo.ca/json-node/\<id\>](https://cantus.uwaterloo.ca/json-node/123591)) are different in NewCantus ([Discussion](https://github.com/DDMAL/CantusDB/issues/106))
- very soon, all people will be represented as Users in NewCantus. This is in contrast to OldCantus, where there were two separate lists of people: one of Indexers and one of Users. ([Discussion](https://github.com/DDMAL/CantusDB/issues/218))

## Logged-In Users
#### Logged-In Users
- on the edit-volpiano page, there are some additional links in NewCantus that were previously unclickable text in OldCantus ([Discussion](https://github.com/DDMAL/CantusDB/issues/253))
29 changes: 20 additions & 9 deletions django/cantusdb_project/latin_syllabification.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,25 @@
"th",
"sp",
]
diphthongs = ["ae", "au", "ei", "oe", "ui", "ya", "ex", "ix"]
vowels = ["a", "e", "i", "o", "u", "y"]
diphthongs = [
"ae",
"au",
"ei",
"oe",
"ui",
"ya",
"ex",
"ix",
"ihe", # ihe-sus, # ihe-ru-sa-lem
]
vowels = [
"a",
"e",
"i",
"o",
"u",
"y",
]

# add uppercase variants of every single symbol.
consonant_groups += [x[0].upper() + x[1:] for x in consonant_groups]
Expand All @@ -34,6 +51,7 @@ def clean_transcript(text):
text = re.sub(r" \| ", " ", text)
# change all runs of consecutive spaces to single spaces
text = re.sub(r" +", " ", text)
text = text.strip()
# convert to lowercase
# text = text.lower()
return text
Expand Down Expand Up @@ -188,17 +206,10 @@ def syllabify_text(input, verbose=False):
syl_list[-1] = syl_list[-1].strip("-")
word_syls_hyphen.append(syl_list)
syls = [item for sublist in word_syls_hyphen for item in sublist]
# syls = [item for sublist in word_syls for item in sublist]
return syls


if __name__ == "__main__":
# fpath = "/Users/tim/Desktop/002v_transcript.txt"
# with open(fpath) as f:
# ss = ' '.join(f.readlines())
# res = syllabify_text(ss, True)
# print(res)

inp = (
"Quique terrigene et filii hominum simul in unum dives et pauper Ite "
"Qui regis israel intende qui deducis velut ovem ioseph qui sedes super cherubin Nuncia "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ def handle(self, *args, **options):
if feast.feast_code:
feast.prefix = str(feast.feast_code)[0:2]
feast.save()
print(feast.prefix)
else: # feast_code is None, ""
feast.prefix = ""
feast.save()
8 changes: 8 additions & 0 deletions django/cantusdb_project/main_app/models/base_chant.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ class Meta:
# dact = models.CharField(blank=True, null=True, max_length=64)
# also a second differentia field

def get_ci_url(self) -> str:
"""Construct the url to the entry in Cantus Index correponding to the chant.
Returns:
str: The url to the Cantus Index page
"""
return f"http://cantusindex.org/id/{self.cantus_id}"

def __str__(self):
incipit = ""
if self.incipit:
Expand Down
7 changes: 0 additions & 7 deletions django/cantusdb_project/main_app/models/chant.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ class Chant(BaseChant):
properties and attributes should be declared in BaseChant in order to keep the two
models harmonized, even if only one of the two models uses a particular field.
"""
def get_ci_url(self) -> str:
"""Construct the url to the entry in Cantus Index correponding to the chant.
Returns:
str: The url to the Cantus Index page
"""
return f"http://cantusindex.org/id/{self.cantus_id}"

def index_components(self) -> dict:
"""Constructs a dictionary of weighted lists of search terms.
Expand Down
2 changes: 1 addition & 1 deletion django/cantusdb_project/main_app/models/feast.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Feast(BaseModel):
)

# the `prefix` field can be automatically populated by running `python manage.py add_prefix`
prefix = models.CharField(max_length=2, blank=True, null=True)
prefix = models.CharField(max_length=2, blank=True, null=True, editable=False)

class Meta:
constraints = [
Expand Down
1 change: 1 addition & 0 deletions django/cantusdb_project/main_app/models/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Source(BaseModel):
'"Provenance notes" field.',
null=True,
blank=True,
related_name="sources",
)
provenance_notes = models.TextField(
blank=True,
Expand Down
17 changes: 17 additions & 0 deletions django/cantusdb_project/main_app/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from main_app.models import Chant
from main_app.models import Sequence
from main_app.models import Feast

@receiver(post_save, sender=Chant)
def on_chant_save(instance, **kwargs):
Expand All @@ -33,6 +34,10 @@ def on_sequence_save(instance, **kwargs):
def on_sequence_delete(instance, **kwargs):
update_source_chant_count(instance)

@receiver(post_save, sender=Feast)
def on_feast_save(instance, **kwargs):
update_prefix_field(instance)


def update_chant_search_vector(instance):
"""When saving an instance of Chant, update its search vector field.
Expand Down Expand Up @@ -170,3 +175,15 @@ def generate_volpiano_intervals(volpiano_notes):
volpiano_intervals=volpiano_intervals,
)

def update_prefix_field(instance):
pk = instance.pk

if instance.feast_code:
prefix = str(instance.feast_code)[0:2]
instance.__class__.objects.filter(pk=pk).update(
prefix=prefix
)
else: # feast_code is None, ""
instance.__class__.objects.filter(pk=pk).update(
prefix=""
)
20 changes: 20 additions & 0 deletions django/cantusdb_project/main_app/templates/century_detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends "base.html" %}
{% block content %}
<title>{{ century.name }} | Cantus Manuscript Database</title>
<div class="mr-3 p-3 mx-auto bg-white rounded">
<!-- global search bar-->
<object align="right">
{% include "global_search_bar.html" %}
</object>
<h3>{{ century.name }}</h3>
<ul>
{% for source in century.sources.all|dictsort:"title" %}
<li>
<a href="{{ source.get_absolute_url }}">
{{ source.title }}
</a>
</li>
{% endfor %}
</ul>
</div>
{% endblock %}
15 changes: 8 additions & 7 deletions django/cantusdb_project/main_app/templates/chant_create.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{% extends "base.html" %}
{% load helper_tags %}
{% block content %}
<title>Create Chant | Cantus Manuscript Database</title>
<div class="container">
Expand Down Expand Up @@ -123,12 +122,15 @@ <h3>Create Chant</h3>
{% if previous_chant %}
Feasts that follow:
{% for feast, count in suggested_feasts.items %}
<a href="" onclick="return false;">{{ feast.name }}</a> ({{ count }}x) |
<a href="javascript:" onclick="autoFillFeast{{ feast.id }}();">{{ feast.name }}</a> ({{ count }}x) |
<script>
function autoFillFeast{{ feast.id }}() {
document.getElementById('id_feast').value = "{{ feast.id }}";
}
</script>
{% endfor %}

<strong>
<a href="" onclick="return false;">Revert Changes</a>
</strong>
<!-- eventually, perhaps: implement a "Reverse Changes" button -->
{% endif %}

</small>
Expand Down Expand Up @@ -272,9 +274,8 @@ <h5><a id="source" href="{{ source.get_absolute_url }}">{{ source.title }}</a></
<strong>{{ chant.genre }}</strong> - {{ chant.fulltext|truncatechars:100 }} (<strong>{{ chant.count }}x</strong>)<br>
<script>
function autoFill{{ chant.cid }}() {
const genreId = Array.prototype.find.call(document.getElementById('id_genre').children, ({ textContent }) => textContent === "{{ chant.genre }}");
document.getElementById('id_cantus_id').value = "{{ chant.cid }}";
document.getElementById('id_genre').value = genreId.value;
document.getElementById('id_genre').value = {{ chant.genre_id }};
document.getElementById('id_manuscript_full_text_std_spelling').value = "{{ chant.fulltext }}";
}
</script>
Expand Down
82 changes: 72 additions & 10 deletions django/cantusdb_project/main_app/templates/chant_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<h3>{{ chant.incipit }}</h3>
{% if user.is_authenticated %}
<p>
View | <a href="{% url 'source-edit-volpiano' chant.source.id %}?pk={{ chant.id }}&folio={{ chant.folio }}">Edit</a>
View | <a href="{% url 'source-edit-chants' chant.source.id %}?pk={{ chant.id }}&folio={{ chant.folio }}">Edit</a>
</p>
{% endif %}
<dl>
Expand Down Expand Up @@ -91,7 +91,11 @@ <h3>{{ chant.incipit }}</h3>
{% if chant.cantus_id %}
<div class="col">
<dt>Cantus ID</dt>
<dd>{{ chant.cantus_id }}</dd>
<dd>
<a href="{{ chant.get_ci_url }}" target="_blank">
{{ chant.cantus_id }}
</a>
</dd>
</div>
{% endif %}

Expand Down Expand Up @@ -193,13 +197,67 @@ <h3>{{ chant.incipit }}</h3>
</dd>
{% endif %}
</dl>

{% if chant.cantus_id %}
<h4>List of concordances</h4>
<span id="concordanceLoadingPrompt" style="display: none; color: #922"><b>Loading concordances...</b></span>
<a id="concordanceButton" href="#" onclick="loadConcordances('{{ chant.cantus_id }}'); return false;">» Display all concordances of this chant</a>
<div id="concordanceDiv"></div>
<br>
<small>{{ concordances_summary | safe }}</small>
<table id="concordanceTable" class="table table-bordered table-sm small" style="table-layout: fixed; width: 100%;">
<thead>
<tr>
<th scope="col" class="text-wrap" style="width:15%">Siglum</th>
<th scope="col" class="text-wrap" style="width:6%">Folio</th>
<th scope="col" class="text-wrap" style="width:23%">Incipit</th>
<th scope="col" class="text-wrap" style="width:4%"></th>
<th scope="col" class="text-wrap" style="width:4%"></th>
<th scope="col" class="text-wrap" style="width:4%"></th>
<th scope="col" class="text-wrap" style="width:20%">Feast</th>
<th scope="col" class="text-wrap" style="width:7%">Mode</th>
<th scope="col" class="text-wrap" style="width:8%">Image</th>
<th scope="col" class="text-wrap" style="width:9%">DB</th>
</tr>
</thead>
<tbody>
{% for chant in concordances %}
<tr>
<td>
<a href="{{ chant.srclink }}" target="_blank">
{{ chant.siglum }}
</a>
</td>
<td>
{{ chant.folio }}
</td>
<td>
<a href="{{ chant.chantlink }}" target="_blank">
{{ chant.incipit }}
</a>
</td>
<td>
{{ chant.office }}
</td>
<td>
{{ chant.genre }}
</td>
<td>
{{ chant.position }}
</td>
<td>
{{ chant.feast }}
</td>
<td>
{{ chant.mode }}
</td>
<td>
{% if chant.image %}
<a href="{{ chant.image }}" target="_blank">Image</a>
{% endif %}
</td>
<td>
{{ chant.db }}
</td>
</tr>
{% endfor %}
</tbody>
</table>

<h4>List of melodies</h4>
<span id="melodyLoadingPrompt" style="display: none; color: #922"><b>Loading melodies...</b></span>
Expand Down Expand Up @@ -322,14 +380,16 @@ <h4>List of melodies</h4>
<div class=" card-body">
<small>
{% if source.provenance.name %}
Provenance: <b>{{ source.provenance.name }}</b>
Provenance: <b><a href="{{ source.provenance.get_absolute_url }}">{{source.provenance.name}}</a></b>
<br>
{% endif %}

{% if source.date %}
Date:
{% for century in source.century.all %}
<b>{{ century.name }}</b>
<b>
<a href="{{ century.get_absolute_url }}">{{ century.name }}</a>
</b>
{% endfor %}
|
<b>{{ source.date|default_if_none:"" }}</b>
Expand All @@ -342,7 +402,9 @@ <h4>List of melodies</h4>
{% endif %}

{% if source.notation.all %}
Notation: <b>{{ source.notation.all.first.name }}</b>
<b>
<a href="{{ source.notation.all.first.get_absolute_url }}">{{ source.notation.all.first.name }}</a>
</b>
<br>
{% endif %}

Expand Down
10 changes: 5 additions & 5 deletions django/cantusdb_project/main_app/templates/chant_edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ <h3>Full text &amp; Volpiano edit form</h3>

<div class="card mb-3 w-100">
<div class="card-header">
<h4>{{ source.siglum }}</h4>
<h4><a href="{{ source.get_absolute_url }}">{{ source.siglum }}</a></h4>
</div>
<div class="card-body">
<small>
Expand All @@ -254,10 +254,10 @@ <h4>{{ source.siglum }}</h4>
</select>

{% if previous_folio %}
<a href="{% url "source-edit-volpiano" source.id %}?folio={{ previous_folio }}">{{ previous_folio }} <</a>
<a href="{% url "source-edit-chants" source.id %}?folio={{ previous_folio }}">{{ previous_folio }} <</a>
{% endif %}
{% if next_folio %}
&nbsp;<a href="{% url "source-edit-volpiano" source.id %}?folio={{ next_folio }}">> {{ next_folio }}</a>
&nbsp;<a href="{% url "source-edit-chants" source.id %}?folio={{ next_folio }}">> {{ next_folio }}</a>
{% endif %}

<br>
Expand All @@ -283,7 +283,7 @@ <h4>{{ source.siglum }}</h4>
<td class="h-25" style="width: 20%"><a href="{{ chant.get_ci_url }}" target="_blank">{{ chant.cantus_id|default_if_none:"" }}</a></td>
<td class="h-25" style="width: 5%">{{ chant.mode|default:"" }}</td>
<td class="h-25" style="width: 10%">
<a href="{% url 'source-edit-volpiano' source.id %}?pk={{ chant.pk }}&folio={{ chant.folio }}">EDIT</button></td>
<a href="{% url 'source-edit-chants' source.id %}?pk={{ chant.pk }}&folio={{ chant.folio }}">EDIT</button></td>
</tr>
{% endfor %}
</table>
Expand All @@ -301,7 +301,7 @@ <h4>{{ source.siglum }}</h4>
<td class="h-25" style="width: 20%"><a href="{{ chant.get_ci_url }}" target="_blank">{{ chant.cantus_id|default_if_none:"" }}</a></td>
<td class="h-25" style="width: 5%">{{ chant.mode|default:"" }}</td>
<td class="h-25" style="width: 10%">
<a href="{% url 'source-edit-volpiano' source.id %}?pk={{ chant.pk }}&feast={{ chant.feast.id }}">EDIT</button>
<a href="{% url 'source-edit-chants' source.id %}?pk={{ chant.pk }}&feast={{ chant.feast.id }}">EDIT</button>
</td>
</tr>
{% endfor %}
Expand Down
Loading

0 comments on commit 73a6cb2

Please sign in to comment.