bitbake/lib/bb/fetch:
[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             return parm['md5sum']
67
68         def verify_md5sum(wanted_sum, got_sum):
69             """
70             Verify the md5sum we wanted with the one we got
71             """
72             if not wanted_sum:
73                 return True
74
75             return wanted_sum == got_sum
76
77         def fetch_uri(uri, basename, dl, md5, parm, d):
78             # the MD5 sum we want to verify
79             wanted_md5sum = md5_sum(parm, d)
80             if os.path.exists(dl):
81 #               file exists, but we didnt complete it.. trying again..
82                 fetchcmd = data.getVar("RESUMECOMMAND", d, 1)
83             else:
84                 fetchcmd = data.getVar("FETCHCOMMAND", d, 1)
85
86             bb.note("fetch " + uri)
87             fetchcmd = fetchcmd.replace("${URI}", uri)
88             fetchcmd = fetchcmd.replace("${FILE}", basename)
89             bb.debug(2, "executing " + fetchcmd)
90             ret = os.system(fetchcmd)
91             if ret != 0:
92                 return False
93
94             # check if sourceforge did send us to the mirror page
95             dl_dir = data.getVar("DL_DIR", d, True)
96             if not os.path.exists(dl):
97                 os.system("rm %s*" % dl) # FIXME shell quote it
98                 bb.debug(2,"sourceforge.net send us to the mirror on %s" % basename)
99                 return False
100
101 #           supposedly complete.. write out md5sum
102             if bb.which(data.getVar('PATH', d), 'md5sum'):
103                 try:
104                     md5pipe = os.popen('md5sum ' + dl)
105                     md5data = (md5pipe.readline().split() or [ "" ])[0]
106                     md5pipe.close()
107                 except OSError:
108                     md5data = ""
109
110             # verify the md5sum
111             if not verify_md5sum(wanted_md5sum, md5data):
112                 raise MD5SumError(uri)
113
114             md5out = file(md5, 'w')
115             md5out.write(md5data)
116             md5out.close()
117             return True
118
119         if not urls:
120             urls = self.urls
121
122         localdata = data.createCopy(d)
123         data.setVar('OVERRIDES', "wget:" + data.getVar('OVERRIDES', localdata), localdata)
124         data.update_data(localdata)
125
126         for uri in urls:
127             completed = 0
128             (type, host, path, user, pswd, parm) = bb.decodeurl(data.expand(uri, localdata))
129             basename = os.path.basename(path)
130             dl = self.localpath(uri, d)
131             dl = data.expand(dl, localdata)
132             md5 = dl + '.md5'
133
134             if os.path.exists(md5):
135 #               complete, nothing to see here..
136                 continue
137
138             premirrors = [ i.split() for i in (data.getVar('PREMIRRORS', localdata, 1) or "").split('\n') if i ]
139             for (find, replace) in premirrors:
140                 newuri = uri_replace(uri, find, replace, d)
141                 if newuri != uri:
142                     if fetch_uri(newuri, basename, dl, md5, parm, localdata):
143                         completed = 1
144                         break
145
146             if completed:
147                 continue
148
149             if fetch_uri(uri, basename, dl, md5, parm, localdata):
150                 continue
151
152 #           try mirrors
153             mirrors = [ i.split() for i in (data.getVar('MIRRORS', localdata, 1) or "").split('\n') if i ]
154             for (find, replace) in mirrors:
155                 newuri = uri_replace(uri, find, replace, d)
156                 if newuri != uri:
157                     if fetch_uri(newuri, basename, dl, md5, parm, localdata):
158                         completed = 1
159                         break
160
161             if not completed:
162                 raise FetchError(uri)
163
164         del localdata