Convert fetchers to use bb.msg
[bitbake.git] / lib / bb / fetch / wget.py
1 #!/usr/bin/env python
2 # ex:ts=4:sw=4:sts=4:et
3 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4 """
5 BitBake 'Fetch' implementations
6
7 Classes for obtaining upstream sources for the
8 BitBake build tools.
9
10 Copyright (C) 2003, 2004  Chris Larson
11
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free Software
14 Foundation; either version 2 of the License, or (at your option) any later
15 version.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 Place, Suite 330, Boston, MA 02111-1307 USA. 
24
25 Based on functions from the base bb module, Copyright 2003 Holger Schurig
26 """
27
28 import os, re
29 import bb
30 from   bb import data
31 from   bb.fetch import Fetch
32 from   bb.fetch import FetchError
33 from   bb.fetch import MD5SumError
34 from   bb.fetch import uri_replace
35
36 class Wget(Fetch):
37     """Class to fetch urls via 'wget'"""
38     def supports(url, d):
39         """Check to see if a given url can be fetched using wget.
40            Expects supplied url in list form, as outputted by bb.decodeurl().
41         """
42         (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d))
43         return type in ['http','https','ftp']
44     supports = staticmethod(supports)
45
46     def localpath(url, d):
47 #       strip off parameters
48         (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(url, d))
49         if "localpath" in parm:
50 #           if user overrides local path, use it.
51             return parm["localpath"]
52         url = bb.encodeurl([type, host, path, user, pswd, {}])
53
54         return os.path.join(data.getVar("DL_DIR", d), os.path.basename(url))
55     localpath = staticmethod(localpath)
56
57     def go(self, d, urls = []):
58         """Fetch urls"""
59
60         def md5_sum(parm, d):
61             """
62             Return the MD5SUM associated with the to be downloaded
63             file.
64             It can return None if no md5sum is associated
65             """
66             try:
67                 return parm['md5sum']
68             except:
69                 return None
70
71         def verify_md5sum(wanted_sum, got_sum):
72             """
73             Verify the md5sum we wanted with the one we got
74             """
75             if not wanted_sum:
76                 return True
77
78             return wanted_sum == got_sum
79
80         def fetch_uri(uri, basename, dl, md5, parm, d):
81             # the MD5 sum we want to verify
82             wanted_md5sum = md5_sum(parm, d)
83             if os.path.exists(dl):
84 #               file exists, but we didnt complete it.. trying again..
85                 fetchcmd = data.getVar("RESUMECOMMAND", d, 1)
86             else:
87                 fetchcmd = data.getVar("FETCHCOMMAND", d, 1)
88
89             bb.msg.note(1, bb.msg.domain.Fetcher, "fetch " + uri)
90             fetchcmd = fetchcmd.replace("${URI}", uri)
91             fetchcmd = fetchcmd.replace("${FILE}", basename)
92             bb.msg.debug(2, bb.msg.domain.Fetcher, "executing " + fetchcmd)
93             ret = os.system(fetchcmd)
94             if ret != 0:
95                 return False
96
97             # check if sourceforge did send us to the mirror page
98             dl_dir = data.getVar("DL_DIR", d, True)
99             if not os.path.exists(dl):
100                 os.system("rm %s*" % dl) # FIXME shell quote it
101                 bb.msg.debug(2, bb.msg.domain.Fetcher, "sourceforge.net send us to the mirror on %s" % basename)
102                 return False
103
104 #           supposedly complete.. write out md5sum
105             if bb.which(data.getVar('PATH', d), 'md5sum'):
106                 try:
107                     md5pipe = os.popen('md5sum ' + dl)
108                     md5data = (md5pipe.readline().split() or [ "" ])[0]
109                     md5pipe.close()
110                 except OSError:
111                     md5data = ""
112
113             # verify the md5sum
114             if not verify_md5sum(wanted_md5sum, md5data):
115                 raise MD5SumError(uri)
116
117             md5out = file(md5, 'w')
118             md5out.write(md5data)
119             md5out.close()
120             return True
121
122         if not urls:
123             urls = self.urls
124
125         localdata = data.createCopy(d)
126         data.setVar('OVERRIDES', "wget:" + data.getVar('OVERRIDES', localdata), localdata)
127         data.update_data(localdata)
128
129         for uri in urls:
130             completed = 0
131             (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(uri, localdata))
132             basename = os.path.basename(path)
133             dl = self.localpath(uri, d)
134             dl = data.expand(dl, localdata)
135             md5 = dl + '.md5'
136
137             if os.path.exists(md5):
138 #               complete, nothing to see here..
139                 continue
140
141             premirrors = [ i.split() for i in (data.getVar('PREMIRRORS', localdata, 1) or "").split('\n') if i ]
142             for (find, replace) in premirrors:
143                 newuri = uri_replace(uri, find, replace, d)
144                 if newuri != uri:
145                     if fetch_uri(newuri, basename, dl, md5, parm, localdata):
146                         completed = 1
147                         break
148
149             if completed:
150                 continue
151
152             if fetch_uri(uri, basename, dl, md5, parm, localdata):
153                 continue
154
155 #           try mirrors
156             mirrors = [ i.split() for i in (data.getVar('MIRRORS', localdata, 1) or "").split('\n') if i ]
157             for (find, replace) in mirrors:
158                 newuri = uri_replace(uri, find, replace, d)
159                 if newuri != uri:
160                     if fetch_uri(newuri, basename, dl, md5, parm, localdata):
161                         completed = 1
162                         break
163
164             if not completed:
165                 raise FetchError(uri)
166
167         del localdata