Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/parklab/refinery-platform
Browse files Browse the repository at this point in the history
…into develop
  • Loading branch information
jkmarx committed Jun 25, 2015
2 parents 5f22c06 + a6fa7c8 commit c537447
Show file tree
Hide file tree
Showing 9 changed files with 359 additions and 272 deletions.
86 changes: 71 additions & 15 deletions refinery/core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from core.models import Project, NodeSet, NodeRelationship, NodePair, \
Workflow, WorkflowInputRelationships, Analysis, DataSet, \
ExternalToolStatus, ResourceStatistics, GroupManagement, ExtendedGroup, \
UserAuthentication, Invitation, EmailInvite
UserAuthentication, Invitation, EmailInvite, UserProfile
from core.tasks import check_tool_status
from data_set_manager.api import StudyResource, AssayResource
from data_set_manager.models import Node, Study
Expand Down Expand Up @@ -112,13 +112,13 @@ def list_to_queryset(self, res_list):
# Apply filters.
def do_filtering(self, res_list, get_req_dict):
mod_list = res_list

for k in get_req_dict:
# Skip if res does not have the attribute. Done to help avoid
# whatever internal filtering can be performed on other things,
# like limiting the return amount.
mod_list = [x for x in mod_list
if not hasattr(x, k) or
if not hasattr(x, k) or
str(getattr(x, k)) == get_req_dict[k]]

return mod_list
Expand All @@ -139,7 +139,7 @@ def build_res_list(self, user, res_list, request, **kwargs):

# Filter for query flags.
res_list = self.do_filtering(res_list, request.GET)

return res_list

def build_bundle_list(self, request, res_list, **kwargs):
Expand Down Expand Up @@ -295,8 +295,21 @@ def obj_get_list(self, bundle, **kwargs):
bundle,
**kwargs)

def get_object_list(self, request):
return SharableResourceAPIInterface.get_object_list(self, request)
# def get_object_list(self, request):
# return SharableResourceAPIInterface.get_object_list(self, request)

def get_object_list(self, request, **kwargs):
if(request.user.is_authenticated()):
return get_objects_for_user(
request.user,
"core.read_project"
).filter(is_catch_all=False)
else:
group = ExtendedGroup.objects.public_group()
return get_objects_for_group(
group,
'core.read_project'
).filter(is_catch_all=False)


class DataSetResource(ModelResource, SharableResourceAPIInterface):
Expand All @@ -316,7 +329,6 @@ class Meta:
# authentication = SessionAuthentication()
# authorization = GuardianAuthorization()
filtering = {'uuid': ALL}
# fields = ['uuid']

def prepend_urls(self):
prepend_urls_list = SharableResourceAPIInterface.prepend_urls(self) + [
Expand All @@ -339,8 +351,28 @@ def obj_get_list(self, bundle, **kwargs):
bundle,
**kwargs)

def get_object_list(self, request):
return SharableResourceAPIInterface.get_object_list(self, request)
# def get_object_list(self, request):
# return SharableResourceAPIInterface.get_object_list(self, request)

def get_object_list(self, request, **kwargs):
if(request.user.is_authenticated()):
data_sets = get_objects_for_user(
request.user,
'core.read_dataset'
)
for data_set in data_sets:
# Assuming that only owners can share an object.
# add_dataset is not unique to owners unfortunately
data_set.is_owner = request.user.has_perm(
'core.share_dataset',
data_set
)
data_set.public = data_set.is_public
else:
group = ExtendedGroup.objects.public_group()
data_sets = get_objects_for_group(group, 'core.read_dataset')

return data_sets

def obj_create(self, bundle, **kwargs):
return SharableResourceAPIInterface.obj_create(self, bundle, **kwargs)
Expand Down Expand Up @@ -448,8 +480,21 @@ def obj_get_list(self, bundle, **kwargs):
bundle,
**kwargs)

def get_object_list(self, request):
return SharableResourceAPIInterface.get_object_list(self, request)
# def get_object_list(self, request):
# return SharableResourceAPIInterface.get_object_list(self, request)

def get_object_list(self, request, **kwargs):
if(request.user.is_authenticated()):
return get_objects_for_user(
request.user,
"core.read_workflow"
).filter(is_active=True)
else:
group = ExtendedGroup.objects.public_group()
return get_objects_for_group(
group,
'core.read_workflow'
).filter(is_active=True)

def obj_create(self, bundle, **kwargs):
return SharableResourceAPIInterface.obj_create(self, bundle, **kwargs)
Expand Down Expand Up @@ -523,6 +568,16 @@ class Meta:
}
ordering = ['name', 'creation_date']

def get_object_list(self, request, **kwargs):
if(request.user.is_authenticated()):
return UserProfile.objects.get(
user=User.objects.get(
username=request.user
)
).catch_all_project.analyses.all().order_by("-time_start")
else:
return Analysis.objects.none()


class NodeResource(ModelResource):
parents = fields.ToManyField('core.api.NodeResource', 'parents')
Expand Down Expand Up @@ -1193,7 +1248,7 @@ def user_authorized(self, user, group):
def has_expired(self, token):
if token.expires is None:
return True

return (datetime.datetime.now() - token.expires).total_seconds() >= 0

def prepend_urls(self):
Expand All @@ -1208,9 +1263,10 @@ def prepend_urls(self):
self.wrap_view('update_db'),
name='api_invitation_update_db'),
url(r'^invitation/send/(?P<group_id>%s)/(?P<email>%s)/$'
% (self.group_id_regex, self.email_regex),
% (self.group_id_regex, self.email_regex),
self.wrap_view('email_token'),
name='api_invitation_email_token'),

]

def get_token(self, request, **kwargs):
Expand All @@ -1219,7 +1275,7 @@ def get_token(self, request, **kwargs):
if request.method == 'GET':
user = request.user
group = self.get_group(int(kwargs['group_id']))

if not self.user_authorized(user, group):
return HttpUnauthorized()

Expand Down Expand Up @@ -1267,6 +1323,7 @@ def update_db(self, request, **kwargs):

return HttpNoContent()


def email_token(self, request, **kwargs):
group = self.get_group(int(kwargs['group_id']))

Expand All @@ -1291,4 +1348,3 @@ def email_token(self, request, **kwargs):
email = EmailMessage(subject, body, to=[address])
email.send()
return HttpAccepted()

9 changes: 4 additions & 5 deletions refinery/data_set_manager/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from data_set_manager.views import (
ImportISATabView, ProcessISATabView, ProcessMetadataTableView,
CheckDataFilesView, FileUploadView, ChunkedFileUploadView,
DataSetImportView, ImportISATabView, ProcessISATabView,
ProcessMetadataTableView, CheckDataFilesView, ChunkedFileUploadView,
ChunkedFileUploadCompleteView
)

Expand All @@ -26,8 +26,9 @@

url(r'^nodes/(?P<study_uuid>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/(?P<assay_uuid>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/(?P<type>[\w ]+)/annotate$', "node_annotate", name="data_set_manager_update_annotated_nodes" ),

url(r'^import/$', DataSetImportView.as_view(), name='import_data_set'),
url(r'^import/isa-tab/$', csrf_exempt(ImportISATabView.as_view()),
name='import_isa_tab'),
name='import_isa_tab'), # csrf_exempt required for POST requests from external sites
url(r'^import/isa-tab-form/$', login_required(ProcessISATabView.as_view()),
name='process_isa_tab'),
url(r'^contents/(?P<study_uuid>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/(?P<assay_uuid>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/$', "contents", name="data_set_manager_contents" ),
Expand All @@ -36,8 +37,6 @@
name='process_metadata_table'),
url(r'^import/check_files/$', CheckDataFilesView.as_view(),
name='check_files'),
url(r'^import/file-upload-form/$', login_required(FileUploadView.as_view()),
name='upload_files'),
url(r'^import/chunked-upload/$',
login_required(ChunkedFileUploadView.as_view()),
name='api_chunked_upload'),
Expand Down
106 changes: 53 additions & 53 deletions refinery/data_set_manager/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,54 +99,18 @@ def search_typeahead(request):
mimetype='application/json')


# ===============================================================================
# ISA-Tab import
#===============================================================================
class ImportISATabView(View):
'''Capture ISA archive URL from POST requests submitted from external sites
'''

def post(self, request, *args, **kwargs):
try:
isa_tab_url = request.POST['isa_tab_url']
except KeyError:
logger.error("ISA archive URL was not provided")
return HttpResponseBadRequest("Please provide an ISA archive URL")
else:
# set cookie and redirect to process_isa_tab view
response = HttpResponseRedirect(reverse('process_isa_tab'))
response.set_cookie('isa_tab_url', isa_tab_url)
return response


class ImportISATabFileForm(forms.Form):
'''ISA-Tab file upload form
# Data set import

'''
isa_tab_file = forms.FileField(label='ISA-Tab file', required=False)
isa_tab_url = forms.URLField(label='ISA-Tab URL', required=False,
widget=forms.TextInput(attrs={'size': '37'}))
class DataSetImportView(View):
"""Main view for data set importing
def clean(self):
cleaned_data = super(ImportISATabFileForm, self).clean()
f = cleaned_data.get("isa_tab_file")
url = cleaned_data.get("isa_tab_url")
# either a file or a URL must be provided
if f or url:
return cleaned_data
else:
raise forms.ValidationError("Please provide either a file or a URL")


class ProcessISATabView(View):
'''Process ISA-Tab archive
'''
template_name = 'data_set_manager/isa-tab-import.html'
"""
template_name = "data_set_manager/import.html"
success_view_name = 'data_set'
isa_tab_cookie_name = 'isa_tab_url'

# def get(self, request, *args, **kwargs):
# return render(request, self.template_name)
# a workaround for automatic ISA archive import after logging in
def get(self, request, *args, **kwargs):
try:
Expand Down Expand Up @@ -200,6 +164,52 @@ def get(self, request, *args, **kwargs):
response.delete_cookie(self.isa_tab_cookie_name)
return response


class ImportISATabView(View):
'''Capture ISA archive URL from POST requests submitted from external sites
'''

def post(self, request, *args, **kwargs):
try:
isa_tab_url = request.POST['isa_tab_url']
except KeyError:
logger.error("ISA archive URL was not provided")
return HttpResponseBadRequest("Please provide an ISA archive URL")
else:
# set cookie and redirect to process_isa_tab view
response = HttpResponseRedirect(reverse('process_isa_tab'))
response.set_cookie('isa_tab_url', isa_tab_url)
return response


class ImportISATabFileForm(forms.Form):
'''ISA-Tab file upload form
'''
isa_tab_file = forms.FileField(label='ISA-Tab file', required=False)
isa_tab_url = forms.URLField(label='ISA-Tab URL', required=False,
widget=forms.TextInput(attrs={'size': '37'}))

def clean(self):
cleaned_data = super(ImportISATabFileForm, self).clean()
f = cleaned_data.get("isa_tab_file")
url = cleaned_data.get("isa_tab_url")
# either a file or a URL must be provided
if f or url:
return cleaned_data
else:
raise forms.ValidationError("Please provide either a file or a URL")


class ProcessISATabView(View):
'''Process ISA-Tab archive
'''
template_name = 'data_set_manager/isa-tab-import.html'
success_view_name = 'data_set'
isa_tab_cookie_name = 'isa_tab_url'

def post(self, request, *args, **kwargs):
form = ImportISATabFileForm(request.POST, request.FILES)
if form.is_valid():
Expand Down Expand Up @@ -352,16 +362,6 @@ def post(self, request, *args, **kwargs):
content_type="application/json")


class FileUploadView(TemplateView):
"""Data file upload form view
"""
template_name = 'data_set_manager/import.html'

def get(self, request, *args, **kwargs):
return render(request, self.template_name)


class ChunkedFileUploadView(ChunkedUploadView):

model = ChunkedUpload
Expand Down
1 change: 1 addition & 0 deletions refinery/settings.json.sample
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"DEBUG_TOOLBAR": false,
"DEBUG": true,
"STATICFILES": [
"static/development",
Expand Down
8 changes: 8 additions & 0 deletions refinery/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ def get_setting(name, settings=local_settings):
'chunked_upload',
)

# required for Django Debug Tool Bar
if get_setting('DEBUG_TOOLBAR'):
INSTALLED_APPS += (
'debug_toolbar',
)
INTERNAL_IPS = ('192.168.50.1' )


# NG: added for django-guardian
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend', # default
Expand Down
3 changes: 2 additions & 1 deletion refinery/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="text/html">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">

Expand Down
2 changes: 1 addition & 1 deletion refinery/templates/core/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ <h3><i class="icon-file m-r-1-4"></i>Data Sets</h3>
{% if user.is_authenticated and not REFINERY_REPOSITORY_MODE %}
<span class="refinery-header-right">
<h4>
<a href={% url "process_isa_tab" %} class="no-underline-hover">
<a href={% url "import_data_set" %} class="no-underline-hover">
<i class="icon-plus-sign"></i>
</a>
</h4>
Expand Down

0 comments on commit c537447

Please sign in to comment.