├── .gitignore
├── .site-packages
├── PIL
│ ├── BdfFontFile.py
│ ├── BlpImagePlugin.py
│ ├── BmpImagePlugin.py
│ ├── BufrStubImagePlugin.py
│ ├── ContainerIO.py
│ ├── CurImagePlugin.py
│ ├── DcxImagePlugin.py
│ ├── DdsImagePlugin.py
│ ├── EpsImagePlugin.py
│ ├── ExifTags.py
│ ├── FitsImagePlugin.py
│ ├── FitsStubImagePlugin.py
│ ├── FliImagePlugin.py
│ ├── FontFile.py
│ ├── FpxImagePlugin.py
│ ├── FtexImagePlugin.py
│ ├── GbrImagePlugin.py
│ ├── GdImageFile.py
│ ├── GifImagePlugin.py
│ ├── GimpGradientFile.py
│ ├── GimpPaletteFile.py
│ ├── GribStubImagePlugin.py
│ ├── Hdf5StubImagePlugin.py
│ ├── IcnsImagePlugin.py
│ ├── IcoImagePlugin.py
│ ├── ImImagePlugin.py
│ ├── Image.py
│ ├── ImageChops.py
│ ├── ImageCms.py
│ ├── ImageColor.py
│ ├── ImageDraw.py
│ ├── ImageDraw2.py
│ ├── ImageEnhance.py
│ ├── ImageFile.py
│ ├── ImageFilter.py
│ ├── ImageFont.py
│ ├── ImageGrab.py
│ ├── ImageMath.py
│ ├── ImageMode.py
│ ├── ImageMorph.py
│ ├── ImageOps.py
│ ├── ImagePalette.py
│ ├── ImagePath.py
│ ├── ImageQt.py
│ ├── ImageSequence.py
│ ├── ImageShow.py
│ ├── ImageStat.py
│ ├── ImageTk.py
│ ├── ImageTransform.py
│ ├── ImageWin.py
│ ├── ImtImagePlugin.py
│ ├── IptcImagePlugin.py
│ ├── Jpeg2KImagePlugin.py
│ ├── JpegImagePlugin.py
│ ├── JpegPresets.py
│ ├── McIdasImagePlugin.py
│ ├── MicImagePlugin.py
│ ├── MpegImagePlugin.py
│ ├── MpoImagePlugin.py
│ ├── MspImagePlugin.py
│ ├── PSDraw.py
│ ├── PaletteFile.py
│ ├── PalmImagePlugin.py
│ ├── PcdImagePlugin.py
│ ├── PcfFontFile.py
│ ├── PcxImagePlugin.py
│ ├── PdfImagePlugin.py
│ ├── PdfParser.py
│ ├── PixarImagePlugin.py
│ ├── PngImagePlugin.py
│ ├── PpmImagePlugin.py
│ ├── PsdImagePlugin.py
│ ├── PyAccess.py
│ ├── SgiImagePlugin.py
│ ├── SpiderImagePlugin.py
│ ├── SunImagePlugin.py
│ ├── TarIO.py
│ ├── TgaImagePlugin.py
│ ├── TiffImagePlugin.py
│ ├── TiffTags.py
│ ├── WalImageFile.py
│ ├── WebPImagePlugin.py
│ ├── WmfImagePlugin.py
│ ├── XVThumbImagePlugin.py
│ ├── XbmImagePlugin.py
│ ├── XpmImagePlugin.py
│ ├── __init__.py
│ ├── __main__.py
│ ├── _binary.py
│ ├── _tkinter_finder.py
│ ├── _util.py
│ ├── _version.py
│ └── features.py
├── bin
│ └── normalizer
├── certifi
│ ├── __init__.py
│ ├── __main__.py
│ ├── cacert.pem
│ └── core.py
├── charset_normalizer
│ ├── __init__.py
│ ├── api.py
│ ├── assets
│ │ └── __init__.py
│ ├── cd.py
│ ├── cli
│ │ ├── __init__.py
│ │ └── normalizer.py
│ ├── constant.py
│ ├── legacy.py
│ ├── md.py
│ ├── models.py
│ ├── py.typed
│ ├── utils.py
│ └── version.py
├── idna
│ ├── __init__.py
│ ├── codec.py
│ ├── compat.py
│ ├── core.py
│ ├── idnadata.py
│ ├── intranges.py
│ ├── package_data.py
│ ├── py.typed
│ └── uts46data.py
├── pyperclip
│ ├── __init__.py
│ └── __main__.py
├── requests
│ ├── __init__.py
│ ├── __version__.py
│ ├── _internal_utils.py
│ ├── adapters.py
│ ├── api.py
│ ├── auth.py
│ ├── certs.py
│ ├── compat.py
│ ├── cookies.py
│ ├── exceptions.py
│ ├── help.py
│ ├── hooks.py
│ ├── models.py
│ ├── packages.py
│ ├── sessions.py
│ ├── status_codes.py
│ ├── structures.py
│ └── utils.py
├── six.py
├── urllib3
│ ├── __init__.py
│ ├── _collections.py
│ ├── _version.py
│ ├── connection.py
│ ├── connectionpool.py
│ ├── contrib
│ │ ├── __init__.py
│ │ ├── _appengine_environ.py
│ │ ├── _securetransport
│ │ │ ├── __init__.py
│ │ │ ├── bindings.py
│ │ │ └── low_level.py
│ │ ├── appengine.py
│ │ ├── ntlmpool.py
│ │ ├── pyopenssl.py
│ │ ├── securetransport.py
│ │ └── socks.py
│ ├── exceptions.py
│ ├── fields.py
│ ├── filepost.py
│ ├── packages
│ │ ├── __init__.py
│ │ ├── backports
│ │ │ ├── __init__.py
│ │ │ └── makefile.py
│ │ └── six.py
│ ├── poolmanager.py
│ ├── request.py
│ ├── response.py
│ └── util
│ │ ├── __init__.py
│ │ ├── connection.py
│ │ ├── proxy.py
│ │ ├── queue.py
│ │ ├── request.py
│ │ ├── response.py
│ │ ├── retry.py
│ │ ├── ssl_.py
│ │ ├── ssl_match_hostname.py
│ │ ├── ssltransport.py
│ │ ├── timeout.py
│ │ ├── url.py
│ │ └── wait.py
└── workflow
│ ├── Notify.tgz
│ ├── __init__.py
│ ├── background.py
│ ├── notify.py
│ ├── update.py
│ ├── util.py
│ ├── version
│ ├── workflow.py
│ └── workflow3.py
├── 7D9DF57A-5DF9-5DB9-AB88-88DAC6AD7FB1.png
├── README.md
├── __version__.py
├── build-workflow-distributable.sh
├── entrypoint.py
├── icon.png
├── info.plist
└── lib
├── biplist-1.0.3.dist-info
├── AUTHORS
├── INSTALLER
├── LICENSE
├── METADATA
├── RECORD
├── REQUESTED
├── WHEEL
└── top_level.txt
└── biplist
└── __init__.py
/.gitignore:
--------------------------------------------------------------------------------
1 | alfred-iterm-profiles-workflow.alfredworkflow
2 |
--------------------------------------------------------------------------------
/.site-packages/PIL/BdfFontFile.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # bitmap distribution font (bdf) file parser
6 | #
7 | # history:
8 | # 1996-05-16 fl created (as bdf2pil)
9 | # 1997-08-25 fl converted to FontFile driver
10 | # 2001-05-25 fl removed bogus __init__ call
11 | # 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev)
12 | # 2003-04-22 fl more robustification (from Graham Dumpleton)
13 | #
14 | # Copyright (c) 1997-2003 by Secret Labs AB.
15 | # Copyright (c) 1997-2003 by Fredrik Lundh.
16 | #
17 | # See the README file for information on usage and redistribution.
18 | #
19 |
20 | """
21 | Parse X Bitmap Distribution Format (BDF)
22 | """
23 |
24 |
25 | from . import FontFile, Image
26 |
27 | bdf_slant = {
28 | "R": "Roman",
29 | "I": "Italic",
30 | "O": "Oblique",
31 | "RI": "Reverse Italic",
32 | "RO": "Reverse Oblique",
33 | "OT": "Other",
34 | }
35 |
36 | bdf_spacing = {"P": "Proportional", "M": "Monospaced", "C": "Cell"}
37 |
38 |
39 | def bdf_char(f):
40 | # skip to STARTCHAR
41 | while True:
42 | s = f.readline()
43 | if not s:
44 | return None
45 | if s[:9] == b"STARTCHAR":
46 | break
47 | id = s[9:].strip().decode("ascii")
48 |
49 | # load symbol properties
50 | props = {}
51 | while True:
52 | s = f.readline()
53 | if not s or s[:6] == b"BITMAP":
54 | break
55 | i = s.find(b" ")
56 | props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii")
57 |
58 | # load bitmap
59 | bitmap = []
60 | while True:
61 | s = f.readline()
62 | if not s or s[:7] == b"ENDCHAR":
63 | break
64 | bitmap.append(s[:-1])
65 | bitmap = b"".join(bitmap)
66 |
67 | [x, y, l, d] = [int(p) for p in props["BBX"].split()]
68 | [dx, dy] = [int(p) for p in props["DWIDTH"].split()]
69 |
70 | bbox = (dx, dy), (l, -d - y, x + l, -d), (0, 0, x, y)
71 |
72 | try:
73 | im = Image.frombytes("1", (x, y), bitmap, "hex", "1")
74 | except ValueError:
75 | # deal with zero-width characters
76 | im = Image.new("1", (x, y))
77 |
78 | return id, int(props["ENCODING"]), bbox, im
79 |
80 |
81 | class BdfFontFile(FontFile.FontFile):
82 | """Font file plugin for the X11 BDF format."""
83 |
84 | def __init__(self, fp):
85 | super().__init__()
86 |
87 | s = fp.readline()
88 | if s[:13] != b"STARTFONT 2.1":
89 | raise SyntaxError("not a valid BDF file")
90 |
91 | props = {}
92 | comments = []
93 |
94 | while True:
95 | s = fp.readline()
96 | if not s or s[:13] == b"ENDPROPERTIES":
97 | break
98 | i = s.find(b" ")
99 | props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii")
100 | if s[:i] in [b"COMMENT", b"COPYRIGHT"]:
101 | if s.find(b"LogicalFontDescription") < 0:
102 | comments.append(s[i + 1 : -1].decode("ascii"))
103 |
104 | while True:
105 | c = bdf_char(fp)
106 | if not c:
107 | break
108 | id, ch, (xy, dst, src), im = c
109 | if 0 <= ch < len(self.glyph):
110 | self.glyph[ch] = xy, dst, src, im
111 |
--------------------------------------------------------------------------------
/.site-packages/PIL/BufrStubImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # BUFR stub adapter
6 | #
7 | # Copyright (c) 1996-2003 by Fredrik Lundh
8 | #
9 | # See the README file for information on usage and redistribution.
10 | #
11 |
12 | from . import Image, ImageFile
13 |
14 | _handler = None
15 |
16 |
17 | def register_handler(handler):
18 | """
19 | Install application-specific BUFR image handler.
20 |
21 | :param handler: Handler object.
22 | """
23 | global _handler
24 | _handler = handler
25 |
26 |
27 | # --------------------------------------------------------------------
28 | # Image adapter
29 |
30 |
31 | def _accept(prefix):
32 | return prefix[:4] == b"BUFR" or prefix[:4] == b"ZCZC"
33 |
34 |
35 | class BufrStubImageFile(ImageFile.StubImageFile):
36 |
37 | format = "BUFR"
38 | format_description = "BUFR"
39 |
40 | def _open(self):
41 |
42 | offset = self.fp.tell()
43 |
44 | if not _accept(self.fp.read(4)):
45 | raise SyntaxError("Not a BUFR file")
46 |
47 | self.fp.seek(offset)
48 |
49 | # make something up
50 | self.mode = "F"
51 | self._size = 1, 1
52 |
53 | loader = self._load()
54 | if loader:
55 | loader.open(self)
56 |
57 | def _load(self):
58 | return _handler
59 |
60 |
61 | def _save(im, fp, filename):
62 | if _handler is None or not hasattr(_handler, "save"):
63 | raise OSError("BUFR save handler not installed")
64 | _handler.save(im, fp, filename)
65 |
66 |
67 | # --------------------------------------------------------------------
68 | # Registry
69 |
70 | Image.register_open(BufrStubImageFile.format, BufrStubImageFile, _accept)
71 | Image.register_save(BufrStubImageFile.format, _save)
72 |
73 | Image.register_extension(BufrStubImageFile.format, ".bufr")
74 |
--------------------------------------------------------------------------------
/.site-packages/PIL/ContainerIO.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # a class to read from a container file
6 | #
7 | # History:
8 | # 1995-06-18 fl Created
9 | # 1995-09-07 fl Added readline(), readlines()
10 | #
11 | # Copyright (c) 1997-2001 by Secret Labs AB
12 | # Copyright (c) 1995 by Fredrik Lundh
13 | #
14 | # See the README file for information on usage and redistribution.
15 | #
16 |
17 |
18 | import io
19 |
20 |
21 | class ContainerIO:
22 | """
23 | A file object that provides read access to a part of an existing
24 | file (for example a TAR file).
25 | """
26 |
27 | def __init__(self, file, offset, length):
28 | """
29 | Create file object.
30 |
31 | :param file: Existing file.
32 | :param offset: Start of region, in bytes.
33 | :param length: Size of region, in bytes.
34 | """
35 | self.fh = file
36 | self.pos = 0
37 | self.offset = offset
38 | self.length = length
39 | self.fh.seek(offset)
40 |
41 | ##
42 | # Always false.
43 |
44 | def isatty(self):
45 | return False
46 |
47 | def seek(self, offset, mode=io.SEEK_SET):
48 | """
49 | Move file pointer.
50 |
51 | :param offset: Offset in bytes.
52 | :param mode: Starting position. Use 0 for beginning of region, 1
53 | for current offset, and 2 for end of region. You cannot move
54 | the pointer outside the defined region.
55 | """
56 | if mode == 1:
57 | self.pos = self.pos + offset
58 | elif mode == 2:
59 | self.pos = self.length + offset
60 | else:
61 | self.pos = offset
62 | # clamp
63 | self.pos = max(0, min(self.pos, self.length))
64 | self.fh.seek(self.offset + self.pos)
65 |
66 | def tell(self):
67 | """
68 | Get current file pointer.
69 |
70 | :returns: Offset from start of region, in bytes.
71 | """
72 | return self.pos
73 |
74 | def read(self, n=0):
75 | """
76 | Read data.
77 |
78 | :param n: Number of bytes to read. If omitted or zero,
79 | read until end of region.
80 | :returns: An 8-bit string.
81 | """
82 | if n:
83 | n = min(n, self.length - self.pos)
84 | else:
85 | n = self.length - self.pos
86 | if not n: # EOF
87 | return b"" if "b" in self.fh.mode else ""
88 | self.pos = self.pos + n
89 | return self.fh.read(n)
90 |
91 | def readline(self):
92 | """
93 | Read a line of text.
94 |
95 | :returns: An 8-bit string.
96 | """
97 | s = b"" if "b" in self.fh.mode else ""
98 | newline_character = b"\n" if "b" in self.fh.mode else "\n"
99 | while True:
100 | c = self.read(1)
101 | if not c:
102 | break
103 | s = s + c
104 | if c == newline_character:
105 | break
106 | return s
107 |
108 | def readlines(self):
109 | """
110 | Read multiple lines of text.
111 |
112 | :returns: A list of 8-bit strings.
113 | """
114 | lines = []
115 | while True:
116 | s = self.readline()
117 | if not s:
118 | break
119 | lines.append(s)
120 | return lines
121 |
--------------------------------------------------------------------------------
/.site-packages/PIL/CurImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # Windows Cursor support for PIL
6 | #
7 | # notes:
8 | # uses BmpImagePlugin.py to read the bitmap data.
9 | #
10 | # history:
11 | # 96-05-27 fl Created
12 | #
13 | # Copyright (c) Secret Labs AB 1997.
14 | # Copyright (c) Fredrik Lundh 1996.
15 | #
16 | # See the README file for information on usage and redistribution.
17 | #
18 | from . import BmpImagePlugin, Image
19 | from ._binary import i16le as i16
20 | from ._binary import i32le as i32
21 |
22 | #
23 | # --------------------------------------------------------------------
24 |
25 |
26 | def _accept(prefix):
27 | return prefix[:4] == b"\0\0\2\0"
28 |
29 |
30 | ##
31 | # Image plugin for Windows Cursor files.
32 |
33 |
34 | class CurImageFile(BmpImagePlugin.BmpImageFile):
35 |
36 | format = "CUR"
37 | format_description = "Windows Cursor"
38 |
39 | def _open(self):
40 |
41 | offset = self.fp.tell()
42 |
43 | # check magic
44 | s = self.fp.read(6)
45 | if not _accept(s):
46 | raise SyntaxError("not a CUR file")
47 |
48 | # pick the largest cursor in the file
49 | m = b""
50 | for i in range(i16(s, 4)):
51 | s = self.fp.read(16)
52 | if not m:
53 | m = s
54 | elif s[0] > m[0] and s[1] > m[1]:
55 | m = s
56 | if not m:
57 | raise TypeError("No cursors were found")
58 |
59 | # load as bitmap
60 | self._bitmap(i32(m, 12) + offset)
61 |
62 | # patch up the bitmap height
63 | self._size = self.size[0], self.size[1] // 2
64 | d, e, o, a = self.tile[0]
65 | self.tile[0] = d, (0, 0) + self.size, o, a
66 |
67 | return
68 |
69 |
70 | #
71 | # --------------------------------------------------------------------
72 |
73 | Image.register_open(CurImageFile.format, CurImageFile, _accept)
74 |
75 | Image.register_extension(CurImageFile.format, ".cur")
76 |
--------------------------------------------------------------------------------
/.site-packages/PIL/DcxImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # DCX file handling
6 | #
7 | # DCX is a container file format defined by Intel, commonly used
8 | # for fax applications. Each DCX file consists of a directory
9 | # (a list of file offsets) followed by a set of (usually 1-bit)
10 | # PCX files.
11 | #
12 | # History:
13 | # 1995-09-09 fl Created
14 | # 1996-03-20 fl Properly derived from PcxImageFile.
15 | # 1998-07-15 fl Renamed offset attribute to avoid name clash
16 | # 2002-07-30 fl Fixed file handling
17 | #
18 | # Copyright (c) 1997-98 by Secret Labs AB.
19 | # Copyright (c) 1995-96 by Fredrik Lundh.
20 | #
21 | # See the README file for information on usage and redistribution.
22 | #
23 |
24 | from . import Image
25 | from ._binary import i32le as i32
26 | from .PcxImagePlugin import PcxImageFile
27 |
28 | MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then?
29 |
30 |
31 | def _accept(prefix):
32 | return len(prefix) >= 4 and i32(prefix) == MAGIC
33 |
34 |
35 | ##
36 | # Image plugin for the Intel DCX format.
37 |
38 |
39 | class DcxImageFile(PcxImageFile):
40 |
41 | format = "DCX"
42 | format_description = "Intel DCX"
43 | _close_exclusive_fp_after_loading = False
44 |
45 | def _open(self):
46 |
47 | # Header
48 | s = self.fp.read(4)
49 | if not _accept(s):
50 | raise SyntaxError("not a DCX file")
51 |
52 | # Component directory
53 | self._offset = []
54 | for i in range(1024):
55 | offset = i32(self.fp.read(4))
56 | if not offset:
57 | break
58 | self._offset.append(offset)
59 |
60 | self.__fp = self.fp
61 | self.frame = None
62 | self.n_frames = len(self._offset)
63 | self.is_animated = self.n_frames > 1
64 | self.seek(0)
65 |
66 | def seek(self, frame):
67 | if not self._seek_check(frame):
68 | return
69 | self.frame = frame
70 | self.fp = self.__fp
71 | self.fp.seek(self._offset[frame])
72 | PcxImageFile._open(self)
73 |
74 | def tell(self):
75 | return self.frame
76 |
77 | def _close__fp(self):
78 | try:
79 | if self.__fp != self.fp:
80 | self.__fp.close()
81 | except AttributeError:
82 | pass
83 | finally:
84 | self.__fp = None
85 |
86 |
87 | Image.register_open(DcxImageFile.format, DcxImageFile, _accept)
88 |
89 | Image.register_extension(DcxImageFile.format, ".dcx")
90 |
--------------------------------------------------------------------------------
/.site-packages/PIL/FitsImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # FITS file handling
6 | #
7 | # Copyright (c) 1998-2003 by Fredrik Lundh
8 | #
9 | # See the README file for information on usage and redistribution.
10 | #
11 |
12 | import math
13 |
14 | from . import Image, ImageFile
15 |
16 |
17 | def _accept(prefix):
18 | return prefix[:6] == b"SIMPLE"
19 |
20 |
21 | class FitsImageFile(ImageFile.ImageFile):
22 |
23 | format = "FITS"
24 | format_description = "FITS"
25 |
26 | def _open(self):
27 | headers = {}
28 | while True:
29 | header = self.fp.read(80)
30 | if not header:
31 | raise OSError("Truncated FITS file")
32 | keyword = header[:8].strip()
33 | if keyword == b"END":
34 | break
35 | value = header[8:].strip()
36 | if value.startswith(b"="):
37 | value = value[1:].strip()
38 | if not headers and (not _accept(keyword) or value != b"T"):
39 | raise SyntaxError("Not a FITS file")
40 | headers[keyword] = value
41 |
42 | naxis = int(headers[b"NAXIS"])
43 | if naxis == 0:
44 | raise ValueError("No image data")
45 | elif naxis == 1:
46 | self._size = 1, int(headers[b"NAXIS1"])
47 | else:
48 | self._size = int(headers[b"NAXIS1"]), int(headers[b"NAXIS2"])
49 |
50 | number_of_bits = int(headers[b"BITPIX"])
51 | if number_of_bits == 8:
52 | self.mode = "L"
53 | elif number_of_bits == 16:
54 | self.mode = "I"
55 | # rawmode = "I;16S"
56 | elif number_of_bits == 32:
57 | self.mode = "I"
58 | elif number_of_bits in (-32, -64):
59 | self.mode = "F"
60 | # rawmode = "F" if number_of_bits == -32 else "F;64F"
61 |
62 | offset = math.ceil(self.fp.tell() / 2880) * 2880
63 | self.tile = [("raw", (0, 0) + self.size, offset, (self.mode, 0, -1))]
64 |
65 |
66 | # --------------------------------------------------------------------
67 | # Registry
68 |
69 | Image.register_open(FitsImageFile.format, FitsImageFile, _accept)
70 |
71 | Image.register_extensions(FitsImageFile.format, [".fit", ".fits"])
72 |
--------------------------------------------------------------------------------
/.site-packages/PIL/FitsStubImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # FITS stub adapter
6 | #
7 | # Copyright (c) 1998-2003 by Fredrik Lundh
8 | #
9 | # See the README file for information on usage and redistribution.
10 | #
11 |
12 | import warnings
13 |
14 | from . import FitsImagePlugin, Image, ImageFile
15 |
16 | _handler = None
17 |
18 |
19 | def register_handler(handler):
20 | """
21 | Install application-specific FITS image handler.
22 |
23 | :param handler: Handler object.
24 | """
25 | global _handler
26 | _handler = handler
27 |
28 | warnings.warn(
29 | "FitsStubImagePlugin is deprecated and will be removed in Pillow "
30 | "10 (2023-07-01). FITS images can now be read without a handler through "
31 | "FitsImagePlugin instead.",
32 | DeprecationWarning,
33 | )
34 |
35 | # Override FitsImagePlugin with this handler
36 | # for backwards compatibility
37 | try:
38 | Image.ID.remove(FITSStubImageFile.format)
39 | except ValueError:
40 | pass
41 |
42 | Image.register_open(
43 | FITSStubImageFile.format, FITSStubImageFile, FitsImagePlugin._accept
44 | )
45 |
46 |
47 | class FITSStubImageFile(ImageFile.StubImageFile):
48 |
49 | format = FitsImagePlugin.FitsImageFile.format
50 | format_description = FitsImagePlugin.FitsImageFile.format_description
51 |
52 | def _open(self):
53 | offset = self.fp.tell()
54 |
55 | im = FitsImagePlugin.FitsImageFile(self.fp)
56 | self._size = im.size
57 | self.mode = im.mode
58 | self.tile = []
59 |
60 | self.fp.seek(offset)
61 |
62 | loader = self._load()
63 | if loader:
64 | loader.open(self)
65 |
66 | def _load(self):
67 | return _handler
68 |
69 |
70 | def _save(im, fp, filename):
71 | raise OSError("FITS save handler not installed")
72 |
73 |
74 | # --------------------------------------------------------------------
75 | # Registry
76 |
77 | Image.register_save(FITSStubImageFile.format, _save)
78 |
--------------------------------------------------------------------------------
/.site-packages/PIL/FliImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # FLI/FLC file handling.
6 | #
7 | # History:
8 | # 95-09-01 fl Created
9 | # 97-01-03 fl Fixed parser, setup decoder tile
10 | # 98-07-15 fl Renamed offset attribute to avoid name clash
11 | #
12 | # Copyright (c) Secret Labs AB 1997-98.
13 | # Copyright (c) Fredrik Lundh 1995-97.
14 | #
15 | # See the README file for information on usage and redistribution.
16 | #
17 |
18 |
19 | from . import Image, ImageFile, ImagePalette
20 | from ._binary import i16le as i16
21 | from ._binary import i32le as i32
22 | from ._binary import o8
23 |
24 | #
25 | # decoder
26 |
27 |
28 | def _accept(prefix):
29 | return (
30 | len(prefix) >= 6
31 | and i16(prefix, 4) in [0xAF11, 0xAF12]
32 | and i16(prefix, 14) in [0, 3] # flags
33 | )
34 |
35 |
36 | ##
37 | # Image plugin for the FLI/FLC animation format. Use the seek
38 | # method to load individual frames.
39 |
40 |
41 | class FliImageFile(ImageFile.ImageFile):
42 |
43 | format = "FLI"
44 | format_description = "Autodesk FLI/FLC Animation"
45 | _close_exclusive_fp_after_loading = False
46 |
47 | def _open(self):
48 |
49 | # HEAD
50 | s = self.fp.read(128)
51 | if not (_accept(s) and s[20:22] == b"\x00\x00"):
52 | raise SyntaxError("not an FLI/FLC file")
53 |
54 | # frames
55 | self.n_frames = i16(s, 6)
56 | self.is_animated = self.n_frames > 1
57 |
58 | # image characteristics
59 | self.mode = "P"
60 | self._size = i16(s, 8), i16(s, 10)
61 |
62 | # animation speed
63 | duration = i32(s, 16)
64 | magic = i16(s, 4)
65 | if magic == 0xAF11:
66 | duration = (duration * 1000) // 70
67 | self.info["duration"] = duration
68 |
69 | # look for palette
70 | palette = [(a, a, a) for a in range(256)]
71 |
72 | s = self.fp.read(16)
73 |
74 | self.__offset = 128
75 |
76 | if i16(s, 4) == 0xF100:
77 | # prefix chunk; ignore it
78 | self.__offset = self.__offset + i32(s)
79 | s = self.fp.read(16)
80 |
81 | if i16(s, 4) == 0xF1FA:
82 | # look for palette chunk
83 | s = self.fp.read(6)
84 | if i16(s, 4) == 11:
85 | self._palette(palette, 2)
86 | elif i16(s, 4) == 4:
87 | self._palette(palette, 0)
88 |
89 | palette = [o8(r) + o8(g) + o8(b) for (r, g, b) in palette]
90 | self.palette = ImagePalette.raw("RGB", b"".join(palette))
91 |
92 | # set things up to decode first frame
93 | self.__frame = -1
94 | self.__fp = self.fp
95 | self.__rewind = self.fp.tell()
96 | self.seek(0)
97 |
98 | def _palette(self, palette, shift):
99 | # load palette
100 |
101 | i = 0
102 | for e in range(i16(self.fp.read(2))):
103 | s = self.fp.read(2)
104 | i = i + s[0]
105 | n = s[1]
106 | if n == 0:
107 | n = 256
108 | s = self.fp.read(n * 3)
109 | for n in range(0, len(s), 3):
110 | r = s[n] << shift
111 | g = s[n + 1] << shift
112 | b = s[n + 2] << shift
113 | palette[i] = (r, g, b)
114 | i += 1
115 |
116 | def seek(self, frame):
117 | if not self._seek_check(frame):
118 | return
119 | if frame < self.__frame:
120 | self._seek(0)
121 |
122 | for f in range(self.__frame + 1, frame + 1):
123 | self._seek(f)
124 |
125 | def _seek(self, frame):
126 | if frame == 0:
127 | self.__frame = -1
128 | self.__fp.seek(self.__rewind)
129 | self.__offset = 128
130 | else:
131 | # ensure that the previous frame was loaded
132 | self.load()
133 |
134 | if frame != self.__frame + 1:
135 | raise ValueError(f"cannot seek to frame {frame}")
136 | self.__frame = frame
137 |
138 | # move to next frame
139 | self.fp = self.__fp
140 | self.fp.seek(self.__offset)
141 |
142 | s = self.fp.read(4)
143 | if not s:
144 | raise EOFError
145 |
146 | framesize = i32(s)
147 |
148 | self.decodermaxblock = framesize
149 | self.tile = [("fli", (0, 0) + self.size, self.__offset, None)]
150 |
151 | self.__offset += framesize
152 |
153 | def tell(self):
154 | return self.__frame
155 |
156 | def _close__fp(self):
157 | try:
158 | if self.__fp != self.fp:
159 | self.__fp.close()
160 | except AttributeError:
161 | pass
162 | finally:
163 | self.__fp = None
164 |
165 |
166 | #
167 | # registry
168 |
169 | Image.register_open(FliImageFile.format, FliImageFile, _accept)
170 |
171 | Image.register_extensions(FliImageFile.format, [".fli", ".flc"])
172 |
--------------------------------------------------------------------------------
/.site-packages/PIL/FontFile.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # base class for raster font file parsers
6 | #
7 | # history:
8 | # 1997-06-05 fl created
9 | # 1997-08-19 fl restrict image width
10 | #
11 | # Copyright (c) 1997-1998 by Secret Labs AB
12 | # Copyright (c) 1997-1998 by Fredrik Lundh
13 | #
14 | # See the README file for information on usage and redistribution.
15 | #
16 |
17 |
18 | import os
19 |
20 | from . import Image, _binary
21 |
22 | WIDTH = 800
23 |
24 |
25 | def puti16(fp, values):
26 | """Write network order (big-endian) 16-bit sequence"""
27 | for v in values:
28 | if v < 0:
29 | v += 65536
30 | fp.write(_binary.o16be(v))
31 |
32 |
33 | class FontFile:
34 | """Base class for raster font file handlers."""
35 |
36 | bitmap = None
37 |
38 | def __init__(self):
39 |
40 | self.info = {}
41 | self.glyph = [None] * 256
42 |
43 | def __getitem__(self, ix):
44 | return self.glyph[ix]
45 |
46 | def compile(self):
47 | """Create metrics and bitmap"""
48 |
49 | if self.bitmap:
50 | return
51 |
52 | # create bitmap large enough to hold all data
53 | h = w = maxwidth = 0
54 | lines = 1
55 | for glyph in self:
56 | if glyph:
57 | d, dst, src, im = glyph
58 | h = max(h, src[3] - src[1])
59 | w = w + (src[2] - src[0])
60 | if w > WIDTH:
61 | lines += 1
62 | w = src[2] - src[0]
63 | maxwidth = max(maxwidth, w)
64 |
65 | xsize = maxwidth
66 | ysize = lines * h
67 |
68 | if xsize == 0 and ysize == 0:
69 | return ""
70 |
71 | self.ysize = h
72 |
73 | # paste glyphs into bitmap
74 | self.bitmap = Image.new("1", (xsize, ysize))
75 | self.metrics = [None] * 256
76 | x = y = 0
77 | for i in range(256):
78 | glyph = self[i]
79 | if glyph:
80 | d, dst, src, im = glyph
81 | xx = src[2] - src[0]
82 | # yy = src[3] - src[1]
83 | x0, y0 = x, y
84 | x = x + xx
85 | if x > WIDTH:
86 | x, y = 0, y + h
87 | x0, y0 = x, y
88 | x = xx
89 | s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0
90 | self.bitmap.paste(im.crop(src), s)
91 | self.metrics[i] = d, dst, s
92 |
93 | def save(self, filename):
94 | """Save font"""
95 |
96 | self.compile()
97 |
98 | # font data
99 | self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG")
100 |
101 | # font metrics
102 | with open(os.path.splitext(filename)[0] + ".pil", "wb") as fp:
103 | fp.write(b"PILfont\n")
104 | fp.write(f";;;;;;{self.ysize};\n".encode("ascii")) # HACK!!!
105 | fp.write(b"DATA\n")
106 | for id in range(256):
107 | m = self.metrics[id]
108 | if not m:
109 | puti16(fp, [0] * 10)
110 | else:
111 | puti16(fp, m[0] + m[1] + m[2])
112 |
--------------------------------------------------------------------------------
/.site-packages/PIL/FtexImagePlugin.py:
--------------------------------------------------------------------------------
1 | """
2 | A Pillow loader for .ftc and .ftu files (FTEX)
3 | Jerome Leclanche
4 |
5 | The contents of this file are hereby released in the public domain (CC0)
6 | Full text of the CC0 license:
7 | https://creativecommons.org/publicdomain/zero/1.0/
8 |
9 | Independence War 2: Edge Of Chaos - Texture File Format - 16 October 2001
10 |
11 | The textures used for 3D objects in Independence War 2: Edge Of Chaos are in a
12 | packed custom format called FTEX. This file format uses file extensions FTC
13 | and FTU.
14 | * FTC files are compressed textures (using standard texture compression).
15 | * FTU files are not compressed.
16 | Texture File Format
17 | The FTC and FTU texture files both use the same format. This
18 | has the following structure:
19 | {header}
20 | {format_directory}
21 | {data}
22 | Where:
23 | {header} = {
24 | u32:magic,
25 | u32:version,
26 | u32:width,
27 | u32:height,
28 | u32:mipmap_count,
29 | u32:format_count
30 | }
31 |
32 | * The "magic" number is "FTEX".
33 | * "width" and "height" are the dimensions of the texture.
34 | * "mipmap_count" is the number of mipmaps in the texture.
35 | * "format_count" is the number of texture formats (different versions of the
36 | same texture) in this file.
37 |
38 | {format_directory} = format_count * { u32:format, u32:where }
39 |
40 | The format value is 0 for DXT1 compressed textures and 1 for 24-bit RGB
41 | uncompressed textures.
42 | The texture data for a format starts at the position "where" in the file.
43 |
44 | Each set of texture data in the file has the following structure:
45 | {data} = format_count * { u32:mipmap_size, mipmap_size * { u8 } }
46 | * "mipmap_size" is the number of bytes in that mip level. For compressed
47 | textures this is the size of the texture data compressed with DXT1. For 24 bit
48 | uncompressed textures, this is 3 * width * height. Following this are the image
49 | bytes for that mipmap level.
50 |
51 | Note: All data is stored in little-Endian (Intel) byte order.
52 | """
53 |
54 | import struct
55 | import warnings
56 | from enum import IntEnum
57 | from io import BytesIO
58 |
59 | from . import Image, ImageFile
60 |
61 | MAGIC = b"FTEX"
62 |
63 |
64 | class Format(IntEnum):
65 | DXT1 = 0
66 | UNCOMPRESSED = 1
67 |
68 |
69 | def __getattr__(name):
70 | deprecated = "deprecated and will be removed in Pillow 10 (2023-07-01). "
71 | for enum, prefix in {Format: "FORMAT_"}.items():
72 | if name.startswith(prefix):
73 | name = name[len(prefix) :]
74 | if name in enum.__members__:
75 | warnings.warn(
76 | prefix
77 | + name
78 | + " is "
79 | + deprecated
80 | + "Use "
81 | + enum.__name__
82 | + "."
83 | + name
84 | + " instead.",
85 | DeprecationWarning,
86 | stacklevel=2,
87 | )
88 | return enum[name]
89 | raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
90 |
91 |
92 | class FtexImageFile(ImageFile.ImageFile):
93 | format = "FTEX"
94 | format_description = "Texture File Format (IW2:EOC)"
95 |
96 | def _open(self):
97 | if not _accept(self.fp.read(4)):
98 | raise SyntaxError("not an FTEX file")
99 | struct.unpack("= 8 and i32(prefix, 0) >= 20 and i32(prefix, 4) in (1, 2)
33 |
34 |
35 | ##
36 | # Image plugin for the GIMP brush format.
37 |
38 |
39 | class GbrImageFile(ImageFile.ImageFile):
40 |
41 | format = "GBR"
42 | format_description = "GIMP brush file"
43 |
44 | def _open(self):
45 | header_size = i32(self.fp.read(4))
46 | if header_size < 20:
47 | raise SyntaxError("not a GIMP brush")
48 | version = i32(self.fp.read(4))
49 | if version not in (1, 2):
50 | raise SyntaxError(f"Unsupported GIMP brush version: {version}")
51 |
52 | width = i32(self.fp.read(4))
53 | height = i32(self.fp.read(4))
54 | color_depth = i32(self.fp.read(4))
55 | if width <= 0 or height <= 0:
56 | raise SyntaxError("not a GIMP brush")
57 | if color_depth not in (1, 4):
58 | raise SyntaxError(f"Unsupported GIMP brush color depth: {color_depth}")
59 |
60 | if version == 1:
61 | comment_length = header_size - 20
62 | else:
63 | comment_length = header_size - 28
64 | magic_number = self.fp.read(4)
65 | if magic_number != b"GIMP":
66 | raise SyntaxError("not a GIMP brush, bad magic number")
67 | self.info["spacing"] = i32(self.fp.read(4))
68 |
69 | comment = self.fp.read(comment_length)[:-1]
70 |
71 | if color_depth == 1:
72 | self.mode = "L"
73 | else:
74 | self.mode = "RGBA"
75 |
76 | self._size = width, height
77 |
78 | self.info["comment"] = comment
79 |
80 | # Image might not be small
81 | Image._decompression_bomb_check(self.size)
82 |
83 | # Data is an uncompressed block of w * h * bytes/pixel
84 | self._data_size = width * height * color_depth
85 |
86 | def load(self):
87 | if not self.im:
88 | self.im = Image.core.new(self.mode, self.size)
89 | self.frombytes(self.fp.read(self._data_size))
90 | return Image.Image.load(self)
91 |
92 |
93 | #
94 | # registry
95 |
96 |
97 | Image.register_open(GbrImageFile.format, GbrImageFile, _accept)
98 | Image.register_extension(GbrImageFile.format, ".gbr")
99 |
--------------------------------------------------------------------------------
/.site-packages/PIL/GdImageFile.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # GD file handling
6 | #
7 | # History:
8 | # 1996-04-12 fl Created
9 | #
10 | # Copyright (c) 1997 by Secret Labs AB.
11 | # Copyright (c) 1996 by Fredrik Lundh.
12 | #
13 | # See the README file for information on usage and redistribution.
14 | #
15 |
16 |
17 | """
18 | .. note::
19 | This format cannot be automatically recognized, so the
20 | class is not registered for use with :py:func:`PIL.Image.open()`. To open a
21 | gd file, use the :py:func:`PIL.GdImageFile.open()` function instead.
22 |
23 | .. warning::
24 | THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This
25 | implementation is provided for convenience and demonstrational
26 | purposes only.
27 | """
28 |
29 |
30 | from . import ImageFile, ImagePalette, UnidentifiedImageError
31 | from ._binary import i16be as i16
32 | from ._binary import i32be as i32
33 |
34 |
35 | class GdImageFile(ImageFile.ImageFile):
36 | """
37 | Image plugin for the GD uncompressed format. Note that this format
38 | is not supported by the standard :py:func:`PIL.Image.open()` function. To use
39 | this plugin, you have to import the :py:mod:`PIL.GdImageFile` module and
40 | use the :py:func:`PIL.GdImageFile.open()` function.
41 | """
42 |
43 | format = "GD"
44 | format_description = "GD uncompressed images"
45 |
46 | def _open(self):
47 |
48 | # Header
49 | s = self.fp.read(1037)
50 |
51 | if not i16(s) in [65534, 65535]:
52 | raise SyntaxError("Not a valid GD 2.x .gd file")
53 |
54 | self.mode = "L" # FIXME: "P"
55 | self._size = i16(s, 2), i16(s, 4)
56 |
57 | trueColor = s[6]
58 | trueColorOffset = 2 if trueColor else 0
59 |
60 | # transparency index
61 | tindex = i32(s, 7 + trueColorOffset)
62 | if tindex < 256:
63 | self.info["transparency"] = tindex
64 |
65 | self.palette = ImagePalette.raw(
66 | "XBGR", s[7 + trueColorOffset + 4 : 7 + trueColorOffset + 4 + 256 * 4]
67 | )
68 |
69 | self.tile = [
70 | ("raw", (0, 0) + self.size, 7 + trueColorOffset + 4 + 256 * 4, ("L", 0, 1))
71 | ]
72 |
73 |
74 | def open(fp, mode="r"):
75 | """
76 | Load texture from a GD image file.
77 |
78 | :param filename: GD file name, or an opened file handle.
79 | :param mode: Optional mode. In this version, if the mode argument
80 | is given, it must be "r".
81 | :returns: An image instance.
82 | :raises OSError: If the image could not be read.
83 | """
84 | if mode != "r":
85 | raise ValueError("bad mode")
86 |
87 | try:
88 | return GdImageFile(fp)
89 | except SyntaxError as e:
90 | raise UnidentifiedImageError("cannot identify this image file") from e
91 |
--------------------------------------------------------------------------------
/.site-packages/PIL/GimpGradientFile.py:
--------------------------------------------------------------------------------
1 | #
2 | # Python Imaging Library
3 | # $Id$
4 | #
5 | # stuff to read (and render) GIMP gradient files
6 | #
7 | # History:
8 | # 97-08-23 fl Created
9 | #
10 | # Copyright (c) Secret Labs AB 1997.
11 | # Copyright (c) Fredrik Lundh 1997.
12 | #
13 | # See the README file for information on usage and redistribution.
14 | #
15 |
16 | """
17 | Stuff to translate curve segments to palette values (derived from
18 | the corresponding code in GIMP, written by Federico Mena Quintero.
19 | See the GIMP distribution for more information.)
20 | """
21 |
22 |
23 | from math import log, pi, sin, sqrt
24 |
25 | from ._binary import o8
26 |
27 | EPSILON = 1e-10
28 | """""" # Enable auto-doc for data member
29 |
30 |
31 | def linear(middle, pos):
32 | if pos <= middle:
33 | if middle < EPSILON:
34 | return 0.0
35 | else:
36 | return 0.5 * pos / middle
37 | else:
38 | pos = pos - middle
39 | middle = 1.0 - middle
40 | if middle < EPSILON:
41 | return 1.0
42 | else:
43 | return 0.5 + 0.5 * pos / middle
44 |
45 |
46 | def curved(middle, pos):
47 | return pos ** (log(0.5) / log(max(middle, EPSILON)))
48 |
49 |
50 | def sine(middle, pos):
51 | return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0
52 |
53 |
54 | def sphere_increasing(middle, pos):
55 | return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2)
56 |
57 |
58 | def sphere_decreasing(middle, pos):
59 | return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2)
60 |
61 |
62 | SEGMENTS = [linear, curved, sine, sphere_increasing, sphere_decreasing]
63 | """""" # Enable auto-doc for data member
64 |
65 |
66 | class GradientFile:
67 |
68 | gradient = None
69 |
70 | def getpalette(self, entries=256):
71 |
72 | palette = []
73 |
74 | ix = 0
75 | x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix]
76 |
77 | for i in range(entries):
78 |
79 | x = i / (entries - 1)
80 |
81 | while x1 < x:
82 | ix += 1
83 | x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix]
84 |
85 | w = x1 - x0
86 |
87 | if w < EPSILON:
88 | scale = segment(0.5, 0.5)
89 | else:
90 | scale = segment((xm - x0) / w, (x - x0) / w)
91 |
92 | # expand to RGBA
93 | r = o8(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5))
94 | g = o8(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5))
95 | b = o8(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5))
96 | a = o8(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5))
97 |
98 | # add to palette
99 | palette.append(r + g + b + a)
100 |
101 | return b"".join(palette), "RGBA"
102 |
103 |
104 | class GimpGradientFile(GradientFile):
105 | """File handler for GIMP's gradient format."""
106 |
107 | def __init__(self, fp):
108 |
109 | if fp.readline()[:13] != b"GIMP Gradient":
110 | raise SyntaxError("not a GIMP gradient file")
111 |
112 | line = fp.readline()
113 |
114 | # GIMP 1.2 gradient files don't contain a name, but GIMP 1.3 files do
115 | if line.startswith(b"Name: "):
116 | line = fp.readline().strip()
117 |
118 | count = int(line)
119 |
120 | gradient = []
121 |
122 | for i in range(count):
123 |
124 | s = fp.readline().split()
125 | w = [float(x) for x in s[:11]]
126 |
127 | x0, x1 = w[0], w[2]
128 | xm = w[1]
129 | rgb0 = w[3:7]
130 | rgb1 = w[7:11]
131 |
132 | segment = SEGMENTS[int(s[11])]
133 | cspace = int(s[12])
134 |
135 | if cspace != 0:
136 | raise OSError("cannot handle HSV colour space")
137 |
138 | gradient.append((x0, x1, xm, rgb0, rgb1, segment))
139 |
140 | self.gradient = gradient
141 |
--------------------------------------------------------------------------------
/.site-packages/PIL/GimpPaletteFile.py:
--------------------------------------------------------------------------------
1 | #
2 | # Python Imaging Library
3 | # $Id$
4 | #
5 | # stuff to read GIMP palette files
6 | #
7 | # History:
8 | # 1997-08-23 fl Created
9 | # 2004-09-07 fl Support GIMP 2.0 palette files.
10 | #
11 | # Copyright (c) Secret Labs AB 1997-2004. All rights reserved.
12 | # Copyright (c) Fredrik Lundh 1997-2004.
13 | #
14 | # See the README file for information on usage and redistribution.
15 | #
16 |
17 | import re
18 |
19 | from ._binary import o8
20 |
21 |
22 | class GimpPaletteFile:
23 | """File handler for GIMP's palette format."""
24 |
25 | rawmode = "RGB"
26 |
27 | def __init__(self, fp):
28 |
29 | self.palette = [o8(i) * 3 for i in range(256)]
30 |
31 | if fp.readline()[:12] != b"GIMP Palette":
32 | raise SyntaxError("not a GIMP palette file")
33 |
34 | for i in range(256):
35 |
36 | s = fp.readline()
37 | if not s:
38 | break
39 |
40 | # skip fields and comment lines
41 | if re.match(rb"\w+:|#", s):
42 | continue
43 | if len(s) > 100:
44 | raise SyntaxError("bad palette file")
45 |
46 | v = tuple(map(int, s.split()[:3]))
47 | if len(v) != 3:
48 | raise ValueError("bad palette entry")
49 |
50 | self.palette[i] = o8(v[0]) + o8(v[1]) + o8(v[2])
51 |
52 | self.palette = b"".join(self.palette)
53 |
54 | def getpalette(self):
55 |
56 | return self.palette, self.rawmode
57 |
--------------------------------------------------------------------------------
/.site-packages/PIL/GribStubImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # GRIB stub adapter
6 | #
7 | # Copyright (c) 1996-2003 by Fredrik Lundh
8 | #
9 | # See the README file for information on usage and redistribution.
10 | #
11 |
12 | from . import Image, ImageFile
13 |
14 | _handler = None
15 |
16 |
17 | def register_handler(handler):
18 | """
19 | Install application-specific GRIB image handler.
20 |
21 | :param handler: Handler object.
22 | """
23 | global _handler
24 | _handler = handler
25 |
26 |
27 | # --------------------------------------------------------------------
28 | # Image adapter
29 |
30 |
31 | def _accept(prefix):
32 | return prefix[0:4] == b"GRIB" and prefix[7] == 1
33 |
34 |
35 | class GribStubImageFile(ImageFile.StubImageFile):
36 |
37 | format = "GRIB"
38 | format_description = "GRIB"
39 |
40 | def _open(self):
41 |
42 | offset = self.fp.tell()
43 |
44 | if not _accept(self.fp.read(8)):
45 | raise SyntaxError("Not a GRIB file")
46 |
47 | self.fp.seek(offset)
48 |
49 | # make something up
50 | self.mode = "F"
51 | self._size = 1, 1
52 |
53 | loader = self._load()
54 | if loader:
55 | loader.open(self)
56 |
57 | def _load(self):
58 | return _handler
59 |
60 |
61 | def _save(im, fp, filename):
62 | if _handler is None or not hasattr(_handler, "save"):
63 | raise OSError("GRIB save handler not installed")
64 | _handler.save(im, fp, filename)
65 |
66 |
67 | # --------------------------------------------------------------------
68 | # Registry
69 |
70 | Image.register_open(GribStubImageFile.format, GribStubImageFile, _accept)
71 | Image.register_save(GribStubImageFile.format, _save)
72 |
73 | Image.register_extension(GribStubImageFile.format, ".grib")
74 |
--------------------------------------------------------------------------------
/.site-packages/PIL/Hdf5StubImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # HDF5 stub adapter
6 | #
7 | # Copyright (c) 2000-2003 by Fredrik Lundh
8 | #
9 | # See the README file for information on usage and redistribution.
10 | #
11 |
12 | from . import Image, ImageFile
13 |
14 | _handler = None
15 |
16 |
17 | def register_handler(handler):
18 | """
19 | Install application-specific HDF5 image handler.
20 |
21 | :param handler: Handler object.
22 | """
23 | global _handler
24 | _handler = handler
25 |
26 |
27 | # --------------------------------------------------------------------
28 | # Image adapter
29 |
30 |
31 | def _accept(prefix):
32 | return prefix[:8] == b"\x89HDF\r\n\x1a\n"
33 |
34 |
35 | class HDF5StubImageFile(ImageFile.StubImageFile):
36 |
37 | format = "HDF5"
38 | format_description = "HDF5"
39 |
40 | def _open(self):
41 |
42 | offset = self.fp.tell()
43 |
44 | if not _accept(self.fp.read(8)):
45 | raise SyntaxError("Not an HDF file")
46 |
47 | self.fp.seek(offset)
48 |
49 | # make something up
50 | self.mode = "F"
51 | self._size = 1, 1
52 |
53 | loader = self._load()
54 | if loader:
55 | loader.open(self)
56 |
57 | def _load(self):
58 | return _handler
59 |
60 |
61 | def _save(im, fp, filename):
62 | if _handler is None or not hasattr(_handler, "save"):
63 | raise OSError("HDF5 save handler not installed")
64 | _handler.save(im, fp, filename)
65 |
66 |
67 | # --------------------------------------------------------------------
68 | # Registry
69 |
70 | Image.register_open(HDF5StubImageFile.format, HDF5StubImageFile, _accept)
71 | Image.register_save(HDF5StubImageFile.format, _save)
72 |
73 | Image.register_extensions(HDF5StubImageFile.format, [".h5", ".hdf"])
74 |
--------------------------------------------------------------------------------
/.site-packages/PIL/ImageDraw2.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # WCK-style drawing interface operations
6 | #
7 | # History:
8 | # 2003-12-07 fl created
9 | # 2005-05-15 fl updated; added to PIL as ImageDraw2
10 | # 2005-05-15 fl added text support
11 | # 2005-05-20 fl added arc/chord/pieslice support
12 | #
13 | # Copyright (c) 2003-2005 by Secret Labs AB
14 | # Copyright (c) 2003-2005 by Fredrik Lundh
15 | #
16 | # See the README file for information on usage and redistribution.
17 | #
18 |
19 |
20 | """
21 | (Experimental) WCK-style drawing interface operations
22 |
23 | .. seealso:: :py:mod:`PIL.ImageDraw`
24 | """
25 |
26 |
27 | from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath
28 |
29 |
30 | class Pen:
31 | """Stores an outline color and width."""
32 |
33 | def __init__(self, color, width=1, opacity=255):
34 | self.color = ImageColor.getrgb(color)
35 | self.width = width
36 |
37 |
38 | class Brush:
39 | """Stores a fill color"""
40 |
41 | def __init__(self, color, opacity=255):
42 | self.color = ImageColor.getrgb(color)
43 |
44 |
45 | class Font:
46 | """Stores a TrueType font and color"""
47 |
48 | def __init__(self, color, file, size=12):
49 | # FIXME: add support for bitmap fonts
50 | self.color = ImageColor.getrgb(color)
51 | self.font = ImageFont.truetype(file, size)
52 |
53 |
54 | class Draw:
55 | """
56 | (Experimental) WCK-style drawing interface
57 | """
58 |
59 | def __init__(self, image, size=None, color=None):
60 | if not hasattr(image, "im"):
61 | image = Image.new(image, size, color)
62 | self.draw = ImageDraw.Draw(image)
63 | self.image = image
64 | self.transform = None
65 |
66 | def flush(self):
67 | return self.image
68 |
69 | def render(self, op, xy, pen, brush=None):
70 | # handle color arguments
71 | outline = fill = None
72 | width = 1
73 | if isinstance(pen, Pen):
74 | outline = pen.color
75 | width = pen.width
76 | elif isinstance(brush, Pen):
77 | outline = brush.color
78 | width = brush.width
79 | if isinstance(brush, Brush):
80 | fill = brush.color
81 | elif isinstance(pen, Brush):
82 | fill = pen.color
83 | # handle transformation
84 | if self.transform:
85 | xy = ImagePath.Path(xy)
86 | xy.transform(self.transform)
87 | # render the item
88 | if op == "line":
89 | self.draw.line(xy, fill=outline, width=width)
90 | else:
91 | getattr(self.draw, op)(xy, fill=fill, outline=outline)
92 |
93 | def settransform(self, offset):
94 | """Sets a transformation offset."""
95 | (xoffset, yoffset) = offset
96 | self.transform = (1, 0, xoffset, 0, 1, yoffset)
97 |
98 | def arc(self, xy, start, end, *options):
99 | """
100 | Draws an arc (a portion of a circle outline) between the start and end
101 | angles, inside the given bounding box.
102 |
103 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.arc`
104 | """
105 | self.render("arc", xy, start, end, *options)
106 |
107 | def chord(self, xy, start, end, *options):
108 | """
109 | Same as :py:meth:`~PIL.ImageDraw2.Draw.arc`, but connects the end points
110 | with a straight line.
111 |
112 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.chord`
113 | """
114 | self.render("chord", xy, start, end, *options)
115 |
116 | def ellipse(self, xy, *options):
117 | """
118 | Draws an ellipse inside the given bounding box.
119 |
120 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.ellipse`
121 | """
122 | self.render("ellipse", xy, *options)
123 |
124 | def line(self, xy, *options):
125 | """
126 | Draws a line between the coordinates in the ``xy`` list.
127 |
128 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.line`
129 | """
130 | self.render("line", xy, *options)
131 |
132 | def pieslice(self, xy, start, end, *options):
133 | """
134 | Same as arc, but also draws straight lines between the end points and the
135 | center of the bounding box.
136 |
137 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.pieslice`
138 | """
139 | self.render("pieslice", xy, start, end, *options)
140 |
141 | def polygon(self, xy, *options):
142 | """
143 | Draws a polygon.
144 |
145 | The polygon outline consists of straight lines between the given
146 | coordinates, plus a straight line between the last and the first
147 | coordinate.
148 |
149 |
150 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.polygon`
151 | """
152 | self.render("polygon", xy, *options)
153 |
154 | def rectangle(self, xy, *options):
155 | """
156 | Draws a rectangle.
157 |
158 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.rectangle`
159 | """
160 | self.render("rectangle", xy, *options)
161 |
162 | def text(self, xy, text, font):
163 | """
164 | Draws the string at the given position.
165 |
166 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.text`
167 | """
168 | if self.transform:
169 | xy = ImagePath.Path(xy)
170 | xy.transform(self.transform)
171 | self.draw.text(xy, text, font=font.font, fill=font.color)
172 |
173 | def textsize(self, text, font):
174 | """
175 | Return the size of the given string, in pixels.
176 |
177 | .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.textsize`
178 | """
179 | return self.draw.textsize(text, font=font.font)
180 |
--------------------------------------------------------------------------------
/.site-packages/PIL/ImageEnhance.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # image enhancement classes
6 | #
7 | # For a background, see "Image Processing By Interpolation and
8 | # Extrapolation", Paul Haeberli and Douglas Voorhies. Available
9 | # at http://www.graficaobscura.com/interp/index.html
10 | #
11 | # History:
12 | # 1996-03-23 fl Created
13 | # 2009-06-16 fl Fixed mean calculation
14 | #
15 | # Copyright (c) Secret Labs AB 1997.
16 | # Copyright (c) Fredrik Lundh 1996.
17 | #
18 | # See the README file for information on usage and redistribution.
19 | #
20 |
21 | from . import Image, ImageFilter, ImageStat
22 |
23 |
24 | class _Enhance:
25 | def enhance(self, factor):
26 | """
27 | Returns an enhanced image.
28 |
29 | :param factor: A floating point value controlling the enhancement.
30 | Factor 1.0 always returns a copy of the original image,
31 | lower factors mean less color (brightness, contrast,
32 | etc), and higher values more. There are no restrictions
33 | on this value.
34 | :rtype: :py:class:`~PIL.Image.Image`
35 | """
36 | return Image.blend(self.degenerate, self.image, factor)
37 |
38 |
39 | class Color(_Enhance):
40 | """Adjust image color balance.
41 |
42 | This class can be used to adjust the colour balance of an image, in
43 | a manner similar to the controls on a colour TV set. An enhancement
44 | factor of 0.0 gives a black and white image. A factor of 1.0 gives
45 | the original image.
46 | """
47 |
48 | def __init__(self, image):
49 | self.image = image
50 | self.intermediate_mode = "L"
51 | if "A" in image.getbands():
52 | self.intermediate_mode = "LA"
53 |
54 | self.degenerate = image.convert(self.intermediate_mode).convert(image.mode)
55 |
56 |
57 | class Contrast(_Enhance):
58 | """Adjust image contrast.
59 |
60 | This class can be used to control the contrast of an image, similar
61 | to the contrast control on a TV set. An enhancement factor of 0.0
62 | gives a solid grey image. A factor of 1.0 gives the original image.
63 | """
64 |
65 | def __init__(self, image):
66 | self.image = image
67 | mean = int(ImageStat.Stat(image.convert("L")).mean[0] + 0.5)
68 | self.degenerate = Image.new("L", image.size, mean).convert(image.mode)
69 |
70 | if "A" in image.getbands():
71 | self.degenerate.putalpha(image.getchannel("A"))
72 |
73 |
74 | class Brightness(_Enhance):
75 | """Adjust image brightness.
76 |
77 | This class can be used to control the brightness of an image. An
78 | enhancement factor of 0.0 gives a black image. A factor of 1.0 gives the
79 | original image.
80 | """
81 |
82 | def __init__(self, image):
83 | self.image = image
84 | self.degenerate = Image.new(image.mode, image.size, 0)
85 |
86 | if "A" in image.getbands():
87 | self.degenerate.putalpha(image.getchannel("A"))
88 |
89 |
90 | class Sharpness(_Enhance):
91 | """Adjust image sharpness.
92 |
93 | This class can be used to adjust the sharpness of an image. An
94 | enhancement factor of 0.0 gives a blurred image, a factor of 1.0 gives the
95 | original image, and a factor of 2.0 gives a sharpened image.
96 | """
97 |
98 | def __init__(self, image):
99 | self.image = image
100 | self.degenerate = image.filter(ImageFilter.SMOOTH)
101 |
102 | if "A" in image.getbands():
103 | self.degenerate.putalpha(image.getchannel("A"))
104 |
--------------------------------------------------------------------------------
/.site-packages/PIL/ImageGrab.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # screen grabber
6 | #
7 | # History:
8 | # 2001-04-26 fl created
9 | # 2001-09-17 fl use builtin driver, if present
10 | # 2002-11-19 fl added grabclipboard support
11 | #
12 | # Copyright (c) 2001-2002 by Secret Labs AB
13 | # Copyright (c) 2001-2002 by Fredrik Lundh
14 | #
15 | # See the README file for information on usage and redistribution.
16 | #
17 |
18 | import sys
19 |
20 | from . import Image
21 |
22 | if sys.platform == "darwin":
23 | import os
24 | import subprocess
25 | import tempfile
26 |
27 |
28 | def grab(bbox=None, include_layered_windows=False, all_screens=False, xdisplay=None):
29 | if xdisplay is None:
30 | if sys.platform == "darwin":
31 | fh, filepath = tempfile.mkstemp(".png")
32 | os.close(fh)
33 | args = ["screencapture"]
34 | if bbox:
35 | left, top, right, bottom = bbox
36 | args += ["-R", f"{left},{right},{right-left},{bottom-top}"]
37 | subprocess.call(args + ["-x", filepath])
38 | im = Image.open(filepath)
39 | im.load()
40 | os.unlink(filepath)
41 | if bbox:
42 | im_resized = im.resize((right - left, bottom - top))
43 | im.close()
44 | return im_resized
45 | return im
46 | elif sys.platform == "win32":
47 | offset, size, data = Image.core.grabscreen_win32(
48 | include_layered_windows, all_screens
49 | )
50 | im = Image.frombytes(
51 | "RGB",
52 | size,
53 | data,
54 | # RGB, 32-bit line padding, origin lower left corner
55 | "raw",
56 | "BGR",
57 | (size[0] * 3 + 3) & -4,
58 | -1,
59 | )
60 | if bbox:
61 | x0, y0 = offset
62 | left, top, right, bottom = bbox
63 | im = im.crop((left - x0, top - y0, right - x0, bottom - y0))
64 | return im
65 | # use xdisplay=None for default display on non-win32/macOS systems
66 | if not Image.core.HAVE_XCB:
67 | raise OSError("Pillow was built without XCB support")
68 | size, data = Image.core.grabscreen_x11(xdisplay)
69 | im = Image.frombytes("RGB", size, data, "raw", "BGRX", size[0] * 4, 1)
70 | if bbox:
71 | im = im.crop(bbox)
72 | return im
73 |
74 |
75 | def grabclipboard():
76 | if sys.platform == "darwin":
77 | fh, filepath = tempfile.mkstemp(".jpg")
78 | os.close(fh)
79 | commands = [
80 | 'set theFile to (open for access POSIX file "'
81 | + filepath
82 | + '" with write permission)',
83 | "try",
84 | " write (the clipboard as JPEG picture) to theFile",
85 | "end try",
86 | "close access theFile",
87 | ]
88 | script = ["osascript"]
89 | for command in commands:
90 | script += ["-e", command]
91 | subprocess.call(script)
92 |
93 | im = None
94 | if os.stat(filepath).st_size != 0:
95 | im = Image.open(filepath)
96 | im.load()
97 | os.unlink(filepath)
98 | return im
99 | elif sys.platform == "win32":
100 | fmt, data = Image.core.grabclipboard_win32()
101 | if fmt == "file": # CF_HDROP
102 | import struct
103 |
104 | o = struct.unpack_from("I", data)[0]
105 | if data[16] != 0:
106 | files = data[o:].decode("utf-16le").split("\0")
107 | else:
108 | files = data[o:].decode("mbcs").split("\0")
109 | return files[: files.index("")]
110 | if isinstance(data, bytes):
111 | import io
112 |
113 | data = io.BytesIO(data)
114 | if fmt == "png":
115 | from . import PngImagePlugin
116 |
117 | return PngImagePlugin.PngImageFile(data)
118 | elif fmt == "DIB":
119 | from . import BmpImagePlugin
120 |
121 | return BmpImagePlugin.DibImageFile(data)
122 | return None
123 | else:
124 | raise NotImplementedError("ImageGrab.grabclipboard() is macOS and Windows only")
125 |
--------------------------------------------------------------------------------
/.site-packages/PIL/ImageMode.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # standard mode descriptors
6 | #
7 | # History:
8 | # 2006-03-20 fl Added
9 | #
10 | # Copyright (c) 2006 by Secret Labs AB.
11 | # Copyright (c) 2006 by Fredrik Lundh.
12 | #
13 | # See the README file for information on usage and redistribution.
14 | #
15 |
16 | import sys
17 |
18 | # mode descriptor cache
19 | _modes = None
20 |
21 |
22 | class ModeDescriptor:
23 | """Wrapper for mode strings."""
24 |
25 | def __init__(self, mode, bands, basemode, basetype, typestr):
26 | self.mode = mode
27 | self.bands = bands
28 | self.basemode = basemode
29 | self.basetype = basetype
30 | self.typestr = typestr
31 |
32 | def __str__(self):
33 | return self.mode
34 |
35 |
36 | def getmode(mode):
37 | """Gets a mode descriptor for the given mode."""
38 | global _modes
39 | if not _modes:
40 | # initialize mode cache
41 | modes = {}
42 | endian = "<" if sys.byteorder == "little" else ">"
43 | for m, (basemode, basetype, bands, typestr) in {
44 | # core modes
45 | # Bits need to be extended to bytes
46 | "1": ("L", "L", ("1",), "|b1"),
47 | "L": ("L", "L", ("L",), "|u1"),
48 | "I": ("L", "I", ("I",), endian + "i4"),
49 | "F": ("L", "F", ("F",), endian + "f4"),
50 | "P": ("P", "L", ("P",), "|u1"),
51 | "RGB": ("RGB", "L", ("R", "G", "B"), "|u1"),
52 | "RGBX": ("RGB", "L", ("R", "G", "B", "X"), "|u1"),
53 | "RGBA": ("RGB", "L", ("R", "G", "B", "A"), "|u1"),
54 | "CMYK": ("RGB", "L", ("C", "M", "Y", "K"), "|u1"),
55 | "YCbCr": ("RGB", "L", ("Y", "Cb", "Cr"), "|u1"),
56 | # UNDONE - unsigned |u1i1i1
57 | "LAB": ("RGB", "L", ("L", "A", "B"), "|u1"),
58 | "HSV": ("RGB", "L", ("H", "S", "V"), "|u1"),
59 | # extra experimental modes
60 | "RGBa": ("RGB", "L", ("R", "G", "B", "a"), "|u1"),
61 | "BGR;15": ("RGB", "L", ("B", "G", "R"), endian + "u2"),
62 | "BGR;16": ("RGB", "L", ("B", "G", "R"), endian + "u2"),
63 | "BGR;24": ("RGB", "L", ("B", "G", "R"), endian + "u3"),
64 | "BGR;32": ("RGB", "L", ("B", "G", "R"), endian + "u4"),
65 | "LA": ("L", "L", ("L", "A"), "|u1"),
66 | "La": ("L", "L", ("L", "a"), "|u1"),
67 | "PA": ("RGB", "L", ("P", "A"), "|u1"),
68 | }.items():
69 | modes[m] = ModeDescriptor(m, bands, basemode, basetype, typestr)
70 | # mapping modes
71 | for i16mode, typestr in {
72 | # I;16 == I;16L, and I;32 == I;32L
73 | "I;16": "u2",
78 | "I;16BS": ">i2",
79 | "I;16N": endian + "u2",
80 | "I;16NS": endian + "i2",
81 | "I;32": "u4",
83 | "I;32L": "i4",
86 | "I;32LS": " half:
117 | break
118 | v.append(j)
119 | return v
120 |
121 | def _getrms(self):
122 | """Get RMS for each layer"""
123 |
124 | v = []
125 | for i in self.bands:
126 | v.append(math.sqrt(self.sum2[i] / self.count[i]))
127 | return v
128 |
129 | def _getvar(self):
130 | """Get variance for each layer"""
131 |
132 | v = []
133 | for i in self.bands:
134 | n = self.count[i]
135 | v.append((self.sum2[i] - (self.sum[i] ** 2.0) / n) / n)
136 | return v
137 |
138 | def _getstddev(self):
139 | """Get standard deviation for each layer"""
140 |
141 | v = []
142 | for i in self.bands:
143 | v.append(math.sqrt(self.var[i]))
144 | return v
145 |
146 |
147 | Global = Stat # compatibility
148 |
--------------------------------------------------------------------------------
/.site-packages/PIL/ImageTransform.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # transform wrappers
6 | #
7 | # History:
8 | # 2002-04-08 fl Created
9 | #
10 | # Copyright (c) 2002 by Secret Labs AB
11 | # Copyright (c) 2002 by Fredrik Lundh
12 | #
13 | # See the README file for information on usage and redistribution.
14 | #
15 |
16 | from . import Image
17 |
18 |
19 | class Transform(Image.ImageTransformHandler):
20 | def __init__(self, data):
21 | self.data = data
22 |
23 | def getdata(self):
24 | return self.method, self.data
25 |
26 | def transform(self, size, image, **options):
27 | # can be overridden
28 | method, data = self.getdata()
29 | return image.transform(size, method, data, **options)
30 |
31 |
32 | class AffineTransform(Transform):
33 | """
34 | Define an affine image transform.
35 |
36 | This function takes a 6-tuple (a, b, c, d, e, f) which contain the first
37 | two rows from an affine transform matrix. For each pixel (x, y) in the
38 | output image, the new value is taken from a position (a x + b y + c,
39 | d x + e y + f) in the input image, rounded to nearest pixel.
40 |
41 | This function can be used to scale, translate, rotate, and shear the
42 | original image.
43 |
44 | See :py:meth:`~PIL.Image.Image.transform`
45 |
46 | :param matrix: A 6-tuple (a, b, c, d, e, f) containing the first two rows
47 | from an affine transform matrix.
48 | """
49 |
50 | method = Image.Transform.AFFINE
51 |
52 |
53 | class ExtentTransform(Transform):
54 | """
55 | Define a transform to extract a subregion from an image.
56 |
57 | Maps a rectangle (defined by two corners) from the image to a rectangle of
58 | the given size. The resulting image will contain data sampled from between
59 | the corners, such that (x0, y0) in the input image will end up at (0,0) in
60 | the output image, and (x1, y1) at size.
61 |
62 | This method can be used to crop, stretch, shrink, or mirror an arbitrary
63 | rectangle in the current image. It is slightly slower than crop, but about
64 | as fast as a corresponding resize operation.
65 |
66 | See :py:meth:`~PIL.Image.Image.transform`
67 |
68 | :param bbox: A 4-tuple (x0, y0, x1, y1) which specifies two points in the
69 | input image's coordinate system. See :ref:`coordinate-system`.
70 | """
71 |
72 | method = Image.Transform.EXTENT
73 |
74 |
75 | class QuadTransform(Transform):
76 | """
77 | Define a quad image transform.
78 |
79 | Maps a quadrilateral (a region defined by four corners) from the image to a
80 | rectangle of the given size.
81 |
82 | See :py:meth:`~PIL.Image.Image.transform`
83 |
84 | :param xy: An 8-tuple (x0, y0, x1, y1, x2, y2, x3, y3) which contain the
85 | upper left, lower left, lower right, and upper right corner of the
86 | source quadrilateral.
87 | """
88 |
89 | method = Image.Transform.QUAD
90 |
91 |
92 | class MeshTransform(Transform):
93 | """
94 | Define a mesh image transform. A mesh transform consists of one or more
95 | individual quad transforms.
96 |
97 | See :py:meth:`~PIL.Image.Image.transform`
98 |
99 | :param data: A list of (bbox, quad) tuples.
100 | """
101 |
102 | method = Image.Transform.MESH
103 |
--------------------------------------------------------------------------------
/.site-packages/PIL/ImtImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # IM Tools support for PIL
6 | #
7 | # history:
8 | # 1996-05-27 fl Created (read 8-bit images only)
9 | # 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.2)
10 | #
11 | # Copyright (c) Secret Labs AB 1997-2001.
12 | # Copyright (c) Fredrik Lundh 1996-2001.
13 | #
14 | # See the README file for information on usage and redistribution.
15 | #
16 |
17 |
18 | import re
19 |
20 | from . import Image, ImageFile
21 |
22 | #
23 | # --------------------------------------------------------------------
24 |
25 | field = re.compile(rb"([a-z]*) ([^ \r\n]*)")
26 |
27 |
28 | ##
29 | # Image plugin for IM Tools images.
30 |
31 |
32 | class ImtImageFile(ImageFile.ImageFile):
33 |
34 | format = "IMT"
35 | format_description = "IM Tools"
36 |
37 | def _open(self):
38 |
39 | # Quick rejection: if there's not a LF among the first
40 | # 100 bytes, this is (probably) not a text header.
41 |
42 | if b"\n" not in self.fp.read(100):
43 | raise SyntaxError("not an IM file")
44 | self.fp.seek(0)
45 |
46 | xsize = ysize = 0
47 |
48 | while True:
49 |
50 | s = self.fp.read(1)
51 | if not s:
52 | break
53 |
54 | if s == b"\x0C":
55 |
56 | # image data begins
57 | self.tile = [
58 | ("raw", (0, 0) + self.size, self.fp.tell(), (self.mode, 0, 1))
59 | ]
60 |
61 | break
62 |
63 | else:
64 |
65 | # read key/value pair
66 | # FIXME: dangerous, may read whole file
67 | s = s + self.fp.readline()
68 | if len(s) == 1 or len(s) > 100:
69 | break
70 | if s[0] == ord(b"*"):
71 | continue # comment
72 |
73 | m = field.match(s)
74 | if not m:
75 | break
76 | k, v = m.group(1, 2)
77 | if k == "width":
78 | xsize = int(v)
79 | self._size = xsize, ysize
80 | elif k == "height":
81 | ysize = int(v)
82 | self._size = xsize, ysize
83 | elif k == "pixel" and v == "n8":
84 | self.mode = "L"
85 |
86 |
87 | #
88 | # --------------------------------------------------------------------
89 |
90 | Image.register_open(ImtImageFile.format, ImtImageFile)
91 |
92 | #
93 | # no extension registered (".im" is simply too common)
94 |
--------------------------------------------------------------------------------
/.site-packages/PIL/McIdasImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # Basic McIdas support for PIL
6 | #
7 | # History:
8 | # 1997-05-05 fl Created (8-bit images only)
9 | # 2009-03-08 fl Added 16/32-bit support.
10 | #
11 | # Thanks to Richard Jones and Craig Swank for specs and samples.
12 | #
13 | # Copyright (c) Secret Labs AB 1997.
14 | # Copyright (c) Fredrik Lundh 1997.
15 | #
16 | # See the README file for information on usage and redistribution.
17 | #
18 |
19 | import struct
20 |
21 | from . import Image, ImageFile
22 |
23 |
24 | def _accept(s):
25 | return s[:8] == b"\x00\x00\x00\x00\x00\x00\x00\x04"
26 |
27 |
28 | ##
29 | # Image plugin for McIdas area images.
30 |
31 |
32 | class McIdasImageFile(ImageFile.ImageFile):
33 |
34 | format = "MCIDAS"
35 | format_description = "McIdas area file"
36 |
37 | def _open(self):
38 |
39 | # parse area file directory
40 | s = self.fp.read(256)
41 | if not _accept(s) or len(s) != 256:
42 | raise SyntaxError("not an McIdas area file")
43 |
44 | self.area_descriptor_raw = s
45 | self.area_descriptor = w = [0] + list(struct.unpack("!64i", s))
46 |
47 | # get mode
48 | if w[11] == 1:
49 | mode = rawmode = "L"
50 | elif w[11] == 2:
51 | # FIXME: add memory map support
52 | mode = "I"
53 | rawmode = "I;16B"
54 | elif w[11] == 4:
55 | # FIXME: add memory map support
56 | mode = "I"
57 | rawmode = "I;32B"
58 | else:
59 | raise SyntaxError("unsupported McIdas format")
60 |
61 | self.mode = mode
62 | self._size = w[10], w[9]
63 |
64 | offset = w[34] + w[15]
65 | stride = w[15] + w[10] * w[11] * w[14]
66 |
67 | self.tile = [("raw", (0, 0) + self.size, offset, (rawmode, stride, 1))]
68 |
69 |
70 | # --------------------------------------------------------------------
71 | # registry
72 |
73 | Image.register_open(McIdasImageFile.format, McIdasImageFile, _accept)
74 |
75 | # no default extension
76 |
--------------------------------------------------------------------------------
/.site-packages/PIL/MicImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # Microsoft Image Composer support for PIL
6 | #
7 | # Notes:
8 | # uses TiffImagePlugin.py to read the actual image streams
9 | #
10 | # History:
11 | # 97-01-20 fl Created
12 | #
13 | # Copyright (c) Secret Labs AB 1997.
14 | # Copyright (c) Fredrik Lundh 1997.
15 | #
16 | # See the README file for information on usage and redistribution.
17 | #
18 |
19 |
20 | import olefile
21 |
22 | from . import Image, TiffImagePlugin
23 |
24 | #
25 | # --------------------------------------------------------------------
26 |
27 |
28 | def _accept(prefix):
29 | return prefix[:8] == olefile.MAGIC
30 |
31 |
32 | ##
33 | # Image plugin for Microsoft's Image Composer file format.
34 |
35 |
36 | class MicImageFile(TiffImagePlugin.TiffImageFile):
37 |
38 | format = "MIC"
39 | format_description = "Microsoft Image Composer"
40 | _close_exclusive_fp_after_loading = False
41 |
42 | def _open(self):
43 |
44 | # read the OLE directory and see if this is a likely
45 | # to be a Microsoft Image Composer file
46 |
47 | try:
48 | self.ole = olefile.OleFileIO(self.fp)
49 | except OSError as e:
50 | raise SyntaxError("not an MIC file; invalid OLE file") from e
51 |
52 | # find ACI subfiles with Image members (maybe not the
53 | # best way to identify MIC files, but what the... ;-)
54 |
55 | self.images = []
56 | for path in self.ole.listdir():
57 | if path[1:] and path[0][-4:] == ".ACI" and path[1] == "Image":
58 | self.images.append(path)
59 |
60 | # if we didn't find any images, this is probably not
61 | # an MIC file.
62 | if not self.images:
63 | raise SyntaxError("not an MIC file; no image entries")
64 |
65 | self.__fp = self.fp
66 | self.frame = None
67 | self._n_frames = len(self.images)
68 | self.is_animated = self._n_frames > 1
69 |
70 | if len(self.images) > 1:
71 | self._category = Image.CONTAINER
72 |
73 | self.seek(0)
74 |
75 | def seek(self, frame):
76 | if not self._seek_check(frame):
77 | return
78 | try:
79 | filename = self.images[frame]
80 | except IndexError as e:
81 | raise EOFError("no such frame") from e
82 |
83 | self.fp = self.ole.openstream(filename)
84 |
85 | TiffImagePlugin.TiffImageFile._open(self)
86 |
87 | self.frame = frame
88 |
89 | def tell(self):
90 | return self.frame
91 |
92 | def _close__fp(self):
93 | try:
94 | if self.__fp != self.fp:
95 | self.__fp.close()
96 | except AttributeError:
97 | pass
98 | finally:
99 | self.__fp = None
100 |
101 |
102 | #
103 | # --------------------------------------------------------------------
104 |
105 | Image.register_open(MicImageFile.format, MicImageFile, _accept)
106 |
107 | Image.register_extension(MicImageFile.format, ".mic")
108 |
--------------------------------------------------------------------------------
/.site-packages/PIL/MpegImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # MPEG file handling
6 | #
7 | # History:
8 | # 95-09-09 fl Created
9 | #
10 | # Copyright (c) Secret Labs AB 1997.
11 | # Copyright (c) Fredrik Lundh 1995.
12 | #
13 | # See the README file for information on usage and redistribution.
14 | #
15 |
16 |
17 | from . import Image, ImageFile
18 | from ._binary import i8
19 |
20 | #
21 | # Bitstream parser
22 |
23 |
24 | class BitStream:
25 | def __init__(self, fp):
26 | self.fp = fp
27 | self.bits = 0
28 | self.bitbuffer = 0
29 |
30 | def next(self):
31 | return i8(self.fp.read(1))
32 |
33 | def peek(self, bits):
34 | while self.bits < bits:
35 | c = self.next()
36 | if c < 0:
37 | self.bits = 0
38 | continue
39 | self.bitbuffer = (self.bitbuffer << 8) + c
40 | self.bits += 8
41 | return self.bitbuffer >> (self.bits - bits) & (1 << bits) - 1
42 |
43 | def skip(self, bits):
44 | while self.bits < bits:
45 | self.bitbuffer = (self.bitbuffer << 8) + i8(self.fp.read(1))
46 | self.bits += 8
47 | self.bits = self.bits - bits
48 |
49 | def read(self, bits):
50 | v = self.peek(bits)
51 | self.bits = self.bits - bits
52 | return v
53 |
54 |
55 | ##
56 | # Image plugin for MPEG streams. This plugin can identify a stream,
57 | # but it cannot read it.
58 |
59 |
60 | class MpegImageFile(ImageFile.ImageFile):
61 |
62 | format = "MPEG"
63 | format_description = "MPEG"
64 |
65 | def _open(self):
66 |
67 | s = BitStream(self.fp)
68 |
69 | if s.read(32) != 0x1B3:
70 | raise SyntaxError("not an MPEG file")
71 |
72 | self.mode = "RGB"
73 | self._size = s.read(12), s.read(12)
74 |
75 |
76 | # --------------------------------------------------------------------
77 | # Registry stuff
78 |
79 | Image.register_open(MpegImageFile.format, MpegImageFile)
80 |
81 | Image.register_extensions(MpegImageFile.format, [".mpg", ".mpeg"])
82 |
83 | Image.register_mime(MpegImageFile.format, "video/mpeg")
84 |
--------------------------------------------------------------------------------
/.site-packages/PIL/MpoImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # MPO file handling
6 | #
7 | # See "Multi-Picture Format" (CIPA DC-007-Translation 2009, Standard of the
8 | # Camera & Imaging Products Association)
9 | #
10 | # The multi-picture object combines multiple JPEG images (with a modified EXIF
11 | # data format) into a single file. While it can theoretically be used much like
12 | # a GIF animation, it is commonly used to represent 3D photographs and is (as
13 | # of this writing) the most commonly used format by 3D cameras.
14 | #
15 | # History:
16 | # 2014-03-13 Feneric Created
17 | #
18 | # See the README file for information on usage and redistribution.
19 | #
20 |
21 | from . import Image, ImageFile, JpegImagePlugin
22 | from ._binary import i16be as i16
23 |
24 | # def _accept(prefix):
25 | # return JpegImagePlugin._accept(prefix)
26 |
27 |
28 | def _save(im, fp, filename):
29 | # Note that we can only save the current frame at present
30 | return JpegImagePlugin._save(im, fp, filename)
31 |
32 |
33 | ##
34 | # Image plugin for MPO images.
35 |
36 |
37 | class MpoImageFile(JpegImagePlugin.JpegImageFile):
38 |
39 | format = "MPO"
40 | format_description = "MPO (CIPA DC-007)"
41 | _close_exclusive_fp_after_loading = False
42 |
43 | def _open(self):
44 | self.fp.seek(0) # prep the fp in order to pass the JPEG test
45 | JpegImagePlugin.JpegImageFile._open(self)
46 | self._after_jpeg_open()
47 |
48 | def _after_jpeg_open(self, mpheader=None):
49 | self._initial_size = self.size
50 | self.mpinfo = mpheader if mpheader is not None else self._getmp()
51 | self.n_frames = self.mpinfo[0xB001]
52 | self.__mpoffsets = [
53 | mpent["DataOffset"] + self.info["mpoffset"] for mpent in self.mpinfo[0xB002]
54 | ]
55 | self.__mpoffsets[0] = 0
56 | # Note that the following assertion will only be invalid if something
57 | # gets broken within JpegImagePlugin.
58 | assert self.n_frames == len(self.__mpoffsets)
59 | del self.info["mpoffset"] # no longer needed
60 | self.is_animated = self.n_frames > 1
61 | self.__fp = self.fp # FIXME: hack
62 | self.__fp.seek(self.__mpoffsets[0]) # get ready to read first frame
63 | self.__frame = 0
64 | self.offset = 0
65 | # for now we can only handle reading and individual frame extraction
66 | self.readonly = 1
67 |
68 | def load_seek(self, pos):
69 | self.__fp.seek(pos)
70 |
71 | def seek(self, frame):
72 | if not self._seek_check(frame):
73 | return
74 | self.fp = self.__fp
75 | self.offset = self.__mpoffsets[frame]
76 |
77 | self.fp.seek(self.offset + 2) # skip SOI marker
78 | segment = self.fp.read(2)
79 | if not segment:
80 | raise ValueError("No data found for frame")
81 | self._size = self._initial_size
82 | if i16(segment) == 0xFFE1: # APP1
83 | n = i16(self.fp.read(2)) - 2
84 | self.info["exif"] = ImageFile._safe_read(self.fp, n)
85 |
86 | mptype = self.mpinfo[0xB002][frame]["Attribute"]["MPType"]
87 | if mptype.startswith("Large Thumbnail"):
88 | exif = self.getexif().get_ifd(0x8769)
89 | if 40962 in exif and 40963 in exif:
90 | self._size = (exif[40962], exif[40963])
91 | elif "exif" in self.info:
92 | del self.info["exif"]
93 |
94 | self.tile = [("jpeg", (0, 0) + self.size, self.offset, (self.mode, ""))]
95 | self.__frame = frame
96 |
97 | def tell(self):
98 | return self.__frame
99 |
100 | def _close__fp(self):
101 | try:
102 | if self.__fp != self.fp:
103 | self.__fp.close()
104 | except AttributeError:
105 | pass
106 | finally:
107 | self.__fp = None
108 |
109 | @staticmethod
110 | def adopt(jpeg_instance, mpheader=None):
111 | """
112 | Transform the instance of JpegImageFile into
113 | an instance of MpoImageFile.
114 | After the call, the JpegImageFile is extended
115 | to be an MpoImageFile.
116 |
117 | This is essentially useful when opening a JPEG
118 | file that reveals itself as an MPO, to avoid
119 | double call to _open.
120 | """
121 | jpeg_instance.__class__ = MpoImageFile
122 | jpeg_instance._after_jpeg_open(mpheader)
123 | return jpeg_instance
124 |
125 |
126 | # ---------------------------------------------------------------------
127 | # Registry stuff
128 |
129 | # Note that since MPO shares a factory with JPEG, we do not need to do a
130 | # separate registration for it here.
131 | # Image.register_open(MpoImageFile.format,
132 | # JpegImagePlugin.jpeg_factory, _accept)
133 | Image.register_save(MpoImageFile.format, _save)
134 |
135 | Image.register_extension(MpoImageFile.format, ".mpo")
136 |
137 | Image.register_mime(MpoImageFile.format, "image/mpo")
138 |
--------------------------------------------------------------------------------
/.site-packages/PIL/PaletteFile.py:
--------------------------------------------------------------------------------
1 | #
2 | # Python Imaging Library
3 | # $Id$
4 | #
5 | # stuff to read simple, teragon-style palette files
6 | #
7 | # History:
8 | # 97-08-23 fl Created
9 | #
10 | # Copyright (c) Secret Labs AB 1997.
11 | # Copyright (c) Fredrik Lundh 1997.
12 | #
13 | # See the README file for information on usage and redistribution.
14 | #
15 |
16 | from ._binary import o8
17 |
18 |
19 | class PaletteFile:
20 | """File handler for Teragon-style palette files."""
21 |
22 | rawmode = "RGB"
23 |
24 | def __init__(self, fp):
25 |
26 | self.palette = [(i, i, i) for i in range(256)]
27 |
28 | while True:
29 |
30 | s = fp.readline()
31 |
32 | if not s:
33 | break
34 | if s[0:1] == b"#":
35 | continue
36 | if len(s) > 100:
37 | raise SyntaxError("bad palette file")
38 |
39 | v = [int(x) for x in s.split()]
40 | try:
41 | [i, r, g, b] = v
42 | except ValueError:
43 | [i, r] = v
44 | g = b = r
45 |
46 | if 0 <= i <= 255:
47 | self.palette[i] = o8(r) + o8(g) + o8(b)
48 |
49 | self.palette = b"".join(self.palette)
50 |
51 | def getpalette(self):
52 |
53 | return self.palette, self.rawmode
54 |
--------------------------------------------------------------------------------
/.site-packages/PIL/PcdImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # PCD file handling
6 | #
7 | # History:
8 | # 96-05-10 fl Created
9 | # 96-05-27 fl Added draft mode (128x192, 256x384)
10 | #
11 | # Copyright (c) Secret Labs AB 1997.
12 | # Copyright (c) Fredrik Lundh 1996.
13 | #
14 | # See the README file for information on usage and redistribution.
15 | #
16 |
17 |
18 | from . import Image, ImageFile
19 |
20 | ##
21 | # Image plugin for PhotoCD images. This plugin only reads the 768x512
22 | # image from the file; higher resolutions are encoded in a proprietary
23 | # encoding.
24 |
25 |
26 | class PcdImageFile(ImageFile.ImageFile):
27 |
28 | format = "PCD"
29 | format_description = "Kodak PhotoCD"
30 |
31 | def _open(self):
32 |
33 | # rough
34 | self.fp.seek(2048)
35 | s = self.fp.read(2048)
36 |
37 | if s[:4] != b"PCD_":
38 | raise SyntaxError("not a PCD file")
39 |
40 | orientation = s[1538] & 3
41 | self.tile_post_rotate = None
42 | if orientation == 1:
43 | self.tile_post_rotate = 90
44 | elif orientation == 3:
45 | self.tile_post_rotate = -90
46 |
47 | self.mode = "RGB"
48 | self._size = 768, 512 # FIXME: not correct for rotated images!
49 | self.tile = [("pcd", (0, 0) + self.size, 96 * 2048, None)]
50 |
51 | def load_end(self):
52 | if self.tile_post_rotate:
53 | # Handle rotated PCDs
54 | self.im = self.im.rotate(self.tile_post_rotate)
55 | self._size = self.im.size
56 |
57 |
58 | #
59 | # registry
60 |
61 | Image.register_open(PcdImageFile.format, PcdImageFile)
62 |
63 | Image.register_extension(PcdImageFile.format, ".pcd")
64 |
--------------------------------------------------------------------------------
/.site-packages/PIL/PixarImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # PIXAR raster support for PIL
6 | #
7 | # history:
8 | # 97-01-29 fl Created
9 | #
10 | # notes:
11 | # This is incomplete; it is based on a few samples created with
12 | # Photoshop 2.5 and 3.0, and a summary description provided by
13 | # Greg Coats . Hopefully, "L" and
14 | # "RGBA" support will be added in future versions.
15 | #
16 | # Copyright (c) Secret Labs AB 1997.
17 | # Copyright (c) Fredrik Lundh 1997.
18 | #
19 | # See the README file for information on usage and redistribution.
20 | #
21 |
22 | from . import Image, ImageFile
23 | from ._binary import i16le as i16
24 |
25 | #
26 | # helpers
27 |
28 |
29 | def _accept(prefix):
30 | return prefix[:4] == b"\200\350\000\000"
31 |
32 |
33 | ##
34 | # Image plugin for PIXAR raster images.
35 |
36 |
37 | class PixarImageFile(ImageFile.ImageFile):
38 |
39 | format = "PIXAR"
40 | format_description = "PIXAR raster image"
41 |
42 | def _open(self):
43 |
44 | # assuming a 4-byte magic label
45 | s = self.fp.read(4)
46 | if not _accept(s):
47 | raise SyntaxError("not a PIXAR file")
48 |
49 | # read rest of header
50 | s = s + self.fp.read(508)
51 |
52 | self._size = i16(s, 418), i16(s, 416)
53 |
54 | # get channel/depth descriptions
55 | mode = i16(s, 424), i16(s, 426)
56 |
57 | if mode == (14, 2):
58 | self.mode = "RGB"
59 | # FIXME: to be continued...
60 |
61 | # create tile descriptor (assuming "dumped")
62 | self.tile = [("raw", (0, 0) + self.size, 1024, (self.mode, 0, 1))]
63 |
64 |
65 | #
66 | # --------------------------------------------------------------------
67 |
68 | Image.register_open(PixarImageFile.format, PixarImageFile, _accept)
69 |
70 | Image.register_extension(PixarImageFile.format, ".pxr")
71 |
--------------------------------------------------------------------------------
/.site-packages/PIL/SunImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # Sun image file handling
6 | #
7 | # History:
8 | # 1995-09-10 fl Created
9 | # 1996-05-28 fl Fixed 32-bit alignment
10 | # 1998-12-29 fl Import ImagePalette module
11 | # 2001-12-18 fl Fixed palette loading (from Jean-Claude Rimbault)
12 | #
13 | # Copyright (c) 1997-2001 by Secret Labs AB
14 | # Copyright (c) 1995-1996 by Fredrik Lundh
15 | #
16 | # See the README file for information on usage and redistribution.
17 | #
18 |
19 |
20 | from . import Image, ImageFile, ImagePalette
21 | from ._binary import i32be as i32
22 |
23 |
24 | def _accept(prefix):
25 | return len(prefix) >= 4 and i32(prefix) == 0x59A66A95
26 |
27 |
28 | ##
29 | # Image plugin for Sun raster files.
30 |
31 |
32 | class SunImageFile(ImageFile.ImageFile):
33 |
34 | format = "SUN"
35 | format_description = "Sun Raster File"
36 |
37 | def _open(self):
38 |
39 | # The Sun Raster file header is 32 bytes in length
40 | # and has the following format:
41 |
42 | # typedef struct _SunRaster
43 | # {
44 | # DWORD MagicNumber; /* Magic (identification) number */
45 | # DWORD Width; /* Width of image in pixels */
46 | # DWORD Height; /* Height of image in pixels */
47 | # DWORD Depth; /* Number of bits per pixel */
48 | # DWORD Length; /* Size of image data in bytes */
49 | # DWORD Type; /* Type of raster file */
50 | # DWORD ColorMapType; /* Type of color map */
51 | # DWORD ColorMapLength; /* Size of the color map in bytes */
52 | # } SUNRASTER;
53 |
54 | # HEAD
55 | s = self.fp.read(32)
56 | if not _accept(s):
57 | raise SyntaxError("not an SUN raster file")
58 |
59 | offset = 32
60 |
61 | self._size = i32(s, 4), i32(s, 8)
62 |
63 | depth = i32(s, 12)
64 | # data_length = i32(s, 16) # unreliable, ignore.
65 | file_type = i32(s, 20)
66 | palette_type = i32(s, 24) # 0: None, 1: RGB, 2: Raw/arbitrary
67 | palette_length = i32(s, 28)
68 |
69 | if depth == 1:
70 | self.mode, rawmode = "1", "1;I"
71 | elif depth == 4:
72 | self.mode, rawmode = "L", "L;4"
73 | elif depth == 8:
74 | self.mode = rawmode = "L"
75 | elif depth == 24:
76 | if file_type == 3:
77 | self.mode, rawmode = "RGB", "RGB"
78 | else:
79 | self.mode, rawmode = "RGB", "BGR"
80 | elif depth == 32:
81 | if file_type == 3:
82 | self.mode, rawmode = "RGB", "RGBX"
83 | else:
84 | self.mode, rawmode = "RGB", "BGRX"
85 | else:
86 | raise SyntaxError("Unsupported Mode/Bit Depth")
87 |
88 | if palette_length:
89 | if palette_length > 1024:
90 | raise SyntaxError("Unsupported Color Palette Length")
91 |
92 | if palette_type != 1:
93 | raise SyntaxError("Unsupported Palette Type")
94 |
95 | offset = offset + palette_length
96 | self.palette = ImagePalette.raw("RGB;L", self.fp.read(palette_length))
97 | if self.mode == "L":
98 | self.mode = "P"
99 | rawmode = rawmode.replace("L", "P")
100 |
101 | # 16 bit boundaries on stride
102 | stride = ((self.size[0] * depth + 15) // 16) * 2
103 |
104 | # file type: Type is the version (or flavor) of the bitmap
105 | # file. The following values are typically found in the Type
106 | # field:
107 | # 0000h Old
108 | # 0001h Standard
109 | # 0002h Byte-encoded
110 | # 0003h RGB format
111 | # 0004h TIFF format
112 | # 0005h IFF format
113 | # FFFFh Experimental
114 |
115 | # Old and standard are the same, except for the length tag.
116 | # byte-encoded is run-length-encoded
117 | # RGB looks similar to standard, but RGB byte order
118 | # TIFF and IFF mean that they were converted from T/IFF
119 | # Experimental means that it's something else.
120 | # (https://www.fileformat.info/format/sunraster/egff.htm)
121 |
122 | if file_type in (0, 1, 3, 4, 5):
123 | self.tile = [("raw", (0, 0) + self.size, offset, (rawmode, stride))]
124 | elif file_type == 2:
125 | self.tile = [("sun_rle", (0, 0) + self.size, offset, rawmode)]
126 | else:
127 | raise SyntaxError("Unsupported Sun Raster file type")
128 |
129 |
130 | #
131 | # registry
132 |
133 |
134 | Image.register_open(SunImageFile.format, SunImageFile, _accept)
135 |
136 | Image.register_extension(SunImageFile.format, ".ras")
137 |
--------------------------------------------------------------------------------
/.site-packages/PIL/TarIO.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # read files from within a tar file
6 | #
7 | # History:
8 | # 95-06-18 fl Created
9 | # 96-05-28 fl Open files in binary mode
10 | #
11 | # Copyright (c) Secret Labs AB 1997.
12 | # Copyright (c) Fredrik Lundh 1995-96.
13 | #
14 | # See the README file for information on usage and redistribution.
15 | #
16 |
17 | import io
18 |
19 | from . import ContainerIO
20 |
21 |
22 | class TarIO(ContainerIO.ContainerIO):
23 | """A file object that provides read access to a given member of a TAR file."""
24 |
25 | def __init__(self, tarfile, file):
26 | """
27 | Create file object.
28 |
29 | :param tarfile: Name of TAR file.
30 | :param file: Name of member file.
31 | """
32 | self.fh = open(tarfile, "rb")
33 |
34 | while True:
35 |
36 | s = self.fh.read(512)
37 | if len(s) != 512:
38 | raise OSError("unexpected end of tar file")
39 |
40 | name = s[:100].decode("utf-8")
41 | i = name.find("\0")
42 | if i == 0:
43 | raise OSError("cannot find subfile")
44 | if i > 0:
45 | name = name[:i]
46 |
47 | size = int(s[124:135], 8)
48 |
49 | if file == name:
50 | break
51 |
52 | self.fh.seek((size + 511) & (~511), io.SEEK_CUR)
53 |
54 | # Open region
55 | super().__init__(self.fh, self.fh.tell(), size)
56 |
57 | # Context manager support
58 | def __enter__(self):
59 | return self
60 |
61 | def __exit__(self, *args):
62 | self.close()
63 |
64 | def close(self):
65 | self.fh.close()
66 |
--------------------------------------------------------------------------------
/.site-packages/PIL/WmfImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library
3 | # $Id$
4 | #
5 | # WMF stub codec
6 | #
7 | # history:
8 | # 1996-12-14 fl Created
9 | # 2004-02-22 fl Turned into a stub driver
10 | # 2004-02-23 fl Added EMF support
11 | #
12 | # Copyright (c) Secret Labs AB 1997-2004. All rights reserved.
13 | # Copyright (c) Fredrik Lundh 1996.
14 | #
15 | # See the README file for information on usage and redistribution.
16 | #
17 | # WMF/EMF reference documentation:
18 | # https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-WMF/[MS-WMF].pdf
19 | # http://wvware.sourceforge.net/caolan/index.html
20 | # http://wvware.sourceforge.net/caolan/ora-wmf.html
21 |
22 | from . import Image, ImageFile
23 | from ._binary import i16le as word
24 | from ._binary import si16le as short
25 | from ._binary import si32le as _long
26 |
27 | _handler = None
28 |
29 |
30 | def register_handler(handler):
31 | """
32 | Install application-specific WMF image handler.
33 |
34 | :param handler: Handler object.
35 | """
36 | global _handler
37 | _handler = handler
38 |
39 |
40 | if hasattr(Image.core, "drawwmf"):
41 | # install default handler (windows only)
42 |
43 | class WmfHandler:
44 | def open(self, im):
45 | im.mode = "RGB"
46 | self.bbox = im.info["wmf_bbox"]
47 |
48 | def load(self, im):
49 | im.fp.seek(0) # rewind
50 | return Image.frombytes(
51 | "RGB",
52 | im.size,
53 | Image.core.drawwmf(im.fp.read(), im.size, self.bbox),
54 | "raw",
55 | "BGR",
56 | (im.size[0] * 3 + 3) & -4,
57 | -1,
58 | )
59 |
60 | register_handler(WmfHandler())
61 |
62 | #
63 | # --------------------------------------------------------------------
64 | # Read WMF file
65 |
66 |
67 | def _accept(prefix):
68 | return (
69 | prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or prefix[:4] == b"\x01\x00\x00\x00"
70 | )
71 |
72 |
73 | ##
74 | # Image plugin for Windows metafiles.
75 |
76 |
77 | class WmfStubImageFile(ImageFile.StubImageFile):
78 |
79 | format = "WMF"
80 | format_description = "Windows Metafile"
81 |
82 | def _open(self):
83 | self._inch = None
84 |
85 | # check placable header
86 | s = self.fp.read(80)
87 |
88 | if s[:6] == b"\xd7\xcd\xc6\x9a\x00\x00":
89 |
90 | # placeable windows metafile
91 |
92 | # get units per inch
93 | self._inch = word(s, 14)
94 |
95 | # get bounding box
96 | x0 = short(s, 6)
97 | y0 = short(s, 8)
98 | x1 = short(s, 10)
99 | y1 = short(s, 12)
100 |
101 | # normalize size to 72 dots per inch
102 | self.info["dpi"] = 72
103 | size = (
104 | (x1 - x0) * self.info["dpi"] // self._inch,
105 | (y1 - y0) * self.info["dpi"] // self._inch,
106 | )
107 |
108 | self.info["wmf_bbox"] = x0, y0, x1, y1
109 |
110 | # sanity check (standard metafile header)
111 | if s[22:26] != b"\x01\x00\t\x00":
112 | raise SyntaxError("Unsupported WMF file format")
113 |
114 | elif s[:4] == b"\x01\x00\x00\x00" and s[40:44] == b" EMF":
115 | # enhanced metafile
116 |
117 | # get bounding box
118 | x0 = _long(s, 8)
119 | y0 = _long(s, 12)
120 | x1 = _long(s, 16)
121 | y1 = _long(s, 20)
122 |
123 | # get frame (in 0.01 millimeter units)
124 | frame = _long(s, 24), _long(s, 28), _long(s, 32), _long(s, 36)
125 |
126 | size = x1 - x0, y1 - y0
127 |
128 | # calculate dots per inch from bbox and frame
129 | xdpi = 2540.0 * (x1 - y0) / (frame[2] - frame[0])
130 | ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1])
131 |
132 | self.info["wmf_bbox"] = x0, y0, x1, y1
133 |
134 | if xdpi == ydpi:
135 | self.info["dpi"] = xdpi
136 | else:
137 | self.info["dpi"] = xdpi, ydpi
138 |
139 | else:
140 | raise SyntaxError("Unsupported file format")
141 |
142 | self.mode = "RGB"
143 | self._size = size
144 |
145 | loader = self._load()
146 | if loader:
147 | loader.open(self)
148 |
149 | def _load(self):
150 | return _handler
151 |
152 | def load(self, dpi=None):
153 | if dpi is not None and self._inch is not None:
154 | self.info["dpi"] = dpi
155 | x0, y0, x1, y1 = self.info["wmf_bbox"]
156 | self._size = (
157 | (x1 - x0) * self.info["dpi"] // self._inch,
158 | (y1 - y0) * self.info["dpi"] // self._inch,
159 | )
160 | return super().load()
161 |
162 |
163 | def _save(im, fp, filename):
164 | if _handler is None or not hasattr(_handler, "save"):
165 | raise OSError("WMF save handler not installed")
166 | _handler.save(im, fp, filename)
167 |
168 |
169 | #
170 | # --------------------------------------------------------------------
171 | # Registry stuff
172 |
173 |
174 | Image.register_open(WmfStubImageFile.format, WmfStubImageFile, _accept)
175 | Image.register_save(WmfStubImageFile.format, _save)
176 |
177 | Image.register_extensions(WmfStubImageFile.format, [".wmf", ".emf"])
178 |
--------------------------------------------------------------------------------
/.site-packages/PIL/XVThumbImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # XV Thumbnail file handler by Charles E. "Gene" Cash
6 | # (gcash@magicnet.net)
7 | #
8 | # see xvcolor.c and xvbrowse.c in the sources to John Bradley's XV,
9 | # available from ftp://ftp.cis.upenn.edu/pub/xv/
10 | #
11 | # history:
12 | # 98-08-15 cec created (b/w only)
13 | # 98-12-09 cec added color palette
14 | # 98-12-28 fl added to PIL (with only a few very minor modifications)
15 | #
16 | # To do:
17 | # FIXME: make save work (this requires quantization support)
18 | #
19 |
20 | from . import Image, ImageFile, ImagePalette
21 | from ._binary import o8
22 |
23 | _MAGIC = b"P7 332"
24 |
25 | # standard color palette for thumbnails (RGB332)
26 | PALETTE = b""
27 | for r in range(8):
28 | for g in range(8):
29 | for b in range(4):
30 | PALETTE = PALETTE + (
31 | o8((r * 255) // 7) + o8((g * 255) // 7) + o8((b * 255) // 3)
32 | )
33 |
34 |
35 | def _accept(prefix):
36 | return prefix[:6] == _MAGIC
37 |
38 |
39 | ##
40 | # Image plugin for XV thumbnail images.
41 |
42 |
43 | class XVThumbImageFile(ImageFile.ImageFile):
44 |
45 | format = "XVThumb"
46 | format_description = "XV thumbnail image"
47 |
48 | def _open(self):
49 |
50 | # check magic
51 | if not _accept(self.fp.read(6)):
52 | raise SyntaxError("not an XV thumbnail file")
53 |
54 | # Skip to beginning of next line
55 | self.fp.readline()
56 |
57 | # skip info comments
58 | while True:
59 | s = self.fp.readline()
60 | if not s:
61 | raise SyntaxError("Unexpected EOF reading XV thumbnail file")
62 | if s[0] != 35: # ie. when not a comment: '#'
63 | break
64 |
65 | # parse header line (already read)
66 | s = s.strip().split()
67 |
68 | self.mode = "P"
69 | self._size = int(s[0]), int(s[1])
70 |
71 | self.palette = ImagePalette.raw("RGB", PALETTE)
72 |
73 | self.tile = [("raw", (0, 0) + self.size, self.fp.tell(), (self.mode, 0, 1))]
74 |
75 |
76 | # --------------------------------------------------------------------
77 |
78 | Image.register_open(XVThumbImageFile.format, XVThumbImageFile, _accept)
79 |
--------------------------------------------------------------------------------
/.site-packages/PIL/XbmImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # XBM File handling
6 | #
7 | # History:
8 | # 1995-09-08 fl Created
9 | # 1996-11-01 fl Added save support
10 | # 1997-07-07 fl Made header parser more tolerant
11 | # 1997-07-22 fl Fixed yet another parser bug
12 | # 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4)
13 | # 2001-05-13 fl Added hotspot handling (based on code from Bernhard Herzog)
14 | # 2004-02-24 fl Allow some whitespace before first #define
15 | #
16 | # Copyright (c) 1997-2004 by Secret Labs AB
17 | # Copyright (c) 1996-1997 by Fredrik Lundh
18 | #
19 | # See the README file for information on usage and redistribution.
20 | #
21 |
22 | import re
23 |
24 | from . import Image, ImageFile
25 |
26 | # XBM header
27 | xbm_head = re.compile(
28 | rb"\s*#define[ \t]+.*_width[ \t]+(?P[0-9]+)[\r\n]+"
29 | b"#define[ \t]+.*_height[ \t]+(?P[0-9]+)[\r\n]+"
30 | b"(?P"
31 | b"#define[ \t]+[^_]*_x_hot[ \t]+(?P[0-9]+)[\r\n]+"
32 | b"#define[ \t]+[^_]*_y_hot[ \t]+(?P[0-9]+)[\r\n]+"
33 | b")?"
34 | b"[\\000-\\377]*_bits\\[\\]"
35 | )
36 |
37 |
38 | def _accept(prefix):
39 | return prefix.lstrip()[:7] == b"#define"
40 |
41 |
42 | ##
43 | # Image plugin for X11 bitmaps.
44 |
45 |
46 | class XbmImageFile(ImageFile.ImageFile):
47 |
48 | format = "XBM"
49 | format_description = "X11 Bitmap"
50 |
51 | def _open(self):
52 |
53 | m = xbm_head.match(self.fp.read(512))
54 |
55 | if not m:
56 | raise SyntaxError("not a XBM file")
57 |
58 | xsize = int(m.group("width"))
59 | ysize = int(m.group("height"))
60 |
61 | if m.group("hotspot"):
62 | self.info["hotspot"] = (int(m.group("xhot")), int(m.group("yhot")))
63 |
64 | self.mode = "1"
65 | self._size = xsize, ysize
66 |
67 | self.tile = [("xbm", (0, 0) + self.size, m.end(), None)]
68 |
69 |
70 | def _save(im, fp, filename):
71 |
72 | if im.mode != "1":
73 | raise OSError(f"cannot write mode {im.mode} as XBM")
74 |
75 | fp.write(f"#define im_width {im.size[0]}\n".encode("ascii"))
76 | fp.write(f"#define im_height {im.size[1]}\n".encode("ascii"))
77 |
78 | hotspot = im.encoderinfo.get("hotspot")
79 | if hotspot:
80 | fp.write(f"#define im_x_hot {hotspot[0]}\n".encode("ascii"))
81 | fp.write(f"#define im_y_hot {hotspot[1]}\n".encode("ascii"))
82 |
83 | fp.write(b"static char im_bits[] = {\n")
84 |
85 | ImageFile._save(im, fp, [("xbm", (0, 0) + im.size, 0, None)])
86 |
87 | fp.write(b"};\n")
88 |
89 |
90 | Image.register_open(XbmImageFile.format, XbmImageFile, _accept)
91 | Image.register_save(XbmImageFile.format, _save)
92 |
93 | Image.register_extension(XbmImageFile.format, ".xbm")
94 |
95 | Image.register_mime(XbmImageFile.format, "image/xbm")
96 |
--------------------------------------------------------------------------------
/.site-packages/PIL/XpmImagePlugin.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # XPM File handling
6 | #
7 | # History:
8 | # 1996-12-29 fl Created
9 | # 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7)
10 | #
11 | # Copyright (c) Secret Labs AB 1997-2001.
12 | # Copyright (c) Fredrik Lundh 1996-2001.
13 | #
14 | # See the README file for information on usage and redistribution.
15 | #
16 |
17 |
18 | import re
19 |
20 | from . import Image, ImageFile, ImagePalette
21 | from ._binary import o8
22 |
23 | # XPM header
24 | xpm_head = re.compile(b'"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)')
25 |
26 |
27 | def _accept(prefix):
28 | return prefix[:9] == b"/* XPM */"
29 |
30 |
31 | ##
32 | # Image plugin for X11 pixel maps.
33 |
34 |
35 | class XpmImageFile(ImageFile.ImageFile):
36 |
37 | format = "XPM"
38 | format_description = "X11 Pixel Map"
39 |
40 | def _open(self):
41 |
42 | if not _accept(self.fp.read(9)):
43 | raise SyntaxError("not an XPM file")
44 |
45 | # skip forward to next string
46 | while True:
47 | s = self.fp.readline()
48 | if not s:
49 | raise SyntaxError("broken XPM file")
50 | m = xpm_head.match(s)
51 | if m:
52 | break
53 |
54 | self._size = int(m.group(1)), int(m.group(2))
55 |
56 | pal = int(m.group(3))
57 | bpp = int(m.group(4))
58 |
59 | if pal > 256 or bpp != 1:
60 | raise ValueError("cannot read this XPM file")
61 |
62 | #
63 | # load palette description
64 |
65 | palette = [b"\0\0\0"] * 256
66 |
67 | for i in range(pal):
68 |
69 | s = self.fp.readline()
70 | if s[-2:] == b"\r\n":
71 | s = s[:-2]
72 | elif s[-1:] in b"\r\n":
73 | s = s[:-1]
74 |
75 | c = s[1]
76 | s = s[2:-2].split()
77 |
78 | for i in range(0, len(s), 2):
79 |
80 | if s[i] == b"c":
81 |
82 | # process colour key
83 | rgb = s[i + 1]
84 | if rgb == b"None":
85 | self.info["transparency"] = c
86 | elif rgb[0:1] == b"#":
87 | # FIXME: handle colour names (see ImagePalette.py)
88 | rgb = int(rgb[1:], 16)
89 | palette[c] = (
90 | o8((rgb >> 16) & 255) + o8((rgb >> 8) & 255) + o8(rgb & 255)
91 | )
92 | else:
93 | # unknown colour
94 | raise ValueError("cannot read this XPM file")
95 | break
96 |
97 | else:
98 |
99 | # missing colour key
100 | raise ValueError("cannot read this XPM file")
101 |
102 | self.mode = "P"
103 | self.palette = ImagePalette.raw("RGB", b"".join(palette))
104 |
105 | self.tile = [("raw", (0, 0) + self.size, self.fp.tell(), ("P", 0, 1))]
106 |
107 | def load_read(self, bytes):
108 |
109 | #
110 | # load all image data in one chunk
111 |
112 | xsize, ysize = self.size
113 |
114 | s = [None] * ysize
115 |
116 | for i in range(ysize):
117 | s[i] = self.fp.readline()[1 : xsize + 1].ljust(xsize)
118 |
119 | return b"".join(s)
120 |
121 |
122 | #
123 | # Registry
124 |
125 |
126 | Image.register_open(XpmImageFile.format, XpmImageFile, _accept)
127 |
128 | Image.register_extension(XpmImageFile.format, ".xpm")
129 |
130 | Image.register_mime(XpmImageFile.format, "image/xpm")
131 |
--------------------------------------------------------------------------------
/.site-packages/PIL/__init__.py:
--------------------------------------------------------------------------------
1 | """Pillow (Fork of the Python Imaging Library)
2 |
3 | Pillow is the friendly PIL fork by Alex Clark and Contributors.
4 | https://github.com/python-pillow/Pillow/
5 |
6 | Pillow is forked from PIL 1.1.7.
7 |
8 | PIL is the Python Imaging Library by Fredrik Lundh and Contributors.
9 | Copyright (c) 1999 by Secret Labs AB.
10 |
11 | Use PIL.__version__ for this Pillow version.
12 |
13 | ;-)
14 | """
15 |
16 | from . import _version
17 |
18 | # VERSION was removed in Pillow 6.0.0.
19 | # PILLOW_VERSION was removed in Pillow 9.0.0.
20 | # Use __version__ instead.
21 | __version__ = _version.__version__
22 | del _version
23 |
24 |
25 | _plugins = [
26 | "BlpImagePlugin",
27 | "BmpImagePlugin",
28 | "BufrStubImagePlugin",
29 | "CurImagePlugin",
30 | "DcxImagePlugin",
31 | "DdsImagePlugin",
32 | "EpsImagePlugin",
33 | "FitsImagePlugin",
34 | "FitsStubImagePlugin",
35 | "FliImagePlugin",
36 | "FpxImagePlugin",
37 | "FtexImagePlugin",
38 | "GbrImagePlugin",
39 | "GifImagePlugin",
40 | "GribStubImagePlugin",
41 | "Hdf5StubImagePlugin",
42 | "IcnsImagePlugin",
43 | "IcoImagePlugin",
44 | "ImImagePlugin",
45 | "ImtImagePlugin",
46 | "IptcImagePlugin",
47 | "JpegImagePlugin",
48 | "Jpeg2KImagePlugin",
49 | "McIdasImagePlugin",
50 | "MicImagePlugin",
51 | "MpegImagePlugin",
52 | "MpoImagePlugin",
53 | "MspImagePlugin",
54 | "PalmImagePlugin",
55 | "PcdImagePlugin",
56 | "PcxImagePlugin",
57 | "PdfImagePlugin",
58 | "PixarImagePlugin",
59 | "PngImagePlugin",
60 | "PpmImagePlugin",
61 | "PsdImagePlugin",
62 | "SgiImagePlugin",
63 | "SpiderImagePlugin",
64 | "SunImagePlugin",
65 | "TgaImagePlugin",
66 | "TiffImagePlugin",
67 | "WebPImagePlugin",
68 | "WmfImagePlugin",
69 | "XbmImagePlugin",
70 | "XpmImagePlugin",
71 | "XVThumbImagePlugin",
72 | ]
73 |
74 |
75 | class UnidentifiedImageError(OSError):
76 | """
77 | Raised in :py:meth:`PIL.Image.open` if an image cannot be opened and identified.
78 | """
79 |
80 | pass
81 |
--------------------------------------------------------------------------------
/.site-packages/PIL/__main__.py:
--------------------------------------------------------------------------------
1 | from .features import pilinfo
2 |
3 | pilinfo()
4 |
--------------------------------------------------------------------------------
/.site-packages/PIL/_binary.py:
--------------------------------------------------------------------------------
1 | #
2 | # The Python Imaging Library.
3 | # $Id$
4 | #
5 | # Binary input/output support routines.
6 | #
7 | # Copyright (c) 1997-2003 by Secret Labs AB
8 | # Copyright (c) 1995-2003 by Fredrik Lundh
9 | # Copyright (c) 2012 by Brian Crowell
10 | #
11 | # See the README file for information on usage and redistribution.
12 | #
13 |
14 |
15 | """Binary input/output support routines."""
16 |
17 |
18 | from struct import pack, unpack_from
19 |
20 |
21 | def i8(c):
22 | return c if c.__class__ is int else c[0]
23 |
24 |
25 | def o8(i):
26 | return bytes((i & 255,))
27 |
28 |
29 | # Input, le = little endian, be = big endian
30 | def i16le(c, o=0):
31 | """
32 | Converts a 2-bytes (16 bits) string to an unsigned integer.
33 |
34 | :param c: string containing bytes to convert
35 | :param o: offset of bytes to convert in string
36 | """
37 | return unpack_from("h", c, o)[0]
58 |
59 |
60 | def i32le(c, o=0):
61 | """
62 | Converts a 4-bytes (32 bits) string to an unsigned integer.
63 |
64 | :param c: string containing bytes to convert
65 | :param o: offset of bytes to convert in string
66 | """
67 | return unpack_from("H", c, o)[0]
82 |
83 |
84 | def i32be(c, o=0):
85 | return unpack_from(">I", c, o)[0]
86 |
87 |
88 | # Output, le = little endian, be = big endian
89 | def o16le(i):
90 | return pack("H", i)
99 |
100 |
101 | def o32be(i):
102 | return pack(">I", i)
103 |
--------------------------------------------------------------------------------
/.site-packages/PIL/_tkinter_finder.py:
--------------------------------------------------------------------------------
1 | """ Find compiled module linking to Tcl / Tk libraries
2 | """
3 | import sys
4 | import tkinter
5 | import warnings
6 | from tkinter import _tkinter as tk
7 |
8 | try:
9 | if hasattr(sys, "pypy_find_executable"):
10 | TKINTER_LIB = tk.tklib_cffi.__file__
11 | else:
12 | TKINTER_LIB = tk.__file__
13 | except AttributeError:
14 | # _tkinter may be compiled directly into Python, in which case __file__ is
15 | # not available. load_tkinter_funcs will check the binary first in any case.
16 | TKINTER_LIB = None
17 |
18 | tk_version = str(tkinter.TkVersion)
19 | if tk_version == "8.4":
20 | warnings.warn(
21 | "Support for Tk/Tcl 8.4 is deprecated and will be removed"
22 | " in Pillow 10 (2023-07-01). Please upgrade to Tk/Tcl 8.5 "
23 | "or newer.",
24 | DeprecationWarning,
25 | )
26 |
--------------------------------------------------------------------------------
/.site-packages/PIL/_util.py:
--------------------------------------------------------------------------------
1 | import os
2 | from pathlib import Path
3 |
4 |
5 | def isPath(f):
6 | return isinstance(f, (bytes, str, Path))
7 |
8 |
9 | # Checks if an object is a string, and that it points to a directory.
10 | def isDirectory(f):
11 | return isPath(f) and os.path.isdir(f)
12 |
13 |
14 | class deferred_error:
15 | def __init__(self, ex):
16 | self.ex = ex
17 |
18 | def __getattr__(self, elt):
19 | raise self.ex
20 |
--------------------------------------------------------------------------------
/.site-packages/PIL/_version.py:
--------------------------------------------------------------------------------
1 | # Master version for Pillow
2 | __version__ = "9.1.0"
3 |
--------------------------------------------------------------------------------
/.site-packages/bin/normalizer:
--------------------------------------------------------------------------------
1 | #!/Library/Developer/CommandLineTools/usr/bin/python3
2 | # -*- coding: utf-8 -*-
3 | import re
4 | import sys
5 | from charset_normalizer.cli.normalizer import cli_detect
6 | if __name__ == '__main__':
7 | sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
8 | sys.exit(cli_detect())
9 |
--------------------------------------------------------------------------------
/.site-packages/certifi/__init__.py:
--------------------------------------------------------------------------------
1 | from .core import contents, where
2 |
3 | __version__ = "2021.10.08"
4 |
--------------------------------------------------------------------------------
/.site-packages/certifi/__main__.py:
--------------------------------------------------------------------------------
1 | import argparse
2 |
3 | from certifi import contents, where
4 |
5 | parser = argparse.ArgumentParser()
6 | parser.add_argument("-c", "--contents", action="store_true")
7 | args = parser.parse_args()
8 |
9 | if args.contents:
10 | print(contents())
11 | else:
12 | print(where())
13 |
--------------------------------------------------------------------------------
/.site-packages/certifi/core.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | certifi.py
5 | ~~~~~~~~~~
6 |
7 | This module returns the installation location of cacert.pem or its contents.
8 | """
9 | import os
10 |
11 | try:
12 | from importlib.resources import path as get_path, read_text
13 |
14 | _CACERT_CTX = None
15 | _CACERT_PATH = None
16 |
17 | def where():
18 | # This is slightly terrible, but we want to delay extracting the file
19 | # in cases where we're inside of a zipimport situation until someone
20 | # actually calls where(), but we don't want to re-extract the file
21 | # on every call of where(), so we'll do it once then store it in a
22 | # global variable.
23 | global _CACERT_CTX
24 | global _CACERT_PATH
25 | if _CACERT_PATH is None:
26 | # This is slightly janky, the importlib.resources API wants you to
27 | # manage the cleanup of this file, so it doesn't actually return a
28 | # path, it returns a context manager that will give you the path
29 | # when you enter it and will do any cleanup when you leave it. In
30 | # the common case of not needing a temporary file, it will just
31 | # return the file system location and the __exit__() is a no-op.
32 | #
33 | # We also have to hold onto the actual context manager, because
34 | # it will do the cleanup whenever it gets garbage collected, so
35 | # we will also store that at the global level as well.
36 | _CACERT_CTX = get_path("certifi", "cacert.pem")
37 | _CACERT_PATH = str(_CACERT_CTX.__enter__())
38 |
39 | return _CACERT_PATH
40 |
41 |
42 | except ImportError:
43 | # This fallback will work for Python versions prior to 3.7 that lack the
44 | # importlib.resources module but relies on the existing `where` function
45 | # so won't address issues with environments like PyOxidizer that don't set
46 | # __file__ on modules.
47 | def read_text(_module, _path, encoding="ascii"):
48 | with open(where(), "r", encoding=encoding) as data:
49 | return data.read()
50 |
51 | # If we don't have importlib.resources, then we will just do the old logic
52 | # of assuming we're on the filesystem and munge the path directly.
53 | def where():
54 | f = os.path.dirname(__file__)
55 |
56 | return os.path.join(f, "cacert.pem")
57 |
58 |
59 | def contents():
60 | return read_text("certifi", "cacert.pem", encoding="ascii")
61 |
--------------------------------------------------------------------------------
/.site-packages/charset_normalizer/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf_8 -*-
2 | """
3 | Charset-Normalizer
4 | ~~~~~~~~~~~~~~
5 | The Real First Universal Charset Detector.
6 | A library that helps you read text from an unknown charset encoding.
7 | Motivated by chardet, This package is trying to resolve the issue by taking a new approach.
8 | All IANA character set names for which the Python core library provides codecs are supported.
9 |
10 | Basic usage:
11 | >>> from charset_normalizer import from_bytes
12 | >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието!'.encode('utf_8'))
13 | >>> best_guess = results.best()
14 | >>> str(best_guess)
15 | 'Bсеки човек има право на образование. Oбразованието!'
16 |
17 | Others methods and usages are available - see the full documentation
18 | at .
19 | :copyright: (c) 2021 by Ahmed TAHRI
20 | :license: MIT, see LICENSE for more details.
21 | """
22 | import logging
23 |
24 | from .api import from_bytes, from_fp, from_path, normalize
25 | from .legacy import (
26 | CharsetDetector,
27 | CharsetDoctor,
28 | CharsetNormalizerMatch,
29 | CharsetNormalizerMatches,
30 | detect,
31 | )
32 | from .models import CharsetMatch, CharsetMatches
33 | from .utils import set_logging_handler
34 | from .version import VERSION, __version__
35 |
36 | __all__ = (
37 | "from_fp",
38 | "from_path",
39 | "from_bytes",
40 | "normalize",
41 | "detect",
42 | "CharsetMatch",
43 | "CharsetMatches",
44 | "CharsetNormalizerMatch",
45 | "CharsetNormalizerMatches",
46 | "CharsetDetector",
47 | "CharsetDoctor",
48 | "__version__",
49 | "VERSION",
50 | "set_logging_handler",
51 | )
52 |
53 | # Attach a NullHandler to the top level logger by default
54 | # https://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library
55 |
56 | logging.getLogger("charset_normalizer").addHandler(logging.NullHandler())
57 |
--------------------------------------------------------------------------------
/.site-packages/charset_normalizer/cli/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/.site-packages/charset_normalizer/cli/__init__.py
--------------------------------------------------------------------------------
/.site-packages/charset_normalizer/legacy.py:
--------------------------------------------------------------------------------
1 | import warnings
2 | from typing import Dict, Optional, Union
3 |
4 | from .api import from_bytes, from_fp, from_path, normalize
5 | from .constant import CHARDET_CORRESPONDENCE
6 | from .models import CharsetMatch, CharsetMatches
7 |
8 |
9 | def detect(byte_str: bytes) -> Dict[str, Optional[Union[str, float]]]:
10 | """
11 | chardet legacy method
12 | Detect the encoding of the given byte string. It should be mostly backward-compatible.
13 | Encoding name will match Chardet own writing whenever possible. (Not on encoding name unsupported by it)
14 | This function is deprecated and should be used to migrate your project easily, consult the documentation for
15 | further information. Not planned for removal.
16 |
17 | :param byte_str: The byte sequence to examine.
18 | """
19 | if not isinstance(byte_str, (bytearray, bytes)):
20 | raise TypeError( # pragma: nocover
21 | "Expected object of type bytes or bytearray, got: "
22 | "{0}".format(type(byte_str))
23 | )
24 |
25 | if isinstance(byte_str, bytearray):
26 | byte_str = bytes(byte_str)
27 |
28 | r = from_bytes(byte_str).best()
29 |
30 | encoding = r.encoding if r is not None else None
31 | language = r.language if r is not None and r.language != "Unknown" else ""
32 | confidence = 1.0 - r.chaos if r is not None else None
33 |
34 | # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process
35 | # but chardet does return 'utf-8-sig' and it is a valid codec name.
36 | if r is not None and encoding == "utf_8" and r.bom:
37 | encoding += "_sig"
38 |
39 | return {
40 | "encoding": encoding
41 | if encoding not in CHARDET_CORRESPONDENCE
42 | else CHARDET_CORRESPONDENCE[encoding],
43 | "language": language,
44 | "confidence": confidence,
45 | }
46 |
47 |
48 | class CharsetNormalizerMatch(CharsetMatch):
49 | pass
50 |
51 |
52 | class CharsetNormalizerMatches(CharsetMatches):
53 | @staticmethod
54 | def from_fp(*args, **kwargs): # type: ignore
55 | warnings.warn( # pragma: nocover
56 | "staticmethod from_fp, from_bytes, from_path and normalize are deprecated "
57 | "and scheduled to be removed in 3.0",
58 | DeprecationWarning,
59 | )
60 | return from_fp(*args, **kwargs) # pragma: nocover
61 |
62 | @staticmethod
63 | def from_bytes(*args, **kwargs): # type: ignore
64 | warnings.warn( # pragma: nocover
65 | "staticmethod from_fp, from_bytes, from_path and normalize are deprecated "
66 | "and scheduled to be removed in 3.0",
67 | DeprecationWarning,
68 | )
69 | return from_bytes(*args, **kwargs) # pragma: nocover
70 |
71 | @staticmethod
72 | def from_path(*args, **kwargs): # type: ignore
73 | warnings.warn( # pragma: nocover
74 | "staticmethod from_fp, from_bytes, from_path and normalize are deprecated "
75 | "and scheduled to be removed in 3.0",
76 | DeprecationWarning,
77 | )
78 | return from_path(*args, **kwargs) # pragma: nocover
79 |
80 | @staticmethod
81 | def normalize(*args, **kwargs): # type: ignore
82 | warnings.warn( # pragma: nocover
83 | "staticmethod from_fp, from_bytes, from_path and normalize are deprecated "
84 | "and scheduled to be removed in 3.0",
85 | DeprecationWarning,
86 | )
87 | return normalize(*args, **kwargs) # pragma: nocover
88 |
89 |
90 | class CharsetDetector(CharsetNormalizerMatches):
91 | pass
92 |
93 |
94 | class CharsetDoctor(CharsetNormalizerMatches):
95 | pass
96 |
--------------------------------------------------------------------------------
/.site-packages/charset_normalizer/py.typed:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/.site-packages/charset_normalizer/py.typed
--------------------------------------------------------------------------------
/.site-packages/charset_normalizer/version.py:
--------------------------------------------------------------------------------
1 | """
2 | Expose version
3 | """
4 |
5 | __version__ = "2.0.12"
6 | VERSION = __version__.split(".")
7 |
--------------------------------------------------------------------------------
/.site-packages/idna/__init__.py:
--------------------------------------------------------------------------------
1 | from .package_data import __version__
2 | from .core import (
3 | IDNABidiError,
4 | IDNAError,
5 | InvalidCodepoint,
6 | InvalidCodepointContext,
7 | alabel,
8 | check_bidi,
9 | check_hyphen_ok,
10 | check_initial_combiner,
11 | check_label,
12 | check_nfc,
13 | decode,
14 | encode,
15 | ulabel,
16 | uts46_remap,
17 | valid_contextj,
18 | valid_contexto,
19 | valid_label_length,
20 | valid_string_length,
21 | )
22 | from .intranges import intranges_contain
23 |
24 | __all__ = [
25 | "IDNABidiError",
26 | "IDNAError",
27 | "InvalidCodepoint",
28 | "InvalidCodepointContext",
29 | "alabel",
30 | "check_bidi",
31 | "check_hyphen_ok",
32 | "check_initial_combiner",
33 | "check_label",
34 | "check_nfc",
35 | "decode",
36 | "encode",
37 | "intranges_contain",
38 | "ulabel",
39 | "uts46_remap",
40 | "valid_contextj",
41 | "valid_contexto",
42 | "valid_label_length",
43 | "valid_string_length",
44 | ]
45 |
--------------------------------------------------------------------------------
/.site-packages/idna/codec.py:
--------------------------------------------------------------------------------
1 | from .core import encode, decode, alabel, ulabel, IDNAError
2 | import codecs
3 | import re
4 | from typing import Tuple, Optional
5 |
6 | _unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')
7 |
8 | class Codec(codecs.Codec):
9 |
10 | def encode(self, data: str, errors: str = 'strict') -> Tuple[bytes, int]:
11 | if errors != 'strict':
12 | raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
13 |
14 | if not data:
15 | return b"", 0
16 |
17 | return encode(data), len(data)
18 |
19 | def decode(self, data: bytes, errors: str = 'strict') -> Tuple[str, int]:
20 | if errors != 'strict':
21 | raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
22 |
23 | if not data:
24 | return '', 0
25 |
26 | return decode(data), len(data)
27 |
28 | class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
29 | def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore
30 | if errors != 'strict':
31 | raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
32 |
33 | if not data:
34 | return "", 0
35 |
36 | labels = _unicode_dots_re.split(data)
37 | trailing_dot = ''
38 | if labels:
39 | if not labels[-1]:
40 | trailing_dot = '.'
41 | del labels[-1]
42 | elif not final:
43 | # Keep potentially unfinished label until the next call
44 | del labels[-1]
45 | if labels:
46 | trailing_dot = '.'
47 |
48 | result = []
49 | size = 0
50 | for label in labels:
51 | result.append(alabel(label))
52 | if size:
53 | size += 1
54 | size += len(label)
55 |
56 | # Join with U+002E
57 | result_str = '.'.join(result) + trailing_dot # type: ignore
58 | size += len(trailing_dot)
59 | return result_str, size
60 |
61 | class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
62 | def _buffer_decode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore
63 | if errors != 'strict':
64 | raise IDNAError('Unsupported error handling \"{}\"'.format(errors))
65 |
66 | if not data:
67 | return ('', 0)
68 |
69 | labels = _unicode_dots_re.split(data)
70 | trailing_dot = ''
71 | if labels:
72 | if not labels[-1]:
73 | trailing_dot = '.'
74 | del labels[-1]
75 | elif not final:
76 | # Keep potentially unfinished label until the next call
77 | del labels[-1]
78 | if labels:
79 | trailing_dot = '.'
80 |
81 | result = []
82 | size = 0
83 | for label in labels:
84 | result.append(ulabel(label))
85 | if size:
86 | size += 1
87 | size += len(label)
88 |
89 | result_str = '.'.join(result) + trailing_dot
90 | size += len(trailing_dot)
91 | return (result_str, size)
92 |
93 |
94 | class StreamWriter(Codec, codecs.StreamWriter):
95 | pass
96 |
97 |
98 | class StreamReader(Codec, codecs.StreamReader):
99 | pass
100 |
101 |
102 | def getregentry() -> codecs.CodecInfo:
103 | # Compatibility as a search_function for codecs.register()
104 | return codecs.CodecInfo(
105 | name='idna',
106 | encode=Codec().encode, # type: ignore
107 | decode=Codec().decode, # type: ignore
108 | incrementalencoder=IncrementalEncoder,
109 | incrementaldecoder=IncrementalDecoder,
110 | streamwriter=StreamWriter,
111 | streamreader=StreamReader,
112 | )
113 |
--------------------------------------------------------------------------------
/.site-packages/idna/compat.py:
--------------------------------------------------------------------------------
1 | from .core import *
2 | from .codec import *
3 | from typing import Any, Union
4 |
5 | def ToASCII(label: str) -> bytes:
6 | return encode(label)
7 |
8 | def ToUnicode(label: Union[bytes, bytearray]) -> str:
9 | return decode(label)
10 |
11 | def nameprep(s: Any) -> None:
12 | raise NotImplementedError('IDNA 2008 does not utilise nameprep protocol')
13 |
14 |
--------------------------------------------------------------------------------
/.site-packages/idna/intranges.py:
--------------------------------------------------------------------------------
1 | """
2 | Given a list of integers, made up of (hopefully) a small number of long runs
3 | of consecutive integers, compute a representation of the form
4 | ((start1, end1), (start2, end2) ...). Then answer the question "was x present
5 | in the original list?" in time O(log(# runs)).
6 | """
7 |
8 | import bisect
9 | from typing import List, Tuple
10 |
11 | def intranges_from_list(list_: List[int]) -> Tuple[int, ...]:
12 | """Represent a list of integers as a sequence of ranges:
13 | ((start_0, end_0), (start_1, end_1), ...), such that the original
14 | integers are exactly those x such that start_i <= x < end_i for some i.
15 |
16 | Ranges are encoded as single integers (start << 32 | end), not as tuples.
17 | """
18 |
19 | sorted_list = sorted(list_)
20 | ranges = []
21 | last_write = -1
22 | for i in range(len(sorted_list)):
23 | if i+1 < len(sorted_list):
24 | if sorted_list[i] == sorted_list[i+1]-1:
25 | continue
26 | current_range = sorted_list[last_write+1:i+1]
27 | ranges.append(_encode_range(current_range[0], current_range[-1] + 1))
28 | last_write = i
29 |
30 | return tuple(ranges)
31 |
32 | def _encode_range(start: int, end: int) -> int:
33 | return (start << 32) | end
34 |
35 | def _decode_range(r: int) -> Tuple[int, int]:
36 | return (r >> 32), (r & ((1 << 32) - 1))
37 |
38 |
39 | def intranges_contain(int_: int, ranges: Tuple[int, ...]) -> bool:
40 | """Determine if `int_` falls into one of the ranges in `ranges`."""
41 | tuple_ = _encode_range(int_, 0)
42 | pos = bisect.bisect_left(ranges, tuple_)
43 | # we could be immediately ahead of a tuple (start, end)
44 | # with start < int_ <= end
45 | if pos > 0:
46 | left, right = _decode_range(ranges[pos-1])
47 | if left <= int_ < right:
48 | return True
49 | # or we could be immediately behind a tuple (int_, end)
50 | if pos < len(ranges):
51 | left, _ = _decode_range(ranges[pos])
52 | if left == int_:
53 | return True
54 | return False
55 |
--------------------------------------------------------------------------------
/.site-packages/idna/package_data.py:
--------------------------------------------------------------------------------
1 | __version__ = '3.3'
2 |
3 |
--------------------------------------------------------------------------------
/.site-packages/idna/py.typed:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/.site-packages/idna/py.typed
--------------------------------------------------------------------------------
/.site-packages/pyperclip/__main__.py:
--------------------------------------------------------------------------------
1 | import pyperclip
2 | import sys
3 |
4 | if len(sys.argv) > 1 and sys.argv[1] in ('-c', '--copy'):
5 | if len(sys.argv) > 2:
6 | pyperclip.copy(sys.argv[2])
7 | else:
8 | pyperclip.copy(sys.stdin.read())
9 | elif len(sys.argv) > 1 and sys.argv[1] in ('-p', '--paste'):
10 | sys.stdout.write(pyperclip.paste())
11 | else:
12 | print('Usage: python -m pyperclip [-c | --copy] [text_to_copy] | [-p | --paste]')
13 | print()
14 | print('If a text_to_copy argument is provided, it is copied to the')
15 | print('clipboard. Otherwise, the stdin stream is copied to the')
16 | print('clipboard. (If reading this in from the keyboard, press')
17 | print('CTRL-Z on Windows or CTRL-D on Linux/macOS to stop.')
18 | print('When pasting, the clipboard will be written to stdout.')
--------------------------------------------------------------------------------
/.site-packages/requests/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # __
4 | # /__) _ _ _ _ _/ _
5 | # / ( (- (/ (/ (- _) / _)
6 | # /
7 |
8 | """
9 | Requests HTTP Library
10 | ~~~~~~~~~~~~~~~~~~~~~
11 |
12 | Requests is an HTTP library, written in Python, for human beings.
13 | Basic GET usage:
14 |
15 | >>> import requests
16 | >>> r = requests.get('https://www.python.org')
17 | >>> r.status_code
18 | 200
19 | >>> b'Python is a programming language' in r.content
20 | True
21 |
22 | ... or POST:
23 |
24 | >>> payload = dict(key1='value1', key2='value2')
25 | >>> r = requests.post('https://httpbin.org/post', data=payload)
26 | >>> print(r.text)
27 | {
28 | ...
29 | "form": {
30 | "key1": "value1",
31 | "key2": "value2"
32 | },
33 | ...
34 | }
35 |
36 | The other HTTP methods are supported - see `requests.api`. Full documentation
37 | is at .
38 |
39 | :copyright: (c) 2017 by Kenneth Reitz.
40 | :license: Apache 2.0, see LICENSE for more details.
41 | """
42 |
43 | import urllib3
44 | import warnings
45 | from .exceptions import RequestsDependencyWarning
46 |
47 | try:
48 | from charset_normalizer import __version__ as charset_normalizer_version
49 | except ImportError:
50 | charset_normalizer_version = None
51 |
52 | try:
53 | from chardet import __version__ as chardet_version
54 | except ImportError:
55 | chardet_version = None
56 |
57 | def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version):
58 | urllib3_version = urllib3_version.split('.')
59 | assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git.
60 |
61 | # Sometimes, urllib3 only reports its version as 16.1.
62 | if len(urllib3_version) == 2:
63 | urllib3_version.append('0')
64 |
65 | # Check urllib3 for compatibility.
66 | major, minor, patch = urllib3_version # noqa: F811
67 | major, minor, patch = int(major), int(minor), int(patch)
68 | # urllib3 >= 1.21.1, <= 1.26
69 | assert major == 1
70 | assert minor >= 21
71 | assert minor <= 26
72 |
73 | # Check charset_normalizer for compatibility.
74 | if chardet_version:
75 | major, minor, patch = chardet_version.split('.')[:3]
76 | major, minor, patch = int(major), int(minor), int(patch)
77 | # chardet_version >= 3.0.2, < 5.0.0
78 | assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0)
79 | elif charset_normalizer_version:
80 | major, minor, patch = charset_normalizer_version.split('.')[:3]
81 | major, minor, patch = int(major), int(minor), int(patch)
82 | # charset_normalizer >= 2.0.0 < 3.0.0
83 | assert (2, 0, 0) <= (major, minor, patch) < (3, 0, 0)
84 | else:
85 | raise Exception("You need either charset_normalizer or chardet installed")
86 |
87 | def _check_cryptography(cryptography_version):
88 | # cryptography < 1.3.4
89 | try:
90 | cryptography_version = list(map(int, cryptography_version.split('.')))
91 | except ValueError:
92 | return
93 |
94 | if cryptography_version < [1, 3, 4]:
95 | warning = 'Old version of cryptography ({}) may cause slowdown.'.format(cryptography_version)
96 | warnings.warn(warning, RequestsDependencyWarning)
97 |
98 | # Check imported dependencies for compatibility.
99 | try:
100 | check_compatibility(urllib3.__version__, chardet_version, charset_normalizer_version)
101 | except (AssertionError, ValueError):
102 | warnings.warn("urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
103 | "version!".format(urllib3.__version__, chardet_version, charset_normalizer_version),
104 | RequestsDependencyWarning)
105 |
106 | # Attempt to enable urllib3's fallback for SNI support
107 | # if the standard library doesn't support SNI or the
108 | # 'ssl' library isn't available.
109 | try:
110 | try:
111 | import ssl
112 | except ImportError:
113 | ssl = None
114 |
115 | if not getattr(ssl, "HAS_SNI", False):
116 | from urllib3.contrib import pyopenssl
117 | pyopenssl.inject_into_urllib3()
118 |
119 | # Check cryptography version
120 | from cryptography import __version__ as cryptography_version
121 | _check_cryptography(cryptography_version)
122 | except ImportError:
123 | pass
124 |
125 | # urllib3's DependencyWarnings should be silenced.
126 | from urllib3.exceptions import DependencyWarning
127 | warnings.simplefilter('ignore', DependencyWarning)
128 |
129 | from .__version__ import __title__, __description__, __url__, __version__
130 | from .__version__ import __build__, __author__, __author_email__, __license__
131 | from .__version__ import __copyright__, __cake__
132 |
133 | from . import utils
134 | from . import packages
135 | from .models import Request, Response, PreparedRequest
136 | from .api import request, get, head, post, patch, put, delete, options
137 | from .sessions import session, Session
138 | from .status_codes import codes
139 | from .exceptions import (
140 | RequestException, Timeout, URLRequired,
141 | TooManyRedirects, HTTPError, ConnectionError,
142 | FileModeWarning, ConnectTimeout, ReadTimeout, JSONDecodeError
143 | )
144 |
145 | # Set default logging handler to avoid "No handler found" warnings.
146 | import logging
147 | from logging import NullHandler
148 |
149 | logging.getLogger(__name__).addHandler(NullHandler())
150 |
151 | # FileModeWarnings go off per the default.
152 | warnings.simplefilter('default', FileModeWarning, append=True)
153 |
--------------------------------------------------------------------------------
/.site-packages/requests/__version__.py:
--------------------------------------------------------------------------------
1 | # .-. .-. .-. . . .-. .-. .-. .-.
2 | # |( |- |.| | | |- `-. | `-.
3 | # ' ' `-' `-`.`-' `-' `-' ' `-'
4 |
5 | __title__ = 'requests'
6 | __description__ = 'Python HTTP for Humans.'
7 | __url__ = 'https://requests.readthedocs.io'
8 | __version__ = '2.27.1'
9 | __build__ = 0x022701
10 | __author__ = 'Kenneth Reitz'
11 | __author_email__ = 'me@kennethreitz.org'
12 | __license__ = 'Apache 2.0'
13 | __copyright__ = 'Copyright 2022 Kenneth Reitz'
14 | __cake__ = u'\u2728 \U0001f370 \u2728'
15 |
--------------------------------------------------------------------------------
/.site-packages/requests/_internal_utils.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | requests._internal_utils
5 | ~~~~~~~~~~~~~~
6 |
7 | Provides utility functions that are consumed internally by Requests
8 | which depend on extremely few external helpers (such as compat)
9 | """
10 |
11 | from .compat import is_py2, builtin_str, str
12 |
13 |
14 | def to_native_string(string, encoding='ascii'):
15 | """Given a string object, regardless of type, returns a representation of
16 | that string in the native string type, encoding and decoding where
17 | necessary. This assumes ASCII unless told otherwise.
18 | """
19 | if isinstance(string, builtin_str):
20 | out = string
21 | else:
22 | if is_py2:
23 | out = string.encode(encoding)
24 | else:
25 | out = string.decode(encoding)
26 |
27 | return out
28 |
29 |
30 | def unicode_is_ascii(u_string):
31 | """Determine if unicode string only contains ASCII characters.
32 |
33 | :param str u_string: unicode string to check. Must be unicode
34 | and not Python 2 `str`.
35 | :rtype: bool
36 | """
37 | assert isinstance(u_string, str)
38 | try:
39 | u_string.encode('ascii')
40 | return True
41 | except UnicodeEncodeError:
42 | return False
43 |
--------------------------------------------------------------------------------
/.site-packages/requests/certs.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 |
4 | """
5 | requests.certs
6 | ~~~~~~~~~~~~~~
7 |
8 | This module returns the preferred default CA certificate bundle. There is
9 | only one — the one from the certifi package.
10 |
11 | If you are packaging Requests, e.g., for a Linux distribution or a managed
12 | environment, you can change the definition of where() to return a separately
13 | packaged CA bundle.
14 | """
15 | from certifi import where
16 |
17 | if __name__ == '__main__':
18 | print(where())
19 |
--------------------------------------------------------------------------------
/.site-packages/requests/compat.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | requests.compat
5 | ~~~~~~~~~~~~~~~
6 |
7 | This module handles import compatibility issues between Python 2 and
8 | Python 3.
9 | """
10 |
11 | try:
12 | import chardet
13 | except ImportError:
14 | import charset_normalizer as chardet
15 |
16 | import sys
17 |
18 | # -------
19 | # Pythons
20 | # -------
21 |
22 | # Syntax sugar.
23 | _ver = sys.version_info
24 |
25 | #: Python 2.x?
26 | is_py2 = (_ver[0] == 2)
27 |
28 | #: Python 3.x?
29 | is_py3 = (_ver[0] == 3)
30 |
31 | has_simplejson = False
32 | try:
33 | import simplejson as json
34 | has_simplejson = True
35 | except ImportError:
36 | import json
37 |
38 | # ---------
39 | # Specifics
40 | # ---------
41 |
42 | if is_py2:
43 | from urllib import (
44 | quote, unquote, quote_plus, unquote_plus, urlencode, getproxies,
45 | proxy_bypass, proxy_bypass_environment, getproxies_environment)
46 | from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag
47 | from urllib2 import parse_http_list
48 | import cookielib
49 | from Cookie import Morsel
50 | from StringIO import StringIO
51 | # Keep OrderedDict for backwards compatibility.
52 | from collections import Callable, Mapping, MutableMapping, OrderedDict
53 |
54 | builtin_str = str
55 | bytes = str
56 | str = unicode
57 | basestring = basestring
58 | numeric_types = (int, long, float)
59 | integer_types = (int, long)
60 | JSONDecodeError = ValueError
61 |
62 | elif is_py3:
63 | from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag
64 | from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment
65 | from http import cookiejar as cookielib
66 | from http.cookies import Morsel
67 | from io import StringIO
68 | # Keep OrderedDict for backwards compatibility.
69 | from collections import OrderedDict
70 | from collections.abc import Callable, Mapping, MutableMapping
71 | if has_simplejson:
72 | from simplejson import JSONDecodeError
73 | else:
74 | from json import JSONDecodeError
75 |
76 | builtin_str = str
77 | str = str
78 | bytes = bytes
79 | basestring = (str, bytes)
80 | numeric_types = (int, float)
81 | integer_types = (int,)
82 |
--------------------------------------------------------------------------------
/.site-packages/requests/exceptions.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | requests.exceptions
5 | ~~~~~~~~~~~~~~~~~~~
6 |
7 | This module contains the set of Requests' exceptions.
8 | """
9 | from urllib3.exceptions import HTTPError as BaseHTTPError
10 |
11 | from .compat import JSONDecodeError as CompatJSONDecodeError
12 |
13 |
14 | class RequestException(IOError):
15 | """There was an ambiguous exception that occurred while handling your
16 | request.
17 | """
18 |
19 | def __init__(self, *args, **kwargs):
20 | """Initialize RequestException with `request` and `response` objects."""
21 | response = kwargs.pop('response', None)
22 | self.response = response
23 | self.request = kwargs.pop('request', None)
24 | if (response is not None and not self.request and
25 | hasattr(response, 'request')):
26 | self.request = self.response.request
27 | super(RequestException, self).__init__(*args, **kwargs)
28 |
29 |
30 | class InvalidJSONError(RequestException):
31 | """A JSON error occurred."""
32 |
33 |
34 | class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError):
35 | """Couldn't decode the text into json"""
36 |
37 |
38 | class HTTPError(RequestException):
39 | """An HTTP error occurred."""
40 |
41 |
42 | class ConnectionError(RequestException):
43 | """A Connection error occurred."""
44 |
45 |
46 | class ProxyError(ConnectionError):
47 | """A proxy error occurred."""
48 |
49 |
50 | class SSLError(ConnectionError):
51 | """An SSL error occurred."""
52 |
53 |
54 | class Timeout(RequestException):
55 | """The request timed out.
56 |
57 | Catching this error will catch both
58 | :exc:`~requests.exceptions.ConnectTimeout` and
59 | :exc:`~requests.exceptions.ReadTimeout` errors.
60 | """
61 |
62 |
63 | class ConnectTimeout(ConnectionError, Timeout):
64 | """The request timed out while trying to connect to the remote server.
65 |
66 | Requests that produced this error are safe to retry.
67 | """
68 |
69 |
70 | class ReadTimeout(Timeout):
71 | """The server did not send any data in the allotted amount of time."""
72 |
73 |
74 | class URLRequired(RequestException):
75 | """A valid URL is required to make a request."""
76 |
77 |
78 | class TooManyRedirects(RequestException):
79 | """Too many redirects."""
80 |
81 |
82 | class MissingSchema(RequestException, ValueError):
83 | """The URL scheme (e.g. http or https) is missing."""
84 |
85 |
86 | class InvalidSchema(RequestException, ValueError):
87 | """The URL scheme provided is either invalid or unsupported."""
88 |
89 |
90 | class InvalidURL(RequestException, ValueError):
91 | """The URL provided was somehow invalid."""
92 |
93 |
94 | class InvalidHeader(RequestException, ValueError):
95 | """The header value provided was somehow invalid."""
96 |
97 |
98 | class InvalidProxyURL(InvalidURL):
99 | """The proxy URL provided is invalid."""
100 |
101 |
102 | class ChunkedEncodingError(RequestException):
103 | """The server declared chunked encoding but sent an invalid chunk."""
104 |
105 |
106 | class ContentDecodingError(RequestException, BaseHTTPError):
107 | """Failed to decode response content."""
108 |
109 |
110 | class StreamConsumedError(RequestException, TypeError):
111 | """The content for this response was already consumed."""
112 |
113 |
114 | class RetryError(RequestException):
115 | """Custom retries logic failed"""
116 |
117 |
118 | class UnrewindableBodyError(RequestException):
119 | """Requests encountered an error when trying to rewind a body."""
120 |
121 | # Warnings
122 |
123 |
124 | class RequestsWarning(Warning):
125 | """Base warning for Requests."""
126 |
127 |
128 | class FileModeWarning(RequestsWarning, DeprecationWarning):
129 | """A file was opened in text mode, but Requests determined its binary length."""
130 |
131 |
132 | class RequestsDependencyWarning(RequestsWarning):
133 | """An imported dependency doesn't match the expected version range."""
134 |
--------------------------------------------------------------------------------
/.site-packages/requests/help.py:
--------------------------------------------------------------------------------
1 | """Module containing bug report helper(s)."""
2 | from __future__ import print_function
3 |
4 | import json
5 | import platform
6 | import sys
7 | import ssl
8 |
9 | import idna
10 | import urllib3
11 |
12 | from . import __version__ as requests_version
13 |
14 | try:
15 | import charset_normalizer
16 | except ImportError:
17 | charset_normalizer = None
18 |
19 | try:
20 | import chardet
21 | except ImportError:
22 | chardet = None
23 |
24 | try:
25 | from urllib3.contrib import pyopenssl
26 | except ImportError:
27 | pyopenssl = None
28 | OpenSSL = None
29 | cryptography = None
30 | else:
31 | import OpenSSL
32 | import cryptography
33 |
34 |
35 | def _implementation():
36 | """Return a dict with the Python implementation and version.
37 |
38 | Provide both the name and the version of the Python implementation
39 | currently running. For example, on CPython 2.7.5 it will return
40 | {'name': 'CPython', 'version': '2.7.5'}.
41 |
42 | This function works best on CPython and PyPy: in particular, it probably
43 | doesn't work for Jython or IronPython. Future investigation should be done
44 | to work out the correct shape of the code for those platforms.
45 | """
46 | implementation = platform.python_implementation()
47 |
48 | if implementation == 'CPython':
49 | implementation_version = platform.python_version()
50 | elif implementation == 'PyPy':
51 | implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major,
52 | sys.pypy_version_info.minor,
53 | sys.pypy_version_info.micro)
54 | if sys.pypy_version_info.releaselevel != 'final':
55 | implementation_version = ''.join([
56 | implementation_version, sys.pypy_version_info.releaselevel
57 | ])
58 | elif implementation == 'Jython':
59 | implementation_version = platform.python_version() # Complete Guess
60 | elif implementation == 'IronPython':
61 | implementation_version = platform.python_version() # Complete Guess
62 | else:
63 | implementation_version = 'Unknown'
64 |
65 | return {'name': implementation, 'version': implementation_version}
66 |
67 |
68 | def info():
69 | """Generate information for a bug report."""
70 | try:
71 | platform_info = {
72 | 'system': platform.system(),
73 | 'release': platform.release(),
74 | }
75 | except IOError:
76 | platform_info = {
77 | 'system': 'Unknown',
78 | 'release': 'Unknown',
79 | }
80 |
81 | implementation_info = _implementation()
82 | urllib3_info = {'version': urllib3.__version__}
83 | charset_normalizer_info = {'version': None}
84 | chardet_info = {'version': None}
85 | if charset_normalizer:
86 | charset_normalizer_info = {'version': charset_normalizer.__version__}
87 | if chardet:
88 | chardet_info = {'version': chardet.__version__}
89 |
90 | pyopenssl_info = {
91 | 'version': None,
92 | 'openssl_version': '',
93 | }
94 | if OpenSSL:
95 | pyopenssl_info = {
96 | 'version': OpenSSL.__version__,
97 | 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER,
98 | }
99 | cryptography_info = {
100 | 'version': getattr(cryptography, '__version__', ''),
101 | }
102 | idna_info = {
103 | 'version': getattr(idna, '__version__', ''),
104 | }
105 |
106 | system_ssl = ssl.OPENSSL_VERSION_NUMBER
107 | system_ssl_info = {
108 | 'version': '%x' % system_ssl if system_ssl is not None else ''
109 | }
110 |
111 | return {
112 | 'platform': platform_info,
113 | 'implementation': implementation_info,
114 | 'system_ssl': system_ssl_info,
115 | 'using_pyopenssl': pyopenssl is not None,
116 | 'using_charset_normalizer': chardet is None,
117 | 'pyOpenSSL': pyopenssl_info,
118 | 'urllib3': urllib3_info,
119 | 'chardet': chardet_info,
120 | 'charset_normalizer': charset_normalizer_info,
121 | 'cryptography': cryptography_info,
122 | 'idna': idna_info,
123 | 'requests': {
124 | 'version': requests_version,
125 | },
126 | }
127 |
128 |
129 | def main():
130 | """Pretty-print the bug information as JSON."""
131 | print(json.dumps(info(), sort_keys=True, indent=2))
132 |
133 |
134 | if __name__ == '__main__':
135 | main()
136 |
--------------------------------------------------------------------------------
/.site-packages/requests/hooks.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | requests.hooks
5 | ~~~~~~~~~~~~~~
6 |
7 | This module provides the capabilities for the Requests hooks system.
8 |
9 | Available hooks:
10 |
11 | ``response``:
12 | The response generated from a Request.
13 | """
14 | HOOKS = ['response']
15 |
16 |
17 | def default_hooks():
18 | return {event: [] for event in HOOKS}
19 |
20 | # TODO: response is the only one
21 |
22 |
23 | def dispatch_hook(key, hooks, hook_data, **kwargs):
24 | """Dispatches a hook dictionary on a given piece of data."""
25 | hooks = hooks or {}
26 | hooks = hooks.get(key)
27 | if hooks:
28 | if hasattr(hooks, '__call__'):
29 | hooks = [hooks]
30 | for hook in hooks:
31 | _hook_data = hook(hook_data, **kwargs)
32 | if _hook_data is not None:
33 | hook_data = _hook_data
34 | return hook_data
35 |
--------------------------------------------------------------------------------
/.site-packages/requests/packages.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | try:
4 | import chardet
5 | except ImportError:
6 | import charset_normalizer as chardet
7 | import warnings
8 |
9 | warnings.filterwarnings('ignore', 'Trying to detect', module='charset_normalizer')
10 |
11 | # This code exists for backwards compatibility reasons.
12 | # I don't like it either. Just look the other way. :)
13 |
14 | for package in ('urllib3', 'idna'):
15 | locals()[package] = __import__(package)
16 | # This traversal is apparently necessary such that the identities are
17 | # preserved (requests.packages.urllib3.* is urllib3.*)
18 | for mod in list(sys.modules):
19 | if mod == package or mod.startswith(package + '.'):
20 | sys.modules['requests.packages.' + mod] = sys.modules[mod]
21 |
22 | target = chardet.__name__
23 | for mod in list(sys.modules):
24 | if mod == target or mod.startswith(target + '.'):
25 | sys.modules['requests.packages.' + target.replace(target, 'chardet')] = sys.modules[mod]
26 | # Kinda cool, though, right?
27 |
--------------------------------------------------------------------------------
/.site-packages/requests/status_codes.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | r"""
4 | The ``codes`` object defines a mapping from common names for HTTP statuses
5 | to their numerical codes, accessible either as attributes or as dictionary
6 | items.
7 |
8 | Example::
9 |
10 | >>> import requests
11 | >>> requests.codes['temporary_redirect']
12 | 307
13 | >>> requests.codes.teapot
14 | 418
15 | >>> requests.codes['\o/']
16 | 200
17 |
18 | Some codes have multiple names, and both upper- and lower-case versions of
19 | the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
20 | ``codes.okay`` all correspond to the HTTP status code 200.
21 | """
22 |
23 | from .structures import LookupDict
24 |
25 | _codes = {
26 |
27 | # Informational.
28 | 100: ('continue',),
29 | 101: ('switching_protocols',),
30 | 102: ('processing',),
31 | 103: ('checkpoint',),
32 | 122: ('uri_too_long', 'request_uri_too_long'),
33 | 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'),
34 | 201: ('created',),
35 | 202: ('accepted',),
36 | 203: ('non_authoritative_info', 'non_authoritative_information'),
37 | 204: ('no_content',),
38 | 205: ('reset_content', 'reset'),
39 | 206: ('partial_content', 'partial'),
40 | 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),
41 | 208: ('already_reported',),
42 | 226: ('im_used',),
43 |
44 | # Redirection.
45 | 300: ('multiple_choices',),
46 | 301: ('moved_permanently', 'moved', '\\o-'),
47 | 302: ('found',),
48 | 303: ('see_other', 'other'),
49 | 304: ('not_modified',),
50 | 305: ('use_proxy',),
51 | 306: ('switch_proxy',),
52 | 307: ('temporary_redirect', 'temporary_moved', 'temporary'),
53 | 308: ('permanent_redirect',
54 | 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0
55 |
56 | # Client Error.
57 | 400: ('bad_request', 'bad'),
58 | 401: ('unauthorized',),
59 | 402: ('payment_required', 'payment'),
60 | 403: ('forbidden',),
61 | 404: ('not_found', '-o-'),
62 | 405: ('method_not_allowed', 'not_allowed'),
63 | 406: ('not_acceptable',),
64 | 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
65 | 408: ('request_timeout', 'timeout'),
66 | 409: ('conflict',),
67 | 410: ('gone',),
68 | 411: ('length_required',),
69 | 412: ('precondition_failed', 'precondition'),
70 | 413: ('request_entity_too_large',),
71 | 414: ('request_uri_too_large',),
72 | 415: ('unsupported_media_type', 'unsupported_media', 'media_type'),
73 | 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),
74 | 417: ('expectation_failed',),
75 | 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
76 | 421: ('misdirected_request',),
77 | 422: ('unprocessable_entity', 'unprocessable'),
78 | 423: ('locked',),
79 | 424: ('failed_dependency', 'dependency'),
80 | 425: ('unordered_collection', 'unordered'),
81 | 426: ('upgrade_required', 'upgrade'),
82 | 428: ('precondition_required', 'precondition'),
83 | 429: ('too_many_requests', 'too_many'),
84 | 431: ('header_fields_too_large', 'fields_too_large'),
85 | 444: ('no_response', 'none'),
86 | 449: ('retry_with', 'retry'),
87 | 450: ('blocked_by_windows_parental_controls', 'parental_controls'),
88 | 451: ('unavailable_for_legal_reasons', 'legal_reasons'),
89 | 499: ('client_closed_request',),
90 |
91 | # Server Error.
92 | 500: ('internal_server_error', 'server_error', '/o\\', '✗'),
93 | 501: ('not_implemented',),
94 | 502: ('bad_gateway',),
95 | 503: ('service_unavailable', 'unavailable'),
96 | 504: ('gateway_timeout',),
97 | 505: ('http_version_not_supported', 'http_version'),
98 | 506: ('variant_also_negotiates',),
99 | 507: ('insufficient_storage',),
100 | 509: ('bandwidth_limit_exceeded', 'bandwidth'),
101 | 510: ('not_extended',),
102 | 511: ('network_authentication_required', 'network_auth', 'network_authentication'),
103 | }
104 |
105 | codes = LookupDict(name='status_codes')
106 |
107 | def _init():
108 | for code, titles in _codes.items():
109 | for title in titles:
110 | setattr(codes, title, code)
111 | if not title.startswith(('\\', '/')):
112 | setattr(codes, title.upper(), code)
113 |
114 | def doc(code):
115 | names = ', '.join('``%s``' % n for n in _codes[code])
116 | return '* %d: %s' % (code, names)
117 |
118 | global __doc__
119 | __doc__ = (__doc__ + '\n' +
120 | '\n'.join(doc(code) for code in sorted(_codes))
121 | if __doc__ is not None else None)
122 |
123 | _init()
124 |
--------------------------------------------------------------------------------
/.site-packages/requests/structures.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | requests.structures
5 | ~~~~~~~~~~~~~~~~~~~
6 |
7 | Data structures that power Requests.
8 | """
9 |
10 | from collections import OrderedDict
11 |
12 | from .compat import Mapping, MutableMapping
13 |
14 |
15 | class CaseInsensitiveDict(MutableMapping):
16 | """A case-insensitive ``dict``-like object.
17 |
18 | Implements all methods and operations of
19 | ``MutableMapping`` as well as dict's ``copy``. Also
20 | provides ``lower_items``.
21 |
22 | All keys are expected to be strings. The structure remembers the
23 | case of the last key to be set, and ``iter(instance)``,
24 | ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
25 | will contain case-sensitive keys. However, querying and contains
26 | testing is case insensitive::
27 |
28 | cid = CaseInsensitiveDict()
29 | cid['Accept'] = 'application/json'
30 | cid['aCCEPT'] == 'application/json' # True
31 | list(cid) == ['Accept'] # True
32 |
33 | For example, ``headers['content-encoding']`` will return the
34 | value of a ``'Content-Encoding'`` response header, regardless
35 | of how the header name was originally stored.
36 |
37 | If the constructor, ``.update``, or equality comparison
38 | operations are given keys that have equal ``.lower()``s, the
39 | behavior is undefined.
40 | """
41 |
42 | def __init__(self, data=None, **kwargs):
43 | self._store = OrderedDict()
44 | if data is None:
45 | data = {}
46 | self.update(data, **kwargs)
47 |
48 | def __setitem__(self, key, value):
49 | # Use the lowercased key for lookups, but store the actual
50 | # key alongside the value.
51 | self._store[key.lower()] = (key, value)
52 |
53 | def __getitem__(self, key):
54 | return self._store[key.lower()][1]
55 |
56 | def __delitem__(self, key):
57 | del self._store[key.lower()]
58 |
59 | def __iter__(self):
60 | return (casedkey for casedkey, mappedvalue in self._store.values())
61 |
62 | def __len__(self):
63 | return len(self._store)
64 |
65 | def lower_items(self):
66 | """Like iteritems(), but with all lowercase keys."""
67 | return (
68 | (lowerkey, keyval[1])
69 | for (lowerkey, keyval)
70 | in self._store.items()
71 | )
72 |
73 | def __eq__(self, other):
74 | if isinstance(other, Mapping):
75 | other = CaseInsensitiveDict(other)
76 | else:
77 | return NotImplemented
78 | # Compare insensitively
79 | return dict(self.lower_items()) == dict(other.lower_items())
80 |
81 | # Copy is required
82 | def copy(self):
83 | return CaseInsensitiveDict(self._store.values())
84 |
85 | def __repr__(self):
86 | return str(dict(self.items()))
87 |
88 |
89 | class LookupDict(dict):
90 | """Dictionary lookup object."""
91 |
92 | def __init__(self, name=None):
93 | self.name = name
94 | super(LookupDict, self).__init__()
95 |
96 | def __repr__(self):
97 | return '' % (self.name)
98 |
99 | def __getitem__(self, key):
100 | # We allow fall-through here, so values default to None
101 |
102 | return self.__dict__.get(key, None)
103 |
104 | def get(self, key, default=None):
105 | return self.__dict__.get(key, default)
106 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
3 | """
4 | from __future__ import absolute_import
5 |
6 | # Set default logging handler to avoid "No handler found" warnings.
7 | import logging
8 | import warnings
9 | from logging import NullHandler
10 |
11 | from . import exceptions
12 | from ._version import __version__
13 | from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url
14 | from .filepost import encode_multipart_formdata
15 | from .poolmanager import PoolManager, ProxyManager, proxy_from_url
16 | from .response import HTTPResponse
17 | from .util.request import make_headers
18 | from .util.retry import Retry
19 | from .util.timeout import Timeout
20 | from .util.url import get_host
21 |
22 | __author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
23 | __license__ = "MIT"
24 | __version__ = __version__
25 |
26 | __all__ = (
27 | "HTTPConnectionPool",
28 | "HTTPSConnectionPool",
29 | "PoolManager",
30 | "ProxyManager",
31 | "HTTPResponse",
32 | "Retry",
33 | "Timeout",
34 | "add_stderr_logger",
35 | "connection_from_url",
36 | "disable_warnings",
37 | "encode_multipart_formdata",
38 | "get_host",
39 | "make_headers",
40 | "proxy_from_url",
41 | )
42 |
43 | logging.getLogger(__name__).addHandler(NullHandler())
44 |
45 |
46 | def add_stderr_logger(level=logging.DEBUG):
47 | """
48 | Helper for quickly adding a StreamHandler to the logger. Useful for
49 | debugging.
50 |
51 | Returns the handler after adding it.
52 | """
53 | # This method needs to be in this __init__.py to get the __name__ correct
54 | # even if urllib3 is vendored within another package.
55 | logger = logging.getLogger(__name__)
56 | handler = logging.StreamHandler()
57 | handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
58 | logger.addHandler(handler)
59 | logger.setLevel(level)
60 | logger.debug("Added a stderr logging handler to logger: %s", __name__)
61 | return handler
62 |
63 |
64 | # ... Clean up.
65 | del NullHandler
66 |
67 |
68 | # All warning filters *must* be appended unless you're really certain that they
69 | # shouldn't be: otherwise, it's very hard for users to use most Python
70 | # mechanisms to silence them.
71 | # SecurityWarning's always go off by default.
72 | warnings.simplefilter("always", exceptions.SecurityWarning, append=True)
73 | # SubjectAltNameWarning's should go off once per host
74 | warnings.simplefilter("default", exceptions.SubjectAltNameWarning, append=True)
75 | # InsecurePlatformWarning's don't vary between requests, so we keep it default.
76 | warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True)
77 | # SNIMissingWarnings should go off only once.
78 | warnings.simplefilter("default", exceptions.SNIMissingWarning, append=True)
79 |
80 |
81 | def disable_warnings(category=exceptions.HTTPWarning):
82 | """
83 | Helper for quickly disabling all urllib3 warnings.
84 | """
85 | warnings.simplefilter("ignore", category)
86 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/_version.py:
--------------------------------------------------------------------------------
1 | # This file is protected via CODEOWNERS
2 | __version__ = "1.26.9"
3 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/contrib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/.site-packages/urllib3/contrib/__init__.py
--------------------------------------------------------------------------------
/.site-packages/urllib3/contrib/_appengine_environ.py:
--------------------------------------------------------------------------------
1 | """
2 | This module provides means to detect the App Engine environment.
3 | """
4 |
5 | import os
6 |
7 |
8 | def is_appengine():
9 | return is_local_appengine() or is_prod_appengine()
10 |
11 |
12 | def is_appengine_sandbox():
13 | """Reports if the app is running in the first generation sandbox.
14 |
15 | The second generation runtimes are technically still in a sandbox, but it
16 | is much less restrictive, so generally you shouldn't need to check for it.
17 | see https://cloud.google.com/appengine/docs/standard/runtimes
18 | """
19 | return is_appengine() and os.environ["APPENGINE_RUNTIME"] == "python27"
20 |
21 |
22 | def is_local_appengine():
23 | return "APPENGINE_RUNTIME" in os.environ and os.environ.get(
24 | "SERVER_SOFTWARE", ""
25 | ).startswith("Development/")
26 |
27 |
28 | def is_prod_appengine():
29 | return "APPENGINE_RUNTIME" in os.environ and os.environ.get(
30 | "SERVER_SOFTWARE", ""
31 | ).startswith("Google App Engine/")
32 |
33 |
34 | def is_prod_appengine_mvms():
35 | """Deprecated."""
36 | return False
37 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/contrib/_securetransport/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/.site-packages/urllib3/contrib/_securetransport/__init__.py
--------------------------------------------------------------------------------
/.site-packages/urllib3/contrib/ntlmpool.py:
--------------------------------------------------------------------------------
1 | """
2 | NTLM authenticating pool, contributed by erikcederstran
3 |
4 | Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
5 | """
6 | from __future__ import absolute_import
7 |
8 | import warnings
9 | from logging import getLogger
10 |
11 | from ntlm import ntlm
12 |
13 | from .. import HTTPSConnectionPool
14 | from ..packages.six.moves.http_client import HTTPSConnection
15 |
16 | warnings.warn(
17 | "The 'urllib3.contrib.ntlmpool' module is deprecated and will be removed "
18 | "in urllib3 v2.0 release, urllib3 is not able to support it properly due "
19 | "to reasons listed in issue: https://github.com/urllib3/urllib3/issues/2282. "
20 | "If you are a user of this module please comment in the mentioned issue.",
21 | DeprecationWarning,
22 | )
23 |
24 | log = getLogger(__name__)
25 |
26 |
27 | class NTLMConnectionPool(HTTPSConnectionPool):
28 | """
29 | Implements an NTLM authentication version of an urllib3 connection pool
30 | """
31 |
32 | scheme = "https"
33 |
34 | def __init__(self, user, pw, authurl, *args, **kwargs):
35 | """
36 | authurl is a random URL on the server that is protected by NTLM.
37 | user is the Windows user, probably in the DOMAIN\\username format.
38 | pw is the password for the user.
39 | """
40 | super(NTLMConnectionPool, self).__init__(*args, **kwargs)
41 | self.authurl = authurl
42 | self.rawuser = user
43 | user_parts = user.split("\\", 1)
44 | self.domain = user_parts[0].upper()
45 | self.user = user_parts[1]
46 | self.pw = pw
47 |
48 | def _new_conn(self):
49 | # Performs the NTLM handshake that secures the connection. The socket
50 | # must be kept open while requests are performed.
51 | self.num_connections += 1
52 | log.debug(
53 | "Starting NTLM HTTPS connection no. %d: https://%s%s",
54 | self.num_connections,
55 | self.host,
56 | self.authurl,
57 | )
58 |
59 | headers = {"Connection": "Keep-Alive"}
60 | req_header = "Authorization"
61 | resp_header = "www-authenticate"
62 |
63 | conn = HTTPSConnection(host=self.host, port=self.port)
64 |
65 | # Send negotiation message
66 | headers[req_header] = "NTLM %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE(
67 | self.rawuser
68 | )
69 | log.debug("Request headers: %s", headers)
70 | conn.request("GET", self.authurl, None, headers)
71 | res = conn.getresponse()
72 | reshdr = dict(res.getheaders())
73 | log.debug("Response status: %s %s", res.status, res.reason)
74 | log.debug("Response headers: %s", reshdr)
75 | log.debug("Response data: %s [...]", res.read(100))
76 |
77 | # Remove the reference to the socket, so that it can not be closed by
78 | # the response object (we want to keep the socket open)
79 | res.fp = None
80 |
81 | # Server should respond with a challenge message
82 | auth_header_values = reshdr[resp_header].split(", ")
83 | auth_header_value = None
84 | for s in auth_header_values:
85 | if s[:5] == "NTLM ":
86 | auth_header_value = s[5:]
87 | if auth_header_value is None:
88 | raise Exception(
89 | "Unexpected %s response header: %s" % (resp_header, reshdr[resp_header])
90 | )
91 |
92 | # Send authentication message
93 | ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(
94 | auth_header_value
95 | )
96 | auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(
97 | ServerChallenge, self.user, self.domain, self.pw, NegotiateFlags
98 | )
99 | headers[req_header] = "NTLM %s" % auth_msg
100 | log.debug("Request headers: %s", headers)
101 | conn.request("GET", self.authurl, None, headers)
102 | res = conn.getresponse()
103 | log.debug("Response status: %s %s", res.status, res.reason)
104 | log.debug("Response headers: %s", dict(res.getheaders()))
105 | log.debug("Response data: %s [...]", res.read()[:100])
106 | if res.status != 200:
107 | if res.status == 401:
108 | raise Exception("Server rejected request: wrong username or password")
109 | raise Exception("Wrong server response: %s %s" % (res.status, res.reason))
110 |
111 | res.fp = None
112 | log.debug("Connection established")
113 | return conn
114 |
115 | def urlopen(
116 | self,
117 | method,
118 | url,
119 | body=None,
120 | headers=None,
121 | retries=3,
122 | redirect=True,
123 | assert_same_host=True,
124 | ):
125 | if headers is None:
126 | headers = {}
127 | headers["Connection"] = "Keep-Alive"
128 | return super(NTLMConnectionPool, self).urlopen(
129 | method, url, body, headers, retries, redirect, assert_same_host
130 | )
131 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/filepost.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 |
3 | import binascii
4 | import codecs
5 | import os
6 | from io import BytesIO
7 |
8 | from .fields import RequestField
9 | from .packages import six
10 | from .packages.six import b
11 |
12 | writer = codecs.lookup("utf-8")[3]
13 |
14 |
15 | def choose_boundary():
16 | """
17 | Our embarrassingly-simple replacement for mimetools.choose_boundary.
18 | """
19 | boundary = binascii.hexlify(os.urandom(16))
20 | if not six.PY2:
21 | boundary = boundary.decode("ascii")
22 | return boundary
23 |
24 |
25 | def iter_field_objects(fields):
26 | """
27 | Iterate over fields.
28 |
29 | Supports list of (k, v) tuples and dicts, and lists of
30 | :class:`~urllib3.fields.RequestField`.
31 |
32 | """
33 | if isinstance(fields, dict):
34 | i = six.iteritems(fields)
35 | else:
36 | i = iter(fields)
37 |
38 | for field in i:
39 | if isinstance(field, RequestField):
40 | yield field
41 | else:
42 | yield RequestField.from_tuples(*field)
43 |
44 |
45 | def iter_fields(fields):
46 | """
47 | .. deprecated:: 1.6
48 |
49 | Iterate over fields.
50 |
51 | The addition of :class:`~urllib3.fields.RequestField` makes this function
52 | obsolete. Instead, use :func:`iter_field_objects`, which returns
53 | :class:`~urllib3.fields.RequestField` objects.
54 |
55 | Supports list of (k, v) tuples and dicts.
56 | """
57 | if isinstance(fields, dict):
58 | return ((k, v) for k, v in six.iteritems(fields))
59 |
60 | return ((k, v) for k, v in fields)
61 |
62 |
63 | def encode_multipart_formdata(fields, boundary=None):
64 | """
65 | Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
66 |
67 | :param fields:
68 | Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
69 |
70 | :param boundary:
71 | If not specified, then a random boundary will be generated using
72 | :func:`urllib3.filepost.choose_boundary`.
73 | """
74 | body = BytesIO()
75 | if boundary is None:
76 | boundary = choose_boundary()
77 |
78 | for field in iter_field_objects(fields):
79 | body.write(b("--%s\r\n" % (boundary)))
80 |
81 | writer(body).write(field.render_headers())
82 | data = field.data
83 |
84 | if isinstance(data, int):
85 | data = str(data) # Backwards compatibility
86 |
87 | if isinstance(data, six.text_type):
88 | writer(body).write(data)
89 | else:
90 | body.write(data)
91 |
92 | body.write(b"\r\n")
93 |
94 | body.write(b("--%s--\r\n" % (boundary)))
95 |
96 | content_type = str("multipart/form-data; boundary=%s" % boundary)
97 |
98 | return body.getvalue(), content_type
99 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/packages/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/.site-packages/urllib3/packages/__init__.py
--------------------------------------------------------------------------------
/.site-packages/urllib3/packages/backports/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/.site-packages/urllib3/packages/backports/__init__.py
--------------------------------------------------------------------------------
/.site-packages/urllib3/packages/backports/makefile.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | backports.makefile
4 | ~~~~~~~~~~~~~~~~~~
5 |
6 | Backports the Python 3 ``socket.makefile`` method for use with anything that
7 | wants to create a "fake" socket object.
8 | """
9 | import io
10 | from socket import SocketIO
11 |
12 |
13 | def backport_makefile(
14 | self, mode="r", buffering=None, encoding=None, errors=None, newline=None
15 | ):
16 | """
17 | Backport of ``socket.makefile`` from Python 3.5.
18 | """
19 | if not set(mode) <= {"r", "w", "b"}:
20 | raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
21 | writing = "w" in mode
22 | reading = "r" in mode or not writing
23 | assert reading or writing
24 | binary = "b" in mode
25 | rawmode = ""
26 | if reading:
27 | rawmode += "r"
28 | if writing:
29 | rawmode += "w"
30 | raw = SocketIO(self, rawmode)
31 | self._makefile_refs += 1
32 | if buffering is None:
33 | buffering = -1
34 | if buffering < 0:
35 | buffering = io.DEFAULT_BUFFER_SIZE
36 | if buffering == 0:
37 | if not binary:
38 | raise ValueError("unbuffered streams must be binary")
39 | return raw
40 | if reading and writing:
41 | buffer = io.BufferedRWPair(raw, raw, buffering)
42 | elif reading:
43 | buffer = io.BufferedReader(raw, buffering)
44 | else:
45 | assert writing
46 | buffer = io.BufferedWriter(raw, buffering)
47 | if binary:
48 | return buffer
49 | text = io.TextIOWrapper(buffer, encoding, errors, newline)
50 | text.mode = mode
51 | return text
52 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/util/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 |
3 | # For backwards compatibility, provide imports that used to be here.
4 | from .connection import is_connection_dropped
5 | from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers
6 | from .response import is_fp_closed
7 | from .retry import Retry
8 | from .ssl_ import (
9 | ALPN_PROTOCOLS,
10 | HAS_SNI,
11 | IS_PYOPENSSL,
12 | IS_SECURETRANSPORT,
13 | PROTOCOL_TLS,
14 | SSLContext,
15 | assert_fingerprint,
16 | resolve_cert_reqs,
17 | resolve_ssl_version,
18 | ssl_wrap_socket,
19 | )
20 | from .timeout import Timeout, current_time
21 | from .url import Url, get_host, parse_url, split_first
22 | from .wait import wait_for_read, wait_for_write
23 |
24 | __all__ = (
25 | "HAS_SNI",
26 | "IS_PYOPENSSL",
27 | "IS_SECURETRANSPORT",
28 | "SSLContext",
29 | "PROTOCOL_TLS",
30 | "ALPN_PROTOCOLS",
31 | "Retry",
32 | "Timeout",
33 | "Url",
34 | "assert_fingerprint",
35 | "current_time",
36 | "is_connection_dropped",
37 | "is_fp_closed",
38 | "get_host",
39 | "parse_url",
40 | "make_headers",
41 | "resolve_cert_reqs",
42 | "resolve_ssl_version",
43 | "split_first",
44 | "ssl_wrap_socket",
45 | "wait_for_read",
46 | "wait_for_write",
47 | "SKIP_HEADER",
48 | "SKIPPABLE_HEADERS",
49 | )
50 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/util/connection.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 |
3 | import socket
4 |
5 | from ..contrib import _appengine_environ
6 | from ..exceptions import LocationParseError
7 | from ..packages import six
8 | from .wait import NoWayToWaitForSocketError, wait_for_read
9 |
10 |
11 | def is_connection_dropped(conn): # Platform-specific
12 | """
13 | Returns True if the connection is dropped and should be closed.
14 |
15 | :param conn:
16 | :class:`http.client.HTTPConnection` object.
17 |
18 | Note: For platforms like AppEngine, this will always return ``False`` to
19 | let the platform handle connection recycling transparently for us.
20 | """
21 | sock = getattr(conn, "sock", False)
22 | if sock is False: # Platform-specific: AppEngine
23 | return False
24 | if sock is None: # Connection already closed (such as by httplib).
25 | return True
26 | try:
27 | # Returns True if readable, which here means it's been dropped
28 | return wait_for_read(sock, timeout=0.0)
29 | except NoWayToWaitForSocketError: # Platform-specific: AppEngine
30 | return False
31 |
32 |
33 | # This function is copied from socket.py in the Python 2.7 standard
34 | # library test suite. Added to its signature is only `socket_options`.
35 | # One additional modification is that we avoid binding to IPv6 servers
36 | # discovered in DNS if the system doesn't have IPv6 functionality.
37 | def create_connection(
38 | address,
39 | timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
40 | source_address=None,
41 | socket_options=None,
42 | ):
43 | """Connect to *address* and return the socket object.
44 |
45 | Convenience function. Connect to *address* (a 2-tuple ``(host,
46 | port)``) and return the socket object. Passing the optional
47 | *timeout* parameter will set the timeout on the socket instance
48 | before attempting to connect. If no *timeout* is supplied, the
49 | global default timeout setting returned by :func:`socket.getdefaulttimeout`
50 | is used. If *source_address* is set it must be a tuple of (host, port)
51 | for the socket to bind as a source address before making the connection.
52 | An host of '' or port 0 tells the OS to use the default.
53 | """
54 |
55 | host, port = address
56 | if host.startswith("["):
57 | host = host.strip("[]")
58 | err = None
59 |
60 | # Using the value from allowed_gai_family() in the context of getaddrinfo lets
61 | # us select whether to work with IPv4 DNS records, IPv6 records, or both.
62 | # The original create_connection function always returns all records.
63 | family = allowed_gai_family()
64 |
65 | try:
66 | host.encode("idna")
67 | except UnicodeError:
68 | return six.raise_from(
69 | LocationParseError(u"'%s', label empty or too long" % host), None
70 | )
71 |
72 | for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
73 | af, socktype, proto, canonname, sa = res
74 | sock = None
75 | try:
76 | sock = socket.socket(af, socktype, proto)
77 |
78 | # If provided, set socket level options before connecting.
79 | _set_socket_options(sock, socket_options)
80 |
81 | if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
82 | sock.settimeout(timeout)
83 | if source_address:
84 | sock.bind(source_address)
85 | sock.connect(sa)
86 | return sock
87 |
88 | except socket.error as e:
89 | err = e
90 | if sock is not None:
91 | sock.close()
92 | sock = None
93 |
94 | if err is not None:
95 | raise err
96 |
97 | raise socket.error("getaddrinfo returns an empty list")
98 |
99 |
100 | def _set_socket_options(sock, options):
101 | if options is None:
102 | return
103 |
104 | for opt in options:
105 | sock.setsockopt(*opt)
106 |
107 |
108 | def allowed_gai_family():
109 | """This function is designed to work in the context of
110 | getaddrinfo, where family=socket.AF_UNSPEC is the default and
111 | will perform a DNS search for both IPv6 and IPv4 records."""
112 |
113 | family = socket.AF_INET
114 | if HAS_IPV6:
115 | family = socket.AF_UNSPEC
116 | return family
117 |
118 |
119 | def _has_ipv6(host):
120 | """Returns True if the system can bind an IPv6 address."""
121 | sock = None
122 | has_ipv6 = False
123 |
124 | # App Engine doesn't support IPV6 sockets and actually has a quota on the
125 | # number of sockets that can be used, so just early out here instead of
126 | # creating a socket needlessly.
127 | # See https://github.com/urllib3/urllib3/issues/1446
128 | if _appengine_environ.is_appengine_sandbox():
129 | return False
130 |
131 | if socket.has_ipv6:
132 | # has_ipv6 returns true if cPython was compiled with IPv6 support.
133 | # It does not tell us if the system has IPv6 support enabled. To
134 | # determine that we must bind to an IPv6 address.
135 | # https://github.com/urllib3/urllib3/pull/611
136 | # https://bugs.python.org/issue658327
137 | try:
138 | sock = socket.socket(socket.AF_INET6)
139 | sock.bind((host, 0))
140 | has_ipv6 = True
141 | except Exception:
142 | pass
143 |
144 | if sock:
145 | sock.close()
146 | return has_ipv6
147 |
148 |
149 | HAS_IPV6 = _has_ipv6("::1")
150 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/util/proxy.py:
--------------------------------------------------------------------------------
1 | from .ssl_ import create_urllib3_context, resolve_cert_reqs, resolve_ssl_version
2 |
3 |
4 | def connection_requires_http_tunnel(
5 | proxy_url=None, proxy_config=None, destination_scheme=None
6 | ):
7 | """
8 | Returns True if the connection requires an HTTP CONNECT through the proxy.
9 |
10 | :param URL proxy_url:
11 | URL of the proxy.
12 | :param ProxyConfig proxy_config:
13 | Proxy configuration from poolmanager.py
14 | :param str destination_scheme:
15 | The scheme of the destination. (i.e https, http, etc)
16 | """
17 | # If we're not using a proxy, no way to use a tunnel.
18 | if proxy_url is None:
19 | return False
20 |
21 | # HTTP destinations never require tunneling, we always forward.
22 | if destination_scheme == "http":
23 | return False
24 |
25 | # Support for forwarding with HTTPS proxies and HTTPS destinations.
26 | if (
27 | proxy_url.scheme == "https"
28 | and proxy_config
29 | and proxy_config.use_forwarding_for_https
30 | ):
31 | return False
32 |
33 | # Otherwise always use a tunnel.
34 | return True
35 |
36 |
37 | def create_proxy_ssl_context(
38 | ssl_version, cert_reqs, ca_certs=None, ca_cert_dir=None, ca_cert_data=None
39 | ):
40 | """
41 | Generates a default proxy ssl context if one hasn't been provided by the
42 | user.
43 | """
44 | ssl_context = create_urllib3_context(
45 | ssl_version=resolve_ssl_version(ssl_version),
46 | cert_reqs=resolve_cert_reqs(cert_reqs),
47 | )
48 |
49 | if (
50 | not ca_certs
51 | and not ca_cert_dir
52 | and not ca_cert_data
53 | and hasattr(ssl_context, "load_default_certs")
54 | ):
55 | ssl_context.load_default_certs()
56 |
57 | return ssl_context
58 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/util/queue.py:
--------------------------------------------------------------------------------
1 | import collections
2 |
3 | from ..packages import six
4 | from ..packages.six.moves import queue
5 |
6 | if six.PY2:
7 | # Queue is imported for side effects on MS Windows. See issue #229.
8 | import Queue as _unused_module_Queue # noqa: F401
9 |
10 |
11 | class LifoQueue(queue.Queue):
12 | def _init(self, _):
13 | self.queue = collections.deque()
14 |
15 | def _qsize(self, len=len):
16 | return len(self.queue)
17 |
18 | def _put(self, item):
19 | self.queue.append(item)
20 |
21 | def _get(self):
22 | return self.queue.pop()
23 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/util/request.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 |
3 | from base64 import b64encode
4 |
5 | from ..exceptions import UnrewindableBodyError
6 | from ..packages.six import b, integer_types
7 |
8 | # Pass as a value within ``headers`` to skip
9 | # emitting some HTTP headers that are added automatically.
10 | # The only headers that are supported are ``Accept-Encoding``,
11 | # ``Host``, and ``User-Agent``.
12 | SKIP_HEADER = "@@@SKIP_HEADER@@@"
13 | SKIPPABLE_HEADERS = frozenset(["accept-encoding", "host", "user-agent"])
14 |
15 | ACCEPT_ENCODING = "gzip,deflate"
16 | try:
17 | try:
18 | import brotlicffi as _unused_module_brotli # noqa: F401
19 | except ImportError:
20 | import brotli as _unused_module_brotli # noqa: F401
21 | except ImportError:
22 | pass
23 | else:
24 | ACCEPT_ENCODING += ",br"
25 |
26 | _FAILEDTELL = object()
27 |
28 |
29 | def make_headers(
30 | keep_alive=None,
31 | accept_encoding=None,
32 | user_agent=None,
33 | basic_auth=None,
34 | proxy_basic_auth=None,
35 | disable_cache=None,
36 | ):
37 | """
38 | Shortcuts for generating request headers.
39 |
40 | :param keep_alive:
41 | If ``True``, adds 'connection: keep-alive' header.
42 |
43 | :param accept_encoding:
44 | Can be a boolean, list, or string.
45 | ``True`` translates to 'gzip,deflate'.
46 | List will get joined by comma.
47 | String will be used as provided.
48 |
49 | :param user_agent:
50 | String representing the user-agent you want, such as
51 | "python-urllib3/0.6"
52 |
53 | :param basic_auth:
54 | Colon-separated username:password string for 'authorization: basic ...'
55 | auth header.
56 |
57 | :param proxy_basic_auth:
58 | Colon-separated username:password string for 'proxy-authorization: basic ...'
59 | auth header.
60 |
61 | :param disable_cache:
62 | If ``True``, adds 'cache-control: no-cache' header.
63 |
64 | Example::
65 |
66 | >>> make_headers(keep_alive=True, user_agent="Batman/1.0")
67 | {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'}
68 | >>> make_headers(accept_encoding=True)
69 | {'accept-encoding': 'gzip,deflate'}
70 | """
71 | headers = {}
72 | if accept_encoding:
73 | if isinstance(accept_encoding, str):
74 | pass
75 | elif isinstance(accept_encoding, list):
76 | accept_encoding = ",".join(accept_encoding)
77 | else:
78 | accept_encoding = ACCEPT_ENCODING
79 | headers["accept-encoding"] = accept_encoding
80 |
81 | if user_agent:
82 | headers["user-agent"] = user_agent
83 |
84 | if keep_alive:
85 | headers["connection"] = "keep-alive"
86 |
87 | if basic_auth:
88 | headers["authorization"] = "Basic " + b64encode(b(basic_auth)).decode("utf-8")
89 |
90 | if proxy_basic_auth:
91 | headers["proxy-authorization"] = "Basic " + b64encode(
92 | b(proxy_basic_auth)
93 | ).decode("utf-8")
94 |
95 | if disable_cache:
96 | headers["cache-control"] = "no-cache"
97 |
98 | return headers
99 |
100 |
101 | def set_file_position(body, pos):
102 | """
103 | If a position is provided, move file to that point.
104 | Otherwise, we'll attempt to record a position for future use.
105 | """
106 | if pos is not None:
107 | rewind_body(body, pos)
108 | elif getattr(body, "tell", None) is not None:
109 | try:
110 | pos = body.tell()
111 | except (IOError, OSError):
112 | # This differentiates from None, allowing us to catch
113 | # a failed `tell()` later when trying to rewind the body.
114 | pos = _FAILEDTELL
115 |
116 | return pos
117 |
118 |
119 | def rewind_body(body, body_pos):
120 | """
121 | Attempt to rewind body to a certain position.
122 | Primarily used for request redirects and retries.
123 |
124 | :param body:
125 | File-like object that supports seek.
126 |
127 | :param int pos:
128 | Position to seek to in file.
129 | """
130 | body_seek = getattr(body, "seek", None)
131 | if body_seek is not None and isinstance(body_pos, integer_types):
132 | try:
133 | body_seek(body_pos)
134 | except (IOError, OSError):
135 | raise UnrewindableBodyError(
136 | "An error occurred when rewinding request body for redirect/retry."
137 | )
138 | elif body_pos is _FAILEDTELL:
139 | raise UnrewindableBodyError(
140 | "Unable to record file position for rewinding "
141 | "request body during a redirect/retry."
142 | )
143 | else:
144 | raise ValueError(
145 | "body_pos must be of type integer, instead it was %s." % type(body_pos)
146 | )
147 |
--------------------------------------------------------------------------------
/.site-packages/urllib3/util/response.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 |
3 | from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect
4 |
5 | from ..exceptions import HeaderParsingError
6 | from ..packages.six.moves import http_client as httplib
7 |
8 |
9 | def is_fp_closed(obj):
10 | """
11 | Checks whether a given file-like object is closed.
12 |
13 | :param obj:
14 | The file-like object to check.
15 | """
16 |
17 | try:
18 | # Check `isclosed()` first, in case Python3 doesn't set `closed`.
19 | # GH Issue #928
20 | return obj.isclosed()
21 | except AttributeError:
22 | pass
23 |
24 | try:
25 | # Check via the official file-like-object way.
26 | return obj.closed
27 | except AttributeError:
28 | pass
29 |
30 | try:
31 | # Check if the object is a container for another file-like object that
32 | # gets released on exhaustion (e.g. HTTPResponse).
33 | return obj.fp is None
34 | except AttributeError:
35 | pass
36 |
37 | raise ValueError("Unable to determine whether fp is closed.")
38 |
39 |
40 | def assert_header_parsing(headers):
41 | """
42 | Asserts whether all headers have been successfully parsed.
43 | Extracts encountered errors from the result of parsing headers.
44 |
45 | Only works on Python 3.
46 |
47 | :param http.client.HTTPMessage headers: Headers to verify.
48 |
49 | :raises urllib3.exceptions.HeaderParsingError:
50 | If parsing errors are found.
51 | """
52 |
53 | # This will fail silently if we pass in the wrong kind of parameter.
54 | # To make debugging easier add an explicit check.
55 | if not isinstance(headers, httplib.HTTPMessage):
56 | raise TypeError("expected httplib.Message, got {0}.".format(type(headers)))
57 |
58 | defects = getattr(headers, "defects", None)
59 | get_payload = getattr(headers, "get_payload", None)
60 |
61 | unparsed_data = None
62 | if get_payload:
63 | # get_payload is actually email.message.Message.get_payload;
64 | # we're only interested in the result if it's not a multipart message
65 | if not headers.is_multipart():
66 | payload = get_payload()
67 |
68 | if isinstance(payload, (bytes, str)):
69 | unparsed_data = payload
70 | if defects:
71 | # httplib is assuming a response body is available
72 | # when parsing headers even when httplib only sends
73 | # header data to parse_headers() This results in
74 | # defects on multipart responses in particular.
75 | # See: https://github.com/urllib3/urllib3/issues/800
76 |
77 | # So we ignore the following defects:
78 | # - StartBoundaryNotFoundDefect:
79 | # The claimed start boundary was never found.
80 | # - MultipartInvariantViolationDefect:
81 | # A message claimed to be a multipart but no subparts were found.
82 | defects = [
83 | defect
84 | for defect in defects
85 | if not isinstance(
86 | defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect)
87 | )
88 | ]
89 |
90 | if defects or unparsed_data:
91 | raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
92 |
93 |
94 | def is_response_to_head(response):
95 | """
96 | Checks whether the request of a response has been a HEAD-request.
97 | Handles the quirks of AppEngine.
98 |
99 | :param http.client.HTTPResponse response:
100 | Response to check if the originating request
101 | used 'HEAD' as a method.
102 | """
103 | # FIXME: Can we do this somehow without accessing private httplib _method?
104 | method = response._method
105 | if isinstance(method, int): # Platform-specific: Appengine
106 | return method == 3
107 | return method.upper() == "HEAD"
108 |
--------------------------------------------------------------------------------
/.site-packages/workflow/Notify.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/.site-packages/workflow/Notify.tgz
--------------------------------------------------------------------------------
/.site-packages/workflow/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | #
4 | # Copyright (c) 2014 Dean Jackson
5 | #
6 | # MIT Licence. See http://opensource.org/licenses/MIT
7 | #
8 | # Created on 2014-02-15
9 | #
10 |
11 | """A helper library for `Alfred `_ workflows."""
12 |
13 | import os
14 |
15 | # Filter matching rules
16 | # Icons
17 | # Exceptions
18 | # Workflow objects
19 | from .workflow import (
20 | ICON_ACCOUNT,
21 | ICON_BURN,
22 | ICON_CLOCK,
23 | ICON_COLOR,
24 | ICON_COLOUR,
25 | ICON_EJECT,
26 | ICON_ERROR,
27 | ICON_FAVORITE,
28 | ICON_FAVOURITE,
29 | ICON_GROUP,
30 | ICON_HELP,
31 | ICON_HOME,
32 | ICON_INFO,
33 | ICON_NETWORK,
34 | ICON_NOTE,
35 | ICON_SETTINGS,
36 | ICON_SWIRL,
37 | ICON_SWITCH,
38 | ICON_SYNC,
39 | ICON_TRASH,
40 | ICON_USER,
41 | ICON_WARNING,
42 | ICON_WEB,
43 | MATCH_ALL,
44 | MATCH_ALLCHARS,
45 | MATCH_ATOM,
46 | MATCH_CAPITALS,
47 | MATCH_INITIALS,
48 | MATCH_INITIALS_CONTAIN,
49 | MATCH_INITIALS_STARTSWITH,
50 | MATCH_STARTSWITH,
51 | MATCH_SUBSTRING,
52 | KeychainError,
53 | PasswordNotFound,
54 | Workflow,
55 | manager,
56 | )
57 | from .workflow3 import Variables, Workflow3
58 |
59 | __title__ = "Alfred-Workflow"
60 | __version__ = open(os.path.join(os.path.dirname(__file__), "version")).read()
61 | __author__ = "Dean Jackson"
62 | __licence__ = "MIT"
63 | __copyright__ = "Copyright 2014-2019 Dean Jackson"
64 |
65 | __all__ = [
66 | "Variables",
67 | "Workflow",
68 | "Workflow3",
69 | "manager",
70 | "PasswordNotFound",
71 | "KeychainError",
72 | "ICON_ACCOUNT",
73 | "ICON_BURN",
74 | "ICON_CLOCK",
75 | "ICON_COLOR",
76 | "ICON_COLOUR",
77 | "ICON_EJECT",
78 | "ICON_ERROR",
79 | "ICON_FAVORITE",
80 | "ICON_FAVOURITE",
81 | "ICON_GROUP",
82 | "ICON_HELP",
83 | "ICON_HOME",
84 | "ICON_INFO",
85 | "ICON_NETWORK",
86 | "ICON_NOTE",
87 | "ICON_SETTINGS",
88 | "ICON_SWIRL",
89 | "ICON_SWITCH",
90 | "ICON_SYNC",
91 | "ICON_TRASH",
92 | "ICON_USER",
93 | "ICON_WARNING",
94 | "ICON_WEB",
95 | "MATCH_ALL",
96 | "MATCH_ALLCHARS",
97 | "MATCH_ATOM",
98 | "MATCH_CAPITALS",
99 | "MATCH_INITIALS",
100 | "MATCH_INITIALS_CONTAIN",
101 | "MATCH_INITIALS_STARTSWITH",
102 | "MATCH_STARTSWITH",
103 | "MATCH_SUBSTRING",
104 | ]
105 |
--------------------------------------------------------------------------------
/.site-packages/workflow/version:
--------------------------------------------------------------------------------
1 | 1.40.0
--------------------------------------------------------------------------------
/7D9DF57A-5DF9-5DB9-AB88-88DAC6AD7FB1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/7D9DF57A-5DF9-5DB9-AB88-88DAC6AD7FB1.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iTerm Profiles Workflow for [Alfred](http://www.alfredapp.com)
2 |
3 | [](http://makeapullrequest.com)
4 |
5 | > Search through your iTerm profiles using Alfred and easily open one. Extremely useful if you have a lot of profiles, e.g. with an SSH command for each server.
6 |
7 | ## 🔧 Installation
8 |
9 | **[Download workflow here](https://github.com/jessedobbelaere/alfred-iterm-profiles-workflow/releases)**
10 |
11 | ## ⚙️ Usage
12 |
13 | 1. Enter keyword `profile` in Alfred, followed by a searchquery to find the profile you need.
14 | 2. Hit and iTerm will open your profile
15 |
16 | 
17 |
--------------------------------------------------------------------------------
/__version__.py:
--------------------------------------------------------------------------------
1 | __version__ = "2.0.0"
2 |
3 | if __name__ == "__main__":
4 | print(__version__)
5 |
--------------------------------------------------------------------------------
/build-workflow-distributable.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 |
4 | # Build the workflow
5 | zip -r alfred-iterm-profiles-workflow.alfredworkflow .site-packages/*
6 | zip -r alfred-iterm-profiles-workflow.alfredworkflow lib/*
7 | zip -r alfred-iterm-profiles-workflow.alfredworkflow *.py
8 | zip -r alfred-iterm-profiles-workflow.alfredworkflow *.png
9 | zip -r alfred-iterm-profiles-workflow.alfredworkflow README.md
10 | zip -r alfred-iterm-profiles-workflow.alfredworkflow icon.png
11 | zip -r alfred-iterm-profiles-workflow.alfredworkflow info.plist
12 |
--------------------------------------------------------------------------------
/entrypoint.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # encoding: utf-8
3 | from __future__ import annotations
4 |
5 | import os
6 | import sys
7 |
8 | # setup access to the local .site-packages
9 | sys.path.insert(0, os.path.dirname(__file__) + "/.site-packages") # noqa
10 |
11 |
12 | from workflow import Workflow3, ICON_WARNING, MATCH_SUBSTRING
13 | from lib import biplist
14 |
15 |
16 | def main(wf: Workflow3):
17 | try:
18 | # Fetch cached profiles
19 | all_profiles = wf.cached_data('profiles', read_iterm_profiles, max_age=30)
20 |
21 | # Query argument Ensure `query` is initialised
22 | query = None
23 | if len(wf.args):
24 | query = wf.args[0]
25 |
26 | # Filter profiles by query
27 | profiles = wf.filter(query, all_profiles, filter_key_for_profile, match_on=MATCH_SUBSTRING)
28 |
29 | if not profiles:
30 | wf.add_item('No profile matches', icon=ICON_WARNING)
31 |
32 | profiles.sort(key=sort_key_for_profile)
33 | for profile in profiles:
34 | wf.add_item(title=profile['name'],
35 | subtitle=((str(profile['tags']) + ' ') if profile['tags'] else '') + profile['command'],
36 | arg=profile['name'],
37 | valid=True,
38 | icon=profile['icon'])
39 |
40 | wf.send_feedback()
41 | except Exception as e:
42 | wf.logger.exception(e)
43 | raise
44 |
45 | def read_iterm_profiles():
46 | # Read iTerm's preferences file
47 | iTermPreferencesPath = os.path.join(os.environ["HOME"], "Library", "Preferences", "com.googlecode.iterm2.plist")
48 | plist = biplist.readPlist(iTermPreferencesPath)
49 | # Extract profile data from plist
50 | profiles = []
51 | for nb in plist['New Bookmarks']:
52 | profiles.append({
53 | 'name': nb.get('Name'),
54 | 'command': nb.get('Command'),
55 | 'icon': nb.get('Custom Icon Path'),
56 | 'tags': nb.get('Tags')
57 | })
58 |
59 | return profiles
60 |
61 | def filter_key_for_profile(profile):
62 | return profile['name'] + ' ' + str(profile['tags'])
63 |
64 | def sort_key_for_profile(profile):
65 | return profile['name']
66 |
67 | if __name__ == "__main__":
68 | # Create a global `Workflow3` object
69 | wf = Workflow3()
70 | wf.logger.info(__name__)
71 | # Call your entry function via `Workflow3.run()` to enable its
72 | # helper functions, like exception catching, ARGV normalization,
73 | # magic arguments etc.
74 | wf.run(main)
75 |
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/icon.png
--------------------------------------------------------------------------------
/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bundleid
6 | re.jessedobbelae.itermprofile
7 | category
8 | Productivity
9 | connections
10 |
11 | 7D9DF57A-5DF9-5DB9-AB88-88DAC6AD7FB1
12 |
13 |
14 | destinationuid
15 | 5ACF9B16-49E7-41E0-925D-A0C40D5DEBED
16 | modifiers
17 | 0
18 | modifiersubtext
19 |
20 | vitoclose
21 |
22 |
23 |
24 |
25 | createdby
26 | Jesse Dobbelaere
27 | description
28 | Easily start an iTerm profile straight from Alfred
29 | disabled
30 |
31 | name
32 | Open iTerm Profile
33 | objects
34 |
35 |
36 | config
37 |
38 | applescript
39 | on alfred_script(q)
40 |
41 | tell application "System Events"
42 | -- some versions might identify as "iTerm2" instead of "iTerm"
43 | set isRunning to (exists (processes where name is "iTerm")) or (exists (processes where name is "iTerm2"))
44 | end tell
45 |
46 | tell application "iTerm"
47 | activate
48 |
49 | if not (isRunning) then
50 | delay 0.5
51 | close the current window
52 | create window with profile q
53 | end if
54 |
55 | set hasNoWindows to ((count of windows) is 0)
56 | if isRunning and hasNoWindows then
57 | delay 0.5
58 | close the current window
59 | create window with profile q
60 | end if
61 |
62 | select first window
63 |
64 | tell the first window
65 | if isRunning and hasNoWindows is false then
66 | create tab with profile q
67 | end if
68 | end tell
69 | end tell
70 |
71 | end alfred_script
72 | cachescript
73 |
74 |
75 | type
76 | alfred.workflow.action.applescript
77 | uid
78 | 5ACF9B16-49E7-41E0-925D-A0C40D5DEBED
79 | version
80 | 1
81 |
82 |
83 | config
84 |
85 | alfredfiltersresults
86 |
87 | alfredfiltersresultsmatchmode
88 | 0
89 | argumenttreatemptyqueryasnil
90 |
91 | argumenttrimmode
92 | 0
93 | argumenttype
94 | 1
95 | escaping
96 | 0
97 | keyword
98 | profile
99 | queuedelaycustom
100 | 3
101 | queuedelayimmediatelyinitially
102 |
103 | queuedelaymode
104 | 0
105 | queuemode
106 | 1
107 | runningsubtext
108 | Please Wait
109 | script
110 |
111 | scriptargtype
112 | 1
113 | scriptfile
114 | entrypoint.py
115 | subtext
116 | Find and open an iTerm profile
117 | title
118 | Enter an iTerm profile name
119 | type
120 | 8
121 | withspace
122 |
123 |
124 | type
125 | alfred.workflow.input.scriptfilter
126 | uid
127 | 7D9DF57A-5DF9-5DB9-AB88-88DAC6AD7FB1
128 | version
129 | 3
130 |
131 |
132 | readme
133 | Search through your iTerm profiles using Alfred and easily open one. Extremely useful if you have a lot of profiles, e.g. with an SSH command for each server.
134 | uidata
135 |
136 | 5ACF9B16-49E7-41E0-925D-A0C40D5DEBED
137 |
138 | xpos
139 | 435
140 | ypos
141 | 120
142 |
143 | 7D9DF57A-5DF9-5DB9-AB88-88DAC6AD7FB1
144 |
145 | xpos
146 | 210
147 | ypos
148 | 120
149 |
150 |
151 | variablesdontexport
152 |
153 | version
154 | 2.0.0
155 | webaddress
156 | https://github.com/jessedobbelaere/alfred-iterm-profiles-workflow
157 |
158 |
159 |
--------------------------------------------------------------------------------
/lib/biplist-1.0.3.dist-info/AUTHORS:
--------------------------------------------------------------------------------
1 | Andrew Wooster (andrew@planetaryscale.com)
2 |
3 | Ported to Python 3 by Kevin Kelley (kelleyk@kelleyk.net)
4 |
--------------------------------------------------------------------------------
/lib/biplist-1.0.3.dist-info/INSTALLER:
--------------------------------------------------------------------------------
1 | pip
2 |
--------------------------------------------------------------------------------
/lib/biplist-1.0.3.dist-info/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010, Andrew Wooster
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | * Neither the name of biplist nor the names of its contributors may be
13 | used to endorse or promote products derived from this software without
14 | specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/lib/biplist-1.0.3.dist-info/METADATA:
--------------------------------------------------------------------------------
1 | Metadata-Version: 2.1
2 | Name: biplist
3 | Version: 1.0.3
4 | Summary: biplist is a library for reading/writing binary plists.
5 | Home-page: https://bitbucket.org/wooster/biplist
6 | Download-URL: https://bitbucket.org/wooster/biplist/downloads/biplist-1.0.3.tar.gz
7 | Author: Andrew Wooster
8 | Author-email: andrew@planetaryscale.com
9 | License: BSD
10 | Platform: UNKNOWN
11 | Classifier: Development Status :: 5 - Production/Stable
12 | Classifier: Intended Audience :: Developers
13 | Classifier: License :: OSI Approved :: BSD License
14 | Classifier: Operating System :: OS Independent
15 | Classifier: Programming Language :: Python
16 | Classifier: Topic :: Software Development :: Libraries :: Python Modules
17 | Classifier: Topic :: Text Processing :: Markup
18 | License-File: LICENSE
19 | License-File: AUTHORS
20 |
21 | `biplist` is a binary plist parser/generator for Python.
22 |
23 | Binary Property List (plist) files provide a faster and smaller serialization
24 | format for property lists on OS X. This is a library for generating binary
25 | plists which can be read by OS X, iOS, or other clients.
26 |
27 | This module requires Python 2.6 or higher or Python 3.4 or higher.
28 |
29 |
--------------------------------------------------------------------------------
/lib/biplist-1.0.3.dist-info/RECORD:
--------------------------------------------------------------------------------
1 | biplist-1.0.3.dist-info/AUTHORS,sha256=ohIvnBZ_jr_4CAO6PvfK22HiA-ZiMM_2hHBJKe-g-7Q,101
2 | biplist-1.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
3 | biplist-1.0.3.dist-info/LICENSE,sha256=aO5PxXo1YY9t7RwJ8_YhZTC5RAc0voBcK1BM9V0kLjQ,1510
4 | biplist-1.0.3.dist-info/METADATA,sha256=qXXZXMAJ9MFl58rGVNFhHYooYootAEtxqgVCvi4lUPo,1085
5 | biplist-1.0.3.dist-info/RECORD,,
6 | biplist-1.0.3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7 | biplist-1.0.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
8 | biplist-1.0.3.dist-info/top_level.txt,sha256=TT2vZtYziYVpLawg8KXvf6vAOlwDVwsHk0OpMih9Mk8,8
9 | biplist/__init__.py,sha256=GEagv9tNCJiD45H_t8Qp_dfqq-fKYLO122HdKzux2Tc,37313
10 | biplist/__pycache__/__init__.cpython-39.pyc,,
11 |
--------------------------------------------------------------------------------
/lib/biplist-1.0.3.dist-info/REQUESTED:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jessedobbelaere/alfred-iterm-profiles-workflow/b6b44e42b1a9c9dff6b4b4fccadcbea1210b6eea/lib/biplist-1.0.3.dist-info/REQUESTED
--------------------------------------------------------------------------------
/lib/biplist-1.0.3.dist-info/WHEEL:
--------------------------------------------------------------------------------
1 | Wheel-Version: 1.0
2 | Generator: bdist_wheel (0.37.1)
3 | Root-Is-Purelib: true
4 | Tag: py3-none-any
5 |
6 |
--------------------------------------------------------------------------------
/lib/biplist-1.0.3.dist-info/top_level.txt:
--------------------------------------------------------------------------------
1 | biplist
2 |
--------------------------------------------------------------------------------