|  | 
| 14 | 14 | import hashlib | 
| 15 | 15 | import json | 
| 16 | 16 | import logging as _logging | 
| 17 |  | -import mimetypes | 
| 18 | 17 | import os | 
| 19 | 18 | import re | 
| 20 | 19 | import sys | 
| 21 |  | -import tempfile | 
| 22 | 20 | import time | 
| 23 | 21 | import urllib | 
| 24 | 22 | import warnings | 
| @@ -606,8 +604,6 @@ def __init__( | 
| 606 | 604 |         if len(context_path) > 0: | 
| 607 | 605 |             self._options["context_path"] = context_path | 
| 608 | 606 | 
 | 
| 609 |  | -        self._try_magic() | 
| 610 |  | - | 
| 611 | 607 |         assert isinstance(self._options["headers"], dict)  # for mypy benefit | 
| 612 | 608 | 
 | 
| 613 | 609 |         # Create Session object and update with config options first | 
| @@ -3336,9 +3332,7 @@ def create_temp_project_avatar( | 
| 3336 | 3332 | 
 | 
| 3337 | 3333 |         The avatar created is temporary and must be confirmed before it can be used. | 
| 3338 | 3334 | 
 | 
| 3339 |  | -        Avatar images are specified by a filename, size, and file object. By default, the client will attempt to autodetect the picture's content type | 
| 3340 |  | -        this mechanism relies on libmagic and will not work out of the box on Windows systems | 
| 3341 |  | -        (see `Their Documentation <https://filemagic.readthedocs.io/en/latest/guide.html>`_ for details on how to install support). | 
|  | 3335 | +        Avatar images are specified by a filename, size, and file object. By default, the client will attempt to autodetect the picture's content type. | 
| 3342 | 3336 | 
 | 
| 3343 | 3337 |         The ``contentType`` argument can be used to explicitly set the value (note that Jira will reject any type other than the well-known ones for images, e.g. ``image/jpg``, ``image/png``, etc.) | 
| 3344 | 3338 | 
 | 
| @@ -4051,9 +4045,7 @@ def create_temp_user_avatar( | 
| 4051 | 4045 | 
 | 
| 4052 | 4046 |         The avatar created is temporary and must be confirmed before it can be used. | 
| 4053 | 4047 | 
 | 
| 4054 |  | -        Avatar images are specified by a filename, size, and file object. By default, the client will attempt to autodetect the picture's content type: | 
| 4055 |  | -        this mechanism relies on ``libmagic`` and will not work out of the box on Windows systems | 
| 4056 |  | -        (see `Their Documentation <https://filemagic.readthedocs.io/en/latest/guide.html>`_ for details on how to install support). | 
|  | 4048 | +        Avatar images are specified by a filename, size, and file object. By default, the client will attempt to autodetect the picture's content type. | 
| 4057 | 4049 |         The ``contentType`` argument can be used to explicitly set the value | 
| 4058 | 4050 |         (note that Jira will reject any type other than the well-known ones for images, e.g. ``image/jpg``, ``image/png``, etc.) | 
| 4059 | 4051 | 
 | 
| @@ -4631,49 +4623,32 @@ def _find_for_resource( | 
| 4631 | 4623 |             raise JIRAError("Unable to find resource %s(%s)", resource_cls, str(ids)) | 
| 4632 | 4624 |         return resource | 
| 4633 | 4625 | 
 | 
| 4634 |  | -    def _try_magic(self): | 
| 4635 |  | -        try: | 
| 4636 |  | -            import weakref | 
| 4637 |  | - | 
| 4638 |  | -            import magic | 
| 4639 |  | -        except ImportError: | 
| 4640 |  | -            self._magic = None | 
| 4641 |  | -        else: | 
| 4642 |  | -            try: | 
| 4643 |  | -                _magic = magic.Magic(flags=magic.MAGIC_MIME_TYPE) | 
| 4644 |  | - | 
| 4645 |  | -                def cleanup(x): | 
| 4646 |  | -                    _magic.close() | 
| 4647 |  | - | 
| 4648 |  | -                self._magic_weakref = weakref.ref(self, cleanup) | 
| 4649 |  | -                self._magic = _magic | 
| 4650 |  | -            except TypeError: | 
| 4651 |  | -                self._magic = None | 
| 4652 |  | -            except AttributeError: | 
| 4653 |  | -                self._magic = None | 
| 4654 |  | - | 
| 4655 | 4626 |     def _get_mime_type(self, buff: bytes) -> str | None: | 
| 4656 |  | -        """Get the MIME type for a given stream of bytes. | 
|  | 4627 | +        """Get the MIME type for a given stream of bytes of an avatar. | 
| 4657 | 4628 | 
 | 
| 4658 | 4629 |         Args: | 
| 4659 | 4630 |             buff (bytes): Stream of bytes | 
| 4660 | 4631 | 
 | 
| 4661 | 4632 |         Returns: | 
| 4662 | 4633 |             Optional[str]: the MIME type | 
| 4663 | 4634 |         """ | 
| 4664 |  | -        if self._magic is not None: | 
| 4665 |  | -            return self._magic.id_buffer(buff) | 
| 4666 |  | -        try: | 
| 4667 |  | -            with tempfile.TemporaryFile() as f: | 
| 4668 |  | -                f.write(buff) | 
| 4669 |  | -                return mimetypes.guess_type(f.name)[0] | 
| 4670 |  | -            return mimetypes.guess_type(f.name)[0] | 
| 4671 |  | -        except (OSError, TypeError): | 
| 4672 |  | -            self.log.warning( | 
| 4673 |  | -                "Couldn't detect content type of avatar image" | 
| 4674 |  | -                ". Specify the 'contentType' parameter explicitly." | 
| 4675 |  | -            ) | 
| 4676 |  | -            return None | 
|  | 4635 | +        # We assume the image is one of supported formats | 
|  | 4636 | +        # https://docs.atlassian.com/software/jira/docs/api/REST/9.14.0/#api/2/project-storeTemporaryAvatar | 
|  | 4637 | +        if buff[:3] == b"\xff\xd8\xff": | 
|  | 4638 | +            return "image/jpeg" | 
|  | 4639 | +        if buff[:8] == b"\x89PNG\r\n\x1a\n": | 
|  | 4640 | +            return "image/png" | 
|  | 4641 | +        if buff[:6] in (b"GIF87a", b"GIF89a"): | 
|  | 4642 | +            return "image/gif" | 
|  | 4643 | +        if buff[:2] == b"BM": | 
|  | 4644 | +            return "image/bmp" | 
|  | 4645 | +        if buff[:2] == b"\0\0": | 
|  | 4646 | +            return "image/vnd.wap.wbmp" | 
|  | 4647 | +        self.log.warning( | 
|  | 4648 | +            "Couldn't detect content type of avatar image" | 
|  | 4649 | +            ". Specify the 'contentType' parameter explicitly." | 
|  | 4650 | +        ) | 
|  | 4651 | +        return None | 
| 4677 | 4652 | 
 | 
| 4678 | 4653 |     def rename_user(self, old_user: str, new_user: str): | 
| 4679 | 4654 |         """Rename a Jira user. | 
|  | 
0 commit comments