Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attributes now take in PDF files #613

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
3 changes: 3 additions & 0 deletions coldfront/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,6 @@
# Add system site static files
if os.path.isdir('/usr/share/coldfront/site/static'):
STATICFILES_DIRS.insert(0, '/usr/share/coldfront/site/static')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
2 changes: 2 additions & 0 deletions coldfront/config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.contrib import admin
from django.urls import include, path
from django.views.generic import TemplateView
from django.conf.urls.static import static

import coldfront.core.portal.views as portal_views

Expand Down Expand Up @@ -36,3 +37,4 @@

if 'django_su.backends.SuBackend' in settings.AUTHENTICATION_BACKENDS:
urlpatterns.append(path('su/', include('django_su.urls')))
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
2 changes: 2 additions & 0 deletions coldfront/core/allocation/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,5 @@ class Meta:
def __init__(self, *args, **kwargs):
super(AllocationAttributeCreateForm, self).__init__(*args, **kwargs)
self.fields['allocation_attribute_type'].queryset = self.fields['allocation_attribute_type'].queryset.order_by(Lower('name'))
self.fields['doc'].required = False
self.fields['value'].required = False
16 changes: 13 additions & 3 deletions coldfront/core/allocation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.utils.module_loading import import_string
from model_utils.models import TimeStampedModel
from simple_history.models import HistoricalRecords

import magic
from coldfront.core.project.models import Project, ProjectPermission
from coldfront.core.resource.models import Resource
from coldfront.core.utils.common import import_from_settings
Expand Down Expand Up @@ -412,6 +412,8 @@ class AllocationAttributeType(TimeStampedModel):
is_private = models.BooleanField(default=True)
is_changeable = models.BooleanField(default=False)
history = HistoricalRecords()



def __str__(self):
return '%s' % (self.name)
Expand All @@ -433,7 +435,7 @@ class AllocationAttribute(TimeStampedModel):
allocation = models.ForeignKey(Allocation, on_delete=models.CASCADE)
value = models.CharField(max_length=128)
history = HistoricalRecords()

doc = models.FileField(default=False, upload_to='documents/')
def save(self, *args, **kwargs):
""" Saves the allocation attribute. """

Expand Down Expand Up @@ -466,7 +468,15 @@ def clean(self):
except ValueError:
raise ValidationError(
'Invalid Value "%s" for "%s". Date must be in format YYYY-MM-DD' % (self.value, self.allocation_attribute_type.name))

elif expected_value_type == "Upload":
if self.doc:
if self.doc.size > 10485760 :
raise ValidationError("This document exceeds size limits")
content_mime_type = magic.Magic(mime=True)
# file_type = content_mime_type.from_buffer(self.doc.read())
if content_mime_type.from_buffer(self.doc.read()) != "application/pdf":
raise ValidationError("Invalid file type")
self.doc.seek(0)
def __str__(self):
return '%s' % (self.allocation_attribute_type.name)

Expand Down
4 changes: 3 additions & 1 deletion coldfront/core/allocation/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.urls import path

import coldfront.core.allocation.views as allocation_views

from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', allocation_views.AllocationListView.as_view(), name='allocation-list'),
path('project/<int:project_pk>/create',
Expand Down Expand Up @@ -45,3 +46,4 @@
path('allocation-account-list/', allocation_views.AllocationAccountListView.as_view(),
name='allocation-account-list'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
7 changes: 6 additions & 1 deletion coldfront/core/allocation/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ class AllocationAttributeCreateView(LoginRequiredMixin, UserPassesTestMixin, Cre
model = AllocationAttribute
form_class = AllocationAttributeCreateForm
template_name = 'allocation/allocation_allocationattribute_create.html'

enctype="multipart/form-data"
def test_func(self):
""" UserPassesTestMixin Tests"""

Expand All @@ -789,6 +789,11 @@ def get_context_data(self, **kwargs):
pk = self.kwargs.get('pk')
allocation_obj = get_object_or_404(Allocation, pk=pk)
context['allocation'] = allocation_obj
text_based_input_attributes = []
for m in AllocationAttribute.objects.all():
if(m.proj_attr_type.attribute_type.name != "Upload"):
text_based_input_attributes.append(m.proj_attr_type.attribute_type.name)
context["text_based_input_attributes"] = text_based_input_attributes
return context

def get_initial(self):
Expand Down
3 changes: 3 additions & 0 deletions coldfront/core/project/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ def __init__(self, *args, **kwargs):
super(ProjectAttributeAddForm, self).__init__(*args, **kwargs)
user =(kwargs.get('initial')).get('user')
self.fields['proj_attr_type'].queryset = self.fields['proj_attr_type'].queryset.order_by(Lower('name'))
self.fields['doc'].required = False
self.fields['value'].required = False

if not user.is_superuser:
self.fields['proj_attr_type'].queryset = self.fields['proj_attr_type'].queryset.filter(is_private=False)

Expand Down
11 changes: 9 additions & 2 deletions coldfront/core/project/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ def __str__(self):

def __repr__(self) -> str:
return str(self)




class Meta:
ordering = ['name', ]
Expand All @@ -418,6 +421,7 @@ class ProjectAttribute(TimeStampedModel):

value = models.CharField(max_length=128)
history = HistoricalRecords()
doc = models.FileField(default=False, upload_to='documents/')

def save(self, *args, **kwargs):
""" Saves the project attribute. """
Expand All @@ -433,8 +437,9 @@ def clean(self):
self.proj_attr_type))

expected_value_type = self.proj_attr_type.attribute_type.name.strip()

validator = AttributeValidator(self.value)
# if not self.doc:
validator = AttributeValidator(self.value, self.doc)


if expected_value_type == "Int":
validator.validate_int()
Expand All @@ -444,6 +449,8 @@ def clean(self):
validator.validate_yes_no()
elif expected_value_type == "Date":
validator.validate_date()
elif expected_value_type == "Upload":
validator.validate_doc()

def __str__(self):
return '%s' % (self.proj_attr_type.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,41 @@
{% block content %}
<h2>Adding project attribute to {{ project }}</h2>

<form method="post">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form | crispy }}

<input class="btn btn-success" type="submit" value="Add" />
<a class="btn btn-secondary" href="{% url 'project-detail' project.pk %}" role="button">Back to
Project</a><br>

</form>
<script>
$('#div_id_doc').hide();
$('#div_id_value').hide();
var text_based_input_attributes = {{ text_based_input_attributes | safe }};
console.log(text_based_input_attributes);

$("#id_proj_attr_type").trigger('change');
$("#id_proj_attr_type").change(function () { console.log("resource_id");
var resource_id = $("#id_proj_attr_type option:selected").val();
if (resource_id in text_based_input_attributes) {
var label = $('label[for="id_value"]');

label.html('Quantity')
$('#div_id_doc').hide();
$('#div_id_value').show();
} else {
var label = $('label[for="id_doc"]');
label.html('Document')

console.log("moefnsr")
$('#div_id_doc').show();
$('#div_id_value').hide();

}
});

</script>

{% endblock %}
3 changes: 3 additions & 0 deletions coldfront/core/project/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static

import coldfront.core.project.views as project_views

Expand Down Expand Up @@ -26,3 +28,4 @@
path('<int:pk>/project-attribute-update/<int:project_attribute_pk>', project_views.ProjectAttributeUpdateView.as_view(), name='project-attribute-update'),

]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
14 changes: 11 additions & 3 deletions coldfront/core/project/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,7 @@ class ProjectNoteCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView)
model = ProjectUserMessage
fields = '__all__'
template_name = 'project/project_note_create.html'

enctype = 'multipart/form-data'
def test_func(self):
""" UserPassesTestMixin Tests"""

Expand Down Expand Up @@ -1210,7 +1210,8 @@ class ProjectAttributeCreateView(LoginRequiredMixin, UserPassesTestMixin, Create
model = ProjectAttribute
form_class = ProjectAttributeAddForm
template_name = 'project/project_attribute_create.html'

enctype="multipart/form-data"
# print("kjenf")
def test_func(self):
""" UserPassesTestMixin Tests"""
project_obj = get_object_or_404(Project, pk=self.kwargs.get('pk'))
Expand All @@ -1233,7 +1234,6 @@ def get_initial(self):
initial['project'] = get_object_or_404(Project, pk=pk)
initial['user'] = self.request.user
return initial

def get_form(self, form_class=None):
"""Return an instance of the form to be used in this view."""
form = super().get_form(form_class)
Expand All @@ -1244,8 +1244,16 @@ def get_context_data(self, *args, **kwargs):
pk = self.kwargs.get('pk')
context = super().get_context_data(*args, **kwargs)
context['project'] = get_object_or_404(Project, pk=pk)
text_based_input_attributes = []
for m in ProjectAttribute.objects.all():
# print(m.doc)
if(m.proj_attr_type.attribute_type.name != "Upload"):
text_based_input_attributes.append(m.proj_attr_type.attribute_type.name)
context["text_based_input_attributes"] = text_based_input_attributes

return context


def get_success_url(self):
return reverse('project-detail', kwargs={'pk': self.object.project_id})

Expand Down
17 changes: 15 additions & 2 deletions coldfront/core/utils/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
from django.core.validators import MinValueValidator
import formencode
from formencode import validators, Invalid
import magic

class AttributeValidator:

def __init__(self, value):
def __init__(self, value, doc):
self.value = value
self.doc = doc

def validate_int(self):
try:
Expand Down Expand Up @@ -38,4 +40,15 @@ def validate_date(self):
datetime.datetime.strptime(self.value.strip(), "%Y-%m-%d")
except:
raise ValidationError(
f'Invalid Value {self.value}. Date must be in format YYYY-MM-DD and date must be today or later.')
f'Invalid Value {self.value}. Date must be in format YYYY-MM-DD and date must be today or later.')

def validate_doc(self):
# try:
if self.doc:
if self.doc.size > 10485760 :
raise ValidationError("This document exceeds size limits")
content_mime_type = magic.Magic(mime=True)
# file_type = content_mime_type.from_buffer(self.doc.read())
if content_mime_type.from_buffer(self.doc.read()) != "application/pdf":
raise ValidationError("Invalid file type")
self.doc.seek(0)