1
2
3 """
4 Network-related methods and classes.
5 """
6 from __future__ import absolute_import
7
8 __docformat__ = 'restructuredtext en'
9
10
11
12
13
14 import urlparse
15 import shutil
16 import tempfile
17 import urllib2
18 import logging
19 import os
20
21
22
23
24
25 __all__ = ['download']
26
27
28
29
30
31 log = logging.getLogger('grizzled.net')
32
33
34
35
36
37
38
39
40
41 -def download(url, directory=None, bufsize=8192):
42 """
43 Download the specified URL to a directory. This module properly handles
44 HTTP authentication for URLs like this one::
45
46 https://user:password@localhost:8080/foo/bar/baz.tgz
47
48 Note, however, that user/password authentication is only supported for
49 "http" and "https" URLs.
50
51 :Parameters:
52 url : str
53 the URL to download
54 directory : str
55 The directory to receive the downloaded file. If this parameter is
56 omitted, ``download()`` will create a temporary directory to
57 contain the file.
58 bufsize : int
59 buffer size to use when reading URL
60
61 :rtype: tuple
62 :return: A (*download_directory*, *downloaded_file*) tuple
63 """
64 pieces = urlparse.urlparse(url)
65 path = pieces.path
66 if not directory:
67 directory = tempfile.mkdtemp(prefix='download')
68
69 outputPath = os.path.join(directory, os.path.basename(path))
70
71
72
73 if pieces.scheme.startswith('http') and pieces.username:
74
75
76
77
78
79
80
81 user, password = pieces.username, pieces.password
82
83 netloc = pieces.hostname
84 if pieces.port:
85 pieces.hostname += ':%d' % pieces.port
86 newPieces = (pieces.scheme, netloc, pieces.path, pieces.query,
87 pieces.params, pieces.fragment)
88 url = urlparse.urlunparse(newPieces)
89 log.debug('Installing authorization handler for URL %s' % url)
90 passwordMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
91 passwordMgr.add_password(realm=None,
92 uri=url,
93 user=user,
94 passwd=password)
95 authHandler = urllib2.HTTPBasicAuthHandler(passwordMgr)
96 opener = urllib2.build_opener(authHandler)
97 opener.open(url)
98 urllib2.install_opener(opener)
99
100 log.debug('Downloading "%s" to "%s"' % (url, outputPath))
101 shutil.copyfileobj(urllib2.urlopen(url), open(outputPath, 'wb'), bufsize)
102
103 return (outputPath, directory)
104