#!/usr/bin/env python
"""
General class for parsing data extracted from Unicorn and generating
COPY-formatted data for loading into Evergreen staging tables.
"""

#    Copyright (C) 2009, Dan Scott
#    Thanks to the Robertson Library, UPEI, for funding these scripts. 

#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import csv
import datetime
import re

class Parser(object):
    """
    Parse data that was exported from Unicorn using the Unicorn API.
    """
    def __init__(self, file_in, file_out, fields_in=(), fields_out=(), date_fields=()):
        """
        Initialize the parser. Currently input and output files are mandatory.
        You also will not get very far if you have no input fields.
        """
        self.file_in = open(file_in, 'r')
        self.file_out = open(file_out, 'w')
        self.fields_in = fields_in
        if len(fields_out) == 0:
            self.fields_out = self.fields_in
        else:
            self.fields_out = fields_out
        print self.fields_in
        print self.fields_out
        self.reader = csv.DictReader(self.file_in, self.fields_in, None, None, quotechar='"', delimiter='|', escapechar=None)
    
    def dump_fields(self, fields=None, date_fields=()):
        """
        Normalize the data and dump it back out
        """
        if not fields:
            fields = self.fields_out
            
        for row in self.reader:
            for field in self.fields_out:
                value = r'\N'
                if field in date_fields:
                    value = self.normalize_date(row[field])
                else:            
                    # only barcode needs stripping, but it won't hurt anything else
                    value = row[field].rstrip()

                # avoid escaped values in any of these strings
                if value != r'\N':
                    escaped_value = value.replace('\\', '\\\\')
                else:
                    escaped_value = value
                self.file_out.write(escaped_value)
                
                # delimit with a tab unless this is the last field
                if field != self.fields_out[-1]:
                    self.file_out.write("\t")
            self.file_out.write("\n")
    
    def normalize_date(self, date):
        """
        Normalizes date to PostgreSQL standard Y-M-D
        """
        if len(date) < 2:
            return r'\N'
        normal_date = datetime.date(int(date[0:4]), int(date[4:6]), int(date[6:8])).isoformat()
        return normal_date


