Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Empty file added __init__.py
Empty file.
6 changes: 6 additions & 0 deletions forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django import forms



class DummyManagerForm(forms.Form):
dummy_field = forms.CharField()
45 changes: 45 additions & 0 deletions hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from django.template import loader

from utils import setting_handler
from submission import forms
from plugins.coversheet.models import Coversheet


def coversheet_upload(context):
request = context.get('request')
coversheet_enabled = setting_handler.get_setting(
setting_group_name='plugin:coversheet',
setting_name='enable_coversheet_upload',
journal=request.journal,
).processed_value

if not coversheet_enabled:
return ''

coversheet_text = setting_handler.get_setting(
setting_group_name='plugin:coversheet',
setting_name='coversheet_text',
journal=request.journal,
).processed_value

coversheet_form = forms.FileDetails(
initial={
"label": 'Cover sheet',
}
)

coversheets = Coversheet.objects.filter(
article=context.get('article'),
)

# Convert RequestContext to plain dict
context_dict = context.flatten()
context_dict['coversheet_text'] = coversheet_text
context_dict['coversheet_form'] = coversheet_form
context_dict['coversheets'] = coversheets

template = loader.get_template('coversheet/upload.html')
return template.render(
context=context_dict,
request=request,
)
32 changes: 32 additions & 0 deletions install/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"group": {
"name": "plugin:coversheet"
},
"setting": {
"description": "Enable coversheet upload for this journal.",
"is_translatable": true,
"name": "enable_coversheet_upload",
"pretty_name": "Enable Coversheet Upload (PLUGIN)",
"type": "boolean"
},
"value": {
"default": false
}
},
{
"group": {
"name": "plugin:coversheet"
},
"setting": {
"description": "Text displayed above the coversheet upload block",
"is_translatable": true,
"name": "coversheet_text",
"pretty_name": "Coversheet Text (PLUGIN)",
"type": "char"
},
"value": {
"default": "Upload a coversheet for your article."
}
}
]
25 changes: 25 additions & 0 deletions migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.2.20 on 2025-09-05 14:29

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


class Migration(migrations.Migration):

initial = True

dependencies = [
('core', '0110_account_accessible_theme'),
('submission', '0088_auto_20250506_1214'),
]

operations = [
migrations.CreateModel(
name='Coversheet',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='submission.article')),
('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.file')),
],
),
]
Empty file added migrations/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.db import models

from submission.models import Article
from core.models import File


class Coversheet(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
file = models.ForeignKey(File, on_delete=models.CASCADE)
49 changes: 49 additions & 0 deletions plugin_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from utils import plugins
from utils.install import update_settings

PLUGIN_NAME = 'Coversheet Plugin'
DISPLAY_NAME = 'Coversheet'
DESCRIPTION = 'A plugin to allow authors to upload a cover sheet.'
AUTHOR = 'Andy Byers'
VERSION = '0.1'
SHORT_NAME = 'coversheet'
MANAGER_URL = 'coversheet_manager'
JANEWAY_VERSION = "1.3.8"



class CoversheetPlugin(plugins.Plugin):
plugin_name = PLUGIN_NAME
display_name = DISPLAY_NAME
description = DESCRIPTION
author = AUTHOR
short_name = SHORT_NAME
manager_url = MANAGER_URL

version = VERSION
janeway_version = JANEWAY_VERSION



def install():
CoversheetPlugin.install()
update_settings(
file_path='plugins/coversheet/install/settings.json'
)



def hook_registry():
# On site load, the load function is run for each installed plugin to generate
# a list of hooks.
return {
'submission_files':
{
'module': 'plugins.coversheet.hooks',
'function': 'coversheet_upload',
},
}


def register_for_events():
pass
15 changes: 15 additions & 0 deletions templates/coversheet/manager.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% extends "admin/core/base.html" %}
{% load foundation %}

{% block title %}Coversheet Manager{% endblock %}

{% block body %}
<div class="box">
<div class="title-area">
<h2>Management Form</h2>
</div>
<div class="content">
{{ form|foundation }}
</div>
</div>
{% endblock body %}
83 changes: 83 additions & 0 deletions templates/coversheet/upload.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<div class="title-area">
<h2>{% trans 'Cover Sheet' %}</h2>
</div>
<div class="row expanded">
<div class="large-3 columns">
<a href="#" data-open="coversheet" class="button success" name="data"><i class="fa fa-upload">
&nbsp;</i>{% trans "Upload" %}
</a>
</div>
<div class="large-9 columns col-md-offset-1">
<table class="scroll small">
<tr>
<th>{% trans "Label" %}</th>
<th>{% trans "File Name" %}</th>
<th></th>
</tr>
<form method="POST">
{% csrf_token %}
{% for coversheet in coversheets %}
<tr>
<td>{{ coversheet.file.label }}</td>
<td>{{ coversheet.file }}</td>
<td>
<button name="delete" type="submit" value="{{ coversheet.file.pk }}"><i
class="fa fa-trash"></i></button>
</td>
</tr>
{% empty %}
<tr>
<td colspan="3">{% trans "No files uploaded" %}</td>
</tr>
{% endfor %}
</form>
</table>
</div>
</div>


{% load foundation %}
{% load i18n %}

<div class="small reveal" id="coversheet" data-reveal>
<div class="card">
<div class="card-divider">
<h5>
<span class="fa fa-upload"></span>
{% trans "Add New File" %}
</h5>
</div>
<div class="card-section">
<div>
<p>{{ coversheet_text }}</p>
</div>
<form method="POST" enctype="multipart/form-data" action="{% url 'coversheet_upload' article.pk %}">
{% csrf_token %}
<div class="row">
<div class="large-12 columns">
<input
name="file"
type="file"
class="filestyle"
data-placeholder="No file"
data-buttonname="btn-primary">
</div>
</div>
{{ coversheet_form|foundation }}
<button
type="submit"
name="coversheet"
class="success button">
{% trans 'Add File' %}
</button>
<button
class="close-button"
data-close=""
aria-label="Close reveal"
type="button">
<span aria-hidden="true">×</span>
</button>
</form>
</div>
</div>
</div>
9 changes: 9 additions & 0 deletions urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.urls import re_path

from plugins.coversheet import views


urlpatterns = [
re_path(r'^manager/$', views.manager, name='coversheet_manager'),
re_path(r'^upload/(?P<article_id>\d+)$', views.coversheet_upload, name='coversheet_upload'),
]
66 changes: 66 additions & 0 deletions views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from django.shortcuts import render, get_object_or_404, redirect, reverse
from django.contrib import messages
from django.contrib.auth.decorators import login_required

from submission import models, forms, decorators
from core import files
from plugins.coversheet.models import Coversheet
from security.decorators import article_is_not_submitted, article_edit_user_required, submission_authorised


def manager(request):
form = forms.DummyManagerForm()

template = 'coversheet/manager.html'
context = {
'form': form,
}

return render(request, template, context)


@login_required
@decorators.submission_is_enabled
@article_is_not_submitted
@article_edit_user_required
@submission_authorised
def coversheet_upload(request, article_id):
article = get_object_or_404(
models.Article,
id=article_id,
journal=request.journal,
)
if "coversheet" in request.POST:
coversheet_form = forms.FileDetails(request.POST)
uploaded_file = request.FILES.get("file")
if coversheet_form.is_valid():
new_file = files.save_file_to_article(
uploaded_file,
article,
request.user,
)
new_file.label = coversheet_form.cleaned_data["label"]
new_file.description = coversheet_form.cleaned_data["description"]
new_file.save()
Coversheet.objects.create(
article=article,
file=new_file,
)

else:
for field, errors in coversheet_form.errors.items():
for error in errors:
messages.error(
request,
f"{field}: {error}",
)

else:
messages.error(
request,
"No file selected for upload.",
)

return redirect(
reverse("submit_files", kwargs={"article_id": article_id}),
)