Example #1
0
 def __init__(self, config):
     self.trello = TrelloUtils(config)
     self.config = config
Example #2
0
class Monitor(object):

    def __init__(self, config):
        self.trello = TrelloUtils(config)
        self.config = config

    def list_trello_cards(self, lists):
        # Loop over the lists and fetch the cards, returning a dictionary keyed with the card title
        cards = {}
        for tlist in lists:
            list_obj = self.trello.get_list(self.trello_board,tlist,True)
            if not list_obj:
                continue
            
            # Loop over the cards in the list
            for card in list_obj.list_cards():
                # Get the description and convert it to a dictionary
                cards[card.name] = card
                
        return cards
    
    def list_runs(self):
        """Get a list of folders matching the run folder pattern"""
        pattern = r'(\d{6})_([SNMD]+\d+)_\d+_([AB]?)([A-Z0-9\-]+)'
        runs = []
        for dump_folder in self.run_folders:
            for fname in os.listdir(dump_folder):
                if not os.path.isdir(os.path.join(dump_folder,fname)):
                    continue
                m = re.match(pattern, fname)
                if m is not None:
                    run = {'name': fname,
                           'path': os.path.join(dump_folder,fname),
                           'date': m.group(1),
                           'instrument': m.group(2),
                           'position': m.group(3),
                           'flowcell_id': m.group(4),
                           'short_name': "{}_{}{}".format(m.group(1),m.group(3),m.group(4))}
                    run['technology'] = 'MiSeq' if self.is_miseq_run(run) else 'HiSeq'
                    run['run_info'] = self.get_run_info(run)
                    run['run_parameters'] = self.get_run_parameters(run)
                    run['samplesheet'] = self.get_run_samplesheet(run)
                    run['projects'] = self.get_run_projects(run)
                    # Don't track MiSeq runs that are not production, qc or applications
                    if self.is_miseq_run(run) and len([d for d in self.get_samplesheet_descriptions(run) if d.lower() in ["qc","production","applications"]]) == 0:
                        continue
                    runs.append(run)
        return runs

    def is_miseq_run(self, run):
        """Determine whether this is a MiSeq run, from the flowcell-id format
        """
        return not run['flowcell_id'].endswith("XX")

    def get_samplesheet_descriptions(self, run):
        """Return the set of descriptions in the samplesheet"""
        ss = run['samplesheet']
        return list(set([s['Description'] for s in ss])) if ss else []

    def get_run_info(self, run):
        """Parse the RunInfo.xml file into a dict"""
        f = os.path.join(run['path'],'RunInfo.xml')
        if not os.path.exists(f):
            return {}
        with open(f) as fh:
            rip = RunInfoParser()
            runinfo = rip.parse(fh)
        return runinfo
    
    def get_run_parameters(self, run):
        """Parse the runParameters.xml file into a dict"""
        f = os.path.join(run['path'],'runParameters.xml')
        if not os.path.exists(f):
            return {}
        with open(f) as fh:
            rpp = RunParametersParser()
            runparameters = rpp.parse(fh)
        return runparameters
    
    def get_run_samplesheet(self, run):
        """Locate and parse the samplesheet for a run"""
        
        fname = "{}.csv".format(run.get("flowcell_id","SampleSheet"))
        ssheet = None
        for folder in self.samplesheet_folders + [run.get("path","")]:
            f = os.path.join(folder,fname)
            if os.path.exists(f):
                ssheet = f
                break
        if ssheet is None:
            return None
        
        return HiSeqSampleSheet(ssheet)
 
    def get_run_projects(self, run):
        """Locate and parse the samplesheet to extract projects in the run"""
        
        ss = run['samplesheet']
        projects = list(set([s['SampleProject'].replace("__",".") for s in ss])) if ss else []
        return projects
           
    def get_run_project_samples(self, run, project):
        """Locate and parse the samplesheet to extract samples for a project in the run"""
        
        ss = run['samplesheet']
        samples = list(set([s['SampleID'].replace("__",".") for s in ss if s['SampleProject'].replace("__",".") == project])) if ss else []
        return samples
           
    def send_notification(self, subject, msg, users=[]):
        """Send an email notification that a run has been moved to a list
        """
        addresses = self.config.get("email",{})
        recipients = []
        for user in users:
            try:
                recipients.extend(addresses[user].split(","))
            except:
                pass
        if len(recipients) == 0:
            recipients = self.config.get("email",{}).get("default","").split(",")
        if len(recipients) == 0 or all([len(r) == 0 for r in recipients]):
            return
        
        msg = MIMEText("{}\nSent from {}".format(msg,
                                                 socket.gethostname()))
        msg['Subject'] = subject
        msg['From'] = SENDER
        msg['To'] = ",".join(recipients)
        try:
            s = smtplib.SMTP(self.config.get("email",{}).get("smtp_host","localhost"))
            s.sendmail(SENDER, recipients, msg.as_string())
            s.quit()
        except Exception, e:
            print("WARNING: Sending email to {} failed: {}".format(",".join(recipients),str(e)))