Voice et bot modif
This commit is contained in:
parent
189d56026b
commit
7333a22bcd
10774 changed files with 634644 additions and 933308 deletions
|
|
@ -76,8 +76,7 @@ def tzip(iter1, *iter2plus, **tqdm_kwargs):
|
|||
"""
|
||||
kwargs = tqdm_kwargs.copy()
|
||||
tqdm_class = kwargs.pop("tqdm_class", tqdm_auto)
|
||||
for i in zip(tqdm_class(iter1, **kwargs), *iter2plus):
|
||||
yield i
|
||||
yield from zip(tqdm_class(iter1, **kwargs), *iter2plus)
|
||||
|
||||
|
||||
def tmap(function, *sequences, **tqdm_kwargs):
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -3,6 +3,8 @@ Even more features than `tqdm.auto` (all the bells & whistles):
|
|||
|
||||
- `tqdm.auto`
|
||||
- `tqdm.tqdm.pandas`
|
||||
- `tqdm.contrib.slack`
|
||||
+ uses `${TQDM_SLACK_TOKEN}` and `${TQDM_SLACK_CHANNEL}`
|
||||
- `tqdm.contrib.telegram`
|
||||
+ uses `${TQDM_TELEGRAM_TOKEN}` and `${TQDM_TELEGRAM_CHAT_ID}`
|
||||
- `tqdm.contrib.discord`
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ Usage:
|
|||
|
||||

|
||||
"""
|
||||
from os import getenv
|
||||
from warnings import warn
|
||||
|
||||
from requests import Session
|
||||
|
|
@ -16,6 +15,7 @@ from requests.utils import default_user_agent
|
|||
|
||||
from ..auto import tqdm as tqdm_auto
|
||||
from ..std import TqdmWarning
|
||||
from ..utils import envwrap
|
||||
from ..version import __version__
|
||||
from .utils_worker import MonoWorker
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ __all__ = ['DiscordIO', 'tqdm_discord', 'tdrange', 'tqdm', 'trange']
|
|||
|
||||
class DiscordIO(MonoWorker):
|
||||
"""Non-blocking file-like IO using a Discord Bot."""
|
||||
API = "https://discord.com/api/v10"
|
||||
API = 'https://discord.com/api/v10'
|
||||
UA = f"tqdm (https://tqdm.github.io, {__version__}) {default_user_agent()}"
|
||||
|
||||
def __init__(self, token, channel_id):
|
||||
|
|
@ -40,21 +40,23 @@ class DiscordIO(MonoWorker):
|
|||
@property
|
||||
def message_id(self):
|
||||
if hasattr(self, '_message_id'):
|
||||
return self._message_id
|
||||
return self._message_id # pylint: disable=access-member-before-definition
|
||||
try:
|
||||
res = self.session.post(
|
||||
req = self.session.post(
|
||||
f'{self.API}/channels/{self.channel_id}/messages',
|
||||
headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA},
|
||||
json={'content': f"`{self.text}`"}).json()
|
||||
json={'content': f"`{self.text}`"})
|
||||
res = req.json()
|
||||
req.raise_for_status()
|
||||
except Exception as e:
|
||||
tqdm_auto.write(str(e))
|
||||
else:
|
||||
if res.get('error_code') == 429:
|
||||
if req.status_code == 429:
|
||||
warn("Creation rate limit: try increasing `mininterval`.",
|
||||
TqdmWarning, stacklevel=2)
|
||||
else:
|
||||
self._message_id = res['id']
|
||||
return self._message_id
|
||||
tqdm_auto.write(str(e))
|
||||
else:
|
||||
self._message_id = res['id']
|
||||
return self._message_id
|
||||
|
||||
def write(self, s):
|
||||
"""Replaces internal `message_id`'s text with `s`."""
|
||||
|
|
@ -91,7 +93,7 @@ class DiscordIO(MonoWorker):
|
|||
return future
|
||||
|
||||
|
||||
class tqdm_discord(tqdm_auto):
|
||||
class tqdm_discord(tqdm_auto): # pylint: disable=inconsistent-mro
|
||||
"""
|
||||
Standard `tqdm.auto.tqdm` but also sends updates to a Discord Bot.
|
||||
May take a few seconds to create (`__init__`).
|
||||
|
|
@ -105,7 +107,8 @@ class tqdm_discord(tqdm_auto):
|
|||
>>> for i in tqdm(iterable, token='{token}', channel_id='{channel_id}'):
|
||||
... ...
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
@envwrap("tqdm", "discord", is_method=True)
|
||||
def __init__(self, *args, token=None, channel_id=None, **kwargs):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -118,19 +121,15 @@ class tqdm_discord(tqdm_auto):
|
|||
"""
|
||||
if not kwargs.get('disable'):
|
||||
kwargs = kwargs.copy()
|
||||
self.dio = DiscordIO(
|
||||
kwargs.pop('token', getenv('TQDM_DISCORD_TOKEN')),
|
||||
kwargs.pop('channel_id', getenv('TQDM_DISCORD_CHANNEL_ID')))
|
||||
self.dio = DiscordIO(token, channel_id)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def display(self, **kwargs):
|
||||
def display(self, **kwargs): # pylint: disable=arguments-differ
|
||||
super().display(**kwargs)
|
||||
fmt = self.format_dict
|
||||
if fmt.get('bar_format', None):
|
||||
fmt['bar_format'] = fmt['bar_format'].replace(
|
||||
'<bar/>', '{bar:10u}').replace('{bar}', '{bar:10u}')
|
||||
else:
|
||||
fmt['bar_format'] = '{l_bar}{bar:10u}{r_bar}'
|
||||
self.dio.write(self.format_meter(**fmt))
|
||||
|
||||
def clear(self, *args, **kwargs):
|
||||
|
|
|
|||
|
|
@ -6,30 +6,96 @@ import itertools
|
|||
from ..auto import tqdm as tqdm_auto
|
||||
|
||||
__author__ = {"github.com/": ["casperdcl"]}
|
||||
__all__ = ['product']
|
||||
__all__ = [
|
||||
'chain', 'product', 'permutations', 'combinations', 'combinations_with_replacement', 'batched']
|
||||
|
||||
|
||||
def product(*iterables, **tqdm_kwargs):
|
||||
"""
|
||||
Equivalent of `itertools.product`.
|
||||
def chain(*iterables, total=None, tqdm_class=tqdm_auto, **kwargs):
|
||||
"""Equivalent of `itertools.chain`."""
|
||||
if total is None:
|
||||
try:
|
||||
total = sum(map(len, iterables))
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
return tqdm_class(itertools.chain(*iterables), total=total, **kwargs)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tqdm_class : [default: tqdm.auto.tqdm].
|
||||
"""
|
||||
kwargs = tqdm_kwargs.copy()
|
||||
tqdm_class = kwargs.pop("tqdm_class", tqdm_auto)
|
||||
try:
|
||||
lens = list(map(len, iterables))
|
||||
except TypeError:
|
||||
total = None
|
||||
else:
|
||||
total = 1
|
||||
for i in lens:
|
||||
total *= i
|
||||
kwargs.setdefault("total", total)
|
||||
with tqdm_class(**kwargs) as t:
|
||||
it = itertools.product(*iterables)
|
||||
for i in it:
|
||||
yield i
|
||||
t.update()
|
||||
|
||||
def product(*iterables, repeat=1, total=None, tqdm_class=tqdm_auto, **kwargs):
|
||||
"""Equivalent of `itertools.product`."""
|
||||
if total is None:
|
||||
try:
|
||||
lens = list(map(len, iterables))
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
else: # py>=3.8: math.prod(lens) ** repeat
|
||||
total = 1
|
||||
for i in lens:
|
||||
total *= i
|
||||
total **= repeat
|
||||
for i in tqdm_class(itertools.product(*iterables, repeat=repeat), total=total, **kwargs):
|
||||
yield i
|
||||
|
||||
|
||||
def permutations(iterable, r=None, total=None, tqdm_class=tqdm_auto, **kwargs):
|
||||
"""Equivalent of `itertools.permutations`."""
|
||||
if total is None:
|
||||
try:
|
||||
n = len(iterable)
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
r = n if r is None else r
|
||||
if r > n:
|
||||
total = 0
|
||||
else: # py>=3.8: math.perm(n, r)
|
||||
total = 1
|
||||
for i in range(n, n-r, -1):
|
||||
total *= i
|
||||
return tqdm_class(itertools.permutations(iterable, r), total=total, **kwargs)
|
||||
|
||||
|
||||
def combinations(iterable, r, total=None, tqdm_class=tqdm_auto, **kwargs):
|
||||
"""Equivalent of `itertools.combinations`."""
|
||||
if total is None:
|
||||
try:
|
||||
n = len(iterable)
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
if r > n:
|
||||
total = 0
|
||||
else: # py>=3.8: math.comb(n, r)
|
||||
total = 1
|
||||
for i in range(n, n-r, -1):
|
||||
total *= i
|
||||
for i in range(1, r+1):
|
||||
total //= i
|
||||
return tqdm_class(itertools.combinations(iterable, r), total=total, **kwargs)
|
||||
|
||||
|
||||
def combinations_with_replacement(iterable, r, total=None, tqdm_class=tqdm_auto, **kwargs):
|
||||
"""Equivalent of `itertools.combinations_with_replacement`."""
|
||||
if total is None:
|
||||
try:
|
||||
n = len(iterable)
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
total = 1
|
||||
for i in range(n+r-1, n-1, -1):
|
||||
total *= i
|
||||
for i in range(1, r+1):
|
||||
total //= i
|
||||
return tqdm_class(itertools.combinations_with_replacement(iterable, r), total=total, **kwargs)
|
||||
|
||||
|
||||
def batched(iterable, n, total=None, tqdm_class=tqdm_auto, **kwargs):
|
||||
"""Equivalent of `itertools.batched`."""
|
||||
if total is None:
|
||||
try:
|
||||
total = len(iterable)
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
return tqdm_class(itertools.batched(iterable, n), unit_scale=n,
|
||||
total=(total+n-1) // n if total is not None else None,
|
||||
**kwargs)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ Usage:
|
|||

|
||||
"""
|
||||
import logging
|
||||
from os import getenv
|
||||
|
||||
try:
|
||||
from slack_sdk import WebClient
|
||||
|
|
@ -17,6 +16,7 @@ except ImportError:
|
|||
raise ImportError("Please `pip install slack-sdk`")
|
||||
|
||||
from ..auto import tqdm as tqdm_auto
|
||||
from ..utils import envwrap
|
||||
from .utils_worker import MonoWorker
|
||||
|
||||
__author__ = {"github.com/": ["0x2b3bfa0", "casperdcl"]}
|
||||
|
|
@ -56,7 +56,7 @@ class SlackIO(MonoWorker):
|
|||
return future
|
||||
|
||||
|
||||
class tqdm_slack(tqdm_auto):
|
||||
class tqdm_slack(tqdm_auto): # pylint: disable=inconsistent-mro
|
||||
"""
|
||||
Standard `tqdm.auto.tqdm` but also sends updates to a Slack app.
|
||||
May take a few seconds to create (`__init__`).
|
||||
|
|
@ -68,7 +68,8 @@ class tqdm_slack(tqdm_auto):
|
|||
>>> for i in tqdm(iterable, token='{token}', channel='{channel}'):
|
||||
... ...
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
@envwrap("tqdm", "slack", is_method=True)
|
||||
def __init__(self, *args, token=None, channel=None, **kwargs):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -84,19 +85,17 @@ class tqdm_slack(tqdm_auto):
|
|||
if not kwargs.get('disable'):
|
||||
kwargs = kwargs.copy()
|
||||
logging.getLogger("HTTPClient").setLevel(logging.WARNING)
|
||||
self.sio = SlackIO(
|
||||
kwargs.pop('token', getenv("TQDM_SLACK_TOKEN")),
|
||||
kwargs.pop('channel', getenv("TQDM_SLACK_CHANNEL")))
|
||||
self.sio = SlackIO(token, channel)
|
||||
kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5))
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def display(self, **kwargs):
|
||||
def display(self, **kwargs): # pylint: disable=arguments-differ
|
||||
super().display(**kwargs)
|
||||
fmt = self.format_dict
|
||||
if fmt.get('bar_format', None):
|
||||
fmt['bar_format'] = fmt['bar_format'].replace(
|
||||
'<bar/>', '`{bar:10}`').replace('{bar}', '`{bar:10u}`')
|
||||
else:
|
||||
elif self.total:
|
||||
fmt['bar_format'] = '{l_bar}`{bar:10}`{r_bar}'
|
||||
if fmt['ascii'] is False:
|
||||
fmt['ascii'] = [":black_square:", ":small_blue_diamond:", ":large_blue_diamond:",
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ Usage:
|
|||
|
||||

|
||||
"""
|
||||
from os import getenv
|
||||
from warnings import warn
|
||||
|
||||
from requests import Session
|
||||
|
||||
from ..auto import tqdm as tqdm_auto
|
||||
from ..std import TqdmWarning
|
||||
from ..utils import envwrap
|
||||
from .utils_worker import MonoWorker
|
||||
|
||||
__author__ = {"github.com/": ["casperdcl"]}
|
||||
|
|
@ -37,21 +37,23 @@ class TelegramIO(MonoWorker):
|
|||
@property
|
||||
def message_id(self):
|
||||
if hasattr(self, '_message_id'):
|
||||
return self._message_id
|
||||
return self._message_id # pylint: disable=access-member-before-definition
|
||||
try:
|
||||
res = self.session.post(
|
||||
self.API + '%s/sendMessage' % self.token,
|
||||
data={'text': '`' + self.text + '`', 'chat_id': self.chat_id,
|
||||
'parse_mode': 'MarkdownV2'}).json()
|
||||
req = self.session.post(
|
||||
f'{self.API}{self.token}/sendMessage',
|
||||
data={'text': f"`{self.text}`", 'chat_id': self.chat_id,
|
||||
'parse_mode': 'MarkdownV2'})
|
||||
res = req.json()
|
||||
req.raise_for_status()
|
||||
except Exception as e:
|
||||
tqdm_auto.write(str(e))
|
||||
else:
|
||||
if res.get('error_code') == 429:
|
||||
if req.status_code == 429:
|
||||
warn("Creation rate limit: try increasing `mininterval`.",
|
||||
TqdmWarning, stacklevel=2)
|
||||
else:
|
||||
self._message_id = res['result']['message_id']
|
||||
return self._message_id
|
||||
tqdm_auto.write(str(e))
|
||||
else:
|
||||
self._message_id = res['result']['message_id']
|
||||
return self._message_id
|
||||
|
||||
def write(self, s):
|
||||
"""Replaces internal `message_id`'s text with `s`."""
|
||||
|
|
@ -66,8 +68,8 @@ class TelegramIO(MonoWorker):
|
|||
self.text = s
|
||||
try:
|
||||
future = self.submit(
|
||||
self.session.post, self.API + '%s/editMessageText' % self.token,
|
||||
data={'text': '`' + s + '`', 'chat_id': self.chat_id,
|
||||
self.session.post, f'{self.API}{self.token}/editMessageText',
|
||||
data={'text': f"`{s}`", 'chat_id': self.chat_id,
|
||||
'message_id': message_id, 'parse_mode': 'MarkdownV2'})
|
||||
except Exception as e:
|
||||
tqdm_auto.write(str(e))
|
||||
|
|
@ -78,7 +80,7 @@ class TelegramIO(MonoWorker):
|
|||
"""Deletes internal `message_id`."""
|
||||
try:
|
||||
future = self.submit(
|
||||
self.session.post, self.API + '%s/deleteMessage' % self.token,
|
||||
self.session.post, '{self.API}{self.token}/deleteMessage',
|
||||
data={'chat_id': self.chat_id, 'message_id': self.message_id})
|
||||
except Exception as e:
|
||||
tqdm_auto.write(str(e))
|
||||
|
|
@ -86,7 +88,7 @@ class TelegramIO(MonoWorker):
|
|||
return future
|
||||
|
||||
|
||||
class tqdm_telegram(tqdm_auto):
|
||||
class tqdm_telegram(tqdm_auto): # pylint: disable=inconsistent-mro
|
||||
"""
|
||||
Standard `tqdm.auto.tqdm` but also sends updates to a Telegram Bot.
|
||||
May take a few seconds to create (`__init__`).
|
||||
|
|
@ -102,7 +104,8 @@ class tqdm_telegram(tqdm_auto):
|
|||
>>> for i in tqdm(iterable, token='{token}', chat_id='{chat_id}'):
|
||||
... ...
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
@envwrap("tqdm", "telegram", is_method=True)
|
||||
def __init__(self, *args, token=None, chat_id=None, **kwargs):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -115,19 +118,15 @@ class tqdm_telegram(tqdm_auto):
|
|||
"""
|
||||
if not kwargs.get('disable'):
|
||||
kwargs = kwargs.copy()
|
||||
self.tgio = TelegramIO(
|
||||
kwargs.pop('token', getenv('TQDM_TELEGRAM_TOKEN')),
|
||||
kwargs.pop('chat_id', getenv('TQDM_TELEGRAM_CHAT_ID')))
|
||||
self.tgio = TelegramIO(token, chat_id)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def display(self, **kwargs):
|
||||
def display(self, **kwargs): # pylint: disable=arguments-differ
|
||||
super().display(**kwargs)
|
||||
fmt = self.format_dict
|
||||
if fmt.get('bar_format', None):
|
||||
fmt['bar_format'] = fmt['bar_format'].replace(
|
||||
'<bar/>', '{bar:10u}').replace('{bar}', '{bar:10u}')
|
||||
else:
|
||||
fmt['bar_format'] = '{l_bar}{bar:10u}{r_bar}'
|
||||
self.tgio.write(self.format_meter(**fmt))
|
||||
|
||||
def clear(self, *args, **kwargs):
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ __author__ = {"github.com/": ["casperdcl"]}
|
|||
__all__ = ['MonoWorker']
|
||||
|
||||
|
||||
class MonoWorker(object):
|
||||
class MonoWorker:
|
||||
"""
|
||||
Supports one running task and one waiting task.
|
||||
The waiting task is the most recent submitted (others are discarded).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue