Compare commits

...

30 Commits
master ... dev

Author SHA1 Message Date
Profitroll 818afa0b74
Fixed caption being added explicitly 2024-04-30 20:57:51 +02:00
Renovate c99f22b1b8 Update dependency pillow to ~=10.3.0 (#76)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [pillow](https://github.com/python-pillow/Pillow) ([changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)) | minor | `~=10.2.0` -> `~=10.3.0` |

---

### Release Notes

<details>
<summary>python-pillow/Pillow (pillow)</summary>

### [`v10.3.0`](https://github.com/python-pillow/Pillow/blob/HEAD/CHANGES.rst#1030-2024-04-01)

[Compare Source](https://github.com/python-pillow/Pillow/compare/10.2.0...10.3.0)

-   CVE-2024-28219: Use `strncpy` to avoid buffer overflow [#&#8203;7928](https://github.com/python-pillow/Pillow/issues/7928)
    \[radarhere, hugovk]

-   Deprecate `eval()`, replacing it with `lambda_eval()` and `unsafe_eval()` [#&#8203;7927](https://github.com/python-pillow/Pillow/issues/7927)
    \[radarhere, hugovk]

-   Raise `ValueError` if seeking to greater than offset-sized integer in TIFF [#&#8203;7883](https://github.com/python-pillow/Pillow/issues/7883)
    \[radarhere]

-   Add `--report` argument to `__main__.py` to omit supported formats [#&#8203;7818](https://github.com/python-pillow/Pillow/issues/7818)
    \[nulano, radarhere, hugovk]

-   Added RGB to I;16, I;16L, I;16B and I;16N conversion [#&#8203;7918](https://github.com/python-pillow/Pillow/issues/7918), [#&#8203;7920](https://github.com/python-pillow/Pillow/issues/7920)
    \[radarhere]

-   Fix editable installation with custom build backend and configuration options [#&#8203;7658](https://github.com/python-pillow/Pillow/issues/7658)
    \[nulano, radarhere]

-   Fix putdata() for I;16N on big-endian [#&#8203;7209](https://github.com/python-pillow/Pillow/issues/7209)
    \[Yay295, hugovk, radarhere]

-   Determine MPO size from markers, not EXIF data [#&#8203;7884](https://github.com/python-pillow/Pillow/issues/7884)
    \[radarhere]

-   Improved conversion from RGB to RGBa, LA and La [#&#8203;7888](https://github.com/python-pillow/Pillow/issues/7888)
    \[radarhere]

-   Support FITS images with GZIP\_1 compression [#&#8203;7894](https://github.com/python-pillow/Pillow/issues/7894)
    \[radarhere]

-   Use I;16 mode for 9-bit JPEG 2000 images [#&#8203;7900](https://github.com/python-pillow/Pillow/issues/7900)
    \[scaramallion, radarhere]

-   Raise ValueError if kmeans is negative [#&#8203;7891](https://github.com/python-pillow/Pillow/issues/7891)
    \[radarhere]

-   Remove TIFF tag OSUBFILETYPE when saving using libtiff [#&#8203;7893](https://github.com/python-pillow/Pillow/issues/7893)
    \[radarhere]

-   Raise ValueError for negative values when loading P1-P3 PPM images [#&#8203;7882](https://github.com/python-pillow/Pillow/issues/7882)
    \[radarhere]

-   Added reading of JPEG2000 palettes [#&#8203;7870](https://github.com/python-pillow/Pillow/issues/7870)
    \[radarhere]

-   Added alpha_quality argument when saving WebP images [#&#8203;7872](https://github.com/python-pillow/Pillow/issues/7872)
    \[radarhere]

-   Fixed joined corners for ImageDraw rounded_rectangle() non-integer dimensions [#&#8203;7881](https://github.com/python-pillow/Pillow/issues/7881)
    \[radarhere]

-   Stop reading EPS image at EOF marker [#&#8203;7753](https://github.com/python-pillow/Pillow/issues/7753)
    \[radarhere]

-   PSD layer co-ordinates may be negative [#&#8203;7706](https://github.com/python-pillow/Pillow/issues/7706)
    \[radarhere]

-   Use subprocess with CREATE_NO_WINDOW flag in ImageShow WindowsViewer [#&#8203;7791](https://github.com/python-pillow/Pillow/issues/7791)
    \[radarhere]

-   When saving GIF frame that restores to background color, do not fill identical pixels [#&#8203;7788](https://github.com/python-pillow/Pillow/issues/7788)
    \[radarhere]

-   Fixed reading PNG iCCP compression method [#&#8203;7823](https://github.com/python-pillow/Pillow/issues/7823)
    \[radarhere]

-   Allow writing IFDRational to UNDEFINED tag [#&#8203;7840](https://github.com/python-pillow/Pillow/issues/7840)
    \[radarhere]

-   Fix logged tag name when loading Exif data [#&#8203;7842](https://github.com/python-pillow/Pillow/issues/7842)
    \[radarhere]

-   Use maximum frame size in IHDR chunk when saving APNG images [#&#8203;7821](https://github.com/python-pillow/Pillow/issues/7821)
    \[radarhere]

-   Prevent opening P TGA images without a palette [#&#8203;7797](https://github.com/python-pillow/Pillow/issues/7797)
    \[radarhere]

-   Use palette when loading ICO images [#&#8203;7798](https://github.com/python-pillow/Pillow/issues/7798)
    \[radarhere]

-   Use consistent arguments for load_read and load_seek [#&#8203;7713](https://github.com/python-pillow/Pillow/issues/7713)
    \[radarhere]

-   Turn off nullability warnings for macOS SDK [#&#8203;7827](https://github.com/python-pillow/Pillow/issues/7827)
    \[radarhere]

-   Fix shift-sign issue in Convert.c [#&#8203;7838](https://github.com/python-pillow/Pillow/issues/7838)
    \[r-barnes, radarhere]

-   Open 16-bit grayscale PNGs as I;16 [#&#8203;7849](https://github.com/python-pillow/Pillow/issues/7849)
    \[radarhere]

-   Handle truncated chunks at the end of PNG images [#&#8203;7709](https://github.com/python-pillow/Pillow/issues/7709)
    \[lajiyuan, radarhere]

-   Match mask size to pasted image size in GifImagePlugin [#&#8203;7779](https://github.com/python-pillow/Pillow/issues/7779)
    \[radarhere]

-   Release GIL while calling `WebPAnimDecoderGetNext` [#&#8203;7782](https://github.com/python-pillow/Pillow/issues/7782)
    \[evanmiller, radarhere]

-   Fixed reading FLI/FLC images with a prefix chunk [#&#8203;7804](https://github.com/python-pillow/Pillow/issues/7804)
    \[twolife]

-   Update wl-paste handling and return None for some errors in grabclipboard() on Linux [#&#8203;7745](https://github.com/python-pillow/Pillow/issues/7745)
    \[nik012003, radarhere]

-   Remove execute bit from `setup.py` [#&#8203;7760](https://github.com/python-pillow/Pillow/issues/7760)
    \[hugovk]

-   Do not support using test-image-results to upload images after test failures [#&#8203;7739](https://github.com/python-pillow/Pillow/issues/7739)
    \[radarhere]

-   Changed ImageMath.ops to be static [#&#8203;7721](https://github.com/python-pillow/Pillow/issues/7721)
    \[radarhere]

-   Fix APNG info after seeking backwards more than twice [#&#8203;7701](https://github.com/python-pillow/Pillow/issues/7701)
    \[esoma, radarhere]

-   Deprecate ImageCms constants and versions() function [#&#8203;7702](https://github.com/python-pillow/Pillow/issues/7702)
    \[nulano, radarhere]

-   Added PerspectiveTransform [#&#8203;7699](https://github.com/python-pillow/Pillow/issues/7699)
    \[radarhere]

-   Add support for reading and writing grayscale PFM images [#&#8203;7696](https://github.com/python-pillow/Pillow/issues/7696)
    \[nulano, hugovk]

-   Add LCMS2 flags to ImageCms [#&#8203;7676](https://github.com/python-pillow/Pillow/issues/7676)
    \[nulano, radarhere, hugovk]

-   Rename x64 to AMD64 in winbuild [#&#8203;7693](https://github.com/python-pillow/Pillow/issues/7693)
    \[nulano]

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #76
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2024-04-02 15:09:37 +03:00
Renovate 1ac5abd7bf Update dependency photosapi_client to v0.6.0 (#75)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| photosapi_client | minor | `==0.5.0` -> `==0.6.0` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Co-authored-by: profitroll <vozhd.kk@gmail.com>
Reviewed-on: #75
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2024-03-19 23:25:03 +02:00
Profitroll bd43ee15ae
Replaced find_one_and* with proper methods 2024-03-11 21:37:01 +01:00
Profitroll f8ec8f6335 Bump libbot to 3.0.0 2024-01-28 21:24:01 +02:00
Renovate e345f31c56 Update dependency pykeyboard to v0.1.7 (#74)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [pykeyboard](https://github.com/pystorage/pykeyboard) | patch | `==0.1.5` -> `==0.1.7` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #74
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2024-01-28 21:23:30 +02:00
Renovate 1c53476e37 Update dependency pillow to ~=10.2.0 (#73)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [pillow](https://github.com/python-pillow/Pillow) ([changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)) | minor | `~=10.1.0` -> `~=10.2.0` |

---

### Release Notes

<details>
<summary>python-pillow/Pillow (pillow)</summary>

### [`v10.2.0`](https://github.com/python-pillow/Pillow/blob/HEAD/CHANGES.rst#1020-2024-01-02)

[Compare Source](https://github.com/python-pillow/Pillow/compare/10.1.0...10.2.0)

-   Add `keep_rgb` option when saving JPEG to prevent conversion of RGB colorspace [#&#8203;7553](https://github.com/python-pillow/Pillow/issues/7553)
    \[bgilbert, radarhere]

-   Trim glyph size in ImageFont.getmask() [#&#8203;7669](https://github.com/python-pillow/Pillow/issues/7669), [#&#8203;7672](https://github.com/python-pillow/Pillow/issues/7672)
    \[radarhere, nulano]

-   Deprecate IptcImagePlugin helpers [#&#8203;7664](https://github.com/python-pillow/Pillow/issues/7664)
    \[nulano, hugovk, radarhere]

-   Allow uncompressed TIFF images to be saved in chunks [#&#8203;7650](https://github.com/python-pillow/Pillow/issues/7650)
    \[radarhere]

-   Concatenate multiple JPEG EXIF markers [#&#8203;7496](https://github.com/python-pillow/Pillow/issues/7496)
    \[radarhere]

-   Changed IPTC tile tuple to match other plugins [#&#8203;7661](https://github.com/python-pillow/Pillow/issues/7661)
    \[radarhere]

-   Do not assign new fp attribute when exiting context manager [#&#8203;7566](https://github.com/python-pillow/Pillow/issues/7566)
    \[radarhere]

-   Support arbitrary masks for uncompressed RGB DDS images [#&#8203;7589](https://github.com/python-pillow/Pillow/issues/7589)
    \[radarhere, akx]

-   Support setting ROWSPERSTRIP tag [#&#8203;7654](https://github.com/python-pillow/Pillow/issues/7654)
    \[radarhere]

-   Apply ImageFont.MAX_STRING_LENGTH to ImageFont.getmask() [#&#8203;7662](https://github.com/python-pillow/Pillow/issues/7662)
    \[radarhere]

-   Optimise `ImageColor` using `functools.lru_cache` [#&#8203;7657](https://github.com/python-pillow/Pillow/issues/7657)
    \[hugovk]

-   Restricted environment keys for ImageMath.eval() [#&#8203;7655](https://github.com/python-pillow/Pillow/issues/7655)
    \[wiredfool, radarhere]

-   Optimise `ImageMode.getmode` using `functools.lru_cache` [#&#8203;7641](https://github.com/python-pillow/Pillow/issues/7641)
    \[hugovk, radarhere]

-   Fix incorrect color blending for overlapping glyphs [#&#8203;7497](https://github.com/python-pillow/Pillow/issues/7497)
    \[ZachNagengast, nulano, radarhere]

-   Attempt memory mapping when tile args is a string [#&#8203;7565](https://github.com/python-pillow/Pillow/issues/7565)
    \[radarhere]

-   Fill identical pixels with transparency in subsequent frames when saving GIF [#&#8203;7568](https://github.com/python-pillow/Pillow/issues/7568)
    \[radarhere]

-   Corrected duration when combining multiple GIF frames into single frame [#&#8203;7521](https://github.com/python-pillow/Pillow/issues/7521)
    \[radarhere]

-   Handle disposing GIF background from outside palette [#&#8203;7515](https://github.com/python-pillow/Pillow/issues/7515)
    \[radarhere]

-   Seek past the data when skipping a PSD layer [#&#8203;7483](https://github.com/python-pillow/Pillow/issues/7483)
    \[radarhere]

-   Import plugins relative to the module [#&#8203;7576](https://github.com/python-pillow/Pillow/issues/7576)
    \[deliangyang, jaxx0n]

-   Translate encoder error codes to strings; deprecate `ImageFile.raise_oserror()` [#&#8203;7609](https://github.com/python-pillow/Pillow/issues/7609)
    \[bgilbert, radarhere]

-   Support reading BC4U and DX10 BC1 images [#&#8203;6486](https://github.com/python-pillow/Pillow/issues/6486)
    \[REDxEYE, radarhere, hugovk]

-   Optimize ImageStat.Stat.extrema [#&#8203;7593](https://github.com/python-pillow/Pillow/issues/7593)
    \[florath, radarhere]

-   Handle pathlib.Path in FreeTypeFont [#&#8203;7578](https://github.com/python-pillow/Pillow/issues/7578)
    \[radarhere, hugovk, nulano]

-   Added support for reading DX10 BC4 DDS images [#&#8203;7603](https://github.com/python-pillow/Pillow/issues/7603)
    \[sambvfx, radarhere]

-   Optimized ImageStat.Stat.count [#&#8203;7599](https://github.com/python-pillow/Pillow/issues/7599)
    \[florath]

-   Correct PDF palette size when saving [#&#8203;7555](https://github.com/python-pillow/Pillow/issues/7555)
    \[radarhere]

-   Fixed closing file pointer with olefile 0.47 [#&#8203;7594](https://github.com/python-pillow/Pillow/issues/7594)
    \[radarhere]

-   Raise ValueError when TrueType font size is not greater than zero [#&#8203;7584](https://github.com/python-pillow/Pillow/issues/7584), [#&#8203;7587](https://github.com/python-pillow/Pillow/issues/7587)
    \[akx, radarhere]

-   If absent, do not try to close fp when closing image [#&#8203;7557](https://github.com/python-pillow/Pillow/issues/7557)
    \[RaphaelVRossi, radarhere]

-   Allow configuring JPEG restart marker interval on save [#&#8203;7488](https://github.com/python-pillow/Pillow/issues/7488)
    \[bgilbert, radarhere]

-   Decrement reference count for PyObject [#&#8203;7549](https://github.com/python-pillow/Pillow/issues/7549)
    \[radarhere]

-   Implement `streamtype=1` option for tables-only JPEG encoding [#&#8203;7491](https://github.com/python-pillow/Pillow/issues/7491)
    \[bgilbert, radarhere]

-   If save_all PNG only has one frame, do not create animated image [#&#8203;7522](https://github.com/python-pillow/Pillow/issues/7522)
    \[radarhere]

-   Fixed frombytes() for images with a zero dimension [#&#8203;7493](https://github.com/python-pillow/Pillow/issues/7493)
    \[radarhere]

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #73
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2024-01-02 13:12:31 +02:00
Renovate 898a63012f Update dependency libbot to v2.1.0 (#71)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [libbot](https://github.com/botlibx/libbot) | minor | `==2.0.1` -> `==2.1.0` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #71
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2023-12-27 16:21:23 +02:00
Renovate 854e3d2832 Update dependency aiohttp to ~=3.9.1 (#68)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [aiohttp](https://github.com/aio-libs/aiohttp) | minor | `~=3.8.4` -> `~=3.9.1` |

---

### Release Notes

<details>
<summary>aio-libs/aiohttp (aiohttp)</summary>

### [`v3.9.1`](https://github.com/aio-libs/aiohttp/blob/HEAD/CHANGES.rst#391-2023-11-26)

[Compare Source](https://github.com/aio-libs/aiohttp/compare/v3.9.0...v3.9.1)

\==================

## Bugfixes

-   Fixed importing aiohttp under PyPy on Windows.

    `#&#8203;7848 <https://github.com/aio-libs/aiohttp/issues/7848>`\_

-   Fixed async concurrency safety in websocket compressor.

    `#&#8203;7865 <https://github.com/aio-libs/aiohttp/issues/7865>`\_

-   Fixed `ClientResponse.close()` releasing the connection instead of closing.

    `#&#8203;7869 <https://github.com/aio-libs/aiohttp/issues/7869>`\_

-   Fixed a regression where connection may get closed during upgrade. -- by :user:`Dreamsorcerer`

    `#&#8203;7879 <https://github.com/aio-libs/aiohttp/issues/7879>`\_

-   Fixed messages being reported as upgraded without an Upgrade header in Python parser. -- by :user:`Dreamsorcerer`

    `#&#8203;7895 <https://github.com/aio-libs/aiohttp/issues/7895>`\_

***

### [`v3.9.0`](https://github.com/aio-libs/aiohttp/blob/HEAD/CHANGES.rst#390-2023-11-18)

[Compare Source](https://github.com/aio-libs/aiohttp/compare/v3.8.6...v3.9.0)

\==================

## Features

-   Introduced `AppKey` for static typing support of `Application` storage.
    See https://docs.aiohttp.org/en/stable/web_advanced.html#application-s-config

    `#&#8203;5864 <https://github.com/aio-libs/aiohttp/issues/5864>`\_

-   Added a graceful shutdown period which allows pending tasks to complete before the application's cleanup is called.
    The period can be adjusted with the `shutdown_timeout` parameter. -- by :user:`Dreamsorcerer`.
    See https://docs.aiohttp.org/en/latest/web_advanced.html#graceful-shutdown

    `#&#8203;7188 <https://github.com/aio-libs/aiohttp/issues/7188>`\_

-   Added `handler_cancellation <https://docs.aiohttp.org/en/stable/web_advanced.html#web-handler-cancellation>`\_ parameter to cancel web handler on client disconnection. -- by :user:`mosquito`
    This (optionally) reintroduces a feature removed in a previous release.
    Recommended for those looking for an extra level of protection against denial-of-service attacks.

    `#&#8203;7056 <https://github.com/aio-libs/aiohttp/issues/7056>`\_

-   Added support for setting response header parameters `max_line_size` and `max_field_size`.

    `#&#8203;2304 <https://github.com/aio-libs/aiohttp/issues/2304>`\_

-   Added `auto_decompress` parameter to `ClientSession.request` to override `ClientSession._auto_decompress`. -- by :user:`Daste745`

    `#&#8203;3751 <https://github.com/aio-libs/aiohttp/issues/3751>`\_

-   Changed `raise_for_status` to allow a coroutine.

    `#&#8203;3892 <https://github.com/aio-libs/aiohttp/issues/3892>`\_

-   Added client brotli compression support (optional with runtime check).

    `#&#8203;5219 <https://github.com/aio-libs/aiohttp/issues/5219>`\_

-   Added `client_max_size` to `BaseRequest.clone()` to allow overriding the request body size. -- :user:`anesabml`.

    `#&#8203;5704 <https://github.com/aio-libs/aiohttp/issues/5704>`\_

-   Added a middleware type alias `aiohttp.typedefs.Middleware`.

    `#&#8203;5898 <https://github.com/aio-libs/aiohttp/issues/5898>`\_

-   Exported `HTTPMove` which can be used to catch any redirection request
    that has a location -- :user:`dreamsorcerer`.

    `#&#8203;6594 <https://github.com/aio-libs/aiohttp/issues/6594>`\_

-   Changed the `path` parameter in `web.run_app()` to accept a `pathlib.Path` object.

    `#&#8203;6839 <https://github.com/aio-libs/aiohttp/issues/6839>`\_

-   Performance: Skipped filtering `CookieJar` when the jar is empty or all cookies have expired.

    `#&#8203;7819 <https://github.com/aio-libs/aiohttp/issues/7819>`\_

-   Performance: Only check origin if insecure scheme and there are origins to treat as secure, in `CookieJar.filter_cookies()`.

    `#&#8203;7821 <https://github.com/aio-libs/aiohttp/issues/7821>`\_

-   Performance: Used timestamp instead of `datetime` to achieve faster cookie expiration in `CookieJar`.

    `#&#8203;7824 <https://github.com/aio-libs/aiohttp/issues/7824>`\_

-   Added support for passing a custom server name parameter to HTTPS connection.

    `#&#8203;7114 <https://github.com/aio-libs/aiohttp/issues/7114>`\_

-   Added support for using Basic Auth credentials from :file:`.netrc` file when making HTTP requests with the
    :py:class:`~aiohttp.ClientSession` `trust_env` argument is set to `True`. -- by :user:`yuvipanda`.

    `#&#8203;7131 <https://github.com/aio-libs/aiohttp/issues/7131>`\_

-   Turned access log into no-op when the logger is disabled.

    `#&#8203;7240 <https://github.com/aio-libs/aiohttp/issues/7240>`\_

-   Added typing information to `RawResponseMessage`. -- by :user:`Gobot1234`

    `#&#8203;7365 <https://github.com/aio-libs/aiohttp/issues/7365>`\_

-   Removed `async-timeout` for Python 3.11+ (replaced with `asyncio.timeout()` on newer releases).

    `#&#8203;7502 <https://github.com/aio-libs/aiohttp/issues/7502>`\_

-   Added support for `brotlicffi` as an alternative to `brotli` (fixing Brotli support on PyPy).

    `#&#8203;7611 <https://github.com/aio-libs/aiohttp/issues/7611>`\_

-   Added `WebSocketResponse.get_extra_info()` to access a protocol transport's extra info.

    `#&#8203;7078 <https://github.com/aio-libs/aiohttp/issues/7078>`\_

-   Allow `link` argument to be set to None/empty in HTTP 451 exception.

    `#&#8203;7689 <https://github.com/aio-libs/aiohttp/issues/7689>`\_

## Bugfixes

-   Implemented stripping the trailing dots from fully-qualified domain names in `Host` headers and TLS context when acting as an HTTP client.
    This allows the client to connect to URLs with FQDN host name like `https://example.com./`.
    \-- by :user:`martin-sucha`.

    `#&#8203;3636 <https://github.com/aio-libs/aiohttp/issues/3636>`\_

-   Fixed client timeout not working when incoming data is always available without waiting. -- by :user:`Dreamsorcerer`.

    `#&#8203;5854 <https://github.com/aio-libs/aiohttp/issues/5854>`\_

-   Fixed `readuntil` to work with a delimiter of more than one character.

    `#&#8203;6701 <https://github.com/aio-libs/aiohttp/issues/6701>`\_

-   Added `__repr__` to `EmptyStreamReader` to avoid `AttributeError`.

    `#&#8203;6916 <https://github.com/aio-libs/aiohttp/issues/6916>`\_

-   Fixed bug when using `TCPConnector` with `ttl_dns_cache=0`.

    `#&#8203;7014 <https://github.com/aio-libs/aiohttp/issues/7014>`\_

-   Fixed response returned from expect handler being thrown away. -- by :user:`Dreamsorcerer`

    `#&#8203;7025 <https://github.com/aio-libs/aiohttp/issues/7025>`\_

-   Avoided raising `UnicodeDecodeError` in multipart and in HTTP headers parsing.

    `#&#8203;7044 <https://github.com/aio-libs/aiohttp/issues/7044>`\_

-   Changed `sock_read` timeout to start after writing has finished, avoiding read timeouts caused by an unfinished write. -- by :user:`dtrifiro`

    `#&#8203;7149 <https://github.com/aio-libs/aiohttp/issues/7149>`\_

-   Fixed missing query in tracing method URLs when using `yarl` 1.9+.

    `#&#8203;7259 <https://github.com/aio-libs/aiohttp/issues/7259>`\_

-   Changed max 32-bit timestamp to an aware datetime object, for consistency with the non-32-bit one, and to avoid a `DeprecationWarning` on Python 3.12.

    `#&#8203;7302 <https://github.com/aio-libs/aiohttp/issues/7302>`\_

-   Fixed `EmptyStreamReader.iter_chunks()` never ending. -- by :user:`mind1m`

    `#&#8203;7616 <https://github.com/aio-libs/aiohttp/issues/7616>`\_

-   Fixed a rare `RuntimeError: await wasn't used with future` exception. -- by :user:`stalkerg`

    `#&#8203;7785 <https://github.com/aio-libs/aiohttp/issues/7785>`\_

-   Fixed issue with insufficient HTTP method and version validation.

    `#&#8203;7700 <https://github.com/aio-libs/aiohttp/issues/7700>`\_

-   Added check to validate that absolute URIs have schemes.

    `#&#8203;7712 <https://github.com/aio-libs/aiohttp/issues/7712>`\_

-   Fixed unhandled exception when Python HTTP parser encounters unpaired Unicode surrogates.

    `#&#8203;7715 <https://github.com/aio-libs/aiohttp/issues/7715>`\_

-   Updated parser to disallow invalid characters in header field names and stop accepting LF as a request line separator.

    `#&#8203;7719 <https://github.com/aio-libs/aiohttp/issues/7719>`\_

-   Fixed Python HTTP parser not treating 204/304/1xx as an empty body.

    `#&#8203;7755 <https://github.com/aio-libs/aiohttp/issues/7755>`\_

-   Ensure empty body response for 1xx/204/304 per RFC 9112 sec 6.3.

    `#&#8203;7756 <https://github.com/aio-libs/aiohttp/issues/7756>`\_

-   Fixed an issue when a client request is closed before completing a chunked payload. -- by :user:`Dreamsorcerer`

    `#&#8203;7764 <https://github.com/aio-libs/aiohttp/issues/7764>`\_

-   Edge Case Handling for ResponseParser for missing reason value.

    `#&#8203;7776 <https://github.com/aio-libs/aiohttp/issues/7776>`\_

-   Fixed `ClientWebSocketResponse.close_code` being erroneously set to `None` when there are concurrent async tasks receiving data and closing the connection.

    `#&#8203;7306 <https://github.com/aio-libs/aiohttp/issues/7306>`\_

-   Added HTTP method validation.

    `#&#8203;6533 <https://github.com/aio-libs/aiohttp/issues/6533>`\_

-   Fixed arbitrary sequence types being allowed to inject values via version parameter. -- by :user:`Dreamsorcerer`

    `#&#8203;7835 <https://github.com/aio-libs/aiohttp/issues/7835>`\_

-   Performance: Fixed increase in latency with small messages from websocket compression changes.

    `#&#8203;7797 <https://github.com/aio-libs/aiohttp/issues/7797>`\_

## Improved Documentation

-   Fixed the `ClientResponse.release`'s type in the doc. Changed from `comethod` to `method`.

    `#&#8203;5836 <https://github.com/aio-libs/aiohttp/issues/5836>`\_

-   Added information on behavior of base_url parameter in `ClientSession`.

    `#&#8203;6647 <https://github.com/aio-libs/aiohttp/issues/6647>`\_

-   Fixed `ClientResponseError` docs.

    `#&#8203;6700 <https://github.com/aio-libs/aiohttp/issues/6700>`\_

-   Updated Redis code examples to follow the latest API.

    `#&#8203;6907 <https://github.com/aio-libs/aiohttp/issues/6907>`\_

-   Added a note about possibly needing to update headers when using `on_response_prepare`. -- by :user:`Dreamsorcerer`

    `#&#8203;7283 <https://github.com/aio-libs/aiohttp/issues/7283>`\_

-   Completed `trust_env` parameter description to honor `wss_proxy`, `ws_proxy` or `no_proxy` env.

    `#&#8203;7325 <https://github.com/aio-libs/aiohttp/issues/7325>`\_

-   Expanded SSL documentation with more examples (e.g. how to use certifi). -- by :user:`Dreamsorcerer`

    `#&#8203;7334 <https://github.com/aio-libs/aiohttp/issues/7334>`\_

-   Fix, update, and improve client exceptions documentation.

    `#&#8203;7733 <https://github.com/aio-libs/aiohttp/issues/7733>`\_

## Deprecations and Removals

-   Added `shutdown_timeout` parameter to `BaseRunner`, while
    deprecating `shutdown_timeout` parameter from `BaseSite`. -- by :user:`Dreamsorcerer`

    `#&#8203;7718 <https://github.com/aio-libs/aiohttp/issues/7718>`\_

-   Dropped Python 3.6 support.

    `#&#8203;6378 <https://github.com/aio-libs/aiohttp/issues/6378>`\_

-   Dropped Python 3.7 support. -- by :user:`Dreamsorcerer`

    `#&#8203;7336 <https://github.com/aio-libs/aiohttp/issues/7336>`\_

-   Removed support for abandoned `tokio` event loop. -- by :user:`Dreamsorcerer`

    `#&#8203;7281 <https://github.com/aio-libs/aiohttp/issues/7281>`\_

## Misc

-   Made `print` argument in `run_app()` optional.

    `#&#8203;3690 <https://github.com/aio-libs/aiohttp/issues/3690>`\_

-   Improved performance of `ceil_timeout` in some cases.

    `#&#8203;6316 <https://github.com/aio-libs/aiohttp/issues/6316>`\_

-   Changed importing Gunicorn to happen on-demand, decreasing import time by ~53%. -- :user:`Dreamsorcerer`

    `#&#8203;6591 <https://github.com/aio-libs/aiohttp/issues/6591>`\_

-   Improved import time by replacing `http.server` with `http.HTTPStatus`.

    `#&#8203;6903 <https://github.com/aio-libs/aiohttp/issues/6903>`\_

-   Fixed annotation of `ssl` parameter to disallow `True`. -- by :user:`Dreamsorcerer`.

    `#&#8203;7335 <https://github.com/aio-libs/aiohttp/issues/7335>`\_

***

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #68
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2023-11-26 21:37:23 +02:00
Renovate 8d57f8e1c6 Update dependency uvloop to v0.19.0 (#53)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [uvloop](https://github.com/MagicStack/uvloop) | minor | `==0.18.0` -> `==0.19.0` |

---

### Release Notes

<details>
<summary>MagicStack/uvloop (uvloop)</summary>

### [`v0.19.0`](https://github.com/MagicStack/uvloop/releases/tag/v0.19.0)

[Compare Source](https://github.com/MagicStack/uvloop/compare/v0.18.0...v0.19.0)

# Changes

-   Drop support of Python 3.7 and update CI ([#&#8203;578](https://github.com/MagicStack/uvloop/issues/578))
    (by [@&#8203;fantix](https://github.com/fantix) in [`ee5ad26`](https://github.com/MagicStack/uvloop/commit/ee5ad26a) for [#&#8203;578](https://github.com/MagicStack/uvloop/issues/578))

# Fixes

-   Restore uvloop.new_event_loop and other missing uvloop members to typing ([#&#8203;573](https://github.com/MagicStack/uvloop/issues/573))
    (by [@&#8203;graingert](https://github.com/graingert) in [`5c500ee`](https://github.com/MagicStack/uvloop/commit/5c500ee2) for [#&#8203;573](https://github.com/MagicStack/uvloop/issues/573))

-   Fix docstring of loop.shutdown_default_executor ([#&#8203;535](https://github.com/MagicStack/uvloop/issues/535))
    (by [@&#8203;Gelbpunkt](https://github.com/Gelbpunkt) in [`919da56`](https://github.com/MagicStack/uvloop/commit/919da567) for [#&#8203;535](https://github.com/MagicStack/uvloop/issues/535))

-   Fix CI status badge ([#&#8203;522](https://github.com/MagicStack/uvloop/issues/522))
    (by [@&#8203;shuuji3](https://github.com/shuuji3) in [`0e9ff6c`](https://github.com/MagicStack/uvloop/commit/0e9ff6cd) for [#&#8203;522](https://github.com/MagicStack/uvloop/issues/522))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #53
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2023-10-29 19:33:07 +02:00
Profitroll 894840ef95 Constant change due to #29 2023-10-16 05:50:32 +00:00
Profitroll a0616ff285
Improved naming 2023-10-15 18:14:22 +02:00
Profitroll c4d31c955f
Fixed context handler 2023-10-15 17:56:20 +02:00
Profitroll 6bd1234d3d
This commit closes #45 2023-10-15 17:40:56 +02:00
Renovate 154db69f20 Update dependency pillow to ~=10.1.0 (#48)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [pillow](https://python-pillow.org) ([source](https://github.com/python-pillow/Pillow), [changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)) | minor | `~=10.0.0` -> `~=10.1.0` |

---

### Release Notes

<details>
<summary>python-pillow/Pillow (pillow)</summary>

### [`v10.1.0`](https://github.com/python-pillow/Pillow/blob/HEAD/CHANGES.rst#1010-2023-10-15)

[Compare Source](https://github.com/python-pillow/Pillow/compare/10.0.1...10.1.0)

-   Added TrueType default font to allow for different sizes [#&#8203;7354](https://github.com/python-pillow/Pillow/issues/7354)
    \[radarhere]

-   Fixed invalid argument warning [#&#8203;7442](https://github.com/python-pillow/Pillow/issues/7442)
    \[radarhere]

-   Added ImageOps cover method [#&#8203;7412](https://github.com/python-pillow/Pillow/issues/7412)
    \[radarhere, hugovk]

-   Catch struct.error from truncated EXIF when reading JPEG DPI [#&#8203;7458](https://github.com/python-pillow/Pillow/issues/7458)
    \[radarhere]

-   Consider default image when selecting mode for PNG save_all [#&#8203;7437](https://github.com/python-pillow/Pillow/issues/7437)
    \[radarhere]

-   Support BGR;15, BGR;16 and BGR;24 access, unpacking and putdata [#&#8203;7303](https://github.com/python-pillow/Pillow/issues/7303)
    \[radarhere]

-   Added CMYK to RGB unpacker [#&#8203;7310](https://github.com/python-pillow/Pillow/issues/7310)
    \[radarhere]

-   Improved flexibility of XMP parsing [#&#8203;7274](https://github.com/python-pillow/Pillow/issues/7274)
    \[radarhere]

-   Support reading 8-bit YCbCr TIFF images [#&#8203;7415](https://github.com/python-pillow/Pillow/issues/7415)
    \[radarhere]

-   Allow saving I;16B images as PNG [#&#8203;7302](https://github.com/python-pillow/Pillow/issues/7302)
    \[radarhere]

-   Corrected drawing I;16 points and writing I;16 text [#&#8203;7257](https://github.com/python-pillow/Pillow/issues/7257)
    \[radarhere]

-   Set blue channel to 128 for BC5S [#&#8203;7413](https://github.com/python-pillow/Pillow/issues/7413)
    \[radarhere]

-   Increase flexibility when reading IPTC fields [#&#8203;7319](https://github.com/python-pillow/Pillow/issues/7319)
    \[radarhere]

-   Set C palette to be empty by default [#&#8203;7289](https://github.com/python-pillow/Pillow/issues/7289)
    \[radarhere]

-   Added gs_binary to control Ghostscript use on all platforms [#&#8203;7392](https://github.com/python-pillow/Pillow/issues/7392)
    \[radarhere]

-   Read bounding box information from the trailer of EPS files if specified [#&#8203;7382](https://github.com/python-pillow/Pillow/issues/7382)
    \[nopperl, radarhere]

-   Added reading 8-bit color DDS images [#&#8203;7426](https://github.com/python-pillow/Pillow/issues/7426)
    \[radarhere]

-   Added has_transparency_data [#&#8203;7420](https://github.com/python-pillow/Pillow/issues/7420)
    \[radarhere, hugovk]

-   Fixed bug when reading BC5S DDS images [#&#8203;7401](https://github.com/python-pillow/Pillow/issues/7401)
    \[radarhere]

-   Prevent TIFF orientation from being applied more than once [#&#8203;7383](https://github.com/python-pillow/Pillow/issues/7383)
    \[radarhere]

-   Use previous pixel alpha for QOI_OP_RGB [#&#8203;7357](https://github.com/python-pillow/Pillow/issues/7357)
    \[radarhere]

-   Added BC5U reading [#&#8203;7358](https://github.com/python-pillow/Pillow/issues/7358)
    \[radarhere]

-   Allow getpixel() to accept a list [#&#8203;7355](https://github.com/python-pillow/Pillow/issues/7355)
    \[radarhere, homm]

-   Allow GaussianBlur and BoxBlur to accept a sequence of x and y radii [#&#8203;7336](https://github.com/python-pillow/Pillow/issues/7336)
    \[radarhere]

-   Expand JPEG buffer size when saving optimized or progressive [#&#8203;7345](https://github.com/python-pillow/Pillow/issues/7345)
    \[radarhere]

-   Added session type check for Linux in ImageGrab.grabclipboard() [#&#8203;7332](https://github.com/python-pillow/Pillow/issues/7332)
    \[TheNooB2706, radarhere, hugovk]

-   Allow "loop=None" when saving GIF images [#&#8203;7329](https://github.com/python-pillow/Pillow/issues/7329)
    \[radarhere]

-   Fixed transparency when saving P mode images to PDF [#&#8203;7323](https://github.com/python-pillow/Pillow/issues/7323)
    \[radarhere]

-   Added saving LA images as PDFs [#&#8203;7299](https://github.com/python-pillow/Pillow/issues/7299)
    \[radarhere]

-   Set SMaskInData to 1 for PDFs with alpha [#&#8203;7316](https://github.com/python-pillow/Pillow/issues/7316), [#&#8203;7317](https://github.com/python-pillow/Pillow/issues/7317)
    \[radarhere]

-   Changed Image mode property to be read-only by default [#&#8203;7307](https://github.com/python-pillow/Pillow/issues/7307)
    \[radarhere]

-   Silence exceptions in *repr_jpeg* and *repr_png* [#&#8203;7266](https://github.com/python-pillow/Pillow/issues/7266)
    \[mtreinish, radarhere]

-   Do not use transparency when saving GIF if it has been removed when normalizing mode [#&#8203;7284](https://github.com/python-pillow/Pillow/issues/7284)
    \[radarhere]

-   Fix missing symbols when libtiff depends on libjpeg [#&#8203;7270](https://github.com/python-pillow/Pillow/issues/7270)
    \[heitbaum]

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #48
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2023-10-15 17:47:05 +03:00
Renovate e719da7750 Update dependency uvloop to v0.18.0 (#46)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [uvloop](https://github.com/MagicStack/uvloop) | minor | `==0.17.0` -> `==0.18.0` |

---

### Release Notes

<details>
<summary>MagicStack/uvloop (uvloop)</summary>

### [`v0.18.0`](https://github.com/MagicStack/uvloop/releases/tag/v0.18.0)

[Compare Source](https://github.com/MagicStack/uvloop/compare/v0.17.0...v0.18.0)

# Fixes

-   CI fixes ([#&#8203;520](https://github.com/MagicStack/uvloop/issues/520), [#&#8203;553](https://github.com/MagicStack/uvloop/issues/553))
    (by [@&#8203;altendky](https://github.com/altendky) in [`7783f1c`](https://github.com/MagicStack/uvloop/commit/7783f1c5), [@&#8203;dulmandakh](https://github.com/dulmandakh) in [`1dd40f1`](https://github.com/MagicStack/uvloop/commit/1dd40f17))

-   Make extract_stack resilient to lacking frames. ([#&#8203;563](https://github.com/MagicStack/uvloop/issues/563))
    (by [@&#8203;jhance](https://github.com/jhance) in [`0687643`](https://github.com/MagicStack/uvloop/commit/06876434) for [#&#8203;563](https://github.com/MagicStack/uvloop/issues/563))

-   Port uvloop to Python 3.12 ([#&#8203;570](https://github.com/MagicStack/uvloop/issues/570))
    (by [@&#8203;1st1](https://github.com/1st1), [@&#8203;fantix](https://github.com/fantix) in [`9f82bd7`](https://github.com/MagicStack/uvloop/commit/9f82bd74) for [#&#8203;569](https://github.com/MagicStack/uvloop/issues/569))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #46
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2023-10-15 17:46:55 +03:00
Profitroll 1d88076285
exp is now exc 2023-08-16 13:27:23 +02:00
Profitroll 5e8506cc12
Attempt to work around #40 2023-08-16 13:20:25 +02:00
Profitroll 235fa37252
Small config reading fix 2023-08-14 15:20:48 +02:00
Profitroll 176f5d35c3
Dependencies cleanup 2023-08-14 14:58:11 +02:00
Profitroll cd26990b7e
Migrate to async_pymongo 2023-08-14 14:52:02 +02:00
Renovate 5b56919b80 Update dependency libbot to v2.0.1 (#39)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| libbot | patch | `==2.0.0` -> `==2.0.1` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4zNS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMzUuMCIsInRhcmdldEJyYW5jaCI6ImRldiJ9-->

Reviewed-on: #39
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2023-08-11 11:31:19 +03:00
Renovate 0e9bed1277 Update dependency libbot to v2 (#38)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| libbot | major | `==0.2.2` -> `==2.0.0` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS41NC4wIiwidXBkYXRlZEluVmVyIjoiMzUuNTQuMCJ9-->

Reviewed-on: #38
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Co-committed-by: Renovate <renovate@git.end-play.xyz>
2023-08-07 13:07:58 +03:00
Profitroll fb37da4195
Bump libbot to 0.2.2 2023-08-06 22:20:27 +02:00
Renovate 065f704923 Update dependency libbot to v1.9 (#35)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| libbot | minor | `==1.8` -> `==1.9` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS41NC4wIiwidXBkYXRlZEluVmVyIjoiMzUuNTQuMCJ9-->

Co-authored-by: Renovate <renovate@git.end-play.xyz>
Reviewed-on: #35
Co-authored-by: Renovate <renovate@noreply.localhost>
Co-committed-by: Renovate <renovate@noreply.localhost>
2023-07-26 15:28:42 +03:00
Renovate a45f6b620f Update dependency black to ~=23.7.0 (#34)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [black](https://github.com/psf/black) ([changelog](https://github.com/psf/black/blob/main/CHANGES.md)) | minor | `~=23.3.0` -> `~=23.7.0` |

---

### Release Notes

<details>
<summary>psf/black</summary>

### [`v23.7.0`](https://github.com/psf/black/blob/HEAD/CHANGES.md#&#8203;2370)

[Compare Source](https://github.com/psf/black/compare/23.3.0...23.7.0)

##### Highlights

-   Runtime support for Python 3.7 has been removed. Formatting 3.7 code will still be
    supported until further notice ([#&#8203;3765](https://github.com/psf/black/issues/3765))

##### Stable style

-   Fix a bug where an illegal trailing comma was added to return type annotations using
    PEP 604 unions ([#&#8203;3735](https://github.com/psf/black/issues/3735))
-   Fix several bugs and crashes where comments in stub files were removed or mishandled
    under some circumstances ([#&#8203;3745](https://github.com/psf/black/issues/3745))
-   Fix a crash with multi-line magic comments like `type: ignore` within parentheses
    ([#&#8203;3740](https://github.com/psf/black/issues/3740))
-   Fix error in AST validation when *Black* removes trailing whitespace in a type comment
    ([#&#8203;3773](https://github.com/psf/black/issues/3773))

##### Preview style

-   Implicitly concatenated strings used as function args are no longer wrapped inside
    parentheses ([#&#8203;3640](https://github.com/psf/black/issues/3640))
-   Remove blank lines between a class definition and its docstring ([#&#8203;3692](https://github.com/psf/black/issues/3692))

##### Configuration

-   The `--workers` argument to *Black* can now be specified via the `BLACK_NUM_WORKERS`
    environment variable ([#&#8203;3743](https://github.com/psf/black/issues/3743))
-   `.pytest_cache`, `.ruff_cache` and `.vscode` are now excluded by default ([#&#8203;3691](https://github.com/psf/black/issues/3691))
-   Fix *Black* not honouring `pyproject.toml` settings when running `--stdin-filename`
    and the `pyproject.toml` found isn't in the current working directory ([#&#8203;3719](https://github.com/psf/black/issues/3719))
-   *Black* will now error if `exclude` and `extend-exclude` have invalid data types in
    `pyproject.toml`, instead of silently doing the wrong thing ([#&#8203;3764](https://github.com/psf/black/issues/3764))

##### Packaging

-   Upgrade mypyc from 0.991 to 1.3 ([#&#8203;3697](https://github.com/psf/black/issues/3697))
-   Remove patching of Click that mitigated errors on Python 3.6 with `LANG=C` ([#&#8203;3768](https://github.com/psf/black/issues/3768))

##### Parser

-   Add support for the new PEP 695 syntax in Python 3.12 ([#&#8203;3703](https://github.com/psf/black/issues/3703))

##### Performance

-   Speed up *Black* significantly when the cache is full ([#&#8203;3751](https://github.com/psf/black/issues/3751))
-   Avoid importing `IPython` in a case where we wouldn't need it ([#&#8203;3748](https://github.com/psf/black/issues/3748))

##### Output

-   Use aware UTC datetimes internally, avoids deprecation warning on Python 3.12 ([#&#8203;3728](https://github.com/psf/black/issues/3728))
-   Change verbose logging to exactly mirror *Black*'s logic for source discovery ([#&#8203;3749](https://github.com/psf/black/issues/3749))

##### *Blackd*

-   The `blackd` argument parser now shows the default values for options in their help
    text ([#&#8203;3712](https://github.com/psf/black/issues/3712))

##### Integrations

-   Black is now tested with
    [`PYTHONWARNDEFAULTENCODING = 1`](https://docs.python.org/3/library/io.html#io-encoding-warning)
    ([#&#8203;3763](https://github.com/psf/black/issues/3763))
-   Update GitHub Action to display black output in the job summary ([#&#8203;3688](https://github.com/psf/black/issues/3688))

##### Documentation

-   Add a CITATION.cff file to the root of the repository, containing metadata on how to
    cite this software ([#&#8203;3723](https://github.com/psf/black/issues/3723))
-   Update the *classes* and *exceptions* documentation in Developer reference to match
    the latest code base ([#&#8203;3755](https://github.com/psf/black/issues/3755))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS41NC4wIiwidXBkYXRlZEluVmVyIjoiMzUuNTQuMCJ9-->

Co-authored-by: Renovate <renovate@git.end-play.xyz>
Reviewed-on: #34
Co-authored-by: Renovate <renovate@noreply.localhost>
Co-committed-by: Renovate <renovate@noreply.localhost>
2023-07-11 11:20:23 +03:00
Profitroll fe8b562a7e master (#33)
Reviewed-on: #33
2023-07-06 17:35:12 +03:00
Profitroll 63164d2169 Merge branch 'master' into dev 2023-07-06 15:21:15 +03:00
Profitroll be288776d9
max_concurrent_transmissions reduced to 1 2023-07-06 14:19:56 +02:00
Profitroll 0c73c51936
unauthorized_client will be created when needed 2023-07-03 14:42:55 +02:00
19 changed files with 347 additions and 302 deletions

4
.gitignore vendored
View File

@ -153,8 +153,12 @@ cython_debug/
#.idea/
# Custom
cache/
config.json
*.session
*.session-wal
*.session-shm
*.session-journal
venv

View File

@ -50,7 +50,7 @@ class PyroClient(PyroClient):
def __init__(self, scheduler: AsyncIOScheduler):
super().__init__(locales_root=Path("locale"), scheduler=scheduler)
self.version: float = 0.2
self.version: float = 0.3
self.owner: int = self.config["bot"]["owner"]
self.admins: List[int] = self.config["bot"]["admins"] + [
@ -104,8 +104,8 @@ class PyroClient(PyroClient):
logger.warning(
"Could not send startup message to bot owner. Perhaps user has not started the bot yet."
)
except Exception as exp:
logger.exception("Update check failed due to %s: %s", exp, format_exc())
except Exception as exc:
logger.exception("Update check failed due to %s: %s", exc, format_exc())
if self.config["mode"]["post"]:
if self.config["posting"]["use_interval"]:
@ -139,9 +139,9 @@ class PyroClient(PyroClient):
await super().stop()
async def submit_media(
self, id: str
self, id: str, purge_caption: bool = False
) -> Tuple[Union[Message, None], Union[str, None]]:
db_entry = col_submitted.find_one({"_id": ObjectId(id)})
db_entry = await col_submitted.find_one({"_id": ObjectId(id)})
submission = None
if db_entry is None:
@ -155,8 +155,8 @@ class PyroClient(PyroClient):
filepath = await self.download_media(
submission, file_name=self.config["locations"]["tmp"] + sep
)
except Exception as exp:
raise SubmissionUnavailableError() from exp
except Exception as exc:
raise SubmissionUnavailableError() from exc
elif not Path(
f"{self.config['locations']['data']}/submissions/{db_entry['temp']['uuid']}/{db_entry['temp']['file']}",
@ -179,7 +179,7 @@ class PyroClient(PyroClient):
response = await photo_upload(
self.config["posting"]["api"]["album"],
client=client,
multipart_data=BodyPhotoUpload(
body=BodyPhotoUpload(
File(media_bytes, filepath.name, "image/jpeg")
),
ignore_duplicates=self.config["submission"]["allow_duplicates"],
@ -190,22 +190,20 @@ class PyroClient(PyroClient):
response = await video_upload(
self.config["posting"]["api"]["album"],
client=client,
multipart_data=BodyVideoUpload(
File(media_bytes, filepath.name, "video/*")
),
body=BodyVideoUpload(File(media_bytes, filepath.name, "video/*")),
caption="queue",
)
# elif db_entry["type"] == SubmissionType.ANIMATION.value:
# response = await video_upload(
# self.config["posting"]["api"]["album"],
# client=client,
# multipart_data=BodyVideoUpload(
# body=BodyVideoUpload(
# File(media_bytes, filepath.name, "video/*")
# ),
# caption="queue",
# )
except UnexpectedStatus as exp:
raise SubmissionUnsupportedError(str(filepath)) from exp
except UnexpectedStatus as exc:
raise SubmissionUnsupportedError(str(filepath)) from exc
response_dict = (
{}
@ -226,10 +224,14 @@ class PyroClient(PyroClient):
)
raise SubmissionDuplicatesError(str(filepath), duplicates)
col_submitted.find_one_and_update(
{"_id": ObjectId(id)}, {"$set": {"done": True}}
db_update = (
{"$set": {"done": True, "caption": None}}
if purge_caption
else {"$set": {"done": True}}
)
await col_submitted.update_one({"_id": ObjectId(id)}, db_update)
try:
if db_entry["temp"]["uuid"] is not None:
rmtree(
@ -258,12 +260,12 @@ class PyroClient(PyroClient):
* `PyroUser`: PyroUser object
"""
if (
col_users.find_one(
await col_users.find_one(
{"id": user.id if isinstance(user, User) else user}
) # type: ignore
is None
):
col_users.insert_one(
await col_users.insert_one(
{
"id": user.id if isinstance(user, User) else user,
"locale": user.language_code if isinstance(user, User) else None,
@ -273,7 +275,7 @@ class PyroClient(PyroClient):
}
) # type: ignore
db_record = col_users.find_one(
db_record = await col_users.find_one(
{"id": user.id if isinstance(user, User) else user}
) # type: ignore

View File

@ -20,19 +20,19 @@ class PyroUser:
cooldown: datetime
subscription: dict
async def update_locale(self, locale: str):
col_users.update_one({"_id": self._id}, {"$set": {"locale": locale}})
async def update_locale(self, locale: str) -> None:
await col_users.update_one({"_id": self._id}, {"$set": {"locale": locale}})
async def update_cooldown(self, time: datetime = datetime.now()):
col_users.update_one({"_id": self._id}, {"$set": {"cooldown": time}})
async def update_cooldown(self, time: datetime = datetime.now()) -> None:
await col_users.update_one({"_id": self._id}, {"$set": {"cooldown": time}})
async def block(self) -> None:
"""Ban user from using command and submitting content."""
col_users.update_one({"_id": self._id}, {"$set": {"banned": True}})
await col_users.update_one({"_id": self._id}, {"$set": {"banned": True}})
async def unblock(self) -> None:
"""Allow user to use command and submit posts again."""
col_users.update_one({"_id": self._id}, {"$set": {"banned": False}})
await col_users.update_one({"_id": self._id}, {"$set": {"banned": False}})
async def is_limited(self, app: Union[PyroClient, None] = None) -> bool:
"""Check if user is on a cooldown after submitting something.
@ -41,11 +41,9 @@ class PyroUser:
`bool`: Must be `True` if on the cooldown and `False` if not
"""
admins = (
app.admins
if app is not None
else (
await config_get("admins", "bot") + [await config_get("owner", "bot")]
)
await config_get("admins", "bot") + [await config_get("owner", "bot")]
if app is None
else app.admins
)
return (datetime.now() - self.cooldown).total_seconds() < (

View File

@ -6,7 +6,7 @@
"api_id": 0,
"api_hash": "",
"bot_token": "",
"max_concurrent_transmissions": 3,
"max_concurrent_transmissions": 1,
"scoped_commands": true
},
"database": {
@ -83,7 +83,8 @@
"address_external": "https://photos.domain.com",
"username": "",
"password": "",
"album": ""
"album": "",
"timeout": 15.0
}
},
"caption": {

View File

@ -117,16 +117,14 @@ async def authorize(custom_session: Union[ClientSession, None] = None) -> str:
unauthorized_client = Client(
base_url=sync.config_get("address", "posting", "api"),
timeout=5.0,
verify_ssl=True,
sync.config_get("address", "posting", "api"),
raise_on_unexpected_status=True,
follow_redirects=False,
timeout=sync.config_get("timeout", "posting", "api"),
)
login_token = login(
client=unauthorized_client,
form_data=BodyLoginForAccessTokenTokenPost(
body=BodyLoginForAccessTokenTokenPost(
grant_type="password",
scope="me albums.list albums.read albums.write photos.list photos.read photos.write videos.list videos.read videos.write",
username=sync.config_get("username", "posting", "api"),
@ -141,12 +139,10 @@ if not isinstance(login_token, Token):
exit()
client = AuthenticatedClient(
base_url=sync.config_get("address", "posting", "api"),
timeout=5.0,
verify_ssl=True,
raise_on_unexpected_status=True,
sync.config_get("address", "posting", "api"),
token=login_token.access_token,
follow_redirects=False,
raise_on_unexpected_status=True,
timeout=sync.config_get("timeout", "posting", "api"),
)
if __name__ == "__main__":

View File

@ -27,13 +27,14 @@ parser.add_argument("--create-album", action="store_true")
args = parser.parse_args()
unauthorized_client = Client(
base_url=sync.config_get("address", "posting", "api"),
timeout=5.0,
verify_ssl=True,
raise_on_unexpected_status=True,
follow_redirects=False,
)
if args.create_user or args.create_album:
unauthorized_client = Client(
base_url=sync.config_get("address", "posting", "api"),
timeout=5.0,
verify_ssl=True,
raise_on_unexpected_status=True,
follow_redirects=False,
)
async def cli_create_user() -> None:
@ -57,8 +58,8 @@ async def cli_create_user() -> None:
none = input(
"Alright. If you have email confirmation enabled - please confirm registration by using the link in your email. After that press Enter. Otherwise just press Enter."
)
except Exception as exp:
print(f"Could not create a user due to {exp}", flush=True)
except Exception as exc:
print(f"Could not create a user due to {exc}", flush=True)
print_exc()
exit()
if not args.create_album:
@ -96,8 +97,8 @@ async def cli_create_album() -> None:
result_2 = await album_create(client=client, name=name, title=title)
# asyncio.run(create_album(name, title))
await config_set("album", name, "posting", "api")
except Exception as exp:
print(f"Could not create an album due to {exp}", flush=True)
except Exception as exc:
print(f"Could not create an album due to {exc}", flush=True)
print_exc()
exit()
print("You're done!", flush=True)

18
modules/custom_filters.py Normal file
View File

@ -0,0 +1,18 @@
"""Custom message filters"""
from pyrogram import filters
from pyrogram.types import Message
from classes.pyroclient import PyroClient
async def _mode_post_func(_, __: PyroClient, message: Message):
return __.config["mode"]["post"]
async def _mode_submit_func(_, __: PyroClient, message: Message):
return __.config["mode"]["submit"]
mode_post = filters.create(_mode_post_func)
mode_submit = filters.create(_mode_submit_func)

View File

@ -1,11 +1,9 @@
"""Module that provides all database columns"""
from pymongo import MongoClient
from ujson import loads
from async_pymongo import AsyncClient
from libbot import sync
with open("config.json", "r", encoding="utf-8") as f:
db_config = loads(f.read())["database"]
f.close()
db_config = sync.config_get("database")
if db_config["user"] is not None and db_config["password"] is not None:
con_string = "mongodb://{0}:{1}@{2}:{3}/{4}".format(
@ -20,15 +18,9 @@ else:
db_config["host"], db_config["port"], db_config["name"]
)
db_client = MongoClient(con_string)
db_client = AsyncClient(con_string)
db = db_client.get_database(name=db_config["name"])
collections = db.list_collection_names()
for collection in ["sent", "users", "submitted"]:
if collection not in collections:
db.create_collection(collection)
col_sent = db.get_collection("sent")
col_users = db.get_collection("users")
col_submitted = db.get_collection("submitted")

View File

@ -77,12 +77,12 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
try:
response: File = await func_iter[1](id=media.id, client=client)
except Exception as exp:
except Exception as exc:
print_exc()
logger.error("Media is invalid: %s", exp)
logger.error("Media is invalid: %s", exc)
if app.config["reports"]["error"]:
await app.send_message(
app.owner, f"Media is invalid: {exp}"
app.owner, f"Media is invalid: {exc}"
)
return
@ -103,11 +103,11 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
).results[0]
try:
response: File = await func[1](id=media.id, client=client)
except Exception as exp:
except Exception as exc:
print_exc()
logger.error("Media is invalid: %s", exp)
logger.error("Media is invalid: %s", exc)
if app.config["reports"]["error"]:
await app.send_message(app.owner, f"Media is invalid: {exp}")
await app.send_message(app.owner, f"Media is invalid: {exc}")
return
except (KeyError, AttributeError, TypeError, IndexError):
@ -152,7 +152,7 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
) and func[0] is photo_random:
image = Image.open(path.join(app.config["locations"]["tmp"], tmp_path))
width, height = image.size
image = image.resize((int(width / 2), int(height / 2)), Image.ANTIALIAS)
image = image.resize((int(width / 2), int(height / 2)), Image.LANCZOS)
if tmp_path.lower().endswith(".jpeg") or tmp_path.lower().endswith(".jpg"):
image.save(
path.join(app.config["locations"]["tmp"], tmp_path),
@ -179,7 +179,7 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
del response
submitted = col_submitted.find_one({"temp.file": media.filename})
submitted = await col_submitted.find_one({"temp.file": media.filename})
if submitted is not None and submitted["caption"] is not None:
caption = submitted["caption"].strip()
@ -217,19 +217,19 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
caption=caption,
disable_notification=app.config["posting"]["silent"],
)
except Exception as exp:
except Exception as exc:
logger.error(
"Could not send media %s (%s) due to %s", media.filename, media.id, exp
"Could not send media %s (%s) due to %s", media.filename, media.id, exc
)
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("post_exception", "message").format(exp, format_exc()),
app._("post_exception", "message").format(exc, format_exc()),
)
# rmtree(path.join(app.config['locations']['tmp'], tmp_dir), ignore_errors=True)
return
col_sent.insert_one(
await col_sent.insert_one(
{
"date": datetime.now(),
"image": media.id,
@ -253,14 +253,14 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
str(app.config["posting"]["silent"]),
)
except Exception as exp:
except Exception as exc:
logger.error(
"Could not send content due to %s. Traceback: %s", exp, format_exc()
"Could not send content due to %s. Traceback: %s", exc, format_exc()
)
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("post_exception", "message").format(exp, format_exc()),
app._("post_exception", "message").format(exc, format_exc()),
)
try:
rmtree(

View File

@ -6,7 +6,7 @@ from classes.pyroclient import PyroClient
@Client.on_callback_query(filters.regex("nothing"))
async def callback_query_nothing(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
async def callback_query_nothing(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
await clb.answer(text=app._("nothing", "callback", locale=user.locale))
await callback.answer(text=app._("nothing", "callback", locale=user.locale))

View File

@ -10,11 +10,11 @@ from classes.pyroclient import PyroClient
@Client.on_callback_query(filters.regex("shutdown"))
async def callback_query_nothing(app: PyroClient, clb: CallbackQuery):
if clb.from_user.id not in app.admins:
async def callback_query_nothing(app: PyroClient, callback: CallbackQuery):
if callback.from_user.id not in app.admins:
return
await clb.answer()
await callback.answer()
makedirs(await config_get("cache", "locations"), exist_ok=True)
await json_write(

View File

@ -21,43 +21,46 @@ logger = logging.getLogger(__name__)
@Client.on_callback_query(filters.regex("sub_yes_[\s\S]*"))
async def callback_query_yes(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
fullclb = str(clb.data).split("_")
async def callback_query_yes(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
fullcallback = str(callback.data).split("_")
db_entry = col_submitted.find_one({"_id": ObjectId(fullclb[2])})
db_entry = await col_submitted.find_one({"_id": ObjectId(fullcallback[2])})
try:
submission = await app.submit_media(fullclb[2])
submission = await app.submit_media(
fullcallback[2],
purge_caption=("caption" not in fullcallback),
)
except SubmissionUnavailableError:
await clb.answer(
await callback.answer(
text=app._("sub_msg_unavail", "callback", locale=user.locale),
show_alert=True,
)
return
except SubmissionUnsupportedError:
await clb.answer(
await callback.answer(
text=app._("mime_not_allowed", "message", locale=user.locale).format(
", ".join(app.config["submission"]["mime_types"]), quote=True
),
show_alert=True,
)
return
except SubmissionDuplicatesError as exp:
await clb.answer(
except SubmissionDuplicatesError as exc:
await callback.answer(
text=app._("sub_duplicates_found", "callback", locale=user.locale),
show_alert=True,
)
await clb.message.reply_text(
await callback.message.reply_text(
app._("sub_media_duplicates_list", "message", locale=user.locale).format(
"\n".join(exp.duplicates)
"\n".join(exc.duplicates)
),
quote=True,
)
logger.info(
"Submission with ID '%s' could not be accepted because of the duplicates: %s",
fullclb[2],
str(exp.duplicates),
fullcallback[2],
str(exc.duplicates),
)
return
@ -80,8 +83,8 @@ async def callback_query_yes(app: PyroClient, clb: CallbackQuery):
),
)
await clb.answer(
text=app._("sub_yes", "callback", locale=user.locale).format(fullclb[2]),
await callback.answer(
text=app._("sub_yes", "callback", locale=user.locale).format(fullcallback[2]),
show_alert=True,
)
@ -93,9 +96,9 @@ async def callback_query_yes(app: PyroClient, clb: CallbackQuery):
callback_data="nothing",
)
],
clb.message.reply_markup.inline_keyboard[1],
callback.message.reply_markup.inline_keyboard[1],
]
if len(clb.message.reply_markup.inline_keyboard) > 1
if len(callback.message.reply_markup.inline_keyboard) > 1
else [
[
InlineKeyboardButton(
@ -107,27 +110,32 @@ async def callback_query_yes(app: PyroClient, clb: CallbackQuery):
)
if await config_get("send_uploaded_id", "submission"):
await clb.message.edit_caption(
f"{clb.message.caption}\n\nID: `{submission[1]}`"
await callback.message.edit_caption(
f"{callback.message.caption}\n\nID: `{submission[1]}`"
)
await clb.message.edit_reply_markup(
await callback.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
logger.info(
"Submission with ID '%s' accepted and uploaded with ID '%s'",
fullclb[2],
fullcallback[2],
submission[1],
)
logger.info(
"Submission with ID '%s' accepted and uploaded with ID '%s'",
fullcallback[2],
submission[1],
)
@Client.on_callback_query(filters.regex("sub_no_[\s\S]*"))
async def callback_query_no(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
fullclb = str(clb.data).split("_")
async def callback_query_no(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
fullcallback = str(callback.data).split("_")
db_entry = col_submitted.find_one_and_delete({"_id": ObjectId(fullclb[2])})
db_entry = await col_submitted.delete_one({"_id": ObjectId(fullcallback[2])})
if (
db_entry["temp"]["uuid"] is not None
@ -146,8 +154,8 @@ async def callback_query_no(app: PyroClient, clb: CallbackQuery):
submission = await app.get_messages(
db_entry["user"], db_entry["telegram"]["msg_id"]
)
except Exception as exp:
await clb.answer(
except Exception as exc:
await callback.answer(
text=app._("sub_msg_unavail", "message", locale=user.locale),
show_alert=True,
)
@ -161,8 +169,8 @@ async def callback_query_no(app: PyroClient, clb: CallbackQuery):
),
quote=True,
)
await clb.answer(
text=app._("sub_no", "callback", locale=user.locale).format(fullclb[2]),
await callback.answer(
text=app._("sub_no", "callback", locale=user.locale).format(fullcallback[2]),
show_alert=True,
)
@ -174,9 +182,9 @@ async def callback_query_no(app: PyroClient, clb: CallbackQuery):
callback_data="nothing",
)
],
clb.message.reply_markup.inline_keyboard[1],
callback.message.reply_markup.inline_keyboard[1],
]
if len(clb.message.reply_markup.inline_keyboard) > 1
if len(callback.message.reply_markup.inline_keyboard) > 1
else [
[
InlineKeyboardButton(
@ -186,81 +194,83 @@ async def callback_query_no(app: PyroClient, clb: CallbackQuery):
]
]
)
await clb.message.edit_reply_markup(
await callback.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
logger.info(
"Submission with ID '%s' rejected",
fullclb[2],
fullcallback[2],
)
@Client.on_callback_query(filters.regex("sub_block_[\s\S]*"))
async def callback_query_block(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
fullclb = str(clb.data).split("_")
async def callback_query_block(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
fullcallback = str(callback.data).split("_")
await app.send_message(
int(fullclb[2]),
int(fullcallback[2]),
app._(
"sub_blocked",
"message",
locale=(await app.find_user(int(fullclb[2]))).locale,
locale=(await app.find_user(int(fullcallback[2]))).locale,
),
)
await user.block()
await clb.answer(
text=app._("sub_block", "callback", locale=user.locale).format(fullclb[2]),
await callback.answer(
text=app._("sub_block", "callback", locale=user.locale).format(fullcallback[2]),
show_alert=True,
)
edited_markup = [
clb.message.reply_markup.inline_keyboard[0],
callback.message.reply_markup.inline_keyboard[0],
[
InlineKeyboardButton(
text=str(app._("sub_unblock", "button", locale=user.locale)),
callback_data=f"sub_unblock_{fullclb[2]}",
callback_data=f"sub_unblock_{fullcallback[2]}",
)
],
]
await clb.message.edit_reply_markup(
await callback.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
logger.info("User %s has been blocked", fullclb[2])
logger.info("User %s has been blocked", fullcallback[2])
@Client.on_callback_query(filters.regex("sub_unblock_[\s\S]*"))
async def callback_query_unblock(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
fullclb = str(clb.data).split("_")
async def callback_query_unblock(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
fullcallback = str(callback.data).split("_")
await app.send_message(
int(fullclb[2]),
int(fullcallback[2]),
app._(
"sub_unblocked",
"message",
locale=(await app.find_user(int(fullclb[2]))).locale,
locale=(await app.find_user(int(fullcallback[2]))).locale,
),
)
await user.unblock()
await clb.answer(
text=app._("sub_unblock", "callback", locale=user.locale).format(fullclb[2]),
await callback.answer(
text=app._("sub_unblock", "callback", locale=user.locale).format(
fullcallback[2]
),
show_alert=True,
)
edited_markup = [
clb.message.reply_markup.inline_keyboard[0],
callback.message.reply_markup.inline_keyboard[0],
[
InlineKeyboardButton(
text=str(app._("sub_block", "button", locale=user.locale)),
callback_data=f"sub_block_{fullclb[2]}",
callback_data=f"sub_block_{fullcallback[2]}",
)
],
]
await clb.message.edit_reply_markup(
await callback.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
logger.info("User %s has been unblocked", fullclb[2])
logger.info("User %s has been unblocked", fullcallback[2])

View File

@ -15,14 +15,14 @@ from modules.utils import USERS_WITH_CONTEXT
@Client.on_message(
~filters.scheduled & filters.command(["shutdown"], prefixes=["", "/"])
)
async def cmd_kill(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
async def cmd_kill(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
return
user = await app.find_user(msg.from_user)
user = await app.find_user(message.from_user)
if len(USERS_WITH_CONTEXT) > 0:
await msg.reply_text(
await message.reply_text(
app._("shutdown_confirm", "message", locale=user.locale).format(
len(USERS_WITH_CONTEXT)
),

View File

@ -3,25 +3,32 @@ from pyrogram.client import Client
from pyrogram.types import Message
from classes.pyroclient import PyroClient
@Client.on_message(~filters.scheduled & filters.command(["start"], prefixes="/"))
async def cmd_start(app: PyroClient, msg: Message):
user = await app.find_user(msg.from_user)
if user.banned:
return
await msg.reply_text(app._("start", "message", locale=user.locale))
from modules import custom_filters
@Client.on_message(
~filters.scheduled & filters.command(["rules", "help"], prefixes="/")
custom_filters.mode_submit
& ~filters.scheduled
& filters.command(["start"], prefixes="/")
)
async def cmd_rules(app: PyroClient, msg: Message):
user = await app.find_user(msg.from_user)
async def cmd_start(app: PyroClient, message: Message):
user = await app.find_user(message.from_user)
if user.banned:
return
await msg.reply_text(app._("rules", "message", locale=user.locale))
await message.reply_text(app._("start", "message", locale=user.locale))
@Client.on_message(
custom_filters.mode_submit
& ~filters.scheduled
& filters.command(["rules", "help"], prefixes="/")
)
async def cmd_rules(app: PyroClient, message: Message):
user = await app.find_user(message.from_user)
if user.banned:
return
await message.reply_text(app._("rules", "message", locale=user.locale))

View File

@ -37,27 +37,27 @@ logger = logging.getLogger(__name__)
@Client.on_message(~filters.scheduled & filters.command(["import"], prefixes=["", "/"]))
async def cmd_import(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
async def cmd_import(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
return
global USERS_WITH_CONTEXT
if msg.from_user.id not in USERS_WITH_CONTEXT:
USERS_WITH_CONTEXT.append(msg.from_user.id)
if message.from_user.id not in USERS_WITH_CONTEXT:
USERS_WITH_CONTEXT.append(message.from_user.id)
else:
return
user = await app.find_user(msg.from_user)
user = await app.find_user(message.from_user)
await msg.reply_text(app._("import_request", "message", locale=user.locale))
await message.reply_text(app._("import_request", "message", locale=user.locale))
answer = await listen_message(app, msg.chat.id, timeout=600)
answer = await listen_message(app, message.chat.id, timeout=600)
USERS_WITH_CONTEXT.remove(msg.from_user.id)
USERS_WITH_CONTEXT.remove(message.from_user.id)
if answer is None:
await msg.reply_text(
await message.reply_text(
app._("import_ignored", "message", locale=user.locale),
quote=True,
)
@ -86,7 +86,7 @@ async def cmd_import(app: PyroClient, msg: Message):
return
if disk_usage(getcwd())[2] < (answer.document.file_size) * 3:
await msg.reply_text(
await message.reply_text(
app._("import_too_big", "message", locale=user.locale).format(
answer.document.file_size // (2**30),
disk_usage(getcwd())[2] // (2**30),
@ -123,16 +123,16 @@ async def cmd_import(app: PyroClient, msg: Message):
for name in handle.namelist()
]
_ = await asyncio.gather(*tasks)
except Exception as exp:
except Exception as exc:
logger.error(
"Could not import '%s' due to %s: %s",
answer.document.file_name,
exp,
exc,
format_exc(),
)
await answer.reply_text(
app._("import_unpack_error", "message", locale=user.locale).format(
exp, format_exc()
exc, format_exc()
)
)
return
@ -158,21 +158,21 @@ async def cmd_import(app: PyroClient, msg: Message):
uploaded = await photo_upload(
app.config["posting"]["api"]["album"],
client=client,
multipart_data=BodyPhotoUpload(
body=BodyPhotoUpload(
File(photo_bytes, Path(filename).name, "image/jpeg")
),
ignore_duplicates=app.config["submission"]["allow_duplicates"],
compress=False,
caption="queue",
)
except UnexpectedStatus as exp:
except UnexpectedStatus as exc:
logger.error(
"Could not upload '%s' from '%s': %s",
filename,
Path(f"{app.config['locations']['tmp']}/{tmp_dir}"),
exp,
exc,
)
await msg.reply_text(
await message.reply_text(
app._(
"import_upload_error_other",
"message",
@ -193,7 +193,7 @@ async def cmd_import(app: PyroClient, msg: Message):
)
if len(uploaded_dict["duplicates"]) > 0:
await msg.reply_text(
await message.reply_text(
app._(
"import_upload_error_duplicate",
"message",
@ -202,7 +202,7 @@ async def cmd_import(app: PyroClient, msg: Message):
disable_notification=True,
)
else:
await msg.reply_text(
await message.reply_text(
app._(
"import_upload_error_other",
"message",
@ -235,33 +235,35 @@ async def cmd_import(app: PyroClient, msg: Message):
@Client.on_message(~filters.scheduled & filters.command(["export"], prefixes=["", "/"]))
async def cmd_export(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
async def cmd_export(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
return
@Client.on_message(~filters.scheduled & filters.command(["remove"], prefixes=["", "/"]))
async def cmd_remove(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
async def cmd_remove(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
return
global USERS_WITH_CONTEXT
if msg.from_user.id not in USERS_WITH_CONTEXT:
USERS_WITH_CONTEXT.append(msg.from_user.id)
if message.from_user.id not in USERS_WITH_CONTEXT:
USERS_WITH_CONTEXT.append(message.from_user.id)
else:
return
user = await app.find_user(msg.from_user)
user = await app.find_user(message.from_user)
await msg.reply_text(app._("remove_request", "message", locale=user.locale))
await message.reply_text(app._("remove_request", "message", locale=user.locale))
answer_id = await listen_message(app, msg.chat.id, timeout=600)
answer_id = await app.listen.Message(
filters.text & ~filters.me, id=filters.user(message.from_user.id), timeout=600
)
USERS_WITH_CONTEXT.remove(msg.from_user.id)
USERS_WITH_CONTEXT.remove(message.from_user.id)
if answer_id is None:
await msg.reply_text(
await message.reply_text(
app._("remove_ignored", "message", locale=user.locale),
quote=True,
)
@ -271,7 +273,7 @@ async def cmd_remove(app: PyroClient, msg: Message):
await answer_id.reply_text(app._("remove_abort", "message", locale=user.locale))
return
await msg.reply_text(
await message.reply_text(
app._("remove_kind", "message", locale=user.locale),
reply_markup=ReplyKeyboardMarkup(
[
@ -285,14 +287,16 @@ async def cmd_remove(app: PyroClient, msg: Message):
),
)
USERS_WITH_CONTEXT.append(msg.from_user.id)
USERS_WITH_CONTEXT.append(message.from_user.id)
answer_kind = await listen_message(app, msg.chat.id, timeout=600)
answer_kind = await app.listen.Message(
filters.text & ~filters.me, id=filters.user(message.from_user.id), timeout=600
)
USERS_WITH_CONTEXT.remove(msg.from_user.id)
USERS_WITH_CONTEXT.remove(message.from_user.id)
if answer_kind is None:
await msg.reply_text(
await message.reply_text(
app._("remove_ignored", "message", locale=user.locale),
quote=True,
reply_markup=ReplyKeyboardRemove(),
@ -351,6 +355,6 @@ async def cmd_remove(app: PyroClient, msg: Message):
@Client.on_message(~filters.scheduled & filters.command(["purge"], prefixes=["", "/"]))
async def cmd_purge(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
async def cmd_purge(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
return

View File

@ -4,32 +4,35 @@ from pyrogram.client import Client
from pyrogram.types import Message, User
from classes.pyroclient import PyroClient
from modules import custom_filters
@Client.on_message(
~filters.scheduled
custom_filters.mode_post
& ~filters.scheduled
& filters.chat(sync.config_get("comments", "posting"))
& filters.reply
& filters.command(["report"], prefixes=["", "/"])
)
async def command_report(app: PyroClient, msg: Message):
if msg.reply_to_message.forward_from_chat.id != app.config["posting"]["channel"]:
async def command_report(app: PyroClient, message: Message):
if (
message.reply_to_message.forward_from_chat.id
!= app.config["posting"]["channel"]
):
return
user = await app.find_user(msg.from_user)
user = await app.find_user(message.from_user)
await msg.reply_text(
await message.reply_text(
app._(
"report_sent",
"message",
locale=user.locale if msg.from_user is not None else None,
locale=user.locale if message.from_user is not None else None,
)
)
print(msg)
report_sent = await msg.reply_to_message.forward(app.owner)
sender = msg.from_user if msg.from_user is not None else msg.sender_chat
report_sent = await message.reply_to_message.forward(app.owner)
sender = message.from_user if message.from_user is not None else message.sender_chat
sender_name = sender.first_name if isinstance(sender, User) else sender.title

View File

@ -13,6 +13,7 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from classes.enums.submission_types import SubmissionType
from classes.exceptions import SubmissionDuplicatesError, SubmissionUnsupportedError
from classes.pyroclient import PyroClient
from modules import custom_filters
from modules.database import col_submitted
from modules.utils import USERS_WITH_CONTEXT
@ -20,120 +21,126 @@ logger = logging.getLogger(__name__)
@Client.on_message(
~filters.scheduled & filters.private & filters.photo
custom_filters.mode_submit & ~filters.scheduled & filters.private & filters.photo
| filters.video
# | filters.animation
| filters.document
)
async def get_submission(app: PyroClient, msg: Message):
async def get_submission(app: PyroClient, message: Message):
global USERS_WITH_CONTEXT
if not hasattr(msg.from_user, "id"):
if not hasattr(message.from_user, "id"):
return
if msg.from_user.id in USERS_WITH_CONTEXT:
if message.from_user.id in USERS_WITH_CONTEXT:
return
user = await app.find_user(msg.from_user)
user = await app.find_user(message.from_user)
user_owner = await app.find_user(app.owner)
try:
if user.banned:
return
await app.send_chat_action(msg.chat.id, ChatAction.TYPING)
await app.send_chat_action(message.chat.id, ChatAction.TYPING)
save_tmp = True
contents = None
if await user.is_limited():
await msg.reply_text(
await message.reply_text(
app._("sub_cooldown", "message", locale=user.locale).format(
app.config["submission"]["timeout"]
)
)
return
if msg.document is not None:
if message.document is not None:
logger.info(
"User %s is trying to submit a file of type '%s' with name '%s' and size of %s MB",
msg.from_user.id,
msg.document.mime_type,
msg.document.file_name,
msg.document.file_size / 1024 / 1024,
message.from_user.id,
message.document.mime_type,
message.document.file_name,
message.document.file_size / 1024 / 1024,
)
if msg.document.mime_type not in app.config["submission"]["mime_types"]:
await msg.reply_text(
if message.document.mime_type not in app.config["submission"]["mime_types"]:
await message.reply_text(
app._("mime_not_allowed", "message", locale=user.locale).format(
", ".join(app.config["submission"]["mime_types"])
),
quote=True,
)
return
if msg.document.file_size > app.config["submission"]["file_size"]:
await msg.reply_text(
if message.document.file_size > app.config["submission"]["file_size"]:
await message.reply_text(
app._("document_too_large", "message", locale=user.locale).format(
app.config["submission"]["file_size"] / 1024 / 1024
),
quote=True,
)
return
if msg.document.file_size > app.config["submission"]["tmp_size"]:
if message.document.file_size > app.config["submission"]["tmp_size"]:
save_tmp = False
contents = (
msg.document.file_id,
message.document.file_id,
SubmissionType.DOCUMENT,
) # , msg.document.file_name
) # , message.document.file_name
if msg.video is not None:
if message.video is not None:
logger.info(
"User %s is trying to submit a video with name '%s' and size of %s MB",
msg.from_user.id,
msg.video.file_name,
msg.video.file_size / 1024 / 1024,
message.from_user.id,
message.video.file_name,
message.video.file_size / 1024 / 1024,
)
if msg.video.file_size > app.config["submission"]["file_size"]:
await msg.reply_text(
if message.video.file_size > app.config["submission"]["file_size"]:
await message.reply_text(
app._("document_too_large", "message", locale=user.locale).format(
app.config["submission"]["file_size"] / 1024 / 1024
),
quote=True,
)
return
if msg.video.file_size > app.config["submission"]["tmp_size"]:
if message.video.file_size > app.config["submission"]["tmp_size"]:
save_tmp = False
contents = msg.video.file_id, SubmissionType.VIDEO # , msg.video.file_name
contents = (
message.video.file_id,
SubmissionType.VIDEO,
) # , message.video.file_name
# if msg.animation is not None:
# if message.animation is not None:
# logger.info(
# "User %s is trying to submit an animation with name '%s' and size of %s MB",
# msg.from_user.id,
# msg.animation.file_name,
# msg.animation.file_size / 1024 / 1024,
# message.from_user.id,
# message.animation.file_name,
# message.animation.file_size / 1024 / 1024,
# )
# if msg.animation.file_size > app.config["submission"]["file_size"]:
# await msg.reply_text(
# if message.animation.file_size > app.config["submission"]["file_size"]:
# await message.reply_text(
# app._("document_too_large", "message", locale=user.locale).format(
# str(app.config["submission"]["file_size"] / 1024 / 1024)
# ),
# quote=True,
# )
# return
# if msg.animation.file_size > app.config["submission"]["tmp_size"]:
# if message.animation.file_size > app.config["submission"]["tmp_size"]:
# save_tmp = False
# contents = (
# msg.animation.file_id,
# message.animation.file_id,
# SubmissionType.ANIMATION,
# ) # , msg.animation.file_name
# ) # , message.animation.file_name
if msg.photo is not None:
if message.photo is not None:
logger.info(
"User %s is trying to submit a photo with ID '%s' and size of %s MB",
msg.from_user.id,
msg.photo.file_id,
msg.photo.file_size / 1024 / 1024,
message.from_user.id,
message.photo.file_id,
message.photo.file_size / 1024 / 1024,
)
contents = msg.photo.file_id, SubmissionType.PHOTO # , "please_generate"
contents = (
message.photo.file_id,
SubmissionType.PHOTO,
) # , "please_generate"
if contents is None:
return
@ -147,33 +154,37 @@ async def get_submission(app: PyroClient, msg: Message):
exist_ok=True,
)
downloaded = await app.download_media(
msg,
message,
str(Path(f"{app.config['locations']['data']}/submissions/{tmp_id}"))
+ sep,
)
inserted = col_submitted.insert_one(
inserted = await col_submitted.insert_one(
{
"user": msg.from_user.id,
"user": message.from_user.id,
"date": datetime.now(),
"done": False,
"type": contents[1].value,
"temp": {"uuid": tmp_id, "file": path.basename(str(downloaded))},
"telegram": {"msg_id": msg.id, "file_id": contents[0]},
"caption": str(msg.caption) if msg.caption is not None else None,
"telegram": {"msg_id": message.id, "file_id": contents[0]},
"caption": str(message.caption)
if message.caption is not None
else None,
}
)
else:
inserted = col_submitted.insert_one(
inserted = await col_submitted.insert_one(
{
"user": msg.from_user.id,
"user": message.from_user.id,
"date": datetime.now(),
"done": False,
"type": contents[1].value,
"temp": {"uuid": None, "file": None},
"telegram": {"msg_id": msg.id, "file_id": contents[0]},
"caption": str(msg.caption) if msg.caption is not None else None,
"telegram": {"msg_id": message.id, "file_id": contents[0]},
"caption": str(message.caption)
if message.caption is not None
else None,
}
)
@ -186,8 +197,8 @@ async def get_submission(app: PyroClient, msg: Message):
]
]
if msg.caption is not None:
caption = str(msg.caption)
if message.caption is not None:
caption = str(message.caption)
buttons[0].append(
InlineKeyboardButton(
text=app._("sub_yes_caption", "button", locale=user_owner.locale),
@ -205,106 +216,108 @@ async def get_submission(app: PyroClient, msg: Message):
)
caption += app._("sub_by", "message", locale=user_owner.locale)
if msg.from_user.first_name is not None:
caption += f" {msg.from_user.first_name}"
if msg.from_user.last_name is not None:
caption += f" {msg.from_user.last_name}"
if msg.from_user.username is not None:
caption += f" (@{msg.from_user.username})"
if msg.from_user.phone_number is not None:
caption += f" ({msg.from_user.phone_number})"
if message.from_user.first_name is not None:
caption += f" {message.from_user.first_name}"
if message.from_user.last_name is not None:
caption += f" {message.from_user.last_name}"
if message.from_user.username is not None:
caption += f" (@{message.from_user.username})"
if message.from_user.phone_number is not None:
caption += f" ({message.from_user.phone_number})"
if (
msg.from_user.id in app.admins
message.from_user.id in app.admins
and app.config["submission"]["require_confirmation"]["admins"] is False
):
try:
submitted = await app.submit_media(str(inserted.inserted_id))
await msg.reply_text(
await message.reply_text(
app._("sub_yes_auto", "message", locale=user.locale),
disable_notification=True,
quote=True,
)
if app.config["submission"]["send_uploaded_id"]:
caption += f"\n\nID: `{submitted[1]}`"
await msg.copy(app.owner, caption=caption, disable_notification=True)
await message.copy(
app.owner, caption=caption, disable_notification=True
)
return
except SubmissionUnsupportedError:
await msg.reply_text(
await message.reply_text(
app._("mime_not_allowed", "message", locale=user.locale).format(
", ".join(app.config["submission"]["mime_types"]), quote=True
),
quote=True,
)
return
except SubmissionDuplicatesError as exp:
await msg.reply_text(
except SubmissionDuplicatesError as exc:
await message.reply_text(
app._(
"sub_media_duplicates_list", "message", locale=user.locale
).format("\n".join(exp.duplicates)),
).format("\n".join(exc.duplicates)),
quote=True,
)
return
except Exception as exp:
await msg.reply_text(format_exc(), quote=True)
except Exception as exc:
await message.reply_text(exc, quote=True)
return
elif (
msg.from_user.id not in app.admins
message.from_user.id not in app.admins
and app.config["submission"]["require_confirmation"]["users"] is False
):
try:
submitted = await app.submit_photo(str(inserted.inserted_id))
await msg.reply_text(
await message.reply_text(
app._("sub_yes_auto", "message", locale=user.locale),
disable_notification=True,
quote=True,
)
if app.config["submission"]["send_uploaded_id"]:
caption += f"\n\nID: `{submitted[1]}`"
await msg.copy(app.owner, caption=caption)
await message.copy(app.owner, caption=caption)
return
except SubmissionUnsupportedError:
await msg.reply_text(
await message.reply_text(
app._("mime_not_allowed", "message", locale=user.locale).format(
", ".join(app.config["submission"]["mime_types"]), quote=True
)
)
return
except SubmissionDuplicatesError as exp:
await msg.reply_text(
except SubmissionDuplicatesError as exc:
await message.reply_text(
app._("sub_dup", "message", locale=user.locale), quote=True
)
return
except Exception as exp:
except Exception as exc:
await app.send_message(
app.owner,
app._(
"sub_error_admin", "message", locale=user_owner.locale
).format(msg.from_user.id, format_exc()),
).format(message.from_user.id, format_exc()),
)
await msg.reply_text("sub_error", quote=True)
await message.reply_text("sub_error", quote=True)
return
if msg.from_user.id not in app.admins:
if message.from_user.id not in app.admins:
buttons += [
[
InlineKeyboardButton(
text=app._("sub_block", "button", locale=user_owner.locale),
callback_data=f"sub_block_{msg.from_user.id}",
callback_data=f"sub_block_{message.from_user.id}",
)
]
]
await user.update_cooldown()
if msg.from_user.id != app.owner:
await msg.reply_text(
if message.from_user.id != app.owner:
await message.reply_text(
app._("sub_sent", "message", locale=user.locale),
disable_notification=True,
quote=True,
)
await msg.copy(
await message.copy(
app.owner, caption=caption, reply_markup=InlineKeyboardMarkup(buttons)
)

View File

@ -8,6 +8,6 @@ from classes.pyroclient import PyroClient
@Client.on_message(
~filters.scheduled & filters.private & filters.command(["remove_commands"], prefixes=["/"]) # type: ignore
)
async def command_remove_commands(app: PyroClient, msg: Message):
await msg.reply_text("Okay.")
async def command_remove_commands(app: PyroClient, message: Message):
await message.reply_text("Okay.")
await app.remove_commands(command_sets=await app.collect_commands())

View File

@ -1,15 +1,11 @@
aiohttp~=3.8.4
black~=23.3.0
aiohttp~=3.9.1
convopyro==0.5
pillow~=10.0.0
psutil~=5.9.4
pykeyboard==0.1.5
pymongo~=4.4.0
pyrogram==2.0.106
python_dateutil==2.8.2
pillow~=10.3.0
pykeyboard==0.1.7
pytimeparse~=1.1.8
tgcrypto==1.2.5
uvloop==0.17.0
#uvloop==0.19.0
--extra-index-url https://git.end-play.xyz/api/packages/profitroll/pypi/simple
libbot[speed,pyrogram]==1.8
photosapi_client==0.5.0
async_pymongo==0.1.4
libbot[speed,pyrogram]==3.0.0
photosapi_client==0.6.0