Browse Source

Functional part working

Akash Singh 3 years ago
parent
commit
ea5bb93b7b
4 changed files with 275 additions and 15 deletions
  1. 66 0
      icopy2xls/FilesOpen.py
  2. 4 1
      icopy2xls/__init__.py
  3. 2 2
      ui.py
  4. 203 12
      uimain.py

+ 66 - 0
icopy2xls/FilesOpen.py

@@ -0,0 +1,66 @@
+import platform
+import os
+import subprocess
+import xl2dict
+from logging import getLogger
+
+logger = getLogger("pyC")
+
+def open(filenameAndPath: str):
+    """Will open the given file with the Operating system default program.
+
+    param
+
+    filenameAndPath : Complete absolute path to file.
+    return : True if sucessfully open. False if file doesn't exists or operating system doesn't have default program.
+    """
+
+    if not isinstance(filenameAndPath, str):
+        filenameAndPath = str(filenameAndPath)
+
+    filenameAndPath = os.path.abspath(filenameAndPath)
+    logger.debug(f"Trying to open file with it's application: {filenameAndPath}")
+
+    if not os.path.exists(filenameAndPath):
+        logger.warning(f"Filename doesn't exist and can't be opened: {filenameAndPath}")
+        return False
+
+    elif platform.system().lower() == "windows":
+        try:
+            filenameAndPath = f'"{filenameAndPath}"'
+            os.startfile(filenameAndPath)
+            return True
+        except Exception as errorcode:
+            if errorcode.errno == 22:
+                os.popen(r"Rundll32.exe SHELL32.DLL, OpenAs_RunDLL "+filenameAndPath)
+                return True
+            else:
+                return False
+
+    elif platform.system().lower() == "linux":
+        logger.debug(f"In Linux trying to call xdg-open with filename: {str(filenameAndPath)}")
+        status = subprocess.call(["xdg-open", str(filenameAndPath)])
+        if status == 0:
+            return True
+        else:
+            return False
+
+    elif platform.system().lower() == "darwin":
+        filenameAndPath = f'"{filenameAndPath}"'
+        status = os.system("open " + str(filenameAndPath))
+        if status == 0:
+            return True
+        else:
+            return False
+
+
+class FilesOpen:
+    """
+    Class is called from UI and will open the corresponding file-type in the os-specific application.
+    """
+    def __init__(self):
+        pass
+
+    @staticmethod
+    def openResultFile(filenameAndPath):
+        return open(filenameAndPath=filenameAndPath)

+ 4 - 1
icopy2xls/__init__.py

@@ -82,7 +82,10 @@ class Mover:
                 if row[ind].value not in filters[filter]:  # check if data is matching with filter
                     remove_data.append(row)
             for row in remove_data:  # removing unmatched data from new_data list
-                new_data.remove(row)
+                try:
+                    new_data.remove(row)
+                except ValueError:
+                    pass
         row_num = destination.nrows  # used to maintain new row number
         for data in new_data:  # iterating through the data to be written and writing then on the correct cells
             row_num += 1

+ 2 - 2
ui.py

@@ -4,7 +4,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
 class Ui_MainWindow(QtCore.QObject):
     def setupUi(self, MainWindow):
         MainWindow.setObjectName("MainWindow")
-        MainWindow.resize(480, 480)
+        MainWindow.resize(480, 300)
         font = QtGui.QFont()
         font.setFamily("Arial")
         font.setPointSize(11)
@@ -283,7 +283,7 @@ class Ui_MainWindow(QtCore.QObject):
         sizePolicy.setHeightForWidth(self.runButton.sizePolicy().hasHeightForWidth())
         self.runButton.setSizePolicy(sizePolicy)
         self.runButton.setMinimumSize(QtCore.QSize(90, 0))
-        self.runButton.setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(114, 159, 207);")
+        self.runButton.setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(138, 226, 52);")
         self.runButton.setObjectName("openLogFilePushButton_4")
         self.horizontalLayout_6.addWidget(self.runButton)
         self.openResultFilePushButton = QtWidgets.QPushButton(self.mainGroupBox)

+ 203 - 12
uimain.py

@@ -1,6 +1,10 @@
 from ui import  Ui_MainWindow
 from PyQt5 import QtCore, QtGui, QtWidgets
-
+import platform
+from icopy2xls import Mover
+import os
+import xlrd
+from  icopy2xls.FilesOpen import FilesOpen
 
 class MainWindow(Ui_MainWindow):
     """ BaangtUI : Logic implementation file for uidesign
@@ -17,25 +21,130 @@ class MainWindow(Ui_MainWindow):
         logic here we want to do with User Interface
         '''
         super().setupUi(MainWindow)
-        self.filterButton.clicked.connect(self.filterDialog)
         self.row_list = []
         self.filters = {}
+        self.sheet_headers = []
+        self.sourceBrowsePushButton.clicked.connect(self.sourceBrowsePathSlot)
+        self.destinationBrowsePushButton.clicked.connect(self.destinationBrowsePathSlot)
+        self.filterButton.clicked.connect(self.filterDialog)
+        self.runButton.clicked.connect(self.runMain)
+        self.openResultFilePushButton.clicked.connect(self.openResultFile)
+
+    def sourceBrowsePathSlot(self):
+        """ Browse Folder Containing *.xlsx file for execution. And
+           globals.json file for Test specific settings
+        """
+        # get path from pathLineEdit
+        basepath = self.sourcePathLineEdit.text()
+        if not basepath:
+            basepath = "./"
+        options = QtWidgets.QFileDialog.Options()
+        options |= QtWidgets.QFileDialog.DontUseNativeDialog
+        dirName = QtWidgets.QFileDialog.getOpenFileName(
+            None,
+            "Select File ",
+            basepath,
+            options=options,
+            filter="Excel (*.xlsx *.xls)"
+        )
+        if dirName:
+            # self.pathLineEdit.insert(dirName)
+            self.setupBasePath(dirName, "source")
+
+    def destinationBrowsePathSlot(self):
+        """ Browse Folder Containing *.xlsx file for execution. And
+           globals.json file for Test specific settings
+        """
+        # get path from pathLineEdit
+        basepath = self.destinationPathLineEdit.text()
+        if not basepath:
+            basepath = "./"
+        options = QtWidgets.QFileDialog.Options()
+        options |= QtWidgets.QFileDialog.DontUseNativeDialog
+        dirName = QtWidgets.QFileDialog.getOpenFileName(
+            None,
+            "Select File ",
+            basepath,
+            options=options,
+            filter="Excel (*.xlsx *.xls)"
+        )
+        if dirName:
+            # self.pathLineEdit.insert(dirName)
+            self.setupBasePath(dirName, "destination")
+
+    def setupBasePath(self, dirPath="", typ=""):
+        """ Setup Base path of Execution as per directory Path"""
+
+        if not dirPath:
+            # Set up base path to Baangt directory
+            # Based on current File path ../../../
+            dirPath = os.path.dirname(os.path.dirname(
+                          os.path.dirname(os.path.dirname(__file__))
+                          ))
+            if not dirPath:
+                dirPath = os.path.abspath(os.curdir)
+            if typ == "source":
+                self.sourcePathLineEdit.insert(dirPath)
+            else:
+                self.destinationPathLineEdit.insert(dirPath)
+        else:
+            if typ == "source":
+                self.sourcePathLineEdit.setText(dirPath[0])
+            else:
+                self.destinationPathLineEdit.setText(dirPath[0])
+        self.statusbar.showMessage(f"Current {typ} Path: {dirPath} ", 2000)
+        if os.path.exists(dirPath[0]):
+            if typ == "source":
+                self.getSheetsSource(dirPath[0])
+            else:
+                self.getSheetsDestination(dirPath[0])
+        else:
+            self.statusbar.showMessage(f"Invalid {typ} Path: {dirPath} ", 3000)
+
+    def getSheetsSource(self, dirName):
+        """ Scan for *.xlsx files and *.json files and
+        update the testRunComboBox and settingsComboBox items
+        """
+        wb = xlrd.open_workbook(dirName)
+        Sheets = wb.sheet_names()
+        self.sourceSheetComboBox.clear()
+        # Add files in Combo Box
+        self.sourceSheetComboBox.addItems(Sheets)
+        # set default selection to 0
+        if len(Sheets) > 0:
+            self.sourceSheetComboBox.setCurrentIndex(0)
+            selectedSheet = self.sourceSheetComboBox.currentText()
+            self.statusbar.showMessage("Sheet: {}".format(selectedSheet), 3000)
+
+    def getSheetsDestination(self, dirName):
+        """ Scan for *.xlsx files and *.json files and
+        update the testRunComboBox and settingsComboBox items
+        """
+        wb = xlrd.open_workbook(dirName)
+        Sheets = wb.sheet_names()
+        self.destinationSheetComboBox.clear()
+        # Add files in Combo Box
+        self.destinationSheetComboBox.addItems(Sheets)
+        # set default selection to 0
+        if len(Sheets) > 0:
+            self.destinationSheetComboBox.setCurrentIndex(0)
+            selectedSheet = self.destinationSheetComboBox.currentText()
+            self.statusbar.showMessage("Sheet: {}".format(selectedSheet), 3000)
 
     def filterDialog(self):
+        self.row_list = []
+        self.update_headers()
         self.filter_dialog = QtWidgets.QDialog(self.centralwidget)
-        #sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
-        #sizePolicy.setHorizontalStretch(0)
-        #sizePolicy.setVerticalStretch(0)
-        #sizePolicy.setHeightForWidth(self.filter_dialog.sizePolicy().hasHeightForWidth())
-        #self.filter_dialog.setSizePolicy(sizePolicy)
         self.filter_dialog.setWindowTitle("Filters")
-        self.filter_dialog.setWindowTitle("Cleanup")
         self.vlay = QtWidgets.QVBoxLayout()
         hori = QtWidgets.QHBoxLayout()
         hori.setSpacing(10)
         add_button = QtWidgets.QPushButton("Add", self.filter_dialog)
+        add_button.setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(114, 159, 207);")
         remove_button = QtWidgets.QPushButton("Remove", self.filter_dialog)
+        remove_button.setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(204, 0, 0);")
         save_button = QtWidgets.QPushButton("Save", self.filter_dialog)
+        save_button.setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(138, 226, 52);")
         hori.addWidget(add_button)
         hori.addWidget(remove_button)
         hori.addWidget(save_button)
@@ -44,8 +153,39 @@ class MainWindow(Ui_MainWindow):
         add_button.clicked.connect(self.add_row)
         remove_button.clicked.connect(self.remove_row)
         save_button.clicked.connect(self.save_filters)
+        for data in self.filters:
+            if not data:
+                continue
+            self.update_filterDialog(data, self.filters[data])
         self.filter_dialog.exec_()
 
+    def update_headers(self):
+        source_file = self.sourcePathLineEdit.text()
+        if source_file:
+            wb = xlrd.open_workbook(source_file)
+            sht = wb.sheet_by_name(self.sourceSheetComboBox.currentText())
+            self.sheet_headers = [s.value for s in sht.row(0)]
+
+    def update_filterDialog(self, key, value):
+        for val in value:
+            hr = QtWidgets.QHBoxLayout()
+            hr.setSpacing(10)
+            cb = QtWidgets.QComboBox()
+            cb.setMinimumSize(QtCore.QSize(200, 0))
+            cb.setMaximumSize(QtCore.QSize(250, 16777215))
+            cb.setStyleSheet("background-color: rgb(255, 255, 255);")
+            line = QtWidgets.QLineEdit()
+            line.setMinimumSize(QtCore.QSize(300, 0))
+            line.setMaximumSize(QtCore.QSize(350, 16777215))
+            line.setStyleSheet("background-color: rgb(255, 255, 255);")
+            cb.addItems(self.sheet_headers)
+            cb.setCurrentIndex(self.sheet_headers.index(key))
+            line.setText(val)
+            hr.addWidget(cb)
+            hr.addWidget(line)
+            self.row_list.append([cb, line, hr])
+            self.vlay.addLayout(hr)
+
     def add_row(self):
         hr = QtWidgets.QHBoxLayout()
         hr.setSpacing(10)
@@ -53,6 +193,7 @@ class MainWindow(Ui_MainWindow):
         cb.setMinimumSize(QtCore.QSize(200, 0))
         cb.setMaximumSize(QtCore.QSize(250, 16777215))
         cb.setStyleSheet("background-color: rgb(255, 255, 255);")
+        cb.addItems(self.sheet_headers)
         line = QtWidgets.QLineEdit()
         line.setMinimumSize(QtCore.QSize(300, 0))
         line.setMaximumSize(QtCore.QSize(350, 16777215))
@@ -65,16 +206,62 @@ class MainWindow(Ui_MainWindow):
     def remove_row(self):
         if self.row_list:
             last = self.row_list.pop()
-            last[0].deleteLater()
-            last[1].deleteLater()
-            last[2].deleteLater()
+            key = last[0].currentText()
+            if key in self.filters:
+                self.filters[key].remove(last[1].text())
+                if not self.filters[key]:
+                    del self.filters[key]
+            for l in last:
+                l.deleteLater()
 
     def save_filters(self):
         filters = {}
         if self.row_list:
             for row in self.row_list:
-                filters[row[0].currentText()] = row[1].text()
+                key = row[0].currentText()
+                if key not in filters:
+                    filters[key] = [row[1].text()]
+                else:
+                    filters[key].append(row[1].text())
         self.filters = filters
+        self.filter_dialog.close()
+
+    def runMain(self):
+        source, source_sheet, destination, destination_sheet = self.check_fields()
+        if not source and not source_sheet and not destination and not destination_sheet:
+            pass
+        else:
+            self.statusbar.showMessage("Running...", 3000)
+            lines = self.linesInput.text()
+            mover = Mover(source, source_sheet, destination, destination_sheet, int(lines))
+            mover.move(self.filters, self.addMissingCheckBox.isChecked())
+            self.statusbar.showMessage("Completed...", 3000)
+
+    def check_fields(self):
+        source = self.sourcePathLineEdit.text()
+        source_sheet = self.sourceSheetComboBox.currentText()
+        destination = self.destinationPathLineEdit.text()
+        destination_sheet = self.destinationSheetComboBox.currentText()
+        if not source:
+            self.statusbar.showMessage(f"Source file path is invalid! Please check", 5000)
+        elif not source_sheet:
+            self.statusbar.showMessage(f"Source sheet name is invalid! Please check", 5000)
+        elif not destination:
+            self.statusbar.showMessage(f"Destination file path is invalid! Please check", 5000)
+        elif not destination_sheet:
+            self.statusbar.showMessage(f"Destination sheet name is invalid! Please check", 5000)
+        return source, source_sheet, destination, destination_sheet
+
+    def openResultFile(self):
+        destinationFile = self.destinationPathLineEdit.text()
+        if destinationFile:
+            if os.path.exists(destinationFile):
+                FilesOpen.openResultFile(destinationFile)
+            else:
+                self.statusbar.showMessage(f"File doesn't exist : {destinationFile}")
+        else:
+            self.statusbar.showMessage(f"No destination File selected")
+
 
 
 class MainController:
@@ -92,6 +279,10 @@ class MainController:
 if __name__ == "__main__":
     import sys
     app = QtWidgets.QApplication(sys.argv)
+    if platform.system() == "Linux":
+        QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
+    elif platform.system() == "Darwin":
+        QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create('Windows'))
     controller = MainController()
     controller.show_main()
     sys.exit(app.exec_())