anbindung an sourceforge's CVS

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Leonidas hat geschrieben:ich grupiere Module beim Import nach Herkuft, also stdlib, gtk usw.
Das finde ich auch besser so... Was ist eigentlich bei Funktions-def? Auch dort statt

Code: Alles auswählen

def send( self, command ):
besser:

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 :?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
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 :roll:
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.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Auch dort statt

Code: Alles auswählen

def send( self, command ):
besser:

Code: Alles auswählen

def send(self, command):
:?:
Ja.
jens hat geschrieben:Der sf.net Server scheint, aber dauer überlastet zu sein...
Ja, ich kenne das Problem.
jens hat geschrieben:So, lokaler CVS läuft... Das Pycketyzer Progrämmchen ist auch recht cool! Kann ich weiterempfehlen...
Klar, nutzt ja auch die exzellente Ethereal-Engine.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
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 :roll: )

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 :cry:

(EDIT: Code gelöscht)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
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:

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()

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab daraus direkt mal ein PyLucid Plugin gebastelt... Nun kann man damit direkt PyLucid aus den CVS Daten als ZIP downloaden:

http://jens.nelanet.de/index.py?p=/Down ... S+download

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten