Normal update

This commit is contained in:
DUOLabs333
2022-10-24 14:17:53 -04:00
parent 64a966eddd
commit aebde3317e
85 changed files with 24241 additions and 16438 deletions

View File

@@ -1,8 +1,9 @@
#!/bin/python3
import requests
import os
import os, sys
import re
import json
sys.path.insert(0,"_vendor")
from tqdm import tqdm
from dataclasses import dataclass
import glob

8
_vendor/bin/tqdm Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from tqdm.cli import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@@ -0,0 +1 @@
pip

View File

@@ -0,0 +1,49 @@
`tqdm` is a product of collaborative work.
Unless otherwise stated, all authors (see commit logs) retain copyright
for their respective work, and release the work under the MIT licence
(text below).
Exceptions or notable authors are listed below
in reverse chronological order:
* files: *
MPLv2.0 2015-2021 (c) Casper da Costa-Luis
[casperdcl](https://github.com/casperdcl).
* files: tqdm/_tqdm.py
MIT 2016 (c) [PR #96] on behalf of Google Inc.
* files: tqdm/_tqdm.py setup.py README.rst MANIFEST.in .gitignore
MIT 2013 (c) Noam Yorav-Raphael, original author.
[PR #96]: https://github.com/tqdm/tqdm/pull/96
Mozilla Public Licence (MPL) v. 2.0 - Exhibit A
-----------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this project,
You can obtain one at https://mozilla.org/MPL/2.0/.
MIT License (MIT)
-----------------
Copyright (c) 2013 noamraph
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
../../bin/tqdm,sha256=UVUXsKXVFuHdXm50YnqTxgmWWMmnw1GXsyFiiLNjN5M,206
tqdm-4.64.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
tqdm-4.64.1.dist-info/LICENCE,sha256=oPwXhajyogCjEk1wPUlVBgG3dBzP_IYXE8LdqgelN90,2006
tqdm-4.64.1.dist-info/METADATA,sha256=jsTR8y5U6BX1aR0f56wIIfTRD3UULEF2gUfjrqpsDek,57320
tqdm-4.64.1.dist-info/RECORD,,
tqdm-4.64.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
tqdm-4.64.1.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110
tqdm-4.64.1.dist-info/entry_points.txt,sha256=ReJCH7Ui3Zyh6M16E4OhsZ1oU7WtMXCfbtoyBhGO29Y,39
tqdm-4.64.1.dist-info/top_level.txt,sha256=NLiUJNfmc9At15s7JURiwvqMEjUi9G5PMGRrmMYzNSM,5
tqdm/__init__.py,sha256=LiezHIqATK3FOij_365eMcu11UPmijmDFKogl72fHp4,1639
tqdm/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30
tqdm/__pycache__/__init__.cpython-310.pyc,,
tqdm/__pycache__/__main__.cpython-310.pyc,,
tqdm/__pycache__/_dist_ver.cpython-310.pyc,,
tqdm/__pycache__/_main.cpython-310.pyc,,
tqdm/__pycache__/_monitor.cpython-310.pyc,,
tqdm/__pycache__/_tqdm.cpython-310.pyc,,
tqdm/__pycache__/_tqdm_gui.cpython-310.pyc,,
tqdm/__pycache__/_tqdm_notebook.cpython-310.pyc,,
tqdm/__pycache__/_tqdm_pandas.cpython-310.pyc,,
tqdm/__pycache__/_utils.cpython-310.pyc,,
tqdm/__pycache__/asyncio.cpython-310.pyc,,
tqdm/__pycache__/auto.cpython-310.pyc,,
tqdm/__pycache__/autonotebook.cpython-310.pyc,,
tqdm/__pycache__/cli.cpython-310.pyc,,
tqdm/__pycache__/dask.cpython-310.pyc,,
tqdm/__pycache__/gui.cpython-310.pyc,,
tqdm/__pycache__/keras.cpython-310.pyc,,
tqdm/__pycache__/notebook.cpython-310.pyc,,
tqdm/__pycache__/rich.cpython-310.pyc,,
tqdm/__pycache__/std.cpython-310.pyc,,
tqdm/__pycache__/tk.cpython-310.pyc,,
tqdm/__pycache__/utils.cpython-310.pyc,,
tqdm/__pycache__/version.cpython-310.pyc,,
tqdm/_dist_ver.py,sha256=t_S6ewuKLyIG83cQE_4p3-9fuVl15vndP1_y1FpoRyM,23
tqdm/_main.py,sha256=9ySvgmi_2Sw4CAo5UDW0Q2dxfTryboEWGHohfCJz0sA,283
tqdm/_monitor.py,sha256=Uku-DPWgzJ7dO5CK08xKJK-E_F6qQ-JB3ksuXczSYR0,3699
tqdm/_tqdm.py,sha256=LfLCuJ6bpsVo9xilmtBXyEm1vGnUCFrliW85j3J-nD4,283
tqdm/_tqdm_gui.py,sha256=03Hc8KayxJveieI5-0-2NGiDpLvw9jZekofJUV7CCwk,287
tqdm/_tqdm_notebook.py,sha256=BuHiLuxu6uEfZFaPJW3RPpPaxaVctEQA3kdSJSDL1hw,307
tqdm/_tqdm_pandas.py,sha256=c9jptUgigN6axRDhRd4Rif98Tmxeopc1nFNFhIpbFUE,888
tqdm/_utils.py,sha256=YIwj0ZJQonXgYa2HaA3U_paP4xOXJqj0ZWMPeZSf6Pw,596
tqdm/asyncio.py,sha256=7CWT2150uMvyXSMDkl9PvG9G_HrfOVY32rWbeP2bw1Y,2789
tqdm/auto.py,sha256=P__dIfklVGqcRdzV4q68SOBVhLHe9QWnrCk3IJIA-fM,1106
tqdm/autonotebook.py,sha256=Yb9F5uaiBPhfbDDFpbtoG8I2YUw3uQJ89rUDLbfR6ws,956
tqdm/cli.py,sha256=h4DvZDBZ2ZlANtlRi2mXblr8yjEe9iUGlOqZc5XPljc,10871
tqdm/completion.sh,sha256=j79KbSmpIj_E11jfTfBXrGnUTzKXVpQ1vGVQvsyDRl4,946
tqdm/contrib/__init__.py,sha256=gpiBeuWB1OaaoGFwiS-G_Nodv8fLPZ_xVxbENL0EYL4,2604
tqdm/contrib/__pycache__/__init__.cpython-310.pyc,,
tqdm/contrib/__pycache__/bells.cpython-310.pyc,,
tqdm/contrib/__pycache__/concurrent.cpython-310.pyc,,
tqdm/contrib/__pycache__/discord.cpython-310.pyc,,
tqdm/contrib/__pycache__/itertools.cpython-310.pyc,,
tqdm/contrib/__pycache__/logging.cpython-310.pyc,,
tqdm/contrib/__pycache__/slack.cpython-310.pyc,,
tqdm/contrib/__pycache__/telegram.cpython-310.pyc,,
tqdm/contrib/__pycache__/utils_worker.cpython-310.pyc,,
tqdm/contrib/bells.py,sha256=Yx1HqGCmHrESCAO700j5wE__JCleNODJxedh1ijPLD0,837
tqdm/contrib/concurrent.py,sha256=YmHJG_jUYUsg2NR1eAhsrl6X-_BfzlANtW32IhNmRTA,4644
tqdm/contrib/discord.py,sha256=VbmiX5-ioD2Lqq0XtO9qx0hxStWokVaiR4l_a9Qozzw,4090
tqdm/contrib/itertools.py,sha256=PW3WkdYKP-aVCrlcOfH53i4IA5R7G8rjEJdp6CF5IO8,814
tqdm/contrib/logging.py,sha256=F4pEE2mRecNKoZNm7jIWr2nMeelvogvZ8aopo_irK44,3844
tqdm/contrib/slack.py,sha256=CQauSUZP5PyKOrXqU0HN5XOQM9E1pU6NgV1BVaGdV0I,4196
tqdm/contrib/telegram.py,sha256=5S6IIZMjDg7rcdxJaGGcvTRC37DnHf0r36ahje_JyyQ,5228
tqdm/contrib/utils_worker.py,sha256=3Mj9TvDa3qRGoZvrmU5cQTnmQLPd8oP7AURuJjVVFXo,1247
tqdm/dask.py,sha256=BqPQ2O_Bd59hnXlC7B5rS7y9C2wI4cPkIHDdeCWGtzc,1377
tqdm/gui.py,sha256=kQP-ezwAUSvJ44f50Up2fEG4Hq-p4snrEyKwSNwcgkI,5943
tqdm/keras.py,sha256=auQQJvAZMHgr0Y3kY6pKQVD-6EAJMPg91ZOJ2WSTN-A,4409
tqdm/notebook.py,sha256=9U5j_FciNUpLaqd6nmJocRlFa3PFcCzvhTaKudrWbbA,11317
tqdm/rich.py,sha256=ocxh5vFqPhpV49g6qrC9JkfB9RK1pNuH74681Otzg5I,5152
tqdm/std.py,sha256=3D8qfR_CdRI12Ad05Fm9ndmfFlD5M6HvtK2gn-KQDAE,58341
tqdm/tk.py,sha256=a3lbj1GsP7jyDpQQgm5ohsFm9Y9-adeklYIhPH69P88,6948
tqdm/tqdm.1,sha256=1YMLZFiY0wGAUYgjmrfr9vQTlyMql6LT31oUWvOyQdU,7997
tqdm/utils.py,sha256=KvE0DM28X__NHYKgGl5jUrk6CM5BV60G4Nf55ITPeJI,9803
tqdm/version.py,sha256=-1yWjfu3P0eghVsysHH07fbzdiADNRdzRtYPqOaqR2A,333

View File

View File

@@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.37.1)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@@ -0,0 +1,2 @@
[console_scripts]
tqdm = tqdm.cli:main

View File

@@ -0,0 +1 @@
tqdm

41
_vendor/tqdm/__init__.py Normal file
View File

@@ -0,0 +1,41 @@
from ._monitor import TMonitor, TqdmSynchronisationWarning
from ._tqdm_pandas import tqdm_pandas
from .cli import main # TODO: remove in v5.0.0
from .gui import tqdm as tqdm_gui # TODO: remove in v5.0.0
from .gui import trange as tgrange # TODO: remove in v5.0.0
from .std import (
TqdmDeprecationWarning, TqdmExperimentalWarning, TqdmKeyError, TqdmMonitorWarning,
TqdmTypeError, TqdmWarning, tqdm, trange)
from .version import __version__
__all__ = ['tqdm', 'tqdm_gui', 'trange', 'tgrange', 'tqdm_pandas',
'tqdm_notebook', 'tnrange', 'main', 'TMonitor',
'TqdmTypeError', 'TqdmKeyError',
'TqdmWarning', 'TqdmDeprecationWarning',
'TqdmExperimentalWarning',
'TqdmMonitorWarning', 'TqdmSynchronisationWarning',
'__version__']
def tqdm_notebook(*args, **kwargs): # pragma: no cover
"""See tqdm.notebook.tqdm for full documentation"""
from warnings import warn
from .notebook import tqdm as _tqdm_notebook
warn("This function will be removed in tqdm==5.0.0\n"
"Please use `tqdm.notebook.tqdm` instead of `tqdm.tqdm_notebook`",
TqdmDeprecationWarning, stacklevel=2)
return _tqdm_notebook(*args, **kwargs)
def tnrange(*args, **kwargs): # pragma: no cover
"""
A shortcut for `tqdm.notebook.tqdm(xrange(*args), **kwargs)`.
On Python3+, `range` is used instead of `xrange`.
"""
from warnings import warn
from .notebook import trange as _tnrange
warn("Please use `tqdm.notebook.trange` instead of `tqdm.tnrange`",
TqdmDeprecationWarning, stacklevel=2)
return _tnrange(*args, **kwargs)

3
_vendor/tqdm/__main__.py Normal file
View File

@@ -0,0 +1,3 @@
from .cli import main
main()

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.

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
__version__ = '4.64.1'

9
_vendor/tqdm/_main.py Normal file
View File

@@ -0,0 +1,9 @@
from warnings import warn
from .cli import * # NOQA
from .cli import __all__ # NOQA
from .std import TqdmDeprecationWarning
warn("This function will be removed in tqdm==5.0.0\n"
"Please use `tqdm.cli.*` instead of `tqdm._main.*`",
TqdmDeprecationWarning, stacklevel=2)

95
_vendor/tqdm/_monitor.py Normal file
View File

@@ -0,0 +1,95 @@
import atexit
from threading import Event, Thread, current_thread
from time import time
from warnings import warn
__all__ = ["TMonitor", "TqdmSynchronisationWarning"]
class TqdmSynchronisationWarning(RuntimeWarning):
"""tqdm multi-thread/-process errors which may cause incorrect nesting
but otherwise no adverse effects"""
pass
class TMonitor(Thread):
"""
Monitoring thread for tqdm bars.
Monitors if tqdm bars are taking too much time to display
and readjusts miniters automatically if necessary.
Parameters
----------
tqdm_cls : class
tqdm class to use (can be core tqdm or a submodule).
sleep_interval : float
Time to sleep between monitoring checks.
"""
_test = {} # internal vars for unit testing
def __init__(self, tqdm_cls, sleep_interval):
Thread.__init__(self)
self.daemon = True # kill thread when main killed (KeyboardInterrupt)
self.woken = 0 # last time woken up, to sync with monitor
self.tqdm_cls = tqdm_cls
self.sleep_interval = sleep_interval
self._time = self._test.get("time", time)
self.was_killed = self._test.get("Event", Event)()
atexit.register(self.exit)
self.start()
def exit(self):
self.was_killed.set()
if self is not current_thread():
self.join()
return self.report()
def get_instances(self):
# returns a copy of started `tqdm_cls` instances
return [i for i in self.tqdm_cls._instances.copy()
# Avoid race by checking that the instance started
if hasattr(i, 'start_t')]
def run(self):
cur_t = self._time()
while True:
# After processing and before sleeping, notify that we woke
# Need to be done just before sleeping
self.woken = cur_t
# Sleep some time...
self.was_killed.wait(self.sleep_interval)
# Quit if killed
if self.was_killed.is_set():
return
# Then monitor!
# Acquire lock (to access _instances)
with self.tqdm_cls.get_lock():
cur_t = self._time()
# Check tqdm instances are waiting too long to print
instances = self.get_instances()
for instance in instances:
# Check event in loop to reduce blocking time on exit
if self.was_killed.is_set():
return
# Only if mininterval > 1 (else iterations are just slow)
# and last refresh exceeded maxinterval
if (
instance.miniters > 1
and (cur_t - instance.last_print_t) >= instance.maxinterval
):
# force bypassing miniters on next iteration
# (dynamic_miniters adjusts mininterval automatically)
instance.miniters = 1
# Refresh now! (works only for manual tqdm)
instance.refresh(nolock=True)
# Remove accidental long-lived strong reference
del instance
if instances != self.get_instances(): # pragma: nocover
warn("Set changed size during iteration" +
" (see https://github.com/tqdm/tqdm/issues/481)",
TqdmSynchronisationWarning, stacklevel=2)
# Remove accidental long-lived strong references
del instances
def report(self):
return not self.was_killed.is_set()

9
_vendor/tqdm/_tqdm.py Normal file
View File

@@ -0,0 +1,9 @@
from warnings import warn
from .std import * # NOQA
from .std import __all__ # NOQA
from .std import TqdmDeprecationWarning
warn("This function will be removed in tqdm==5.0.0\n"
"Please use `tqdm.std.*` instead of `tqdm._tqdm.*`",
TqdmDeprecationWarning, stacklevel=2)

View File

@@ -0,0 +1,9 @@
from warnings import warn
from .gui import * # NOQA
from .gui import __all__ # NOQA
from .std import TqdmDeprecationWarning
warn("This function will be removed in tqdm==5.0.0\n"
"Please use `tqdm.gui.*` instead of `tqdm._tqdm_gui.*`",
TqdmDeprecationWarning, stacklevel=2)

View File

@@ -0,0 +1,9 @@
from warnings import warn
from .notebook import * # NOQA
from .notebook import __all__ # NOQA
from .std import TqdmDeprecationWarning
warn("This function will be removed in tqdm==5.0.0\n"
"Please use `tqdm.notebook.*` instead of `tqdm._tqdm_notebook.*`",
TqdmDeprecationWarning, stacklevel=2)

View File

@@ -0,0 +1,24 @@
import sys
__author__ = "github.com/casperdcl"
__all__ = ['tqdm_pandas']
def tqdm_pandas(tclass, **tqdm_kwargs):
"""
Registers the given `tqdm` instance with
`pandas.core.groupby.DataFrameGroupBy.progress_apply`.
"""
from tqdm import TqdmDeprecationWarning
if isinstance(tclass, type) or (getattr(tclass, '__name__', '').startswith(
'tqdm_')): # delayed adapter case
TqdmDeprecationWarning(
"Please use `tqdm.pandas(...)` instead of `tqdm_pandas(tqdm, ...)`.",
fp_write=getattr(tqdm_kwargs.get('file', None), 'write', sys.stderr.write))
tclass.pandas(**tqdm_kwargs)
else:
TqdmDeprecationWarning(
"Please use `tqdm.pandas(...)` instead of `tqdm_pandas(tqdm(...))`.",
fp_write=getattr(tclass.fp, 'write', sys.stderr.write))
type(tclass).pandas(deprecated_t=tclass)

12
_vendor/tqdm/_utils.py Normal file
View File

@@ -0,0 +1,12 @@
from warnings import warn
from .std import TqdmDeprecationWarning
from .utils import ( # NOQA, pylint: disable=unused-import
CUR_OS, IS_NIX, IS_WIN, RE_ANSI, Comparable, FormatReplace, SimpleTextIOWrapper, _basestring,
_environ_cols_wrapper, _is_ascii, _is_utf, _range, _screen_shape_linux, _screen_shape_tput,
_screen_shape_windows, _screen_shape_wrapper, _supports_unicode, _term_move_up, _unich,
_unicode, colorama)
warn("This function will be removed in tqdm==5.0.0\n"
"Please use `tqdm.utils.*` instead of `tqdm._utils.*`",
TqdmDeprecationWarning, stacklevel=2)

93
_vendor/tqdm/asyncio.py Normal file
View File

@@ -0,0 +1,93 @@
"""
Asynchronous progressbar decorator for iterators.
Includes a default `range` iterator printing to `stderr`.
Usage:
>>> from tqdm.asyncio import trange, tqdm
>>> async for i in trange(10):
... ...
"""
import asyncio
from sys import version_info
from .std import tqdm as std_tqdm
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['tqdm_asyncio', 'tarange', 'tqdm', 'trange']
class tqdm_asyncio(std_tqdm):
"""
Asynchronous-friendly version of tqdm (Python 3.6+).
"""
def __init__(self, iterable=None, *args, **kwargs):
super(tqdm_asyncio, self).__init__(iterable, *args, **kwargs)
self.iterable_awaitable = False
if iterable is not None:
if hasattr(iterable, "__anext__"):
self.iterable_next = iterable.__anext__
self.iterable_awaitable = True
elif hasattr(iterable, "__next__"):
self.iterable_next = iterable.__next__
else:
self.iterable_iterator = iter(iterable)
self.iterable_next = self.iterable_iterator.__next__
def __aiter__(self):
return self
async def __anext__(self):
try:
if self.iterable_awaitable:
res = await self.iterable_next()
else:
res = self.iterable_next()
self.update()
return res
except StopIteration:
self.close()
raise StopAsyncIteration
except BaseException:
self.close()
raise
def send(self, *args, **kwargs):
return self.iterable.send(*args, **kwargs)
@classmethod
def as_completed(cls, fs, *, loop=None, timeout=None, total=None, **tqdm_kwargs):
"""
Wrapper for `asyncio.as_completed`.
"""
if total is None:
total = len(fs)
kwargs = {}
if version_info[:2] < (3, 10):
kwargs['loop'] = loop
yield from cls(asyncio.as_completed(fs, timeout=timeout, **kwargs),
total=total, **tqdm_kwargs)
@classmethod
async def gather(cls, *fs, loop=None, timeout=None, total=None, **tqdm_kwargs):
"""
Wrapper for `asyncio.gather`.
"""
async def wrap_awaitable(i, f):
return i, await f
ifs = [wrap_awaitable(i, f) for i, f in enumerate(fs)]
res = [await f for f in cls.as_completed(ifs, loop=loop, timeout=timeout,
total=total, **tqdm_kwargs)]
return [i for _, i in sorted(res)]
def tarange(*args, **kwargs):
"""
A shortcut for `tqdm.asyncio.tqdm(range(*args), **kwargs)`.
"""
return tqdm_asyncio(range(*args), **kwargs)
# Aliases
tqdm = tqdm_asyncio
trange = tarange

44
_vendor/tqdm/auto.py Normal file
View File

@@ -0,0 +1,44 @@
"""
Enables multiple commonly used features.
Method resolution order:
- `tqdm.autonotebook` without import warnings
- `tqdm.asyncio` on Python3.6+
- `tqdm.std` base class
Usage:
>>> from tqdm.auto import trange, tqdm
>>> for i in trange(10):
... ...
"""
import sys
import warnings
from .std import TqdmExperimentalWarning
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=TqdmExperimentalWarning)
from .autonotebook import tqdm as notebook_tqdm
from .autonotebook import trange as notebook_trange
if sys.version_info[:2] < (3, 6):
tqdm = notebook_tqdm
trange = notebook_trange
else: # Python3.6+
from .asyncio import tqdm as asyncio_tqdm
from .std import tqdm as std_tqdm
if notebook_tqdm != std_tqdm:
class tqdm(notebook_tqdm, asyncio_tqdm): # pylint: disable=inconsistent-mro
pass
else:
tqdm = asyncio_tqdm
def trange(*args, **kwargs):
"""
A shortcut for `tqdm.auto.tqdm(range(*args), **kwargs)`.
"""
return tqdm(range(*args), **kwargs)
__all__ = ["tqdm", "trange"]

View File

@@ -0,0 +1,29 @@
"""
Automatically choose between `tqdm.notebook` and `tqdm.std`.
Usage:
>>> from tqdm.autonotebook import trange, tqdm
>>> for i in trange(10):
... ...
"""
import sys
from warnings import warn
try:
get_ipython = sys.modules['IPython'].get_ipython
if 'IPKernelApp' not in get_ipython().config: # pragma: no cover
raise ImportError("console")
from .notebook import WARN_NOIPYW, IProgress
if IProgress is None:
from .std import TqdmWarning
warn(WARN_NOIPYW, TqdmWarning, stacklevel=2)
raise ImportError('ipywidgets')
except Exception:
from .std import tqdm, trange
else: # pragma: no cover
from .notebook import tqdm, trange
from .std import TqdmExperimentalWarning
warn("Using `tqdm.autonotebook.tqdm` in notebook mode."
" Use `tqdm.tqdm` instead to force console mode"
" (e.g. in jupyter console)", TqdmExperimentalWarning, stacklevel=2)
__all__ = ["tqdm", "trange"]

315
_vendor/tqdm/cli.py Normal file
View File

@@ -0,0 +1,315 @@
"""
Module version for monitoring CLI pipes (`... | python -m tqdm | ...`).
"""
import logging
import re
import sys
from ast import literal_eval as numeric
from .std import TqdmKeyError, TqdmTypeError, tqdm
from .version import __version__
__all__ = ["main"]
log = logging.getLogger(__name__)
def cast(val, typ):
log.debug((val, typ))
if " or " in typ:
for t in typ.split(" or "):
try:
return cast(val, t)
except TqdmTypeError:
pass
raise TqdmTypeError(val + ' : ' + typ)
# sys.stderr.write('\ndebug | `val:type`: `' + val + ':' + typ + '`.\n')
if typ == 'bool':
if (val == 'True') or (val == ''):
return True
elif val == 'False':
return False
else:
raise TqdmTypeError(val + ' : ' + typ)
try:
return eval(typ + '("' + val + '")')
except Exception:
if typ == 'chr':
return chr(ord(eval('"' + val + '"'))).encode()
else:
raise TqdmTypeError(val + ' : ' + typ)
def posix_pipe(fin, fout, delim=b'\\n', buf_size=256,
callback=lambda float: None, callback_len=True):
"""
Params
------
fin : binary file with `read(buf_size : int)` method
fout : binary file with `write` (and optionally `flush`) methods.
callback : function(float), e.g.: `tqdm.update`
callback_len : If (default: True) do `callback(len(buffer))`.
Otherwise, do `callback(data) for data in buffer.split(delim)`.
"""
fp_write = fout.write
if not delim:
while True:
tmp = fin.read(buf_size)
# flush at EOF
if not tmp:
getattr(fout, 'flush', lambda: None)()
return
fp_write(tmp)
callback(len(tmp))
# return
buf = b''
len_delim = len(delim)
# n = 0
while True:
tmp = fin.read(buf_size)
# flush at EOF
if not tmp:
if buf:
fp_write(buf)
if callback_len:
# n += 1 + buf.count(delim)
callback(1 + buf.count(delim))
else:
for i in buf.split(delim):
callback(i)
getattr(fout, 'flush', lambda: None)()
return # n
while True:
i = tmp.find(delim)
if i < 0:
buf += tmp
break
fp_write(buf + tmp[:i + len(delim)])
# n += 1
callback(1 if callback_len else (buf + tmp[:i]))
buf = b''
tmp = tmp[i + len_delim:]
# ((opt, type), ... )
RE_OPTS = re.compile(r'\n {8}(\S+)\s{2,}:\s*([^,]+)')
# better split method assuming no positional args
RE_SHLEX = re.compile(r'\s*(?<!\S)--?([^\s=]+)(\s+|=|$)')
# TODO: add custom support for some of the following?
UNSUPPORTED_OPTS = ('iterable', 'gui', 'out', 'file')
# The 8 leading spaces are required for consistency
CLI_EXTRA_DOC = r"""
Extra CLI Options
-----------------
name : type, optional
TODO: find out why this is needed.
delim : chr, optional
Delimiting character [default: '\n']. Use '\0' for null.
N.B.: on Windows systems, Python converts '\n' to '\r\n'.
buf_size : int, optional
String buffer size in bytes [default: 256]
used when `delim` is specified.
bytes : bool, optional
If true, will count bytes, ignore `delim`, and default
`unit_scale` to True, `unit_divisor` to 1024, and `unit` to 'B'.
tee : bool, optional
If true, passes `stdin` to both `stderr` and `stdout`.
update : bool, optional
If true, will treat input as newly elapsed iterations,
i.e. numbers to pass to `update()`. Note that this is slow
(~2e5 it/s) since every input must be decoded as a number.
update_to : bool, optional
If true, will treat input as total elapsed iterations,
i.e. numbers to assign to `self.n`. Note that this is slow
(~2e5 it/s) since every input must be decoded as a number.
null : bool, optional
If true, will discard input (no stdout).
manpath : str, optional
Directory in which to install tqdm man pages.
comppath : str, optional
Directory in which to place tqdm completion.
log : str, optional
CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET.
"""
def main(fp=sys.stderr, argv=None):
"""
Parameters (internal use only)
---------
fp : file-like object for tqdm
argv : list (default: sys.argv[1:])
"""
if argv is None:
argv = sys.argv[1:]
try:
log_idx = argv.index('--log')
except ValueError:
for i in argv:
if i.startswith('--log='):
logLevel = i[len('--log='):]
break
else:
logLevel = 'INFO'
else:
# argv.pop(log_idx)
# logLevel = argv.pop(log_idx)
logLevel = argv[log_idx + 1]
logging.basicConfig(level=getattr(logging, logLevel),
format="%(levelname)s:%(module)s:%(lineno)d:%(message)s")
d = tqdm.__init__.__doc__ + CLI_EXTRA_DOC
opt_types = dict(RE_OPTS.findall(d))
# opt_types['delim'] = 'chr'
for o in UNSUPPORTED_OPTS:
opt_types.pop(o)
log.debug(sorted(opt_types.items()))
# d = RE_OPTS.sub(r' --\1=<\1> : \2', d)
split = RE_OPTS.split(d)
opt_types_desc = zip(split[1::3], split[2::3], split[3::3])
d = ''.join(('\n --{0} : {2}{3}' if otd[1] == 'bool' else
'\n --{0}=<{1}> : {2}{3}').format(
otd[0].replace('_', '-'), otd[0], *otd[1:])
for otd in opt_types_desc if otd[0] not in UNSUPPORTED_OPTS)
help_short = "Usage:\n tqdm [--help | options]\n"
d = help_short + """
Options:
-h, --help Print this help and exit.
-v, --version Print version and exit.
""" + d.strip('\n') + '\n'
# opts = docopt(d, version=__version__)
if any(v in argv for v in ('-v', '--version')):
sys.stdout.write(__version__ + '\n')
sys.exit(0)
elif any(v in argv for v in ('-h', '--help')):
sys.stdout.write(d + '\n')
sys.exit(0)
elif argv and argv[0][:2] != '--':
sys.stderr.write(
"Error:Unknown argument:{0}\n{1}".format(argv[0], help_short))
argv = RE_SHLEX.split(' '.join(["tqdm"] + argv))
opts = dict(zip(argv[1::3], argv[3::3]))
log.debug(opts)
opts.pop('log', True)
tqdm_args = {'file': fp}
try:
for (o, v) in opts.items():
o = o.replace('-', '_')
try:
tqdm_args[o] = cast(v, opt_types[o])
except KeyError as e:
raise TqdmKeyError(str(e))
log.debug('args:' + str(tqdm_args))
delim_per_char = tqdm_args.pop('bytes', False)
update = tqdm_args.pop('update', False)
update_to = tqdm_args.pop('update_to', False)
if sum((delim_per_char, update, update_to)) > 1:
raise TqdmKeyError("Can only have one of --bytes --update --update_to")
except Exception:
fp.write("\nError:\n" + help_short)
stdin, stdout_write = sys.stdin, sys.stdout.write
for i in stdin:
stdout_write(i)
raise
else:
buf_size = tqdm_args.pop('buf_size', 256)
delim = tqdm_args.pop('delim', b'\\n')
tee = tqdm_args.pop('tee', False)
manpath = tqdm_args.pop('manpath', None)
comppath = tqdm_args.pop('comppath', None)
if tqdm_args.pop('null', False):
class stdout(object):
@staticmethod
def write(_):
pass
else:
stdout = sys.stdout
stdout = getattr(stdout, 'buffer', stdout)
stdin = getattr(sys.stdin, 'buffer', sys.stdin)
if manpath or comppath:
from os import path
from shutil import copyfile
try: # py<3.7
import importlib_resources as resources
except ImportError:
from importlib import resources
def cp(name, dst):
"""copy resource `name` to `dst`"""
if hasattr(resources, 'files'):
copyfile(str(resources.files('tqdm') / name), dst)
else: # py<3.9
with resources.path('tqdm', name) as src:
copyfile(str(src), dst)
log.info("written:%s", dst)
if manpath is not None:
cp('tqdm.1', path.join(manpath, 'tqdm.1'))
if comppath is not None:
cp('completion.sh', path.join(comppath, 'tqdm_completion.sh'))
sys.exit(0)
if tee:
stdout_write = stdout.write
fp_write = getattr(fp, 'buffer', fp).write
class stdout(object): # pylint: disable=function-redefined
@staticmethod
def write(x):
with tqdm.external_write_mode(file=fp):
fp_write(x)
stdout_write(x)
if delim_per_char:
tqdm_args.setdefault('unit', 'B')
tqdm_args.setdefault('unit_scale', True)
tqdm_args.setdefault('unit_divisor', 1024)
log.debug(tqdm_args)
with tqdm(**tqdm_args) as t:
posix_pipe(stdin, stdout, '', buf_size, t.update)
elif delim == b'\\n':
log.debug(tqdm_args)
write = stdout.write
if update or update_to:
with tqdm(**tqdm_args) as t:
if update:
def callback(i):
t.update(numeric(i.decode()))
else: # update_to
def callback(i):
t.update(numeric(i.decode()) - t.n)
for i in stdin:
write(i)
callback(i)
else:
for i in tqdm(stdin, **tqdm_args):
write(i)
else:
log.debug(tqdm_args)
with tqdm(**tqdm_args) as t:
callback_len = False
if update:
def callback(i):
t.update(numeric(i.decode()))
elif update_to:
def callback(i):
t.update(numeric(i.decode()) - t.n)
else:
callback = t.update
callback_len = True
posix_pipe(stdin, stdout, delim, buf_size, callback, callback_len)

19
_vendor/tqdm/completion.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
_tqdm(){
local cur prv
cur="${COMP_WORDS[COMP_CWORD]}"
prv="${COMP_WORDS[COMP_CWORD - 1]}"
case ${prv} in
--bar_format|--buf_size|--colour|--comppath|--delay|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor)
# await user input
;;
"--log")
COMPREPLY=($(compgen -W 'CRITICAL FATAL ERROR WARN WARNING INFO DEBUG NOTSET' -- ${cur}))
;;
*)
COMPREPLY=($(compgen -W '--ascii --bar_format --buf_size --bytes --colour --comppath --delay --delim --desc --disable --dynamic_ncols --help --initial --leave --lock_args --log --manpath --maxinterval --mininterval --miniters --ncols --nrows --null --position --postfix --smoothing --tee --total --unit --unit_divisor --unit_scale --update --update_to --version --write_bytes -h -v' -- ${cur}))
;;
esac
}
complete -F _tqdm tqdm

View File

@@ -0,0 +1,98 @@
"""
Thin wrappers around common functions.
Subpackages contain potentially unstable extensions.
"""
import sys
from functools import wraps
from ..auto import tqdm as tqdm_auto
from ..std import tqdm
from ..utils import ObjectWrapper
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['tenumerate', 'tzip', 'tmap']
class DummyTqdmFile(ObjectWrapper):
"""Dummy file-like that will write to tqdm"""
def __init__(self, wrapped):
super(DummyTqdmFile, self).__init__(wrapped)
self._buf = []
def write(self, x, nolock=False):
nl = b"\n" if isinstance(x, bytes) else "\n"
pre, sep, post = x.rpartition(nl)
if sep:
blank = type(nl)()
tqdm.write(blank.join(self._buf + [pre, sep]),
end=blank, file=self._wrapped, nolock=nolock)
self._buf = [post]
else:
self._buf.append(x)
def __del__(self):
if self._buf:
blank = type(self._buf[0])()
try:
tqdm.write(blank.join(self._buf), end=blank, file=self._wrapped)
except (OSError, ValueError):
pass
def builtin_iterable(func):
"""Wraps `func()` output in a `list()` in py2"""
if sys.version_info[:1] < (3,):
@wraps(func)
def inner(*args, **kwargs):
return list(func(*args, **kwargs))
return inner
return func
def tenumerate(iterable, start=0, total=None, tqdm_class=tqdm_auto, **tqdm_kwargs):
"""
Equivalent of `numpy.ndenumerate` or builtin `enumerate`.
Parameters
----------
tqdm_class : [default: tqdm.auto.tqdm].
"""
try:
import numpy as np
except ImportError:
pass
else:
if isinstance(iterable, np.ndarray):
return tqdm_class(np.ndenumerate(iterable), total=total or iterable.size,
**tqdm_kwargs)
return enumerate(tqdm_class(iterable, total=total, **tqdm_kwargs), start)
@builtin_iterable
def tzip(iter1, *iter2plus, **tqdm_kwargs):
"""
Equivalent of builtin `zip`.
Parameters
----------
tqdm_class : [default: tqdm.auto.tqdm].
"""
kwargs = tqdm_kwargs.copy()
tqdm_class = kwargs.pop("tqdm_class", tqdm_auto)
for i in zip(tqdm_class(iter1, **kwargs), *iter2plus):
yield i
@builtin_iterable
def tmap(function, *sequences, **tqdm_kwargs):
"""
Equivalent of builtin `map`.
Parameters
----------
tqdm_class : [default: tqdm.auto.tqdm].
"""
for i in tzip(*sequences, **tqdm_kwargs):
yield function(*i)

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,26 @@
"""
Even more features than `tqdm.auto` (all the bells & whistles):
- `tqdm.auto`
- `tqdm.tqdm.pandas`
- `tqdm.contrib.telegram`
+ uses `${TQDM_TELEGRAM_TOKEN}` and `${TQDM_TELEGRAM_CHAT_ID}`
- `tqdm.contrib.discord`
+ uses `${TQDM_DISCORD_TOKEN}` and `${TQDM_DISCORD_CHANNEL_ID}`
"""
__all__ = ['tqdm', 'trange']
import warnings
from os import getenv
if getenv("TQDM_SLACK_TOKEN") and getenv("TQDM_SLACK_CHANNEL"):
from .slack import tqdm, trange
elif getenv("TQDM_TELEGRAM_TOKEN") and getenv("TQDM_TELEGRAM_CHAT_ID"):
from .telegram import tqdm, trange
elif getenv("TQDM_DISCORD_TOKEN") and getenv("TQDM_DISCORD_CHANNEL_ID"):
from .discord import tqdm, trange
else:
from ..auto import tqdm, trange
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=FutureWarning)
tqdm.pandas()

View File

@@ -0,0 +1,130 @@
"""
Thin wrappers around `concurrent.futures`.
"""
from __future__ import absolute_import
from contextlib import contextmanager
from ..auto import tqdm as tqdm_auto
from ..std import TqdmWarning
try:
from operator import length_hint
except ImportError:
def length_hint(it, default=0):
"""Returns `len(it)`, falling back to `default`"""
try:
return len(it)
except TypeError:
return default
try:
from os import cpu_count
except ImportError:
try:
from multiprocessing import cpu_count
except ImportError:
def cpu_count():
return 4
import sys
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['thread_map', 'process_map']
@contextmanager
def ensure_lock(tqdm_class, lock_name=""):
"""get (create if necessary) and then restore `tqdm_class`'s lock"""
old_lock = getattr(tqdm_class, '_lock', None) # don't create a new lock
lock = old_lock or tqdm_class.get_lock() # maybe create a new lock
lock = getattr(lock, lock_name, lock) # maybe subtype
tqdm_class.set_lock(lock)
yield lock
if old_lock is None:
del tqdm_class._lock
else:
tqdm_class.set_lock(old_lock)
def _executor_map(PoolExecutor, fn, *iterables, **tqdm_kwargs):
"""
Implementation of `thread_map` and `process_map`.
Parameters
----------
tqdm_class : [default: tqdm.auto.tqdm].
max_workers : [default: min(32, cpu_count() + 4)].
chunksize : [default: 1].
lock_name : [default: "":str].
"""
kwargs = tqdm_kwargs.copy()
if "total" not in kwargs:
kwargs["total"] = length_hint(iterables[0])
tqdm_class = kwargs.pop("tqdm_class", tqdm_auto)
max_workers = kwargs.pop("max_workers", min(32, cpu_count() + 4))
chunksize = kwargs.pop("chunksize", 1)
lock_name = kwargs.pop("lock_name", "")
with ensure_lock(tqdm_class, lock_name=lock_name) as lk:
pool_kwargs = {'max_workers': max_workers}
sys_version = sys.version_info[:2]
if sys_version >= (3, 7):
# share lock in case workers are already using `tqdm`
pool_kwargs.update(initializer=tqdm_class.set_lock, initargs=(lk,))
map_args = {}
if not (3, 0) < sys_version < (3, 5):
map_args.update(chunksize=chunksize)
with PoolExecutor(**pool_kwargs) as ex:
return list(tqdm_class(ex.map(fn, *iterables, **map_args), **kwargs))
def thread_map(fn, *iterables, **tqdm_kwargs):
"""
Equivalent of `list(map(fn, *iterables))`
driven by `concurrent.futures.ThreadPoolExecutor`.
Parameters
----------
tqdm_class : optional
`tqdm` class to use for bars [default: tqdm.auto.tqdm].
max_workers : int, optional
Maximum number of workers to spawn; passed to
`concurrent.futures.ThreadPoolExecutor.__init__`.
[default: max(32, cpu_count() + 4)].
"""
from concurrent.futures import ThreadPoolExecutor
return _executor_map(ThreadPoolExecutor, fn, *iterables, **tqdm_kwargs)
def process_map(fn, *iterables, **tqdm_kwargs):
"""
Equivalent of `list(map(fn, *iterables))`
driven by `concurrent.futures.ProcessPoolExecutor`.
Parameters
----------
tqdm_class : optional
`tqdm` class to use for bars [default: tqdm.auto.tqdm].
max_workers : int, optional
Maximum number of workers to spawn; passed to
`concurrent.futures.ProcessPoolExecutor.__init__`.
[default: min(32, cpu_count() + 4)].
chunksize : int, optional
Size of chunks sent to worker processes; passed to
`concurrent.futures.ProcessPoolExecutor.map`. [default: 1].
lock_name : str, optional
Member of `tqdm_class.get_lock()` to use [default: mp_lock].
"""
from concurrent.futures import ProcessPoolExecutor
if iterables and "chunksize" not in tqdm_kwargs:
# default `chunksize=1` has poor performance for large iterables
# (most time spent dispatching items to workers).
longest_iterable_len = max(map(length_hint, iterables))
if longest_iterable_len > 1000:
from warnings import warn
warn("Iterable length %d > 1000 but `chunksize` is not set."
" This may seriously degrade multiprocess performance."
" Set `chunksize=1` or more." % longest_iterable_len,
TqdmWarning, stacklevel=2)
if "lock_name" not in tqdm_kwargs:
tqdm_kwargs = tqdm_kwargs.copy()
tqdm_kwargs["lock_name"] = "mp_lock"
return _executor_map(ProcessPoolExecutor, fn, *iterables, **tqdm_kwargs)

View File

@@ -0,0 +1,125 @@
"""
Sends updates to a Discord bot.
Usage:
>>> from tqdm.contrib.discord import tqdm, trange
>>> for i in trange(10, token='{token}', channel_id='{channel_id}'):
... ...
![screenshot](https://img.tqdm.ml/screenshot-discord.png)
"""
from __future__ import absolute_import
import logging
from os import getenv
try:
from disco.client import Client, ClientConfig
except ImportError:
raise ImportError("Please `pip install disco-py`")
from ..auto import tqdm as tqdm_auto
from ..utils import _range
from .utils_worker import MonoWorker
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['DiscordIO', 'tqdm_discord', 'tdrange', 'tqdm', 'trange']
class DiscordIO(MonoWorker):
"""Non-blocking file-like IO using a Discord Bot."""
def __init__(self, token, channel_id):
"""Creates a new message in the given `channel_id`."""
super(DiscordIO, self).__init__()
config = ClientConfig()
config.token = token
client = Client(config)
self.text = self.__class__.__name__
try:
self.message = client.api.channels_messages_create(channel_id, self.text)
except Exception as e:
tqdm_auto.write(str(e))
self.message = None
def write(self, s):
"""Replaces internal `message`'s text with `s`."""
if not s:
s = "..."
s = s.replace('\r', '').strip()
if s == self.text:
return # skip duplicate message
message = self.message
if message is None:
return
self.text = s
try:
future = self.submit(message.edit, '`' + s + '`')
except Exception as e:
tqdm_auto.write(str(e))
else:
return future
class tqdm_discord(tqdm_auto):
"""
Standard `tqdm.auto.tqdm` but also sends updates to a Discord Bot.
May take a few seconds to create (`__init__`).
- create a discord bot (not public, no requirement of OAuth2 code
grant, only send message permissions) & invite it to a channel:
<https://discordpy.readthedocs.io/en/latest/discord.html>
- copy the bot `{token}` & `{channel_id}` and paste below
>>> from tqdm.contrib.discord import tqdm, trange
>>> for i in tqdm(iterable, token='{token}', channel_id='{channel_id}'):
... ...
"""
def __init__(self, *args, **kwargs):
"""
Parameters
----------
token : str, required. Discord token
[default: ${TQDM_DISCORD_TOKEN}].
channel_id : int, required. Discord channel ID
[default: ${TQDM_DISCORD_CHANNEL_ID}].
mininterval : float, optional.
Minimum of [default: 1.5] to avoid rate limit.
See `tqdm.auto.tqdm.__init__` for other parameters.
"""
if not kwargs.get('disable'):
kwargs = kwargs.copy()
logging.getLogger("HTTPClient").setLevel(logging.WARNING)
self.dio = DiscordIO(
kwargs.pop('token', getenv("TQDM_DISCORD_TOKEN")),
kwargs.pop('channel_id', getenv("TQDM_DISCORD_CHANNEL_ID")))
kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5))
super(tqdm_discord, self).__init__(*args, **kwargs)
def display(self, **kwargs):
super(tqdm_discord, self).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):
super(tqdm_discord, self).clear(*args, **kwargs)
if not self.disable:
self.dio.write("")
def tdrange(*args, **kwargs):
"""
A shortcut for `tqdm.contrib.discord.tqdm(xrange(*args), **kwargs)`.
On Python3+, `range` is used instead of `xrange`.
"""
return tqdm_discord(_range(*args), **kwargs)
# Aliases
tqdm = tqdm_discord
trange = tdrange

View File

@@ -0,0 +1,37 @@
"""
Thin wrappers around `itertools`.
"""
from __future__ import absolute_import
import itertools
from ..auto import tqdm as tqdm_auto
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['product']
def product(*iterables, **tqdm_kwargs):
"""
Equivalent of `itertools.product`.
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()

View File

@@ -0,0 +1,128 @@
"""
Helper functionality for interoperability with stdlib `logging`.
"""
from __future__ import absolute_import
import logging
import sys
from contextlib import contextmanager
try:
from typing import Iterator, List, Optional, Type # pylint: disable=unused-import
except ImportError:
pass
from ..std import tqdm as std_tqdm
class _TqdmLoggingHandler(logging.StreamHandler):
def __init__(
self,
tqdm_class=std_tqdm # type: Type[std_tqdm]
):
super(_TqdmLoggingHandler, self).__init__()
self.tqdm_class = tqdm_class
def emit(self, record):
try:
msg = self.format(record)
self.tqdm_class.write(msg, file=self.stream)
self.flush()
except (KeyboardInterrupt, SystemExit):
raise
except: # noqa pylint: disable=bare-except
self.handleError(record)
def _is_console_logging_handler(handler):
return (isinstance(handler, logging.StreamHandler)
and handler.stream in {sys.stdout, sys.stderr})
def _get_first_found_console_logging_handler(handlers):
for handler in handlers:
if _is_console_logging_handler(handler):
return handler
@contextmanager
def logging_redirect_tqdm(
loggers=None, # type: Optional[List[logging.Logger]],
tqdm_class=std_tqdm # type: Type[std_tqdm]
):
# type: (...) -> Iterator[None]
"""
Context manager redirecting console logging to `tqdm.write()`, leaving
other logging handlers (e.g. log files) unaffected.
Parameters
----------
loggers : list, optional
Which handlers to redirect (default: [logging.root]).
tqdm_class : optional
Example
-------
```python
import logging
from tqdm import trange
from tqdm.contrib.logging import logging_redirect_tqdm
LOG = logging.getLogger(__name__)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
with logging_redirect_tqdm():
for i in trange(9):
if i == 4:
LOG.info("console logging redirected to `tqdm.write()`")
# logging restored
```
"""
if loggers is None:
loggers = [logging.root]
original_handlers_list = [logger.handlers for logger in loggers]
try:
for logger in loggers:
tqdm_handler = _TqdmLoggingHandler(tqdm_class)
orig_handler = _get_first_found_console_logging_handler(logger.handlers)
if orig_handler is not None:
tqdm_handler.setFormatter(orig_handler.formatter)
tqdm_handler.stream = orig_handler.stream
logger.handlers = [
handler for handler in logger.handlers
if not _is_console_logging_handler(handler)] + [tqdm_handler]
yield
finally:
for logger, original_handlers in zip(loggers, original_handlers_list):
logger.handlers = original_handlers
@contextmanager
def tqdm_logging_redirect(
*args,
# loggers=None, # type: Optional[List[logging.Logger]]
# tqdm=None, # type: Optional[Type[tqdm.tqdm]]
**kwargs
):
# type: (...) -> Iterator[None]
"""
Convenience shortcut for:
```python
with tqdm_class(*args, **tqdm_kwargs) as pbar:
with logging_redirect_tqdm(loggers=loggers, tqdm_class=tqdm_class):
yield pbar
```
Parameters
----------
tqdm_class : optional, (default: tqdm.std.tqdm).
loggers : optional, list.
**tqdm_kwargs : passed to `tqdm_class`.
"""
tqdm_kwargs = kwargs.copy()
loggers = tqdm_kwargs.pop('loggers', None)
tqdm_class = tqdm_kwargs.pop('tqdm_class', std_tqdm)
with tqdm_class(*args, **tqdm_kwargs) as pbar:
with logging_redirect_tqdm(loggers=loggers, tqdm_class=tqdm_class):
yield pbar

View File

@@ -0,0 +1,126 @@
"""
Sends updates to a Slack app.
Usage:
>>> from tqdm.contrib.slack import tqdm, trange
>>> for i in trange(10, token='{token}', channel='{channel}'):
... ...
![screenshot](https://img.tqdm.ml/screenshot-slack.png)
"""
from __future__ import absolute_import
import logging
from os import getenv
try:
from slack_sdk import WebClient
except ImportError:
raise ImportError("Please `pip install slack-sdk`")
from ..auto import tqdm as tqdm_auto
from ..utils import _range
from .utils_worker import MonoWorker
__author__ = {"github.com/": ["0x2b3bfa0", "casperdcl"]}
__all__ = ['SlackIO', 'tqdm_slack', 'tsrange', 'tqdm', 'trange']
class SlackIO(MonoWorker):
"""Non-blocking file-like IO using a Slack app."""
def __init__(self, token, channel):
"""Creates a new message in the given `channel`."""
super(SlackIO, self).__init__()
self.client = WebClient(token=token)
self.text = self.__class__.__name__
try:
self.message = self.client.chat_postMessage(channel=channel, text=self.text)
except Exception as e:
tqdm_auto.write(str(e))
self.message = None
def write(self, s):
"""Replaces internal `message`'s text with `s`."""
if not s:
s = "..."
s = s.replace('\r', '').strip()
if s == self.text:
return # skip duplicate message
message = self.message
if message is None:
return
self.text = s
try:
future = self.submit(self.client.chat_update, channel=message['channel'],
ts=message['ts'], text='`' + s + '`')
except Exception as e:
tqdm_auto.write(str(e))
else:
return future
class tqdm_slack(tqdm_auto):
"""
Standard `tqdm.auto.tqdm` but also sends updates to a Slack app.
May take a few seconds to create (`__init__`).
- create a Slack app with the `chat:write` scope & invite it to a
channel: <https://api.slack.com/authentication/basics>
- copy the bot `{token}` & `{channel}` and paste below
>>> from tqdm.contrib.slack import tqdm, trange
>>> for i in tqdm(iterable, token='{token}', channel='{channel}'):
... ...
"""
def __init__(self, *args, **kwargs):
"""
Parameters
----------
token : str, required. Slack token
[default: ${TQDM_SLACK_TOKEN}].
channel : int, required. Slack channel
[default: ${TQDM_SLACK_CHANNEL}].
mininterval : float, optional.
Minimum of [default: 1.5] to avoid rate limit.
See `tqdm.auto.tqdm.__init__` for other parameters.
"""
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")))
kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5))
super(tqdm_slack, self).__init__(*args, **kwargs)
def display(self, **kwargs):
super(tqdm_slack, self).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:
fmt['bar_format'] = '{l_bar}`{bar:10}`{r_bar}'
if fmt['ascii'] is False:
fmt['ascii'] = [":black_square:", ":small_blue_diamond:", ":large_blue_diamond:",
":large_blue_square:"]
fmt['ncols'] = 336
self.sio.write(self.format_meter(**fmt))
def clear(self, *args, **kwargs):
super(tqdm_slack, self).clear(*args, **kwargs)
if not self.disable:
self.sio.write("")
def tsrange(*args, **kwargs):
"""
A shortcut for `tqdm.contrib.slack.tqdm(xrange(*args), **kwargs)`.
On Python3+, `range` is used instead of `xrange`.
"""
return tqdm_slack(_range(*args), **kwargs)
# Aliases
tqdm = tqdm_slack
trange = tsrange

View File

@@ -0,0 +1,159 @@
"""
Sends updates to a Telegram bot.
Usage:
>>> from tqdm.contrib.telegram import tqdm, trange
>>> for i in trange(10, token='{token}', chat_id='{chat_id}'):
... ...
![screenshot](https://img.tqdm.ml/screenshot-telegram.gif)
"""
from __future__ import absolute_import
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 _range
from .utils_worker import MonoWorker
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['TelegramIO', 'tqdm_telegram', 'ttgrange', 'tqdm', 'trange']
class TelegramIO(MonoWorker):
"""Non-blocking file-like IO using a Telegram Bot."""
API = 'https://api.telegram.org/bot'
def __init__(self, token, chat_id):
"""Creates a new message in the given `chat_id`."""
super(TelegramIO, self).__init__()
self.token = token
self.chat_id = chat_id
self.session = Session()
self.text = self.__class__.__name__
self.message_id
@property
def message_id(self):
if hasattr(self, '_message_id'):
return self._message_id
try:
res = self.session.post(
self.API + '%s/sendMessage' % self.token,
data={'text': '`' + self.text + '`', 'chat_id': self.chat_id,
'parse_mode': 'MarkdownV2'}).json()
except Exception as e:
tqdm_auto.write(str(e))
else:
if res.get('error_code') == 429:
warn("Creation rate limit: try increasing `mininterval`.",
TqdmWarning, stacklevel=2)
else:
self._message_id = res['result']['message_id']
return self._message_id
def write(self, s):
"""Replaces internal `message_id`'s text with `s`."""
if not s:
s = "..."
s = s.replace('\r', '').strip()
if s == self.text:
return # avoid duplicate message Bot error
message_id = self.message_id
if message_id is None:
return
self.text = s
try:
future = self.submit(
self.session.post, self.API + '%s/editMessageText' % self.token,
data={'text': '`' + s + '`', 'chat_id': self.chat_id,
'message_id': message_id, 'parse_mode': 'MarkdownV2'})
except Exception as e:
tqdm_auto.write(str(e))
else:
return future
def delete(self):
"""Deletes internal `message_id`."""
try:
future = self.submit(
self.session.post, self.API + '%s/deleteMessage' % self.token,
data={'chat_id': self.chat_id, 'message_id': self.message_id})
except Exception as e:
tqdm_auto.write(str(e))
else:
return future
class tqdm_telegram(tqdm_auto):
"""
Standard `tqdm.auto.tqdm` but also sends updates to a Telegram Bot.
May take a few seconds to create (`__init__`).
- create a bot <https://core.telegram.org/bots#6-botfather>
- copy its `{token}`
- add the bot to a chat and send it a message such as `/start`
- go to <https://api.telegram.org/bot`{token}`/getUpdates> to find out
the `{chat_id}`
- paste the `{token}` & `{chat_id}` below
>>> from tqdm.contrib.telegram import tqdm, trange
>>> for i in tqdm(iterable, token='{token}', chat_id='{chat_id}'):
... ...
"""
def __init__(self, *args, **kwargs):
"""
Parameters
----------
token : str, required. Telegram token
[default: ${TQDM_TELEGRAM_TOKEN}].
chat_id : str, required. Telegram chat ID
[default: ${TQDM_TELEGRAM_CHAT_ID}].
See `tqdm.auto.tqdm.__init__` for other parameters.
"""
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')))
super(tqdm_telegram, self).__init__(*args, **kwargs)
def display(self, **kwargs):
super(tqdm_telegram, self).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):
super(tqdm_telegram, self).clear(*args, **kwargs)
if not self.disable:
self.tgio.write("")
def close(self):
if self.disable:
return
super(tqdm_telegram, self).close()
if not (self.leave or (self.leave is None and self.pos == 0)):
self.tgio.delete()
def ttgrange(*args, **kwargs):
"""
A shortcut for `tqdm.contrib.telegram.tqdm(xrange(*args), **kwargs)`.
On Python3+, `range` is used instead of `xrange`.
"""
return tqdm_telegram(_range(*args), **kwargs)
# Aliases
tqdm = tqdm_telegram
trange = ttgrange

View File

@@ -0,0 +1,40 @@
"""
IO/concurrency helpers for `tqdm.contrib`.
"""
from __future__ import absolute_import
from collections import deque
from concurrent.futures import ThreadPoolExecutor
from ..auto import tqdm as tqdm_auto
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['MonoWorker']
class MonoWorker(object):
"""
Supports one running task and one waiting task.
The waiting task is the most recent submitted (others are discarded).
"""
def __init__(self):
self.pool = ThreadPoolExecutor(max_workers=1)
self.futures = deque([], 2)
def submit(self, func, *args, **kwargs):
"""`func(*args, **kwargs)` may replace currently waiting task."""
futures = self.futures
if len(futures) == futures.maxlen:
running = futures.popleft()
if not running.done():
if len(futures): # clear waiting
waiting = futures.pop()
waiting.cancel()
futures.appendleft(running) # re-insert running
try:
waiting = self.pool.submit(func, *args, **kwargs)
except Exception as e:
tqdm_auto.write(str(e))
else:
futures.append(waiting)
return waiting

46
_vendor/tqdm/dask.py Normal file
View File

@@ -0,0 +1,46 @@
from __future__ import absolute_import
from functools import partial
from dask.callbacks import Callback
from .auto import tqdm as tqdm_auto
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['TqdmCallback']
class TqdmCallback(Callback):
"""Dask callback for task progress."""
def __init__(self, start=None, pretask=None, tqdm_class=tqdm_auto,
**tqdm_kwargs):
"""
Parameters
----------
tqdm_class : optional
`tqdm` class to use for bars [default: `tqdm.auto.tqdm`].
tqdm_kwargs : optional
Any other arguments used for all bars.
"""
super(TqdmCallback, self).__init__(start=start, pretask=pretask)
if tqdm_kwargs:
tqdm_class = partial(tqdm_class, **tqdm_kwargs)
self.tqdm_class = tqdm_class
def _start_state(self, _, state):
self.pbar = self.tqdm_class(total=sum(
len(state[k]) for k in ['ready', 'waiting', 'running', 'finished']))
def _posttask(self, *_, **__):
self.pbar.update()
def _finish(self, *_, **__):
self.pbar.close()
def display(self):
"""Displays in the current cell in Notebooks."""
container = getattr(self.bar, 'container', None)
if container is None:
return
from .notebook import display
display(container)

191
_vendor/tqdm/gui.py Normal file
View File

@@ -0,0 +1,191 @@
"""
Matplotlib GUI progressbar decorator for iterators.
Usage:
>>> from tqdm.gui import trange, tqdm
>>> for i in trange(10):
... ...
"""
# future division is important to divide integers and get as
# a result precise floating numbers (instead of truncated int)
from __future__ import absolute_import, division
import re
from warnings import warn
# to inherit from the tqdm class
from .std import TqdmExperimentalWarning
from .std import tqdm as std_tqdm
# import compatibility functions and utilities
from .utils import _range
__author__ = {"github.com/": ["casperdcl", "lrq3000"]}
__all__ = ['tqdm_gui', 'tgrange', 'tqdm', 'trange']
class tqdm_gui(std_tqdm): # pragma: no cover
"""Experimental Matplotlib GUI version of tqdm!"""
# TODO: @classmethod: write() on GUI?
def __init__(self, *args, **kwargs):
from collections import deque
import matplotlib as mpl
import matplotlib.pyplot as plt
kwargs = kwargs.copy()
kwargs['gui'] = True
colour = kwargs.pop('colour', 'g')
super(tqdm_gui, self).__init__(*args, **kwargs)
if self.disable:
return
warn("GUI is experimental/alpha", TqdmExperimentalWarning, stacklevel=2)
self.mpl = mpl
self.plt = plt
# Remember if external environment uses toolbars
self.toolbar = self.mpl.rcParams['toolbar']
self.mpl.rcParams['toolbar'] = 'None'
self.mininterval = max(self.mininterval, 0.5)
self.fig, ax = plt.subplots(figsize=(9, 2.2))
# self.fig.subplots_adjust(bottom=0.2)
total = self.__len__() # avoids TypeError on None #971
if total is not None:
self.xdata = []
self.ydata = []
self.zdata = []
else:
self.xdata = deque([])
self.ydata = deque([])
self.zdata = deque([])
self.line1, = ax.plot(self.xdata, self.ydata, color='b')
self.line2, = ax.plot(self.xdata, self.zdata, color='k')
ax.set_ylim(0, 0.001)
if total is not None:
ax.set_xlim(0, 100)
ax.set_xlabel("percent")
self.fig.legend((self.line1, self.line2), ("cur", "est"),
loc='center right')
# progressbar
self.hspan = plt.axhspan(0, 0.001, xmin=0, xmax=0, color=colour)
else:
# ax.set_xlim(-60, 0)
ax.set_xlim(0, 60)
ax.invert_xaxis()
ax.set_xlabel("seconds")
ax.legend(("cur", "est"), loc='lower left')
ax.grid()
# ax.set_xlabel('seconds')
ax.set_ylabel((self.unit if self.unit else "it") + "/s")
if self.unit_scale:
plt.ticklabel_format(style='sci', axis='y', scilimits=(0, 0))
ax.yaxis.get_offset_text().set_x(-0.15)
# Remember if external environment is interactive
self.wasion = plt.isinteractive()
plt.ion()
self.ax = ax
def close(self):
if self.disable:
return
self.disable = True
with self.get_lock():
self._instances.remove(self)
# Restore toolbars
self.mpl.rcParams['toolbar'] = self.toolbar
# Return to non-interactive mode
if not self.wasion:
self.plt.ioff()
if self.leave:
self.display()
else:
self.plt.close(self.fig)
def clear(self, *_, **__):
pass
def display(self, *_, **__):
n = self.n
cur_t = self._time()
elapsed = cur_t - self.start_t
delta_it = n - self.last_print_n
delta_t = cur_t - self.last_print_t
# Inline due to multiple calls
total = self.total
xdata = self.xdata
ydata = self.ydata
zdata = self.zdata
ax = self.ax
line1 = self.line1
line2 = self.line2
# instantaneous rate
y = delta_it / delta_t
# overall rate
z = n / elapsed
# update line data
xdata.append(n * 100.0 / total if total else cur_t)
ydata.append(y)
zdata.append(z)
# Discard old values
# xmin, xmax = ax.get_xlim()
# if (not total) and elapsed > xmin * 1.1:
if (not total) and elapsed > 66:
xdata.popleft()
ydata.popleft()
zdata.popleft()
ymin, ymax = ax.get_ylim()
if y > ymax or z > ymax:
ymax = 1.1 * y
ax.set_ylim(ymin, ymax)
ax.figure.canvas.draw()
if total:
line1.set_data(xdata, ydata)
line2.set_data(xdata, zdata)
try:
poly_lims = self.hspan.get_xy()
except AttributeError:
self.hspan = self.plt.axhspan(0, 0.001, xmin=0, xmax=0, color='g')
poly_lims = self.hspan.get_xy()
poly_lims[0, 1] = ymin
poly_lims[1, 1] = ymax
poly_lims[2] = [n / total, ymax]
poly_lims[3] = [poly_lims[2, 0], ymin]
if len(poly_lims) > 4:
poly_lims[4, 1] = ymin
self.hspan.set_xy(poly_lims)
else:
t_ago = [cur_t - i for i in xdata]
line1.set_data(t_ago, ydata)
line2.set_data(t_ago, zdata)
d = self.format_dict
# remove {bar}
d['bar_format'] = (d['bar_format'] or "{l_bar}<bar/>{r_bar}").replace(
"{bar}", "<bar/>")
msg = self.format_meter(**d)
if '<bar/>' in msg:
msg = "".join(re.split(r'\|?<bar/>\|?', msg, 1))
ax.set_title(msg, fontname="DejaVu Sans Mono", fontsize=11)
self.plt.pause(1e-9)
def tgrange(*args, **kwargs):
"""
A shortcut for `tqdm.gui.tqdm(xrange(*args), **kwargs)`.
On Python3+, `range` is used instead of `xrange`.
"""
return tqdm_gui(_range(*args), **kwargs)
# Aliases
tqdm = tqdm_gui
trange = tgrange

124
_vendor/tqdm/keras.py Normal file
View File

@@ -0,0 +1,124 @@
from __future__ import absolute_import, division
from copy import copy
from functools import partial
from .auto import tqdm as tqdm_auto
try:
import keras
except (ImportError, AttributeError) as e:
try:
from tensorflow import keras
except ImportError:
raise e
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['TqdmCallback']
class TqdmCallback(keras.callbacks.Callback):
"""Keras callback for epoch and batch progress."""
@staticmethod
def bar2callback(bar, pop=None, delta=(lambda logs: 1)):
def callback(_, logs=None):
n = delta(logs)
if logs:
if pop:
logs = copy(logs)
[logs.pop(i, 0) for i in pop]
bar.set_postfix(logs, refresh=False)
bar.update(n)
return callback
def __init__(self, epochs=None, data_size=None, batch_size=None, verbose=1,
tqdm_class=tqdm_auto, **tqdm_kwargs):
"""
Parameters
----------
epochs : int, optional
data_size : int, optional
Number of training pairs.
batch_size : int, optional
Number of training pairs per batch.
verbose : int
0: epoch, 1: batch (transient), 2: batch. [default: 1].
Will be set to `0` unless both `data_size` and `batch_size`
are given.
tqdm_class : optional
`tqdm` class to use for bars [default: `tqdm.auto.tqdm`].
tqdm_kwargs : optional
Any other arguments used for all bars.
"""
if tqdm_kwargs:
tqdm_class = partial(tqdm_class, **tqdm_kwargs)
self.tqdm_class = tqdm_class
self.epoch_bar = tqdm_class(total=epochs, unit='epoch')
self.on_epoch_end = self.bar2callback(self.epoch_bar)
if data_size and batch_size:
self.batches = batches = (data_size + batch_size - 1) // batch_size
else:
self.batches = batches = None
self.verbose = verbose
if verbose == 1:
self.batch_bar = tqdm_class(total=batches, unit='batch', leave=False)
self.on_batch_end = self.bar2callback(
self.batch_bar, pop=['batch', 'size'],
delta=lambda logs: logs.get('size', 1))
def on_train_begin(self, *_, **__):
params = self.params.get
auto_total = params('epochs', params('nb_epoch', None))
if auto_total is not None and auto_total != self.epoch_bar.total:
self.epoch_bar.reset(total=auto_total)
def on_epoch_begin(self, epoch, *_, **__):
if self.epoch_bar.n < epoch:
ebar = self.epoch_bar
ebar.n = ebar.last_print_n = ebar.initial = epoch
if self.verbose:
params = self.params.get
total = params('samples', params(
'nb_sample', params('steps', None))) or self.batches
if self.verbose == 2:
if hasattr(self, 'batch_bar'):
self.batch_bar.close()
self.batch_bar = self.tqdm_class(
total=total, unit='batch', leave=True,
unit_scale=1 / (params('batch_size', 1) or 1))
self.on_batch_end = self.bar2callback(
self.batch_bar, pop=['batch', 'size'],
delta=lambda logs: logs.get('size', 1))
elif self.verbose == 1:
self.batch_bar.unit_scale = 1 / (params('batch_size', 1) or 1)
self.batch_bar.reset(total=total)
else:
raise KeyError('Unknown verbosity')
def on_train_end(self, *_, **__):
if self.verbose:
self.batch_bar.close()
self.epoch_bar.close()
def display(self):
"""Displays in the current cell in Notebooks."""
container = getattr(self.epoch_bar, 'container', None)
if container is None:
return
from .notebook import display
display(container)
batch_bar = getattr(self, 'batch_bar', None)
if batch_bar is not None:
display(batch_bar.container)
@staticmethod
def _implements_train_batch_hooks():
return True
@staticmethod
def _implements_test_batch_hooks():
return True
@staticmethod
def _implements_predict_batch_hooks():
return True

329
_vendor/tqdm/notebook.py Normal file
View File

@@ -0,0 +1,329 @@
"""
IPython/Jupyter Notebook progressbar decorator for iterators.
Includes a default `range` iterator printing to `stderr`.
Usage:
>>> from tqdm.notebook import trange, tqdm
>>> for i in trange(10):
... ...
"""
# future division is important to divide integers and get as
# a result precise floating numbers (instead of truncated int)
from __future__ import absolute_import, division
# import compatibility functions and utilities
import re
import sys
from weakref import proxy
# to inherit from the tqdm class
from .std import tqdm as std_tqdm
from .utils import _range
if True: # pragma: no cover
# import IPython/Jupyter base widget and display utilities
IPY = 0
try: # IPython 4.x
import ipywidgets
IPY = 4
except ImportError: # IPython 3.x / 2.x
IPY = 32
import warnings
with warnings.catch_warnings():
warnings.filterwarnings(
'ignore', message=".*The `IPython.html` package has been deprecated.*")
try:
import IPython.html.widgets as ipywidgets # NOQA: F401
except ImportError:
pass
try: # IPython 4.x / 3.x
if IPY == 32:
from IPython.html.widgets import HTML
from IPython.html.widgets import FloatProgress as IProgress
from IPython.html.widgets import HBox
IPY = 3
else:
from ipywidgets import HTML
from ipywidgets import FloatProgress as IProgress
from ipywidgets import HBox
except ImportError:
try: # IPython 2.x
from IPython.html.widgets import HTML
from IPython.html.widgets import ContainerWidget as HBox
from IPython.html.widgets import FloatProgressWidget as IProgress
IPY = 2
except ImportError:
IPY = 0
IProgress = None
HBox = object
try:
from IPython.display import display # , clear_output
except ImportError:
pass
# HTML encoding
try: # Py3
from html import escape
except ImportError: # Py2
from cgi import escape
__author__ = {"github.com/": ["lrq3000", "casperdcl", "alexanderkuk"]}
__all__ = ['tqdm_notebook', 'tnrange', 'tqdm', 'trange']
WARN_NOIPYW = ("IProgress not found. Please update jupyter and ipywidgets."
" See https://ipywidgets.readthedocs.io/en/stable"
"/user_install.html")
class TqdmHBox(HBox):
"""`ipywidgets.HBox` with a pretty representation"""
def _json_(self, pretty=None):
pbar = getattr(self, 'pbar', None)
if pbar is None:
return {}
d = pbar.format_dict
if pretty is not None:
d["ascii"] = not pretty
return d
def __repr__(self, pretty=False):
pbar = getattr(self, 'pbar', None)
if pbar is None:
return super(TqdmHBox, self).__repr__()
return pbar.format_meter(**self._json_(pretty))
def _repr_pretty_(self, pp, *_, **__):
pp.text(self.__repr__(True))
class tqdm_notebook(std_tqdm):
"""
Experimental IPython/Jupyter Notebook widget using tqdm!
"""
@staticmethod
def status_printer(_, total=None, desc=None, ncols=None):
"""
Manage the printing of an IPython/Jupyter Notebook progress bar widget.
"""
# Fallback to text bar if there's no total
# DEPRECATED: replaced with an 'info' style bar
# if not total:
# return super(tqdm_notebook, tqdm_notebook).status_printer(file)
# fp = file
# Prepare IPython progress bar
if IProgress is None: # #187 #451 #558 #872
raise ImportError(WARN_NOIPYW)
if total:
pbar = IProgress(min=0, max=total)
else: # No total? Show info style bar with no progress tqdm status
pbar = IProgress(min=0, max=1)
pbar.value = 1
pbar.bar_style = 'info'
if ncols is None:
pbar.layout.width = "20px"
ltext = HTML()
rtext = HTML()
if desc:
ltext.value = desc
container = TqdmHBox(children=[ltext, pbar, rtext])
# Prepare layout
if ncols is not None: # use default style of ipywidgets
# ncols could be 100, "100px", "100%"
ncols = str(ncols) # ipywidgets only accepts string
try:
if int(ncols) > 0: # isnumeric and positive
ncols += 'px'
except ValueError:
pass
pbar.layout.flex = '2'
container.layout.width = ncols
container.layout.display = 'inline-flex'
container.layout.flex_flow = 'row wrap'
return container
def display(self, msg=None, pos=None,
# additional signals
close=False, bar_style=None, check_delay=True):
# Note: contrary to native tqdm, msg='' does NOT clear bar
# goal is to keep all infos if error happens so user knows
# at which iteration the loop failed.
# Clear previous output (really necessary?)
# clear_output(wait=1)
if not msg and not close:
d = self.format_dict
# remove {bar}
d['bar_format'] = (d['bar_format'] or "{l_bar}<bar/>{r_bar}").replace(
"{bar}", "<bar/>")
msg = self.format_meter(**d)
ltext, pbar, rtext = self.container.children
pbar.value = self.n
if msg:
# html escape special characters (like '&')
if '<bar/>' in msg:
left, right = map(escape, re.split(r'\|?<bar/>\|?', msg, 1))
else:
left, right = '', escape(msg)
# Update description
ltext.value = left
# never clear the bar (signal: msg='')
if right:
rtext.value = right
# Change bar style
if bar_style:
# Hack-ish way to avoid the danger bar_style being overridden by
# success because the bar gets closed after the error...
if pbar.bar_style != 'danger' or bar_style != 'success':
pbar.bar_style = bar_style
# Special signal to close the bar
if close and pbar.bar_style != 'danger': # hide only if no error
try:
self.container.close()
except AttributeError:
self.container.visible = False
self.container.layout.visibility = 'hidden' # IPYW>=8
if check_delay and self.delay > 0 and not self.displayed:
display(self.container)
self.displayed = True
@property
def colour(self):
if hasattr(self, 'container'):
return self.container.children[-2].style.bar_color
@colour.setter
def colour(self, bar_color):
if hasattr(self, 'container'):
self.container.children[-2].style.bar_color = bar_color
def __init__(self, *args, **kwargs):
"""
Supports the usual `tqdm.tqdm` parameters as well as those listed below.
Parameters
----------
display : Whether to call `display(self.container)` immediately
[default: True].
"""
kwargs = kwargs.copy()
# Setup default output
file_kwarg = kwargs.get('file', sys.stderr)
if file_kwarg is sys.stderr or file_kwarg is None:
kwargs['file'] = sys.stdout # avoid the red block in IPython
# Initialize parent class + avoid printing by using gui=True
kwargs['gui'] = True
# convert disable = None to False
kwargs['disable'] = bool(kwargs.get('disable', False))
colour = kwargs.pop('colour', None)
display_here = kwargs.pop('display', True)
super(tqdm_notebook, self).__init__(*args, **kwargs)
if self.disable or not kwargs['gui']:
self.disp = lambda *_, **__: None
return
# Get bar width
self.ncols = '100%' if self.dynamic_ncols else kwargs.get("ncols", None)
# Replace with IPython progress bar display (with correct total)
unit_scale = 1 if self.unit_scale is True else self.unit_scale or 1
total = self.total * unit_scale if self.total else self.total
self.container = self.status_printer(self.fp, total, self.desc, self.ncols)
self.container.pbar = proxy(self)
self.displayed = False
if display_here and self.delay <= 0:
display(self.container)
self.displayed = True
self.disp = self.display
self.colour = colour
# Print initial bar state
if not self.disable:
self.display(check_delay=False)
def __iter__(self):
try:
it = super(tqdm_notebook, self).__iter__()
for obj in it:
# return super(tqdm...) will not catch exception
yield obj
# NB: except ... [ as ...] breaks IPython async KeyboardInterrupt
except: # NOQA
self.disp(bar_style='danger')
raise
# NB: don't `finally: close()`
# since this could be a shared bar which the user will `reset()`
def update(self, n=1):
try:
return super(tqdm_notebook, self).update(n=n)
# NB: except ... [ as ...] breaks IPython async KeyboardInterrupt
except: # NOQA
# cannot catch KeyboardInterrupt when using manual tqdm
# as the interrupt will most likely happen on another statement
self.disp(bar_style='danger')
raise
# NB: don't `finally: close()`
# since this could be a shared bar which the user will `reset()`
def close(self):
if self.disable:
return
super(tqdm_notebook, self).close()
# Try to detect if there was an error or KeyboardInterrupt
# in manual mode: if n < total, things probably got wrong
if self.total and self.n < self.total:
self.disp(bar_style='danger', check_delay=False)
else:
if self.leave:
self.disp(bar_style='success', check_delay=False)
else:
self.disp(close=True, check_delay=False)
def clear(self, *_, **__):
pass
def reset(self, total=None):
"""
Resets to 0 iterations for repeated use.
Consider combining with `leave=True`.
Parameters
----------
total : int or float, optional. Total to use for the new bar.
"""
if self.disable:
return super(tqdm_notebook, self).reset(total=total)
_, pbar, _ = self.container.children
pbar.bar_style = ''
if total is not None:
pbar.max = total
if not self.total and self.ncols is None: # no longer unknown total
pbar.layout.width = None # reset width
return super(tqdm_notebook, self).reset(total=total)
def tnrange(*args, **kwargs):
"""
A shortcut for `tqdm.notebook.tqdm(xrange(*args), **kwargs)`.
On Python3+, `range` is used instead of `xrange`.
"""
return tqdm_notebook(_range(*args), **kwargs)
# Aliases
tqdm = tqdm_notebook
trange = tnrange

156
_vendor/tqdm/rich.py Normal file
View File

@@ -0,0 +1,156 @@
"""
`rich.progress` decorator for iterators.
Usage:
>>> from tqdm.rich import trange, tqdm
>>> for i in trange(10):
... ...
"""
from __future__ import absolute_import
from warnings import warn
from rich.progress import (
BarColumn, Progress, ProgressColumn, Text, TimeElapsedColumn, TimeRemainingColumn, filesize)
from .std import TqdmExperimentalWarning
from .std import tqdm as std_tqdm
from .utils import _range
__author__ = {"github.com/": ["casperdcl"]}
__all__ = ['tqdm_rich', 'trrange', 'tqdm', 'trange']
class FractionColumn(ProgressColumn):
"""Renders completed/total, e.g. '0.5/2.3 G'."""
def __init__(self, unit_scale=False, unit_divisor=1000):
self.unit_scale = unit_scale
self.unit_divisor = unit_divisor
super().__init__()
def render(self, task):
"""Calculate common unit for completed and total."""
completed = int(task.completed)
total = int(task.total)
if self.unit_scale:
unit, suffix = filesize.pick_unit_and_suffix(
total,
["", "K", "M", "G", "T", "P", "E", "Z", "Y"],
self.unit_divisor,
)
else:
unit, suffix = filesize.pick_unit_and_suffix(total, [""], 1)
precision = 0 if unit == 1 else 1
return Text(
f"{completed/unit:,.{precision}f}/{total/unit:,.{precision}f} {suffix}",
style="progress.download")
class RateColumn(ProgressColumn):
"""Renders human readable transfer speed."""
def __init__(self, unit="", unit_scale=False, unit_divisor=1000):
self.unit = unit
self.unit_scale = unit_scale
self.unit_divisor = unit_divisor
super().__init__()
def render(self, task):
"""Show data transfer speed."""
speed = task.speed
if speed is None:
return Text(f"? {self.unit}/s", style="progress.data.speed")
if self.unit_scale:
unit, suffix = filesize.pick_unit_and_suffix(
speed,
["", "K", "M", "G", "T", "P", "E", "Z", "Y"],
self.unit_divisor,
)
else:
unit, suffix = filesize.pick_unit_and_suffix(speed, [""], 1)
precision = 0 if unit == 1 else 1
return Text(f"{speed/unit:,.{precision}f} {suffix}{self.unit}/s",
style="progress.data.speed")
class tqdm_rich(std_tqdm): # pragma: no cover
"""Experimental rich.progress GUI version of tqdm!"""
# TODO: @classmethod: write()?
def __init__(self, *args, **kwargs):
"""
This class accepts the following parameters *in addition* to
the parameters accepted by `tqdm`.
Parameters
----------
progress : tuple, optional
arguments for `rich.progress.Progress()`.
options : dict, optional
keyword arguments for `rich.progress.Progress()`.
"""
kwargs = kwargs.copy()
kwargs['gui'] = True
# convert disable = None to False
kwargs['disable'] = bool(kwargs.get('disable', False))
progress = kwargs.pop('progress', None)
options = kwargs.pop('options', {}).copy()
super(tqdm_rich, self).__init__(*args, **kwargs)
if self.disable:
return
warn("rich is experimental/alpha", TqdmExperimentalWarning, stacklevel=2)
d = self.format_dict
if progress is None:
progress = (
"[progress.description]{task.description}"
"[progress.percentage]{task.percentage:>4.0f}%",
BarColumn(bar_width=None),
FractionColumn(
unit_scale=d['unit_scale'], unit_divisor=d['unit_divisor']),
"[", TimeElapsedColumn(), "<", TimeRemainingColumn(),
",", RateColumn(unit=d['unit'], unit_scale=d['unit_scale'],
unit_divisor=d['unit_divisor']), "]"
)
options.setdefault('transient', not self.leave)
self._prog = Progress(*progress, **options)
self._prog.__enter__()
self._task_id = self._prog.add_task(self.desc or "", **d)
def close(self):
if self.disable:
return
super(tqdm_rich, self).close()
self._prog.__exit__(None, None, None)
def clear(self, *_, **__):
pass
def display(self, *_, **__):
if not hasattr(self, '_prog'):
return
self._prog.update(self._task_id, completed=self.n, description=self.desc)
def reset(self, total=None):
"""
Resets to 0 iterations for repeated use.
Parameters
----------
total : int or float, optional. Total to use for the new bar.
"""
if hasattr(self, '_prog'):
self._prog.reset(total=total)
super(tqdm_rich, self).reset(total=total)
def trrange(*args, **kwargs):
"""
A shortcut for `tqdm.rich.tqdm(xrange(*args), **kwargs)`.
On Python3+, `range` is used instead of `xrange`.
"""
return tqdm_rich(_range(*args), **kwargs)
# Aliases
tqdm = tqdm_rich
trange = trrange

1541
_vendor/tqdm/std.py Normal file

File diff suppressed because it is too large Load Diff

207
_vendor/tqdm/tk.py Normal file
View File

@@ -0,0 +1,207 @@
"""
Tkinter GUI progressbar decorator for iterators.
Usage:
>>> from tqdm.tk import trange, tqdm
>>> for i in trange(10):
... ...
"""
from __future__ import absolute_import, division
import re
import sys
from warnings import warn
try:
import tkinter
import tkinter.ttk as ttk
except ImportError:
import Tkinter as tkinter
import ttk as ttk
from .std import TqdmExperimentalWarning, TqdmWarning
from .std import tqdm as std_tqdm
from .utils import _range
__author__ = {"github.com/": ["richardsheridan", "casperdcl"]}
__all__ = ['tqdm_tk', 'ttkrange', 'tqdm', 'trange']
class tqdm_tk(std_tqdm): # pragma: no cover
"""
Experimental Tkinter GUI version of tqdm!
Note: Window interactivity suffers if `tqdm_tk` is not running within
a Tkinter mainloop and values are generated infrequently. In this case,
consider calling `tqdm_tk.refresh()` frequently in the Tk thread.
"""
# TODO: @classmethod: write()?
def __init__(self, *args, **kwargs):
"""
This class accepts the following parameters *in addition* to
the parameters accepted by `tqdm`.
Parameters
----------
grab : bool, optional
Grab the input across all windows of the process.
tk_parent : `tkinter.Wm`, optional
Parent Tk window.
cancel_callback : Callable, optional
Create a cancel button and set `cancel_callback` to be called
when the cancel or window close button is clicked.
"""
kwargs = kwargs.copy()
kwargs['gui'] = True
# convert disable = None to False
kwargs['disable'] = bool(kwargs.get('disable', False))
self._warn_leave = 'leave' in kwargs
grab = kwargs.pop('grab', False)
tk_parent = kwargs.pop('tk_parent', None)
self._cancel_callback = kwargs.pop('cancel_callback', None)
super(tqdm_tk, self).__init__(*args, **kwargs)
if self.disable:
return
if tk_parent is None: # Discover parent widget
try:
tk_parent = tkinter._default_root
except AttributeError:
raise AttributeError(
"`tk_parent` required when using `tkinter.NoDefaultRoot()`")
if tk_parent is None: # use new default root window as display
self._tk_window = tkinter.Tk()
else: # some other windows already exist
self._tk_window = tkinter.Toplevel()
else:
self._tk_window = tkinter.Toplevel(tk_parent)
warn("GUI is experimental/alpha", TqdmExperimentalWarning, stacklevel=2)
self._tk_dispatching = self._tk_dispatching_helper()
self._tk_window.protocol("WM_DELETE_WINDOW", self.cancel)
self._tk_window.wm_title(self.desc)
self._tk_window.wm_attributes("-topmost", 1)
self._tk_window.after(0, lambda: self._tk_window.wm_attributes("-topmost", 0))
self._tk_n_var = tkinter.DoubleVar(self._tk_window, value=0)
self._tk_text_var = tkinter.StringVar(self._tk_window)
pbar_frame = ttk.Frame(self._tk_window, padding=5)
pbar_frame.pack()
_tk_label = ttk.Label(pbar_frame, textvariable=self._tk_text_var,
wraplength=600, anchor="center", justify="center")
_tk_label.pack()
self._tk_pbar = ttk.Progressbar(
pbar_frame, variable=self._tk_n_var, length=450)
if self.total is not None:
self._tk_pbar.configure(maximum=self.total)
else:
self._tk_pbar.configure(mode="indeterminate")
self._tk_pbar.pack()
if self._cancel_callback is not None:
_tk_button = ttk.Button(pbar_frame, text="Cancel", command=self.cancel)
_tk_button.pack()
if grab:
self._tk_window.grab_set()
def close(self):
if self.disable:
return
self.disable = True
with self.get_lock():
self._instances.remove(self)
def _close():
self._tk_window.after('idle', self._tk_window.destroy)
if not self._tk_dispatching:
self._tk_window.update()
self._tk_window.protocol("WM_DELETE_WINDOW", _close)
# if leave is set but we are self-dispatching, the left window is
# totally unresponsive unless the user manually dispatches
if not self.leave:
_close()
elif not self._tk_dispatching:
if self._warn_leave:
warn("leave flag ignored if not in tkinter mainloop",
TqdmWarning, stacklevel=2)
_close()
def clear(self, *_, **__):
pass
def display(self, *_, **__):
self._tk_n_var.set(self.n)
d = self.format_dict
# remove {bar}
d['bar_format'] = (d['bar_format'] or "{l_bar}<bar/>{r_bar}").replace(
"{bar}", "<bar/>")
msg = self.format_meter(**d)
if '<bar/>' in msg:
msg = "".join(re.split(r'\|?<bar/>\|?', msg, 1))
self._tk_text_var.set(msg)
if not self._tk_dispatching:
self._tk_window.update()
def set_description(self, desc=None, refresh=True):
self.set_description_str(desc, refresh)
def set_description_str(self, desc=None, refresh=True):
self.desc = desc
if not self.disable:
self._tk_window.wm_title(desc)
if refresh and not self._tk_dispatching:
self._tk_window.update()
def cancel(self):
"""
`cancel_callback()` followed by `close()`
when close/cancel buttons clicked.
"""
if self._cancel_callback is not None:
self._cancel_callback()
self.close()
def reset(self, total=None):
"""
Resets to 0 iterations for repeated use.
Parameters
----------
total : int or float, optional. Total to use for the new bar.
"""
if hasattr(self, '_tk_pbar'):
if total is None:
self._tk_pbar.configure(maximum=100, mode="indeterminate")
else:
self._tk_pbar.configure(maximum=total, mode="determinate")
super(tqdm_tk, self).reset(total=total)
@staticmethod
def _tk_dispatching_helper():
"""determine if Tkinter mainloop is dispatching events"""
codes = {tkinter.mainloop.__code__, tkinter.Misc.mainloop.__code__}
for frame in sys._current_frames().values():
while frame:
if frame.f_code in codes:
return True
frame = frame.f_back
return False
def ttkrange(*args, **kwargs):
"""
A shortcut for `tqdm.tk.tqdm(xrange(*args), **kwargs)`.
On Python3+, `range` is used instead of `xrange`.
"""
return tqdm_tk(_range(*args), **kwargs)
# Aliases
tqdm = tqdm_tk
trange = ttkrange

316
_vendor/tqdm/tqdm.1 Normal file
View File

@@ -0,0 +1,316 @@
.\" Automatically generated by Pandoc 1.19.2
.\"
.TH "TQDM" "1" "2015\-2021" "tqdm User Manuals" ""
.hy
.SH NAME
.PP
tqdm \- fast, extensible progress bar for Python and CLI
.SH SYNOPSIS
.PP
tqdm [\f[I]options\f[]]
.SH DESCRIPTION
.PP
See <https://github.com/tqdm/tqdm>.
Can be used as a pipe:
.IP
.nf
\f[C]
$\ #\ count\ lines\ of\ code
$\ cat\ *.py\ |\ tqdm\ |\ wc\ \-l
327it\ [00:00,\ 981773.38it/s]
327
$\ #\ find\ all\ files
$\ find\ .\ \-name\ "*.py"\ |\ tqdm\ |\ wc\ \-l
432it\ [00:00,\ 833842.30it/s]
432
#\ ...\ and\ more\ info
$\ find\ .\ \-name\ \[aq]*.py\[aq]\ \-exec\ wc\ \-l\ \\{}\ \\;\ \\
\ \ |\ tqdm\ \-\-total\ 432\ \-\-unit\ files\ \-\-desc\ counting\ \\
\ \ |\ awk\ \[aq]{\ sum\ +=\ $1\ };\ END\ {\ print\ sum\ }\[aq]
counting:\ 100%|█████████|\ 432/432\ [00:00<00:00,\ 794361.83files/s]
131998
\f[]
.fi
.SH OPTIONS
.TP
.B \-h, \-\-help
Print this help and exit.
.RS
.RE
.TP
.B \-v, \-\-version
Print version and exit.
.RS
.RE
.TP
.B \-\-desc=\f[I]desc\f[]
str, optional.
Prefix for the progressbar.
.RS
.RE
.TP
.B \-\-total=\f[I]total\f[]
int or float, optional.
The number of expected iterations.
If unspecified, len(iterable) is used if possible.
If float("inf") or as a last resort, only basic progress statistics are
displayed (no ETA, no progressbar).
If \f[C]gui\f[] is True and this parameter needs subsequent updating,
specify an initial arbitrary large positive number, e.g.
9e9.
.RS
.RE
.TP
.B \-\-leave
bool, optional.
If [default: True], keeps all traces of the progressbar upon termination
of iteration.
If \f[C]None\f[], will leave only if \f[C]position\f[] is \f[C]0\f[].
.RS
.RE
.TP
.B \-\-ncols=\f[I]ncols\f[]
int, optional.
The width of the entire output message.
If specified, dynamically resizes the progressbar to stay within this
bound.
If unspecified, attempts to use environment width.
The fallback is a meter width of 10 and no limit for the counter and
statistics.
If 0, will not print any meter (only stats).
.RS
.RE
.TP
.B \-\-mininterval=\f[I]mininterval\f[]
float, optional.
Minimum progress display update interval [default: 0.1] seconds.
.RS
.RE
.TP
.B \-\-maxinterval=\f[I]maxinterval\f[]
float, optional.
Maximum progress display update interval [default: 10] seconds.
Automatically adjusts \f[C]miniters\f[] to correspond to
\f[C]mininterval\f[] after long display update lag.
Only works if \f[C]dynamic_miniters\f[] or monitor thread is enabled.
.RS
.RE
.TP
.B \-\-miniters=\f[I]miniters\f[]
int or float, optional.
Minimum progress display update interval, in iterations.
If 0 and \f[C]dynamic_miniters\f[], will automatically adjust to equal
\f[C]mininterval\f[] (more CPU efficient, good for tight loops).
If > 0, will skip display of specified number of iterations.
Tweak this and \f[C]mininterval\f[] to get very efficient loops.
If your progress is erratic with both fast and slow iterations (network,
skipping items, etc) you should set miniters=1.
.RS
.RE
.TP
.B \-\-ascii=\f[I]ascii\f[]
bool or str, optional.
If unspecified or False, use unicode (smooth blocks) to fill the meter.
The fallback is to use ASCII characters " 123456789#".
.RS
.RE
.TP
.B \-\-disable
bool, optional.
Whether to disable the entire progressbar wrapper [default: False].
If set to None, disable on non\-TTY.
.RS
.RE
.TP
.B \-\-unit=\f[I]unit\f[]
str, optional.
String that will be used to define the unit of each iteration [default:
it].
.RS
.RE
.TP
.B \-\-unit\-scale=\f[I]unit_scale\f[]
bool or int or float, optional.
If 1 or True, the number of iterations will be reduced/scaled
automatically and a metric prefix following the International System of
Units standard will be added (kilo, mega, etc.) [default: False].
If any other non\-zero number, will scale \f[C]total\f[] and \f[C]n\f[].
.RS
.RE
.TP
.B \-\-dynamic\-ncols
bool, optional.
If set, constantly alters \f[C]ncols\f[] and \f[C]nrows\f[] to the
environment (allowing for window resizes) [default: False].
.RS
.RE
.TP
.B \-\-smoothing=\f[I]smoothing\f[]
float, optional.
Exponential moving average smoothing factor for speed estimates (ignored
in GUI mode).
Ranges from 0 (average speed) to 1 (current/instantaneous speed)
[default: 0.3].
.RS
.RE
.TP
.B \-\-bar\-format=\f[I]bar_format\f[]
str, optional.
Specify a custom bar string formatting.
May impact performance.
[default: \[aq]{l_bar}{bar}{r_bar}\[aq]], where l_bar=\[aq]{desc}:
{percentage:3.0f}%|\[aq] and r_bar=\[aq]| {n_fmt}/{total_fmt}
[{elapsed}<{remaining}, \[aq] \[aq]{rate_fmt}{postfix}]\[aq] Possible
vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, percentage,
elapsed, elapsed_s, ncols, nrows, desc, unit, rate, rate_fmt,
rate_noinv, rate_noinv_fmt, rate_inv, rate_inv_fmt, postfix,
unit_divisor, remaining, remaining_s, eta.
Note that a trailing ": " is automatically removed after {desc} if the
latter is empty.
.RS
.RE
.TP
.B \-\-initial=\f[I]initial\f[]
int or float, optional.
The initial counter value.
Useful when restarting a progress bar [default: 0].
If using float, consider specifying \f[C]{n:.3f}\f[] or similar in
\f[C]bar_format\f[], or specifying \f[C]unit_scale\f[].
.RS
.RE
.TP
.B \-\-position=\f[I]position\f[]
int, optional.
Specify the line offset to print this bar (starting from 0) Automatic if
unspecified.
Useful to manage multiple bars at once (eg, from threads).
.RS
.RE
.TP
.B \-\-postfix=\f[I]postfix\f[]
dict or *, optional.
Specify additional stats to display at the end of the bar.
Calls \f[C]set_postfix(**postfix)\f[] if possible (dict).
.RS
.RE
.TP
.B \-\-unit\-divisor=\f[I]unit_divisor\f[]
float, optional.
[default: 1000], ignored unless \f[C]unit_scale\f[] is True.
.RS
.RE
.TP
.B \-\-write\-bytes
bool, optional.
If (default: None) and \f[C]file\f[] is unspecified, bytes will be
written in Python 2.
If \f[C]True\f[] will also write bytes.
In all other cases will default to unicode.
.RS
.RE
.TP
.B \-\-lock\-args=\f[I]lock_args\f[]
tuple, optional.
Passed to \f[C]refresh\f[] for intermediate output (initialisation,
iterating, and updating).
.RS
.RE
.TP
.B \-\-nrows=\f[I]nrows\f[]
int, optional.
The screen height.
If specified, hides nested bars outside this bound.
If unspecified, attempts to use environment height.
The fallback is 20.
.RS
.RE
.TP
.B \-\-colour=\f[I]colour\f[]
str, optional.
Bar colour (e.g.
\[aq]green\[aq], \[aq]#00ff00\[aq]).
.RS
.RE
.TP
.B \-\-delay=\f[I]delay\f[]
float, optional.
Don\[aq]t display until [default: 0] seconds have elapsed.
.RS
.RE
.TP
.B \-\-delim=\f[I]delim\f[]
chr, optional.
Delimiting character [default: \[aq]\\n\[aq]].
Use \[aq]\\0\[aq] for null.
N.B.: on Windows systems, Python converts \[aq]\\n\[aq] to
\[aq]\\r\\n\[aq].
.RS
.RE
.TP
.B \-\-buf\-size=\f[I]buf_size\f[]
int, optional.
String buffer size in bytes [default: 256] used when \f[C]delim\f[] is
specified.
.RS
.RE
.TP
.B \-\-bytes
bool, optional.
If true, will count bytes, ignore \f[C]delim\f[], and default
\f[C]unit_scale\f[] to True, \f[C]unit_divisor\f[] to 1024, and
\f[C]unit\f[] to \[aq]B\[aq].
.RS
.RE
.TP
.B \-\-tee
bool, optional.
If true, passes \f[C]stdin\f[] to both \f[C]stderr\f[] and
\f[C]stdout\f[].
.RS
.RE
.TP
.B \-\-update
bool, optional.
If true, will treat input as newly elapsed iterations, i.e.
numbers to pass to \f[C]update()\f[].
Note that this is slow (~2e5 it/s) since every input must be decoded as
a number.
.RS
.RE
.TP
.B \-\-update\-to
bool, optional.
If true, will treat input as total elapsed iterations, i.e.
numbers to assign to \f[C]self.n\f[].
Note that this is slow (~2e5 it/s) since every input must be decoded as
a number.
.RS
.RE
.TP
.B \-\-null
bool, optional.
If true, will discard input (no stdout).
.RS
.RE
.TP
.B \-\-manpath=\f[I]manpath\f[]
str, optional.
Directory in which to install tqdm man pages.
.RS
.RE
.TP
.B \-\-comppath=\f[I]comppath\f[]
str, optional.
Directory in which to place tqdm completion.
.RS
.RE
.TP
.B \-\-log=\f[I]log\f[]
str, optional.
CRITICAL|FATAL|ERROR|WARN(ING)|[default: \[aq]INFO\[aq]]|DEBUG|NOTSET.
.RS
.RE
.SH AUTHORS
tqdm developers <https://github.com/tqdm>.

354
_vendor/tqdm/utils.py Normal file
View File

@@ -0,0 +1,354 @@
"""
General helpers required for `tqdm.std`.
"""
import os
import re
import sys
from functools import wraps
from warnings import warn
from weakref import proxy
# py2/3 compat
try:
_range = xrange
except NameError:
_range = range
try:
_unich = unichr
except NameError:
_unich = chr
try:
_unicode = unicode
except NameError:
_unicode = str
try:
_basestring = basestring
except NameError:
_basestring = str
CUR_OS = sys.platform
IS_WIN = any(CUR_OS.startswith(i) for i in ['win32', 'cygwin'])
IS_NIX = any(CUR_OS.startswith(i) for i in ['aix', 'linux', 'darwin'])
RE_ANSI = re.compile(r"\x1b\[[;\d]*[A-Za-z]")
try:
if IS_WIN:
import colorama
else:
raise ImportError
except ImportError:
colorama = None
else:
try:
colorama.init(strip=False)
except TypeError:
colorama.init()
class FormatReplace(object):
"""
>>> a = FormatReplace('something')
>>> "{:5d}".format(a)
'something'
""" # NOQA: P102
def __init__(self, replace=''):
self.replace = replace
self.format_called = 0
def __format__(self, _):
self.format_called += 1
return self.replace
class Comparable(object):
"""Assumes child has self._comparable attr/@property"""
def __lt__(self, other):
return self._comparable < other._comparable
def __le__(self, other):
return (self < other) or (self == other)
def __eq__(self, other):
return self._comparable == other._comparable
def __ne__(self, other):
return not self == other
def __gt__(self, other):
return not self <= other
def __ge__(self, other):
return not self < other
class ObjectWrapper(object):
def __getattr__(self, name):
return getattr(self._wrapped, name)
def __setattr__(self, name, value):
return setattr(self._wrapped, name, value)
def wrapper_getattr(self, name):
"""Actual `self.getattr` rather than self._wrapped.getattr"""
try:
return object.__getattr__(self, name)
except AttributeError: # py2
return getattr(self, name)
def wrapper_setattr(self, name, value):
"""Actual `self.setattr` rather than self._wrapped.setattr"""
return object.__setattr__(self, name, value)
def __init__(self, wrapped):
"""
Thin wrapper around a given object
"""
self.wrapper_setattr('_wrapped', wrapped)
class SimpleTextIOWrapper(ObjectWrapper):
"""
Change only `.write()` of the wrapped object by encoding the passed
value and passing the result to the wrapped object's `.write()` method.
"""
# pylint: disable=too-few-public-methods
def __init__(self, wrapped, encoding):
super(SimpleTextIOWrapper, self).__init__(wrapped)
self.wrapper_setattr('encoding', encoding)
def write(self, s):
"""
Encode `s` and pass to the wrapped object's `.write()` method.
"""
return self._wrapped.write(s.encode(self.wrapper_getattr('encoding')))
def __eq__(self, other):
return self._wrapped == getattr(other, '_wrapped', other)
class DisableOnWriteError(ObjectWrapper):
"""
Disable the given `tqdm_instance` upon `write()` or `flush()` errors.
"""
@staticmethod
def disable_on_exception(tqdm_instance, func):
"""
Quietly set `tqdm_instance.miniters=inf` if `func` raises `errno=5`.
"""
tqdm_instance = proxy(tqdm_instance)
def inner(*args, **kwargs):
try:
return func(*args, **kwargs)
except OSError as e:
if e.errno != 5:
raise
try:
tqdm_instance.miniters = float('inf')
except ReferenceError:
pass
except ValueError as e:
if 'closed' not in str(e):
raise
try:
tqdm_instance.miniters = float('inf')
except ReferenceError:
pass
return inner
def __init__(self, wrapped, tqdm_instance):
super(DisableOnWriteError, self).__init__(wrapped)
if hasattr(wrapped, 'write'):
self.wrapper_setattr(
'write', self.disable_on_exception(tqdm_instance, wrapped.write))
if hasattr(wrapped, 'flush'):
self.wrapper_setattr(
'flush', self.disable_on_exception(tqdm_instance, wrapped.flush))
def __eq__(self, other):
return self._wrapped == getattr(other, '_wrapped', other)
class CallbackIOWrapper(ObjectWrapper):
def __init__(self, callback, stream, method="read"):
"""
Wrap a given `file`-like object's `read()` or `write()` to report
lengths to the given `callback`
"""
super(CallbackIOWrapper, self).__init__(stream)
func = getattr(stream, method)
if method == "write":
@wraps(func)
def write(data, *args, **kwargs):
res = func(data, *args, **kwargs)
callback(len(data))
return res
self.wrapper_setattr('write', write)
elif method == "read":
@wraps(func)
def read(*args, **kwargs):
data = func(*args, **kwargs)
callback(len(data))
return data
self.wrapper_setattr('read', read)
else:
raise KeyError("Can only wrap read/write methods")
def _is_utf(encoding):
try:
u'\u2588\u2589'.encode(encoding)
except UnicodeEncodeError:
return False
except Exception:
try:
return encoding.lower().startswith('utf-') or ('U8' == encoding)
except Exception:
return False
else:
return True
def _supports_unicode(fp):
try:
return _is_utf(fp.encoding)
except AttributeError:
return False
def _is_ascii(s):
if isinstance(s, str):
for c in s:
if ord(c) > 255:
return False
return True
return _supports_unicode(s)
def _screen_shape_wrapper(): # pragma: no cover
"""
Return a function which returns console dimensions (width, height).
Supported: linux, osx, windows, cygwin.
"""
_screen_shape = None
if IS_WIN:
_screen_shape = _screen_shape_windows
if _screen_shape is None:
_screen_shape = _screen_shape_tput
if IS_NIX:
_screen_shape = _screen_shape_linux
return _screen_shape
def _screen_shape_windows(fp): # pragma: no cover
try:
import struct
from ctypes import create_string_buffer, windll
from sys import stdin, stdout
io_handle = -12 # assume stderr
if fp == stdin:
io_handle = -10
elif fp == stdout:
io_handle = -11
h = windll.kernel32.GetStdHandle(io_handle)
csbi = create_string_buffer(22)
res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
if res:
(_bufx, _bufy, _curx, _cury, _wattr, left, top, right, bottom,
_maxx, _maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
return right - left, bottom - top # +1
except Exception: # nosec
pass
return None, None
def _screen_shape_tput(*_): # pragma: no cover
"""cygwin xterm (windows)"""
try:
import shlex
from subprocess import check_call # nosec
return [int(check_call(shlex.split('tput ' + i))) - 1
for i in ('cols', 'lines')]
except Exception: # nosec
pass
return None, None
def _screen_shape_linux(fp): # pragma: no cover
try:
from array import array
from fcntl import ioctl
from termios import TIOCGWINSZ
except ImportError:
return None, None
else:
try:
rows, cols = array('h', ioctl(fp, TIOCGWINSZ, '\0' * 8))[:2]
return cols, rows
except Exception:
try:
return [int(os.environ[i]) - 1 for i in ("COLUMNS", "LINES")]
except (KeyError, ValueError):
return None, None
def _environ_cols_wrapper(): # pragma: no cover
"""
Return a function which returns console width.
Supported: linux, osx, windows, cygwin.
"""
warn("Use `_screen_shape_wrapper()(file)[0]` instead of"
" `_environ_cols_wrapper()(file)`", DeprecationWarning, stacklevel=2)
shape = _screen_shape_wrapper()
if not shape:
return None
@wraps(shape)
def inner(fp):
return shape(fp)[0]
return inner
def _term_move_up(): # pragma: no cover
return '' if (os.name == 'nt') and (colorama is None) else '\x1b[A'
try:
# TODO consider using wcswidth third-party package for 0-width characters
from unicodedata import east_asian_width
except ImportError:
_text_width = len
else:
def _text_width(s):
return sum(2 if east_asian_width(ch) in 'FW' else 1 for ch in _unicode(s))
def disp_len(data):
"""
Returns the real on-screen length of a string which may contain
ANSI control codes and wide chars.
"""
return _text_width(RE_ANSI.sub('', data))
def disp_trim(data, length):
"""
Trim a string which may contain ANSI control characters.
"""
if len(data) == disp_len(data):
return data[:length]
ansi_present = bool(RE_ANSI.search(data))
while disp_len(data) > length: # carefully delete one char at a time
data = data[:-1]
if ansi_present and bool(RE_ANSI.search(data)):
# assume ANSI reset is required
return data if data.endswith("\033[0m") else data + "\033[0m"
return data

9
_vendor/tqdm/version.py Normal file
View File

@@ -0,0 +1,9 @@
"""`tqdm` version detector. Precedence: installed dist, git, 'UNKNOWN'."""
try:
from ._dist_ver import __version__
except ImportError:
try:
from setuptools_scm import get_version
__version__ = get_version(root='..', relative_to=__file__)
except (ImportError, LookupError):
__version__ = "UNKNOWN"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -3,7 +3,7 @@
<html>
<head>
<script>
var lastMsg, allowed=false, dir=null;
var lastMsg, allowed=false, dir=null, noThumbs=null;
var locStor = {};
@@ -117,6 +117,8 @@
if(ext=="jpeg") ext="jpg";
if(ext=="tiff") ext="tif";
if(["dng","cr2","nef","arw","3fr","fff","gpr"].indexOf(ext)!=-1) ext="tif";
if(noThumbs) ext="---";
var thmb=null;
if(thmb==null && (ext=="jpg" || ext=="tif")) { // || ext=="--psd"
var lim = 130000;
@@ -202,10 +204,11 @@
async function askPermissions() {
if(dir) {
if(await dir.requestPermission({mode:"readwrite"})!="granted") return;
if(await dir.requestPermission({mode:"readwrite"})!="granted") { send("1","You must give Photopea access to some folder."); return; }
}
else {
dir = await window.showDirectoryPicker();
try { dir = await window.showDirectoryPicker(); }
catch(e) { send("1","You must give Photopea access to some folder."); return; }
locStor.fset = dir;
var os = locStor.db["transaction"](["rsrc"], "readwrite")["objectStore"]("rsrc");
@@ -229,7 +232,8 @@
if(msg.code=="show") {
printFolder(msg.prm);
noThumbs=msg.nothumbs;
printFolder(msg.prm);
}
else if(msg.code=="load") {
printFile(msg.prm);

View File

@@ -10,28 +10,47 @@
<script type="text/javascript">
var sentFalse = false;
var clientId = '463342976776-04ub3ijsr7i5qobn8ha32ap6vsaae75a.apps.googleusercontent.com';
var scope = 'https://www.googleapis.com/auth/drive';
var discoveryDocs = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';
var clientId = "463342976776-04ub3ijsr7i5qobn8ha32ap6vsaae75a.apps.googleusercontent.com";
var scope = "https://www.googleapis.com/auth/drive";
var discoveryDocs = "https://www.googleapis.com/discovery/v1/apis/drive/v3/rest";
var mode3dir = "Photopea";
var client;
var isShared = false;
//var isShared = false;
var sharedDrives = null;
var mode = 0; //0 = normal, 1 = shared drives, 2 = application folder, 3 = PP folder
function go()
{
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
if(urlParams.get('sharedDrive') == 'true') isShared = true;
if(urlParams.get('mode')) mode = urlParams.get('mode');
if(mode == 2) { scope = "https://www.googleapis.com/auth/drive.appdata"; }
else if(mode == 3) { scope = "https://www.googleapis.com/auth/drive.file"; }
else { scope = "https://www.googleapis.com/auth/drive"; }
window.addEventListener("message", onMessage, false);
gapi.load('client', gapiInit);
}
function saveToken(e)
{
localStorage.setItem("googledriveAccessToken", e.access_token);
localStorage.setItem("googledriveAccessTokenValidUntil", Date.now() + e.expires_in * 1000);
if(mode == 2)
{
localStorage.setItem("googledriveAppFolderAccessToken", e.access_token);
localStorage.setItem("googledriveAppFolderAccessTokenValidUntil", Date.now() + e.expires_in * 1000);
}
else if(mode == 3)
{
localStorage.setItem("googledriveFileAccessToken", e.access_token);
localStorage.setItem("googledriveFileAccessTokenValidUntil", Date.now() + e.expires_in * 1000);
}
else
{
localStorage.setItem("googledriveAccessToken", e.access_token);
localStorage.setItem("googledriveAccessTokenValidUntil", Date.now() + e.expires_in * 1000);
}
send("ready", true);
}
@@ -45,6 +64,24 @@
scope: scope,
callback: saveToken,
});
if(mode == 2)
{
if(Date.now() < localStorage.getItem("googledriveAppFolderAccessTokenValidUntil"))
{
gapi.client.setToken({ "access_token" : localStorage.getItem("googledriveAppFolderAccessToken") });
send("ready", true);
return;
}
}
else if(mode == 3)
{
if(Date.now() < localStorage.getItem("googledriveFileAccessTokenValidUntil"))
{
gapi.client.setToken({ "access_token" : localStorage.getItem("googledriveFileAccessToken") });
send("ready", true);
return;
}
}
if(Date.now() < localStorage.getItem("googledriveAccessTokenValidUntil"))
{
gapi.client.setToken({ "access_token" : localStorage.getItem("googledriveAccessToken") });
@@ -97,7 +134,20 @@
{
if(!id)
{
if(!isShared) id = "root";
if(mode == 0) id = "root";
else if(mode == 3 )
{
if(path.length == 2 && path[1] == "")
{
checkFile("root", path[0], null, null);
return;
}
else
{
id = "root";
}
}
else if(mode == 2) id = "appDataFolder";
else if(path.length == 1 && path[0] == "")
{
listDrives(null, []);
@@ -147,11 +197,15 @@
'pageToken' : pageToken,
'pageSize': 1000,
'fields': "nextPageToken, files(id, name, size, modifiedTime, kind, mimeType, trashed)",};
if(isShared)
if(mode == 1)
{
req['supportsAllDrives'] = true;
req['includeItemsFromAllDrives'] = true;
}
else if(mode == 2)
{
req['spaces'] = "appDataFolder";
}
gapi.client.drive.files.list(req)
.then(function(response) {
var files = response.result.files;
@@ -189,7 +243,7 @@
{
out.push([drives[i].name, -1, Math.round(Date.parse(drives[i].createdTime)/1000)])
}
if(pageToken) listDir(pageToken,query,out);
if(pageToken) listDrives(pageToken,out);
else { send(0,out); }
})
.catch(handleError);
@@ -202,11 +256,15 @@
'pageToken' : pageToken,
'pageSize': 1000,
'fields': "nextPageToken, files(id, name, size, modifiedTime, kind, mimeType, thumbnailLink, trashed)",};
if(isShared)
if(mode == 1)
{
req['supportsAllDrives'] = true;
req['includeItemsFromAllDrives'] = true;
}
else if(mode == 2)
{
req['spaces'] = "appDataFolder";
}
gapi.client.drive.files.list(req)
.then(function(response) {
var files = response.result.files;
@@ -233,7 +291,7 @@
{
var xhr = new XMLHttpRequest();
var shared = "";
if(isShared) shared = "&supportsAllDrives=true";
if(mode == 1) shared = "&supportsAllDrives=true";
xhr.open('GET', "https://www.googleapis.com/drive/v3/files/" + fileId + "?alt=media" + shared);
xhr.responseType = "arraybuffer";
xhr.setRequestHeader('Authorization', 'Bearer ' + gapi.client.getToken().access_token);
@@ -246,7 +304,7 @@
{
var xhr = new XMLHttpRequest();
var shared = "";
if(isShared) shared = "&supportsAllDrives=true";
if(mode == 1) shared = "&supportsAllDrives=true";
xhr.open('GET', "https://www.googleapis.com/drive/v3/files/" + fileId + "?fields=thumbnailLink" + shared);
xhr.setRequestHeader('Authorization', 'Bearer ' + gapi.client.getToken().access_token);
xhr.onload = function(e)
@@ -270,9 +328,9 @@
function deleteFile(fileId)
{
if(isShared) { trashFile(fileId); return; }
if(mode == 1) { trashFile(fileId); return; }
var req = { 'fileId' : fileId, };
if(isShared) req['supportsAllDrives'] = true;
//if(isShared) req['supportsAllDrives'] = true;
gapi.client.drive.files.delete(req)
.then(function(response) {
send(0,"");
@@ -292,7 +350,7 @@
'trashed' : true,
}
};
if(isShared) req['supportsAllDrives'] = true;
if(mode == 1) req['supportsAllDrives'] = true;
gapi.client.drive.files.update(req)
.then(function(response) {
send(0,"");
@@ -313,9 +371,15 @@
'mimeType': 'application/vnd.google-apps.folder',
}
}
if(isShared) req['supportsAllDrives'] = true;
if(mode == 1) req['supportsAllDrives'] = true;
gapi.client.drive.files.create( req )
.then(function(response) {
.then(function(response) {
if(response.result.name == mode3dir)
{
var query = "'" + response.result.id + "' in parents";
listDir(null, query, [])
return;
}
send(0,"");
})
.catch(function(response) {
@@ -333,7 +397,7 @@
'name' : newName,
}
};
if(isShared) req['supportsAllDrives'] = true;
if(mode == 1) req['supportsAllDrives'] = true;
gapi.client.drive.files.update(req)
.then(function(response) {
send(0,"");
@@ -345,6 +409,7 @@
}
//check if file exists, then overwrite, otherwise create new file.
//if buffer is null, we check whether direcory exist and if not, we create it
function checkFile(parentId, name, pageToken, buffer)
{
var query = "'" + parentId + "' in parents";
@@ -353,11 +418,15 @@
'pageToken' : pageToken,
'pageSize': 1000,
'fields': "nextPageToken, files(id, name, trashed)",};
if(isShared)
if(mode == 1)
{
req['supportsAllDrives'] = true;
req['includeItemsFromAllDrives'] = true;
}
else if(mode == 2)
{
req['spaces'] = "appDataFolder";
}
gapi.client.drive.files.list(req)
.then(function(response) {
var files = response.result.files;
@@ -369,12 +438,18 @@
if(files[i].name == name)
{
found = true;
uploadFile(files[i].id,parentId,name,buffer);
if(buffer) { uploadFile(files[i].id,parentId,name,buffer); }
else
{
query = "'" + files[i].id + "' in parents";
listDir(null, query, []);
}
return;
}
}
if(!found && pageToken) checkFile(parentId, name, pageToken, buffer);
else uploadFile(null,parentId,name,buffer);
else if(buffer) uploadFile(null,parentId,name,buffer);
else { createDir('root', name)}
})
.catch(handleError);
}
@@ -392,7 +467,7 @@
metadata['Content-Type'] = contentType;
metadata['Content-Length'] = file.size;
var shared = "";
if(isShared) shared = "&supportsAllDrives=true";
if(mode == 1) shared = "&supportsAllDrives=true";
if(!fileId) xhr.open("POST", "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable" + shared);
else xhr.open("PATCH", "https://www.googleapis.com/upload/drive/v3/files/" + fileId + "?uploadType=resumable" + shared);
xhr.setRequestHeader('Authorization', 'Bearer ' + gapi.client.getToken().access_token);
@@ -430,7 +505,7 @@
form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
form.append('file', file);
var shared = "";
if(isShared) shared = "&supportsAllDrives=true";
if(mode == 1) shared = "&supportsAllDrives=true";
if(!fileId) xhr.open('POST', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id' + shared);
else xhr.open('PATCH', 'https://www.googleapis.com/upload/drive/v3/files/' + fileId + '?uploadType=multipart&fields=id' + shared);
xhr.setRequestHeader('Authorization', 'Bearer ' + gapi.client.getToken().access_token);
@@ -442,12 +517,27 @@
function signOutUser()
{
localStorage.removeItem("googledriveAccessToken");
localStorage.removeItem("googledriveAccessTokenValidUntil");
if(mode == 2)
{
localStorage.removeItem("googledriveAppFolderAccessToken");
localStorage.removeItem("googledriveAppFolderAccessTokenValidUntil");
}
if(mode == 3)
{
localStorage.removeItem("googledriveFileAccessToken");
localStorage.removeItem("googledriveFileAccessTokenValidUntil");
}
else
{
localStorage.removeItem("googledriveAccessToken");
localStorage.removeItem("googledriveAccessTokenValidUntil");
}
gapi.client.setToken('');
send("ready", false);
var cred = gapi.client.getToken();
if (cred !== null) {
google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
gapi.client.setToken('');
gapi.client.setToken("");
}
}
@@ -463,17 +553,21 @@
if(e.origin && (e.origin == "https://accounts.google.com" || e.origin == "https://content.googleapis.com")) { return; }
if((typeof e.data) == "string") {
var msg = JSON.parse(e.data);
if(mode == 3 && msg.code != "forget")
{
msg.prm = "/" + mode3dir + msg.prm;
}
console.log(msg);
//TODO: cannot list directory if name contains forwardslash
if(msg.code=="show") { doAction(listDir, { "path" : msg.prm }) }
else if(msg.code=="load") { doAction(downloadFile, { "path" : msg.prm }); }
else if(msg.code=="delete") { doAction(deleteFile, { "path" : msg.prm }); }
else if(msg.code=="save" && msg.prm.endsWith("/")) { doAction(createDir, { "path" : msg.prm.slice(0, -1) }); }
//TODO: will not work if filename contains colon(s)
else if(msg.code=="rename") { doAction(renameFile, {"path" : msg.prm }); }
else if(msg.code=="forget") { doAction(signOutUser); }
lastMsg=msg;
}
//TODO: cannot list directory if name contains forwardslash
if(msg.code=="show") { doAction(listDir, { "path" : msg.prm }) }
else if(msg.code=="load") { doAction(downloadFile, { "path" : msg.prm }); }
else if(msg.code=="delete") { doAction(deleteFile, { "path" : msg.prm }); }
else if(msg.code=="save" && msg.prm.endsWith("/")) { doAction(createDir, { "path" : msg.prm.slice(0, -1) }); }
//TODO: will not work if filename contains colon(s)
else if(msg.code=="rename") { doAction(renameFile, {"path" : msg.prm }); }
else if(msg.code=="forget") { doAction(signOutUser); }
lastMsg=msg;
}
else {
if(lastMsg.code=="save") doAction(checkFile, { "path": lastMsg.prm, "buffer" : e.data });
}

View File

@@ -67,11 +67,12 @@
<script src="code/pp/pp.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-4249565-37"></script>
<script async src="https:#/gtag/js?id=G-49YR1RB5KP"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag("js", new Date()); gtag("config", "UA-4249565-37");
gtag("js", new Date()); gtag('config', 'G-49YR1RB5KP'); //gtag("config", "UA-4249565-37");
</script>
</body>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@
border-width: 0;
border-color: var(--brdr);
column-rule-style:solid;
column-rule-color: var(--bg-panel);
column-rule-color: var(--bg-panel);
}
body, button, input, textarea, select { font-family: "Open Sans", Sans-Serif; }
@@ -45,7 +45,6 @@
.colorpicker .form .flabel, .numlist .flabel {
display: inline-block;
min-width : 17px;
margin-left:15px;
}
body {overscroll-behavior-x: contain; /* two-finger swipe left can navigate to a previous website */}
@@ -439,7 +438,6 @@
.lpfoot
{
text-align:right;
height:22px;
border-top-width: 1px;
}
.lpfoot button { padding-bottom:0; }
@@ -677,6 +675,19 @@
background-color: #fff;
color: #000000;
}
.cp_trsp {
background-color: rgba(var(--abs255),var(--abs255),var(--abs255),0.4);
color: rgb(calc(255 - var(--abs255)),calc(255 - var(--abs255)),calc(255 - var(--abs255)));
backdrop-filter: blur(24px);
-webkit-backdrop-filter: blur(24px);
border-radius:6px;
outline: 1px solid rgba(255,255,255,0.12);
outline-offset: -2px;
padding:6px;
/*border: 1px solid rgba(255,255,255,0.15);*/
}
.contextpanel .check {
display: inline-block;
@@ -698,10 +709,14 @@
margin:0.25em 0;
background: #bebebe;
}
.cp_trsp hr { background:rgba(255,255,255,0.15); margin:0.25em 0.65em; }
.contextpanel div {
padding: 0.5em 1em 0.5em 0.7em;
}
.cp_trsp div {
padding: 0.35em 1em 0.35em 0.7em;
}
.cp_light .enab:hover, .cp_light .active {
/*color:#fff;*/
@@ -711,9 +726,14 @@
/*color:#fff;*/
background-color: rgba(0,0,0, var(--alphaDark) );
}
.cp_trsp .enab:hover, .cp_trsp .active {
/*color:#fff;*/
background-color: #206bcd;
border-radius:6px;
}
.contextpanel .disab {
color:#bbb;
opacity:0.4;
pointer-events: none;
}
@@ -762,6 +782,7 @@
vertical-align:middle;
height: 1.6em;
padding: 0;
border:none;
/*background-color: #000000;*/
/*box-shadow: inset 0 0 60px rgba(0,0,0,0.5)*/
}
@@ -770,6 +791,7 @@
background-color: var(--base);
border-radius:6px;
box-shadow: 0px 0px 20px rgba(0,0,0,0.25);
opacity:0; transform: scale(0.95);
}
.rangecontFloat {
padding: 3px 8px 4px 8px;
@@ -955,17 +977,19 @@ input[type="checkbox"]:checked + label:before { content: "\2713"; }
{
margin-left:0;
margin-right:0;
width:32%;
width:33%;
text-align:right;
}
.trangeinput label
{
display:inline-block;
width:66%;
width:67%;
margin:0px;
}
.trangeinput input[type='range']
{
margin-top: -10px;
margin: -10px 0 0 0;
width:100%;
}
@@ -1129,7 +1153,7 @@ input[type="checkbox"]:checked + label:before { content: "\2713"; }
}
*/
.window .flabel
.window .flabel, .labfxd .flabel
{
display:inline-block;
min-width:4em;
@@ -1579,8 +1603,8 @@ input[type="checkbox"]:checked + label:before { content: "\2713"; }
padding: 4px 4px;
}
.storage .bar .btn {
.storage .btn {
cursor:pointer; display:inline-block;
background-color: #aaccff; padding: 4px 8px; border-radius: 3px; margin:0px 3px;
background-color: #aaccff; padding: 0.3em 0.6em; border-radius: 0.2em; margin:0px 3px;
}