Instruction:
Explain what the following Python 3 code does
def load_defaults(self):
        '''
        Loads default extraction rules from the user and system extract.conf files.

        Returns None.
        '''
        # Load the user extract file first to ensure its rules take precedence.
        extract_files = [
            self.config.settings.user.extract,
            self.config.settings.system.extract,
        ]

        for extract_file in extract_files:
            if extract_file:
                try:
                    self.load_from_file(extract_file)
                except KeyboardInterrupt as e:
                    raise e
                except Exception as e:
                    if binwalk.core.common.DEBUG:
                        raise Exception("Extractor.load_defaults failed to load file '%s': %s" % (extract_file, str(e)))

Response: Loads default extraction rules from the user and system extract. conf files. Returns None.


Instruction:
Here you have a function in Python 3, explain what it does
def build_output_directory(self, path):
        '''
        Set the output directory for extracted files.

        @path - The path to the file that data will be extracted from.

        Returns None.
        '''
        # If we have not already created an output directory for this target
        # file, create one now
        if not has_key(self.extraction_directories, path):
            basedir = os.path.dirname(path)
            basename = os.path.basename(path)

            if basedir != self.directory:
                # During recursive extraction, extracted files will be in subdirectories
                # of the CWD. This allows us to figure out the subdirectory by simply
                # splitting the target file's base directory on our known CWD.
                #
                # However, the very *first* file being scanned is not necessarily in the
                # CWD, so this will raise an IndexError. This is easy to handle though,
                # since the very first file being scanned needs to have its contents
                # extracted to ${CWD}/_basename.extracted, so we just set the subdir
                # variable to a blank string when an IndexError is encountered.
                try:
                    subdir = basedir.split(self.directory)[1][1:]
                except IndexError as e:
                    subdir = ""
            else:
                subdir = ""

            if self.output_directory_override:
                output_directory = os.path.join(self.directory, subdir, self.output_directory_override)
            else:
                outdir = os.path.join(self.directory, subdir, '_' + basename)
                output_directory = unique_file_name(outdir, extension='extracted')

            if not os.path.exists(output_directory):
                os.mkdir(output_directory)

            self.extraction_directories[path] = output_directory
            self.output[path].directory = os.path.realpath(output_directory) + os.path.sep
        # Else, just use the already created directory
        else:
            output_directory = self.extraction_directories[path]

        return output_directory

Response: Build the output directory for extracted files.


Instruction:
Make a summary of the following Python 3 code
def extract(self, offset, description, file_name, size, name=None):
        '''
        Extract an embedded file from the target file, if it matches an extract rule.
        Called automatically by Binwalk.scan().

        @offset      - Offset inside the target file to begin the extraction.
        @description - Description of the embedded file to extract, as returned by libmagic.
        @file_name   - Path to the target file.
        @size        - Number of bytes to extract.
        @name        - Name to save the file as.

        Returns the name of the extracted file (blank string if nothing was extracted).
        '''
        fname = ''
        rule = None
        recurse = False
        command_line = ''
        original_dir = os.getcwd()
        rules = self.match(description)
        file_path = os.path.realpath(file_name)

        # No extraction rules for this file
        if not rules:
            binwalk.core.common.debug("No extraction rules found for '%s'" % description)
            return (None, None, False, str(None))
        else:
            binwalk.core.common.debug("Found %d matching extraction rules" % len(rules))

        # Generate the output directory name where extracted files will be stored
        output_directory = self.build_output_directory(file_name)

        # Extract to end of file if no size was specified
        if not size:
            size = file_size(file_path) - offset

        if os.path.isfile(file_path):
            binwalk.core.common.debug("Changing directory to: %s" % output_directory)
            os.chdir(output_directory)

            # Extract into subdirectories named by the offset
            if self.extract_into_subdirs:
                # Remove trailing L that is added by hex()
                offset_dir = "0x%X" % offset
                os.mkdir(offset_dir)
                os.chdir(offset_dir)

            # Loop through each extraction rule until one succeeds
            for i in range(0, len(rules)):
                rule = rules[i]

                binwalk.core.common.debug("Processing extraction rule #%d (%s)" % (i, str(rule['cmd'])))

                # Make sure we don't recurse into any extracted directories if
                # instructed not to
                if rule['recurse'] in [True, False]:
                    recurse = rule['recurse']
                else:
                    recurse = True

                binwalk.core.common.debug("Extracting %s[%d:] to %s" % (file_path, offset, name))

                # Copy out the data to disk, if we haven't already
                fname = self._dd(file_path, offset, size, rule['extension'], output_file_name=name)

                # If there was a command specified for this rule, try to execute it.
                # If execution fails, the next rule will be attempted.
                if rule['cmd']:

                    # Note the hash of the original file; if --rm is specified and the
                    # extraction utility modifies the original file rather than creating
                    # a new one (AFAIK none currently do, but could happen in the future),
                    # we don't want to remove this file.
                    if self.remove_after_execute:
                        fname_md5 = file_md5(fname)

                    binwalk.core.common.debug("Executing extraction command %s" % (str(rule['cmd'])))

                    # Execute the specified command against the extracted file
                    if self.run_extractors:
                        (extract_ok, command_line) = self.execute(rule['cmd'], fname, rule['codes'])
                    else:
                        extract_ok = True
                        command_line = ''

                    binwalk.core.common.debug("Ran extraction command: %s" % command_line)
                    binwalk.core.common.debug("Extraction successful: %s" % extract_ok)

                    # Only clean up files if remove_after_execute was specified.
                    # Only clean up files if the file was extracted sucessfully, or if we've run
                    # out of extractors.
                    if self.remove_after_execute and (extract_ok == True or i == (len(rules) - 1)):

                        # Remove the original file that we extracted,
                        # if it has not been modified by the extractor.
                        try:
                            if file_md5(fname) == fname_md5:
                                os.unlink(fname)
                        except KeyboardInterrupt as e:
                            raise e
                        except Exception as e:
                            pass

                    # If the command executed OK, don't try any more rules
                    if extract_ok == True:
                        break
                    # Else, remove the extracted file if this isn't the last rule in the list.
                    # If it is the last rule, leave the file on disk for the
                    # user to examine.
                    elif i != (len(rules) - 1):
                        try:
                            os.unlink(fname)
                        except KeyboardInterrupt as e:
                            raise e
                        except Exception as e:
                            pass

                # If there was no command to execute, just use the first rule
                else:
                    break

            binwalk.core.common.debug("Changing directory back to: %s" % original_dir)
            os.chdir(original_dir)

        return (output_directory, fname, recurse, command_line)

Response: Extracts an embedded file from the target file.


Instruction:
Here you have a function in Python 3, explain what it does
def _entry_offset(self, index, entries, description):
        '''
        Gets the offset of the first entry that matches the description.

        @index       - Index into the entries list to begin searching.
        @entries     - Dictionary of result entries.
        @description - Case insensitive description.

        Returns the offset, if a matching description is found.
        Returns -1 if a matching description is not found.
        '''
        description = description.lower()

        for (offset, infos) in entries[index:]:
            for info in infos:
                if info['description'].lower().startswith(description):
                    return offset
        return -1

Response: Returns the offset of the first entry that matches the description.


Instruction:
Can you implement a function in Python 3 that
checks to see if the provided description string matches an extract rule. Returns the associated rule dictionary ordered by priority.

Response:
def match(self, description):
        '''
        Check to see if the provided description string matches an extract rule.
        Called internally by self.extract().

        @description - Description string to check.

        Returns the associated rule dictionary if a match is found.
        Returns None if no match is found.
        '''
        rules = []
        ordered_rules = []
        description = description.lower()

        for rule in self.extract_rules:
            if rule['regex'].search(description):
                rules.append(rule)

        # Plugin rules should take precedence over external extraction commands.
        for rule in rules:
            if callable(rule['cmd']):
                ordered_rules.append(rule)
        for rule in rules:
            if not callable(rule['cmd']):
                ordered_rules.append(rule)

        return ordered_rules


Instruction:
Can you generate the documentation for the following Python 3 function
def _parse_rule(self, rule):
        '''
        Parses an extraction rule.

        @rule - Rule string.

        Returns an array of ['<case insensitive matching string>', '<file extension>', '<command to run>', '<comma separated return codes>', <recurse into extracted directories: True|False>].
        '''
        values = rule.strip().split(self.RULE_DELIM, 4)

        if len(values) >= 4:
            codes = values[3].split(',')
            for i in range(0, len(codes)):
                try:
                    codes[i] = int(codes[i], 0)
                except ValueError as e:
                    binwalk.core.common.warning("The specified return code '%s' for extractor '%s' is not a valid number!" % (codes[i], values[0]))
            values[3] = codes

        if len(values) >= 5:
            values[4] = (values[4].lower() == 'true')

        return values

Response: Parses an extraction rule.


Instruction:
Write a Python 3 script to
extract a file embedded inside the target file. @file_name - Path to the target file. @offset - Offset inside the target file where the embedded file begins. @size - Number of bytes to extract. @extension - The file exension to assign to the extracted file on disk. @output_file_name - The requested name of the output file. Returns the extracted file name.

Response:
def _dd(self, file_name, offset, size, extension, output_file_name=None):
        '''
        Extracts a file embedded inside the target file.

        @file_name        - Path to the target file.
        @offset           - Offset inside the target file where the embedded file begins.
        @size             - Number of bytes to extract.
        @extension        - The file exension to assign to the extracted file on disk.
        @output_file_name - The requested name of the output file.

        Returns the extracted file name.
        '''
        total_size = 0
        # Default extracted file name is <displayed hex offset>.<extension>
        default_bname = "%X" % (offset + self.config.base)

        # Make sure the output file name is a string
        if output_file_name is not None:
            output_file_name = str(output_file_name)

        if self.max_size and size > self.max_size:
            size = self.max_size

        if not output_file_name or output_file_name is None:
            bname = default_bname
        else:
            # Strip the output file name of invalid/dangerous characters (like file paths)
            bname = os.path.basename(output_file_name)

        fname = unique_file_name(bname, extension)

        try:
            # If byte swapping is enabled, we need to start reading at a swap-size
            # aligned offset, then index in to the read data appropriately.
            if self.config.swap_size:
                adjust = offset % self.config.swap_size
            else:
                adjust = 0

            offset -= adjust

            # Open the target file and seek to the offset
            fdin = self.config.open_file(file_name)
            fdin.seek(offset)

            # Open the output file
            try:
                fdout = BlockFile(fname, 'w')
            except KeyboardInterrupt as e:
                raise e
            except Exception as e:
                # Fall back to the default name if the requested name fails
                fname = unique_file_name(default_bname, extension)
                fdout = BlockFile(fname, 'w')

            while total_size < size:
                (data, dlen) = fdin.read_block()
                if dlen < 1:
                    break
                else:
                    total_size += (dlen - adjust)
                    if total_size > size:
                        dlen -= (total_size - size)
                    fdout.write(str2bytes(data[adjust:dlen]))
                    adjust = 0

            # Cleanup
            fdout.close()
            fdin.close()
        except KeyboardInterrupt as e:
            raise e
        except Exception as e:
            raise Exception("Extractor.dd failed to extract data from '%s' to '%s': %s" %
                            (file_name, fname, str(e)))

        binwalk.core.common.debug("Carved data block 0x%X - 0x%X from '%s' to '%s'" %
                                  (offset, offset + size, file_name, fname))
        return fname


Instruction:
Given the following Python 3 function, write the documentation
def execute(self, cmd, fname, codes=[0, None]):
        '''
        Execute a command against the specified file.

        @cmd   - Command to execute.
        @fname - File to run command against.
        @codes - List of return codes indicating cmd success.

        Returns True on success, False on failure, or None if the external extraction utility could not be found.
        '''
        tmp = None
        rval = 0
        retval = True
        command_list = []

        binwalk.core.common.debug("Running extractor '%s'" % str(cmd))

        try:
            if callable(cmd):
                command_list.append(get_class_name_from_method(cmd))

                try:
                    retval = cmd(fname)
                except KeyboardInterrupt as e:
                    raise e
                except Exception as e:
                    binwalk.core.common.warning("Internal extractor '%s' failed with exception: '%s'" % (str(cmd), str(e)))
            elif cmd:
                # If not in debug mode, create a temporary file to redirect
                # stdout and stderr to
                if not binwalk.core.common.DEBUG:
                    tmp = tempfile.TemporaryFile()

                # Generate unique file paths for all paths in the current
                # command that are surrounded by UNIQUE_PATH_DELIMITER
                while self.UNIQUE_PATH_DELIMITER in cmd:
                    need_unique_path = cmd.split(self.UNIQUE_PATH_DELIMITER)[
                        1].split(self.UNIQUE_PATH_DELIMITER)[0]
                    unique_path = binwalk.core.common.unique_file_name(need_unique_path)
                    cmd = cmd.replace(self.UNIQUE_PATH_DELIMITER + need_unique_path + self.UNIQUE_PATH_DELIMITER, unique_path)

                # Execute.
                for command in cmd.split("&&"):

                    # Replace all instances of FILE_NAME_PLACEHOLDER in the
                    # command with fname
                    command = command.strip().replace(self.FILE_NAME_PLACEHOLDER, fname)

                    binwalk.core.common.debug("subprocess.call(%s, stdout=%s, stderr=%s)" % (command, str(tmp), str(tmp)))
                    rval = subprocess.call(shlex.split(command), stdout=tmp, stderr=tmp)

                    if rval in codes:
                        retval = True
                    else:
                        retval = False

                    binwalk.core.common.debug('External extractor command "%s" completed with return code %d (success: %s)' % (cmd, rval, str(retval)))
                    command_list.append(command)

                    # TODO: Should errors from all commands in a command string be checked? Currently we only support
                    #       specifying one set of error codes, so at the moment, this is not done; it is up to the
                    #       final command to return success or failure (which presumably it will if previous necessary
                    #       commands were not successful, but this is an assumption).
                    # if retval == False:
                    #    break

        except KeyboardInterrupt as e:
            raise e
        except Exception as e:
            binwalk.core.common.warning("Extractor.execute failed to run external extractor '%s': %s, '%s' might not be installed correctly" % (str(cmd), str(e), str(cmd)))
            retval = None

        if tmp is not None:
            tmp.close()

        return (retval, '&&'.join(command_list))

Response: Execute a command against the specified file.


Instruction:
Can you write a function in Python 3 where it
formats a line of text to fit in the terminal window.

Response:
def _format_line(self, line):
        '''
        Formats a line of text to fit in the terminal window.
        For Tim.
        '''
        delim = '\n'
        offset = 0
        self.string_parts = []

        # Split the line into an array of columns, e.g., ['0', '0x00000000',
        # 'Some description here']
        line_columns = line.split(None, self.num_columns - 1)
        if line_columns:
            # Find where the start of the last column (description) starts in the line of text.
            # All line wraps need to be aligned to this offset.
            offset = line.rfind(line_columns[-1])
            # The delimiter will be a newline followed by spaces padding out
            # the line wrap to the alignment offset.
            delim += ' ' * offset

        if line_columns and self.fit_to_screen and len(line) > self.SCREEN_WIDTH:
            # Calculate the maximum length that each wrapped line can be
            max_line_wrap_length = self.SCREEN_WIDTH - offset
            # Append all but the last column to formatted_line
            formatted_line = line[:offset]

            # Loop to split up line into multiple max_line_wrap_length pieces
            while len(line[offset:]) > max_line_wrap_length:
                # Find the nearest space to wrap the line at (so we don't split
                # a word across two lines)
                split_offset = line[
                    offset:offset + max_line_wrap_length].rfind(' ')
                # If there were no good places to split the line, just truncate
                # it at max_line_wrap_length
                if split_offset < 1:
                    split_offset = max_line_wrap_length

                self._append_to_data_parts(line, offset, offset + split_offset)
                offset += split_offset

            # Add any remaining data (guarunteed to be max_line_wrap_length
            # long or shorter) to self.string_parts
            self._append_to_data_parts(line, offset, offset + len(line[offset:]))

            # Append self.string_parts to formatted_line; each part seperated
            # by delim
            formatted_line += delim.join(self.string_parts)
        else:
            formatted_line = line

        return formatted_line


Instruction:
How would you explain what the following Python 3 function does
def _configure_formatting(self):
        '''
        Configures output formatting, and fitting output to the current terminal width.

        Returns None.
        '''
        self.format_strings(self.DEFAULT_FORMAT, self.DEFAULT_FORMAT)

        if self.fit_to_screen:
            try:
                import fcntl
                import struct
                import termios

                # Get the terminal window width
                hw = struct.unpack('hh', fcntl.ioctl(1, termios.TIOCGWINSZ, '1234'))
                self.SCREEN_WIDTH = self.HEADER_WIDTH = hw[1]
            except KeyboardInterrupt as e:
                raise e
            except Exception:
                pass

Response: Configures output formatting and fitting output to the current terminal width.


Instruction:
Here you have a function in Python 3, explain what it does
def _magic_signature_files(self, system_only=False, user_only=False):
        '''
        Find all user/system magic signature files.

        @system_only - If True, only the system magic file directory will be searched.
        @user_only   - If True, only the user magic file directory will be searched.

        Returns a list of user/system magic signature files.
        '''
        files = []
        user_binarch = self._user_path(self.BINWALK_MAGIC_DIR, self.BINARCH_MAGIC_FILE)
        system_binarch = self._system_path(self.BINWALK_MAGIC_DIR, self.BINARCH_MAGIC_FILE)

        def list_files(dir_path):
            # Ignore hidden dotfiles.
            return [os.path.join(dir_path, x) for x in os.listdir(dir_path) if not x.startswith('.')]

        if not system_only:
            user_dir = os.path.join(self.user_dir, self.BINWALK_USER_DIR, self.BINWALK_MAGIC_DIR)
            files += list_files(user_dir)
        if not user_only:
            system_dir = os.path.join(self.system_dir, self.BINWALK_MAGIC_DIR)
            files += list_files(system_dir)

        # Don't include binarch signatures in the default list of signature files.
        # It is specifically loaded when -A is specified on the command line.
        if user_binarch in files:
            files.remove(user_binarch)
        if system_binarch in files:
            files.remove(system_binarch)

        return files

Response: Return a list of all user and system magic signature files.


Instruction:
Implement a function in Python 3 to
find the specified magic file in the system or user magic file directories.

Response:
def find_magic_file(self, fname, system_only=False, user_only=False):
        '''
        Finds the specified magic file name in the system / user magic file directories.

        @fname       - The name of the magic file.
        @system_only - If True, only the system magic file directory will be searched.
        @user_only   - If True, only the user magic file directory will be searched.

        If system_only and user_only are not set, the user directory is always searched first.

        Returns the path to the file on success; returns None on failure.
        '''
        loc = None

        if not system_only:
            fpath = self._user_path(self.BINWALK_MAGIC_DIR, fname)
            if os.path.exists(fpath) and common.file_size(fpath) > 0:
                loc = fpath

        if loc is None and not user_only:
            fpath = self._system_path(self.BINWALK_MAGIC_DIR, fname)
            if os.path.exists(fpath) and common.file_size(fpath) > 0:
                loc = fpath

        return fpath


Instruction:
How would you implement a function in Python 3 that
gets the user s home directory.

Response:
def _get_user_dir(self):
        '''
        Get the user's home directory.
        '''
        try:
            # This should work in both Windows and Unix environments
            for envname in ['USERPROFILE', 'HOME']:
                user_dir = os.getenv(envname)
                if user_dir is not None:
                    return user_dir
        except KeyboardInterrupt as e:
            raise e
        except Exception:
            pass

        return ''


Instruction:
Create a Python 3 function to
build an absolute path and creates the directory and file if they don t already exist.

Response:
def _file_path(self, dirname, filename):
        '''
        Builds an absolute path and creates the directory and file if they don't already exist.

        @dirname  - Directory path.
        @filename - File name.

        Returns a full path of 'dirname/filename'.
        '''
        if not os.path.exists(dirname):
            try:
                os.makedirs(dirname)
            except KeyboardInterrupt as e:
                raise e
            except Exception:
                pass

        fpath = os.path.join(dirname, filename)

        if not os.path.exists(fpath):
            try:
                open(fpath, "w").close()
            except KeyboardInterrupt as e:
                raise e
            except Exception:
                pass

        return fpath


Instruction:
Explain what the following Python 3 code does
def _user_path(self, subdir, basename=''):
        '''
        Gets the full path to the 'subdir/basename' file in the user binwalk directory.

        @subdir   - Subdirectory inside the user binwalk directory.
        @basename - File name inside the subdirectory.

        Returns the full path to the 'subdir/basename' file.
        '''
        try:
            return self._file_path(os.path.join(self.user_dir, self.BINWALK_USER_DIR, subdir), basename)
        except KeyboardInterrupt as e:
            raise e
        except Exception:
            return None

Response: Gets the full path to the user binwalk file.


Instruction:
Write a Python 3 script to
return the full path to the basename file in the system binwalk directory.

Response:
def _system_path(self, subdir, basename=''):
        '''
        Gets the full path to the 'subdir/basename' file in the system binwalk directory.

        @subdir   - Subdirectory inside the system binwalk directory.
        @basename - File name inside the subdirectory.

        Returns the full path to the 'subdir/basename' file.
        '''
        try:
            return self._file_path(os.path.join(self.system_dir, subdir), basename)
        except KeyboardInterrupt as e:
            raise e
        except Exception:
            return None


Instruction:
Given the following Python 3 function, write the documentation
def _decrypt_and_extract(self, fname):
        '''
        This does the extraction (e.g., it decrypts the image and writes it to a new file on disk).
        '''
        with open(fname, "r") as fp_in:
            encrypted_data = fp_in.read()

            decrypted_data = self._hilink_decrypt(encrypted_data)

            with open(binwalk.core.common.unique_file_name(fname[:-4], "dec"), "w") as fp_out:
                fp_out.write(decrypted_data)

Response: This does the decryption and extraction of the image.


Instruction:
Write a Python 3 function that can
lock the main thread while the subscription in running

Response:
def run():
    print("Environment", os.environ)
    try:
        os.environ["SELENIUM"]
    except KeyError:
        print("Please set the environment variable SELENIUM to Selenium URL")
        sys.exit(1)

    driver = WhatsAPIDriver(client='remote', command_executor=os.environ["SELENIUM"])
    print("Waiting for QR")
    driver.wait_for_login()
    print("Bot started")

    driver.subscribe_new_messages(NewMessageObserver())
    print("Waiting for new messages...")

    """ Locks the main thread while the subscription in running """
    while True:
        time.sleep(60)


Instruction:
Write a Python 3 script for
functioning to save the firefox profile to the permanant one

Response:
def save_firefox_profile(self, remove_old=False):
        """Function to save the firefox profile to the permanant one"""
        self.logger.info("Saving profile from %s to %s" % (self._profile.path, self._profile_path))

        if remove_old:
            if os.path.exists(self._profile_path):
                try:
                    shutil.rmtree(self._profile_path)
                except OSError:
                    pass

            shutil.copytree(os.path.join(self._profile.path), self._profile_path,
                            ignore=shutil.ignore_patterns("parent.lock", "lock", ".parentlock"))
        else:
            for item in os.listdir(self._profile.path):
                if item in ["parent.lock", "lock", ".parentlock"]:
                    continue
                s = os.path.join(self._profile.path, item)
                d = os.path.join(self._profile_path, item)
                if os.path.isdir(s):
                    shutil.copytree(s, d,
                                    ignore=shutil.ignore_patterns("parent.lock", "lock", ".parentlock"))
                else:
                    shutil.copy2(s, d)

        with open(os.path.join(self._profile_path, self._LOCAL_STORAGE_FILE), 'w') as f:
            f.write(dumps(self.get_local_storage()))


Instruction:
Write a Python 3 function for
waiting for QR to go away

Response:
def wait_for_login(self, timeout=90):
        """Waits for the QR to go away"""
        WebDriverWait(self.driver, timeout).until(
            EC.visibility_of_element_located((By.CSS_SELECTOR, self._SELECTORS['mainPage']))
        )


Instruction:
Write a Python 3 script for
getting pairing QR code from client

Response:
def get_qr(self, filename=None):
        """Get pairing QR code from client"""
        if "Click to reload QR code" in self.driver.page_source:
            self.reload_qr()
        qr = self.driver.find_element_by_css_selector(self._SELECTORS['qrCode'])
        if filename is None:
            fd, fn_png = tempfile.mkstemp(prefix=self.username, suffix='.png')
        else:
            fd = os.open(filename, os.O_RDWR | os.O_CREAT)
            fn_png = os.path.abspath(filename)
        self.logger.debug("QRcode image saved at %s" % fn_png)
        qr.screenshot(fn_png)
        os.close(fd)
        return fn_png


Instruction:
Create a Python 3 function for
fetching list of all contacts

Response:
def get_contacts(self):
        """
        Fetches list of all contacts
        This will return chats with people from the address book only
        Use get_all_chats for all chats

        :return: List of contacts
        :rtype: list[Contact]
        """
        all_contacts = self.wapi_functions.getAllContacts()
        return [Contact(contact, self) for contact in all_contacts]


Instruction:
Can you write a function in Python 3 where it
fetches list of added contacts

Response:
def get_my_contacts(self):
        """
        Fetches list of added contacts

        :return: List of contacts
        :rtype: list[Contact]
        """
        my_contacts = self.wapi_functions.getMyContacts()
        return [Contact(contact, self) for contact in my_contacts]


Instruction:
Write a Python 3 script for
fetching all chats in the system

Response:
def get_all_chats(self):
        """
        Fetches all chats

        :return: List of chats
        :rtype: list[Chat]
        """
        chats = self.wapi_functions.getAllChats()
        if chats:
            return [factory_chat(chat, self) for chat in chats]
        else:
            return []


Instruction:
Write a Python 3 script for
fetching all unread messages from the server.

Response:
def get_unread(self, include_me=False, include_notifications=False, use_unread_count=False):
        """
        Fetches unread messages
        :param include_me: Include user's messages
        :type include_me: bool or None
        :param include_notifications: Include events happening on chat
        :type include_notifications: bool or None
        :param use_unread_count: If set uses chat's 'unreadCount' attribute to fetch last n messages from chat
        :type use_unread_count: bool
        :return: List of unread messages grouped by chats
        :rtype: list[MessageGroup]
        """
        raw_message_groups = self.wapi_functions.getUnreadMessages(include_me, include_notifications, use_unread_count)

        unread_messages = []
        for raw_message_group in raw_message_groups:
            chat = factory_chat(raw_message_group, self)
            messages = [factory_message(message, self) for message in raw_message_group['messages']]
            messages.sort(key=lambda message: message.timestamp)
            unread_messages.append(MessageGroup(chat, messages))

        return unread_messages


Instruction:
Write a Python 3 script to
fetch all messages in a chat

Response:
def get_all_messages_in_chat(self, chat, include_me=False, include_notifications=False):
        """
        Fetches messages in chat

        :param include_me: Include user's messages
        :type include_me: bool or None
        :param include_notifications: Include events happening on chat
        :type include_notifications: bool or None
        :return: List of messages in chat
        :rtype: list[Message]
        """
        message_objs = self.wapi_functions.getAllMessagesInChat(chat.id, include_me, include_notifications)

        messages = []
        for message in message_objs:
            yield(factory_message(message, self))


Instruction:
Explain what the following Python 3 code does
def get_all_message_ids_in_chat(self, chat, include_me=False, include_notifications=False):
        return self.wapi_functions.getAllMessageIdsInChat(chat.id, include_me, include_notifications)

Response: Fetches all message ids in a chat


Instruction:
Implement a function in Python 3 to
fetch a message by its ID

Response:
def get_message_by_id(self, message_id):
        """
        Fetch a message

        :param message_id: Message ID
        :type message_id: str
        :return: Message or False
        :rtype: Message
        """
        result = self.wapi_functions.getMessageById(message_id)

        if result:
            result = factory_message(result, self)

        return result


Instruction:
Write a Python 3 function that can
fetch a contact given its ID

Response:
def get_contact_from_id(self, contact_id):
        """
        Fetches a contact given its ID

        :param contact_id: Contact ID
        :type contact_id: str
        :return: Contact or Error
        :rtype: Contact
        """
        contact = self.wapi_functions.getContact(contact_id)

        if contact is None:
            raise ContactNotFoundError("Contact {0} not found".format(contact_id))

        return Contact(contact, self)


Instruction:
Write a Python 3 script for
fetching a chat given its ID

Response:
def get_chat_from_id(self, chat_id):
        """
        Fetches a chat given its ID

        :param chat_id: Chat ID
        :type chat_id: str
        :return: Chat or Error
        :rtype: Chat
        """
        chat = self.wapi_functions.getChatById(chat_id)
        if chat:
            return factory_chat(chat, self)

        raise ChatNotFoundError("Chat {0} not found".format(chat_id))


Instruction:
Given the following Python 3 function, write the documentation
def get_chat_from_phone_number(self, number, createIfNotFound = False):
        for chat in self.get_all_chats():
            if not isinstance(chat, UserChat) or number not in chat.id:
                continue
            return chat
        if createIfNotFound:
            self.create_chat_by_number(number)
            self.wait_for_login()
            for chat in self.get_all_chats():
                if not isinstance(chat, UserChat) or number not in chat.id:
                    continue
                return chat

        raise ChatNotFoundError('Chat for phone {0} not found'.format(number))

Response: Gets chat by phone number


Instruction:
Can you implement a function in Python 3 that
returns the status of the driver

Response:
def get_status(self):
        """
        Returns status of the driver

        :return: Status
        :rtype: WhatsAPIDriverStatus
        """
        if self.driver is None:
            return WhatsAPIDriverStatus.NotConnected
        if self.driver.session_id is None:
            return WhatsAPIDriverStatus.NotConnected
        try:
            self.driver.find_element_by_css_selector(self._SELECTORS['mainPage'])
            return WhatsAPIDriverStatus.LoggedIn
        except NoSuchElementException:
            pass
        try:
            self.driver.find_element_by_css_selector(self._SELECTORS['qrCode'])
            return WhatsAPIDriverStatus.NotLoggedIn
        except NoSuchElementException:
            pass
        return WhatsAPIDriverStatus.Unknown


Instruction:
Here you have a function in Python 3, explain what it does
def contact_get_common_groups(self, contact_id):
        for group in self.wapi_functions.getCommonGroups(contact_id):
            yield factory_chat(group, self)

Response: Returns the groups common between a user and a contact with given id.


Instruction:
Can you generate the documentation for the following Python 3 function
def convert_to_base64(self, path):

        mime = magic.Magic(mime=True)
        content_type = mime.from_file(path)
        archive = ''
        with open(path, "rb") as image_file:
            archive = b64encode(image_file.read())
            archive = archive.decode('utf-8')
        return 'data:' + content_type + ';base64,' + archive

Response: converts the file path to base64 and returns the converted string formatted for the send media function


Instruction:
Can you generate the documentation for the following Python 3 function
def send_media(self, path, chatid, caption):
        imgBase64 = self.convert_to_base64(path)
        filename = os.path.split(path)[-1]
        return self.wapi_functions.sendImage(imgBase64, chatid, filename, caption)

Response: This method is used to send a file to the chat using the sendImage function of wapi. js


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_profile_pic_from_id(self, id):
        profile_pic = self.wapi_functions.getProfilePicFromId(id)
        if profile_pic:
            return b64decode(profile_pic)
        else:
            return False

Response: Get full profile picture from an ID


Instruction:
Here you have a function in Python 3, explain what it does
def get_profile_pic_small_from_id(self, id):
        profile_pic_small = self.wapi_functions.getProfilePicSmallFromId(id)
        if profile_pic:
            return b64decode(profile_pic_small)
        else:
            return False

Response: Get small profile pic from an ID


Instruction:
Implement a Python 3 function for
using this method to delete a message from a chat

Response:
def delete_message(self, chat_id, message_array, revoke=False):
        """
        Delete a chat

        :param chat_id: id of chat
        :param message_array: one or more message(s) id
        :param revoke: Set to true so the message will be deleted for everyone, not only you
        :return:
        """
        return self.wapi_functions.deleteMessage(chat_id, message_array, revoke=False)


Instruction:
Create a Python 3 function for
checking if a number is valid in the whatsapp service.

Response:
def check_number_status(self, number_id):
        """
        Check if a number is valid/registered in the whatsapp service

        :param number_id: number id
        :return:
        """
        number_status = self.wapi_functions.checkNumberStatus(number_id)
        return NumberStatus(number_status, self)


Instruction:
Make a summary of the following Python 3 code
def get_unread_messages(self,
                            include_me=False,
                            include_notifications=False):
        """
        I fetch unread messages.

        :param include_me: if user's messages are to be included
        :type  include_me: bool

        :param include_notifications: if events happening on chat are to be included
        :type  include_notifications: bool

        :return: list of unread messages
        :rtype: list
        """
        return list(self.driver.get_unread_messages_in_chat(
            self.id,
            include_me,
            include_notifications
        ))

Response: I fetch unread messages.


Instruction:
Here you have a function in Python 3, explain what it does
def load_earlier_messages_till(self, last):
        timestamp = time.mktime(last.timetuple())
        self.driver.wapi_functions.loadEarlierMessagesTillDate(self.id, timestamp)

Response: Triggers loading of messages till a specific point in time


Instruction:
Explain what the following Python 3 code does
def factory_message(js_obj, driver):
    if js_obj is None:
        return

    if "lat" in js_obj and "lng" in js_obj and js_obj["lat"] and js_obj["lng"]:
        return GeoMessage(js_obj, driver)

    if js_obj["isMedia"]:
        return MediaMessage(js_obj, driver)

    if js_obj["isNotification"]:
        return NotificationMessage(js_obj, driver)

    if 'isMMS' in js_obj and js_obj["isMMS"]:
        return MMSMessage(js_obj, driver)

    if js_obj["type"] in ["vcard", "multi_vcard"]:
        return VCardMessage(js_obj, driver)

    return Message(js_obj, driver)

Response: Factory function for creating appropriate object given selenium JS object


Instruction:
How would you code a function in Python 3 to
initial the global logger variable

Response:
def create_logger():
    """Initial the global logger variable"""
    global logger

    formatter = logging.Formatter('%(asctime)s|%(levelname)s|%(message)s')
    handler = TimedRotatingFileHandler(log_file, when="midnight", interval=1)
    handler.setFormatter(formatter)
    handler.setLevel(log_level)
    handler.suffix = "%Y-%m-%d"
    logger = logging.getLogger("sacplus")
    logger.setLevel(log_level)
    logger.addHandler(handler)


Instruction:
Can you implement a function in Python 3 that
initialises a new webwhatsapi object based on the given client_id.

Response:
def init_driver(client_id):
    """Initialises a new driver via webwhatsapi module

    @param client_id: ID of user client
    @return webwhatsapi object
    """

    # Create profile directory if it does not exist
    profile_path = CHROME_CACHE_PATH + str(client_id)
    if not os.path.exists(profile_path):
        os.makedirs(profile_path)

    # Options to customize chrome window
    chrome_options = [
        'window-size=' + CHROME_WINDOW_SIZE,
        '--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/60.0.3112.78 Chrome/60.0.3112.78 Safari/537.36'
    ]
    if CHROME_IS_HEADLESS:
        chrome_options.append('--headless')
    if CHROME_DISABLE_GPU:
        chrome_options.append('--disable-gpu')

    # Create a whatsapidriver object
    d = WhatsAPIDriver(
        username=client_id,
        profile=profile_path,
        client='chrome',
        chrome_options=chrome_options
    )
    return d


Instruction:
How would you explain what the following Python 3 function does
def delete_client(client_id, preserve_cache):
    if client_id in drivers:
        drivers.pop(client_id).quit()
        try:
            timers[client_id].stop()
            timers[client_id] = None
            release_semaphore(client_id)
            semaphores[client_id] = None
        except:
            pass

    if not preserve_cache:
        pth = CHROME_CACHE_PATH + g.client_id
        shutil.rmtree(pth)

Response: Delete all objects related to a client.


Instruction:
Can you generate the documentation for the following Python 3 function
def init_timer(client_id):
    if client_id in timers and timers[client_id]:
        timers[client_id].start()
        return
    # Create a timer to call check_new_message function after every 2 seconds.
    # client_id param is needed to be passed to check_new_message
    timers[client_id] = RepeatedTimer(2, check_new_messages, client_id)

Response: Create a timer for the client driver to watch for events


Instruction:
How would you code a function in Python 3 to
check for new unread messages and send them to the custom api

Response:
def check_new_messages(client_id):
    """Check for new unread messages and send them to the custom api

    @param client_id: ID of client user
    """
    # Return if driver is not defined or if whatsapp is not logged in.
    # Stop the timer as well
    if client_id not in drivers or not drivers[client_id] or not drivers[client_id].is_logged_in():
        timers[client_id].stop()
        return

    # Acquire a lock on thread
    if not acquire_semaphore(client_id, True):
        return

    try:
        # Get all unread messages
        res = drivers[client_id].get_unread()
        # Mark all of them as seen
        for message_group in res:
            message_group.chat.send_seen()
        # Release thread lock
        release_semaphore(client_id)
        # If we have new messages, do something with it
        if res:
            print(res)
    except:
        pass
    finally:
        # Release lock anyway, safekeeping
        release_semaphore(client_id)


Instruction:
Write a Python 3 script to
get the status of a perticular client.

Response:
def get_client_info(client_id):
    """Get the status of a perticular client, as to he/she is connected or not

    @param client_id: ID of client user
    @return JSON object {
        "driver_status": webdriver status
        "is_alive": if driver is active or not
        "is_logged_in": if user is logged in or not
        "is_timer": if timer is running or not
    }
    """
    if client_id not in drivers:
        return None

    driver_status = drivers[client_id].get_status()
    is_alive = False
    is_logged_in = False
    if (driver_status == WhatsAPIDriverStatus.NotLoggedIn
        or driver_status == WhatsAPIDriverStatus.LoggedIn):
        is_alive = True
    if driver_status == WhatsAPIDriverStatus.LoggedIn:
        is_logged_in = True

    return {
        "is_alive": is_alive,
        "is_logged_in": is_logged_in,
        "is_timer": bool(timers[client_id]) and timers[client_id].is_running
    }


Instruction:
Explain what the following Python 3 code does
def create_static_profile_path(client_id):
    profile_path = os.path.join(STATIC_FILES_PATH, str(client_id))
    if not os.path.exists(profile_path):
        os.makedirs(profile_path)
    return profile_path

Response: Create a profile path folder if not exist


Instruction:
Can you generate the documentation for the following Python 3 function
def before_request():
    global logger

    if not request.url_rule:
        abort(404)

    if logger == None:
        create_logger()
    logger.info("API call " + request.method + " " + request.url)

    auth_key = request.headers.get('auth-key')
    g.client_id = request.headers.get('client_id')
    rule_parent = request.url_rule.rule.split('/')[1]

    if API_KEY and auth_key != API_KEY:
        abort(401, 'you must send valid auth-key')
        raise Exception()

    if not g.client_id and rule_parent != 'admin':
        abort(400, 'client ID is mandatory')

    acquire_semaphore(g.client_id)

    # Create a driver object if not exist for client requests.
    if rule_parent != 'admin':
        if g.client_id not in drivers:
            drivers[g.client_id] = init_client(g.client_id)

        g.driver = drivers[g.client_id]
        g.driver_status = WhatsAPIDriverStatus.Unknown

        if g.driver is not None:
            g.driver_status = g.driver.get_status()

        # If driver status is unkown, means driver has closed somehow, reopen it
        if (g.driver_status != WhatsAPIDriverStatus.NotLoggedIn
            and g.driver_status != WhatsAPIDriverStatus.LoggedIn):
            drivers[g.client_id] = init_client(g.client_id)
            g.driver_status = g.driver.get_status()

        init_timer(g.client_id)

Response: This function runs before every API request. It creates a new object and checks for required prerequisites and sets global variables for other functions to use.


Instruction:
Implement a function in Python 3 to
create a new client driver.

Response:
def create_client():
    """Create a new client driver. The driver is automatically created in
    before_request function."""
    result = False
    if g.client_id in drivers:
        result = True
    return jsonify({'Success': result})


Instruction:
Here you have a function in Python 3, explain what it does
def delete_client():
    preserve_cache = request.args.get('preserve_cache', False)
    delete_client(g.client_id, preserve_cache)
    return jsonify({'Success': True})

Response: Delete all objects related to client


Instruction:
Implement a function in Python 3 to
capture chrome screen image and send it back.

Response:
def get_screen():
    """Capture chrome screen image and send it back. If the screen is currently
    at qr scanning phase, return the image of qr only, else return image of full
    screen"""
    img_title = 'screen_' + g.client_id + '.png'
    image_path = STATIC_FILES_PATH + img_title
    if g.driver_status != WhatsAPIDriverStatus.LoggedIn:
        try:
            g.driver.get_qr(image_path)
            return send_file(image_path, mimetype='image/png')
        except Exception as err:
            pass
    g.driver.screenshot(image_path)
    return send_file(image_path, mimetype='image/png')


Instruction:
How would you code a function in Python 3 to
get all unread messages

Response:
def get_unread_messages():
    """Get all unread messages"""
    mark_seen = request.args.get('mark_seen', True)
    unread_msg = g.driver.get_unread()

    if mark_seen:
        for msg in unread_msg:
            msg.chat.send_seen()

    return jsonify(unread_msg)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_messages(chat_id):

    mark_seen = request.args.get('mark_seen', True)

    chat = g.driver.get_chat_from_id(chat_id)
    msgs = list(g.driver.get_all_messages_in_chat(chat))

    for msg in msgs:
        print(msg.id)

    if mark_seen:
        for msg in msgs:
            try:
                msg.chat.send_seen()
            except:
                pass

    return jsonify(msgs)

Response: Return all of the chat messages in a single chat


Instruction:
Can you write a function in Python 3 where it
sends a message to a chat

Response:
def send_message(chat_id):
    """Send a message to a chat
    If a media file is found, send_media is called, else a simple text message
    is sent
    """

    files = request.files

    if files:
        res = send_media(chat_id, request)
    else:
        message = request.form.get('message')
        res = g.driver.chat_send_message(chat_id, message)

    if res:
        return jsonify(res)
    else:
        return False


Instruction:
Write a Python 3 function that can
download a media file from the message

Response:
def download_message_media(msg_id):
    """Download a media file"""
    message = g.driver.get_message_by_id(msg_id)

    if not message or not message.mime:
        abort(404)

    profile_path = create_static_profile_path(g.client_id)
    filename = message.save_media(profile_path, True)

    if os.path.exists(filename):
        return send_file(filename, mimetype=message.mime)

    abort(404)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_active_clients():
    global drivers

    if not drivers:
        return jsonify([])

    result = {client: get_client_info(client) for client in drivers}
    return jsonify(result)

Response: Get a list of all active clients and their status


Instruction:
Can you generate a brief explanation for the following Python 3 code
def run_clients():
    clients = request.form.get('clients')
    if not clients:
        return jsonify({'Error': 'no clients provided'})

    result = {}
    for client_id in clients.split(','):
        if client_id not in drivers:
            init_client(client_id)
            init_timer(client_id)

        result[client_id] = get_client_info(client_id)

    return jsonify(result)

Response: Create driver for all clients


Instruction:
Given the following Python 3 function, write the documentation
def kill_clients():
    clients = request.form.get('clients').split(',')
    kill_dead = request.args.get('kill_dead', default=False)
    kill_dead = kill_dead and kill_dead in ['true', '1']

    if not kill_dead and not clients:
        return jsonify({'Error': 'no clients provided'})

    for client in list(drivers.keys()):
        if kill_dead and not drivers[client].is_logged_in() or client in clients:
            drivers.pop(client).quit()
            try:
                timers[client].stop()
                timers[client] = None
                release_semaphore(client)
                semaphores[client] = None
            except:
                pass

    return get_active_clients()

Response: Force kill all the clients and all the others


Instruction:
Explain what the following Python 3 code does
def driver_needed(func):

    def wrapped(self, *args):
        if not self.driver:
            raise AttributeError("No driver passed to object")

        return func(self, *args)

    return wrapped

Response: Decorator for WhatsappObjectWithId methods that need to communicate with the browser


Instruction:
Here you have a function in Python 3, explain what it does
def dist_dir(self):
        '''The dist dir at which to place the finished distribution.'''
        if self.distribution is None:
            warning('Tried to access {}.dist_dir, but {}.distribution '
                    'is None'.format(self, self))
            exit(1)
        return self.distribution.dist_dir

Response: The dist dir at which to place the finished distribution.


Instruction:
Write a Python 3 function for
checking what recipes are being built to see which of the alternative and optional dependencies are being used and returns a list of these.

Response:
def check_recipe_choices(self):
        '''Checks what recipes are being built to see which of the alternative
        and optional dependencies are being used,
        and returns a list of these.'''
        recipes = []
        built_recipes = self.ctx.recipe_build_order
        for recipe in self.recipe_depends:
            if isinstance(recipe, (tuple, list)):
                for alternative in recipe:
                    if alternative in built_recipes:
                        recipes.append(alternative)
                        break
        return sorted(recipes)


Instruction:
Make a summary of the following Python 3 code
def prepare_build_dir(self):
        '''Ensure that a build dir exists for the recipe. This same single
        dir will be used for building all different archs.'''
        self.build_dir = self.get_build_dir()
        self.common_dir = self.get_common_dir()
        copy_files(join(self.bootstrap_dir, 'build'), self.build_dir)
        copy_files(join(self.common_dir, 'build'), self.build_dir,
                   override=False)
        if self.ctx.symlink_java_src:
            info('Symlinking java src instead of copying')
            shprint(sh.rm, '-r', join(self.build_dir, 'src'))
            shprint(sh.mkdir, join(self.build_dir, 'src'))
            for dirn in listdir(join(self.bootstrap_dir, 'build', 'src')):
                shprint(sh.ln, '-s', join(self.bootstrap_dir, 'build', 'src', dirn),
                        join(self.build_dir, 'src'))
        with current_directory(self.build_dir):
            with open('project.properties', 'w') as fileh:
                fileh.write('target=android-{}'.format(self.ctx.android_api))

Response:
Ensure that a build dir exists for the recipe. This same single
        dir will be used for building all different archs.


Instruction:
Create a Python 3 function for
finding all the available bootstraps and return them.

Response:
def list_bootstraps(cls):
        '''Find all the available bootstraps and return them.'''
        forbidden_dirs = ('__pycache__', 'common')
        bootstraps_dir = join(dirname(__file__), 'bootstraps')
        for name in listdir(bootstraps_dir):
            if name in forbidden_dirs:
                continue
            filen = join(bootstraps_dir, name)
            if isdir(filen):
                yield name


Instruction:
Can you tell what is the following Python 3 function doing
def get_bootstrap_from_recipes(cls, recipes, ctx):
        '''Returns a bootstrap whose recipe requirements do not conflict with
        the given recipes.'''
        info('Trying to find a bootstrap that matches the given recipes.')
        bootstraps = [cls.get_bootstrap(name, ctx)
                      for name in cls.list_bootstraps()]
        acceptable_bootstraps = []
        for bs in bootstraps:
            if not bs.can_be_chosen_automatically:
                continue
            possible_dependency_lists = expand_dependencies(bs.recipe_depends)
            for possible_dependencies in possible_dependency_lists:
                ok = True
                for recipe in possible_dependencies:
                    recipe = Recipe.get_recipe(recipe, ctx)
                    if any([conflict in recipes for conflict in recipe.conflicts]):
                        ok = False
                        break
                for recipe in recipes:
                    try:
                        recipe = Recipe.get_recipe(recipe, ctx)
                    except ValueError:
                        conflicts = []
                    else:
                        conflicts = recipe.conflicts
                    if any([conflict in possible_dependencies
                            for conflict in conflicts]):
                        ok = False
                        break
                if ok and bs not in acceptable_bootstraps:
                    acceptable_bootstraps.append(bs)
        info('Found {} acceptable bootstraps: {}'.format(
            len(acceptable_bootstraps),
            [bs.name for bs in acceptable_bootstraps]))
        if acceptable_bootstraps:
            info('Using the first of these: {}'
                 .format(acceptable_bootstraps[0].name))
            return acceptable_bootstraps[0]
        return None

Response: Returns a bootstrap that matches the given recipes.


Instruction:
Explain what the following Python 3 code does
def get_bootstrap(cls, name, ctx):
        '''Returns an instance of a bootstrap with the given name.

        This is the only way you should access a bootstrap class, as
        it sets the bootstrap directory correctly.
        '''
        if name is None:
            return None
        if not hasattr(cls, 'bootstraps'):
            cls.bootstraps = {}
        if name in cls.bootstraps:
            return cls.bootstraps[name]
        mod = importlib.import_module('pythonforandroid.bootstraps.{}'
                                      .format(name))
        if len(logger.handlers) > 1:
            logger.removeHandler(logger.handlers[1])
        bootstrap = mod.bootstrap
        bootstrap.bootstrap_dir = join(ctx.root_dir, 'bootstraps', name)
        bootstrap.ctx = ctx
        return bootstrap

Response: Returns an instance of a bootstrap with the given name.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def distribute_libs(self, arch, src_dirs, wildcard='*', dest_dir="libs"):
        '''Copy existing arch libs from build dirs to current dist dir.'''
        info('Copying libs')
        tgt_dir = join(dest_dir, arch.arch)
        ensure_dir(tgt_dir)
        for src_dir in src_dirs:
            for lib in glob.glob(join(src_dir, wildcard)):
                shprint(sh.cp, '-a', lib, tgt_dir)

Response: Copy existing arch libs from build dirs to current dist dir.


Instruction:
Can you create a Python 3 function that
copies existing javaclasses from build dir to current dist dir.

Response:
def distribute_javaclasses(self, javaclass_dir, dest_dir="src"):
        '''Copy existing javaclasses from build dir to current dist dir.'''
        info('Copying java files')
        ensure_dir(dest_dir)
        for filename in glob.glob(javaclass_dir):
            shprint(sh.cp, '-a', filename, dest_dir)


Instruction:
Can you generate the documentation for the following Python 3 function
def distribute_aars(self, arch):
        '''Process existing .aar bundles and copy to current dist dir.'''
        info('Unpacking aars')
        for aar in glob.glob(join(self.ctx.aars_dir, '*.aar')):
            self._unpack_aar(aar, arch)

Response: Process existing. aar bundles and copy to current dist dir.


Instruction:
Can you write a function in Python 3 where it
unpacks content of. aar bundle and copy to current dist dir.

Response:
def _unpack_aar(self, aar, arch):
        '''Unpack content of .aar bundle and copy to current dist dir.'''
        with temp_directory() as temp_dir:
            name = splitext(basename(aar))[0]
            jar_name = name + '.jar'
            info("unpack {} aar".format(name))
            debug("  from {}".format(aar))
            debug("  to {}".format(temp_dir))
            shprint(sh.unzip, '-o', aar, '-d', temp_dir)

            jar_src = join(temp_dir, 'classes.jar')
            jar_tgt = join('libs', jar_name)
            debug("copy {} jar".format(name))
            debug("  from {}".format(jar_src))
            debug("  to {}".format(jar_tgt))
            ensure_dir('libs')
            shprint(sh.cp, '-a', jar_src, jar_tgt)

            so_src_dir = join(temp_dir, 'jni', arch.arch)
            so_tgt_dir = join('libs', arch.arch)
            debug("copy {} .so".format(name))
            debug("  from {}".format(so_src_dir))
            debug("  to {}".format(so_tgt_dir))
            ensure_dir(so_tgt_dir)
            so_files = glob.glob(join(so_src_dir, '*.so'))
            for f in so_files:
                shprint(sh.cp, '-a', f, so_tgt_dir)


Instruction:
Write a Python 3 function that can
return a set of modified recipes between the current branch and the one in param.

Response:
def modified_recipes(branch='origin/master'):
    """
    Returns a set of modified recipes between the current branch and the one
    in param.
    """
    # using the contrib version on purpose rather than sh.git, since it comes
    # with a bunch of fixes, e.g. disabled TTY, see:
    # https://stackoverflow.com/a/20128598/185510
    git_diff = sh.contrib.git.diff('--name-only', branch)
    recipes = set()
    for file_path in git_diff:
        if 'pythonforandroid/recipes/' in file_path:
            recipe = file_path.split('/')[2]
            recipes.add(recipe)
    return recipes


Instruction:
Can you tell what is the following Python 3 function doing
def build(target_python, requirements):
    if not requirements:
        return
    testapp = 'setup_testapp_python2.py'
    android_sdk_home = os.environ['ANDROID_SDK_HOME']
    android_ndk_home = os.environ['ANDROID_NDK_HOME']
    if target_python == TargetPython.python3:
        testapp = 'setup_testapp_python3_sqlite_openssl.py'
    requirements.add(target_python.name)
    requirements = ','.join(requirements)
    logger.info('requirements: {}'.format(requirements))
    with current_directory('testapps/'):
        # iterates to stream the output
        for line in sh.python(
                testapp, 'apk', '--sdk-dir', android_sdk_home,
                '--ndk-dir', android_ndk_home, '--bootstrap', 'sdl2', '--requirements',
                requirements, _err_to_out=True, _iter=True):
            print(line)

Response: Builds an APK given a target Python and a set of requirements.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_recipe_env(self, arch=None, with_flags_in_cc=True):
        env = super(GeventRecipe, self).get_recipe_env(arch, with_flags_in_cc)
        # CFLAGS may only be used to specify C compiler flags, for macro definitions use CPPFLAGS
        regex = re.compile(r'(?:\s|^)-[DI][\S]+')
        env['CPPFLAGS'] = ''.join(re.findall(regex, env['CFLAGS'])).strip()
        env['CFLAGS'] = re.sub(regex, '', env['CFLAGS'])
        info('Moved "{}" from CFLAGS to CPPFLAGS.'.format(env['CPPFLAGS']))
        # LDFLAGS may only be used to specify linker flags, for libraries use LIBS
        regex = re.compile(r'(?:\s|^)-l[\w\.]+')
        env['LIBS'] = ''.join(re.findall(regex, env['LDFLAGS'])).strip()
        env['LDFLAGS'] = re.sub(regex, '', env['LDFLAGS'])
        info('Moved "{}" from LDFLAGS to LIBS.'.format(env['LIBS']))
        return env

Response: Returns the environment dictionary for the gevent recipe.


Instruction:
Can you generate the documentation for the following Python 3 function
def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS,
                     babel_style=True):
    """Extract localizable strings from the given template node.  Per
    default this function returns matches in babel style that means non string
    parameters as well as keyword arguments are returned as `None`.  This
    allows Babel to figure out what you really meant if you are using
    gettext functions that allow keyword arguments for placeholder expansion.
    If you don't want that behavior set the `babel_style` parameter to `False`
    which causes only strings to be returned and parameters are always stored
    in tuples.  As a consequence invalid gettext calls (calls without a single
    string parameter or string parameters after non-string parameters) are
    skipped.

    This example explains the behavior:

    >>> from jinja2 import Environment
    >>> env = Environment()
    >>> node = env.parse('{{ (_("foo"), _(), ngettext("foo", "bar", 42)) }}')
    >>> list(extract_from_ast(node))
    [(1, '_', 'foo'), (1, '_', ()), (1, 'ngettext', ('foo', 'bar', None))]
    >>> list(extract_from_ast(node, babel_style=False))
    [(1, '_', ('foo',)), (1, 'ngettext', ('foo', 'bar'))]

    For every string found this function yields a ``(lineno, function,
    message)`` tuple, where:

    * ``lineno`` is the number of the line on which the string was found,
    * ``function`` is the name of the ``gettext`` function used (if the
      string was extracted from embedded Python code), and
    *  ``message`` is the string itself (a ``unicode`` object, or a tuple
       of ``unicode`` objects for functions with multiple string arguments).

    This extraction function operates on the AST and is because of that unable
    to extract any comments.  For comment support you have to use the babel
    extraction interface or extract comments yourself.
    """
    for node in node.find_all(nodes.Call):
        if not isinstance(node.node, nodes.Name) or \
           node.node.name not in gettext_functions:
            continue

        strings = []
        for arg in node.args:
            if isinstance(arg, nodes.Const) and \
               isinstance(arg.value, basestring):
                strings.append(arg.value)
            else:
                strings.append(None)

        for arg in node.kwargs:
            strings.append(None)
        if node.dyn_args is not None:
            strings.append(None)
        if node.dyn_kwargs is not None:
            strings.append(None)

        if not babel_style:
            strings = tuple(x for x in strings if x is not None)
            if not strings:
                continue
        else:
            if len(strings) == 1:
                strings = strings[0]
            else:
                strings = tuple(strings)
        yield node.lineno, node.node.name, strings

Response: Extract localizable strings from the given template node.


Instruction:
Make a summary of the following Python 3 code
def babel_extract(fileobj, keywords, comment_tags, options):
    extensions = set()
    for extension in options.get('extensions', '').split(','):
        extension = extension.strip()
        if not extension:
            continue
        extensions.add(import_string(extension))
    if InternationalizationExtension not in extensions:
        extensions.add(InternationalizationExtension)

    environment = get_spontaneous_environment(
        options.get('block_start_string', BLOCK_START_STRING),
        options.get('block_end_string', BLOCK_END_STRING),
        options.get('variable_start_string', VARIABLE_START_STRING),
        options.get('variable_end_string', VARIABLE_END_STRING),
        options.get('comment_start_string', COMMENT_START_STRING),
        options.get('comment_end_string', COMMENT_END_STRING),
        options.get('line_statement_prefix') or LINE_STATEMENT_PREFIX,
        options.get('line_comment_prefix') or LINE_COMMENT_PREFIX,
        str(options.get('trim_blocks', TRIM_BLOCKS)).lower() in \
            ('1', 'on', 'yes', 'true'),
        NEWLINE_SEQUENCE, frozenset(extensions),
        # fill with defaults so that environments are shared
        # with other spontaneus environments.  The rest of the
        # arguments are optimizer, undefined, finalize, autoescape,
        # loader, cache size, auto reloading setting and the
        # bytecode cache
        True, Undefined, None, False, None, 0, False, None
    )

    source = fileobj.read().decode(options.get('encoding', 'utf-8'))
    try:
        node = environment.parse(source)
        tokens = list(environment.lex(environment.preprocess(source)))
    except TemplateSyntaxError as e:
        # skip templates with syntax errors
        return

    finder = _CommentFinder(tokens, comment_tags)
    for lineno, func, message in extract_from_ast(node, keywords):
        yield lineno, func, message, finder.find_comments(lineno)

Response: This method is used to extract a set of translation functions from a file - like object.


Instruction:
Make a summary of the following Python 3 code
def parse(self, parser):
        lineno = next(parser.stream).lineno

        # find all the variables referenced.  Additionally a variable can be
        # defined in the body of the trans block too, but this is checked at
        # a later state.
        plural_expr = None
        variables = {}
        while parser.stream.current.type != 'block_end':
            if variables:
                parser.stream.expect('comma')

            # skip colon for python compatibility
            if parser.stream.skip_if('colon'):
                break

            name = parser.stream.expect('name')
            if name.value in variables:
                parser.fail('translatable variable %r defined twice.' %
                            name.value, name.lineno,
                            exc=TemplateAssertionError)

            # expressions
            if parser.stream.current.type == 'assign':
                next(parser.stream)
                variables[name.value] = var = parser.parse_expression()
            else:
                variables[name.value] = var = nodes.Name(name.value, 'load')
            if plural_expr is None:
                plural_expr = var

        parser.stream.expect('block_end')

        plural = plural_names = None
        have_plural = False
        referenced = set()

        # now parse until endtrans or pluralize
        singular_names, singular = self._parse_block(parser, True)
        if singular_names:
            referenced.update(singular_names)
            if plural_expr is None:
                plural_expr = nodes.Name(singular_names[0], 'load')

        # if we have a pluralize block, we parse that too
        if parser.stream.current.test('name:pluralize'):
            have_plural = True
            next(parser.stream)
            if parser.stream.current.type != 'block_end':
                name = parser.stream.expect('name')
                if name.value not in variables:
                    parser.fail('unknown variable %r for pluralization' %
                                name.value, name.lineno,
                                exc=TemplateAssertionError)
                plural_expr = variables[name.value]
            parser.stream.expect('block_end')
            plural_names, plural = self._parse_block(parser, False)
            next(parser.stream)
            referenced.update(plural_names)
        else:
            next(parser.stream)

        # register free names as simple name expressions
        for var in referenced:
            if var not in variables:
                variables[var] = nodes.Name(var, 'load')

        # no variables referenced?  no need to escape
        if not referenced:
            singular = singular.replace('%%', '%')
            if plural:
                plural = plural.replace('%%', '%')

        if not have_plural:
            plural_expr = None
        elif plural_expr is None:
            parser.fail('pluralize without variables', lineno)

        if variables:
            variables = nodes.Dict([nodes.Pair(nodes.Const(x, lineno=lineno), y)
                                    for x, y in variables.items()])
        else:
            variables = None

        node = self._make_node(singular, plural, variables, plural_expr)
        node.set_lineno(lineno)
        return node

Response: Parse a translatable tag.


Instruction:
Can you tell what is the following Python 3 function doing
def _make_node(self, singular, plural, variables, plural_expr):
        # singular only:
        if plural_expr is None:
            gettext = nodes.Name('gettext', 'load')
            node = nodes.Call(gettext, [nodes.Const(singular)],
                              [], None, None)

        # singular and plural
        else:
            ngettext = nodes.Name('ngettext', 'load')
            node = nodes.Call(ngettext, [
                nodes.Const(singular),
                nodes.Const(plural),
                plural_expr
            ], [], None, None)

        # mark the return value as safe if we are in an
        # environment with autoescaping turned on
        if self.environment.autoescape:
            node = nodes.MarkSafe(node)

        if variables:
            node = nodes.Mod(node, variables)
        return nodes.Output([node])

Response: Generates a useful node from the data provided.


Instruction:
Can you generate the documentation for the following Python 3 function
def load_extensions(environment, extensions):
    result = {}
    for extension in extensions:
        if isinstance(extension, basestring):
            extension = import_string(extension)
        result[extension.identifier] = extension(environment)
    return result

Response: Load the extensions from the list and bind it to the environment.


Instruction:
Explain what the following Python 3 code does
def extend(self, **attributes):
        for key, value in attributes.iteritems():
            if not hasattr(self, key):
                setattr(self, key, value)

Response: Add the items to the instance of the environment if they do not exist yet.


Instruction:
Can you implement a function in Python 3 that
compiles a node or template source code.

Response:
def compile(self, source, name=None, filename=None, raw=False,
                defer_init=False):
        """Compile a node or template source code.  The `name` parameter is
        the load name of the template after it was joined using
        :meth:`join_path` if necessary, not the filename on the file system.
        the `filename` parameter is the estimated filename of the template on
        the file system.  If the template came from a database or memory this
        can be omitted.

        The return value of this method is a python code object.  If the `raw`
        parameter is `True` the return value will be a string with python
        code equivalent to the bytecode returned otherwise.  This method is
        mainly used internally.

        `defer_init` is use internally to aid the module code generator.  This
        causes the generated code to be able to import without the global
        environment variable to be set.

        .. versionadded:: 2.4
           `defer_init` parameter added.
        """
        source_hint = None
        try:
            if isinstance(source, basestring):
                source_hint = source
                source = self._parse(source, name, filename)
            if self.optimized:
                source = optimize(source, self)
            source = generate(source, self, name, filename,
                              defer_init=defer_init)
            if raw:
                return source
            if filename is None:
                filename = '<template>'
            else:
                filename = _encode_filename(filename)
            return compile(source, filename, 'exec')
        except TemplateSyntaxError:
            exc_info = sys.exc_info()
        self.handle_exception(exc_info, source_hint=source)


Instruction:
Implement a Python 3 function for
creating a new object from a compiled code and the globals.

Response:
def from_code(cls, environment, code, globals, uptodate=None):
        """Creates a template object from compiled code and the globals.  This
        is used by the loaders and environment to create a template object.
        """
        namespace = {
            'environment':  environment,
            '__file__':     code.co_filename
        }
        exec code in namespace
        rv = cls._from_namespace(environment, namespace, globals)
        rv._uptodate = uptodate
        return rv


Instruction:
Can you generate the documentation for the following Python 3 function
def render(self, *args, **kwargs):
        vars = dict(*args, **kwargs)
        try:
            return concat(self.root_render_func(self.new_context(vars)))
        except:
            exc_info = sys.exc_info()
        return self.environment.handle_exception(exc_info, True)

Response: This method renders the template with the given arguments.


Instruction:
Write a Python 3 script for
generating a generator that yields one item after another.

Response:
def generate(self, *args, **kwargs):
        """For very large templates it can be useful to not render the whole
        template at once but evaluate each statement after another and yield
        piece for piece.  This method basically does exactly that and returns
        a generator that yields one item after another as unicode strings.

        It accepts the same arguments as :meth:`render`.
        """
        vars = dict(*args, **kwargs)
        try:
            for event in self.root_render_func(self.new_context(vars)):
                yield event
        except:
            exc_info = sys.exc_info()
        else:
            return
        yield self.environment.handle_exception(exc_info, True)


Instruction:
Can you tell what is the following Python 3 function doing
def module(self):
        if self._module is not None:
            return self._module
        self._module = rv = self.make_module()
        return rv

Response: The module that contains the available template variables.


Instruction:
How would you explain what the following Python 3 function does
def debug_info(self):
        return [tuple(map(int, x.split('='))) for x in
                self._debug_info.split('&')]

Response: The debug info mapping.


Instruction:
How would you implement a function in Python 3 that
dumps the complete stream into a file - like object.

Response:
def dump(self, fp, encoding=None, errors='strict'):
        """Dump the complete stream into a file or file-like object.
        Per default unicode strings are written, if you want to encode
        before writing specifiy an `encoding`.

        Example usage::

            Template('Hello {{ name }}!').stream(name='foo').dump('hello.html')
        """
        close = False
        if isinstance(fp, basestring):
            fp = file(fp, 'w')
            close = True
        try:
            if encoding is not None:
                iterable = (x.encode(encoding, errors) for x in self)
            else:
                iterable = self
            if hasattr(fp, 'writelines'):
                fp.writelines(iterable)
            else:
                for item in iterable:
                    fp.write(item)
        finally:
            if close:
                fp.close()


Instruction:
Write a Python 3 function for
disabling the output buffering.

Response:
def disable_buffering(self):
        """Disable the output buffering."""
        self._next = self._gen.next
        self.buffered = False


Instruction:
Implement a Python 3 function for
enabling buffering. Buffer `size` items before yielding them.

Response:
def enable_buffering(self, size=5):
        """Enable buffering.  Buffer `size` items before yielding them."""
        if size <= 1:
            raise ValueError('buffer size too small')

        def generator(next):
            buf = []
            c_size = 0
            push = buf.append

            while 1:
                try:
                    while c_size < size:
                        c = next()
                        push(c)
                        if c:
                            c_size += 1
                except StopIteration:
                    if not c_size:
                        return
                yield concat(buf)
                del buf[:]
                c_size = 0

        self.buffered = True
        self._next = generator(self._gen.next).next


Instruction:
How would you explain what the following Python 3 function does
def dist_from_args(ctx, args):
    return Distribution.get_distribution(
        ctx,
        name=args.dist_name,
        recipes=split_argument_list(args.requirements),
        ndk_api=args.ndk_api,
        force_build=args.force_build,
        require_perfect_match=args.require_perfect_match,
        allow_replace_dist=args.allow_replace_dist)

Response:
Parses out any distribution - related arguments and uses them to
    obtain a Distribution class instance for the build.


Instruction:
Can you generate the documentation for the following Python 3 function
def build_dist_from_args(ctx, dist, args):
    bs = Bootstrap.get_bootstrap(args.bootstrap, ctx)
    blacklist = getattr(args, "blacklist_requirements", "").split(",")
    if len(blacklist) == 1 and blacklist[0] == "":
        blacklist = []
    build_order, python_modules, bs = (
        get_recipe_order_and_bootstrap(
            ctx, dist.recipes, bs,
            blacklist=blacklist
        ))
    assert set(build_order).intersection(set(python_modules)) == set()
    ctx.recipe_build_order = build_order
    ctx.python_modules = python_modules

    info('The selected bootstrap is {}'.format(bs.name))
    info_main('# Creating dist with {} bootstrap'.format(bs.name))
    bs.distribution = dist
    info_notify('Dist will have name {} and requirements ({})'.format(
        dist.name, ', '.join(dist.recipes)))
    info('Dist contains the following requirements as recipes: {}'.format(
        ctx.recipe_build_order))
    info('Dist will also contain modules ({}) installed from pip'.format(
        ', '.join(ctx.python_modules)))

    ctx.dist_name = bs.distribution.name
    ctx.prepare_bootstrap(bs)
    if dist.needs_build:
        ctx.prepare_dist(ctx.dist_name)

    build_recipes(build_order, python_modules, ctx, args.private,
                  ignore_project_setup_py=args.ignore_setup_py,
                 )

    ctx.bootstrap.run_distribute()

    info_main('# Your distribution was created successfully, exiting.')
    info('Dist can be found at (for now) {}'
         .format(join(ctx.dist_dir, ctx.dist_name)))

Response: Parses out any bootstrap related arguments and uses them to build a dist.


Instruction:
Can you write a function in Python 3 where it
prints warning messages for any deprecated arguments that were passed.

Response:
def warn_on_deprecated_args(self, args):
        """
        Print warning messages for any deprecated arguments that were passed.
        """

        # Output warning if setup.py is present and neither --ignore-setup-py
        # nor --use-setup-py was specified.
        if getattr(args, "private", None) is not None and \
                (os.path.exists(os.path.join(args.private, "setup.py")) or
                 os.path.exists(os.path.join(args.private, "pyproject.toml"))
                ):
            if not getattr(args, "use_setup_py", False) and \
                    not getattr(args, "ignore_setup_py", False):
                warning("  **** FUTURE BEHAVIOR CHANGE WARNING ****")
                warning("Your project appears to contain a setup.py file.")
                warning("Currently, these are ignored by default.")
                warning("This will CHANGE in an upcoming version!")
                warning("")
                warning("To ensure your setup.py is ignored, please specify:")
                warning("    --ignore-setup-py")
                warning("")
                warning("To enable what will some day be the default, specify:")
                warning("    --use-setup-py")

        # NDK version is now determined automatically
        if args.ndk_version is not None:
            warning('--ndk-version is deprecated and no longer necessary, '
                    'the value you passed is ignored')
        if 'ANDROIDNDKVER' in environ:
            warning('$ANDROIDNDKVER is deprecated and no longer necessary, '
                    'the value you set is ignored')


Instruction:
How would you implement a function in Python 3 that
lists all the bootstraps available to build with.

Response:
def bootstraps(self, _args):
        """List all the bootstraps available to build with."""
        for bs in Bootstrap.list_bootstraps():
            bs = Bootstrap.get_bootstrap(bs, self.ctx)
            print('{Fore.BLUE}{Style.BRIGHT}{bs.name}{Style.RESET_ALL}'
                  .format(bs=bs, Fore=Out_Fore, Style=Out_Style))
            print('    {Fore.GREEN}depends: {bs.recipe_depends}{Fore.RESET}'
                  .format(bs=bs, Fore=Out_Fore))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def clean_all(self, args):
        self.clean_dists(args)
        self.clean_builds(args)
        self.clean_download_cache(args)

Response: Delete all build components ; the package cache package builds bootstrap builds and distributions.


Instruction:
Explain what the following Python 3 code does
def clean_dists(self, _args):
        ctx = self.ctx
        if exists(ctx.dist_dir):
            shutil.rmtree(ctx.dist_dir)

Response:
Delete all compiled distributions in the internal distribution
        directory.


Instruction:
Can you write a function in Python 3 where it
deletes all the bootstrap builds.

Response:
def clean_bootstrap_builds(self, _args):
        """Delete all the bootstrap builds."""
        if exists(join(self.ctx.build_dir, 'bootstrap_builds')):
            shutil.rmtree(join(self.ctx.build_dir, 'bootstrap_builds'))


Instruction:
Here you have a function in Python 3, explain what it does
def clean_builds(self, _args):
        ctx = self.ctx
        if exists(ctx.build_dir):
            shutil.rmtree(ctx.build_dir)
        if exists(ctx.python_installs_dir):
            shutil.rmtree(ctx.python_installs_dir)
        libs_dir = join(self.ctx.build_dir, 'libs_collections')
        if exists(libs_dir):
            shutil.rmtree(libs_dir)

Response:
Delete all build caches for each recipe python - install java code
        and compiled libs collection.


Instruction:
Given the following Python 3 function, write the documentation
def clean_recipe_build(self, args):
        recipe = Recipe.get_recipe(args.recipe, self.ctx)
        info('Cleaning build for {} recipe.'.format(recipe.name))
        recipe.clean_build()
        if not args.no_clean_dists:
            self.clean_dists(args)

Response: Deletes the build files of the given recipe.


Instruction:
Implement a Python 3 function for
cleaning up the download cache for recipes passed as arguments.

Response:
def clean_download_cache(self, args):
        """ Deletes a download cache for recipes passed as arguments. If no
        argument is passed, it'll delete *all* downloaded caches. ::

            p4a clean_download_cache kivy,pyjnius

        This does *not* delete the build caches or final distributions.
        """
        ctx = self.ctx
        if hasattr(args, 'recipes') and args.recipes:
            for package in args.recipes:
                remove_path = join(ctx.packages_path, package)
                if exists(remove_path):
                    shutil.rmtree(remove_path)
                    info('Download cache removed for: "{}"'.format(package))
                else:
                    warning('No download cache found for "{}", skipping'.format(
                        package))
        else:
            if exists(ctx.packages_path):
                shutil.rmtree(ctx.packages_path)
                info('Download cache removed.')
            else:
                print('No cache found at "{}"'.format(ctx.packages_path))


Instruction:
Make a summary of the following Python 3 code
def export_dist(self, args):
        ctx = self.ctx
        dist = dist_from_args(ctx, args)
        if dist.needs_build:
            raise BuildInterruptingException(
                'You asked to export a dist, but there is no dist '
                'with suitable recipes available. For now, you must '
                ' create one first with the create argument.')
        if args.symlink:
            shprint(sh.ln, '-s', dist.dist_dir, args.output_dir)
        else:
            shprint(sh.cp, '-r', dist.dist_dir, args.output_dir)

Response: Copies a created dist to an output dir.


Instruction:
Can you implement a function in Python 3 that
creates an APK using the given distribution.

Response:
def apk(self, args):
        """Create an APK using the given distribution."""

        ctx = self.ctx
        dist = self._dist

        # Manually fixing these arguments at the string stage is
        # unsatisfactory and should probably be changed somehow, but
        # we can't leave it until later as the build.py scripts assume
        # they are in the current directory.
        fix_args = ('--dir', '--private', '--add-jar', '--add-source',
                    '--whitelist', '--blacklist', '--presplash', '--icon')
        unknown_args = args.unknown_args
        for i, arg in enumerate(unknown_args):
            argx = arg.split('=')
            if argx[0] in fix_args:
                if len(argx) > 1:
                    unknown_args[i] = '='.join(
                        (argx[0], realpath(expanduser(argx[1]))))
                elif i + 1 < len(unknown_args):
                    unknown_args[i+1] = realpath(expanduser(unknown_args[i+1]))

        env = os.environ.copy()
        if args.build_mode == 'release':
            if args.keystore:
                env['P4A_RELEASE_KEYSTORE'] = realpath(expanduser(args.keystore))
            if args.signkey:
                env['P4A_RELEASE_KEYALIAS'] = args.signkey
            if args.keystorepw:
                env['P4A_RELEASE_KEYSTORE_PASSWD'] = args.keystorepw
            if args.signkeypw:
                env['P4A_RELEASE_KEYALIAS_PASSWD'] = args.signkeypw
            elif args.keystorepw and 'P4A_RELEASE_KEYALIAS_PASSWD' not in env:
                env['P4A_RELEASE_KEYALIAS_PASSWD'] = args.keystorepw

        build = imp.load_source('build', join(dist.dist_dir, 'build.py'))
        with current_directory(dist.dist_dir):
            self.hook("before_apk_build")
            os.environ["ANDROID_API"] = str(self.ctx.android_api)
            build_args = build.parse_args(args.unknown_args)
            self.hook("after_apk_build")
            self.hook("before_apk_assemble")

            build_type = ctx.java_build_tool
            if build_type == 'auto':
                info('Selecting java build tool:')

                build_tools_versions = os.listdir(join(ctx.sdk_dir,
                                                       'build-tools'))
                build_tools_versions = sorted(build_tools_versions,
                                              key=LooseVersion)
                build_tools_version = build_tools_versions[-1]
                info(('Detected highest available build tools '
                      'version to be {}').format(build_tools_version))

                if build_tools_version >= '25.0' and exists('gradlew'):
                    build_type = 'gradle'
                    info('    Building with gradle, as gradle executable is '
                         'present')
                else:
                    build_type = 'ant'
                    if build_tools_version < '25.0':
                        info(('    Building with ant, as the highest '
                              'build-tools-version is only {}').format(
                            build_tools_version))
                    else:
                        info('    Building with ant, as no gradle executable '
                             'detected')

            if build_type == 'gradle':
                # gradle-based build
                env["ANDROID_NDK_HOME"] = self.ctx.ndk_dir
                env["ANDROID_HOME"] = self.ctx.sdk_dir

                gradlew = sh.Command('./gradlew')
                if exists('/usr/bin/dos2unix'):
                    # .../dists/bdisttest_python3/gradlew
                    # .../build/bootstrap_builds/sdl2-python3crystax/gradlew
                    # if docker on windows, gradle contains CRLF
                    output = shprint(
                        sh.Command('dos2unix'), gradlew._path.decode('utf8'),
                        _tail=20, _critical=True, _env=env
                    )
                if args.build_mode == "debug":
                    gradle_task = "assembleDebug"
                elif args.build_mode == "release":
                    gradle_task = "assembleRelease"
                else:
                    raise BuildInterruptingException(
                        "Unknown build mode {} for apk()".format(args.build_mode))
                output = shprint(gradlew, gradle_task, _tail=20,
                                 _critical=True, _env=env)

                # gradle output apks somewhere else
                # and don't have version in file
                apk_dir = join(dist.dist_dir,
                               "build", "outputs", "apk",
                               args.build_mode)
                apk_glob = "*-{}.apk"
                apk_add_version = True

            else:
                # ant-based build
                try:
                    ant = sh.Command('ant')
                except sh.CommandNotFound:
                    raise BuildInterruptingException(
                        'Could not find ant binary, please install it '
                        'and make sure it is in your $PATH.')
                output = shprint(ant, args.build_mode, _tail=20,
                                 _critical=True, _env=env)
                apk_dir = join(dist.dist_dir, "bin")
                apk_glob = "*-*-{}.apk"
                apk_add_version = False

            self.hook("after_apk_assemble")

        info_main('# Copying APK to current directory')

        apk_re = re.compile(r'.*Package: (.*\.apk)$')
        apk_file = None
        for line in reversed(output.splitlines()):
            m = apk_re.match(line)
            if m:
                apk_file = m.groups()[0]
                break

        if not apk_file:
            info_main('# APK filename not found in build output. Guessing...')
            if args.build_mode == "release":
                suffixes = ("release", "release-unsigned")
            else:
                suffixes = ("debug", )
            for suffix in suffixes:
                apks = glob.glob(join(apk_dir, apk_glob.format(suffix)))
                if apks:
                    if len(apks) > 1:
                        info('More than one built APK found... guessing you '
                             'just built {}'.format(apks[-1]))
                    apk_file = apks[-1]
                    break
            else:
                raise BuildInterruptingException('Couldn\'t find the built APK')

        info_main('# Found APK file: {}'.format(apk_file))
        if apk_add_version:
            info('# Add version number to APK')
            apk_name, apk_suffix = basename(apk_file).split("-", 1)
            apk_file_dest = "{}-{}-{}".format(
                apk_name, build_args.version, apk_suffix)
            info('# APK renamed to {}'.format(apk_file_dest))
            shprint(sh.cp, apk_file, apk_file_dest)
        else:
            shprint(sh.cp, apk_file, './')


Instruction:
Can you generate the documentation for the following Python 3 function
def archs(self, _args):
        print('{Style.BRIGHT}Available target architectures are:'
              '{Style.RESET_ALL}'.format(Style=Out_Style))
        for arch in self.ctx.archs:
            print('    {}'.format(arch.arch))

Response: List the target architectures available to be built for.


Instruction:
Here you have a function in Python 3, explain what it does
def distributions(self, _args):
        ctx = self.ctx
        dists = Distribution.get_distributions(ctx)

        if dists:
            print('{Style.BRIGHT}Distributions currently installed are:'
                  '{Style.RESET_ALL}'.format(Style=Out_Style, Fore=Out_Fore))
            pretty_log_dists(dists, print)
        else:
            print('{Style.BRIGHT}There are no dists currently built.'
                  '{Style.RESET_ALL}'.format(Style=Out_Style))

Response: Lists all distributions currently installed.


Instruction:
Can you tell what is the following Python 3 function doing
def sdk_tools(self, args):
        ctx = self.ctx
        ctx.prepare_build_environment(user_sdk_dir=self.sdk_dir,
                                      user_ndk_dir=self.ndk_dir,
                                      user_android_api=self.android_api,
                                      user_ndk_api=self.ndk_api)
        android = sh.Command(join(ctx.sdk_dir, 'tools', args.tool))
        output = android(
            *args.unknown_args, _iter=True, _out_bufsize=1, _err_to_out=True)
        for line in output:
            sys.stdout.write(line)
            sys.stdout.flush()

Response: Runs the android tools from the detected SDK directory passing all arguments straight to it.