def __call__(self, prev): name = self.path + "[]" address, size, last = next(self.cluster) if self.filesize: if self.done >= self.filesize: error("(FAT) bad metadata for " + self.path) return field = File(self.root, name, size=size) if prev.first is None: field._description = 'File size: %s' % humanFilesize( self.filesize // 8) field.setSubIStream(self.createInputStream) field.datasize = min(self.filesize - self.done, size) self.done += field.datasize else: field = Directory(self.root, name, size=size) padding = self.root.getFieldByAddress(address, feed=False) if not isinstance(padding, (PaddingBytes, RawBytes)): error("(FAT) address %u doesn't point to a padding field" % address) return if last: link_next = None else: def link_next(): return self(field) field.setLinks(prev.first, link_next) self.root.writeFieldsIn(padding, address, (field, )) return field
def extractMetadata(parser, quality=QUALITY_NORMAL, **kwargs): """ Create a Metadata class from a parser. Returns None if no metadata extractor does exist for the parser class. """ try: extractor = extractors[parser.__class__] except KeyError: return None metadata = extractor(quality) meta_extract_error = True try: if 'scan_index' in kwargs: metadata.extract(parser, scan_index=kwargs['scan_index']) else: metadata.extract(parser) meta_extract_error = False except (BaseException, Exception) as err: error("Error during metadata extraction: %s" % str(err)) if meta_extract_error: try: # noinspection PyProtectedMember parser.stream._input.close() except (BaseException, Exception): pass return None if metadata: metadata.mime_type = parser.mime_type metadata.endian = endian_name[parser.endian] return metadata
def _getContentSize(self): if not hasattr(self, "_content_size"): try: self._content_size = self.createContentSize() except Exception as err: error("Unable to compute %s content size: %s" % (self.__class__.__name__, err)) self._content_size = None return self._content_size
def _getDescription(self): if self._description is None: try: self._description = self.createDescription() if isinstance(self._description, str): self._description = makeUnicode(self._description) except Exception as err: error("Error getting description of %s: %s" % (self.path, str(err))) self._description = self.PARSER_TAGS["description"] return self._description
def _getMimeType(self): if not self._mime_type: try: self._mime_type = self.createMimeType() except Exception as err: error("Error when creating MIME type: %s" % str(err)) if not self._mime_type \ and self.createMimeType != Parser.createMimeType: self._mime_type = Parser.createMimeType(self) if not self._mime_type: self._mime_type = "application/octet-stream" return self._mime_type
def writeFile(self, filename, stream, offset, size): # Create directory (only on first call) if not self.mkdir: self.createDirectory() self.mkdir = True # Create output file filename = path.join(self.directory, filename) output = FileOutputStream(filename) # Write output try: output.copyBytesFrom(stream, offset, size // 8) except StreamError as err: error("copyBytesFrom() error: %s" % err) return filename
def add(self, parser): tags = parser.getParserTags() err = self.validParser(parser, tags) if err: error("Skip parser %s: %s" % (parser.__name__, err)) return _tags = [] for tag in tags.items(): tag = self.translate(*tag) if isinstance(tag, tuple): _tags.append(tag) elif tag is not True: error("[%s] %s" % (parser.__name__, tag)) return self.parser_list.append(parser) for name, values in _tags: byname = self.bytag.setdefault(name, {}) for value in values: byname.setdefault(value, []).append(parser)
def processFile(values, filename, display_filename=False, priority=None, human=True, display=True): charset = getTerminalCharset() # Create parser try: if values.force_parser: tags = [("id", values.force_parser), None] else: tags = None parser = createParser(filename, tags=tags) except InputStreamError as err: error(str(err)) return False if not parser: error("Unable to parse file: %s" % filename) return False with parser: # Extract metadata extract_metadata = not (values.mime or values.type) if extract_metadata: try: metadata = extractMetadata(parser, values.quality) except Exception as err: error(str(err)) metadata = None if not metadata: parser.error( "Hachoir can't extract metadata, but is able to parse: %s" % filename) return False else: if values.type: result = parser.description else: result = parser.mime_type if display: # Display metadatas on stdout if extract_metadata: text = metadata.exportPlaintext(priority=priority, human=human) if not text: text = ["(no metadata, priority may be too small)"] if display_filename: for line in text: line = "%s: %s" % (filename, line) print(makePrintable(line, charset)) else: for line in text: print(makePrintable(line, charset)) else: text = result if display_filename: text = "%s: %s" % (filename, text) print(text) return True