mirror of
https://gitflic.ru/project/photopea-v2/photopea-v-2.git
synced 2026-04-19 06:50:10 +00:00
Normal update
This commit is contained in:
@@ -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
8
_vendor/bin/tqdm
Executable 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())
|
||||
1
_vendor/tqdm-4.64.1.dist-info/INSTALLER
Normal file
1
_vendor/tqdm-4.64.1.dist-info/INSTALLER
Normal file
@@ -0,0 +1 @@
|
||||
pip
|
||||
49
_vendor/tqdm-4.64.1.dist-info/LICENCE
Normal file
49
_vendor/tqdm-4.64.1.dist-info/LICENCE
Normal 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.
|
||||
1589
_vendor/tqdm-4.64.1.dist-info/METADATA
Normal file
1589
_vendor/tqdm-4.64.1.dist-info/METADATA
Normal file
File diff suppressed because it is too large
Load Diff
75
_vendor/tqdm-4.64.1.dist-info/RECORD
Normal file
75
_vendor/tqdm-4.64.1.dist-info/RECORD
Normal 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
|
||||
0
_vendor/tqdm-4.64.1.dist-info/REQUESTED
Normal file
0
_vendor/tqdm-4.64.1.dist-info/REQUESTED
Normal file
6
_vendor/tqdm-4.64.1.dist-info/WHEEL
Normal file
6
_vendor/tqdm-4.64.1.dist-info/WHEEL
Normal 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
|
||||
|
||||
2
_vendor/tqdm-4.64.1.dist-info/entry_points.txt
Normal file
2
_vendor/tqdm-4.64.1.dist-info/entry_points.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
[console_scripts]
|
||||
tqdm = tqdm.cli:main
|
||||
1
_vendor/tqdm-4.64.1.dist-info/top_level.txt
Normal file
1
_vendor/tqdm-4.64.1.dist-info/top_level.txt
Normal file
@@ -0,0 +1 @@
|
||||
tqdm
|
||||
41
_vendor/tqdm/__init__.py
Normal file
41
_vendor/tqdm/__init__.py
Normal 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
3
_vendor/tqdm/__main__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .cli import main
|
||||
|
||||
main()
|
||||
BIN
_vendor/tqdm/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/__main__.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/__main__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/_dist_ver.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/_dist_ver.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/_main.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/_main.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/_monitor.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/_monitor.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/_tqdm.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/_tqdm.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/_tqdm_gui.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/_tqdm_gui.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/_tqdm_notebook.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/_tqdm_notebook.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/_tqdm_pandas.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/_tqdm_pandas.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/_utils.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/_utils.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/asyncio.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/asyncio.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/auto.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/auto.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/autonotebook.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/autonotebook.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/cli.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/cli.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/dask.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/dask.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/gui.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/gui.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/keras.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/keras.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/notebook.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/notebook.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/rich.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/rich.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/std.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/std.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/tk.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/tk.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/utils.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/utils.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/__pycache__/version.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/__pycache__/version.cpython-310.pyc
Normal file
Binary file not shown.
1
_vendor/tqdm/_dist_ver.py
Normal file
1
_vendor/tqdm/_dist_ver.py
Normal file
@@ -0,0 +1 @@
|
||||
__version__ = '4.64.1'
|
||||
9
_vendor/tqdm/_main.py
Normal file
9
_vendor/tqdm/_main.py
Normal 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
95
_vendor/tqdm/_monitor.py
Normal 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
9
_vendor/tqdm/_tqdm.py
Normal 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)
|
||||
9
_vendor/tqdm/_tqdm_gui.py
Normal file
9
_vendor/tqdm/_tqdm_gui.py
Normal 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)
|
||||
9
_vendor/tqdm/_tqdm_notebook.py
Normal file
9
_vendor/tqdm/_tqdm_notebook.py
Normal 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)
|
||||
24
_vendor/tqdm/_tqdm_pandas.py
Normal file
24
_vendor/tqdm/_tqdm_pandas.py
Normal 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
12
_vendor/tqdm/_utils.py
Normal 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
93
_vendor/tqdm/asyncio.py
Normal 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
44
_vendor/tqdm/auto.py
Normal 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"]
|
||||
29
_vendor/tqdm/autonotebook.py
Normal file
29
_vendor/tqdm/autonotebook.py
Normal 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
315
_vendor/tqdm/cli.py
Normal 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
19
_vendor/tqdm/completion.sh
Executable 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
|
||||
98
_vendor/tqdm/contrib/__init__.py
Normal file
98
_vendor/tqdm/contrib/__init__.py
Normal 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)
|
||||
BIN
_vendor/tqdm/contrib/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/contrib/__pycache__/bells.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/bells.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/contrib/__pycache__/concurrent.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/concurrent.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/contrib/__pycache__/discord.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/discord.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/contrib/__pycache__/itertools.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/itertools.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/contrib/__pycache__/logging.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/logging.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/contrib/__pycache__/slack.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/slack.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/contrib/__pycache__/telegram.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/telegram.cpython-310.pyc
Normal file
Binary file not shown.
BIN
_vendor/tqdm/contrib/__pycache__/utils_worker.cpython-310.pyc
Normal file
BIN
_vendor/tqdm/contrib/__pycache__/utils_worker.cpython-310.pyc
Normal file
Binary file not shown.
26
_vendor/tqdm/contrib/bells.py
Normal file
26
_vendor/tqdm/contrib/bells.py
Normal 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()
|
||||
130
_vendor/tqdm/contrib/concurrent.py
Normal file
130
_vendor/tqdm/contrib/concurrent.py
Normal 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)
|
||||
125
_vendor/tqdm/contrib/discord.py
Normal file
125
_vendor/tqdm/contrib/discord.py
Normal 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}'):
|
||||
... ...
|
||||
|
||||

|
||||
"""
|
||||
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
|
||||
37
_vendor/tqdm/contrib/itertools.py
Normal file
37
_vendor/tqdm/contrib/itertools.py
Normal 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()
|
||||
128
_vendor/tqdm/contrib/logging.py
Normal file
128
_vendor/tqdm/contrib/logging.py
Normal 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
|
||||
126
_vendor/tqdm/contrib/slack.py
Normal file
126
_vendor/tqdm/contrib/slack.py
Normal 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}'):
|
||||
... ...
|
||||
|
||||

|
||||
"""
|
||||
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
|
||||
159
_vendor/tqdm/contrib/telegram.py
Normal file
159
_vendor/tqdm/contrib/telegram.py
Normal 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}'):
|
||||
... ...
|
||||
|
||||

|
||||
"""
|
||||
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
|
||||
40
_vendor/tqdm/contrib/utils_worker.py
Normal file
40
_vendor/tqdm/contrib/utils_worker.py
Normal 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
46
_vendor/tqdm/dask.py
Normal 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
191
_vendor/tqdm/gui.py
Normal 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
124
_vendor/tqdm/keras.py
Normal 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
329
_vendor/tqdm/notebook.py
Normal 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
156
_vendor/tqdm/rich.py
Normal 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
1541
_vendor/tqdm/std.py
Normal file
File diff suppressed because it is too large
Load Diff
207
_vendor/tqdm/tk.py
Normal file
207
_vendor/tqdm/tk.py
Normal 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
316
_vendor/tqdm/tqdm.1
Normal 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
354
_vendor/tqdm/utils.py
Normal 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
9
_vendor/tqdm/version.py
Normal 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
@@ -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);
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user