scripts/dtrx

branch
trunk
changeset 41
e3675644bbb6
parent 40
ee6a869f8da1
child 42
4a4cab75d5e6
equal deleted inserted replaced
40:ee6a869f8da1 41:e3675644bbb6
61 RECURSE_NOT_NOW = 3 61 RECURSE_NOT_NOW = 3
62 RECURSE_NEVER = 4 62 RECURSE_NEVER = 4
63 63
64 mimetypes.encodings_map.setdefault('.bz2', 'bzip2') 64 mimetypes.encodings_map.setdefault('.bz2', 'bzip2')
65 mimetypes.encodings_map.setdefault('.lzma', 'lzma') 65 mimetypes.encodings_map.setdefault('.lzma', 'lzma')
66 mimetypes.types_map.setdefault('.gem', 'x-ruby-gem') 66 mimetypes.types_map.setdefault('.gem', 'application/x-ruby-gem')
67 67
68 logger = logging.getLogger('dtrx-log') 68 logger = logging.getLogger('dtrx-log')
69 69
70 def run_command(command, description, stdout=None, stderr=None, stdin=None): 70 def run_command(command, description, stdout=None, stderr=None, stdin=None):
71 process = subprocess.Popen(command, stdin=stdin, stdout=stdout, 71 process = subprocess.Popen(command, stdin=stdin, stdout=stdout,
86 self.original_name = original_name 86 self.original_name = original_name
87 87
88 def is_free(self, filename): 88 def is_free(self, filename):
89 return not os.path.exists(filename) 89 return not os.path.exists(filename)
90 90
91 def create(self):
92 fd, filename = tempfile.mkstemp(prefix=self.original_name + '.',
93 dir='.')
94 os.close(fd)
95 return filename
96
91 def check(self): 97 def check(self):
98 if self.is_free(self.original_name):
99 return self.original_name
92 for suffix in [''] + ['.%s' % (x,) for x in range(1, 10)]: 100 for suffix in [''] + ['.%s' % (x,) for x in range(1, 10)]:
93 filename = '%s%s' % (self.original_name, suffix) 101 filename = '%s%s' % (self.original_name, suffix)
94 if self.is_free(filename): 102 if self.is_free(filename):
95 return filename 103 return filename
96 raise ValueError("all alternatives for name %s taken" % 104 return self.create()
97 (self.original_name,)) 105
98
99 106
100 class DirectoryChecker(FilenameChecker): 107 class DirectoryChecker(FilenameChecker):
101 def is_free(self, filename): 108 def is_free(self, filename):
102 try: 109 try:
103 os.mkdir(filename) 110 os.mkdir(filename)
104 except OSError, error: 111 except OSError, error:
105 if error.errno == errno.EEXIST: 112 if error.errno == errno.EEXIST:
106 return False 113 return False
107 raise 114 raise
108 return True 115 return True
116
117 def create(self):
118 return tempfile.mkdtemp(prefix=self.original_name + '.', dir='.')
109 119
110 120
111 class ExtractorError(Exception): 121 class ExtractorError(Exception):
112 pass 122 pass
113 123
139 149
140 def pipe(self, command, description="extraction"): 150 def pipe(self, command, description="extraction"):
141 self.pipes.append((command, description)) 151 self.pipes.append((command, description))
142 152
143 def run_pipes(self, final_stdout=None): 153 def run_pipes(self, final_stdout=None):
144 if final_stdout is None: 154 if not self.pipes:
155 return
156 elif final_stdout is None:
145 # FIXME: Buffering this might be dumb. 157 # FIXME: Buffering this might be dumb.
146 final_stdout = tempfile.TemporaryFile() 158 final_stdout = tempfile.TemporaryFile()
147 if not self.pipes:
148 return
149 num_pipes = len(self.pipes) 159 num_pipes = len(self.pipes)
150 last_pipe = num_pipes - 1 160 last_pipe = num_pipes - 1
151 processes = [] 161 processes = []
152 for index, command in enumerate([pipe[0] for pipe in self.pipes]): 162 for index, command in enumerate([pipe[0] for pipe in self.pipes]):
153 if index == 0: 163 if index == 0:
445 self.extractor.target]) 455 self.extractor.target])
446 if status != 0: 456 if status != 0:
447 return "%s returned with exit status %s" % (command, status) 457 return "%s returned with exit status %s" % (command, status)
448 return self.organize() 458 return self.organize()
449 459
460 def set_target(self, target, checker):
461 self.target = checker(target).check()
462 if self.target != target:
463 logger.warning("extracting %s to %s" %
464 (self.extractor.filename, self.target))
465
450 466
451 # The "where to extract" table, with options and archive types. 467 # The "where to extract" table, with options and archive types.
452 # This dictates the contents of each can_handle method. 468 # This dictates the contents of each can_handle method.
453 # 469 #
454 # Flat Overwrite None 470 # Flat Overwrite None
511 checker = FilenameChecker 527 checker = FilenameChecker
512 if self.options.one_entry_policy == EXTRACT_HERE: 528 if self.options.one_entry_policy == EXTRACT_HERE:
513 destination = self.extractor.content_name.rstrip('/') 529 destination = self.extractor.content_name.rstrip('/')
514 else: 530 else:
515 destination = self.extractor.basename() 531 destination = self.extractor.basename()
516 self.target = checker(destination).check() 532 self.set_target(destination, checker)
517 if os.path.isdir(self.extractor.target): 533 if os.path.isdir(self.extractor.target):
518 os.rename(source, self.target) 534 os.rename(source, self.target)
519 os.rmdir(self.extractor.target) 535 os.rmdir(self.extractor.target)
520 else: 536 else:
521 os.rename(self.extractor.target, self.target) 537 os.rename(self.extractor.target, self.target)
535 return True 551 return True
536 can_handle = staticmethod(can_handle) 552 can_handle = staticmethod(can_handle)
537 553
538 def organize(self): 554 def organize(self):
539 basename = self.extractor.basename() 555 basename = self.extractor.basename()
540 self.target = self.extractor.name_checker(basename).check() 556 self.set_target(basename, self.extractor.name_checker)
541 os.rename(self.extractor.target, self.target) 557 os.rename(self.extractor.target, self.target)
542 558
543 559
544 class BasePolicy(object): 560 class BasePolicy(object):
545 def __init__(self, options): 561 def __init__(self, options):

mercurial