Nein, ich habe eine Klasse, in dem diese beiden Listen über Funktionen befüllt und abgefragt werden können...
Ich weiß nicht ob du damit was anfangen kannst, aber hier mal mein Stand der Dinge:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: cp1252 -*-
__version__="0.0.3"
import os.path, time, sys
# Damit "Unterroutinen" gefunden werden, wird der Pfad erweitert:
sys.path.append("Routinen")
import FileVersionInfo
import REGinfo
class DiscData:
"""
=====================
DirInfo - Type:List
=====================
Jeder Verzeichnis ist ein Eintrag als Liste mit folgenden Informationen:
0 - ID ('NUMBER', 11, 10, 0, 0, 1) PathWalkID - Nummer auch für Dateien!
1 - parent ('NUMBER', 11, 10, 0, 0, 1) ID-Nr. des nächst höheren Verzeichnisses
2 - name ('STRING', 255, 255, 0, 0, 1)
3 - size ('NUMBER', 11, 10, 0, 0, 1)
4 - description ('STRING', 255, 255, 0, 0, 1)
5 - attrib ('STRING', 10, 10, 0, 0, 1)
6 - createdate ('DATE', 19, 19, 0, 0, 1)
7 - lastdate ('DATE', 19, 19, 0, 0, 1)
8 - moddate ('DATE', 19, 19, 0, 0, 1)
9 - depth ('NUMBER', 6, 5, 0, 0, 1)
Bsp (zwei Einträge):
(1, 0, 'R:', 576814470, None, 'D', <DbiDate object at 0x008AE060>, <DbiDate object at 0x008AE050>, <DbiDate object at 0x008AE070>, 0)
(18, 1, 'IE5', 79407911, None, 'DR', <DbiDate object at 0x008AE080>, <DbiDate object at 0x008AE090>, <DbiDate object at 0x008AE0A0>, 0)
======================
FileInfo - Type:List
======================
Jede Datei ist ein Eintrag in Form einer Liste mit folgenden Informationen:
0 - ID ('NUMBER', 11, 10, 0, 0, 1) PathWalkID, Nummer auch für Verzeichnisse!
1 - parent ('NUMBER', 11, 10, 0, 0, 1) ID-Nr. des Verz. in dem die Datei liegt!
2 - name ('STRING', 255, 255, 0, 0, 1)
3 - size ('NUMBER', 11, 10, 0, 0, 1)
4 - description ('STRING', 255, 255, 0, 0, 1)
5 - attrib ('STRING', 10, 10, 0, 0, 1)
6 - createdate ('DATE', 19, 19, 0, 0, 1)
7 - lastdate ('DATE', 19, 19, 0, 0, 1)
8 - moddate ('DATE', 19, 19, 0, 0, 1)
9 - depth ('NUMBER', 6, 5, 0, 0, 1)
Bsp (zwei Einträge):
(3, 1, 'AUTORUN.INF', 1838, None, 'R', <DbiDate object at 0x008AE060>, <DbiDate object at 0x008AE050>, <DbiDate object at 0x008AE070>, 0)
(4, 1, 'DATA1.MSI', 2348544, None, 'R', <DbiDate object at 0x008AE080>, <DbiDate object at 0x008AE090>, <DbiDate object at 0x008AE0A0>, 0)
*************
Anmerkungen
*************
PathWalkID
----------
Die ID wird für jeder Verz. und jede Datei um eins erhöht und gilt dabei als ID für
Verz. und Dateien gleichzeitig.
Bsp.:
ID | Verz.+Dateien
0 | \
1 | |--UnterVerz\
2 | |- Datei1.txt
3 | `- Datei2.txt
depth
-----
Bei Verz. gilt für das ROOT-Verzeichnis und die ersten UnterVerz. (also die Verz. im ROOT, ohne deren UnterVerz.) beide "depth = 0".
Erst das UnterVerz. eines UnterVerz. des ROOT erhält "depth = 1"
Bsp.:
depth | Verz.Struktur
0 | \ <- (Root-Verz.)
0 | |--UnterVerz1\
1 | `--UnterVerz2\
Für Dateien gilt dagegen die Regel "depth = Anzahl der Verz.". Also haben Dateien im ROOT-Verz. "depth = 0", Dateien im ersten
UnterVerz. (UnterVerz1\*.*) "depth = 1", Dateien im zweiten UnterVerz. (UnterVerz1\UnterVerz2\*.*) gilt "depth = 2" usw.
"""
def __init__( self ):
self.Disc = []
self.MyFileTypeInfo = REGinfo.FileTypeInfo()
###
### Funktionen zum hinzufügen von Daten
###
def newDisc( self, ID ):
self.Disc.append( ID )
self.currentDisc = ID
# Liste für die Verzeichniss-Informationen
self.DirInfo = []
self.currentVerzID = 0
# Liste der Datei-Daten
self.FileInfo = []
# Informationen zum Dateityp, Verknüpfung mit Programmen
self.ExtInfo = {}
def newDirectory( self, PathWalkID, DirName, DirStat ):
# Aktuelles Verz.ID für Dateien speichern, damit die Datei-Funktion auch weiß, aus
# welchem Verz. die Dateien stammen
self.currentVerzID = PathWalkID
# Pfad aufsplitten in Laufwerk und Verz.
DriveLetter, DirName = os.path.splitdrive( DirName )
if DirName == "": ### Aktuelles Verzeichnis ist das Hauptverzeichniss
# Laufwerk = Root-Verz als ersten Eintrag in der DirInfo eintragen
ParentDirID = 0
currentDirName = DriveLetter
self.DirDepth = 0
else: ### Normales Verzeichnis
# Liste erstellen mit allen Verzeichnissen
# Bsp.: ['r:', 'Verz', 'UnterVerz']
DirList = [DriveLetter] + DirName.split(os.sep)
currentDirName = DirList[-1]
# Verzeichnis Tiefe: Root + erstes Unterverz = 0
# auch genutzt für Dateien!
self.DirDepth = len(DirList) - 2
# vorletzte Verzeichniss ist das Parent-Verz.
ParentDirName = DirList[-2]
# Hohlt ID des Parent-Verz.
ParentDirID = self.getDirIDbyName( ParentDirName )
CreationTime = DirStat.st_ctime
LastAccess = DirStat.st_atime
LastModification = DirStat.st_mtime
# Stellt den Eintrag für das aktuelle Verzeichniss zusammen
Info = [
PathWalkID, # 0 - ID
ParentDirID, # 1 - parent
currentDirName, # 2 - name
0, # 3 - size
"", # 4 - description
"", # 5 - attrib
CreationTime, # 6 - createdate
LastAccess, # 7 - lastdate
LastModification, # 8 - moddate
self.DirDepth # 9 - depth
]
if ParentDirID == 0: ### Root-Verzeichnis
# Damit die "FileDepth" für Dateien im Root-Verzeichniss stimmt, wird
# self.DirDepth manipuliert
self.DirDepth = -1
self.DirInfo.append( Info )
def newFile( self, PathWalkID, FileName, FileStat ):
"""
Eine neue Datei aufnehmen
Die ID der Datei ist die PathWalkID, die auch glaichzeitig für Verzeichnisse ist, aber nicht für
den Zusammenhang zwischen Verzeichnis <-> Datei!!! Dafür ist die "parent"-ID zuständig!!! Sie
gibt die ID-Nr. des Verzeichnisses an, in dem die Datei liegt.
"""
# ID zur verknpüpfung zwischen Datei <-> Endungs-Information
ExtInfoID = self.newExtInfo( FileName )
self.FileInfo.append(
{
"ID" : PathWalkID,
"parent" : self.currentVerzID,
"name" : FileName,
"size" : FileStat.st_size, # FileSize
"description" : "",
"attrib" : "",
"createdate" : FileStat.st_ctime, # CreationTime
"lastdate" : FileStat.st_atime, # LastAccess
"moddate" : FileStat.st_mtime, # LastModification
"depth" : self.DirDepth + 1, # FileDepth
"extInfoID" : ExtInfoID
}
)
def newExtInfo( self, FileName ):
"""
wird von self.newFile() aufgerufen!
DateiTyp Informationen über Verknüpfung und Programm-Versionen
benötigt Modul: REGinfo und FileVersionInfo
0 - Ext Dateiendung
1 - TypeInfo Allgemeine Beschreibung des DateiTyps
2 - Program Programm mit dem der DateiTyp verknüpft ist
3 - CompanyName |-- Firma
4 - FileDescription |--
5 - FileVersion |-- Version
6 - LegalCopyright `-- Copyright
self.ExtInfo
"""
FileExt = os.path.splitext( FileName )[1]
if FileExt == "": return -1
if self.ExtInfo.has_key(FileExt):
return self.ExtInfo[FileExt]["ID"]
ExtInfo = self.MyFileTypeInfo.getInfo( FileExt )
#~ "Type" - DateiTyp-Kennung (wie Win-Befehl "assoc" herrausliefert)
#~ "TypeInfo" - Allgemeine Beschreibung des DateiTyps
#~ "Program" - direkter Pfad zur Datei (sofern existiert)
if ExtInfo != None:#and ExtInfo.has_key("Program"):
print FileExt, ExtInfo
DescItems = ["CompanyName", "FileDescription", "FileVersion", "LegalCopyright"]
FileInfo = FileVersionInfo.getFileVerInfo( ExtInfo["Program"], DescItems )
if FileInfo:
for i in FileInfo:
print i,"-", FileInfo[i]
else:
print "- Keine DateiInformation vorhanden -"
print
#~ self.ExtInfo
#~ print Ext
###
### allgemeine Funktionen zum Auslesen der Daten, die nicht
### konkreten Problemlösungen sind
def getItemsByItem( self, List, SearchNr, SearchValue, SourceNr ):
"""
Liefert eine Liste aller Werte in der >SourceNr<-Spalte, wenn in
der >SearchNr<-Spalte der Wert = >SearchValue< ist.
Das ganze wird in der >List< durchgeführt.
Bsp.
| 0 | 1 | 2
----------------
0 | A1 | B1 | C1
1 | A2 | B1 | C2
2 | A3 | B1 | C3
getItemsByItem( XXX, 0, "A2", 2) => ["C2"]
getItemsByItem( XXX, 1, "B1", 1) => ["A1","A2","A3"]
"""
Results = []
for i in List:
if i[SearchNr] == SearchValue:
Results.append( i[SourceNr] )
return Results
def getItemByItem( self, List, SearchNr, SearchValue, SourceNr ):
"""
Im Prinzip die gleiche Funktion wie getItemsByItem()!
Jedoch wird beim ersten Treffer abgebrochen.
"""
for i in List:
if i[SearchNr] == SearchValue:
return i[SourceNr]
###
### Funktionen zum auslesen der Daten
###
def getVerzFromIDlist( self, DirIDlist ):
"""
Liefert eine Liste der VerzNamen von der >DirIDlist< zurück.
Wird bei fullPath() verwendet.
"""
DirList = []
for DirID in DirIDlist:
DirList.append( getItemByItem( self.DirInfo, 1, DirID, 2) )
print "DirList:",DirList
return DirList
def getFilesByDirID( self, DirID ):
"""
Liefert eine Liste aller Datei-IDs zurück, die in dem Verzeichnis mit dem
>DirID< sind, zurück.
"""
return self.getItemListByItemValue( self.FileInfo, "ID", DirID, "parent" )
def getDirIDbyName( self, DirName ):
"""
Liefert die ID des ersten Verz. mit dem Namen >DirName< zurück
Wird z.B. von newDirectory() benötigt
"""
for i in self.DirInfo:
currentDirName = i[2]
if currentDirName == DirName:
return i[0]
print ">Fehler! [%s] nicht gefunden!" % DirName
def getfullPathByDirID( self, DirID ):
"""
Liefert den kompletten Pfad eines Verzeichnisses zurück, in dem
die Parent-Verkettung vollständig aufgelöst wird.
"""
PathIDs = []
while 1:
PathIDs.append( DirID )
# DirID des Parent-Verzeichnisses:
DirID = self.getItemByItem( self.DirInfo, 1, DirID, 0 )
if ID==0: break
# ID-Liste umkehren
PathIDs.reverse()
VerzListe = self.getVerzFromIDlist( PathIDs )
print "\\".join(VerzListe)
###
### Hilfsfunktionen
###
def getMaxDirDepth( self ):
"""
Liefert den höchsten "depth"-Wert für Verz. zurück
Wird von MakeDirInfoComplete() gebraucht
"""
MaxDirDepth = 0
for i in self.DirInfo:
if i[9]>MaxDirDepth:
MaxDirDepth = i[9]
return MaxDirDepth
def MakeDirInfoComplete( self ):
"""
Addiert alle Dateigrößen
"""
print "="*79
for i in self.DirInfo[::-1]:
print ">",i[2]
DirID = i[0]
print DirID
# BytesListe, jeder Datei in dem aktuellen Verzeichniss:
BytesList = self.getItemListByItemValue( self.FileInfo, "size", DirID, "parent" )
AllBytes = 0
for Bytes in BytesList:
AllBytes += Bytes
print AllBytes
print self.getFilesByDirID( DirID )
print "--XXX"
def getItemListByItemValue( self, Liste, getKey, filterValue, filterKey ):
"""
Gibt eine gefilterte Liste aus einer >Liste<, die ein Dict beinhaltet, zurück.
Bsp "Liste":
L=[
{ "item1":"1" , "item2":"2" }
{ "item1":"10" , "item2":"20" }
{ "item1":"100", "item2":"200" }
{ "item1":"33" , "item2":"20" }
]
getItemListByItemValue(
Liste = L,
getKey = "item1",
filterValue = "20"
filterKey = "item2"
)
Ergebnis-Liste:
[ "10", "33" ]
"""
result = []
for i in Liste:
if i[filterKey] == filterValue:
result.append( i[getKey] )
return result
###
### Debug-Funktionen:
###
def dumpDirData( self ):
print "-"*79
print "Disc:",self.Disc
for i in self.DirInfo:
print i
print "-"*79
def dumpFileData( self ):
print "-"*79
print "Disc:",self.Disc
for i in self.FileInfo:
print i, self.FileInfo[i]
print "-"*79
def getDiscID( DriveLetter ):
from os import popen
shell = popen( "dir %s:" % DriveLetter )
DiscID = shell.readlines()[1].split(":")[1].strip()
shell.close()
DiscID = DiscID[:4]+DiscID[5:] # MittelStrich entfernen
return DiscID
def GetData( PathWalkID, dirname, FileNameList ):
if PathWalkID[0]>100: return
PathWalkID[0] += 1
print ">",PathWalkID[0],dirname
DirStat = os.stat( dirname+"\\" )
MyDiscData.newDirectory( PathWalkID[0], dirname, DirStat )
for FileName in FileNameList:
CompleteFilePath = dirname+os.sep+FileName
if os.path.isfile( CompleteFilePath ):
#~ print CompleteFilePath
PathWalkID[0] += 1
FileStat = os.stat( CompleteFilePath )
MyDiscData.newFile( PathWalkID[0], FileName, FileStat )
#~ time.strftime("%d.%m.%Y - %H:%M:%S",time.localtime(Datum))
MyDiscData = DiscData()
DriveLetter = "r"
DiscID = getDiscID( DriveLetter )
MyDiscData.newDisc( DiscID )
DiscPath = DriveLetter+":"
PathWalkID = [0]
os.path.walk( DiscPath, GetData, PathWalkID)
#~ MyDiscData.dumpFileData()
MyDiscData.MakeDirInfoComplete()
#~ MyDiscData.dumpDirData()
z.B. ist die Funktion MakeDirInfoComplete nicht wirklich fertig...
Jetzt nutze ich os.path.walk(), aber einfachere ist os.walk()...
Es ist also noch viel zu tun...
Außerdem ist dort auch verweise zu FileVersionInfo und REGinfo... Aber die kannst du vielleicht einfach ausklammern...
Mir ist auch aufgefallen, das ich im Prinzip einige Sachen direkt in eine DB schreiben und "bearbeiten" könnte... Denn irgendwie baue ich damit fast eine kleine DB selber... Aber da ich mich noch nicht auf eine bestimmten DB festgelegt hab, kann ich z.Z. nicht recht weiter machen...