Wie einfach oder schwer ist es an sourceforge's CVS Daten herran zu kommen?
Ich fänd es nett, wenn man per CGI sich eine aktuelle build machen könnte. In meinem Fall ist das theoretisch recht einfach, weil ich nur alle Dateien auf dem letzten Stand vom CVS Server downloaden müßte. Dann das ganze zu einer ZIP zusammen packen und zum Client schicken...
Ist das CVS Protokoll kompliziert, oder gibt es da fertige Module für? Ich hab bisher nur CVStoys gefunden und schaue mir das mal an...
EDIT: CVSToys benötigt twisted, also kann ich das schonmal vergessen... Ich muß ja eigentlich auch keine gesicherte Verbindung zum CVS Server aufbauen, ein Anonymous Zugang würde doch reichen, oder?
anbindung an sourceforge's CVS
Warum machst du es nicht einfach mit den CVS Commandozeilen Tools? Die müssen doch sowieso installiert sein.
Code: Alles auswählen
Python 2.3.5 (#1, Sep 10 2005, 19:23:30)
[GCC 3.3.5-20050130 (Gentoo Linux 3.3.5.20050130-r1, ssp-3.3.5.20050130-1, pie- on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system( 'cvs co' )
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ich denke der befehl cvs export (oder lautet der anders), ist besser in dem Fall, da dann nicht in jedem Unterordner noch ein Ordner 'CVS' ist.
SVN hat von Haus aus Python-Bindings, noch ein Grund mehr, es einzusetzen
SVN hat von Haus aus Python-Bindings, noch ein Grund mehr, es einzusetzen

My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Was meinst du mit von Haus aus?!? Für mich sieht es ehr so aus, als wäre pysvn ein von Subversion unabhängiges Projekt.Leonidas hat geschrieben:SVN hat von Haus aus Python-Bindings [...]

-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ich meine dass auf Tigris.org die Python Bindings zu Subversion im gleichen Download-Bereich waren und daher habe ich sie als zu Sbversion zugehörig eingestuft.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Hab rumgesucht, aber nix gefunden....
Hier ist das Protokoll beschrieben:
http://www.elegosoft.com/cvs/cvsclient.html
Werd mal versuchen das umzusetzten... Mal sehen wie weit ich komme
Hier ist das Protokoll beschrieben:
http://www.elegosoft.com/cvs/cvsclient.html
Werd mal versuchen das umzusetzten... Mal sehen wie weit ich komme

- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Hast recht, ich stolper schon über das Passwort
Ich weiß nicht was ich als Passwort senden muß, wenn ich als anonymous rein gehe... Ich erhalte nur:
(EDIT: Source gelöscht. Neuere Version weiter unten...)
Schau mit gerade http://www.networkchemistry.com/products/packetyzer/ an...

Hier mein Code:cvs [pserver aborted]: descramble: unknown scrambling method
(EDIT: Source gelöscht. Neuere Version weiter unten...)
Schau mit gerade http://www.networkchemistry.com/products/packetyzer/ an...
Zuletzt geändert von jens am Sonntag 18. September 2005, 21:52, insgesamt 1-mal geändert.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Steht doch hier.jens hat geschrieben:Hast recht, ich stolper schon über das PasswortIch weiß nicht was ich als Passwort senden muß, wenn ich als anonymous rein gehe... Ich erhalte nur:
cvs [pserver aborted]: descramble: unknown scrambling method
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Mal was ganz anderes: Warum schreibst du immer zwischen die Funktionsklammern Leerzeichen? Also zum Beispiel: self.sock.recv( 1024 ) statt self.sock.recv(1024). Ich kenne niemanden sonst, der das so schreibt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Hm... Weiß nicht... Hab ich mir so angewöhnt... Schlechter Stile?Leonidas hat geschrieben:Mal was ganz anderes: Warum schreibst du immer zwischen die Funktionsklammern Leerzeichen? Also zum Beispiel: self.sock.recv( 1024 ) statt self.sock.recv(1024). Ich kenne niemanden sonst, der das so schreibt.
Ich kann mich nun anmelden! Das Passwort wird anscheinend immer mit einem "A" eingeleitet. Also einfach "A\n" senden...
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
jens hat geschrieben:Hm... Weiß nicht... Hab ich mir so angewöhnt... Schlechter Stile?Leonidas hat geschrieben:Mal was ganz anderes: Warum schreibst du immer zwischen die Funktionsklammern Leerzeichen? Also zum Beispiel: self.sock.recv( 1024 ) statt self.sock.recv(1024). Ich kenne niemanden sonst, der das so schreibt.
Die meisten halten sich daran. Ich versuche mich auch an die meisten Sachen zu halten, nur eine Ausnahme mache ich mit voller Absicht (ich grupiere Module beim Import nach Herkuft, also stdlib, gtk usw. weil ich das sehr informativ finde, besonder für Leute die meinen Code lesen).PEP 8 hat geschrieben:Guido hates whitespace in the following places:
- Immediately inside parentheses, brackets or braces, as in:
"spam( ham[ 1 ], { eggs: 2 } )". Always write this as
"spam(ham[1], {eggs: 2})".
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Das finde ich auch besser so... Was ist eigentlich bei Funktions-def? Auch dort stattLeonidas hat geschrieben:ich grupiere Module beim Import nach Herkuft, also stdlib, gtk usw.
Code: Alles auswählen
def send( self, command ):
Code: Alles auswählen
def send(self, command):

Zurück zu CVS... Ich kann mich nun connecten:
(EDIT: Altes Listing gelöscht, s. unten)
Der sf.net Server scheint, aber dauer überlastet zu sein... Ich installiere mir mal einen lokalen Server, dann kann ich besser testen... Ich weiß nur nicht, ob mein vorhaben überhaupt Erfolgversprechend ist, oder ob ich mich direkt das Kommandozeilentool "cvs" nutzten sollte... Wobei ich das auf dem WebServer natürlich nicht haben dürfte... Andererseits könnte ich das direkt auf sf.net-WebServer machen... Weiß nur nicht ob die das so toll finden würden

- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
So, lokaler CVS läuft... Das Pycketyzer Progrämmchen ist auch recht cool! Kann ich weiterempfehlen...
Ich hab's nun soweit, das ich connecten und ein export zumindest anfangen kann... Nun hackelt es ein wenig... Dabei fällt mir ein, das ich bei Hosteurope, glaub ich, keine sockets öffnen darf
Aber das muß ich mal checken...
Hier der aktuelle Code:
(EDIT: Code gelöscht...)
Bin kein Experte, im Client <-> Server Programmierung... Hat jemand verbesserungs Vorschläge für mich?
EDIT: Code aktualisiert:
Es hackelte, weil ich einfach nicht versucht hab, Daten weiter zu empfangen
Also ich bekomme nun die Daten geliefert, weiß allerdings noch nicht so ganz, wie ich diese vernünftig weiter verarbeiten kann
Ich hab's nun soweit, das ich connecten und ein export zumindest anfangen kann... Nun hackelt es ein wenig... Dabei fällt mir ein, das ich bei Hosteurope, glaub ich, keine sockets öffnen darf

Hier der aktuelle Code:
(EDIT: Code gelöscht...)
Bin kein Experte, im Client <-> Server Programmierung... Hat jemand verbesserungs Vorschläge für mich?
EDIT: Code aktualisiert:
Es hackelte, weil ich einfach nicht versucht hab, Daten weiter zu empfangen

Also ich bekomme nun die Daten geliefert, weiß allerdings noch nicht so ganz, wie ich diese vernünftig weiter verarbeiten kann

Zuletzt geändert von jens am Montag 19. September 2005, 08:51, insgesamt 1-mal geändert.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ja.jens hat geschrieben:Auch dort stattbesser:Code: Alles auswählen
def send( self, command ):
Code: Alles auswählen
def send(self, command):
Ja, ich kenne das Problem.jens hat geschrieben:Der sf.net Server scheint, aber dauer überlastet zu sein...
Klar, nutzt ja auch die exzellente Ethereal-Engine.jens hat geschrieben:So, lokaler CVS läuft... Das Pycketyzer Progrämmchen ist auch recht cool! Kann ich weiterempfehlen...
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Also ich komm nicht ganz weiter... Ich habe es nun soweit, das ich die Daten bekomme... Aber mit der Auswertung ist es nicht ganz einfach...
Es scheint so, das die Daten auch immer wieder unterschiedlich eintreffen (Und das liegt nicht daran, das ich zwischenzeitlich auf dem CVS-Server was geändert hätte
)
Der Dateiname wird mit "M U " eingeleitet (ob das immer so ist, weiß ich allerdings auch nicht)
Danach kommen ein paar Zeilen (alles getrennt mit "\n") mit ein paar CVS Daten...
Zum schluß kommt dann die Dateigröße in Bytes und danach die eigentlichen Nutzdaten...
Das verarbeiten der Daten klappt bei mir allerdings nicht wirklich.... Je nach Blockgröße erkenne ich mehr oder weniger Dateien
(EDIT: Code gelöscht)
Es scheint so, das die Daten auch immer wieder unterschiedlich eintreffen (Und das liegt nicht daran, das ich zwischenzeitlich auf dem CVS-Server was geändert hätte

Der Dateiname wird mit "M U " eingeleitet (ob das immer so ist, weiß ich allerdings auch nicht)
Danach kommen ein paar Zeilen (alles getrennt mit "\n") mit ein paar CVS Daten...
Zum schluß kommt dann die Dateigröße in Bytes und danach die eigentlichen Nutzdaten...
Das verarbeiten der Daten klappt bei mir allerdings nicht wirklich.... Je nach Blockgröße erkenne ich mehr oder weniger Dateien

(EDIT: Code gelöscht)
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
So, der export funktioniert nun richtig! Die Dateien werden auf Platte geschrieben...
Hier der aktuelle Code:
Hier der aktuelle Code:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: UTF-8 -*-
__author__ = "Jens Diemer (www.jensdiemer.de)"
__license__ = "GNU General Public License (GPL)"
"""
CVS-pserver-Client
* Only export implemented
pserver Protokoll Beschreibung:
http://www.elegosoft.com/cvs/cvsclient.html
"""
__version__="0.1.0"
__history__="""
v0.1.0
- erste Version, export Funktioniert.
"""
#~ print "Content-type: text/html; charset=utf-8\r\n"
#~ import cgitb;cgitb.enable()
import os, sys, socket
class pserver:
def __init__(self, blocklen=1024, debug=False):
self.blocklen = blocklen
self.debug = debug
def connect(self, host, port, timeout=30):
print "connect...",
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
try:
self.sock.settimeout(timeout)
except AttributeError:
# Geht erst ab Python 2.3 :(
pass
print self.sock.getpeername(),
print "OK"
def auth_anonymous(self, repos_path):
print "auth...",
self.sock.send("BEGIN AUTH REQUEST\n")
self.sock.send("%s\n" % repos_path) # Repository Path
self.sock.send("anonymous\n") # Username
self.sock.send("A\n") # Password
self.sock.send("END AUTH REQUEST\n")
result = self.recv_lines()
if result[0] != "I LOVE YOU":
# "login" nicht erfolgreich
print "Error:"
print "-"*80
print "\n".join(result)
print "-"*80
sys.exit()
else:
print "OK"
def print_valid_requests(self):
result = self.process("valid-requests")[0]
result = result.split()
print "\n".join(result)
def send(self, command):
if self.debug: print "send '%s'..." % command,
self.sock.send("%s\n" % command)
if self.debug: print "OK"
def recv_lines(self, buffer=1024):
result = self.sock.recv(1024)
return result.splitlines()
def process(self, command, buffer=1024):
self.send(command)
return self.recv_lines(buffer)
def close(self):
print "close...",
self.sock.close()
print "OK"
#__________________________________________________________________
# Hight-level methods
def export(self, module_name, directory, dest_path):
self.root_dir = directory
self.send("UseUnchanged")
self.send("Root %s" % self.root_dir)
#~ self.send("Global_option -q")
#~ self.send("Argument %s" % module_name)
#~ self.send("Directory .")
#~ self.send(directory)
#~ self.send("expand-modules")
#~ print "export: ", self.recv_lines()
#~ print
self.send("Argument -N")
self.send("Argument -r")
self.send("Argument HEAD")
self.send("Argument %s" % module_name)
self.send("Directory .")
self.send(directory)
self.send("export")
self.get_files(module_name, dest_path)
def get_files(self, module_name, dest_path):
print "-"*80
block = ""
while 1:
new_data = self.sock.recv(self.blocklen)
block += new_data
while 1:
try:
current, block = block.split("\n",1)
except ValueError:
break
if current[:4] == "M U ": # Dateinamen
file_name = current[4:]
continue
if current[:2] == "E ": # neues Verzeichnis
continue
if current.endswith("THEAD"): # Datei-Versionsnummer
#~ print current
continue
if current.startswith( "u=" ): # Dateirechte
continue
if current.startswith( "Updated" ):
# Verzeichnis, relativ
continue
if current.startswith( self.root_dir ):
# absoluter CVS-Pfad der Datei
continue
try:
# Der Header wird abgeschlossen mit das Angabe
# der Dateigröße, danach folgt der Dateiinhalt
file_len = int( current )
#~ print ">file_len:", file_len
except:
# Die eigentlichen Daten kommen noch nicht
# Wir sind noch im Header
#~ print "\t",current
continue
readed_bytes = len(block)
rest_bytes = file_len - readed_bytes
if rest_bytes<0:
# Alle Daten zur Datei sind schon im aktuellen Block
self.write_file( file_name, dest_path, block[:rest_bytes], file_len )
# Restlichen Bytes für den nächsten Durchlauf aufbewahren
block = block[rest_bytes:]
break
current_blocklen = self.blocklen
while 1:
# Restlichen Bytes in Blöcke einlesen
if rest_bytes<current_blocklen:
# Letzter Block ist kleiner als die normale Blockgröße
current_blocklen = rest_bytes
new_data = self.sock.recv(current_blocklen)
current_bytes = len(new_data)
readed_bytes += current_bytes
rest_bytes -= current_bytes
block += new_data
if rest_bytes<=0:
# Alle Daten gelesen
break
self.write_file(file_name, dest_path, block, file_len)
block = ""
break
if new_data == "ok\n":
# Alle Dateien wurden empfangen
print "ENDE"
return
def write_file( self, file_name, dest_path, content, file_len ):
content_len = len(content)
if content_len != file_len:
print "+++ Error '%s' +++" % file_name
print "content_len != file_len:", content_len, file_len
return
complete_path = os.path.join( dest_path, file_name )
path = os.path.split( complete_path )[0]
if not os.path.isdir(path):
os.makedirs(path)
print "write '%s' %s Bytes..." % (file_name, content_len),
f=file(complete_path, "wb")
f.write(content)
f.close()
print "OK"
host = "cvs.sourceforge.net"
repos_path = "/cvsroot/pylucid"
timeout=30
port = 2401
cvs = pserver(blocklen=1024, debug=True)
cvs.connect(host, port, timeout)
cvs.auth_anonymous(repos_path)
#~ print cvs.print_valid_requests()
cvs.export(
module_name = "PyLucid_tarball",
directory = repos_path,
dest_path = r"d:\temp\test"
)
cvs.close()