Beispiel #1
0
 def createFields(self):
     addr = self.absolute_address
     len = self.stream.searchBytesLength(b':', False, addr,
                                         addr + (MAX_STRING_LENGTH + 1) * 8)
     if len is None:
         raise ParserError("Torrent: unable to find string separator (':')")
     if not len:
         raise ParserError("Torrent: error: no string length!")
     val = String(self, "length", len, "String length")
     yield val
     try:
         len = int(val.value)
     except ValueError:
         len = -1
     if len < 0:
         raise ParserError("Invalid string length (%s)" %
                           makePrintable(val.value, "ASCII"))
     yield String(self, "separator", 1, "String length/value separator")
     if not len:
         self.info("Empty string: len=%i" % len)
         return
     if len < 512:
         yield String(self,
                      "value",
                      len,
                      "String value",
                      charset="ISO-8859-1")
     else:
         # Probably raw data
         yield RawBytes(self, "value", len, "Raw data")
Beispiel #2
0
 def _createDisplay(self, human):
     max_bytes = config.max_byte_length
     try:
         display = makePrintable(self.value[:max_bytes], "ASCII")
     except Exception:
         if self._display is None:
             address = self.absolute_address
             length = min(self._size // 8, max_bytes)
             self._display = self._parent.stream.readBytes(address, length)
         display = makePrintable(self._display, "ASCII")
     truncated = (8 * len(display) < self._size)
     if human:
         if truncated:
             display += "(...)"
         return makePrintable(display, "latin-1", quote='"')
     else:
         if truncated:
             return '"%s(...)"' % display
         else:
             return '"%s"' % display
Beispiel #3
0
 def __init__(self, parent, name, length, decompressor, description=None,
              parser=None, filename=None, mime_type=None, parser_class=None):
     if filename:
         if not isinstance(filename, str):
             filename = makePrintable(filename, "ISO-8859-1")
         if not description:
             description = 'File "%s" (%s)' % (
                 filename, humanFilesize(length))
     Bytes.__init__(self, parent, name, length, description)
     self.setupInputStream(decompressor, parser,
                           filename, mime_type, parser_class)
Beispiel #4
0
 def getFilename(self):
     name = self["name"].value
     if isinstance(name, str):
         name = makePrintable(name, "ASCII")
     ext = self["ext"].value
     if ext:
         name += "." + ext
     if name[0] == 5:
         name = "\xE5" + name[1:]
     if not self.LFN and self["directory"].value:
         name += "/"
     return name
Beispiel #5
0
    def processFile(self, filename):
        print("[%s] Process file %s..." % (self.total, filename))
        parser = createParser(filename)
        if not parser:
            print("Unable to parse file", file=stderr)
            return None
        try:
            metadata = extractMetadata(parser)
        except Exception as err:
            print("Metadata extraction error: %s" % str(err), file=stderr)
            return None
        if not metadata:
            print("Unable to extract metadata", file=stderr)
            return None

        filename = makePrintable(filename, self.charset)
        line = [filename]
        for field in self.fields:
            value = metadata.getText(field, '')
            value = makePrintable(value, self.charset)
            line.append(value)
        return '; '.join(line)
Beispiel #6
0
    def description(self):
        """str: Informal description of this field. Cached.

        The description of a field may provide a general summary of its usage
        or for field sets it can be used to give a short indication of the
        contents without having to expand the node.
        """
        if self._description is None:
            try:
                self._description = self.createDescription()
                if isinstance(self._description, str):
                    self._description = makePrintable(
                        self._description, "ISO-8859-1")
            except Exception as err:
                self.error("Error getting description: " + str(err))
                self._description = ""
        return self._description
Beispiel #7
0
    def processID3v2(self, field):
        # Read value
        if "content" not in field:
            return
        content = field["content"]
        if "text" not in content:
            return
        if "title" in content and content["title"].value:
            value = "%s: %s" % (content["title"].value, content["text"].value)
        else:
            value = content["text"].value

        # Known tag?
        tag = field["tag"].value
        if tag not in self.TAG_TO_KEY:
            if tag:
                if isinstance(tag, str):
                    tag = makePrintable(tag, "ISO-8859-1")
                self.warning("Skip ID3v2 tag %s: %s" % (tag, value))
            return
        key = self.TAG_TO_KEY[tag]
        setattr(self, key, value)
Beispiel #8
0
    def __init__(self, parent, name, length, description=None,
                 parser=None, filename=None, mime_type=None, parser_class=None):
        if filename:
            if not isinstance(filename, str):
                filename = makePrintable(filename, "ISO-8859-1")
            if not description:
                description = 'File "%s" (%s)' % (
                    filename, humanFilesize(length))
        Bytes.__init__(self, parent, name, length, description)

        def createInputStream(cis, **args):
            tags = args.setdefault("tags", [])
            if parser_class:
                tags.append(("class", parser_class))
            if parser is not None:
                tags.append(("id", parser.PARSER_TAGS["id"]))
            if mime_type:
                tags.append(("mime", mime_type))
            if filename:
                tags.append(("filename", filename))
            return cis(**args)
        self.setSubIStream(createInputStream)
Beispiel #9
0
 def __str__(self):
     return makePrintable(str(self.regex), 'ASCII')
Beispiel #10
0
 def __str__(self):
     return makePrintable(self.text, 'ASCII')
Beispiel #11
0
 def __repr__(self, **kw):
     regex = self.__str__(**kw)
     regex = makePrintable(regex, 'ASCII')
     return "<%s '%s'>" % (self.__class__.__name__, regex)
Beispiel #12
0
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
Beispiel #13
0
 def createDisplay(self):
     return makePrintable(self.value, "UTF-8", quote='"')
Beispiel #14
0
 def createDisplay(self):
     return makePrintable(self.value, "ASCII", quote="'")
Beispiel #15
0
 def createDisplay(self):
     if self._display_pattern:
         return "<padding pattern=%s>" % makePrintable(
             self.pattern, "ASCII", quote="'")
     else:
         return Bytes.createDisplay(self)
Beispiel #16
0
    def processHeader(self, header):
        compression = []
        is_vbr = None

        if "ext_desc/content" in header:
            # Extract all data from ext_desc
            data = {}
            for desc in header.array("ext_desc/content/descriptor"):
                self.useExtDescItem(desc, data)

            # Have ToolName and ToolVersion? If yes, group them to producer key
            if "ToolName" in data and "ToolVersion" in data:
                self.producer = "%s (version %s)" % (data["ToolName"],
                                                     data["ToolVersion"])
                del data["ToolName"]
                del data["ToolVersion"]

            # "IsVBR" key
            if "IsVBR" in data:
                is_vbr = (data["IsVBR"] == 1)
                del data["IsVBR"]

            # Store data
            for key, value in data.items():
                if key in self.EXT_DESC_TO_ATTR:
                    key = self.EXT_DESC_TO_ATTR[key]
                else:
                    if isinstance(key, str):
                        key = makePrintable(key, "ISO-8859-1")
                    value = "%s=%s" % (key, value)
                    key = "comment"
                setattr(self, key, value)

        if "file_prop/content" in header:
            self.useFileProp(header["file_prop/content"], is_vbr)

        if "codec_list/content" in header:
            for codec in header.array("codec_list/content/codec"):
                if "name" in codec:
                    text = codec["name"].value
                    if "desc" in codec and codec["desc"].value:
                        text = "%s (%s)" % (text, codec["desc"].value)
                    compression.append(text)

        audio_index = 1
        video_index = 1
        for index, stream_prop in enumerate(header.array("stream_prop")):
            if "content/audio_header" in stream_prop:
                meta = Metadata(self)
                self.streamProperty(header, index, meta)
                self.streamAudioHeader(stream_prop["content/audio_header"],
                                       meta)
                if self.addGroup("audio[%u]" % audio_index, meta,
                                 "Audio stream #%u" % audio_index):
                    audio_index += 1
            elif "content/video_header" in stream_prop:
                meta = Metadata(self)
                self.streamProperty(header, index, meta)
                self.streamVideoHeader(stream_prop["content/video_header"],
                                       meta)
                if self.addGroup("video[%u]" % video_index, meta,
                                 "Video stream #%u" % video_index):
                    video_index += 1

        if "metadata/content" in header:
            info = header["metadata/content"]
            try:
                self.title = info["title"].value
                self.author = info["author"].value
                self.copyright = info["copyright"].value
            except MissingField:
                pass
Beispiel #17
0
 def createRawDisplay(self):
     value = self.value
     if isinstance(value, str):
         return makePrintable(value, "ASCII")
     else:
         return str(value)