Exemple #1
0
def export_to_csv(
    table,
    filename_or_fobj=None,
    encoding="utf-8",
    dialect=unicodecsv.excel,
    batch_size=100,
    callback=None,
    *args,
    **kwargs
):
    """Export a `rows.Table` to a CSV file.


    If a file-like object is provided it MUST be in binary mode, like in
    `open(filename, mode='wb')`.
    If not filename/fobj is provided, the function returns a string with CSV
    contents.
    """
    # TODO: will work only if table.fields is OrderedDict
    # TODO: should use fobj? What about creating a method like json.dumps?

    if filename_or_fobj is not None:
        _, fobj = get_filename_and_fobj(filename_or_fobj, mode="wb")
    else:
        fobj = BytesIO()

    # TODO: may use `io.BufferedWriter` instead of `ipartition` so user can
    # choose the real size (in Bytes) when to flush to the file system, instead
    # number of rows
    writer = unicodecsv.writer(fobj, encoding=encoding, dialect=dialect)

    if callback is None:
        for batch in ipartition(serialize(table, *args, **kwargs), batch_size):
            writer.writerows(batch)

    else:
        serialized = serialize(table, *args, **kwargs)
        writer.writerow(next(serialized))  # First, write the header
        total = 0
        for batch in ipartition(serialized, batch_size):
            writer.writerows(batch)
            total += len(batch)
            callback(total)

    if filename_or_fobj is not None:
        fobj.flush()
        return fobj
    else:
        fobj.seek(0)
        result = fobj.read()
        fobj.close()
        return result
Exemple #2
0
def export_to_csv(table,
                  filename_or_fobj=None,
                  encoding="utf-8",
                  dialect=unicodecsv.excel,
                  batch_size=100,
                  callback=None,
                  *args,
                  **kwargs):
    """Export a `rows.Table` to a CSV file.


    If a file-like object is provided it MUST be in binary mode, like in
    `open(filename, mode='wb')`.
    If not filename/fobj is provided, the function returns a string with CSV
    contents.
    """
    # TODO: will work only if table.fields is OrderedDict
    # TODO: should use fobj? What about creating a method like json.dumps?

    if filename_or_fobj is not None:
        _, fobj = get_filename_and_fobj(filename_or_fobj, mode="wb")
    else:
        fobj = BytesIO()

    # TODO: may use `io.BufferedWriter` instead of `ipartition` so user can
    # choose the real size (in Bytes) when to flush to the file system, instead
    # number of rows
    writer = unicodecsv.writer(fobj, encoding=encoding, dialect=dialect)

    if callback is None:
        for batch in ipartition(serialize(table, *args, **kwargs), batch_size):
            writer.writerows(batch)

    else:
        serialized = serialize(table, *args, **kwargs)
        writer.writerow(next(serialized))  # First, write the header
        total = 0
        for batch in ipartition(serialized, batch_size):
            writer.writerows(batch)
            total += len(batch)
            callback(total)

    if filename_or_fobj is not None:
        fobj.flush()
        return fobj
    else:
        fobj.seek(0)
        result = fobj.read()
        fobj.close()
        return result
Exemple #3
0
def export_to_sqlite(table_obj, filename_or_connection, table_name='rows',
                     batch_size=100, *args, **kwargs):
    # TODO: should add transaction support?


    serialized_table = serialize(table_obj, *args, **kwargs)
    connection = _get_connection(filename_or_connection)
    table_names = [item[0]
                   for item in connection.execute(SQL_TABLE_NAMES).fetchall()]
    table_name = make_unique_name(name=table_name, existing_names=table_names)

    field_names = serialized_table.next()
    columns = ['{} {}'.format(field_name,
                              SQLITE_TYPES[table_obj.fields[field_name]])
               for field_name in field_names]
    sql = SQL_CREATE_TABLE.format(table_name=table_name,
                                  field_types=', '.join(columns))
    connection.execute(sql)

    columns = ', '.join(field_names)
    placeholders = ', '.join(['?' for field in field_names])
    insert_sql = SQL_INSERT.format(table_name=table_name,
                                   field_names=columns,
                                   placeholders=placeholders)
    field_types = [table_obj.fields[field_name] for field_name in field_names]
    for batch in ipartition(serialized_table, batch_size):
        rows_values = [[_convert(field_types[index], value)
                        for index, value in enumerate(row)]
                       for row in batch]
        connection.executemany(insert_sql, rows_values)

    connection.commit()
    return connection
Exemple #4
0
def export_to_csv(table, filename_or_fobj=None, encoding='utf-8',
                  dialect=unicodecsv.excel, *args, **kwargs):
    '''Export a `rows.Table` to a CSV file

    If a file-like object is provided it MUST be in binary mode, like in
    `open(filename, mode='wb')`.
    If not filename/fobj is provided, the function returns a string with CSV
    contents.
    '''
    # TODO: will work only if table.fields is OrderedDict
    # TODO: should use fobj? What about creating a method like json.dumps?

    if filename_or_fobj is not None:
        _, fobj = get_filename_and_fobj(filename_or_fobj, mode='wb')
    else:
        fobj = BytesIO()

    writer = unicodecsv.writer(fobj, encoding=encoding, dialect=dialect)
    for row in serialize(table, *args, **kwargs):
        writer.writerow(row)

    if filename_or_fobj is not None:
        fobj.flush()
        return fobj
    else:
        fobj.seek(0)
        result = fobj.read()
        fobj.close()
        return result
Exemple #5
0
def export_to_txt(table, filename_or_fobj=None, encoding='utf-8', *args, **kwargs):
    # TODO: should be able to change DASH, PLUS and PIPE
    # TODO: will work only if table.fields is OrderedDict
    # TODO: should use fobj? What about creating a method like json.dumps?

    kwargs['encoding'] = encoding
    serialized_table = serialize(table, *args, **kwargs)
    field_names = serialized_table.next()
    table_rows = list(serialized_table)
    max_sizes = _max_column_sizes(field_names, table_rows)

    dashes = [DASH * (max_sizes[field] + 2) for field in field_names]
    header = [field.center(max_sizes[field]) for field in field_names]
    header = '{} {} {}'.format(PIPE, ' {} '.format(PIPE).join(header), PIPE)
    split_line = PLUS + PLUS.join(dashes) + PLUS

    result = [split_line, header, split_line]
    for row in table_rows:
        values = [value.rjust(max_sizes[field_name])
                  for field_name, value in zip(field_names, row)]
        row_data = ' {} '.format(PIPE).join(values)
        result.append('{} {} {}'.format(PIPE, row_data, PIPE))
    result.extend([split_line, ''])
    data = '\n'.join(result).encode(encoding)

    return export_data(filename_or_fobj, data)
Exemple #6
0
def export_to_txt(table,
                  filename_or_fobj=None,
                  encoding='utf-8',
                  *args,
                  **kwargs):
    # TODO: should be able to change DASH, PLUS and PIPE
    # TODO: will work only if table.fields is OrderedDict
    # TODO: should use fobj? What about creating a method like json.dumps?

    kwargs['encoding'] = encoding
    serialized_table = serialize(table, *args, **kwargs)
    field_names = serialized_table.next()
    table_rows = list(serialized_table)
    max_sizes = _max_column_sizes(field_names, table_rows)

    dashes = [DASH * (max_sizes[field] + 2) for field in field_names]
    header = [field.center(max_sizes[field]) for field in field_names]
    header = '{} {} {}'.format(PIPE, ' {} '.format(PIPE).join(header), PIPE)
    split_line = PLUS + PLUS.join(dashes) + PLUS

    result = [split_line, header, split_line]
    for row in table_rows:
        values = [
            value.rjust(max_sizes[field_name])
            for field_name, value in zip(field_names, row)
        ]
        row_data = ' {} '.format(PIPE).join(values)
        result.append('{} {} {}'.format(PIPE, row_data, PIPE))
    result.extend([split_line, ''])
    data = '\n'.join(result).encode(encoding)

    return export_data(filename_or_fobj, data)
Exemple #7
0
def export_to_csv(table,
                  filename_or_fobj=None,
                  encoding='utf-8',
                  dialect=unicodecsv.excel,
                  *args,
                  **kwargs):
    '''Export a `rows.Table` to a CSV file

    If a file-like object is provided it MUST be in binary mode, like in
    `open(filename, mode='wb')`.
    If not filename/fobj is provided, the function returns a string with CSV
    contents.
    '''
    # TODO: will work only if table.fields is OrderedDict
    # TODO: should use fobj? What about creating a method like json.dumps?

    if filename_or_fobj is not None:
        _, fobj = get_filename_and_fobj(filename_or_fobj, mode='wb')
    else:
        fobj = BytesIO()

    writer = unicodecsv.writer(fobj, encoding=encoding, dialect=dialect)
    for row in serialize(table, *args, **kwargs):
        writer.writerow(row)

    if filename_or_fobj is not None:
        fobj.flush()
        return fobj
    else:
        fobj.seek(0)
        result = fobj.read()
        fobj.close()
        return result
Exemple #8
0
    def test_serialize(self):
        result = plugins_utils.serialize(utils.table)
        field_types = utils.table.fields.values()
        self.assertEqual(result.next(), utils.table.fields.keys())

        for row, expected_row in zip(result, utils.table._rows):
            values = [field_type.serialize(value)
                      for field_type, value in zip(field_types, expected_row)]
            self.assertEqual(values, row)
Exemple #9
0
 def test_serialize_should_call_prepare_to_export(self, mocked_prepare_to_export):
     table = utils.table
     kwargs = {"export_fields": 123, "other_parameter": 3.14}
     result = plugins_utils.serialize(table, **kwargs)
     self.assertFalse(mocked_prepare_to_export.called)
     field_names, table_rows = next(result), list(result)
     self.assertTrue(mocked_prepare_to_export.called)
     self.assertEqual(mocked_prepare_to_export.call_count, 1)
     self.assertEqual(mock.call(table, **kwargs), mocked_prepare_to_export.call_args)
Exemple #10
0
def export_to_html(table, filename_or_fobj=None, encoding="utf-8", *args, **kwargs):
    """Export and return rows.Table data to HTML file."""
    serialized_table = serialize(table, *args, **kwargs)
    fields = next(serialized_table)
    result = ["<table>\n\n", "  <thead>\n", "    <tr>\n"]
    header = ["      <th> {} </th>\n".format(field) for field in fields]
    result.extend(header)
    result.extend(["    </tr>\n", "  </thead>\n", "\n", "  <tbody>\n", "\n"])
    for index, row in enumerate(serialized_table, start=1):
        css_class = "odd" if index % 2 == 1 else "even"
        result.append('    <tr class="{}">\n'.format(css_class))
        for value in row:
            result.extend(["      <td> ", escape(value), " </td>\n"])
        result.append("    </tr>\n\n")
    result.append("  </tbody>\n\n</table>\n")
    html = "".join(result).encode(encoding)

    return export_data(filename_or_fobj, html, mode="wb")
Exemple #11
0
def export_to_html(table, filename_or_fobj=None, encoding='utf-8', *args,
                   **kwargs):
    serialized_table = serialize(table, *args, **kwargs)
    fields = next(serialized_table)
    result = ['<table>\n\n', '  <thead>\n', '    <tr>\n']
    header = ['      <th> {} </th>\n'.format(field) for field in fields]
    result.extend(header)
    result.extend(['    </tr>\n', '  </thead>\n', '\n', '  <tbody>\n', '\n'])
    for index, row in enumerate(serialized_table, start=1):
        css_class = 'odd' if index % 2 == 1 else 'even'
        result.append('    <tr class="{}">\n'.format(css_class))
        for value in row:
            result.extend(['      <td> ', escape(value), ' </td>\n'])
        result.append('    </tr>\n\n')
    result.append('  </tbody>\n\n</table>\n')
    html = ''.join(result).encode(encoding)

    return export_data(filename_or_fobj, html, mode='wb')
Exemple #12
0
def export_to_csv(table, filename_or_fobj=None, encoding='utf-8', *args, **kwargs):
    # TODO: will work only if table.fields is OrderedDict
    # TODO: should use fobj? What about creating a method like json.dumps?

    kwargs['encoding'] = encoding
    if filename_or_fobj is not None:
        _, fobj = get_filename_and_fobj(filename_or_fobj, mode='w')
    else:
        fobj = BytesIO()

    csv_writer = unicodecsv.writer(fobj, encoding=encoding)
    map(csv_writer.writerow, serialize(table, *args, **kwargs))

    if filename_or_fobj is not None:
        fobj.flush()
        return fobj
    else:
        fobj.seek(0)
        result = fobj.read()
        fobj.close()
        return result
Exemple #13
0
def export_to_html(table,
                   filename_or_fobj=None,
                   encoding='utf-8',
                   *args,
                   **kwargs):
    serialized_table = serialize(table, *args, **kwargs)
    fields = next(serialized_table)
    result = ['<table>\n\n', '  <thead>\n', '    <tr>\n']
    header = ['      <th> {} </th>\n'.format(field) for field in fields]
    result.extend(header)
    result.extend(['    </tr>\n', '  </thead>\n', '\n', '  <tbody>\n', '\n'])
    for index, row in enumerate(serialized_table, start=1):
        css_class = 'odd' if index % 2 == 1 else 'even'
        result.append('    <tr class="{}">\n'.format(css_class))
        for value in row:
            result.extend(['      <td> ', value, ' </td>\n'])
        result.append('    </tr>\n\n')
    result.append('  </tbody>\n\n</table>\n')
    html = ''.join(result).encode(encoding)

    return export_data(filename_or_fobj, html, mode='wb')
Exemple #14
0
def export_to_html(table, filename_or_fobj=None, encoding='utf-8', *args,
                   **kwargs):
    kwargs['encoding'] = encoding
    serialized_table = serialize(table, *args, **kwargs)
    fields = serialized_table.next()
    result = ['<table>\n\n', '  <thead>\n', '    <tr>\n']
    header = ['      <th> {} </th>\n'.format(field) for field in fields]
    result.extend(header)
    result.extend(['    </tr>\n', '  </thead>\n', '\n', '  <tbody>\n', '\n'])
    for index, row in enumerate(serialized_table, start=1):
        css_class = 'odd' if index % 2 == 1 else 'even'
        result.append('    <tr class="{}">\n'.format(css_class))
        for value in row:
            result.extend(['      <td> ', value, ' </td>\n'])
        result.append('    </tr>\n\n')
    result.append('  </tbody>\n\n</table>\n')
    new_result = [value.encode(encoding) if isinstance(value, unicode)
                  else value
                  for value in result]
    html = ''.encode(encoding).join(new_result)

    return export_data(filename_or_fobj, html)
Exemple #15
0
def export_to_txt(table, filename_or_fobj=None, encoding=None,
                  *args, **kwargs):
    '''Export a `rows.Table` to text

    This function can return the result as a string or save into a file (via
    filename or file-like object).

    `encoding` could be `None` if no filename/file-like object is specified,
    then the return type will be `six.text_type`.
    '''
    # TODO: should be able to change DASH, PLUS and PIPE
    # TODO: will work only if table.fields is OrderedDict

    serialized_table = serialize(table, *args, **kwargs)
    field_names = next(serialized_table)
    table_rows = list(serialized_table)
    max_sizes = _max_column_sizes(field_names, table_rows)

    dashes = [DASH * (max_sizes[field] + 2) for field in field_names]
    header = [field.center(max_sizes[field]) for field in field_names]
    header = '{} {} {}'.format(PIPE, ' {} '.format(PIPE).join(header), PIPE)
    split_line = PLUS + PLUS.join(dashes) + PLUS

    result = [split_line, header, split_line]
    for row in table_rows:
        values = [value.rjust(max_sizes[field_name])
                  for field_name, value in zip(field_names, row)]
        row_data = ' {} '.format(PIPE).join(values)
        result.append('{} {} {}'.format(PIPE, row_data, PIPE))
    result.extend([split_line, ''])
    data = '\n'.join(result)

    if encoding is not None:
        data = data.encode(encoding)

    return export_data(filename_or_fobj, data, mode='wb')
Exemple #16
0
def export_to_txt(table,
                  filename_or_fobj=None,
                  encoding=None,
                  frame_style="ASCII",
                  safe_none_frame=True,
                  *args,
                  **kwargs):
    """Export a `rows.Table` to text.

    This function can return the result as a string or save into a file (via
    filename or file-like object).

    `encoding` could be `None` if no filename/file-like object is specified,
    then the return type will be `six.text_type`.
    `frame_style`: will select the frame style to be printed around data.
    Valid values are: ('None', 'ASCII', 'single', 'double') - ASCII is default.
    Warning: no checks are made to check the desired encoding allows the
    characters needed by single and double frame styles.

    `safe_none_frame`: bool, defaults to True. Affects only output with
    frame_style == "None":
    column titles are left-aligned and have
    whitespace replaced for "_".  This enables
    the output to be parseable. Otherwise, the generated table will look
    prettier but can not be imported back.
    """
    # TODO: will work only if table.fields is OrderedDict

    frame_style = _parse_frame_style(frame_style)
    frame = FRAMES[frame_style.lower()]

    serialized_table = serialize(table, *args, **kwargs)
    field_names = next(serialized_table)
    table_rows = list(serialized_table)
    max_sizes = _max_column_sizes(field_names, table_rows)

    dashes = [
        frame['HORIZONTAL'] * (max_sizes[field] + 2) for field in field_names
    ]

    if frame_style != 'None' or not safe_none_frame:
        header = [field.center(max_sizes[field]) for field in field_names]
    else:
        header = [
            field.replace(" ", "_").ljust(max_sizes[field])
            for field in field_names
        ]
    header = '{0} {1} {0}'.format(
        frame['VERTICAL'], ' {} '.format(frame['VERTICAL']).join(header))
    top_split_line = (frame['DOWN AND RIGHT'] +
                      frame['DOWN AND HORIZONTAL'].join(dashes) +
                      frame['DOWN AND LEFT'])

    body_split_line = (frame['VERTICAL AND RIGHT'] +
                       frame['VERTICAL AND HORIZONTAL'].join(dashes) +
                       frame['VERTICAL AND LEFT'])

    botton_split_line = (frame['UP AND RIGHT'] +
                         frame['UP AND HORIZONTAL'].join(dashes) +
                         frame['UP AND LEFT'])

    result = []
    if frame_style != 'None':
        result += [top_split_line]
    result += [header, body_split_line]

    for row in table_rows:
        values = [
            value.rjust(max_sizes[field_name])
            for field_name, value in zip(field_names, row)
        ]
        row_data = ' {} '.format(frame['VERTICAL']).join(values)
        result.append('{0} {1} {0}'.format(frame['VERTICAL'], row_data))

    if frame_style != 'None':
        result.append(botton_split_line)
    result.append('')
    data = '\n'.join(result)

    if encoding is not None:
        data = data.encode(encoding)

    return export_data(filename_or_fobj, data, mode='wb')
Exemple #17
0
def export_to_txt(
    table,
    filename_or_fobj=None,
    encoding=None,
    frame_style="ASCII",
    safe_none_frame=True,
    *args,
    **kwargs
):
    """Export a `rows.Table` to text.

    This function can return the result as a string or save into a file (via
    filename or file-like object).

    `encoding` could be `None` if no filename/file-like object is specified,
    then the return type will be `six.text_type`.
    `frame_style`: will select the frame style to be printed around data.
    Valid values are: ('None', 'ASCII', 'single', 'double') - ASCII is default.
    Warning: no checks are made to check the desired encoding allows the
    characters needed by single and double frame styles.

    `safe_none_frame`: bool, defaults to True. Affects only output with
    frame_style == "None":
    column titles are left-aligned and have
    whitespace replaced for "_".  This enables
    the output to be parseable. Otherwise, the generated table will look
    prettier but can not be imported back.
    """
    # TODO: will work only if table.fields is OrderedDict

    frame_style = _parse_frame_style(frame_style)
    frame = FRAMES[frame_style.lower()]

    serialized_table = serialize(table, *args, **kwargs)
    field_names = next(serialized_table)
    table_rows = list(serialized_table)
    max_sizes = _max_column_sizes(field_names, table_rows)

    dashes = [frame["HORIZONTAL"] * (max_sizes[field] + 2) for field in field_names]

    if frame_style != "None" or not safe_none_frame:
        header = [field.center(max_sizes[field]) for field in field_names]
    else:
        header = [
            field.replace(" ", "_").ljust(max_sizes[field]) for field in field_names
        ]
    header = "{0} {1} {0}".format(
        frame["VERTICAL"], " {} ".format(frame["VERTICAL"]).join(header)
    )
    top_split_line = (
        frame["DOWN AND RIGHT"]
        + frame["DOWN AND HORIZONTAL"].join(dashes)
        + frame["DOWN AND LEFT"]
    )

    body_split_line = (
        frame["VERTICAL AND RIGHT"]
        + frame["VERTICAL AND HORIZONTAL"].join(dashes)
        + frame["VERTICAL AND LEFT"]
    )

    botton_split_line = (
        frame["UP AND RIGHT"]
        + frame["UP AND HORIZONTAL"].join(dashes)
        + frame["UP AND LEFT"]
    )

    result = []
    if frame_style != "None":
        result += [top_split_line]
    result += [header, body_split_line]

    for row in table_rows:
        values = [
            value.rjust(max_sizes[field_name])
            for field_name, value in zip(field_names, row)
        ]
        row_data = " {} ".format(frame["VERTICAL"]).join(values)
        result.append("{0} {1} {0}".format(frame["VERTICAL"], row_data))

    if frame_style != "None":
        result.append(botton_split_line)
    result.append("")
    data = "\n".join(result)

    if encoding is not None:
        data = data.encode(encoding)

    return export_data(filename_or_fobj, data, mode="wb")