ConfigParser Problem-Daten werden nicht in Datei geschrieben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
rumilmirion
User
Beiträge: 34
Registriert: Mittwoch 3. Mai 2006, 12:09

Hi! Ich hab da mal ein kleines Problem, und zwar hab ich untenstehende Function geschrieben. Wenn ich's laufen lasse, wird die INI-Datei auch erzeugt - nur ist die immer leer, die neuen Sections werden einfach nicht erzeugt. Was mich wirklich stutzig macht, ist das Verhalten beim wiederholten Aufrufen der Funktion. Beim ersten Durchgang gibt das "print self.config.has_section(npcname)" wie erwartet False aus. Allerdings wird bei allen weiteren Aufrufen immer True ausgegeben - obwohl in der INI-Datei am Ende nichts drin steht. Irgendeine Ahnung, wo das Problem liegen könnte?

Im Vorraus schon mal danke.

Code: Alles auswählen

def CheckIniFile(self,event):
        """Compare data in profiles.ini to actual save games and update as needed."""
        if (not os.path.exists(self.profileIni)) or (not os.path.isfile(self.profileIni)):
            inifile = open(self.profileIni,'a')
            inifile.close()
            del inifile
        self.config.read(open(self.profileIni))
        savesList=[]
        for item in os.listdir(self.saveDir):
            if '.ess' in item:
                savesList.append(item)
        for item in savesList:
            save = open(os.path.join(settings['mwDir'],'Saves',item),'rb')
            savestr = save.read()
            countnpc = savestr.count('NPC_')
            counter = 0
            start = 0
            start2 = 0
            while counter<countnpc:
                start = savestr.find('NPC_',start,len(savestr))+20
                save.seek(start)
                length = struct.unpack('i',save.read(4))[0]
                npcid = save.read(length)
                if npcid == 'player\x00':
                    start2 = savestr.find('FNAM',start,len(savestr))+4
                    save.seek(start2)
                    length = struct.unpack('i',save.read(4))[0]
                    npcname = save.read(length)
                    print item
                    print npcid
                    print npcname
                    print self.config.has_section(npcname)
                    print '\n'
                    if not self.config.has_section(npcname):
                        self.config.add_section(npcname)
                        self.config.set(npcname, 'Status', 'Not Hidden')
                    options = self.config.items(npcname)
                    if not item in options:
                        self.config.set(npcname,'Save File '+str(len(options)/2),item)
                counter+=1
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Mmh, ich seh da nirgends sowas wie

Code: Alles auswählen

self.config.write(open(myfile, 'w'))
Vor diesem Befehl wird naemlich nix in eine Datei geschrieben, sondern das configParser-Objekt besteht allein im Speicher, mitsamt den ganzen Sections und Options (deswegen gibt has_section auch True zurueck).
rumilmirion
User
Beiträge: 34
Registriert: Mittwoch 3. Mai 2006, 12:09

Rebecca hat geschrieben:Mmh, ich seh da nirgends sowas wie

Code: Alles auswählen

self.config.write(open(myfile, 'w'))
Vor diesem Befehl wird naemlich nix in eine Datei geschrieben, sondern das configParser-Objekt besteht allein im Speicher, mitsamt den ganzen Sections und Options (deswegen gibt has_section auch True zurueck).
So was ähnliches ist schon da - hab nur wegen Länge nicht das ganze gepostet, sorry.
Weil ich sehe, dass du self.config.write benutzt - kann man darüber lesen und schreiben? Wenn nicht, wie dann?
Der Code ist noch nicht fertig, daher ist so einiges noch temporär. So schaut das Ganze bis jetzt aus:

Code: Alles auswählen

class ProfileManager(wx.Frame):
    """Profile Mananger frame."""
    def __init__(self,profileName=None):
        """Initialize.
        profileName -- current profile name (or None) - currently unused"""
        #--Data
        self.profileIni = os.path.join(settings['mwDir'],'profiles.ini')
        self.hiddenProfileDir = os.path.join(settings['mwDir'],'Hidden Profiles')
        self.saveDir = os.path.join(settings['mwDir'],'Saves')
        self.config = ConfigParser.ConfigParser()
        #--Window
        pos = settings['wrye.mash.modDocs.pos']
        size = settings['wrye.mash.modDocs.size']
        wx.Frame.__init__(self, mashFrame, -1, _('Profile Manager'), pos, size,
            style=wx.DEFAULT_FRAME_STYLE)
        self.SetBackgroundColour(wx.NullColour)
        self.SetSizeHints(250,250)
        #--Icons
        self.SetIcons(images['wrye.mash.icons2'].GetIconBundle())
        #--Doc fields
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        #--Button Sizer
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(buttonSizer,0,wx.GROW|wx.ALL^wx.BOTTOM,4)
        #--Hide Profile
        self.unHideButton = wx.ToggleButton(self,ID_UN_HIDE,_("Hide/Unhide Profile"))
        wx.EVT_TOGGLEBUTTON(self.unHideButton,ID_UN_HIDE,self.DoHide)
        buttonSizer.Add(self.unHideButton,0,wx.GROW)
        #--Scan Button
        self.scanButton = wx.Button(self,ID_SCAN,_("Scan for Profiles"))
        wx.EVT_BUTTON(self.scanButton,ID_SCAN,self.CheckIniFile)
        buttonSizer.Add(self.scanButton,0,wx.GROW)
        #--Profile Name
        self.profileNameBox = wx.ComboBox(self,ID_SELECT,'',wx.DefaultPosition,(-1,-1),
            self.profileNames(),style=wx.CB_DROPDOWN|wx.CB_SORT)
        wx.EVT_COMBOBOX(self.profileNameBox,ID_SELECT,self.listSaves)
        buttonSizer.Add(self.profileNameBox,2,wx.GROW|wx.ALL)
        #--Saves sizer
        savesSizer = wx.GridSizer(0,0)
        mainSizer.Add(savesSizer,1,wx.GROW,0)
        #--Saves display
        self.savesList = wx.ListBox(self, -1, wx.DefaultPosition,(-1,-1),
            style=wx.LB_SINGLE|wx.LB_NEEDED_SB)
        wx.EVT_LISTBOX(self.savesList,ID_SELECT,self.DoHide)
        savesSizer.Add(self.savesList,0,wx.GROW)
        #--Show window
        self.SetSizer(mainSizer)
        self.Show()

    def CheckIniFile(self,event):
        """Compare data in profiles.ini to actual save games and update as needed."""
        if (not os.path.exists(self.profileIni)) or (not os.path.isfile(self.profileIni)):
            inifile = open(self.profileIni,'a')
            inifile.close()
            del inifile
        self.config.read(open(self.profileIni))
        savesList=[]
        for item in os.listdir(self.saveDir):
            if '.ess' in item:
                savesList.append(item)
        for item in savesList:
            save = open(os.path.join(settings['mwDir'],'Saves',item),'rb')
            savestr = save.read()
            countnpc = savestr.count('NPC_')
            counter = 0
            start = 0
            start2 = 0
            while counter<countnpc:
                start = savestr.find('NPC_',start,len(savestr))+4
                save.seek(start+16)
                length = struct.unpack('i',save.read(4))[0]
                npcid = save.read(length)
                if 'player' in npcid:
                    start2 = savestr.find('FNAM',start,len(savestr))+4
                    save.seek(start2)
                    length = struct.unpack('i',save.read(4))[0]
                    npcname = save.read(length)
                    print item
                    print npcid
                    print npcname
                    print self.config.has_section(npcname)
                    print '\n'
                    if not self.config.has_section(npcname):
                        self.config.add_section(npcname)
                        self.config.set(npcname, 'Status', 'Not Hidden')
                    options = self.config.items(npcname)
                    if not item in options:
                        self.config.set(npcname,'Save File '+str(len(options)/2),item)
                counter+=1
        

    def DoHide(self,event):
        """Handle "Hide Profile" button click."""
        pass

    def profileNames(self):
        return ('Profile 1:Mike','Profile 2:John')

    def listSaves(self,event):
        saveslist = ('test0000.esp','test0001.esp','test0002.esp')
        self.savesList.Set(saveslist)
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

rumilmirion hat geschrieben:So was ähnliches ist schon da
Okay, vielleicht habe ich heute Tomaten auf den Augen, aber ich seh's nicht. Hier mal kurzes Beispiel:

Code: Alles auswählen

#Erstellen eines Parser-Objekts:
parser = SafeConfigParser();

#Einmaliges Einlesen einer vorhandenen ini-Datei,
#die Datei wird geparst, das Parser-Objekt gefuellt,
#und die Datei wieder geschlossen.
parser.read("bla.ini"); 

#Mit dem parser-Objekt kann man jetzt arbeiten
#z.B. Werte lesen:
foo = parser.get("network", "hostname")

#oder neue Sections und Optionen hinzufuegen:
parser.set("network", "hostname", "saturn")
parser.add_section("usercolors")
parser.set("usercolors", "foreground", "blue")

#Dieses Objekt parser befindet sich im Speicher.
#Es hat nix mit irgendeiner Datei zu tun, trotzdem
#kann man daraus wieder Werte auslesen!
foo = parser.get("usercolors", "foreground")

#Um es einmalig in eine Datei zu speichern:
parser.write(open("blupp.ini"))
rumilmirion
User
Beiträge: 34
Registriert: Mittwoch 3. Mai 2006, 12:09

Rebecca hat geschrieben:Okay, vielleicht habe ich heute Tomaten auf den Augen, aber ich seh's nicht. Hier mal kurzes Beispiel:
Zeile 57 des Codes in meinem vorigen Post. :)
Ne, aber ich seh jetzt wo mein Problem liegt - ich habe self.config.read(open(self.profileIni)) geschrieben. Als self.config.write(open(self.profileIni)) wird's wohl gehen. Danke.
rumilmirion
User
Beiträge: 34
Registriert: Mittwoch 3. Mai 2006, 12:09

Nochmal Nachschlag, was die Fragen angeht...

Code: Alles auswählen

class ProfileManager(wx.Frame):
    """Profile Mananger frame."""
    def __init__(self,profileName=None):
        """Initialize.
        profileName -- current profile name (or None) - currently unused"""
        #--Data
        self.profileIni = os.path.join(settings['mwDir'],'profiles.ini')
        self.hiddenProfileDir = os.path.join(settings['mwDir'],'Hidden Profiles')
        self.saveDir = os.path.join(settings['mwDir'],'Saves')
        self.config = ConfigParser.ConfigParser()
        #--Hidden profile dir
        if not os.path.exists(self.hiddenProfileDir):
            os.mkdir(self.hiddenProfileDir)
        #--Window
        pos = settings['wrye.mash.modDocs.pos']
        size = settings['wrye.mash.modDocs.size']
        wx.Frame.__init__(self, mashFrame, -1, _('Profile Manager'), pos, size,
            style=wx.DEFAULT_FRAME_STYLE)
        self.SetBackgroundColour(wx.NullColour)
        self.SetSizeHints(250,250)
        #--Icons
        self.SetIcons(images['wrye.mash.icons2'].GetIconBundle())
        #--Doc fields
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        #--Button Sizer
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(buttonSizer,0,wx.GROW|wx.ALL^wx.BOTTOM,4)
        #--Profile Text
        self.profileText = wx.StaticText(self, -1, "Profile: ", wx.DefaultPosition,(-1,-1),
            style=wx.ALIGN_LEFT)
        buttonSizer.Add(self.profileText,0,wx.GROW)
        #--Profile Name
        self.profileNameBox = wx.ComboBox(self,ID_SELECT,'',wx.DefaultPosition,(-1,-1),
            self.profileNames(),style=wx.CB_DROPDOWN|wx.CB_SORT|wx.ALIGN_LEFT)
        wx.EVT_COMBOBOX(self.profileNameBox,ID_SELECT,self.listSaves)
        buttonSizer.Add(self.profileNameBox,1,wx.GROW|wx.ALL)
        #--Activate Profile
        self.activateButton = wx.Button(self,ID_ACTIVATE_PROFILE,_("Set profile as active"))
        wx.EVT_BUTTON(self.activateButton,ID_ACTIVATE_PROFILE,self.ActivateProfile)
        buttonSizer.Add(self.activateButton,0,wx.GROW)
        #--Saves sizer
        savesSizer = wx.GridSizer(0,0)
        mainSizer.Add(savesSizer,1,wx.GROW,0)
        #--Saves display
        self.savesList = wx.ListBox(self, -1, wx.DefaultPosition,(-1,-1),
            style=wx.LB_SINGLE|wx.LB_NEEDED_SB)
        savesSizer.Add(self.savesList,0,wx.GROW|wx.ALL^wx.BOTTOM)
        #--Bottom status bar sizer
        bottomStateSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(bottomStateSizer,0,wx.GROW|wx.BOTTOM,4)
        #--Bottom status bar
        self.bottomStateBar = wx.StatusBar(self, -1, style=wx.SB_NORMAL)
        bottomStateSizer.Add(self.bottomStateBar,0,wx.GROW)
        #--Show window
        self.SetSizer(mainSizer)
        self.Show()
        self.CheckIniFile()

    def CheckIniFile(self,event=None):
        """Compare data in profiles.ini to actual save games and update as needed."""
        savesList=[]
        if (not os.path.exists(self.profileIni)) or (os.path.isdir(self.profileIni)):
            temp = open(self.profileIni,'w')
            temp.close()
            del temp
        self.config.read(self.profileIni)
        #--add stuff to profiles.ini
        for item in os.listdir(self.saveDir):
            if '.ess' in item:
                savesList.append(item)
        for item in savesList:
            save = open(os.path.join(settings['mwDir'],'Saves',item),'rb')
            savestr = save.read()
            countnpc = savestr.count('NPC_')
            counter = 0
            start = 0
            start2 = 0
            while counter<countnpc:
                start = savestr.find('NPC_',start,len(savestr))+20
                save.seek(start)
                length = struct.unpack('i',save.read(4))[0]
                npcid = save.read(length)
                if 'player' in npcid:
                    start2 = savestr.find('FNAM',start,len(savestr))+4
                    save.seek(start2)
                    length = struct.unpack('i',save.read(4))[0]
                    npcname = save.read(length-1)
                    if not self.config.has_section(npcname):
                        self.config.add_section(npcname)
                        self.config.set(npcname, 'status', 'not initialized')
                    options = self.config.items(npcname)
                    valueList = []
                    for pair in options:
                        if pair[0] != 'status':
                            valueList.append(pair[1])
                    if not item in valueList:
                        self.config.set(npcname,'save file '+str(len(valueList)),item)
                counter+=1
        #--remove stuff from profiles.ini
        for profile in self.config.sections():
            for option in self.config.options(profile):
                if self.config.get(profile,'status') == 'inactive':
                    if option != 'status':
                        if (not os.path.exists(os.path.join(self.hiddenProfileDir,profile,self.config.get(profile,option)))) and (not os.path.exists(os.path.join(self.saveDir,profile,self.config.get(profile,option)))):
                            self.config.remove_option(profile,option)
            if len(self.config.options(profile)) == 1:
                self.config.remove_section(profile)
        self.config.write(open(self.profileIni,'w'))

    def ActivateProfile(self,event):
        """Handle "Activate Profile" button click."""
        self.config.read(self.profileIni)
        if not self.profileNameBox.GetValue():
            ErrorMessage(self,'You need to select a profile to activate it.','Error: No profile selected!')
            return
        profile = self.profileNameBox.GetValue()
        if self.config.get(profile,'status') == 'active':
            ErrorMessage(self,'This profile is already active.','Error: Profile already active.')
            return
        for section in self.config.sections():
            if str(profile) is not str(section):
                savesList = []
                for option in self.config.options(section):
                    if option == 'status':
                        pass
                    else:
                        savesList.append(self.config.get(section,option))
                if not os.path.exists(os.path.join(self.hiddenProfileDir,section)):
                    os.mkdir(os.path.join(self.hiddenProfileDir,section))
                for save in savesList:
                    if os.path.exists(os.path.join(self.saveDir,save)):
                        shutil.move(os.path.join(self.saveDir,save),os.path.join(self.hiddenProfileDir,section))
                self.config.set(section,'status','inactive')
            else:
                if not os.path.exists(self.hiddenProfileDir):
                    break
                if not os.path.exists(os.path.join(self.hiddenProfileDir,section)):
                    break
                for save in os.listdir(os.path.join(self.hiddenProfileDir,section)):
                    shutil.move(os.path.join(self.hiddenProfileDir,section,save),self.saveDir)
                self.config.set(section,'status','active')
        self.config.write(open(self.profileIni,'w'))
        self.listSaves()

    def profileNames(self):
        self.CheckIniFile()
        self.config.read(self.profileIni)
        return self.config.sections()

    def listSaves(self,event=None):
        self.config.read(self.profileIni)
        saveList = []
        for option in self.config.options(self.profileNameBox.GetValue()):
            if option != 'status':
                saveList.append(self.config.get(self.profileNameBox.GetValue(),
                    option))
        self.savesList.Set(saveList)
        self.bottomStateBar.SetStatusText('Profile "'+self.profileNameBox.GetValue()+'" is '+self.config.get(self.profileNameBox.GetValue(),
                                        'status')+'.')
Das Problem liegt bei der Funktion ActivateProfile - in die INI-Datei wird immer 'inactive' beim status reingeschrieben - irgendeine Ahnung, warum? Ich hab's schon zigmal durchgelesen, mir fällt aber nichts auf. Danke schonmal.
BlackJack

Also ich seh' in diesem Riesenquelltextbrocken auf die Schnelle nichts. Und habe auch keine Lust bei so einem nicht-lauffähigen Stück Code zu raten.

Schreib doch einfach mal ein paar ``print`` Anweisungen da rein und teste ob der Code, wo auf "active" gesetzt wird, jemals ausgeführt wird und warum (nicht).
rumilmirion
User
Beiträge: 34
Registriert: Mittwoch 3. Mai 2006, 12:09

BlackJack hat geschrieben:Also ich seh' in diesem Riesenquelltextbrocken auf die Schnelle nichts. Und habe auch keine Lust bei so einem nicht-lauffähigen Stück Code zu raten.
Nicht-lauffähigen Stück Code?? Sorry, aber bei mir läuft das bis auf den einen Teil schon. Wenn du meinst, dass du das ganze Program brauchst, gerne, kann ich auch reinposten. Sind so um die 20,000 Zeilen, lieste die dann? :roll:
BlackJack hat geschrieben:Schreib doch einfach mal ein paar ``print`` Anweisungen da rein und teste ob der Code, wo auf "active" gesetzt wird, jemals ausgeführt wird und warum (nicht).
Hab ich ja schon. Wird er eben nicht, deswegen wird ja für jede section in der INI-Datei 'inactive' als status reingeschrieben. Ausserdem, wenn ich wüsste warum's nicht geht, hätte ich wohl kaum hier nachgefragt, meinste nicht auch?
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Wenn ich bei einem Fehler absolut nicht weiterkomme, versuche ich, den Code auf das allernodwendigste zu reduzieren, sodass der Fehler aber noch auftritt. Entweder wird einem der Fehler dabei sowieso schon klar, oder man kann was kurzes Posten. :)
rumilmirion
User
Beiträge: 34
Registriert: Mittwoch 3. Mai 2006, 12:09

Hab inzwischen rausbekommen, warum's nicht funktioniert hat. Mal wieder typischer Fall von zu nah am eigenen Code sein. War total offensichtlich, das Problem. Na ja, trotzdem danke.
Antworten