Dateien zippen mit Hilfe von Python

Um mit Hilfe des Moduls “zipfile” eine Zipdatei zu erstellen und eine Datei hinzuzufügen, braucht es nur 4 Zeilen Python Code.


import zipfile
zipper = zipfile.ZipFile(zipfilename, 'w')
zipper.write(filename,filenameArchive,zipfile.ZIP_DEFLATED)
zipper.close()

Erklärung zu den Codezeilen:

  1. Importieren des zip Moduls
  2. Es wird ein Objekt zipper erstellt, welches auf die Zipdatei “zipfilename” zeigt. Mit dem Flag ‘w’ wird die Datei im Schreibmodus geöffnet
  3. Der Zipdatei wird die Datei “filename” hinzugefügt und mit dem Namen “filenameArchive” abgelegt. Die Konstante ‘zipfile.ZIP_DEFLATED’ sorgt dafür, dass die Datei komprimiert gespeichert wird
  4. Wenn alle Dateien hinzugefügt wurden, muss die Methode .close() aufgerufen werden. Ansonsten werden nicht alle wichtigen Informationen in die Datei geschrieben und die Zipdatei wird nicht lesbar sein

Soll einer vorhandenen Zipdatei eine weitere Datei hinzugefügt werden, ändert sich nur das Flag in Zeile 2 von ‘w’ nach ‘a’. (w = write, a = append)

Work with ZIP archives – Python Doc

<a> Tag Attribut target=”_new”

In älteren und zum Teil auch noch in neueren Webseiten, findet man den Wert “_new” für das Attribute target beim a-Element. Um es gleich vorwegzunehmen: Dieser Wert ist nicht definiert und somit ein ungütltiger Wert. Leider musste ich feststellen, dass auch in einigen alten Webapplikationen, die ich erstellt habe, dieser Wert verwendet wird 🙁

Die Erklärung wieso “_blank” der richtige Wert dafür ist, findet man bei SELFHTML:

Viele Anwender verwenden statt target=”_blank” irgendeinen nicht existenten Framenamen oder sogar unzulässig target=”_new”, um einen Verweis in einem neuen Fenster zu öffnen. Das erzielt nicht den gewünschten Effekt, da das neue Fenster nicht fokussiert wird und der Anwender es unter Umständen nicht sieht (bei target=”_blank” wird das Fenster sehr wohl fokussiert). Außerdem werden andere Verweise, die diesen eigentlich nicht verwendeten Framenamen verwenden, ebenfalls in diesem neuen Fenster geöffnet.

Definierte und gültige Werte sind:

  • _blank um den Verweis in einem neuen Fenster zu öffnen (Achtung: nur zusammen mit rel=”noopener” verwenden),
  • _self um den Verweis im aktuellen Fenster zu öffnen,
  • _parent um bei verschachtelten Framesets das aktuelle Frameset zu sprengen,
  • _top um bei verschachtelten Framesets alle Framesets zu sprengen.

VBScript: Text von UTF-8 nach Windows-1252 konvertieren mit dem ADO Stream-Objekt

Soll ein Text, der als UTF-8 codiert wurde, in eine andere Zeichencodierung umgewandelt werden, kann dazu das ADO Stream-Objekt verwendet werden. Die hier verwendete Codierung “Windows-1252” ist eine Untermenge des ISO-8859-1 Character Sets.


'/***
' @brief convert a utf-8 text to an Windows-1252 text
' @param utf8xml, value
' @return text with Windows-1252 character set
'***/
Function UTF8TOISO(byval utf8xml)
On Error Resume Next

Dim objStream
const adTypeText = 2

Set objStream = CreateObject( "ADODB.Stream" )
Set objStreamISO = CreateObject( "ADODB.Stream" )

objStream.Type = adTypeText
objStream.Charset = "utf-8"
objStream.Open

'write data to stream
objStream.WriteText utf8xml
objStream.Position = 0

objStreamISO.Type = adTypeText
objStreamISO.Charset = "Windows-1252"
objStreamISO.Open
objStreamISO.WriteText objStream.ReadText
objStream.Position = 0

If Err Then
UTF8TOISO = ""
Else
UTF8TOISO = objStreamISO.ReadText
End If

objStream.Close
objStreamISO.Close
Set objStream = Nothing
Set objStreamISO = Nothing
End Function

Die verwendeten Properties und Funktionen des Stream-Objekts sind:

  • .Open  Öffnet den Stream
  • .Close  Schliesst den Stream
  • .Charset  Legt fest, welche Zeichencodierung verwendet werden soll
  • .Type  Definiert ob es ein Binär- oder Textstream ist
  • .WriteText  Schreibt Textdaten in den Stream
  • .ReadText  Liest Textdaten vom Stream
  • .Position  Legt die Position im Stream fest (in Bytes)

Diese Funktion lässt sich auch leicht modifizieren, wenn der konvertierte Text in einer Datei gespeichert werden soll. Dazu muss nur die Funktion “.SaveToFile(filename, adSaveCreateOverWrite)” des ADO Stream aufgerufen werden.

Text UTF-8 codiert in einer Datei speichern

Um einen Text UTF-8 codiert in einer Datei zu speichern kann folgender Code verwendet werden:


'/***
' @brief save a text UTF-8 coded in a file
' @param textToSave, value
' @param filename, the name of the file to create
' @return true on no error or false on error
'***/
Function saveFileAsUTF8(byval textToSave, byval filename)
	On Error Resume Next
    Dim objStream
	const adTypeText = 2
	Const adSaveCreateOverWrite = 2
    
    Set objStream = CreateObject( "ADODB.Stream" )
	objStream.Charset = "utf-8"
	objStream.Mode = adModeReadWrite	
	objStream.Type = adTypeText
	objStream.Open
	
	'write data to stream and save to file
    objStream.WriteText textToSave	
	objStream.Flush
	objStream.Position = 0	
	objStream.SaveToFile filename, adSaveCreateOverWrite	
    
    If Err Then
        ISOTOUTF8 = false
    Else
		ISOTOUTF8 = true
    End If	

    objStream.Close
    Set objStream = Nothing
End Function

'Aufruf der Funktion
call saveFileAsUTF8("Die bunte Welt besteht aus einem grünen Wald, einer hässlichen Geschichte und dem öffentlichen Grund...", "D:\tmp\ASP\utf8.txt")

Einbinden von Skripts in VBScript-Dateien

Beim Arbeiten mit Skripts (.vbs Dateien) gelangt man oft an den Punkt, an dem Funktionen bereits in mehreren anderen Skripts erstellt und verwendet wurden. Dabei wäre es praktisch, wenn man im neuen Skript nur noch eine Funktionssammlung einbinden könnte um die bereits erstellten Funktionen zu verwenden.

Der VBScript-Code zum Einbinden von Dateien:


Sub Include(Byval filename)
  Dim codeToInclude
  Dim FileToInclude

  Const OpenAsDefault = -2
  Const FailIfNotExist = 0
  Const ForReading = 1
  Const OpenFileForReading = 1
  Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")

  'Check for existance of include
  If Not FSO.FileExists(filename) Then
    wscript.Echo "Include file not found."
	Set FSO = Nothing
    Exit Sub
  End If

  'open file to include
  Set FileToInclude = FSO.OpenTextFile(filename, ForReading, _
  FailIfNotExist, OpenAsDefault)

  'read all contet of the file
  codeToInclude = FileToInclude.ReadAll
  
  'close file after reading
  FileToInclude.Close
 
  'now cleanup the unused objects
  Set FSO = Nothing
  Set FileToInclude = Nothing

  'now execute code from include file
  ExecuteGlobal codeToInclude
End Sub

Ein kleines Beispiel mit 2 Skript-Dateien:

Die Datei “include.vbs” enthält eine Funktion “hello()”, welche “Hello %name%” ausgibt:


sub hello(Byval person)
	wscript.echo "Hello " & person
end sub

Das Hauptskript ist in der Datei “sayHello.vbs” und bindet die Datei “include.vbs” mit der obigen Funktion ein.


call Include("include.vbs")
call hello("Thomas")

Nach dem Aufruf der Funktion “hello()”, erscheint wie erwartet “Hello Thomas” als Output. Somit wurde die Funktion “hello()” erfolgreich eingebunden.

Herunterladen der Demo-Dateien

Anzeigen der Spaltennamen einer Tabelle, bei einer Sqlite Datenbank, mit Python

Die Spaltennamen einer Tabelle können mit dem “Cursor” herausgelesen werden. Dazu verwendet man das Attribut “description” des Cursors. Dieses Attribut enthält alle Spaltennamen der letzten Abfrage, auch wenn diese keine Resultate zurückgeliefert hat.


import sqlite3

#connect to in memory db
connection = sqlite3.connect(':memory:')
mycursor = connection.cursor()

# Create table
mycursor.execute("create table spydb (id INTEGER PRIMARY KEY ASC, ipsend text, iprecv text)")

#select on table
mycursor.execute('select * from spydb order by id desc')

#get col names with the description attribute
names = [tuple[0] for tuple in mycursor.description]
print names;

#close the cursor
mycursor.close()

In der Zeile 14 erhalten wir vom Attribut “description” ein 7-Tupel pro Spalte. Dabei enthält das erste Element eines Tupels den Spaltennamen und die anderen 6 Elemente sind vom Typ “none”.

Die Ausgabe der Zeile 15:

 ['id', 'ipsend', 'iprecv'] 

Verwendung von sqlite3 in Python

Beim Entwickeln von Python-Scripts benötigt man oft eine Möglichkeit, Daten schnell und komfortabel zu speichern. Dazu eignet sich die Programmbibliothek SQLite hervorragend. Bei SQLite befindet sich die gesamte relationale Datenbank in einer einzigen Datei, da dieses System für die Verwendung im Embedded-Bereich entworfen wurde. Dabei unterstützt SQLite viele SQL-Sprachbefehle, welche im SQL-92-Standard festgelegt wurden. Das sind Funktionen wie Transaktionen, Views, Subselects und Trigger. Um SQLite in Python zu verwenden müssen wir die Bibliothek erst einbinden:


import sqlite3

Der nächste Schritt ist das Erstellen einer Verbindung zu der SQLite-Datenbank. Dies geschieht mit Hilfe eines “connection objects” das die Datenbank repräsentiert.


connection = sqlite3.connect('c:\\temp\spy.db')

Es existiert die Möglichkeit die Datenbank im Memory zu erzeugen, dazu wird anstelle des Pfades zur Datenbank “:memory:” verwendet.

Hier ein simples Beispiel bei dem eine Tabelle mit dem Namen “spydb” erstellt wird. Die Tabelle enthält 3 Spalten: id mit dem Autowert, ipsend und iprecv als Textfeld.
In der Zeile 8 und 9 werden Daten in die Tabelle geschrieben und in Zeile 12 mit einem “commit” die Transaktion ausgeführt.


# create a cursor to work with the database
mycursor = connection.cursor()

# create a new table
mycursor.execute("create table spydb (id INTEGER PRIMARY KEY ASC, ipsend text, iprecv text)")

# insert data to the table
mycursor.execute("insert into spydb (ipsend , iprecv ) values('10.0.0.1','10.0.0.2')")
mycursor.execute("insert into spydb (ipsend , iprecv ) values('10.0.0.3','10.0.0.15')")

# save the changes
connection.commit();

# insert data to the table
mycursor.execute("insert into spydb (ipsend , iprecv ) values('10.0.13.99','10.0.0.15')")

# rollback the changes
connection.rollback();

mycursor.execute('select * from spydb order by id desc')
for row in mycursor:
    print row

# close the cursor if we are finish
mycursor.close()

Wenn wir nun auf der Zeile 20 alle Daten aus der Tabelle auswählen und ausgeben, sieht dies wie folgt aus:

In der Zeile 15 wird ein weiterer Datensatz hinzugefügt, dieser wird jedoch nicht ausgegeben, da die Transaktion rückgängig (Zeile 18) gemacht wurde.

Python Docs

Mit VBScript OS Version bestimmen

Dieses Skript kann verwendet werden um die Server OS Version zu bestimmen. Das Skript liefert das Resultat für Windows 2000, Windows 2003, Windows 2008. Es kann jedoch auf einfache Weise erweitert werden, damit auch Client Versionen zurückgeliefert werden.


'/*
'	check windows version
'	return: 
'			win2k for windows 2000
'			win2k3 for windows 2003
'			win2k8 for windows 2008
'			unknown if the os is older / newer
'*/
function getOSVersion()
	strWinVersion = ""
	set objWMIService = GetObject("winmgmts:" _
		& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
	Set colOperatingSystems = objWMIService.ExecQuery _
		("Select * from Win32_OperatingSystem")
	For Each objOperatingSystem in colOperatingSystems
			strWinVersion = objOperatingSystem.Version
	Next

	'/**/	
	strMajor = left(strWinVersion,3)
	strOS = ""
	SELECT CASE strMajor
	case "5.0"
		'WScript.Echo "Windows 2000"
		strOS = "win2k"
	case "5.2"
		'WScript.Echo "Windows 2003"
		strOS = "win2k3"
	case "6.0"
		'WScript.Echo "Windows 2008"	
		strOS = "win2k8"
	case else
		'WScript.Echo "Windows x?" & "(" & strWinVersion & ")"
		strOS = "unknown"
	end select
	getOSVersion = strOS
End Function

DNS – Blacklists abfragen mit Python

Ein einfaches Python-Skript zum Abfragen von DNS-Blacklists, welche adressbasiert sind.
Bei adressbasierten Blacklists wird die zu überprüfende IP-Adresse, in umgekehrter Reihenfolge, an die Domain angehängt. Dann wird eine DNS-Abfrage auf einen A-Record gestartet. Wird ein A-Record zurück geliefert, gilt die IP-Adresse als gelistet. Der A-Record wird eine IP vom Typ 127.0.0.x aufweisen.

Wenn man wissen möchte warum eine IP-Adresse in die Liste aufgenommen wurde, kann der TXT-Record abgefragt werden. In diesem Record wird vom Blacklist Betreiber oft der Grund für die Aufnahme hinterlegt.


SHOW_DEBUG_MSG = 0

import string
import sys
import socket

'''
@return: 0    If the ip-address is not blacklisted
@return: 1    If the ip-address is blacklisted
'''
def checkIfBlacklisted( ip, blacklistURL):
if SHOW_DEBUG_MSG: print "Checking %s on %s" %(ip,blacklistURL)

# turn ip "a.b.c.d" into "d.c.b.a.DNS_BLACKLIST_DOMAIN"
iplist = string.split(ip, ".")
iplist.reverse()
ip = string.join(iplist, ".")
ip += "." + blacklistURL

try:
#if blacklisted, we receive a IP in the range 127.0.0.x
ret = socket.gethostbyname( ip )
if SHOW_DEBUG_MSG: print "Blacklisted! returned: %s" %ret
return 1
except socket.gaierror, message:
if SHOW_DEBUG_MSG: print "Not blacklisted [%s]" % message
return 0

if __name__ == "__main__":
if len(sys.argv) > 2:
print checkIfBlacklisted( sys.argv[1] , sys.argv[2])

DNSBlacklistChecker.py

Zum Ausführen:


python script x.x.x.x zen.spamhaus.org

Mögliche Blacklists:

  • no-more-funn.moensted.dk
  • dnsbl.sorbs.net
  • zen.spamhaus.org
  • spews.dnsbl.net.au
  • dnsbl.NJABL.org
  • proxies.relays.monkeys.com
  • list.dsbl.org