mkv-episode-matcher 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mkv-episode-matcher might be problematic. Click here for more details.

@@ -1 +1 @@
1
- version = "0.1.1"
1
+ version = "0.1.3"
@@ -0,0 +1 @@
1
+ gitdir: ../../.git/modules/libraries/pgs2srt
@@ -0,0 +1,2 @@
1
+ __pycache__/
2
+ .DS_Store
@@ -0,0 +1,295 @@
1
+ # MIT License
2
+ #
3
+ # Copyright (c) 2018 Hannes Tismer
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+ #
23
+ #
24
+ # Copyright for portions of project Sub-Zero are held by Bram Walet, 2014 as part of project Subliminal.bundle.
25
+ # The original license is supplied below.
26
+ #
27
+ # The MIT License (MIT)
28
+ #
29
+ # Copyright (c) 2014 Bram Walet
30
+ #
31
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
32
+ # of this software and associated documentation files (the "Software"), to deal
33
+ # in the Software without restriction, including without limitation the rights
34
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
+ # copies of the Software, and to permit persons to whom the Software is
36
+ # furnished to do so, subject to the following conditions:
37
+ #
38
+ # The above copyright notice and this permission notice shall be included in all
39
+ # copies or substantial portions of the Software.
40
+ #
41
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
47
+ # SOFTWARE.
48
+
49
+
50
+ class Processor:
51
+ """
52
+ Processor base class
53
+ """
54
+ name = None
55
+ parent = None
56
+ supported = None
57
+ enabled = True
58
+
59
+ def __init__(self, name=None, parent=None, supported=None, **kwargs):
60
+ self.name = name
61
+ self.parent = parent
62
+ self.supported = supported if supported else lambda parent: True
63
+
64
+ @property
65
+ def info(self):
66
+ return self.name
67
+
68
+ def process(self, content, debug=False, **kwargs):
69
+ return content
70
+
71
+ def __repr__(self):
72
+ return "Processor <%s %s>" % (self.__class__.__name__, self.info)
73
+
74
+ def __str__(self):
75
+ return repr(self)
76
+
77
+ # def __unicode__(self):
78
+ # return unicode(repr(self))
79
+
80
+
81
+ class ReProcessor(Processor):
82
+ """
83
+ Regex processor
84
+ """
85
+ pattern = None
86
+ replace_with = None
87
+
88
+ def __init__(self, pattern, replace_with, name=None, supported=None, entry=False, **kwargs):
89
+ super(ReProcessor, self).__init__(name=name, supported=supported)
90
+ self.pattern = pattern
91
+ self.replace_with = replace_with
92
+ self.use_entry = entry
93
+
94
+ def process(self, content, debug=False, entry=None, **kwargs):
95
+ if not self.use_entry:
96
+ return self.pattern.sub(self.replace_with, content)
97
+
98
+ ret = self.pattern.sub(self.replace_with, entry)
99
+ if not ret:
100
+ raise EmptyEntryError
101
+ elif ret != entry:
102
+ return ret
103
+ return content
104
+
105
+
106
+ class NReProcessor(ReProcessor):
107
+ pass
108
+
109
+
110
+ class MultipleWordReProcessor(ReProcessor):
111
+ """
112
+ Expects a dictionary in the form of:
113
+ dict = {
114
+ "data": {"old_value": "new_value"},
115
+ "pattern": compiled re object that matches data.keys()
116
+ }
117
+ replaces found key in pattern with the corresponding value in data
118
+ """
119
+ def __init__(self, snr_dict, name=None, parent=None, supported=None, **kwargs):
120
+ super(ReProcessor, self).__init__(name=name, supported=supported)
121
+ self.snr_dict = snr_dict
122
+
123
+ def process(self, content, debug=False, **kwargs):
124
+ if not self.snr_dict["data"]:
125
+ return content
126
+
127
+ return self.snr_dict["pattern"].sub(lambda x: self.snr_dict["data"][x.group(0)], content)
128
+
129
+
130
+ class EmptyEntryError(Exception):
131
+ pass
132
+
133
+
134
+ class SubtitleModification:
135
+ identifier = None
136
+ description = None
137
+ long_description = None
138
+ exclusive = False
139
+ advanced = False # has parameters
140
+ args_mergeable = False
141
+ order = None
142
+ modifies_whole_file = False # operates on the whole file, not individual entries
143
+ apply_last = False
144
+ only_uppercase = False
145
+ pre_processors = []
146
+ processors = []
147
+ post_processors = []
148
+ last_processors = []
149
+ languages = []
150
+
151
+ def __init__(self):
152
+ return
153
+
154
+ def _process(self, content, processors, debug=False, parent=None, index=None, **kwargs):
155
+ if not content:
156
+ return
157
+
158
+ # processors may be a list or a callable
159
+ # if callable(processors):
160
+ # _processors = processors()
161
+ # else:
162
+ # _processors = processors
163
+ _processors = processors
164
+
165
+ new_content = content
166
+ for processor in _processors:
167
+ if not processor.supported(parent):
168
+ if debug and processor.enabled:
169
+ # logger.debug("Processor not supported, skipping: %s", processor.name)
170
+ processor.enabled = False
171
+ continue
172
+
173
+ old_content = new_content
174
+ new_content = processor.process(new_content, debug=debug, **kwargs)
175
+ if not new_content:
176
+ # if debug:
177
+ # logger.debug("Processor returned empty line: %s", processor.name)
178
+ break
179
+ if debug:
180
+ if old_content == new_content:
181
+ continue
182
+ # logger.debug("%d: %s: %s -> %s", index, processor.name, repr(old_content), repr(new_content))
183
+
184
+ return new_content
185
+
186
+ def pre_process(self, content, debug=False, parent=None, **kwargs):
187
+ return self._process(content, self.pre_processors, debug=debug, parent=parent, **kwargs)
188
+
189
+ def process(self, content, debug=False, parent=None, **kwargs):
190
+ return self._process(content, self.processors, debug=debug, parent=parent, **kwargs)
191
+
192
+ def post_process(self, content, debug=False, parent=None, **kwargs):
193
+ return self._process(content, self.post_processors, debug=debug, parent=parent, **kwargs)
194
+
195
+ def modify(self, content, debug=False, parent=None, procs=None, **kwargs):
196
+ if not content:
197
+ return
198
+
199
+ new_content = content
200
+ for method in procs or ("pre_process", "process", "post_process"):
201
+ if not new_content:
202
+ return
203
+ new_content = self._process(new_content, getattr(self, "%sors" % method),
204
+ debug=debug, parent=parent, **kwargs)
205
+
206
+ return new_content
207
+
208
+ @classmethod
209
+ def get_signature(cls, **kwargs):
210
+ string_args = ",".join(["%s=%s" % (key, value) for key, value in kwargs.items()])
211
+ return "%s(%s)" % (cls.identifier, string_args)
212
+
213
+ @classmethod
214
+ def merge_args(cls, args1, args2):
215
+ raise NotImplementedError
216
+
217
+
218
+ class SubtitleTextModification(SubtitleModification):
219
+ pass
220
+
221
+
222
+ class StringProcessor(Processor):
223
+ """
224
+ String replacement processor base
225
+ """
226
+
227
+ def __init__(self, search, replace, name=None, parent=None, supported=None, **kwargs):
228
+ super(StringProcessor, self).__init__(name=name, supported=supported)
229
+ self.search = search
230
+ self.replace = replace
231
+
232
+ def process(self, content, debug=False, **kwargs):
233
+ return content.replace(self.search, self.replace)
234
+
235
+
236
+ class MultipleLineProcessor(Processor):
237
+ """
238
+ replaces stuff in whole lines
239
+
240
+ takes a search/replace dict as first argument
241
+ Expects a dictionary in the form of:
242
+ dict = {
243
+ "data": {"old_value": "new_value"}
244
+ }
245
+ """
246
+ def __init__(self, snr_dict, name=None, parent=None, supported=None, **kwargs):
247
+ super(MultipleLineProcessor, self).__init__(name=name, supported=supported)
248
+ self.snr_dict = snr_dict
249
+
250
+ def process(self, content, debug=False, **kwargs):
251
+ if not self.snr_dict["data"]:
252
+ return content
253
+
254
+ for key, value in self.snr_dict["data"].items():
255
+ # if debug and key in content:
256
+ # logger.debug(u"Replacing '%s' with '%s' in '%s'", key, value, content)
257
+
258
+ content = content.replace(key, value)
259
+
260
+ return content
261
+
262
+
263
+ class WholeLineProcessor(MultipleLineProcessor):
264
+ def process(self, content, debug=False, **kwargs):
265
+ if not self.snr_dict["data"]:
266
+ return content
267
+ content = content.strip()
268
+
269
+ for key, value in self.snr_dict["data"].items():
270
+ if content == key:
271
+ # if debug:
272
+ # logger.debug(u"Replacing '%s' with '%s'", key, value)
273
+
274
+ content = value
275
+ break
276
+
277
+ return content
278
+
279
+
280
+ class MultipleWordProcessor(MultipleLineProcessor):
281
+ """
282
+ replaces words
283
+ takes a search/replace dict as first argument
284
+ Expects a dictionary in the form of:
285
+ dict = {
286
+ "data": {"old_value": "new_value"}
287
+ }
288
+ """
289
+ def process(self, content, debug=False, **kwargs):
290
+ words = content.split(" ")
291
+ new_words = []
292
+ for word in words:
293
+ new_words.append(self.snr_dict.get(word, word))
294
+
295
+ return " ".join(new_words)