Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
3601c29
fix #1505
antgonza Jan 2, 2017
0d6788e
improving some GUI stuff
antgonza Jan 3, 2017
12406cc
improving some GUI stuff - missing lines
antgonza Jan 3, 2017
958fcbe
pull upstream master
antgonza Jan 4, 2017
a57ef23
addressing all comments
antgonza Jan 5, 2017
2ead7a6
ready for review
antgonza Jan 5, 2017
73a78e7
fix #1987
antgonza Jan 16, 2017
e64a22a
Merge pull request #2036 from antgonza/fix-1505
josenavas Jan 16, 2017
0dcae8b
Merge pull request #2047 from antgonza/fix-1987
josenavas Jan 17, 2017
4a5bbbc
initial commit
antgonza Jan 18, 2017
f99975c
requested changes
antgonza Jan 18, 2017
ed899a8
Merge pull request #2049 from antgonza/add-processing-suggestions
josenavas Jan 18, 2017
d508320
fix filter job list
antgonza Jan 18, 2017
025cc1e
Merge pull request #2050 from antgonza/fix-filter-job-list
josenavas Jan 18, 2017
599bcde
Fixing server cert (#2051)
josenavas Jan 19, 2017
d12ccfe
fix get_studies
antgonza Jan 20, 2017
b33983b
flake8
antgonza Jan 20, 2017
b4f1b1f
fix #503
antgonza Jan 20, 2017
62a1b93
fix #2010
antgonza Jan 20, 2017
2e36141
fix #1913
antgonza Jan 21, 2017
e006e20
fix errors
antgonza Jan 21, 2017
c174693
Merge pull request #2052 from antgonza/fix-get_studies
josenavas Jan 23, 2017
131dd6a
Merge pull request #2053 from antgonza/fix-by-blinking
josenavas Jan 23, 2017
ccb55bd
addressing @josenavas comment
antgonza Jan 24, 2017
dfe2e83
flake8
antgonza Jan 24, 2017
15fcceb
Merge pull request #2056 from antgonza/fix-1913
josenavas Jan 24, 2017
7f97f2a
fix #1010
antgonza Jan 26, 2017
9eb9dbb
fix #1066 (#2058)
antgonza Jan 26, 2017
23104d7
addressing @josenavas comments
antgonza Jan 27, 2017
1f1e826
fix #1961
antgonza Jan 27, 2017
19a9dda
fix #1837
antgonza Jan 27, 2017
19889f9
Automatic jobs & new stats (#2057)
antgonza Jan 27, 2017
4e380e0
Merge pull request #2060 from antgonza/fix-1961
wasade Jan 28, 2017
6f0dd71
generalizing this functionality
antgonza Jan 28, 2017
ed9fc65
fix #1816
antgonza Jan 29, 2017
4b19b45
fix #1959
antgonza Jan 30, 2017
d9b41e8
addressing @josenavas comments
antgonza Feb 1, 2017
5ef06ae
addressing @josenavas comments
antgonza Feb 2, 2017
5e3504a
fixing error
antgonza Feb 2, 2017
d10096a
Merge branch 'master' of https://github.com/biocore/qiita into fix-1010
antgonza Feb 2, 2017
661342f
fixed?
antgonza Feb 2, 2017
fcd249b
addressing @josenavas comments
antgonza Feb 3, 2017
f3c1216
Merge pull request #2063 from antgonza/fix-1816
josenavas Feb 3, 2017
a91a6fd
Merge pull request #2064 from antgonza/fix-1959
tanaes Feb 3, 2017
7b9fa6f
addressing @wasade comments
antgonza Feb 3, 2017
33bcbe5
Merge pull request #2059 from antgonza/fix-1010
josenavas Feb 3, 2017
5e4bd9b
Merge branch 'master' of https://github.com/biocore/qiita into fix-1837
antgonza Feb 3, 2017
8bf3d6e
fix flake8
antgonza Feb 3, 2017
7807bac
Merge pull request #2061 from antgonza/fix-1837
josenavas Feb 3, 2017
6360675
generate biom and metadata release (#2066)
antgonza Feb 3, 2017
811b7a7
database changes to fix 969
antgonza Feb 3, 2017
751d4ad
adding delete
antgonza Feb 3, 2017
65a86df
addressing @josenavas comments
antgonza Feb 3, 2017
b1817dd
addressing @ElDeveloper comments
antgonza Feb 4, 2017
18d77e1
duh!
antgonza Feb 4, 2017
01c656c
Merge pull request #2071 from antgonza/fix-969-db
josenavas Feb 6, 2017
53188a6
fix generate_biom_and_metadata_release (#2072)
antgonza Feb 7, 2017
1ab4e3b
Fixing merge conflicts with master
josenavas Feb 8, 2017
1e8332e
Merge branch 'analysis-refactor' of https://github.com/biocore/qiita …
josenavas Feb 9, 2017
cb67d3d
Removing qiita ware code that will not be used anymore
josenavas Feb 9, 2017
5a5127d
Merge branch 'analysis-refactor' of https://github.com/biocore/qiita …
josenavas Feb 9, 2017
0033480
Organizing the handlers and new analysis description page
josenavas Feb 9, 2017
3809ad5
Connecting the analysis creation and making interface responsive
josenavas Feb 9, 2017
067f14f
Addressing @antgonza's comments
josenavas Feb 10, 2017
cf4862d
Solving merge conflicts
josenavas Feb 10, 2017
3b07151
Initial artifact GUI refactor
josenavas Feb 10, 2017
a6595a9
Removing unused code
josenavas Feb 10, 2017
6343b49
Merge branch 'analysis-refactor-gui-part2' into analysis-refactor-gui…
josenavas Feb 10, 2017
f731768
Adding can_edit call to the analysis
josenavas Feb 14, 2017
7542658
Fixing artifact rest API since not all artifacts have study
josenavas Feb 14, 2017
e0180e8
Adding can_be_publicized call to analysis
josenavas Feb 15, 2017
f55ca5c
Adding QiitaHTTPError to handle errors gracefully
josenavas Feb 15, 2017
1fa4b19
Adding safe_execution contextmanager
josenavas Feb 15, 2017
b61ae87
Fixing typo
josenavas Feb 15, 2017
bb68303
Adding qiita test checker
josenavas Feb 15, 2017
b31a025
Adapting some artifact handlers
josenavas Feb 15, 2017
378d7ff
Fixing merge conflicts
josenavas Feb 15, 2017
444da08
Merge branch 'analysis-refactor-gui-part2' into analysis-refactor-gui…
josenavas Feb 15, 2017
f6b4c46
Abstracting the graph reloading and adding some documentation
josenavas Feb 15, 2017
e9d3af3
Fixing typo
josenavas Feb 15, 2017
69b6412
Merge branch 'analysis-refactor-gui-part3' into analysis-refactor-gui…
josenavas Feb 15, 2017
60cd430
Fixing changing artifact visibility
josenavas Feb 15, 2017
be099cb
Fixing delete
josenavas Feb 15, 2017
819e9a5
Fixing artifact deletion
josenavas Feb 15, 2017
85d4aa7
Solving merge conflicts
josenavas Apr 24, 2017
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
4 changes: 4 additions & 0 deletions qiita_db/artifact.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,10 @@ def delete(cls, artifact_id):
sql = "DELETE FROM qiita.study_artifact WHERE artifact_id = %s"
qdb.sql_connection.TRN.add(sql, [artifact_id])

# Detach the artifact from the analysis_artifact table
sql = "DELETE FROM qiita.analysis_artifact WHERE artifact_id = %s"
qdb.sql_connection.TRN.add(sql, [artifact_id])

# Delete the row in the artifact table
sql = "DELETE FROM qiita.artifact WHERE artifact_id = %s"
qdb.sql_connection.TRN.add(sql, [artifact_id])
Expand Down
15 changes: 15 additions & 0 deletions qiita_db/test/test_artifact.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,21 @@ def test_delete(self):
with self.assertRaises(qdb.exceptions.QiitaDBUnknownIDError):
qdb.artifact.Artifact(test.id)

# Analysis artifact
parameters = qdb.software.Parameters.from_default_params(
qdb.software.DefaultParameters(1), {'input_data': 1})
test = qdb.artifact.Artifact.create(
self.filepaths_processed, "Demultiplexed",
parents=[qdb.artifact.Artifact(9)],
processing_parameters=parameters)

self._clean_up_files.extend(
[join(uploads_fp, basename(fp)) for _, fp, _ in test.filepaths])
qdb.artifact.Artifact.delete(test.id)

with self.assertRaises(qdb.exceptions.QiitaDBUnknownIDError):
qdb.artifact.Artifact(test.id)

def test_delete_with_html(self):
fd, html_fp = mkstemp(suffix=".html")
close(fd)
Expand Down
46 changes: 41 additions & 5 deletions qiita_pet/handlers/analysis_handlers/base_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
# The full license is in the file LICENSE, distributed with this software.
# -----------------------------------------------------------------------------

from json import loads

from tornado.web import authenticated
from moi import r_client

from qiita_core.util import execute_as_transaction
from qiita_core.qiita_settings import qiita_config
Expand All @@ -29,16 +32,49 @@ def post(self):
% (qiita_config.portal_dir, analysis.id))


def analysis_description_handler_get_request(analysis_id, user):
"""Returns the analysis information

Parameters
----------
analysis_id : int
The analysis id
user : qiita_db.user.User
The user performing the request
"""
analysis = Analysis(analysis_id)
check_analysis_access(user, analysis)

job_info = r_client.get("analysis_%s" % analysis.id)
alert_type = 'info'
alert_msg = ''
if job_info:
job_info = loads(job_info)
job_id = job_info['job_id']
if job_id:
redis_info = loads(r_client.get(job_id))
if redis_info['status_msg'] == 'running':
alert_msg = 'An artifact is being deleted from this analysis'
elif redis_info['return'] is not None:
alert_type = redis_info['return']['status']
alert_msg = redis_info['return']['message'].replace(
'\n', '</br>')

return {'analysis_name': analysis.name,
'analysis_id': analysis.id,
'analysis_description': analysis.description,
'alert_type': alert_type,
'alert_msg': alert_msg}


class AnalysisDescriptionHandler(BaseHandler):
@authenticated
@execute_as_transaction
def get(self, analysis_id):
analysis = Analysis(analysis_id)
check_analysis_access(self.current_user, analysis)
res = analysis_description_handler_get_request(analysis_id,
self.current_user)

self.render("analysis_description.html", analysis_name=analysis.name,
analysis_id=analysis_id,
analysis_description=analysis.description)
self.render("analysis_description.html", **res)


def analyisis_graph_handler_get_request(analysis_id, user):
Expand Down
40 changes: 38 additions & 2 deletions qiita_pet/handlers/analysis_handlers/tests/test_base_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,56 @@
# -----------------------------------------------------------------------------

from unittest import TestCase, main
from json import loads
from json import loads, dumps

from tornado.web import HTTPError
from moi import r_client

from qiita_core.util import qiita_test_checker
from qiita_db.user import User
from qiita_db.analysis import Analysis
from qiita_pet.test.tornado_test_base import TestHandlerBase
from qiita_pet.handlers.analysis_handlers.base_handlers import (
analyisis_graph_handler_get_request)
analyisis_graph_handler_get_request,
analysis_description_handler_get_request)


@qiita_test_checker()
class TestBaseHandlersUtils(TestCase):
def tearDown(self):
r_client.flushdb()

def test_analysis_description_handler_get_request(self):
obs = analysis_description_handler_get_request(1, User('test@foo.bar'))
exp = {'analysis_name': 'SomeAnalysis',
'analysis_id': 1,
'analysis_description': 'A test analysis',
'alert_type': 'info',
'alert_msg': ''}
self.assertEqual(obs, exp)

r_client.set('analysis_1', dumps({'job_id': 'job_id'}))
r_client.set('job_id', dumps({'status_msg': 'running'}))
obs = analysis_description_handler_get_request(1, User('test@foo.bar'))
exp = {'analysis_name': 'SomeAnalysis',
'analysis_id': 1,
'analysis_description': 'A test analysis',
'alert_type': 'info',
'alert_msg': 'An artifact is being deleted from this analysis'}
self.assertEqual(obs, exp)

r_client.set('job_id', dumps(
{'status_msg': 'Success',
'return': {'status': 'danger',
'message': 'Error deleting artifact'}}))
obs = analysis_description_handler_get_request(1, User('test@foo.bar'))
exp = {'analysis_name': 'SomeAnalysis',
'analysis_id': 1,
'analysis_description': 'A test analysis',
'alert_type': 'danger',
'alert_msg': 'Error deleting artifact'}
self.assertEqual(obs, exp)

def test_analyisis_graph_handler_get_request(self):
obs = analyisis_graph_handler_get_request(1, User('test@foo.bar'))
# The job id is randomly generated in the test environment. Gather
Expand Down
76 changes: 66 additions & 10 deletions qiita_pet/handlers/artifact_handlers/base_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,24 @@
# -----------------------------------------------------------------------------

from os.path import basename
from json import dumps

from tornado.web import authenticated
from moi import r_client

from qiita_core.qiita_settings import qiita_config
from qiita_pet.handlers.base_handlers import BaseHandler
from qiita_pet.handlers.util import safe_execution
from qiita_pet.exceptions import QiitaHTTPError
from qiita_ware.context import safe_submit
from qiita_ware.dispatchable import delete_artifact
from qiita_db.artifact import Artifact
from qiita_db.software import Command, Parameters
from qiita_db.processing_job import ProcessingJob
from qiita_db.util import get_visibilities


PREP_TEMPLATE_KEY_FORMAT = 'prep_template_%s'


def check_artifact_access(user, artifact):
Expand Down Expand Up @@ -131,7 +139,7 @@ def artifact_summary_get_request(user, artifact_id):
# If the artifact is part of an analysis, we don't require admin
# approval, and the artifact can be made public only if all the
# artifacts used to create the initial artifact set are public
if analysis.can_be_publicized:
if analysis.can_be_publicized and visibility != 'public':
buttons.append(btn_base % ('make public', 'public', 'Make public'))

else:
Expand All @@ -145,13 +153,12 @@ def artifact_summary_get_request(user, artifact_id):
buttons.append(
btn_base % ('request approval for', 'awaiting_approval',
'Request approval'))

elif user.level == 'admin' and visibility == 'awaiting_approval':
# The approve artifact button only appears if the user is an admin
# the artifact is waiting to be approvaed and the qiita config
# requires artifact approval
buttons.append(btn_base % ('approve', 'private',
'Approve artifact'))
elif user.level == 'admin' and visibility == 'awaiting_approval':
# The approve artifact button only appears if the user is an
# admin the artifact is waiting to be approvaed and the qiita
# config requires artifact approval
buttons.append(btn_base % ('approve', 'private',
'Approve artifact'))

if visibility == 'private':
# The make public button only appears if the artifact is private
Expand Down Expand Up @@ -206,8 +213,7 @@ def artifact_summary_get_request(user, artifact_id):
'processing_jobs': processing_jobs,
'summary': summary,
'job': job_info,
'errored_jobs': errored_jobs
}
'errored_jobs': errored_jobs}


def artifact_summary_post_request(user, artifact_id):
Expand Down Expand Up @@ -311,6 +317,23 @@ def artifact_patch_request(user, artifact_id, req_op, req_path, req_value=None,
if attribute == 'name':
artifact.name = req_value
return
elif attribute == 'visibility':
if req_value not in get_visibilities():
raise QiitaHTTPError(400, 'Unknown visibility value: %s'
% req_value)
# Set the approval to private if needs approval and admin
if req_value == 'private':
if not qiita_config.require_approval:
artifact.visibility = 'private'
# Set the approval to private if approval not required
elif user.level == 'admin':
artifact.visibility = 'private'
# Trying to set approval without admin privileges
else:
raise QiitaHTTPError(403, 'User does not have permissions '
'to approve change')
else:
artifact.visibility = req_value
else:
# We don't understand the attribute so return an error
raise QiitaHTTPError(404, 'Attribute "%s" not found. Please, '
Expand All @@ -320,7 +343,40 @@ def artifact_patch_request(user, artifact_id, req_op, req_path, req_value=None,
'supported operations: replace' % req_op)


def artifact_post_req(user, artifact_id):
"""Deletes the artifact

Parameters
----------
user : qiita_db.user.User
The user requesting the action
artifact_id : int
Id of the artifact being deleted
"""
artifact_id = int(artifact_id)
artifact = Artifact(artifact_id)
check_artifact_access(user, artifact)

analysis = artifact.analysis

if analysis:
# Do something when deleting in the analysis part to keep track of it
redis_key = "analysis_%s" % analysis.id
else:
pt_id = artifact.prep_templates[0].id
redis_key = PREP_TEMPLATE_KEY_FORMAT % pt_id

job_id = safe_submit(user.id, delete_artifact, artifact_id)
r_client.set(redis_key, dumps({'job_id': job_id, 'is_qiita_job': False}))


class ArtifactAJAX(BaseHandler):
@authenticated
def post(self, artifact_id):
with safe_execution():
artifact_post_req(self.current_user, artifact_id)
self.finish()

@authenticated
def patch(self, artifact_id):
"""Patches a prep template in the system
Expand Down
33 changes: 27 additions & 6 deletions qiita_pet/handlers/artifact_handlers/tests/test_base_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,10 @@ def test_artifact_summary_post_request(self):

def test_artifact_patch_request(self):
a = Artifact(1)
test_user = User('test@foo.bar')
self.assertEqual(a.name, 'Raw data 1')

artifact_patch_request(User('test@foo.bar'), 1, 'replace', '/name/',
artifact_patch_request(test_user, 1, 'replace', '/name/',
req_value='NEW_NAME')
self.assertEqual(a.name, 'NEW_NAME')

Expand All @@ -268,24 +269,44 @@ def test_artifact_patch_request(self):

# Incorrect path parameter
with self.assertRaises(QiitaHTTPError):
artifact_patch_request(User('test@foo.bar'), 1, 'replace',
artifact_patch_request(test_user, 1, 'replace',
'/name/wrong/', req_value='NEW_NAME')

# Missing value
with self.assertRaises(QiitaHTTPError):
artifact_patch_request(User('test@foo.bar'), 1, 'replace',
'/name/')
artifact_patch_request(test_user, 1, 'replace', '/name/')

# Wrong attribute
with self.assertRaises(QiitaHTTPError):
artifact_patch_request(User('test@foo.bar'), 1, 'replace',
artifact_patch_request(test_user, 1, 'replace',
'/wrong/', req_value='NEW_NAME')

# Wrong operation
with self.assertRaises(QiitaHTTPError):
artifact_patch_request(User('test@foo.bar'), 1, 'add', '/name/',
artifact_patch_request(test_user, 1, 'add', '/name/',
req_value='NEW_NAME')

# Changing visibility
self.assertEqual(a.visibility, 'private')
artifact_patch_request(test_user, 1, 'replace', '/visibility/',
req_value='sandbox')
self.assertEqual(a.visibility, 'sandbox')

# Admin can change to private
artifact_patch_request(User('admin@foo.bar'), 1, 'replace',
'/visibility/', req_value='private')
self.assertEqual(a.visibility, 'private')

# Test user can't change to private
with self.assertRaises(QiitaHTTPError):
artifact_patch_request(test_user, 1, 'replace', '/visibility/',
req_value='private')

# Unkown req value
with self.assertRaises(QiitaHTTPError):
artifact_patch_request(test_user, 1, 'replace', '/visibility/',
req_value='wrong')


class TestBaseHandlers(TestHandlerBase):
def test_get_artifact_summary_ajax_handler(self):
Expand Down
26 changes: 26 additions & 0 deletions qiita_pet/templates/analysis_description.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@
{% block head %}
<script type="text/javascript">

/**
*
* This function is needed by the artifact subsection of the page. Since the
* artifact can be either embedded in the analysis pipeline or in the study
* pipeline, we take advantage of the templating system to abstract the way
* the graph should be updated. In the analysis pipeline (current) the graph
* is reloaded by calling the update_graph function of the Vue component.
*/
function reload_graph() {
$("#analysis-network-div").data('data-graph-vue').update_graph();
}

/**
*
* This function is needed by the artifact subsection of the page. After the
* artifact is sent for deletion, we need to reload the current page to
* update the UI.
*
*/
function reload_UI_post_artifact_delete() {
location.reload();
}

/**
* Creates the HTML with the job information and adds it to `target`
*
Expand Down Expand Up @@ -170,6 +193,9 @@

// Add the vue object to the div, so we avoid to have global variables
$("#analysis-network-div").data('data-graph-vue', vueGraph);
{% if alert_msg %}
bootstrapAlert("{{alert_msg}}", "{{alert_type}}");
{% end %}
});
</script>
<style>
Expand Down
Loading