Best Python code snippet using uiautomator
epubview.py
Source:epubview.py  
1# Copyright 2009 One Laptop Per Child2# Author: Sayamindu Dasgupta <sayamindu@laptop.org>3# WebKit2 port Copyright (C) 2018 Lubomir Rintel <lkundrak@v3.sk>4#5# This program is free software; you can redistribute it and/or modify6# it under the terms of the GNU General Public License as published by7# the Free Software Foundation; either version 2 of the License, or8# (at your option) any later version.9#10# This program is distributed in the hope that it will be useful,11# but WITHOUT ANY WARRANTY; without even the implied warranty of12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the13# GNU General Public License for more details.14#15# You should have received a copy of the GNU General Public License16# along with this program; if not, write to the Free Software17# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA18import gi19gi.require_version('WebKit2', '4.0')20from gi.repository import Gtk21from gi.repository import GObject22from gi.repository import Gdk23from gi.repository import WebKit224from . import widgets25import logging26import os.path27import math28import shutil29from .jobs import _JobPaginator as _Paginator30LOADING_HTML = '''31<html style="height: 100%; margin: 0; padding: 0; width: 100%;">32    <body style="display: table; height: 100%; margin: 0; padding: 0; width: 100%;">33        <div style="display: table-cell; text-align: center; vertical-align: middle;">34            <h1>Loading...</h1>35        </div>36    </body>37</html>38'''39class _View(Gtk.HBox):40    __gproperties__ = {41        'scale': (GObject.TYPE_FLOAT, 'the zoom level',42                  'the zoom level of the widget',43                  0.5, 4.0, 1.0, GObject.PARAM_READWRITE),44    }45    __gsignals__ = {46        'page-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,47                         ([int, int])),48        'selection-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,49                              ([])),50    }51    def __init__(self):52        GObject.threads_init()53        Gtk.HBox.__init__(self)54        self.connect("destroy", self._destroy_cb)55        self._ready = False56        self._paginator = None57        self._loaded_page = -158        # self._old_scrollval = -159        self._loaded_filename = None60        self._pagecount = -161        self.__scroll_to_end = False62        self.__page_changed = False63        self._has_selection = False64        self._scrollval = 0.065        self.scale = 1.066        self._epub = None67        self._findjob = None68        self.__in_search = False69        self.__search_fwd = True70        self._filelist = None71        self._internal_link = None72        self._view = widgets._WebView()73        self._view.load_html(LOADING_HTML, '/')74        settings = self._view.get_settings()75        settings.props.default_font_family = 'DejaVu LGC Serif'76        settings.props.enable_plugins = False77        settings.props.default_charset = 'utf-8'78        self._view.connect('load-changed', self._view_load_changed_cb)79        self._view.connect('scrolled', self._view_scrolled_cb)80        self._view.connect('scrolled-top', self._view_scrolled_top_cb)81        self._view.connect('scrolled-bottom', self._view_scrolled_bottom_cb)82        self._view.connect('selection-changed', self._view_selection_changed_cb)83        find = self._view.get_find_controller()84        find.connect('failed-to-find-text', self._find_failed_cb)85        self._eventbox = Gtk.EventBox()86        self._eventbox.connect('scroll-event', self._eventbox_scroll_event_cb)87        self._eventbox.add_events(Gdk.EventMask.SCROLL_MASK)88        self._eventbox.add(self._view)89        self._scrollbar = Gtk.VScrollbar()90        self._scrollbar_change_value_cb_id = self._scrollbar.connect(91            'change-value', self._scrollbar_change_value_cb)92        hbox = Gtk.HBox()93        hbox.pack_start(self._eventbox, True, True, 0)94        hbox.pack_end(self._scrollbar, False, True, 0)95        self.pack_start(hbox, True, True, 0)96        self._view.set_can_default(True)97        self._view.set_can_focus(True)98        def map_cp(widget):99            widget.setup_touch()100            widget.disconnect(self._setup_handle)101        self._setup_handle = self._view.connect('map', map_cp)102    def set_document(self, epubdocumentinstance):103        '''104        Sets document (should be a Epub instance)105        '''106        self._epub = epubdocumentinstance107        GObject.idle_add(self._paginate)108    def do_get_property(self, property):109        if property.name == 'has-selection':110            return self._has_selection111        elif property.name == 'scale':112            return self.scale113        else:114            raise AttributeError('unknown property %s' % property.name)115    def do_set_property(self, property, value):116        if property.name == 'scale':117            self.__set_zoom(value)118        else:119            raise AttributeError('unknown property %s' % property.name)120    def get_has_selection(self):121        '''122        Returns True if any part of the content is selected123        '''124        return self._has_selection125    def get_zoom(self):126        '''127        Returns the current zoom level128        '''129        return self.get_property('scale') * 100.0130    def set_zoom(self, value):131        '''132        Sets the current zoom level133        '''134        scrollbar_pos = self.get_vertical_pos()135        self._view.set_zoom_level(value / 100.0)136        self.set_vertical_pos(scrollbar_pos)137    def _get_scale(self):138        '''139        Returns the current zoom level140        '''141        return self.get_property('scale')142    def _set_scale(self, value):143        '''144        Sets the current zoom level145        '''146        self.set_property('scale', value)147    def zoom_in(self):148        '''149        Zooms in (increases zoom level by 0.1)150        '''151        if self.can_zoom_in():152            scrollbar_pos = self.get_vertical_pos()153            self._set_scale(self._get_scale() + 0.1)154            self.set_vertical_pos(scrollbar_pos)155            return True156        else:157            return False158    def zoom_out(self):159        '''160        Zooms out (decreases zoom level by 0.1)161        '''162        if self.can_zoom_out():163            scrollbar_pos = self.get_vertical_pos()164            self._set_scale(self._get_scale() - 0.1)165            self.set_vertical_pos(scrollbar_pos)166            return True167        else:168            return False169    def get_vertical_pos(self):170        """171        Used to save the scrolled position and restore when needed172        """173        return self._scrollval174    def set_vertical_pos(self, position):175        """176        Used to save the scrolled position and restore when needed177        """178        self._view.scroll_to(position)179    def can_zoom_in(self):180        '''181        Returns True if it is possible to zoom in further182        '''183        if self.scale < 4:184            return True185        else:186            return False187    def can_zoom_out(self):188        '''189        Returns True if it is possible to zoom out further190        '''191        if self.scale > 0.5:192            return True193        else:194            return False195    def get_current_page(self):196        '''197        Returns the currently loaded page198        '''199        return self._loaded_page200    def get_current_file(self):201        '''202        Returns the currently loaded XML file203        '''204        # return self._loaded_filename205        if self._paginator:206            return self._paginator.get_file_for_pageno(self._loaded_page)207        else:208            return None209    def get_pagecount(self):210        '''211        Returns the pagecount of the loaded file212        '''213        return self._pagecount214    def set_current_page(self, n):215        '''216        Loads page number n217        '''218        if n < 1 or n > self._pagecount:219            return False220        self._load_page(n)221        return True222    def next_page(self):223        '''224        Loads next page if possible225        Returns True if transition to next page is possible and done226        '''227        if self._loaded_page == self._pagecount:228            return False229        self._load_next_page()230        return True231    def previous_page(self):232        '''233        Loads previous page if possible234        Returns True if transition to previous page is possible and done235        '''236        if self._loaded_page == 1:237            return False238        self._load_prev_page()239        return True240    def scroll(self, scrolltype, horizontal):241        '''242        Scrolls through the pages.243        Scrolling is horizontal if horizontal is set to True244        Valid scrolltypes are:245        Gtk.ScrollType.PAGE_BACKWARD, Gtk.ScrollType.PAGE_FORWARD,246        Gtk.ScrollType.STEP_BACKWARD, Gtk.ScrollType.STEP_FORWARD247        Gtk.ScrollType.STEP_START and Gtk.ScrollType.STEP_END248        '''249        if scrolltype == Gtk.ScrollType.PAGE_BACKWARD:250            pages = self._paginator.get_pagecount_for_file(self._loaded_filename)251            self._view.scroll_by(self._page_height / pages * -1)252        elif scrolltype == Gtk.ScrollType.PAGE_FORWARD:253            pages = self._paginator.get_pagecount_for_file(self._loaded_filename)254            self._view.scroll_by(self._page_height / pages * 1)255        elif scrolltype == Gtk.ScrollType.STEP_BACKWARD:256            self._view.scroll_by(self._view.get_settings().get_default_font_size() * -3)257        elif scrolltype == Gtk.ScrollType.STEP_FORWARD:258            self._view.scroll_by(self._view.get_settings().get_default_font_size() * 3)259        elif scrolltype == Gtk.ScrollType.START:260            self.set_current_page(0)261        elif scrolltype == Gtk.ScrollType.END:262            self.__scroll_to_end = True263            self.set_current_page(self._pagecount - 1)264        else:265            print('Got unsupported scrolltype %s' % str(scrolltype))266    def __touch_page_changed_cb(self, widget, forward):267        if forward:268            self.scroll(Gtk.ScrollType.PAGE_FORWARD, False)269        else:270            self.scroll(Gtk.ScrollType.PAGE_BACKWARD, False)271    def copy(self):272        '''273        Copies the current selection to clipboard.274        '''275        self._view.run_javascript('document.execCommand("copy")')276    def find_next(self):277        '''278        Highlights the next matching item for current search279        '''280        self._view.grab_focus()281        self.__search_fwd = True282        self._view.get_find_controller().search_next()283    def find_previous(self):284        '''285        Highlights the previous matching item for current search286        '''287        self._view.grab_focus()288        self.__search_fwd = False289        self._view.get_find_controller().search_previous()290    def _find_failed_cb(self, find_controller):291        try:292            if self.__search_fwd:293                path = os.path.join(self._epub.get_basedir(),294                                    self._findjob.get_next_file())295            else:296                path = os.path.join(self._epub.get_basedir(),297                                    self._findjob.get_prev_file())298            self.__in_search = True299            self._load_file(path)300        except IndexError:301            # No match anywhere, no other file to pick302            pass303    def _find_changed(self, job):304        self._view.grab_focus()305        self._findjob = job306        find = self._view.get_find_controller()307        find.search (self._findjob.get_search_text(),308                     self._findjob.get_flags(),309                     GObject.G_MAXUINT)310    def __set_zoom(self, value):311        self._view.set_zoom_level(value)312        self.scale = value313    def _view_scrolled_cb(self, view, scrollval):314        if self._loaded_page < 1:315            return316        self._scrollval = scrollval317        scroll_upper = self._page_height318        scroll_page_size = self._view.get_allocated_height()319        if scrollval > 0:320            try:321                scrollfactor = scrollval / (scroll_upper - scroll_page_size)322            except ZeroDivisionError:323                scrollfactor = 0324        else:325            scrollfactor = 0326        if not self._loaded_page == self._pagecount and \327           not self._paginator.get_file_for_pageno(self._loaded_page) != \328               self._paginator.get_file_for_pageno(self._loaded_page + 1):329            scrollfactor_next = \330                self._paginator.get_scrollfactor_pos_for_pageno(331                    self._loaded_page + 1)332            if scrollfactor >= scrollfactor_next:333                self._on_page_changed(self._loaded_page, self._loaded_page + 1)334                return335        if self._loaded_page > 1 and \336           not self._paginator.get_file_for_pageno(self._loaded_page) != \337               self._paginator.get_file_for_pageno(self._loaded_page - 1):338            scrollfactor_cur = \339                self._paginator.get_scrollfactor_pos_for_pageno(340                    self._loaded_page)341            if scrollfactor <= scrollfactor_cur:342                self._on_page_changed(self._loaded_page, self._loaded_page - 1)343                return344    def _view_scrolled_top_cb(self, view):345        if self._loaded_page > 1:346            self.__scroll_to_end = True347            self._load_prev_page()348    def _view_scrolled_bottom_cb(self, view):349        if self._loaded_page < self._pagecount:350            self._load_next_page()351    def _view_selection_changed_cb(self, view, has_selection):352        self._has_selection = has_selection353        self.emit('selection-changed')354    def _eventbox_scroll_event_cb(self, view, event):355        if event.direction == Gdk.ScrollDirection.DOWN:356            self.scroll(Gtk.ScrollType.STEP_FORWARD, False)357        elif event.direction == Gdk.ScrollDirection.UP:358            self.scroll(Gtk.ScrollType.STEP_BACKWARD, False)359    def _view_load_changed_cb(self, v, load_event):360        if load_event != WebKit2.LoadEvent.FINISHED:361            return True362        filename = self._view.props.uri.replace('file://', '')363        if os.path.exists(filename.replace('xhtml', 'xml')):364            # Hack for making javascript work365            filename = filename.replace('xhtml', 'xml')366        filename = filename.split('#')[0]  # Get rid of anchors367        if self._loaded_page < 1 or filename is None:368            return False369        self._loaded_filename = filename370        remfactor = self._paginator.get_remfactor_for_file(filename)371        pages = self._paginator.get_pagecount_for_file(filename)372        extra = int(math.ceil(373            remfactor * self._view.get_page_height() / (pages - remfactor)))374        if extra > 0:375            self._view.add_bottom_padding(extra)376        self._page_height = self._view.get_page_height()377        if self.__in_search:378            self.__in_search = False379            find = self._view.get_find_controller()380            find.search (self._findjob.get_search_text(),381                         self._findjob.get_flags(self.__search_fwd),382                         GObject.G_MAXUINT)383        else:384            self._scroll_page()385        # process_file = True386        if self._internal_link is not None:387            self._view.go_to_link(self._internal_link)388            vertical_pos = \389                self._view.get_vertical_position_element(self._internal_link)390            # set the page number based in the vertical position391            initial_page = self._paginator.get_base_pageno_for_file(filename)392            self._loaded_page = initial_page + int(393                vertical_pos / self._paginator.get_single_page_height())394            # There are epub files, created with Calibre,395            # where the link in the index points to the end of the previos396            # file to the needed chapter.397            # if the link is at the bottom of the page, we open the next file398            one_page_height = self._paginator.get_single_page_height()399            self._internal_link = None400            if vertical_pos > self._page_height - one_page_height:401                logging.error('bottom page link, go to next file')402                next_file = self._paginator.get_next_filename(filename)403                if next_file is not None:404                    logging.error('load next file %s', next_file)405                    self.__in_search = False406                    self.__scroll_to_end = False407                    # process_file = False408                    GObject.idle_add(self._load_file, next_file)409#        if process_file:410#            # prepare text to speech411#            html_file = open(self._loaded_filename)412#            soup = BeautifulSoup.BeautifulSoup(html_file)413#            body = soup.find('body')414#            tags = body.findAll(text=True)415#            self._all_text = ''.join([tag for tag in tags])416#            self._prepare_text_to_speech(self._all_text)417    def _prepare_text_to_speech(self, page_text):418        i = 0419        j = 0420        word_begin = 0421        word_end = 0422        ignore_chars = [' ',  '\n',  '\r',  '_',  '[', '{', ']', '}', '|',423                        '<',  '>',  '*',  '+',  '/',  '\\']424        ignore_set = set(ignore_chars)425        self.word_tuples = []426        len_page_text = len(page_text)427        while i < len_page_text:428            if page_text[i] not in ignore_set:429                word_begin = i430                j = i431                while j < len_page_text and page_text[j] not in ignore_set:432                    j = j + 1433                    word_end = j434                    i = j435                word_tuple = (word_begin, word_end,436                              page_text[word_begin: word_end])437                if word_tuple[2] != '\r':438                    self.word_tuples.append(word_tuple)439            i = i + 1440    def _scroll_page(self):441        v_upper = self._page_height442        if self.__scroll_to_end:443            # We need to scroll to the last page444            scrollval = v_upper445            self.__scroll_to_end = False446        else:447            pageno = self._loaded_page448            scrollfactor = self._paginator.get_scrollfactor_pos_for_pageno(pageno)449            scrollval = math.ceil(v_upper  * scrollfactor)450        self._view.scroll_to(scrollval)451    def _paginate(self):452        filelist = []453        for i in self._epub._navmap.get_flattoc():454            filelist.append(os.path.join(self._epub._tempdir, i))455        # init files info456        self._filelist = filelist457        self._paginator = _Paginator(filelist)458        self._paginator.connect('paginated', self._paginated_cb)459    def get_filelist(self):460        return self._filelist461    def get_tempdir(self):462        return self._epub._tempdir463    def _load_next_page(self):464        self._load_page(self._loaded_page + 1)465    def _load_prev_page(self):466        self._load_page(self._loaded_page - 1)467    def _on_page_changed(self, oldpage, pageno):468        if oldpage == pageno:469            return470        self.__page_changed = True471        self._loaded_page = pageno472        self._scrollbar.handler_block(self._scrollbar_change_value_cb_id)473        self._scrollbar.set_value(pageno)474        self._scrollbar.handler_unblock(self._scrollbar_change_value_cb_id)475        # the indexes in read activity are zero based476        self.emit('page-changed', (oldpage - 1), (pageno - 1))477    def _load_page(self, pageno):478        if pageno > self._pagecount or pageno < 1:479            # TODO: Cause an exception480            return481        if self._loaded_page == pageno:482            return483        oldpage = self._loaded_page484        filename = self._paginator.get_file_for_pageno(pageno)485        filename = filename.replace('file://', '')486        if filename != self._loaded_filename:487            self._loaded_filename = filename488            """489            TODO: disabled because javascript can't be executed490            with the velocity needed491            # Copy javascript to highligth text to speech492            destpath, destname = os.path.split(filename.replace('file://', ''))493            shutil.copy('./epubview/highlight_words.js', destpath)494            self._insert_js_reference(filename.replace('file://', ''),495                    destpath)496            IMPORTANT: Find a way to do this without modify the files497            now text highlight is implemented and the epub file is saved498            """499            self._view.stop_loading()500            if filename.endswith('xml'):501                dest = filename.replace('xml', 'xhtml')502                if not os.path.exists(dest):503                    os.symlink(filename, dest)504                self._view.load_uri('file://' + dest)505            else:506                self._view.load_uri('file://' + filename)507        else:508            self._loaded_page = pageno509            self._scroll_page()510        self._on_page_changed(oldpage, pageno)511    def _insert_js_reference(self, file_name, path):512        js_reference = '<script type="text/javascript" ' + \513            'src="./highlight_words.js"></script>'514        o = open(file_name + '.tmp', 'a')515        for line in open(file_name):516            line = line.replace('</head>', js_reference + '</head>')517            o.write(line + "\n")518        o.close()519        shutil.copy(file_name + '.tmp', file_name)520    def _load_file(self, path):521        self._internal_link = None522        if path.find('#') > -1:523            self._internal_link = path[path.find('#'):]524            path = path[:path.find('#')]525        for filepath in self._filelist:526            if filepath.endswith(path):527                self._view.load_uri('file://' + filepath)528                oldpage = self._loaded_page529                self._loaded_page = \530                    self._paginator.get_base_pageno_for_file(filepath)531                self._scroll_page()532                self._on_page_changed(oldpage, self._loaded_page)533                break534    def _scrollbar_change_value_cb(self, range, scrolltype, value):535        if scrolltype == Gtk.ScrollType.STEP_FORWARD or \536                scrolltype == Gtk.ScrollType.STEP_BACKWARD:537            self.scroll(scrolltype, False)538        elif scrolltype == Gtk.ScrollType.JUMP or \539                scrolltype == Gtk.ScrollType.PAGE_FORWARD or \540                scrolltype == Gtk.ScrollType.PAGE_BACKWARD:541            if value > self._scrollbar.props.adjustment.props.upper:542                self._load_page(self._pagecount)543            else:544                self._load_page(int(value))545        else:546            print('Warning: unknown scrolltype %s with value %f' \547                % (str(scrolltype), value))548        # FIXME: This should not be needed here549        self._scrollbar.set_value(self._loaded_page)550        if self.__page_changed:551            self.__page_changed = False552            return False553        else:554            return True555    def _paginated_cb(self, object):556        self._ready = True557        self._pagecount = self._paginator.get_total_pagecount()558        self._scrollbar.set_range(1.0, self._pagecount)559        self._scrollbar.set_increments(1.0, 1.0)560        self._view.grab_focus()561        self._view.grab_default()562    def _destroy_cb(self, widget):...scraper.py
Source:scraper.py  
...20        image_urls = set()21        image_count = 022        results_start = 023        while image_count < max_urls:24            self.__scroll_to_end(sleep_between_interactions)25            thumbnail_results = self.driver.find_elements_by_css_selector(26                "img.Q4LuWd")27            number_results = len(thumbnail_results)28            self.logger.info(29                f"Found: {number_results} search results. Extracting links from {results_start}:{number_results}")30            for img in thumbnail_results[results_start:number_results]:31                self.__click_and_wait(img, sleep_between_interactions)32                self.__add_image_urls_to_set(image_urls)33                image_count = len(image_urls)34                if image_count >= max_urls:35                    self.logger.info(36                        f"Found: {len(image_urls)} image links, done!")37                    break38            else:39                self.logger.info(40                    f"Found: {len(image_urls)} image links, looking for more ...")41                load_more_button = self.driver.find_element_by_css_selector(42                    ".mye4qd")43                if load_more_button:44                    self.logger.info("loading more...")45                    self.driver.execute_script(46                        "document.querySelector('.mye4qd').click();")47            # move the result startpoint further down48            results_start = len(thumbnail_results)49        return image_urls50    def persist_image(self, folder_path: str, url: str):51        """The persist_image function grabs an image URL url and downloads it into the folder_path. The function will assign the image a random 10-digit id."""52        image_content = self.__download_image_content(url)53        try:54            image_file = io.BytesIO(image_content)55            image = Image.open(image_file).convert('RGB')56            file_path = os.path.join(folder_path, hashlib.sha1(57                image_content).hexdigest()[:10] + '.jpg')58            with open(file_path, 'wb') as f:59                image.save(f, "JPEG", quality=85)60            self.logger.info(f"SUCCESS - saved {url} - as {file_path}")61        except Exception as e:62            self.logger.error(f"ERROR - Could not save {url} - {e}")63    def get_in_memory_image(self, url: str, format: str):64        image_content = self.__download_image_content(url)65        image_hash = hashlib.sha1(image_content).hexdigest()[:10] + '.jpeg'66        try:67            image_file = io.BytesIO(image_content)68            pil_image = Image.open(image_file).convert('RGB')69            in_mem_file = io.BytesIO()70            pil_image.save(in_mem_file, format=format)71            return in_mem_file.getvalue(), image_hash72        except Exception as e:73            self.logger.error(f"Could not get image data: {e}")74    def close_connection(self):75        self.driver.quit()76    def __download_image_content(self, url):77        try:78            return requests.get(url).content79        except Exception as e:80            self.logger.error(f"ERROR - Could not download {url} - {e}")81    def __scroll_to_end(self, sleep_time):82        self.driver.execute_script(83            "window.scrollTo(0, document.body.scrollHeight);")84        time.sleep(sleep_time)85    def __click_and_wait(self, img, wait_time):86        try:87            img.click()88            time.sleep(wait_time)89        except Exception:90            return91    def __add_image_urls_to_set(self, image_urls: set):92        actual_images = self.driver.find_elements_by_css_selector('img.n3VNCb')93        for actual_image in actual_images:94            if actual_image.get_attribute('src') and 'http' in actual_image.get_attribute('src'):95                image_urls.add(actual_image.get_attribute('src'))...image_scraper.py
Source:image_scraper.py  
...18        image_urls = set()19        image_count = 020        results_start = 021        while image_count < max_urls:22            self.__scroll_to_end(sleep_between_interactions)23            thumbnail_results = self.driver.find_elements_by_css_selector("img.Q4LuWd")24            number_results = len(thumbnail_results)25            self.logger.info(f"Found: {number_results} search results. Extracting links from {results_start}:{number_results}")26            for img in thumbnail_results[results_start:number_results]:27                self.__click_and_wait(img, sleep_between_interactions)28                self.__add_image_urls_to_set(image_urls)29                image_count = len(image_urls)30                if image_count >= max_urls:31                    self.logger.info(f"Found: {len(image_urls)} image links, done!")32                    break33            else:34                self.logger.info(f"Found: {len(image_urls)} image links, looking for more ...")35                load_more_button = self.driver.find_element_by_css_selector(".mye4qd")36                if load_more_button:37                    self.logger.info("loading more...")38                    self.driver.execute_script("document.querySelector('.mye4qd').click();")39            # move the result startpoint further down40            results_start = len(thumbnail_results)41        return image_urls42    def persist_image(self, folder_path: str, url: str):43        image_content = self.__download_image_content(url)44        try:45            image_file = io.BytesIO(image_content)46            image = Image.open(image_file).convert('RGB')47            file_path = os.path.join(folder_path, hashlib.sha1(image_content).hexdigest()[:10] + '.jpg')48            with open(file_path, 'wb') as f:49                image.save(f, "JPEG", quality=85)50            self.logger.info(f"SUCCESS - saved {url} - as {file_path}")51        except Exception as e:52            self.logger.error(f"ERROR - Could not save {url} - {e}")53    def get_in_memory_image(self, url: str, format: str):54        image_content = self.__download_image_content(url)55        try:56            image_file = io.BytesIO(image_content)57            pil_image = Image.open(image_file).convert('RGB')58            in_mem_file = io.BytesIO()59            pil_image.save(in_mem_file, format=format)60            return in_mem_file.getvalue()61        except Exception as e:62            self.logger.error(f"Could not get image data: {e}")63    def close_connection(self):64        self.driver.quit()65    def __download_image_content(self, url):66        try:67            return requests.get(url).content68        except Exception as e:69            self.logger.error(f"ERROR - Could not download {url} - {e}")70    def __scroll_to_end(self, sleep_time):71        self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")72        time.sleep(sleep_time)73    def __click_and_wait(self, img, wait_time):74        try:75            img.click()76            time.sleep(wait_time)77        except Exception:78            return79    def __add_image_urls_to_set(self, image_urls: set):80        actual_images = self.driver.find_elements_by_css_selector('img.n3VNCb')81        for actual_image in actual_images:82            if actual_image.get_attribute('src') and 'http' in actual_image.get_attribute('src'):...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
