import repository from arizona
[raven.git] / lib / arizona-lib / transfer / arizonatransfer_coral.py
1 #! /usr/bin/env python
2 """
3 Stork Project (http://www.cs.arizona.edu/stork/)
4 Module: arizonatransfer_coral
5 Description:   Provides a general file transferring by Coral
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 close_transfer_program():
24    """
25    <Purpose>
26       This closes a connection (dummy function for Coral).
27
28    <Arguments>
29       None.
30    
31    <Exceptions>
32       None.
33
34    <Side Effects>
35       None.
36
37    <Returns>
38       True.
39    """
40  
41    return True
42
43
44
45 def init_transfer_program(ignore=None, ignore2=None, ignore3=None, ignore4=None):
46    """
47    <Purpose>
48       This initializes a connection (dummy function for Coral).
49
50    <Arguments>
51       None.
52    
53    <Exceptions>
54       None.
55
56    <Side Effects>
57       None.
58
59    <Returns>
60       True.
61    """
62    return True
63
64
65
66
67 def retrieve_files(host, filelist, destdir='.', indicator=None):
68    """
69    <Purpose>
70       This retrieves files from a host to a destdir.
71
72    <Arguments>
73       host:
74          'host' holds two things, a server name and target directory.
75          For example, if you want to retrieve files from '/tmp/' directory
76          in 'quadrus.cs.arizona.edu' server, the 'host' will be
77          'quadrus.cs.arizona.edu/tmp'.         
78
79       filelist:
80          'filelist' is a list of files which need to be retrieved.
81
82       junk_hashlist:
83          'junk_hashlist' is a list of the hashes for this list of files.
84          It should be a list of strings.
85
86       destdir:
87          'destdir' is a destination directory where retrieved files will 
88          be placed. A user should have 'destdir' exist before retrieving 
89          files. 'destdir' should be a string. Default is a current dir.
90
91       indicator:
92          'indicator' is a module which has set_filename and 
93          download_indicator functions. 'indicator' will be passed in 
94          'urlretrieve' function so that progress bar will be shown 
95          while downloading files. Default is 'None'.
96
97    <Exceptions>
98       None.
99
100    <Side Effects>
101       None.
102
103    <Returns>
104       (True, grabbed_list)
105       'grabbed_list' is a list of files which are retrieved
106    """
107    # set grabbed_list as a empty list. Later it will be appended with retrieved files
108    grabbed_list = []
109
110    # check if host is a string   
111    if not isinstance(host, str):
112       arizonareport.send_syslog(arizonareport.ERR, "retrieve_files(): host should be a string")
113       # return false and empty list
114       return (False, grabbed_list)
115    
116    # check if filelist contains only strings
117    # Later I should just use something like justin.valid_sl   TODO!!!
118    # TODO - check for valid tuple list
119    #if not valid_sl(filelist):
120    #   arizonareport.send_syslog(arizonareport.ERR, "retrieve_files(): filelist should be a list of strings")
121    #   # return false and empty list
122    #   return (False, grabbed_list)
123
124    # check if destdir is a string
125    if not isinstance(destdir,str):
126       arizonareport.send_syslog(arizonareport.ERR, "retrieve_files(): destdir should be a string")
127       # return false and empty list
128       return (False, grabbed_list)
129
130    # check that the destination directory exists
131    if not os.path.isdir(destdir):
132       arizonareport.send_syslog(arizonareport.ERR, "\nretrieve_files(): The destination directory '" + destdir + "' for a requested does not exist")
133       # return false and empty list
134       return (False, grabbed_list)
135
136    # if destdir is a empty string, then make it as a current directory
137    if destdir == '':
138       destdir = '.'
139
140    #don't verify the connection!  it takes way too long to try transferring as it is
141    #if not __verify_connection(host):
142    #   # return false and empty list
143    #   return (False, grabbed_list)
144
145
146    # go through every file in the file list
147    for file in filelist:
148       filename = file['filename']
149       starttime = time.time()
150
151       # build url which specifies host and filename to be retrieved
152       thisurl = __build_url(host,filename)
153       # open given url
154       try:
155          aurl = urllib2.urlopen(thisurl)
156          aurl.close()
157
158          # if idicator is passed in
159          if (indicator):
160             # make indicator_file store a file name which will be used in download_indicator function
161             indicator_file = filename
162             # make indicator_file hold only filename itself (without directory)
163             i = indicator_file.rfind("/")
164             if i != -1:
165                indicator_file = indicator_file[i + 1:]
166
167             try:
168                # set the filename so that indicator module can use the name to show for progress bar
169                indicator.set_filename(indicator_file)
170                arizonareport.send_out(0, "")
171                # download_indicator method of indicator module is passed
172                (filename,info) = urllib.urlretrieve(thisurl,destdir+"/"+filename, indicator.download_indicator)
173                arizonareport.send_out(0, "")
174             # indicator doesn't have method set_filename or download_indicator
175             except AttributeError:
176                arizonareport.send_syslog(arizonareport.ERR, 'retrieve_files(): indicator module passed in is incorrect')
177                return (False, grabbed_list)
178             # if indicator_file which used for set_filename is not a string
179             except TypeError:
180                arizonareport.send_syslog(arizonareport.ERR, 'retrieve_files(): indicator_file is incorrect')
181                return (False, grabbed_list)
182          else:
183             # retrieve a file
184             (filename,info) = urllib.urlretrieve(thisurl,destdir+"/"+filename)
185
186          grabbed_list = grabbed_list + [file]
187          endtime = time.time()
188          log_transfer("coral", str(os.getpid()), str(starttime), str(endtime))
189       # if file is not permitted to be retrieved
190       except urllib2.HTTPError, (errstr):
191          arizonareport.send_syslog(arizonareport.ERR, 'retrieve_files(): "' + str(errstr) + '" on the file "' + filename + '"')
192
193    if (grabbed_list) :
194       return (True, grabbed_list)
195    # if nothing in grabbed_list
196    else:
197       return (False, grabbed_list)
198
199
200
201 def transfer_name():
202    """
203    <Purpose>
204       This gives the name of this transfer method.
205
206    <Arguments>
207       None.
208
209    <Exceptions>
210       None.
211
212    <Side Effects>
213       None.
214
215    <Returns>
216       'arizona_coral' as an string
217    """
218
219    return 'arizona_coral'
220
221
222
223 def __build_url(host,fname):
224    """
225    <Purpose>
226       This builds a url string with a Coralized address.
227
228    <Arguments>
229        host:
230          'host' holds two things, a server name and target directory.
231          For example, if you want to retrieve files from '/tmp/' directory
232          in 'quadrus.cs.arizona.edu' server, the 'host' will be
233          'quadrus.cs.arizona.edu/tmp'.
234       fname:
235          A file name to be retrieved
236    
237    <Exceptions>
238       None.
239
240    <Side Effects>
241       None.
242
243    <Returns>
244       A whole url string created
245    """
246
247    # make the host does not contain 'http://' or 'ftp://'
248    host = host.replace("ftp://", "")      
249    host = host.replace("http://", "")\r
250 \r
251    #coral requires that the directory be separated from the host name   \r
252    dir=""\r
253    dpos=host.find("/")\r
254    if dpos!=-1:\r
255        dir=host[dpos:]\r
256        host=host[:dpos]
257 \r
258    # if we're specifying a port, we must change it to proper format for coral\r
259    host=host.replace(":",".")\r
260    
261    # add '/' at the end of the directory if the file name doesn't begin with one and the directory doesn't end with one, so that file name is added properly
262    if (len(fname)>0 and not fname[0] == '/') and not dir[-1] == '/':
263       dir = dir + '/'
264    # return url which contains host and filename\r
265    return "http://"+ host + ".nyud.net:8090" + dir + fname
266
267           
268       
269 def __verify_connection(host):
270    """
271    <Purpose>
272       This verifies a connection, testing a host and target directory.
273
274    <Arguments>
275       host:
276          'host' holds two things, a server name and target directory.
277          For example, if you want to retrieve files from '/tmp/' directory
278          in 'quadrus.cs.arizona.edu' server, the 'host' will be
279          'quadrus.cs.arizona.edu/tmp'.
280             
281    <Exceptions>
282       None.\r
283
284    <Side Effects>
285       None.
286
287    <Returns>
288       True or False (see above)
289    """
290    
291    # split host into server name and directory
292    index = host.find('/')
293    # set hostname to hold only a server name
294    if index != -1:
295       hostname = host[:index]
296    else :
297       hostname = host   
298
299    # checking only host
300    checkurl = __build_url(hostname, "")
301
302    # urllib2 is used since urllib doestn't offer a nice way to check the connection is valid
303    try :
304       urllib2.urlopen(checkurl)
305    # incorrect host name or host is dead
306    except urllib2.URLError, (msg):      
307       arizonareport.send_syslog(arizonareport.ERR, '__verify_connection(): "' + hostname + '" '+ str(msg).split("'")[1])
308       return False
309
310
311    # checking if a directory exists in the server
312    checkurl = __build_url(host, "")
313    try:
314       urllib2.urlopen(checkurl)
315    # if a directory doesn't exist in the server
316    except urllib2.HTTPError, (strerror):
317       arizonareport.send_syslog(arizonareport.ERR, '__verify_connection(): "' + str(strerror) + '" on the url "' + checkurl + '"')
318       return False
319
320    # everything is fine       
321    return True
322    
323
324
325
326 # TODO: should go away!!!
327 def valid_sl(stringlist):
328    """
329    <Purpose>
330       This returns True if stringlist is a list of strings or False if it is 
331       not.
332
333    <Arguments>
334       stringlist:
335           The variable to be checked.
336
337    <Exceptions>
338       None
339
340    <Side Effects>
341       None
342
343    <Returns>
344       True or False (see above)
345    """
346
347    # If it's a list
348    if isinstance(stringlist,list):
349
350       for item in stringlist:
351          # If an item in the list isn't a string then False
352          if not isinstance(item,str):
353             return False
354       else:
355          # It's a list of strings so True
356          return True
357    else:
358       # Not a list so false
359       return False
360
361