<commit_before>import numpy
from PIL import Image
from the_ark.selenium_helpers import SeleniumHelperExceptions, ElementNotVisibleError, ElementError
from StringIO import StringIO
import traceback

DEFAULT_SCROLL_PADDING = 100
SCREENSHOT_FILE_EXTENSION = "png"
DEFAULT_PIXEL_MATCH_OFFSET = 100

class Screenshot:
    """
    A helper class for taking screenshots using a Selenium Helper instance
    """
    def __init__(self, selenium_helper, paginated=False, header_ids=None, footer_ids=None,
                 scroll_padding=DEFAULT_SCROLL_PADDING, pixel_match_offset=DEFAULT_PIXEL_MATCH_OFFSET,
                 file_extenson=SCREENSHOT_FILE_EXTENSION):
        """
        Initializes the Screenshot class. These variable will be used throughout to help determine how to capture pages
        for this website.
        :param
            - selenium_helper:  SeleniumHelper() - The Selenium Helper object whose browser you are capturing
            - paginated:        bool - if True, all full page screenshots captured by this class will be a sequence of
                                    viewport sized images
            - header_ids:       list - A list of css_selectors for elements that "stick" to the top of the screen when
                                    scrolling. These hidden and shown while capturing the screen so that they display
                                    only at the top of the page, and do not cover any content
            - footer_ids:       list - A list of css_selectors for elements that "stick" to the bottom of the screen
                                    when scrolling. These hidden and shown while capturing the screen so that they
                                    display  only at the bottom of the page, and do not cover any content
            - scroll_padding:   int - The height, in pixels, of the overlap between paginated captures. This is also
                                    used when scrolling elements. the element is scrolled its height minus the padding
                                    to create an overlapping of content shown on both images to not cut any text in half
            - file_extenson:    string - If provided, this extension will be used while creating the image. This must
                                        be an extension that is usable with PIL
        """
        #- Set parameters as class variables
        self.sh = selenium_helper
        self.paginated = paginated
        self.headers = header_ids
        self.footers = footer_ids
        self.scroll_padding = scroll_padding
        self.pixel_match_offset = pixel_match_offset
        self.file_extenson = file_extenson

    def capture_page(self, viewport_only=False):
        """
        Entry point for a screenshot of the whole page. This will send the screenshot off to the correct methods
        depending on whether you need paginated screenshots, just the current viewport area, or the whole page in
        one large shot.
        :param
            - viewport_only:  bool - Whether to capture just the viewport's visible area or not
        :return
            - StringIO: A StingIO object containing the captured image(s)
        """
        try:
            if viewport_only:
                return self._capture_single_viewport()
            elif self.paginated:
                return self._capture_paginated_page()
            else:
                return self._capture_full_page()

        except SeleniumHelperExceptions as selenium_error:
            message = "A selenium issue arose while taking the screenshot".format()
            error = SeleniumError(message, selenium_error)
            raise error
        except Exception as e:
            message = "Unhandled exception while taking the screenshot | {0}".format(e)
            raise ScreenshotException(message, stacktrace=traceback.format_exc())

    def capture_scrolling_element(self, css_selector, viewport_only=True):
        """
        This method will scroll an element one height (with padding) and take a screenshot each scroll until the element
        has been scrolled to the bottom. You can choose to capture the whole page (helpful when the scrollable element
        is taller than the viewport) or just the viewport area
        :param
            - css_selector:     string - The css selector for the element that you plan to scroll
            - viewport_only:    bool   - Whether to capture just the viewport's visible area or not (each screenshot
                                       after scrolling)
        :return
            - StringIO:     list - A list containing multiple StringIO image objects
        """
        try:
            image_list = []
            # Scroll the element to the top
            self.sh.scroll_an_element(css_selector, scroll_top=True)

            while True:
                #- Capture the image
                if viewport_only:
                    image_list.append(self._capture_single_viewport())
                else:
                    image_list.append(self._capture_full_page())

                if self.sh.get_is_element_scroll_position_at_bottom(css_selector):
                    #- Stop capturing once you're at the bottom
                    break
                else:
                    #- Scroll down for the next one!
                    self.sh.scroll_an_element(css_selector, scroll_padding=self.scroll_padding)

            return image_list

        except SeleniumHelperExceptions as selenium_error:
            message = "A selenium issue arose while trying to capture the scrolling element"
            error = SeleniumError(message, selenium_error)
            raise error
        except Exception as e:
            message = "Unhandled exception while taking the scrolling screenshot " \
                      "of the element '{0}' | {1}".format(css_selector, e)
            raise ScreenshotException(message,
                                      stacktrace=traceback.format_exc(),
                                      details={"css_selector": css_selector})

    def _capture_single_viewport(self):
        """
        Grabs an image of the page and then craps it to just the visible / viewport area
        :return
            - StringIO: A StingIO object containing the captured image
        """
        cropped_image = self._get_image_data(viewport_only=True)
        return self._create_image_file(cropped_image)

    def _capture_full_page(self):<commit_msg>Allowed scroll padding override for element scrolls<commit_after>import numpy
from PIL import Image
from the_ark.selenium_helpers import SeleniumHelperExceptions, ElementNotVisibleError, ElementError
from StringIO import StringIO
import traceback

DEFAULT_SCROLL_PADDING = 100
SCREENSHOT_FILE_EXTENSION = "png"
DEFAULT_PIXEL_MATCH_OFFSET = 100

class Screenshot:
    """
    A helper class for taking screenshots using a Selenium Helper instance
    """
    def __init__(self, selenium_helper, paginated=False, header_ids=None, footer_ids=None,
                 scroll_padding=DEFAULT_SCROLL_PADDING, pixel_match_offset=DEFAULT_PIXEL_MATCH_OFFSET,
                 file_extenson=SCREENSHOT_FILE_EXTENSION):
        """
        Initializes the Screenshot class. These variable will be used throughout to help determine how to capture pages
        for this website.
        :param
            - selenium_helper:  SeleniumHelper() - The Selenium Helper object whose browser you are capturing
            - paginated:        bool - if True, all full page screenshots captured by this class will be a sequence of
                                    viewport sized images
            - header_ids:       list - A list of css_selectors for elements that "stick" to the top of the screen when
                                    scrolling. These hidden and shown while capturing the screen so that they display
                                    only at the top of the page, and do not cover any content
            - footer_ids:       list - A list of css_selectors for elements that "stick" to the bottom of the screen
                                    when scrolling. These hidden and shown while capturing the screen so that they
                                    display  only at the bottom of the page, and do not cover any content
            - scroll_padding:   int - The height, in pixels, of the overlap between paginated captures. This is also
                                    used when scrolling elements. the element is scrolled its height minus the padding
                                    to create an overlapping of content shown on both images to not cut any text in half
            - file_extenson:    string - If provided, this extension will be used while creating the image. This must
                                        be an extension that is usable with PIL
        """
        #- Set parameters as class variables
        self.sh = selenium_helper
        self.paginated = paginated
        self.headers = header_ids
        self.footers = footer_ids
        self.scroll_padding = scroll_padding
        self.pixel_match_offset = pixel_match_offset
        self.file_extenson = file_extenson

    def capture_page(self, viewport_only=False):
        """
        Entry point for a screenshot of the whole page. This will send the screenshot off to the correct methods
        depending on whether you need paginated screenshots, just the current viewport area, or the whole page in
        one large shot.
        :param
            - viewport_only:  bool - Whether to capture just the viewport's visible area or not
        :return
            - StringIO: A StingIO object containing the captured image(s)
        """
        try:
            if viewport_only:
                return self._capture_single_viewport()
            elif self.paginated:
                return self._capture_paginated_page()
            else:
                return self._capture_full_page()

        except SeleniumHelperExceptions as selenium_error:
            message = "A selenium issue arose while taking the screenshot".format()
            error = SeleniumError(message, selenium_error)
            raise error
        except Exception as e:
            message = "Unhandled exception while taking the screenshot | {0}".format(e)
            raise ScreenshotException(message, stacktrace=traceback.format_exc())

    def capture_scrolling_element(self, css_selector, viewport_only=True, scroll_padding=None):
        """
        This method will scroll an element one height (with padding) and take a screenshot each scroll until the element
        has been scrolled to the bottom. You can choose to capture the whole page (helpful when the scrollable element
        is taller than the viewport) or just the viewport area
        :param
            - css_selector:     string - The css selector for the element that you plan to scroll
            - viewport_only:    bool   - Whether to capture just the viewport's visible area or not (each screenshot
                                       after scrolling)
            - scroll_padding:   int    - Overwrites the default scroll padding for the class. This can be used when the
                                       element, or site, have greatly different scroll padding numbers
        :return
            - StringIO:     list - A list containing multiple StringIO image objects
        """
        padding = scroll_padding if scroll_padding else self.scroll_padding

        try:
            image_list = []
            # Scroll the element to the top
            self.sh.scroll_an_element(css_selector, scroll_top=True)

            while True:
                #- Capture the image
                if viewport_only:
                    image_list.append(self._capture_single_viewport())
                else:
                    image_list.append(self._capture_full_page())

                if self.sh.get_is_element_scroll_position_at_bottom(css_selector):
                    #- Stop capturing once you're at the bottom
                    break
                else:
                    #- Scroll down for the next one!
                    self.sh.scroll_an_element(css_selector, scroll_padding=padding)

            return image_list

        except SeleniumHelperExceptions as selenium_error:
            message = "A selenium issue arose while trying to capture the scrolling element"
            error = SeleniumError(message, selenium_error)
            raise error
        except Exception as e:
            message = "Unhandled exception while taking the scrolling screenshot " \
                      "of the element '{0}' | {1}".format(css_selector, e)
            raise ScreenshotException(message,
                                      stacktrace=traceback.format_exc(),
                                      details={"css_selector": css_selector})

    def _capture_single_viewport(self):
        """
        Grabs an image of the page and then craps it to just the visible / viewport area
        :return
            - StringIO: A StingIO object containing the captured image
        """
        cropped_image = self._get_image_data(viewport_only=True)
        return self._create_image_file(cropped_image)

    def _capture_full_page(self):
{'fraction_non_alphanumeric': 0.0461677051272427, 'fraction_numerical': 0.001351249906163201, 'mean_word_length': 1.9749888343010273, 'pattern_counts': {'":': 2, '<': 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': 31, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3188754', 'n_tokens_mistral': 3255, 'n_tokens_neox': 3055, 'n_words': 1217}