\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7<F<2PFAFZUP_xxnnx\F5\AF\B9\91\C8\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\DB\00CUZZxix‚\EB\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\FF\C0\00\00b\00d\00\FF\C4\00\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\C4\00\00\00\00\00\00\00\00\00\00\001A!Q\FF\C4\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\C4\00\00\00\00\00\00\00\00\00\00!1AQ\FF\DA\00\00\00?\00\F6\00\00\00\00\00\00\00\00\00\00\A0\00\00\C5\CF\F8\E7Ó\FCjD~\B9^\AD\%\B3]\D8cs-\BBs,-\A0\00"\80\00%\B83rÏ^K~F\A4ea\00E\00\C6\EE=u\B1\9B\D1\00@\00r\BE8\F9:\FE5#.M\00\E7\CB\C9q\CBq\D6\F2\BE\B7\C7>\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7	\8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh
\00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€
\00$\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95
59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>C///</title>
</head>
"""upload_docs

Implements a Distutils 'upload_docs' subcommand (upload documentation to
sites other than PyPi such as devpi).
"""

from base64 import standard_b64encode
from distutils import log
from distutils.errors import DistutilsOptionError
import os
import zipfile
import tempfile
import shutil
import itertools
import functools
import http.client
import urllib.parse

from .._importlib import metadata
from ..warnings import SetuptoolsDeprecationWarning

from .upload import upload


def _encode(s):
    return s.encode('utf-8', 'surrogateescape')


class upload_docs(upload):
    # override the default repository as upload_docs isn't
    # supported by Warehouse (and won't be).
    DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi/'

    description = 'Upload documentation to sites other than PyPi such as devpi'

    user_options = [
        (
            'repository=',
            'r',
            "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY,
        ),
        ('show-response', None, 'display full response text from server'),
        ('upload-dir=', None, 'directory to upload'),
    ]
    boolean_options = upload.boolean_options

    def has_sphinx(self):
        return bool(
            self.upload_dir is None
            and metadata.entry_points(group='distutils.commands', name='build_sphinx')
        )

    sub_commands = [('build_sphinx', has_sphinx)]

    def initialize_options(self):
        upload.initialize_options(self)
        self.upload_dir = None
        self.target_dir = None

    def finalize_options(self):
        log.warn(
            "Upload_docs command is deprecated. Use Read the Docs "
            "(https://readthedocs.org) instead."
        )
        upload.finalize_options(self)
        if self.upload_dir is None:
            if self.has_sphinx():
                build_sphinx = self.get_finalized_command('build_sphinx')
                self.target_dir = dict(build_sphinx.builder_target_dirs)['html']
            else:
                build = self.get_finalized_command('build')
                self.target_dir = os.path.join(build.build_base, 'docs')
        else:
            self.ensure_dirname('upload_dir')
            self.target_dir = self.upload_dir
        self.announce('Using upload directory %s' % self.target_dir)

    def create_zipfile(self, filename):
        zip_file = zipfile.ZipFile(filename, "w")
        try:
            self.mkpath(self.target_dir)  # just in case
            for root, dirs, files in os.walk(self.target_dir):
                if root == self.target_dir and not files:
                    tmpl = "no files found in upload directory '%s'"
                    raise DistutilsOptionError(tmpl % self.target_dir)
                for name in files:
                    full = os.path.join(root, name)
                    relative = root[len(self.target_dir) :].lstrip(os.path.sep)
                    dest = os.path.join(relative, name)
                    zip_file.write(full, dest)
        finally:
            zip_file.close()

    def run(self):
        SetuptoolsDeprecationWarning.emit(
            "Deprecated command",
            """
            upload_docs is deprecated and will be removed in a future version.
            Instead, use tools like devpi and Read the Docs; or lower level tools like
            httpie and curl to interact directly with your hosting service API.
            """,
            due_date=(2023, 9, 26),  # warning introduced in 27 Jul 2022
        )

        # Run sub commands
        for cmd_name in self.get_sub_commands():
            self.run_command(cmd_name)

        tmp_dir = tempfile.mkdtemp()
        name = self.distribution.metadata.get_name()
        zip_file = os.path.join(tmp_dir, "%s.zip" % name)
        try:
            self.create_zipfile(zip_file)
            self.upload_file(zip_file)
        finally:
            shutil.rmtree(tmp_dir)

    @staticmethod
    def _build_part(item, sep_boundary):
        key, values = item
        title = '\nContent-Disposition: form-data; name="%s"' % key
        # handle multiple entries for the same name
        if not isinstance(values, list):
            values = [values]
        for value in values:
            if isinstance(value, tuple):
                title += '; filename="%s"' % value[0]
                value = value[1]
            else:
                value = _encode(value)
            yield sep_boundary
            yield _encode(title)
            yield b"\n\n"
            yield value
            if value and value[-1:] == b'\r':
                yield b'\n'  # write an extra newline (lurve Macs)

    @classmethod
    def _build_multipart(cls, data):
        """
        Build up the MIME payload for the POST data
        """
        boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
        sep_boundary = b'\n--' + boundary.encode('ascii')
        end_boundary = sep_boundary + b'--'
        end_items = (
            end_boundary,
            b"\n",
        )
        builder = functools.partial(
            cls._build_part,
            sep_boundary=sep_boundary,
        )
        part_groups = map(builder, data.items())
        parts = itertools.chain.from_iterable(part_groups)
        body_items = itertools.chain(parts, end_items)
        content_type = 'multipart/form-data; boundary=%s' % boundary
        return b''.join(body_items), content_type

    def upload_file(self, filename):
        with open(filename, 'rb') as f:
            content = f.read()
        meta = self.distribution.metadata
        data = {
            ':action': 'doc_upload',
            'name': meta.get_name(),
            'content': (os.path.basename(filename), content),
        }
        # set up the authentication
        credentials = _encode(self.username + ':' + self.password)
        credentials = standard_b64encode(credentials).decode('ascii')
        auth = "Basic " + credentials

        body, ct = self._build_multipart(data)

        ms