def __init__(self, config): self.trello = TrelloUtils(config) self.config = config
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)))