pyGet - nächster Versuch

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hallo zusammen

Mir war wieder einmal langweilig, da hab ich pyGet komplett überarbeitet. Jetzt gefällts mir viel besser, jedoch hab ich den Resume-Support noch nicht integriert. Ich glaube die Trennung von GUI und Code ist mir besser gelungen als in der ersten Version.

Features:
- Console, Tk, Wx GUI (mit -g <gui>)
- Parts einstellbar (mit -p <parts>)
- URL kann man nur noch per Commandline übergeben, nicht mehr per GUI

Screenshot:
Bild
Bild
Bild

Download:
main.py
tkgui.py Wird nur bei "-g tk" gebraucht
wxgui.py Wird nur bei "-g wx" gebraucht

Usage:

Code: Alles auswählen

main.py [options] url

options:
  -h, --help            show this help message and exit
  -g GUI, --gui=GUI     GUI to use: console=Console GUI, wx=wxPython GUI,
                        tk=Tkinter GUI
  -p PARTS, --parts=PARTS
                        Partcount for downloading
Getestet habe ich es nur auf Windows

Gruss
tuxthekiller
User
Beiträge: 18
Registriert: Samstag 2. Dezember 2006, 12:17

Ich begrüße deine Änderungen sehr, da mir die Trennung sehr gut gefällt. Vor allen Dingen ist man nicht auf Tkinter beschränkt...
Zuletzt geändert von tuxthekiller am Freitag 12. Oktober 2007, 13:57, insgesamt 1-mal geändert.
Costi
User
Beiträge: 545
Registriert: Donnerstag 17. August 2006, 14:21

wieso hast du eigentlich nicht urllib2 benutzt sondern HTTP selber implementiert?

gruesse
costi
cp != mv
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Mh warum genau weiss ich nicht.

Hier ein paar Dinge, die glaubs nicht gehen würden mit urllib2:

Verwendet die urllib2 auch nicht blockende Sockets? (Ich hab genau 2 Threads, bei urllib2 brauch ich pro Part ein Thread)
Kann ich mit der urllib2 auch direkt von 4 Anfragen in eine Datei schreiben?
Kann ich jederzeit den Fortschritt auslesen?

Gruss
Costi
User
Beiträge: 545
Registriert: Donnerstag 17. August 2006, 14:21

ich schreib mir ja auch grad ein kleines download ding, das downloading selbst habe ich so implementiert:

Code: Alles auswählen

>>> class Download(threading.Thread):
	def __init__(self, url, file):
		self.file = open(file,'wb')
		self.url = url
		threading.Thread.__init__(self)
	def run(self):
		req = urllib2.Request(self.url)
		req.add_header('User-Agent', 'Mozilla/5.001 (windows; U; NT4.0; en-us) Gecko/25250101')
		conn = urllib2.urlopen(self.url)
		content_len = conn.info()['Content-length']
		arived_len = 0
		self.downloaded = lambda: 100.0*arived_len/int(content_len)
		for chunk in conn:
			arived_len += len(chunk)
			self.file.write(chunk)
		self.file.close()

		
>>> d = Download('http://viadrina.euv-frankfurt-o.de/~juso-hsg/lieder/mp3/inter_de.mp3', '~bla.mp3')
>>> d.start()
>>> d.downloaded()
1.4079486087171964
>>> d.downloaded()
2.7483427772895874
>>> d.downloaded()
2.7483427772895874
>>> d.downloaded()
4.3546768527117132
>>> d.downloaded()
4.3546768527117132
>>> d.downloaded()
5.7989872181295441
>>> d.downloaded()
5.7989872181295441
>>> d.downloaded()
13.136754071536409
cp != mv
foxx
User
Beiträge: 18
Registriert: Montag 25. September 2006, 22:24
Kontaktdaten:

@Costi:

Ich bin Python Anfänger und mir gefällt dein einfaches Script ziemlich gut. Ich will mit pygtk eine Download-Fortschrittsanzeige machen und brauche dafür ein Download-Script was ich immer nach dem Fortschritt abfragen kann. Deins ist also ideal aber irgendwie stell ich mich zu doof an. Wenn ich alles so in die python-Konsole eingeb kann ich mit downloaded() immer den Downloadstand erfragen doch wenn ich alles in eine Datei packe klappt das aus irgend einem Grund nicht (Ich denke mal Verständnisfehler).

Code: Alles auswählen

import urllib2
import threading
import time


class Download(threading.Thread):
    def __init__(self, url, file):
        self.file = open(file,'wb')
        self.url = url
        threading.Thread.__init__(self)

    def run(self):
        req = urllib2.Request(self.url)
        req.add_header('User-Agent', 'Mozilla/5.001 (windows; U; NT4.0; en-us) Gecko/25250101')
        conn = urllib2.urlopen(self.url)
        content_len = conn.info()['Content-length']
        arived_len = 0
        self.downloaded = lambda: 100.0*arived_len/int(content_len)
        for chunk in conn:
            arived_len += len(chunk)
            self.file.write(chunk)
        self.file.close()


d = Download('http://viadrina.euv-frankfurt-o.de/~juso-hsg/lieder/mp3/inter_de.mp3', '~bla.mp3')
d.start()

progress = d.downloaded()

while progress < 100.0:
    print progress
    time.sleep(1)
Hat das was mit den Threads zu tun? Und wenn ja, wie sollte ich das am besten machen? (Ich denke mal am besten wär eine Funktion die als Thread aufgerufen wird und die jede Sekunde oder so den Fortschrittsbalken anpasst)

Gruß,
foxx
[url=http://www.php4you.de/]PHP4You[/url]
[url=http://forum.php4you.de]PHP4You-Forum[/url]
[url=http://janek.php4you.de/]Mein Blog[/url]
[url=http://www.php4you.de/against_icq.html]Against ICQ[/url]
Crush
User
Beiträge: 44
Registriert: Montag 1. Mai 2006, 11:32

Hi foxx

In den zeilen 29 bis 33 musst du jeweils d.downloaded() neu aufrufen um den aktuellen Wert zu erhalten (wenn ich das jetzt richtig sehe ...), so zum Beispiel:

Code: Alles auswählen

progress = d.downloaded()
while progress < 100.:
    print progress
    time.sleep(1)
    progress = d.downloaded()
crush

edit: habe das Skript nun kurz ausprobiert, da scheint noch wo anders etwas nicht ganz in Ordnung zu sein. Das habe ich nicht gesehen, sorry!

edit2: so funktioniert das jetzt, wenn ich das richtig sehe... Aber habe das nur kurz angeschaut, möglich dass ich noch was falsch gemacht habe...

Code: Alles auswählen

import urllib2
import threading
import time


class Download(threading.Thread):
    def __init__(self, url, file):
        self.file = open(file,'wb')
        self.url = url
        threading.Thread.__init__(self)
        self.arived_len = 0
        self.content_len = 100
        self.downloaded = lambda: 100.0*self.arived_len/int(self.content_len)

    def run(self):
        req = urllib2.Request(self.url)
        req.add_header('User-Agent', 'Mozilla/5.001 (windows; U; NT4.0; en-us) Gecko/25250101')
        conn = urllib2.urlopen(self.url)
        self.content_len = conn.info()['Content-length']
        arived_len = 0
        #self.downloaded = lambda: 100.0*arived_len/int(content_len)
        for chunk in conn:
            self.arived_len += len(chunk)
            self.file.write(chunk)
        self.file.close()


#d = Download('http://viadrina.euv-frankfurt-o.de/~juso-hsg/lieder/mp3/inter_de.mp3', 'bla.mp3')
d = Download('http://cdimage.debian.org/debian-cd/4.0_r0/i386/iso-cd/debian-40r0-i386-businesscard.iso', 'debian.iso')
d.start()

progress = d.downloaded()

while progress < 100.0:
    print progress
    time.sleep(1) 
    progress = d.downloaded()
foxx
User
Beiträge: 18
Registriert: Montag 25. September 2006, 22:24
Kontaktdaten:

Danke!
Das funktioniert super so :P

Gruß,
foxx
[url=http://www.php4you.de/]PHP4You[/url]
[url=http://forum.php4you.de]PHP4You-Forum[/url]
[url=http://janek.php4you.de/]Mein Blog[/url]
[url=http://www.php4you.de/against_icq.html]Against ICQ[/url]
Costi
User
Beiträge: 545
Registriert: Donnerstag 17. August 2006, 14:21

ups, da hat sich auch noch ein kleiner bug eingeschlichen:

statt:

Code: Alles auswählen

conn = urllib2.urlopen(self.url)
in Download.run muss es:

Code: Alles auswählen

conn = urllib2.urlopen(req)
lauten.

urlopen´s arg muss naemlich eine url oder ein Request objekt sein
und wenn wir schon einen erstellen koenne wir ihm auch benutzen :D

folgendes kann uebrigens auch noch zu nen fehler fuehren
die HTTP resp header enthaelt keine content-length angabe (gibts sowas?)


gruesse
costi
cp != mv
Antworten