Source code for Assign_GUP.proposal


# Copyright (c) 2009 - 2016, UChicago Argonne, LLC.
# See LICENSE file for details.

'''
Data for one General User Proposal
'''

from lxml import etree

import tools
import topics
import xml_utility

PRIMARY_REVIEWER_ROLE = 1
SECONDARY_REVIEWER_ROLE = 2


[docs]class AGUP_Proposal_Data(object): ''' A single General User Proposal ''' tagList = ( # these are the XML tags to find in a proposal 'proposal_id', 'proposal_type', 'proposal_title', 'review_period', 'spk_name', 'recent_req_period', 'first_choice_bl' ) def __init__(self, xmlParentNode = None, xmlFile = None): self.db = {} self.eligible_reviewers = {} self.topics = topics.Topics() self.xmlFile = xmlFile if xmlParentNode != None: self.importXml( xmlParentNode )
[docs] def importXml(self, proposal_node): ''' Fill the class variables with values from the XML node :param proposal_node: lxml node of the Proposal ''' for key in self.tagList: text = xml_utility.getXmlText(proposal_node, key) if text is None: self.db[key] = None else: self.db[key] = tools.text_encode(text) subject_node = proposal_node.find('subject') if subject_node is not None: subjects = [node.text.strip() for node in subject_node.findall('name')] else: subjects = '' self.db['subjects'] = ", ".join(subjects) # get list of eligible reviewers (specified by full name) eligibles = self.eligible_reviewers # search for any existing reviewer assignments node = proposal_node.find('reviewer') for name in node.findall('name'): who = name.text.strip() assignment = name.get('assigned', None) if assignment is not None: assignment = int(assignment[-1]) excluded = name.get('excluded', 'false') == 'true' if who not in eligibles and not excluded: eligibles[who] = assignment # search for any existing topic strength assessments self.topics.importXmlTopics(proposal_node, True)
[docs] def writeXmlNode(self, specified_node): ''' write this Proposal's data to a specified node in the XML document :param obj specified_node: XML node to contain this data ''' for tag in self.tagList: etree.SubElement(specified_node, tag).text = self.getKey(tag) node = etree.SubElement(specified_node, 'subject') for v in [_.strip() for _ in self.db['subjects'].split(',')]: subnode = etree.SubElement(node, 'name') subnode.text = str(v) node = etree.SubElement(specified_node, 'reviewer') for k, v in sorted(self.eligible_reviewers.items()): subnode = etree.SubElement(node, 'name') subnode.text = str(k) if v in (1, 2): subnode.attrib['assigned'] = 'reviewer' + str(v) self.topics.writeXml(specified_node)
[docs] def setAssignedReviewer(self, reviewer, role=None): ''' assign a reviewer to this proposal as primary (role=1) or secondary (role=2) or None (unassigned) ''' if role not in (None, PRIMARY_REVIEWER_ROLE, SECONDARY_REVIEWER_ROLE): raise ValueError('unknown role: ' + str(role)) full_name = reviewer.getFullName() if full_name not in self.eligible_reviewers: raise KeyError('unknown reviewer: ' + full_name) self.eligible_reviewers[full_name] = role # un-assign any other reviewer from this role if role is not None: for k, v in self.eligible_reviewers.items(): if k != full_name and v == role: self.eligible_reviewers[k] = None
[docs] def getAssignedReviewers(self): ''' return a list of assigned reviewers for this proposal ''' r = [None, None] for k, v in self.eligible_reviewers.items(): if v is not None: r[v-1] = k return r
[docs] def getExcludedReviewers(self, reviewers): ''' return a list of excluded reviewers for this proposal :param obj reviewers: list of all available reviewers ''' r = [] for rvwr in reviewers: full_name = rvwr.getFullName() if full_name not in self.eligible_reviewers.keys(): r.append(full_name) return r
[docs] def getKey(self, key): '''get the item from self.db identified by ``key``''' return tools.text_decode(self.db[key])
[docs] def getSubjects(self): ''' return the list of subjects as specified in the Proposal ''' subjects = [] for subject in [_.strip() for _ in self.getKey('subjects').split(',')]: subjects.append(subject) return subjects
[docs] def getTopic(self, topic): ''' return the value of the named topic ''' return self.topics.get(topic)
[docs] def getTopicList(self): ''' return a list of all topics ''' return self.topics.getTopicList()
[docs] def hasTopic(self, topic): ''' does the named topic exist? ''' return self.topics.exists(topic)
[docs] def addTopic(self, topic, value=None): ''' declare a new topic and give it an initial value (default value=0.0) topic must not exist or KeyError exception will be raised ''' value = value or topics.DEFAULT_TOPIC_VALUE self.topics.add(topic, value)
[docs] def addTopics(self, topics_list): ''' declare several new topics and give them all default values each topic must not exist or KeyError exception will be raised ''' self.topics.addTopics(topics_list)
[docs] def setTopic(self, topic, value=None): ''' set value of an existing topic topic must exist or KeyError exception will be raised ''' value = value or topics.DEFAULT_TOPIC_VALUE self.topics.set(topic, float(value))
[docs] def removeTopic(self, key): ''' remove the named topic ''' self.topics.remove(key)
[docs] def removeTopics(self, key_list): ''' remove several topics at once ''' self.topics.removeTopics(key_list)