+copyright
[burette/bikecoop_init.git] / tools / scripts / csv2xml.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 # Bikecoop Init for OpenERP, Tools for begin a Bikecoop OpenERP project
5 # Copyright (C) 2017 L'Heureux Cyclage (<http://www.heureux-cyclage.org>)
6 # Ludovic CHEVALIER
7 #
8 # This file is a part of Bikecoop Init
9 #
10 # Bikecoop Init is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation, either version 3 of the License, or
13 # (at your option) any later version.
14 #
15 # Bikecoop Init is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #
23 ##############################################################################
24
25 from sys import argv
26 import os
27 from lxml import etree
28 from description import ds, xml_prefix, files
29 import csv
30 # import datetime
31 # from dateutil.relativedelta import relativedelta
32
33 base_dir = './../..'
34 debug = 0
35 nodisplay = 0
36 limit = 0
37 noupdate = 0
38
39 for arg in argv:
40 if arg[:2] == '--':
41 arg = arg[2:]
42 if arg == 'help':
43 print('Membership Import documentation')
44 print('===============================')
45 print(' --help: read this doc.')
46 print(' --debug: debug mode. Displays debug messages and doesn\'t generate xml files.')
47 print(' --noupdate: add noupdate feature in xml files.')
48 print(' --nodisplay: no display result in standard output and write it in previous files. This is not compatible with debug mode.')
49 exit(0)
50 elif arg == 'debug':
51 debug = 1
52 elif arg == 'noupdate':
53 noupdate = 1
54 elif arg == 'nodisplay':
55 nodisplay = 1
56
57
58 def create_xml_tree():
59 openerp = etree.Element('openerp')
60 if noupdate:
61 data = etree.SubElement(openerp, 'data', noupdate="1")
62 else:
63 data = etree.SubElement(openerp, 'data')
64 return (openerp, data)
65
66
67 def pass_head(f, nb_ignore_lines):
68 """Ignore a defined number of lines"""
69 repeat = 0
70 while repeat <= nb_ignore_lines - 1:
71 f.next()
72 repeat += 1
73
74 class Field():
75 """Field object"""
76
77 def __init__(self, row, descr):
78 """ __init__"""
79
80 def uppercase(self, value):
81 return value.upper()
82
83 def capitalize(self, value):
84 return value.capitalize()
85
86 def test(self, value):
87 return "test_%s" % value
88
89
90 def pre(self, pre, values):
91 for col in pre:
92 if type(pre[col]) == str:
93 f = getattr(self, pre[col])
94 values[col] = f(values[col])
95 else:
96 for p in pre[col]:
97 f = getattr(self, p)
98 values[col] = f(values[col])
99 return values
100
101 def get_value(self):
102 """Analyse descr and return a value calculated from descr and row"""
103 values = {}
104 if descr.has_key('col'):
105 if type(descr['col']) == int:
106 cols = (descr['col'],)
107 else:
108 cols = descr['col']
109 for col in cols:
110 values[col] = row[col]
111
112 if descr.has_key('pre'):
113 values = self.pre(descr['pre'], values)
114
115 value = ()
116 for col in cols:
117 value = value + (values[col],)
118 value = " ".join(value)
119 return value
120
121
122 for f in files:
123 fname = '../data_to_import/%s.csv' % f['name']
124 xml_tree, xml_data = create_xml_tree()
125 repeat = 0
126 with open(fname, 'rb') as csvfile:
127 rows = csv.reader(csvfile, delimiter=',', quotechar='"')
128 pass_head(rows, f['nb_ignore_lines'])
129 line = f['nb_ignore_lines']
130 xml_id = f['xml_id']
131 for row in rows:
132 line += 1
133 record = etree.SubElement(xml_data, 'record', id="%s_%s_%d" % (xml_prefix, xml_id, line), model=ds[f['name']]['model'])
134 fields = ds[f['name']]['descr']
135 for field in fields:
136 descr = fields[field]
137 thisfield = Field(row, descr)
138 value = thisfield.get_value()
139 etree.SubElement(record, 'field', name=field).text = unicode(str(value), 'utf-8')
140 content = '<?xml version="1.0" encoding="UTF-8"?>\n%s' % etree.tostring(xml_tree, pretty_print=True)
141 if nodisplay:
142 dest_dir = '%s/%s' % (base_dir, f['dest_dir'])
143 dest_file = '%s/%s.xml' % (dest_dir, f['name'])
144 try:
145 os.makedirs(dest_dir)
146 except OSError:
147 pass
148 with open(dest_file, 'wb') as cur_file:
149 for line in content:
150 cur_file.write(line)
151 elif not nodisplay and not debug:
152 print(content)