73a442b847b19f399c896b6f89025c7d3404d0f5
[rarslave2.git] / RarslaveDetector.py
1 #!/usr/bin/env python
2 # vim: set ts=4 sts=4 sw=4 textwidth=92:
3
4 """
5 Class which runs each detector in the PAR2Set classes, and attempts
6 to run all matches on the current set.
7 """
8
9 __author__    = "Ira W. Snyder (devel@irasnyder.com)"
10 __copyright__ = "Copyright (c) 2006, Ira W. Snyder (devel@irasnyder.com)"
11 __license__   = "GNU GPL v2 (or, at your option, any later version)"
12
13 #    RarslaveDetector.py
14 #
15 #    Copyright (C) 2006,2007  Ira W. Snyder (devel@irasnyder.com)
16 #
17 #    This program is free software; you can redistribute it and/or modify
18 #    it under the terms of the GNU General Public License as published by
19 #    the Free Software Foundation; either version 2 of the License, or
20 #    (at your option) any later version.
21 #
22 #    This program is distributed in the hope that it will be useful,
23 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
24 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 #    GNU General Public License for more details.
26 #
27 #    You should have received a copy of the GNU General Public License
28 #    along with this program; if not, write to the Free Software
29 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30
31 import rsutil.common
32
33 # PAR2Set-derived types
34 import PAR2Set.Join
35 import PAR2Set.ZIP
36 import PAR2Set.OldRAR
37 import PAR2Set.NewRAR
38 import PAR2Set.ExtractFirstOldRAR
39 import PAR2Set.ExtractFirstNewRAR
40 import PAR2Set.NoExtract
41
42 import logging
43
44 class RarslaveDetector (object):
45
46         """A class to detect the type of a set, and then run the appropriate class
47            on the set."""
48
49         # A tuple of tuples of the following type:
50         # (type_detection_function, type_working_class)
51         TYPES = (       (PAR2Set.Join.detector,   PAR2Set.Join.Join),
52                                 (PAR2Set.ZIP.detector,    PAR2Set.ZIP.ZIP),
53                                 (PAR2Set.OldRAR.detector, PAR2Set.OldRAR.OldRAR),
54                                 (PAR2Set.NewRAR.detector, PAR2Set.NewRAR.NewRAR),
55                                 (PAR2Set.ExtractFirstOldRAR.detector, PAR2Set.ExtractFirstOldRAR.ExtractFirstOldRAR),
56                                 (PAR2Set.ExtractFirstNewRAR.detector, PAR2Set.ExtractFirstNewRAR.ExtractFirstNewRAR),
57                                 (PAR2Set.NoExtract.detector, PAR2Set.NoExtract.NoExtract),
58                         )
59
60         def __init__ (self, dir, p2file):
61                 """Constructor
62
63                    dir -- the directory containing this set
64                    p2file -- a single PAR2 file from this set"""
65
66                 # The real "meat" of the class
67                 self.dir = dir
68                 self.p2file = p2file
69                 self.basename = rsutil.common.get_basename (p2file)
70
71                 # Find files that match by name only
72                 self.name_matched_files = rsutil.common.find_name_matches (self.dir, self.basename)
73
74                 # Find all par2 files for this set using name matches
75                 self.all_p2files = rsutil.common.find_par2_files (self.name_matched_files)
76
77                 # Try to get the protected files for this set
78                 self.prot_matched_files = rsutil.common.parse_all_par2 (self.dir, self.p2file, self.all_p2files)
79
80         def runMatchingTypes (self):
81                 """Run all matching PAR2Set types for which the detection function detects that
82                    the class is valid."""
83
84                 detected = False
85
86                 for (detector, classname) in self.TYPES:
87                         if detector (self.name_matched_files, self.prot_matched_files):
88                                 # The detector matched, so we're up and running!
89
90                                 p2set = classname (self.dir, self.p2file)
91
92                                 detected = True
93                                 logging.debug ('Detected type: %s' % p2set)
94
95                                 # Try to have rarslave do it's thing
96                                 ret = p2set.runAll ()
97
98                                 # If something already worked, there is no need to continue,
99                                 # since we've already finished!
100                                 if ret == rsutil.common.SUCCESS:
101                                         break
102                                 else:
103                                         logging.error ('Detected type (%s) failed for: %s' % (p2set,
104                                                         self.p2file))
105
106                 # Make sure we detected at least one valid type
107                 if not detected:
108                         logging.warning ('Unable to determine type: %s' % self.p2file)
109                         logging.debug ('The following information will help in writing a detector:')
110                         logging.debug ('name_matches: %s' % self.name_matched_files)
111                         logging.debug ('prot_matches: %s' % self.prot_matched_files)
112                         return -rsutil.common.EDETECT
113
114                 # Make sure that something worked
115                 if ret != rsutil.common.SUCCESS:
116                         logging.critical ('All types failed for: %s' % self.p2file)
117
118                 return ret
119
120 def main ():
121         pass
122
123 if __name__ == '__main__':
124         main ()
125