Skip to content

Commit

Permalink
fix version file upload for large files
Browse files Browse the repository at this point in the history
  • Loading branch information
IonMich committed Oct 27, 2023
1 parent 13c9ebd commit f28a94a
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 45 deletions.
6 changes: 5 additions & 1 deletion assignments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.db.models import F, Max, Q
from django.urls import reverse

from assignments.utils import versionfile_upload_to
from courses.models import Course
from courses.utils import API_URL, get_canvas_course, get_canvas_object
from courses.views import course_detail_view
Expand Down Expand Up @@ -482,7 +483,10 @@ def __str__(self):

class VersionFile(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
version_file = models.FileField(upload_to='assignments/versions/', null=True, blank=True)
version_file = models.FileField(
upload_to=versionfile_upload_to,
null=True,
blank=True)
version = models.ForeignKey(Version, on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
Expand Down
22 changes: 12 additions & 10 deletions assignments/static/assignments/detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,6 @@ function version_modal (data) {
newTabContent.className = 'tab-pane fade';
newTabContent.id = 'pills-home' + i;
newTabContent.setAttribute('role', 'tabpanel');
newTabContent.setAttribute('role', 'tabpanel');
newTabContent.setAttribute('aria-labelledby', 'pills-home-tab' + i);
// show the first tab content by default
if (i == 1) {
Expand Down Expand Up @@ -1296,7 +1295,10 @@ function version_modal (data) {
let oldFiles = document.createElement('div');
oldFiles.className = 'form-group';
oldFiles.id = 'oldFiles' + i;
// add the old texts to the old files div
// if there are no old files/texts, add display none to the old files div
if ((data['version_texts'][i] == undefined) && (data['version_pdfs'][i] == undefined)) {
oldFilesDiv.style = 'display: none;';
}
// check if data['version_texts'][i] is not empty
if (data['version_texts'][i] != undefined) {
for (let j = 0; j < data['version_texts'][i].length; j++) {
Expand All @@ -1308,9 +1310,9 @@ function version_modal (data) {

// create a new button to delete the old files and texts
let deleteButton = document.createElement('button');
deleteButton.className = 'btn btn-outline-light';
deleteButton.className = 'btn btn-outline-danger';
deleteButton.id = 'deleteButtonText' + i + j;
deleteButton.innerHTML = 'x';
deleteButton.innerHTML = '<i class="bi bi-trash"></i>';
// make its size smaller
deleteButton.style = 'font-size: 12px; padding: 0px 4px; margin-left: 8px; border-radius: 4px;';
deleteButton.addEventListener('click', function() {
Expand Down Expand Up @@ -1351,9 +1353,9 @@ function version_modal (data) {
fileLink.innerHTML = data['version_pdfs'][i][j]['name'];
// create a new button to delete the old files and texts
let deleteButton = document.createElement('button');
deleteButton.className = 'btn btn-outline-light';
deleteButton.className = 'btn btn-outline-danger';
deleteButton.id = 'deleteButtonFile' + i + j;
deleteButton.innerHTML = 'x';
deleteButton.innerHTML = '<i class="bi bi-trash"></i>';


// make its size smaller
Expand Down Expand Up @@ -1503,15 +1505,15 @@ if(updateVersion) {
// display the success message in the div with id clusterMessage
let clusterMessage = document.getElementById('clusterMessage');
clusterMessage.className = 'alert alert-success';
clusterMessage.innerHTML = 'Solutions for versions uploaded successfully.';
clusterMessage.innerHTML = 'Version comments added successfully.';

}
// if the message is failure
else {
// display the failure message in the div with id clusterMessage
let clusterMessage = document.getElementById('clusterMessage');
clusterMessage.className = 'alert alert-danger';
clusterMessage.innerHTML = 'Solutions for versions uploaded unsuccessfully.';
clusterMessage.innerHTML = 'Version comments could not be added.';
}
})
.catch(error => {
Expand All @@ -1523,8 +1525,8 @@ if(updateVersion) {

// add an event listener to update version button
const btnClusterV = document.getElementById('btnClusterV');
if(btnClusterV) {
btnClusterV.addEventListener('click', function(event) {
if (btnClusterV) {
btnClusterV.addEventListener('click', function(event) {
// stop the default action of the button
event.preventDefault();

Expand Down
5 changes: 2 additions & 3 deletions assignments/static/assignments/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@
}

.oldFiles {
background-color: #f5f5f5;
padding: 8px;
border-radius: 4px;
border-radius: 0.5rem;
margin-bottom: 8px;
border: 2px solid #e3e3e3;
border: 2px solid var(--bs-gray-300);
}

.labels {
Expand Down
16 changes: 15 additions & 1 deletion assignments/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import os


def delete_versions(assignment):
"""Delete all versions of an assignment."""
# delete the old versions if any
Expand All @@ -8,4 +11,15 @@ def delete_versions(assignment):
pass
finally:
assignment.versioned = False
assignment.save()
assignment.save()

def versionfile_upload_to(instance, filename):
"""
Return the relative path where the version file should be saved.
"""
return os.path.join(
"submissions",
f"course_{instance.version.assignment.course.pk}",
f"assignment_{instance.version.assignment.pk}",
"comment",
filename)
40 changes: 10 additions & 30 deletions assignments/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core import serializers
from django.core.files.storage import FileSystemStorage
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.core.files.base import ContentFile
from django.db.models import Max
from django.forms.models import model_to_dict
from django.http import JsonResponse
Expand Down Expand Up @@ -305,38 +304,19 @@ def version_submission(request, course_pk, assignment_pk):
new_version_text.save()
# get the files for this version
if request.FILES.get('versionFiles' + str(version.name)):
# set up the file system storage
new_comment_file_dir_in_media = os.path.join("submissions",
f"course_{version.assignment.course.pk}",
f"assignment_{version.assignment.pk}",
"comment")
new_comment_file_dir = os.path.join(
settings.MEDIA_ROOT,
new_comment_file_dir_in_media)

if not os.path.exists(new_comment_file_dir):
os.makedirs(new_comment_file_dir)
# add this as comment file for this submission
files = request.FILES.getlist('versionFiles' + str(version.name))
for file in files:
if isinstance(file, InMemoryUploadedFile):
# save the file to the file system
file_name = FileSystemStorage(location=new_comment_file_dir).save(file.name, file)
# copy file to new location, while keeping the original name
new_file_path_in_media = os.path.join(
new_comment_file_dir_in_media,
file_name,
file_bytes = file.read()
file_name = file.name
django_file = ContentFile(file_bytes, name=file_name)
new_version_file = VersionFile.objects.create(
version=version,
version_file=django_file,
author=request.user,
)

# add this to the database
new_version_file = VersionFile.objects.create(
version=version,
version_file=new_file_path_in_media,
author=request.user,
)
new_version_file.save()
else:
print("file was not an InMemoryUploadedFile")
print(f"File {new_version_file} added to media for version {version}")



return JsonResponse({'message': 'success'})
Expand Down

0 comments on commit f28a94a

Please sign in to comment.