def getiChipsForTesting(self, assay): """Get ALL iChips that can be used for the selected assay [[<iChipLotID>,[<iChip>,<iChip>,<iChip>]]] """ ichips_for_assay = [] brains = find(portal_type='iChipLot', review_state='released', sort_on='expires') if not brains: raise NoIchipLotsFound ichiplots = [] for brain in brains: ichiplot = brain.getObject() if assay.title in ichiplot.intended_assay \ and int(ichiplot.frames) == int(assay.framecount): # commercial needs, correct assay # want to order the ichiplots in this list by exp date ichiplots.append(ichiplot) for ichiplot in ichiplots: ichips = ichiplot.objectValues() filtered = [ic for ic in ichips if get_state(ic) == 'released'] ichips_for_assay.append([ichiplot, filtered]) return ichips_for_assay
def handle_edit(self): obj = get_working_copy(self.context) # TODO: use the stagingbehavior API to get the best object, in all cases print "WC: ", obj print "Baseline: ", get_baseline(self.context) if obj is None: obj = self.context state = get_state(obj) if state == 'private': url = '{0}/edit'.format(obj.absolute_url()) return self.request.response.redirect(url) elif state == 'published': # create copy, go to it wc = self._checkout() url = '{0}/edit'.format(wc.absolute_url()) return self.request.response.redirect(url) elif state == 'pending': # create copy, go to it transition(obj, to_state='private') url = '{0}/edit'.format(obj.absolute_url()) return self.request.response.redirect(url) raise ValueError('unknown state')
def getiChipsForTesting(self, assay): """Get ALL iChips that can be used for the selected assay [[<iChipLotID>,[<iChip>,<iChip>,<iChip>]]] """ ichips_for_assay = [] brains = find(portal_type='iChipLot', review_state='released', sort_on='expires') if not brains: raise NoIchipLotsFound ichiplots = [] for brain in brains: ichiplot = brain.getObject() if assay.title in ichiplot.intended_assay \ and int(ichiplot.frames) == int(assay.framecount): # commercial needs, correct assay # want to order the ichiplots in this list by exp date ichiplots.append(ichiplot) for ichiplot in ichiplots: ichips = ichiplot.objectValues() filtered = [ic for ic in ichips if get_state(ic) == 'released'] ichips_for_assay.append([ichiplot, filtered]) return ichips_for_assay
def handle_edit(self): policy = ICheckinCheckoutPolicy(self.context) obj = policy.getWorkingCopy() #baseline = policy.getBaseline() if obj is None: obj = self.context state = get_state(obj) if state in ['private', 'sent']: url = '{0}/edit'.format(obj.absolute_url()) return self.request.response.redirect(url) elif state == 'published': # create copy, go to it wc = self._checkout() url = '{0}/edit'.format(wc.absolute_url()) return self.request.response.redirect(url) elif state == 'pending': # retract object, go to it transition(obj, to_state='sent') url = '{0}/edit'.format(obj.absolute_url()) return self.request.response.redirect(url) raise ValueError ('unknown state')
def __call__(self): site = portal.get() sf = site.unrestrictedTraverse('marine/frontpage-slides') self.images = [o for o in sf.contentValues() if content.get_state(o) == 'published'] return self.index()
def get_baseline_state(self): policy = ICheckinCheckoutPolicy(self.context) baseline = policy.getBaseline() if baseline is None: baseline = self.context return get_state(baseline)
def handle_edit(self): obj = get_working_copy(self.context) # TODO: use the stagingbehavior API to get the best object, in all cases print "WC: ", obj print "Baseline: ", get_baseline(self.context) if obj is None: obj = self.context state = get_state(obj) if state == "private": url = "{0}/edit".format(obj.absolute_url()) return self.request.response.redirect(url) elif state == "published": # create copy, go to it wc = self._checkout() url = "{0}/edit".format(wc.absolute_url()) return self.request.response.redirect(url) elif state == "pending": # create copy, go to it transition(obj, to_state="private") url = "{0}/edit".format(obj.absolute_url()) return self.request.response.redirect(url) raise ValueError("unknown state")
def add_comment(self): form = self.request.form question_id = form.get('q').lower() thread_id = form.get('thread_id') transition_id = 'open_for_{}'.format(thread_id) text = form.get('text') folder = self.context if question_id in folder.contentIds(): q_folder = folder[question_id] # Due to a bug, For 'EC' the wrong state was given (opened_for_tl) # transition to the correct state if necessary current_state = get_state(q_folder) correct_state = 'opened_for_{}'.format(thread_id) if current_state != 'closed' and current_state != correct_state: transition(obj=q_folder, transition='close') transition(obj=q_folder, transition=transition_id) else: # initially create the question folder for comments q_folder = create(folder, 'wise.msfd.commentsfolder', id=question_id, title='Comments for question ' + question_id) transition(obj=q_folder, transition=transition_id) comment = create(q_folder, 'wise.msfd.comment', text=text) logger.info('Added comment %r in %r:, %r', q_folder, comment, text) return self.template()
def get_baseline_state(self): policy = ICheckinCheckoutPolicy(self.context) baseline = policy.getBaseline() if baseline is None: baseline = self.context return get_state(baseline)
def results(self): portal = api.portal.get() annot = IAnnotations(portal)['broken_links_data'] latest_dates = sorted(annot.keys())[-5:] res = {} broken_links = [] for date in latest_dates: for info in annot[date]: info = info.copy() try: obj = self.context.restrictedTraverse(info['object_url']) except: continue state = get_state(obj) if state not in ['private', 'archived']: info['date'] = date.Date() if isinstance( date, DateTime) else date if (isinstance(date, str) and date == 'pre_nov7_data'): continue broken_links.append(info) for link in broken_links: res[link['url']] = link return res
def queryClinicalSamples(self, assay): """Get all the samples that are review_state='received', and which contain an "AssayRequest" who's title matches the assay_name, and who have a review_state of (re_run or to_be_tested). """ sample_data = [] for testable_state in ['re_run', 'to_be_tested']: # this does get Clinical Samples keep reading jp brains = find(portal_type="AssayRequest", Title=assay.title, review_state=testable_state) tmp = [] for brain in brains: assay_request = brain.getObject() sample = assay_request.aq_parent tmp.append({ 'uid': sample.UID(), 'draw_date': sample.collection_date, 'test_status': get_state(assay_request), 'sample': sample }) tmp = sorted(tmp, key=itemgetter('draw_date')) sample_data.extend(tmp) max_nr_samples = self.maxNumberOfSamplesToRun(assay) return sample_data[:max_nr_samples]
def guard_make_available(instance): """ """ if IBulkAliquot.providedBy(instance): return False if get_state(instance.aq_parent) == 'in_review': return False return True
def guard_make_available(instance): """ """ if IBulkAliquot.providedBy(instance): return False if get_state(instance.aq_parent) == 'in_review': return False return True
def get_wf_state_id(self, context): state = get_state(context) wftool = get_tool('portal_workflow') wf = wftool.getWorkflowsFor(context)[0] # assumes one wf wf_state = wf.states[state] wf_state_id = wf_state.id or state return wf_state_id
def render(self): try: state = get_state(self.context) except: return'' if state == 'cancelled': # noinspection PyArgumentList return self.index() return ''
def render(self): try: state = get_state(self.context) except: return '' if state == 'cancelled': # noinspection PyArgumentList return self.index() return ''
def _transition_to_initial(self, obj): if content.get_state(obj=obj) == 'initial': return obj elif obj.portal_type == self.program_name: return self.create_test_program() elif obj.portal_type == self.participant_name: return self.create_test_participant() else: return
def _get_current_wf_state(self, context=None): if context is None: context = self.context state = get_state(context) wftool = get_tool('portal_workflow') wf = wftool.getWorkflowsFor(context)[0] # assumes one wf wf_state = wf.states[state] return state, wf_state
def render(self): try: state = get_state(self.context) except WorkflowException: return "" if state == "archived": return self.index() return ""
def _transition_to_state(self, obj=None, destination_state=None): self.assertIsNotNone(obj) self.assertIn(destination_state, STATES.keys()) setRoles(self.portal, TEST_USER_ID, ['Manager']) self.assertTrue('Manager' in self._get_roles_in_context(obj)) transition_steps = self._get_transition_steps_to_state( state=destination_state) # noqa : E501 obj = self._transition_to_initial(obj) self._recursive_transition_to_state(obj, transition_steps) self.assertEqual(content.get_state(obj=obj), destination_state) return obj
def handle_ObjectStateModified(site, uid): """ Handle when a CaseStudy is published / unpublished If published: * if this is a working copy, abort * check if object already exists in ArcGIS * if doesn't exist, add one * if exists, update the existing one If unpublished: * if this is a working copy, abort * check if object exists in ArcGIS * if exists, remove it """ obj = _get_obj_by_measure_id(site, uid) if IWorkingCopy.providedBy(obj): logger.debug("Skipping CaseStudy status change processing") return state = get_state(obj) token = get_auth_token() fid = _get_obj_FID(obj=obj, token=token) if (state != 'published') and fid: # it's unpublished, we'll remove the object logger.info("ArcGIS: Deleting CaseStudy with FID %s", fid) res = apply_edits(fid, op='deletes', token=token) assert res['deleteResults'] assert res['deleteResults'][0]['objectId'] == fid return if state == "published": repr = obj._repr_for_arcgis() # new case study, add it to ArcGIS if fid is None: logger.info("ArcGIS: Adding CaseStudy with measure id %s", uid) entry = json.dumps([repr]) res = apply_edits(entry, op='adds', token=token) assert len(res.get('addResults', [])) == 1 assert res['addResults'][0]['success'] == True # existing case study, sync its info else: logger.info("ArcGIS: Updating CaseStudy with FID %s", fid) repr['attributes']['FID'] = fid entry = json.dumps([repr]) res = apply_edits(entry, op='updates', token=token) assert res['updateResults'] assert res['updateResults'][0]['objectId'] == fid
def get_status_color(self, context=None): if context is None: context = self.context state = get_state(context) wftool = get_tool('portal_workflow') wf = wftool.getWorkflowsFor(context)[0] # assumes one wf wf_state = wf.states[state] wf_state_id = wf_state.id or state return self.status_colors.get(wf_state_id, "secondary")
def process_phase(self, context=None): if context is None: context = self.context state = get_state(context) wftool = get_tool('portal_workflow') wf = wftool.getWorkflowsFor(context)[0] # assumes one wf wf_state = wf.states[state] title = wf_state.title.strip() or state return state, title
def _verify_allowed_transition_by_role( self, obj=None, initial_state=None, role=None, transition=None, destination_state=None, end_state=None, ): self.assertIsNotNone(obj) self.assertIn(initial_state, STATES.keys()) self.assertIn(role, ROLES) self.assertIn(transition, TRANSITIONS) self.assertIn(destination_state, STATES.keys()) self.assertIn(end_state, STATES.keys()) self.assertEqual(content.get_state(obj=obj), initial_state) self._switch_role(obj, role) content.transition(obj=obj, transition=transition) self.assertEqual(content.get_state(obj=obj), destination_state) # send it back to the end state self._transition_to_state(obj, destination_state=end_state)
def _transition_and_or_roles_test( self, fast, initial_state, transition, end_state, authorized_roles, ): if fast: self.assertEqual(content.get_state(obj=self.test_obj), initial_state) content.transition(obj=self.test_obj, transition=transition) self.assertEqual(content.get_state(obj=self.test_obj), end_state) else: self._verify_transition_by_all_roles( obj=self.test_obj, initial_state=initial_state, authorized_roles=authorized_roles, transition=transition, destination_state=end_state, end_state=initial_state, )
def _verify_transition_by_all_roles( self, obj=None, initial_state=None, authorized_roles=None, unauthorized_roles=None, transition=None, destination_state=None, end_state=None, ): self.assertIsNotNone(obj) self.assertIn(initial_state, STATES.keys()) self.assertIn(transition, TRANSITIONS) self.assertIn(destination_state, STATES.keys()) self.assertIn(end_state, STATES.keys()) self.assertIsSubset(authorized_roles, ROLES) if unauthorized_roles is None: unauthorized_roles = list(ROLES - set(authorized_roles)) self._verify_allowed_transition_by_roles( obj=obj, initial_state=initial_state, roles=authorized_roles, transition=transition, destination_state=destination_state, end_state=end_state, ) # verify can view the item # verify can view viewable fields # verify can edit editable fields self._verify_unauthorized_transition_by_roles( obj=obj, initial_state=initial_state, roles=unauthorized_roles, transition=transition, end_state=end_state, ) # verify cannot view item # verify cannot view certain fields # verify cannot edit certain fields # check if we have to get to the destination_state if content.get_state(obj=obj) != destination_state: self._switch_role(obj, 'Manager') self._transition_to_state( obj, transition=transition, state=destination_state, )
def can_checkin(self): # user is Reviewer/Editor, state is submitted, context is wc local_roles = get_roles(obj=self.context, inherit=True) control = getMultiAdapter((self.context, self.request), name="iterate_control") if not hasattr(control, 'is_checkout'): return False is_wc = control.is_checkout() is_ready = get_state(self.context) == 'ready_for_checkin' can_checkin = bool(set(['Editor', 'Reviewer']). intersection(set(local_roles))) return is_wc and is_ready and can_checkin
def results(self): annot = IAnnotations(self.context) res = [] for info in annot.get('broken_links_data', []): try: obj = self.context.restrictedTraverse(info['object_url']) except: continue try: state = get_state(obj) except Exception: state = "N/A" if state not in ['private', 'archived', 'N/A']: res.append(info) return res
def _attempt_invalid_transition( self, obj=None, transition=None, end_state=None, ): self.assertIsNotNone(obj) self.assertIn(transition, TRANSITIONS) self.assertIn(end_state, STATES.keys()) error_str = '' try: content.transition(obj=obj, transition=transition) except InvalidParameterError as e: error_str = e.message found_expected_error = 'Invalid transition' in error_str self.assertTrue(found_expected_error) self.assertEqual(content.get_state(obj=obj), end_state)
def get_run(self, path): run_nr = self.get_run_nr(path) # get the run nr so we can loop the plates brains = find(object_provides=IVeracisRunBase.__identifier__, run_number=run_nr) if not brains: msg = "No test run found with run_number=%s." % run_nr raise RuntimeError(msg) run = brains[0].getObject() # verify that run is in correct state for import. state = get_state(run) if state != 'scanning': if state == 'resulted': return None msg = "Test run %s is in state '%s'. Expected state: 'scanning'" \ % (run.title, state) raise RunInIncorrectState(msg) return run
def _verify_unauthorized_transition_by_role( self, obj=None, initial_state=None, role=None, transition=None, end_state=None, ): self.assertIsNotNone(obj) self.assertIn(initial_state, STATES.keys()) self.assertIn(role, ROLES) self.assertIn(transition, TRANSITIONS) self.assertIn(end_state, STATES.keys()) self.assertEqual(content.get_state(obj=obj), initial_state) self._switch_role(obj, role) self._attempt_invalid_transition( obj, transition=transition, end_state=end_state, )
def can_checkout(self): # user is Contributer, state is published, context is baseline and # doesn't have a checkout # if self.context.portal_type == 'Document': # import pdb; pdb.set_trace() local_roles = get_roles(obj=self.context, inherit=True) control = getMultiAdapter((self.context, self.request), name="iterate_control") # currently enable the viewlet only for mtr page if 'mtr/countries' not in self.context.absolute_url_path(): return False # this happens if the context is not registered for @@iterate_control # for example, content types we don't care about if not hasattr(control, 'is_checkout'): return False policy = ICheckinCheckoutPolicy(self.context, None) if policy is None: return False wc = policy.getWorkingCopy() is_baseline = not control.is_checkout() is_published = get_state(self.context) == 'published' # is_country_draft = get_state(self.context) == 'country_draft' is_contributor = 'Contributor' in local_roles has_wc = wc is not None correct_state = is_published # or is_country_draft return is_baseline \ and correct_state \ and is_contributor \ and (not has_wc)
def queryClinicalSamples(self, assay): """Get all the samples that are review_state='received', and which contain an "AssayRequest" who's title matches the assay_name, and who have a review_state of (re_run or to_be_tested). """ sample_data = [] for testable_state in ['re_run', 'to_be_tested']: # this does get Clinical Samples keep reading jp brains = find(portal_type="AssayRequest", Title=assay.title, review_state=testable_state) tmp = [] for brain in brains: assay_request = brain.getObject() sample = assay_request.aq_parent tmp.append({'uid': sample.UID(), 'draw_date': sample.collection_date, 'test_status': get_state(assay_request), 'sample': sample}) tmp = sorted(tmp, key=itemgetter('draw_date')) sample_data.extend(tmp) max_nr_samples = self.maxNumberOfSamplesToRun(assay) return sample_data[:max_nr_samples]
def after_release(instance): """ """ for ichip in instance.objectValues(): if get_state(ichip) == "quarantined": transition(ichip, "release")
def process_results_xlsx(self, path): """Take values from path/Out/Results/SLEkey_Results.xlsx, and write them to the database """ run = self.get_run(path) # Get the first sheet filename = join(path, 'Out', 'Results', 'SLEkey_Results.xlsx') wb = openpyxl.load_workbook(filename) ws = wb.get_sheet_by_name('Sheet1') # header rows for blocks containg QC and Clinical aliquot/sample info qc_head_row = self.findnextSerial_Numberrow(ws, 1) clin_head_row = self.findnextSerial_Numberrow(ws, qc_head_row + 1) # get column letters of all qc headers that start with "ichip*" qc_ichip_cols = [] passfail_col = None for col in all_cols: coord = "%s%s" % (col, qc_head_row) val = "%s" % ws[coord].value if val: if val.lower().startswith("fina"): passfail_col = coord if val.lower().startswith("ichip"): qc_ichip_cols.append(col) ichip_passfail_combos = [] if passfail_col: for row in range(qc_head_row + 1, clin_head_row): passfail = "%s" % ws["%s%s" % (passfail_col, row)].value ichip_titles = [] for col in qc_ichip_cols: ichip_titles.append(ws["%s%s" % (col, row)].value) ichip_passfail_combos.append([ichip_titles, passfail]) # for each plate for plate in run.plates: plate_ichips = [] plate_ichiplot_titles = [] # get all unique ichip lot numbers in a list for key, uid in plate.items(): if key.startswith('ichip-id'): ichip = find(UID=uid)[0].getObject() plate_ichips.append(ichip) ichiplot_title = ichip.title.upper().split('-')[0] if ichiplot_title not in plate_ichiplot_titles: plate_ichiplot_titles.append(ichiplot_title) for combo in ichip_passfail_combos: if sorted(plate_ichiplot_titles) == sorted(combo[0]): for ichip in plate_ichips: transition(ichip, 'qc_' + combo[1].lower()) # 'consume' qc aliquots. for uid in plate.values(): brains = find(object_provides=IQCAliquot.__identifier__, UID=uid, review_state='in_process') if brains: transition(brains[0].getObject(), 'done') # find the column at which the following headers are located: cols = {'Sample_ID': '', 'SLE_key_Score': '', 'SLE_key_Classification': '', 'Assay_QC_Status': ''} if not all(cols): msg = "One of the column headers can't be located:" % pformat(cols) raise SpreadsheetParseError(msg) for col in all_cols: coord = "%s%s" % (col, clin_head_row) value = ws[coord].value if value in cols: cols[value] = col # get values from each row and colum into aliquot_results. results is: # {sample_id: [SLE_key_Score, # SLE_key_Classification, # Assay_QC_Status],} aliquot_results = {} first_empty = self.get_first_empty_row(ws, clin_head_row) for row in range(clin_head_row + 1, first_empty): sample_id = ws["%s%s" % (cols['Sample_ID'], row)].value score = ws["%s%s" % (cols['SLE_key_Score'], row)].value classif = ws["%s%s" % (cols['SLE_key_Classification'], row)].value status = ws["%s%s" % (cols['Assay_QC_Status'], row)].value aliquot_results[sample_id] = { 'SLE_key_Score': score, 'SLE_key_Classification': "%s" % classif, 'Assay_QC_Status': "%s" % status } log = [] _used_uids = [] for plate in run.plates: for uid in plate.values(): if uid in _used_uids: continue _used_uids.append(uid) brains = find(UID=uid) if not brains: continue aliquot = brains[0].getObject() if not IAliquot.providedBy(aliquot): continue sample = self.get_sample_from_aliquot(aliquot) if IClinicalSample.providedBy(sample): if sample.title not in aliquot_results: msg = "Sample '%s' not in spreadsheet results: %s" % \ (sample.title, pformat(aliquot_results)) raise RuntimeError(msg) result = aliquot_results[sample.title] ar = self.get_ar_from_sample(sample, run.assay_name) state = result['Assay_QC_Status'].lower() ar.aliquot_evaluated = aliquot.title ar.date_resulted = self.get_date(ws) # assayrequest is associated with multiple aliquots, # so we only transition if the AR's state is expected. if get_state(ar) == 'in_process': transition(ar, 'qc_' + state) aliquot.numeric_result = result['SLE_key_Score'] aliquot.text_result = result['SLE_key_Classification'] ts = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M") log.append("%s: Sample: %s, Aliquot: %s, Results: %s, %s" % ( ts, sample.title, aliquot.title, result['SLE_key_Score'], result['SLE_key_Classification'], )) return log
def current_state(self): return get_state(self.context)
def current_state(self): return get_state(self.context)
def generate_source_dict_from_event(self, event): """generate_source_dict_from_event. :param event: """ view = self.request.get('view') ret = [] title = event.Title() description = event.Description() if event.text: description = event.text.output editable = api.user.has_permission('Modify portal content', obj=event) deletable = api.user.has_permission('Delete objects', obj=event) color = 'grey' if event.tag: for _view_type, group_color, categories in CATEGORIES: for cat_id, _cat_title in categories: if cat_id in event.tag: color = group_color break else: # for events imported from ICS for _view_type, group_color, categories in CATEGORIES: for cat_id, _cat_tile in categories: for tag in event.subject: if cat_id == tag.lower(): color = group_color break adapter = IRecurrenceSupport(event) # get all occurrences of the current event (if not recurrent, # the generator will only produce the event itself) and create a # results entry for each one for occurrence in adapter.occurrences( range_start=DateTime(self.request.get('start')), range_end=DateTime(self.request.get('end'))): # The default source marks an event as all day if it is longer than # one day. Marking an event as all day in contentpage will set # the times to 00:00 and 23:59. If those times are on the same # date they will not be recognised as all day because that's only a # 0.999.. day. This check will mark those events as all day. start = occurrence.start end = occurrence.end duration = occurrence.end - occurrence.start if isinstance(duration, timedelta): duration = duration.total_seconds() / 60. / 60. / 24. # compute real all day for the tooltip information real_allday = (event.whole_day or duration > 0.99 or start == end or occurrence.start.date() != occurrence.end.date()) # For the main calendar_view we set all events to allday because we # don't show start and end times anyway and we need the background # color that only appears on full day events. if view == 'calendar_view': allday = True end += timedelta(days=1) else: # on all other views we need the allday to be correct allday = real_allday iso = 'isoformat' if hasattr(start, 'isoformat') else 'ISO8601' start = getattr(start, iso)() end = getattr(end, iso)() ret.append({ "id": "UID_%s" % (event.UID()), "title": title, "start": start, "end": end, "url": event.absolute_url(), "can_edit": editable, "can_delete": deletable, "backgroundColor": color, "allDay": allday, "realAllDay": real_allday, "className": "state-" + str(get_state(event)) + (editable and " editable" or ""), "description": description, "location": event.location, "realStartTime": occurrence.start.strftime('%H:%M'), "realEndTime": occurrence.end.strftime('%H:%M'), "realStartDate": occurrence.start.strftime('%B %d'), "realEndDate": occurrence.end.strftime('%B %d'), "oneday": occurrence.start.date() == occurrence.end.date() }) return ret
def state(self): """return the current review_state of context """ return get_state(self.context)
def is_not_private(self): return get_state(self.context) != 'private'
def render(self): if get_state(self.context, 'cancelled'): return '' else: # noinspection PyArgumentList return self.index()
def get_status(self, city): try: return get_state(city) except Exception, e: return "Error: %s" % e
def guard_release(instance): """ """ if get_state(instance.aq_parent) != "released": return False return True
def votable_update(votable_object, event): votable = IVoting(votable_object) if get_state(votable_object) == 'pending': if votable.average_vote() > 0.5: transition(votable_object, transition='publish')
def myState(self): """ """ return content.get_state(self, "None")