Exemple #1
0
def test_15_display_ListWindow_fillEmpty_skipTable(preCreatedListWindow,
                                                   capsys, height):
    createdListWindow = ListWindow(height, 100, {"Title": "List"}, 3,
                                   ("Column1", "Column2", "Column3"))
    createdListWindow.setHeader()
    createdListWindow.makeheader()
    headerLines = createdListWindow.header
    createdListWindow.draw(fillWindow=True, skipTable=True)
    captured = capsys.readouterr()
    lineIdentifiers = list(string.ascii_lowercase) + list(
        string.ascii_uppercase)
    blankLines = (height - len(headerLines)) * [100 * " "]
    expectedLines = []
    for iline, line in enumerate(headerLines + blankLines):
        expectedLines.append(line.replace(" ", lineIdentifiers[iline]))
    modCapturedLines = []
    for iline, line in enumerate(captured.out.split("\n")):
        if line != "":
            modCapturedLines.append(line.replace(" ", lineIdentifiers[iline]))
    #####################################################################################
    print(
        "/////////////////////////////// EXPECTATION /////////////////////////////////////"
    )
    for line in expectedLines:
        print(line)
    print(
        "///////////////////////////////// RETURN ////////////////////////////////////////"
    )
    for line in modCapturedLines:
        print(line)
    #####################################################################################
    assert len(expectedLines) == len(modCapturedLines)
    for iline in range(len(modCapturedLines)):
        assert modCapturedLines[iline] == expectedLines[iline]
Exemple #2
0
def test_07_display_ListWindow_init():
    createdListWindow = ListWindow(100, 100, {"Title": "List"}, 3,
                                   ("Column1", "Column2", "Column3"))
    createdListWindow.setHeader()
    #Check inherited values:
    assert createdListWindow.boxWidth == createdListWindow.width - 2
    assert createdListWindow.headerTitle == "List"
    assert len(createdListWindow.headerText) == 0
    assert createdListWindow.headerOptions is None
    #Check ListWidow init options:
    assert createdListWindow.nColumns == 3
    assert createdListWindow.lines == []
    assert createdListWindow.tableMaxLen == [
        len("Column1"),
        len("Column2"),
        len("Column3"),
    ]
    with pytest.raises(ValueError):
        ListWindow(100, 100, {"Title": "List"}, 2,
                   ("Column1", "Column2", "Column3"))
Exemple #3
0
def preCreatedListWindow():
    headerElements = {
        "Title": "This is the Title",
        "Text": ["First line text", "Second line text"],
        "Options": [("FirstName", "FirstComment"),
                    ("SecondName", "SecondComment")]
    }
    fixWindow = ListWindow(100, 100, headerElements, 3,
                           ("Column1", "Column2", "Column3"))
    fixWindow.setHeader()
    entry1 = ("Entry1,1", "Entry1,2", "Entry1,3")
    entry2 = ("Entry2,1", "Entry2,2", "Entry2,3")
    entry3 = ("Entry3,1", "Entry3,2", "Entry3,3")
    fixWindow.update([entry1, entry2, entry3])
    return fixWindow
Exemple #4
0
    def __init__(self, dababase: DataBase, enableStartupSeatch=True):
        self.database = dababase
        if not os.path.exists(self.database.mimirdir + "/MTF_model.json"):
            raise RuntimeError(
                "No MTF configuration found in .mimir directory. Use make MTFconfig.py to create on from the database config"
            )
        self.config = MTFConfig(self.database.mimirdir + "/MTF_model.json")
        self.lastIDList = self.database.getAllValuebyItemName("ID")
        self.windowHeight = self.config.height
        self.windowWidth = self.config.width
        self.tableColumns = len(self.config.items)
        self.tableColumnItems = self.config.items
        self.tableColumnNames = []
        for item in self.config.items:
            self.tableColumnNames.append(
                self.config.itemInfo[item]["DisplayName"])
        self.tableColumnNames = tuple(self.tableColumnNames)

        ################### Main Window ###################
        mainHeader = {
            "Title":
            self.config.windows["Main"]["Title"],
            "Text":
            ["Mimir base dir: {0}".format(self.database.databaseRoot)] +
            self.config.windows["Main"]["Text"],
            "Options":
            self.config.windows["Main"]["Options"],
        }
        self.mainWindow = Window(self.windowHeight, self.windowWidth,
                                 mainHeader)
        self.mainWindow.setHeader()
        ################### List Window ###################
        listHeader = {
            "Title": self.config.windows["List"]["Title"],
            "Options": self.config.windows["List"]["Options"],
        }
        self.listWindow = ListWindow(self.windowHeight, self.windowWidth,
                                     listHeader, self.tableColumns,
                                     self.tableColumnNames)
        self.listWindow.setHeader()
        self.listWindowDrawn = False
        self.firstInteraction = True
        self.inOverflow = False
        ################### DB Window ###################
        dbHeader = {
            "Title": self.config.windows["DB"]["Title"],
            "Text": self.config.windows["DB"]["Text"],
            "Options": self.config.windows["DB"]["Options"],
        }
        self.dbWindow = Window(self.windowHeight, self.windowWidth, dbHeader)
        self.dbWindow.setHeader()
        for key in self.config.windows:
            print(self.config.windows[key])
        ################### Modification Window ###################
        modHeader = {
            "Title": self.config.windows["Modify"]["Title"],
            "Text": self.config.windows["Modify"]["Text"],
            "Options": self.config.windows["Modify"]["Options"],
        }
        self.modWindow = Window(self.windowHeight, self.windowWidth, modHeader)
        self.modWindow.setHeader()
        ################### Mulit Modification Window ###################
        self.mulitModExecVal = len(
            self.config.windows["MultiModify"]["Options"])
        self.config.windows["MultiModify"]["Options"].append(
            ("Silent Execute", "Will not count to opened"))
        multiModHeader = {
            "Title": self.config.windows["MultiModify"]["Title"],
            "Text": self.config.windows["MultiModify"]["Text"],
            "Options": self.config.windows["MultiModify"]["Options"],
        }
        self.multiModWindow = Window(self.windowHeight, self.windowWidth,
                                     multiModHeader)
        self.multiModWindow.setHeader()
        self.allMultiModWindow = {}

        self.modSingleItems = []
        self.modListItems = []
        for item in self.config.modItems:
            if item in self.database.model.items:
                self.modSingleItems.append(item)
            else:
                self.modListItems.append(item)
Exemple #5
0
class App:
    """
    App class that manages the communication between the Window module and the database model

    Args:
        dababase (DataBase) : Initialized mimir DataBase
        enableStartupSeatch (bool) : If True, a search for new files will be enabled on startup
    """
    def __init__(self, dababase: DataBase, enableStartupSeatch=True):
        self.database = dababase
        if not os.path.exists(self.database.mimirdir + "/MTF_model.json"):
            raise RuntimeError(
                "No MTF configuration found in .mimir directory. Use make MTFconfig.py to create on from the database config"
            )
        self.config = MTFConfig(self.database.mimirdir + "/MTF_model.json")
        self.lastIDList = self.database.getAllValuebyItemName("ID")
        self.windowHeight = self.config.height
        self.windowWidth = self.config.width
        self.tableColumns = len(self.config.items)
        self.tableColumnItems = self.config.items
        self.tableColumnNames = []
        for item in self.config.items:
            self.tableColumnNames.append(
                self.config.itemInfo[item]["DisplayName"])
        self.tableColumnNames = tuple(self.tableColumnNames)

        ################### Main Window ###################
        mainHeader = {
            "Title":
            self.config.windows["Main"]["Title"],
            "Text":
            ["Mimir base dir: {0}".format(self.database.databaseRoot)] +
            self.config.windows["Main"]["Text"],
            "Options":
            self.config.windows["Main"]["Options"],
        }
        self.mainWindow = Window(self.windowHeight, self.windowWidth,
                                 mainHeader)
        self.mainWindow.setHeader()
        ################### List Window ###################
        listHeader = {
            "Title": self.config.windows["List"]["Title"],
            "Options": self.config.windows["List"]["Options"],
        }
        self.listWindow = ListWindow(self.windowHeight, self.windowWidth,
                                     listHeader, self.tableColumns,
                                     self.tableColumnNames)
        self.listWindow.setHeader()
        self.listWindowDrawn = False
        self.firstInteraction = True
        self.inOverflow = False
        ################### DB Window ###################
        dbHeader = {
            "Title": self.config.windows["DB"]["Title"],
            "Text": self.config.windows["DB"]["Text"],
            "Options": self.config.windows["DB"]["Options"],
        }
        self.dbWindow = Window(self.windowHeight, self.windowWidth, dbHeader)
        self.dbWindow.setHeader()
        for key in self.config.windows:
            print(self.config.windows[key])
        ################### Modification Window ###################
        modHeader = {
            "Title": self.config.windows["Modify"]["Title"],
            "Text": self.config.windows["Modify"]["Text"],
            "Options": self.config.windows["Modify"]["Options"],
        }
        self.modWindow = Window(self.windowHeight, self.windowWidth, modHeader)
        self.modWindow.setHeader()
        ################### Mulit Modification Window ###################
        self.mulitModExecVal = len(
            self.config.windows["MultiModify"]["Options"])
        self.config.windows["MultiModify"]["Options"].append(
            ("Silent Execute", "Will not count to opened"))
        multiModHeader = {
            "Title": self.config.windows["MultiModify"]["Title"],
            "Text": self.config.windows["MultiModify"]["Text"],
            "Options": self.config.windows["MultiModify"]["Options"],
        }
        self.multiModWindow = Window(self.windowHeight, self.windowWidth,
                                     multiModHeader)
        self.multiModWindow.setHeader()
        self.allMultiModWindow = {}

        self.modSingleItems = []
        self.modListItems = []
        for item in self.config.modItems:
            if item in self.database.model.items:
                self.modSingleItems.append(item)
            else:
                self.modListItems.append(item)

    def start(self):
        """
        Start point for the app. Launches the mainWindow.
        """
        logger.info("Starting App")
        self.runMainWindow(None)

    def runMainWindow(self, startVal):
        """
        Function defining the interactions of the main window
        """
        logger.info("Switching to main window")
        retVal = startVal
        while retVal != "0":
            retVal = self.mainWindow.draw("Enter Value")
            if retVal == "1":
                executeID = self.mainWindow.draw("Enter ID to execute")
                self.execute(executeID, self.mainWindow)
            elif retVal == "2":
                self.runModWindow(None, fromMain=True, fromList=False)
            elif retVal == "3":
                self.runListWindow(None)
            elif retVal == "4":
                self.executeRandom(self.mainWindow)
            elif retVal == "5":
                self.runDBWindow(None)
            elif retVal == "0":
                self.terminate()
            else:
                if retVal != "0":
                    self.mainWindow.update("Please enter value present in %s" %
                                           self.mainWindow.validOptions)

    def runListWindow(self, startVal):
        """
        Function defining the interactions of the List window
        """
        logger.info("Switching to ListWindow")
        retVal = startVal
        if self.listWindow.nLinesPrinted > self.windowHeight:
            logger.info("Listwindow in overflow -> nPrinted %s",
                        self.listWindow.nLinesPrinted)
            self.inOverflow = True
        logger.debug("self.inOverflow=%s  self.listWindowDrawn=%s",
                     self.inOverflow, self.listWindowDrawn)
        self.listWindow.draw(skipHeader=self.inOverflow,
                             skipTable=(not self.listWindowDrawn),
                             fillWindow=(not self.inOverflow))
        self.listWindowDrawn = True
        #retVal = self.listWindow.interact("Enter Value:", None)
        while retVal != "0":
            retVal = self.listWindow.interact(
                "Enter Value", None, onlyInteraction=self.firstInteraction)
            if self.firstInteraction:
                self.firstInteraction = False
            if retVal == "1":  #Print All
                allIDs = sorted(list(
                    self.database.getAllValuebyItemName("ID")),
                                key=lambda x: int(x))
                tableElements = self.generateList(allIDs)
                #tableElements = self.generateList("All")
                self.listWindow.lines = []
                self.listWindow.update(tableElements)
                #print("=========================================")
                #self.listWindow.draw(skipHeader = True, skipTable = False, fillWindow = False)
                #print("+++++++++++++++++++++++++++++++++++++++++")
                #retVal = self.listWindow.interact("Enter Value", None, onlyInteraction = False)
            elif retVal == "2":
                self.runModWindow(None, fromMain=False, fromList=True)
            elif retVal == "3":
                executeID = self.listWindow.interact("Enter ID to execute")
                self.execute(executeID, self.listWindow, fromList=True)
            elif retVal == "4":
                self.executeRandom(self.listWindow, fromList=True)
            elif retVal == "5":
                queryString = self.listWindow.interact("Enter Query",
                                                       None,
                                                       onlyInteraction=True)
                thisQuery = queryString.split(" ")
                queryIDs = self.database.query(self.config.queryItems,
                                               thisQuery,
                                               returnIDs=True)
                queryIDs = sorted(queryIDs, key=lambda x: int(x))
                tableElements = self.generateList(queryIDs)
                self.listWindow.lines = []
                self.listWindow.update(tableElements)
            elif retVal == "6":
                sortedIDs = self.database.getSortedIDs(
                    "Added",
                    reverseOrder=True)[0:self.config.restrictedListLen]
                tableElements = self.generateList(sortedIDs)
                self.listWindow.lines = []
                self.listWindow.update(tableElements)
            elif retVal == "7":
                sortedIDs = self.database.getSortedIDs(
                    "Opened",
                    reverseOrder=True)[0:self.config.restrictedListLen]
                tableElements = self.generateList(sortedIDs)
                self.listWindow.lines = []
                self.listWindow.update(tableElements)
            elif retVal == "8":
                sortedIDs = self.database.getSortedIDs(
                    "Changed",
                    reverseOrder=True)[0:self.config.restrictedListLen]
                tableElements = self.generateList(sortedIDs)
                self.listWindow.lines = []
                self.listWindow.update(tableElements)
            elif retVal == "9":
                del_ID = self.listWindow.interact(
                    "Enter ID to be marked/unmarked for deletion")
                self.toggle_for_deletion(del_ID, self.listWindow)
            elif retVal == "10":
                queryIDs = self.database.query(["DeletionMark"],
                                               "1",
                                               returnIDs=True)
                queryIDs = sorted(queryIDs, key=lambda x: int(x))
                tableElements = self.generateList(queryIDs)
                self.listWindow.lines = []
                self.listWindow.update(tableElements)
            else:
                if retVal != "0":
                    self.listWindow.print("Please enter value present in %s" %
                                          self.listWindow.validOptions)
                #tableElements = self.generateList("All")
        self.runMainWindow(None)

    def runDBWindow(self, startVal):
        """
        Function defining the interactions of the DB interaction window
        """
        logger.info("Switching to main window")
        retVal = startVal
        while retVal != "0":
            retVal = self.dbWindow.draw("Enter Value: ")
            if retVal == "1":
                self.dbWindow.update("Saving database")
                self.database.saveMain()
            elif retVal == "2":
                newFiles, file_id_pair = self.database.findNewFiles()
                for newFile, ID in file_id_pair:
                    self.dbWindow.update("Added file %s with ID %s" %
                                         (newFile, ID))
                    suggestedOptions = self.database.getItemsPyPath(newFile)
                    foundOne = False
                    for item in suggestedOptions:
                        if suggestedOptions[item] != set():
                            foundOne = True
                    if not foundOne:
                        continue
                    for item in suggestedOptions:
                        for option in suggestedOptions[item]:
                            answer = self.dbWindow.draw(
                                "Do you want to add %s to %s [Yes/No]" %
                                (option, item))
                            if answer.lower() == "yes":
                                if item in self.database.model.items:
                                    self.database.modifySingleEntry(ID,
                                                                    item,
                                                                    option,
                                                                    byID=True)
                                elif item in self.database.model.listitems:
                                    self.database.modifyListEntry(ID,
                                                                  item,
                                                                  option,
                                                                  "Append",
                                                                  byID=True)
                                else:
                                    raise RuntimeError(
                                        "This should not happen!")
            elif retVal == "3":
                updatedFiles = self.database.checkChangedPaths()
                if updatedFiles:
                    for id_, oldPath_, newPath_ in updatedFiles:
                        self.dbWindow.update(
                            "Moved entry with ID %s now has path %s" %
                            (id_, newPath_))
                else:
                    self.dbWindow.update("No files with changed paths")

            elif retVal == "4":
                IDchanges = self.database.checkMissingFiles()
                if IDchanges:
                    for oldID, newID in IDchanges:
                        self.dbWindow.update("Moved entry from ID %s to %s" %
                                             (oldID, newID))
                else:
                    self.dbWindow.update("No Files removed")
            elif retVal == "5":
                queryIDs = self.database.query(["DeletionMark"],
                                               "1",
                                               returnIDs=True)
                queryIDs = sorted(queryIDs, key=lambda x: int(x))
                if len(queryIDs) > 0:
                    total_size = 0
                    for id_ in queryIDs:
                        e = self.database.getEntryByItemName("ID", id_)[0]
                        total_size += float(e.Size)
                        self.dbWindow.update(
                            f"{id_} is marked for delection(Name: {e.Name}; Size: {e.Size} GB)"
                        )
                    self.dbWindow.update(
                        f"{len(queryIDs)} entries marked for deletion with a total size of {total_size} GB"
                    )
                    del_q = self.dbWindow.draw(
                        "Are you sure you want to delete these entries? [Y/n]: "
                    )
                    if del_q == "Y":
                        self.del_ids(queryIDs, self.dbWindow)
                        IDchanges = self.database.checkMissingFiles()
                        if IDchanges:
                            for oldID, newID in IDchanges:
                                self.dbWindow.update(
                                    "Moved entry from ID %s to %s" %
                                    (oldID, newID))
                else:
                    self.dbWindow.update("No entries marked for deletion")
            else:
                if retVal != "0":
                    self.dbWindow.update("Please enter value present in %s" %
                                         self.dbWindow.validOptions)
        self.runMainWindow(None)

    def runModWindow(self, startVal, fromMain, fromList):
        """
        Function defining the interactions of the modification window
        """
        logger.info("Switching to modification window")
        retVal = startVal
        while retVal != "0":
            retVal = self.modWindow.draw("Enter Value: ")
            if retVal == "0":
                pass
            elif retVal == "1":
                ID = self.modWindow.draw("Enter ID: ")
                if ID in self.database.getAllValuebyItemName("ID"):
                    newWindow = False
                    if ID not in self.allMultiModWindow.keys():
                        self.allMultiModWindow[ID] = deepcopy(
                            self.multiModWindow)
                        newWindow = True
                    self.runMultiModWindow(None, ID, newWindow, fromMain,
                                           fromList)
                else:
                    self.modWindow.update("ID %s not in database" % ID)
            elif retVal == "2":
                IDs = self.modWindow.draw("Enter IDs as XXX - YYY")
                IDs = IDs.replace(" ", "")
                res = re.search("[0-9]+-[0-9]+", IDs)
                validInput = False
                if res is not None:
                    if res.span() == (0, len(IDs)):
                        validInput = True
                if validInput:
                    self.modWindow.update("%s is a valid intput" % IDs)
                    fistID, lastID = IDs.split("-")
                    IDList = [
                        str(x)
                        for x in list(range(int(fistID),
                                            int(lastID) + 1))
                    ]
                    self.processListOfModification(self.modWindow, IDList)
                else:
                    self.modWindow.update("%s is a invalid intput" % IDs)
            elif retVal == "3":
                IDs = self.modWindow.draw("Enter IDs as XXX,YYY,..")
                IDs = IDs.replace(" ", "")
                res = re.search("([0-9],)+[0-9]", IDs)
                validInput = False
                if res is not None:
                    if res.span() == (0, len(IDs)):
                        validInput = True
                if validInput:
                    IDList = IDs.split(",")
                    self.processListOfModification(self.modWindow, IDList)
                else:
                    self.modWindow.update("%s is a invalid intput" % IDs)
            else:
                if retVal != "0":
                    self.modWindow.update("Please enter value present in %s" %
                                          self.modWindow.validOptions)
        if fromMain:
            self.runMainWindow(None)
        if fromList:
            self.runListWindow(None)

    def processListOfModification(self, window, IDList):
        """
        Function prevalidating the IDs set in the ModWindows for bulk updating of Entries
        """
        IDList = sorted(IDList, key=lambda x: int(x))
        _validIDs = []
        _rmIDs = []
        for ID in IDList:
            if int(ID) > len(self.database.entries) - 1:
                _rmIDs.append(ID)
            else:
                _validIDs.append(ID)
        if len(_rmIDs) > 0:
            window.update("IDs %s are larger than max (%s)" %
                          (_rmIDs, len(self.database.entries) - 1))
        if len(_validIDs) > 0:
            window.update("IDList : %s" % _validIDs)
            self.modListOfItems(self.modWindow, _validIDs)

    def runMultiModWindow(self, startVal, ID, isNewWindow, fromMain, fromList):
        """
        Function defining the interactions of the multi modification window. Will spawn a new one for each ID modified in the current scope of the app
        """
        logger.info("Switching to multi modification window for ID %s", ID)
        thisWindow = self.allMultiModWindow[ID]
        entry = self.database.getEntrybyID(ID)
        if isNewWindow:
            thisWindow.headerText.append("Entry information:")
            thisWindow.headerText.append("ID: %s" % ID)
            thisWindow.headerText.append("Path: %s" %
                                         entry.getItem("Path").value)
        for elem in thisWindow.headerOptions:
            modID, name, comment = elem
            if name in self.database.model.allItems:
                thisWindow.headerTextSecondary[name] = self.getPrintItemValues(
                    ID, name, joinFull=True)
        retVal = startVal
        while retVal != "0":
            retVal = thisWindow.draw("Enter Value: ")
            if retVal == "0":
                pass
            elif retVal in thisWindow.validOptions:
                if retVal == str(self.mulitModExecVal):
                    thisWindow.update("Silent Execute triggered")  ###TEMP
                    self.execute(ID, thisWindow, silent=True)
                else:
                    for elem in thisWindow.headerOptions:
                        modID, name, comment = elem
                        if modID == retVal:
                            thisWindow.update("%s, %s" %
                                              (modID, name))  ###TEMP
                            if name in self.database.model.items.keys():
                                thisWindow.update("%s is a Item" %
                                                  name)  ###TEMP
                                self.modSingleItem(thisWindow, [ID],
                                                   name,
                                                   fromMultiMod=True)
                            elif name in self.database.model.listitems.keys():
                                thisWindow.update("%s is a ListItem" %
                                                  name)  ###TEMP
                                self.modListItem(thisWindow, [ID],
                                                 name,
                                                 fromMultiMod=True)
                            else:
                                thisWindow.update(
                                    "Something weird happend for %s" % (name))
            else:
                thisWindow.update("Please enter value present in %s" %
                                  thisWindow.validOptions)
        self.runModWindow(None, fromMain, fromList)

    def modListItem(self, window, IDs, name, verbose=True, fromMultiMod=False):
        """
        Wrapper for the different modification options and how they are called in the database

        Args:
            windows (Window or ListWindows) : Current window
            IDs (list) : List of IDs to be modified
            name (str) : Item name to be modified
        """
        method = window.draw("Choose Method (Append | Replace | Remove)")
        if method in ["Append", "Replace", "Remove"]:
            if method == "Append":
                newValue = window.draw("New Value")
                for ID in IDs:
                    self.makeListModifications(ID, name, "Append", None,
                                               newValue)
                    if verbose:
                        window.update("Appended %s" % newValue)
            elif method == "Remove":
                oldValue = window.draw("Remove Value")
                for ID in IDs:
                    sucess = self.makeListModifications(
                        ID, name, "Remove", oldValue, None)
                    if sucess:
                        if verbose:
                            window.update("Removed %s from entry" % oldValue)
                    else:
                        window.update("Value %s no in entry" % oldValue)
            else:
                oldValue = window.draw("Value to replace")
                newValue = window.draw("New Value")
                for ID in IDs:
                    sucess = self.makeListModifications(
                        ID, name, "Replace", oldValue, newValue)
                    if not sucess:
                        window.update("Value %s no in entry" % oldValue)
                    else:
                        if verbose:
                            window.update("Replaces %s with %s" %
                                          (oldValue, newValue))
        else:
            window.update("!!! - %s is Invalid Method" % method)
        if fromMultiMod:
            window.headerTextSecondary[name] = self.getPrintItemValues(
                IDs[0], name, joinFull=True)

    def modListOfItems(self, window, IDs):
        """
        Multiple modification of a single Item
        """
        item = window.draw("Change item ({0})".format(" | ".join(
            self.config.modItems)))
        if item in self.modSingleItems:
            newValue = window.draw("New Value for %s" % item)
            for ID in IDs:
                self.database.modifySingleEntry(ID, item, newValue, byID=True)
        elif item in self.modListItems:
            self.modListItem(window, IDs, item, verbose=False)
        else:
            window.update("Input is no valid item")

    def modSingleItem(self, window, IDs, name=None, fromMultiMod=False):
        """
        Wrapper for modifying a Single Item
        """
        if name is None:
            name = window.draw("Change item ({0})".format(" | ".join(
                self.modSingleItems)))
        if name in self.modSingleItems:
            newValue = window.draw("New Value for %s" % name)
            for ID in IDs:
                self.database.modifySingleEntry(ID, name, newValue, byID=True)
            if fromMultiMod:
                window.headerTextSecondary[name] = self.getPrintItemValues(
                    IDs[0], name, joinFull=True)

    def makeListModifications(self, ID, name, method, oldValue, newValue):
        """
        Making a singel modification to a ListItem
        """
        if method == "Append":
            self.database.modifyListEntry(ID,
                                          name,
                                          newValue,
                                          "Append",
                                          byID=True)
            return True
        elif method == "Remove":
            try:
                self.database.modifyListEntry(ID,
                                              name,
                                              None,
                                              "Remove",
                                              oldValue,
                                              byID=True)
            except ValueError:
                return False
            else:
                return True
        elif method == "Replace":
            try:
                self.database.modifyListEntry(ID,
                                              name,
                                              newValue,
                                              "Replace",
                                              oldValue,
                                              byID=True)
            except ValueError:
                return False
            else:
                return True
        else:
            pass

    def execute(self, ID, window, fromList=False, silent=False):
        """
        Function called when a entry should be executed. The idea is, that for a desired 
        execution program etc. a shell script with the called (as done in the terminal) 
        is placed in the executable folder.

        After execution the **Opened** will be incrememented.
        """
        if ID not in self.database.getAllValuebyItemName("ID"):
            window.print("ID %s not in database" % ID)
        else:
            entry2Exec = self.database.getEntryByItemName("ID", ID)[0]
            path2Exec = self.database.databaseRoot + "/" + entry2Exec.Path
            if not fromList:
                window.print("Path: %s" % path2Exec)
            os.system("{0} {1}".format(self.config.executable, path2Exec))
            if not silent:
                self.database.modifyListEntry(
                    ID,
                    "Opened",
                    mimir.backend.helper.getTimeFormatted("Full"),
                    byID=True)

    def executeRandom(self, window, fromList=False):
        """
        Function for getting a random entry from the last printed List of entries (if none printed from all)
        """
        if not self.lastIDList:
            window.print("No entries to choose from. Maybe requery?")
        else:
            randID = self.database.getRandomEntry(chooseFrom=self.lastIDList)
            _listIDList = self.lastIDList
            if fromList:
                tableElements = self.generateList([randID])
                self.lastIDList = _listIDList
                window.lines = []
                window.update(tableElements)
            else:
                window.update("Executing entry with ID {0}".format(randID))
            self.execute(randID, window, fromList)

    def toggle_for_deletion(self, ID, window):
        if ID not in self.database.getAllValuebyItemName("ID"):
            window.update("ID %s not in database" % ID)
        else:
            e = self.database.getEntryByItemName("ID", ID)[0]
            if e.DeletionMark == "0":
                logger.info("Marking ID %s for deletion", ID)
                self.database.modifySingleEntry(ID,
                                                "DeletionMark",
                                                "1",
                                                byID=True)
            else:
                logger.info("Unmarking ID %s for deletion", ID)
                self.database.modifySingleEntry(ID,
                                                "DeletionMark",
                                                "0",
                                                byID=True)

    def del_ids(self, ids, window):
        window.update("Will delete entries...")
        for id_ in ids:
            e = self.database.getEntryByItemName("ID", id_)[0]
            path2del = self.database.databaseRoot + "/" + e.Path
            window.update(f"Removing {path2del}")
            os.remove(path2del)
        window.update("...done deleting entries.")

    def terminate(self):
        """
        Function called form the main window to terminate the app
        """
        logger.info("Checking if database was saved")
        #TODO: CHeck if database is modified but nit saved
        logger.info("Terminating app")
        exit()

    def generateList(self, get="All"):
        """
        Function generating the necessary table elements win using the ListWindow. Will used all items set in the DisplayItems configuration option
        """
        #TODO Check get input
        tableElements = []
        ids2Print = None
        if get == "All":
            ids2Print = self.database.getAllValuebyItemName("ID")
            ids2Print = sorted(list(ids2Print), key=lambda x: int(x))
        elif isinstance(get, list):
            ids2Print = get
        self.lastIDList = ids2Print
        #logger.info(ids2Print)
        for id in ids2Print:
            entryElements = []
            thisEntry = self.database.getEntryByItemName("ID", id)[0]
            for item in self.tableColumnItems:
                isCounter = False
                if self.config.itemInfo[item]["Type"] == "Counter":
                    thisItem = None
                    isCounter = True
                else:
                    thisItem = thisEntry.getItem(item)
                if isCounter:
                    value = str(
                        self.database.getCount(
                            id, self.config.itemInfo[item]["Base"], byID=True))
                else:
                    value = self.getPrintItemValues(id, item)
                entryElements.append(value)
            tableElements.append(tuple(entryElements))
        return tableElements

    def getPrintItemValues(self, ID, item, joinWith=", ", joinFull=False):
        retValue = None
        thisEntry = self.database.getEntryByItemName("ID", ID)[0]
        if item in self.database.model.items:
            value = thisEntry.getItem(item).value
            self.modDisaply(item, value)
            if len(value
                   ) > self.config.itemInfo[item]["maxLen"] and not joinFull:
                retValue = value[:self.config.itemInfo[item]["maxLen"]] + ".."
            else:
                retValue = value
        elif item in self.database.model.listitems:
            retValue = self.joinItemValues(thisEntry, item, joinWith, joinFull)
        else:
            raise KeyError("Item %s no listitem or singelitem")

        return retValue

    def joinItemValues(self, entry, item, joinWith=", ", joinFull=False):
        """
        Will join all values in a ListItem. Will use the config settings Priority, DisplayDefault and nDisplay to format the return value. nDisplay can be overruled by the joinFull argument.

        Args:
            entry (DataBaseEntry)
            item (str) : ListItem to be joined (Function expects listitem no check implemented)
            joinWith (str) : String that will be used to join values
            joinFull (bool) : Will overrule the maximum lenghts

        Returns:
            value (str) : Joined values
        """
        thisValue = []
        for priority in self.config.itemInfo[item]["Priority"]:
            if priority in entry.getItem(item).value:
                thisValue.append(priority)
        loopVals = deepcopy(entry.getItem(item).value)
        if self.config.itemInfo[item]["Sorting"] == "reverse":
            loopVals.reverse()
        for val in loopVals:
            if val not in thisValue and len(
                    thisValue) <= self.config.itemInfo[item]["nDisplay"]:
                if (val == self.database.model.getDefaultValue(item)
                        and self.config.itemInfo[item]["DisplayDefault"]
                        is not None):
                    if self.config.itemInfo[item]["DisplayDefault"] != "":
                        thisValue.append(
                            self.config.itemInfo[item]["DisplayDefault"])
                else:
                    thisValue.append(self.modDisaply(item, val))
            if len(thisValue) >= self.config.itemInfo[item]["nDisplay"]:
                if item not in ["Opened", "Changed"]:
                    thisValue.append("..")
                break
        value = joinWith.join(thisValue)
        return value

    def modDisaply(self, item, value):
        """
        Function processes the modDisplay setting from the config.
        """
        if "modDisplay" in self.config.itemInfo[item].keys():
            if self.config.itemInfo[item]["modDisplay"] == "Date":
                value = value.split("|")[0]
            elif self.config.itemInfo[item]["modDisplay"] == "Time":
                value = value.split("|")[1]
            elif self.config.itemInfo[item]["modDisplay"] == "Full":
                pass
            else:
                raise NotImplementedError(
                    "modDisplay value %s not implemented" %
                    self.config.itemInfo[item]["modDisplay"])
        return value

    def modifyItemDisplay(self, item, value):
        """
        Function for processing the modDisplay option in the MTF coniguration:

        Args:
            value (str) : Item Value
            item (str) : Item name

        Returns:
            value (str) : If modDispaly set will return modified value otherwise passed one
        """
        if "modDisplay" in self.config.itemInfo[item].keys():
            if self.config.itemInfo[item]["modDisplay"] == "Date":
                value = value.split("|")[0]
            elif self.config.itemInfo[item]["modDisplay"] == "Time":
                value = value.split("|")[1]
            elif self.config.itemInfo[item]["modDisplay"] == "Full":
                pass
            else:
                raise NotImplementedError(
                    "modDisplay value %s not implemented" %
                    self.config.itemInfo[item]["modDisplay"])

        return value

    def about(self):
        """
        Method that returns the information for the about screen. Like python-version, number entryies, number if values per ListItem, most used Value

        Returns:
            aboutInfo (dict) : All values of interest

        TODO: Implement
        """
        pass
Exemple #6
0
def test_16_display_ListWindow_fillEmpty_afterTableDraw(capsys, height):
    """
    This test is used to varify
    """
    def mock_input(s):
        return s + " (mocked)"

    createdListWindow = ListWindow(height, 100, {"Title": "List"}, 3,
                                   ("Column1", "Column2", "Column3"))
    createdListWindow.setHeader()
    createdListWindow.makeheader()
    headerLines = createdListWindow.header
    tableEntries = []
    tableEntries2 = []
    for i in range(5):
        tableEntries.append(("Entry" + str(i) + ",1", "Entry" + str(i) + ",2",
                             "Entry" + str(i) + ",3"))
        tableEntries2.append(
            ("SecEntry" + str(i) + ",1", "SecEntry" + str(i) + ",2",
             "SecEntry" + str(i) + ",3"))
    createdListWindow.update(tableEntries)
    tableLines = createdListWindow.makeTable(
        createdListWindow.tableHeaderElements, createdListWindow.lines,
        createdListWindow.tableMaxLen)
    createdListWindow.draw(fillWindow=True)
    captured = capsys.readouterr()
    # -1 because there is one empty element after the split
    assert len(captured.out.split("\n")) - 1 == height

    # for iline, line in enumerate(captured.out.split("\n")):
    #     print(iline, "a ",line)
    # captured = capsys.readouterr()
    display.input = mock_input
    createdListWindow.interact("Requesting input", None, onlyInteraction=True)
    createdListWindow.lines = []
    createdListWindow.update(tableEntries2)
    tableLines2 = createdListWindow.makeTable(
        createdListWindow.tableHeaderElements, createdListWindow.lines,
        createdListWindow.tableMaxLen)
    createdListWindow.draw(fillWindow=True)

    captured = capsys.readouterr()
    assert len(captured.out.split("\n")) - 1 == height
    # for iline, line in enumerate(captured.out.split("\n")):
    #     print("{0:2}".format(iline), "b",line)

    #Build expectation
    lineIdentifiers = 3 * (list(string.ascii_lowercase) +
                           list(string.ascii_uppercase) + list(range(10)))
    leftAlignTableLines = []
    for line in tableLines:
        lineLen = len(line)
        leftAlignTableLines.append(" " + line + " " +
                                   (createdListWindow.boxWidth - lineLen) *
                                   " ")
    leftAlignTableLines2 = []
    for line in tableLines2:
        lineLen = len(line)
        leftAlignTableLines2.append(" " + line + " " +
                                    (createdListWindow.boxWidth - lineLen) *
                                    " ")

    interactionStr = "" + mock_input("Requesting input: Requesting input: ")
    interaction = [interactionStr + " " * (100 - len(interactionStr))]

    blankLines = (height - len(headerLines) - len(leftAlignTableLines) -
                  len(leftAlignTableLines2) - 1) * [100 * " "]

    expectedLines = []
    for iline, line in enumerate(headerLines + blankLines +
                                 leftAlignTableLines + interaction +
                                 leftAlignTableLines2):
        expectedLines.append(line.replace(" ", lineIdentifiers[iline]))

    modCapturedLines = []
    for iline, line in enumerate(captured.out.split("\n")):
        if line != "":
            modCapturedLines.append(
                line.replace(" ", str(lineIdentifiers[iline])))

    ####################################################################################
    print(
        "/////////////////////////////// EXPECTATION /////////////////////////////////////"
    )
    for line in expectedLines:
        print(line)
    print(
        "///////////////////////////////// RETURN ////////////////////////////////////////"
    )
    for line in modCapturedLines:
        print(line)
    ####################################################################################
    assert len(expectedLines) == len(modCapturedLines)
    for iline in range(len(modCapturedLines)):
        assert modCapturedLines[iline] == expectedLines[iline]
Exemple #7
0
def test_08_display_ListWindow_update():
    createdListWindow = ListWindow(100, 100, {"Title": "List"}, 3,
                                   ("Column1", "Column2", "Column3"))
    createdListWindow.setHeader()
    with pytest.raises(TypeError):
        createdListWindow.update("NotATuple")
    with pytest.raises(TypeError):
        createdListWindow.update(["NotATuple"])
    with pytest.raises(ValueError):
        createdListWindow.update(("1", "2", "3", "4"))
    with pytest.raises(ValueError):
        createdListWindow.update(("1", "2"))
    createdListWindow.lines = []
    entry1 = ("Entry1,1", "Entry1,2", "Entry1,3")
    createdListWindow.update(entry1)
    assert entry1 == createdListWindow.lines[0]
    entry2 = ("Entry2,1", "Entry2,2", "Entry2,3")
    entry3 = ("Entry3,1", "Entry3,2", "Entry3,3")
    createdListWindow.update([entry2, entry3])
    assert entry2 == createdListWindow.lines[1]
    assert entry3 == createdListWindow.lines[2]