예제 #1
0
    def _mod_doc(self, doc_type, doc_title, doc_xml, doc_id):
        """
        Add a new version for a document which was different on the two tiers.
        """

        args = doc_type, doc_title, doc_id
        self._logger.info("updating %r document %r (CDR%d)", *args)

        # Lock the document, breaking any existing locks if necessary.
        doc = self._lock_doc(doc_id)
        if doc:

            # Plug in the preserved XML from PROD and create the new version.
            doc.xml = doc_xml.encode("utf-8")
            doc.ctrl["DocTitle"] = doc_title.encode("utf-8")
            response = cdr.repDoc(self._session,
                                  doc=str(doc),
                                  checkIn="Y",
                                  val="Y",
                                  ver="Y",
                                  reason=Job.COMMENT,
                                  comment=Job.COMMENT)
            err = cdr.checkErr(response)
            if err:
                args = cdr.normalize(doc_id), err
                self._logger.error("failure saving %s: %s", *args)
예제 #2
0
    def getCipsContactAddress(self, id, withPersonTitle=TITLE_OMITTED):
        """
        Constructs and returns a new Address object for the document.

        Parameters:
            id              - Integer ID for CDR Person document.
            docType         - 'Person' (default) or 'Organization'
            withPersonTitle - For Address constructor.
        Return value:
            Returns an Address object for the CIPS contact.
        """
        # Make string version of id
        docId = cdr.normalize(id)

        # Find fragment ID for CIPS contact location in Person doc
        rows = cdr.getQueryTermValueForId(
            '/Person/PersonLocations/CIPSContact', id, self.__conn)
        if not rows:
            raise Exception("no CIPSContact for %s" % docId)
        fragId = rows[0]

        # Filter to create AddressElement XML
        filters = ["name:Person Address Fragment With Name"]
        result = cdr.filterDoc(self.__session,
                               filters,
                               docId,
                               parm=(('fragId', fragId), ))

        # Expecting tuple of xml fragment, messages.  Single string is error.
        if type(result) == type(""):
            raise Exception("failure extracting contact address "
                            "for %s: %s" % (docId, result))
        return Address(result[0], withPersonTitle)
예제 #3
0
    def save_pair(self, doc_id, before, after, pair_type, errors=None):
        """
        Write before and after XML to the file system

        Used in test mode to save everything to the file system
        for review, instead of writing to the repository.

        Pass:
          doc_id - integer identifying the document being processed
          before - serialized XML for the document before transformation
          after - serialzed XML for the document after transformation
          pair_type - string identifying what was transformed (cwd|pub|lastv)
          errors - optional sequence of validation error messages
        """

        args = self.output_directory, cdr.normalize(doc_id), pair_type
        old_path = "{}/{}.{}old.xml".format(*args)
        new_path = "{}/{}.{}new.xml".format(*args)
        diff_path = "{}/{}.{}.diff".format(*args)
        errors_path = "{}/{}.{}.NEW_ERRORS.txt".format(*args)
        try:
            with open(old_path, "wb") as fp:
                fp.write(before)
            with open(new_path, "wb") as fp:
                fp.write(after)
            diff = cdr.diffXmlDocs(before, after) or b"-- No differences --"
            with open(diff_path, "wb") as fp:
                fp.write(diff)
            if errors:
                with open(errors_path, "wb") as fp:
                    for error in errors:
                        fp.write(error.encode("utf-8") + b"\n")
        except:
            self.logger.exception("Failure writing XML pair")
            raise
예제 #4
0
 def show(self, page):
     "Add the summary to the HTML object"
     B = self.control.HTMLPage.B
     doc_id = B.BR()
     doc_id.tail = cdr.normalize(self.doc_id)
     page.append(B.H2(self.title, doc_id, B.CLASS("summary")))
     page.append(self.changes)
예제 #5
0
        def replace(self):
            """
            Update an existing CDR document (if not testing).

            Return True, which is bubbled up to the main loop in `run()`.
            """

            if self.control.opts.test:
                self.control.logger.info("%s is changed", self.name)
                return True
            cdr.checkOutDoc(self.control.session, self.id, force="Y")
            comment = "Updated by install-docset.py"
            ctrl = { "DocTitle": self.title }
            opts = { "type": self.doctype, "encoding": "utf-8", "ctrl": ctrl }
            opts["id"] = cdr.normalize(self.id)
            cdr_doc = cdr.Doc(self.xml, **opts)
            opts = dict(doc=str(cdr_doc), checkIn="Y", ver="Y", comment=comment)
            opts["publishable"] = self.control.PUBLISHABLE
            cdr_id = cdr.repDoc(self.control.session, **opts)
            error = cdr.checkErr(cdr_id)
            if error:
                self.control.logger.error(error)
                sys.exit(1)
            self.control.logger.info("replaced %s (%s)", self.name, cdr_id)
            return True
예제 #6
0
 def _unlock_doc(self, doc_id):
     """
     Release an existing lock on a CDR document.
     """
     id_string = cdr.normalize(doc_id)
     response = cdr.unlock(self._session, id_string, Job.COMMENT)
     if response:
         self._logger.error("failure unlocking %s: %s", id_string, response)
         return False
     return True
예제 #7
0
    def getBoardMemberAddress(self, personId, memberId):

        # Find fragment ID for CIPS contact location in BoardMemberInfo doc
        path = '/PDQBoardMemberInfo/BoardMemberContact/PersonContactID'
        rows = cdr.getQueryTermValueForId(path, memberId, self.__conn)

        # Filter to create AddressElement XML
        if rows:
            docId = cdr.normalize(personId)
            parms = (('fragId', rows[0]), )
            filters = ["name:Person Address Fragment With Name"]
        else:
            docId = cdr.normalize(memberId)
            parms = ()
            filters = ["name:Board Member Address Fragment With Name"]
        result = cdr.filterDoc(self.__session, filters, docId, parm=parms)
        if isinstance(result, (str, bytes)):
            raise Exception("failure extracting contact address "
                            "for %s: %s" % (docId, result))
        return Address(result[0])
예제 #8
0
        def __init__(self, job, doc_id):

            self.job = job
            self.id = doc_id
            self.cdr_id = cdr.normalize(doc_id)
            self.versions = cdr.lastVersions("guest", doc_id, tier=job.tier)
            self.status = cdr.getDocStatus("guest", doc_id, tier=job.tier)
            self.saved = set()
            self.doc_objects = {}
            self.transformed_xml = {}
            self.errors = {}
            self.changed = set()
            self.load_versions()
예제 #9
0
    def _lock_doc(self, doc_id):
        """
        Check out an existing CDR document.
        """

        # If someone else has the document locked, break the lock.
        locker = self._find_locker(doc_id)
        if locker and locker.lower() != self._uid.lower():
            if not self._unlock_doc(doc_id):
                return None

        # Fetch the document with a lock.
        doc = cdr.getDoc(self._session, doc_id, checkout="Y", getObject=True)
        err = cdr.checkErr(doc)
        if not err:
            return doc
        args = cdr.normalize(doc_id), err
        self._logger.error("failure locking %s: %r", *args)
        return None
예제 #10
0
    def addMailerTrackingDoc(self,
                             doc,
                             recipient,
                             mailerType,
                             remailerFor=None,
                             protOrgId=None,
                             email=None):
        """
        Parameters:
            doc         - Object of type Document, defined below
            recipient   - Object of type Recipient, defined below
            mailerType  - String containing a values matching the
                          list of valid values for MailerType
                          enumerated in the schema for Mailer docs.
            remailerFor - optional integer for the document ID of
                          an earlier mailer that was sent out and
                          never responded to, and for which this
                          is a followup remailer.
            protOrgId   - string or integer form of CDR ID for a
                          protocol's lead organization (the one to
                          which this mailer is being sent); used to
                          distinguish between Status and Participant
                          mailers for the same protocol in the
                          same job.
            email       - address used for electronic mailer.
        Return value:
            Integer ID for the newly inserted Mailer document.
        """

        if remailerFor:
            remailerFor = "\n   <RemailerFor cdr:ref='%s'/>" % \
                          cdr.normalize(remailerFor)
        else:
            remailerFor = ""
        if protOrgId:
            protOrg     = "\n   <ProtocolOrg cdr:ref='%s'/>" % \
                          cdr.normalize(protOrgId)
        else:
            protOrg = ""
        if email:
            mode = "Web-based"
            address = """\
   <MailerAddress>
    <Email>%s</Email>
   </MailerAddress>""" % email
        else:
            mode = "Mail"
            address = recipient.getAddress().getXml()
        recipId = "CDR%010d" % recipient.getId()
        docId = "CDR%010d" % doc.getId()
        xml = """\
<CdrDoc Type="Mailer">
 <CdrDocCtl>
  <DocTitle>Mailer for document %s sent to %s</DocTitle>
 </CdrDocCtl>
 <CdrDocXml><![CDATA[
  <Mailer xmlns:cdr="cips.nci.nih.gov/cdr">
   <Type Mode='%s'>%s</Type>%s
   <JobId>%d</JobId>
   <Recipient cdr:ref="%s">%s</Recipient>%s
%s
   <Document cdr:ref="%s">%s</Document>
   <Sent>%s</Sent>
   <Deadline>%s</Deadline>
  </Mailer>]]>
 </CdrDocXml>
</CdrDoc>
""" % (docId, recipId, mode, mailerType, remailerFor, self.__id, recipId,
        recipient.getName(), protOrg, address, docId, doc.getTitle(),
        self.__now, self.getDeadline())
        rsp = cdr.addDoc(self.__session,
                         doc=xml.encode('utf-8'),
                         checkIn="Y",
                         ver="Y",
                         val='Y')
        match = self.__ERR_PATTERN.search(rsp)
        if match:
            err = match.group(1)
            raise Exception("failure adding tracking document for %s: %s" %
                            (docId, err))
        self.__nMailers += 1
        digits = re.sub("[^\d]", "", rsp)
        return int(digits)