summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorjvoisin2011-06-10 01:29:29 +0200
committerjvoisin2011-06-10 01:29:29 +0200
commitc308cf7daaa4fa46377e2df0f2e9a397981e19b2 (patch)
treef016ce17cd6747acc068a7d2fc5093d1bd96fa9e /lib
parentf7082a21d6511c5069fbb9ff186ce22f3e22fed7 (diff)
The current version is (mostly) working
Diffstat (limited to 'lib')
-rw-r--r--lib/check/images/jpg.py17
-rw-r--r--lib/hachoir_editor/__init__.py8
-rw-r--r--lib/hachoir_editor/field.py69
-rw-r--r--lib/hachoir_editor/fieldset.py346
-rw-r--r--lib/hachoir_editor/typed_field.py253
-rw-r--r--lib/mat.py104
-rw-r--r--lib/strippers.py3
-rw-r--r--lib/test.py70
8 files changed, 0 insertions, 870 deletions
diff --git a/lib/check/images/jpg.py b/lib/check/images/jpg.py
deleted file mode 100644
index 7f29587..0000000
--- a/lib/check/images/jpg.py
+++ /dev/null
@@ -1,17 +0,0 @@
1import hachoir_core.error
2import hachoir_core.cmd_line
3import hachoir_parser
4import hachoir_metadata
5import sys
6import mat
7
8
9class JpegStripper(file):
10 def checkField(self, field):
11 print(field.description)
12 if field.name.startswith("comment"):
13 return True
14 return field.name in ("photoshop", "exif", "adobe")
15 return False
16
17
diff --git a/lib/hachoir_editor/__init__.py b/lib/hachoir_editor/__init__.py
deleted file mode 100644
index b106278..0000000
--- a/lib/hachoir_editor/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
1from hachoir_editor.field import (
2 EditorError, FakeField)
3from hachoir_editor.typed_field import (
4 EditableField, EditableBits, EditableBytes,
5 EditableInteger, EditableString,
6 createEditableField)
7from hachoir_editor.fieldset import EditableFieldSet, NewFieldSet, createEditor
8
diff --git a/lib/hachoir_editor/field.py b/lib/hachoir_editor/field.py
deleted file mode 100644
index 6b1efe3..0000000
--- a/lib/hachoir_editor/field.py
+++ /dev/null
@@ -1,69 +0,0 @@
1from hachoir_core.error import HachoirError
2from hachoir_core.field import joinPath, MissingField
3
4class EditorError(HachoirError):
5 pass
6
7class FakeField(object):
8 """
9 This class have API looks similar to Field API, but objects don't contain
10 any value: all values are _computed_ by parent methods.
11
12 Example: FakeField(editor, "abc").size calls editor._getFieldSize("abc").
13 """
14 is_field_set = False
15
16 def __init__(self, parent, name):
17 self._parent = parent
18 self._name = name
19
20 def _getPath(self):
21 return joinPath(self._parent.path, self._name)
22 path = property(_getPath)
23
24 def _getName(self):
25 return self._name
26 name = property(_getName)
27
28 def _getAddress(self):
29 return self._parent._getFieldAddress(self._name)
30 address = property(_getAddress)
31
32 def _getSize(self):
33 return self._parent.input[self._name].size
34 size = property(_getSize)
35
36 def _getValue(self):
37 return self._parent.input[self._name].value
38 value = property(_getValue)
39
40 def createDisplay(self):
41 # TODO: Returns new value if field is altered
42 return self._parent.input[self._name].display
43 display = property(createDisplay)
44
45 def _getParent(self):
46 return self._parent
47 parent = property(_getParent)
48
49 def hasValue(self):
50 return self._parent.input[self._name].hasValue()
51
52 def __getitem__(self, key):
53 # TODO: Implement this function!
54 raise MissingField(self, key)
55
56 def _isAltered(self):
57 return False
58 is_altered = property(_isAltered)
59
60 def writeInto(self, output):
61 size = self.size
62 addr = self._parent._getFieldInputAddress(self._name)
63 input = self._parent.input
64 stream = input.stream
65 if size % 8:
66 output.copyBitsFrom(stream, addr, size, input.endian)
67 else:
68 output.copyBytesFrom(stream, addr, size//8)
69
diff --git a/lib/hachoir_editor/fieldset.py b/lib/hachoir_editor/fieldset.py
deleted file mode 100644
index 1669b5a..0000000
--- a/lib/hachoir_editor/fieldset.py
+++ /dev/null
@@ -1,346 +0,0 @@
1from hachoir_core.dict import UniqKeyError
2from hachoir_core.field import MissingField, Float32, Float64, FakeArray
3from hachoir_core.compatibility import any
4from hachoir_core.i18n import _
5from hachoir_editor import createEditableField, EditorError
6from collections import deque # Python 2.4
7import weakref # Python 2.1
8import struct
9
10class EditableFieldSet(object):
11 MAX_SIZE = (1 << 40) # Arbitrary limit to catch errors
12 is_field_set = True
13
14 def __init__(self, parent, fieldset):
15 self._parent = parent
16 self.input = fieldset # original FieldSet
17 self._fields = {} # cache of editable fields
18 self._deleted = set() # Names of deleted fields
19 self._inserted = {} # Inserted field (name => list of field,
20 # where name is the name after)
21
22 def array(self, key):
23 # FIXME: Use cache?
24 return FakeArray(self, key)
25
26 def _getParent(self):
27 return self._parent
28 parent = property(_getParent)
29
30 def _isAltered(self):
31 if self._inserted:
32 return True
33 if self._deleted:
34 return True
35 return any(field.is_altered for field in self._fields.itervalues())
36 is_altered = property(_isAltered)
37
38 def reset(self):
39 """
40 Reset the field set and the input field set.
41 """
42 for key, field in self._fields.iteritems():
43 if not field.is_altered:
44 del self._fields[key]
45 self.input.reset()
46
47 def __len__(self):
48 return len(self.input) \
49 - len(self._deleted) \
50 + sum( len(new) for new in self._inserted.itervalues() )
51
52 def __iter__(self):
53 for field in self.input:
54 name = field.name
55 if name in self._inserted:
56 for newfield in self._inserted[name]:
57 yield weakref.proxy(newfield)
58 if name not in self._deleted:
59 yield self[name]
60 if None in self._inserted:
61 for newfield in self._inserted[None]:
62 yield weakref.proxy(newfield)
63
64 def insertBefore(self, name, *new_fields):
65 self._insert(name, new_fields, False)
66
67 def insertAfter(self, name, *new_fields):
68 self._insert(name, new_fields, True)
69
70 def insert(self, *new_fields):
71 self._insert(None, new_fields, True)
72
73 def _insert(self, key, new_fields, next):
74 """
75 key is the name of the field before which new_fields
76 will be inserted. If next is True, the fields will be inserted
77 _after_ this field.
78 """
79 # Set unique field name
80 for field in new_fields:
81 if field._name.endswith("[]"):
82 self.input.setUniqueFieldName(field)
83
84 # Check that there is no duplicate in inserted fields
85 new_names = list(field.name for field in new_fields)
86 names_set = set(new_names)
87 if len(names_set) != len(new_fields):
88 duplicates = (name for name in names_set if 1 < new_names.count(name))
89 raise UniqKeyError(_("Duplicates in inserted fields: %s") % ", ".join(duplicates))
90
91 # Check that field names are not in input
92 if self.input: # Write special version for NewFieldSet?
93 for name in new_names:
94 if name in self.input and name not in self._deleted:
95 raise UniqKeyError(_("Field name '%s' already exists") % name)
96
97 # Check that field names are not in inserted fields
98 for fields in self._inserted.itervalues():
99 for field in fields:
100 if field.name in new_names:
101 raise UniqKeyError(_("Field name '%s' already exists") % field.name)
102
103 # Input have already inserted field?
104 if key in self._inserted:
105 if next:
106 self._inserted[key].extend( reversed(new_fields) )
107 else:
108 self._inserted[key].extendleft( reversed(new_fields) )
109 return
110
111 # Whould like to insert in inserted fields?
112 if key:
113 for fields in self._inserted.itervalues():
114 names = [item.name for item in fields]
115 try:
116 pos = names.index(key)
117 except ValueError:
118 continue
119 if 0 <= pos:
120 if next:
121 pos += 1
122 fields.rotate(-pos)
123 fields.extendleft( reversed(new_fields) )
124 fields.rotate(pos)
125 return
126
127 # Get next field. Use None if we are at the end.
128 if next:
129 index = self.input[key].index + 1
130 try:
131 key = self.input[index].name
132 except IndexError:
133 key = None
134
135 # Check that field names are not in input
136 if key not in self.input:
137 raise MissingField(self, key)
138
139 # Insert in original input
140 self._inserted[key]= deque(new_fields)
141
142 def _getDescription(self):
143 return self.input.description
144 description = property(_getDescription)
145
146 def _getStream(self):
147 # FIXME: This property is maybe a bad idea since address may be differents
148 return self.input.stream
149 stream = property(_getStream)
150
151 def _getName(self):
152 return self.input.name
153 name = property(_getName)
154
155 def _getEndian(self):
156 return self.input.endian
157 endian = property(_getEndian)
158
159 def _getAddress(self):
160 if self._parent:
161 return self._parent._getFieldAddress(self.name)
162 else:
163 return 0
164 address = property(_getAddress)
165
166 def _getAbsoluteAddress(self):
167 address = self.address
168 current = self._parent
169 while current:
170 address += current.address
171 current = current._parent
172 return address
173 absolute_address = property(_getAbsoluteAddress)
174
175 def hasValue(self):
176 return False
177# return self._parent.input[self.name].hasValue()
178
179 def _getSize(self):
180 if self.is_altered:
181 return sum(field.size for field in self)
182 else:
183 return self.input.size
184 size = property(_getSize)
185
186 def _getPath(self):
187 return self.input.path
188 path = property(_getPath)
189
190 def _getOriginalField(self, name):
191 assert name in self.input
192 return self.input[name]
193
194 def _getFieldInputAddress(self, name):
195 """
196 Absolute address of a field from the input field set.
197 """
198 assert name in self.input
199 return self.input[name].absolute_address
200
201 def _getFieldAddress(self, name):
202 """
203 Compute relative address of a field. The operation takes care of
204 deleted and resized fields.
205 """
206 #assert name not in self._deleted
207 addr = 0
208 for field in self:
209 if field.name == name:
210 return addr
211 addr += field.size
212 raise MissingField(self, name)
213
214 def _getItemByPath(self, path):
215 if not path[0]:
216 path = path[1:]
217 field = self
218 for name in path:
219 field = field[name]
220 return field
221
222 def __contains__(self, name):
223 try:
224 field = self[name]
225 return (field is not None)
226 except MissingField:
227 return False
228
229 def __getitem__(self, key):
230 """
231 Create a weak reference to an editable field (EditableField) for the
232 field with specified name. If the field is removed later, using the
233 editable field will raise a weakref.ReferenceError exception.
234
235 May raise a MissingField error if the field doesn't exist in original
236 field set or it has been deleted.
237 """
238 if "/" in key:
239 return self._getItemByPath(key.split("/"))
240 if isinstance(key, (int, long)):
241 raise EditorError("Integer index are not supported")
242
243 if (key in self._deleted) or (key not in self.input):
244 raise MissingField(self, key)
245 if key not in self._fields:
246 field = self.input[key]
247 if field.is_field_set:
248 self._fields[key] = createEditableFieldSet(self, field)
249 else:
250 self._fields[key] = createEditableField(self, field)
251 return weakref.proxy(self._fields[key])
252
253 def __delitem__(self, name):
254 """
255 Remove a field from the field set. May raise an MissingField exception
256 if the field has already been deleted.
257 """
258 if name in self._deleted:
259 raise MissingField(self, name)
260 self._deleted.add(name)
261 if name in self._fields:
262 del self._fields[name]
263
264 def writeInto(self, output):
265 """
266 Write the content if this field set into the output stream
267 (OutputStream).
268 """
269 if not self.is_altered:
270 # Not altered: just copy bits/bytes
271 input = self.input
272 if input.size % 8:
273 output.copyBitsFrom(input.stream,
274 input.absolute_address, input.size, input.endian)
275 else:
276 output.copyBytesFrom(input.stream,
277 input.absolute_address, input.size//8)
278 else:
279 # Altered: call writeInto() method of each field
280 realaddr = 0
281 for field in self:
282 field.writeInto(output)
283 realaddr += field.size
284
285 def _getValue(self):
286 raise EditorError('Field set "%s" has no value' % self.path)
287 def _setValue(self, value):
288 raise EditorError('Field set "%s" value is read only' % self.path)
289 value = property(_getValue, _setValue, "Value of field")
290
291class EditableFloat(EditableFieldSet):
292 _value = None
293
294 def _isAltered(self):
295 return (self._value is not None)
296 is_altered = property(_isAltered)
297
298 def writeInto(self, output):
299 if self._value is not None:
300 self._write(output)
301 else:
302 EditableFieldSet.writeInto(self, output)
303
304 def _write(self, output):
305 format = self.input.struct_format
306 raw = struct.pack(format, self._value)
307 output.writeBytes(raw)
308
309 def _setValue(self, value):
310 self.parent._is_altered = True
311 self._value = value
312 value = property(EditableFieldSet._getValue, _setValue)
313
314def createEditableFieldSet(parent, field):
315 cls = field.__class__
316 # FIXME: Support Float80
317 if cls in (Float32, Float64):
318 return EditableFloat(parent, field)
319 else:
320 return EditableFieldSet(parent, field)
321
322class NewFieldSet(EditableFieldSet):
323 def __init__(self, parent, name):
324 EditableFieldSet.__init__(self, parent, None)
325 self._name = name
326 self._endian = parent.endian
327
328 def __iter__(self):
329 if None in self._inserted:
330 return iter(self._inserted[None])
331 else:
332 raise StopIteration()
333
334 def _getName(self):
335 return self._name
336 name = property(_getName)
337
338 def _getEndian(self):
339 return self._endian
340 endian = property(_getEndian)
341
342 is_altered = property(lambda self: True)
343
344def createEditor(fieldset):
345 return EditableFieldSet(None, fieldset)
346
diff --git a/lib/hachoir_editor/typed_field.py b/lib/hachoir_editor/typed_field.py
deleted file mode 100644
index 4abc989..0000000
--- a/lib/hachoir_editor/typed_field.py
+++ /dev/null
@@ -1,253 +0,0 @@
1from hachoir_core.field import (
2 RawBits, Bit, Bits, PaddingBits,
3 RawBytes, Bytes, PaddingBytes,
4 GenericString, Character,
5 isInteger, isString)
6from hachoir_editor import FakeField
7
8class EditableField(FakeField):
9 """
10 Pure virtual class used to write editable field class.
11 """
12
13 _is_altered = False
14 def __init__(self, parent, name, value=None):
15 FakeField.__init__(self, parent, name)
16 self._value = value
17
18 def _isAltered(self):
19 return self._is_altered
20 is_altered = property(_isAltered)
21
22 def hasValue(self):
23 return True
24
25 def _computeSize(self):
26 raise NotImplementedError()
27 def _getValue(self):
28 return self._value
29 def _setValue(self, value):
30 self._value = value
31
32 def _propGetValue(self):
33 if self._value is not None:
34 return self._getValue()
35 else:
36 return FakeField._getValue(self)
37 def _propSetValue(self, value):
38 self._setValue(value)
39 self._is_altered = True
40 value = property(_propGetValue, _propSetValue)
41
42 def _getSize(self):
43 if self._value is not None:
44 return self._computeSize()
45 else:
46 return FakeField._getSize(self)
47 size = property(_getSize)
48
49 def _write(self, output):
50 raise NotImplementedError()
51
52 def writeInto(self, output):
53 if self._is_altered:
54 self._write(output)
55 else:
56 return FakeField.writeInto(self, output)
57
58class EditableFixedField(EditableField):
59 """
60 Editable field with fixed size.
61 """
62
63 def __init__(self, parent, name, value=None, size=None):
64 EditableField.__init__(self, parent, name, value)
65 if size is not None:
66 self._size = size
67 else:
68 self._size = self._parent._getOriginalField(self._name).size
69
70 def _getSize(self):
71 return self._size
72 size = property(_getSize)
73
74class EditableBits(EditableFixedField):
75 def __init__(self, parent, name, *args):
76 if args:
77 if len(args) != 2:
78 raise TypeError(
79 "Wrong argument count, EditableBits constructor prototype is: "
80 "(parent, name, [size, value])")
81 size = args[0]
82 value = args[1]
83 assert isinstance(value, (int, long))
84 else:
85 size = None
86 value = None
87 EditableFixedField.__init__(self, parent, name, value, size)
88 if args:
89 self._setValue(args[1])
90 self._is_altered = True
91
92 def _setValue(self, value):
93 if not(0 <= value < (1 << self._size)):
94 raise ValueError("Invalid value, must be in range %s..%s"
95 % (0, (1 << self._size) - 1))
96 self._value = value
97
98 def _write(self, output):
99 output.writeBits(self._size, self._value, self._parent.endian)
100
101class EditableBytes(EditableField):
102 def _setValue(self, value):
103 if not value: raise ValueError(
104 "Unable to set empty string to a EditableBytes field")
105 self._value = value
106
107 def _computeSize(self):
108 return len(self._value) * 8
109
110 def _write(self, output):
111 output.writeBytes(self._value)
112
113class EditableString(EditableField):
114 MAX_SIZE = {
115 "Pascal8": (1 << 8)-1,
116 "Pascal16": (1 << 16)-1,
117 "Pascal32": (1 << 32)-1,
118 }
119
120 def __init__(self, parent, name, *args, **kw):
121 if len(args) == 2:
122 value = args[1]
123 assert isinstance(value, str) # TODO: support Unicode
124 elif not args:
125 value = None
126 else:
127 raise TypeError(
128 "Wrong argument count, EditableString constructor prototype is:"
129 "(parent, name, [format, value])")
130 EditableField.__init__(self, parent, name, value)
131 if len(args) == 2:
132 self._charset = kw.get('charset', None)
133 self._format = args[0]
134 if self._format in GenericString.PASCAL_FORMATS:
135 self._prefix_size = GenericString.PASCAL_FORMATS[self._format]
136 else:
137 self._prefix_size = 0
138 self._suffix_str = GenericString.staticSuffixStr(
139 self._format, self._charset, self._parent.endian)
140 self._is_altered = True
141 else:
142 orig = self._parent._getOriginalField(name)
143 self._charset = orig.charset
144 self._format = orig.format
145 self._prefix_size = orig.content_offset
146 self._suffix_str = orig.suffix_str
147
148 def _setValue(self, value):
149 size = len(value)
150 if self._format in self.MAX_SIZE and self.MAX_SIZE[self._format] < size:
151 raise ValueError("String is too big")
152 self._value = value
153
154 def _computeSize(self):
155 return (self._prefix_size + len(self._value) + len(self._suffix_str))*8
156
157 def _write(self, output):
158 if self._format in GenericString.SUFFIX_FORMAT:
159 output.writeBytes(self._value)
160 output.writeBytes(self._suffix_str)
161 elif self._format == "fixed":
162 output.writeBytes(self._value)
163 else:
164 assert self._format in GenericString.PASCAL_FORMATS
165 size = GenericString.PASCAL_FORMATS[self._format]
166 output.writeInteger(len(self._value), False, size, self._parent.endian)
167 output.writeBytes(self._value)
168
169class EditableCharacter(EditableFixedField):
170 def __init__(self, parent, name, *args):
171 if args:
172 if len(args) != 3:
173 raise TypeError(
174 "Wrong argument count, EditableCharacter "
175 "constructor prototype is: (parent, name, [value])")
176 value = args[0]
177 if not isinstance(value, str) or len(value) != 1:
178 raise TypeError("EditableCharacter needs a character")
179 else:
180 value = None
181 EditableFixedField.__init__(self, parent, name, value, 8)
182 if args:
183 self._is_altered = True
184
185 def _setValue(self, value):
186 if not isinstance(value, str) or len(value) != 1:
187 raise TypeError("EditableCharacter needs a character")
188 self._value = value
189
190 def _write(self, output):
191 output.writeBytes(self._value)
192
193class EditableInteger(EditableFixedField):
194 VALID_VALUE_SIGNED = {
195 8: (-(1 << 8), (1 << 8)-1),
196 16: (-(1 << 15), (1 << 15)-1),
197 32: (-(1 << 31), (1 << 31)-1),
198 }
199 VALID_VALUE_UNSIGNED = {
200 8: (0, (1 << 8)-1),
201 16: (0, (1 << 16)-1),
202 32: (0, (1 << 32)-1)
203 }
204
205 def __init__(self, parent, name, *args):
206 if args:
207 if len(args) != 3:
208 raise TypeError(
209 "Wrong argument count, EditableInteger constructor prototype is: "
210 "(parent, name, [signed, size, value])")
211 size = args[1]
212 value = args[2]
213 assert isinstance(value, (int, long))
214 else:
215 size = None
216 value = None
217 EditableFixedField.__init__(self, parent, name, value, size)
218 if args:
219 self._signed = args[0]
220 self._is_altered = True
221 else:
222 self._signed = self._parent._getOriginalField(self._name).signed
223
224 def _setValue(self, value):
225 if self._signed:
226 valid = self.VALID_VALUE_SIGNED
227 else:
228 valid = self.VALID_VALUE_UNSIGNED
229 minval, maxval = valid[self._size]
230 if not(minval <= value <= maxval):
231 raise ValueError("Invalid value, must be in range %s..%s"
232 % (minval, maxval))
233 self._value = value
234
235 def _write(self, output):
236 output.writeInteger(
237 self.value, self._signed, self._size//8, self._parent.endian)
238
239def createEditableField(fieldset, field):
240 if isInteger(field):
241 cls = EditableInteger
242 elif isString(field):
243 cls = EditableString
244 elif field.__class__ in (RawBytes, Bytes, PaddingBytes):
245 cls = EditableBytes
246 elif field.__class__ in (RawBits, Bits, Bit, PaddingBits):
247 cls = EditableBits
248 elif field.__class__ == Character:
249 cls = EditableCharacter
250 else:
251 cls = FakeField
252 return cls(fieldset, field.name)
253
diff --git a/lib/mat.py b/lib/mat.py
deleted file mode 100644
index d22c9ab..0000000
--- a/lib/mat.py
+++ /dev/null
@@ -1,104 +0,0 @@
1import hachoir_core.error
2import hachoir_core.cmd_line
3import hachoir_parser
4import hachoir_metadata
5
6from strippers import *
7
8from hachoir_editor import (createEditor,
9 NewFieldSet, EditableInteger, EditableBytes)
10
11import hachoir_editor
12
13import sys
14
15__version__ = "0.1"
16__author__ = "jvoisin"
17
18
19class file():
20 def __init__(self, filename):
21 self.metadata = {}
22 self.clean = False
23 self.editor = createEditor(self.parser)
24 self.filename = filename
25 self.filename, self.realname = hachoir_core.cmd_line.unicodeFilename(
26 self.filename), self.filename
27 self.parser = hachoir_parser.createParser(self.filename, self.realname)
28
29 if not self.parser:
30 print("Unable to parse file : sorry")
31 sys.exit(1)
32
33 try:
34 self.meta = hachoir_metadata.extractMetadata(self.parser)
35 except hachoir_core.error.HachoirError, err:
36 print "Metadata extraction error: %s" % unicode(err)
37 self.data = None
38
39 if not self.meta:
40 print "Unable to extract metadata"
41 sys.exit(1)
42
43 def is_clean(self):
44 '''
45 Return true if the file is clean from any compromizing meta
46 '''
47 return self.clean
48
49 def remove_all(self):
50 '''
51 Remove all the files that are compromizing
52 '''
53 stripEditor(self.editor, self.realname, level, not(values.quiet))
54 for key, field in metadata:
55 if should_remove(key):
56 remove(self, key)
57
58 def remove(self, field):
59 '''
60 Remove the given file
61 '''
62 del editor[field]
63 return True
64
65
66 def get_meta(self):
67 '''return a dict with all the meta of the file'''
68 #FIXME : sooooooooooo dirty !
69 for title in self.meta:
70 if title.values != []: #if the field is not empty
71 value = ""
72 for item in title.values:
73 value = item.text
74 self.metadata[title.key] = value
75 return self.metadata
76
77 def should_remove(self, field):
78 '''
79 return True if the field is compromizing
80 abstract method
81 '''
82 raise NotImplementedError()
83
84def stripEditor(editor, filename, realname, level, verbose):
85 '''
86 Assign a stripper to an editor
87 '''
88 cls = editor.input.__class__
89 try:
90 stripper_cls = strippers[cls]
91 except KeyError:
92 print "Don't have stripper for file type: %s" % editor.description
93 return False
94 stripper = stripper_cls(editor, level, verbose)
95
96 if stripper():
97 output = FileOutputStream(filename, realname)
98 editor.writeInto(output)
99
100 else:
101 print _("Stripper doesn't touch the file")
102 return True
103
104file(sys.argv[1]).get_meta()
diff --git a/lib/strippers.py b/lib/strippers.py
deleted file mode 100644
index 70d0fc7..0000000
--- a/lib/strippers.py
+++ /dev/null
@@ -1,3 +0,0 @@
1strippers = {
2 JpegFile: JpegStripper,
3}
diff --git a/lib/test.py b/lib/test.py
deleted file mode 100644
index b1ff2a3..0000000
--- a/lib/test.py
+++ /dev/null
@@ -1,70 +0,0 @@
1import mat
2import unittest
3import shutil
4import glob
5import tempfile
6
7FILE_LIST = zip(glob.glob('clean*'), glob.glob('dirty*'))
8
9class MATTest(unittest.TestCase):
10 def setUp(self):
11 '''create working copy of the clean and the dirty file in the TMP dir'''
12 self.file_list = []
13 self.tmpdir = tempfile.mkdtemp()
14
15 for clean, dirty in FILE_LIST:
16 shutil.copy2(clean, self.tmpdir + clean)
17 shutil.copy2(dirty, self.tmpdir + dirty)
18 self.file_list.append((self.tmpdir + clean, self.tmpdir + dirty))
19
20 def tearDown(self):
21 '''Remove the tmp folder'''
22 shutil.rmtree(self.tmpdir)
23
24class Test_Remove(MATTest):
25 def test_remove(self):
26 '''make sure that the lib remove all compromizing meta'''
27 for clean, dirty in self.file_list:
28 mat.file(dirty).remove_all()
29 self.assertTrue(mat.file(dirty).is_clean())
30
31 def test_remove_empty(self):
32 '''Test removal with clean files'''
33 for clean, dirty in self.file_list:
34 mat.file(clean).remove_all()
35 self.assertTrue(mat.file(clean).is_clean())
36
37
38class Test_List(MATTest):
39 def test_list(self):
40 '''check if get_meta returns all the expected meta'''
41 for clean, dirty in self.file_list:
42 meta_list = dict() #FIXME
43 self.assertDictEqual(mat.file(dirty).get_meta(), meta_list)
44
45 def testlist_list_empty(self):
46 '''check that a listing of a clean file return an empty dict'''
47 for clean, dirty in self.file_list:
48 self.assertEqual(mat.file(clean).get_meta(), None)
49
50
51class Test_isClean(MATTest):
52 def test_clean(self):
53 '''test is_clean on clean files'''
54 for clean, dirty in self.file_list:
55 print "e"
56 self.assertTrue(mat.file(clean).is_clean())
57
58 def test_clean(self):
59 '''test is_clean on dirty files'''
60 for clean, dirty in self.file_list:
61 self.assertFalse(mat.file(dirty).is_clean())
62
63
64if __name__ == '__main__':
65 suite = unittest.TestSuite()
66 suite.addTest(unittest.makeSuite(Test_Remove))
67 suite.addTest(unittest.makeSuite(Test_List))
68 suite.addTest(unittest.makeSuite(Test_isClean))
69 unittest.TextTestRunner(verbosity=2).run(suite)
70