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