Source

orderfilter / orderfilter.py

# -*- coding: utf-8 -*-
# Author:   Joel Wang <joel_wang@wistron.com>

"""The main program. """

import os
import sys
import glob
from fnmatch import fnmatch
from time import sleep

from wistron.gcf import GCF, GCFError
from wistron.sdrparser2 import SDR2, SDRError

from config import cfg, VERSION, MatchObj
from reporter import report_failed
from operations import pass_process, fail_process


def multiglob(path, globs=[]):
    "glob with multiple criterias. "
    filepaths = []
    for g in globs:
        filepaths.extend(glob.glob(os.path.join(path, g)))
    return filepaths


class Invalid:
    """An adapter class or invalid XML files, used in fail_process()"""
    def __init__(self, filepath):
        self.filepath = filepath
        if fnmatch(filepath, '*.xml'):
            self.type = 'GCF'
        elif fnmatch(filepath, '*.txt') or fnmatch(filepath, '*.sdr'):
            self.type = 'SDR'
        else:
            self.type = ''


class OrderError(Exception):
    pass


class Order(object):
    "Adapter for GCF and SDR"
    def __init__(self, order):
        if fnmatch(order, '*.xml'):
            self.type = 'GCF'
            self.filepath = order
            try:
                self.obj = GCF(order)
            except GCFError, e:
                raise OrderError(e)
            self.po = self.obj.po
        elif fnmatch(order, '*.sdr') or fnmatch(order, "*.txt"):
            self.type = "SDR"
            self.filepath = order
            try:
                self.obj = SDR2(order)
            except SDRError, e:
                raise OrderError(e)
        else:
            raise OrderError("Unknown order type")
    def sdrlines(self):
        if self.type == 'GCF':
            return self.obj.sdrlines()
        elif self.type == 'SDR':
            return self.obj.sdrlines


def main(cfg):
    print "Order filter (version %s) started." % VERSION
    globs = ['*.xml', '*.txt', '*.sdr']
    cfg.init_dirs()
    while True:

        if cfg.is_changed():
            cfg.load()
            print "Rules loaded."

        report_failed(cfg)

        ordernames = multiglob(cfg.srcdir, globs)

        # Reduce loop intensity and lower CPU usage.
        sleep(3)

        for orderpath in ordernames:
            try:
                order = Order(orderpath)
            except OrderError, e:
                fail_process(cfg, Invalid(orderpath), MatchObj('invalid'))
                continue

            match = None
            for rule in cfg.rules:
                try:
                    match = rule.match(order.obj)
                except SDRError, e:
                    fail_process(cfg, Invalid(orderpath), MatchObj('invalid'))
                    break

                if match:
                    fail_process(cfg, order, match)
                    break
            
            if not match:
                pass_process(cfg, order)
            
if __name__ == '__main__':
    try:
        import psyco
        psyco.full()
    except ImportError:
        print 'Psyco not installed, the program will just run slower'    
    sys.exit(main(cfg))