2655320638d2558f33b19e7cca55c04610dda376
[htsworkflow.git] / uashelper / copier.py
1 import copy
2 import logging
3 import logging.handlers
4 import os
5 import re
6 import subprocess
7 import sys
8 import time
9 import traceback
10
11 from benderjab.bot import BenderFactory
12
13 class rsync(object):
14  
15   def __init__(self, pwfile):
16     self.pwfile = pwfile
17     self.cmd = ['/usr/bin/rsync', ]
18     self.cmd.append('--password-file=%s' % (pwfile))
19     self.source_base = 'rsync://sequencer@jumpgate.caltech.edu:8730/sequencer/'
20     self.dest_base = '/home/diane/gec/'
21     self.processes = {}
22     self.exit_code = None
23
24   def list(self):
25     """Get a directory listing"""
26     dirs_to_copy = []
27     args = copy.copy(self.cmd)
28     args.append(self.source_base)
29
30     logging.debug("Rsync cmd:" + " ".join(args))
31     short_process = subprocess.Popen(args, stdout=subprocess.PIPE)
32     direntries = [ x.split() for x in short_process.stdout ]
33     for permissions, size, filedate, filetime, filename in direntries:
34       if permissions[0] == 'd':
35         # hey its a directory, the first step to being something we want to 
36         # copy
37         if re.match("[0-9]{6}", filename):
38           # it starts with something that looks like a 6 digit date
39           # aka good enough for me
40           dirs_to_copy.append(filename)
41     return dirs_to_copy
42
43   def create_copy_process(self, dirname):
44     args = copy.copy(self.cmd)
45     # we want to copy everything
46     args.append('-rlt') 
47     # from here
48     args.append(os.path.join(self.source_base, dirname))
49     # to here
50     args.append(self.dest_base)
51     logging.debug("Rsync cmd:" + " ".join(args))
52     return subprocess.Popen(args)
53  
54   def copy(self):
55     """copy any interesting looking directories over
56     """
57     dirs_to_copy = self.list()
58     for d in dirs_to_copy:
59       process = self.processes.get(d, None)
60       if process is None:
61         # we don't have a process, so make one
62         logging.info("rsyncing %s" % (d))
63         self.processes[d] = self.create_copy_process(d)
64       else:
65         retcode = process.poll()
66         if retcode is not None:
67            # we finished
68            logging.info("finished rsyncing %s, exitcode %d" % (d, retcode))
69            del self.processes[d]
70
71 class copier_bot_parser(object):
72   def __init__(self, ):
73     self.rsync = rsync('/home/diane/.sequencer')
74   
75   def __call__(self, msg, who):
76     try:
77       if re.match("start copy", msg):
78         logging.info("starting copy for %s" % (who.getStripped()))
79         self.rsync.copy()
80     except Exception, e:
81       errmsg = "Exception: " + str(e)
82       logging.error(errmsg)
83       logging.error(traceback.format_exc())
84       return errmsg
85
86 def main(args=None):
87   if len(args) != 1:
88     print "need .benderjab config name"
89   configname = args[0]
90
91   logging.basicConfig(level=logging.INFO, 
92                       format='%(asctime)s %(levelname)s %(message)s')
93   log = logging.getLogger()
94   log.addHandler(logging.handlers.RotatingFileHandler(
95                    '/tmp/copier_bot.log', maxBytes=1000000, backupCount = 3)
96                 )
97   bot = BenderFactory(configname)
98   bot.parser = copier_bot_parser()
99   bot.logon()
100   bot.eventLoop()
101   logging.shutdown()
102   return 0
103
104 if __name__ == "__main__":
105   sys.exit(main(sys.argv[1:]))
106