Ejemplo n.º 1
0
Archivo: excel.py Proyecto: leofigs/bag
def excel_reader(stream, worksheet_name=None, required_headers=[]):
    '''Reads an XLSX file (from ``stream``) and yields objects so you can
        access the values conveniently.

        You can pass in the ``worksheet_name`` to be read.  If not passed in or
        not present in the file, the first worksheet will be read.

        In addition, you may pass a sequence of *required_headers*, and if they
        aren't all present, KeyError is raised.

        Let's see an example. Suppose you are reading some Excel file and
        all you know is it contains the columns "E-mail", "Full Name" and
        "Gender", not necessarily in that order::

            reader = excel_reader(
                open('contacts.xlsx', mode='rb'),
                worksheet_name='Mailing',
                required_headers=['E-mail', 'Full Name', 'Gender'])
            for o in reader:
                print(o.full_name, o.e_mail, o.gender)
        '''
    try:
        wb = load_workbook(stream, data_only=True)
    except (BadZipFile, InvalidFileException) as e:
        raise Problem(
            _('That is not an XLSX file.'),
            error_title=_('Unable to read the XLSX file'), error_debug=str(e))

    # Grab either the worksheet named "Assets", or simply the first one
    if worksheet_name and worksheet_name in wb:
        sheet = wb[worksheet_name]
    else:
        sheet = wb[wb.sheetnames[0]]

    this_is_the_first_row = True
    for row in sheet.rows:
        if this_is_the_first_row:  # Read and validate the headers
            this_is_the_first_row = False
            headers = [cell.value for cell in row]
            raise_if_missing_required_headers(headers, required_headers)
            vars = get_corresponding_variable_names(headers, required_headers)
            index_of_var = {var: i for i, var in enumerate(vars)}

            class SpreadsheetRow(object):
                '''View on a spreadsheet row so you can access data as if
                    they were instance variables.
                    '''
                __slots__ = ('__cells',)

                def __init__(self, cells):
                    self.__cells = cells

                def __getattr__(self, attr):
                    content = self.__cells[index_of_var[attr]].value
                    return content

        else:
            yield SpreadsheetRow(row)
Ejemplo n.º 2
0
def raise_if_missing_required_headers(headers, required_headers=[], case_sensitive=False):
    '''Raises KeyError if the ``required_headers`` aren't all present in
        ``headers``.
        '''
    if not case_sensitive:
        headers = [h.lower() if h else None for h in headers]
        missing_headers = [h for h in required_headers
                           if h.lower() not in headers]
    else:
        missing_headers = [h for h in required_headers if h not in headers]

    if missing_headers:
        if len(missing_headers) == 1:
            msg = _('The spreadsheet is missing the required header: ')
        else:
            msg = _('The spreadsheet is missing the required headers: ')
        raise KeyError(
            msg + ', '.join(['"{}"'.format(h) for h in missing_headers]))
Ejemplo n.º 3
0
Archivo: views.py Proyecto: leofigs/bag
def maybe_raise_unprocessable(e, **adict):
    '''If the provided exception looks like a validation error, raise
        422 Unprocessable Entity, optionally with additional information.
        '''
    if hasattr(e, 'asdict') and callable(e.asdict):
        error_msg = getattr(
            e, 'error_msg', _('Please correct error(s) in the form.'))
        adict['invalid'] = e.asdict()
        adict.setdefault('error_title', 'Invalid')
        adict.setdefault('error_msg', error_msg)
        raise HTTPError(
            status_int=422,  # Unprocessable Entity
            content_type='application/json',
            body=dumps(adict),
            detail=error_msg,  # could be shown to end users
            # *comment* is not displayed to end users:
            comment=str(e) or 'Form validation error',
            )
Ejemplo n.º 4
0
Archivo: burla.py Proyecto: leofigs/bag
    pages: PAGES,
    ops: OPERATIONS,

    _find: function (map, name, options) {
        var s = map[name].url_templ;
        if (!s)  throw new Error('burla: No item called "' + name + '".');
        for (var key in options) {
            var placeholder = ':' + key;
            if (s.indexOf(placeholder) == -1) {
                throw new Error('burla: URL template "' + name + '" does not use parameter "' + key + '".');
            }
            var val = options[key];
            if (val == null)  throw new Error('burla: Operation "' + name + '" needs parameter "' + key + '".');
            s = s.replace(placeholder, val);
        }
        return this.root + s;
    },

    page: function (name, options) { return this._find(this.pages, name, options); },
    op: function (name, options) { return this._find(this.ops, name, options); },
}\n''' \
            .replace('PAGES', dumps(
                {o.name: o.to_dict() for o in self.gen_pages()},
                sort_keys=True)) \
            .replace('OPERATIONS', dumps(
                {o.name: o.to_dict() for o in self.gen_ops()},
                sort_keys=True)) \
            .replace('ROOT', dumps(self.root))

DOC_TITLE = _('HTTP API Documentation')