def __init__(self, config):
        """
        class initializer
        :param config: configuration file for WorklistManager 
        :return:
        """

        cfg_defaults = {
            'pdb_hostname': 'localhost',
            'pdb_username': '******',
            'pdb_password': '******',
            'pdb_dbname': 'fcdctest',
            'mr_scanner_regex': '.*(SKYRA|PRASMA(FIT)).*',
            'dcmtk_setup_cmd': '',
            'dcmtk_wlbroker_store':
            '/scratch/OrthancData/DicomWorklist/WLBROKER'
        }

        cfg = ConfigParser.ConfigParser(defaults=cfg_defaults)
        cfg.read(config)

        self.mr_scanner_regex = re.compile(
            cfg.get('WLBROKER', 'mr_scanner_regex'))
        self.dcmtk_setup = cfg.get('WLBROKER', 'dcmtk_setup_cmd')
        self.dcmtk_wlbroker_dir = cfg.get('WLBROKER', 'dcmtk_wlbroker_store')
        self.logger = getLogger(name=self.__class__.__name__,
                                lvl=int(cfg.get('LOGGING', 'level')))

        self.__getDBConnectInfo__(cfg)
        self.pdb = IMySQL(db_host=self.pdb_host,
                          db_username=self.pdb_uid,
                          db_password=self.pdb_pass,
                          db_name=self.pdb_name)
    def __init__(self, config):
        """
        class initializer
        :param config: configuration file for WorklistManager 
        :return:
        """

        cfg_defaults = {'pdb_hostname': 'localhost',
                        'pdb_username': '******',
                        'pdb_password': '******',
                        'pdb_dbname': 'fcdctest',
                        'mr_scanner_regex': '.*(SKYRA|PRASMA(FIT)).*',
                        'dcmtk_setup_cmd': '',
                        'dcmtk_wlbroker_store': '/scratch/OrthancData/DicomWorklist/WLBROKER'}

        cfg = ConfigParser.ConfigParser(defaults=cfg_defaults)
        cfg.read(config)

        self.mr_scanner_regex = re.compile(cfg.get('WLBROKER','mr_scanner_regex'))
        self.dcmtk_setup = cfg.get('WLBROKER','dcmtk_setup_cmd')
        self.dcmtk_wlbroker_dir = cfg.get('WLBROKER','dcmtk_wlbroker_store')
        self.logger = getLogger(name=self.__class__.__name__, lvl=int(cfg.get('LOGGING', 'level')))

        self.__getDBConnectInfo__(cfg)
        self.pdb = IMySQL(db_host = self.pdb_host,
                          db_username = self.pdb_uid,
                          db_password = self.pdb_pass,
                          db_name = self.pdb_name)
class WorklistManager:
    def __init__(self, config):
        """
        class initializer
        :param config: configuration file for WorklistManager 
        :return:
        """

        cfg_defaults = {
            'pdb_hostname': 'localhost',
            'pdb_username': '******',
            'pdb_password': '******',
            'pdb_dbname': 'fcdctest',
            'mr_scanner_regex': '.*(SKYRA|PRASMA(FIT)).*',
            'dcmtk_setup_cmd': '',
            'dcmtk_wlbroker_store':
            '/scratch/OrthancData/DicomWorklist/WLBROKER'
        }

        cfg = ConfigParser.ConfigParser(defaults=cfg_defaults)
        cfg.read(config)

        self.mr_scanner_regex = re.compile(
            cfg.get('WLBROKER', 'mr_scanner_regex'))
        self.dcmtk_setup = cfg.get('WLBROKER', 'dcmtk_setup_cmd')
        self.dcmtk_wlbroker_dir = cfg.get('WLBROKER', 'dcmtk_wlbroker_store')
        self.logger = getLogger(name=self.__class__.__name__,
                                lvl=int(cfg.get('LOGGING', 'level')))

        self.__getDBConnectInfo__(cfg)
        self.pdb = IMySQL(db_host=self.pdb_host,
                          db_username=self.pdb_uid,
                          db_password=self.pdb_pass,
                          db_name=self.pdb_name)

    def __del__(self):
        self.pdb.closeConnector()

    def __getDBConnectInfo__(self, cfg):
        '''common function to get database connection information
        '''
        ## project database connection information
        self.pdb_host = cfg.get('PDB', 'pdb_hostname')
        self.pdb_uid = cfg.get('PDB', 'pdb_username')
        self.pdb_pass = cfg.get('PDB', 'pdb_password')
        self.pdb_name = cfg.get('PDB', 'pdb_dbname')

        if not self.pdb_pass:
            ## try ask for password from the interactive shell
            if sys.stdin.isatty():  ## for interactive password typing
                self.pdb_pass = getpass.getpass('Project DB password: '******'Project DB password: '******''):
        """
        make worklist items for DICOM worklist broker
        :param eDate: the date in which the MR scan is planned
        :param worklistStore: (optional) the filesystem path in which the DICOM worklist items will be stored.
                              If it's specified, it replaces the path specified by 'dcmtk_wlbroker_store' in
                              the config file.
        :return: a list of filesystem paths to the successfully created worklist items
        """

        worklistFiles = []

        s = Shell()
        dump2dcm_cmd = 'dump2dcm'
        if self.dcmtk_setup:
            dump2dcm_cmd = '%s; %s' % (self.dcmtk_setup, dump2dcm_cmd)

        if not worklistStore:
            worklistStore = self.dcmtk_wlbroker_dir

        for wl in self.getWorklistItems(eDate):
            # save worklist as human-readable (DICOM dump)
            dump_fpath = os.path.join(
                worklistStore, '%s_%s.dump' % (wl.modalityAE, wl.eventId))
            f = open(dump_fpath, 'w')
            f.write(str(wl))
            f.close()

            # convert DICOM dump to DICOM format
            dcm_fpath = os.path.join(worklistStore,
                                     '%s_%s.wl' % (wl.modalityAE, wl.eventId))
            s_cmd = '%s %s %s' % (dump2dcm_cmd, dump_fpath, dcm_fpath)
            self.logger.debug('dump2dcm command: %s' % s_cmd)
            rc, output, m = s.cmd1(s_cmd)
            if rc != 0:
                self.logger.error('DICOM worklist item creation failed: ' %
                                  wl.studyId)
            else:
                worklistFiles.append(dcm_fpath)

        return worklistFiles

    def getWorklistItems(self, eDate=date.today()):
        '''compose worklist items based on booking events retrieved from calendar table in PDB
        '''

        conn = self.pdb.getConnector()
        crs = None

        worklist = []

        try:
            qry = 'SELECT a.id,a.project_id,a.subj_ses,a.start_date,a.start_time,a.user_id,b.projectName,c.description AS lab_desc FROM calendar_items_new AS a, projects AS b, calendars AS c WHERE a.status IN (\'CONFIRMED\',\'TENTATIVE\') AND a.subj_ses NOT IN (\'Cancellation\',\'0\') AND a.start_date = DATE(\'%s\') AND a.project_id = b.id AND a.calendar_id = c.id ORDER BY a.start_time' % eDate.strftime(
                '%Y-%m-%d')

            self.logger.debug(qry)

            crs = conn.cursor()
            crs.execute(qry)

            for (eId, projectId, subj_ses, startDate, startTime, userId,
                 projectName, labDesc) in crs.fetchall():

                # only events for MR scanners are considered
                m = self.mr_scanner_regex.match(labDesc.upper())

                if not m:
                    continue

                scannerAE = m.group(1)

                d = re.compile('\s*(-)\s*').split(subj_ses)
                subjectId = d[0]

                # always set session id to '1' if it's not part of subj_ses string
                sessionId = d[-1] if len(d) > 1 else '1'

                # in some MySQL library, the startTime is returned as timedelta object
                eStartTime = None
                if type(startTime) is timedelta:
                    eStartTime = datetime(startDate.year, startDate.month,
                                          startDate.day)
                    eStartTime += startTime
                else:
                    eStartTime = startTime

                # make another SQL query to get user name
                try:
                    crs1 = conn.cursor()
                    crs1.execute(
                        'SELECT firstName,lastName FROM users WHERE id = \'%s\''
                        % userId)
                    (firstName, lastName) = crs1.fetchone()
                    userId = '%s %s' % (firstName, lastName)
                except Exception, e:
                    self.logger.exception('User name select failed: %s' %
                                          userId)
                else:
                    pass
                finally:
                    try:
                        crs1.close()
                    except Exception, e:
                        pass

                # construct worklist item
                wl = WorklistItem(projectId, projectName, subjectId, sessionId,
                                  startDate.strftime('%Y%m%d'),
                                  eStartTime.strftime('%H%M%S'), scannerAE,
                                  userId)

                worklist.append(wl)
class WorklistManager:

    def __init__(self, config):
        """
        class initializer
        :param config: configuration file for WorklistManager 
        :return:
        """

        cfg_defaults = {'pdb_hostname': 'localhost',
                        'pdb_username': '******',
                        'pdb_password': '******',
                        'pdb_dbname': 'fcdctest',
                        'mr_scanner_regex': '.*(SKYRA|PRASMA(FIT)).*',
                        'dcmtk_setup_cmd': '',
                        'dcmtk_wlbroker_store': '/scratch/OrthancData/DicomWorklist/WLBROKER'}

        cfg = ConfigParser.ConfigParser(defaults=cfg_defaults)
        cfg.read(config)

        self.mr_scanner_regex = re.compile(cfg.get('WLBROKER','mr_scanner_regex'))
        self.dcmtk_setup = cfg.get('WLBROKER','dcmtk_setup_cmd')
        self.dcmtk_wlbroker_dir = cfg.get('WLBROKER','dcmtk_wlbroker_store')
        self.logger = getLogger(name=self.__class__.__name__, lvl=int(cfg.get('LOGGING', 'level')))

        self.__getDBConnectInfo__(cfg)
        self.pdb = IMySQL(db_host = self.pdb_host,
                          db_username = self.pdb_uid,
                          db_password = self.pdb_pass,
                          db_name = self.pdb_name)

    def __del__(self):
        self.pdb.closeConnector()

    def __getDBConnectInfo__(self, cfg):
        '''common function to get database connection information
        '''
        ## project database connection information
        self.pdb_host   = cfg.get('PDB','pdb_hostname')
        self.pdb_uid    = cfg.get('PDB','pdb_username')
        self.pdb_pass   = cfg.get('PDB','pdb_password')
        self.pdb_name   = cfg.get('PDB','pdb_dbname')
 
        if not self.pdb_pass:
            ## try ask for password from the interactive shell
            if sys.stdin.isatty(): ## for interactive password typing
                self.pdb_pass = getpass.getpass('Project DB password: '******'Project DB password: '******''):
        """
        make worklist items for DICOM worklist broker
        :param eDate: the date in which the MR scan is planned
        :param worklistStore: (optional) the filesystem path in which the DICOM worklist items will be stored.
                              If it's specified, it replaces the path specified by 'dcmtk_wlbroker_store' in
                              the config file.
        :return: a list of filesystem paths to the successfully created worklist items
        """

        worklistFiles = []

        s = Shell()
        dump2dcm_cmd = 'dump2dcm'
        if self.dcmtk_setup:
            dump2dcm_cmd = '%s; %s' % (self.dcmtk_setup, dump2dcm_cmd)

        if not worklistStore:
            worklistStore = self.dcmtk_wlbroker_dir

        for wl in self.getWorklistItems(eDate):
            # save worklist as human-readable (DICOM dump)
            dump_fpath = os.path.join(worklistStore, '%s_%s.dump' % (wl.modalityAE, wl.eventId))
            f = open( dump_fpath,'w')
            f.write( str(wl) )
            f.close()

            # convert DICOM dump to DICOM format
            dcm_fpath = os.path.join(worklistStore, '%s_%s.wl' % (wl.modalityAE, wl.eventId))
            s_cmd = '%s %s %s' % (dump2dcm_cmd, dump_fpath, dcm_fpath)
            self.logger.debug('dump2dcm command: %s' % s_cmd)
            rc,output,m = s.cmd1(s_cmd)
            if rc != 0:
                self.logger.error('DICOM worklist item creation failed: ' % wl.studyId)
            else:
                worklistFiles.append(dcm_fpath)

        return worklistFiles

    def getWorklistItems(self, eDate=date.today()):
        '''compose worklist items based on booking events retrieved from calendar table in PDB
        '''

        conn = self.pdb.getConnector()
        crs  = None

        worklist = []

        try:
            qry = 'SELECT a.id,a.project_id,a.subj_ses,a.start_date,a.start_time,a.user_id,b.projectName,c.description AS lab_desc FROM calendar_items_new AS a, projects AS b, calendars AS c WHERE a.status IN (\'CONFIRMED\',\'TENTATIVE\') AND a.subj_ses NOT IN (\'Cancellation\',\'0\') AND a.start_date = DATE(\'%s\') AND a.project_id = b.id AND a.calendar_id = c.id ORDER BY a.start_time' % eDate.strftime('%Y-%m-%d')

            self.logger.debug(qry)

            crs = conn.cursor()
            crs.execute(qry)

            for (eId, projectId, subj_ses, startDate, startTime, userId, projectName, labDesc) in crs.fetchall():

                # only events for MR scanners are considered
                m = self.mr_scanner_regex.match(labDesc.upper())

                if not m:
                    continue

                scannerAE = m.group(1)

                d = re.compile('\s*(-)\s*').split(subj_ses)
                subjectId = d[0]

                # always set session id to '1' if it's not part of subj_ses string 
                sessionId = d[-1] if len(d) > 1 else '1'

                # in some MySQL library, the startTime is returned as timedelta object
                eStartTime = None
                if type(startTime) is timedelta:
                    eStartTime = datetime(startDate.year, startDate.month, startDate.day)
                    eStartTime += startTime
                else:
                    eStartTime = startTime

                # make another SQL query to get user name
                try:
                    crs1 = conn.cursor()
                    crs1.execute('SELECT firstName,lastName FROM users WHERE id = \'%s\'' % userId)
                    (firstName, lastName) = crs1.fetchone()
                    userId = '%s %s' % (firstName, lastName)
                except Exception, e:
                    self.logger.exception('User name select failed: %s' % userId)
                else:
                    pass
                finally:
                    try:
                        crs1.close()
                    except Exception, e:
                        pass

                # construct worklist item
                wl = WorklistItem(projectId,
                                  projectName,
                                  subjectId,
                                  sessionId,
                                  startDate.strftime('%Y%m%d'),
                                  eStartTime.strftime('%H%M%S'),
                                  scannerAE,
                                  userId)

                worklist.append(wl)