コード例 #1
0
ファイル: excel.py プロジェクト: yeleman/bolibana
    def __init__(self, filepath, sheet=None, version=None):

        self.errors = ErrorManager()

        if version:
            self.version = version

        self.filepath = filepath
        self.sheet = sheet
        self.read()
コード例 #2
0
ファイル: excel.py プロジェクト: yeleman/bolibana
class ExcelForm(object):

    """ A Form in an Excel File """

    _mapping = {None: {}}
    version = None
    data = {}

    def __init__(self, filepath, sheet=None, version=None):

        self.errors = ErrorManager()

        if version:
            self.version = version

        self.filepath = filepath
        self.sheet = sheet
        self.read()

    def read(self, sheet=None):
        """ parses all fields in mapping and stores converted data """
        if not sheet:
            sheet = self.sheet

        # one can re-call read() at any time
        self.errors.reset()

        try:
            book = xlrd.open_workbook(self.filepath)
            if isinstance(sheet, basestring):
                self.ws = book.sheet_by_name(sheet)
            elif isinstance(sheet, int):
                self.ws = book.sheets()[sheet]
            else:
                self.ws = book.sheets()[0]
        except Exception as e:
            logger.warning(u"Unable to read Excel Uploaded file %(path)s. "
                           "Raised %(e)r" % {'path': self.filepath, 'e': e})
            self.errors.add(u"Impossible d'ouvrir le masque de saisie. "
                            u"Le fichier est corrompu ou a été modifié.")
            return

        for fieldid, field in self.mapping().items():
            self.map_field(field, fieldid)

    def mapping(self):
        """ dict mapping of the current version """
        if self.version:
            return self._mapping[self.version]
        else:
            return self._mapping[self._mapping.keys()[0]]

    def data_for_coord(self, coord):
        """ raw data from Excel coordinates """
        XLS_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        letter, line = re.match(r'([a-zA-Z]+)([0-9]+)', coord).groups()
        row = int(line) - 1
        column = XLS_LETTERS.index(letter.upper())
        return self.ws.row_values(row)[column]

    def field_name(self, variable):
        """ name of field from slug """
        return self.mapping()[variable].display_name()

    def get(self, variable, silent=False):
        """ value of field from slug. Silent returns None instaed of raise """
        try:
            return self.data[variable]
        except KeyError:
            if silent:
                return None
            raise MissingData

    def set(self, variable, value):
        """ store value for that slug variable """
        self.data[variable] = value

    def map_field(self, field, variable):
        """ retrieve and store data from excel to mapping for field+slug """
        # raw data
        fdata = self.data_for_coord(field.coord)
        try:
            self.set(variable, field.convert_data(fdata))
        except ValueError as e:
            # field is blank
            if ExcelTypeConverter.clean_str(fdata).__len__() == 0:
                self.set(variable, None)
            else:
                self.value_error(fdata, field, variable, e)

    def value_error(self, data, field, variable, exception):
        """ adds an error if data is not valid """
        self.errors.add(_("%(data)s is not a valid data for %(field)s")
                        % {'data': data, 'field': field.display_name()})

    def is_valid(self, *args, **kwargs):
        """ [override] complete with no errors ? """
        # check completeness
        if self.is_complete(*args, **kwargs):
            # check for errors
            self.validate(*args, **kwargs)

        return self.errors.count() == 0

    def is_complete(self, *args, **kwargs):
        """ [override] required fields filled? """
        return False

    def to_dict(self):
        """ raw dict of all data """
        return self.data