예제 #1
0
class Ridirect(object):
    
        
    def __init__(self, gui,ini):
        self.version="V1.12"
        self.gui=gui
        if not self.gui is None:
            pass #just in case where, one day, we have a TKinter GUI
        #
        # recall parms in .ini
        #
        self.ini=ini
        self.debug= self.ini.get('mode','debug')=="yes"
        self.want_collect_measurements= self.ini.get('mode','collect_measurements')=="yes"
        self.want_collect_reports= self.ini.get('mode','collect_reports')=="yes"
        self.want_dispatch_measurements= self.ini.get('mode','dispatch_measurements')=="yes"
        self.want_dispatch_reports= self.ini.get('mode','dispatch_reports')=="yes"
        self.want_run_merge= self.ini.get('mode','run_merge')=="yes"
        self.want_send_ftp= self.ini.get('mode','send_ftp')=="yes"
        #
        #
        self.report=None
        self.measurement=None
        self.mapping=None
        #
        self.outbox=self.ini.get('files', 'outbox_path')
        #
        #
        #
        # set-up log file
        #
        log_path=self.ini.get('files','log_path').strip()
        log_file="ridirect.log"
        if log_path<>"." and log_path<>"":
            log_file=os.path.join(log_path, log_file)   
        #
        logger=logging.getLogger()
        logger.setLevel(logging.INFO)
        formatter=logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s')
        file_handler = RotatingFileHandler(log_file, 'a', 1000000, 1)

        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)

        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(logging.DEBUG)
        formatter=logging.Formatter('%(asctime)s \t %(filename)s \t %(levelname)s \t %(message)s', "%H:%M:%S")
        stream_handler.setFormatter(formatter)
        logger.addHandler(stream_handler)

        

    def complete_report(self):
        op_path=self.ini.get('files','operations_path')
        #
        # for each site
        #
        for site in os.listdir(op_path):
            #
            # for each techno -2G or 3G-
            #
            site_path=os.path.join(op_path,site)
            for techno in os.listdir(site_path):
                tech_path=os.path.join(site_path,techno)
                #
                # Check content
                #
                complete_report_present=False
                measurement_present=False
                for f in os.listdir(tech_path):
                    if f.startswith('Complete'):
                        complete_report_present=True;
                    if f=="measurement":
                        measurement_present=True
                #
                # if "Complete_" report is lacking and measurements are present
                #
                if not complete_report_present and measurement_present:
                    #
                    # proceed with merge
                    #
                    logging.info("Merging "+tech_path)
                    try:
                        self.merge(tech_path)
                    except Exception as e:
                        logging.error(e)
                        logging.error("Cannot restore formulas for "+tech_path)


                        
    def merge(self, folder):
        #
        # get techno from folder path, not from filename because it may be dualtech
        #
        ignore_head, techno=os.path.split(folder)
        subfolder ="report"
        #
        # find and analyze the report first
        #
        rf=None
        sector_list=None
        path=os.path.join(folder,subfolder)
        for f in os.listdir(path):
            #
            # loop is needed because filename is unknown.
            # Only one file is present in principle.
            #
            if self.report.parse_filename(f):
                #
                # open report
                #
                rf=Report_file(folder,f,techno)
                rf.open_in()
                #
                # version number for the report template  (to guide mapping)
                # ex V1.3c
                #
                version=rf.get_version()
                #
                # get list of sectors from report
                #
                # dict 2G900, 2G1800, 3G 900, 3G 1800 where dict[3G 1800]=(12, 234, 33)
                #
                sector_list=rf.get_sectors()
                break
        #
        # report not properly analysed,
        # discontinue - complete file will not be created
        #
        if rf is None:
            return
        if sector_list is None:
            return
        if len(sector_list)==0:
            return
        #
        # then, first loop on measurements to
        # to take an inventory and
        # check that they match the sectors
        # if not an error is logged
        #
        measured_sector_list=[]
        for f in os.listdir(os.path.join(folder, "measurement")): #todo check naming
            m=self.measurement.parse_filename(f)
            if m:
                if m.sector in sector_list[(m.techno,m.band)]:
                    if m.sector not in measured_sector_list:
                        measured_sector_list.append(m.sector)
                else:
                    logging.error("Foreign "+techno+" sector "+m.sector+" for "+rf.filename)
        #
        # count total number of sectors found in the report
        # compare it with the number of sectors mentionned in measurements
        #
        unique_sector_list=[]
        for tec, ban in sector_list:
            for sector in sector_list[(tec,ban)]:
                if sector not in unique_sector_list:
                    unique_sector_list.append(sector)
        if len(measured_sector_list)<>len(unique_sector_list):
            logging.error("Measurements do not match "+m.techno+" sectors for "+rf.filename)
        #
        # create the write-enabled copy of the report, so that we are ready to insert
        #
        rf.open_out()
        #
        # second loop on measurements to collect the mesures with the filenames sorted
        # in ascending order
        # only the matching sectors are processed
        #
        modified=False
        subfolder="measurement"
        for f in sorted(os.listdir(os.path.join(folder, subfolder))): #todo check naming
            m=self.measurement.parse_filename(f)
            if m:
                if m.sector in sector_list[(m.techno, m.band)]:
                    #
                    #
                    #
                    mf=Measurement_file(os.path.join(folder, subfolder, f), m.techno, m.sector)
                    mf.open()
                    #
                    # collect the measurements
                    # we need to pass the mapping limited to the version of the report, the techno and the band
                    #
                    measurements=mf.get_measurements(self.mapping.get_subset(m.techno, m.band, version))
                    #
                    # stuff the measurements in the report
                    #
                    for measure in measurements.keys():
                        if m.techno=="3G" and m.band=="2100":
                            step=4
                        else:
                            step=1
                        if not modified:
                            rf.restore_formulas()
                        rf.insert(sector_list[(m.techno,m.band)].index(m.sector), measure,measurements[measure],step,m.band)
                        modified=True
        #
        # save the report with a new name starting with Complete_ and copy it to
        # outbox for future sending
        #
        if modified:
            rf.close(self.outbox)

        

    def run(self):
        logging.info("Start "+self.version)
        #
        # Collect measurements
        #
        self.measurement=Measurement(None,self.ini)
        #
        #
        if self.want_collect_measurements:
            self.measurement.collect_new()
        #
        # Collect raw_reports
        #
        #
        self.report=Report(None, self.ini)
        if self.want_collect_reports:
            self.report.collect_new()
        #
        # Dispatch raw_reports
        #
        if self.want_dispatch_reports:
            self.report.dispatch_new()
        #
        # Dispatch measurements
        #
        if self.want_dispatch_measurements:
            self.measurement.dispatch_new()
        #
        # Load mappings (how to transfer the values found in measurements in the reports)
        #
        self.mapping=Mapping(None, self.ini)
        self.mapping.load()
        #
        # Complete reports
        #
        if self.want_run_merge:
            self.complete_report()
        # 
        # send files from outbox and erase them one by one
        #
        if self.want_send_ftp:
            sender=Ftp_sender(None,self.ini)
            sender.send_all()
        #
        logging.info("Stop")