E.6.1 Basisklassen und Funktionen

# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1997
#
# Dateiname : p_bitstream.py
# Datum : 03.11.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Paket Bitstream, fasst alle Bitstrompaket
# Klassen zusammen
#
# Anmerkungen :
#
# -------------------------------------------------------------
import c_store
import c_bsio
import c_search
import c_glimpsearch
 
Klasse c_bsio
#!/usr/local/bin/python
# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1997
#
# Dateiname : c_bsio.py
# Datum : 03.11.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Eine einfache Klasse, die Methoden für
# Dateizugriffe bereitstellt
# Anmerkungen :
#
# -------------------------------------------------------------
 
 
class c_bsio:
    # Dateiname und Filedekriptor init.
    fname=""
    fd=0
 
    #
    # Konstruktor
    # Initialisiert die Variablen
    # filename - Dateiname
    # mode - Modus wie unter 'man fopen' beschrieben
    #
    def __init__(self,filename,mode="rw"):
        self.fname=filename
        self.mode=mode
         
         
    #
    # Öffnet die Datei
    # gibt den Filedeskriptor
    # der geöffneten Datei zurück
    #
    def open(self):
        self.fd=open(self.fname,self.mode)
        return self.fd
     
 
    #
    # Schliesst die Datei
    #
    def close(self):
        return self.fd.close()
 
     
 
    #
    # liest size Bytes aus der Datei und gibt sie zurueck
    #
    def read(self,size):
        return self.fd.read(size)
     
 
    #
    # Liest solange aus der Datei bis entweder
    # ein Zeilenumbruch oder das Dateiende erreicht ist
    #
    def readline(self):
        return self.fd.readline()
 
 
    #
    # Schreibt einen String in die Datei
    # und gibt die Anzahl der geschriebenen Bytes zurueck
     
    def write(self,buff):
        return self.fd.write(buff)
 
 
    #
    # Setzt den Dateizeiger auf eine neu Position
    # Argumente : offset - die Anzahl der Bytes um die der
    # Dateizeiger bzgl. der von whence bestimmten
    # Position verschoben werden soll.
    # whence - 0 für den Anfang der Datei,
    # 1 für die aktuelle Position
    # 2 für das Ende der Datei
   
    def seek(self,offset,whence):
        return self.fd.seek(offset,whence)
     
     
    #
    # Ermittelt die aktuelle Position des Dateizeigers
    #
     
    def tell(self):
        return self.fd.tell()
 
 
Klasse c_sgmlread
# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1998
# Dateiname : c_sgmlread.py
# Datum : 09.12.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Klasse zum komfortablen Zugriff auf die
# Elemente eines als Bitstrom vorliegenden
# SGML-Dokuments
# Anmerkungen : Diese Klasse wird von der Klasse c_bsio
# abgeleitet.
# -------------------------------------------------------------
 
# imports
import regex
import string
import c_bsio
 
class c_sgmlread(c_bsio.c_bsio):
    #
    # Konstruktor
    # fname gibt den Dateinamen des SGML-Dokuments an
    #
    def __init__(self,fname):
        # Konstruktor der Basisklasse
        c_bsio.c_bsio.__init__(self,fname,"r")
        # Oeffnen der Eingabedatei
        self.open()
 
    #
    # Destruktor
    #
    def __del__(self):
        # Datei schliessen
        self.close()
    #
    # Lese-/Schreibmarke auf den Dateianfang setzen
    #
    def seek_begin(self):
        self.fd.seek(0,0)
 
    #
    # Lese-/Schreibmarke auf das Dateiende setzen
    #
    def seek_end(self):
        self.fd.seek(0,2)
         
    #
    # liest das Doctype Tag des SGML-Dokuments aus
    # und gibt es zurueck
    #
    def get_doctype(self):
        self.oldpos=self.tell()
        self.seek(0,0)
        buff=" "
        erg=""
        while regex.search("<!DOCTYPE",buff)==-1 and buff!="":
            buff=self.fd.readline()
             
            if buff =="":
                erg= ""
            else:
                self.fd.seek(-len(buff),1)
                buff=""
                while buff!=">" and buff!="[":
                    buff=self.read(1)
                    erg=erg+buff
                     
            if len(erg)>0 and erg[len(erg)-1]=="[":
                erg=erg[0:-2]
                erg=erg+">"
            self.seek(self.oldpos,0)
            return erg
                                 
    #
    # liefert den DTD Bezeichner des SGML-Dokuments zurueck
    #
    def get_dtdname(self):
        dtyp=self.get_doctype()
        return string.split(dtyp[1:-1])[1]
    #
    # liefert den Filenamen der DTD zurueck
    #
    def get_dtdfile(self):
        dtyp=self.get_doctype()
        return string.split(dtyp[1:-1])[3][1:-1]
    #
    # gibt eine Liste alle Attribute des Doctype-Tags zurueck
    #
    def get_dtd(self):
        import string
        doctypetag=self.get_doctype()
        doctypetag=doctypetag[2:-1]
        return string.split(doctypetag," ")
             
    #
    # sucht ausgehend von der aktuellen Position der
    # Lese-/Schreibmarke das naechste Tag mit Namen str
    #
    def get_tag(self,str):
        buff=" "
        while regex.search("<"+str+"*",buff)==-1 and regex.search("</"+str+"*",buff)==-1 and buff!="":
            buff=self.fd.readline()
            if buff!="":
                self.fd.seek(-len(buff)+regex.search("<"+str,buff)-1,1)
                if regex.search("</"+str+" ",buff)!=-1 or regex.search("</"+str+">",buff)!=-1:
                    self.fd.seek(1,1)
                    erg=""
                    buff=""
                    while buff!=">":
                        buff=self.fd.read(1)
                        erg=erg+buff
            else:
                erg=""
                                         
        return erg
 
    #
    # sucht ausgehend von der aktuellen Position der
    # Lese-/Schreibmarke das naechste Tag
    #
    def get_nexttag(self):
        buff=" "
        while regex.search("<",buff)==-1 and buff!="":
            buff=self.fd.readline()
                 
        if buff!="":
            self.fd.seek(-len(buff)+regex.search("<",buff),1)
            # lese Taginhalt
            erg=""
            buff=""
            while buff!=">":
                buff=self.fd.read(1)
                erg=erg+buff
        else:
            erg=""
        return erg
 
    #
    # sucht ausgehend von der aktuellen Position der
    # Lese-/Schreibmarke das naechste Tag mit Namen str
    # und liefert den Inhalt des Tags zurueck
    #
    def get_tagcontents(self,str):
        erg=self.get_tag(str)
        if erg=="</"+str+">":
            erg=self.get_tag(str)
        erg1=""
        buff=" "
        while regex.search("</"+str+" ",buff)==-1 and regex.search("</"+str+">",buff)==-1 and buff!="":
            buff=self.fd.readline()
            erg1=erg1+buff
 
        erg1=erg1[:regex.search("</"+str+">",erg1)+len(str)+3]
        return erg+erg1
 
    #
    # teilt ein gegebenes Tag (tagstr) in den Tagnamen
    # und die einzelnen Attribute auf und liefert ein
    # Dictionaries zurueck, dessen Schluessel die
    # Attributnamen sind.
    #
    def split_tag(tagstr):
        ergdict={}
             
        # tagklammern entfernen
        tagstr=tagstr[1:-1]
 
        #hole tagname
        pos=string.find(tagstr," ")
        tag=tagstr[:pos]
        tagstr=tagstr[pos:]
 
        # tagname in dictionary einfuegen
        ergdict["TAG"]=tag
 
        # hole attribute
        while len(tagstr)!=0:
         
            # whitespace entfernen
            tagstr=string.strip(tagstr)
 
            # attributname holen
            pos1 = string.find(tagstr,"=")
            attrib = string.strip( tagstr[:pos1] )
            tagstr = tagstr[pos1+1:]
                 
            # whitespace entfernen
            tagstr=string.strip(tagstr)
                 
            # hole werte
            pos3 = string.find(tagstr," ")
            if pos3 == -1:
                pos3=len(tagstr)
            wert = string.strip( tagstr[:pos3] )
            tagstr = tagstr[pos3+1:]
                 
            # attribute werte paar in dictionary einfuegen
            ergdict[attrib]=wert
 
        return ergdict
 
 
 
 
 
 
 
 
 
 
 
 
Verwaltungsfunktionen
# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1998
# Dateiname : c_maintenance.py
# Datum : 09.12.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Diese Klasse realisiert ein paar Methoden
# zur Pflege des Systems
# Anmerkungen :
# -------------------------------------------------------------
 
#imports
from sc_globals import *
import pgpy
 
 
class c_maintenance:
    #
    # Reorganisert die Postgresdatenbank
    #
    def vacuum(self):
        self.conn=pgpy.pgconn(DL_PGHOST,DL_PGPORT,DL_DBNAME)
        res=self.conn.exec_query("vacuum;")
        erg=res.commandstatus()
        if str(erg)[0:6]!="VACUUM":
            return -1
        else:
            return 0
                 
    #
    # loescht ein als Bitstrom gespeichertes Dokument
    #
    def delete_bs(self,ident):
        import os
        os.system("rm "+"-f "+DL_BSOUTPATH+str(ident)+".bs")
        conn=pgpy.pgconn(DL_PGHOST,DL_PGPORT,DL_DBNAME)
        res=self.conn.exec_query(
            "update doc_description set bs_stored='f' where docnr="+
            str(ident)+";")
        erg=res.commandstatus()
        if str(erg)[0:6]!="UPDATE":
            return -1
        else:
            return 0
                     
 
    #
    # loescht ein Dokument aus dem Speicher
    #
    def delete_doc(self,ident):
        # erstmal als Bitstrom loeschen
        self.delete_bs(ident)
        # dann die Datenbank leeren
        conn=pgpy.pgconn(DL_PGHOST,DL_PGPORT,DL_DBNAME)
        res=self.conn.exec_query(
            "delete from doc_elements* where docnr=" + str(ident)+";")
        res=self.conn.exec_query(
            "delete from doc_methods where docnr=" + str(ident)+";")
        res=self.conn.exec_query(
            "update doc_description set sgml_stored='f' where docnr="+
            str(ident)+";")
        erg=res.commandstatus()
        if str(erg)[0:6]!="UPDATE":
            return -1
        else:
            return 0
 
         
    #
    # fuehrt ein SQL Statement auf der Datenbank aus
    #
    def sql_exec(self,querystr):
        conn=pgpy.pgconn(DL_PGHOST,DL_PGPORT,DL_DBNAME)
        res=self.conn.exec_query(querystr)
         # Fehler aufgetreten ?
        if res.get_tuple_count()==0:
            # wenn ja, -1 zurueckgeben
            return -1
        else:
            #wenn nein Ergebnis zurueckgeben
            erg=res.get_resultlist(1,"|",1,0)
            return erg
 
        return erg
    #
    # Reinitialisiert die Datenbank
    # VORSICHT alle gespeicherten Daten gehen verloren
    #
    def dali_reinit(self):
        import time
 
        print "-------------------------------------------------------"
        print "Sie sind dabei die komplette DALI Datenbank zu loeschen."
        print ""
        print " Ich warte jetzt mal 20 Sekunden, wenn Sie es sich anders"
        print ""
        print "ueberlegt haben, sollten sie ein paarmal CTRL-C druecken."
        print "--------------------------------------------------------"
        time.sleep(20)
 
        # Verbindung zu Postgres aufbauen
        conn=pgpy.pgconn(DL_PGHOST,DL_PGPORT,DL_DBNAME)
         
        # Alle Klassen entfernen
        res=self.conn.exec_query("drop table doc_description;")
        res=self.conn.exec_query("drop table doc_elements;")
        res=self.conn.exec_query("drop table doc_bin;")
        res=self.conn.exec_query("drop table doc_tags;")
        res=self.conn.exec_query("drop table doc_text;")
        res=self.conn.exec_query("drop table doc_methods;")
        res=self.conn.exec_query("drop table dtd;")
        res=self.conn.exec_query("drop table local_doc_ids;")
         
        # neue leere Klassen erzeugen
        res=self.conn.exec_query("CREATE TABLE local_doc_ids (docnr int4, dtdnr int4) archive = none;")
         
        res=self.conn.exec_query("CREATE TABLE doc_elements (docnr int4, elementnr int4, brother int4, son int4, contents text) archive = none;")
         
        res=self.conn.exec_query("CREATE TABLE dtd (dtdnr int4, dtdid text,publicname text, systemname text) archive = none;")
         
        res=self.conn.exec_query("CREATE TABLE doc_tags () inherits ( doc_elements) archive = none;")
         
        res=self.conn.exec_query("CREATE TABLE doc_text () inherits ( doc_elements) archive = none;")
         
        res=self.conn.exec_query("CREATE TABLE doc_bin () inherits ( doc_elements) archive = none;")
         
        res=self.conn.exec_query("CREATE TABLE doc_description (docnr int4, dtdnr int4, title text, author text, owner text, ident text, pubkey text, info text, metadtdnr int4, bs_stored bool, sgml_stored bool) archive = none;")
         
        res=self.conn.exec_query("CREATE TABLE doc_methods (docnr int4, meth_class text, meth_location text, meth_mimetype text) archive = none;")
         
        # Initialen Zaehlerstand einfuegen
        res=self.conn.exec_query("INSERT INTO local_doc_ids VALUES (100,1);")
 
        self.read_sgmlcat(self)
    #
    # traegt alle auf dem System verfuegbaren DTD's in die
    # DTD Klasse der Datenbnak ein
    #
    def read_sgmlcat(self):
        import c_bsio
        import class_funcs
        import string
         
        fname=DL_SGMLCATPATH+DL_SGMLCATNAME
        fd=c_bsio.c_bsio(fname,"r")
        fd.open()
        buff=" "
        while buff!="":
            buff=fd.readline()
            if buff[0:6]=="PUBLIC":
                newdtdid=class_funcs.get_newdtdid()
                publictup=string.split(buff,"\"")
                 
                dtdid=string.strip(publictup[2])
                publicname=string.strip(publictup[1])
                systemname=DL_SGMLCATPATH+dtdid
                 
                query="insert into dtd values ("+str(newdtdid)+","
                query=query+"'"+dtdid+"',"
                query=query+"'"+publicname+"',"
                query=query+"'"+systemname+"');"
 
                res=conn.exec_query(query)
                if res.commandstatus()[0:6]!="INSERT":
                    print "Fehler bei INSERT in c_maintenance.read_sgmlcat"
 
        fd.close()