Source code for openwpm.deploy_browsers.selenium_firefox

"""
Workarounds for Selenium headaches.
"""

import errno
import logging
import os
import tempfile
import threading

from openwpm.types import BrowserId

__all__ = ["FirefoxLogInterceptor"]


def mktempfifo(suffix="", prefix="tmp", dir=None):
    """
    Same as 'tempfile.mkdtemp' but creates a fifo instead of a
    directory.
    """
    if dir is None:
        dir = tempfile.gettempdir()
    names = tempfile._get_candidate_names()
    for seq in range(tempfile.TMP_MAX):
        name = next(names)
        file = os.path.join(dir, prefix + name + suffix)
        try:
            os.mkfifo(file, 0o600)
            return file
        except OSError as e:
            if e.errno == errno.EEXIST:
                continue
            raise
    if hasattr(__builtins__, "FileExistsError"):
        exc = FileExistsError  # noqa
    else:
        exc = IOError
    raise exc(errno.EEXIST, "No usable fifo name found")


[docs] class FirefoxLogInterceptor(threading.Thread): """ Intercept logs from Selenium and/or geckodriver, using a named pipe and a detached thread, and feed them to the primary logger for this instance. """ def __init__(self, browser_id: BrowserId) -> None: threading.Thread.__init__( self, name=f"log-interceptor-{browser_id}", ) self.browser_id = browser_id self.fifo = mktempfifo(suffix=".log", prefix="owpm_driver_") self.daemon = True self.logger = logging.getLogger("openwpm") assert self.fifo is not None
[docs] def run(self) -> None: # We might not ever get EOF on the FIFO, so instead we delete # it after we receive the first line (which means the other # end has actually opened it). assert self.fifo is not None try: with open(self.fifo, "rt") as f: for line in f: self.logger.debug( "BROWSER %i: driver: %s" % (self.browser_id, line.strip()) ) if self.fifo is not None: os.unlink(self.fifo) self.fifo = None except Exception: self.logger.error("Error in LogInterceptor", exc_info=True) finally: if self.fifo is not None: os.unlink(self.fifo) self.fifo = None