问:
How to create a looping module that creates one window at a time per SQL row result?
I'm creating an IP Configuration program where in one part, I have to modify selected rows from my database to modify information into them.

In order for me to do this, I have to create a window at every row, then wait for the user to finish the input before the user presses next, and a new window will pop out and the old window would be Destroyed.

Here is the Code I have for the module:

class moddtb(wx.Frame):
    def __init__(self, title, parent=None):
        global l_a
        t = len(l_a)
        self.n = 0
        self.b = 0
        while self.n<t:
            while True:
                wx.Frame.__init__(self, parent=parent, title=title, size=(1100, 500))
                panel = wx.Panel(self)
                self.Centre(direction=wx.BOTH)
                self.Bind(wx.EVT_CLOSE, self.cls)
                print(self.n)
                mycursor.execute("SELECT * FROM ip_config WHERE id=%s;", (l_a[self.n],))
                new_ip = mycursor.fetchone()
                self.n_id = str(new_ip[0])
                self.n_hn = str(new_ip[1])
                self.n_rl = str(new_ip[2])
                self.n_aut = str(new_ip[3])
                self.n_ali = str(new_ip[4])
                self.n_typ = str(new_ip[5])
                self.n_env = str(new_ip[6])
                self.n_isc = str(new_ip[7])
                self.n_sta = str(new_ip[8])
                self.n_vla = str(new_ip[9])
                self.n_ip = str(new_ip[10])
                self.n_pui = str(new_ip[11])
                self.n_gri = str(new_ip[12])
                self.n_idr = str(new_ip[13])
                self.n_sys = str(new_ip[14])
                self.n_aps = str(new_ip[15])
                self.n_das = str(new_ip[16])
                self.n_phs = str(new_ip[17])
                self.n_rac = str(new_ip[18])
                self.n_lom = str(new_ip[19])
                self.n_phm = str(new_ip[20])
                self.n_mod = str(new_ip[21])
                self.n_ser = str(new_ip[22])
                self.n_prv = str(new_ip[23])
                self.n_os = str(new_ip[24])
                self.n_war = str(new_ip[25])
                self.n_es = str(new_ip[26])
                self.n_el = str(new_ip[27])
                if self.n_hn is None:
                    wx.MessageBox('An error has been made, selected row %s is empty. Skipping to next row.' % (self.n_id), 'Creation Error', wx.OK | wx.ICON_ERROR)
                    continue
                f1 = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, "Arial")
                f2 = wx.Font(18, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD, False, "Sergoe UI")

                ttllbl = TransparentText(panel, id=wx.ID_ANY, label="Please fill out the information in this form:   ", pos=(60,27),
                                         size=(200,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                ttllbl.SetFont(f2)
                idlbl = TransparentText(panel, id=wx.ID_ANY, label="ID: ", pos=(60,77),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                idlbl.SetFont(f1)
                idtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_id, pos=(150, 77), size=(180,25), style=wx.TE_READONLY)
                hnlbl = TransparentText(panel, id=wx.ID_ANY, label="Host Name: ", pos=(60,107),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                hnlbl.SetFont(f1)
                self.hntbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_hn, pos=(150, 107), size=(180,25))
                rolelbl = TransparentText(panel, id=wx.ID_ANY, label="Role: ", pos=(60,137),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                rolelbl.SetFont(f1)
                self.roletbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_rl, pos=(150, 137), size=(180,25))
                athlbl = TransparentText(panel, id=wx.ID_ANY, label="Authorize: ", pos=(60,167),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                athlbl.SetFont(f1)
                self.athtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_aut, pos=(150, 167), size=(180,25))
                alslbl = TransparentText(panel, id=wx.ID_ANY, label="Alias: ", pos=(60,197),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                alslbl.SetFont(f1)
                self.alstbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_ali, pos=(150, 197), size=(180,25))
                typlbl = TransparentText(panel, id=wx.ID_ANY, label="Type: ", pos=(60,227),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                typlbl.SetFont(f1)
                self.typtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_typ, pos=(150, 227), size=(180,25))
                envlbl = TransparentText(panel, id=wx.ID_ANY, label="Enviroment: ", pos=(60,257),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                envlbl.SetFont(f1)
                self.envtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_env, pos=(150, 257), size=(180,25))
                isiplbl = TransparentText(panel, id=wx.ID_ANY, label="ISCI IP: ", pos=(60,287),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                isiplbl.SetFont(f1)
                self.isiptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_isc, pos=(150, 287), size=(180,25))
                staiplbl = TransparentText(panel, id=wx.ID_ANY, label="Static IP: ", pos=(60,317),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                staiplbl.SetFont(f1)
                self.staiptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_sta, pos=(150, 317), size=(180,25))
                vliplbl = TransparentText(panel, id=wx.ID_ANY, label="VLAN: ", pos=(60,347),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                vliplbl.SetFont(f1)
                self.vliptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_vla, pos=(150, 347), size=(180,25))

                maniplbl = TransparentText(panel, id=wx.ID_ANY, label="Management IP: ", pos=(360,77),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                maniplbl.SetFont(f1)
                self.maniptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_ip, pos=(500, 77), size=(180,25), style=wx.TE_READONLY)
                pubiplbl = TransparentText(panel, id=wx.ID_ANY, label="Public IP: ", pos=(360,107),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                pubiplbl.SetFont(f1)
                self.pubiptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_pui, pos=(500, 107), size=(180,25))
                grpiplbl = TransparentText(panel, id=wx.ID_ANY, label="Group IP: ", pos=(360,137),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                grpiplbl.SetFont(f1)
                self.grpiptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_gri, pos=(500, 137), size=(180,25))
                idriplbl = TransparentText(panel, id=wx.ID_ANY, label="IDRAC IP: ", pos=(360,167),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                idriplbl.SetFont(f1)
                self.idriptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_idr, pos=(500, 167), size=(180,25))
                sysszlbl = TransparentText(panel, id=wx.ID_ANY, label="System Size: ", pos=(360,197),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                sysszlbl.SetFont(f1)
                self.syssztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_sys, pos=(500, 197), size=(180,25))
                appszlbl = TransparentText(panel, id=wx.ID_ANY, label="Application Size: ", pos=(360,227),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                appszlbl.SetFont(f1)
                self.appsztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_aps, pos=(500, 227), size=(180,25))
                dtszlbl = TransparentText(panel, id=wx.ID_ANY, label="Data Size: ", pos=(360,257),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                dtszlbl.SetFont(f1)
                self.dtsztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_das, pos=(500, 257), size=(180,25))
                physzlbl = TransparentText(panel, id=wx.ID_ANY, label="Physical Size: ", pos=(360,287),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                physzlbl.SetFont(f1)
                self.physztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_phs, pos=(500, 287), size=(180,25))
                rdconlbl = TransparentText(panel, id=wx.ID_ANY, label="Raid Config: ", pos=(360,317),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                rdconlbl.SetFont(f1)
                self.rdcontbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_rac, pos=(500, 317), size=(180,25))
                lgmemszlbl = TransparentText(panel, id=wx.ID_ANY, label="Logical Memory \nSize: ", pos=(360,347),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                lgmemszlbl.SetFont(f1)
                self.lgmemsztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_lom, pos=(500, 347), size=(180,25))

                phymemszlbl = TransparentText(panel, id=wx.ID_ANY, label="Physical Memory \nSize: ", pos=(700,77),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                phymemszlbl.SetFont(f1)
                self.phymemsztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_phm, pos=(840, 77), size=(180,25))
                mdllbl = TransparentText(panel, id=wx.ID_ANY, label="Model: ", pos=(700,117),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                mdllbl.SetFont(f1)
                self.mdltbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_mod, pos=(840, 117), size=(180,25))
                srlnumlbl = TransparentText(panel, id=wx.ID_ANY, label="Serial Number: ", pos=(700,147),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                srlnumlbl.SetFont(f1)
                self.srlnumtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_ser, pos=(840, 147), size=(180,25))
                prvcpulbl = TransparentText(panel, id=wx.ID_ANY, label="Processor/VCPU: ", pos=(700,177),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                prvcpulbl.SetFont(f1)
                self.prvcputbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_prv, pos=(840, 177), size=(180,25))
                oslbl = TransparentText(panel, id=wx.ID_ANY, label="OS: ", pos=(700,207),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                oslbl.SetFont(f1)
                self.ostbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_os, pos=(840, 207), size=(180,25))
                wrtylbl = TransparentText(panel, id=wx.ID_ANY, label="Warranty: ", pos=(700,237),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                wrtylbl.SetFont(f1)
                self.wrtytbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_war, pos=(840, 237), size=(180,25))
                eoslbl = TransparentText(panel, id=wx.ID_ANY, label="End of Support: ", pos=(700,267),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                eoslbl.SetFont(f1)
                self.eostbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_es, pos=(840, 267), size=(180,25))
                eollbl = TransparentText(panel, id=wx.ID_ANY, label="End of Life: ", pos=(700,297),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                eollbl.SetFont(f1)
                self.eoltbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_el, pos=(840, 297), size=(180,25))
                if self.b==1:
                    b3a = wx.Bitmap("button3 a.png")
                    b3b = wx.Bitmap("button3 b.png")
                    b4a = wx.Bitmap("button4 a.png")
                    b4b = wx.Bitmap("button4 b.png")
                    dtbbtnc = btn.GenBitmapButton(panel, wx.ID_ANY, bitmap=b3a, pos=(700,330),  style=wx.NO_BORDER|wx.BU_EXACTFIT,size=(147, 62))
                    dtbbtnc.SetBitmapSelected(b3b)
                    dtbbtnc.Bind(wx.EVT_BUTTON, self.cc)
                    dtbbtnd = btn.GenBitmapButton(panel, wx.ID_ANY, bitmap=b4a, pos=(880,330),  style=wx.NO_BORDER|wx.BU_EXACTFIT,size=(147, 62))
                    dtbbtnd.SetBitmapSelected(b4b)
                    dtbbtnd.Bind(wx.EVT_BUTTON, self.cls2)
                    self.Show()
                else:
                    b8a = wx.Bitmap("button8 a.png")
                    b8b = wx.Bitmap("button8 b.png")
                    b4a = wx.Bitmap("button4 a.png")
                    b4b = wx.Bitmap("button4 b.png")
                    dtbbtnc = btn.GenBitmapButton(panel, wx.ID_ANY, bitmap=b8a, pos=(880,330),  style=wx.NO_BORDER|wx.BU_EXACTFIT,size=(147, 62))
                    dtbbtnc.SetBitmapSelected(b8b)
                    dtbbtnc.Bind(wx.EVT_BUTTON, self.cc)
                    dtbbtnd = btn.GenBitmapButton(panel, wx.ID_ANY, bitmap=b4a, pos=(700,330),  style=wx.NO_BORDER|wx.BU_EXACTFIT,size=(147, 62))
                    dtbbtnd.SetBitmapSelected(b4b)
                    dtbbtnd.Bind(wx.EVT_BUTTON, self.cls)
                    self.Show()
                if t-1==self.n or t==1:
                    self.b=1
                if moddtb.IsShown(self)==False:
                    break
            self.n+=1
    def cls2(self, event):
        frame = dspdtb()
        self.Destroy()
    def cls(self, event):
        nf = MainPage()
        nf.Show()
        self.Destroy()
    def cc(self, event):
        cr_a = self.hntbx.GetValue()
        print ("Value: \"",cr_a,"\"")
        if cr_a != None or cr_a !="" or cr_a !=" " or cr_a !="  " :
            id = self.n_id
            ip = self.n_ip
            cr_b = self.roletbx.GetValue()
            cr_c = self.athtbx.GetValue()
            cr_d = self.alstbx.GetValue()
            cr_e = self.typtbx.GetValue()
            cr_f = self.envtbx.GetValue()
            cr_g = self.isiptbx.GetValue()
            cr_h = self.staiptbx.GetValue()
            cr_i = self.vliptbx.GetValue()
            cr_j = self.pubiptbx.GetValue()
            cr_k = self.grpiptbx.GetValue()
            cr_l = self.idriptbx.GetValue()
            cr_m = self.syssztbx.GetValue()
            cr_n = self.appsztbx.GetValue()
            cr_o = self.dtsztbx.GetValue()
            cr_p = self.physztbx.GetValue()
            cr_q = self.rdcontbx.GetValue()
            cr_r = self.lgmemsztbx.GetValue()
            cr_s = self.phymemsztbx.GetValue()
            cr_t = self.mdltbx.GetValue()
            cr_u = self.srlnumtbx.GetValue()
            cr_v = self.prvcputbx.GetValue()
            cr_w = self.ostbx.GetValue()
            cr_x = self.wrtytbx.GetValue()
            cr_y = self.eostbx.GetValue()
            cr_z = self.eoltbx.GetValue()
            mycursor.execute("UPDATE ip_config SET host_name=%s, role=%s, authorize=%s, alias=%s, type=%s, enviroment=%s, isci_ip=%s, static_ip=%s, vlan=%s, public_ip=%s, group_ip=%s, idrac_ip=%s, system_size=%s, application_size=%s, data_size=%s, physical_size=%s, raid_config=%s, logical_mem=%s, physical_mem=%s, model=%s, serial_number=%s, `processor/vcpu`=%s, os=%s, warranty=%s, end_of_support=%s, end_of_life=%s WHERE id=%s;", (cr_a, cr_b, cr_c, cr_d, cr_e, cr_f, cr_g, cr_h, cr_i, cr_j, cr_k, cr_l, cr_m, cr_n, cr_o, cr_p, cr_q, cr_r, cr_s, cr_t, cr_u, cr_v, cr_w, cr_x, cr_y, cr_z, id))
            if self.b==1:
                LoadThread()
                loada = load()
                loada.ShowModal()
                wx.MessageBox('A new connection has been created, ', 'Connection Created', wx.OK)
            frame = MainPage()
            self.Destroy()
        else:
            wx.MessageBox('An error has been made, please fill out the host name before you continue...', 'Creation Error', wx.OK | wx.ICON_ERROR)
            frame = MainPage()
            self.Destroy()
```

The problem with this module however are two things:

If I run this program, an infinite loop happens, which results to a never ending cycle of opened windows.

Even without the weird infinite loop problem, if I fixed it with only the first loop in mind, then it'll just display all the windows at once instead of displaying them one by one. Creating confusion within the program.

Is there a way to display the modification windows one by one per row without having to display them all at once?

Any help is appreciated. Thanks in advance.

答:
One way to achieve what you want is to show each configuration window as a modal window, just like the window you get when searching for a file (wx.FileDialog).

See the code (and the comments) below for one way to do this.

The problem with the code is that it works perfectly only in Windows. In macOS and Linux the main window is not perfectly disabled. For example, in macOS you cannot minimize and maximize the main window but you can interact with the buttons; in Linux you cannot interact with the buttons but you can minimize and maximize the window. Thus, depending on the platforms you want to support you will need to tweek the code a little bit.

```<code>import wx

class MyFrame(wx.Frame):
    """
    Main Window of the App
    """
    def __init__(self):
        title='Multiple consecutive windows (ShowModal way)'
        super().__init__(None, title=title)

        #### Variables
        # Number of configuration windows that will be created
        self.WinNum = 5
        #### Widgets
        self.panel = wx.Panel(self)
        self.buttonShow = wx.Button(self.panel, pos=(50, 50), label='ShowModal')
        self.buttonTest = wx.Button(self.panel, pos=(50, 100), label='Test')
        #### Bind
        self.buttonShow.Bind(wx.EVT_BUTTON, self.ShowWindows)
        #### Position of the window
        self.SetPosition(pt=(50, 50))

    def ShowWindows(self, event):
        """
        This will create the configuration windows as modal windows.
        """
        i = 0
        # This is to show a way to pass information from the configuration
        # windows to the main window. Just in case.
        self.configResults = []

        #### Depending of the OS you want to support you will need to modify the
        #### this window as explained in the answer. For macOS at least the
        #### ShowModal button must be disable to avoid launching parallel
        #### configuration windows. Remove the comment in the line below
        #self.buttonShow.Disable()

        while i < self.WinNum:
            a = WinModal(i)
            a.ShowModal()
            i += 1

        #### After all windows are closed the button must be enable again in
        #### macOS. Remove the comment in the line below.
        #self.buttonShow.Enable()

        #### Check that the information was passed
        print(self.configResults)

class WinModal(wx.Frame):
    """
    Configuration window
    """
    def __init__(self, ThisWinNum):
        title = 'This is window number: ' + str(ThisWinNum)
        super().__init__(None, title=title)
        #### Variables
        self.ThisWinNum = ThisWinNum
        # To append Cancel when closing the configuration window without
        # clicking Ok
        self.cancel = True
        #### Widgets
        self.panel = wx.Panel(self)
        self.buttonOk = wx.Button(self.panel, pos=(50, 50), label='Ok')
        #### Positions
        self.SetPosition(pt=(200, 200))
        #### Bind
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.Bind(wx.EVT_BUTTON, self.onOk)

    def ShowModal(self):
        """
        This function is the one giving the wx.FileDialog behavior
        """
        self._disabler = wx.WindowDisabler(self)
        self.Show()
        self.eventLoop = wx.GUIEventLoop()
        self.eventLoop.Run()

    def OnClose(self, event):
        """
        To handle closing the windows because you need to exit the eventLoop
        of the modal window.
        """
        if self.cancel:
            frame.configResults.append('Cancel')
        else:
            pass

        del self._disabler
        self.eventLoop.Exit()
        self.Destroy()

    def onOk(self, event):
        """
        Do your configuration and exit by calling self.OnClose. You will need
        something similar if you place a Cancel button in the configuration
        windows.
        """
        print(self.ThisWinNum)
        # Pass the informartion to the main window
        frame.configResults.append(self.ThisWinNum)
        # To avoid append when Ok is clicked
        self.cancel = False
        self.OnClose(event)

if __name__ == '__main__':
    app = wx.App()
    frame = MyFrame()
    frame.Show()
    app.MainLoop()
else:
    pass
</code>```

Body:
I'm creating an IP Configuration program where in one part, I have to modify selected rows from my database to modify information into them.

In order for me to do this, I have to create a window at every row, then wait for the user to finish the input before the user presses next, and a new window will pop out and the old window would be Destroyed.

Here is the Code I have for the module:

class moddtb(wx.Frame):
    def __init__(self, title, parent=None):
        global l_a
        t = len(l_a)
        self.n = 0
        self.b = 0
        while self.n<t:
            while True:
                wx.Frame.__init__(self, parent=parent, title=title, size=(1100, 500))
                panel = wx.Panel(self)
                self.Centre(direction=wx.BOTH)
                self.Bind(wx.EVT_CLOSE, self.cls)
                print(self.n)
                mycursor.execute("SELECT * FROM ip_config WHERE id=%s;", (l_a[self.n],))
                new_ip = mycursor.fetchone()
                self.n_id = str(new_ip[0])
                self.n_hn = str(new_ip[1])
                self.n_rl = str(new_ip[2])
                self.n_aut = str(new_ip[3])
                self.n_ali = str(new_ip[4])
                self.n_typ = str(new_ip[5])
                self.n_env = str(new_ip[6])
                self.n_isc = str(new_ip[7])
                self.n_sta = str(new_ip[8])
                self.n_vla = str(new_ip[9])
                self.n_ip = str(new_ip[10])
                self.n_pui = str(new_ip[11])
                self.n_gri = str(new_ip[12])
                self.n_idr = str(new_ip[13])
                self.n_sys = str(new_ip[14])
                self.n_aps = str(new_ip[15])
                self.n_das = str(new_ip[16])
                self.n_phs = str(new_ip[17])
                self.n_rac = str(new_ip[18])
                self.n_lom = str(new_ip[19])
                self.n_phm = str(new_ip[20])
                self.n_mod = str(new_ip[21])
                self.n_ser = str(new_ip[22])
                self.n_prv = str(new_ip[23])
                self.n_os = str(new_ip[24])
                self.n_war = str(new_ip[25])
                self.n_es = str(new_ip[26])
                self.n_el = str(new_ip[27])
                if self.n_hn is None:
                    wx.MessageBox('An error has been made, selected row %s is empty. Skipping to next row.' % (self.n_id), 'Creation Error', wx.OK | wx.ICON_ERROR)
                    continue
                f1 = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, "Arial")
                f2 = wx.Font(18, wx.DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD, False, "Sergoe UI")

                ttllbl = TransparentText(panel, id=wx.ID_ANY, label="Please fill out the information in this form:   ", pos=(60,27),
                                         size=(200,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                ttllbl.SetFont(f2)
                idlbl = TransparentText(panel, id=wx.ID_ANY, label="ID: ", pos=(60,77),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                idlbl.SetFont(f1)
                idtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_id, pos=(150, 77), size=(180,25), style=wx.TE_READONLY)
                hnlbl = TransparentText(panel, id=wx.ID_ANY, label="Host Name: ", pos=(60,107),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                hnlbl.SetFont(f1)
                self.hntbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_hn, pos=(150, 107), size=(180,25))
                rolelbl = TransparentText(panel, id=wx.ID_ANY, label="Role: ", pos=(60,137),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                rolelbl.SetFont(f1)
                self.roletbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_rl, pos=(150, 137), size=(180,25))
                athlbl = TransparentText(panel, id=wx.ID_ANY, label="Authorize: ", pos=(60,167),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                athlbl.SetFont(f1)
                self.athtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_aut, pos=(150, 167), size=(180,25))
                alslbl = TransparentText(panel, id=wx.ID_ANY, label="Alias: ", pos=(60,197),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                alslbl.SetFont(f1)
                self.alstbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_ali, pos=(150, 197), size=(180,25))
                typlbl = TransparentText(panel, id=wx.ID_ANY, label="Type: ", pos=(60,227),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                typlbl.SetFont(f1)
                self.typtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_typ, pos=(150, 227), size=(180,25))
                envlbl = TransparentText(panel, id=wx.ID_ANY, label="Enviroment: ", pos=(60,257),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                envlbl.SetFont(f1)
                self.envtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_env, pos=(150, 257), size=(180,25))
                isiplbl = TransparentText(panel, id=wx.ID_ANY, label="ISCI IP: ", pos=(60,287),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                isiplbl.SetFont(f1)
                self.isiptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_isc, pos=(150, 287), size=(180,25))
                staiplbl = TransparentText(panel, id=wx.ID_ANY, label="Static IP: ", pos=(60,317),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                staiplbl.SetFont(f1)
                self.staiptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_sta, pos=(150, 317), size=(180,25))
                vliplbl = TransparentText(panel, id=wx.ID_ANY, label="VLAN: ", pos=(60,347),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                vliplbl.SetFont(f1)
                self.vliptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_vla, pos=(150, 347), size=(180,25))

                maniplbl = TransparentText(panel, id=wx.ID_ANY, label="Management IP: ", pos=(360,77),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                maniplbl.SetFont(f1)
                self.maniptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_ip, pos=(500, 77), size=(180,25), style=wx.TE_READONLY)
                pubiplbl = TransparentText(panel, id=wx.ID_ANY, label="Public IP: ", pos=(360,107),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                pubiplbl.SetFont(f1)
                self.pubiptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_pui, pos=(500, 107), size=(180,25))
                grpiplbl = TransparentText(panel, id=wx.ID_ANY, label="Group IP: ", pos=(360,137),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                grpiplbl.SetFont(f1)
                self.grpiptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_gri, pos=(500, 137), size=(180,25))
                idriplbl = TransparentText(panel, id=wx.ID_ANY, label="IDRAC IP: ", pos=(360,167),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                idriplbl.SetFont(f1)
                self.idriptbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_idr, pos=(500, 167), size=(180,25))
                sysszlbl = TransparentText(panel, id=wx.ID_ANY, label="System Size: ", pos=(360,197),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                sysszlbl.SetFont(f1)
                self.syssztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_sys, pos=(500, 197), size=(180,25))
                appszlbl = TransparentText(panel, id=wx.ID_ANY, label="Application Size: ", pos=(360,227),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                appszlbl.SetFont(f1)
                self.appsztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_aps, pos=(500, 227), size=(180,25))
                dtszlbl = TransparentText(panel, id=wx.ID_ANY, label="Data Size: ", pos=(360,257),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                dtszlbl.SetFont(f1)
                self.dtsztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_das, pos=(500, 257), size=(180,25))
                physzlbl = TransparentText(panel, id=wx.ID_ANY, label="Physical Size: ", pos=(360,287),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                physzlbl.SetFont(f1)
                self.physztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_phs, pos=(500, 287), size=(180,25))
                rdconlbl = TransparentText(panel, id=wx.ID_ANY, label="Raid Config: ", pos=(360,317),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                rdconlbl.SetFont(f1)
                self.rdcontbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_rac, pos=(500, 317), size=(180,25))
                lgmemszlbl = TransparentText(panel, id=wx.ID_ANY, label="Logical Memory \nSize: ", pos=(360,347),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                lgmemszlbl.SetFont(f1)
                self.lgmemsztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_lom, pos=(500, 347), size=(180,25))

                phymemszlbl = TransparentText(panel, id=wx.ID_ANY, label="Physical Memory \nSize: ", pos=(700,77),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                phymemszlbl.SetFont(f1)
                self.phymemsztbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_phm, pos=(840, 77), size=(180,25))
                mdllbl = TransparentText(panel, id=wx.ID_ANY, label="Model: ", pos=(700,117),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                mdllbl.SetFont(f1)
                self.mdltbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_mod, pos=(840, 117), size=(180,25))
                srlnumlbl = TransparentText(panel, id=wx.ID_ANY, label="Serial Number: ", pos=(700,147),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                srlnumlbl.SetFont(f1)
                self.srlnumtbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_ser, pos=(840, 147), size=(180,25))
                prvcpulbl = TransparentText(panel, id=wx.ID_ANY, label="Processor/VCPU: ", pos=(700,177),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                prvcpulbl.SetFont(f1)
                self.prvcputbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_prv, pos=(840, 177), size=(180,25))
                oslbl = TransparentText(panel, id=wx.ID_ANY, label="OS: ", pos=(700,207),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                oslbl.SetFont(f1)
                self.ostbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_os, pos=(840, 207), size=(180,25))
                wrtylbl = TransparentText(panel, id=wx.ID_ANY, label="Warranty: ", pos=(700,237),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                wrtylbl.SetFont(f1)
                self.wrtytbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_war, pos=(840, 237), size=(180,25))
                eoslbl = TransparentText(panel, id=wx.ID_ANY, label="End of Support: ", pos=(700,267),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                eoslbl.SetFont(f1)
                self.eostbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_es, pos=(840, 267), size=(180,25))
                eollbl = TransparentText(panel, id=wx.ID_ANY, label="End of Life: ", pos=(700,297),
                                         size=(50,50), style=wx.TRANSPARENT_WINDOW, name='transparenttext')
                eollbl.SetFont(f1)
                self.eoltbx = wx.TextCtrl(panel, id=wx.ID_ANY, value=self.n_el, pos=(840, 297), size=(180,25))
                if self.b==1:
                    b3a = wx.Bitmap("button3 a.png")
                    b3b = wx.Bitmap("button3 b.png")
                    b4a = wx.Bitmap("button4 a.png")
                    b4b = wx.Bitmap("button4 b.png")
                    dtbbtnc = btn.GenBitmapButton(panel, wx.ID_ANY, bitmap=b3a, pos=(700,330),  style=wx.NO_BORDER|wx.BU_EXACTFIT,size=(147, 62))
                    dtbbtnc.SetBitmapSelected(b3b)
                    dtbbtnc.Bind(wx.EVT_BUTTON, self.cc)
                    dtbbtnd = btn.GenBitmapButton(panel, wx.ID_ANY, bitmap=b4a, pos=(880,330),  style=wx.NO_BORDER|wx.BU_EXACTFIT,size=(147, 62))
                    dtbbtnd.SetBitmapSelected(b4b)
                    dtbbtnd.Bind(wx.EVT_BUTTON, self.cls2)
                    self.Show()
                else:
                    b8a = wx.Bitmap("button8 a.png")
                    b8b = wx.Bitmap("button8 b.png")
                    b4a = wx.Bitmap("button4 a.png")
                    b4b = wx.Bitmap("button4 b.png")
                    dtbbtnc = btn.GenBitmapButton(panel, wx.ID_ANY, bitmap=b8a, pos=(880,330),  style=wx.NO_BORDER|wx.BU_EXACTFIT,size=(147, 62))
                    dtbbtnc.SetBitmapSelected(b8b)
                    dtbbtnc.Bind(wx.EVT_BUTTON, self.cc)
                    dtbbtnd = btn.GenBitmapButton(panel, wx.ID_ANY, bitmap=b4a, pos=(700,330),  style=wx.NO_BORDER|wx.BU_EXACTFIT,size=(147, 62))
                    dtbbtnd.SetBitmapSelected(b4b)
                    dtbbtnd.Bind(wx.EVT_BUTTON, self.cls)
                    self.Show()
                if t-1==self.n or t==1:
                    self.b=1
                if moddtb.IsShown(self)==False:
                    break
            self.n+=1
    def cls2(self, event):
        frame = dspdtb()
        self.Destroy()
    def cls(self, event):
        nf = MainPage()
        nf.Show()
        self.Destroy()
    def cc(self, event):
        cr_a = self.hntbx.GetValue()
        print ("Value: \"",cr_a,"\"")
        if cr_a != None or cr_a !="" or cr_a !=" " or cr_a !="  " :
            id = self.n_id
            ip = self.n_ip
            cr_b = self.roletbx.GetValue()
            cr_c = self.athtbx.GetValue()
            cr_d = self.alstbx.GetValue()
            cr_e = self.typtbx.GetValue()
            cr_f = self.envtbx.GetValue()
            cr_g = self.isiptbx.GetValue()
            cr_h = self.staiptbx.GetValue()
            cr_i = self.vliptbx.GetValue()
            cr_j = self.pubiptbx.GetValue()
            cr_k = self.grpiptbx.GetValue()
            cr_l = self.idriptbx.GetValue()
            cr_m = self.syssztbx.GetValue()
            cr_n = self.appsztbx.GetValue()
            cr_o = self.dtsztbx.GetValue()
            cr_p = self.physztbx.GetValue()
            cr_q = self.rdcontbx.GetValue()
            cr_r = self.lgmemsztbx.GetValue()
            cr_s = self.phymemsztbx.GetValue()
            cr_t = self.mdltbx.GetValue()
            cr_u = self.srlnumtbx.GetValue()
            cr_v = self.prvcputbx.GetValue()
            cr_w = self.ostbx.GetValue()
            cr_x = self.wrtytbx.GetValue()
            cr_y = self.eostbx.GetValue()
            cr_z = self.eoltbx.GetValue()
            mycursor.execute("UPDATE ip_config SET host_name=%s, role=%s, authorize=%s, alias=%s, type=%s, enviroment=%s, isci_ip=%s, static_ip=%s, vlan=%s, public_ip=%s, group_ip=%s, idrac_ip=%s, system_size=%s, application_size=%s, data_size=%s, physical_size=%s, raid_config=%s, logical_mem=%s, physical_mem=%s, model=%s, serial_number=%s, `processor/vcpu`=%s, os=%s, warranty=%s, end_of_support=%s, end_of_life=%s WHERE id=%s;", (cr_a, cr_b, cr_c, cr_d, cr_e, cr_f, cr_g, cr_h, cr_i, cr_j, cr_k, cr_l, cr_m, cr_n, cr_o, cr_p, cr_q, cr_r, cr_s, cr_t, cr_u, cr_v, cr_w, cr_x, cr_y, cr_z, id))
            if self.b==1:
                LoadThread()
                loada = load()
                loada.ShowModal()
                wx.MessageBox('A new connection has been created, ', 'Connection Created', wx.OK)
            frame = MainPage()
            self.Destroy()
        else:
            wx.MessageBox('An error has been made, please fill out the host name before you continue...', 'Creation Error', wx.OK | wx.ICON_ERROR)
            frame = MainPage()
            self.Destroy()

The problem with this module however are two things:

If I run this program, an infinite loop happens, which results to a never ending cycle of opened windows.

Even without the weird infinite loop problem, if I fixed it with only the first loop in mind, then it'll just display all the windows at once instead of displaying them one by one. Creating confusion within the program.

Is there a way to display the modification windows one by one per row without having to display them all at once?

Any help is appreciated. Thanks in advance.

Body:
One way to achieve what you want is to show each configuration window as a modal window, just like the window you get when searching for a file (wx.FileDialog).

See the code (and the comments) below for one way to do this.

The problem with the code is that it works perfectly only in Windows. In macOS and Linux the main window is not perfectly disabled. For example, in macOS you cannot minimize and maximize the main window but you can interact with the buttons; in Linux you cannot interact with the buttons but you can minimize and maximize the window. Thus, depending on the platforms you want to support you will need to tweek the code a little bit.

import wx

class MyFrame(wx.Frame):
    """
    Main Window of the App
    """
    def __init__(self):
        title='Multiple consecutive windows (ShowModal way)'
        super().__init__(None, title=title)

        #### Variables
        # Number of configuration windows that will be created
        self.WinNum = 5
        #### Widgets
        self.panel = wx.Panel(self)
        self.buttonShow = wx.Button(self.panel, pos=(50, 50), label='ShowModal')
        self.buttonTest = wx.Button(self.panel, pos=(50, 100), label='Test')
        #### Bind
        self.buttonShow.Bind(wx.EVT_BUTTON, self.ShowWindows)
        #### Position of the window
        self.SetPosition(pt=(50, 50))

    def ShowWindows(self, event):
        """
        This will create the configuration windows as modal windows.
        """
        i = 0
        # This is to show a way to pass information from the configuration
        # windows to the main window. Just in case.
        self.configResults = []

        #### Depending of the OS you want to support you will need to modify the
        #### this window as explained in the answer. For macOS at least the
        #### ShowModal button must be disable to avoid launching parallel
        #### configuration windows. Remove the comment in the line below
        #self.buttonShow.Disable()

        while i < self.WinNum:
            a = WinModal(i)
            a.ShowModal()
            i += 1

        #### After all windows are closed the button must be enable again in
        #### macOS. Remove the comment in the line below.
        #self.buttonShow.Enable()

        #### Check that the information was passed
        print(self.configResults)

class WinModal(wx.Frame):
    """
    Configuration window
    """
    def __init__(self, ThisWinNum):
        title = 'This is window number: ' + str(ThisWinNum)
        super().__init__(None, title=title)
        #### Variables
        self.ThisWinNum = ThisWinNum
        # To append Cancel when closing the configuration window without
        # clicking Ok
        self.cancel = True
        #### Widgets
        self.panel = wx.Panel(self)
        self.buttonOk = wx.Button(self.panel, pos=(50, 50), label='Ok')
        #### Positions
        self.SetPosition(pt=(200, 200))
        #### Bind
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.Bind(wx.EVT_BUTTON, self.onOk)

    def ShowModal(self):
        """
        This function is the one giving the wx.FileDialog behavior
        """
        self._disabler = wx.WindowDisabler(self)
        self.Show()
        self.eventLoop = wx.GUIEventLoop()
        self.eventLoop.Run()

    def OnClose(self, event):
        """
        To handle closing the windows because you need to exit the eventLoop
        of the modal window.
        """
        if self.cancel:
            frame.configResults.append('Cancel')
        else:
            pass

        del self._disabler
        self.eventLoop.Exit()
        self.Destroy()

    def onOk(self, event):
        """
        Do your configuration and exit by calling self.OnClose. You will need
        something similar if you place a Cancel button in the configuration
        windows.
        """
        print(self.ThisWinNum)
        # Pass the informartion to the main window
        frame.configResults.append(self.ThisWinNum)
        # To avoid append when Ok is clicked
        self.cancel = False
        self.OnClose(event)

if __name__ == '__main__':
    app = wx.App()
    frame = MyFrame()
    frame.Show()
    app.MainLoop()
else:
    pass


来源: stackexchange

问:
How to target .NET framework to use on Windows 7 and 10 without install?
I am developing a simple C# WPF application that I want to share to internal users. Many users do not have admin rights to install new versions of .NET.

I targeted .NET Framework 3.5 as it came with with Windows 7. Now some users are on Windows 10, and I see .NET Framework 4.6 comes as standard and 3.5 needs to be enabled for the application to run.

Is there any way to target multiple frameworks? Or build a launcher that will run the relevant Win 7 / Win 10 version?

答:
This is addressed by .NET Core as you can publish the runtime along with your application, which is called as self-contained deployment.

In .NET Core 3.0 (in preview at the time of writing), you will be able to build WPF apps as well and publish them to windows 7+ without requiring installations beyond required dependencies (Service Pack level).

ContentLicense: CC BY-SA 4.0


问:
Issue with monitoring custom service on prometheus in kubernetes namespace
My goal is to monitor services with Prometheus, so I was following a guide located at:

https://github.com/coreos/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md

I am relatively new to all of this, so please forgive my naiveness. I tried looking into the error, but all the answers were convoluted. I have no idea where to start on the debug process (perhaps look into the YAMLs?)

I wanted to monitor a custom Service. So, I deployed a service.yaml of the following into a custom namespace (t):

```<code>kind: Service
apiVersion: v1
metadata:
  namespace: t
  name: example-service-test
  labels:
    app: example-service-test
spec:
  selector:
    app: example-service-test
  type: NodePort
  ports:
  - name: http
    nodePort: 30901
    port: 8080
    protocol: TCP
    targetPort: http
---
apiVersion: v1
kind: Pod
metadata:
  name: example-service-test
  namespace: t
  labels:
    app: example-service-test
spec:
  containers:
  - name: example-service-test
    image: python:2.7
    imagePullPolicy: IfNotPresent
    command: ["/bin/bash"]
    args: ["-c", "echo \"<p>This is POD1 $(hostname)</p>\" > index.html; python -m SimpleHTTPServer 8080"]
    ports:
    - name: http
      containerPort: 8080
</code>```

And deployed a service monitor into the namespace:

```<code>apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-service-test
  labels:
    team: frontendtest1
  namespace: t
spec:
  selector:
    matchLabels:
      app: example-service-test
  endpoints:
  - port: http
</code>```

So far, the service monitor is detecting the service, as shown:
Prometheus Service Discovery.
However, there is an error with obtaining the metrics from the service: Prometheus Targets.

From what I know, prometheus isn't able to access the /metrics on the sample service - in that case, do I need to expose the metrics? If so, could I get a step by step guide solution to how to expose metrics? If not, what route should I take?

答:
I'm afraid you could miss the key thing from the tutorial you're following on CoreOS website, about how a metrics from an app are getting to Prometheus:

First, deploy three instances of a simple example application, which
  listens and exposes metrics on port 8080

Yes, your application (website) listens on port 8080, but does not expose any metrics on '/metrics' endpoint in the known to Prometheus format.

You can verify about what kind of metrics I'm talking about by hiting the endpoint from inside of Pod/Conatiner where it's hosted.

```<code>kubectl exec -it $(kubectl get po -l app=example-app -o jsonpath='{.items[0].metadata.name}') -c example-app -- curl localhost:8080/metrics
</code>```

You should see similar output to this one:

# HELP codelab_api_http_requests_in_progress The current number of API HTTP requests in progress.
# TYPE codelab_api_http_requests_in_progress gauge
codelab_api_http_requests_in_progress 1
# HELP codelab_api_request_duration_seconds A histogram of the API HTTP request durations in seconds.
# TYPE codelab_api_request_duration_seconds histogram
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0001"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00015000000000000001"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00022500000000000002"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0003375"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00050625"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.000759375"} 0```

Please read more here on ways of exposing metrics.

Body:
My goal is to monitor services with Prometheus, so I was following a guide located at:

https://github.com/coreos/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md

I am relatively new to all of this, so please forgive my naiveness. I tried looking into the error, but all the answers were convoluted. I have no idea where to start on the debug process (perhaps look into the YAMLs?)

I wanted to monitor a custom Service. So, I deployed a service.yaml of the following into a custom namespace (t):

kind: Service
apiVersion: v1
metadata:
  namespace: t
  name: example-service-test
  labels:
    app: example-service-test
spec:
  selector:
    app: example-service-test
  type: NodePort
  ports:
  - name: http
    nodePort: 30901
    port: 8080
    protocol: TCP
    targetPort: http
---
apiVersion: v1
kind: Pod
metadata:
  name: example-service-test
  namespace: t
  labels:
    app: example-service-test
spec:
  containers:
  - name: example-service-test
    image: python:2.7
    imagePullPolicy: IfNotPresent
    command: ["/bin/bash"]
    args: ["-c", "echo \"
This is POD1 $(hostname)
\" > index.html; python -m SimpleHTTPServer 8080"]
    ports:
    - name: http
      containerPort: 8080

And deployed a service monitor into the namespace:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-service-test
  labels:
    team: frontendtest1
  namespace: t
spec:
  selector:
    matchLabels:
      app: example-service-test
  endpoints:
  - port: http

So far, the service monitor is detecting the service, as shown:
Prometheus Service Discovery.
However, there is an error with obtaining the metrics from the service: Prometheus Targets.

From what I know, prometheus isn't able to access the /metrics on the sample service - in that case, do I need to expose the metrics? If so, could I get a step by step guide solution to how to expose metrics? If not, what route should I take?

Body:
I'm afraid you could miss the key thing from the tutorial you're following on CoreOS website, about how a metrics from an app are getting to Prometheus:

First, deploy three instances of a simple example application, which
  listens and exposes metrics on port 8080

Yes, your application (website) listens on port 8080, but does not expose any metrics on '/metrics' endpoint in the known to Prometheus format.

You can verify about what kind of metrics I'm talking about by hiting the endpoint from inside of Pod/Conatiner where it's hosted.

kubectl exec -it $(kubectl get po -l app=example-app -o jsonpath='{.items[0].metadata.name}') -c example-app -- curl localhost:8080/metrics

You should see similar output to this one:

# HELP codelab_api_http_requests_in_progress The current number of API HTTP requests in progress.
# TYPE codelab_api_http_requests_in_progress gauge
codelab_api_http_requests_in_progress 1
# HELP codelab_api_request_duration_seconds A histogram of the API HTTP request durations in seconds.
# TYPE codelab_api_request_duration_seconds histogram
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0001"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00015000000000000001"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00022500000000000002"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0003375"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00050625"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.000759375"} 0

Please read more here on ways of exposing metrics.


问:
Rancher show alerting but email is not received?
I am using Rancher for Kubernetes deployment. I have setup alerts if pod are downs. If a pod is down then it shows alerting but email is never received. Kindly let me know what is the issue?

I have opened an issue on GitHub for same.
https://github.com/rancher/rancher/issues/20492

答:
As per attached issue on github

Hello,
I have resolved this issue. I have checked log for alertmanager
AlertManager is found in CluserName ->System (DropDown) & there is AlertManager Pod.

My issue was i have added the Non TLS enabled SMTP credentials though rancher validated non TLS enabled credentials & sent Test email but looks like rancher required a TLS enabled SMTP Credentials.


问:
sort string date and sort it
I would like to use sort my list of article by date (dd/mm/yyyy).
Dates are String.

```<code>public class ArticleComparator implements Comparator<Article> {

    @Override
    public int compare(Article a1, Article a2) {
        // TODO Auto-generated method stub
        int result = a1.getDate().compareTo(a2.getDate());
        if(result == 0)
            result = a1.getAuteur().getPseudo().compareTo(a2.getAuteur().getPseudo());
    return result;
}
</code>```

```<code>public class ReseauSocial {

    private HashMap<String, CompteUtilisateur> utilisateurs;
    private List <Article> article;

    public ReseauSocial() {
    }

    public void tirerArticles() {
        Collections.sort(article, new ArticleComparator());
    }

    public void connecter(String pseudo, String mdp) {
    }
}
</code>```

But can you help me to sort dates from newest to oldest

Thank you for your answer but it does not works.. That is I obtain after modifying my code

```<code>public class MainClass {

    static List<Article> articles = new ArrayList<>();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Article a1 = new Article ("article1", "TP1", true, "01/02/2018");
        Article a2 = new Article ("article2", "TP2", true, "01/02/2019");
        articles.add(a1);
        articles.add(a2);

        ReseauSocial rsc = new ReseauSocial(articles);
        rsc.tirerArticles();

        for(int i = 0; i<articles.size(); i++) {
            System.out.print("Articles : "+ articles.get(i).getDate().toString()+"\n");

        }

    }

}
</code>```

```<code>Article 1 : Fri Feb 01 00:00:00 CET 2019
Articles 2 : Thu Feb 01 00:00:00 CET 2018
Articles : 01/02/2018
Articles : 01/02/2019
</code>```

答:
You need to parse date first</p>

```<code>public int compare(Article a1, Article a2) {
   SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
   Date date1 = sdf.parse(a1.getDate());
   Date date2 = sdf.parse(a2.getDate());

   int result = date1.compareTo(date2);
   if(result == 0) {
      result = a1.getAuteur().getPseudo().compareTo(a2.getAuteur().getPseudo());
   }

   return result;
}
</code>```

Title: sort string date and sort it

Body:
I would like to use sort my list of article by date (dd/mm/yyyy).
Dates are String.

public class ArticleComparator implements Comparator
 {

    @Override
    public int compare(Article a1, Article a2) {
        // TODO Auto-generated method stub
        int result = a1.getDate().compareTo(a2.getDate());
        if(result == 0)
            result = a1.getAuteur().getPseudo().compareTo(a2.getAuteur().getPseudo());
    return result;
}

public class ReseauSocial {

    private HashMap<String, CompteUtilisateur> utilisateurs;
    private List
 article;

    public ReseauSocial() {
    }

    public void tirerArticles() {
        Collections.sort(article, new ArticleComparator());
    }

    public void connecter(String pseudo, String mdp) {
    }
}

But can you help me to sort dates from newest to oldest

Thank you for your answer but it does not works.. That is I obtain after modifying my code

public class MainClass {

    static List
 articles = new ArrayList<>();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Article a1 = new Article ("article1", "TP1", true, "01/02/2018");
        Article a2 = new Article ("article2", "TP2", true, "01/02/2019");
        articles.add(a1);
        articles.add(a2);

        ReseauSocial rsc = new ReseauSocial(articles);
        rsc.tirerArticles();

        for(int i = 0; i<articles.size(); i++) {
            System.out.print("Articles : "+ articles.get(i).getDate().toString()+"\n");

        }

    }

}

Article 1 : Fri Feb 01 00:00:00 CET 2019
Articles 2 : Thu Feb 01 00:00:00 CET 2018
Articles : 01/02/2018
Articles : 01/02/2019

Body:
You need to parse date first

public int compare(Article a1, Article a2) {
   SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
   Date date1 = sdf.parse(a1.getDate());
   Date date2 = sdf.parse(a2.getDate());

   int result = date1.compareTo(date2);
   if(result == 0) {
      result = a1.getAuteur().getPseudo().compareTo(a2.getAuteur().getPseudo());
   }

   return result;
}


问:
how to make a POST request via async call in NodeJs
I have the following route

route

```<code>{
    method: "POST",
    path: "/g/{gId}/exchange",
    config: {
      handler: eHandler ,
    }
  },
</code>```

my handler

```<code>const { pExchange } = require("../lib/gStore");

const eHandler = async (req, h) => {
  if(req.payload.card === undefined){
    return h.response("...").code(202);
  }
  if(req.params.gId === undefined){
    return h.response("...").code(202);
  }
  if (!pExchange (req.params.gId,req.state.player)) {
    return h.response("...").code(202);
  }

  return h.response("OK");
};

module.exports = eHandler ;
</code>```

I want to make this into a post request so the response is in an ajax call and not redirecting me to a blank page with the result.

答:
try this</p>

```<code>const { pExchange } = require("../lib/gStore");

const eHandler = async (req, h) => {

let pExchangeValue = await pExchange(req.params.gId,req.state.player);

  if(req.payload.card === undefined){
    return h.response("...").code(202);
  }
  if(req.params.gId === undefined){
    return h.response("...").code(202);
  }
  if (!pExchangeValue) {
    return h.response("...").code(202);
  }

  return h.response("OK");
};

module.exports = eHandler ;
</code>```

Body:
I have the following route

route

{
    method: "POST",
    path: "/g/{gId}/exchange",
    config: {
      handler: eHandler ,
    }
  },

my handler

const { pExchange } = require("../lib/gStore");

const eHandler = async (req, h) => {
  if(req.payload.card === undefined){
    return h.response("...").code(202);
  }
  if(req.params.gId === undefined){
    return h.response("...").code(202);
  }
  if (!pExchange (req.params.gId,req.state.player)) {
    return h.response("...").code(202);
  }

  return h.response("OK");
};

module.exports = eHandler ;

I want to make this into a post request so the response is in an ajax call and not redirecting me to a blank page with the result.

Body:
try this

const { pExchange } = require("../lib/gStore");

const eHandler = async (req, h) => {

let pExchangeValue = await pExchange(req.params.gId,req.state.player);

  if(req.payload.card === undefined){
    return h.response("...").code(202);
  }
  if(req.params.gId === undefined){
    return h.response("...").code(202);
  }
  if (!pExchangeValue) {
    return h.response("...").code(202);
  }

  return h.response("OK");
};

module.exports = eHandler ;


问:
How to implement a UI widget that collapses on scroll, in React Native?
The standard iOS weather app has a special scrolling UI behavior:

There are various parts in the UI: the upper part (with the big 20), the middle (horizontal) bar, the lower part with the weekdays and the footer.

When you scroll up,

The upper part does not scroll, but it collapses until it has a certain minimum height, then it stays there "stickyly".

The middle bar scrolls up until the upper part does not collapse anymore, then it stays there "stickily".

The lower part (which has more height than fits onto the screen) scrolls up without any special behavior.

The footer is fixed, and overlaps the lower part.

How can I implement something similar in React Native? I don't need all the details, just an idea of how the upper part could be realized, i.e. a component that collapses while scrolling, until it stays fixed at the top, with a minimum height.

Of course, I'd prefer a pure RN solution, which works both on iOS and Android.

答:
Found an example here.

Only the part which really scrolls is inside a ScrollView, the collapsing part is not. Then you hook up on the ScrollView.onScroll event and connect the contentOffset property via Animated.event and Animated.interpolate to the height of the header:

```<code>const HEADER_EXPANDED_HEIGHT = 300
const HEADER_COLLAPSED_HEIGHT = 60
export default class App extends Component {
  constructor() {
    super()
    this.state = {
      scrollY: new Animated.Value(0)
    }
  }
  render() {
    const headerHeight = this.state.scrollY.interpolate({
      inputRange: [0, HEADER_EXPANDED_HEIGHT-HEADER_COLLAPSED_HEIGHT],
      outputRange: [HEADER_EXPANDED_HEIGHT, HEADER_COLLAPSED_HEIGHT],
      extrapolate: 'clamp'
    })
    return(
      <View style={styles.container}>
        <Animated.View style={{height: headerHeight}}/>
          <ScrollView
            contentContainerStyle={styles.scrollContainer}
            onScroll={Animated.event(
              [{ nativeEvent: {
                   contentOffset: {
                     y: this.state.scrollY
                   }
                 }
              }])}
            scrollEventThrottle={16}>
            ...
          </ScrollView>
      </View>
    )
  }
}
</code>```

Body:
Found an example here.

Only the part which really scrolls is inside a ScrollView, the collapsing part is not. Then you hook up on the ScrollView.onScroll event and connect the contentOffset property via Animated.event and Animated.interpolate to the height of the header:

const HEADER_EXPANDED_HEIGHT = 300
const HEADER_COLLAPSED_HEIGHT = 60
export default class App extends Component {
  constructor() {
    super()
    this.state = {
      scrollY: new Animated.Value(0)
    }
  }
  render() {
    const headerHeight = this.state.scrollY.interpolate({
      inputRange: [0, HEADER_EXPANDED_HEIGHT-HEADER_COLLAPSED_HEIGHT],
      outputRange: [HEADER_EXPANDED_HEIGHT, HEADER_COLLAPSED_HEIGHT],
      extrapolate: 'clamp'
    })
    return(
      <View style={styles.container}>
        <Animated.View style={{height: headerHeight}}/>
          <ScrollView
            contentContainerStyle={styles.scrollContainer}
            onScroll={Animated.event(
              [{ nativeEvent: {
                   contentOffset: {
                     y: this.state.scrollY
                   }
                 }
              }])}
            scrollEventThrottle={16}>
            ...
          </ScrollView>
      </View>
    )
  }
}


问:
unmarshal json field is int or string
I have an app where the type is

```<code>type Person struct {
  Name string `json:"name"`
  Age  int    `json:"age"`
}
</code>```

But we have legacy clients that send the Age field as either a string or an integer, so...

```<code>{
  "name": "Joe",
  "age": "42"
}
</code>```

OR

```<code>{
  "name": "Joe",
  "age": 42
}
</code>```

I know I can annotate the "age" field with ",string" if it's a string that I want coerced into an integer, but what if the field could be either one?

答:
```<code>package main

import (
    "encoding/json"
    "fmt"
    "strconv"
)

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func (p *Person) UnmarshalJSON(b []byte) error {
    var objMap map[string]*json.RawMessage
    err := json.Unmarshal(b, &objMap)
    if err != nil {
        return err
    }

    var name string
    err = json.Unmarshal(*objMap["name"], &name)
    if err != nil {
        return err
    }

    var ageInt int
    err = json.Unmarshal(*objMap["age"], &ageInt)
    if err != nil {
        // age  is string
        var ageString string
        err = json.Unmarshal(*objMap["age"], &ageString)
        if err != nil {
            return err
        }
        aI, err := strconv.Atoi(ageString)
        if err != nil {
            return err
        }
        p.Age = aI

    } else {
        p.Age = ageInt
    }

    p.Name = name

    fmt.Printf("%+v", *p)

    return nil
}

func main() {
    p := `{"name": "John", "age": "10"}`
    //  p := `{"name": "John", "age": 10}`

    newP := Person{}
    err := newP.UnmarshalJSON([]byte(p))
    if err != nil {
        fmt.Printf("Error %+v", err)
    }

}
</code>```

https://play.golang.org/p/AK8H_wdNqmt

You can try something like this. Try to read and parse Into int, if that fails check for string value, parse it to int and then assign int value to person struct

Title: unmarshal json field is int or string

Body:
I have an app where the type is

type Person struct {
  Name string `json:"name"`
  Age  int    `json:"age"`
}

But we have legacy clients that send the Age field as either a string or an integer, so...

{
  "name": "Joe",
  "age": "42"
}

OR

{
  "name": "Joe",
  "age": 42
}

I know I can annotate the "age" field with ",string" if it's a string that I want coerced into an integer, but what if the field could be either one?

Body:
package main

import (
    "encoding/json"
    "fmt"
    "strconv"
)

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func (p *Person) UnmarshalJSON(b []byte) error {
    var objMap map[string]*json.RawMessage
    err := json.Unmarshal(b, &objMap)
    if err != nil {
        return err
    }

    var name string
    err = json.Unmarshal(*objMap["name"], &name)
    if err != nil {
        return err
    }

    var ageInt int
    err = json.Unmarshal(*objMap["age"], &ageInt)
    if err != nil {
        // age  is string
        var ageString string
        err = json.Unmarshal(*objMap["age"], &ageString)
        if err != nil {
            return err
        }
        aI, err := strconv.Atoi(ageString)
        if err != nil {
            return err
        }
        p.Age = aI

    } else {
        p.Age = ageInt
    }

    p.Name = name

    fmt.Printf("%+v", *p)

    return nil
}

func main() {
    p := `{"name": "John", "age": "10"}`
    //  p := `{"name": "John", "age": 10}`

    newP := Person{}
    err := newP.UnmarshalJSON([]byte(p))
    if err != nil {
        fmt.Printf("Error %+v", err)
    }

}

https://play.golang.org/p/AK8H_wdNqmt

You can try something like this. Try to read and parse Into int, if that fails check for string value, parse it to int and then assign int value to person struct


问:
How can I get a List of subelements from a subdictionary?
I want to get a list of subelements from a subdictionary

I have this:

```<code>Dictionary<string, Dictionary<string, List<InstanceLog>>> dic;
</code>```

And I want something like this (Fetch all InstanceLog-Lists from the subdictinary in one big list.):

```<code>List<InstanceLog> logList = GetValues(dic);
</code>```

I have tried something like this but it don't work:

```<code>List<InstanceLog> logList = GetFetchtedList()
  .Select(x => x.Value.ToList())
  .Cast<InstanceLog>()
  .ToList()
</code>```

Thanks a lot for the help!

答:
In technical language, you want to flatten the lists which are stored inside the values of dictionary, so you need SelectMany:

```<code>var values = dic.Values
                 .SelectMany(val => val.Values)
                 .SelectMany(val => val);
</code>```

where values will be a collectopn of your data of type IEnumerable<InstanceLog> which is exactly what you want.

Body:
I want to get a list of subelements from a subdictionary

I have this:

Dictionary<string, Dictionary<string, List<InstanceLog>>> dic;

And I want something like this (Fetch all InstanceLog-Lists from the subdictinary in one big list.):

List<InstanceLog> logList = GetValues(dic);

I have tried something like this but it don't work:

List<InstanceLog> logList = GetFetchtedList()
  .Select(x => x.Value.ToList())
  .Cast<InstanceLog>()
  .ToList()

Thanks a lot for the help!

Body:
In technical language, you want to flatten the lists which are stored inside the values of dictionary, so you need SelectMany:

var values = dic.Values
                 .SelectMany(val => val.Values)
                 .SelectMany(val => val);

where values will be a collectopn of your data of type IEnumerable<InstanceLog> which is exactly what you want.


问:
How can I write messages in a specified channel?
In 0.16 I just said "client.get_channel("ID"), and could work with it. Now everything changed and when I try this, it says me "client" has no attribute "get_channel"...

So I tried "guild", because the API told me so on their Website.
Iam going to put this in another command, but this shows my problem...

     @commands.command()
     async def test(self, ctx):
        guild = ctx.message.guild
        channel = guild.get_channel(channel_id="573422681983025193")
        await channel.send(content="Test")
```

I tried "id", in stead of "channel_id", no kind of "id", just client.get_channel, but nothing worked!

答:
Thanks to Minn, who told me the answer!
You have to use guild.get_channel(ID) , without the "" for a String...
I thought I tried it, but it was just with client.get_channel(ID), so use

guild = ctx.message.guild
channel = guild.get_channel(ID)
await channel.send(content="Test")
```

Body:
In 0.16 I just said "client.get_channel("ID"), and could work with it. Now everything changed and when I try this, it says me "client" has no attribute "get_channel"...

So I tried "guild", because the API told me so on their Website.
Iam going to put this in another command, but this shows my problem...

     @commands.command()
     async def test(self, ctx):
        guild = ctx.message.guild
        channel = guild.get_channel(channel_id="573422681983025193")
        await channel.send(content="Test")

I tried "id", in stead of "channel_id", no kind of "id", just client.get_channel, but nothing worked!


问:
IE11 form submit event is called, but the form is not submitted
I'm having a weird problem that happens only on IE11. I have the following form:

```<code><form id="myform" action="http://my.url.com/mypage" method="POST">
    <a href="#" class="js-triggerFileInput">Send the file</a>
    <input type="file" name="myfile" class="hidden js-inputFile" />
    <input type="submit" value="submit" class="hidden" />
</form>
</code>```

And the following javascript (ES6 with a transpiler):

```<code>class MyForm {
  constructor() {
    this.button = $('.js-triggerFileInput');
    this.file = $('.js-inputFile');
    this.form = $('#myform');
  }

  // when I click on the visible button, triggers the file input dialog box
  this.button.click(() => {
    this.file.click();
  });

  // the the file is selected in the dialog box, submit the form
  this.file.change(() => {
    this.form.submit();
  });

  // I added this just to debug
  this.form.submit(() => {
    console.log('submitted');
    return true;
  });
}
</code>```

This work on all browsers, except IE11, the form is not submitted at all.

I added a debug to see if the submit event is called, and is called every time, but the browser don't submit the form.

If I try to submit the form using the submit button, it works fine, but when I try to submit using javascript, it triggers the event but doesn't work.

Does anyone know that is wrong with my code?

I even tried a different approach:

```<code><label for="myinput">Send the file</label>
<input id="myinput" type="file" class="hidden" />
</code>```

And use the default label/input behavior to trigger the input file without having to use .click() and it seems to work better, but in IE11 this doesn't work if the input file is hidden is invible (display: none, visibility: hidden or opacity: 0).

Edit1: if I trigger the event through the browser console, the form is submitted.

答:
I didn't found the source of the problem, but I found a way to bypass this IE bug:

HTML:

```<code><form id="myform" action="http://my.url.com/mypage" method="POST">
    <label for="myfile">Send the file</label>
    <input type="file" name="myfile" id="myfile" class="js-inputFile" />
    <input type="submit" value="submit" class="hidden" />
</form>
</code>```

JS:

```<code>class MyForm {
  constructor() {
    this.file = $('.js-inputFile');
    this.form = $('#myform');
  }

  // the the file is selected in the dialog box, submit the form
  this.file.change(() => {
    this.form.submit();
  });
}
</code>```

If I don't use a button + JS to trigger the input[type="file"] behavior, and instead use label + id to trigger the click, it works like a charm. The problem seems to be related to triggering the input[type="file"] using JS.

Also:

IE doesn't send the form if there isn't a input[type="submit"] inside the form.

IE doesn't trigger the input[type="file"] is is hidden or invisible, I've achieved the same behavior using height: 0; width: 0;

Body:
I'm having a weird problem that happens only on IE11. I have the following form:

<form id="myform" action="http://my.url.com/mypage" method="POST">
    Send the file
    <input type="file" name="myfile" class="hidden js-inputFile" />
    <input type="submit" value="submit" class="hidden" />
</form>

And the following javascript (ES6 with a transpiler):

class MyForm {
  constructor() {
    this.button = $('.js-triggerFileInput');
    this.file = $('.js-inputFile');
    this.form = $('#myform');
  }

  // when I click on the visible button, triggers the file input dialog box
  this.button.click(() => {
    this.file.click();
  });

  // the the file is selected in the dialog box, submit the form
  this.file.change(() => {
    this.form.submit();
  });

  // I added this just to debug
  this.form.submit(() => {
    console.log('submitted');
    return true;
  });
}

This work on all browsers, except IE11, the form is not submitted at all.

I added a debug to see if the submit event is called, and is called every time, but the browser don't submit the form.

If I try to submit the form using the submit button, it works fine, but when I try to submit using javascript, it triggers the event but doesn't work.

Does anyone know that is wrong with my code?

I even tried a different approach:

Send the file
<input id="myinput" type="file" class="hidden" />

And use the default label/input behavior to trigger the input file without having to use .click() and it seems to work better, but in IE11 this doesn't work if the input file is hidden is invible (display: none, visibility: hidden or opacity: 0).

Edit1: if I trigger the event through the browser console, the form is submitted.

Body:
I didn't found the source of the problem, but I found a way to bypass this IE bug:

HTML:

<form id="myform" action="http://my.url.com/mypage" method="POST">
    <label for="myfile">Send the file</label>
    <input type="file" name="myfile" id="myfile" class="js-inputFile" />
    <input type="submit" value="submit" class="hidden" />
</form>

JS:

class MyForm {
  constructor() {
    this.file = $('.js-inputFile');
    this.form = $('#myform');
  }

  // the the file is selected in the dialog box, submit the form
  this.file.change(() => {
    this.form.submit();
  });
}

If I don't use a button + JS to trigger the input[type="file"] behavior, and instead use label + id to trigger the click, it works like a charm. The problem seems to be related to triggering the input[type="file"] using JS.

Also:

IE doesn't send the form if there isn't a input[type="submit"] inside the form.

IE doesn't trigger the input[type="file"] is is hidden or invisible, I've achieved the same behavior using height: 0; width: 0;


问:
How to check map has values or not react
I have a list users, those details want to show in table format. Want to check if map has value, if not show the message 'no data found'.
how can I achieve that.?</p>

```<code> {filteredList && filteredList
                .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                .map(row =>
                  ( row===null ? (
                  <TableRow key={row.id}>
                    <TableCell className={classes.tableCell}>{items++}</TableCell>

                    <TableCell className={classes.tableCell}>
                      {row.sp_Name}
                    </TableCell>
                    <TableCell className={classes.tableCell}>{row.sp_Phone}</TableCell>
                    <TableCell className={classes.tableCell}>{row.sp_Role}</TableCell>
                    <TableCell className={classes.tableCell}>{row.sp_Service}</TableCell>
                    <TableCell className={classes.tableCell}>{row.sp_Location}</TableCell>

                    <TableCell className={classes.tableCell}>
                      <Link to={'/admin/profile/' + row.id} key={row.id} style={{ textDecoration: "none" }} >
                        <Chip
                          icon={<FaceIcon />}
                          label="View Profile/Action"
                          color="primary"
                          className={classes.chip}
                          variant="outlined"
                          onClcik={this.handleAction}
                        />
                      </Link>
                    </TableCell>
                    <TableCell className={classes.tableCell}>
                      <Tooltip title="Delete">
                        <DeleteIcon color="danger" onClick={() => this.handleClickDialogOpen(row.id)} className={classes.icon} />
                        {/* <DeleteIcon onClick={() => deleteSP(row.id)} className={classes.icon} /> */}
                      </Tooltip>
                    </TableCell>

                  </TableRow>
                ) : "no data"
                  )
                )}
</code>```

答:
Your can check if data exist first, if yes, render the table and row. If no data,
then you just render the required 'no data found' text

```<code>getData = () => {
  const filteredList = this.state.list // your logic to get data

  // Perform your logic to filter the data
  return filteredList.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
}

render() {
   const filteredList = this.getData()
   return (
       filteredList.length > 0 ?
       <table>
           {data.map( /* Make your <tr> */ )}
       </table> :
       "no data found"
   )
}
</code>```

Body:
I have a list users, those details want to show in table format. Want to check if map has value, if not show the message 'no data found'.
how can I achieve that.?

 {filteredList && filteredList
                .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                .map(row =>
                  ( row===null ? (
                  <TableRow key={row.id}>
                    <TableCell className={classes.tableCell}>{items++}</TableCell>

                    <TableCell className={classes.tableCell}>
                      {row.sp_Name}
                    </TableCell>
                    <TableCell className={classes.tableCell}>{row.sp_Phone}</TableCell>
                    <TableCell className={classes.tableCell}>{row.sp_Role}</TableCell>
                    <TableCell className={classes.tableCell}>{row.sp_Service}</TableCell>
                    <TableCell className={classes.tableCell}>{row.sp_Location}</TableCell>

                    <TableCell className={classes.tableCell}>
                      <Link to={'/admin/profile/' + row.id} key={row.id} style={{ textDecoration: "none" }} >
                        <Chip
                          icon={<FaceIcon />}
                          label="View Profile/Action"
                          color="primary"
                          className={classes.chip}
                          variant="outlined"
                          onClcik={this.handleAction}
                        />
                      </Link>
                    </TableCell>
                    <TableCell className={classes.tableCell}>
                      <Tooltip title="Delete">
                        <DeleteIcon color="danger" onClick={() => this.handleClickDialogOpen(row.id)} className={classes.icon} />
                        {/* <DeleteIcon onClick={() => deleteSP(row.id)} className={classes.icon} /> */}
                      </Tooltip>
                    </TableCell>

                  </TableRow>
                ) : "no data"
                  )
                )}

Body:
Your can check if data exist first, if yes, render the table and row. If no data,
then you just render the required 'no data found' text

getData = () => {
  const filteredList = this.state.list // your logic to get data

  // Perform your logic to filter the data
  return filteredList.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
}

render() {
   const filteredList = this.getData()
   return (
       filteredList.length > 0 ?
       <table>
           {data.map( /* Make your <tr> */ )}
       </table> :
       "no data found"
   )
}


问:
Ionic PWA get version number from config.xml
I want to show the version number from config.xml in an Ionic PWA.

It is easy to get it done for ios/android builds using ionic native app version plugin.

But what is a good approach for a PWA build
(npm run build --release --prod)?

答:
Found proper way to do all that with using custom webpack configuration and webpack.DefinePlugin. It's working everywhere, during ionic serve as well (as I needed because I send that to API), and not only on real devices as cordova-plugin-app-version. Only place where it's not working is when you do ionic serve --devapp (issue in @ionic/angular-toolkit)

Everything below is for Ionic 4 (Angular 7):

add @angular-builders/custom-webpack@7 @angular-builders/dev-server@7 dev packages with yarn add @angular-builders/custom-webpack@7 @angular-builders/dev-server@7 --dev

need to replace architect.build and architect.serve builders in angular.json with new ones:

```<code>...
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./custom.webpack.config.js"
            },
...
</code>```

```<code>...
        "serve": {
          "builder": "@angular-builders/dev-server:generic",
          "options": {
            "browserTarget": "app:build"
          },
...
</code>```

create custom.webpack.config.js with next content:

```<code>const webpack = require('webpack');
console.log('[WEBPACK] custom.webpack.config.js is loaded');

function getAppVersion() {
  const fs = require('fs');
  const DOMParser = require('xmldom').DOMParser;

  const content = fs.readFileSync('./config.xml').toString('utf-8');
  const config = new DOMParser().parseFromString(content, 'text/xml');
  return config.getElementsByTagName('widget')[0].getAttribute('version');
}

module.exports = (config, options) => {
  config.plugins.push(
    new webpack.DefinePlugin({
      'APP_VERSION': JSON.stringify(getAppVersion()),
    }),
  );

  return config;
};
</code>```

if all done correctly, you will see [WEBPACK] custom.webpack.config.js is loaded in terminal when running the app.

now global variable APP_VERSION will be injected and should be available in any place of the app. console.log('APP_VERSION', APP_VERSION);. With that you can inject other variables like that which known only during build time or adding other custom Webpack plugins.

you may need to add APP_VERSION definition for TypeScript into your custom-typings.d.ts as next:

```<code>// Variables injected by webpack DefinePlugin
declare const APP_VERSION: string;
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Found proper way to do all that with using custom webpack configuration and webpack.DefinePlugin. It's working everywhere, during ionic serve as well (as I needed because I send that to API), and not only on real devices as cordova-plugin-app-version. Only place where it's not working is when you do ionic serve --devapp (issue in @ionic/angular-toolkit)

Everything below is for Ionic 4 (Angular 7):

add @angular-builders/custom-webpack@7 @angular-builders/dev-server@7 dev packages with yarn add @angular-builders/custom-webpack@7 @angular-builders/dev-server@7 --dev

need to replace architect.build and architect.serve builders in angular.json with new ones:

...
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./custom.webpack.config.js"
            },
...

...
        "serve": {
          "builder": "@angular-builders/dev-server:generic",
          "options": {
            "browserTarget": "app:build"
          },
...

create custom.webpack.config.js with next content:

const webpack = require('webpack');
console.log('[WEBPACK] custom.webpack.config.js is loaded');

function getAppVersion() {
  const fs = require('fs');
  const DOMParser = require('xmldom').DOMParser;

  const content = fs.readFileSync('./config.xml').toString('utf-8');
  const config = new DOMParser().parseFromString(content, 'text/xml');
  return config.getElementsByTagName('widget')[0].getAttribute('version');
}

module.exports = (config, options) => {
  config.plugins.push(
    new webpack.DefinePlugin({
      'APP_VERSION': JSON.stringify(getAppVersion()),
    }),
  );

  return config;
};

if all done correctly, you will see [WEBPACK] custom.webpack.config.js is loaded in terminal when running the app.

now global variable APP_VERSION will be injected and should be available in any place of the app. console.log('APP_VERSION', APP_VERSION);. With that you can inject other variables like that which known only during build time or adding other custom Webpack plugins.

you may need to add APP_VERSION definition for TypeScript into your custom-typings.d.ts as next:

// Variables injected by webpack DefinePlugin
declare const APP_VERSION: string;


问:
Trying to output what I want rather then the values it returns
Im trying to output Quantity <10 rather then output the values that are <10

for example my code is

```<code>SELECT job_id, po_id, 'Vendor ' || vendor_id as 'Reason'
FROM pos
WHERE vendor_id = 'SOS'
UNION
SELECT job_id, po_id, 'Quantity <10 ' || quantity as 'Reason'
FROM po_items
where quantity < 10
ORDER BY  job_id, po_id;
</code>```

and its outputting

```<code>job_id      po_id       Reason
 ----------  ----------  --------------
002         AAA         Quantity <10 2
004         CCC         Quantity <10 4
004         CCC         Vendor SOS
005         EEE         Vendor SOS
006         GGG         Quantity <10 2
</code>```

And this is what im trying to get. As you can see the only thing im missing from my code is the ability to output just the 'Quantity <10'

```<code>job_id      po_id       Reason
----------  ----------  -------------
002         AAA         Quantity < 10
004         CCC         Quantity < 10
004         CCC         Vendor SOS
005         EEE         Vendor SOS
006         GGG         Quantity < 10
</code>```

答:
Does this work?</p>

```<code>SELECT job_id, po_id,
       'Vendor ' || vendor_id as Reason
FROM pos
WHERE vendor_id = 'SOS'
UNION ALL
SELECT job_id, po_id,
       'Quantity < 10' as Reason
FROM po_items
WHERE quantity < 10
ORDER BY  job_id, po_id;
</code>```

Body:
Im trying to output Quantity <10 rather then output the values that are <10

for example my code is

SELECT job_id, po_id, 'Vendor ' || vendor_id as 'Reason'
FROM pos
WHERE vendor_id = 'SOS'
UNION
SELECT job_id, po_id, 'Quantity <10 ' || quantity as 'Reason'
FROM po_items
where quantity < 10
ORDER BY  job_id, po_id;

and its outputting

job_id      po_id       Reason
 ----------  ----------  --------------
002         AAA         Quantity <10 2
004         CCC         Quantity <10 4
004         CCC         Vendor SOS
005         EEE         Vendor SOS
006         GGG         Quantity <10 2

And this is what im trying to get. As you can see the only thing im missing from my code is the ability to output just the 'Quantity <10'

job_id      po_id       Reason
----------  ----------  -------------
002         AAA         Quantity < 10
004         CCC         Quantity < 10
004         CCC         Vendor SOS
005         EEE         Vendor SOS
006         GGG         Quantity < 10

Body:
Does this work?

SELECT job_id, po_id,
       'Vendor ' || vendor_id as Reason
FROM pos
WHERE vendor_id = 'SOS'
UNION ALL
SELECT job_id, po_id,
       'Quantity < 10' as Reason
FROM po_items
WHERE quantity < 10
ORDER BY  job_id, po_id;


问:
Node bCrypt.compareSync
I am creating a user login. I am able to have the user sign up and when the user sings up his password is encrypted before it is saved in the database.

When that same user tries to log in, I am getting an "invalid password".

This is because it is comparing the user input to an encrypted password in the database. Example if password is 1234, then in database it is saved as "$2a$104$0301". When the user tries to log in, the user input which is "1234" is compared to "2a$104$0301". How would I fix?

Here is my code for login:

```<code>var LocalStrategy = require('passport-local').Strategy;
var User = require('../Models/users.js');
var bcrypt = require('bcrypt-nodejs');

module.exports = function(passport){
passport.use('login', new LocalStrategy({
     passReqToCallback : true
 },
    function(req, username, password, done){
        User.findOne({'username' : username},
        function(err, user){
            if(err)
                return done(err);
            if(!user){
                console.log('User Not Found with username: '+username);
                return done(null, false,
                    req.flash('message', 'User Not Found.'));
            }
            if (!isValidPassword(user, password)){
                console.log('Invalid Password');
                return done (null, false,
                    req.flash('message', 'Invalid Password'));
            }
            return done(null, user);
        }
    );
})
);
var isValidPassword = function(user, password){
    var result = bcrypt.compareSync(password, user.password);
    if (result) {
     console.log("Password correct");
    } else {
    console.log("Password wrong");
    }
    return result;

 }
}
</code>```

答:
Really late to the party, however I just had this same problem and the reason it wasn't working for me was that I had encrypted the input password before trying to compare with the already encrypted 'user.password'.

Once I realised there was no need to encrypt the input password, the compareSync worked perfectly.

From bcrypt - npm:

To check a password:

```<code>// Load hash from your password DB.
bcrypt.compareSync(myPlaintextPassword, hash); // true
bcrypt.compareSync(someOtherPlaintextPassword, hash); // false
</code>```

The "compareSync" function counters timing attacks (using a so-called 'constant-time' algorithm). In general, don't use the normal JavaScript string comparison functions to compare passwords, cryptographic keys, or cryptographic hashes if they are relevant to security.

Title: Node bCrypt.compareSync

Body:
I am creating a user login. I am able to have the user sign up and when the user sings up his password is encrypted before it is saved in the database.

When that same user tries to log in, I am getting an "invalid password".

This is because it is comparing the user input to an encrypted password in the database. Example if password is 1234, then in database it is saved as "$2a$104$0301". When the user tries to log in, the user input which is "1234" is compared to "2a$104$0301". How would I fix?

Here is my code for login:

var LocalStrategy = require('passport-local').Strategy;
var User = require('../Models/users.js');
var bcrypt = require('bcrypt-nodejs');

module.exports = function(passport){
passport.use('login', new LocalStrategy({
     passReqToCallback : true
 },
    function(req, username, password, done){
        User.findOne({'username' : username},
        function(err, user){
            if(err)
                return done(err);
            if(!user){
                console.log('User Not Found with username: '+username);
                return done(null, false,
                    req.flash('message', 'User Not Found.'));
            }
            if (!isValidPassword(user, password)){
                console.log('Invalid Password');
                return done (null, false,
                    req.flash('message', 'Invalid Password'));
            }
            return done(null, user);
        }
    );
})
);
var isValidPassword = function(user, password){
    var result = bcrypt.compareSync(password, user.password);
    if (result) {
     console.log("Password correct");
    } else {
    console.log("Password wrong");
    }
    return result;

 }
}

Body:
Really late to the party, however I just had this same problem and the reason it wasn't working for me was that I had encrypted the input password before trying to compare with the already encrypted 'user.password'.

Once I realised there was no need to encrypt the input password, the compareSync worked perfectly.

From bcrypt - npm:

To check a password:

// Load hash from your password DB.
bcrypt.compareSync(myPlaintextPassword, hash); // true
bcrypt.compareSync(someOtherPlaintextPassword, hash); // false

The "compareSync" function counters timing attacks (using a so-called 'constant-time' algorithm). In general, don't use the normal JavaScript string comparison functions to compare passwords, cryptographic keys, or cryptographic hashes if they are relevant to security.


问:
Can an iOS App's system settings be configured via Enterprise Distribution?
Apple's Enterprise Deployment Guide says that apps distributed internally to an organization can be accompanied by a "Configuration Profile" that changes certain system settings (like VPN or wifi preferences).  Can the same system be used to distribute custom settings (as defined in the system wide "settings" application) for the enterprise application itself?</p>

答:
Not externally pushed upon the app.

The way I would implement it is that the app checks in with the enterprise server upon launch and gets any app settings that way. A simple REST exchange should do it.