import repository from arizona
[raven.git] / lib / arizona-lib / transfer / arizonatransfer_coblitz.py
1 #! /usr/bin/env python
2 """
3 Stork Project (http://www.cs.arizona.edu/stork/)
4 Module: arizonatransfer_coblitz
5 Description:   Provides a general file transferring by Coblitz
6
7 """
8
9 import urllib
10 import urllib2
11 import os
12 import time
13 import arizonareport
14
15 def log_transfer(function, pid, timestamp, timestampend):
16    try:
17       import storklog
18       storklog.log_transfer(function, pid, timestamp, timestampend)
19    except:
20       pass
21
22
23 def init_transfer_program(ignore=None, ignore2=None, ignore3=None, ignore4= None):
24    # Need to turn proxy off because we already use codeen
25    opener = urllib.FancyURLopener({})
26    # TODO: why?????
27    # BECAUSE: it was to deal with stale content. since we don't get the metafile
28    # anymore via coblitz, and the tarballs all have unique names when they change,
29    # we don't need it anymore.
30    # opener.addheader('Cache-Control','max-age=300')
31    urllib._urlopener = opener
32
33
34
35       
36 def close_transfer_program():
37    # clean cache which may be created by urlretrieve
38    urllib.urlcleanup()
39    return
40
41
42
43 def retrieve_files(host, filelist, destdir='.', indicator=None):
44    """
45    <Purpose>
46       This retrieves files from a host to a destdir.
47
48    <Arguments>
49       host:
50          'host' holds two things, a server name and target directory.
51          For example, if you want to retrieve files from '/tmp/' directory
52          in 'quadrus.cs.arizona.edu' server, the 'host' will be
53          'quadrus.cs.arizona.edu/tmp'.
54
55       filelist:
56          'filelist' is a list of files which need to be retrieved.
57
58       destdir:
59          'destdir' is a destination directory where retrieved files will 
60          be placed. A user should have 'destdir' exist before retrieving 
61          files. 'destdir' should be a string. Default is a current dir.
62
63       indicator:
64          'indicator' is a module which has set_filename and 
65          download_indicator functions. 'indicator' will be passed in 
66          'urlretrieve' function so that progress bar will be shown 
67          while downloading files. Default is 'None'.
68
69    <Exceptions>
70       None.
71
72    <Side Effects>
73       None.
74
75    <Returns>
76       (True, grabbed_list)
77       'grabbed_list' is a list of files which are retrieved
78    """
79    # set grabbed_list as a empty list. Later it will be appended with retrieved files
80    grabbed_list = []
81
82    # check if host is a string   
83    if not isinstance(host, str):
84       arizonareport.send_syslog(arizonareport.ERR, "retrieve_files(): host should be a string")
85       # return false and empty list
86       return (False, grabbed_list)
87    
88    # check if filelist contains only strings
89    # TODO: Later I should just use something like justin.valid_sl
90    # TODO - check for valid list of tuples  
91    #if not valid_sl(filelist):
92    #   arizonareport.send_syslog(arizonareport.ERR, "retrieve_files(): filelist should be a list of strings")
93    #   # return false and empty list
94    #   return (False, grabbed_list)
95
96    # check if destdir is a string
97    if not isinstance(destdir,str):
98       arizonareport.send_syslog(arizonareport.ERR, "retrieve_files(): destdir should be a string")
99       # return false and empty list
100       return (False, grabbed_list)
101
102    # check that the destination directory exists
103    if not os.path.isdir(destdir):
104       arizonareport.send_syslog(arizonareport.ERR, "\nretrieve_files(): The destination directory '" + destdir + "' for a requested does not exist")
105       # return false and empty list
106       return (False, grabbed_list)
107
108    # if destdir is a empty string, then make it as a current directory
109    if destdir == '':
110       destdir = '.'
111
112    #attempting to retrieve directories can be fatal for coblitz.
113    #if not __verify_connection(host):
114    #   # return false and empty list
115    #   return (False, grabbed_list)
116
117
118    # go through every file in the file list
119    for file in filelist:
120       filename = file['filename']
121       starttime = time.time()
122
123       # build url which specifies host and filename to be retrieved
124       thisurl = __build_url(host,filename)
125       # open given url
126       try:
127          aurl = urllib2.urlopen(thisurl)
128          aurl.close()
129
130          # if idicator is passed in
131          if (indicator):
132             # make indicator_file store a file name which will be used in download_indicator function
133             indicator_file = filename
134             # make indicator_file hold only filename itself (without directory)
135             i = indicator_file.rfind("/")
136             if i != -1:
137                indicator_file = indicator_file[i + 1:]
138
139             try:
140                # set the filename so that indicator module can use the name to show for progress bar
141                indicator.set_filename(indicator_file)
142                arizonareport.send_out(0, "")
143                # download_indicator method of indicator module is passed
144                (filename,info) = urllib.urlretrieve(thisurl,destdir+"/"+filename, indicator.download_indicator)
145                arizonareport.send_out(0, "")
146             # indicator doesn't have method set_filename or download_indicator
147             except AttributeError:
148                arizonareport.send_syslog(arizonareport.ERR, 'retrieve_files(): indicator module passed in is incorrect')
149                return (False, grabbed_list)
150             # if indicator_file which used for set_filename is not a string
151             except TypeError:
152                arizonareport.send_syslog(arizonareport.ERR, 'retrieve_files(): indicator_file is incorrect')
153                return (False, grabbed_list)
154          else:
155             # retrieve a file
156             (filename,info) = urllib.urlretrieve(thisurl,destdir+"/"+filename)
157
158          grabbed_list = grabbed_list + [file] 
159          endtime = time.time()
160          log_transfer("coblitz", str(os.getpid()), str(starttime), str(endtime))
161       # if file is not permitted to be retrieved
162       except urllib2.HTTPError, (errstr):
163          arizonareport.send_syslog(arizonareport.ERR, 'retrieve_files(): "' + str(errstr) + '" on the file "' + filename + '"')
164
165    if (grabbed_list) :
166       return (True, grabbed_list)
167    # if nothing in grabbed_list
168    else:
169       return (False, grabbed_list)
170
171
172 def transfer_name():
173    """
174    <Purpose>
175       This gives the name of this transfer method.
176
177    <Arguments>
178       None.
179
180    <Exceptions>
181       None.
182
183    <Side Effects>
184       None.
185
186    <Returns>
187       'arizona_coblitz' as an string
188    """
189
190    return 'arizona_coblitz'
191
192
193
194 def __build_url(host,fname):
195    """
196    <Purpose>
197       This builds a url string with Http address for coblitz.
198
199    <Arguments>
200        host:
201          'host' holds two things, a server name and target directory.
202          For example, if you want to retrieve files from '/tmp/' directory
203          in 'quadrus.cs.arizona.edu' server, the 'host' will be
204          'quadrus.cs.arizona.edu/tmp'.
205       fname:
206          A file name to be retrieved
207    
208    <Exceptions>
209       None.
210
211    <Side Effects>
212       None.
213
214    <Returns>
215       A whole url string created
216    """
217
218    host = host.replace("ftp://", "")
219    host = host.replace("http://", "")
220    
221    # add '/' at the end of the host if there is not, so that file name is added properly
222    if not host[len(host) - 1] == '/':
223       host = host + '/'
224
225    # return url which contains host and filename and starts with address for coblitz  
226    return "http://coblitz.codeen.org:3125/"+host+fname
227
228
229
230
231 def __verify_connection(host):
232    """
233    <Purpose>
234       This verifies a connection, testing a host and target directory.
235
236    <Arguments>
237       host:
238          'host' holds two things, a server name and target directory.
239          For example, if you want to retrieve files from '/tmp/' directory
240          in 'quadrus.cs.arizona.edu' server, the 'host' will be
241          'quadrus.cs.arizona.edu/tmp'.
242             
243    <Exceptions>
244       None.\r
245       
246    <Side Effects>
247       None.
248
249    <Returns>
250       True or False (see above)
251    """
252    
253    # split host into server name and directory\r
254    #this could potentially be bad:(eg: http://quadrus.cs.arizona.edu/PlanetLab/...\r
255    # would return http:
256    #index = host.find('/')\r
257    thost=host.replace("http://","")\r
258    thost=thost.replace("ftp://","")\r
259    index=thost.find("/")
260    # set hostname to hold only a server name
261    if index != -1:
262       hostname = thost[:index]
263    else :
264       hostname = host   
265
266    # checking only host
267    checkurl = __build_url(hostname, "")
268
269    # urllib2 is used since urllib doestn't offer a nice way to check the connection is valid
270    try :
271       urllib2.urlopen(checkurl)
272    # incorrect host name or host is dead
273    except urllib2.URLError, (msg):      
274       arizonareport.send_syslog(arizonareport.ERR, '__verify_connection(): "' + hostname + '" '+ str(msg).split("'")[1])
275       return False
276
277
278    # checking if either a directory exist in the server
279    checkurl = __build_url(host, "")
280    try:
281       urllib2.urlopen(checkurl)
282    # if either a directory doesn't exist in the server
283    except urllib2.HTTPError, (strerror):
284       arizonareport.send_syslog(arizonareport.ERR, '__verify_connection(): "' + str(strerror) + '" on the url "' + checkurl + '"')
285       return False
286
287    # everything is fine       
288    return True
289
290
291
292 # TODO: should go away!!!
293 def valid_sl(stringlist):
294    """
295    <Purpose>
296       This returns True if stringlist is a list of strings or False if it is 
297       not.
298
299    <Arguments>
300       stringlist:
301           The variable to be checked.
302
303    <Exceptions>
304       None
305
306    <Side Effects>
307       None
308
309    <Returns>
310       True or False (see above)
311    """
312
313    # If it's a list
314    if isinstance(stringlist,list):
315
316       for item in stringlist:
317          # If an item in the list isn't a string then False
318          if not isinstance(item,str):
319             return False
320       else:
321          # It's a list of strings so True
322          return True
323    else:
324       # Not a list so false
325       return False
326
327