Skip to content

Commit

Permalink
Merge pull request #212 from CMSTrackerDPG/#209
Browse files Browse the repository at this point in the history
Save extra summary information submitted by shifters [Closes #209]
  • Loading branch information
nothingface0 authored Aug 26, 2022
2 parents 758001f + 473eaa5 commit 2412575
Show file tree
Hide file tree
Showing 15 changed files with 397 additions and 88 deletions.
9 changes: 9 additions & 0 deletions certifier/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from shiftleader.exceptions import CannotAssumeRunTypeException
from listruns.utilities.luminosity import convert_luminosity_to_pb
from oms.models import OmsFill
from summary.models import SummaryInfo

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -314,6 +315,14 @@ def fill_numbers(self):
.values("fill_number")
]

def prompt_feedback_plots(self):
""" """
run_numbers = self.run_numbers()
return [
summary.links_prompt_feedback
for summary in SummaryInfo.objects.filter(runs=run_numbers)
]

def pks(self):
"""
:return: sorted list of primary keys
Expand Down
2 changes: 1 addition & 1 deletion dqmhelper/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
messages.ERROR: "danger",
}
# Version to display in order to keep track of changes
CERTHELPER_VERSION = "1.9.2"
CERTHELPER_VERSION = "1.10.0"

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = Path(__file__).resolve().parent.parent
Expand Down
30 changes: 23 additions & 7 deletions dqmhelper/test_settings.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
from .settings import *

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'database',
if os.environ.get("GITHUB_WORKFLOW"):
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "github_actions",
"USER": "postgres",
"PASSWORD": "postgres",
"HOST": "127.0.0.1",
"PORT": "5432",
}
}
else:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "postgres-local",
"USER": "postgres",
"PASSWORD": "postgres",
"PORT": "5432"
# 'HOST': 'localhost'
}
}
}

DYNAMIC_PREFERENCES = {
'ENABLE_CACHE': False,
"ENABLE_CACHE": False,
}

EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
16 changes: 14 additions & 2 deletions shiftleader/templates/shiftleader/day-by-day.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,20 @@ <h3>Day by day notes: {{ day.name|title }}, {{ day.date|yyyymmdd_to_ddmmyyyy }}<
</li>
</ul>

Daily Shifter Summaries: <strong>link1</strong>, <strong>link2</strong>
Prompt Feedback plots: <strong>link1</strong>
<p>
Daily Shifter Summaries: <strong>link1</strong>, <strong>link2</strong>
</p>
<p>
Prompt Feedback plots:
<ul>
{% for link in day.runs.prompt_feedback_plots %}
<li><strong>{{ link }}</strong></li>
{%endfor%}
</ul>



</p>
</p>
</div>
{% endfor %}
4 changes: 4 additions & 0 deletions shiftleader/utilities/shiftleader_report_presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,11 @@ def _generate_flag_changed_good_run_list_element(runs) -> Element:
)
tb.addElement(list1)
tb.addElement(P(text="Daily Shifter Summaries:"))

tb.addElement(P(text="Prompt Feedback plots:"))
tb.addElement(
self._generate_list(list_items=day.runs.prompt_feedback_plots())
)

frame.addElement(tb)
page.addElement(frame)
Expand Down
2 changes: 2 additions & 0 deletions summary/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from django.contrib import admin
from summary.models import SummaryInfo

# Register your models here.
admin.site.register(SummaryInfo)
8 changes: 8 additions & 0 deletions summary/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django import forms
from summary.models import SummaryInfo


class SummaryExtraInfoForm(forms.ModelForm):
class Meta:
model = SummaryInfo
fields = ["links_prompt_feedback", "special_comment"]
24 changes: 24 additions & 0 deletions summary/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 4.0.6 on 2022-08-26 13:09

import django.contrib.postgres.fields
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='SummaryInfo',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('runs', django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), help_text='Unique summary for list of runs', size=None, unique=True)),
('links_prompt_feedback', models.TextField(help_text='tinyurl links to plots on cmsweb.cern.ch')),
('special_comment', models.TextField(blank=True, help_text='Special comment by shifter for this summary')),
],
),
]
30 changes: 29 additions & 1 deletion summary/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
from django.db import models
from django.contrib.postgres.fields import ArrayField
from summary.validators import validate_list_length

# Create your models here.

class SummaryInfo(models.Model):
"""
Information regarding a summary/Elog.
A summary is identified by the list of runs it is composed of
"""

runs = ArrayField(
base_field=models.IntegerField(null=False),
help_text="Unique summary for list of runs",
unique=True,
)
links_prompt_feedback = models.TextField(
help_text="tinyurl links to plots on cmsweb.cern.ch"
)
special_comment = models.TextField(
help_text="Special comment by shifter for this summary", blank=True
)

def save(self, *args, **kwargs):
# ArrayField does not seem to use a validators argument
validate_list_length(self.runs)
super().save(*args, **kwargs)

def __str__(self):
return f"{self.__class__.__name__} {self.runs}"
72 changes: 52 additions & 20 deletions summary/templates/summary/summary.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ <h6>Generated summary</h6>
I.e. new lines, spaces between <p> and <div> will
*also show inside the <pre>* !!
-->
<pre id="summary" class="pt-3">
-->
<form id="summary_form">
{{ csfr_token }}
<pre id="summary" class="pt-3">
=============Reference Runs===============
{% for ref in refs %}{{ ref }}
{% endfor %}
Expand All @@ -118,42 +120,61 @@ <h6>Generated summary</h6>
=============Sum of Quantities============
{% for sum in sums %}{{ sum }}
{% endfor %}
<div id=comment_div style="display: none;">
<div id="comment_div" style="{% if not form.special_comment %}display: none;{% else %}display: block;{% endif %}">
=============Special Comments=============
<p id=specialcomment_text></p><div id=formarea><textarea
rows="4" cols="40"
id=special_comment_textarea
form="usrform"
placeholder="Enter text here"></textarea><div align="center" class="row p-1"><div class="col"><button type="button" class="btn btn-light" onclick="write_to_comment_area()"><i class="bi bi-check-lg"></i> Apply</button></div><div class="col"><button type="button" class="btn btn-light" onclick="hide_comment_area()"><i class="bi bi-x-lg"></i> Remove</button></div></div></div></div>
<p id="specialcomment_text">{% if form.special_comment.initial %}{{ form.special_comment.initial }}{% endif %}</p><div id="formarea" style="display: none;">{{form.special_comment}}<div align="center" class="row p-1"><div class="col"><button type="button" class="btn btn-light" onclick="write_to_comment_area()"><i class="bi bi-check-lg"></i> Apply</button></div><div class="col"><button type="button" class="btn btn-light" onclick="hide_comment_area()"><i class="bi bi-x-lg"></i> Remove</button></div></div></div></div>
=============Link to the Prompt Feedback plots============
<p id=links_text>Please add the link</p><div id=links_div style="display: none;"><div id=linksarea><textarea
rows="4" cols="40"
id=links_textarea
form="usrform"
placeholder="Enter text here"></textarea><div align="center" class="row p-1"><div class="col"><button type="button" class="btn btn-light" onclick="write_to_text_area()"><i class="bi bi-check-lg"></i> OK</button></div></div></div></div></pre>
<!-- END PREFORMATTED TEXT -->
<p id="links_text">{% if form.links_prompt_feedback.initial %}{{ form.links_prompt_feedback.initial }}{%endif%}</p><div id="links_div" style="display: none;"><div id="linksarea">{{form.links_prompt_feedback}}<div align="center" class="row p-1"><div class="col"><button type="button" class="btn btn-light" onclick="write_to_text_area()"><i class="bi bi-check-lg"></i> OK</button></div></div></div></div></pre>
<!-- END PREFORMATTED TEXT -->
</form>
</div>
</div>
</div>
{% endblock content %}

{% block scripts %}
<script>
function submit_form(){
$.ajax({
headers: { "X-CSRFToken": '{{csrf_token}}' },
type: "POST",
url: "{% url 'summary:summary' %}",
data: {
// Is there a better idea which automatically gets
// all form fields without directly referencing them? dunno
'links_prompt_feedback': $('#id_links_prompt_feedback').val(),
'special_comment' : $('#id_special_comment').val(),
'runs_list': "{{runs_list}}"
},
success: function(data) {
if(!data.success){
alert(`Error! ${data.msg}`)
}

},
})
}

function show_special_comment_area() {
$('#comment_div').css('display', 'inline-block');
$('#formarea').css('display', 'inline-block');
$('#specialcomment_text').css('display', 'None');
$('#comment_div').css('display', 'inline-block');
$('#formarea').css('display', 'inline-block');
$('#specialcomment_text').css('display', 'None');
}

function write_to_comment_area() {
let t = $('#special_comment_textarea').val();
// Get text from form field, append it to HTML
function write_to_comment_area(t=$('#id_special_comment').val()) {
console.log(t)
$('#specialcomment_text').html(t);
$('#formarea').css('display', 'None');
$('#specialcomment_text').css('display', 'inline-block');
submit_form();
}

function hide_comment_area() {
$('#comment_div').css('display', 'None');
$('#id_special_comment').html(""),
write_to_comment_area("");

}

function show_links_area() {
Expand All @@ -162,12 +183,23 @@ <h6>Generated summary</h6>
$('#links_text').css('display', 'None');
}

// Get text from links field, append it to HTML
function write_to_text_area() {
let t = $('#links_textarea').val();
let t = $('#id_links_prompt_feedback').val();
$('#links_text').html(t);
$('#linksarea').css('display', 'None');
$('#links_text').css('display', 'inline-block');
submit_form();
}

window.addEventListener("load", function(){
// Prevent refreshing the page on submission
var form = document.getElementById("summary_form");
form.onsubmit =function(e){
e.preventDefault();
}
});


</script>
{% endblock scripts %}
88 changes: 81 additions & 7 deletions summary/tests/test_summary_views.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,95 @@
import pytest
import json
from django.test import RequestFactory
from mixer.backend.django import mixer

from django.urls import reverse
from django.contrib.auth.models import AnonymousUser
from django.contrib.auth import get_user_model
from summary.views import *
from users.models import User
from summary.views import SummaryView
from summary.forms import SummaryExtraInfoForm
from oms.models import OmsRun
from certifier.models import TrackerCertification

pytestmark = pytest.mark.django_db


def test_view_requires_login():
req = RequestFactory().get("summary/")
def test_view_requires_shifter_rights():
#
req = RequestFactory().get(reverse("summary:summary"))
req.user = AnonymousUser()
resp = summaryView(req)
resp = SummaryView.as_view()(req)
assert resp.status_code == 302

req.user = mixer.blend(get_user_model())
resp = summaryView(req)
req.user = mixer.blend(User, user_privilege=User.SHIFTER)

resp = SummaryView.as_view()(req)
assert resp.status_code == 200


def test_get_success():

user = mixer.blend(User, user_privilege=User.SHIFTER)
certs = [
mixer.blend(
TrackerCertification, runreconstruction__run__run_number=355555, user=user
),
mixer.blend(
TrackerCertification, runreconstruction__run__run_number=299929, user=user
),
]
runs_list = [cert.runreconstruction.run.run_number for cert in certs]

req = RequestFactory().get(reverse("summary:summary"))

req.user = user

resp = SummaryView.as_view()(req)
assert resp.status_code == 200
assert (
TrackerCertification.objects.filter(
runreconstruction__run__run_number__in=[355555, 299929]
).count()
== 2
)


def test_post_success():
runs = [
mixer.blend(OmsRun, run_number=355555),
mixer.blend(OmsRun, run_number=299929),
]

runs_list = [run.run_number for run in runs]
form = SummaryExtraInfoForm(
data={"runs_list": str(runs_list), "links_prompt_feedback": "link1, link2"}
)
assert form.is_valid()

req = RequestFactory().post(reverse("summary:summary"), data=form.data)

req.user = mixer.blend(User, user_privilege=User.SHIFTER)

resp = SummaryView.as_view()(req)
assert resp.status_code == 200
result = json.loads(resp.content)
assert result["success"] == True


def test_post_failure():

form = SummaryExtraInfoForm(
data={
"runs_list": str([]),
}
)
assert form.is_valid() == False

req = RequestFactory().post(reverse("summary:summary"), data=form.data)

req.user = mixer.blend(User, user_privilege=User.SHIFTER)

resp = SummaryView.as_view()(req)
assert resp.status_code == 200
result = json.loads(resp.content)
assert result["success"] == False
Loading

0 comments on commit 2412575

Please sign in to comment.