gget r24 - trunk/gget
- From: johans svn gnome org
- To: svn-commits-list gnome org
- Subject: gget r24 - trunk/gget
- Date: Wed, 9 Jul 2008 10:06:16 +0000 (UTC)
Author: johans
Date: Wed Jul 9 10:06:16 2008
New Revision: 24
URL: http://svn.gnome.org/viewvc/gget?rev=24&view=rev
Log:
Remember downloads between sessions.
Added:
trunk/gget/DownloadList.py
Modified:
trunk/gget/AddDownloadDialog.py
trunk/gget/Configuration.py
trunk/gget/Download.py
trunk/gget/DownloadManager.py
trunk/gget/GUI.py
trunk/gget/Main.py
trunk/gget/MainWindow.py
trunk/gget/Utils.py
trunk/gget/metalink.py
Modified: trunk/gget/AddDownloadDialog.py
==============================================================================
--- trunk/gget/AddDownloadDialog.py (original)
+++ trunk/gget/AddDownloadDialog.py Wed Jul 9 10:06:16 2008
@@ -24,7 +24,7 @@
import GUI
from Configuration import Configuration
-from DownloadManager import DownloadManager
+from DownloadList import DownloadList
from gget import NAME
class AddDownloadDialog:
@@ -93,8 +93,8 @@
self.add_button.clicked()
def __add_button_clicked(self, button):
- download_manager = DownloadManager()
- download_manager.start_download(self.url_entry.get_text(),
+ download_list = DownloadList()
+ download_list.add_download(self.url_entry.get_text(),
self.download_filechooserbutton.get_current_folder())
self.dialog.destroy()
Modified: trunk/gget/Configuration.py
==============================================================================
--- trunk/gget/Configuration.py (original)
+++ trunk/gget/Configuration.py Wed Jul 9 10:06:16 2008
@@ -133,9 +133,9 @@
return Configuration.instance
def __init(self, *args):
- # self.base_dir = os.path.expanduser("~/.gnome2/gget")
- # if not os.path.exists(self.base_dir):
- # os.makedirs(self.base_dir)
+ self.base_dir = os.path.expanduser("~/.gnome2/gget")
+ if not os.path.exists(self.base_dir):
+ os.makedirs(self.base_dir)
self.client = gconf.client_get_default()
if self.client.dir_exists(DIR_GGET):
Modified: trunk/gget/Download.py
==============================================================================
--- trunk/gget/Download.py (original)
+++ trunk/gget/Download.py Wed Jul 9 10:06:16 2008
@@ -26,26 +26,34 @@
import Utils
import GUI
+import metalink
from gget import NAME
-class Download(gobject.GObject):
- __gproperties__ = {"url": (str, "Download URL", "URL to the file being \
- downloaded", "", gobject.PARAM_READWRITE),
- "path": (str, "Download path", "Path to the location \
- where to save the download", "",
- gobject.PARAM_READWRITE)}
+CONNECTING = 0
+DOWNLOADING = 1
+STOPPED = 2
+PAUSED = 3
+COMPLETED = 4
+ERROR = 5
+class Download(gobject.GObject):
__gsignals__ = {"update": (gobject.SIGNAL_RUN_LAST, None, (int, int,
int)),
"speed-changed": (gobject.SIGNAL_RUN_LAST, None, (int,)),
"status-changed": (gobject.SIGNAL_RUN_LAST, None, (int,))}
- def __init__(self, url, path):
+ def __init__(self, uri, path):
gobject.GObject.__init__(self)
- self.url = url
+ self.uri = uri
self.path = path
- self.file_name = os.path.basename(self.url)
+ if uri.endswith(".metalink") or metalink.urlhead(uri,
+ metalink=True)["content-type"].startswith(metalink.MIME_TYPE):
+ self.is_metalink = True
+ else:
+ self.is_metalink = False
+
+ self.file_name = os.path.basename(self.uri)
self.file = os.path.join(path, self.file_name)
self.total_size = 0
@@ -53,23 +61,15 @@
self.block_size = 0
self.percent_complete = 0
- def __str__(self):
- return self.url
+ self.status = -1
- def do_get_property(self, property):
- if property.name == "url":
- return self.url
- elif property.name == "path":
- return self.path
-
- def do_set_property(self, property, value):
- if property.name == "url":
- self.url = value
- elif property.name == "path":
- self.path = path
+ def __str__(self):
+ return self.uri
def update(self, block_count, block_size, total_size):
- Utils.debug_print("Download.update called with block_count: %s block_size: %s total_size: %s" % (block_count, block_size, total_size))
+ Utils.debug_print("Download.update called with block_count: %s \
+ block_size: %s total_size: %s" % (block_count, block_size,
+ total_size))
self.block_count = block_count
self.block_size = block_size
self.total_size = total_size
@@ -81,13 +81,43 @@
except ZeroDivisionError:
self.percent_complete = 0
+ if self.status != DOWNLOADING and self.percent_complete > 0:
+ self.set_status(DOWNLOADING)
+
if self.percent_complete > 100:
self.percent_complete = 100
+ if self.percent_complete == 100:
+ self.set_status(COMPLETED)
+
Utils.debug_print("Percent complete: %s" % self.percent_complete)
gtk.gdk.threads_enter()
- self.emit("update", block_count, block_size, total_size)
+ self.emit("update", int(block_count), int(block_size), int(total_size))
gtk.gdk.threads_leave()
+ def set_status(self, status):
+ self.status = status
+ Utils.debug_print("Download status for %s changed to: %s (%s)" % (self,
+ self.get_status_string(), status))
+ gtk.gdk.threads_enter()
+ self.emit("status-changed", status)
+ gtk.gdk.threads_leave()
+
+ def get_status_string(self, status=None):
+ if self.status == CONNECTING:
+ return _("Connecting")
+ elif self.status == DOWNLOADING:
+ return _("Downloading")
+ elif self.status == STOPPED:
+ return _("Stopped")
+ elif self.status == PAUSED:
+ return _("Paused")
+ elif self.status == COMPLETED:
+ return _("Completed")
+ elif self.status == ERROR:
+ return _("Error")
+ else:
+ return _("N/A")
+
# vim: set sw=4 et sts=4 tw=79 fo+=l:
Added: trunk/gget/DownloadList.py
==============================================================================
--- (empty file)
+++ trunk/gget/DownloadList.py Wed Jul 9 10:06:16 2008
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2008 Johan Svedberg <johan svedberg com>
+
+# This file is part of gget.
+
+# gget is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# gget is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with gget; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+import os.path
+import sys
+from xml.etree import cElementTree as ET
+
+import gobject
+
+import Utils
+from Configuration import Configuration
+from Download import Download
+
+XML_HEADER = '<?xml version="1.0" encoding="UTF-8" ?>\n'
+DOWNLOADS_FILE = "downloads.xml"
+
+class DownloadList(gobject.GObject):
+ """Singleton holding the list of downloads"""
+
+ __gsignals__ = {"download-added": (gobject.SIGNAL_RUN_LAST, None,
+ (object,))}
+
+ instance = None
+
+ def __new__(type, *args):
+ if DownloadList.instance is None:
+ DownloadList.instance = gobject.GObject.__new__(type)
+ DownloadList.instance.__init(*args)
+ return DownloadList.instance
+
+ def __init(self, *args):
+ gobject.GObject.__init__(self)
+ self.config = Configuration()
+ self.downloads = []
+
+ def load_from_xml(self):
+ """Loads download objects from the xml file."""
+ self.download_file_path = os.path.join(self.config.base_dir,
+ DOWNLOADS_FILE)
+ if not os.path.exists(self.download_file_path):
+ self.__create_xml()
+ else:
+ self.tree = ET.parse(self.download_file_path)
+ downloads_element = self.tree.getroot()
+ for download_element in list(downloads_element):
+ uri = download_element.findtext("uri")
+ path = download_element.findtext("path")
+ status = download_element.findtext("status")
+ download = Download(uri, path)
+ download.status = status
+ self.__append_download(download)
+
+ def __create_xml(self):
+ file = open(self.download_file_path, "w")
+ file.write(XML_HEADER)
+ self.tree = ET.ElementTree(ET.fromstring("<downloads>\n</downloads>"))
+ self.tree.write(file)
+ file.close()
+
+ def add_download(self, uri, path=None):
+ if path is None:
+ path = self.config.default_folder
+
+ download = Download(uri, path)
+ self.__append_download(download)
+ self.__add_download_to_xml(download)
+
+ def __append_download(self, download):
+ download.connect("status-changed", self.__download_status_changed)
+ self.downloads.append(download)
+ Utils.debug_print("Appended download %s to list of downloads." %
+ download)
+ self.emit("download-added", (download))
+
+ def __add_download_to_xml(self, download):
+ """Adds the download to the xml tree and saves it to disk."""
+ downloads_element = self.tree.getroot()
+ download_element = ET.SubElement(downloads_element, "download")
+ uri_element = ET.SubElement(download_element, "uri")
+ uri_element.text = download.uri
+ path_element = ET.SubElement(download_element, "path")
+ path_element.text = download.path
+ # filename_element = ET.SubElement(download_element, "filename")
+ # filename_element.text = download.file_name
+ # size_element = ET.SubElement(download_element, "size")
+ # size_element.text = download.total_size
+ status_element = ET.SubElement(download_element, "status")
+ status_element.text = str(download.status)
+ self.__save_xml()
+
+ def __download_status_changed(self, download, status):
+ """Finds the download element which status changed and update
+ the xml tree."""
+ downloads_element = self.tree.getroot()
+ for download_element in list(downloads_element):
+ uri = download_element.findtext("uri")
+ path = download_element.findtext("path")
+ if download.uri == uri and download.path == path:
+ status_element = download_element.find("status")
+ status_element.text = str(status)
+ break
+ self.__save_xml()
+
+ def __save_xml(self):
+ """Adds a header and indents the xml tree before saving it to disk."""
+ file = open(self.download_file_path, "w")
+ file.write(XML_HEADER)
+ Utils.indent(self.tree.getroot())
+ self.tree.write(file)
+ file.close()
+
+# vim: set sw=4 et sts=4 tw=79 fo+=l:
Modified: trunk/gget/DownloadManager.py
==============================================================================
--- trunk/gget/DownloadManager.py (original)
+++ trunk/gget/DownloadManager.py Wed Jul 9 10:06:16 2008
@@ -28,16 +28,16 @@
import metalink
-import Utils
+import Download
import GUI
-from Download import Download
+import Utils
from Configuration import Configuration
from gget import NAME, VERSION
class DownloadManager(gobject.GObject):
"""Singleton handling the downloads"""
- __gsignals__ = {"download-added": (gobject.SIGNAL_RUN_LAST, None,
+ __gsignals__ = {"download-started": (gobject.SIGNAL_RUN_LAST, None,
(object,))}
instance = None
@@ -51,7 +51,6 @@
def __init(self, *args):
gobject.GObject.__init__(self)
self.config = Configuration()
- self.downloads = []
metalink.USER_AGENT = "%s %s" % (NAME, VERSION)
@@ -73,26 +72,37 @@
else:
metalink.HTTP_PROXY = "http://%s:%s" % (self.config.proxy_host, self.config.proxy_port)
- def start_download(self, uri, path=None):
- if path is None:
- path = self.config.default_folder
- download = Download(uri, path)
+ def download_added(self, download_list, download):
+ self.start_download(download)
+ def start_download(self, download):
Utils.debug_print("Starting download %s" % download)
- self.downloads.append(download)
result = thread.start_new_thread(self.__start_download_in_thread,
(download,))
- self.emit("download-added", (download))
+ self.emit("download-started", (download))
# self.__start_download_in_thread(download)
if not result:
- print "Failed downloading of file %s" % download.url
+ download.set_status(Download.ERROR)
+ print "Failed downloading of file %s" % download.uri
def __start_download_in_thread(self, download):
# Python 2.5 seems to have a bug: sys.excepthook is not call from code
# in a thread, see http://spyced.blogspot.com/2007/06/workaround-for-sysexcepthook-bug.html
# sys.excepthook(*sys.exc_info())
- metalink.get(download.url, download.path, handler=download.update)
+ download.set_status(Download.CONNECTING)
+ metalink.get(download.uri, download.path, handler=download.update)
+ def set_proxy(self, protocol, proxy):
+ """Sets the proxy to use for the specified protocol."""
+ if protocol == "http":
+ metalink.HTTP_PROXY = proxy
+ Utils.debug_print("HTTP proxy: %s", metalink.HTTP_PROXY)
+ elif protocol == "https":
+ metalink.HTTPS_PROXY = proxy
+ Utils.debug_print("HTTPS proxy: %s", metalink.HTTPS_PROXY)
+ elif protocol == "ftp":
+ metalink.FTP_PROXY = proxy
+ Utils.debug_print("FTP proxy: %s", metalink.FTP_PROXY)
# vim: set sw=4 et sts=4 tw=79 fo+=l:
Modified: trunk/gget/GUI.py
==============================================================================
--- trunk/gget/GUI.py (original)
+++ trunk/gget/GUI.py Wed Jul 9 10:06:16 2008
@@ -68,12 +68,18 @@
def load_icon_from_mime_type(mime_type, size=48):
"""Loads an icon from a mime type string. This is ugly and error prone,
there must be a better way to do this."""
+ pixbuf = None
l = mime_type.split("/")
mime = "%s-%s" % (l[0], l[1])
- pixbuf = icon_theme.load_icon(mime, size, gtk.ICON_LOOKUP_USE_BUILTIN)
- if not pixbuf:
- mime = "gnome-mime-%s" % mime
+ try:
pixbuf = icon_theme.load_icon(mime, size, gtk.ICON_LOOKUP_USE_BUILTIN)
+ except Exception, msg1:
+ try:
+ mime = "gnome-mime-%s" % mime
+ pixbuf = icon_theme.load_icon(mime, size,
+ gtk.ICON_LOOKUP_USE_BUILTIN)
+ except Exception, msg2:
+ pass
return pixbuf
def queue_resize(treeview):
Modified: trunk/gget/Main.py
==============================================================================
--- trunk/gget/Main.py (original)
+++ trunk/gget/Main.py Wed Jul 9 10:06:16 2008
@@ -30,6 +30,8 @@
import gnome
import GUI
+from AddDownloadDialog import AddDownloadDialog
+from DownloadList import DownloadList
from DownloadManager import DownloadManager
from MainWindow import MainWindow
from StatusIcon import StatusIcon
@@ -61,9 +63,11 @@
gtk.window_set_default_icon_list(*GUI.get_icon_list([16, 22, 24, 32]))
config = Configuration(debug)
+ download_list = DownloadList()
download_manager = DownloadManager()
+ download_list.connect("download-added", download_manager.download_added)
- main_window = MainWindow(config, download_manager)
+ main_window = MainWindow(config, download_list)
if config.show_main_window:
main_window.window.show()
@@ -73,8 +77,14 @@
# sys.excepthook = main_window.on_unhandled_exception
+ download_list.load_from_xml()
+
for uri in args:
- download_manager.start_download(uri)
+ if config.ask_for_location:
+ add = AddDownloadDialog(uri)
+ add.dialog.show()
+ else:
+ download_list.add_download(uri, config.default_folder)
gtk.main()
Modified: trunk/gget/MainWindow.py
==============================================================================
--- trunk/gget/MainWindow.py (original)
+++ trunk/gget/MainWindow.py Wed Jul 9 10:06:16 2008
@@ -42,10 +42,10 @@
TARGET_NETSCAPE_URL = 1
class MainWindow:
- def __init__(self, config, download_manager):
+ def __init__(self, config, download_list):
self.config = config
- self.download_manager = download_manager
- self.download_manager.connect("download-added", self.__download_added)
+ self.download_list = download_list
+ self.download_list.connect("download-added", self.__download_added)
self.__get_widgets()
@@ -228,8 +228,8 @@
"""Data function for the image of the download."""
download = model.get_value(iter, 0)
mime_type = gnomevfs.get_file_mime_type(download.file_name)
- cell.props.pixbuf = GUI.load_icon_from_mime_type(mime_type,
- 32)
+ pixbuf = GUI.load_icon_from_mime_type(mime_type, 32)
+ cell.props.pixbuf = pixbuf
def __name_cell_data_func(self, column, cell, model, iter):
"""Data function for the name of downloads."""
@@ -239,12 +239,12 @@
def __status_cell_data_func(self, column, cell, model, iter):
"""Data function for the status of downloads."""
download = model.get_value(iter, 0)
- cell.props.text = "N/A"
+ cell.props.text = download.get_status_string()
def __size_cell_data_func(self, column, cell, model, iter):
"""Data function for the file size of downloads."""
download = model.get_value(iter, 0)
- cell.props.text = Utils.get_readable_size(float(download.block_count * download.block_size))
+ cell.props.text = Utils.get_readable_size(download.block_count * download.block_size)
def __total_size_cell_data_func(self, column, cell, model, iter):
"""Data function for the file size of downloads."""
@@ -352,11 +352,7 @@
add = AddDownloadDialog(uri)
add.dialog.show()
else:
- # print uri
- # print self.config.default_folder
- self.download_manager.start_download(uri,
- self.config.default_folder)
-
+ self.download_list.add_download(uri, self.config.default_folder)
context.finish(True, False, time)
def show_add_download_dialog(self, widget):
@@ -612,17 +608,26 @@
else:
self.eta_treeview_column.props.visible = True
- def __download_added(self, download_manager, download):
+ def __download_added(self, download_list, download):
"""Called when a new download is added to DownloadManager. Adds the
download to the treeview model and sets up the update handler."""
self.downloads_model.append([download])
download.connect("update", self.__download_update)
+ download.connect("status-changed", self.__download_status_changed)
GUI.queue_resize(self.downloads_treeview)
def __download_update(self, download, block_count, block_size, total_size):
"""Called on download updates. Finds the associated treeview row and
fires a row changed signal."""
# self.window.set_title("%s %s (%.2f%%)" % (NAME, download.file_name, download.percent_complete))
+ self.update_download_row(download)
+
+ def __download_status_changed(self, download, status):
+ self.update_download_row(download)
+
+ def update_download_row(self, download):
+ """Called on download updates. Finds the associated treeview row and
+ fires a row changed signal."""
downloads_iter = self.downloads_model.get_iter_first()
for row in self.downloads_model:
if row[0] is download:
Modified: trunk/gget/Utils.py
==============================================================================
--- trunk/gget/Utils.py (original)
+++ trunk/gget/Utils.py Wed Jul 9 10:06:16 2008
@@ -24,8 +24,9 @@
def get_readable_size(bits):
for unit in ['bytes','KB','MB','GB','TB']:
- if bits < 1024.0:
+ if float(bits) < 1024.0:
return "%3.1f %s" % (bits, unit)
+ bits = float(bits)
bits /= 1024.0
def debug_print(message):
@@ -34,4 +35,18 @@
print("[%s] %s" % (time.strftime("%Y/%m/%d %H:%M:%S", time.localtime()),
message))
+def indent(element, level=0):
+ """Indents a xml.ElementTree starting from element."""
+ i = "\n" + level*" "
+ if len(element):
+ if not element.text or not element.text.strip():
+ element.text = i + " "
+ for element in element:
+ indent(element, level+1)
+ if not element.tail or not element.tail.strip():
+ element.tail = i
+ else:
+ if level and (not element.tail or not element.tail.strip()):
+ element.tail = i
+
# vim: set sw=4 et sts=4 tw=79 fo+=l:
Modified: trunk/gget/metalink.py
==============================================================================
--- trunk/gget/metalink.py (original)
+++ trunk/gget/metalink.py Wed Jul 9 10:06:16 2008
@@ -67,6 +67,10 @@
#
# CHANGELOG:
#
+# Version 4.0
+# -----------
+# - Bugfixes
+#
# Version 3.8
# -----------
# - Will now download any file type and auto-detect metalink files
@@ -190,6 +194,7 @@
import ftplib
import locale
import gettext
+import logging
import urllib2
import urlparse
import hashlib
@@ -202,10 +207,11 @@
import socket
import ftplib
import httplib
-import logging
import base64
import sys
import gettext
+import StringIO
+import gzip
import os
import StringIO
import os.path
@@ -213,6 +219,11 @@
import gettext
import sys
import locale
+
+try:
+ import win32process
+except ImportError: pass
+
import xml.dom.minidom
import optparse
import socket
@@ -289,7 +300,7 @@
#print base, localedir
t = gettext.translation(base, localedir, [locale.getdefaultlocale()[0]], None, 'en')
- return t.lgettext
+ return t.ugettext
_ = translate()
@@ -613,8 +624,9 @@
########################################################################
#import utils
+#import logging
-USER_AGENT = "Metalink Checker/3.8 +http://www.nabber.org/projects/"
+USER_AGENT = "Metalink Checker/4.0 +http://www.nabber.org/projects/"
SEGMENTED = True
LIMIT_PER_HOST = 1
@@ -668,7 +680,7 @@
#print base, localedir
t = gettext.translation(base, localedir, [locale.getdefaultlocale()[0]], None, 'en')
- return t.lgettext
+ return t.ugettext
_ = translate()
@@ -684,23 +696,61 @@
self.preference = int(preference)
self.maxconnections = int(maxconnections)
+
+class DecompressFile(gzip.GzipFile):
+ def __init__(self, fp):
+ self.fp = fp
+ self.geturl = fp.geturl
+
+ compressed = StringIO.StringIO(fp.read())
+ gzip.GzipFile.__init__(self, fileobj=compressed)
+
+ def info(self):
+ info = self.fp.info()
+ # store current position, must reset if in middle of read operation
+ reset = self.tell()
+ # reset to start
+ self.seek(0)
+ newsize = str(len(self.read()))
+ # reset to original position
+ self.seek(reset)
+ info["Content-Length"] = newsize
+ return info
+
def urlopen(url, data = None, metalink=False):
+ #print "URLOPEN:", url
url = complete_url(url)
- headers = {'User-agent': USER_AGENT}
+ req = urllib2.Request(url, data)
+ req.add_header('User-agent', USER_AGENT)
+ req.add_header('Cache-Control', "no-cache")
+ req.add_header('Pragma', "no-cache")
+ req.add_header('Accept-Encoding', 'gzip')
if metalink:
- headers['Accept'] = MIME_TYPE + ", */*"
- req = urllib2.Request(url, data, headers)
+ req.add_header('Accept', MIME_TYPE + ", */*")
+
fp = urllib2.urlopen(req)
+ try:
+ if fp.headers['Content-Encoding'] == "gzip":
+ return DecompressFile(fp)
+ except KeyError: pass
+ #print fp.info()
#print fp.read()
return fp
def urlhead(url, metalink=False):
+ '''
+ raise IOError for example if the URL does not exist
+ '''
url = complete_url(url)
- headers = {'User-agent': USER_AGENT}
+ req = urllib2.Request(url, None)
+ req.add_header('User-agent', USER_AGENT)
+ req.add_header('Cache-Control', "no-cache")
+ req.add_header('Pragma', "no-cache")
if metalink:
- headers['Accept'] = MIME_TYPE + ", */*"
- req = urllib2.Request(url, None, headers)
+ req.add_header('Accept', MIME_TYPE + ", */*")
+
req.get_method = lambda: "HEAD"
+ logging.debug(url)
fp = urllib2.urlopen(req)
headers = fp.headers
fp.close()
@@ -738,19 +788,27 @@
# assume metalink if ends with .metalink
if src.endswith(".metalink"):
return download_metalink(src, path, force, handler)
- # add head check for metalink type, if MIME_TYPE or application/xml? treat as metalink
- elif urlhead(src, metalink=True)["content-type"].startswith(MIME_TYPE):
- print _("Metalink content-type detected.")
- return download_metalink(src, path, force, handler)
- # assume normal file download here
else:
- # parse out filename portion here
- filename = os.path.basename(src)
- result = download_file(src, os.path.join(path, filename),
- 0, checksums, force, handler, segmented = segmented)
- if result:
- return [result]
- return False
+ # not all servers support HEAD where GET is also supported
+ # also a WindowsError is thrown if a local file does not exist
+ try:
+ # add head check for metalink type, if MIME_TYPE or application/xml? treat as metalink
+ if urlhead(src, metalink=True)["content-type"].startswith(MIME_TYPE):
+ print _("Metalink content-type detected.")
+ return download_metalink(src, path, force, handler)
+ except IOError, e:
+ pass
+ except WindowsError, e:
+ pass
+
+ # assume normal file download here
+ # parse out filename portion here
+ filename = os.path.basename(src)
+ result = download_file(src, os.path.join(path, filename),
+ 0, checksums, force, handler, segmented = segmented)
+ if result:
+ return [result]
+ return False
def download_file(url, local_file, size=0, checksums={}, force = False,
handler = None, segmented = SEGMENTED, chunksums = {}, chunk_size = None):
@@ -928,7 +986,6 @@
result = download_file_node(filenode, path, force, handler)
if result:
results.append(result)
-
if len(results) == 0:
return False
@@ -1026,7 +1083,7 @@
### FIXME need to check contents from previous download here
resume = FileResume(filename + ".temp")
resume.add_block(0)
-
+
while block:
block = temp.read(block_size)
data.write(block)
@@ -1083,15 +1140,15 @@
offset = count
total += self.size
elif offset != None:
- start = ((offset * self.size) / size) + 1
- newblocks.extend(range(start, start + (total / size)))
+ start = ((offset * self.size) / size)
+ newblocks.extend(map(str, range(start, start + (total / size))))
total = 0
offset = None
count += 1
if offset != None:
- start = ((offset * self.size) / size) + 1
- newblocks.extend(range(start, start + (total / size)))
+ start = ((offset * self.size) / size)
+ newblocks.extend(map(str, range(start, start + (total / size))))
self.blocks = newblocks
self.set_block_size(size)
@@ -1147,6 +1204,7 @@
filehandle.write("%s:" % str(self.size))
#for block_id in self.blocks:
#filehandle.write(str(block_id) + ",")
+ #print self.blocks
filehandle.write(",".join(self.blocks))
filehandle.close()
@@ -1305,6 +1363,7 @@
return True
return False
+
def is_remote(name):
transport = get_transport(name)
@@ -1344,10 +1403,11 @@
except:
return ""
- data = filehandle.read()
+ chunksize = 1024*1024
+ data = filehandle.read(chunksize)
while(data != ""):
filesha.update(data)
- data = filehandle.read()
+ data = filehandle.read(chunksize)
filehandle.close()
return filesha.hexdigest()
@@ -1500,34 +1560,34 @@
'''
?
'''
- try:
- if self.size == "" or self.size == 0:
- self.size = self.get_size()
- if self.size == None:
- #crap out and do it the old way
- self.close_handler()
- return False
-
- while True:
- #print "\ntc:", self.active_count(), len(self.sockets), len(self.urls)
- #if self.active_count() == 0:
- #print self.byte_total(), self.size
- time.sleep(0.1)
- self.update()
- self.resume.extend_blocks(self.chunk_list())
- if self.byte_total() >= self.size and self.active_count() == 0:
- self.resume.complete()
- self.close_handler()
- return True
+ #try:
+ if self.size == "" or self.size == 0:
+ self.size = self.get_size()
+ if self.size == None:
#crap out and do it the old way
- if len(self.urls) == 0:
- self.close_handler()
- return False
-
- return False
- except BaseException, e:
- logging.warning(unicode(e))
- return False
+ self.close_handler()
+ return False
+
+ while True:
+ #print "\ntc:", self.active_count(), len(self.sockets), len(self.urls)
+ #if self.active_count() == 0:
+ #print self.byte_total(), self.size
+ time.sleep(0.1)
+ self.update()
+ self.resume.extend_blocks(self.chunk_list())
+ if self.byte_total() >= self.size and self.active_count() == 0:
+ self.resume.complete()
+ self.close_handler()
+ return True
+ #crap out and do it the old way
+ if len(self.urls) == 0:
+ self.close_handler()
+ return False
+
+ return False
+## except BaseException, e:
+## logging.warning(unicode(e))
+## return False
def update(self):
next = self.next_url()
@@ -2300,6 +2360,7 @@
download = Dummy()
download.CONNECT_RETRY_COUNT = CONNECT_RETRY_COUNT
download.COUNTRY = COUNTRY
+download.DecompressFile = DecompressFile
download.FTP = FTP
download.FTP_PROXY = FTP_PROXY
download.FileResume = FileResume
@@ -2387,7 +2448,7 @@
#print base, localedir
t = gettext.translation(base, localedir, [locale.getdefaultlocale()[0]], None, 'en')
- return t.lgettext
+ return t.ugettext
_ = translate()
@@ -2405,17 +2466,23 @@
self.signature_id = self.key_id = None
self.username = None
self.error = None
+ self.nopubkey = False
def BADSIG(self, value):
+ self.error = "BADSIG"
self.valid = 0
self.key_id, self.username = value.split(None, 1)
def GOODSIG(self, value):
self.valid = 1
+ #self.error = "GOODSIG"
self.key_id, self.username = value.split(None, 1)
def VALIDSIG(self, value):
#print value
+ #self.valid = 1
+ #self.error = "VALID_SIG"
self.fingerprint, self.creation_date, self.timestamp, other = value.split(" ", 3)
def SIG_ID(self, value):
+ #self.error = "SIG_ID"
self.signature_id, self.creation_date, self.timestamp = value.split(" ", 2)
def NODATA(self, value):
self.error = _("File not properly loaded for signature.")
@@ -2423,10 +2490,19 @@
#print value
self.error = _("Signature error.")
def NO_PUBKEY(self, value):
- #print value
+ self.key_id = value
+ self.nopubkey = True
self.error = _("Signature error, missing public key with id 0x%s.") % value[-8:]
+
+ def TRUST_ULTIMATE(self, value):
+ '''
+ see http://cvs.gnupg.org/cgi-bin/viewcvs.cgi/trunk/doc/DETAILS?rev=289
+ Trust settings do NOT determine if a signature is good or not! That is reserved for GOOD_SIG!
+ '''
+ return
+
def TRUST_UNDEFINED(self, value):
- pass
+ self.error = _("Trust undefined")
#print value.split()
#raise AssertionError, "File not properly loaded for signature."
@@ -2577,7 +2653,7 @@
# the file objects for communicating with it.
cmd = [self.gpg_binary, '--status-fd 2']
if self.keyring:
- cmd.append('--keyring "%s" --no-default-keyring'%self.keyring)
+ cmd.append('--keyring "%s" --no-default-keyring'% self.keyring)
cmd.extend(args)
cmd = ' '.join(cmd)
@@ -2586,7 +2662,14 @@
shell = True
if os.name == 'nt':
shell = False
- process = subprocess.Popen(cmd, shell=shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ # From: http://www.py2exe.org/index.cgi/Py2ExeSubprocessInteractions
+ creationflags = 0
+ try:
+ creationflags = win32process.CREATE_NO_WINDOW
+ except NameError: pass
+
+ process = subprocess.Popen(cmd, shell=shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags = creationflags)
#child_stdout, child_stdin, child_stderr = #popen2.popen3(cmd)
#return child_stdout, child_stdin, child_stderr
#print process.stderr
@@ -2939,7 +3022,7 @@
# DO NOT CHANGE
-VERSION="Metalink Checker Version 3.8"
+VERSION="Metalink Checker Version 4.0"
def translate():
@@ -2960,7 +3043,7 @@
#print base, localedir
t = gettext.translation(base, localedir, [locale.getdefaultlocale()[0]], None, 'en')
- return t.lgettext
+ return t.ugettext
_ = translate()
@@ -2971,7 +3054,7 @@
# Command line parser options.
parser = optparse.OptionParser(version=VERSION)
parser.add_option("--download", "-d", action="store_true", dest="download", help=_("Actually download the file(s) in the metalink"))
- parser.add_option("--file", "-f", dest="filevar", metavar="FILE", help=_("Metalink file to check"))
+ parser.add_option("--file", "-f", dest="filevar", metavar="FILE", help=_("Metalink file to check or file to download"))
parser.add_option("--timeout", "-t", dest="timeout", metavar="TIMEOUT", help=_("Set timeout in seconds to wait for response (default=10)"))
parser.add_option("--os", "-o", dest="os", metavar="OS", help=_("Operating System preference"))
parser.add_option("--no-segmented", "-s", action="store_true", dest="nosegmented", help=_("Do not use the segmented download method"))
@@ -3009,13 +3092,9 @@
return
if options.download:
- download.SEGMENTED = True
- if options.nosegmented:
- download.SEGMENTED = False
progress = ProgressBar(55)
- result = download.get(options.filevar, os.getcwd(), handler=progress.download_update)
- #result = download.download_metalink(options.filevar, os.getcwd(), handler=progress.download_update)
+ result = download.get(options.filevar, os.getcwd(), handler=progress.download_update, segmented = not options.nosegmented)
progress.download_end()
if not result:
sys.exit(-1)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]