Пример #1
0
def main():

    wsOpts = WSOpts()

    parser = wsOpts.get_common_opts()

    parser.add_option("--username", dest="username", help="Username")

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ('username', )):
        parser.print_help()
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options)

    logging.debug("Creating LDAP account " + options.username)
    success = configServiceClient.create_user(options.username,
                                              role=None,
                                              ldap=True)
    successConvert = False
    if not success:
        # assume the user exists as local user and switch to LDAP
        successConvert = configServiceClient.convert_to_ldap_user(
            options.username)
        if not successConvert:
            print "Couldn't create and couldn't convert, sorry!"
            sys.exit(1)
    subject = "Your Coverity account has been created"
    userDO = configServiceClient.get_user(options.username)
    url = "http://coverity.mongodb.com"
    if successConvert:
        subject = "Your Coverity account has been converted to Crowd/Jira"
    text = """
       <html><pre>
          Dear %s,
          \n
          An account has been created for you at MongoDB Coverity Instance.
          Your username is %s, same as your Crowd/Jira username.
          You can go to <a href=%s>%s</a> to securely log in using your Crowd/Jira password.
          \n
          Your Coverity Admin Team
          \n
       </pre></html>
    """
    name = str(options.username)
    body = text % (name, options.username, url, url)
    try:
        configServiceClient.send_notifications(options.username, subject, body)
    except Exception, err:
        print "Error sending user notification", str(err)
        sys.exit(1)
Пример #2
0
def main():

    wsOpts = WSOpts()

    parser = wsOpts.get_common_opts()

    parser.add_option("--username",  dest="username",  help="Username")
    parser.add_option("--first",  dest="first",  help="First name")
    parser.add_option("--last",  dest="last",  help="Last Name")
    parser.add_option("--email", dest="email",  help="Email")
    parser.add_option("--group", dest="group",  help="Existing Group to add user to")

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ('username','email','group')):
        parser.print_help()
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options);

    logging.debug("Creating local account " + options.username)
    success = configServiceClient.create_user(options.username,options.first,options.last,options.email,'Administrators','xxxxxx',role=None, locked=True)
    if not success:
        print "Error!"
        sys.exit(1)
    subject = "Your Coverity account has been created"
    text = """
       <html><pre>
          Dear %s,
          \n
          An account has been created for you at MongoDB Coverity Instance.
          Your username is %s
          You have been added to %s group
          Please go to %s
          and click on "Forgot Password?" link - this will allow you to set your password.
          \n
          Your Coverity Admin Team
          \n
       </pre></html>
    """
    name = str(options.username)
    if options.first:
        name = str(options.first)
    url = configServiceClient.create_url()
    body = text % (name, options.username, options.group, url)
    try:
        configServiceClient.send_notifications(options.username, subject, body)
    except Exception, err:
        print "Error sending user notification", str(err)
        sys.exit(1)
Пример #3
0
def main():

    wsOpts = WSOpts()

    parser = wsOpts.get_common_opts()

    parser.add_option("--username",  dest="username",  help="Username")

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ('username',)):
        parser.print_help()
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options);

    logging.debug("Creating LDAP account " + options.username)
    success = configServiceClient.create_user(options.username,role=None, ldap=True)
    successConvert=False
    if not success:
        # assume the user exists as local user and switch to LDAP
        successConvert=configServiceClient.convert_to_ldap_user(options.username)
        if not successConvert:
           print "Couldn't create and couldn't convert, sorry!"
           sys.exit(1)
    subject = "Your Coverity account has been created"
    userDO = configServiceClient.get_user(options.username)
    url = "http://coverity.mongodb.com"
    if successConvert: subject = "Your Coverity account has been converted to Crowd/Jira"
    text = """
       <html><pre>
          Dear %s,
          \n
          An account has been created for you at MongoDB Coverity Instance.
          Your username is %s, same as your Crowd/Jira username.
          You can go to <a href=%s>%s</a> to securely log in using your Crowd/Jira password.
          \n
          Your Coverity Admin Team
          \n
       </pre></html>
    """
    name = str(options.username)
    body = text % (name, options.username, url, url)
    try:
        configServiceClient.send_notifications(options.username, subject, body)
    except Exception, err:
        print "Error sending user notification", str(err)
        sys.exit(1)
def main():
    """
     create and send notifications to all users who were assigned
     any new defects in the past N days (N=1 or specified)
    """
    wsOpts = WSOpts()
    parser = wsOpts.get_common_opts()

    # use --test flag to avoid sending e-mail while debugging this script
    parser.set_defaults(testing="False")
    parser.add_option("--test",  action="store_true", dest="testing",  default="False", help="Testing flag: no mail just echo to stdout");
    parser.add_option("--days",  dest="days",  type=int, default=1, help="Days to check to notify about (default last 24 hours)");

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ()):
        parser.print_help()
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options)
    defectServiceClient = DefectServiceClient(options)

    # calculate when the action would have to be since to get reported
    cutoff = datetime.datetime.today()-datetime.timedelta(options.days)

    # all assignable users - no disabled users, since they should not be notified
    users = configServiceClient.get_all_users()

    # get the streams for relevant project or get all if none
    streamIdDO = configServiceClient.get_streams(options.project,options.stream)

    mergedDefectDOs = defectServiceClient.get_merged_defects(streamIdDO,users=users)

    email_cid = {}
    totalFetched = mergedDefectDOs.totalNumberOfRecords
    if totalFetched < 1:
        logging.info("No defects")
        sys.exit(totalFetched)
    logging.info("Total fetched "+ repr(totalFetched))
    for md in mergedDefectDOs.mergedDefects:
        defectChangeDataObj = defectServiceClient.get_md_history(md.cid,streamIdDO)
        i = len(defectChangeDataObj)-1
        while i >= 0:
            if defectChangeDataObj[i].dateModified > cutoff and len(set(defectChangeDataObj[i].affectedStreams).difference(set(streamIdDO))) > 0:
                for fieldChangeDO in defectChangeDataObj[i].attributeChanges:
                  if fieldChangeDO != None and fieldChangeDO.fieldName=='Owner': 
                    logging.debug("defectChangeDataObj with new owner is "+ repr(defectChangeDataObj[i]))
                    new_owner = fieldChangeDO.newValue
                    if new_owner not in email_cid:
                        email_cid[new_owner] = []
                    if md.cid not in email_cid[new_owner]:
                        email_cid[new_owner].append(md.cid)
                    break
            i = i - 1


    if len(email_cid) == 0:
        logging.info("Nothing to notify about")
        sys.exit(0)

    if options.project:
        subject = "New defects assigned to you in Coverity Project "+options.project
    else:
        subject = "New defects assigned to you in Coverity Projects"
    project_id = None
    url = None
    if options.project and '*' not in options.project:
        project_id =configServiceClient.get_project_id(options.project)
    else:
        if options.project:
            projectDOs = configServiceClient.get_projects(options.project)
        else:
            projectDOs = configServiceClient.get_projects()
            logging.debug("Got Project DOs " + str(len(projectDOs)))
    if options.days == 1:
        leadin = "<html>\n<br>The following defects were assigned to you in the past 24 hours<br>\n"
    else:
        leadin = "<html>\n<br>The following defects were assigned to you in the past " + str(options.days) + " days<br>\n"
    if project_id:
        projId=str(project_id)
    for u in email_cid.keys():
        body = leadin
        for cid in email_cid[u]:
            if not project_id:
                (projId,streamDefectId) = defectServiceClient.get_project_for_CID_and_user(projectDOs, cid, u)
                url = defectServiceClient.create_url(cid, projId,streamDefectId)
            else:
                url = defectServiceClient.create_url(cid, projId)
            body = body + "CID " + str(cid) + ": <a href=" + url + ">" + url + "</a><br>\n"

        body = body + "</html>"
        if options.testing == True:
            logging.warning("Testing: no actual e-mail will be sent")
            print "Username:  "******"Subject:   " + subject
            print body
        else:
            logging.debug("Users:" + str(u))
            logging.debug("Subject:" + str(subject))
            logging.debug("Body:" + str(body))
            try:
                resp = configServiceClient.send_notifications(u, subject, body)
                logging.debug("Mail sent to %d recepient" % (len(resp)))
            except Exception, err:
                logging.error(str(err))
                logging.error("Mail not sent to " + u)
Пример #5
0
def main():

    wsOpts = WSOpts()
    parser = wsOpts.get_common_opts()

    # use --test flag to avoid sending e-mail while debugging this script
    parser.add_option("--test",  action="store_true", dest="testing",  default="False", help="Testing flag: no mail just echo to stdout");
    parser.add_option("--last",  action="store_true", dest="last",  help="Notify about last commit: project or stream MUST be specified");

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ('last','stream'),('last','project')):
        logging.error("Must specify --last with either --stream or --project")
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options)
    defectServiceClient = DefectServiceClient(options)

    streamIdDOs = configServiceClient.get_streams(options.project,options.stream)
    if not streamIdDOs:
        logging.error("No valid streams found")
        sys.exit(-1)

    cws = configServiceClient.get_components_with_subscribers(options.project,options.stream)
    if len(cws) == 0:
        logging.warning("No subscribers for specified streams/projects")
        sys.exit(-1)
    logging.debug([(c.componentId.name, c.subscribers) for c in cws])
    comps = [c.componentId.name for c in cws]

    total = 0
    mds = []
    for streamIdDO in streamIdDOs:
        lastSnapshotIdDO = configServiceClient.get_last_snapshot(streamIdDO)
        nextToLastSnapshotIdDO = configServiceClient.get_next_to_last_snapshot(streamIdDO)
        logging.debug(lastSnapshotIdDO)
        logging.debug(nextToLastSnapshotIdDO)
        mergedDefectsDOs = defectServiceClient.get_merged_defects_by_snapshot(lastSnapshotIdDO, streamIdDO, nextToLastSnapshotIdDO)
        logging.debug(mergedDefectsDOs.totalNumberOfRecords)
        if mergedDefectsDOs.totalNumberOfRecords > 0:
            total += mergedDefectsDOs.totalNumberOfRecords
            mds.extend(mergedDefectsDOs.mergedDefects)

    if total == 0:
        print "No records new in latest snapshots"
        sys.exit(0)

    md = [m for m in mds if m.componentName in comps]
    if len(md) == 0:
        print "No records found for notification"
        sys.exit(0)

    # iterate over merged defects
    email_cid = {}
    for mergedDefectDO in md:
        # if the component the defect belongs to has subscribers
        cName = mergedDefectDO.componentName
        componentDO = configServiceClient.get_component(cName)
        try:
            subscribers = componentDO.subscribers
        except:
            # shouldn't be here as we filtered out the defects without subscribers
            logging.debug("no subscribers for "+cName)
            continue
        else:
            # store user and defects in a dictionary
            for user in subscribers:
                if user not in email_cid:
                    email_cid[user] = {}
                if cName not in email_cid[user]:
                    email_cid[user][cName] = []
                if mergedDefectDO.cid not in email_cid[user]:
                    email_cid[user][cName].append(mergedDefectDO.cid)

    if len(email_cid) == 0:
        print "Nothing to notify about"
        sys.exit(0)

    logging.debug("Will notify %d users about %d defects" % (len(email_cid), len(mds)))

    if options.project:
        subject = "New defects found in your subscribed components of Coverity project "+options.project
    elif options.stream:
        subject = "New defects in your subscribed components of Coverity stream "+options.stream
    else:
        logging.warning("Not yet implemented")
    project_id = None
    url = None
    if options.project:
        project_id = configServiceClient.get_project_id(options.project)
    elif options.stream:
        pDO = configServiceClient.get_projects(None, options.stream)
        if len(pDO) == 0:
            logging.error("Stream %s doesn't have a primary parent owner" % (options.stream))
        project_id = configServiceClient.get_project_id(pDO[0].id.name)
    else:
        logging.warning("Not yet implemented")
    leadin = "<html>\n<br>The following new defects were found in your subscribed components in the latest snapshot:<br>\n"
    if project_id:
        projId=str(project_id)
        url = "http://"+options.host+":"+options.port+"/sourcebrowser.htm?projectId="+projId+"#mergedDefectId="
    for u in email_cid.keys():
        body = leadin
        for c in email_cid[u].keys():
            body = body + "Component " + c + ":<br>\n"
            for cid in email_cid[u][c]:
                U = url+str(cid)
                body = body + "  CID " + str(cid) + ": <a href " + U + ">" + U + "</a><br>\n"

        body = body + "</html>"
        if options.testing == True:
            logging.info("just testing")
            print u
            print subject
            print body
        else:
            logging.debug(u)
            logging.debug(subject)
            logging.debug(body)
            configServiceClient.send_notifications(u, subject, body)
def main():
    """
     create and send notifications to all users who were assigned
     any new defects in the past N days (N=1 or specified)
    """
    wsOpts = WSOpts()
    parser = wsOpts.get_common_opts()

    # use --test flag to avoid sending e-mail while debugging this script
    parser.set_defaults(testing="False")
    parser.add_option("--test",
                      action="store_true",
                      dest="testing",
                      default="False",
                      help="Testing flag: no mail just echo to stdout")
    parser.add_option(
        "--days",
        dest="days",
        type=int,
        default=1,
        help="Days to check to notify about (default last 24 hours)")

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ()):
        parser.print_help()
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options)
    defectServiceClient = DefectServiceClient(options)

    # calculate when the action would have to be since to get reported
    cutoff = datetime.datetime.today() - datetime.timedelta(options.days)

    # all assignable users - no disabled users, since they should not be notified
    users = configServiceClient.get_all_users()

    # get the streams for relevant project or get all if none
    streamIdDO = configServiceClient.get_streams(options.project,
                                                 options.stream)

    mergedDefectDOs = defectServiceClient.get_merged_defects(streamIdDO,
                                                             users=users)

    email_cid = {}
    totalFetched = mergedDefectDOs.totalNumberOfRecords
    if totalFetched < 1:
        logging.info("No defects")
        sys.exit(totalFetched)
    for md in mergedDefectDOs.mergedDefects:
        defectChangeDataObj = defectServiceClient.get_md_history(
            md.cid, options.project, options.stream)
        i = len(defectChangeDataObj) - 1
        while i >= 0:
            if defectChangeDataObj[i].dateModified > cutoff and len(
                    set(defectChangeDataObj[i].affectedStreams).difference(
                        set(streamIdDO))) > 0:
                if getattr(defectChangeDataObj[i], 'ownerChange', None):
                    new_owner = defectChangeDataObj[i].ownerChange.newValue
                    if new_owner not in email_cid:
                        email_cid[new_owner] = []
                    if md.cid not in email_cid[new_owner]:
                        email_cid[new_owner].append(md.cid)
                    break
            i = i - 1

    if len(email_cid) == 0:
        logging.info("Nothing to notify about")
        sys.exit(0)

    if options.project:
        subject = "New defects assigned to you in Coverity Project " + options.project
    else:
        subject = "New defects assigned to you in Coverity Projects"
    project_id = None
    url = None
    if options.project and '*' not in options.project:
        project_id = configServiceClient.get_project_id(options.project)
    else:
        if options.project:
            projectDOs = configServiceClient.get_projects(options.project)
        else:
            projectDOs = configServiceClient.get_projects()
            logging.debug("Got Project DOs " + str(len(projectDOs)))
    if options.days == 1:
        leadin = "<html>\n<br>The following defects were assigned to you in the past 24 hours<br>\n"
    else:
        leadin = "<html>\n<br>The following defects were assigned to you in the past " + str(
            options.days) + " days<br>\n"
    if project_id:
        projId = str(project_id)
    for u in email_cid.keys():
        body = leadin
        for cid in email_cid[u]:
            if not project_id:
                (projId, streamDefectId
                 ) = defectServiceClient.get_project_for_CID_and_user(
                     projectDOs, cid, u)
                url = defectServiceClient.create_url(cid, projId,
                                                     streamDefectId)
            else:
                url = defectServiceClient.create_url(cid, projId)
            body = body + "CID " + str(
                cid) + ": <a href=" + url + ">" + url + "</a><br>\n"

        body = body + "</html>"
        if options.testing == True:
            logging.warning("Testing: no actual e-mail will be sent")
            print "Username:  "******"Subject:   " + subject
            print body
        else:
            logging.debug("Users:" + str(u))
            logging.debug("Subject:" + str(subject))
            logging.debug("Body:" + str(body))
            try:
                resp = configServiceClient.send_notifications(u, subject, body)
                logging.debug("Mail sent to %d recepient" % (len(resp)))
            except Exception, err:
                logging.error(str(err))
                logging.error("Mail not sent to " + u)
def main():
    """
     create and send notifications to all users who currently have assigned
     any defects that are outstanding (maybe flagging those that are new)
    """
    wsOpts = WSOpts()
    parser = wsOpts.get_common_opts()

    # use --test flag to avoid sending e-mail while debugging this script
    parser.set_defaults(testing="False")
    parser.add_option("--test",  action="store_true", dest="testing",  default="False", help="Testing flag: no mail just echo to stdout");
    parser.add_option("--detail",  action="store_true", dest="detail",  default="False", help="Detail flag: add a bunch of details about the bugs");
    parser.add_option("--days",  dest="days",  type=int, default=1, help="Days to check for new to notify about (default last 24 hours)");

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ()):
        parser.print_help()
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options)
    defectServiceClient = DefectServiceClient(options)

    # calculate when the action would have to be since to get reported
    cutoff = datetime.datetime.today()-datetime.timedelta(options.days)

    # all assignable users - no disabled users, since they should not be notified
    users = configServiceClient.get_all_users()

    # get the streams for relevant project or get all if none
    streamIdDO = configServiceClient.get_streams(options.project,options.stream)

    mergedDefectDOs = defectServiceClient.get_merged_defects(streamIdDO,users=users)

    email_cid = {}
    totalFetched = mergedDefectDOs.totalNumberOfRecords
    if totalFetched < 1:
        logging.info("No defects")
        sys.exit(totalFetched)
    logging.debug("Total fetched "+ repr(totalFetched))
    for md in mergedDefectDOs.mergedDefects:
        for attr in md.defectStateAttributeValues:
            logging.debug("Attribute is " + repr(attr) + "\n")
            if attr.attributeDefinitionId.name=="Owner":
               owner = attr.attributeValueId.name
               logging.debug("\n\n***********  Found owner " + owner)
               if owner not in email_cid:
                        email_cid[owner] = []
               if md.cid not in email_cid[owner]:
                        email_cid[owner].append(md)
               break

    logging.debug(repr(md))
    if len(email_cid) == 0:
        logging.info("Nothing to notify about")
        sys.exit(0)

    if options.project:
        subject = "Outstanding defects assigned to you in Coverity Project "+options.project
    else:
        subject = "Outstanding defects assigned to you in Coverity Projects"
    project_id = None
    url = None
    if options.project and '*' not in options.project:
        project_id =configServiceClient.get_project_id(options.project)
        logging.debug("Project id is " + repr(project_id))
    else:
        if options.project:
            projectDOs = configServiceClient.get_projects(options.project)
        else:
            projectDOs = configServiceClient.get_projects()
            logging.debug("Got Project DOs " + str(len(projectDOs)))
    if options.days == 1:
        leadin = "<html>\n<br>\n<br>The following defects were newly detected in the past 24 hours<br>\n"
    else:
        leadin = "<html>\n<br>\n<br>The following defects were newly detected in the past " + str(options.days) + " days<br>\n"
    leadinOthers = "\n<br>\n<br>In addition the following existing unresolved defects are assigned to you:<br>\n"

    if project_id:
        projId=str(project_id)
    for u in email_cid.keys():
        body = leadin
        restOfBody = leadinOthers
        for md in email_cid[u]:
            if not project_id:
                (projId,streamDefectId) = defectServiceClient.get_project_for_CID_and_user(projectDOs, md.cid, u)
                url = defectServiceClient.create_url(md.cid, projId,streamDefectId)
            else:
                url = defectServiceClient.create_url(md.cid, projId)
            logging.debug("First detected " + md.firstDetected.strftime('%Y/%m/%d'))
            if md.firstDetected > cutoff:
                body = body + "New CID " + str(md.cid) + ":\n<br>   Issue " + md.checkerName + " in file " + md.filePathname + " was detected on " + md.firstDetected.strftime('%Y/%m/%d') + ". \n<br> <a href=" + url + ">" + url + "</a>\n<br>\n"
            else:
                restOfBody = restOfBody + "CID " + str(md.cid) + ": " + md.checkerName + ". <a href=" + url + ">" + url + "</a><br>\n"

        body = body + restOfBody + "</html>"
        #server = smtplib.SMTP('smtp.gmail.com',587)
        server = 'localhost'
        fromaddr = "*****@*****.**"
        if options.testing == True:
            logging.warning("Testing: no actual e-mail will be sent")
            print "Username:  "******"Subject:   " + subject
            print body
        else:
            logging.debug("Users:" + str(u))
            logging.debug("Subject:" + str(subject))
            logging.debug("Body:" + str(body))
            try:
                sent = False
                resp = configServiceClient.send_notifications(u+"@local", subject, body)
                logging.info("Mail sent to %d recepient" % (len(resp)))
                if len(resp) > 0: sent=True
            except Exception, err:
                logging.error(str(err))
                logging.error("Mail not sent to " + u)
                sent=False
            # now fall back on doing a regular email send...
            if sent == False:
                logging.info("Sending e-mail the regular way since notify failed")
                udo = configServiceClient.user_details(u)
                toaddr = udo.email
                msg = ("Subject: %s\nFrom: %s\nTo: %s\n\n" % (subject, fromaddr, toaddr)) + body
                server.sendmail(fromaddr, toaddr, msg)
                server.quit()
Пример #8
0
def main():

    wsOpts = WSOpts()
    parser = wsOpts.get_common_opts()

    # use --test flag to avoid sending e-mail while debugging this script
    parser.add_option("--test",
                      action="store_true",
                      dest="testing",
                      default="False",
                      help="Testing flag: no mail just echo to stdout")
    parser.add_option(
        "--last",
        action="store_true",
        dest="last",
        help="Notify about last commit: project or stream MUST be specified")

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ('last', 'stream'),
                                   ('last', 'project')):
        logging.error("Must specify --last with either --stream or --project")
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options)
    defectServiceClient = DefectServiceClient(options)

    streamIdDOs = configServiceClient.get_streams(options.project,
                                                  options.stream)
    if not streamIdDOs:
        logging.error("No valid streams found")
        sys.exit(-1)

    cws = configServiceClient.get_components_with_subscribers(
        options.project, options.stream)
    if len(cws) == 0:
        logging.warning("No subscribers for specified streams/projects")
        sys.exit(-1)
    logging.debug([(c.componentId.name, c.subscribers) for c in cws])
    comps = [c.componentId.name for c in cws]

    total = 0
    mds = []
    for streamIdDO in streamIdDOs:
        lastSnapshotIdDO = configServiceClient.get_last_snapshot(streamIdDO)
        nextToLastSnapshotIdDO = configServiceClient.get_next_to_last_snapshot(
            streamIdDO)
        logging.debug(lastSnapshotIdDO)
        logging.debug(nextToLastSnapshotIdDO)
        mergedDefectsDOs = defectServiceClient.get_merged_defects_by_snapshot(
            lastSnapshotIdDO, streamIdDO, nextToLastSnapshotIdDO)
        logging.debug(mergedDefectsDOs.totalNumberOfRecords)
        if mergedDefectsDOs.totalNumberOfRecords > 0:
            total += mergedDefectsDOs.totalNumberOfRecords
            mds.extend(mergedDefectsDOs.mergedDefects)

    if total == 0:
        print "No records new in latest snapshots"
        sys.exit(0)

    md = [m for m in mds if m.componentName in comps]
    if len(md) == 0:
        print "No records found for notification"
        sys.exit(0)

    # iterate over merged defects
    email_cid = {}
    for mergedDefectDO in md:
        # if the component the defect belongs to has subscribers
        cName = mergedDefectDO.componentName
        componentDO = configServiceClient.get_component(cName)
        try:
            subscribers = componentDO.subscribers
        except:
            # shouldn't be here as we filtered out the defects without subscribers
            logging.debug("no subscribers for " + cName)
            continue
        else:
            # store user and defects in a dictionary
            for user in subscribers:
                if user not in email_cid:
                    email_cid[user] = {}
                if cName not in email_cid[user]:
                    email_cid[user][cName] = []
                if mergedDefectDO.cid not in email_cid[user]:
                    email_cid[user][cName].append(mergedDefectDO.cid)

    if len(email_cid) == 0:
        print "Nothing to notify about"
        sys.exit(0)

    logging.debug("Will notify %d users about %d defects" %
                  (len(email_cid), len(mds)))

    if options.project:
        subject = "New defects found in your subscribed components of Coverity project " + options.project
    elif options.stream:
        subject = "New defects in your subscribed components of Coverity stream " + options.stream
    else:
        logging.warning("Not yet implemented")
    project_id = None
    url = None
    if options.project:
        project_id = configServiceClient.get_project_id(options.project)
    elif options.stream:
        pDO = configServiceClient.get_projects(None, options.stream)
        if len(pDO) == 0:
            logging.error("Stream %s doesn't have a primary parent owner" %
                          (options.stream))
        project_id = configServiceClient.get_project_id(pDO[0].id.name)
    else:
        logging.warning("Not yet implemented")
    leadin = "<html>\n<br>The following new defects were found in your subscribed components in the latest snapshot:<br>\n"
    if project_id:
        projId = str(project_id)
        url = "http://" + options.host + ":" + options.port + "/sourcebrowser.htm?projectId=" + projId + "#mergedDefectId="
    for u in email_cid.keys():
        body = leadin
        for c in email_cid[u].keys():
            body = body + "Component " + c + ":<br>\n"
            for cid in email_cid[u][c]:
                U = url + str(cid)
                body = body + "  CID " + str(
                    cid) + ": <a href=" + U + ">" + U + "</a><br>\n"

        body = body + "</html>"
        if options.testing == True:
            logging.info("just testing")
            print u
            print subject
            print body
        else:
            logging.debug(u)
            logging.debug(subject)
            logging.debug(body)
            configServiceClient.send_notifications(u, subject, body)
def main():
    """
     create and send notifications to all users who currently have assigned
     any defects that are outstanding (maybe flagging those that are new)
    """
    wsOpts = WSOpts()
    parser = wsOpts.get_common_opts()

    # use --test flag to avoid sending e-mail while debugging this script
    parser.set_defaults(testing="False")
    parser.add_option("--test",
                      action="store_true",
                      dest="testing",
                      default="False",
                      help="Testing flag: no mail just echo to stdout")
    parser.add_option(
        "--detail",
        action="store_true",
        dest="detail",
        default="False",
        help="Detail flag: add a bunch of details about the bugs")
    parser.add_option(
        "--days",
        dest="days",
        type=int,
        default=1,
        help="Days to check for new to notify about (default last 24 hours)")

    (options, args) = parser.parse_args()
    wsOpts.setLogging(options.debug)

    if wsOpts.checkRequiredMissing(options, ()):
        parser.print_help()
        sys.exit(-1)

    configServiceClient = ConfigServiceClient(options)
    defectServiceClient = DefectServiceClient(options)

    # calculate when the action would have to be since to get reported
    cutoff = datetime.datetime.today() - datetime.timedelta(options.days)

    # all assignable users - no disabled users, since they should not be notified
    users = configServiceClient.get_all_users()

    # get the streams for relevant project or get all if none
    streamIdDO = configServiceClient.get_streams(options.project,
                                                 options.stream)

    mergedDefectDOs = defectServiceClient.get_merged_defects(streamIdDO,
                                                             users=users)

    email_cid = {}
    totalFetched = mergedDefectDOs.totalNumberOfRecords
    if totalFetched < 1:
        logging.info("No defects")
        sys.exit(totalFetched)
    logging.debug("Total fetched " + repr(totalFetched))
    for md in mergedDefectDOs.mergedDefects:
        for attr in md.defectStateAttributeValues:
            logging.debug("Attribute is " + repr(attr) + "\n")
            if attr.attributeDefinitionId.name == "Owner":
                owner = attr.attributeValueId.name
                logging.debug("\n\n***********  Found owner " + owner)
                if owner not in email_cid:
                    email_cid[owner] = []
                if md.cid not in email_cid[owner]:
                    email_cid[owner].append(md)
                break

    logging.debug(repr(md))
    if len(email_cid) == 0:
        logging.info("Nothing to notify about")
        sys.exit(0)

    if options.project:
        subject = "Outstanding defects assigned to you in Coverity Project " + options.project
    else:
        subject = "Outstanding defects assigned to you in Coverity Projects"
    project_id = None
    url = None
    if options.project and '*' not in options.project:
        project_id = configServiceClient.get_project_id(options.project)
        logging.debug("Project id is " + repr(project_id))
    else:
        if options.project:
            projectDOs = configServiceClient.get_projects(options.project)
        else:
            projectDOs = configServiceClient.get_projects()
            logging.debug("Got Project DOs " + str(len(projectDOs)))
    if options.days == 1:
        leadin = "<html>\n<br>\n<br>The following defects were newly detected in the past 24 hours<br>\n"
    else:
        leadin = "<html>\n<br>\n<br>The following defects were newly detected in the past " + str(
            options.days) + " days<br>\n"
    leadinOthers = "\n<br>\n<br>In addition the following existing unresolved defects are assigned to you:<br>\n"

    if project_id:
        projId = str(project_id)
    for u in email_cid.keys():
        body = leadin
        restOfBody = leadinOthers
        for md in email_cid[u]:
            if not project_id:
                (projId, streamDefectId
                 ) = defectServiceClient.get_project_for_CID_and_user(
                     projectDOs, md.cid, u)
                url = defectServiceClient.create_url(md.cid, projId,
                                                     streamDefectId)
            else:
                url = defectServiceClient.create_url(md.cid, projId)
            logging.debug("First detected " +
                          md.firstDetected.strftime('%Y/%m/%d'))
            if md.firstDetected > cutoff:
                body = body + "New CID " + str(
                    md.cid
                ) + ":\n<br>   Issue " + md.checkerName + " in file " + md.filePathname + " was detected on " + md.firstDetected.strftime(
                    '%Y/%m/%d'
                ) + ". \n<br> <a href=" + url + ">" + url + "</a>\n<br>\n"
            else:
                restOfBody = restOfBody + "CID " + str(
                    md.cid
                ) + ": " + md.checkerName + ". <a href=" + url + ">" + url + "</a><br>\n"

        body = body + restOfBody + "</html>"
        #server = smtplib.SMTP('smtp.gmail.com',587)
        server = 'localhost'
        fromaddr = "*****@*****.**"
        if options.testing == True:
            logging.warning("Testing: no actual e-mail will be sent")
            print "Username:  "******"Subject:   " + subject
            print body
        else:
            logging.debug("Users:" + str(u))
            logging.debug("Subject:" + str(subject))
            logging.debug("Body:" + str(body))
            try:
                sent = False
                resp = configServiceClient.send_notifications(
                    u + "@local", subject, body)
                logging.info("Mail sent to %d recepient" % (len(resp)))
                if len(resp) > 0: sent = True
            except Exception, err:
                logging.error(str(err))
                logging.error("Mail not sent to " + u)
                sent = False
            # now fall back on doing a regular email send...
            if sent == False:
                logging.info(
                    "Sending e-mail the regular way since notify failed")
                udo = configServiceClient.user_details(u)
                toaddr = udo.email
                msg = ("Subject: %s\nFrom: %s\nTo: %s\n\n" %
                       (subject, fromaddr, toaddr)) + body
                server.sendmail(fromaddr, toaddr, msg)
                server.quit()