Example #1
0
def get_confsubmit_message(curdir, ln=CFG_SITE_LANG):
    """
    @return: a message suitable to display to the user, explaining the current
        status of the system.
    @rtype: string
    """
    bibupload_id = ParamFromFile(os.path.join(curdir, 'bibupload_id'))
    if not bibupload_id:
        ## No BibUpload scheduled? Then we don't care about bibsched
        return ""
    ## Let's get an estimate about how many processes are waiting in the queue.
    ## Our bibupload might be somewhere in it, but it's not really so important
    ## WRT informing the user.
    _ = gettext_set_language(ln)
    res = run_sql(
        "SELECT id,proc,runtime,status,priority FROM schTASK WHERE (status='WAITING' AND runtime<=NOW()) OR status='SLEEPING'"
    )
    pre = _(
        "Note that your submission has been inserted into the task queue and is waiting for execution.\n"
    )
    if server_pid():
        ## BibSched is up and running
        msg = _(
            "The task queue is currently running in automatic mode, and there are currently %s tasks waiting to be executed. Your record should be available within a few minutes and searchable within an hour or thereabouts.\n"
        ) % (len(res), )
    else:
        msg = _(
            "Because of a human intervention or a temporary problem, the task queue is currently set to the manual mode. Your submission is well registered but may take longer than usual before it is fully integrated and searchable.\
n")

    return pre + msg
Example #2
0
def Print_Success(parameters, curdir, form, user_info=None):
    """
    This function simply displays a text on the screen, telling the
    user the submission went fine. To be used in the 'Submit New
    Record' action.

    Parameters:

       * status: Depending on the value of this parameter, the
         function adds an additional text to the email.
         This parameter can be one of:
           - ADDED: The file has been integrated in the database.
           - APPROVAL: The file has been sent for approval to a referee.
                       or can stay empty.

       * edsrn: Name of the file containing the reference of the
                document

       * newrnin: Name of the file containing the 2nd reference of the
                  document (if any)
    """
    t = ""
    edsrn = parameters['edsrn']
    newrnin = parameters['newrnin']
    status = parameters['status']
    sysno = ParamFromFile("%s/%s" % (curdir, 'SN')).strip()
    fp = open("%s/%s" % (curdir, edsrn), "r")
    rn = fp.read()
    fp.close()
    if newrnin != "" and os.path.exists("%s/%s" % (curdir, newrnin)):
        fp = open("%s/%s" % (curdir, newrnin), "r")
        additional_rn = fp.read()
        fp.close()
        additional_rn = " and %s" % additional_rn
    else:
        additional_rn = ""
    t = t + Request_Print(
        "A", "<br /><br /><b>Submission Complete!</b><br /><br />")
    t = t + Request_Print(
        "A",
        "Your document has the following reference(s): <b>%s%s</b><br /><br />"
        % (rn, additional_rn))
    if sysno:
        url = '%s/%s/%s' % (CFG_SITE_URL, CFG_SITE_RECORD, sysno)
        t = t + Request_Print(
            'A',
            'Your document has the following URL: <b><a href="%s">%s</a></b><br /><br />'
            % (url, url))
    if status == "APPROVAL":
        t = t + Request_Print(
            "A",
            "An email has been sent to the referee. You will be warned by email as soon as the referee takes his/her decision regarding your document.<br /><br />\n"
        )
    if status == "ADDED":
        t = t + Request_Print(
            "A", "It will soon appear on our server.<br /><br />\n")
    t = t + Request_Print("A", "Thank you for using %s!" % CFG_SITE_NAME)
    t = t + Request_Print("A", "<br /><br /><br /><br />")
    t += txt2html(get_nice_bibsched_related_message(curdir))
    return t
def Withdraw_Approval_Request(parameters, curdir, form, user_info=None):
    """
    This function is used in a "withdraw approval request" submission
    in order to register the withdral of the request in the WebSubmit
    "Approvals" DB (sbmAPPROVAL).
    At the time of the approval request withdrawal, the document could be
    in one of several different approval "states" and depending upon that
    state, the action taken by this function differs. The states are as
    follows:
          * Approval of the document has previously been requested and it is
            still in the "waiting" state.
             -> In this case, the status of the document in the sbmAPPROVAL
                table is set to "withdrawn".
          * Approval for the document has never been requested.
             -> In this case, there is nothing to do.
          * Approval of the document has previously been requested, but the
            document was rejected.
             -> In this case, it's too late to withdraw the approval request
                and there is nothing left to do.
          * Approval of the document has previously been requested and it has
            been approved.
             -> In this case, it's too late to withdraw the approval request
                and there is nothing left to do.
          * Approval of the document has previously been requested, but the
            request withdrawn.
             -> In this case, there is nothing to do.

    @param categ_file_withd: (string) - some document types are
           separated into different categories, each of which has its own
           referee(s).
           In such document types, it's necessary to know the document-
           type's category in order to choose the referee.
           This parameter provides a means by which the category information
           can be extracted from a file in the current submission's working
           directory. It should therefore be a filename.

    @param categ_rnseek_withd: (string) - some document types are
           separated into different categories, each of which has its own
           referee(s).
           In such document types, it's necessary to know the document-
           type's category in order to choose the referee.
           This parameter provides a means by which the category information
           can be extracted from the document's reference number.
           It is infact a string that will be compiled into a regexp and
           an attempt will be made to match it agains the document's reference
           number starting from the left-most position.
           The only pre-requisite is that the segment in which the category is
           sought should be indicated with <CATEGORY>.
           Thus, an example might be as follows:
              ATL(-COM)?-<CATEGORY>-.+
           This would allow "PHYS" in the following reference number to be
           recognised as the category:
              ATL-COM-PHYS-2008-001

    @return: (string) - a message for the user.

    @Exceptions raised: + InvenioWebSubmitFunctionStop when the submission
                          should be halted.
                        + InvenioWebSubmitFunctionError when an unexpected
                          error has been encountered and execution cannot
                          continue.
    """
    ## Get the reference number (as global rn - sorry!) and the document type:
    global rn
    doctype = form['doctype']

    ## A string variable to contain any information that should be displayed
    ## in the user's browser:
    info_out = ""

    ########
    ## Get the parameters from the list:

    ########
    ## Get the name of the category file:
    #######
    try:
        ## If it has been provided, get the name of the file in which the
        ## category is stored:
        category_file = parameters["categ_file_withd"]
    except KeyError:
        ## No value given for the category file:
        category_file = None
    else:
        if category_file is not None:
            category_file = str(category_file)
            category_file = os.path.basename(category_file).strip()
            if category_file == "":
                category_file = None
    ########
    ## Get the regexp that is used to find the category in the report number:
    ########
    try:
        ## If it has been provided, get the regexp used for identifying
        ## a document-type's category from its reference number:
        category_rn_regexp = parameters["categ_rnseek_withd"]
    except KeyError:
        ## No value given for the category regexp:
        category_rn_regexp = None
    else:
        if category_rn_regexp is not None:
            category_rn_regexp = str(category_rn_regexp).strip()
        if category_rn_regexp == "":
            category_rn_regexp = None

    #######
    ## Resolve the document type's category:
    ##
    ## This is a long process. The end result is that the category is extracted
    ## either from a file in curdir, or from the report number.
    ## If it's taken from the report number, the admin must configure the
    ## function to accept a regular expression that is used to find the
    ## category in the report number.
    ##
    if category_file is not None and category_rn_regexp is not None:
        ## It is not valid to have both a category file and a pattern
        ## describing how to extract the category from a report number.
        ## raise an InvenioWebSubmitFunctionError
        msg = "Error in Withdraw_Approval_Request function: received " \
              "instructions to search for the document's category in " \
              "both its report number AND in a category file. Could " \
              "not determine which to use - please notify " \
              "%(suppt-email)s." \
              % { 'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
        raise InvenioWebSubmitFunctionError(msg)
    elif category_file is not None:
        ## Attempt to recover the category information from a file in the
        ## current submission's working directory:
        category = ParamFromFile("%s/%s" % (curdir, category_file))
        if category is not None:
            category = category.strip()
        if category in (None, ""):
            ## The category cannot be resolved.
            msg = "Error in Withdraw_Approval_Request function: received " \
                  "instructions to search for the document's category in " \
                  "a category file, but could not recover the category " \
                  "from that file. The approval request therefore cannot " \
                  "be withdrawn for the document. Please report this " \
                  "problem to %(suppt-email)s." \
                  % { 'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
            raise InvenioWebSubmitFunctionError(msg)
    elif category_rn_regexp is not None:
        ## Attempt to recover the category information from the document's
        ## reference number using the regexp in category_rn_regexp:
        ##
        ## Does the category regexp contain the key-phrase "<CATEG>"?
        if category_rn_regexp.find("<CATEG>") != -1:
            ## Yes. Replace "<CATEG>" with "(?P<category>.+?)".
            ## For example, this:
            ##    ATL(-COM)?-<CATEG>-
            ## Will be transformed into this:
            ##    ATL(-COM)?-(?P<category>.+?)-
            category_rn_final_regexp = \
                category_rn_regexp.replace("<CATEG>", r"(?P<category>.+?)", 1)
        else:
            ## The regexp for category didn't contain "<CATEG>", but this is
            ## mandatory.
            msg = "Error in Withdraw_Approval_Request function: The " \
                  "[%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number, " \
                  "using a poorly formed search expression (no marker for " \
                  "the category was present.) Since the document's category " \
                  "therefore cannot be retrieved, its approval request " \
                  "cannot be withdrawn. Please report this problem to " \
                  "%(suppt-email)s." \
                  % { 'doctype'     : cgi.escape(doctype),
                      'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
            raise InvenioWebSubmitFunctionError(msg)
        ##
        try:
            ## Attempt to compile the regexp for finding the category:
            re_categ_from_rn = re.compile(category_rn_final_regexp)
        except sre_constants.error:
            ## The expression passed to this function could not be compiled
            ## into a regexp. Register this exception and raise an
            ## InvenioWebSubmitFunctionError:
            exception_prefix = "Error in Withdraw_Approval_Request function: " \
                               "The [%(doctype)s] submission has been " \
                               "configured to search for the document type's " \
                               "category in its reference number, using the " \
                               "following regexp: /%(regexp)s/. This regexp, " \
                               "however, could not be compiled correctly " \
                               "(created it from %(categ-search-term)s.)" \
                               % { 'doctype'       : doctype, \
                                   'regexp'        : category_rn_final_regexp, \
                                   'categ-search-term' : category_rn_regexp, }
            register_exception(prefix=exception_prefix)
            msg = "Error in Withdraw_Approval_Request function: The " \
                  "[%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number, " \
                  "using a poorly formed search expression. Since the " \
                  "document's category therefore cannot be retrieved, its " \
                  "approval request cannot be withdrawn. Please " \
                  "report this problem to %(suppt-email)s." \
                  % { 'doctype'     : cgi.escape(doctype),
                      'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
            raise InvenioWebSubmitFunctionError(msg)
        else:
            ## Now attempt to recover the category from the RN string:
            m_categ_from_rn = re_categ_from_rn.match(rn)
            if m_categ_from_rn is not None:
                ## The pattern matched in the string.
                ## Extract the category from the match:
                try:
                    category = m_categ_from_rn.group("category")
                except IndexError:
                    ## There was no "category" group. That group is mandatory.
                    exception_prefix = \
                       "Error in Withdraw_Approval_Request function: The " \
                       "[%(doctype)s] submission has been configured to " \
                       "search for the document type's category in its " \
                       "reference number using the following regexp: " \
                       "/%(regexp)s/. The search produced a match, but " \
                       "there was no \"category\" group in the match " \
                       "object although this group is mandatory. The " \
                       "regexp was compiled from the following string: " \
                       "[%(categ-search-term)s]." \
                       % { 'doctype'           : doctype, \
                           'regexp'            : category_rn_final_regexp, \
                           'categ-search-term' : category_rn_regexp, }
                    register_exception(prefix=exception_prefix)
                    msg = "Error in Withdraw_Approval_Request function: The " \
                          "[%(doctype)s] submission has been configured to " \
                          "search for the document type's category in its " \
                          "reference number, using a poorly formed search " \
                          "expression (there was no category marker). Since " \
                          "the document's category therefore cannot be " \
                          "retrieved, its approval request cannot be " \
                          "withdrawn. Please report this problem to " \
                          "%(suppt-email)s." \
                          % { 'doctype'     : cgi.escape(doctype),
                              'suppt-email' : \
                                  cgi.escape(CFG_SITE_SUPPORT_EMAIL),}
                    raise InvenioWebSubmitFunctionError(msg)
                else:
                    category = category.strip()
                    if category == "":
                        msg = "Error in Withdraw_Approval_Request function: " \
                              "The [%(doctype)s] submission has been " \
                              "configured to search for the document type's " \
                              "category in its reference number, but no " \
                              "category was found. The request for approval " \
                              "cannot be withdrawn. Please report this " \
                              "problem to %(suppt-email)s." \
                              % { 'doctype'     : cgi.escape(doctype),
                                  'suppt-email' : \
                                     cgi.escape(CFG_SITE_SUPPORT_EMAIL),}
                        raise InvenioWebSubmitFunctionError(msg)
            else:
                ## No match. Cannot find the category and therefore cannot
                ## continue:
                msg = "Error in Withdraw_Approval_Request function: The " \
                      "[%(doctype)s] submission has been configured to " \
                      "search for the document type's category in its " \
                      "reference number, but no match was made. The request " \
                      "for approval cannot be withdrawn. Please report " \
                      "this problem to %(suppt-email)s." \
                      % { 'doctype'     : cgi.escape(doctype),
                          'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL),}
                raise InvenioWebSubmitFunctionError(msg)
    else:
        ## The document type has no category.
        category = ""
    ##
    ## End of category recovery
    #######

    #######
    ##
    ## Query the "approvals" DB table to determine whether approval of this
    ## document has already been requested:
    approval_status = get_simple_approval_status(doctype, rn)
    if approval_status is None:
        ## Approval has never been requested for this document.
        ## One cannot withdraw an approval request that was never made.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> A request for the approval of the
 document [%s] has never been made.<br />
There is nothing to do.
</div>
""" % cgi.escape(rn)
        raise InvenioWebSubmitFunctionStop(msg)
    elif approval_status.lower() == "approved":
        ## This document has already been approved. It's too late to withdraw
        ## the approval request.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> The document [%s] has already been
 approved.<br />
It is too late to withdraw the approval request.<br />
If you believe this to be an error, please contact %s, quoting the<br />
document's report-number [%s] and describing the problem.
</div>
""" % (cgi.escape(rn), cgi.escape(CFG_SITE_SUPPORT_EMAIL), cgi.escape(rn))
        raise InvenioWebSubmitFunctionStop(msg)
    elif approval_status.lower() == "rejected":
        ## This document has already been rejected. It's too late to withdraw
        ## the approval request.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> The document [%s] has already been
 rejected.<br />
It is too late to withdraw the approval request.<br />
If you believe this to be an error, please contact %s, quoting the<br />
document's report-number [%s] and describing the problem.
</div>
""" % (cgi.escape(rn), cgi.escape(CFG_SITE_SUPPORT_EMAIL), cgi.escape(rn))
        raise InvenioWebSubmitFunctionStop(msg)
    elif approval_status.lower() == "withdrawn":
        ## The approval request for this document has already been withdrawn.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> The approval request for the document
 [%s] has already been withdrawn.<br />
There is nothing to do.
</div>
""" % cgi.escape(rn)
        raise InvenioWebSubmitFunctionStop(msg)
    elif approval_status.lower() == "waiting":
        ## Mark the approval request as withdrawn:
        note = "Withdrawn by [%s]: %s\n#####\n" \
               % (cgi.escape(user_info['email']), \
                  cgi.escape(time.strftime("%d/%m/%Y %H:%M:%S", \
                                           time.localtime())))
        update_approval_request_status(doctype, \
                                       rn, \
                                       note=note, \
                                       status="withdrawn")
        info_out += """
<br />
<div>
The approval request for the document [%s] has been withdrawn.
</div>
""" % cgi.escape(rn)
    else:
        ## The document had an unrecognised "status". Raise an error.
        msg = "Error in Withdraw_Approval_Request function: The " \
              "[%(reportnum)s] document has an unknown approval status " \
              "(%(status)s). Unable to withdraw the request for its " \
              "approval. Please report this problem to the %(suppt-email)s." \
              % { 'reportnum'   : cgi.escape(rn),
                  'status'      : cgi.escape(approval_status),
                  'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
        raise InvenioWebSubmitFunctionError(msg)
    ##
    ## Finished - return any message to be displayed on the user's screen.
    return info_out
def Mail_Approval_Withdrawn_to_Referee(parameters, \
                                       curdir, \
                                       form, \
                                       user_info=None):
    """
    This function sends an email to the referee of a document informing
    him/her that the request for its approval has been withdrawn.

    @param categ_file_withd: (string) - some document types are
           separated into different categories, each of which has its own
           referee(s).
           In such document types, it's necessary to know the document-
           type's category in order to choose the referee.
           This parameter provides a means by which the category information
           can be extracted from a file in the current submission's working
           directory. It should therefore be a filename.

    @param categ_rnseek_withd: (string) - some document types are
           separated into different categories, each of which has its own
           referee(s).
           In such document types, it's necessary to know the document-
           type's category in order to choose the referee.
           This parameter provides a means by which the category information
           can be extracted from the document's reference number.
           It is infact a string that will be compiled into a regexp and
           an attempt will be made to match it agains the document's reference
           number starting from the left-most position.
           The only pre-requisite is that the segment in which the category is
           sought should be indicated with <CATEGORY>.
           Thus, an example might be as follows:
              ATL(-COM)?-<CATEGORY>-.+
           This would allow "PHYS" in the following reference number to be
           recognised as the category:
              ATL-COM-PHYS-2008-001

    @return: (string) - empty string.
    """
    ## Get the reference number (as global rn - sorry!) and the document type:
    global sysno, rn
    doctype = form['doctype']

    ########
    ## Get the parameters from the list:

    ########
    ## Get the name of the category file:
    #######
    try:
        ## If it has been provided, get the name of the file in which the
        ## category is stored:
        category_file = parameters["categ_file_withd"]
    except KeyError:
        ## No value given for the category file:
        category_file = None
    else:
        if category_file is not None:
            category_file = str(category_file)
            category_file = os.path.basename(category_file).strip()
            if category_file == "":
                category_file = None
    ########
    ## Get the regexp that is used to find the category in the report number:
    ########
    try:
        ## If it has been provided, get the regexp used for identifying
        ## a document-type's category from its reference number:
        category_rn_regexp = parameters["categ_rnseek_withd"]
    except KeyError:
        ## No value given for the category regexp:
        category_rn_regexp = None
    else:
        if category_rn_regexp is not None:
            category_rn_regexp = str(category_rn_regexp).strip()
        if category_rn_regexp == "":
            category_rn_regexp = None
    #######
    ## Resolve the document type's category:
    ##
    ## This is a long process. The end result is that the category is extracted
    ## either from a file in curdir, or from the report number.
    ## If it's taken from the report number, the admin must configure the
    ## function to accept a regular expression that is used to find the
    ## category in the report number.
    ##
    if category_file is not None and category_rn_regexp is not None:
        ## It is not valid to have both a category file and a pattern
        ## describing how to extract the category from a report number.
        ## raise an InvenioWebSubmitFunctionWarning:
        msg = "Error in Mail_Approval_Withdrawn_to_Referee function: " \
              "received instructions to search for the document's category " \
              "in both its report number AND in a category file. Could " \
              "not determine which to use - please notify the " \
              "administrator."
        raise InvenioWebSubmitFunctionWarning(msg)
    elif category_file is not None:
        ## Attempt to recover the category information from a file in the
        ## current submission's working directory:
        category = ParamFromFile("%s/%s" % (curdir, category_file))
        if category is not None:
            category = category.strip()
        if category in (None, ""):
            ## The category cannot be resolved.
            msg = "Error in Mail_Approval_Withdrawn_to_Referee function: " \
                  "received instructions to search for the document's " \
                  "category in a category file, but could not recover the " \
                  "category from that file. The referee cannot be notified " \
                  "of the approval request withdrawal by mail."
            raise InvenioWebSubmitFunctionWarning(msg)
    elif category_rn_regexp is not None:
        ## Attempt to recover the category information from the document's
        ## reference number using the regexp in category_rn_regexp:
        ##
        ## Does the category regexp contain the key-phrase "<CATEG>"?
        if category_rn_regexp.find("<CATEG>") != -1:
            ## Yes. Replace "<CATEG>" with "(?P<category>.+?)".
            ## For example, this:
            ##    ATL(-COM)?-<CATEG>-
            ## Will be transformed into this:
            ##    ATL(-COM)?-(?P<category>.+?)-
            category_rn_final_regexp = \
                category_rn_regexp.replace("<CATEG>", r"(?P<category>.+?)", 1)
        else:
            ## The regexp for category didn't contain "<CATEG>", but this is
            ## mandatory.
            msg = "Error in Mail_Approval_Withdrawn_to_Referee function: The" \
                  " [%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number," \
                  " using a poorly formed search expression (no marker for " \
                  "the category was present.) Since the document's category " \
                  "cannot be retrieved, the referee cannot be " \
                  "notified of the approval request withdrawal by mail." \
                  % { 'doctype' : doctype, }
            raise InvenioWebSubmitFunctionWarning(msg)
        ##
        try:
            ## Attempt to compile the regexp for finding the category:
            re_categ_from_rn = re.compile(category_rn_final_regexp)
        except sre_constants.error:
            ## The expression passed to this function could not be compiled
            ## into a regexp. Register this exception and raise an
            ## InvenioWebSubmitFunctionWarning:
            exception_prefix = "Error in Mail_Approval_Withdrawn_to_Referee " \
                               "function: The [%(doctype)s] submission has " \
                               "been configured to search for the document " \
                               "type's category in its reference number, " \
                               "using the following regexp: /%(regexp)s/. " \
                               "This regexp, however, could not be " \
                               "compiled correctly (created it from " \
                               "%(categ-search-term)s.)" \
                               % { 'doctype'      : doctype, \
                                   'regexp'       : category_rn_final_regexp, \
                                   'categ-search-term' : category_rn_regexp, }
            register_exception(prefix=exception_prefix)
            msg = "Error in Mail_Approval_Withdrawn_to_Referee function: The" \
                  " [%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number," \
                  " using a poorly formed search expression. Since the " \
                  "document's category cannot be retrieved, the referee" \
                  "cannot be notified of the approval request withdrawal by " \
                  "mail." \
                  % { 'doctype' : doctype, }
            raise InvenioWebSubmitFunctionWarning(msg)
        else:
            ## Now attempt to recover the category from the RN string:
            m_categ_from_rn = re_categ_from_rn.match(rn)
            if m_categ_from_rn is not None:
                ## The pattern matched in the string.
                ## Extract the category from the match:
                try:
                    category = m_categ_from_rn.group("category")
                except IndexError:
                    ## There was no "category" group. That group is mandatory.
                    exception_prefix = \
                       "Error in Mail_Approval_Withdrawn_to_Referee " \
                       "function: The [%(doctype)s] submission has been " \
                       "configured to search for the document type's " \
                       "category in its reference number using the " \
                       "following regexp: " \
                       "/%(regexp)s/. The search produced a match, but " \
                       "there was no \"category\" group in the match " \
                       "object although this group is mandatory. The " \
                       "regexp was compiled from the following string: " \
                       "[%(categ-search-term)s]." \
                       % { 'doctype'           : doctype, \
                           'regexp'            : category_rn_final_regexp, \
                           'categ-search-term' : category_rn_regexp, }
                    register_exception(prefix=exception_prefix)
                    msg = "Error in Mail_Approval_Withdrawn_to_Referee " \
                          "function: The [%(doctype)s] submission has been " \
                          "configured to search for the document type's " \
                          "category in its reference number, using a poorly " \
                          "formed search expression (there was no category " \
                          "marker). Since the document's category therefore " \
                          "cannot be retrieved, the referee cannot be " \
                          "notified of the approval request withdrawal " \
                          "by mail." \
                          % { 'doctype' : doctype, }
                    raise InvenioWebSubmitFunctionWarning(msg)
                else:
                    category = category.strip()
                    if category == "":
                        msg = "Error in Mail_Approval_Withdrawn_to_Referee " \
                              "function: The [%(doctype)s] submission has " \
                              "been configured to search for the document " \
                              "type's category in its reference number, but " \
                              "no category was found. The referee cannot be " \
                              "notified of the approval request withdrawal " \
                              "by mail." \
                              % { 'doctype' : doctype, }
                        raise InvenioWebSubmitFunctionWarning(msg)
            else:
                ## No match. Cannot find the category and therefore cannot
                ## continue:
                msg = "Error in Mail_Approval_Withdrawn_to_Referee function:" \
                      " The [%(doctype)s] submission has been configured to " \
                      "search for the document type's category in its " \
                      "reference number, but no match was made. The referee " \
                      "cannot be notified of the approval request " \
                      "withdrawal by mail." \
                      % { 'doctype' : doctype, }
                raise InvenioWebSubmitFunctionWarning(msg)
    else:
        ## The document type has no category.
        category = ""
    ##
    ## End of category recovery
    #######

    ## Get the referee email address:
    if CFG_CERN_SITE:
        ## The referees system in CERN now works with listbox membership.
        ## List names should take the format
        ## "*****@*****.**"
        ## Make sure that your list exists!
        ## FIXME - to be replaced by a mailing alias in webaccess in the
        ## future.
        ## see if was a PROC request or not
        notes = get_approval_request_notes(doctype,rn)
        was_proc = 'n'
        was_slide = 'n'
        if notes:
            note_lines = notes.split('\n')
            for note_line in note_lines:
                if note_line.find('Requested Note Classification:') == 0:
                    note_type = note_line.split()[-1]
                    if note_type == 'PROC':
                        was_proc = 'y'
                    elif note_type == 'SLIDE':
                        was_slide = 'y'
                    break  # there may be more than one - just take the first
        if was_proc == 'y':
            referee_listname = "service-cds-referee-%s" % doctype.lower()
            referee_listname += "-%s" %  'proc'
        elif was_slide == 'y':
            referee_listname = "atlas-speakers-comm"
        else:
            referee_listname = "service-cds-referee-%s" % doctype.lower()
            if category != "":
                referee_listname += "-%s" % category.lower()
        referee_listname += "@cern.ch"
        mailto_addresses = referee_listname
        if category == 'CDSTEST':    ## our special testing category
            referee_listname = "service-cds-referee-%s" % doctype.lower()
            referee_listname += "-%s" % category.lower()
            mailto_addresses = referee_listname + "@cern.ch"
    else:
        referee_address = ""
        ## Try to retrieve the referee's email from the referee's database:
        for user in \
            acc_get_role_users(acc_get_role_id("referee_%s_%s" \
                                               % (doctype, category))):
            referee_address += user[1] + ","
        ## And if there are general referees:
        for user in \
            acc_get_role_users(acc_get_role_id("referee_%s_*" % doctype)):
            referee_address += user[1] + ","
        referee_address = re.sub(",$", "", referee_address)
        # Creation of the mail for the referee
        mailto_addresses = ""
        if referee_address != "":
            mailto_addresses = referee_address + ","
        else:
            mailto_addresses = re.sub(",$", "", mailto_addresses)
    ##
    ## Send the email:
    mail_subj = "Request for approval of [%s] withdrawn" % rn
    mail_body = CFG_MAIL_BODY % \
                { 'site-name'               : CFG_SITE_NAME,
                  'report-number'           : rn,
                }
    send_email(CFG_SITE_SUPPORT_EMAIL,
               mailto_addresses,
               mail_subj,
               mail_body,
               copy_to_admin=CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN)
    ##
    return ""
def Mail_Approval_Request_to_Referee(parameters, curdir, form, user_info=None):
    """
    This function sends an email to the referee of a document informing
    him/her that a request for its approval has been submitted by the
    user.

    @param categ_file_appreq: (string) - some document types are
          separated into different categories, each of which has its own
          referee(s).
          In such document types, it's necessary to know the document-
          type's category in order to choose the referee.
          This parameter provides a means by which the category information
          can be extracted from a file in the current submission's working
          directory. It should therefore be a filename.

    @param categ_rnseek_appreq: (string) - some document types are
          separated into different categories, each of which has its own
          referee(s).
          In such document types, it's necessary to know the document-
          type's category in order to choose the referee.
          This parameter provides a means by which the category information
          can be extracted from the document's reference number.
          It is infact a string that will be compiled into a regexp and
          an attempt will be made to match it agains the document's reference
          number starting from the left-most position.
          The only pre-requisite is that the segment in which the category is
          sought should be indicated with <CATEGORY>.
          Thus, an example might be as follows:
             ATL(-COM)?-<CATEGORY>-.+

          This would allow "PHYS" in the following reference number to be
          recognised as the category:
             ATL-COM-PHYS-2008-001

    @param edsrn: (string) - the name of the field in which the report
          number should be placed when the referee visits the form for making
          a decision.

    @return: (string) - empty string.
    """
    ## Get the reference number (as global rn - sorry!) and the document type:
    global sysno, rn
    doctype = form['doctype']

    ########
    ## Get the parameters from the list:

    ########
    ## Get the name of the report-number file:
    ########
    try:
        edsrn_file = parameters["edsrn"]
    except KeyError:
        ## No value given for the edsrn file:
        msg = "Error in Mail_Approval_Request_to_Referee function: unable " \
              "to determine the name of the file in which the document's " \
              "report number should be stored."
        raise InvenioWebSubmitFunctionError(msg)
    else:
        edsrn_file = str(edsrn_file)
        edsrn_file = os.path.basename(edsrn_file).strip()
        if edsrn_file == "":
            msg = "Error in Mail_Approval_Request_to_Referee function: " \
                  "unable to determine the name of the file in which " \
                  "the document's report number should be stored."
            raise InvenioWebSubmitFunctionError(msg)
    ########
    ## Get the name of the category file:
    #######
    try:
        ## If it has been provided, get the name of the file in which the
        ## category is stored:
        category_file = parameters["categ_file_appreq"]
    except KeyError:
        ## No value given for the category file:
        category_file = None
    else:
        if category_file is not None:
            category_file = str(category_file)
            category_file = os.path.basename(category_file).strip()
            if category_file == "":
                category_file = None
    ########
    ## Get the regexp that is used to find the category in the report number:
    ########
    try:
        ## If it has been provided, get the regexp used for identifying
        ## a document-type's category from its reference number:
        category_rn_regexp = parameters["categ_rnseek_appreq"]
    except KeyError:
        ## No value given for the category regexp:
        category_rn_regexp = None
    else:
        if category_rn_regexp is not None:
            category_rn_regexp = str(category_rn_regexp).strip()
        if category_rn_regexp == "":
            category_rn_regexp = None
    #######
    ## Resolve the document type's category:
    ##
    ## This is a long process. The end result is that the category is extracted
    ## either from a file in curdir, or from the report number.
    ## If it's taken from the report number, the admin must configure the
    ## function to accept a regular expression that is used to find the
    ## category in the report number.
    ##
    if category_file is not None and category_rn_regexp is not None:
        ## It is not valid to have both a category file and a pattern
        ## describing how to extract the category from a report number.
        ## raise an InvenioWebSubmitFunctionError
        msg = "Error in Register_Approval_Request function: received " \
              "instructions to search for the document's category in " \
              "both its report number AND in a category file. Could " \
              "not determine which to use - please notify the " \
              "administrator."
        raise InvenioWebSubmitFunctionError(msg)
    elif category_file is not None:
        ## Attempt to recover the category information from a file in the
        ## current submission's working directory:
        category = ParamFromFile("%s/%s" % (curdir, category_file))
        if category is not None:
            category = category.strip()
        if category in (None, ""):
            ## The category cannot be resolved.
            msg = "Error in Register_Approval_Request function: received " \
                  "instructions to search for the document's category in " \
                  "a category file, but could not recover the category " \
                  "from that file. An approval request therefore cannot " \
                  "be registered for the document."
            raise InvenioWebSubmitFunctionError(msg)
    elif category_rn_regexp is not None:
        ## Attempt to recover the category information from the document's
        ## reference number using the regexp in category_rn_regexp:
        ##
        ## Does the category regexp contain the key-phrase "<CATEG>"?
        if category_rn_regexp.find("<CATEG>") != -1:
            ## Yes. Replace "<CATEG>" with "(?P<category>.+?)".
            ## For example, this:
            ##    ATL(-COM)?-<CATEG>-
            ## Will be transformed into this:
            ##    ATL(-COM)?-(?P<category>.+?)-
            category_rn_final_regexp = \
                category_rn_regexp.replace("<CATEG>", r"(?P<category>.+?)", 1)
        else:
            ## The regexp for category didn't contain "<CATEG>", but this is
            ## mandatory.
            msg = "Error in Register_Approval_Request function: The " \
                  "[%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number, " \
                  "using a poorly formed search expression (no marker for " \
                  "the category was present.) Since the document's category " \
                  "therefore cannot be retrieved, an approval request cannot " \
                  "be registered for it. Please report this problem to the " \
                  "administrator." \
                  % { 'doctype' : doctype, }
            raise InvenioWebSubmitFunctionError(msg)
        ##
        try:
            ## Attempt to compile the regexp for finding the category:
            re_categ_from_rn = re.compile(category_rn_final_regexp)
        except sre_constants.error:
            ## The expression passed to this function could not be compiled
            ## into a regexp. Register this exception and raise an
            ## InvenioWebSubmitFunctionError:
            exception_prefix = "Error in Register_Approval_Request function: " \
                               "The [%(doctype)s] submission has been " \
                               "configured to search for the document type's " \
                               "category in its reference number, using the " \
                               "following regexp: /%(regexp)s/. This regexp, " \
                               "however, could not be compiled correctly " \
                               "(created it from %(categ-search-term)s.)" \
                               % { 'doctype'       : doctype, \
                                   'regexp'        : category_rn_final_regexp, \
                                   'categ-search-term' : category_rn_regexp, }
            register_exception(prefix=exception_prefix)
            msg = "Error in Register_Approval_Request function: The " \
                  "[%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number, " \
                  "using a poorly formed search expression. Since the " \
                  "document's category therefore cannot be retrieved, an " \
                  "approval request cannot be registered for it. Please " \
                  "report this problem to the administrator." \
                  % { 'doctype' : doctype, }
            raise InvenioWebSubmitFunctionError(msg)
        else:
            ## Now attempt to recover the category from the RN string:
            m_categ_from_rn = re_categ_from_rn.match(rn)
            if m_categ_from_rn is not None:
                ## The pattern matched in the string.
                ## Extract the category from the match:
                try:
                    category = m_categ_from_rn.group("category")
                except IndexError:
                    ## There was no "category" group. That group is mandatory.
                    exception_prefix = \
                       "Error in Register_Approval_Request function: The " \
                       "[%(doctype)s] submission has been configured to " \
                       "search for the document type's category in its " \
                       "reference number using the following regexp: " \
                       "/%(regexp)s/. The search produced a match, but " \
                       "there was no \"category\" group in the match " \
                       "object although this group is mandatory. The " \
                       "regexp was compiled from the following string: " \
                       "[%(categ-search-term)s]." \
                       % { 'doctype'           : doctype, \
                           'regexp'            : category_rn_final_regexp, \
                           'categ-search-term' : category_rn_regexp, }
                    register_exception(prefix=exception_prefix)
                    msg = "Error in Register_Approval_Request function: The " \
                          "[%(doctype)s] submission has been configured to " \
                          "search for the document type's category in its " \
                          "reference number, using a poorly formed search " \
                          "expression (there was no category marker). Since " \
                          "the document's category therefore cannot be " \
                          "retrieved, an approval request cannot be " \
                          "registered for it. Please report this problem to " \
                          "the administrator." \
                          % { 'doctype' : doctype, }
                    raise InvenioWebSubmitFunctionError(msg)
                else:
                    category = category.strip()
                    if category == "":
                        msg = "Error in Register_Approval_Request function: " \
                              "The [%(doctype)s] submission has been " \
                              "configured to search for the document type's " \
                              "category in its reference number, but no " \
                              "category was found. The request for approval " \
                              "cannot be registered. Please report this " \
                              "problem to the administrator." \
                              % { 'doctype' : doctype, }
                        raise InvenioWebSubmitFunctionError(msg)
            else:
                ## No match. Cannot find the category and therefore cannot
                ## continue:
                msg = "Error in Register_Approval_Request function: The " \
                      "[%(doctype)s] submission has been configured to " \
                      "search for the document type's category in its " \
                      "reference number, but no match was made. The request " \
                      "for approval cannot be registered. Please report " \
                      "this problem to the administrator." \
                      % { 'doctype' : doctype, }
                raise InvenioWebSubmitFunctionError(msg)
    else:
        ## The document type has no category.
        category = ""
    ##
    ## End of category recovery
    #######
    #######
    ## Get the title and author(s) from the record:
    #######
    ## Author(s):
    rec_authors = ""
    rec_first_author    = print_record(int(sysno), 'tm', "100__a")
    rec_other_authors   = print_record(int(sysno), 'tm', "700__a")
    if rec_first_author != "":
        rec_authors += "".join(["%s\n" % author.strip() for \
                                author in rec_first_author.split("\n")])
    if rec_other_authors != "":
        rec_authors += "".join(["%s\n" % author.strip() for \
                                author in rec_other_authors.split("\n")])
    ## Title:
    rec_title = "".join(["%s\n" % title.strip() for title in \
                          print_record(int(sysno), 'tm', "245__a").split("\n")])
    ##
    #######
    ## the normal approval action
    approve_act = 'APP'
    ## Get notes about the approval request:
    approval_notes = get_approval_request_notes(doctype, rn)
    ## Get the referee email address:
    if CFG_CERN_SITE:
        ## The referees system in CERN now works with listbox membership.
        ## List names should take the format
        ## "*****@*****.**"
        ## Make sure that your list exists!
        ## FIXME - to be replaced by a mailing alias in webaccess in the
        ## future.
        if doctype == 'ATN':  ## Special case of 'RPR' action for doctype ATN
            action = ParamFromFile("%s/%s" % (curdir,'act')).strip()
            if action == 'RPR':
                notetype = ParamFromFile("%s/%s" % (curdir,'ATN_NOTETYPE')).strip()
                if notetype not in ('SLIDE','PROC'):
                    raise InvenioWebSubmitFunctionError('ERROR function Mail_Approval_Request_to_Referee:: do not recognize notetype ' + notetype)
                if notetype == 'PROC':
                    approve_act = 'APR'  # RPR PROC requires APR action to approve
                    referee_listname = "*****@*****.**"
                elif notetype == 'SLIDE':  ## SLIDES approval
                    approve_act = 'APS'  # RPR SLIDE requires APS action to approve
                    referee_listname = "*****@*****.**"
                else:
                    raise InvenioWebSubmitFunctionError('ERROR function Mail_Approval_Request_to_Referee:: do not understand notetype: ' +notetype)
            else:
                referee_listname = "service-cds-referee-%s" % doctype.lower()
                if category != "":
                    referee_listname += "-%s" % category.lower()
            mailto_addresses = referee_listname + "@cern.ch"
            if category == 'CDSTEST':
                referee_listname = "service-cds-referee-%s" % doctype.lower()
                referee_listname += "-%s" % category.lower()
                mailto_addresses = referee_listname + "@cern.ch"
    else:
        referee_address = ""
        ## Try to retrieve the referee's email from the referee's database:
        for user in \
            acc_get_role_users(acc_get_role_id("referee_%s_%s" \
                                               % (doctype, category))):
            referee_address += user[1] + ","
        ## And if there are general referees:
        for user in \
            acc_get_role_users(acc_get_role_id("referee_%s_*" % doctype)):
            referee_address += user[1] + ","
        referee_address = re.sub(",$", "", referee_address)
        # Creation of the mail for the referee
        mailto_addresses = ""
        if referee_address != "":
            mailto_addresses = referee_address + ","
        else:
            mailto_addresses = re.sub(",$", "", mailto_addresses)
    ##
    ## Send the email:
    mail_subj = "Request for approval of [%s]" % rn
    mail_body = CFG_MAIL_BODY % \
                { 'site-name'               : CFG_SITE_NAME,
                  'report-number-fieldname' : edsrn_file,
                  'report-number'           : rn,
                  'title'                   : rec_title,
                  'authors'                 : rec_authors,
                  'site-url'                : CFG_SITE_URL,
                  'record-id'               : sysno,
                  'approval-action'         : approve_act,
                  'doctype'                 : doctype,
                  'notes'                   : approval_notes,
                  'category'                : category,
                }
    send_email(CFG_SITE_SUPPORT_EMAIL,
               mailto_addresses,
               mail_subj,
               mail_body,
               copy_to_admin=CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN)
    ##
    return ""
def Run_PlotExtractor(parameters, curdir, form, user_info=None):
    """
    Run the plot extraction on the current record.

    The record ID (sysno) must be defined and known already, and the
    files attached already (so the function must be run after
    'Move_Uploaded_Files_To_Storage' & co., not after a FFT that could
    be scheduled later).

    @param parameters:(dictionary) - contains:

      + with_docname: run plot extraction only on files matching this
                    docname only. If the value starts with "file:", read
                    the docname value from the specified file.

      + with_doctype: run plot extraction only on files matching this
                    doctype only. If the value starts with "file:", read
                    the doctype value from the specified file.

      + with_docformat: run plot extraction only on files matching this
                      format only. If the value starts with "file:", read
                      the doctype value from the specified file.

      + extract_plots_switch_file: run plot extraction only if the filename
                                  exists in curdir. Typically one would set
                                  'files' to extract plots only if some files
                                  have been uploaded.

    If none of the with_* parameters is provided, the current plot
    extractor behaviour will not lead to extracting the plots from all
    the files, but will fall back on 'arXiv' source extraction (see
    plotextractor for details).

    """
    global sysno

    extract_plots_switch_file = parameters["extract_plots_switch_file"]
    if extract_plots_switch_file and \
           not os.path.exists(os.path.join(curdir, extract_plots_switch_file)):
        return ""

    if sysno:
        cmd = os.path.join(
            CFG_BINDIR,
            'plotextractor') + ' -u --upload-mode=correct -r %s --yes-i-know'
        arguments = [
            str(sysno),
        ]

        if parameters["with_docname"]:
            with_docname = parameters["with_docname"]
            if with_docname.startswith('file:'):
                with_docname = ParamFromFile(
                    os.path.join(curdir, with_docname[5:]))
            cmd += ' --with-docname=%s'
            arguments.append(with_docname)

        if parameters["with_doctype"]:
            with_doctype = parameters["with_doctype"]
            if with_doctype.startswith('file:'):
                with_doctype = ParamFromFile(
                    os.path.join(curdir, with_doctype[5:]))
            cmd += ' --with-doctype=%s'
            arguments.append(with_doctype)

        if parameters["with_docformat"]:
            with_docformat = parameters["with_docformat"]
            if with_docformat.startswith('file:'):
                with_docformat = ParamFromFile(
                    os.path.join(curdir, with_docformat[5:]))
            cmd += ' --with-docformat=%s'
            arguments.append(with_docformat)

        cmd += ' &'
        run_shell_command(cmd, args=arguments)

    return ""
def Set_RN_From_Sysno(parameters, curdir, form, user_info=None):
    """
    Set the global variable 'rn' to the report number of the record
    identified by 'sysno' (recid) global variable.

    Useful at MBI step when the user specifies the record to modify
    using the recid instead of the report number.  Since most
    WebSubmit functions relies on the global 'rn' variable, it is
    necessary in these cases to include this function.

    This function MUST be preceded by 'Get_Recid' function.

    To identify the record to update via 'recid' instead of report
    number, one MUST on the MBI form request the recid/sysno using a
    form element named 'SN'.

    Parameters:

         edsrn - file where to write the report number if found

      rep_tags - comma-separater list of tags where the report number
                 can be found. Default is '037__a', '088__a', '021__a'
                 if no value is specified.

  record_search_pattern - this enforces restrictions on which type of
                 documents can be modified via a certain submission
                 interface. If the record_search_pattern is not
                 defined, no restriction will be enforced.  The
                 record_search_pattern can be anything that can be
                 used by search_pattern to search for. Also, one can
                 use variables stored locally, like
                 &lt;comboDEMOJRN&gt; to denote the category or
                 subcategory.
                 Ex:
                    reportnumber:DEMO-&lt;comboDEMOJRN&gt;-*
                    collection:ATLANTISTIMESNEWS
                    reportnumber:DEMO-&lt;comboDEMOJRN&gt;-* | collection:ATLANTISTIMESNEWS

                 As a note, you can test your pattern, using the
                 search engine and see if it retrieves the expected
                 results.

                 WARNING: this check is not applied if the report
                 number has already been written to 'edsrn' file.

    Exceptions raised:
        + InvenioWebSubmitFunctionStop
              - if trying to access unauthorized path to read/write report number;
              - if accessing a recid that does not exist or is deleted;
              - if recid should not be handled by the current submission;
    """
    global rn, sysno
    if not sysno:
        return

    try:
        sysno = int(sysno)
    except:
        raise InvenioWebSubmitFunctionStop(CFG_ALERT_RECORD_ID_MUST_BE_INT % \
                                           cgi.escape((sysno)))

    edsrn = parameters['edsrn']
    path_to_repnum_file = os.path.join(curdir, edsrn)

    if not os.path.abspath(path_to_repnum_file).startswith(curdir):
        # Trying to access invalid path...
        raise InvenioWebSubmitFunctionStop(CFG_ALERT_INVALID_EDSRN_PATH % \
                                           (cgi.escape(path_to_repnum_file),
                                            cgi.escape(CFG_SITE_SUPPORT_EMAIL)))

    if os.path.exists(path_to_repnum_file):
        # Have we already written RN to disk? If so, read from there
        possible_rn = ParamFromFile(path_to_repnum_file)
        if possible_rn.strip():
            # No empty
            rn = possible_rn
            return

    if record_exists(sysno) != 1:
        # Record does not exist
        raise InvenioWebSubmitFunctionStop(CFG_ALERT_DOCUMENT_NOT_FOUND %
                                           sysno)

    ## Check if the record needs to comply to any restriction.
    ## Basically checks if this record can/should be handled by this submission
    if parameters['record_search_pattern']:
        if not is_record_matching_pattern(parameters['record_search_pattern'],
                                          sysno, curdir):
            # delete the SN file and reset the sysno,
            # because this record is not the good record to be hadled by this submission
            os.rename("%s/SN" % curdir, "%s/SN_WRONG" % curdir)
            sysno = ""
            raise InvenioWebSubmitFunctionStop(
                CFG_ALERT_WRONG_RECORD_FOR_THIS_SUBMISSION)

    rn_tags = [tag.strip() for tag in parameters['rep_tags'].split(',') \
               if tag.strip()]
    if not rn_tags:
        rn_tags = CFG_DEFAULT_RN_TAGS

    # Retrieve report number in metadata
    for rn_tag in rn_tags:
        possible_report_numbers = get_fieldvalues(sysno, rn_tag)
        if possible_report_numbers:
            rn = possible_report_numbers[0].strip()
            break

    edsrn = parameters['edsrn']
    path_to_repnum_file = os.path.join(curdir, edsrn)

    if rn and not os.path.exists(path_to_repnum_file):
        # Write report number to specified file
        fp = open(path_to_repnum_file, 'w')
        fp.write(rn)
        fp.close()
def Withdraw_Approval_Request(parameters, curdir, form, user_info=None):
    """
    This function is used in a "withdraw approval request" submission
    in order to register the withdral of the request in the WebSubmit
    "Approvals" DB (sbmAPPROVAL).
    At the time of the approval request withdrawal, the document could be
    in one of several different approval "states" and depending upon that
    state, the action taken by this function differs. The states are as
    follows:
          * Approval of the document has previously been requested and it is
            still in the "waiting" state.
             -> In this case, the status of the document in the sbmAPPROVAL
                table is set to "withdrawn".
          * Approval for the document has never been requested.
             -> In this case, there is nothing to do.
          * Approval of the document has previously been requested, but the
            document was rejected.
             -> In this case, it's too late to withdraw the approval request
                and there is nothing left to do.
          * Approval of the document has previously been requested and it has
            been approved.
             -> In this case, it's too late to withdraw the approval request
                and there is nothing left to do.
          * Approval of the document has previously been requested, but the
            request withdrawn.
             -> In this case, there is nothing to do.

    @param categ_file_withd: (string) - some document types are
           separated into different categories, each of which has its own
           referee(s).
           In such document types, it's necessary to know the document-
           type's category in order to choose the referee.
           This parameter provides a means by which the category information
           can be extracted from a file in the current submission's working
           directory. It should therefore be a filename.

    @param categ_rnseek_withd: (string) - some document types are
           separated into different categories, each of which has its own
           referee(s).
           In such document types, it's necessary to know the document-
           type's category in order to choose the referee.
           This parameter provides a means by which the category information
           can be extracted from the document's reference number.
           It is infact a string that will be compiled into a regexp and
           an attempt will be made to match it agains the document's reference
           number starting from the left-most position.
           The only pre-requisite is that the segment in which the category is
           sought should be indicated with <CATEGORY>.
           Thus, an example might be as follows:
              ATL(-COM)?-<CATEGORY>-.+
           This would allow "PHYS" in the following reference number to be
           recognised as the category:
              ATL-COM-PHYS-2008-001

    @return: (string) - a message for the user.

    @Exceptions raised: + InvenioWebSubmitFunctionStop when the submission
                          should be halted.
                        + InvenioWebSubmitFunctionError when an unexpected
                          error has been encountered and execution cannot
                          continue.
    """
    ## Get the reference number (as global rn - sorry!) and the document type:
    global rn
    doctype = form['doctype']

    ## A string variable to contain any information that should be displayed
    ## in the user's browser:
    info_out = ""

    ########
    ## Get the parameters from the list:

    ########
    ## Get the name of the category file:
    #######
    try:
        ## If it has been provided, get the name of the file in which the
        ## category is stored:
        category_file = parameters["categ_file_withd"]
    except KeyError:
        ## No value given for the category file:
        category_file = None
    else:
        if category_file is not None:
            category_file = str(category_file)
            category_file = os.path.basename(category_file).strip()
            if category_file == "":
                category_file = None
    ########
    ## Get the regexp that is used to find the category in the report number:
    ########
    try:
        ## If it has been provided, get the regexp used for identifying
        ## a document-type's category from its reference number:
        category_rn_regexp = parameters["categ_rnseek_withd"]
    except KeyError:
        ## No value given for the category regexp:
        category_rn_regexp = None
    else:
        if category_rn_regexp is not None:
            category_rn_regexp = str(category_rn_regexp).strip()
        if category_rn_regexp == "":
            category_rn_regexp = None

    #######
    ## Resolve the document type's category:
    ##
    ## This is a long process. The end result is that the category is extracted
    ## either from a file in curdir, or from the report number.
    ## If it's taken from the report number, the admin must configure the
    ## function to accept a regular expression that is used to find the
    ## category in the report number.
    ##
    if category_file is not None and category_rn_regexp is not None:
        ## It is not valid to have both a category file and a pattern
        ## describing how to extract the category from a report number.
        ## raise an InvenioWebSubmitFunctionError
        msg = "Error in Withdraw_Approval_Request function: received " \
              "instructions to search for the document's category in " \
              "both its report number AND in a category file. Could " \
              "not determine which to use - please notify " \
              "%(suppt-email)s." \
              % { 'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
        raise InvenioWebSubmitFunctionError(msg)
    elif category_file is not None:
        ## Attempt to recover the category information from a file in the
        ## current submission's working directory:
        category = ParamFromFile("%s/%s" % (curdir, category_file))
        if category is not None:
            category = category.strip()
        if category in (None, ""):
            ## The category cannot be resolved.
            msg = "Error in Withdraw_Approval_Request function: received " \
                  "instructions to search for the document's category in " \
                  "a category file, but could not recover the category " \
                  "from that file. The approval request therefore cannot " \
                  "be withdrawn for the document. Please report this " \
                  "problem to %(suppt-email)s." \
                  % { 'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
            raise InvenioWebSubmitFunctionError(msg)
    elif category_rn_regexp is not None:
        ## Attempt to recover the category information from the document's
        ## reference number using the regexp in category_rn_regexp:
        ##
        ## Does the category regexp contain the key-phrase "<CATEG>"?
        if category_rn_regexp.find("<CATEG>") != -1:
            ## Yes. Replace "<CATEG>" with "(?P<category>.+?)".
            ## For example, this:
            ##    ATL(-COM)?-<CATEG>-
            ## Will be transformed into this:
            ##    ATL(-COM)?-(?P<category>.+?)-
            category_rn_final_regexp = \
                category_rn_regexp.replace("<CATEG>", r"(?P<category>.+?)", 1)
        else:
            ## The regexp for category didn't contain "<CATEG>", but this is
            ## mandatory.
            msg = "Error in Withdraw_Approval_Request function: The " \
                  "[%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number, " \
                  "using a poorly formed search expression (no marker for " \
                  "the category was present.) Since the document's category " \
                  "therefore cannot be retrieved, its approval request " \
                  "cannot be withdrawn. Please report this problem to " \
                  "%(suppt-email)s." \
                  % { 'doctype'     : cgi.escape(doctype),
                      'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
            raise InvenioWebSubmitFunctionError(msg)
        ##
        try:
            ## Attempt to compile the regexp for finding the category:
            re_categ_from_rn = re.compile(category_rn_final_regexp)
        except sre_constants.error:
            ## The expression passed to this function could not be compiled
            ## into a regexp. Register this exception and raise an
            ## InvenioWebSubmitFunctionError:
            exception_prefix = "Error in Withdraw_Approval_Request function: " \
                               "The [%(doctype)s] submission has been " \
                               "configured to search for the document type's " \
                               "category in its reference number, using the " \
                               "following regexp: /%(regexp)s/. This regexp, " \
                               "however, could not be compiled correctly " \
                               "(created it from %(categ-search-term)s.)" \
                               % { 'doctype'       : doctype, \
                                   'regexp'        : category_rn_final_regexp, \
                                   'categ-search-term' : category_rn_regexp, }
            register_exception(prefix=exception_prefix)
            msg = "Error in Withdraw_Approval_Request function: The " \
                  "[%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number, " \
                  "using a poorly formed search expression. Since the " \
                  "document's category therefore cannot be retrieved, its " \
                  "approval request cannot be withdrawn. Please " \
                  "report this problem to %(suppt-email)s." \
                  % { 'doctype'     : cgi.escape(doctype),
                      'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
            raise InvenioWebSubmitFunctionError(msg)
        else:
            ## Now attempt to recover the category from the RN string:
            m_categ_from_rn = re_categ_from_rn.match(rn)
            if m_categ_from_rn is not None:
                ## The pattern matched in the string.
                ## Extract the category from the match:
                try:
                    category = m_categ_from_rn.group("category")
                except IndexError:
                    ## There was no "category" group. That group is mandatory.
                    exception_prefix = \
                       "Error in Withdraw_Approval_Request function: The " \
                       "[%(doctype)s] submission has been configured to " \
                       "search for the document type's category in its " \
                       "reference number using the following regexp: " \
                       "/%(regexp)s/. The search produced a match, but " \
                       "there was no \"category\" group in the match " \
                       "object although this group is mandatory. The " \
                       "regexp was compiled from the following string: " \
                       "[%(categ-search-term)s]." \
                       % { 'doctype'           : doctype, \
                           'regexp'            : category_rn_final_regexp, \
                           'categ-search-term' : category_rn_regexp, }
                    register_exception(prefix=exception_prefix)
                    msg = "Error in Withdraw_Approval_Request function: The " \
                          "[%(doctype)s] submission has been configured to " \
                          "search for the document type's category in its " \
                          "reference number, using a poorly formed search " \
                          "expression (there was no category marker). Since " \
                          "the document's category therefore cannot be " \
                          "retrieved, its approval request cannot be " \
                          "withdrawn. Please report this problem to " \
                          "%(suppt-email)s." \
                          % { 'doctype'     : cgi.escape(doctype),
                              'suppt-email' : \
                                  cgi.escape(CFG_SITE_SUPPORT_EMAIL),}
                    raise InvenioWebSubmitFunctionError(msg)
                else:
                    category = category.strip()
                    if category == "":
                        msg = "Error in Withdraw_Approval_Request function: " \
                              "The [%(doctype)s] submission has been " \
                              "configured to search for the document type's " \
                              "category in its reference number, but no " \
                              "category was found. The request for approval " \
                              "cannot be withdrawn. Please report this " \
                              "problem to %(suppt-email)s." \
                              % { 'doctype'     : cgi.escape(doctype),
                                  'suppt-email' : \
                                     cgi.escape(CFG_SITE_SUPPORT_EMAIL),}
                        raise InvenioWebSubmitFunctionError(msg)
            else:
                ## No match. Cannot find the category and therefore cannot
                ## continue:
                msg = "Error in Withdraw_Approval_Request function: The " \
                      "[%(doctype)s] submission has been configured to " \
                      "search for the document type's category in its " \
                      "reference number, but no match was made. The request " \
                      "for approval cannot be withdrawn. Please report " \
                      "this problem to %(suppt-email)s." \
                      % { 'doctype'     : cgi.escape(doctype),
                          'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL),}
                raise InvenioWebSubmitFunctionError(msg)
    else:
        ## The document type has no category.
        category = ""
    ##
    ## End of category recovery
    #######

    #######
    ##
    ## Query the "approvals" DB table to determine whether approval of this
    ## document has already been requested:
    approval_status = get_simple_approval_status(doctype, rn)
    if approval_status is None:
        ## Approval has never been requested for this document.
        ## One cannot withdraw an approval request that was never made.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> A request for the approval of the
 document [%s] has never been made.<br />
There is nothing to do.
</div>
""" % cgi.escape(rn)
        raise InvenioWebSubmitFunctionStop(msg)
    elif approval_status.lower() == "approved":
        ## This document has already been approved. It's too late to withdraw
        ## the approval request.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> The document [%s] has already been
 approved.<br />
It is too late to withdraw the approval request.<br />
If you believe this to be an error, please contact %s, quoting the<br />
document's report-number [%s] and describing the problem.
</div>
""" % (cgi.escape(rn), cgi.escape(CFG_SITE_SUPPORT_EMAIL), cgi.escape(rn))
        raise InvenioWebSubmitFunctionStop(msg)
    elif approval_status.lower() == "rejected":
        ## This document has already been rejected. It's too late to withdraw
        ## the approval request.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> The document [%s] has already been
 rejected.<br />
It is too late to withdraw the approval request.<br />
If you believe this to be an error, please contact %s, quoting the<br />
document's report-number [%s] and describing the problem.
</div>
""" % (cgi.escape(rn), cgi.escape(CFG_SITE_SUPPORT_EMAIL), cgi.escape(rn))
        raise InvenioWebSubmitFunctionStop(msg)
    elif approval_status.lower() == "withdrawn":
        ## The approval request for this document has already been withdrawn.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> The approval request for the document
 [%s] has already been withdrawn.<br />
There is nothing to do.
</div>
""" % cgi.escape(rn)
        raise InvenioWebSubmitFunctionStop(msg)
    elif approval_status.lower() == "waiting":
        ## Mark the approval request as withdrawn:
        note = "Withdrawn by [%s]: %s\n#####\n" \
               % (cgi.escape(user_info['email']), \
                  cgi.escape(time.strftime("%d/%m/%Y %H:%M:%S", \
                                           time.localtime())))
        update_approval_request_status(doctype, \
                                       rn, \
                                       note=note, \
                                       status="withdrawn")
        info_out += """
<br />
<div>
The approval request for the document [%s] has been withdrawn.
</div>
""" % cgi.escape(rn)
    else:
        ## The document had an unrecognised "status". Raise an error.
        msg = "Error in Withdraw_Approval_Request function: The " \
              "[%(reportnum)s] document has an unknown approval status " \
              "(%(status)s). Unable to withdraw the request for its " \
              "approval. Please report this problem to the %(suppt-email)s." \
              % { 'reportnum'   : cgi.escape(rn),
                  'status'      : cgi.escape(approval_status),
                  'suppt-email' : cgi.escape(CFG_SITE_SUPPORT_EMAIL), }
        raise InvenioWebSubmitFunctionError(msg)
    ##
    ## Finished - return any message to be displayed on the user's screen.
    return info_out
Example #9
0
def Set_RN_From_Sysno(parameters, curdir, form, user_info=None):
    """
    Set the global variable 'rn' to the report number of the record
    identified by 'sysno' (recid) global variable.

    Useful at MBI step when the user specifies the record to modify
    using the recid instead of the report number.  Since most
    WebSubmit functions relies on the global 'rn' variable, it is
    necessary in these cases to include this function.

    This function MUST be preceded by 'Get_Recid' function.

    To identify the record to update via 'recid' instead of report
    number, one MUST on the MBI form request the recid/sysno using a
    form element named 'SN'.

    Parameters:

         edsrn - file where to write the report number if found

      rep_tags - comma-separater list of tags where the report number
                 can be found. Default is '037__a', '088__a', '021__a'
                 if no value is specified.

  record_search_pattern - this enforces restrictions on which type of
                 documents can be modified via a certain submission
                 interface. If the record_search_pattern is not
                 defined, no restriction will be enforced.  The
                 record_search_pattern can be anything that can be
                 used by search_pattern to search for. Also, one can
                 use variables stored locally, like
                 &lt;comboDEMOJRN&gt; to denote the category or
                 subcategory.
                 Ex:
                    reportnumber:DEMO-&lt;comboDEMOJRN&gt;-*
                    collection:ATLANTISTIMESNEWS
                    reportnumber:DEMO-&lt;comboDEMOJRN&gt;-* | collection:ATLANTISTIMESNEWS

                 As a note, you can test your pattern, using the
                 search engine and see if it retrieves the expected
                 results.

                 WARNING: this check is not applied if the report
                 number has already been written to 'edsrn' file.

    Exceptions raised:
        + InvenioWebSubmitFunctionStop
              - if trying to access unauthorized path to read/write report number;
              - if accessing a recid that does not exist or is deleted;
              - if recid should not be handled by the current submission;
    """
    global rn, sysno
    if not sysno:
        return

    try:
        sysno = int(sysno)
    except:
        raise InvenioWebSubmitFunctionStop(CFG_ALERT_RECORD_ID_MUST_BE_INT % \
                                           cgi.escape((sysno)))

    edsrn = parameters['edsrn']
    path_to_repnum_file = os.path.join(curdir, edsrn)

    if not os.path.abspath(path_to_repnum_file).startswith(curdir):
        # Trying to access invalid path...
        raise InvenioWebSubmitFunctionStop(CFG_ALERT_INVALID_EDSRN_PATH % \
                                           (cgi.escape(path_to_repnum_file),
                                            cgi.escape(CFG_SITE_SUPPORT_EMAIL)))

    if os.path.exists(path_to_repnum_file):
        # Have we already written RN to disk? If so, read from there
        possible_rn = ParamFromFile(path_to_repnum_file)
        if possible_rn.strip():
            # No empty
            rn = possible_rn
            return

    if record_exists(sysno) != 1:
        # Record does not exist
        raise InvenioWebSubmitFunctionStop(CFG_ALERT_DOCUMENT_NOT_FOUND % sysno)

    ## Check if the record needs to comply to any restriction.
    ## Basically checks if this record can/should be handled by this submission
    if parameters['record_search_pattern']:
        if not is_record_matching_pattern(parameters['record_search_pattern'], sysno, curdir):
            # delete the SN file and reset the sysno,
            # because this record is not the good record to be hadled by this submission
            os.rename("%s/SN" % curdir, "%s/SN_WRONG" % curdir)
            sysno = ""
            raise InvenioWebSubmitFunctionStop(CFG_ALERT_WRONG_RECORD_FOR_THIS_SUBMISSION)

    rn_tags = [tag.strip() for tag in parameters['rep_tags'].split(',') \
               if tag.strip()]
    if not rn_tags:
        rn_tags  = CFG_DEFAULT_RN_TAGS

    # Retrieve report number in metadata
    for rn_tag in rn_tags:
        possible_report_numbers = get_fieldvalues(sysno, rn_tag)
        if possible_report_numbers:
            rn = possible_report_numbers[0].strip()
            break

    edsrn = parameters['edsrn']
    path_to_repnum_file = os.path.join(curdir, edsrn)

    if rn and not os.path.exists(path_to_repnum_file):
        # Write report number to specified file
        fp = open(path_to_repnum_file, 'w')
        fp.write(rn)
        fp.close()
def Register_Referee_Decision(parameters, curdir, form, user_info=None):
    """
    A referee may either "accept" or "reject" a refereed document.
    The referee's decision is stored in a file in the submission's working
    directory and it is this function's job to read the contents of that
    file and update the status of the document's entry in the approvals
    table (sbmAPPROVAL) to be either "accepted" or "rejected" depending
    upon the referee's decision.

    @param decision_file: (string) - the name of the file in which the
        referee's decision is to be found.
        NOTE: A referee's decision _MUST_ be either "accept" or "reject".
              If not, an InvenioWebSubmitFunctionError will be raised.
              If a document's "approval status" is not "waiting" at the
              time of the referee's decision, the decision will not be
              taken into account and the submission will be halted.
              (This is because it's not appropriate to approve a document
              that has already been approved or rejected, has been
              withdrawn, etc.)

    @return: empty string.

    @Exceptions raised: InvenioWebSubmitFunctionError on unexpected error.
                        InvenioWebSubmitFunctionStop in the case where the
                        approval should be stopped for whatever reason.
                        (E.g. when it has already been approved.)
    """
    global rn
    doctype = form['doctype']
    ########
    ## Get the parameters from the list:
    ########
    ## Get the name of the "decision" file and read its value:
    ########
    decision = ""  ## variable to hold the referee's decision
    try:
        decision_file = parameters["decision_file"]
    except KeyError:
        ## No value given for the decision file:
        decision_file = None
    else:
        if decision_file is not None:
            decision_file = os.path.basename(decision_file).strip()
            if decision_file == "":
                decision_file = None
    if decision_file is None:
        ## Unable to obtain the name of the file in which the referee's
        ## decision is stored. Halt.
        err_msg = "Error in Register_Referee_Decision: Function was not " \
                  "configured with a valid value for decision_file - the " \
                  "file in which the referee's decision is stored. " \
                  "The referee's decision has not been processed for " \
                  "[%s]. Please inform the administrator." \
                  % rn
        raise InvenioWebSubmitFunctionError(err_msg)
    ## Read in the referee's decision:
    decision = ParamFromFile("%s/%s" % (curdir, decision_file)).lower()
    ##
    ########
    if decision not in ("approve", "reject"):
        ## Invalid value for the referee's decision.
        err_msg = "Error in Register_Referee_Decision: The value for the " \
                  "referee's decision (%s) was invalid. Please inform the " \
                  "administrator." % decision
        raise InvenioWebSubmitFunctionError(err_msg)
    ##
    ## Get the status of the approval request for this document from the DB:
    document_status = get_simple_approval_status(doctype, rn)
    if document_status is None:
        ## No information about this document in the approval database.
        ## Its approval has never been requested.
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> No details about an approval request
 for the document [%s] have been found in the database.<br />
Before a decision can be made about it, a request for its approval must have
 been submitted.<br />
If you feel that there is a problem, please contact &lt;%s&gt;, quoting the
document's report number.
</div>""" % (cgi.escape(rn), cgi.escape(CFG_SITE_SUPPORT_EMAIL))
        raise InvenioWebSubmitFunctionStop(msg)
    elif document_status in ("approved", "rejected"):
        ## If a document was already approved or rejected, halt the approval
        ## process with a message for the referee:
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> The document [%s] has
 already been %s.<br />
There is nothing more to be done in this case and your decision
 has <b>NOT</b> been taken into account.<br />
If you believe this to be an error, please contact &lt;%s&gt;, quoting the<br />
document's report-number [%s] and describing the problem.
</div>""" % (cgi.escape(rn), \
             cgi.escape(document_status), \
             cgi.escape(CFG_SITE_SUPPORT_EMAIL), \
             cgi.escape(rn))
        raise InvenioWebSubmitFunctionStop(msg)
    elif document_status == "withdrawn":
        ## Somebody had withdrawn the approval request for this document
        ## before the referee made this decision. Halt the approval process
        ## with a message for the referee:
        msg = """
<br />
<div>
<span style="color: red;">Note:</span> The request for the approval of the
 document [%s] had been withdrawn prior to the submission of your
 decision.<br />
Before a decision can be made regarding its status, a new request for its
 approval must be submitted by the author.<br />
Your decision has therefore <b>NOT</b> been taken into account.<br />
If you believe this to be an error, please contact &lt;%s&gt;, quoting the
 document's report-number [%s] and describing the problem.
</div>
""" % (cgi.escape(rn), \
       cgi.escape(CFG_SITE_SUPPORT_EMAIL), \
       cgi.escape(rn))
        raise InvenioWebSubmitFunctionStop(msg)
    elif document_status == "waiting":
        ## The document is awaiting approval. Register the referee's decision:
        if decision == "approve":
            ## Register the approval:
            update_approval_request_status(doctype, \
                                           rn, \
                                           note="",
                                           status="approved")
        else:
            ## Register the rejection:
            update_approval_request_status(doctype, \
                                           rn, \
                                           note="",
                                           status="rejected")
        ## Now retrieve the status of the document once more and check that
        ## it is either approved or rejected.  If not, the decision couldn't
        ## be registered and an error should be raised.
        status_after_update = get_simple_approval_status(doctype, rn)
        if status_after_update not in ("approved", "rejected"):
            msg = "Error in Register_Referee_Decision function: It was " \
                  "not possible to update the approvals database when " \
                  "trying to register the referee's descision of [%s] " \
                  "for the document [%s]. Please report this this " \
                  "problem to [%s], quoting the document's " \
                  "report-number [%s]." \
                  % (decision, rn, CFG_SITE_SUPPORT_EMAIL, rn)
            raise InvenioWebSubmitFunctionError(msg)
    else:
        ## The document had an unrecognised "status". Halt with an error.
        msg = "Error in Register_Referee_Decision function: The " \
              "document [%s] has an unknown approval status " \
              "[%s]. Unable to process the referee's decision. Please " \
              "report this problem to [%s], quoting the document's " \
              "report-number [%s] and describing the problem." \
              % (rn, document_status, CFG_SITE_SUPPORT_EMAIL, rn)
        raise InvenioWebSubmitFunctionError(msg)
    ## Finished.
    return ""
Example #11
0
def Mail_Approval_Withdrawn_to_Referee(parameters, \
                                       curdir, \
                                       form, \
                                       user_info=None):
    """
    This function sends an email to the referee of a document informing
    him/her that the request for its approval has been withdrawn.

    @param categ_file_withd: (string) - some document types are
           separated into different categories, each of which has its own
           referee(s).
           In such document types, it's necessary to know the document-
           type's category in order to choose the referee.
           This parameter provides a means by which the category information
           can be extracted from a file in the current submission's working
           directory. It should therefore be a filename.

    @param categ_rnseek_withd: (string) - some document types are
           separated into different categories, each of which has its own
           referee(s).
           In such document types, it's necessary to know the document-
           type's category in order to choose the referee.
           This parameter provides a means by which the category information
           can be extracted from the document's reference number.
           It is infact a string that will be compiled into a regexp and
           an attempt will be made to match it agains the document's reference
           number starting from the left-most position.
           The only pre-requisite is that the segment in which the category is
           sought should be indicated with <CATEGORY>.
           Thus, an example might be as follows:
              ATL(-COM)?-<CATEGORY>-.+
           This would allow "PHYS" in the following reference number to be
           recognised as the category:
              ATL-COM-PHYS-2008-001

    @return: (string) - empty string.
    """
    ## Get the reference number (as global rn - sorry!) and the document type:
    global sysno, rn
    doctype = form['doctype']

    ########
    ## Get the parameters from the list:

    ########
    ## Get the name of the category file:
    #######
    try:
        ## If it has been provided, get the name of the file in which the
        ## category is stored:
        category_file = parameters["categ_file_withd"]
    except KeyError:
        ## No value given for the category file:
        category_file = None
    else:
        if category_file is not None:
            category_file = str(category_file)
            category_file = os.path.basename(category_file).strip()
            if category_file == "":
                category_file = None
    ########
    ## Get the regexp that is used to find the category in the report number:
    ########
    try:
        ## If it has been provided, get the regexp used for identifying
        ## a document-type's category from its reference number:
        category_rn_regexp = parameters["categ_rnseek_withd"]
    except KeyError:
        ## No value given for the category regexp:
        category_rn_regexp = None
    else:
        if category_rn_regexp is not None:
            category_rn_regexp = str(category_rn_regexp).strip()
        if category_rn_regexp == "":
            category_rn_regexp = None
    #######
    ## Resolve the document type's category:
    ##
    ## This is a long process. The end result is that the category is extracted
    ## either from a file in curdir, or from the report number.
    ## If it's taken from the report number, the admin must configure the
    ## function to accept a regular expression that is used to find the
    ## category in the report number.
    ##
    if category_file is not None and category_rn_regexp is not None:
        ## It is not valid to have both a category file and a pattern
        ## describing how to extract the category from a report number.
        ## raise an InvenioWebSubmitFunctionWarning:
        msg = "Error in Mail_Approval_Withdrawn_to_Referee function: " \
              "received instructions to search for the document's category " \
              "in both its report number AND in a category file. Could " \
              "not determine which to use - please notify the " \
              "administrator."
        raise InvenioWebSubmitFunctionWarning(msg)
    elif category_file is not None:
        ## Attempt to recover the category information from a file in the
        ## current submission's working directory:
        category = ParamFromFile("%s/%s" % (curdir, category_file))
        if category is not None:
            category = category.strip()
        if category in (None, ""):
            ## The category cannot be resolved.
            msg = "Error in Mail_Approval_Withdrawn_to_Referee function: " \
                  "received instructions to search for the document's " \
                  "category in a category file, but could not recover the " \
                  "category from that file. The referee cannot be notified " \
                  "of the approval request withdrawal by mail."
            raise InvenioWebSubmitFunctionWarning(msg)
    elif category_rn_regexp is not None:
        ## Attempt to recover the category information from the document's
        ## reference number using the regexp in category_rn_regexp:
        ##
        ## Does the category regexp contain the key-phrase "<CATEG>"?
        if category_rn_regexp.find("<CATEG>") != -1:
            ## Yes. Replace "<CATEG>" with "(?P<category>.+?)".
            ## For example, this:
            ##    ATL(-COM)?-<CATEG>-
            ## Will be transformed into this:
            ##    ATL(-COM)?-(?P<category>.+?)-
            category_rn_final_regexp = \
                category_rn_regexp.replace("<CATEG>", r"(?P<category>.+?)", 1)
        else:
            ## The regexp for category didn't contain "<CATEG>", but this is
            ## mandatory.
            msg = "Error in Mail_Approval_Withdrawn_to_Referee function: The" \
                  " [%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number," \
                  " using a poorly formed search expression (no marker for " \
                  "the category was present.) Since the document's category " \
                  "cannot be retrieved, the referee cannot be " \
                  "notified of the approval request withdrawal by mail." \
                  % { 'doctype' : doctype, }
            raise InvenioWebSubmitFunctionWarning(msg)
        ##
        try:
            ## Attempt to compile the regexp for finding the category:
            re_categ_from_rn = re.compile(category_rn_final_regexp)
        except sre_constants.error:
            ## The expression passed to this function could not be compiled
            ## into a regexp. Register this exception and raise an
            ## InvenioWebSubmitFunctionWarning:
            exception_prefix = "Error in Mail_Approval_Withdrawn_to_Referee " \
                               "function: The [%(doctype)s] submission has " \
                               "been configured to search for the document " \
                               "type's category in its reference number, " \
                               "using the following regexp: /%(regexp)s/. " \
                               "This regexp, however, could not be " \
                               "compiled correctly (created it from " \
                               "%(categ-search-term)s.)" \
                               % { 'doctype'      : doctype, \
                                   'regexp'       : category_rn_final_regexp, \
                                   'categ-search-term' : category_rn_regexp, }
            register_exception(prefix=exception_prefix)
            msg = "Error in Mail_Approval_Withdrawn_to_Referee function: The" \
                  " [%(doctype)s] submission has been configured to search " \
                  "for the document type's category in its reference number," \
                  " using a poorly formed search expression. Since the " \
                  "document's category cannot be retrieved, the referee" \
                  "cannot be notified of the approval request withdrawal by " \
                  "mail." \
                  % { 'doctype' : doctype, }
            raise InvenioWebSubmitFunctionWarning(msg)
        else:
            ## Now attempt to recover the category from the RN string:
            m_categ_from_rn = re_categ_from_rn.match(rn)
            if m_categ_from_rn is not None:
                ## The pattern matched in the string.
                ## Extract the category from the match:
                try:
                    category = m_categ_from_rn.group("category")
                except IndexError:
                    ## There was no "category" group. That group is mandatory.
                    exception_prefix = \
                       "Error in Mail_Approval_Withdrawn_to_Referee " \
                       "function: The [%(doctype)s] submission has been " \
                       "configured to search for the document type's " \
                       "category in its reference number using the " \
                       "following regexp: " \
                       "/%(regexp)s/. The search produced a match, but " \
                       "there was no \"category\" group in the match " \
                       "object although this group is mandatory. The " \
                       "regexp was compiled from the following string: " \
                       "[%(categ-search-term)s]." \
                       % { 'doctype'           : doctype, \
                           'regexp'            : category_rn_final_regexp, \
                           'categ-search-term' : category_rn_regexp, }
                    register_exception(prefix=exception_prefix)
                    msg = "Error in Mail_Approval_Withdrawn_to_Referee " \
                          "function: The [%(doctype)s] submission has been " \
                          "configured to search for the document type's " \
                          "category in its reference number, using a poorly " \
                          "formed search expression (there was no category " \
                          "marker). Since the document's category therefore " \
                          "cannot be retrieved, the referee cannot be " \
                          "notified of the approval request withdrawal " \
                          "by mail." \
                          % { 'doctype' : doctype, }
                    raise InvenioWebSubmitFunctionWarning(msg)
                else:
                    category = category.strip()
                    if category == "":
                        msg = "Error in Mail_Approval_Withdrawn_to_Referee " \
                              "function: The [%(doctype)s] submission has " \
                              "been configured to search for the document " \
                              "type's category in its reference number, but " \
                              "no category was found. The referee cannot be " \
                              "notified of the approval request withdrawal " \
                              "by mail." \
                              % { 'doctype' : doctype, }
                        raise InvenioWebSubmitFunctionWarning(msg)
            else:
                ## No match. Cannot find the category and therefore cannot
                ## continue:
                msg = "Error in Mail_Approval_Withdrawn_to_Referee function:" \
                      " The [%(doctype)s] submission has been configured to " \
                      "search for the document type's category in its " \
                      "reference number, but no match was made. The referee " \
                      "cannot be notified of the approval request " \
                      "withdrawal by mail." \
                      % { 'doctype' : doctype, }
                raise InvenioWebSubmitFunctionWarning(msg)
    else:
        ## The document type has no category.
        category = ""
    ##
    ## End of category recovery
    #######

    ## Get the referee email address:
    if CFG_CERN_SITE:
        ## The referees system in CERN now works with listbox membership.
        ## List names should take the format
        ## "*****@*****.**"
        ## Make sure that your list exists!
        ## FIXME - to be replaced by a mailing alias in webaccess in the
        ## future.
        ## see if was a PROC request or not
        notes = get_approval_request_notes(doctype, rn)
        was_proc = 'n'
        was_slide = 'n'
        if notes:
            note_lines = notes.split('\n')
            for note_line in note_lines:
                if note_line.find('Requested Note Classification:') == 0:
                    note_type = note_line.split()[-1]
                    if note_type == 'PROC':
                        was_proc = 'y'
                    elif note_type == 'SLIDE':
                        was_slide = 'y'
                    break  # there may be more than one - just take the first
        if was_proc == 'y':
            referee_listname = "service-cds-referee-%s" % doctype.lower()
            referee_listname += "-%s" % 'proc'
        elif was_slide == 'y':
            referee_listname = "atlas-speakers-comm"
        else:
            referee_listname = "service-cds-referee-%s" % doctype.lower()
            if category != "":
                referee_listname += "-%s" % category.lower()
        referee_listname += "@cern.ch"
        mailto_addresses = referee_listname
        if category == 'CDSTEST':  ## our special testing category
            referee_listname = "service-cds-referee-%s" % doctype.lower()
            referee_listname += "-%s" % category.lower()
            mailto_addresses = referee_listname + "@cern.ch"
    else:
        referee_address = ""
        ## Try to retrieve the referee's email from the referee's database:
        for user in \
            acc_get_role_users(acc_get_role_id("referee_%s_%s" \
                                               % (doctype, category))):
            referee_address += user[1] + ","
        ## And if there are general referees:
        for user in \
            acc_get_role_users(acc_get_role_id("referee_%s_*" % doctype)):
            referee_address += user[1] + ","
        referee_address = re.sub(",$", "", referee_address)
        # Creation of the mail for the referee
        mailto_addresses = ""
        if referee_address != "":
            mailto_addresses = referee_address + ","
        else:
            mailto_addresses = re.sub(",$", "", mailto_addresses)
    ##
    ## Send the email:
    mail_subj = "Request for approval of [%s] withdrawn" % rn
    mail_body = CFG_MAIL_BODY % \
                { 'site-name'               : CFG_SITE_NAME,
                  'report-number'           : rn,
                }
    send_email(CFG_SITE_SUPPORT_EMAIL,
               mailto_addresses,
               mail_subj,
               mail_body,
               copy_to_admin=CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN)
    ##
    return ""
Example #12
0
def Notify_URL(parameters, curdir, form, user_info=None):
    """
    Access a given URL, and possibly post some content.

    Could be used to notify that a record has been fully integrated.
    (the URL is only accessed once the BibTask created by this
    function runs in BibSched, not the when the function is run. The
    BibTask uses a task sequence ID to respect ordering of tasks)

    if URL is empty, skip the notification.

    @param parameters: (dictionary) - contains the following parameter
         strings used by this function:

         + url: (string) - the URL to be contacted by this function
                           (must start with http/https)
                           If value starts with "FILE:", will look for
                           the URL in a file on curdir with the given name.
                           for eg: "FILE:my_url"
                           (value retrieved when function is run)

         + data: (string) - (optional) the data to be posted at the
                            given URL.  if no value is given, the URL
                            will be accessed via GET.
                            If value starts with "FILE:", will look for
                            the data in a file on curdir with the given name.
                            for eg: "FILE:my_data"
                            (value retrieved when function is run)

         + content_type: (string) - (optional) the content-type to use
                                    to post data. Default is 'text/plain'.
                                    Ignored if not data is posted.

         + attempt_times: (int) - (optional) up to how many time shall
                                  we try to contact the URL in case we
                                  fail at contacting it?

         + attempt_sleeptime: (int) - (optional) how many seconds to
                                       sleep between each attempt?

         + admin_emails: (string) - (optional) list of emails (comma-separated
                                    values) to contact in case the URL
                                    cannot be accessed after all attempts.
                                    If value starts with "FILE:", will look for
                                    the emails in a file on curdir with the given name.
                                    for eg: "FILE:my_email"
                                    (value retrieved when function is run)

         + user: (string) - the user to be used to launch the task
                            (visible in BibSched).  If value starts
                            with"FILE:", will look for the emails in a file on
                            curdir with the given name.
                            for eg:"FILE:my_user"
                            (value retrieved when function is run)

    """

    other_bibtasklet_arguments = []
    sequence_id = bibtask_allocate_sequenceid(curdir)

    url = parameters["url"]
    data = parameters["data"]
    admin_emails = parameters["admin_emails"]
    content_type = parameters["content_type"]
    attempt_times = parameters["attempt_times"]
    attempt_sleeptime = parameters["attempt_sleeptime"]
    user = parameters["user"]

    # Maybe some params must be read from disk
    if url.startswith('FILE:'):
        url = ParamFromFile(os.path.join(curdir, url[5:]))
    if not url:
        return ""
    if data.startswith('FILE:'):
        data = ParamFromFile(os.path.join(curdir, data[5:]))
    if admin_emails.startswith('FILE:'):
        admin_emails = ParamFromFile(os.path.join(curdir, admin_emails[5:]))
    if user.startswith('FILE:'):
        user = ParamFromFile(os.path.join(curdir, user[5:]))

    if data:
        other_bibtasklet_arguments.extend(("-a", "data=%s" % data))
        other_bibtasklet_arguments.extend(
            ("-a", "content_type=%s" % content_type))

    return task_low_level_submission(
        "bibtasklet", user, "-T", "bst_notify_url", "-I", str(sequence_id),
        "-a", "url=%s" % url, "-a", "attempt_times=%s" % attempt_times, "-a",
        "attempt_sleeptime=%s" % attempt_sleeptime, "-a",
        "admin_emails=%s" % admin_emails, *other_bibtasklet_arguments)