Subversion Repositories programming

Rev

Rev 358 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
358 ira 1
################################################################################
2
# The PAR2 Classifier Module
3
#
4
# Copyright 2006, Ira W. Snyder (devel@irasnyder.com)
5
# License: GNU General Public License v2 (or, at your option, any later version)
6
#
7
# This class makes a best guess as to what type of set we're dealing
8
# with here. Of course, this is just a _GUESS_, but I hope it's pretty good.
9
#
10
# Future Improvements
11
# 1. Read a config file to get a few extra customizable types, which
12
#    will let you run an arbitrary command on a set of files that contains
13
#    a certain type of file
14
################################################################################
15
 
16
import os, re, sys
17
 
18
class Par2Classifier (object):
19
 
20
    def __init__ (self, Par2Parser):
21
        # Give this function a valid Par2Parser that has already
22
        # been run on your set of files. It will be used to figure
23
        # out the types that are in this set
24
 
25
        # An enum of types
26
        ( self.UNKNOWN_TYPE,     # Represents a type that we don't know about yet
27
 
28
          self.S_SPLIT_000,      # Single file protected,    LXSplit, starting with .000
29
          self.M_SPLIT_000,      # Multiple files protected, LXSplit, starting with .000
30
          self.S_SPLIT_001,      # Single file protected,    LXSplit, starting with .001
31
          self.M_SPLIT_001,      # Multiple files protected, LXSplit, starting with .001
32
 
33
          self.S_PROT_SPLIT_000, # All .DDD files protected, LXSplit, starting with .000 (single set)
34
          self.M_PROT_SPLIT_000, # All .DDD files protected, LXSplit, starting with .000 (multiple sets)
35
          self.S_PROT_SPLIT_001, # All .DDD files protected, LXSplit, starting with .001 (single set)
36
          self.M_PROT_SPLIT_001, # All .DDD files protected, LXSplit, starting with .001 (multiple sets)
37
 
38
          self.S_RAR_OLD,        # Single set of rars,   Old style,   starting with .rDD
39
          self.M_RAR_OLD,        # Multiple set of rars, Old style,   starting with .rDD
40
          self.S_RAR_NEW,        # Single set of rars,   New style,   starting with .partDD.rar
41
          self.M_RAR_NEW,        # Multiple set of rars, New style,   starting with .partDD.rar
42
 
43
        ) = range (13)      # WARNING: If adding types, increment this number appropriately
44
 
359 ira 45
        # Storage for regexes
46
        self.regexes = {
47
            self.UNKNOWN_TYPE : None,
48
 
49
            self.S_SPLIT_000 : '^.*\.000$',
50
            self.M_SPLIT_000 : '^.*\.000$',
51
            self.S_SPLIT_001 : '^.*\.001$',
52
            self.M_SPLIT_001 : '^.*\.001$',
358 ira 53
 
359 ira 54
            self.S_PROT_SPLIT_000 : '^.*\.000$',
55
            self.M_PROT_SPLIT_000 : '^.*\.000$',
56
            self.S_PROT_SPLIT_001 : '^.*\.001$',
57
            self.M_PROT_SPLIT_001 : '^.*\.001$',
58
 
59
            self.S_RAR_OLD : '^.*\.r00$',
60
            self.M_RAR_OLD : '^.*\.r00$',
61
            self.S_RAR_NEW : '^.*\.part0*1\.rar$',
62
            self.M_RAR_NEW : '^.*\.part0*1\.rar$',
63
        }
64
 
358 ira 65
        self.Par2Parser = Par2Parser
359 ira 66
        self.type = self.__get_type ()
67
        self.heads = self.__get_extractable_files ()
358 ira 68
 
69
    def __get_type (self):
70
        # This will return one of the enums above corresponding to the
71
        # best guess about what type of set we're trying to extract.
72
        #
73
        # This information will be used later to decide how to repair
74
        # and possibly extract this set of files
75
 
76
        matches = self.__apply_regex ('^.*\.000$', self.Par2Parser.protected_files)
77
 
78
        # Check to see if we've got a M_PROT_SPLIT_000 set
79
        if len (matches) > 1:
80
            return      self.M_PROT_SPLIT_000
81
 
82
        # Check to see if we've got a S_PROT_SPLIT_000 set
83
        if len (matches) == 1:
84
            return      self.S_PROT_SPLIT_000
85
 
86
        matches = self.__apply_regex ('^.*\.001$', self.Par2Parser.protected_files)
87
 
88
        # Check to see if we've got a M_PROT_SPLIT_001 set
89
        if len (matches) > 1:
90
            return      self.M_PROT_SPLIT_001
91
 
92
        # Check if we've got a S_PROT_SPLIT_001 set
93
        if len (matches) == 1:
94
            return      self.S_PROT_SPLIT_001
95
 
96
        matches = self.__apply_regex ('^.*\.000$', self.Par2Parser.possible_files)
97
 
98
        # Check if we've got a M_SPLIT_000 set
99
        if len (matches) > 1 and len (self.Par2Parser.protected_files) > 1:
100
            return      self.M_SPLIT_000
101
 
102
        # Check if we've got a S_SPLIT_000 set
103
        if len (matches) == 1 and len (self.Par2Parser.protected_files) == 1:
104
            return      self.S_SPLIT_000
105
 
106
        matches = self.__apply_regex ('^.*\.001$', self.Par2Parser.possible_files)
107
 
108
        # Check if we've got a M_SPLIT_001 set
109
        if len (matches) > 1 and len (self.Par2Parser.protected_files) > 1:
110
            return      self.M_SPLIT_001
111
 
112
        # Check if we've got a S_SPLIT_001 set
113
        if len (matches) == 1 and len (self.Par2Parser.protected_files) == 1:
114
            return      self.S_SPLIT_001
115
 
116
        matches = self.__apply_regex ('^.*\.part0*1\.rar$',
117
                                      self.Par2Parser.protected_files,
118
                                      ignorecase=True)
119
 
120
        # Check if we've got a M_RAR_NEW set
121
        if len (matches) > 1:
122
            return      self.M_RAR_NEW
123
 
124
        # Check if we've got a S_RAR_NEW set
125
        if len (matches) == 1:
126
            return      self.S_RAR_NEW
127
 
128
        matches = self.__apply_regex ('^.*\.r00$',
129
                                      self.Par2Parser.protected_files,
130
                                      ignorecase=True)
131
 
132
        # Check if we've got a M_RAR_OLD set
133
        if len (matches) > 1:
134
            return      self.M_RAR_OLD
135
 
136
        # Check if we've got a S_RAR_OLD set
137
        if len (matches) == 1:
138
            return      self.S_RAR_OLD
139
 
140
        return self.UNKNOWN_TYPE
141
 
142
    def __apply_regex (self, regex_str, li, ignorecase=False, search=False):
143
        """Runs the regex given through the list, and returns matches
144
           a list of things that either match() (the default) or search()"""
145
 
146
        # Decide whether or not to use re.IGNORECASE
147
        if ignorecase:
148
            regex = re.compile (regex_str, re.IGNORECASE)
149
        else:
150
            regex = re.compile (regex_str)
151
 
152
        # Decide whether to use re.search() or re.match()
153
        if search:
154
            return [i for i in li if regex.search (i)]
155
        else:
156
            return [i for i in li if regex.match (i)]
157
 
158
    def __get_extractable_files (self):
159
        # Returns a list of all of the "head" extractable files
160
        # NOTE: an extractable file is a .000, .001, .r00, .rar
161
        #       or whatever else makes sense for this type of set
162
        #
163
        if self.type == self.S_SPLIT_000 or self.type == self.M_SPLIT_000:
164
            return self.__apply_regex ('^.*\.000$', self.Par2Parser.possible_files)
165
 
166
        if self.type == self.S_SPLIT_001 or self.type == self.M_SPLIT_001:
167
            return self.__apply_regex ('^.*\.001$', self.Par2Parser.possible_files)
168
 
169
        if self.type == self.S_PROT_SPLIT_000 or self.type == self.M_PROT_SPLIT_000:
170
            return self.__apply_regex ('^.*\.000$', self.Par2Parser.protected_files)
171
 
172
        if self.type == self.S_PROT_SPLIT_001 or self.type == self.M_PROT_SPLIT_001:
173
            return self.__apply_regex ('^.*\.001$', self.Par2Parser.protected_files)
174
 
175
        if self.type == self.S_RAR_OLD or self.type == self.M_RAR_OLD:
176
            return self.__apply_regex ('^.*\.r00$', self.Par2Parser.protected_files,
177
                    ignorecase=True)
178
 
179
        if self.type == self.S_RAR_NEW or self.type == self.M_RAR_NEW:
180
            return self.__apply_regex ('^.*\.part0*1\.rar$', self.Par2Parser.protected_files,
181
                    ignorecase=True)
182
 
183
        return [] # Return nothing by default (this covers UNKNOWN_TYPE)
184
 
185
if __name__ == '__main__':
186
    pass