- 
                Notifications
    You must be signed in to change notification settings 
- Fork 79
Share analyses #1758
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
Share analyses #1758
Changes from 10 commits
7df98ca
              997274b
              5fe04bc
              01ac908
              1a3414a
              9d7524b
              63d0a7a
              5fb1147
              2314e24
              b40bb8b
              32f052b
              3f60461
              5ad25f0
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -17,19 +17,22 @@ | |
| from functools import partial | ||
|  | ||
| from tornado.web import authenticated, HTTPError, StaticFileHandler | ||
| from tornado.gen import coroutine, Task | ||
| from moi import ctx_default, r_client | ||
| from moi.job import submit | ||
| from moi.group import get_id_from_user, create_info | ||
|  | ||
| from qiita_pet.util import is_localhost | ||
| from qiita_pet.handlers.base_handlers import BaseHandler | ||
| from qiita_pet.handlers.util import download_link_or_path | ||
| from qiita_pet.handlers.util import ( | ||
| download_link_or_path, get_shared_links) | ||
| from qiita_pet.exceptions import QiitaPetAuthorizationError | ||
| from qiita_ware.dispatchable import run_analysis | ||
| from qiita_db.analysis import Analysis | ||
| from qiita_db.artifact import Artifact | ||
| from qiita_db.job import Command | ||
| from qiita_db.util import (get_db_files_base_dir, | ||
| from qiita_db.user import User | ||
| from qiita_db.util import (get_db_files_base_dir, add_message, | ||
| check_access_to_analysis_result, | ||
| filepath_ids_to_rel_paths, get_filepath_id) | ||
| from qiita_db.exceptions import QiitaDBUnknownIDError | ||
|  | @@ -172,10 +175,13 @@ def get(self, analysis_id): | |
| data_type = proc_data.data_type | ||
| dropped[data_type].append((proc_data.study.title, len(samples), | ||
| ', '.join(samples))) | ||
| share_access = (self.current_user.id in analysis.shared_with or | ||
| self.current_user.id == analysis.owner) | ||
|  | ||
| self.render("analysis_results.html", analysis_id=analysis_id, | ||
| jobres=jobres, aname=analysis.name, dropped=dropped, | ||
| basefolder=get_db_files_base_dir()) | ||
| basefolder=get_db_files_base_dir(), | ||
| share_access=share_access) | ||
|  | ||
| @authenticated | ||
| @execute_as_transaction | ||
|  | @@ -349,3 +355,49 @@ class AnalysisSummaryAJAX(BaseHandler): | |
| def get(self): | ||
| info = self.current_user.default_analysis.summary_data() | ||
| self.write(dumps(info)) | ||
|  | ||
|  | ||
| class ShareAnalysisAJAX(BaseHandler): | ||
| @execute_as_transaction | ||
| def _get_shared_for_study(self, analysis, callback): | ||
| shared_links = get_shared_links(analysis) | ||
| users = [u.email for u in analysis.shared_with] | ||
| callback((users, shared_links)) | ||
|  | ||
| @execute_as_transaction | ||
| def _share(self, analysis, user, callback): | ||
| user = User(user) | ||
| add_message('Analysis <a href="/analysis/results/%d">\'%s\'</a> ' | ||
| 'has been shared with you.' % | ||
| (analysis.id, analysis.name), [user]) | ||
| callback(analysis.share(user)) | ||
|  | ||
| @execute_as_transaction | ||
| def _unshare(self, analysis, user, callback): | ||
| user = User(user) | ||
| add_message('Analysis \'%s\' has been unshared from you.' % | ||
| analysis.name, [user]) | ||
| callback(analysis.unshare(user)) | ||
|  | ||
| @authenticated | ||
| @coroutine | ||
| @execute_as_transaction | ||
| def get(self): | ||
| analysis_id = int(self.get_argument('id')) | ||
| analysis = Analysis(analysis_id) | ||
| if self.current_user != analysis.owner: | ||
| raise HTTPError(403, 'User %s does not have permissions to share ' | ||
| 'analysis %s' % ( | ||
| self.current_user.id, analysis.id)) | ||
|  | ||
| selected = self.get_argument('selected', None) | ||
| deselected = self.get_argument('deselected', None) | ||
|  | ||
| if selected is not None: | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if both are  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No share or unshare actions, but the user email links and user list is still returned. This is leveraged for initial population of the shared list in the page. | ||
| yield Task(self._share, analysis, selected) | ||
| if deselected is not None: | ||
| yield Task(self._unshare, analysis, deselected) | ||
|  | ||
| users, links = yield Task(self._get_shared_for_study, analysis) | ||
|  | ||
| self.write(dumps({'users': users, 'links': links})) | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -89,3 +89,32 @@ def to_int(value): | |
| except ValueError: | ||
| raise HTTPError(400, "%s cannot be converted to an integer" % value) | ||
| return res | ||
|  | ||
|  | ||
| @execute_as_transaction | ||
| def get_shared_links(obj): | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why rewrite this one vs. using the one for studies? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the one from studies. listing_handlers.py has it removed and moved here, since this function is now used in more than just that file. | ||
| """Createse HTML links for users obj is shared with | ||
|          | ||
|  | ||
| Parameters | ||
| ---------- | ||
| obj : QiitaObject | ||
| A qiita object with a 'shared_with' property that returns a list of | ||
| User objects | ||
|  | ||
| Returns | ||
| ------- | ||
| str | ||
| Email links for each person obj is shared with | ||
| """ | ||
| shared = [] | ||
| for person in obj.shared_with: | ||
| name = person.info['name'] | ||
| email = person.email | ||
| # Name is optional, so default to email if non existant | ||
| if name: | ||
| shared.append(study_person_linkifier( | ||
| (email, name))) | ||
| else: | ||
| shared.append(study_person_linkifier( | ||
| (email, email))) | ||
| return ", ".join(shared) | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| var current_study = null; | ||
| var current_id = null; | ||
|          | ||
|  | ||
| $(document).ready(function () { | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually I just saw this - this is a library, why does it has a  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because you can have as many document.ready calls in a single page as needed, and this also standardizes naming and initialization of the sharing dropdown for use in the other helper functions. | ||
| $('#shares-select').select2({ | ||
|  | @@ -18,18 +18,18 @@ $(document).ready(function () { | |
| }); | ||
|  | ||
| $('#shares-select').on("select2:select", function (e) { | ||
| update_share({selected: e.params.data.text}); | ||
| update_share(e.target.classList[0], {selected: e.params.data.text}); | ||
| }); | ||
|  | ||
| $('#shares-select').on("select2:unselect", function (e) { | ||
| update_share({deselected: e.params.data.text}); | ||
| update_share(e.target.classList[0], {deselected: e.params.data.text}); | ||
| }); | ||
| }); | ||
|  | ||
| function modify_sharing(study_id) { | ||
| function modify_sharing(share_type, id) { | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like the indentation in this function is messed up. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed | ||
| var shared_list; | ||
| current_study = study_id; | ||
| $.get('/study/sharing/', {study_id: study_id}) | ||
| current_id = id; | ||
| $.get('/' + share_type + '/sharing/', {id: id}) | ||
| .done(function(data) { | ||
| var users_links = JSON.parse(data); | ||
| var users = users_links.users; | ||
|  | @@ -43,13 +43,13 @@ $.get('/study/sharing/', {study_id: study_id}) | |
| }); | ||
| } | ||
|  | ||
| function update_share(params) { | ||
| function update_share(share_type, params) { | ||
| data = params || {}; | ||
| data.study_id = current_study; | ||
| $.get('/study/sharing/', data) | ||
| data.id = current_id; | ||
| $.get('/' + share_type + '/sharing/', data) | ||
| .done(function(data) { | ||
| users_links = JSON.parse(data); | ||
| links = users_links.links; | ||
| $("#shared_html_"+current_study).html(links); | ||
| $("#shared_html_"+current_id).html(links); | ||
| }); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are missing
and user.id in self.shared_with, right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.