def on_gen(self): '''生成工程''' if not self.currentConfig: return #获取工程名及有效路径 project_name = self.et_project_name.text() project_location = self.et_project_location.text() qdir = QDir(project_location) if not qdir.exists(): if not qdir.mkpath(project_location): QMessageBox.warning(self, '警告', '路径无效!') return project_location = qdir.absolutePath() if not project_location.endsWith( '/') and not project_location.endsWith('\\'): project_location += os.sep project_location.replace('\\', '/') if project_name.isEmpty() or project_location.isEmpty(): QMessageBox.warning(self, '警告', '项目名称或路径不能为空!') return self.currentConfig.project_name = app.QString2str(project_name) self.currentConfig.project_location = app.QString2str(project_location) content = self.currentConfig.toJson() fileInfo = QFileInfo(self.path) if not self.path.isEmpty(): path = app.QString2str(self.path) with open(path, 'w+') as f: f.write(content) item = self.lw.currentItem() item.setData(QtCore.Qt.UserRole, content) template_name = self.currentConfig.template_source template_dir = app.g_pwd + os.sep + 'templates' + os.sep + template_name.encode( 'utf-8') with open(template_dir + os.sep + 'config.json', 'r') as f: self.currentConfig.config_content = f.read() ret_json = app.render(self.currentConfig.config_content, config=self.currentConfig) self.currentConfig.config = json.loads(ret_json) for file in self.currentConfig.config['files']: sourcepath = template_dir + os.sep + file['source'].encode('utf-8') targetdir = self.currentConfig.project_location + self.currentConfig.project_name targetpath = targetdir + os.sep + file['target'] fi = QFileInfo(targetpath) qdir = fi.absoluteDir() if not qdir.exists(): qdir.mkpath(fi.absolutePath()) with open(sourcepath, 'r') as f: content = f.read() content = app.render(content, config=self.currentConfig) #渲染文件 with open(targetpath, 'w+') as f: f.write(content.encode('utf-8')) QMessageBox.information(self, '提示', '生成成功!')
def move_symbol(oldPath, newPath): """ Move the the symbol at oldPath to newPath. The function returns True on success and False otherwise. """ symOldDir = QDir(oldPath) symNewDir = QDir(newPath) if symOldDir.exists(): if not symNewDir.exists(): move(oldPath, newPath) return True return False
def CheckInputValues(self): if self.textNameSubproject.Text is None or self.textNameSubproject.Text == "": QMessageBox.warning(self, "Warning", "Please input project name!") return False if self.textPathSubproject.Text is None or self.textPathSubproject.Text == "": QMessageBox.warning(self, "Warning", "Please input project path!") return False if self.comboProjectSubproject.SelectedIndex < 0: QMessageBox.warning(self, "Warning", "Please select an project!") return False directory = QDir(self.textPathSubproject.Text) if not directory.exists(): if QMessageBox.question( self, "Question", "Procedure path dose not exist! Do you create the directory?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes: directory.mkpath(self.textPathSubproject.Text) else: return False return True
def _check_path_exists(self, path, text_box): #Validates if the specified folder exists dir = QDir() if not dir.exists(path): msg = self.tr(u"'{0}' directory does not exist.".format(path)) self.notif_bar.insertErrorNotification(msg) #Highlight textbox control text_box.setStyleSheet(INVALIDATESTYLESHEET) timer = QTimer(self) #Sync interval with that of the notification bar timer.setInterval(self.notif_bar.interval) timer.setSingleShot(True) #Remove previous connected slots (if any) receivers = timer.receivers(SIGNAL('timeout()')) if receivers > 0: self._timer.timeout.disconnect() timer.start() timer.timeout.connect(lambda: self._restore_stylesheet(text_box)) return False return True
def parse_settings_from_ui(self): # Download settings download_data = {} download_default_folder = self.ui.lineedit_default_download_folder.text() dir_check = QDir(download_default_folder) if dir_check.exists(): download_data["default-folder"] = str(download_default_folder) else: download_data["default-folder"] = self.config_helper.datahandler.get_data_dir_path() self.ui.lineedit_default_download_folder.setText(download_data["default-folder"]) self.main_ui_handler.show_banner("Could not validate default download folder " + str(download_default_folder) + ", reseted to default") self.logger.warning("Default download folder invalid, reseted to default") download_data["no-dialog"] = self.ui.checkbox_no_dl_dialog.isChecked() # Authentication settings authentication_data = {} authentication_data["store-auth"] = self.ui.checkbox_enable_store_auth.isChecked() # Automated sync automate_sync_data = {} automate_sync_data["enabled"] = self.ui.checkbox_enable_sync.isChecked() automate_sync_data["only-sync-on-wlan"] = self.ui.checkbox_only_wlan_sync.isChecked() automate_sync_data["update-interval"] = self.ui.spinbox_sync_interval.value() automate_sync_data["sync-path"] = str(self.sync_path_button.valueText()) self.config_helper.write_settings(download_data, authentication_data, automate_sync_data)
def _check_path_exists(self, path, text_box): #Validates if the specified folder exists dir = QDir() if not dir.exists(path): msg = self.tr(u"'{0}' directory does not exist.".format(path)) self.notif_bar.insertErrorNotification(msg) #Highlight textbox control text_box.setStyleSheet(INVALIDATESTYLESHEET) timer = QTimer(self) #Sync interval with that of the notification bar timer.setInterval(self.notif_bar.interval) timer.setSingleShot(True) #Remove previous connected slots (if any) receivers = timer.receivers(SIGNAL('timeout()')) if receivers > 0: self._timer.timeout.disconnect() timer.start() timer.timeout.connect(lambda:self._restore_stylesheet( text_box) ) return False return True
def validate(self): """ :return: Return True if the source document directory exists, otherwise False. :rtype: bool """ source_doc_path = self.txtRootFolder.text() #Clear previous notifications self._notif_bar.clear() if not source_doc_path: msg = self.tr( 'Please set the root directory of source documents.' ) self._notif_bar.insertErrorNotification(msg) return False dir = QDir() if not dir.exists(source_doc_path): msg = self.tr(u"'{0}' directory does not exist.".format( source_doc_path)) self._notif_bar.insertErrorNotification(msg) return False return True
def setup_logger(): from stdm.settings.registryconfig import debug_logging logger = logging.getLogger('stdm') logger.setLevel(logging.ERROR) # Create log directory if it does not exist log_folder = QDir() if not log_folder.exists(LOG_DIR): status = log_folder.mkpath(LOG_DIR) # Log directory could not be created if not status: raise IOError('Log directory for STDM could not be created.') # File handler for logging debug messages file_handler = TimedRotatingFileHandler(LOG_FILE_PATH, when='D', interval=1, backupCount=14) file_handler.setLevel(logging.DEBUG) # Create formatter and add it to the handler formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') file_handler.setFormatter(formatter) # Add handler to the logger logger.addHandler(file_handler) # Enable/disable debugging. Defaults to ERROR level. lvl = debug_logging() if lvl: file_handler.setLevel(logging.DEBUG) else: file_handler.setLevel(logging.ERROR)
def validate(self): """ :return: Return True if the source document directory exists, otherwise False. :rtype: bool """ source_doc_path = self.txtRootFolder.text() #Clear previous notifications self._notif_bar.clear() if not source_doc_path: msg = self.tr('Please set the root directory of source documents.') self._notif_bar.insertErrorNotification(msg) return False dir = QDir() if not dir.exists(source_doc_path): msg = self.tr( u"'{0}' directory does not exist.".format(source_doc_path)) self._notif_bar.insertErrorNotification(msg) return False return True
def config_dir(self): confd = QString2str( QApplication.applicationDirPath()) + os.sep + 'configs' dir = QDir(confd) if not dir.exists(): dir.mkpath(confd) return confd
def CheckInputValues(self): if (self.textNameProcedure.Text == None or self.textNameProcedure.Text == ""): QMessageBox.warning(self, "Warning", "Please input project name!") return False if (self.textPathProcedure.Text == None or self.textPathProcedure.Text == ""): QMessageBox.warning(self, "Warning", "Please input project path!") return False if (self.comboProjectProcedure.SelectedIndex < 0): QMessageBox.warning(self, "Warning", "Please select an Project!") return False if (self.comboSubProjectProcedure.SelectedIndex < 0): QMessageBox.warning(self, "Warning", "Please select an Sub-Project!") return False if (self.comboWorkspaceProcedure.SelectedIndex < 0): QMessageBox.warning(self, "Warning", "Please select an Workspace!") return directory = QDir(self.textPathProcedure.Text) if (not directory.exists()): if (QMessageBox.question( self, "Question", "Procedure path dose not exist! Do you create the directory?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes): directory.mkpath(self.textPathProcedure.Text) else: return False return True
def get_music_storage_folder(): storage_path = "%s%s%s" % (QDesktopServices.storageLocation(QDesktopServices.DataLocation).replace("\\", "/"), Config.DataPrefix, Config.MusicPrefix) dir = QDir(storage_path) if dir.exists() != True: dir.mkpath('.') return storage_path
def mkdir(self, path): directory = QDir(path) SCJ.lock.lock() if not directory.exists() : if not directory.mkpath(path) : self.emit(SIGNAL("error(QString)"), QString(self.trUtf8("Cannot create %s" % path))) SCJ.lock.unlock()
def removeDir(dirName): d = QDir(dirName) if d.exists(): for info in d.entryInfoList(QDir.Dirs | QDir.Files | QDir.NoDotAndDotDot): if info.isDir(): removeDir(info.absoluteFilePath()) else: d.remove(info.fileName()) d.rmdir(dirName)
def setup_search(): # Create search directory if it does not exist search_folder = QDir() if not search_folder.exists(SEARCH_DIR): status = search_folder.mkpath(SEARCH_DIR) # Log directory could not be created if not status: raise IOError('Search directory for FLTS could not be created.')
def setup_templates_folder(): # Create reports directory and templates sub-directory if it does not # exist reports_folder = QDir() if not reports_folder.exists(TEMPLATES_DIR): status = reports_folder.mkpath(TEMPLATES_DIR) # Log directory could not be created if not status: raise IOError('Reports directory for FLTS could not be created.')
def on_gen(self): '''生成工程''' if not self.currentConfig: return #获取工程名及有效路径 project_name = self.et_project_name.text() project_location = self.et_project_location.text() qdir = QDir(project_location) if not qdir.exists(): if not qdir.mkpath(project_location): QMessageBox.warning(self, '警告', '路径无效!') return project_location = qdir.absolutePath() if not project_location.endsWith('/') and not project_location.endsWith('\\'): project_location += os.sep if project_name.isEmpty() or project_location.isEmpty(): QMessageBox.warning(self, '警告', '项目名称或路径不能为空!') return self.currentConfig.project_name = app.QString2str(project_name) self.currentConfig.project_location = app.QString2str(project_location) template_name = self.currentConfig.template_source template_dir = app.g_pwd + os.sep + 'templates' + os.sep + template_name with open(template_dir + os.sep + 'config.json', 'r') as f: self.currentConfig.config_content = f.read() ret_json = app.render(self.currentConfig.config_content, config=self.currentConfig) self.currentConfig.config = json.loads(ret_json) for file in self.currentConfig.config['files']: sourcepath = template_dir + os.sep + file['source'] targetdir = self.currentConfig.project_location + self.currentConfig.project_name targetpath = targetdir + os.sep + file['target'] fi = QFileInfo(targetpath) qdir = fi.absoluteDir() if not qdir.exists(): qdir.mkpath(fi.absolutePath()) with open(sourcepath, 'r') as f: content = f.read() content = app.render(content, config=self.currentConfig) #渲染文件 with open(targetpath, 'w+') as f: f.write(content.encode('utf-8')) QMessageBox.information(self,'提示','生成成功!')
def deleteDir(self,dirPath): dr = QDir(dirPath) result=True if (dr.exists()): for entry in dr.entryInfoList(filters=QDir.NoDotAndDotDot.__or__(QDir.Hidden).__or__(QDir.AllDirs).__or__(QDir.Files) , sort=QDir.NoSort): if entry.isDir(): result&=self.deleteDir(entry.absoluteFilePath()) else: result&=QFile.remove(entry.absoluteFilePath()) dr.rmdir(dirPath) return result
def check_settings(self): self.sync_path_selected(str(self.sync_path_button.valueText())) download_default_folder = self.ui.lineedit_default_download_folder.text() dir_check = QDir(download_default_folder) if not dir_check.exists(): confirmation = QMessageBox.question(None, "Default Download Folder", "The folder " + str(download_default_folder) + " does not exist anymore. Define new folder now or reset to default?", QMessageBox.Yes, QMessageBox.Reset) if confirmation == QMessageBox.Yes: self.set_default_dl_folder(False, self.datahandler.default_data_root) if confirmation == QMessageBox.Reset: self.ui.lineedit_default_download_folder.setText(self.datahandler.default_data_root) self.parse_settings_from_ui()
def uploadDocument(self, entity_source, doc_type, fileinfo): """ Upload document in central repository """ self._entity_source = entity_source self._doc_type = doc_type self.fileID = self.generateFileID() self.sourcePath = fileinfo.filePath() profile_name = self.curr_profile.name root_dir = QDir(self.networkPath) doc_dir = QDir('{}/{}/{}/{}'.format( self.networkPath, unicode(profile_name).lower(), self._entity_source, unicode(self._doc_type).lower().replace(' ', '_'))) doc_path_str = u'{}/{}/{}/{}'.format( self.networkPath, profile_name.lower(), self._entity_source, self._doc_type.lower().replace(' ', '_')).lower() if not doc_dir.exists(): res = root_dir.mkpath(doc_path_str) if res: root_doc_type_path = doc_path_str else: root_doc_type_path = self.networkPath else: root_doc_type_path = doc_path_str self.destinationPath = '{}/{}.{}'.format(root_doc_type_path, self.fileID, fileinfo.completeSuffix()) srcFile = open(self.sourcePath, 'rb') destinationFile = open(self.destinationPath, 'wb') #srcLen = self.sourceFile.bytesAvailable() totalRead = 0 while True: inbytes = srcFile.read(4096) if not inbytes: break destinationFile.write(inbytes) totalRead += len(inbytes) #Raise signal on each block written self.emit(SIGNAL("blockWritten(int)"), totalRead) self.emit(SIGNAL("completed(QString)"), self.fileID) srcFile.close() destinationFile.close() return self.fileID
def CheckInputValues(self): if (self.textNameProject.Value == None or self.textNameProject.Value == ""): raise ("Please input project name!") if (self.textPathProject.Value == None or self.textPathProject.Value == ""): raise ("Please input project path!") d = QDir(self.textPathProject.Value) if (not d.exists()): if (QMessageBox.question(self, "Question", "Procedure path dose not exist! Do you create the directory?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes): d = QDir(self.textPathProject.Value) d.mkpath(self.textPathProject.Value) else: return False return True
def set_default_dl_folder(self, magic, open_in_path = None): if open_in_path == None: open_in_path = self.ui.lineedit_default_download_folder.text() local_folder_path = QFileDialog.getExistingDirectory(None, QString("Select Default Download Folder"), QString(open_in_path), (QFileDialog.ShowDirsOnly|QFileDialog.HideNameFilterDetails|QFileDialog.ReadOnly)) if local_folder_path.isEmpty(): self.ui.lineedit_default_download_folder.setText(open_in_path) return dir_check = QDir(local_folder_path) if dir_check.exists(): self.ui.lineedit_default_download_folder.setText(local_folder_path) else: self.logger.warning("Could not validate " + str(local_folder_path) + " folder, resetting to default.") self.ui.lineedit_default_download_folder.setText(open_in_path)
def generate_recovery_filepath(filePath): """ Based on a filePath generate the name for the recovery File. """ # check if sconcho directory in user's home directory exists sconchoDirName = QDir.homePath() + "/.sconcho" sconchoDir = QDir(sconchoDirName) if not sconchoDir.exists(): status = sconchoDir.mkdir(sconchoDirName) recoveryFileInfo = QFileInfo(filePath) recoveryFilePath = sconchoDirName + "/" + \ recoveryFileInfo.fileName() + ".recovery" return recoveryFilePath
def checkTempDir(): tempDir = QDir(WorkerPopulateGroup.TEMP_DIR) if not tempDir.exists(): msgtrans1 = QCoreApplication.translate( "CatalogOTF", "Created temporary directory '%s' for GDAL_WMS") msgtrans2 = QCoreApplication.translate( "CatalogOTF", "Not possible create temporary directory '%s' for GDAL_WMS" ) isOk = tempDir.mkpath(WorkerPopulateGroup.TEMP_DIR) msgtrans = msgtrans1 if isOk else msgtrans2 tempDir.setPath(WorkerPopulateGroup.TEMP_DIR) msg = msgtrans % tempDir.absolutePath() msgBar.pushMessage(NAME_PLUGIN, msg, QpluginNamegsMessageBar.CRITICAL, 5)
def _on_add_supporting_document(self): #Slot raised when the user select to add a supporting document if self.count == 0: return select = self.tr('Select') supporting_docs_str = 'Supporting Documents' title = u'{0} {1} {2}'.format( select, self.current_document_type(), supporting_docs_str ) filter_str = u'{0} (*.jpg *.jpeg *.png *.bmp *.tiff *.svg)'.format( supporting_docs_str ) #Get last path for supporting documents last_path = last_document_path() if last_path is None: last_path = '/home' else: dir = QDir(last_path) if not dir.exists(): last_path = '/home' source_docs = QFileDialog.getOpenFileNames( self, title, last_path, filter_str ) doc_type_id = self._cbo_doc_type.itemData(self._cbo_doc_type.currentIndex()) parent_entity = self._entity_supporting_doc.parent_entity for doc in source_docs: self.source_document_manager.insertDocumentFromFile( doc, doc_type_id, parent_entity ) #Set last path if len(source_docs) > 0: doc = source_docs[0] fi = QFileInfo(doc) dir_path = fi.absolutePath() set_last_document_path(dir_path)
def set_settings_to_ui(self, download_data, authentication_data, automate_sync_data): # Download settings dir_check = QDir(download_data["default-folder"]) if dir_check.exists(): self.ui.lineedit_default_download_folder.setText(download_data["default-folder"]) else: self.ui.lineedit_default_download_folder.setText(str(QDir.home().absolutePath()) + "/MyDocs/DropN900/") self.ui.checkbox_no_dl_dialog.setChecked(download_data["no-dialog"]) # Authentication settings self.ui.checkbox_enable_store_auth.setChecked(authentication_data["store-auth"]) # Automated sync self.ui.checkbox_enable_sync.setChecked(automate_sync_data["enabled"]) self.set_sync_widgets_enabled(automate_sync_data["enabled"]) self.ui.checkbox_only_wlan_sync.setChecked(automate_sync_data["only-sync-on-wlan"]) self.ui.spinbox_sync_interval.setValue(automate_sync_data["update-interval"])
def fillTemplateList(self): """ Fill the listbox of composer template files. """ if self.ui.TemplateList.currentItem() is not None: oldSelectedTemplate = self.ui.TemplateList.currentItem().text() else: oldSelectedTemplate = "" self.ui.TemplateList.clear() tempdir = QDir(self.templatepath) if tempdir.exists(): fileinfolist = tempdir.entryInfoList(["*.qpt"], QDir.Files | QDir.NoDotAndDotDot | QDir.NoSymLinks, QDir.NoSort) for fi in fileinfolist: item = QListWidgetItem(fi.fileName()) self.ui.TemplateList.addItem(item) if fi.fileName() == oldSelectedTemplate: self.ui.TemplateList.setCurrentItem( item )
def exportInterp(self,row): thisGraphData = self.ui.tableWidget.item(row,self.cols.keys().index('plotBtn')).data(Qt.UserRole).toPyObject() fitX = thisGraphData[QString(u'fitX')] modelY = thisGraphData[QString(u'modelY')] splineY = thisGraphData[QString(u'splineY')] a = np.asarray([fitX, modelY, splineY]) a = np.transpose(a) destinationFolder = os.path.join(self.workingDirectory,'exports') QDestinationFolder = QDir(destinationFolder) if not QDestinationFolder.exists(): QDir().mkdir(destinationFolder) saveFile = os.path.join(destinationFolder,str(self.ui.tableWidget.item(row,self.cols.keys().index('file')).text())+'.csv') header = 'Voltage [V],CharEqn Current [mA/cm^2],Spline Current [mA/cm^2]' try: np.savetxt(saveFile, a, delimiter=",",header=header) self.ui.statusbar.showMessage("Exported " + saveFile,5000) except: self.ui.statusbar.showMessage("Could not export " + saveFile,self.messageDuration)
def uploadDocument(self,doc_type, fileinfo): """ Upload document in central repository """ self._document_type = doc_type self.fileID = self.generateFileID() self.sourcePath = fileinfo.filePath() root_dir = QDir(self.networkPath) if not root_dir.exists(self._document_type): res = root_dir.mkdir(self._document_type) if res: root_doc_type_path = self.networkPath + "/" + self._document_type else: root_doc_type_path = self.networkPath else: root_doc_type_path = self.networkPath + "/" + self._document_type self.destinationPath = root_doc_type_path + "/" + self.fileID + "." + \ fileinfo.completeSuffix() srcFile = open(self.sourcePath,'rb') destinationFile = open(self.destinationPath,'wb') #srcLen = self.sourceFile.bytesAvailable() totalRead = 0 while True: inbytes = srcFile.read(4096) if not inbytes: break destinationFile.write(inbytes) totalRead += len(inbytes) #Raise signal on each block written self.emit(SIGNAL("blockWritten(int)"),totalRead) self.emit(SIGNAL("completed(QString)"),self.fileID) srcFile.close() destinationFile.close() return self.fileID
def check_for_data_folder(self): if self.data_root == (self.user_home + "/MyDocs/DropN900/"): data_dir = QDir.home() if data_dir.cd("MyDocs"): if not data_dir.cd("DropN900"): if data_dir.mkdir("DropN900"): print ">> [INFO] Created default data dir " + str(data_dir.absolutePath()) + "/DropN900" else: print ">> [ERROR] Could not create default data dir 'DropN900' to " + str(data_dir.absolutePath()) else: print ">> [ERROR] Could not find 'MyDocs' folder from " + str(data_dir.absolutePath()) else: non_default_data_dir = QDir(self.data_root) if non_default_data_dir.exists(): print ">> [INFO] Default data dir: " + self.data_root else: print ">> [WARNING] User set default data dir " + self.data_root + " does not exist, resetting to default" self.data_root = self.user_home + "/MyDocs/DropN900/" self.check_for_data_folder()
def fillTemplateList(self): """ Fill the listbox of composer template files. """ if self.ui.TemplateList.currentItem() is not None: oldSelectedTemplate = self.ui.TemplateList.currentItem().text() else: oldSelectedTemplate = "" self.ui.TemplateList.clear() tempdir = QDir(self.templatepath) if tempdir.exists(): fileinfolist = tempdir.entryInfoList( ["*.qpt"], QDir.Files | QDir.NoDotAndDotDot | QDir.NoSymLinks, QDir.NoSort) for fi in fileinfolist: item = QListWidgetItem(fi.fileName()) self.ui.TemplateList.addItem(item) if fi.fileName() == oldSelectedTemplate: self.ui.TemplateList.setCurrentItem(item)
def readFile(path, default=None, encoding=None): if not os.path.supports_unicode_filenames: path = path.encode("utf-8") if QFile.exists(path): f = QFile(path,parent) if f.open(QIODevice.ReadOnly): data=f.readAll().__str__() else: raise ErrorRead(u'Couldn\'t open file %s with code error %d'%path,f.error()) f.close() if encoding: data = data.decode(encoding) return data else: dir = QDir(os.path.dirname(path)) if not dir.exists(): if not dir.mkpath(dir.path()): raise ErrorCreatePath(u'impossible to create a path!') writeFile(path, default) return default
def remove_symbol(symbolTopPath, name): """ This function removes the symbol named name from the database located at symbolPath. NOTE: I purposefully don't use rmtree here to avoid that users accidentally or maliciously delete other data. """ symbolPath = symbolTopPath + "/" + name symbolPathDir = QDir(symbolPath) if not symbolPathDir.exists(): return False descriptionFile = symbolPath + "/description" svgFile = symbolPath + "/" + name + ".svg" if (symbolPathDir.remove(descriptionFile) and symbolPathDir.remove(svgFile) and symbolPathDir.rmdir(symbolPath)): return True return False
def set_source_document_location(doc_path): """ Set the latest source directory of uploaded source documents. :param doc_path: Directory path or file path. The system will attempt to extract the directory path from the file name. """ doc_dir_path = "" #Check if it is a file or directory doc_dir = QDir(doc_path) if not doc_dir.exists(): doc_file_info = QFileInfo(doc_path) if doc_file_info.exists(): doc_dir_path = doc_file_info.dir().path() else: doc_dir_path = doc_path if len(doc_dir_path) > 0: reg_config = RegistryConfig() reg_config.write({LOCAL_SOURCE_DOC:doc_dir_path})
def item_download(self): data = self.get_selected_data() if data == None: return if self.datahandler.dont_show_dl_dialog == False: # This dialog shows sometimes strange stuff on maemo5 # It's a PyQt4 bug and its the best we got, you can cope with this if self.last_dl_location == None: self.last_dl_location = self.datahandler.get_data_dir_path() local_folder_path = QFileDialog.getExistingDirectory(self.manager_widget, QString("Select Download Folder"), QString(self.last_dl_location), QFileDialog.ShowDirsOnly|QFileDialog.HideNameFilterDetails|QFileDialog.ReadOnly) if local_folder_path.isEmpty(): return py_unicode_path = self.datahandler.to_unicode(str(local_folder_path.toUtf8())) self.last_dl_location = py_unicode_path store_path = py_unicode_path + "/" + data.name else: dir_check = QDir(self.datahandler.get_data_dir_path()) if not dir_check.exists(): self.show_note("Cannot download, destination " + self.datahandler.get_data_dir_path() + " does not exist. Please set a new folder in settings.") return store_path = self.datahandler.get_data_dir_path() + data.name self.controller.connection.get_file(data.path, data.root, store_path, data.get_size(), data.mime_type)
def setup_logger(): from stdm.settings.registryconfig import debug_logging logger = logging.getLogger('stdm') logger.setLevel(logging.ERROR) # Create log directory if it does not exist log_folder = QDir() if not log_folder.exists(LOG_DIR): status = log_folder.mkpath(LOG_DIR) # Log directory could not be created if not status: raise IOError('Log directory for STDM could not be created.') # File handler for logging debug messages file_handler = TimedRotatingFileHandler(LOG_FILE_PATH, when='D', interval=1, backupCount=14) file_handler.setLevel(logging.DEBUG) # Create formatter and add it to the handler formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') file_handler.setFormatter(formatter) # Add handler to the logger logger.addHandler(file_handler) # Enable/disable debugging. Defaults to ERROR level. lvl = debug_logging() if lvl: file_handler.setLevel(logging.DEBUG) else: file_handler.setLevel(logging.ERROR)
def setup_logger(): logger = logging.getLogger('stdm') logger.setLevel(logging.DEBUG) #Create log directory if it does not exist log_folder = QDir() if not log_folder.exists(LOG_DIR): status = log_folder.mkpath(LOG_DIR) #Log directory could not be created if not status: raise IOError('Log directory for STDM could not be created.') #File handler for logging debug messages file_handler = TimedRotatingFileHandler(LOG_FILE_PATH, when='D', interval=1, backupCount=14) file_handler.setLevel(logging.DEBUG) #Create formatter and add it to the handler formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') file_handler.setFormatter(formatter) #Add handler to the logger logger.addHandler(file_handler)
def run(self, *args, **kwargs): """ :param templatePath: The file path to the user-defined template. :param entityFieldName: The name of the column for the specified entity which must exist in the data source view or table. :param entityFieldValue: The value for filtering the records in the data source view or table. :param outputMode: Whether the output composition should be an image or PDF. :param filePath: The output file where the composition will be written to. Applies to single mode output generation. :param dataFields: List containing the field names whose values will be used to name the files. This is used in multiple mode configuration. :param fileExtension: The output file format. Used in multiple mode configuration. :param data_source: Name of the data source table or view whose row values will be used to name output files if the options has been specified by the user. """ templatePath = args[0] entityFieldName = args[1] entityFieldValue = args[2] outputMode = args[3] filePath = kwargs.get("filePath", None) dataFields = kwargs.get("dataFields", []) fileExtension = kwargs.get("fileExtension", "") data_source = kwargs.get("data_source", "") templateFile = QFile(templatePath) if not templateFile.open(QIODevice.ReadOnly): return False, QApplication.translate("DocumentGenerator", "Cannot read template file.") templateDoc = QDomDocument() if templateDoc.setContent(templateFile): composerDS = ComposerDataSource.create(templateDoc) spatialFieldsConfig = SpatialFieldsConfiguration.create( templateDoc) composerDS.setSpatialFieldsConfig(spatialFieldsConfig) #Check if data source exists and return if it doesn't if not self.data_source_exists(composerDS): msg = QApplication.translate( "DocumentGenerator", u"'{0}' data source does not exist in the database." u"\nPlease contact your database " u"administrator.".format(composerDS.name())) return False, msg #Set file name value formatter self._file_name_value_formatter = EntityValueFormatter( name=data_source) #Register field names to be used for file naming self._file_name_value_formatter.register_columns(dataFields) #TODO: Need to automatically register custom configuration collections #Photo config collection ph_config_collection = PhotoConfigurationCollection.create( templateDoc) #Table configuration collection table_config_collection = TableConfigurationCollection.create( templateDoc) #Create chart configuration collection object chart_config_collection = ChartConfigurationCollection.create( templateDoc) #Load the layers required by the table composer items self._table_mem_layers = load_table_layers(table_config_collection) #Execute query dsTable, records = self._exec_query(composerDS.name(), entityFieldName, entityFieldValue) if records is None or len(records) == 0: return False, QApplication.translate( "DocumentGenerator", "No matching records in the database") """ Iterate through records where a single file output will be generated for each matching record. """ for rec in records: composition = QgsComposition(self._map_renderer) composition.loadFromTemplate(templateDoc) ref_layer = None #Set value of composer items based on the corresponding db values for composerId in composerDS.dataFieldMappings().reverse: #Use composer item id since the uuid is stripped off composerItem = composition.getComposerItemById(composerId) if not composerItem is None: fieldName = composerDS.dataFieldName(composerId) fieldValue = getattr(rec, fieldName) self._composeritem_value_handler( composerItem, fieldValue) # Extract photo information self._extract_photo_info(composition, ph_config_collection, rec) # Set table item values based on configuration information self._set_table_data(composition, table_config_collection, rec) # Refresh non-custom map composer items self._refresh_composer_maps( composition, spatialFieldsConfig.spatialFieldsMapping().keys()) # Create memory layers for spatial features and add them to the map for mapId, spfmList in spatialFieldsConfig.spatialFieldsMapping( ).iteritems(): map_item = composition.getComposerItemById(mapId) if not map_item is None: # #Clear any previous map memory layer #self.clear_temporary_map_layers() for spfm in spfmList: #Use the value of the label field to name the layer lbl_field = spfm.labelField() spatial_field = spfm.spatialField() if not spatial_field: continue if lbl_field: if hasattr(rec, spfm.labelField()): layerName = getattr(rec, spfm.labelField()) else: layerName = self._random_feature_layer_name( spatial_field) else: layerName = self._random_feature_layer_name( spatial_field) #Extract the geometry using geoalchemy spatial capabilities geom_value = getattr(rec, spatial_field) if geom_value is None: continue geom_func = geom_value.ST_AsText() geomWKT = self._dbSession.scalar(geom_func) #Get geometry type geom_type, srid = geometryType( composerDS.name(), spatial_field) #Create reference layer with feature ref_layer = self._build_vector_layer( layerName, geom_type, srid) if ref_layer is None or not ref_layer.isValid(): continue #Add feature bbox = self._add_feature_to_layer( ref_layer, geomWKT) bbox.scale(spfm.zoomLevel()) #Workaround for zooming to single point extent if ref_layer.wkbType() == QGis.WKBPoint: canvas_extent = self._iface.mapCanvas( ).fullExtent() cnt_pnt = bbox.center() canvas_extent.scale(1.0 / 32, cnt_pnt) bbox = canvas_extent #Style layer based on the spatial field mapping symbol layer symbol_layer = spfm.symbolLayer() if not symbol_layer is None: ref_layer.rendererV2().symbols( )[0].changeSymbolLayer(0, spfm.symbolLayer()) ''' Add layer to map and ensure its always added at the top ''' self.map_registry.addMapLayer(ref_layer) self._iface.mapCanvas().setExtent(bbox) self._iface.mapCanvas().refresh() # Add layer to map memory layer list self._map_memory_layers.append(ref_layer.id()) self._hide_layer(ref_layer) ''' Use root layer tree to get the correct ordering of layers in the legend ''' self._refresh_map_item(map_item) #Extract chart information and generate chart self._generate_charts(composition, chart_config_collection, rec) #Build output path and generate composition if not filePath is None and len(dataFields) == 0: self._write_output(composition, outputMode, filePath) elif filePath is None and len(dataFields) > 0: docFileName = self._build_file_name( data_source, entityFieldName, entityFieldValue, dataFields, fileExtension) # Replace unsupported characters in Windows file naming docFileName = docFileName.replace('/', '_').replace \ ('\\', '_').replace(':', '_').strip('*?"<>|') if not docFileName: return ( False, QApplication.translate( "DocumentGenerator", "File name could not be generated from the data fields." )) outputDir = self._composer_output_path() if outputDir is None: return ( False, QApplication.translate( "DocumentGenerator", "System could not read the location of the output directory in the registry." )) qDir = QDir() if not qDir.exists(outputDir): return (False, QApplication.translate( "DocumentGenerator", "Output directory does not exist")) absDocPath = u"{0}/{1}".format(outputDir, docFileName) self._write_output(composition, outputMode, absDocPath) return True, "Success" return False, "Document composition could not be generated"
def referencing_column_value(self, field_values): """ Uploads documents based on the file name specified in the source column. :param field_values: Pair of field names and corresponding values i.e. {field1:value1, field2:value2, field3:value3...} :type field_values: dict :return: Ignore type since te source document manager will handle the supporting document uploads. :rtype: IgnoreType """ if self.source_document_manager is None or self.entity is None: return IgnoreType if self.document_type_id is None: msg = QApplication.translate( 'SourceDocumentTranslator', 'Document type has not been set for the source document ' 'translator.') raise RuntimeError(msg) if self.source_directory is None: msg = QApplication.translate( 'SourceDocumentTranslator', u'Source directory for {0} has not been set.'.format( self.document_type)) raise RuntimeError(msg) source_dir = QDir() if not source_dir.exists(self.source_directory): msg = QApplication.translate( 'SourceDocumentTranslator', u'Source directory for {0} does not exist.'.format( self.document_type)) raise IOError(msg) if len(field_values) == 0: return IgnoreType source_column = field_values.keys()[0] # Check if the source column is in the field_values if not source_column in field_values: return IgnoreType # Get file name doc_file_name = field_values.get(source_column) if not doc_file_name: return IgnoreType #Separate files docs = doc_file_name.split(';') #Create document container doc_container = QVBoxLayout() #Register container self.source_document_manager.registerContainer(doc_container, self.document_type_id) for d in docs: if not d: continue # Normalize slashes d_name = d.replace('\\', '/').strip() # Build absolute document path abs_doc_path = u'{0}/{1}'.format(self.source_directory, d_name) if not QFile.exists(abs_doc_path): msg = QApplication.translate( 'SourceDocumentTranslator', u'Supporting document {0} does not exist.'.format( abs_doc_path)) raise IOError(msg) # Upload supporting document self.source_document_manager.insertDocumentFromFile( abs_doc_path, self.document_type_id, self.entity) # Move file to 'uploaded' directory # Documents are handles by the source document manager so we just # instruct the system to ignore the return value return IgnoreType
def insertDocumentFromFile(self, path, doc_type_id, entity, record_count=1): """ Insert a new document into one of the registered containers with the document type id. This document is registered :param path: The local user path of the document :type path: String :param doc_type_id: The entity document type id :type doc_type_id: Integer :param entity: The entity in which the document is inserted into. :type entity: Entity class :param record_count: The number of records for which a document is uploaded. Default is 1. For instance, more records could be used in STR wizard in multi-party. :type record_count: Integer :return: None :rtype: NoneType """ if len(self.containers) > 0: if doc_type_id in self.containers: container = self.containers[doc_type_id] #Check if the file exists if QFile.exists(path): network_location = network_document_path() if not network_location: self._doc_repository_error() return #Check if the directory exists doc_dir = QDir(network_location) if not doc_dir.exists(): msg = QApplication.translate( "sourceDocumentManager", u"The root document " u"repository '{0}' does " u"not exist.\nPlease " u"check the path settings." ) parent = self.parent() if not isinstance(parent, QWidget): parent = None QMessageBox.critical( parent, QApplication.translate( "sourceDocumentManager", "Document Manager" ), msg.format(network_location) ) return for i in range(record_count): # Use the default network file manager networkManager = NetworkFileManager( network_location, self.parent() ) # Add document widget docWidg = DocumentWidget( self.document_model, networkManager, parent=self.parent(), view_manager=self._doc_view_manager ) # Connect slot once the document # has been successfully uploaded. docWidg.fileUploadComplete.connect( lambda: self.onFileUploadComplete(doc_type_id) ) self._linkWidgetRemovedSignal(docWidg) doc_type_entity = entity.supporting_doc.document_type_entity doc_type_value = entity_id_to_attr( doc_type_entity, 'value', doc_type_id ) docWidg.setFile( path, entity.name, doc_type_value, doc_type_id ) container.addWidget(docWidg)
def run(self, *args, **kwargs): """ :param templatePath: The file path to the user-defined template. :param entityFieldName: The name of the column for the specified entity which must exist in the data source view or table. :param entityFieldValue: The value for filtering the records in the data source view or table. :param outputMode: Whether the output composition should be an image or PDF. :param filePath: The output file where the composition will be written to. Applies to single mode output generation. :param dataFields: List containing the field names whose values will be used to name the files. This is used in multiple mode configuration. :param fileExtension: The output file format. Used in multiple mode configuration. :param dbmodel: In order to name the files using the custom column mapping, a callable sqlalchemy data model must be specified. """ #Unpack arguments templatePath = args[0] entityFieldName = args[1] entityFieldValue = args[2] outputMode = args[3] filePath = kwargs.get("filePath", None) dataFields = kwargs.get("dataFields", []) fileExtension = kwargs.get("fileExtension", "") dataModel = kwargs.get("dbmodel", None) templateFile = QFile(templatePath) if not templateFile.open(QIODevice.ReadOnly): return (False, QApplication.translate("DocumentGenerator", "Cannot read template file.")) templateDoc = QDomDocument() if templateDoc.setContent(templateFile): composerDS = ComposerDataSource.create(templateDoc) spatialFieldsConfig = SpatialFieldsConfiguration.create( templateDoc) composerDS.setSpatialFieldsConfig(spatialFieldsConfig) #Execute query dsTable, records = self._execQuery(composerDS.name(), entityFieldName, entityFieldValue) if records == None: return (False, QApplication.translate( "DocumentGenerator", "No matching records in the database")) """ Iterate through records where a single file output will be generated for each matching record. """ for rec in records: composition = QgsComposition(self._mapRenderer) composition.loadFromTemplate(templateDoc) #Set value of composer items based on the corresponding db values for composerId in composerDS.dataFieldMappings().reverse: #Use composer item id since the uuid is stripped off composerItem = composition.getComposerItemById(composerId) if composerItem != None: fieldName = composerDS.dataFieldName(composerId) fieldValue = getattr(rec, fieldName) self._composerItemValueHandler(composerItem, fieldValue) #Create memory layers for spatial features and add them to the map for mapId, spfmList in spatialFieldsConfig.spatialFieldsMapping( ).iteritems(): mapItem = composition.getComposerItemById(mapId) if mapItem != None: #Clear any previous memory layer self.clearTemporaryLayers() for spfm in spfmList: #Use the value of the label field to name the layer layerName = getattr(rec, spfm.labelField()) #Extract the geometry using geoalchemy spatial capabilities geomFunc = getattr( rec, spfm.spatialField()).ST_AsText() geomWKT = self._dbSession.scalar(geomFunc) #Create reference layer with feature refLayer = self._buildVectorLayer(layerName) #Add feature bbox = self._addFeatureToLayer(refLayer, geomWKT) bbox.scale(spfm.zoomLevel()) #Add layer to map QgsMapLayerRegistry.instance().addMapLayer( refLayer) self._iface.mapCanvas().setExtent(bbox) self._iface.mapCanvas().refresh() #mapItem.storeCurrentLayerSet() #mapItem.updateCachedImage() #Add layer to memory layer list self._memoryLayers.append(refLayer) mapItem.setNewExtent(self._mapRenderer.extent()) #Build output path and generate composition if filePath != None and len(dataFields) == 0: self._writeOutput(composition, outputMode, filePath) elif filePath == None and len(dataFields) > 0: docFileName = self._buildFileName(dataModel, entityFieldName, entityFieldValue, dataFields, fileExtension) if docFileName == "": return ( False, QApplication.translate( "DocumentGenerator", "File name could not be generated from the data fields." )) outputDir = self._composerOutputPath() if outputDir == None: return ( False, QApplication.translate( "DocumentGenerator", "System could not read the location of the output directory in the registry." )) qDir = QDir() if not qDir.exists(outputDir): return (False, QApplication.translate( "DocumentGenerator", "Output directory does not exist")) absDocPath = unicode(outputDir) + "/" + docFileName self._writeOutput(composition, outputMode, absDocPath) #Clear temporary layers self.clearTemporaryLayers() return (True, "Success") return (False, "Composition could not be generated")
def on_pushButton_2_clicked(self): """ Slot documentation goes here. """ PF = '' Result = [] ProgBarValue = 0 # TODO: not implemented yet if self.StationBox.count() == 0: PyQt4.QtGui.QMessageBox.warning(self, "Not select Station or Model yet", "Please select correct Station name and Model Name." ,1, 0) if self.lineEdit_2.text() == '': PyQt4.QtGui.QMessageBox.warning(self, "Missing file name", "Please input the file name." ,1, 0) else: FileName = self.lineEdit_2.text() FolderDir = self.lineEdit.text() CurrentFolder = QDir(FolderDir) ResultFolder = QDir(FolderDir + "\\Result\\" ) ResultFolder2 = FolderDir + "\\Result\\" CurrentFile = QFile(FileName+".xls") # Generate the title according to the configuration file print TitleIndex for item in TitleIndex: if item != "Null": sheet1.write(0,TitleIndex.index(item)+3,item,TitleFormat) sheet1.col(TitleIndex.index(item)+3).width = 4000 ResultFolder.setCurrent(FolderDir) for fileName in glob.glob( '*.csv'): ProgBarValue = ProgBarValue +1 if ProgBarValue == 0: PyQt4.QtGui.QMessageBox.warning(self, "No CSV Files", "This folder contains no CSV files, please select again." ,1, 0) for fileName in glob.glob( '*.csv'): Num = glob.glob( '*.csv').index(fileName)+1 print glob.glob( '*.csv').index(fileName), ":", fileName self.progressBar.setValue(round(float(Num)/float(ProgBarValue)*100)) # Open CSV file and use ',' to seperate the column reader = csv.reader(open(fileName), delimiter=",") # First Column to Save File name instead of Serial No. or Test Time sheet1.row(Num).write(0, fileName, NormalFormat) for row in reader: # search every row in the csv file if row != [] and row[0] == 'Part Number' : PartNumber = row[1] sheet1.row(Num).write(1, PartNumber, NormalFormat) if row != [] and ( row[0] == 'OVERALL RESULT' or row[0] == 'DUT P/F' or row[0] == 'Overall Result' ) : PF = row[1] if (PF.find('F')>0) or (PF.find('f')>0): sheet1.row(Num).write(2, PF, FailFormat) else: sheet1.row(Num).write(2, PF, PassFormat) for item in CellIndex: if item != "Null": if reader.line_num == (StrConversionY(item)): if(row != [] and len(row)>= StrConversionX(item)): #Result.append(row[StrConversionX(item)-1]) TempResult = row[StrConversionX(item)-1] if (TempResult.find('F')>0) or (TempResult.find('f')>0): sheet1.row(Num).write(CellIndex.index(item)+3, TempResult, FailFormat) else: if(str.isalpha(TempResult) or str.istitle(TempResult)): # if the contain is not numbers. sheet1.row(Num).write(CellIndex.index(item)+3, TempResult, NormalFormat) elif(str.isspace(TempResult)): # if the contain is not numbers. sheet1.row(Num).write(CellIndex.index(item)+3, TempResult, NormalFormat) else: if row[StrConversionX(item)].find('F')>0 : sheet1.row(Num).write(CellIndex.index(item)+3, float(TempResult), ItemFailFormat) else: sheet1.row(Num).write(CellIndex.index(item)+3, float(TempResult), NormalFormat) if Result==[] : continue #for i in range(0,len(Result)): # if (Result[i].find('F')>0) or (Result[i].find('f')>0): # sheet1.row(Num).write(i+3, Result[i], FailFormat) # else: # if(str.isalpha(Result[i])): # if the contain is not numbers. # sheet1.row(Num).write(i+3, Result[i], NormalFormat) # elif(str.isspace(Result[i])): # if the contain is not numbers. # sheet1.row(Num).write(i+3, Result[i], NormalFormat) # else: # sheet1.row(Num).write(i+3, float(Result[i]), NormalFormat) #Result = [] self.textEdit.append(fileName) ################################################################## #Save to excel file, Save to the result folder in target directory if not(ResultFolder.exists()): CurrentFolder.mkdir(FolderDir+"\\Result\\") ResultFolder.setCurrent(ResultFolder2) # Set to the working folder!! if CurrentFile.exists(): book.save(FileName+'-'+time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime(time.time()))+'.xls') else: book.save(FileName+'.xls') book.save(TemporaryFile()) PyQt4.QtGui.QMessageBox.warning(self, "Done", "Conversion Done!." ,1, 0) sys.exit(app.exec_())
def referencing_column_value(self, field_values): """ Uploads documents based on the file name specified in the source column. :param field_values: Pair of field names and corresponding values i.e. {field1:value1, field2:value2, field3:value3...} :type field_values: dict :return: Ignore type since te source document manager will handle the supporting document uploads. :rtype: IgnoreType """ if self.source_document_manager is None or self.entity is None: return IgnoreType if self.document_type_id is None: msg = QApplication.translate( 'SourceDocumentTranslator', 'Document type has not been set for the source document ' 'translator.' ) raise RuntimeError(msg) if self.source_directory is None: msg = QApplication.translate( 'SourceDocumentTranslator', u'Source directory for {0} has not been set.'.format( self.document_type ) ) raise RuntimeError(msg) source_dir = QDir() if not source_dir.exists(self.source_directory): msg = QApplication.translate( 'SourceDocumentTranslator', u'Source directory for {0} does not exist.'.format( self.document_type ) ) raise IOError(msg) if len(field_values) == 0: return IgnoreType source_column = field_values.keys()[0] # Check if the source column is in the field_values if not source_column in field_values: return IgnoreType # Get file name doc_file_name = field_values.get(source_column) if not doc_file_name: return IgnoreType #Separate files docs = doc_file_name.split(';') #Create document container doc_container = QVBoxLayout() #Register container self.source_document_manager.registerContainer( doc_container, self.document_type_id ) for d in docs: if not d: continue # Normalize slashes d_name = d.replace('\\','/').strip() # Build absolute document path abs_doc_path = u'{0}/{1}'.format(self.source_directory, d_name) if not QFile.exists(abs_doc_path): msg = QApplication.translate( 'SourceDocumentTranslator', u'Supporting document {0} does not exist.'.format( abs_doc_path ) ) raise IOError(msg) # Upload supporting document self.source_document_manager.insertDocumentFromFile( abs_doc_path, self.document_type_id, self.entity ) # Move file to 'uploaded' directory # Documents are handles by the source document manager so we just # instruct the system to ignore the return value return IgnoreType
def create_new_symbol(symbolPath, data): """ This function creates a new knitting symbol as specified by the user. """ # make sure the user's symbol directory exists. If not we # create it symbolTopDir = QDir(symbolPath) if not symbolTopDir.exists(): if not symbolTopDir.mkdir(symbolPath): QMessageBox.critical(None, msg.failedToCreateDirectoryTitle, msg.failedToCreateDirectoryText % symbolPath, QMessageBox.Close) logger.error(msg.failedToCreateDirectoryText % symbolPath) return False # this should never happen since the manageKnittingSymbolDialog is # supposed to check. We'll check anyways. symbolDirPath = symbolPath + "/" + data["svgName"] symbolDir = QDir(symbolDirPath) if symbolDir.exists(): QMessageBox.critical(None, msg.symbolExistsTitle, msg.symbolExistsText % (data["category"], data["name"]), QMessageBox.Close) logger.error(msg.symbolExistsText % (data["category"], data["name"])) return False symbolDir.mkdir(symbolDirPath) # the following try/except suite attempts to return things back # to the initial state if writing fails for some reason descriptionFilePath = None symbolTargetFilePath = None try: # copy the svg file symbolTargetSvgPath = symbolDirPath + "/" + data["svgName"] + ".svg" if not QFile(data["svgPath"]).copy(symbolTargetSvgPath): QMessageBox.critical(None, msg.failedToCopySvgTitle, msg.failedToCopySvgText % symbolTargetSvgPath, QMessageBox.Close) logger.error(msg.failedToCopySvgText % symbolTargetSvgPath) raise IOError # write the description file descriptionFilePath = symbolDirPath + "/" + "description" descriptionFileHandle = QFile(descriptionFilePath) if not descriptionFileHandle.open(QIODevice.WriteOnly): QMessageBox.critical(None, msg.failedCreateDescriptionFileTitle, msg.failedCreateDescriptionFileText % (data["name"], data["category"]), QMessageBox.Close) logger.error(msg.failedCreateDescriptionFileText % (data["name"], data["category"])) raise IOError # finally try to write the content of the file try: write_description_content(descriptionFileHandle, data) except: raise IOError # this does some cleanup in case writing fails for some reason except IOError: if descriptionFilePath: symbolDir.remove(descriptionFilePath) if symbolTargetSvgPath: symbolDir.remove(symbolTargetSvgPath) symbolDir.rmdir(symbolDirPath) return False return True
def run(self,*args,**kwargs): """ :param templatePath: The file path to the user-defined template. :param entityFieldName: The name of the column for the specified entity which must exist in the data source view or table. :param entityFieldValue: The value for filtering the records in the data source view or table. :param outputMode: Whether the output composition should be an image or PDF. :param filePath: The output file where the composition will be written to. Applies to single mode output generation. :param dataFields: List containing the field names whose values will be used to name the files. This is used in multiple mode configuration. :param fileExtension: The output file format. Used in multiple mode configuration. :param dbmodel: In order to name the files using the custom column mapping, a callable sqlalchemy data model must be specified. """ #Unpack arguments templatePath = args[0] entityFieldName = args[1] entityFieldValue = args[2] outputMode = args[3] filePath = kwargs.get("filePath",None) dataFields = kwargs.get("dataFields",[]) fileExtension = kwargs.get("fileExtension","") dataModel = kwargs.get("dbmodel",None) templateFile = QFile(templatePath) if not templateFile.open(QIODevice.ReadOnly): return (False,QApplication.translate("DocumentGenerator","Cannot read template file.")) templateDoc = QDomDocument() if templateDoc.setContent(templateFile): composerDS = ComposerDataSource.create(templateDoc) spatialFieldsConfig = SpatialFieldsConfiguration.create(templateDoc) composerDS.setSpatialFieldsConfig(spatialFieldsConfig) #Execute query dsTable,records = self._execQuery(composerDS.name(), entityFieldName, entityFieldValue) if records == None: return (False,QApplication.translate("DocumentGenerator","No matching records in the database")) """ Iterate through records where a single file output will be generated for each matching record. """ for rec in records: composition = QgsComposition(self._mapRenderer) composition.loadFromTemplate(templateDoc) #Set value of composer items based on the corresponding db values for composerId in composerDS.dataFieldMappings().reverse: #Use composer item id since the uuid is stripped off composerItem = composition.getComposerItemById(composerId) if composerItem != None: fieldName = composerDS.dataFieldName(composerId) fieldValue = getattr(rec,fieldName) self._composerItemValueHandler(composerItem, fieldValue) #Create memory layers for spatial features and add them to the map for mapId,spfmList in spatialFieldsConfig.spatialFieldsMapping().iteritems(): mapItem = composition.getComposerItemById(mapId) if mapItem!= None: #Clear any previous memory layer self.clearTemporaryLayers() for spfm in spfmList: #Use the value of the label field to name the layer layerName = getattr(rec,spfm.labelField()) #Extract the geometry using geoalchemy spatial capabilities geomFunc = getattr(rec,spfm.spatialField()).ST_AsText() geomWKT = self._dbSession.scalar(geomFunc) #Create reference layer with feature refLayer = self._buildVectorLayer(layerName) #Add feature bbox = self._addFeatureToLayer(refLayer, geomWKT) bbox.scale(spfm.zoomLevel()) #Add layer to map QgsMapLayerRegistry.instance().addMapLayer(refLayer) self._iface.mapCanvas().setExtent(bbox) self._iface.mapCanvas().refresh() #mapItem.storeCurrentLayerSet() #mapItem.updateCachedImage() #Add layer to memory layer list self._memoryLayers.append(refLayer) mapItem.setNewExtent(self._mapRenderer.extent()) #Build output path and generate composition if filePath != None and len(dataFields) == 0: self._writeOutput(composition,outputMode,filePath) elif filePath == None and len(dataFields) > 0: docFileName = self._buildFileName(dataModel,entityFieldName,entityFieldValue,dataFields,fileExtension) if docFileName == "": return (False,QApplication.translate("DocumentGenerator", "File name could not be generated from the data fields.")) outputDir = self._composerOutputPath() if outputDir == None: return (False,QApplication.translate("DocumentGenerator", "System could not read the location of the output directory in the registry.")) qDir = QDir() if not qDir.exists(outputDir): return (False,QApplication.translate("DocumentGenerator", "Output directory does not exist")) absDocPath = unicode(outputDir) + "/" + docFileName self._writeOutput(composition,outputMode,absDocPath) #Clear temporary layers self.clearTemporaryLayers() return (True,"Success") return (False,"Composition could not be generated")
def uploadDocument(self, entity_source, doc_type, fileinfo): """ Upload document in central repository """ self._entity_source = entity_source self._doc_type = doc_type self.fileID = self.generateFileID() self.sourcePath = unicode(fileinfo.filePath()) profile_name = self.curr_profile.name root_dir = QDir(self.networkPath) doc_dir = QDir(u'{}/{}/{}/{}'.format( self.networkPath, profile_name.lower(), self._entity_source, self._doc_type.lower().replace(' ', '_') ) ) doc_path_str = u'{}/{}/{}/{}'.format( self.networkPath, profile_name.lower(), self._entity_source, self._doc_type.lower().replace(' ', '_') ).lower() if not doc_dir.exists(): res = root_dir.mkpath(doc_path_str) if res: root_doc_type_path = doc_path_str else: root_doc_type_path = self.networkPath else: root_doc_type_path = doc_path_str self.destinationPath = u'{}/{}.{}'.format( root_doc_type_path, self.fileID, fileinfo.completeSuffix() ) srcFile = open(self.sourcePath,'rb') destinationFile = open(self.destinationPath,'wb') #srcLen = self.sourceFile.bytesAvailable() totalRead = 0 while True: inbytes = srcFile.read(4096) if not inbytes: break destinationFile.write(inbytes) totalRead += len(inbytes) #Raise signal on each block written self.emit(SIGNAL("blockWritten(int)"),totalRead) self.emit(SIGNAL("completed(QString)"),self.fileID) srcFile.close() destinationFile.close() return self.fileID
def run(self, *args, **kwargs): """ :param templatePath: The file path to the user-defined template. :param entityFieldName: The name of the column for the specified entity which must exist in the data source view or table. :param entityFieldValue: The value for filtering the records in the data source view or table. :param outputMode: Whether the output composition should be an image or PDF. :param filePath: The output file where the composition will be written to. Applies to single mode output generation. :param dataFields: List containing the field names whose values will be used to name the files. This is used in multiple mode configuration. :param fileExtension: The output file format. Used in multiple mode configuration. :param data_source: Name of the data source table or view whose row values will be used to name output files if the options has been specified by the user. """ templatePath = args[0] entityFieldName = args[1] entityFieldValue = args[2] outputMode = args[3] filePath = kwargs.get("filePath", None) dataFields = kwargs.get("dataFields", []) fileExtension = kwargs.get("fileExtension", "") data_source = kwargs.get("data_source", "") templateFile = QFile(templatePath) if not templateFile.open(QIODevice.ReadOnly): return False, QApplication.translate("DocumentGenerator", "Cannot read template file.") templateDoc = QDomDocument() if templateDoc.setContent(templateFile): composerDS = ComposerDataSource.create(templateDoc) spatialFieldsConfig = SpatialFieldsConfiguration.create(templateDoc) composerDS.setSpatialFieldsConfig(spatialFieldsConfig) #Check if data source exists and return if it doesn't if not self.data_source_exists(composerDS): msg = QApplication.translate("DocumentGenerator", u"'{0}' data source does not exist in the database." u"\nPlease contact your database " u"administrator.".format(composerDS.name())) return False, msg #TODO: Need to automatically register custom configuration collections #Photo config collection ph_config_collection = PhotoConfigurationCollection.create(templateDoc) #Table configuration collection table_config_collection = TableConfigurationCollection.create(templateDoc) #Create chart configuration collection object chart_config_collection = ChartConfigurationCollection.create(templateDoc) #Load the layers required by the table composer items self._table_mem_layers = load_table_layers(table_config_collection) #Execute query dsTable,records = self._exec_query(composerDS.name(), entityFieldName, entityFieldValue) if records is None or len(records) == 0: return False, QApplication.translate("DocumentGenerator", "No matching records in the database") """ Iterate through records where a single file output will be generated for each matching record. """ for rec in records: composition = QgsComposition(self._map_renderer) composition.loadFromTemplate(templateDoc) #Set value of composer items based on the corresponding db values for composerId in composerDS.dataFieldMappings().reverse: #Use composer item id since the uuid is stripped off composerItem = composition.getComposerItemById(composerId) if not composerItem is None: fieldName = composerDS.dataFieldName(composerId) fieldValue = getattr(rec,fieldName) self._composeritem_value_handler(composerItem, fieldValue) #Extract photo information self._extract_photo_info(composition, ph_config_collection, rec) #Set table item values based on configuration information self._set_table_data(composition, table_config_collection, rec) #Refresh non-custom map composer items self._refresh_composer_maps(composition, spatialFieldsConfig.spatialFieldsMapping().keys()) #Create memory layers for spatial features and add them to the map for mapId,spfmList in spatialFieldsConfig.spatialFieldsMapping().iteritems(): map_item = composition.getComposerItemById(mapId) if not map_item is None: #Clear any previous map memory layer self.clear_temporary_map_layers() for spfm in spfmList: #Use the value of the label field to name the layer lbl_field = spfm.labelField() spatial_field = spfm.spatialField() if not spatial_field: continue if lbl_field: if hasattr(rec, spfm.labelField()): layerName = getattr(rec, spfm.labelField()) else: layerName = self._random_feature_layer_name(spatial_field) else: layerName = self._random_feature_layer_name(spatial_field) #Extract the geometry using geoalchemy spatial capabilities geom_value = getattr(rec, spatial_field) if geom_value is None: continue geom_func = geom_value.ST_AsText() geomWKT = self._dbSession.scalar(geom_func) #Get geometry type geom_type, srid = geometryType(composerDS.name(), spatial_field) #Create reference layer with feature ref_layer = self._build_vector_layer(layerName, geom_type, srid) if ref_layer is None or not ref_layer.isValid(): continue #Add feature bbox = self._add_feature_to_layer(ref_layer, geomWKT) bbox.scale(spfm.zoomLevel()) #Workaround for zooming to single point extent if ref_layer.wkbType() == QGis.WKBPoint: canvas_extent = self._iface.mapCanvas().fullExtent() cnt_pnt = bbox.center() canvas_extent.scale(1.0/32, cnt_pnt) bbox = canvas_extent #Style layer based on the spatial field mapping symbol layer symbol_layer = spfm.symbolLayer() if not symbol_layer is None: ref_layer.rendererV2().symbols()[0].changeSymbolLayer(0,spfm.symbolLayer()) ''' Add layer to map and ensure its always added at the top ''' QgsMapLayerRegistry.instance().addMapLayer(ref_layer, False) QgsProject.instance().layerTreeRoot().insertLayer(0, ref_layer) self._iface.mapCanvas().setExtent(bbox) self._iface.mapCanvas().refresh() #Add layer to map memory layer list self._map_memory_layers.append(ref_layer) ''' Use root layer tree to get the correct ordering of layers in the legend ''' self._refresh_map_item(map_item) #Extract chart information and generate chart self._generate_charts(composition, chart_config_collection, rec) #Build output path and generate composition if not filePath is None and len(dataFields) == 0: self._write_output(composition, outputMode, filePath) elif filePath is None and len(dataFields) > 0: docFileName = self._build_file_name(data_source, entityFieldName, entityFieldValue, dataFields, fileExtension) if not docFileName: return (False, QApplication.translate("DocumentGenerator", "File name could not be generated from the data fields.")) outputDir = self._composer_output_path() if outputDir is None: return (False, QApplication.translate("DocumentGenerator", "System could not read the location of the output directory in the registry.")) qDir = QDir() if not qDir.exists(outputDir): return (False, QApplication.translate("DocumentGenerator", "Output directory does not exist")) absDocPath = u"{0}/{1}".format(outputDir, docFileName) self._write_output(composition, outputMode, absDocPath) #Clear temporary layers self.clear_temporary_layers() return True, "Success" return False, "Document composition could not be generated"