Commit 95a2b05d authored by Samuel GAIST's avatar Samuel GAIST Committed by Flavio TARSETTI
Browse files

[reports][all] Pre-commit cleanup

parent e893f0c4
Pipeline #42746 passed with stage
in 15 minutes and 33 seconds
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
#!/usr/bin/env python
# encoding: utf-8
###############################################################################
......@@ -30,86 +28,92 @@
# Flavio Tarsetti <flavio.tarsetti@idiap.ch>
# Wed May 20 15:46:11 CEST 2015
from django.contrib import admin
import simplejson as json
from django import forms
from django.contrib import admin
from ..common.texts import Messages
from ..ui.forms import CodeMirrorJSONCharField
from ..ui.forms import CodeMirrorRSTCharField
from .models import Report
from ..ui.forms import CodeMirrorRSTCharField, CodeMirrorJSONCharField
from ..ui.forms import NameField
import simplejson as json
class ReportModelForm(forms.ModelForm):
description = CodeMirrorRSTCharField(
label='Description',
required=False,
help_text=Messages['description'],
label="Description", required=False, help_text=Messages["description"],
)
content = CodeMirrorJSONCharField(
label='Content',
help_text=Messages['json'],
)
content = CodeMirrorJSONCharField(label="Content", help_text=Messages["json"],)
def clean_content(self):
"""Cleans-up the content data, make sure it is really new"""
try:
data = json.loads(self.cleaned_data['content'])
data = json.loads(self.cleaned_data["content"])
return json.dumps(data, indent=4)
except Exception as e:
raise forms.ValidationError(str(e))
class ReportAdmin(admin.ModelAdmin):
form = ReportModelForm
readonly_fields = ('referenced_plotters', 'referenced_plotterparameters')
readonly_fields = ("referenced_plotters", "referenced_plotterparameters")
filter_horizontal = [
'experiments',
'referenced_plotters',
'referenced_plotterparameters'
"experiments",
"referenced_plotters",
"referenced_plotterparameters",
]
fieldsets = (
(None,
dict(
fields=('status', 'name', 'number', 'author',),
),
),
('Dates',
dict(
classes=('collapse',),
fields=('creation_date', 'expiration_date', 'publication_date',),
),
),
('Documentation',
dict(
classes=('collapse',),
fields=('short_description', 'description',),
),
),
(None,
dict(
fields=('analyzer', 'experiments', 'referenced_plotters', 'referenced_plotterparameters', 'content',),
),
),
(None, dict(fields=("status", "name", "number", "author",),),),
(
"Dates",
dict(
classes=("collapse",),
fields=("creation_date", "expiration_date", "publication_date",),
),
),
(
"Documentation",
dict(classes=("collapse",), fields=("short_description", "description",),),
),
(
None,
dict(
fields=(
"analyzer",
"experiments",
"referenced_plotters",
"referenced_plotterparameters",
"content",
),
),
),
)
list_display = ('id', 'name', 'number', 'author', 'creation_date', 'expiration_date', 'publication_date')
search_fields = [
'author__username',
'name',
'short_description',
'description',
'number',
list_display = (
"id",
"name",
"number",
"author",
"creation_date",
"expiration_date",
"publication_date",
)
search_fields = [
"author__username",
"name",
"short_description",
"description",
"number",
]
list_display_links = ('id', 'name')
list_display_links = ("id", "name")
list_filter = ("author", "name")
list_filter = ('author', 'name')
admin.site.register(Report, ReportAdmin)
......@@ -26,44 +26,38 @@
###############################################################################
import json
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from django.conf import settings
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from django.db.models import Q
from django.shortcuts import get_object_or_404
from django.urls import reverse
from rest_framework import generics
from rest_framework import views
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework import status
from rest_framework import views
from rest_framework.response import Response
from ..common.models import Shareable
from ..common.exceptions import ShareError
from ..common.mixins import CommonContextMixin
from ..common.responses import BadRequestResponse, ForbiddenResponse
from ..common.models import Shareable
from ..common.responses import BadRequestResponse
from ..common.responses import ForbiddenResponse
from ..common.utils import ensure_html
from ..experiments.serializers import ExperimentResultsSerializer
from .serializers import SimpleReportSerializer
from .models import Report
from .permissions import IsAccessibleOutside
from .permissions import IsAuthor
from .permissions import IsAuthorOrPublished
from .permissions import IsEditable
from .permissions import IsLocked
from .serializers import FullReportSerializer
from .serializers import ReportCreationFailedException
from .serializers import ReportCreationSerializer
from .serializers import ReportUpdateSerializer
from .serializers import ReportCreationFailedException
from .models import Report
from .permissions import (
IsAuthor,
IsAuthorOrPublished,
IsAccessibleOutside,
IsEditable,
IsLocked,
)
from .serializers import SimpleReportSerializer
# ----------------------------------------------------------
......
......@@ -25,55 +25,60 @@
# #
###############################################################################
from django.db import models
import random
from datetime import datetime
import simplejson as json
from django.conf import settings
from django.contrib.auth.models import User
from django.core import exceptions as django_exceptions
from django.db import models
from django.urls import reverse
from django.utils.encoding import force_bytes, force_text
from django.conf import settings
from ..common.utils import validate_restructuredtext
from ..ui.templatetags.markup import restructuredtext
from django.utils.encoding import force_bytes
from django.utils.encoding import force_text
from docutils.core import publish_parts
from ..algorithms.models import Algorithm
from ..common.texts import Messages
from ..experiments.models import Experiment
from ..plotters.models import Plotter
from ..plotters.models import PlotterParameter
from ..common.texts import Messages
import random
from datetime import datetime
import simplejson as json
#----------------------------------------------------------
# ----------------------------------------------------------
class ReportManager(models.Manager):
def create_object(self, author, name, short_description='', description='', content={},
experiments=[]):
def create_object(
self,
author,
name,
short_description="",
description="",
content={},
experiments=[],
):
# Creation of the report
report = Report()
report.name = name
report.author = author
report = Report()
report.name = name
report.author = author
report.short_description = short_description
report.description = description
report.description = description
if isinstance(content, dict):
report.content = json.dumps(content, indent=4)
report.content = json.dumps(content, indent=4)
else:
report.content = content
report.creation_date = datetime.now()
report.last_edited_date = datetime.now()
report.publication_date = None
report.expiration_date = None
report.status = self.model.EDITABLE
report.content = content
report.creation_date = datetime.now()
report.last_edited_date = datetime.now()
report.publication_date = None
report.expiration_date = None
report.status = self.model.EDITABLE
report.save()
# Add the experiments
result = report.add_experiments(experiments)
if not(result['success']):
if not (result["success"]):
report.delete()
report = None
......@@ -88,116 +93,99 @@ class ReportManager(models.Manager):
def published(self):
return self.filter(status=Report.PUBLISHED)
#----------------------------------------------------------
# ----------------------------------------------------------
class Report(models.Model):
#_____ Constants __________
# _____ Constants __________
EDITABLE = 'E'
LOCKED = 'L'
PUBLISHED = 'P'
EDITABLE = "E"
LOCKED = "L"
PUBLISHED = "P"
REPORT_STATUS = (
(EDITABLE, 'Editable'),
(LOCKED, 'Locked'),
(PUBLISHED, 'Published'),
(EDITABLE, "Editable"),
(LOCKED, "Locked"),
(PUBLISHED, "Published"),
)
# _____ Fields __________
#_____ Fields __________
status = models.CharField(max_length=1, choices=REPORT_STATUS, default=EDITABLE)
name = models.CharField(max_length=200, help_text=Messages['name'], blank=False)
number = models.IntegerField(blank=True)
author = models.ForeignKey(User, related_name='%(class)ss', on_delete=models.CASCADE)
experiments = models.ManyToManyField(Experiment, related_name='reports', blank=True)
creation_date = models.DateTimeField()
last_edited_date = models.DateTimeField(null=True)
expiration_date = models.DateTimeField(null=True, blank=True)
publication_date = models.DateTimeField(null=True, blank=True)
short_description = models.CharField(max_length=100, default='', blank=True, help_text=Messages['short_description'])
description = models.TextField(default='', blank=True)
content = models.TextField(default='{}', blank=True)
analyzer = models.ForeignKey(Algorithm, related_name='reports', null=True, blank=True, on_delete=models.CASCADE)
status = models.CharField(max_length=1, choices=REPORT_STATUS, default=EDITABLE)
name = models.CharField(max_length=200, help_text=Messages["name"], blank=False)
number = models.IntegerField(blank=True)
author = models.ForeignKey(
User, related_name="%(class)ss", on_delete=models.CASCADE
)
experiments = models.ManyToManyField(Experiment, related_name="reports", blank=True)
creation_date = models.DateTimeField()
last_edited_date = models.DateTimeField(null=True)
expiration_date = models.DateTimeField(null=True, blank=True)
publication_date = models.DateTimeField(null=True, blank=True)
short_description = models.CharField(
max_length=100, default="", blank=True, help_text=Messages["short_description"]
)
description = models.TextField(default="", blank=True)
content = models.TextField(default="{}", blank=True)
analyzer = models.ForeignKey(
Algorithm,
related_name="reports",
null=True,
blank=True,
on_delete=models.CASCADE,
)
# read-only parameters that are updated at every save(), if required
referenced_plotters = models.ManyToManyField(Plotter, related_name='reports', blank=True)
referenced_plotterparameters = models.ManyToManyField(PlotterParameter, related_name='reports', blank=True)
referenced_plotters = models.ManyToManyField(
Plotter, related_name="reports", blank=True
)
referenced_plotterparameters = models.ManyToManyField(
PlotterParameter, related_name="reports", blank=True
)
objects = ReportManager()
def __str__(self):
return "Report %s (#%d)" % (self.fullname(), self.number)
def fullname(self):
return '%s/%s' % (self.author.username, self.name)
return "%s/%s" % (self.author.username, self.name)
def get_absolute_url(self):
return reverse(
'reports:view',
args=(
self.number,
),
)
return reverse("reports:view", args=(self.number,),)
def get_author_absolute_url(self):
return reverse(
'reports:author-view',
args=(
self.author.username,
self.name
),
)
return reverse("reports:author-view", args=(self.author.username, self.name),)
def get_api_update_url(self):
return reverse(
'api_reports:object',
args=(
self.author.username,
self.name
),
)
return reverse("api_reports:object", args=(self.author.username, self.name),)
def get_api_add_url(self):
return reverse(
'api_reports:add_experiments',
args=(
self.author.username,
self.name
),
"api_reports:add_experiments", args=(self.author.username, self.name),
)
def get_api_remove_url(self):
return reverse(
'api_reports:remove_experiments',
args=(
self.author.username,
self.name
),
"api_reports:remove_experiments", args=(self.author.username, self.name),
)
def save(self, *args, **kwargs):
if self.number is None:
# Generate a unique report number
used_numbers = map(lambda x: x.number, Report.objects.all())
used_numbers = Report.objects.values_list("number", flat=True)
number = 0
while (number == 0) or number in used_numbers:
number = random.randint(100000, 2**31)
number = random.randint(100000, 2 ** 31) # nosec
self.number = number
report_content = json.loads(self.content)
report_content_charts = dict(filter(lambda item: item[0].startswith("chart"),report_content.items()))
report_content_charts = dict(
filter(lambda item: item[0].startswith("chart"), report_content.items())
)
self.last_edited_date = datetime.now()
......@@ -206,38 +194,46 @@ class Report(models.Model):
self.referenced_plotters.clear()
self.referenced_plotterparameters.clear()
for key, value in report_content_charts.items():
plotter_parts = value['data']['plotter'].split("/")
plotterparameters_parts = value['selected_template'].split("/")
plotter = Plotter.objects.get(author__username = plotter_parts[0], name = plotter_parts[1], version = plotter_parts[2])
plotterparameter = PlotterParameter.objects.get(author__username = plotterparameters_parts[0], name = plotterparameters_parts[1], version = plotterparameters_parts[2])
plotter_parts = value["data"]["plotter"].split("/")
plotterparameters_parts = value["selected_template"].split("/")
plotter = Plotter.objects.get(
author__username=plotter_parts[0],
name=plotter_parts[1],
version=plotter_parts[2],
)
plotterparameter = PlotterParameter.objects.get(
author__username=plotterparameters_parts[0],
name=plotterparameters_parts[1],
version=plotterparameters_parts[2],
)
self.referenced_plotters.add(plotter)
self.referenced_plotterparameters.add(plotterparameter)
def add_experiments(self, experiment_fullname_list):
# Check that the report is modifiable
if self.status != Report.EDITABLE:
return {
'success': False,
'error': "Report not modifiable",
"success": False,
"error": "Report not modifiable",
}
# Process the list of experiments
accessible_experiments = []
inaccessible_experiments = []
experiments, unknown_experiments = self._get_experiments_from_fullname_list(experiment_fullname_list)
experiments, unknown_experiments = self._get_experiments_from_fullname_list(
experiment_fullname_list
)
for experiment in experiments:
# Check experiments accessibility
(is_accessible, accessibility) = experiment.accessibility_for(self.author)
if not(is_accessible) or (experiment.status != Experiment.DONE):
if not (is_accessible) or (experiment.status != Experiment.DONE):
inaccessible_experiments.append(experiment.fullname())
continue
accessible_experiments.append(experiment)
# Add the experiments to the report
incompatible_experiments = []
for experiment in accessible_experiments:
......@@ -247,20 +243,21 @@ class Report(models.Model):
incompatible_experiments.append(experiment.fullname())
return {
'success': True,
'unknown_experiments': unknown_experiments,
'inaccessible_experiments': inaccessible_experiments,
'incompatible_experiments': incompatible_experiments,
"success": True,
"unknown_experiments": unknown_experiments,
"inaccessible_experiments": inaccessible_experiments,
"incompatible_experiments": incompatible_experiments,
}
def remove_experiments(self, experiment_fullname_list):
# Check that the report is modifiable
if self.status != Report.EDITABLE:
return
experiments, unknown_experiments = self._get_experiments_from_fullname_list(experiment_fullname_list)
experiments, unknown_experiments = self._get_experiments_from_fullname_list(
experiment_fullname_list
)
for experiment in experiments:
self.experiments.remove(experiment)
......@@ -269,23 +266,26 @@ class Report(models.Model):
self.analyzer = None
self.save()
def _get_experiments_from_fullname_list(self, experiment_fullname_list):
experiments = []
unknown_experiments = []
for experiment_name in experiment_fullname_list:
parts = experiment_name.split('/')
parts = experiment_name.split("/")
if len(parts) != 5:
raise ValidationError({'experiment': 'Invalid experiment full name'})
raise django_exceptions.ValidationError(
{"experiment": "Invalid experiment full name"}
)
try:
experiment = Experiment.objects.get(author__username=parts[0],
toolchain__author__username=parts[1],
toolchain__name=parts[2],
toolchain__version=int(parts[3]),
name=parts[4])
experiment = Experiment.objects.get(
author__username=parts[0],
toolchain__author__username=parts[1],
toolchain__name=parts[2],
toolchain__version=int(parts[3]),
name=parts[4],
)
except Experiment.DoesNotExist:
unknown_experiments.append(experiment_name)
else:
......@@ -293,7 +293,6 @@ class Report(models.Model):
return experiments, unknown_experiments
def _get_experiments_and_alias(self, alias_filter):
experiments_list = []
......@@ -306,38 +305,40 @@ class Report(models.Model):
for experiment in self.experiments.iterator():
if experiment.fullname() not in report_content["alias_experiments"]:
report_content["alias_experiments"][experiment.fullname()] = experiment.name
report_content["alias_experiments"][
experiment.fullname()
] = experiment.name
try:
index = alias_filter.index(report_content["alias_experiments"][experiment.fullname()])
alias_filter.index(
report_content["alias_experiments"][experiment.fullname()]
)
experiments_list.append(experiment.fullname())
except:
except Exception: # nosec
pass
alias_list = map(lambda x: report_content["alias_experiments"][x], experiments_list)
alias_list = map(
lambda x: report_content["alias_experiments"][x], experiments_list