Force linking of liboctbstack to require all symbols resolved
[platform/upstream/iotivity.git] / tools / scons / URLDownload.py
1 # -*- coding: utf-8 -*-\r
2 \r
3 ############################################################################\r
4 # GPL License                                                              #\r
5 #                                                                          #\r
6 # This file is a SCons (http://www.scons.org/) builder                     #\r
7 # Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #\r
8 # Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.     #\r
9 # This program is free software: you can redistribute it and/or modify     #\r
10 # it under the terms of the GNU General Public License as                  #\r
11 # published by the Free Software Foundation, either version 3 of the       #\r
12 # License, or (at your option) any later version.                          #\r
13 #                                                                          #\r
14 # This program is distributed in the hope that it will be useful,          #\r
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of           #\r
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            #\r
17 # GNU General Public License for more details.                             #\r
18 #                                                                          #\r
19 # You should have received a copy of the GNU General Public License        #\r
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.     #\r
21 ############################################################################\r
22 \r
23 # the URLDownload-Builder can download any data from an URL into a target\r
24 # file. The target name is used are the file name of the downloaded file.\r
25 \r
26 # This builder originated from work by Philipp Kraus and flashpixx project\r
27 # (see https://github.com/flashpixx). It has been modified to leverage\r
28 # the HTTP ETag header to be used as the csig. This allows the download\r
29 # builder to determine if the file should be downloaded again when the\r
30 # ETag header is supported\r
31 \r
32 import os, time\r
33 import urllib2, urlparse\r
34 import SCons.Builder, SCons.Node, SCons.Errors\r
35 \r
36 # Define a source node to represent the remote file. The construction of the\r
37 # node will query the hosting site to get the ETag, size and last-modified\r
38 # date.  This node also defines the method by which we will determine if\r
39 # the file should be downloaded again.\r
40 #\r
41 # This node derives from the Python.Value node\r
42 #\r
43 class URLNode(SCons.Node.Python.Value) :\r
44     def make_ready(self) :\r
45         try :\r
46             stream = urllib2.urlopen( str(self.value) )\r
47             info = stream.info()\r
48 \r
49             self.url_etag = None\r
50             self.url_last_modified = None\r
51             self.url_content_length = None\r
52 \r
53             if 'ETag' in info :\r
54                 self.url_etag = info['ETag']\r
55             if 'Last-Modified' in info :\r
56                 self.url_last_modified = time.mktime(time.strptime(info['Last-Modified'], '%a, %d %b %Y %H:%M:%S GMT'))\r
57             if 'Content-Length' in info :\r
58                 self.url_content_legth = info['Content-Length']\r
59         except Exception, e :\r
60             raise SCons.Errors.StopError( '%s [%s]' % (e, self.value) )\r
61 \r
62     def visited(self) :\r
63         ninfo = self.get_ninfo()\r
64 \r
65         if self.url_etag :\r
66             ninfo.csig = self.url_etag\r
67         if self.url_last_modified :\r
68             ninfo.timestamp = self.url_last_modified\r
69         if self.url_content_length :\r
70             ninfo.size = self.url_content_length\r
71         SCons.Node.Node.visited(self);\r
72 \r
73     def changed_since_last_build(self, target, prev_ni):\r
74         if prev_ni :\r
75             if self.url_etag :\r
76                 if prev_ni.csig == self.url_etag :\r
77                     # print 'Matched on ETag:'+prev_ni.csig\r
78                     return False\r
79 \r
80             if not self.url_last_modified :\r
81                 # print 'Last modified date is not available'\r
82                 return True\r
83             if not self.url_content_length :\r
84                 # print 'Content length is not available'\r
85                 return True\r
86             if prev_ni.timestamp != self.url_last_modified :\r
87                 # print 'Modified since last build'\r
88                 return True\r
89             if prev_ni.size != self.url_content_length :\r
90                 # print 'Content length has changed'\r
91                 return True\r
92 \r
93             return False\r
94 \r
95         # print 'Not previous built'\r
96         return True\r
97 \r
98 # Creates the output message\r
99 # @param s original message\r
100 # @param target target name\r
101 # @param source source name\r
102 # @param env environment object\r
103 def __message( s, target, source, env ) :\r
104     print 'downloading [%s] from [%s] ...' % (target[0], source[0])\r
105 \r
106 # Creates the action ie. the download function.\r
107 # This reads the data from the URL and writes it down to the file\r
108 # @param target target file on the local drive\r
109 # @param source URL for download\r
110 # @@param env environment object\r
111 def __action( target, source, env ) :\r
112     try :\r
113         source_name = str(source[0])\r
114         target_name = str(target[0])\r
115         stream = urllib2.urlopen(source_name)\r
116         file = open( target_name, 'wb' )\r
117         file.write(stream.read())\r
118         file.close()\r
119 \r
120         # Change the access/modified time to match\r
121         # the date on the downloaded file, if available\r
122         ninfo = source[0].get_ninfo()\r
123         if hasattr(ninfo, 'timestamp') :\r
124             mtime = ninfo.timestamp\r
125             if mtime :\r
126                 os.utime(target_name, (mtime, mtime))\r
127     except Exception, e :\r
128         raise SCons.Errors.StopError( '%s [%s]' % (e, source[0]) )\r
129 \r
130 \r
131 # Defines the emitter of the builder\r
132 # @param target target file on the local drive\r
133 # @param source URL for download\r
134 # @param env environment object\r
135 def __emitter( target, source, env ) :\r
136     return target, source\r
137 \r
138 # generate function, that adds the builder to the environment,\r
139 # @param env environment object\r
140 def generate( env ) :\r
141     env['BUILDERS']['URLDownload'] = SCons.Builder.Builder( action = __action,  emitter = __emitter,  target_factory = SCons.Node.FS.File,  source_factory = URLNode,  single_source = True,  PRINT_CMD_LINE_FUNC = __message )\r
142 \r
143 # existing function of the builder\r
144 # @param env environment object\r
145 # @return true\r
146 def exists(env) :\r
147     return 1\r