<commit_before>
def read(stream):
    return CSVReader(stream)


class CSVReader:
    def __init__(self, stream, rowparser=None):
        self.stream = stream

    def __next__(self):
        line = self.stream.readline()
        return self.parse_row(line)

    def parse_row(self, line):
        pass
<commit_msg>Implement csv.py<commit_after>from picdump.pixiv import item
from picdump.pixiv import illust
from picdump.pixiv import manga


CSV_DELIMITER = ','
NEWLINE = '\n'


class ItemFactory:
    def __call__(self, row):
        if row.pages == '':
            return illust.Illust(row)
        else:
            return manga.Manga(row)


def parse(doc):
    item_factory = ItemFactory()
    for line in doc.split(NEWLINE):
        if line == '':
            continue
        row = CSVRow(line)
        yield item_factory(row)


class CSVRow:
    CELLS = {
        'illust_id': 0,
        'author_id': 1,
        'extension': 2,
        'title': 3,
        'server': 4,
        'author_screen_name': 5,
        'thumbnail': 6,
        'mobile_image': 9,
        'timestamp': 12,
        'tags': 13,
        'tools': 14,
        'comments': 15,
        'points': 16,
        'views': 17,
        'caption': 18,
        'pages': 19,
        'author_name': 24,
        'author_thumbnail': 29
    }

    def __init__(self, line, delimiter=CSV_DELIMITER):
        self.cells = [c.strip('"') for c in line.split(delimiter)]

    def __getattr__(self, key):
        if not key in self.CELLS:
            raise AttributeError()
        else:
            col = self.CELLS[key]
            return self.cells[col]

    def __getitem__(self, index):
        return self.cells[index]

    def __contains__(self, key):
        return key in self.CELLS


class CSVReader:
    def __init__(self, doc):
        self.doc = doc

    def __iter__(self):
        return self

    def __next__(self):
        line = self.stream.readline()
        if not line:  # Reaches end
            raise StopIteration()
        return self.parse_row(line)

    def on_closing(self):
        if self.close_on_finish:
            self.stream.close()

    def parse_row(self, line):
        pass




{'fraction_non_alphanumeric': 0.11290322580645161, 'fraction_numerical': 0.012903225806451613, 'mean_word_length': 1.9780521262002744, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '194104', 'n_tokens_mistral': 738, 'n_tokens_neox': 679, 'n_words': 175}