<commit_before>import abc
from abc import ABCMeta

from redux.helper.decorators import memoize
from redux.helper.image import Image
from redux.helper.traits.hasurl import HasUrl
from redux.helper.util import Util


class MangaSite(object):
    __metaclass__ = ABCMeta

    @classmethod
    @memoize
    def series(cls, name):
        return cls.Series(cls, name)

    class Chapter(HasUrl):
        __metaclass__ = ABCMeta

        VOLUME_AND_CHAPTER_FROM_URL_REGEX = NotImplemented
        TOTAL_PAGES_FROM_SOURCE_REGEX = NotImplemented
        CHAPTER_TITLE_FROM_SOURCE_REGEX = NotImplemented

        def __init__(self, series, title, url):
            """
            :type series: Series
            :type title: str
            :type url: str
            """
            self.series = series
            self.title = title
            self.url = url

        @property
        @memoize
        def volume(self):
            """
            :rtype: str or None
            """
            match = self.VOLUME_AND_CHAPTER_FROM_URL_REGEX.match(self.url)

            if match is not None and match.group('volume') is not None:
                return Util.normalize_value(match.group('volume'))
            else:
                return None

        @property
        @memoize
        def chapter(self):
            """
            :rtype: str or None
            """
            match = self.VOLUME_AND_CHAPTER_FROM_URL_REGEX.match(self.url)

            if match is not None and match.group('chapter') is not None:
                return Util.normalize_value(match.group('chapter'))
            else:
                return None

        @property
        @memoize
        def number_of_pages(self):
            """
            :rtype: int
            """
            return int(self.TOTAL_PAGES_FROM_SOURCE_REGEX.search(self.source).group('count'))

        @abc.abstractproperty
        @memoize
        def pages(self):
            """
            :rtype: list of Page
            """
            pass

    class Page(HasUrl):
        __metaclass__ = ABCMeta

        IMAGE_FROM_SOURCE_REGEX = NotImplemented

        def __init__(self, chapter, url):
            """
            :type chapter: Chapter
            :type url: str
            """
            self.chapter = chapter
            self.url = url

        @property
        @memoize
        def image(self):
            """
            :rtype: Image
            """
            return Image(str(self.IMAGE_FROM_SOURCE_REGEX.search(self.source).group('link')))

    class Series(HasUrl):
        __metaclass__ = ABCMeta

        CHAPTER_FROM_SOURCE_REGEX = NotImplemented
        TEMPLATE_URL = NotImplemented

        def __init__(self, site, name):
            """
            :type site: MangaSite
            :type name: str
            """
            self.site = site
            self.name = name

        @property
        @memoize
        def url(self):
            """
            :rtype: str
            """
            return self.TEMPLATE_URL.format(name=self.normalized_name)

        @abc.abstractproperty
        @memoize
        def normalized_name(self):
            """
            :rtype: str
            """
            pass

        @abc.abstractproperty
        @memoize
        def chapters(self):
            """
            :rtype: list of Chapter
            """
            pass
<commit_msg>Return None for image if it doesn't exist.<commit_after>import abc
from abc import ABCMeta

from redux.helper.decorators import memoize
from redux.helper.image import Image
from redux.helper.traits.hasurl import HasUrl
from redux.helper.util import Util


class MangaSite(object):
    __metaclass__ = ABCMeta

    @classmethod
    @memoize
    def series(cls, name):
        return cls.Series(cls, name)

    class Chapter(HasUrl):
        __metaclass__ = ABCMeta

        VOLUME_AND_CHAPTER_FROM_URL_REGEX = NotImplemented
        TOTAL_PAGES_FROM_SOURCE_REGEX = NotImplemented
        CHAPTER_TITLE_FROM_SOURCE_REGEX = NotImplemented

        def __init__(self, series, title, url):
            """
            :type series: Series
            :type title: str
            :type url: str
            """
            self.series = series
            self.title = title
            self.url = url

        @property
        @memoize
        def volume(self):
            """
            :rtype: str or None
            """
            match = self.VOLUME_AND_CHAPTER_FROM_URL_REGEX.match(self.url)

            if match is not None and match.group('volume') is not None:
                return Util.normalize_value(match.group('volume'))
            else:
                return None

        @property
        @memoize
        def chapter(self):
            """
            :rtype: str or None
            """
            match = self.VOLUME_AND_CHAPTER_FROM_URL_REGEX.match(self.url)

            if match is not None and match.group('chapter') is not None:
                return Util.normalize_value(match.group('chapter'))
            else:
                return None

        @property
        @memoize
        def number_of_pages(self):
            """
            :rtype: int
            """
            return int(self.TOTAL_PAGES_FROM_SOURCE_REGEX.search(self.source).group('count'))

        @abc.abstractproperty
        @memoize
        def pages(self):
            """
            :rtype: list of Page
            """
            pass

    class Page(HasUrl):
        __metaclass__ = ABCMeta

        IMAGE_FROM_SOURCE_REGEX = NotImplemented

        def __init__(self, chapter, url):
            """
            :type chapter: Chapter
            :type url: str
            """
            self.chapter = chapter
            self.url = url

        @property
        @memoize
        def image(self):
            """
            :rtype: Image or None
            """
            return Image(str(self.IMAGE_FROM_SOURCE_REGEX.search(self.source).group('link'))) if self.IMAGE_FROM_SOURCE_REGEX.search(self.source) is not None else None

    class Series(HasUrl):
        __metaclass__ = ABCMeta

        CHAPTER_FROM_SOURCE_REGEX = NotImplemented
        TEMPLATE_URL = NotImplemented

        def __init__(self, site, name):
            """
            :type site: MangaSite
            :type name: str
            """
            self.site = site
            self.name = name

        @property
        @memoize
        def url(self):
            """
            :rtype: str
            """
            return self.TEMPLATE_URL.format(name=self.normalized_name)

        @abc.abstractproperty
        @memoize
        def normalized_name(self):
            """
            :rtype: str
            """
            pass

        @abc.abstractproperty
        @memoize
        def chapters(self):
            """
            :rtype: list of Chapter
            """
            pass

{'fraction_non_alphanumeric': 0.0844354018311292, 'fraction_numerical': 0.0, 'mean_word_length': 1.4889692585895118, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '636666', 'n_tokens_mistral': 1933, 'n_tokens_neox': 1857, 'n_words': 426}