mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 08:53:37 +00:00
0d9fbc1ad7
This version of SickBeard uses both TVDB and TVRage to search and gather it's series data from allowing you to now have access to and download shows that you couldn't before because of being locked into only what TheTVDB had to offer. Also this edition is based off the code we used in our XEM editon so it does come with scene numbering support as well as all the other features our XEM edition has to offer. Please before using this with your existing database (sickbeard.db) please make a backup copy of it and delete any other database files such as cache.db and failed.db if present, we HIGHLY recommend starting out with no database files at all to make this a fresh start but the choice is at your own risk! Enjoy!
154 lines
5.6 KiB
Python
154 lines
5.6 KiB
Python
import lib.hachoir_core.config as config
|
|
from lib.hachoir_core.field import Parser as GenericParser
|
|
from lib.hachoir_core.error import HACHOIR_ERRORS, HachoirError, error
|
|
from lib.hachoir_core.tools import makeUnicode
|
|
from lib.hachoir_core.i18n import _
|
|
from inspect import getmro
|
|
|
|
|
|
class ValidateError(HachoirError):
|
|
pass
|
|
|
|
class HachoirParser(object):
|
|
"""
|
|
A parser is the root of all other fields. It create first level of fields
|
|
and have special attributes and methods:
|
|
- tags: dictionnary with keys:
|
|
- "file_ext": classical file extensions (string or tuple of strings) ;
|
|
- "mime": MIME type(s) (string or tuple of strings) ;
|
|
- "description": String describing the parser.
|
|
- endian: Byte order (L{BIG_ENDIAN} or L{LITTLE_ENDIAN}) of input data ;
|
|
- stream: Data input stream (set in L{__init__()}).
|
|
|
|
Default values:
|
|
- size: Field set size will be size of input stream ;
|
|
- mime_type: First MIME type of tags["mime"] (if it does exist,
|
|
None otherwise).
|
|
"""
|
|
|
|
_autofix = False
|
|
|
|
def __init__(self, stream, **args):
|
|
validate = args.pop("validate", False)
|
|
self._mime_type = None
|
|
while validate:
|
|
nbits = self.getParserTags()["min_size"]
|
|
if stream.sizeGe(nbits):
|
|
res = self.validate()
|
|
if res is True:
|
|
break
|
|
res = makeUnicode(res)
|
|
else:
|
|
res = _("stream is smaller than %s.%s bytes" % divmod(nbits, 8))
|
|
raise ValidateError(res or _("no reason given"))
|
|
self._autofix = True
|
|
|
|
#--- Methods that can be overridden -------------------------------------
|
|
def createDescription(self):
|
|
"""
|
|
Create an Unicode description
|
|
"""
|
|
return self.PARSER_TAGS["description"]
|
|
|
|
def createMimeType(self):
|
|
"""
|
|
Create MIME type (string), eg. "image/png"
|
|
|
|
If it returns None, "application/octet-stream" is used.
|
|
"""
|
|
if "mime" in self.PARSER_TAGS:
|
|
return self.PARSER_TAGS["mime"][0]
|
|
return None
|
|
|
|
def validate(self):
|
|
"""
|
|
Check that the parser is able to parse the stream. Valid results:
|
|
- True: stream looks valid ;
|
|
- False: stream is invalid ;
|
|
- str: string describing the error.
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
#--- Getter methods -----------------------------------------------------
|
|
def _getDescription(self):
|
|
if self._description is None:
|
|
try:
|
|
self._description = self.createDescription()
|
|
if isinstance(self._description, str):
|
|
self._description = makeUnicode(self._description)
|
|
except HACHOIR_ERRORS, err:
|
|
error("Error getting description of %s: %s" \
|
|
% (self.path, unicode(err)))
|
|
self._description = self.PARSER_TAGS["description"]
|
|
return self._description
|
|
description = property(_getDescription,
|
|
doc="Description of the parser")
|
|
|
|
def _getMimeType(self):
|
|
if not self._mime_type:
|
|
try:
|
|
self._mime_type = self.createMimeType()
|
|
except HACHOIR_ERRORS, err:
|
|
self.error("Error when creating MIME type: %s" % unicode(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 = u"application/octet-stream"
|
|
return self._mime_type
|
|
mime_type = property(_getMimeType)
|
|
|
|
def createContentSize(self):
|
|
return None
|
|
def _getContentSize(self):
|
|
if not hasattr(self, "_content_size"):
|
|
try:
|
|
self._content_size = self.createContentSize()
|
|
except HACHOIR_ERRORS, err:
|
|
error("Unable to compute %s content size: %s" % (self.__class__.__name__, err))
|
|
self._content_size = None
|
|
return self._content_size
|
|
content_size = property(_getContentSize)
|
|
|
|
def createFilenameSuffix(self):
|
|
"""
|
|
Create filename suffix: "." + first value of self.PARSER_TAGS["file_ext"],
|
|
or None if self.PARSER_TAGS["file_ext"] doesn't exist.
|
|
"""
|
|
file_ext = self.getParserTags().get("file_ext")
|
|
if isinstance(file_ext, (tuple, list)):
|
|
file_ext = file_ext[0]
|
|
return file_ext and '.' + file_ext
|
|
def _getFilenameSuffix(self):
|
|
if not hasattr(self, "_filename_suffix"):
|
|
self._filename_extension = self.createFilenameSuffix()
|
|
return self._filename_extension
|
|
filename_suffix = property(_getFilenameSuffix)
|
|
|
|
@classmethod
|
|
def getParserTags(cls):
|
|
tags = {}
|
|
for cls in reversed(getmro(cls)):
|
|
if hasattr(cls, "PARSER_TAGS"):
|
|
tags.update(cls.PARSER_TAGS)
|
|
return tags
|
|
|
|
@classmethod
|
|
def print_(cls, out, verbose):
|
|
tags = cls.getParserTags()
|
|
print >>out, "- %s: %s" % (tags["id"], tags["description"])
|
|
if verbose:
|
|
if "mime" in tags:
|
|
print >>out, " MIME type: %s" % (", ".join(tags["mime"]))
|
|
if "file_ext" in tags:
|
|
file_ext = ", ".join(
|
|
".%s" % file_ext for file_ext in tags["file_ext"])
|
|
print >>out, " File extension: %s" % file_ext
|
|
|
|
autofix = property(lambda self: self._autofix and config.autofix)
|
|
|
|
class Parser(HachoirParser, GenericParser):
|
|
def __init__(self, stream, **args):
|
|
GenericParser.__init__(self, stream)
|
|
HachoirParser.__init__(self, stream, **args)
|
|
|