# AUTOGENERATED! DO NOT EDIT! File to edit: 02_extractor.ipynb (unless otherwise specified).

__all__ = ['PageExtractor']

# Cell
import re
import logging
from bs4 import BeautifulSoup
from typing import Union,List,Dict

# Cell
class PageExtractor:
    """
    A class to represent an information extractor from a football preview.

    ...

    Methods
    -------
    get_values_matching_regex(content,response_type pattern_returned_values)
        return all matched patterns from a preview page.
    extract_teams_names(title)
        returns team names from the preview title.
    extract_text_authors(content, response_type)
        returns the text and author of the preview.
    extract_match_infos(content, response_type, venue_regex, referee_regex, odds_regex)
        returns a football match information (venue,referee,odds).
    """

    @staticmethod
    def get_values_matching_regex(
        content: BeautifulSoup, response_type: str, pattern_returned_values: "re.Pattern"
    ) -> Union[List[str], None]:
        """
        returns all matched patterns from a preview page.

        Parameters
        ----------
        content: bs4.BeautifulSoup
            the html format of the preview content
        response_type: str
            the parsing method('api' or 'html')
        pattern_returned_values: re.Pattern
            the regex pattern

        Returns
        -------
        result: list of str
          matched values of the regex expression, None otherwise

        """
        # All Information are located in the "p tag" of html
        # We pick up all the p tags
        if response_type == "api":
            paragraphs = content.find_all("p")
        else:
            # some previews in 2009 have a different html tags and classes
            all_p_tags_new_formats = content.find_all("p", {"class": "dcr-bixwrd"})
            all_p_tags_old_format = content.select("div > p")
            # if exist
            if all_p_tags_new_formats:
                paragraphs = all_p_tags_new_formats
            else:
                paragraphs = all_p_tags_old_format

        for paragraph in paragraphs:
            # We pick up the string values located in the paragraph
            # For "odds" information, "Evens" or "Evs" or "odds-on" are replaced by 1-1
            pattern_odds = re.compile("Evens|Evs|odds-on", re.IGNORECASE)
            section = pattern_odds.sub("1-1", paragraph.text)
            # To extract our information regex pattern
            # To ignore case sensitivity we use re.I
            # pattern_returned_values = re.compile(regex, re.IGNORECASE)
            # If a regex match is found, we return the list of values.
            # otherwise, an empty array is returned.
            if pattern_returned_values.findall(section):
                matching_result = pattern_returned_values.findall(section)
                # remove empty tuples from the list
                # example of a matching_result value
                # [('12-5', '11-10', '23-10', '', '')]
                result = [element for element in matching_result[0] if element]
                return result
        return None

    @staticmethod
    def extract_teams_names(title: str) -> Dict[str, object]:
        """
        returns team names from the preview title.

        Parameters
        ----------
        title: str
            the title of the preview

        Returns
        -------
        names: dict of object

        """
        # 3 possible formats for previews title
        # For example:
        # {Squad Sheets: Team A v Team B} or
        # {{Team A v Team B : match preview}} or
        # {{Team A v Team B : Squad sheets}}
        # We remove text before or after team names
        pattern = re.compile(
            "Squad Sheets:|: Squad[\s]sheets|Squad sheets|Squad sheet:|: match preview",
            re.IGNORECASE,
        )
        preview_title = pattern.sub("", title).strip()
        # Names are located in the title of the preview
        # Home team
        try:
            home_team = preview_title.split(" v ")[0]
        except Exception as e:
            home_team = None
            logging.warning("Home team name does not exist")

        # Away team
        try:
            away_team = preview_title.split(" v ")[1].split("\t")[
                0
            ]  # for some preview we find team A v Team B \t date
        except Exception as e:
            away_team = None
            logging.warning("Away team name does not exist")
        # we return names
        names = dict({"home": home_team, "away": away_team})
        return names

    @staticmethod
    def extract_text_authors(
        content: BeautifulSoup, response_type: str
    ) -> Dict[str, str]:
        """
        returns the text and author of the preview.

        Parameters
        ----------
        content: bs4.BeautifulSoup
            the html format of the preview content
        response_type: str
            the parsing method('api' or 'html')

        Returns
        -------
        preview_text_author: dict of str

        """
        # Preview may not have text and author,
        # We initialize author and text to None (not available),
        author = None
        text = None
        # all items are stored in a p tag
        if response_type == "api":
            all_p_tags = content.find_all("p")
        else:
            # Some previews in 2009 have different html tags and classes
            all_p_tags_new_formats = content.find_all("p", {"class": "dcr-bixwrd"})
            all_p_tags_old_format = content.select("div > p")
            # if exist
            if all_p_tags_new_formats:
                all_p_tags = all_p_tags_new_formats
            else:
                all_p_tags = all_p_tags_old_format

        # it's quite difficult to determine which section is the text
        # the length of the text is usually the longest
        # dictionnary to store each p and its length
        length_texts = {}
        for p in all_p_tags:
            section = p.text
            length_texts[p] = len(section)

        # we pick the section with the largest size
        possible_text_section = max(length_texts, key=length_texts.get)
        # We double-check and only select texts with a size greater than 160
        if len(possible_text_section.text) > 160:
            text_section = possible_text_section
            text = text_section.text
            # the author name is located inside the text section
            # it is located in the strong tag
            possible_author_section = text_section.find("strong")
            # for some previews the author information is not found
            # if it's available we take it , else it will be None
            if str(possible_author_section) != "None":
                author = possible_author_section.text
        else:
            logging.warning("There is no text or author information available")

        preview_text_author = dict({"text": text, "author": author})
        return preview_text_author

    @staticmethod
    def extract_match_infos(
        content: BeautifulSoup,
        response_type: str,
        venue_regex: str,
        referee_regex: str,
        odds_regex: str,
    ) -> Dict[str, object]:
        """
          returns a football match information (venue,referee,odds).

        Parameters
        ----------
        content: bs4.BeautifulSoup
            the html format of the preview content
        response_type: str
            the parsing method('api' or 'html')
        venue_regex: str
            venue regex expression
        referee_regex: str
            referee regex expression
        odds_regex: str
            odds regex expression

        Returns
        -------
        match_infos: dict of object

        """
        # Extract venue, referee and odds values
        try:
            pattern_venue_values = re.compile(venue_regex)
            venue = PageExtractor.get_values_matching_regex(
                content, response_type, pattern_venue_values
            )[0].strip()
        except Exception as e:
            logging.error("Venue information is not available")
            venue = None
        try:
            pattern_referee_values = re.compile(referee_regex)
            referee = PageExtractor.get_values_matching_regex(
                content, response_type, pattern_referee_values
            )[0].strip().split(",")[0]
        except Exception as e:
            logging.error("Referee information is not available")
            referee = None

        pattern_odds_values = re.compile(odds_regex, re.IGNORECASE)
        odds = PageExtractor.get_values_matching_regex(
            content, response_type, pattern_odds_values
        )

        match_infos = dict({"venue": venue, "referee": referee, "odds": odds})
        return match_infos