00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 from PyQt4.QtCore import *
00031 from PyQt4.QtGui import *
00032 from PyQt4.uic import *
00033 import gettext
00034 from Koo.Common import Common
00035 from Koo.Screen.ViewQueue import *
00036
00037 from Koo import Rpc
00038
00039 import csv, StringIO
00040
00041 from ImportExportCommon import *
00042
00043 def import_csv(csv_data, fields, model):
00044 fname = csv_data['fname']
00045 try:
00046 content = file(fname,'rb').read()
00047 except Exception, e:
00048 QMessageBox.information( None, _('Error'), _('Error opening file: %s') % unicode(e.args) )
00049 return False
00050 try:
00051 input=StringIO.StringIO(content)
00052 data = list(csv.reader(input, quotechar=csv_data['del'], delimiter=csv_data['sep']))[int(csv_data['skip']):]
00053
00054 datas = []
00055 for line in data:
00056 datas.append(map(lambda x:x.decode(csv_data['encoding']).encode('utf-8'), line))
00057 except Exception, e:
00058 QMessageBox.information( None, _('Error'), _('Error reading file: %s') % unicode(e.args) )
00059 return False
00060
00061 res = Rpc.session.execute('/object', 'execute', model, 'import_data', fields, datas)
00062 if res[0]>=0:
00063 QMessageBox.information( None, _('Information'), _('Imported %d objects !') % (res[0]))
00064 else:
00065 d = ''
00066 for key,val in res[1].items():
00067 d+= ('\t%s: %s\n' % (str(key),str(val)))
00068 error = _('Error trying to import this record:\n%(record)s\nError Message:\n%(error1)s\n\n%(error2)s') % {
00069 'record': d,
00070 'error1': res[2],
00071 'error2': res[3]
00072 }
00073 QMessageBox.warning(None, _('Error importing data'), error )
00074 return False
00075 return True
00076
00077 (ImportDialogUi, ImportDialogBase) = loadUiType( Common.uiPath('win_import.ui') )
00078
00079 class ImportDialog(QDialog, ImportDialogUi):
00080 def __init__(self, parent=None):
00081 QDialog.__init__(self, parent)
00082 ImportDialogUi.__init__(self)
00083 self.setupUi( self )
00084
00085 self.model = None
00086 self.fields = None
00087 self.connect( self.pushAccept, SIGNAL('clicked()'), self.slotAccept )
00088 self.connect( self.pushCancel, SIGNAL('clicked()'), self.reject )
00089 self.connect( self.pushAdd, SIGNAL('clicked()'), self.slotAdd )
00090 self.connect( self.pushRemove, SIGNAL('clicked()'), self.slotRemove )
00091 self.connect( self.pushRemoveAll, SIGNAL('clicked()'), self.slotRemoveAll )
00092 self.connect( self.pushAutoDetect, SIGNAL('clicked()'), self.slotAutoDetect )
00093 self.connect( self.pushOpenFile, SIGNAL('clicked()'), self.slotOpenFile )
00094
00095 def setModel(self, model):
00096 self.model = model
00097
00098 def setup( self, viewTypes, viewIds ):
00099 self.viewTypes = viewTypes
00100 self.viewIds = viewIds
00101 QTimer.singleShot( 0, self.initGui )
00102
00103 def initGui(self):
00104 QApplication.setOverrideCursor( Qt.WaitCursor )
00105
00106 try:
00107 self.fields = {}
00108 queue = ViewQueue()
00109 queue.setup( self.viewTypes, self.viewIds )
00110 while not queue.isEmpty():
00111 id, type = queue.next()
00112 view = Rpc.session.execute('/object', 'execute', self.model, 'fields_view_get', id, type, Rpc.session.context)
00113 self.fields.update( view['fields'] )
00114 except Rpc.RpcException, e:
00115 QApplication.restoreOverrideCursor()
00116 return
00117
00118 self.fieldsInfo = {}
00119 self.fieldsInvertedInfo = {}
00120 self.allModel = FieldsModel()
00121 self.allModel.load( self.fields, self.fieldsInfo, self.fieldsInvertedInfo )
00122 self.uiAllFields.setModel( self.allModel )
00123 self.uiAllFields.sortByColumn( 0, Qt.AscendingOrder )
00124
00125 self.selectedModel = FieldsModel()
00126 self.uiSelectedFields.setModel( self.selectedModel )
00127 QApplication.restoreOverrideCursor()
00128
00129 def slotOpenFile(self):
00130 file = QFileDialog.getOpenFileName(self, _('File to import'))
00131 if file.isNull():
00132 return
00133 self.uiFileName.setText( file )
00134
00135 def slotAccept(self):
00136 self.uiLinesToSkip.setValue(1)
00137 csv = {
00138 'fname': unicode(self.uiFileName.text()).strip(),
00139 'sep': unicode(self.uiFieldSeparator.text()).encode('ascii','ignore').strip(),
00140 'del': unicode(self.uiTextDelimiter.text()).encode('ascii','ignore').strip(),
00141 'skip': self.uiLinesToSkip.value(),
00142 'encoding': unicode(self.uiEncoding.currentText())
00143 }
00144 if csv['fname'] == '':
00145 QMessageBox.warning(self, _('Import error'), _('No file specified.'))
00146 return
00147 if len(csv['sep']) != 1:
00148 QMessageBox.warning(self, _('Import error'), _('Separator must be a single character.'))
00149 return
00150 if len(csv['del']) != 1:
00151 QMessageBox.warning(self, _('Import error'), _('Delimiter must be a single character.'))
00152 return
00153 fieldsData = []
00154 for x in range(0, self.selectedModel.rowCount() ):
00155 fieldsData.append( unicode( self.selectedModel.item( x ).data().toString() ) )
00156
00157 if csv['fname']:
00158 if not import_csv(csv, fieldsData, self.model):
00159 return
00160 self.accept()
00161
00162 def slotAdd(self):
00163 idx = self.uiAllFields.selectionModel().selectedRows()
00164 if len(idx) != 1:
00165 return
00166 idx = idx[0]
00167 item = self.allModel.itemFromIndex( idx )
00168 newItem = QStandardItem( item )
00169 newItem.setText( self.fullPathText(item) )
00170 newItem.setData( QVariant(self.fullPathData(item)) )
00171 self.selectedModel.appendRow( newItem )
00172
00173 def slotRemove(self):
00174 idx = self.uiSelectedFields.selectedIndexes()
00175 if len(idx) != 1:
00176 return
00177 idx = idx[0]
00178 self.selectedModel.removeRows( idx.row(), 1 )
00179
00180 def slotRemoveAll(self):
00181 if self.selectedModel.rowCount() > 0:
00182 self.selectedModel.removeRows(0, self.selectedModel.rowCount())
00183
00184 def fullPathText(self, item):
00185 path = unicode( item.text() )
00186 while item.parent() != None:
00187 item = item.parent()
00188 path = item.text() + "/" + path
00189 return path
00190
00191 def fullPathData(self, item):
00192 path = unicode( item.data().toString() )
00193 while item.parent() != None:
00194 item = item.parent()
00195 path = item.data().toString() + "/" + path
00196 return path
00197
00198 def slotAutoDetect(self):
00199 fname=unicode(self.uiFileName.text())
00200 if not fname:
00201 QMessageBox.information(self, _('Auto-detect error'), 'You must select an import file first !')
00202 return
00203 csvsep=unicode(self.uiFieldSeparator.text()).encode('ascii','ignore').strip()
00204 csvdel=unicode(self.uiTextDelimiter.text()).encode('ascii','ignore').strip()
00205 csvcode=unicode(self.uiEncoding.currentText()) or 'UTF-8'
00206
00207 self.uiLinesToSkip.setValue(1)
00208 if len(csvsep) != 1:
00209 QMessageBox.warning(self, _('Auto-detect error'), _('Separator must be a single character.'))
00210 return
00211 if len(csvdel) != 1:
00212 QMessageBox.warning(self, _('Auto-detect error'), _('Delimiter must be a single character.'))
00213 return
00214
00215 try:
00216 data = csv.reader(file(fname), quotechar=csvdel, delimiter=csvsep)
00217 except:
00218 QMessageBox.warning(self, _('Auto-detect error'), _('Error opening .CSV file: Input Error.') )
00219 return
00220 self.slotRemoveAll()
00221 try:
00222 for line in data:
00223 for word in line:
00224 word=unicode(word, csvcode, errors='replace')
00225 self.selectedModel.addField( word, self.fieldsInvertedInfo[word] )
00226 break
00227 except:
00228 QMessageBox.warning(self, _('Auto-detect error'), _('Error processing your first line of the file.\nField %s is unknown !') % (word) )
00229