├── #install.cmd ├── #install.sh ├── #setup.cmd ├── #update-readme.cmd ├── .gitignore ├── .idea └── dictionaries │ ├── mo_han.xml │ └── mohan.xml ├── .vscode └── settings.json ├── LICENSE ├── _README.md ├── __dump__ ├── #open-new-console.py ├── #open-new-ptpython.py ├── #update-winscript.cmd ├── __init__.py ├── _x_segslice.py ├── bilidl_worker.py ├── catalog_hentainexus_archive.py ├── cloudapi.py ├── cut_file.py ├── dota2_lib.py ├── dota2_waiter.py ├── ets_ │ ├── __init__.py │ ├── i0_sel_null.py │ ├── i0_sel_qt.py │ ├── i0_sel_wx.py │ ├── i1_traits.py │ ├── i1_traitsui.py │ ├── i1_traitsui_qt.py │ ├── i1_traitsui_wx.py │ ├── i1_util.py │ ├── i2_chaco.py │ ├── i2_enable.py │ ├── i2_qt_binder.py │ ├── m_path.py │ └── ui_rename.py ├── ffmpeg_concat.py ├── hentai.py ├── hentai_cafe.py ├── ip138.py ├── jijidown_rename.py ├── nhentai.py ├── photosmasters.py ├── pick_zip_files_none_webp.py ├── rename_md5.py ├── uia_android.py ├── winscript │ ├── _bldl.cmd │ ├── bilidl.cmd │ ├── conv.bilimovie2hevc8b.infolder.cmd │ ├── conv.copy2mp4.cmd │ ├── conv.film2hevc8b.infolder.cmd │ ├── conv.hevc8b.cmd │ ├── conv.hevc8b.infolder.cmd │ ├── conv.limit10mbwebm2gif.batch.cmd │ ├── conv.manga2webp.cmd │ ├── conv.manga2webp.infolder.cmd │ ├── conv.mmd2hevc8b.infolder.cmd │ ├── conv.pic2webp.infolder.cmd │ ├── conv.pic2webp.infolders.cmd │ ├── conv.pic2webp.smart.cmd │ ├── delete.nonwebp.infolder.cmd │ ├── delete.webp.infolder.cmd │ ├── drawincmd.cmd │ ├── fname.cbz.cmd │ ├── fname.clear.__tag__.batch.cmd │ ├── fname.lefthead.cmd │ ├── fname.spechar.convert.cmd │ ├── fname.spechar.revert.cmd │ ├── fname.tag.videocodec.cmd │ ├── pycharm-add-context-menu.cmd │ ├── tag.folder.nozip.cmd │ ├── tag.hevc8b.cmd │ ├── tag.nonhdvideo.__origin__.infolder.cmd │ ├── tag.videocodec.infolder.cmd │ ├── videoinfo.cmd │ ├── wincmdlib.cmd │ ├── wrap.antrenamer.cmd │ ├── wrap.ffprobe.cmd │ ├── wrap.subst.cmd │ ├── ytdl.cmd │ └── ytdl.worker.cmd └── ytdl_iwara_na2uploader.py ├── cmds.py ├── cmds_danmaku.py ├── cmds_ehentai.py ├── cmds_envar.py ├── cmds_ffmpeg.py ├── cmds_file2link.py ├── cmds_fstk.py ├── cmds_img.py ├── cmds_iwara.py ├── cmds_koditools.py ├── cmds_ostk.py ├── cmds_test.py ├── cmds_text.py ├── cmds_time.py ├── cmds_webp.py ├── cmds_webscrape.py ├── cmds_webtools.py ├── devkit ├── __init__.py └── setup_for_humans.py ├── dotnetkit └── rpcb │ ├── .vs │ └── rpcb │ │ └── v15 │ │ ├── .suo │ │ └── Server │ │ └── sqlite3 │ │ ├── db.lock │ │ ├── storage.ide │ │ ├── storage.ide-shm │ │ └── storage.ide-wal │ ├── packages │ └── NNanomsg.0.5.2 │ │ ├── .signature.p7s │ │ ├── NNanomsg.0.5.2.nupkg │ │ ├── content │ │ └── net40 │ │ │ ├── x64 │ │ │ ├── libnanomsg.so │ │ │ └── nanomsg.dll │ │ │ └── x86 │ │ │ ├── libnanomsg.so │ │ │ └── nanomsg.dll │ │ ├── lib │ │ └── net40 │ │ │ └── NNanomsg.dll │ │ └── tools │ │ └── net40 │ │ └── install.ps1 │ ├── rpcb.netfx45 │ ├── DaemonProcess.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── packages.config │ ├── rpcb.netfx45.csproj │ ├── x64 │ │ ├── libnanomsg.so │ │ └── nanomsg.dll │ └── x86 │ │ ├── libnanomsg.so │ │ └── nanomsg.dll │ ├── rpcb.sln │ └── rpcb.sln.DotSettings.user ├── etc ├── bashrc ├── byobu ├── clash │ ├── custom_direct.yaml │ ├── custom_proxy.yaml │ ├── note │ ├── public_free.config.yaml │ ├── public_proxy_provider.yaml │ ├── readme.md │ ├── rule.js │ └── rule.yaml ├── hosts ├── kitsunebi-android │ └── rules │ │ ├── self-use-ehentai-ip-direct.conf │ │ └── self-use.conf ├── nginx │ ├── install-snippets.sh │ ├── sites-available │ │ └── subdomain-redir-to-port │ └── snippets │ │ ├── location-acme-challenge │ │ ├── location-acme-challenge-with-fallback │ │ ├── location-autoindex │ │ ├── location-netdata │ │ ├── location-redir-root-to-https │ │ ├── location-redir-to-port │ │ ├── location-webdav-common │ │ ├── location-webdav-path-rewrite-add-slash │ │ ├── proxy-set-headers │ │ ├── proxy-websocket │ │ ├── rewrite-subdir-to-port │ │ ├── server-hsts │ │ ├── server-http │ │ ├── server-https │ │ └── v2ray-ws ├── plug.vim ├── screenrc └── vimrc ├── gallery-dl-wrap.py ├── i18n ├── en.yml └── zh-Hans.yml ├── ipy.cmd ├── lib_pkg └── libusb-1.0.24-windows.7z ├── my_tg_bot.py ├── mykit.py ├── mykits ├── bilibili_aocx.py ├── bilibili_aocx.spec ├── console_transcode.py ├── e.envar.autoset.py ├── script_snippets.md └── web_viewer.py ├── mylib ├── __deprecated__.py ├── __init__.py ├── _misc.py ├── cli.py ├── const.py ├── device.py ├── dukto.py ├── easy │ ├── __common__.py │ ├── __init__.py │ ├── asyncio.py │ ├── builtin_dict.py │ ├── common │ │ └── __init__.py │ ├── extra │ │ ├── __init__.py │ │ ├── call.py │ │ └── path_checker.py │ ├── filename_tags.py │ ├── fstk.py │ ├── io.py │ ├── logging.py │ ├── ostk.py │ ├── socket.py │ ├── stdlibs │ │ ├── __init__.py │ │ ├── threading.py │ │ └── typing.py │ ├── text.py │ └── webbrowser.py ├── enchant │ ├── __init__.py │ └── potplayer.py ├── ext │ ├── PIL.py │ ├── __init__.py │ ├── colour.py │ ├── console_app.py │ ├── ezqt │ │ ├── __init__.py │ │ └── util │ │ │ ├── __init__.py │ │ │ ├── enable_auto_screen_scale.py │ │ │ └── enable_qt_virtual_keyboard.py │ ├── fstk.py │ ├── getch.py │ ├── html.py │ ├── http_headers.py │ ├── i18n.py │ ├── ostk.py │ ├── ostk_nt.py │ ├── ostk_posix.py │ ├── pure_python_adb.py │ ├── pyside2 │ │ ├── __init__.py │ │ ├── const.py │ │ ├── layout.py │ │ ├── model.py │ │ ├── signal.py │ │ ├── thread.py │ │ ├── ui_loader.py │ │ ├── util.py │ │ ├── view.py │ │ └── widget.py │ ├── splinter.py │ ├── text.py │ ├── tricks.py │ └── tui.py ├── ffmpeg_alpha.py ├── gui_im.py ├── gui_old.py ├── math.py ├── microsoft_office.py ├── picture.py ├── pip2pi_x.py ├── shards │ ├── __init__.py │ ├── qt_web_render.py │ └── win32_named_pipe.py ├── sites │ ├── __init__.py │ ├── bilibili │ │ ├── __init__.py │ │ ├── __to_be_deprecated__.py │ │ ├── bili_plus_3rd_party.py │ │ ├── browser.py │ │ └── mobile_app_offline_cache.py │ ├── ehentai.py │ ├── hentai_cafe.py │ ├── iwara.py │ ├── misc.py │ ├── pixiv.py │ ├── pornhub.py │ ├── sankakucomplex.py │ └── youtube.py ├── tg_bot.py ├── tools │ ├── __init__.py │ └── mykit_parts.py ├── uia.py ├── unifont-13.0.04.ttf ├── web_client.py ├── wrapper │ ├── MKVToolNix.py │ ├── __init__.py │ ├── aria2c.py │ ├── cwebp.py │ ├── ffmpeg.py │ ├── readme.md │ └── tesseract_ocr.py └── youtube_dl_x.py ├── nixscript ├── cftrace.sh ├── ssh-forward-smb-clear.sh └── ssh-forward-smb.sh ├── oldezpykit ├── LICENSE ├── README.md ├── __init__.py ├── allinone.py ├── builtin │ ├── __init__.py │ ├── _dict.py │ ├── _list.py │ └── _str.py ├── const │ ├── __init__.py │ └── color.py ├── metautil │ ├── __init__.py │ ├── objutil.py │ ├── singleton.py │ ├── timer.py │ └── typing.py ├── readme-src.md ├── setup.py ├── something.py ├── stdlib │ ├── __init__.py │ ├── argparse.py │ ├── base64.py │ ├── datetime.py │ ├── glob.py │ ├── http │ │ ├── __init__.py │ │ ├── cookiejar.py │ │ └── cookiejar_backport_from_cpython_v_3_10.py │ ├── io │ │ ├── __init__.py │ │ ├── slicefileio.py │ │ └── virtualfileio.py │ ├── logging.py │ ├── os │ │ ├── __init__.py │ │ ├── common.py │ │ ├── nt.py │ │ └── posix.py │ ├── re.py │ ├── shutil │ │ ├── __deprecated__.py │ │ ├── __deprecated_patch_copyfileobj_lame__.py │ │ ├── __init__.py │ │ └── patch_fastercopy.py │ ├── subprocess.py │ ├── threading.py │ └── urllib │ │ ├── __init__.py │ │ └── parse.py └── wip │ ├── __init__.py │ ├── call.py │ ├── config.py │ └── contractor.py ├── oldezpykitext ├── __init__.py ├── allinone.py ├── appkit.py ├── config.py ├── extlib │ ├── PIL.py │ ├── __init__.py │ ├── backoff.py │ ├── daemoniker.py │ ├── decorator.py │ ├── decorators.py │ ├── filetype.py │ ├── retry.py │ ├── retrying.py │ ├── termcolor.py │ ├── win32clipboard.py │ └── yaml.py ├── rig │ ├── BBDown.py │ ├── __init__.py │ └── aria2.py ├── setup.py ├── stdlib │ ├── __init__.py │ └── os │ │ ├── __init__.py │ │ └── clipboard │ │ ├── HTMLClipboard.py │ │ ├── __init__.py │ │ ├── common.py │ │ ├── nt.py │ │ ├── nt_win32cb.py │ │ ├── nt_win32cb_html.py │ │ └── posix.py ├── webclient │ ├── __init__.py │ ├── browser.py │ ├── cookie.py │ ├── header.py │ └── lxml_html.py ├── wip │ ├── __init__.py │ └── rpc │ │ ├── __init__.py │ │ ├── common_bak.py │ │ ├── nanomsg_bak.py │ │ └── nng.py └── yaml.py ├── readme-src.md ├── requirements ├── _async_io.txt ├── _cli.txt ├── _decorator.txt ├── _device_input.txt ├── _ecad.txt ├── _enthought_tool_suite.txt ├── _graphic.txt ├── _html_parse.txt ├── _i18n.txt ├── _image.txt ├── _json_query.txt ├── _macos_enhance.txt ├── _mswin_enhance.txt ├── _new_stdlib.txt ├── _ocr.txt ├── _plot_data.txt ├── _pypi.txt ├── _toolkit_for_devel.txt ├── _webp.txt ├── common.txt ├── discard.txt ├── gui.txt ├── linux.txt ├── mswin.txt ├── note.txt ├── telegram.txt └── wishlist.txt ├── scpi_shell ├── __init__.py ├── cli.onefile.spec ├── cli.py ├── cli.spec ├── core.py ├── icon.ico ├── icon.ico.bak ├── icon.png ├── icon.svg └── requirements.txt ├── the_new_protoplasm ├── __init__.py ├── base64.py ├── func.py └── the_base.py ├── websites ├── __init__.py ├── bilibili │ ├── __init__.py │ └── webapi.py └── ehentai.py ├── whl ├── tesserocr-2.4.0-cp36-cp36m-win32.whl ├── tesserocr-2.4.0-cp36-cp36m-win_amd64.whl ├── tesserocr-2.4.0-cp37-cp37m-win32.whl └── tesserocr-2.4.0-cp37-cp37m-win_amd64.whl └── whl_gohlke ├── enable-4.8.1-cp36-cp36m-win32.whl └── enable-4.8.1-cp36-cp36m-win_amd64.whl /#install.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | set default.dst=%locallib_env%\ 3 | set dst=%1 4 | if not defined dst set dst=%default.dst% 5 | 6 | pushd "%~dp0" 7 | pyclean . 8 | 9 | mkdir %dst%\mylib 10 | xcopy /s /y mylib %dst%\mylib 11 | mkdir %dst%\mykits 12 | xcopy /s /y mykits %dst% 13 | mkdir %dst%\i18n 14 | xcopy /s /y i18n %dst%\i18n 15 | 16 | mkdir %dst%\oldezpykit 17 | xcopy /s /y oldezpykit %dst%\oldezpykit 18 | mkdir %dst%\oldezpykitext 19 | xcopy /s /y oldezpykitext %dst%\oldezpykitext 20 | mkdir %dst%\websites 21 | xcopy /s /y websites %dst%\websites 22 | mkdir %dst%\apps 23 | xcopy /s /y apps %dst% 24 | 25 | popd -------------------------------------------------------------------------------- /#install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | pyclean . 4 | cp -rp mylib ~/bin/ 5 | cp -rp i18n ~/bin/ 6 | install -p -m 755 mykits/mykit.py ~/bin/mykit 7 | install -p -m 755 mykits/my_tg_bot.py ~/bin/my_tg_bot 8 | 9 | cp -rp oldezpykit ~/bin/ 10 | cp -rp oldezpykitext ~/bin/ 11 | cp -rp websites ~/bin/ 12 | chmod -R +x apps 13 | cp -pt ~/bin apps/* -------------------------------------------------------------------------------- /#setup.cmd: -------------------------------------------------------------------------------- 1 | %1\setup.py clean --all bdist_wheel upload clean --all -------------------------------------------------------------------------------- /#update-readme.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set file.input=readme-src.md 4 | set file.output=README.MD 5 | cd /d "%~dp0" 6 | 7 | gh-md-toc %file.input% > %file.output% 8 | echo=>> %file.output% 9 | echo=>> %file.output% 10 | type %file.input% >> %file.output% -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | __pycache__/ 4 | build/ 5 | dist/ 6 | *.tmp 7 | tmp/ 8 | tmp*.* 9 | test/ 10 | test.* 11 | *.exe 12 | *.log 13 | dukto.txt 14 | scpi_shell/extra.py 15 | scpi_shell/commands.txt 16 | scpi_shell/functions.txt 17 | __enamlcache__ 18 | pyface 19 | traitsui 20 | .ipynb_checkpoints/ 21 | mykits/cmds_*.yml 22 | python36.dll 23 | .venv 24 | *.egg-info 25 | scpi_shell/extra_old.py 26 | scpi_shell/more-items.txt 27 | dotnetkit/**/*.cache 28 | dotnetkit/**/TemporaryGeneratedFile_* 29 | iwara images 30 | temp/ 31 | wt3000波形采集临时工具.spec 32 | add_to_envar_path_cd.bat 33 | -------------------------------------------------------------------------------- /.idea/dictionaries/mohan.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | alpharacks 5 | appcache 6 | autoremove 7 | bldl 8 | bvid 9 | cloudapi 10 | coinit 11 | coverpage 12 | cython 13 | danmaku 14 | decomposer 15 | dirname 16 | dota 17 | dropdown 18 | fileinfo 19 | filepath 20 | filesize 21 | fmpeg 22 | fullsize 23 | gallerythumb 24 | ghostdriver 25 | hentai 26 | hevc 27 | imagefile 28 | jijidown 29 | localapi 30 | locallib 31 | loglevel 32 | lowendspirit 33 | lxml 34 | mpeg 35 | mtime 36 | multitype 37 | nhentai 38 | numlock 39 | objectpath 40 | pagedown 41 | pageup 42 | phantomjs 43 | photosmasters 44 | pornhub 45 | potplayer 46 | ptpython 47 | pyautogui 48 | pyperclip 49 | pythonpath 50 | pywinauto 51 | realpath 52 | repl 53 | robocopy 54 | solus 55 | solusvm 56 | subsampling 57 | tableh 58 | tbtitle 59 | uiautomator 60 | virmach 61 | vmstat 62 | vpscp 63 | vupload 64 | webdriver 65 | webm 66 | winbin 67 | 68 | 69 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.analysis.typeCheckingMode": "basic" 3 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 墨焓 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /__dump__/#open-new-console.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | 4 | import os 5 | 6 | os.environ['pythonpath'] = '.' 7 | cmd = {'nt': 'start /max cmd'} 8 | os.system(cmd[os.name]) 9 | -------------------------------------------------------------------------------- /__dump__/#open-new-ptpython.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | 4 | import os 5 | 6 | os.environ['pythonpath'] = '.' 7 | cmd = {'nt': 'start /max ptpython'} 8 | os.system(cmd[os.name]) 9 | -------------------------------------------------------------------------------- /__dump__/#update-winscript.cmd: -------------------------------------------------------------------------------- 1 | pushd "%~dp0" 2 | 3 | copy /y %locallib_env%\_winbin\drawincmd.cmd winscript\ 4 | copy /y %locallib_env%\_winbin\wincmdlib.cmd winscript\ 5 | copy /y %locallib_env%\_winbin\ytdl*.cmd winscript\ 6 | copy /y %locallib_env%\_winbin\conv.*.cmd winscript\ 7 | copy /y %locallib_env%\_winbin\fname.*.cmd winscript\ 8 | copy /y %locallib_env%\_winbin\tag.*.cmd winscript\ 9 | copy /y %locallib_env%\_winbin\delete.*.cmd winscript\ 10 | copy /y %locallib_env%\_winbin\wrap.*.cmd winscript\ 11 | 12 | copy /y %locallib_env%\_winbin\bldl.cmd winscript\ 13 | copy /y %locallib_env%\_winbin\videoinfo.cmd winscript\ 14 | 15 | popd -------------------------------------------------------------------------------- /__dump__/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /__dump__/cut_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | 6 | def _cut_file_bytes(file: str, size: int) -> bytes: 7 | if size == 0: 8 | return b'' 9 | with open(file, 'rb') as f: 10 | if size > 0: 11 | return f.read()[0:size] 12 | else: 13 | return f.read()[size:] 14 | 15 | 16 | if __name__ == '__main__': 17 | fp = sys.argv[1] 18 | s = sys.argv[2] 19 | with open('cutfile.tmp', 'wb') as cf: 20 | cf.write(_cut_file_bytes(fp, int(s))) 21 | -------------------------------------------------------------------------------- /__dump__/dota2_waiter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | """ 5 | 6 | from dota2_lib import Dota2Controller 7 | from os.path import realpath, dirname, expanduser 8 | from sys import argv 9 | 10 | __author__ = '墨焓 ' 11 | __program__ = 'dota2 waiter' 12 | __version__ = 'demo' 13 | 14 | if __name__ == '__main__': 15 | feed = expanduser('~/etc/dota2_waiter') 16 | print('素材文件夹路径', realpath(feed)) 17 | g = Dota2Controller(feed) 18 | g.auto_waiter((5, 20)) 19 | -------------------------------------------------------------------------------- /__dump__/ets_/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | -------------------------------------------------------------------------------- /__dump__/ets_/i0_sel_null.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from traits.etsconfig.api import ETSConfig 4 | 5 | TRAITS_TOOLKIT = ETSConfig.toolkit = 'null' 6 | -------------------------------------------------------------------------------- /__dump__/ets_/i0_sel_qt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from traits.etsconfig.api import ETSConfig 4 | 5 | TRAITS_TOOLKIT = ETSConfig.toolkit = 'qt4' 6 | 7 | 8 | def make_item_style_sheet( 9 | *, 10 | font_px: int = None, 11 | font_bold: bool = False, 12 | font_italic: bool = False, 13 | font_family: str = None, 14 | color: str = None, 15 | color_bg: str = None 16 | ): 17 | font_l = [e for e in ( 18 | # order matters 19 | 'italic' if font_italic else '', 20 | 'bold' if font_bold else '', 21 | f'{font_px}px' if font_px else '', 22 | font_family 23 | ) if e] 24 | sec_l = [f'font: {" ".join(font_l)}'] 25 | sec_l.append(f'color: {color}') if color else ... 26 | sec_l.append(f'background: {color_bg}') if color_bg else ... 27 | ss = '; '.join(sec_l) 28 | print(ss) 29 | return ss 30 | -------------------------------------------------------------------------------- /__dump__/ets_/i0_sel_wx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from traits.etsconfig.api import ETSConfig 4 | 5 | TRAITS_TOOLKIT = ETSConfig.toolkit = 'wx' 6 | -------------------------------------------------------------------------------- /__dump__/ets_/i1_traits.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | import traits.observation.api as ob_api 4 | import traits.observation.events as ob_evt 5 | import traits.observation.expression as ob_exp 6 | from traits.api import * 7 | 8 | from .i1_util import * 9 | 10 | 11 | def __refer_sth(): 12 | return HasTraits, TraitType, ob_api, ob_evt, ob_exp 13 | -------------------------------------------------------------------------------- /__dump__/ets_/i1_traitsui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from enable.savage.trait_defs.ui.svg_button import SVGButton 4 | from pyface.api import * 5 | from traitsui.api import * 6 | from traitsui.key_bindings import * 7 | 8 | from .i1_traits import * 9 | 10 | 11 | def __unused_import_keeper(): 12 | return ImageResource, TraitType, SVGButton 13 | 14 | 15 | class SimpleHandler(Handler): 16 | def __hdlr_do_nothing__(self, *args): 17 | pass 18 | 19 | @staticmethod 20 | def __hdlr_close_view__(info: UIInfo): 21 | if not info.initialized: 22 | return 23 | info.ui.dispose() 24 | 25 | @staticmethod 26 | def __hdlr_quit__(*args): 27 | sys.exit() 28 | 29 | def __hdlr_close_view_and_quit__(self, info: UIInfo): 30 | self.__hdlr_close_view__(info) 31 | self.__hdlr_quit__() 32 | 33 | 34 | KB_ESC_NOTHING = KeyBinding(binding1='Esc', method_name=SimpleHandler.__hdlr_do_nothing__.__name__) 35 | KB_ESC_CLOSE = KeyBinding(binding1='Esc', method_name=SimpleHandler.__hdlr_close_view__.__name__) 36 | KB_ESC_QUIT = KeyBinding(binding1='Esc', method_name=SimpleHandler.__hdlr_quit__.__name__) 37 | -------------------------------------------------------------------------------- /__dump__/ets_/i1_traitsui_qt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from .i0_sel_qt import * 4 | from .i1_traitsui import * 5 | 6 | 7 | def __unused_import_keeper(): 8 | return TRAITS_TOOLKIT, SimpleHandler 9 | -------------------------------------------------------------------------------- /__dump__/ets_/i1_traitsui_wx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from .i0_sel_wx import * 4 | from .i1_traitsui import * 5 | 6 | 7 | def __refer_sth(): 8 | return TRAITS_TOOLKIT, SimpleHandler 9 | -------------------------------------------------------------------------------- /__dump__/ets_/i1_util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from traits.api import HasTraits 4 | from varname import nameof 5 | 6 | from oldezpykit import AttrName 7 | 8 | 9 | def trait_extra_attr_name(attr_name: str): 10 | return f'__extra_attr_{attr_name}__' 11 | 12 | 13 | def trait_with_attr(traits_obj: HasTraits, name: str, value=...): 14 | if value is ...: 15 | return getattr(traits_obj, trait_extra_attr_name(name)) 16 | else: 17 | setattr(traits_obj, trait_extra_attr_name(name), value) 18 | 19 | 20 | def trait_with_label(traits_obj: HasTraits, label=...): 21 | attr_name = 'label' 22 | return trait_with_attr(traits_obj, attr_name, label) 23 | 24 | 25 | def trait_with_id(traits_obj: HasTraits, id_=...): 26 | attr_name = 'id' 27 | return trait_with_attr(traits_obj, attr_name, id_) 28 | 29 | 30 | class TraitName(AttrName): 31 | def __setattr__(self, key, value): 32 | super(TraitName, self).__setattr__(key, value) 33 | trait_with_id(value, key) 34 | 35 | 36 | def var_name(*obj): 37 | return nameof(*obj, caller=2) 38 | 39 | 40 | def var_name_path(*obj): 41 | return nameof(*obj, caller=2, full=True) 42 | 43 | 44 | def object_trait_name(trait_name): 45 | return f'object.{trait_name}' 46 | 47 | 48 | an = AttrName() 49 | tn = TraitName() 50 | tl = trait_with_label 51 | ti = trait_with_id 52 | vn = var_name 53 | vp = var_name_path 54 | ot = object_trait_name 55 | -------------------------------------------------------------------------------- /__dump__/ets_/i2_chaco.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from chaco.api import * 4 | from chaco.tools.api import * 5 | from chaco.tools.cursor_tool import * 6 | 7 | 8 | def __keep_unref_imports(): 9 | return ImageData, BetterZoom, BaseCursorTool 10 | -------------------------------------------------------------------------------- /__dump__/ets_/i2_enable.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from enable.api import * 4 | from enable.savage.trait_defs.ui.svg_button import * 5 | 6 | 7 | def __keep_unref_imports(): 8 | return SVGButton, Component 9 | -------------------------------------------------------------------------------- /__dump__/ets_/i2_qt_binder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from qt_binder.api import * 4 | from qt_binder.binding import * 5 | from qt_binder.raw_widgets import * 6 | from qt_binder.widgets import * 7 | 8 | assert (Binding, Bound, Widget, binder_registry) 9 | -------------------------------------------------------------------------------- /__dump__/ets_/ui_rename.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from .i1_traitsui_qt import * 4 | from .m_path import Path 5 | from mylib.ext import i18n 6 | 7 | i18n.preset___alpha() 8 | tt = i18n.tt 9 | 10 | 11 | class RenameDialog(Path): 12 | info_src = tn.info_src = Str(tn.info_src * 100) 13 | info_text = tn.info_text = Str('\n'.join([str(i) for i in range(20)])) 14 | 15 | traits_view = View( 16 | VGroup( 17 | Item(' '), 18 | HGroup( 19 | Item(' '), 20 | Item(vn(self.full), label=f"{tt('Source')} {tt('Path')}", editor=TextEditor(read_only=True)), 21 | # Item(' '), 22 | ), 23 | VGroup( 24 | Item(tn.info_src, show_label=False, editor=TextEditor(read_only=True)), 25 | Item(tn.info_text, show_label=False, style='custom', editor=TextEditor(read_only=True)), 26 | show_border=True, 27 | ), 28 | Item(vn(self.dirname), show_label=False), 29 | HGroup( 30 | Item(vn(self.stem), show_label=False, has_focus=True, width=0.9), 31 | Item(vn(self.extension), show_label=False, width=0.1), 32 | ), 33 | ), 34 | 35 | title=f'{tt("Rename")} - {self.full}', 36 | resizable=True, width=0.5 37 | ) 38 | -------------------------------------------------------------------------------- /__dump__/ffmpeg_concat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | 6 | from mylib.__deprecated__ import _concat_videos_deprecated 7 | 8 | args = sys.argv[1:] 9 | if args: 10 | _concat_videos_deprecated(*args) 11 | else: 12 | print('{} input1 input2 ... output'.format(sys.argv[1])) 13 | -------------------------------------------------------------------------------- /__dump__/hentai_cafe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import logging 5 | 6 | from __dump__.hentai import HentaiCafeKit 7 | from mylib.easy.logging import LOG_FMT_MESSAGE_ONLY 8 | from mylib.easy.ostk import ensure_sigint_signal 9 | 10 | logging.basicConfig( 11 | level=logging.INFO, 12 | format=LOG_FMT_MESSAGE_ONLY 13 | ) 14 | 15 | 16 | if __name__ == '__main__': 17 | ensure_sigint_signal() 18 | uri = sys.argv[1] 19 | if len(sys.argv) >= 3: 20 | hc = HentaiCafeKit(int(sys.argv[2])) 21 | else: 22 | hc = HentaiCafeKit(5) 23 | hc.save_entry_to_cbz(uri) 24 | -------------------------------------------------------------------------------- /__dump__/ip138.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import requests 4 | import argparse 5 | from bs4 import BeautifulSoup 6 | 7 | 8 | def query_geo(ip: str): 9 | url = 'http://www.ip138.com/ips138.asp?ip={}&action=2'.format(ip) 10 | soup = BeautifulSoup(requests.get(url).content, 'lxml') 11 | text_l = [li.text for li in soup.find('ul', class_='ul1')('li')] 12 | return text_l 13 | 14 | 15 | def this_geo(): 16 | url = 'http://www.ip138.com/' 17 | soup = BeautifulSoup(requests.get(url).content, 'lxml') 18 | url = soup.iframe['mylib'] 19 | soup = BeautifulSoup(requests.get(url).content, 'lxml') 20 | return soup.body.text 21 | 22 | 23 | if __name__ == '__main__': 24 | ap = argparse.ArgumentParser(description='ip138.com') 25 | ap.add_argument('ip', nargs='?', default='', 26 | help='IP Address') 27 | ap.add_argument('-l', '--loop', action='store_true', 28 | help='Loop mode, type in and query IPs one by one, type q to quit') 29 | ap.add_argument('-i', '--this', action='store_true', 30 | help='Show IP and GeoInfo of this device') 31 | args = ap.parse_args() 32 | 33 | if args.loop: 34 | while True: 35 | ip = input('> ') 36 | if ip == 'q': 37 | exit(0) 38 | else: 39 | for i in query_geo(ip): 40 | print(i) 41 | elif args.this: 42 | print(this_geo()) 43 | elif args.ip: 44 | for i in query_geo(args.ip): 45 | print(i) 46 | else: 47 | print(this_geo()) 48 | 49 | -------------------------------------------------------------------------------- /__dump__/jijidown_rename.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from glob import glob 3 | 4 | from mylib.sites.bilibili.__to_be_deprecated__ import jijidown_rename_alpha 5 | 6 | if __name__ == '__main__': 7 | # _, allinone = os.path.split(sys.argv[1]) 8 | if sys.argv[1][-1] == '*': 9 | args = glob(sys.argv[1]) 10 | else: 11 | args = sys.argv[1:] 12 | for i in args: 13 | jijidown_rename_alpha(i) 14 | -------------------------------------------------------------------------------- /__dump__/nhentai.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import logging 5 | 6 | from mylib._misc import ExitCode 7 | from mylib.easy.logging import LOG_FMT_MESSAGE_ONLY 8 | from mylib.easy.ostk import ensure_sigint_signal 9 | from __dump__.hentai import NHentaiKit 10 | 11 | if __name__ == '__main__': 12 | ensure_sigint_signal() 13 | logging.basicConfig( 14 | level=logging.INFO, 15 | format=LOG_FMT_MESSAGE_ONLY, 16 | ) 17 | nhk = NHentaiKit() 18 | try: 19 | nhk.save_gallery_to_cbz(nhk.get_gallery(sys.argv[1])) 20 | except KeyboardInterrupt: 21 | exit(ExitCode.CTRL_C) 22 | -------------------------------------------------------------------------------- /__dump__/pick_zip_files_none_webp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | import argparse 4 | import os 5 | from time import time 6 | from zipfile import ZipFile, BadZipFile 7 | import shutil 8 | from mylib.ext.ostk import clipboard as cb 9 | from mylib.easy import ez_thread_factory 10 | from mylib.__deprecated__ import list_files 11 | from queue import Queue 12 | 13 | ap = argparse.ArgumentParser() 14 | ap.add_argument('-s', '--src', nargs='*') 15 | ap.add_argument('-d', '--dest-dir') 16 | ap.add_argument('-r', '--recursive') 17 | args = ap.parse_args() 18 | 19 | src = args.src 20 | dest = args.dest_dir 21 | recursive = args.recursive 22 | 23 | print(f'-> {dest}') 24 | q = Queue() 25 | 26 | 27 | def progress(): 28 | w = shutil.get_terminal_size()[0] - 1 29 | m = (w - 5) // 4 30 | t0 = time() 31 | while True: 32 | p = q.get() 33 | if p is None: 34 | break 35 | ps = f'{" " * w}\r{p[:m]} ... {p[-m:]}' 36 | t1 = time() 37 | if t1 - t0 > 0.2: 38 | print(ps, end='\r') 39 | t0 = t1 40 | 41 | 42 | t = ez_thread_factory(daemon=True)(progress) 43 | t.run() 44 | files_l = list_files(src or cb, recursive=recursive, progress_queue=q) 45 | x, y, z = 0, 0, 0 46 | print() 47 | for fp in files_l: 48 | z += 1 49 | try: 50 | zf = ZipFile(fp) 51 | except BadZipFile: 52 | continue 53 | y += 1 54 | for f in zf.namelist(): 55 | if f.endswith('.webp'): 56 | break 57 | else: 58 | zf.close() 59 | dfp = os.path.join(dest, os.path.split(fp)[-1]) 60 | shutil.move(fp, dfp) 61 | x += 1 62 | print(f'* {fp}') 63 | print(f'| {x} | {y} | {z} |', end='\r') 64 | -------------------------------------------------------------------------------- /__dump__/rename_md5.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Rename file(s) to MD5 with original file extension.""" 3 | 4 | from glob import glob 5 | from hashlib import md5 6 | from os import rename 7 | from os.path import splitext, split, join 8 | from sys import argv 9 | 10 | if __name__ == '__main__': 11 | for a in argv[1:]: 12 | print('+ {}:'.format(a)) 13 | al = glob(a.replace('[', '[[]')) 14 | if not al: 15 | al = [a] 16 | for f in al: 17 | with open(f, 'rb') as fd: 18 | h = md5(fd.read()).hexdigest() 19 | pd, bn = split(f) 20 | _, x = splitext(bn) 21 | n = join(pd, h + x) 22 | print(' + {} -> {}'.format(f, n)) 23 | rename(f, n) 24 | -------------------------------------------------------------------------------- /__dump__/uia_android.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | """Android UI Automate""" 4 | import uiautomator2 5 | import ppadb.client 6 | 7 | 8 | class RemoteAndroidUI: 9 | def __init__(self): 10 | self._adb = ppadb.client.Client() 11 | self._devices_dict = {} 12 | self.get_devices() 13 | self._remote_ui: uiautomator2.Device or None = None 14 | 15 | @property 16 | def adb(self): 17 | return self._adb 18 | 19 | @property 20 | def devices(self): 21 | return self._devices_dict 22 | 23 | @property 24 | def remote_ui(self): 25 | return self._remote_ui 26 | 27 | def get_devices(self) -> dict: 28 | d = {} 29 | for device in self.adb.devices(): 30 | d[device.serial] = device 31 | self._devices_dict = d 32 | return d 33 | 34 | def add_remote(self, addr: str) -> bool: 35 | host, port = addr.split(':', maxsplit=1) 36 | ok = self.adb.remote_connect(host, int(port)) 37 | if ok: 38 | self.get_devices() 39 | return ok 40 | 41 | def sel_remote_ui(self, addr: str) -> bool: 42 | if addr not in self.devices: 43 | if not self.add_remote(addr): 44 | return False 45 | self._remote_ui = uiautomator2.connect(addr) 46 | return True 47 | 48 | def click_object(self, prop: str, value: str, timeout=None, offset=None) -> bool: 49 | if self.remote_ui is None: 50 | return False 51 | uio = self.find_object(prop, value) 52 | if uio: 53 | try: 54 | uio.click(timeout=timeout, offset=offset) 55 | return True 56 | except uiautomator2.exceptions.UiObjectNotFoundError: 57 | return False 58 | else: 59 | return False 60 | 61 | def find_object(self, prop: str, value: str, timeout=None) -> uiautomator2.UiObject or None: 62 | if self.remote_ui is None: 63 | return None 64 | uio = self.remote_ui(**{prop: value}) 65 | try: 66 | uio.must_wait(timeout=timeout) 67 | return uio 68 | except uiautomator2.exceptions.UiObjectNotFoundError: 69 | return None 70 | -------------------------------------------------------------------------------- /__dump__/winscript/_bldl.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set cookies=%locallib_usretc%\cookies.bilibili.txt 4 | set workdir=%locallib_usrdl% 5 | set args=%* 6 | if not defined args ( 7 | set loopmode.title=%~nx0 8 | set loopmode.header=download from bilibili 9 | set loopmode.callee=bldl 10 | call wincmdlib loopmode 11 | goto :eof 12 | ) 13 | if not defined root set root=%workdir% 14 | pushd %root% 15 | title bldl %* 16 | bilidl_worker.py %* -c %cookies% 17 | popd 18 | goto :eof -------------------------------------------------------------------------------- /__dump__/winscript/bilidl.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set cookies=%locallib_usretc%\cookies.bilibili.txt 4 | set workdir=%locallib_usrdl% 5 | set args=%* 6 | if not defined args ( 7 | set loopmode.title=%~nx0 8 | set loopmode.header=download from bilibili 9 | set loopmode.callee=bilidl 10 | call wincmdlib loopmode 11 | goto :eof 12 | ) 13 | if not defined root set root=%workdir% 14 | pushd %root% 15 | bilidl_worker.py %* -c %cookies% 16 | popd 17 | goto :eof -------------------------------------------------------------------------------- /__dump__/winscript/conv.bilimovie2hevc8b.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set args=%* 5 | call set args=%%args:*%1=%% 6 | if defined args set args=%args:* =% 7 | 8 | conv.hevc8b.infolder %1 -vf "scale='min(iw,1280)':-2" -crf 25 %args% -------------------------------------------------------------------------------- /__dump__/winscript/conv.copy2mp4.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | if %~x1==.mp4 goto :eof 5 | set _localargs=%* 6 | call set _localargs=%%_localargs:*%1=%% 7 | if defined _localargs set _localargs=%_localargs:* =% 8 | ffmpeg -i %1 -codec copy %_localargs% "%~dp1%~n1.mp4" -------------------------------------------------------------------------------- /__dump__/winscript/conv.film2hevc8b.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set args=%* 5 | call set args=%%args:*%1=%% 6 | if defined args set args=%args:* =% 7 | 8 | conv.hevc8b.infolder %1 -vf "scale='min(iw,1280)':-2" -crf 25 %args% -------------------------------------------------------------------------------- /__dump__/winscript/conv.hevc8b.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set ffmpegargs=-c:v hevc -pix_fmt yuv420p 4 | set tag.origin=.__origin__ 5 | set /a thres.hd=960*720 6 | 7 | if not "%~2"=="" set args=%~2 8 | if defined args set ffmpegargs=%ffmpegargs% %args% 9 | call :check_hevc8b "%~n1" 10 | if %hevc8b%==1 echo # skip %~n1 && goto :eof 11 | call :check_encoded "%~n1" 12 | if %encoded%==1 echo # skip %~n1 && goto :eof 13 | title %args% %1 14 | set ext=%~x1 15 | if %ext%==.webm set ext=.mkv 16 | if %ext%==.flv set ext=.mp4 17 | call wincmdlib.cmd returnback wrap.ffprobe res "%~1" >nul 18 | set /a ipix=%_% 19 | if %ipix% lss %thres.hd% set ffmpegargs=%ffmpegargs% -crf 23 20 | ffmpeg -i "%~1" %ffmpegargs% "%~dpn1.hevc8b%ext%" && rename "%~1" "%~n1%tag.origin%%~x1" || pause 21 | goto :eof 22 | 23 | :check_hevc8b 24 | if "%~x1"==".hevc8b" (set hevc8b=1) else (set hevc8b=0) 25 | goto :eof 26 | 27 | :check_encoded 28 | if "%~x1"=="%tag.origin%" (set encoded=1) else (set encoded=0) 29 | goto :eof -------------------------------------------------------------------------------- /__dump__/winscript/conv.hevc8b.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set workdir="%~1" 5 | set args=%* 6 | call set args=%%args:*%1=%% 7 | if defined args set args=%args:* =% 8 | 9 | pushd %workdir% 10 | for %%i in (*.mp4) do call conv.hevc8b "%%~i" 11 | for %%i in (*.mkv) do call conv.hevc8b "%%~i" 12 | for %%i in (*.flv) do call conv.hevc8b "%%~i" 13 | popd 14 | goto :eof 15 | -------------------------------------------------------------------------------- /__dump__/winscript/conv.limit10mbwebm2gif.batch.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | for %%i in (*.webm) do (call :webm2gif "%%~i") 5 | del temp.i.webm 6 | del temp.o.gif 7 | goto :eof 8 | 9 | :webm2gif 10 | copy /y "%~1" temp.i.webm 11 | ffmpeg -i temp.i.webm temp.o.gif -y 12 | call :setsize temp.o.gif 13 | if %__size% gtr 10000000 ffmpeg -i temp.i.webm -vf "scale=iw/2:ih/2" temp.o.gif -y 14 | call :setsize temp.o.gif 15 | if %__size% gtr 10000000 ffmpeg -i temp.i.webm -vf "scale=iw/3:ih/3" temp.o.gif -y 16 | call :setsize temp.o.gif 17 | if %__size% gtr 10000000 ffmpeg -i temp.i.webm -vf "scale=iw/4:ih/4" temp.o.gif -y 18 | copy /y temp.o.gif "%~n1.gif" 19 | goto :eof 20 | 21 | :setsize 22 | set __size=%~z1 23 | goto :eof -------------------------------------------------------------------------------- /__dump__/winscript/conv.manga2webp.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set title=%~nx0 5 | %~2 6 | if not "%~1"=="" pushd %1 7 | call fname.spechar.convert * 8 | call :infolder 9 | call delete.nonwebp.infolder . 10 | call fname.spechar.revert * 11 | if not "%~1"=="" popd 12 | goto :eof 13 | 14 | :infolder 15 | setlocal 16 | move .ehviewer 0.ehviewer.txt >nul 2>&1 17 | move .thumb 0.thumb.jpg >nul 2>&1 18 | if exist 0.thumb.jpg (call wincmdlib filesize 0.thumb.jpg >nul) else set _=0 19 | if %_%==0 del 0.thumb.jpg >nul 2>&1 20 | for %%i in (*) do call :file "%%~i" 21 | goto :eof 22 | 23 | :file 24 | setlocal 25 | set /a ratio=67 26 | set /a q.max=80 27 | set /a q.min=50 28 | if /i %~x1==.gif ( 29 | call conv.gif2mp4 "%~1" 30 | goto :eof 31 | ) 32 | if /i %~x1==.mp4 goto :eof 33 | if /i %~x1==.webm goto :eof 34 | if /i %~x1==.webp goto :eof 35 | if /i %~x1==.txt goto :eof 36 | if /i %~x1==.tag goto :eof 37 | if /i %~x1==.json goto :eof 38 | call wincmdlib returnback wrap.ffprobe w %1 >nul 39 | set /a w=_ 40 | call wincmdlib returnback wrap.ffprobe h %1 >nul 41 | set /a h=_ 42 | set /a res=w*h 43 | set /a max=1024*512 44 | :: 1280*1920=2457600 _*2=4915200 _*1.5=7372800 45 | if %res% leq 2457600 (set /a max=1024*256) else (set /a max=1024*384) 46 | if %res% gtr 4915200 (set /a max=1024*512 & set /a scale.min=85) else (set /a scale.min=100) 47 | if %res% gtr 7372800 (set /a scale.min=70) 48 | call conv.pic2webp.smart %1 49 | goto :eof 50 | -------------------------------------------------------------------------------- /__dump__/winscript/conv.manga2webp.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set title=%~nx0 5 | %~2 6 | if not "%~1"=="" pushd %1 7 | call fname.spechar.convert -aF * 8 | call :folders 9 | call fname.spechar.revert -aF * 10 | if not "%~1"=="" popd 11 | goto :eof 12 | 13 | :folders 14 | setlocal 15 | for /d %%i in (*) do ( 16 | call drawincmd line double 17 | echo %%i 18 | title %title% %%i 19 | pushd "%%~i" 20 | call conv.manga2webp 21 | popd 22 | if not exist "%%~i"\FOLDER.TAG 7za a "%%~i.zip" "%%~i" -r && rd /s /q "%%~i" 23 | ) 24 | call drawincmd line double 25 | call fname.cbz.cmd 26 | goto :eof 27 | -------------------------------------------------------------------------------- /__dump__/winscript/conv.mmd2hevc8b.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set /a pixels.fhd=1920*800 4 | set /a pixels.hd=1280*720 5 | 6 | set _args=%* 7 | call set _args=%%_args:*%1=%% 8 | if defined _args set _args=%_args:* =% 9 | 10 | if not "%~1"=="" pushd "%~1" 11 | call fname.spechar.convert *.mp4 *.mkv *.webm *.flv 12 | for %%i in (*.mp4) do call :smart_conv "%%~i" 13 | for %%i in (*.mkv) do call :smart_conv "%%~i" 14 | for %%i in (*.webm) do call :smart_conv "%%~i" 15 | for %%i in (*.flv) do call :smart_conv "%%~i" 16 | call fname.spechar.revert *.mp4 *.mkv *.webm *.flv 17 | if not "%~1"=="" popd 18 | rem pause 19 | goto :eof 20 | 21 | :smart_conv 22 | call wincmdlib.cmd returnback wrap.ffprobe w "%~1" >nul 23 | set /a iw=_ 24 | call wincmdlib.cmd returnback wrap.ffprobe h "%~1" >nul 25 | set /a ih=_ 26 | set /a ipix=iw*ih 27 | set /a rwh=10000*iw/ih 28 | set /a rhw=10000*ih/iw 29 | call drawincmd.cmd line lower 30 | if %ipix% lss %pixels.hd% ( 31 | echo # skip non-HD^(%iw%x%ih%^) %1 32 | goto :eof 33 | ) 34 | if %rhw% lss 10000 set scale=-2:1080 35 | if %rhw% lss 5625 set scale=1920:-2 36 | if %rwh% lss 10000 set scale=1080:-2 37 | if %rwh% lss 5625 set scale=-2:1920 38 | if %ipix% geq %pixels.fhd% ( 39 | set args=-crf 25 %_args% -vf scale=%scale% 40 | ) else ( 41 | set args=-crf 22 %_args% 42 | ) 43 | if %~x1==.webm set args=-c:a copy %args% 44 | call conv.hevc8b.cmd "%~1" 45 | rem timeout /t 1 46 | goto :eof -------------------------------------------------------------------------------- /__dump__/winscript/conv.pic2webp.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | call drawincmd.cmd line double 4 | echo %* 5 | pushd %1 6 | for %%i in (*) do ( 7 | call conv.pic2webp.smart "%%~i" %2 8 | ) 9 | call delete.nonwebp.infolder . 10 | popd 11 | -------------------------------------------------------------------------------- /__dump__/winscript/conv.pic2webp.infolders.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | for %%i in (%*) do call conv.pic2webp.infolder %%i 5 | pause -------------------------------------------------------------------------------- /__dump__/winscript/delete.nonwebp.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | echo %~nx0 %1 4 | pushd "%~1" 5 | for %%i in (*) do call :save_only_webp "%%~i" 6 | popd 7 | goto :eof 8 | 9 | :save_only_webp 10 | if not exist "%~1.webp" goto :eof 11 | if not %~x1==.webp del "%~1" 12 | goto :eof 13 | -------------------------------------------------------------------------------- /__dump__/winscript/delete.webp.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | pushd "%~1" 4 | for %%i in (*.webp) do call :delete_webp_twin "%%~i" 5 | popd 6 | goto :eof 7 | 8 | :delete_webp_twin 9 | if not exist "%~n1" goto :eof 10 | del "%~1" 11 | goto :eof 12 | -------------------------------------------------------------------------------- /__dump__/winscript/drawincmd.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set /a default.len=64 4 | 5 | call :%* 6 | goto :eof 7 | 8 | :line 9 | if "%*"=="" call :line.underscore && goto :eof 10 | call :line.%* && goto :eof 11 | 12 | :line.single 13 | :line.dash 14 | echo ---------------------------------------------------------------- && goto :eof 15 | 16 | :line.double 17 | :line.doubledash 18 | echo ================================================================ && goto :eof 19 | 20 | :line.lower 21 | :line.under 22 | :line.underscore 23 | echo ________________________________________________________________ && goto :eof 24 | 25 | :line.wave 26 | :line.tilde 27 | echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ && goto :eof 28 | 29 | :line.dot 30 | echo ................................................................ && goto :eof 31 | 32 | :line.char 33 | setlocal 34 | call :line.char.multiply %~1 8 8 35 | goto :eof 36 | 37 | :line.char.multiply 38 | setlocal 39 | set /a i=0 40 | call :line.char.add %~1 %~2 >nul 41 | :line.char.multiply.loop 42 | set s=%s%%_% 43 | set /a i=i+1 44 | if %i%==%~3 ( 45 | endlocal & set _=%s% 46 | echo %s% 47 | goto :eof) else goto :line.char.multiply.loop 48 | 49 | :line.char.add 50 | setlocal 51 | set /a i=0 52 | if "%~2"=="" (set /a len=default.len) else set /a len=%~2 53 | :line.char.add.loop 54 | set s=%s%%~1 55 | set /a i=i+1 56 | if %i%==%len% ( 57 | endlocal & set _=%s% 58 | echo %s% 59 | goto :eof) else goto :line.char.add.loop -------------------------------------------------------------------------------- /__dump__/winscript/fname.cbz.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | rename *.zip *.cbz 2>nul 3 | Renamer.exe -b %locallib_etc%\antrenamer\cbz-1280x.arb -af *.cbz -g -x 4 | Renamer.exe -b %locallib_etc%\antrenamer\spaces2space.arb -af *.cbz -g -x 5 | Renamer.exe -b %locallib_etc%\antrenamer\lstrip.digits.arb -af *.cbz -g -x -------------------------------------------------------------------------------- /__dump__/winscript/fname.clear.__tag__.batch.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | for %%i in (%*) do call :intodir %%i 5 | pause 6 | goto :eof 7 | 8 | :intodir 9 | pushd %1 10 | for %%i in (*) do call :rm__tag__ "%%~i" 11 | popd 12 | goto :eof 13 | 14 | :rm__tag__ 15 | call :get_tag "%~n1" 16 | if not [%_tag:~0,2%]==[__] goto :eof 17 | if not [%_tag:~-2%]==[__] goto :eof 18 | set newfilename="%_name%%~x1" 19 | echo %1 -^> %newfilename% 20 | rename %1 %newfilename% 21 | goto :eof 22 | 23 | :get_tag 24 | set "_tag=%~x1" 25 | set _tag=%_tag:~1% 26 | set "_name=%~n1" 27 | goto :eof -------------------------------------------------------------------------------- /__dump__/winscript/fname.lefthead.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set default.delimiter=. 4 | 5 | set delimiter=%default.delimiter% 6 | if "%~1"=="" ( 7 | set loopmode.header=%~nx0 8 | set loopmode.caller=call 9 | set loopmode.callee=%~nx0 10 | call wincmdlib loopmode 11 | goto :eof 12 | ) 13 | call :%* 14 | goto :eof 15 | 16 | :test 17 | echo %~n1 18 | goto :eof 19 | 20 | :get 21 | setlocal 22 | :: get [set var...] 23 | set fn=%~n1 24 | call %~2 25 | call set nohead=%%fn:*%delimiter%=%% 26 | call set head=%%fn:%delimiter%%nohead%=%% 27 | echo %head% 28 | endlocal & set _=%head% 29 | goto :eof 30 | 31 | :max 32 | setlocal 33 | :: max [folder] [set var...] 34 | if not "%~1"=="" pushd "%~1" 35 | call %~2 36 | setlocal enabledelayedexpansion 37 | for %%i in (*) do ( 38 | call :get "%%~i" >nul 39 | if not defined max set max=!_! 40 | if !_! gtr !max! set max=!_! 41 | ) 42 | echo !max! 43 | if not "%~1"=="" pushd "%~1" 44 | goto :eof 45 | 46 | :min 47 | setlocal 48 | :: min [folder] [set var...] 49 | if not "%~1"=="" pushd "%~1" 50 | call %~2 51 | setlocal enabledelayedexpansion 52 | for %%i in (*) do ( 53 | call :get "%%~i" >nul 54 | if not defined min set min=!_! 55 | if !_! lss !min! set min=!_! 56 | ) 57 | echo !min! 58 | if not "%~1"=="" pushd "%~1" 59 | goto :eof 60 | -------------------------------------------------------------------------------- /__dump__/winscript/fname.spechar.convert.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | wrap.antrenamer spechar convert -g -x -afFr %* 3 | -------------------------------------------------------------------------------- /__dump__/winscript/fname.spechar.revert.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | wrap.antrenamer spechar revert -g -x -afFr %* 3 | -------------------------------------------------------------------------------- /__dump__/winscript/fname.tag.videocodec.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | goto :bof 4 | :bof 5 | for %%i in (%*) do (call :settag "%%~i" || pause) 6 | goto :eof 7 | 8 | :settag 9 | setlocal 10 | call wincmdlib returnback videoinfo vc %~s1 >nul 11 | set vc=%_% 12 | if %vc%==h264 echo Skip H264 video: %1 && goto :eof 13 | call wincmdlib returnback videoinfo vprofile %~s1 >nul 14 | set vp=%_% 15 | set /a bit=%vp:~-2% 16 | if %bit%==0 set bit=8 17 | set tag=.%vc%%bit%b 18 | call wincmdlib fileextension "%~n1" >nul 19 | if defined _ set oldtag=%_% 20 | if "%oldtag%"=="%tag%" echo Skip tagged file: %1 && goto :eof 21 | echo %1 -^> "%~n1%tag%%~x1%" 22 | rename %1 "%~n1.%vc%%bit%b%~x1%" 23 | goto :eof 24 | -------------------------------------------------------------------------------- /__dump__/winscript/pycharm-add-context-menu.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | pushd "%~dp0" 5 | set bin_dir=%cd% 6 | if exist "%bin_dir%"\pycharm64.exe ( 7 | set bin=%bin_dir%\pycharm64.exe 8 | goto :editreg 9 | ) 10 | if exist "%bin_dir%"\pycharm.exe ( 11 | set bin=%bin_dir%\pycharm.exe 12 | goto :editreg 13 | ) 14 | if not defined %bin% ( 15 | echo Can not find pycharm*.exe 16 | pause 17 | goto :eof 18 | ) 19 | 20 | :editreg 21 | echo File 22 | @reg add "HKEY_CLASSES_ROOT\*\shell\Open in PyCharm" /t REG_SZ /v "" /d "Open in PyCharm (&Y)" /f 23 | @reg add "HKEY_CLASSES_ROOT\*\shell\Open in PyCharm" /t REG_EXPAND_SZ /v "Icon" /d "%bin%,0" /f 24 | @reg add "HKEY_CLASSES_ROOT\*\shell\Open in PyCharm\command" /t REG_SZ /v "" /d "%bin% \"%%1\"" /f 25 | echo Folder 26 | @reg add "HKEY_CLASSES_ROOT\Directory\shell\Open directory in PyCharm" /t REG_SZ /v "" /d "Open with PyCharm (&Y)" /f 27 | @reg add "HKEY_CLASSES_ROOT\Directory\shell\Open directory in PyCharm" /t REG_EXPAND_SZ /v "Icon" /d "%bin%,0" /f 28 | @reg add "HKEY_CLASSES_ROOT\Directory\shell\Open directory in PyCharm\command" /t REG_SZ /v "" /d "%bin% \"%%1\"" /f 29 | echo Folder background 30 | @reg add "HKEY_CLASSES_ROOT\Directory\background\shell\Open directory in PyCharm" /t REG_SZ /v "" /d "Open with PyCharm (&Y)" /f 31 | @reg add "HKEY_CLASSES_ROOT\Directory\background\shell\Open directory in PyCharm" /t REG_EXPAND_SZ /v "Icon" /d "%bin%,0" /f 32 | @reg add "HKEY_CLASSES_ROOT\Directory\background\shell\Open directory in PyCharm\command" /t REG_SZ /v "" /d "%bin% \"%%V\"" /f 33 | 34 | pause -------------------------------------------------------------------------------- /__dump__/winscript/tag.folder.nozip.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set tagfile=FOLDER.TAG 4 | 5 | for %%i in (%*) do echo > "%%~i"\%tagfile% -------------------------------------------------------------------------------- /__dump__/winscript/tag.hevc8b.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set tag.origin=.__origin__ 4 | 5 | call :check.tagged "%~n1" 6 | 7 | :check.tagged 8 | -------------------------------------------------------------------------------- /__dump__/winscript/tag.nonhdvideo.__origin__.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set /a const.nonhdres=960*540 4 | set tag.origin=.__origin__ 5 | set tag.hevc8b=.hevc8b 6 | 7 | if not "%~1"=="" pushd "%~1" 8 | call fname.spechar.convert * 9 | for %%i in (*) do call :tag "%%~i" 10 | call fname.spechar.revert * 11 | if not "%~1"=="" popd 12 | goto :eof 13 | 14 | :tag 15 | if /i %~x1==.mp4 goto :tag.video 16 | if /i %~x1==.flv goto :tag.video 17 | if /i %~x1==.mkv goto :tag.video 18 | if /i %~x1==.m4v goto :tag.video 19 | if /i %~x1==.mov goto :tag.video 20 | if /i %~x1==.webm goto :tag.video 21 | goto :eof 22 | :tag.video 23 | set _=%~n1 24 | if "%_:~-11%"=="%tag.origin%" echo # skip %1 && goto :eof 25 | if "%_:~-7%"=="%tag.hevc8b%" echo # skip %1 && goto :eof 26 | call wincmdlib returnback wrap.ffprobe res %1>nul 27 | echo %_% %1 28 | set /a res=%_% 29 | if %res% lss %const.nonhdres% rename %1 "%~n1.__origin__%~x1" && echo * "%~1" ^> "%~n1.__origin__%~x1" 30 | goto :eof 31 | -------------------------------------------------------------------------------- /__dump__/winscript/tag.videocodec.infolder.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | goto :bof 4 | :bof 5 | if not "%~1"=="" set (flag.infolder=%1) else set flag.infolder= 6 | if defined flag.infolder pushd %flag.infolder% 7 | for %%i in (*) do (call :tag "%%~i" || pause) 8 | if defined flag.infolder popd 9 | 10 | :tag 11 | setlocal 12 | if "%~x1"=="" goto :eof 13 | if /i %~x1==.mp4 goto :tag.run 14 | if /i %~x1==.mkv goto :tag.run 15 | if /i %~x1==.m4v goto :tag.run 16 | if /i %~x1==.flv goto :tag.run 17 | if /i %~x1==.mov goto :tag.run 18 | echo # %1 19 | goto :eof 20 | :tag.run 21 | call wincmdlib returnback videoinfo vc %~s1 >nul 22 | set vc=%_% 23 | if %vc%==h264 echo Skip H264 video: %1 && goto :eof 24 | call wincmdlib returnback videoinfo vprofile %~s1 >nul 25 | set vp=%_% 26 | set /a bit=%vp:~-2% 27 | if %bit%==0 set bit=8 28 | set tag=.%vc%%bit%b 29 | call wincmdlib fileextension "%~n1" >nul 30 | if defined _ set oldtag=%_% 31 | if "%oldtag%"=="%tag%" echo Skip tagged file: %1 && goto :eof 32 | echo %1 -^> "%~n1%tag%%~x1%" 33 | rename %1 "%~n1.%vc%%bit%b%~x1%" 34 | goto :eof 35 | -------------------------------------------------------------------------------- /__dump__/winscript/videoinfo.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set ffprob=ffprobe -v error 4 | 5 | call :%* 6 | goto :eof 7 | 8 | :w 9 | :width 10 | %ffprob% -select_streams v:0 -show_entries stream=width -of csv=p=0 %* 11 | goto :eof 12 | 13 | :h 14 | :height 15 | %ffprob% -select_streams v:0 -show_entries stream=height -of csv=p=0 %* 16 | goto :eof 17 | 18 | :res 19 | :resolution 20 | %ffprob% -select_streams v:0 -show_entries stream=width,height -of csv=p=0:s=* %* 21 | goto :eof 22 | 23 | :vc 24 | :vcodec 25 | :vencoder 26 | %ffprob% -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 %* 27 | goto :eof 28 | 29 | :all 30 | %ffprob% -show_streams -of json %* 31 | goto :eof 32 | 33 | :vprofile 34 | %ffprob% -select_streams v:0 -show_entries stream=profile -of csv=p=0 %* 35 | goto :eof 36 | 37 | :vpixfmt 38 | %ffprob% -select_streams v:0 -show_entries stream=pix_fmt -of csv=p=0 %* 39 | goto :eof 40 | -------------------------------------------------------------------------------- /__dump__/winscript/wrap.antrenamer.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set arbdir=%locallib_etc%\antrenamer 5 | call :%* 6 | goto :eof 7 | 8 | :spechar 9 | :: spechar [options] 10 | set arb=%arbdir%\spechar.%~1.arb 11 | call wincmdlib lstriparg1 %* 12 | call antrenamer -b "%arb%" %_% 13 | goto :eof 14 | -------------------------------------------------------------------------------- /__dump__/winscript/wrap.ffprobe.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set ffprobe=ffprobe -v error 4 | 5 | call :%* 6 | goto :eof 7 | 8 | :w 9 | :width 10 | %ffprobe% -select_streams v:0 -show_entries stream=width -of csv=p=0 -i %* 11 | goto :eof 12 | 13 | :h 14 | :height 15 | %ffprobe% -select_streams v:0 -show_entries stream=height -of csv=p=0 -i %* 16 | goto :eof 17 | 18 | :res 19 | :resolution 20 | %ffprobe% -select_streams v:0 -show_entries stream=width,height -of csv=p=0:s=* -i %* 21 | goto :eof 22 | 23 | :v.encoder 24 | :v.codecname 25 | %ffprobe% -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 -i %* 26 | goto :eof 27 | 28 | :all.json 29 | %ffprobe% -show_streams -of json -i %* 30 | goto :eof 31 | 32 | :v.prof 33 | :v.profile 34 | %ffprobe% -select_streams v:0 -show_entries stream=profile -of csv=p=0 -i %* 35 | goto :eof 36 | 37 | :pixfmt 38 | %ffprobe% -select_streams v:0 -show_entries stream=pix_fmt -of csv=p=0 -i %* 39 | goto :eof 40 | -------------------------------------------------------------------------------- /__dump__/winscript/wrap.subst.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set drive=%1 5 | set pth=%2 6 | if not defined drive set drive=z 7 | if not defined pth set pth=. 8 | subst %drive%: %pth% 9 | pause 10 | subst %drive%: /d -------------------------------------------------------------------------------- /__dump__/winscript/ytdl.cmd: -------------------------------------------------------------------------------- 1 | :: yt-dl.cmd 2 | :: Mo Han 3 | :: @ ytdl.worker.cmd 4 | 5 | @echo off 6 | setlocal 7 | call u_var.cmd 8 | set proxy=%u_autoproxy% 9 | rem set proxy=%u_proxy% 10 | pushd "%u_dl%" 11 | 12 | set default=false 13 | set worker=start "" cmd /c "ytdl.worker.cmd|| pause" 14 | if "%1"=="m" goto :push_default 15 | if "%1"=="md" goto :push_default 16 | if "%1"=="w" goto :push_default 17 | if "%1"=="wd" goto :push_default 18 | if "%1"=="b" goto :push_default 19 | if "%1"=="j" goto :push_default 20 | if "%1"=="n" goto :push_default 21 | 22 | :pop_default 23 | set "args=%*" 24 | if "%1"=="" ( 25 | goto :i_main_loop 26 | ) else ( 27 | call set "url=%%args:*%default% =%%" 28 | %worker% 29 | popd 30 | goto :eof 31 | ) 32 | 33 | :push_default 34 | set default=%1 35 | if %default%==n ( 36 | set worker=call ytdl.worker.cmd 37 | ) else ( 38 | set worker=start /min "" cmd /c "ytdl.worker.cmd|| pause" 39 | ) 40 | shift 41 | goto :pop_default 42 | 43 | :i_main_loop 44 | set url= 45 | echo INPUT URL TO DOWNLOAD ([q] QUIT): 46 | set /p url=#URL: 47 | if "%url%"=="q" ( 48 | popd 49 | goto :eof 50 | ) 51 | if not "%url%"=="" ( 52 | %worker% 53 | ) 54 | goto :i_main_loop 55 | 56 | :: Changelog 57 | :: [0.2] - 2017-12-12 58 | :: + Three possible options: `m`, `w`, and `b` 59 | :: 170620 60 | :: + New param `d` for "automatically select default" (will not prompt for format). 61 | :: 170430 62 | :: + One-shot downloading with url provided as param. 63 | :: 160906 64 | :: [*] set _proxy=%u_proxy% -------------------------------------------------------------------------------- /__dump__/ytdl_iwara_na2uploader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | import sys 4 | from glob import glob 5 | from os import rename 6 | from os.path import split, splitext, join 7 | from urllib.parse import urlparse 8 | 9 | from lxml import html 10 | from requests import get 11 | 12 | 13 | class IwaraVideo: 14 | def __init__(self, url: str): 15 | self.urlparse = urlparse(url) 16 | if 'iwara' not in self.urlparse.hostname: 17 | raise ValueError(url) 18 | elif 'video' not in self.urlparse.path: 19 | raise ValueError(url) 20 | self.url = url 21 | self.html = None 22 | self.meta = { 23 | 'id': self.urlparse.path.split('/')[-1], 24 | } 25 | 26 | def get_page(self): 27 | if not self.html: 28 | r = get(self.url) 29 | self.html = html.document_fromstring(r.text) 30 | return self.html 31 | 32 | def get_uploader(self): 33 | key_str = 'uploader' 34 | if key_str in self.meta: 35 | return self.meta[key_str] 36 | else: 37 | video_page = self.get_page() 38 | uploader = video_page.xpath('//div[@class="node-info"]//div[@class="submitted"]//a[@class="username"]')[0].text 39 | self.meta[key_str] = uploader 40 | return uploader 41 | 42 | def find_files_by_id(self, search_in=''): 43 | id_tag = '[{}]'.format(self.meta['id']) 44 | self.meta['id_tag'] = id_tag 45 | mp4_l = glob(search_in + '*.mp4') 46 | r_l = [] 47 | for i in mp4_l: 48 | if id_tag in i: 49 | r_l.append(i) 50 | return r_l 51 | 52 | def rename_files_from_ytdl_na_to_uploader(self, search_in=''): 53 | na_tag = '[NA]' 54 | path_l = self.find_files_by_id(search_in=search_in) 55 | id_tag = self.meta['id_tag'] 56 | uploader = self.get_uploader() 57 | up_tag = '[{}]'.format(uploader) 58 | for p in path_l: 59 | dirname, basename = split(p) 60 | filename, extension = splitext(basename) 61 | if na_tag in filename: 62 | left, right = filename.split(id_tag, maxsplit=1) 63 | right = right.replace(na_tag, up_tag, 1) 64 | new_basename = left + id_tag + right + extension 65 | new_path = join(dirname, new_basename) 66 | rename(p, new_path) 67 | 68 | 69 | if __name__ == '__main__': 70 | u = sys.argv[1] 71 | video = IwaraVideo(u) 72 | video.rename_files_from_ytdl_na_to_uploader() 73 | -------------------------------------------------------------------------------- /cmds.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from functools import lru_cache 3 | 4 | import tabulate 5 | 6 | from oldezpykit.allinone import * 7 | from mylib.easy import python_module_from_filepath 8 | 9 | __dirname__, __stem__, __ext__ = os.split_path_dir_stem_ext(__file__) 10 | sub_apr = argparse.ArgumentParserWrapper() 11 | an = sub_apr.an 12 | meta_apr = argparse.ArgumentParserWrapper() 13 | 14 | 15 | @lru_cache() 16 | def find_module_path(): 17 | r = {} 18 | with os.common.ctx_pushd(__dirname__): 19 | for f in glob.glob(__stem__ + '*.py*'): 20 | match = re.match(rf'({__stem__})_([^.-]+)', f) 21 | if not match: 22 | continue 23 | name = match.group(2) 24 | r[name] = os.join_path(__dirname__, f) 25 | return r 26 | 27 | 28 | an.l = an.list = None 29 | 30 | 31 | @meta_apr.root() 32 | @meta_apr.true(an.l, an.list) 33 | @meta_apr.map(list_cmd=an.list) 34 | def meta_cmd(list_cmd): 35 | if list_cmd: 36 | root_dir = os.path.commonpath(list(find_module_path().values())) 37 | table = [(k, os.path.relpath(v, root_dir)) for k, v in find_module_path().items()] 38 | table.insert(0, ('', f'{os.path.relpath(__file__, root_dir)} (in {root_dir})')) 39 | print(tabulate.tabulate(table, headers=('Command', 'Module Path'))) 40 | 41 | 42 | an.sub_cmd = an.args = None 43 | 44 | 45 | @sub_apr.root() 46 | @sub_apr.arg(an.sub_cmd, nargs='?') 47 | @sub_apr.arg(an.args, nargs='*') 48 | @sub_apr.true(an.l, an.list, help='list all sub-cmd modules') 49 | @sub_apr.map(cmd_name=an.sub_cmd) 50 | def goto_sub_cmd_module(cmd_name=None): 51 | if cmd_name: 52 | module_paths_d = find_module_path() 53 | if cmd_name in module_paths_d: 54 | module_path = module_paths_d[cmd_name] 55 | argv = sys.argv 56 | argv = [f'{__stem__}{__ext__} {cmd_name}', *argv[2:]] 57 | if len(argv) < 2: 58 | argv.append('-h') 59 | sys.argv = argv 60 | module = python_module_from_filepath(f'{__stem__}_{cmd_name}', module_path) 61 | module.main() 62 | else: 63 | print('module not found:', cmd_name, file=sys.stderr) 64 | else: 65 | meta_apr.parse() 66 | meta_apr.run() 67 | 68 | 69 | def main(): 70 | argv = sys.argv 71 | if len(argv) == 1: 72 | argv.append('-h') 73 | if len(argv) > 1 and argv[1] not in meta_apr.option_names: 74 | goto_sub_cmd_module(argv[1]) 75 | else: 76 | sub_apr.parse(catch_unknown_args=True) 77 | sub_apr.run() 78 | 79 | 80 | if __name__ == '__main__': 81 | try: 82 | main() 83 | except KeyboardInterrupt: 84 | sys.exit(2) 85 | -------------------------------------------------------------------------------- /cmds_danmaku.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from xml.etree import ElementTree 3 | 4 | from oldezpykitext.appkit import * 5 | 6 | __logger__ = logging.get_logger(__name__) 7 | ap = argparse.ArgumentParserWrapper() 8 | 9 | 10 | def sign(x): 11 | if x == '+': 12 | return 1 13 | if x == '-': 14 | return -1 15 | raise ValueError(x) 16 | 17 | 18 | def parse_time_offset(x): 19 | if isinstance(x, (float, int)): 20 | return x 21 | elif isinstance(x, str): 22 | try: 23 | return float(x) 24 | except ValueError: 25 | d = re.BatchMatchWrapper( 26 | re.search(r'(?P[+-])?(?P\d+):(?P\d{1,2}):(?P\d{1,2}(\.\d+)?)', x), 27 | re.search(r'(?P[+-])?(?P\d+):(?P\d{1,2}(\.\d+)?)', x), 28 | types=(sign, float,) 29 | ).first_match().pick_existing(h=0, m=0, s=0, sign=1) 30 | __logger__.debug(d) 31 | return (d['h'] * 3600 + d['m'] * 60 + d['s']) * d['sign'] 32 | else: 33 | raise TypeError('invalid time type', type(x)) 34 | 35 | 36 | @ap.sub() 37 | @ap.opt('t', 'time', required=True) 38 | @ap.arg('file', nargs='*') 39 | @ap.map('time', 'file') 40 | def offset(dt, files): 41 | __logger__.debug(files) 42 | dt = parse_time_offset(dt) 43 | if not dt: 44 | __logger__.info('# zero offset') 45 | for fp in iter_path(files): 46 | __logger__.debug(fp) 47 | if not fp.endswith('.xml'): 48 | continue 49 | et = ElementTree.fromstring(io.IOKit.read_exit(open(fp, 'rb'))) 50 | for d in et.findall('d'): 51 | a = d.attrib 52 | p = a['p'] 53 | parts = p.split(',') 54 | parts[0] = f'{float(parts[0]) + dt:.5f}' 55 | a['p'] = ','.join(parts) 56 | io.IOKit.write_exit(open(fp, 'wb'), ElementTree.tostring(et, encoding='UTF-8', xml_declaration=True)) 57 | pm = '+' if dt > 0 else '' 58 | __logger__.info(f'{pm}{dt:.5f}s {fp}') 59 | 60 | 61 | def main(): 62 | logging.init_root(fmt=logging.FMT_MESSAGE_ONLY) 63 | logging.set_root_level('INFO') 64 | # logging.set_root_level('DEBUG') 65 | ap.parse() 66 | ap.run() 67 | 68 | 69 | if __name__ == '__main__': 70 | main() 71 | -------------------------------------------------------------------------------- /cmds_envar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykitext.appkit import * 3 | from oldezpykitext.yaml import EzYAML 4 | 5 | ap = argparse.ArgumentParserWrapper() 6 | an = ap.an 7 | 8 | 9 | def main(): 10 | ap.parse() 11 | ap.run() 12 | 13 | 14 | @ap.sub('setuv') 15 | @ap.arg('entry', nargs='*', help='name=value') 16 | @ap.opt('f', 'file', nargs='*') 17 | @ap.map('entry', files='file') 18 | def set_user_vars(entries=None, files=None): 19 | # print(entries, files) 20 | entries = entries or [] 21 | files = files or [] 22 | envars = {} 23 | for e in entries: 24 | k, v = e.split('=', maxsplit=1) 25 | envars[str(k)] = str(v) 26 | # print(envars) 27 | for fp in files: 28 | y = EzYAML().set_file(fp).load() 29 | for x in y.documents: 30 | if isinstance(x, dict): 31 | for k, v in x.items(): 32 | envars[str(k)] = str(v) 33 | else: 34 | continue 35 | # print(envars) 36 | os.EnVarKit.save(envars) 37 | # print(envars) 38 | for k, v in envars.items(): 39 | print(f'{k}={v}') 40 | 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /cmds_ffmpeg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from mylib.ffmpeg_alpha import FFmpegArgsList 3 | from oldezpykitext.appkit import * 4 | from mylib import ffmpeg_alpha 5 | 6 | __logger__ = logging.get_logger(__name__) 7 | ap = argparse.ArgumentParserWrapper() 8 | 9 | 10 | @ap.sub() 11 | @ap.map() 12 | def test(): 13 | print(ap.extra) 14 | 15 | 16 | @ap.sub() 17 | def concat_seg_in_folder(): 18 | for dp in os.clpb.get_path(): 19 | if not os.path_isdir(dp): 20 | return 21 | seg_l = [os.join_path(dp, f) for f in sorted(os.listdir(dp))] 22 | if not seg_l: 23 | return 24 | seg_ext = '.mkv' 25 | dst = f'{dp} +{{seg}}{seg_ext}' 26 | ff = ffmpeg_alpha.FFmpegRunnerAlpha() 27 | ff.concat(seg_l, dst, output_args=ap.extra) 28 | 29 | 30 | @ap.sub() 31 | @ap.arg('frame_size_and_rate', help='{width}x{height}@{fps}') 32 | @ap.map('frame_size_and_rate') 33 | def concat_frame_in_folder(frame_size_and_rate): 34 | w, h, r = re.search(r'(\d+)x(\d+)@(\d+)', frame_size_and_rate).groups() 35 | a = FFmpegArgsList( 36 | vf=f'scale={w}:{h}:force_original_aspect_ratio=1,pad={w}:{h}:(ow-iw)/2:(oh-ih)/2', 37 | c__v='hevc', crf=22, pix_fmt='yuv420p', 38 | # x265_params='log-level=error:aq-mode=3', 39 | x265_params='aq-mode=3', 40 | x264opts='aq-mode=3', 41 | ) 42 | for dp in os.clpb.get_path(): 43 | if not os.path_isdir(dp): 44 | return 45 | seg_l = [os.join_path(dp, f) for f in sorted(os.listdir(dp))] 46 | if not seg_l: 47 | return 48 | seg_ext = '.mkv' 49 | dst = f'{dp}{seg_ext}' 50 | ff = ffmpeg_alpha.FFmpegRunnerAlpha() 51 | ff.concat( 52 | seg_l, dst, 53 | input_args=['-r', str(r)], 54 | output_args=a + ap.extra, 55 | ) 56 | 57 | 58 | def main(): 59 | logging.init_root(fmt=logging.FMT_MESSAGE_ONLY) 60 | logging.set_root_level('INFO') 61 | # logging.set_root_level('DEBUG') 62 | ap.parse(catch_unknown_args=True) 63 | ap.run() 64 | 65 | 66 | if __name__ == '__main__': 67 | main() 68 | -------------------------------------------------------------------------------- /cmds_file2link.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import oldezpykit.stdlib.re 3 | from mylib.ext.console_app import * 4 | 5 | import webbrowser 6 | 7 | apr = ArgumentParserWrapper() 8 | an = apr.an 9 | an.s = an.src = an.B = an.not_browse = '' 10 | 11 | 12 | @apr.sub() 13 | @apr.opt(an.s, an.src, nargs='*') 14 | @apr.true(an.B, apr.dst2opt(an.not_browse)) 15 | @apr.map(an.src, an.not_browse) 16 | def post_id(fp_list, not_browse): 17 | sites_post_url_fmt = { 18 | 'sankaku': 'https://chan.sankakucomplex.com/post/show/{}', 19 | 'pixiv': 'https://www.pixiv.net/artworks/{}', 20 | 'danbooru': 'https://danbooru.donmai.us/posts/{}', 21 | 'gelbooru': 'https://gelbooru.com/index.php?page=post&s=view&id={}', 22 | 'idolcomplex': 'https://idol.sankakucomplex.com/post/show/{}', 23 | 'twitter': 'https://twitter.com/twitter/statuses/{}', 24 | } 25 | urls_l = [] 26 | for bn in map(path_basename, resolve_path_to_dirs_files(fp_list)[1] or ostk.clipboard.get().splitlines()): 27 | print(f'@ {bn}') 28 | words = oldezpykit.stdlib.re.find_words(bn, allow_mix_non_word_chars='-') 29 | intersect = set(words) & set(sites_post_url_fmt.keys()) 30 | if not intersect: 31 | continue 32 | if len(intersect) > 1: 33 | print(f'# {bn}') 34 | continue 35 | site_name = intersect.pop() 36 | url_fmt = sites_post_url_fmt[site_name] 37 | for w in words: 38 | # print(f': {w}') 39 | if w == site_name: 40 | continue 41 | m1 = re.fullmatch(r'\d+', w) 42 | m2 = re.fullmatch(r'(\d+)(?:[_-])p?(\d+)', w) 43 | if m1: 44 | id_num = int(w) 45 | elif m2: 46 | id_num = int(m2.groups()[0]) 47 | else: 48 | continue 49 | url = url_fmt.format(id_num) 50 | urls_l.append(url) 51 | print(f'* {url}') 52 | if not not_browse: 53 | webbrowser.open_new_tab(url) 54 | break 55 | if not_browse: 56 | ostk.clipboard.set('\r\n'.join(urls_l)) 57 | 58 | 59 | def main(): 60 | apr.parse() 61 | apr.run() 62 | 63 | 64 | if __name__ == '__main__': 65 | main() 66 | -------------------------------------------------------------------------------- /cmds_img.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from mylib.easy import * 3 | from oldezpykit.stdlib import argparse 4 | from mylib.ext import ostk 5 | 6 | apr = argparse.ArgumentParserWrapper() 7 | an = apr.an 8 | 9 | 10 | def main(): 11 | apr.parse() 12 | apr.run() 13 | 14 | 15 | an.img = an.l = an.lang = an.v = an.verbose = None 16 | 17 | 18 | @apr.sub() 19 | @apr.arg(an.img, nargs='?') 20 | @apr.opt(an.l, an.lang, nargs='*') 21 | @apr.true(an.v, an.verbose) 22 | @apr.map(an.img, lang=an.lang, verbose=an.verbose) 23 | def ocr(image=None, lang=None, verbose=False): 24 | from PIL.ImageGrab import grabclipboard 25 | from mylib.wrapper.tesseract_ocr import TesseractOCRCLIWrapper 26 | import yaml 27 | config = yaml.safe_load(open(os.path.join( 28 | os.path.expanduser('~'), 29 | '.config', 30 | os.path.splitext(os.path.split(__file__)[1])[0] + '.yaml' 31 | )).read())[ocr.__name__]['tesseract'] 32 | tess = TesseractOCRCLIWrapper(config['which']) 33 | if verbose: 34 | tess.logger.setLevel('DEBUG') 35 | tess.logger.set_all_handlers_format('# %(message)s') 36 | lang = lang or config.get('lang') 37 | image = image or grabclipboard() 38 | if lang: 39 | tess.lang(*lang) 40 | try: 41 | s = '\r\n'.join(tess.img(image, gray=True).txt().strip().splitlines()) 42 | if s.strip(): 43 | ostk.clipboard.clear().set(s) 44 | print(s) 45 | except TypeError: 46 | print(f'! non-image provided', file=sys.stderr) 47 | sys.exit(1) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /cmds_iwara.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from mylib.ext.console_app import * 3 | from mylib.sites import iwara 4 | 5 | apr = ArgumentParserWrapper() 6 | an = apr.an 7 | an.user = an.general = an.L = an.single_line = '' 8 | 9 | 10 | @apr.sub() 11 | @apr.arg(an.user) 12 | @apr.true(long_name=an.general) 13 | @apr.true(an.L, an.single_line) 14 | @apr.map(user=an.user, general=an.general, single_line=an.single_line) 15 | def user_video_url(user, general=False, single_line=False): 16 | s = (' ' if single_line else '\n').join(iwara.iter_all_video_url_of_user(user, ecchi=not general, only_urls=True)) 17 | print(s) 18 | ostk.clipboard.set(s) 19 | 20 | 21 | def main(): 22 | apr.parse() 23 | apr.run() 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /cmds_ostk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os.path 3 | 4 | from mylib.ext.console_app import * 5 | 6 | apr = ArgumentParserWrapper() 7 | an = apr.an 8 | an.l = an.multiline = an.L = an.single_line = an.q = an.quote = '' 9 | 10 | 11 | def main(): 12 | apr.parse() 13 | apr.run() 14 | 15 | 16 | @apr.sub(apr.rpl_dot, aliases=['cb.paths']) 17 | @apr.true(an.L, apr.dst2opt(an.single_line)) 18 | @apr.true(an.q, an.quote) 19 | @apr.true('b', 'basename_only') 20 | @apr.map(single_line=an.single_line, quote=an.quote, basename_only='basename_only') 21 | def clipboard_print_paths(single_line=False, quote=False, basename_only=False): 22 | paths = ostk.clipboard.list_path() 23 | if basename_only: 24 | paths = [os.path.basename(i) for i in paths] 25 | if quote: 26 | paths = [f'"{p}"' for p in paths] 27 | if single_line: 28 | print(' '.join(paths)) 29 | else: 30 | for p in paths: 31 | print(p) 32 | 33 | 34 | if __name__ == '__main__': 35 | main() 36 | -------------------------------------------------------------------------------- /cmds_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def main(): 4 | print('cmd:', 'test') 5 | print('module path:', __file__) 6 | -------------------------------------------------------------------------------- /cmds_time.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykitext.appkit import * 3 | 4 | apr = argparse.ArgumentParserWrapper() 5 | an = apr.an 6 | 7 | an.unix_timestamp = an.iso_datetime = '' 8 | 9 | 10 | @apr.sub(aliases=['u2i'], help='UTC unix timestamp to iso8601') 11 | @apr.arg(an.unix_timestamp, type=float, nargs='?', default=time.time()) 12 | @apr.map(an.unix_timestamp) 13 | def unix2iso(t): 14 | r = datetime.datetime.utcfromtimestamp(t).isoformat() 15 | print(r) 16 | return r 17 | 18 | 19 | @apr.sub(aliases=['i2u'], help='UTC iso8601 to unix timestamp') 20 | @apr.arg(an.iso_datetime) 21 | @apr.map(an.iso_datetime) 22 | def iso2unix(s): 23 | r = datetime.from_iso_format(s).timestamp() 24 | print(r) 25 | return r 26 | 27 | 28 | def main(): 29 | apr.parse() 30 | apr.run() 31 | 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /cmds_webscrape.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from mylib.ext.console_app import * 3 | from mylib.sites import misc 4 | 5 | apr = ArgumentParserWrapper() 6 | an = apr.an 7 | 8 | 9 | def main(): 10 | apr.parse() 11 | apr.run() 12 | 13 | 14 | @apr.sub(aliases=['freevmessuuid']) 15 | def free_ss_site_v2ray_uid(): 16 | print(misc.free_ss_site_vmess_uuid()) 17 | 18 | 19 | @apr.sub(aliases=['xvideos.url.quickies', 'xvq']) 20 | def get_xvideos_quickies_url(): 21 | import lxml.html 22 | from oldezpykitext.stdlib import os 23 | import re 24 | 25 | h = lxml.html.fromstring(os.clpb.get_html()) 26 | urls = [] 27 | for e in h.xpath('//div[starts-with(@class, "quickies")]'): 28 | if 'data-id' not in e.attrib: 29 | continue 30 | d = e.attrib 31 | vid = d['data-id'] 32 | title = e.xpath('.//div[contains(@class, "title")]')[-1].text.lower() 33 | title = re.sub(r'\W', '_', title) 34 | title = re.sub('_+', '_', title) 35 | urls.append(f'https://www.xvideos.com/video{vid}/{title}') 36 | urls_s = '\n'.join(urls) 37 | print(urls_s) 38 | os.clpb.set(urls_s) 39 | return urls 40 | 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /cmds_webtools.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykitext.appkit import * 3 | from oldezpykitext.extlib.termcolor import * 4 | from oldezpykitext.webclient import * 5 | 6 | apr = argparse.ArgumentParserWrapper() 7 | 8 | 9 | def main(): 10 | logging.init_root(fmt=logging.FMT_MESSAGE_ONLY) 11 | apr.parse() 12 | apr.run() 13 | 14 | 15 | @apr.sub(aliases=['get-cookies', 'getck']) 16 | @apr.opt('s', 'src') 17 | @apr.opt('d', 'dst') 18 | @apr.true('v', 'verbose') 19 | @apr.map('src', 'dst', verbose='verbose') 20 | def get_netscape_cookies(src, dst, verbose=False): 21 | """get netscape format cookies, from src to dst""" 22 | if verbose: 23 | logging.set_root_level('INFO') 24 | lg = logging.get_logger(__name__, get_netscape_cookies.__name__) 25 | src = get_from_source(src) 26 | lg.info(colored(str(src), 'grey', 'on_white', ['bold'])) 27 | cj = cookie.EzCookieJar() 28 | cj_kw = dict(ignore_expires=True, ignore_discard=True) 29 | cj.smart_load(src, **cj_kw) 30 | r = cj.get_netscape_text(**cj_kw) 31 | lg.info(colored(str(r), 'grey', None, ['bold'])) 32 | give_to_sink(r, dst) 33 | 34 | 35 | if __name__ == '__main__': 36 | main() 37 | -------------------------------------------------------------------------------- /devkit/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /dotnetkit/rpcb/.vs/rpcb/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/.vs/rpcb/v15/.suo -------------------------------------------------------------------------------- /dotnetkit/rpcb/.vs/rpcb/v15/Server/sqlite3/db.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/.vs/rpcb/v15/Server/sqlite3/db.lock -------------------------------------------------------------------------------- /dotnetkit/rpcb/.vs/rpcb/v15/Server/sqlite3/storage.ide-shm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/.vs/rpcb/v15/Server/sqlite3/storage.ide-shm -------------------------------------------------------------------------------- /dotnetkit/rpcb/.vs/rpcb/v15/Server/sqlite3/storage.ide-wal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/.vs/rpcb/v15/Server/sqlite3/storage.ide-wal -------------------------------------------------------------------------------- /dotnetkit/rpcb/packages/NNanomsg.0.5.2/.signature.p7s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/packages/NNanomsg.0.5.2/.signature.p7s -------------------------------------------------------------------------------- /dotnetkit/rpcb/packages/NNanomsg.0.5.2/NNanomsg.0.5.2.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/packages/NNanomsg.0.5.2/NNanomsg.0.5.2.nupkg -------------------------------------------------------------------------------- /dotnetkit/rpcb/packages/NNanomsg.0.5.2/content/net40/x64/libnanomsg.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/packages/NNanomsg.0.5.2/content/net40/x64/libnanomsg.so -------------------------------------------------------------------------------- /dotnetkit/rpcb/packages/NNanomsg.0.5.2/content/net40/x64/nanomsg.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/packages/NNanomsg.0.5.2/content/net40/x64/nanomsg.dll -------------------------------------------------------------------------------- /dotnetkit/rpcb/packages/NNanomsg.0.5.2/content/net40/x86/libnanomsg.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/packages/NNanomsg.0.5.2/content/net40/x86/libnanomsg.so -------------------------------------------------------------------------------- /dotnetkit/rpcb/packages/NNanomsg.0.5.2/content/net40/x86/nanomsg.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/packages/NNanomsg.0.5.2/content/net40/x86/nanomsg.dll -------------------------------------------------------------------------------- /dotnetkit/rpcb/packages/NNanomsg.0.5.2/lib/net40/NNanomsg.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/packages/NNanomsg.0.5.2/lib/net40/NNanomsg.dll -------------------------------------------------------------------------------- /dotnetkit/rpcb/packages/NNanomsg.0.5.2/tools/net40/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | $platformNames = "x86", "x64" 4 | $propertyName = "CopyToOutputDirectory" 5 | 6 | foreach($platformName in $platformNames) { 7 | $folder = $project.ProjectItems.Item($platformName) 8 | 9 | if ($folder -eq $null) { 10 | continue 11 | } 12 | 13 | $fileName = "nanomsg.dll" 14 | $item = $folder.ProjectItems.Item($fileName) 15 | if ($item -eq $null) { 16 | continue 17 | } 18 | $property = $item.Properties.Item($propertyName) 19 | if ($property -eq $null) { 20 | continue 21 | } 22 | $property.Value = 1 23 | 24 | $fileName = "libnanomsg.so" 25 | $item = $folder.ProjectItems.Item($fileName) 26 | if ($item -eq $null) { 27 | continue 28 | } 29 | $property = $item.Properties.Item($propertyName) 30 | if ($property -eq $null) { 31 | continue 32 | } 33 | $property.Value = 1 34 | } 35 | -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.netfx45/DaemonProcess.cs: -------------------------------------------------------------------------------- 1 | namespace rpcb.netfx45 2 | { 3 | public class DaemonProcess 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.netfx45/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("rpcb.netfx45")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("rpcb.netfx45")] 12 | [assembly: AssemblyCopyright("Copyright © 2022")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("E5B0F85A-9A27-4FCD-90CD-1A7DAC492E4B")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.netfx45/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.netfx45/x64/libnanomsg.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/rpcb.netfx45/x64/libnanomsg.so -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.netfx45/x64/nanomsg.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/rpcb.netfx45/x64/nanomsg.dll -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.netfx45/x86/libnanomsg.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/rpcb.netfx45/x86/libnanomsg.so -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.netfx45/x86/nanomsg.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/dotnetkit/rpcb/rpcb.netfx45/x86/nanomsg.dll -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rpcb.netfx45", "rpcb.netfx45\rpcb.netfx45.csproj", "{E5B0F85A-9A27-4FCD-90CD-1A7DAC492E4B}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Any CPU = Debug|Any CPU 8 | Release|Any CPU = Release|Any CPU 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {E5B0F85A-9A27-4FCD-90CD-1A7DAC492E4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 12 | {E5B0F85A-9A27-4FCD-90CD-1A7DAC492E4B}.Debug|Any CPU.Build.0 = Debug|Any CPU 13 | {E5B0F85A-9A27-4FCD-90CD-1A7DAC492E4B}.Release|Any CPU.ActiveCfg = Release|Any CPU 14 | {E5B0F85A-9A27-4FCD-90CD-1A7DAC492E4B}.Release|Any CPU.Build.0 = Release|Any CPU 15 | EndGlobalSection 16 | EndGlobal 17 | -------------------------------------------------------------------------------- /dotnetkit/rpcb/rpcb.sln.DotSettings.user: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /etc/bashrc: -------------------------------------------------------------------------------- 1 | stty ixany 2 | stty ixoff -ixon -------------------------------------------------------------------------------- /etc/byobu: -------------------------------------------------------------------------------- 1 | # ~/.byobu/keybindings 2 | # disable fn keys 3 | source $BYOBU_PREFIX/share/byobu/keybindings/f-keys.screen.disable -------------------------------------------------------------------------------- /etc/clash/custom_direct.yaml: -------------------------------------------------------------------------------- 1 | payload: 2 | - DOMAIN-SUFFIX,mozilla.org 3 | - DOMAIN-SUFFIX,mozilla.com 4 | - DOMAIN-SUFFIX,firefox.com 5 | - DOMAIN-SUFFIX,outlook.com 6 | - DOMAIN-SUFFIX,steamcontent.com 7 | - DOMAIN-SUFFIX,vip.ffzy-play5.com 8 | - DOMAIN-SUFFIX,microsoft.com 9 | - DOMAIN-SUFFIX,googleads.g.doubleclick.net 10 | - DOMAIN-SUFFIX,lan 11 | - DOMAIN-SUFFIX,local 12 | - DOMAIN-SUFFIX,domi.teracloud.jp 13 | - DOMAIN-SUFFIX,windowsupdate.com 14 | - DOMAIN-SUFFIX,download-cdn.jetbrains.com.cn 15 | -------------------------------------------------------------------------------- /etc/clash/custom_proxy.yaml: -------------------------------------------------------------------------------- 1 | payload: 2 | - DOMAIN-SUFFIX,sleazyfork.org 3 | - DOMAIN-SUFFIX,realbooru.com 4 | - DOMAIN-SUFFIX,googleapis.cn 5 | 6 | -------------------------------------------------------------------------------- /etc/clash/note: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/etc/clash/note -------------------------------------------------------------------------------- /etc/clash/public_proxy_provider.yaml: -------------------------------------------------------------------------------- 1 | proxy-providers: 2 | aiboboxx/clashfree: 3 | type: http 4 | # https://raw.githubusercontent.com/aiboboxx/clashfree/main/clash.yml 5 | url: https://api.dler.io/sub?target=clash&new_name=true&url=https%3A%2F%2Fraw.githubusercontent.com%2Faiboboxx%2Fclashfree%2Fmain%2Fclash.yml&insert=false&config=https%3A%2F%2Fraw.githubusercontent.com%2FACL4SSR%2FACL4SSR%2Fmaster%2FClash%2Fconfig%2FACL4SSR_Online.ini&exclude=%E6%9B%B4%E5%A4%9A%E5%85%8D%E8%B4%B9%E9%AB%98%E9%80%9Fv2ray%E3%80%81clash%E8%8A%82%E7%82%B9&emoji=true&list=true&tfo=false&scv=false&fdn=false&sort=false 6 | interval: 21600 7 | path: ./proxy-provider/aiboboxx-clashfree.yaml 8 | health-check: 9 | enable: true 10 | interval: 60 11 | lazy: true 12 | url: http://www.gstatic.com/generate_204 13 | Pawdroid/Free-servers@api.dler.io: 14 | type: http 15 | # https://9527521.xyz/pubconfig/2tD4xMbQTo9zwpYN 16 | url: https://api.dler.io/sub?target=clash&new_name=true&url=https%3A%2F%2F9527521.xyz%2Fpubconfig%2F2tD4xMbQTo9zwpYN&insert=true&config=https%3A%2F%2Fraw.githubusercontent.com%2FACL4SSR%2FACL4SSR%2Fmaster%2FClash%2Fconfig%2FACL4SSR_Online.ini&append_type=true&emoji=true&list=true&tfo=false&scv=false&fdn=true&sort=true&udp=true&surge.doh=true 17 | interval: 21600 18 | path: ./proxy-provider/Pawdroid-Free-servers.yaml 19 | health-check: 20 | enable: true 21 | interval: 60 22 | lazy: true 23 | url: http://www.gstatic.com/generate_204 24 | freefq@api.dler.io: 25 | type: http 26 | # https://raw.githubusercontent.com/freefq/free/master/v2 27 | url: https://api.dler.io/sub?target=clash&new_name=true&url=https%3A%2F%2Fgithub.com%2Ffreefq%2Ffree%2Fraw%2Fmaster%2Fv2&insert=true&config=https%3A%2F%2Fraw.githubusercontent.com%2FACL4SSR%2FACL4SSR%2Fmaster%2FClash%2Fconfig%2FACL4SSR_Online.ini&append_type=true&emoji=true&list=true&tfo=false&scv=false&fdn=true&sort=true&udp=true&surge.doh=true 28 | interval: 21600 29 | path: ./proxy-provider/freefq.yaml 30 | health-check: 31 | enable: true 32 | interval: 60 33 | lazy: true 34 | url: http://www.gstatic.com/generate_204 35 | -------------------------------------------------------------------------------- /etc/clash/readme.md: -------------------------------------------------------------------------------- 1 | # config files for clash (a rule-based tunnel) -------------------------------------------------------------------------------- /etc/clash/rule.js: -------------------------------------------------------------------------------- 1 | const test_url = "http://www.gstatic.com/generate_204"; 2 | const proxy_groups_key = "proxy-groups"; 3 | const interval = 60; 4 | const tolerance = 150; 5 | const proxy_providers_key = "proxy-providers"; 6 | const proxies_key = "proxies"; 7 | function main(config) { 8 | if (!(proxy_groups_key in config)) { 9 | config[proxy_groups_key] = []; 10 | } 11 | config[proxy_groups_key] = [ 12 | { 13 | name: "PROXY", 14 | type: "select", 15 | proxies: ["SELECT", "URL-TEST", "FALLBACK", "DIRECT"], 16 | }, 17 | { name: "SELECT", type: "select", use: [], proxies: [] }, 18 | { 19 | name: "URL-TEST", 20 | type: "url-test", 21 | url: test_url, 22 | interval: interval, 23 | tolerance: tolerance, 24 | use: [], 25 | proxies: [], 26 | }, 27 | { 28 | name: "FALLBACK", 29 | type: "fallback", 30 | url: test_url, 31 | interval: interval, 32 | use: [], 33 | proxies: [], 34 | }, 35 | ]; 36 | config[proxy_groups_key] 37 | .filter((group) => group.name !== "PROXY") 38 | .forEach((group) => { 39 | if (proxy_providers_key in config) { 40 | Object.keys(config[proxy_providers_key]).forEach((provider_name) => { 41 | group.use.push(provider_name); 42 | }); 43 | } 44 | if (proxies_key in config) { 45 | config[proxies_key].forEach((proxy) => { 46 | group.proxies.push(proxy.name); 47 | }); 48 | } 49 | }); 50 | return config; 51 | } 52 | -------------------------------------------------------------------------------- /etc/hosts: -------------------------------------------------------------------------------- 1 | 101.19.14.100 cf.ip -------------------------------------------------------------------------------- /etc/kitsunebi-android/rules/self-use.conf: -------------------------------------------------------------------------------- 1 | [RoutingRule] 2 | DOMAIN-SUFFIX, v2ex.com, Proxy 3 | #DOMAIN-SUFFIX, mo-han.com, Direct 4 | DOMAIN-KEYWORD, geosite:microsoft, Direct 5 | DOMAIN-SUFFIX, addons.mozilla.org, Direct 6 | #DOMAIN-SUFFIX, mtalk.google.com, Direct 7 | DOMAIN-KEYWORD, geosite:google, Proxy 8 | #DOMAIN-SUFFIX, sankakucomplex.com, Direct 9 | DOMAIN-KEYWORD, geosite:pixiv, Proxy 10 | # direct 11 | DOMAIN-SUFFIX, leanplum.com, Direct 12 | DOMAIN-SUFFIX, app.adjust.com, Direct 13 | DOMAIN-SUFFIX, app-measurement.com, Direct 14 | DOMAIN-SUFFIX, taobao.com, Direct 15 | DOMAIN-SUFFIX, qq.com, Direct 16 | DOMAIN-SUFFIX, bilivideo.com, Direct 17 | DOMAIN-SUFFIX, alibabausercontent.com, Direct 18 | # E-Hentai 19 | #DOMAIN-SUFFIX, exhentai.org, Direct 20 | #DOMAIN-SUFFIX, ehgt.org, Direct 21 | DOMAIN-SUFFIX, hath.network, Direct 22 | 23 | # Bypass mainland china domains. 24 | DOMAIN-KEYWORD, geosite:cn, Direct 25 | 26 | # Bypass mainland china IPs and LAN IPs. 27 | GEOIP, cn, Direct 28 | GEOIP, private, Direct 29 | 30 | # Block ads. 31 | DOMAIN-KEYWORD, geosite:category-ads, Reject 32 | 33 | # Other requests go through the proxy. 34 | FINAL, Proxy 35 | 36 | [RoutingDomainStrategy] 37 | AsIs 38 | 39 | [FreedomDomainStrategy] 40 | AsIs 41 | 42 | [LocalPolicy] 43 | bufferSize = 4096 44 | connIdle = 300 45 | downlinkOnly = 0 46 | handshake = 4 47 | uplinkOnly = 0 48 | 49 | [DnsServer] 50 | 223.5.5.5 51 | 1.1.1.1 52 | 53 | [DnsRule] 54 | 55 | [DnsHost] 56 | 57 | [DnsClientIp] 58 | 59 | [Log] 60 | loglevel = none 61 | 62 | [PerAppVpn] 63 | 64 | [PerAppMode] 65 | 66 | [PerAppAllow] 67 | 68 | [PerAppDisallow] -------------------------------------------------------------------------------- /etc/nginx/install-snippets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pushd "$(dirname "$(realpath "$0")")" 4 | install -v -m 644 snippets/* /etc/nginx/snippets/ 5 | install -v -m 644 sites-available/* /etc/nginx/sites-available/ 6 | popd -------------------------------------------------------------------------------- /etc/nginx/sites-available/subdomain-redir-to-port: -------------------------------------------------------------------------------- 1 | # This is a template, while can be used directly too. 2 | server { 3 | include snippets/server-http; 4 | include snippets/proxy-set-headers; 5 | #server_name "~^port\-(?\d{1,5})\.example\.com$"; 6 | server_name "~^port\-(?\d{1,5})\..*$"; 7 | 8 | #include snippets/SOME-SNIPPETS; 9 | location / { 10 | proxy_pass http://127.0.0.1:$port; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /etc/nginx/snippets/location-acme-challenge: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Configuration file for Let's Encrypt ACME Challenge location 3 | # This file is already included in listen_xxx.conf files. 4 | # Do NOT include it separately! 5 | ############################################################################# 6 | # 7 | # This config enables to access /.well-known/acme-challenge/xxxxxxxxxxx 8 | # on all our sites (HTTP), including all subdomains. 9 | # This is required by ACME Challenge (webroot authentication). 10 | # You can check that this location is working by placing ping.txt here: 11 | # /var/www/letsencrypt/.well-known/acme-challenge/ping.txt 12 | # And pointing your browser to: 13 | # http://xxx.domain.tld/.well-known/acme-challenge/ping.txt 14 | # 15 | # Sources: 16 | # https://community.letsencrypt.org/t/howto-easy-cert-generation-and-renewal-with-nginx/3491 17 | # 18 | ############################################################################# 19 | 20 | # Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx) 21 | # We use ^~ here, so that we don't check other regexes (for speed-up). We actually MUST cancel 22 | # other regex checks, because in our other config files have regex rule that denies access to files with dotted names. 23 | location ^~ /.well-known/acme-challenge/ { 24 | 25 | # Set correct content type. According to this: 26 | # https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29 27 | # Current specification requires "text/plain" or no content header at all. 28 | # It seems that "text/plain" is a safe option. 29 | default_type "text/plain"; 30 | 31 | # This directory must be the same as in /etc/letsencrypt/cli.ini 32 | # as "webroot-path" parameter. Also don't forget to set "authenticator" parameter 33 | # there to "webroot". 34 | # Do NOT use alias, use root! Target directory is located here: 35 | # /var/www/common/letsencrypt/.well-known/acme-challenge/ 36 | #root /var/www/letsencrypt; 37 | root /var/www/html; 38 | } 39 | 40 | # Hide /acme-challenge subdirectory and return 404 on all requests. 41 | # It is somewhat more secure than letting Nginx return 403. 42 | # Ending slash is important! 43 | location = /.well-known/acme-challenge/ { 44 | return 404; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /etc/nginx/snippets/location-acme-challenge-with-fallback: -------------------------------------------------------------------------------- 1 | location ^~ /.well-known/acme-challenge/ { 2 | default_type "text/plain"; 3 | root /var/www/html; 4 | try_files $uri @acme-challenge-fallback; 5 | } 6 | 7 | location = /.well-known/acme-challenge/ { 8 | return 404; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /etc/nginx/snippets/location-autoindex: -------------------------------------------------------------------------------- 1 | autoindex on; 2 | charset UTF-8; -------------------------------------------------------------------------------- /etc/nginx/snippets/location-netdata: -------------------------------------------------------------------------------- 1 | location /netdata/ { 2 | rewrite "^/netdata/(.*)$" /$1 break; 3 | proxy_pass http://127.0.0.1:19999; 4 | } -------------------------------------------------------------------------------- /etc/nginx/snippets/location-redir-root-to-https: -------------------------------------------------------------------------------- 1 | location / { 2 | return 302 https://$server_name$request_uri; 3 | } -------------------------------------------------------------------------------- /etc/nginx/snippets/location-redir-to-port: -------------------------------------------------------------------------------- 1 | location ~ "^/\.port\-\d{1,5}/" { 2 | rewrite "^/\.port\-(\d+)/(.*)$" /$2 break; 3 | proxy_pass http://127.0.0.1:$1; 4 | } 5 | -------------------------------------------------------------------------------- /etc/nginx/snippets/location-webdav-common: -------------------------------------------------------------------------------- 1 | client_max_body_size 0; 2 | #proxy_read_timeout 300; # answer from server, 5 min 3 | #proxy_send_timeout 300; # chunks to server, 5 min 4 | dav_methods PUT DELETE MKCOL COPY MOVE; 5 | dav_ext_methods PROPFIND OPTIONS; 6 | create_full_put_path on; -------------------------------------------------------------------------------- /etc/nginx/snippets/location-webdav-path-rewrite-add-slash: -------------------------------------------------------------------------------- 1 | set $dest $http_destination; 2 | if (-d $request_filename) { 3 | rewrite ^(.*[^/])$ $1/; 4 | set $dest $dest/; 5 | } 6 | if ($request_method ~ (MOVE|COPY)) { 7 | more_set_input_headers 'Destination: $dest'; 8 | } 9 | if ($request_method ~ MKCOL) { 10 | rewrite ^(.*[^/])$ $1/ break; 11 | } -------------------------------------------------------------------------------- /etc/nginx/snippets/proxy-set-headers: -------------------------------------------------------------------------------- 1 | proxy_set_header Host $host; 2 | proxy_set_header X-Real-IP $remote_addr; 3 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 4 | proxy_set_header X-Forwarded-Proto $scheme; -------------------------------------------------------------------------------- /etc/nginx/snippets/proxy-websocket: -------------------------------------------------------------------------------- 1 | proxy_set_header Upgrade $http_upgrade; 2 | proxy_set_header Connection "Upgrade"; 3 | proxy_set_header Host $http_host; -------------------------------------------------------------------------------- /etc/nginx/snippets/rewrite-subdir-to-port: -------------------------------------------------------------------------------- 1 | rewrite "^/\.port\-(\d{1,5})/(.*)$" /$2 break; 2 | proxy_pass http://127.0.0.1:$1; 3 | -------------------------------------------------------------------------------- /etc/nginx/snippets/server-hsts: -------------------------------------------------------------------------------- 1 | add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; 2 | -------------------------------------------------------------------------------- /etc/nginx/snippets/server-http: -------------------------------------------------------------------------------- 1 | listen 80; 2 | listen [::]:80; 3 | server_tokens off; -------------------------------------------------------------------------------- /etc/nginx/snippets/server-https: -------------------------------------------------------------------------------- 1 | listen 443 ssl http2; 2 | listen [::]:443 ssl http2; 3 | gzip off; 4 | server_tokens off; 5 | 6 | #ssl_protocols TLSv1.3; # Requires nginx >= 1.13.0 else use TLSv1.2 7 | ssl_protocols TLSv1.3 TLSv1.2; 8 | ssl_prefer_server_ciphers on; 9 | ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096 10 | ssl_ciphers EECDH+AESGCM:EDH+AESGCM; 11 | ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0 12 | ssl_session_timeout 10m; 13 | ssl_session_cache shared:SSL:10m; 14 | ssl_session_tickets off; # Requires nginx >= 1.5.9 15 | ssl_stapling on; # Requires nginx >= 1.3.7 16 | ssl_stapling_verify on; # Requires nginx => 1.3.7 17 | resolver 1.1.1.1 8.8.8.8 valid=300s; 18 | resolver_timeout 5s; 19 | #add_header X-Frame-Options DENY; # too restricted 20 | add_header X-Frame-Options SAMEORIGIN; 21 | add_header X-Content-Type-Options nosniff; 22 | add_header X-XSS-Protection "1; mode=block"; -------------------------------------------------------------------------------- /etc/nginx/snippets/v2ray-ws: -------------------------------------------------------------------------------- 1 | proxy_redirect off; 2 | proxy_http_version 1.1; 3 | proxy_set_header Upgrade $http_upgrade; 4 | proxy_set_header Connection "upgrade"; 5 | proxy_set_header Host $http_host; 6 | proxy_set_header X-Real-IP $remote_addr; 7 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -------------------------------------------------------------------------------- /etc/screenrc: -------------------------------------------------------------------------------- 1 | #caption always # activates window caption 2 | #caption string '%{= wk}[ %{k}%H %{k}][%= %{= wk}%?%-Lw%?%{r}(%{r}%n*%f%t%?(%u)%?%{r})%{k}%?%+Lw%?%?%= %{k}][%{b} %Y-%m-%d %{k}%c %{k}]' 3 | 4 | # look and feel 5 | caption always "%{= bb}%{+b w}%h %=%{=b rw} %l %{= db} ${USER}@%H %{= dg}%Y-%m-%d %c:%s" 6 | hardstatus alwayslastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<" 7 | 8 | # skip the startup message 9 | startup_message off 10 | 11 | # go to home dir 12 | chdir 13 | 14 | # Automatically detach on hangup. 15 | autodetach on 16 | 17 | # Change default scrollback value for new windows 18 | defscrollback 10000 19 | 20 | # start with visual bell as default 21 | vbell on 22 | vbell_msg "bell on %t (%n)" 23 | 24 | activity "Activity in %t(%n)" 25 | 26 | shelltitle "shell" 27 | shell -$SHELL 28 | -------------------------------------------------------------------------------- /etc/vimrc: -------------------------------------------------------------------------------- 1 | set nocompatible " shut down vi-compat 2 | 3 | "> vim-plug 4 | "> curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim 5 | "> https://github.com/junegunn/vim-plug#usage 6 | call plug#begin() 7 | Plug 'scrooloose/nerdcommenter' 8 | Plug 'ervandew/supertab' 9 | Plug 'chr4/nginx.vim' 10 | Plug 'vim-airline/vim-airline' 11 | Plug 'vim-airline/vim-airline-themes' 12 | call plug#end() 13 | 14 | syntax on 15 | filetype plugin indent on 16 | 17 | " line number 18 | set number 19 | noremap :set invnumber 20 | inoremap :set invnumber 21 | 22 | " Toggle paste 23 | nnoremap :set invpaste paste? 24 | set pastetoggle= 25 | 26 | " set cursorline 27 | :hi CursorLine term=inverse cterm=inverse gui=inverse 28 | :nnoremap h :set cursorline! 29 | set ruler 30 | set showmode " Show mode in INSERT, REPLACE, VISUAL 31 | 32 | " Tab Settings 33 | set tabstop=2 34 | set expandtab " Ctrl+V,Tab;Ctrl+Q,Tab 35 | set softtabstop=2 36 | set shiftwidth=2 37 | set autoindent 38 | set smartindent 39 | set smarttab " shiftwidth at beginning, tabstop & softtabstop elsewhere 40 | 41 | " Searching 42 | set ignorecase 43 | set smartcase 44 | set incsearch " Incremetal Searching 45 | set hlsearch " Highlight -------------------------------------------------------------------------------- /i18n/en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | helloworld: Hello world ! -------------------------------------------------------------------------------- /i18n/zh-Hans.yml: -------------------------------------------------------------------------------- 1 | zh-Hans: 2 | Bytes: 字节 3 | Path: 路径 4 | Rename: 重命名 5 | Replace: 替换 6 | Source: 源 7 | __separator__: 8 | foo.bar: 9 | hhh: 10 | testhelloworld: 你好世界! 11 | -------------------------------------------------------------------------------- /ipy.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set pythonpath=%~dp0;%pythonpath% 4 | 5 | ipython %* -------------------------------------------------------------------------------- /lib_pkg/libusb-1.0.24-windows.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/lib_pkg/libusb-1.0.24-windows.7z -------------------------------------------------------------------------------- /mykits/bilibili_aocx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """bilibili mobile client APP offline cache extractor. 4 | \"offline cache\" means downloaded content.""" 5 | 6 | import os 7 | from glob import glob 8 | import argparse 9 | 10 | from mylib.sites.bilibili.__to_be_deprecated__ import BilibiliAppCacheEntry 11 | from oldezpykit.stdlib.argparse import CompactHelpFormatterWithDefaults 12 | 13 | 14 | def parse_args(): 15 | common_parser_kwargs = {'formatter_class': CompactHelpFormatterWithDefaults} 16 | ap = argparse.ArgumentParser(**common_parser_kwargs, 17 | description='bilibili APP offline cache extractor') 18 | ap.add_argument('-c', '--cookies', help='netscape format cookies (text) file', metavar='') 19 | ap.add_argument('folder', metavar='', 20 | help='a bilibili app offline cache entry folder, usually named in digits, wildcard glob supported') 21 | return ap.parse_args() 22 | 23 | 24 | def main(): 25 | args = parse_args() 26 | cookies = args.cookies 27 | folders = glob(args.folder) 28 | for folder in folders: 29 | if not os.path.isdir(folder): 30 | continue 31 | b = BilibiliAppCacheEntry(folder, cookies) 32 | b.extract_part() 33 | 34 | 35 | if __name__ == '__main__': 36 | main() 37 | -------------------------------------------------------------------------------- /mykits/bilibili_aocx.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | block_cipher = None 4 | 5 | 6 | a = Analysis(['mykits\\bilibili_aocx.py'], 7 | pathex=['C:\\Users\\mo-han\\locallib\\kit\\_github\\mo-han-toolbox'], 8 | binaries=[], 9 | datas=[], 10 | hiddenimports=[], 11 | hookspath=[], 12 | runtime_hooks=[], 13 | excludes=[], 14 | win_no_prefer_redirects=False, 15 | win_private_assemblies=False, 16 | cipher=block_cipher, 17 | noarchive=False) 18 | pyz = PYZ(a.pure, a.zipped_data, 19 | cipher=block_cipher) 20 | exe = EXE(pyz, 21 | a.scripts, 22 | a.binaries, 23 | a.zipfiles, 24 | a.datas, 25 | [], 26 | name='bilibili_aocx', 27 | debug=False, 28 | bootloader_ignore_signals=False, 29 | strip=False, 30 | upx=True, 31 | upx_exclude=['vcruntime140.dll'], 32 | runtime_tmpdir=None, 33 | console=True ) 34 | -------------------------------------------------------------------------------- /mykits/console_transcode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import codecs 3 | 4 | from mylib.ext.console_app import * 5 | from oldezpykit.stdlib.threading import thread_factory 6 | 7 | apr = ArgumentParserWrapper() 8 | 9 | 10 | @apr.root() 11 | @apr.arg('inner_encoding') 12 | @apr.arg('outer_encoding') 13 | @apr.map(inner_encoding='inner_encoding', outer_encoding='outer_encoding', args=apr.ticket_of_extra) 14 | def stdout_stderr_transcode(inner_encoding, outer_encoding, args): 15 | def read_1byte_from_pipe(pipe): 16 | def read_1byte(): 17 | return pipe.read(1) 18 | 19 | return read_1byte 20 | 21 | def transcode_pipe(from_pipe, from_encoding, to_pipe, to_encoding): 22 | from_decoder = codecs.getincrementaldecoder(from_encoding)(errors='surrogateescape') 23 | to_encoder = codecs.getincrementaldecoder(to_encoding)(errors='surrogateescape') 24 | for data in iter(read_1byte_from_pipe(from_pipe), b''): 25 | if not data: 26 | break 27 | s = from_decoder.decode(data) 28 | if s: 29 | from_decoder.reset() 30 | to_pipe.write(s.encode(to_encoding, errors='surrogateescape')) 31 | to_pipe.flush() 32 | 33 | p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) 34 | thread_factory(name='out')(transcode_pipe, p.stdout, inner_encoding, sys.stdout.buffer, outer_encoding).start() 35 | thread_factory(name='err')(transcode_pipe, p.stderr, inner_encoding, sys.stderr.buffer, outer_encoding).start() 36 | thread_factory(name='in')(transcode_pipe, sys.stdin.buffer, outer_encoding, p.stdin, inner_encoding).start() 37 | p.wait() 38 | 39 | 40 | def main(): 41 | apr.parse(catch_unknown_args=True) 42 | apr.run() 43 | 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /mykits/e.envar.autoset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from pprint import pprint 3 | 4 | from oldezpykit.allinone import * 5 | 6 | locallib_env = os.get_dirname(__file__) 7 | locallib = os.get_dirname(locallib_env) 8 | 9 | envar = { 10 | 'locallib': locallib, 11 | } 12 | for p in ('env', 'etc', 'usr'): 13 | envar[f'locallib_{p}'] = os.join_path(locallib, p) 14 | for p in ('env', 'etc', 'dl'): 15 | envar[f'locallib_usr{p}'] = os.join_path(locallib, 'usr', p) 16 | 17 | paths = [ 18 | os.join_path(locallib, 'usr', 'env'), 19 | os.join_path(locallib, 'env'), 20 | os.join_path(locallib, 'env', '_win64'), 21 | os.join_path(locallib, 'env', '_winbin'), 22 | ] 23 | 24 | os.EnVarKit.save(envar) 25 | pprint(envar) 26 | os.EnVarKit.save_path(insert=paths) 27 | pprint(paths) 28 | -------------------------------------------------------------------------------- /mykits/script_snippets.md: -------------------------------------------------------------------------------- 1 | ytdl.sh.cmd 2 | ```shell script 3 | #!/bin/sh 4 | mykit ytdl -- $* 2>&1 || exit 3 5 | ``` 6 | 7 | .config/youtube-dl/config 8 | ```shell script 9 | -o "%(title).70s [%(id)s][%(uploader)s].%(ext)s" 10 | --yes-playlist 11 | --fragment-retries infinite 12 | -icw 13 | --external-downloader aria2c 14 | --external-downloader-args "-x10 -s10 -k 1M" 15 | -f (299/137)[height<=?1080][fps<=60]+(m4a/aac)/bestvideo+bestaudio/best 16 | ``` 17 | 18 | bldl.sh.cmd 19 | ```shell script 20 | #!/bin/sh 21 | mykit bldl -c .config/cookies.bilibili.txt $* 2>&1 || exit 3 22 | ``` 23 | 24 | tree2path.py 25 | ```python 26 | """convert fs tree to full path (from stdin)""" 27 | import sys 28 | 29 | HEAD = '│ ' 30 | TAIL = '── ' 31 | IGNORE_DIR = True 32 | 33 | parts = [] 34 | for line in sys.stdin: 35 | clean_line = line.rstrip('\n').encode(errors='surrogateescape', encoding='ansi').decode() 36 | name = clean_line.split(TAIL)[-1] 37 | is_dir = name.endswith('/') 38 | if is_dir: 39 | name = name[:-1] 40 | indent = clean_line.count(HEAD) 41 | parts = [*parts[:indent], name] 42 | if is_dir and IGNORE_DIR: 43 | continue 44 | print('/'.join(parts)) 45 | ``` 46 | 47 | 48 | 微信 盛言奉天城韵 配音视频 49 | ```python 50 | import lxml.html 51 | import splinter 52 | 53 | from mylib.easy import * 54 | from mylib.wrapper import aria2c 55 | 56 | b = splinter.browser.FirefoxWebDriver(headless=True) 57 | 58 | 59 | def visit_util_title(url): 60 | b.visit(url) 61 | while not b.title: 62 | sleep(.1) 63 | 64 | 65 | def visit_blank(): 66 | b.visit('about:blank') 67 | while b.html != '' or b.title: 68 | sleep(.1) 69 | 70 | 71 | home = '' 72 | b.visit(home) 73 | ht = lxml.html.fromstring(b.html) 74 | pages = {i.attrib['href'] for i in ht.xpath('//section/section/a')} 75 | pages = sorted(pages) 76 | for page in pages: 77 | visit_blank() 78 | visit_util_title(page) 79 | title = b.title 80 | if not title: 81 | raise RuntimeError(repr(title), page) 82 | print(title) 83 | print(page) 84 | ht = lxml.html.fromstring(b.html) 85 | for i, v in enumerate(ht.find_class('video_fill'), 1): 86 | v_url = v.attrib['origin_src'] 87 | fp = f'{title} {i}.mp4' 88 | print(fp) 89 | print(v_url) 90 | aria2c.run_aria2c(v_url, o=fp) 91 | ``` -------------------------------------------------------------------------------- /mykits/web_viewer.py: -------------------------------------------------------------------------------- 1 | import webview.window 2 | 3 | from mylib.ext.console_app import * 4 | 5 | screen_width, screen_height = ostk.get_screen_size_via_tkinter() 6 | 7 | 8 | def get_page_title(window: webview.window.Window): 9 | return window.evaluate_js('document.title') 10 | 11 | 12 | def window_handler(window: webview.window.Window, title=None): 13 | if not title: 14 | sleep(.1) 15 | title = get_page_title(window) 16 | while not title: 17 | sleep(.1) 18 | title = get_page_title(window) 19 | window.set_title(title) 20 | 21 | 22 | apr = ArgumentParserWrapper() 23 | an = apr.an 24 | 25 | an.url = an.t = an.title = '' 26 | 27 | 28 | @apr.root() 29 | @apr.arg(an.url) 30 | @apr.opt(an.t, an.title) 31 | @apr.map(an.url, an.title) 32 | @ostk.deco_factory_pythonw_subprocess() 33 | def view_page(url, title=None): 34 | parse = urllib.parse.urlparse 35 | r = parse(url) 36 | if not r.scheme: 37 | r = parse('http://' + url) 38 | w = webview.create_window(title, r.geturl(), width=int(screen_width * .7), height=int(screen_height * .7)) 39 | webview.start(window_handler, (w, title)) 40 | 41 | 42 | def main(): 43 | apr.parse() 44 | apr.run() 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /mylib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 -------------------------------------------------------------------------------- /mylib/cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | import argparse 4 | 5 | from oldezpykit.stdlib.argparse import CompactHelpFormatterWithDefaults 6 | from mylib.math import int_is_power_of_2 7 | 8 | 9 | def arg_type_pow2(x): 10 | i = int(x) 11 | if int_is_power_of_2(i): 12 | return i 13 | else: 14 | raise argparse.ArgumentTypeError("'{}' is not power of 2".format(x)) 15 | 16 | 17 | def arg_type_range_factory(x_type, x_range_condition: str): 18 | def arg_type_range(x): 19 | x = x_type(x) 20 | if eval(x_range_condition): 21 | return x 22 | else: 23 | raise argparse.ArgumentTypeError("'{}' not in range {}".format(x, x_range_condition)) 24 | 25 | return arg_type_range 26 | 27 | 28 | def new_argument_parser(formatter_class=CompactHelpFormatterWithDefaults): 29 | return argparse.ArgumentParser(formatter_class=formatter_class) 30 | 31 | 32 | def add_dry_run(parser: argparse.ArgumentParser): 33 | parser.add_argument('-D', '--dry-run', action='store_true') 34 | -------------------------------------------------------------------------------- /mylib/const.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | -------------------------------------------------------------------------------- /mylib/device.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | 4 | import serial 5 | 6 | import mylib.easy.logging 7 | 8 | 9 | def short_serial_port(port: str, baudrate: int = 9600, **kwargs): 10 | p = serial.Serial(port=port, baudrate=baudrate, **kwargs) 11 | logger = mylib.easy.logging.ez_get_logger('{} shorter'.format(p.name)) 12 | while True: 13 | b = p.read_all() 14 | if b: 15 | logger.info(b) 16 | p.write(b) 17 | -------------------------------------------------------------------------------- /mylib/easy/__common__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import glob as glob 3 | import itertools as itertools 4 | import os as os 5 | import pathlib as pathlib 6 | import queue as queue 7 | import re as re 8 | import subprocess as subprocess 9 | import sys as sys 10 | import time as time 11 | 12 | from .stdlibs import typing as typing 13 | 14 | T = typing 15 | sleep = time.sleep 16 | 17 | 18 | def __refer_sth(): 19 | return queue, re, sys, subprocess, time, pathlib, glob, itertools 20 | 21 | 22 | path_is_file = os.path.isfile 23 | path_is_dir = os.path.isdir 24 | path_exist = os.path.exists 25 | path_dirname = os.path.dirname 26 | path_basename = os.path.basename 27 | path_common = os.path.commonpath 28 | path_common_prefix = os.path.commonprefix 29 | path_join = os.path.join 30 | path_user_tilde = os.path.expanduser 31 | path_env_var = os.path.expandvars 32 | path_split = os.path.split 33 | path_split_ext = os.path.splitext 34 | path_absolute = os.path.abspath 35 | path_real = os.path.realpath 36 | path_relative = os.path.relpath 37 | path_normalize = os.path.normpath 38 | path_size = os.path.getsize 39 | path_ctime = os.path.getctime 40 | path_mtime = os.path.getmtime 41 | -------------------------------------------------------------------------------- /mylib/easy/asyncio.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys as _sys 3 | from asyncio import * 4 | 5 | __REF = get_event_loop 6 | 7 | if _sys.version_info < (3, 9): 8 | async def to_thread(func, *args, **kwargs): 9 | """Asynchronously run function *func* in a separate thread. 10 | Any *args and **kwargs supplied for this function are directly passed 11 | to *func*. Also, the current :class:`contextvars.Context` is propogated, 12 | allowing context variables from the main thread to be accessed in the 13 | separate thread. 14 | Return a coroutine that can be awaited to get the eventual result of *func*. 15 | """ 16 | import contextvars 17 | import functools 18 | from asyncio import events 19 | loop = events._get_running_loop() 20 | ctx = contextvars.copy_context() 21 | func_call = functools.partial(ctx.run, func, *args, **kwargs) 22 | return await loop.run_in_executor(None, func_call) 23 | -------------------------------------------------------------------------------- /mylib/easy/builtin_dict.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from functools import reduce 3 | 4 | 5 | def ez_dict_intersection(*dicts): 6 | return reduce(lambda x, y: dict([(k, v) for k, v in x.items() if (k, v) in y.items()]), dicts) 7 | 8 | 9 | def ez_dict_union(*dicts): 10 | r = {} 11 | for d in dicts: 12 | r.update(d) 13 | return r 14 | 15 | 16 | def ez_dict_difference(x: dict, y: dict): 17 | return dict([(k, v) for k, v in x.items() if (k, v) not in y.items()]) 18 | 19 | 20 | def ez_dict_multi_get(d: dict, **kwargs): 21 | return {k: d.get(k, v) for k, v in kwargs.items()} 22 | -------------------------------------------------------------------------------- /mylib/easy/common/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # !/usr/bin/env python3 3 | import glob as glob 4 | import itertools as itertools 5 | import os as os 6 | import pathlib as pathlib 7 | import queue as queue 8 | import re as re 9 | import subprocess as subprocess 10 | import sys as sys 11 | import time as time 12 | 13 | from mylib.easy.stdlibs import typing as typing 14 | 15 | T = typing 16 | sleep = time.sleep 17 | 18 | 19 | def __refer_sth(): 20 | return queue, re, sys, subprocess, time, pathlib, glob, itertools 21 | 22 | 23 | path_is_file = os.path.isfile 24 | path_is_dir = os.path.isdir 25 | path_exist = os.path.exists 26 | path_dirname = os.path.dirname 27 | path_basename = os.path.basename 28 | path_common = os.path.commonpath 29 | path_common_prefix = os.path.commonprefix 30 | path_join = os.path.join 31 | path_user_tilde = os.path.expanduser 32 | path_env_var = os.path.expandvars 33 | path_split = os.path.split 34 | path_split_ext = os.path.splitext 35 | path_absolute = os.path.abspath 36 | path_real = os.path.realpath 37 | path_relative = os.path.relpath 38 | path_normalize = os.path.normpath 39 | path_size = os.path.getsize 40 | path_ctime = os.path.getctime 41 | path_mtime = os.path.getmtime 42 | -------------------------------------------------------------------------------- /mylib/easy/extra/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from .call import * 3 | -------------------------------------------------------------------------------- /mylib/easy/logging.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from logging import * 4 | from logging.handlers import * 5 | 6 | # logging format 7 | LOG_FMT_MESSAGE_ONLY = '%(message)s' 8 | LOG_FMT_1LEVEL_MESSAGE_ONLY = '[%(levelname).1s] %(message)s' 9 | LOG_FMT_1LEVEL_NO_TIME = '[%(levelname).1s][%(name)s] %(message)s' 10 | LOG_FMT_1LEVEL_DATE_TIME = '[%(levelname).1s][%(asctime).19s][%(name)s] %(message)s' 11 | LOG_FMT_1LEVEL_DATE_TIME_ZONE = '[%(levelname).1s][%(asctime)s][%(name)s] %(message)s' 12 | # logging datetime format 13 | LOG_DATE_FMT_SEC = '%Y-%m-%d %H:%M:%S' 14 | LOG_DATE_FMT_SEC_ZONE = '%Y-%m-%d %H:%M:%S%z' 15 | 16 | 17 | class EzLogger(Logger): 18 | def set_all_handlers_format(self, fmt=None, date_fmt=None): 19 | if not fmt and not date_fmt and hasattr(self, 'formatter'): 20 | formatter = self.formatter 21 | else: 22 | formatter = Formatter(fmt=fmt, datefmt=date_fmt) 23 | for h in self.handlers: 24 | h.setFormatter(formatter) 25 | return self 26 | 27 | def set_all_handlers_level(self, level): 28 | self.setLevel(level) 29 | for h in self.handlers: 30 | h.setLevel(level) 31 | return self 32 | 33 | def add_handlers(self, *handlers): 34 | for h in handlers: 35 | self.addHandler(h) 36 | return self 37 | 38 | 39 | class EzLoggingMixin: 40 | @property 41 | def __logger__(self): 42 | try: 43 | r = self.__self_logger 44 | except AttributeError: 45 | r = self.__self_logger = ez_get_logger(f'{self.__class__.__name__}', 'DEBUG') 46 | finally: 47 | return r 48 | 49 | 50 | def ez_get_logger(logger_name: str, level: str = 'INFO', fmt=LOG_FMT_1LEVEL_NO_TIME, date_fmt=LOG_DATE_FMT_SEC_ZONE, 51 | handlers: list = None) -> EzLogger: 52 | formatter = Formatter(fmt=fmt, datefmt=date_fmt) 53 | logger = getLogger(logger_name) 54 | logger.setLevel(level) 55 | if not handlers: 56 | handlers = [StreamHandler()] 57 | for h in handlers: 58 | h.setFormatter(formatter) 59 | logger.handlers = handlers 60 | logger.__class__ = EzLogger 61 | logger.formatter = formatter 62 | return logger 63 | -------------------------------------------------------------------------------- /mylib/easy/ostk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import getpass 3 | import platform 4 | import signal 5 | import tempfile 6 | 7 | from mylib.easy import * 8 | 9 | 10 | def ensure_sigint_signal(): 11 | if sys.platform == 'win32': 12 | signal.signal(signal.SIGINT, signal.SIG_DFL) # %ERRORLEVEL% = '-1073741510' 13 | 14 | 15 | TEMPDIR = tempfile.gettempdir() 16 | HOSTNAME = platform.node() 17 | OSNAME = platform.system() 18 | USERNAME = getpass.getuser() 19 | -------------------------------------------------------------------------------- /mylib/easy/socket.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from socket import * 3 | from ..easy import ez_parse_netloc 4 | 5 | 6 | def ez_parse_host_port(url): 7 | r = ez_parse_netloc(url) 8 | return r.hostname, r.port 9 | 10 | 11 | class EzSocket(socket): 12 | address: tuple 13 | 14 | def set_netloc(self, url): 15 | r = ez_parse_netloc(url) 16 | self.address = r.hostname, r.port 17 | return self 18 | 19 | def set_host_port(self, host, port): 20 | self.address = host, port 21 | return self 22 | 23 | def connect(self, address=None) -> 'EzSocket': 24 | address = address or self.address 25 | super(EzSocket, self).connect(address) 26 | return self 27 | 28 | def shutdown(self, how: int = SHUT_RDWR) -> 'EzSocket': 29 | super(EzSocket, self).shutdown(how) 30 | return self 31 | -------------------------------------------------------------------------------- /mylib/easy/stdlibs/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /mylib/easy/stdlibs/threading.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from threading import * 3 | from mylib.easy.common import T 4 | 5 | 6 | def ez_thread_factory(group=None, name=None, daemon=None): 7 | def new_thread(target: T.Callable, *args, **kwargs): 8 | return Thread(group=group, target=target, name=name, args=args, kwargs=kwargs, daemon=daemon) 9 | 10 | return new_thread 11 | -------------------------------------------------------------------------------- /mylib/easy/stdlibs/typing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from typing import * 3 | from typing import IO, BinaryIO, TextIO # necessary! 4 | 5 | 6 | def __ref(): 7 | return IO, BinaryIO, TextIO 8 | 9 | 10 | Decorator = Callable[[Callable], Callable] 11 | 12 | 13 | class QueueType: 14 | def put(self, *args, **kwargs): 15 | ... 16 | 17 | def get(self, *args, **kwargs): 18 | ... 19 | 20 | 21 | JSONType = Union[str, int, float, bool, None, Mapping[str, 'JSON'], List['JSON']] 22 | 23 | NoneType = type(None) 24 | 25 | EllipsisType = type(Ellipsis) 26 | -------------------------------------------------------------------------------- /mylib/easy/webbrowser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from webbrowser import * 3 | from webbrowser import BackgroundBrowser 4 | 5 | from . import * 6 | 7 | 8 | def get_web_browser(name: str, path: str): 9 | register(name, None, BackgroundBrowser(path)) 10 | return get(name) 11 | 12 | 13 | def get_firefox(path=None): 14 | name = 'firefox' 15 | if not path: 16 | if os.name == 'nt': 17 | mozilla_firefox = 'Mozilla Firefox' 18 | make_call = functools.partial(ACall, shutil.which, name) 19 | path = ALotCall( 20 | *[make_call(path=path_join(os.environ[env_var], mozilla_firefox)) for env_var in 21 | ['ProgramFiles', 'ProgramW6432', 'ProgramFiles(x86)']], 22 | make_call(), 23 | ).any_result(ignore_exceptions=Exception) 24 | else: 25 | path = shutil.which(name) 26 | if not path: 27 | raise FileNotFoundError(name) 28 | return get_web_browser(name, path) 29 | -------------------------------------------------------------------------------- /mylib/enchant/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /mylib/ext/PIL.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import io 3 | 4 | from PIL import Image 5 | from PIL import ImageFile 6 | from PIL import ImageGrab 7 | 8 | 9 | def __refer_sth(): 10 | return ImageGrab, ImageFile 11 | 12 | 13 | def save_image_to_bytes(img: Image.Image, save_fmt=None, **kwargs): 14 | with io.BytesIO() as _: 15 | img.save(_, format=save_fmt or img.format, **kwargs) 16 | return _.getvalue() 17 | 18 | 19 | def open_bytes_as_image(b: bytes, mode="r"): 20 | fd = io.BytesIO() # DO NOT CLOSE THIS FILE OBJECT! 21 | fd.write(b) 22 | fd.seek(0) 23 | return Image.open(fd, mode=mode) 24 | 25 | 26 | def enable_load_truncated_image(): 27 | ImageFile.LOAD_TRUNCATED_IMAGES = True 28 | 29 | 30 | def disable_load_truncated_image(): 31 | ImageFile.LOAD_TRUNCATED_IMAGES = False 32 | -------------------------------------------------------------------------------- /mylib/ext/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /mylib/ext/colour.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from mylib.easy import * 3 | import colour 4 | 5 | 6 | class Color(colour.Color): 7 | HEX_PATTERN_3 = r'[0-9a-fA-F]{3}' 8 | HEX_PATTERN_6 = r'[0-9a-fA-F]{6}' 9 | HEX_PATTERN_GROUP = rf'({HEX_PATTERN_3}|{HEX_PATTERN_6})' 10 | 11 | def as_hex(self, x: str): 12 | x = str_remove_prefix(x, '#') 13 | if re.match(self.HEX_PATTERN_3, x): 14 | self.set_hex(f'#{x}') 15 | elif re.match(self.HEX_PATTERN_6, x): 16 | self.set_hex_l(f'#{x}') 17 | else: 18 | raise ValueError(x) 19 | return self 20 | 21 | def as_rgb(self, r: int, g: int, b: int): 22 | rgb = (r, g, b) 23 | hex_s = ''.join([f'{i:02x}' for i in rgb]) 24 | return self.as_hex(hex_s) 25 | 26 | def __getattr__(self, item): 27 | match = re.match(self.as_hex.__name__ + '_' + self.HEX_PATTERN_GROUP, item) 28 | if match: 29 | hex_s = match.group(1) 30 | return self.as_hex(hex_s) 31 | match = re.match(self.as_rgb.__name__ + '_' + r'(\d{1,3})_(\d{1,3})_(\d{1,3})', item) 32 | if match: 33 | r, g, b = [int(s) for s in match.groups()] 34 | return self.as_rgb(r, g, b) 35 | return super(Color, self).__getattr__(item) 36 | -------------------------------------------------------------------------------- /mylib/ext/console_app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.stdlib.argparse import * 3 | from mylib.easy import * 4 | from mylib.ext import fstk, text, ostk 5 | 6 | ___ref = fstk, text, ArgumentParserWrapper 7 | 8 | PathSourceTypeTuple = list, str, T.NoneType 9 | PathSourceType = T.Union[T.List[str], str, T.NoneType] 10 | 11 | stderr_print = functools.partial(print, file=sys.stderr) 12 | 13 | 14 | def resolve_path_to_dirs_files(x: PathSourceType, *, 15 | use_clipboard=True, use_stdin=False, 16 | glob_recurse=False, exist_prior_to_glob=True): 17 | if not isinstance(x, PathSourceTypeTuple): 18 | raise TypeError('x', PathSourceType, type(x), x) 19 | 20 | if not x: 21 | if use_clipboard: 22 | xl = ostk.clipboard.list_path() 23 | else: 24 | return [], [] 25 | elif use_stdin and x in ('-', ['-']): 26 | xl = sys.stdin.read().splitlines() 27 | else: 28 | if isinstance(x, list): 29 | xl = x 30 | else: 31 | xl = [x] 32 | return glob_or_exist_to_dirs_files(xl, glob_recurse=glob_recurse, exist_prior_to_glob=exist_prior_to_glob) 33 | 34 | 35 | class ConsolePrinter: 36 | def __init__(self, file=sys.stdout): 37 | self.file = file 38 | 39 | @property 40 | def width(self): 41 | return shutil.get_terminal_size()[0] 42 | 43 | def split_line(self, char='-'): 44 | print(char * (self.width - 1), file=self.file) 45 | 46 | ll = split_line 47 | 48 | def clear_line(self, mask_char=' '): 49 | print(f'\r{mask_char * (self.width - 1)}\r', end='', file=self.file) 50 | 51 | cl = clear_line 52 | 53 | def in_line(self, *args, cursor_at_end=True): 54 | self.clear_line() 55 | if cursor_at_end: 56 | print(*args, end='', file=self.file, flush=True) 57 | else: 58 | print(*args, end='\r', file=self.file) 59 | 60 | il = in_line 61 | 62 | def new_line(self): 63 | print('', file=self.file) 64 | 65 | nl = new_line 66 | -------------------------------------------------------------------------------- /mylib/ext/ezqt/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /mylib/ext/ezqt/util/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /mylib/ext/ezqt/util/enable_auto_screen_scale.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | 4 | os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = '1' 5 | # app.setAttribute(Qt.AA_EnableHighDpiScaling) 6 | -------------------------------------------------------------------------------- /mylib/ext/ezqt/util/enable_qt_virtual_keyboard.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import PySide2.QtQuick # qtvirtualkeyboard need QtQuick 4 | 5 | 6 | def __ref(): 7 | return PySide2.QtQuick 8 | 9 | 10 | os.environ["QT_IM_MODULE"] = "qtvirtualkeyboard" 11 | -------------------------------------------------------------------------------- /mylib/ext/fstk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from mylib.easy.fstk import * 3 | from mylib.ext import tricks 4 | 5 | 6 | def __ref(): 7 | return POTENTIAL_INVALID_CHARS_MAP 8 | 9 | 10 | def read_sqlite_dict_file(filepath, *, with_dill=False, **kwargs): 11 | if with_dill: 12 | sqlitedict = tricks.module_sqlitedict_with_dill(dill_detect_trace=True) 13 | else: 14 | import sqlitedict 15 | with sqlitedict.SqliteDict(filepath, **kwargs) as sd: 16 | return dict(sd) 17 | 18 | 19 | def write_sqlite_dict_file(filepath, data, *, with_dill=False, dill_detect_trace=False, update_only=False, **kwargs): 20 | if with_dill: 21 | sqlitedict = tricks.module_sqlitedict_with_dill(dill_detect_trace=dill_detect_trace) 22 | else: 23 | import sqlitedict 24 | with sqlitedict.SqliteDict(filepath, **kwargs) as sd: 25 | if not update_only: 26 | sd.clear() 27 | sd.update(data) 28 | sd.commit() 29 | 30 | 31 | def does_file_mime_has(file, mime_keyword): 32 | from filetype import filetype 33 | guess = filetype.guess(file) 34 | return guess and mime_keyword in guess.mime 35 | -------------------------------------------------------------------------------- /mylib/ext/getch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from getch import * # py-getch 4 | -------------------------------------------------------------------------------- /mylib/ext/html.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import lxml.html as lxml_html 3 | import requests as requests 4 | 5 | from mylib import easy 6 | 7 | 8 | class ResponseError(Exception): 9 | pass 10 | 11 | 12 | class HTMLResponseParser: 13 | def __init__(self, response=requests.Response): 14 | self._response = response 15 | 16 | @property 17 | def response(self): 18 | return self._response 19 | 20 | @property 21 | def r(self): 22 | return self._response 23 | 24 | @property 25 | def ok(self): 26 | return self.r.ok 27 | 28 | def check_ok_or_raise(self): 29 | if not self.ok: 30 | raise ResponseError(self.r) 31 | return self 32 | 33 | @easy.functools.lru_cache() 34 | def get_html_element(self) -> lxml_html.HtmlElement: 35 | return lxml_html.fromstring(self.r.text) 36 | -------------------------------------------------------------------------------- /mylib/ext/i18n.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import i18n as python_i18n 3 | import yaml 4 | 5 | from mylib.easy import get_os_default_lang, functools 6 | 7 | SEP_KEY = '__separator__' 8 | 9 | load_path: list = python_i18n.load_path 10 | records = {} 11 | 12 | 13 | def translate_and_record(key, **kwargs): 14 | try: 15 | r = python_i18n.t(key, **kwargs) 16 | v = None if r == key else r 17 | except TypeError: 18 | r = key 19 | v = None 20 | records[key] = v 21 | return r 22 | 23 | 24 | @functools.lru_cache() 25 | def cached_translate(key, **kwargs): 26 | return translate_and_record(key, **kwargs) 27 | 28 | 29 | def dump_records_to_yaml_source_file___pre_alpha(fp: str, null_as_blank=True, unicode=True, **kwargs): 30 | encoding = 'utf-8' 31 | old = yaml.safe_load(open(fp, encoding=encoding).read()) 32 | for k in old.keys(): 33 | v: dict = old[k] 34 | v.update(records) 35 | old[k] = dict(sorted(v.items())) 36 | s = yaml.safe_dump(old, allow_unicode=unicode, **kwargs) 37 | if null_as_blank: 38 | s = s.replace(': null\n', ':\n') 39 | with open(fp, 'w', encoding=encoding) as f: 40 | f.write(s) 41 | 42 | 43 | def get_separator(default=' ') -> str: 44 | sep = translate_and_record(SEP_KEY) 45 | return default if sep == SEP_KEY else sep 46 | 47 | 48 | def join(*args): 49 | sep = get_separator() 50 | return sep.join(args) 51 | 52 | 53 | def insert_load_dir(path: str = 'i18n', index=0): 54 | load_path.insert(index, path) 55 | 56 | 57 | def remove_namespace_from_filename_format(): 58 | python_i18n.set('filename_format', '{locale}.{format}') 59 | 60 | 61 | def map_locale_to_rfc5646___alpha(the_locale: str): 62 | """RFC 5646""" 63 | d = {'zh-cn': 'zh-Hans', 'zh-hk': 'zh-Hant', 'zh-tw': 'zh-Hant'} 64 | the_locale = the_locale.replace('_', '-').lower() 65 | return d.get(the_locale, the_locale.split('-')[0]) 66 | 67 | 68 | def set_locale(the_locale: str = get_os_default_lang()): 69 | python_i18n.config.set('locale', map_locale_to_rfc5646___alpha(the_locale)) 70 | 71 | 72 | def get_locale(): 73 | return python_i18n.config.get('locale') 74 | 75 | 76 | def reload_all(): 77 | for p in load_path: 78 | python_i18n.resource_loader.load_directory(p, locale=get_locale()) 79 | 80 | 81 | def enable_memoization(): 82 | python_i18n.set('enable_memoization', True) 83 | 84 | 85 | def disable_memoization(): 86 | python_i18n.set('enable_memoization', False) 87 | 88 | 89 | def preset___alpha(): 90 | remove_namespace_from_filename_format() 91 | insert_load_dir() 92 | set_locale() 93 | -------------------------------------------------------------------------------- /mylib/ext/ostk_posix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os.path 3 | 4 | import pyperclip 5 | 6 | from mylib.easy.ostk import * 7 | 8 | 9 | class Clipboard(metaclass=SingletonMetaClass): 10 | _cb = pyperclip 11 | 12 | def __enter__(self): 13 | return self 14 | 15 | def __exit__(self, exc_type, exc_val, exc_tb): 16 | pass 17 | 18 | def clear(self): 19 | self.set('') 20 | return self 21 | 22 | def set(self, data): 23 | self._cb.copy(data) 24 | 25 | def get(self): 26 | return self._cb.paste() 27 | 28 | def list_path(self, exist_only=True): 29 | lines = [line.strip() for line in str(self.get()).splitlines()] 30 | return [line for line in lines if os.path.exists(line)] 31 | 32 | 33 | clipboard = Clipboard() 34 | 35 | 36 | def fs_copy_cli(src, dst): 37 | subprocess.run(['cp', '-r', src, dst], shell=True).check_returncode() 38 | 39 | 40 | def fs_move_cli(src, dst): 41 | subprocess.run(['mv', src, dst], shell=True).check_returncode() 42 | 43 | 44 | def set_console_title(title: str): 45 | print(f'\33]0;{title}\a', end='', flush=True) 46 | -------------------------------------------------------------------------------- /mylib/ext/pure_python_adb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import ppadb.client 3 | import ppadb.command.host 4 | import ppadb.device 5 | 6 | from mylib.easy import * 7 | 8 | 9 | class AndroidDevice(ppadb.device.Device): 10 | def input_roll(self, dx, dy): 11 | return self.shell(f'input roll {dx} {dy}') 12 | 13 | def input_swipe(self, x1, y1, x2, y2, seconds=None): 14 | return super().input_swipe(x1, y1, x2, y2, (int(seconds * 1000) if seconds is not None else '')) 15 | 16 | 17 | ppadb.device.Device = ppadb.command.host.Device = AndroidDevice 18 | ppadb.client.Host = ppadb.command.host.Host 19 | 20 | 21 | class ADBClient(ppadb.client.Client): 22 | def connect(self, address: str): 23 | r = ez_parse_netloc(address) 24 | return self.remote_connect(r.hostname, r.port or 5555) 25 | 26 | 27 | ppadb.client.Client = ADBClient 28 | -------------------------------------------------------------------------------- /mylib/ext/pyside2/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /mylib/ext/pyside2/signal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from typing import Iterable 3 | 4 | from PySide2.QtCore import Signal, Slot 5 | 6 | 7 | def __ref_sth(): 8 | return Signal, Slot 9 | 10 | 11 | def ez_qt_signal_connect(signal, slot): 12 | r = [] 13 | if isinstance(slot, Iterable): 14 | for i_slot in slot: 15 | ez_qt_signal_connect(signal, i_slot) 16 | elif slot: 17 | signal.connect(slot) 18 | r.append(slot) 19 | return r 20 | 21 | 22 | def ez_qt_signal_disconnect(signal, slot=None): 23 | try: 24 | if isinstance(slot, Iterable): 25 | for i_slot in slot: 26 | ez_qt_signal_disconnect(signal, i_slot) # nested calling 27 | elif slot: 28 | while True: 29 | signal.disconnect(slot) 30 | else: 31 | try: 32 | signal.disconnect() 33 | except RuntimeError: 34 | pass 35 | except TypeError: 36 | pass 37 | 38 | 39 | def ez_qt_signal_map(mapping: dict): 40 | r = {} 41 | for signal, slot in mapping.items(): 42 | r[signal] = ez_qt_signal_connect(signal, slot) 43 | return r 44 | 45 | 46 | def ez_qt_signal_reconnect(signal, new=None, old=None): 47 | ez_qt_signal_disconnect(signal, old) 48 | if new: 49 | return ez_qt_signal_connect(signal, new) 50 | else: 51 | return [] 52 | -------------------------------------------------------------------------------- /mylib/ext/text.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from mylib.easy.text import * 3 | 4 | 5 | def __ref(): 6 | return 7 | 8 | 9 | def remove_accent_chars_regex(x: str): 10 | import regex 11 | return regex.sub(r'\p{Mn}', '', unicodedata.normalize('NFKD', x)) 12 | -------------------------------------------------------------------------------- /mylib/gui_im.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from dearpygui.core import add_additional_font 4 | 5 | 6 | def add_additional_font_uni(file='mylib/unifont-13.0.04.ttf', size=13): 7 | # https://github.com/hoffstadt/DearPyGui/issues/209#issuecomment-691930697 8 | add_additional_font(file, size, 9 | custom_glyph_ranges=( 10 | # the more ranges, the slower -> BAD METHOD! 11 | (0x3400, 0x4dbf), # CJK Unified Ideographs Extension A 12 | (0x4E00, 0x9FFF), # CJK Unified Ideographs (Chinese chars, Han unification) 13 | (0x3040, 0x30ff), # Japanese (Hiragana & Katakana) 14 | (0xac00, 0xd7a3), (0x1100, 0x11ff), (0x3131, 0x318e), (0xffa1, 0xffdc), # Korean 15 | (0x0e00, 0x0e7f), # Thai 16 | (0x370, 0x377), # Greek and Coptic 17 | (0x400, 0x4ff), # Cyrillic 18 | (0x530, 0x58f), # Armenian 19 | (0x10a0, 0x10ff), # Georgian 20 | )) 21 | -------------------------------------------------------------------------------- /mylib/math.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | 4 | 5 | def int_is_power_of_2(x: int): 6 | if x > 1: 7 | return x & (x - 1) == 0 8 | elif x == 1: 9 | return True 10 | else: 11 | return False 12 | 13 | 14 | class Pow2(int): 15 | def __new__(cls, x): 16 | new = super(Pow2, cls).__new__(cls, x) 17 | if int_is_power_of_2(new): 18 | return new 19 | else: 20 | raise ValueError("invalid literal for {}(): '{}'".format(cls.__name__, x)) 21 | -------------------------------------------------------------------------------- /mylib/pip2pi_x.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | from .easy import python_module_from_source_code 4 | 5 | 6 | def code_modify_pip2pi(x: str) -> str: 7 | x = x.replace(""" 8 | self.add_option( 9 | '-S', '--no-symlink', dest="use_symlink", action="store_false") 10 | """, """ 11 | self.add_option( 12 | '-A', '--absolute-symlink', dest='absolute_symlink', 13 | default=False, action='store_true', 14 | help='Use absolute path symlink (default is relative path).' 15 | ) 16 | self.add_option( 17 | '-S', '--no-symlink', dest="use_symlink", action="store_false") 18 | """) 19 | x = x.replace(""" 20 | symlink_source = os.path.join("../../", pkg_basename) 21 | """, """ 22 | if option.absolute_symlink: 23 | symlink_source = os.path.abspath(os.path.join("../../", pkg_basename)) 24 | else: 25 | symlink_source = os.path.join("../../", pkg_basename) 26 | """) 27 | return x 28 | 29 | 30 | libpip2pi_commands_x = python_module_from_source_code('libpip2pi.commands', code_modify_pip2pi) 31 | -------------------------------------------------------------------------------- /mylib/shards/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | -------------------------------------------------------------------------------- /mylib/shards/qt_web_render.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import requests_html 4 | from qtpy.QtCore import QUrl 5 | from qtpy.QtWebEngineWidgets import QWebEnginePage 6 | from qtpy.QtWidgets import QApplication 7 | 8 | from mylib.easy import * 9 | 10 | 11 | @deco_cached_call 12 | def get_qt_application_singleton(klass=QApplication, argv=None): 13 | argv = argv or sys.argv 14 | return klass(argv) 15 | 16 | 17 | class QtWebPageRender: 18 | url: str 19 | html_str: str 20 | html_parser: requests_html.HTML 21 | 22 | def __init__(self, qt_app_singleton=None): 23 | self._qt_app = qt_app_singleton or get_qt_application_singleton() 24 | self._qt_webpage = QWebEnginePage() 25 | self._qt_webpage.loadFinished.connect(self._on_load_finished) 26 | 27 | def _on_load_finished(self): 28 | self._qt_webpage.toHtml(self._update_html) 29 | 30 | def _update_html(self, qt_webpage_to_html: str): 31 | self.html_str = qt_webpage_to_html 32 | self.html_parser = requests_html.HTML(url=self.url, html=self.html_str) 33 | self.find = self.html_parser.find 34 | self.xpath = self.html_parser.xpath 35 | self._qt_app.quit() 36 | 37 | def set_url(self, url: str): 38 | self.url = url 39 | self._qt_webpage.load(QUrl(url)) 40 | self._qt_app.exec_() 41 | 42 | def set_html(self, html: str, base_url: str = ''): 43 | self.url = base_url 44 | self._qt_webpage.setHtml(html, QUrl(base_url)) 45 | self._qt_app.exec_() 46 | 47 | @property 48 | def text(self): 49 | return self.html_parser.text 50 | -------------------------------------------------------------------------------- /mylib/sites/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | -------------------------------------------------------------------------------- /mylib/sites/bilibili/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /mylib/sites/bilibili/bili_plus_3rd_party.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # todo: make this 3 | -------------------------------------------------------------------------------- /mylib/sites/bilibili/browser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from mylib.ext import http_headers 4 | 5 | ROOT_DOMAIN = 'bilibili.com' 6 | 7 | 8 | class BilibiliSplinterBrowserWrapper: 9 | def __init__(self, splinter_browser, cookies_dict=None, cookies_source=None): 10 | b = self.browser = splinter_browser 11 | b.visit('https://' + ROOT_DOMAIN) 12 | if cookies_dict: 13 | self.add_cookies(cookies_dict) 14 | elif cookies_source: 15 | self.add_cookies_from(cookies_source) 16 | 17 | def add_cookies_from(self, x): 18 | self.add_cookies(http_headers.get_cookies_dict_from(x)) 19 | 20 | def add_cookies(self, cookies: dict): 21 | self.browser.cookies.add(cookies) 22 | for cookie in self.list_cookies(): 23 | cookie['domain'] = ROOT_DOMAIN 24 | self.add_single_cookie_dict(cookie) 25 | self.browser.reload() 26 | 27 | def add_single_cookie_dict(self, single_cookie_dict): 28 | self.browser.driver.add_cookie(single_cookie_dict) 29 | 30 | def get_cookies(self): 31 | return self.browser.cookies.all() 32 | 33 | def list_cookies(self): 34 | return self.browser.driver.get_cookies() 35 | -------------------------------------------------------------------------------- /mylib/sites/bilibili/mobile_app_offline_cache.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | DANMAKU_XML_BASENAME = 'danmaku.xml' 4 | ENTRY_JSON_BASENAME = 'entry.json' 5 | 6 | 7 | -------------------------------------------------------------------------------- /mylib/sites/misc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from mylib.ext.html import * 3 | 4 | 5 | def get_cloudflare_ipaddr_hostmonit(key="o1zrmHAF"): 6 | # https://github.com/ddgth/cf2dns/blob/master/cf2dns.py 7 | url = 'https://api.hostmonit.com/get_optimization_ip' 8 | r = requests.post(url, json={"key": key}, headers={'Content-Type': 'application/json'}) 9 | return r.json() 10 | 11 | 12 | def free_ss_site_vmess_uuid(): 13 | r = requests.get('https://free-ss.site/') 14 | for e in lxml_html.fromstring(r.text).cssselect('script'): 15 | s = e.text 16 | if s and 'www.kernels.bid' in s: 17 | return easy.re.findall(easy.REGEX_GUID, s) 18 | -------------------------------------------------------------------------------- /mylib/sites/pornhub.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from abc import ABCMeta 3 | 4 | import youtube_dl.extractor.pornhub as ytdl_pornhub 5 | 6 | from mylib.easy import text 7 | from mylib.web_client import get_html_element_tree 8 | 9 | 10 | def find_url_in_text(x: str) -> list: 11 | prefix = 'https://www.pornhub.com' 12 | pattern = r'/view_video\.php\?viewkey=(?:ph[0-9a-f]+|[0-9a-f]+)' 13 | return [prefix + e for e in text.regex_find(pattern, x, dedup=True)] 14 | 15 | 16 | # ytdl_pornhub.InfoExtractor = youtube_dl_x.ytdl_common.InfoExtractor # SEEMINGLY NO EFFECT 17 | 18 | 19 | class PornHubIE(ytdl_pornhub.PornHubIE, metaclass=ABCMeta): 20 | def _real_extract(self, url): 21 | data = super()._real_extract(url) 22 | # youtube_dl_x.safe_title(data) 23 | try: 24 | if data.get('uploader'): 25 | return data 26 | html = get_html_element_tree(url) 27 | uploader = html.xpath('//div[@class="userInfo"]//a')[0].text 28 | data['uploader'] = uploader 29 | # print('#', 'uploader:', uploader) 30 | except IndexError: 31 | pass 32 | return data 33 | -------------------------------------------------------------------------------- /mylib/sites/sankakucomplex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import oldezpykit.stdlib.shutil.__deprecated__ 3 | from mylib.ext.console_app import * 4 | import hashlib 5 | 6 | 7 | def file_is_bad(file): 8 | size = path_size(file) 9 | if not size: 10 | return True 11 | if size in (14802, 8508) and hashlib.md5(open(file, 'rb').read()).hexdigest() in ( 12 | 'b325d6ba8efb828686667aa58ab549e8', 'fba5c45637db04d4797bc730c849ce30'): 13 | return True 14 | return False 15 | 16 | 17 | def find_bad_files_iter(files): 18 | for fp in files: 19 | if file_is_bad(fp): 20 | yield fp 21 | 22 | 23 | apr = ArgumentParserWrapper() 24 | an = apr.an 25 | an.src = an.v = an.verbose = '' 26 | 27 | 28 | @apr.sub(aliases=['rm.bad.files']) 29 | @apr.arg(an.src, nargs='*') 30 | @apr.true(an.v, an.verbose) 31 | @apr.map(an.src, verbose=an.verbose, print_dirname=apr.obj(True)) 32 | def remove_expired_link_files(src, verbose=False, print_dirname=False): 33 | dirs, files = resolve_path_to_dirs_files(src) 34 | bad_files = [] 35 | dir_with_bad_files = {} 36 | for path in itertools.chain(dirs, files): 37 | for fp in find_bad_files_iter(fstk.find_iter('f', path, recursive=True)): 38 | oldezpykit.stdlib.shutil.__deprecated__.remove(fp) 39 | bad_files.append(fp) 40 | dp = path_dirname(fp) 41 | if dp not in dir_with_bad_files: 42 | dir_with_bad_files[dp] = ... 43 | if verbose: 44 | for fp in bad_files: 45 | print(fp) 46 | if print_dirname: 47 | ConsolePrinter().ll() 48 | for dp in dir_with_bad_files.keys(): 49 | print(dp) 50 | return bad_files 51 | 52 | 53 | def main(): 54 | apr.parse() 55 | apr.run() 56 | 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /mylib/sites/youtube.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | 4 | from mylib.easy.text import regex_find 5 | 6 | 7 | def find_url_in_text(text: str) -> list: 8 | p = r'/watch\?v=[-\w]+' 9 | return ['https://www.youtube.com' + e for e in regex_find(p, text, dedup=True)] 10 | 11 | -------------------------------------------------------------------------------- /mylib/tools/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | -------------------------------------------------------------------------------- /mylib/uia.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | 4 | import mouse 5 | 6 | 7 | def module_pywinauto(disable_warning: bool = False, coinit: int = 2): 8 | """sys.coinit_flags=2 before import pywinauto 9 | https://github.com/pywinauto/pywinauto/issues/472""" 10 | if disable_warning: 11 | import warnings 12 | warnings.simplefilter('ignore', category=UserWarning) 13 | if coinit is not None: 14 | import sys 15 | sys.coinit_flags = coinit 16 | import pywinauto 17 | return pywinauto 18 | 19 | 20 | def pywinauto_set_focus(pywinauto_object, homing_mouse: bool = True): 21 | if homing_mouse: 22 | original_coord = mouse.get_position() 23 | r = pywinauto_object.set_focus() 24 | mouse.move(*original_coord) 25 | else: 26 | r = pywinauto_object.set_focus() 27 | return r 28 | -------------------------------------------------------------------------------- /mylib/unifont-13.0.04.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/mylib/unifont-13.0.04.ttf -------------------------------------------------------------------------------- /mylib/wrapper/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /mylib/wrapper/aria2c.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from mylib.ext import http_headers 4 | from mylib.easy import * 5 | from mylib.easy import logging 6 | 7 | logger = logging.ez_get_logger(__name__) 8 | 9 | 10 | class Aria2cCLIArgs(CLIArgumentsList): 11 | def __init__(self, *args, **kwargs): 12 | super().__init__() 13 | self.merge_option_nargs = False 14 | self.add('aria2c') 15 | self.add(*args, **kwargs) 16 | 17 | def set_cookies(self, cookies: dict): 18 | return self.set_headers(dict(Cookie=http_headers.make_cookie_str(cookies))) 19 | 20 | def set_headers(self, headers: dict): 21 | return self.add(header=[f'{k}: {v}' for k, v in headers.items()]) 22 | 23 | 24 | def run_aria2c(*link, cookies: dict = None, headers: dict = None, **options): 25 | cli_args = Aria2cCLIArgs() 26 | if cookies: 27 | cli_args.set_cookies(cookies) 28 | if headers: 29 | cli_args.set_headers(headers) 30 | cli_args.add(**options).add(*link) 31 | logger.info(cli_args) 32 | return subprocess.run(cli_args) 33 | -------------------------------------------------------------------------------- /nixscript/cftrace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -vL http://$1/cdn-cgi/trace -------------------------------------------------------------------------------- /nixscript/ssh-forward-smb-clear.sh: -------------------------------------------------------------------------------- 1 | for p in $(ps | awk '/ssh-forward-smb.sh/ {print $1}'); do kill -9 $p; done 2 | -------------------------------------------------------------------------------- /nixscript/ssh-forward-smb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cmd="ssh -N -L 0.0.0.0:139:localhost:139 -L 0.0.0.0:445:localhost:445 $*" 3 | echo $cmd 4 | 5 | exec >>/tmp/ssh-forward-smb.log 6 | exec 2>&1 7 | 8 | loop() { 9 | echo ------------------------ 10 | date -Is 11 | while : 12 | do 13 | $cmd || echo RETRY && sleep 3 14 | done 15 | } 16 | 17 | loop & 18 | sleep 3 19 | -------------------------------------------------------------------------------- /oldezpykit/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 墨焓 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /oldezpykit/README.md: -------------------------------------------------------------------------------- 1 | *under construction...* -------------------------------------------------------------------------------- /oldezpykit/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykit/allinone.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import functools 3 | import getpass 4 | import json 5 | import operator 6 | import pathlib 7 | import platform 8 | import queue 9 | import signal 10 | import sys 11 | import tempfile 12 | import time 13 | import contextlib 14 | 15 | from oldezpykit.wip import call, config 16 | from oldezpykit.builtin import * 17 | from oldezpykit.metautil import * 18 | from oldezpykit.stdlib import * 19 | 20 | ___ref = [pathlib, queue, ezstr, deco_singleton, T, os, call, config, functools, json, operator, contextlib] 21 | ___ref.extend([]) 22 | 23 | sleep = time.sleep 24 | 25 | TEMPDIR = tempfile.gettempdir() 26 | UNAME = platform.uname() 27 | NETWORK_NAME = HOSTNAME = NODE_NAME = platform.node() 28 | USERNAME = getpass.getuser() 29 | OSNAME = platform.system() 30 | 31 | 32 | def ensure_sigint(): 33 | if sys.platform == 'win32': 34 | signal.signal(signal.SIGINT, signal.SIG_DFL) # %ERRORLEVEL% = '-1073741510' 35 | -------------------------------------------------------------------------------- /oldezpykit/builtin/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from ._str import * 3 | from ._list import * 4 | from ._dict import * 5 | -------------------------------------------------------------------------------- /oldezpykit/builtin/_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.metautil import typing as T 3 | 4 | 5 | class ezlist(list, T.Generic[T.T]): 6 | current_index = 0 7 | 8 | def to_dict(self): 9 | d = {} 10 | for i, e in enumerate(self): 11 | d[i] = e 12 | return d 13 | 14 | @property 15 | def current(self): 16 | return self.get(self.current_index) 17 | 18 | @property 19 | def next(self): 20 | self.current_index += 1 21 | total = len(self) 22 | if self.current_index >= total: 23 | self.current_index -= total 24 | return self.current 25 | 26 | @property 27 | def previous(self): 28 | self.current_index -= 1 29 | total = len(self) 30 | if self.current_index <= - total: 31 | self.current_index += total * 2 32 | return self.current 33 | 34 | def append_dedup(self, x, reindex=False): 35 | if x in self: 36 | if reindex: 37 | self.remove_all(x) 38 | self.append(x) 39 | else: 40 | self.append(x) 41 | 42 | def remove_all(self, x): 43 | i = 0 44 | while True: 45 | try: 46 | if self[i] == x: 47 | del self[i] 48 | else: 49 | i += 1 50 | except IndexError: 51 | break 52 | 53 | def get(self, index, default=None): 54 | try: 55 | return self[index] 56 | except IndexError: 57 | return default 58 | 59 | def get_first(self, default=None): 60 | return ezlist.get(self, 0, default=default) 61 | 62 | def get_last(self, default=None): 63 | return ezlist.get(self, -1, default=default) 64 | 65 | @property 66 | def first(self): 67 | return self.get_first() 68 | 69 | @first.setter 70 | def first(self, value): 71 | self[0] = value 72 | 73 | @property 74 | def last(self): 75 | return self.get_last() 76 | 77 | @last.setter 78 | def last(self, value): 79 | self[-1] = value 80 | 81 | def iter_chunks(self: T.Iterable[T.T], n): 82 | r = [] 83 | for e in self: 84 | r.append(e) 85 | if len(r) == n: 86 | yield r 87 | r = [] 88 | yield r 89 | -------------------------------------------------------------------------------- /oldezpykit/const/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykit/metautil/singleton.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from functools import wraps 3 | 4 | 5 | class SingletonMetaClass(type): 6 | _instances = {} 7 | 8 | def __call__(cls, *args, **kwargs): 9 | if cls not in cls._instances: 10 | cls._instances[cls] = super().__call__(*args, **kwargs) 11 | return cls._instances[cls] 12 | 13 | 14 | def deco_singleton(cls): 15 | _instances = {} 16 | 17 | @wraps(cls) 18 | def new(*args, **kwargs): 19 | if cls not in _instances: 20 | _instances[cls] = cls(*args, **kwargs) 21 | return _instances[cls] 22 | 23 | return new 24 | -------------------------------------------------------------------------------- /oldezpykit/metautil/timer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from time import perf_counter, sleep 3 | from contextlib import contextmanager 4 | 5 | 6 | @contextmanager 7 | def ctx_ensure_min_time_duration(t): 8 | t0 = perf_counter() 9 | yield 10 | td = perf_counter() - t0 11 | if td < t: 12 | sleep(t - td) 13 | 14 | 15 | class Stopwatch: 16 | t0: float 17 | 18 | class NotStarted(Exception): 19 | pass 20 | 21 | def __init__(self): 22 | self.results = [] 23 | 24 | def start(self): 25 | self.t0 = perf_counter() 26 | return self 27 | 28 | def _check_t0(self): 29 | try: 30 | self.t0 31 | except AttributeError: 32 | raise self.NotStarted 33 | 34 | def stop(self): 35 | t1 = perf_counter() 36 | self._check_t0() 37 | td = t1 - self.t0 38 | self.results.append(td) 39 | return td 40 | 41 | def clear(self): 42 | del self.t0 43 | return self 44 | -------------------------------------------------------------------------------- /oldezpykit/metautil/typing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from typing import * 3 | from typing import IO, BinaryIO, TextIO, Match, Pattern # necessary! 4 | 5 | ___ref = [IO, BinaryIO, TextIO, Match, Pattern] 6 | 7 | T = TypeVar('T') # Any type. 8 | KT = TypeVar('KT') # Key type. 9 | VT = TypeVar('VT') # Value type. 10 | T_co = TypeVar('T_co', covariant=True) # Any type covariant containers. 11 | V_co = TypeVar('V_co', covariant=True) # Any type covariant containers. 12 | VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers. 13 | T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. 14 | 15 | NoneType = type(None) 16 | EllipsisType = type(Ellipsis) 17 | 18 | Decorator = Callable[[Callable], Callable] 19 | 20 | 21 | class QueueType: 22 | def put(self, *args, **kwargs): 23 | ... 24 | 25 | def get(self, *args, **kwargs): 26 | ... 27 | 28 | 29 | JSONType = Union[str, int, float, bool, None, Mapping[str, 'JSON'], List['JSON']] 30 | -------------------------------------------------------------------------------- /oldezpykit/readme-src.md: -------------------------------------------------------------------------------- 1 | *under construction...* -------------------------------------------------------------------------------- /oldezpykit/setup.py: -------------------------------------------------------------------------------- 1 | from devkit import setup_for_humans as setup 2 | 3 | setup.VERSION = '0.1a' 4 | setup.DEV = True 5 | setup.NAME = 'oldezpykit' 6 | setup.DESCRIPTION = 'A easy, simple lib pack, based on python builtins and standard libraries.' 7 | setup.URL = 'https://github.com/mo-han/mo-han-toolbox/tree/master/ezpykit' 8 | setup.EMAIL = 'zmhungrown@gmail.com' 9 | setup.AUTHOR = 'mo-han' 10 | setup.REQUIRES_PYTHON = '>=3.6.0' 11 | 12 | setup.main() 13 | -------------------------------------------------------------------------------- /oldezpykit/something.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.stdlib import argparse 3 | from oldezpykit.stdlib import base64 4 | from oldezpykit.stdlib import datetime 5 | from oldezpykit.stdlib import glob 6 | from oldezpykit.stdlib import http 7 | from oldezpykit.stdlib import io 8 | from oldezpykit.stdlib import logging 9 | from oldezpykit.stdlib import os 10 | from oldezpykit.stdlib import re 11 | from oldezpykit.stdlib import shutil 12 | from oldezpykit.stdlib import subprocess 13 | from oldezpykit.stdlib import threading 14 | from oldezpykit.stdlib import urllib 15 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/base64.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from base64 import * 3 | from base64 import _bytes_from_decode_data as bytes_from_decode_data 4 | 5 | 6 | def tolerant_b64decode(s, altchars=None, validate=False): 7 | s = bytes_from_decode_data(s) 8 | remainder = len(s) % 4 9 | if remainder: 10 | s += b'=' * (4 - remainder) 11 | return b64decode(s, altchars=altchars, validate=validate) 12 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/datetime.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from datetime import * 3 | import re 4 | 5 | 6 | def datetime_to_delta(time_obj: time): 7 | return datetime.combine(date.min, time_obj) - datetime.min 8 | 9 | 10 | def delta_to_datetime(time_delta: timedelta): 11 | return (datetime.min + time_delta).time() 12 | 13 | 14 | def from_iso_format(s): 15 | yr, mon, day, h, m, s, ss, tzs, tzh, tzm = re.match( 16 | r'(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(\.\d+)?([+-])?(\d{2})?:?(\d{2})?', s).groups() 17 | tzs = int((tzs or '') + '1') 18 | tzh = int(tzh or 0) * tzs 19 | tzm = int(tzm or 0) * tzs 20 | if tzh or tzm: 21 | tz = timezone(timedelta(hours=tzh, minutes=tzm)) 22 | else: 23 | tz = timezone.utc 24 | new: datetime = datetime.min 25 | new = new.replace(year=int(yr), month=int(mon), day=int(day), hour=int(h), minute=int(m), second=int(s), 26 | microsecond=int(float(ss or 0) * 1000000), tzinfo=tz) 27 | return new 28 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/glob.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from glob import * 3 | from urllib.parse import urlparse 4 | from oldezpykit.builtin import ezstr 5 | 6 | 7 | def iglob_url(glob_url, **kwargs): 8 | u = urlparse(glob_url) 9 | if u.scheme != 'glob': 10 | raise ValueError('URL scheme', 'glob', u.scheme) 11 | if u.netloc not in ('', 'localhost'): 12 | raise NotImplementedError('remote glob') 13 | return iglob(ezstr.removeprefix(u.path, '/')) 14 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/http/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/http/cookiejar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | 4 | if sys.version_info < (3, 10): 5 | from oldezpykit.stdlib.http.cookiejar_backport_from_cpython_v_3_10 import * 6 | else: 7 | from http.cookiejar import * 8 | 9 | __ref = MozillaCookieJar 10 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/io/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from io import * 3 | from oldezpykit.metautil import T 4 | 5 | from oldezpykit.stdlib.io.slicefileio import * 6 | from oldezpykit.stdlib.io.virtualfileio import * 7 | 8 | ___ref = IOBase 9 | 10 | 11 | class IOKit: 12 | @staticmethod 13 | def read_exit(io_obj, *args, **kwargs) -> T.Union[str, bytes]: 14 | with io_obj: 15 | return io_obj.read(*args, **kwargs) 16 | 17 | @staticmethod 18 | def write_exit(io_obj, x, *args, **kwargs): 19 | with io_obj: 20 | return io_obj.write(x, *args, **kwargs) 21 | 22 | @staticmethod 23 | def open(fp, *args, open_with=True, **kwargs): 24 | if isinstance(open_with, str): 25 | return open(fp, *args, encoding=open_with, **kwargs) 26 | elif isinstance(open_with, tuple): 27 | mode, enc = open_with 28 | return open(fp, mode, *args, encoding=enc, **kwargs) 29 | elif isinstance(open_with, dict): 30 | return open(fp, *args, **open_with, **kwargs) 31 | else: 32 | return open(fp, *args, **kwargs) 33 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/logging.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from logging import * 3 | from logging import config 4 | 5 | FMT_MESSAGE_ONLY = '%(message)s' 6 | FMT_LEVEL1_MESSAGE_ONLY = '%(levelname).1s: %(message)s' 7 | FMT_LEVEL1_NO_TIME = '%(levelname).1s|%(name)s: %(message)s' 8 | FMT_LEVEL1_DATE_TIME = '%(levelname).1s|%(asctime).19s|%(name)s: %(message)s' 9 | FMT_LEVEL1_DATE_TIME_ZONE = '%(levelname).1s|%(asctime)s|%(name)s: %(message)s' 10 | 11 | DTFMT_ISO = '%Y-%m-%d %H:%M:%S' 12 | DTFMT_ISO_Z = '%Y-%m-%d %H:%M:%S%z' 13 | 14 | 15 | class LoggerKit: 16 | def set_all_handlers_format(self: Logger, fmt=None, date_fmt=None): 17 | if not fmt and not date_fmt and hasattr(self, 'formatter'): 18 | formatter = self.formatter 19 | else: 20 | formatter = Formatter(fmt=fmt, datefmt=date_fmt) 21 | for h in self.handlers: 22 | h.setFormatter(formatter) 23 | return self 24 | 25 | def set_all_handlers_level(self: Logger, level): 26 | self.setLevel(level) 27 | for h in self.handlers: 28 | h.setLevel(level) 29 | return self 30 | 31 | def add_handlers(self: Logger, *handlers): 32 | for h in handlers: 33 | self.addHandler(h) 34 | return self 35 | 36 | 37 | class LoggerMixin: 38 | __logger_name__ = None 39 | 40 | @property 41 | def __logger__(self): 42 | return self.__dict__.setdefault( 43 | '__logger__', getLogger(self.__logger_name__ or f'{self.__module__}.{self.__class__.__name__}')) 44 | 45 | 46 | def dict_config(d: dict, only_new=False, incremental=False): 47 | d = d.copy() 48 | d.update(disable_existing_loggers=only_new, incremental=incremental) 49 | config.dictConfig(d) 50 | 51 | 52 | def init_root(fmt=FMT_LEVEL1_NO_TIME, dtfmt=DTFMT_ISO, **kwargs): 53 | basicConfig(format=fmt, datefmt=dtfmt) 54 | 55 | 56 | def set_root_level(level): 57 | d = dict(version=1, root=dict(level=level)) 58 | dict_config(d, only_new=False, incremental=True) 59 | 60 | 61 | def get_logger(name, suffix=None): 62 | if suffix: 63 | name = f'{name}.{suffix}' 64 | return getLogger(name) 65 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/os/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from os import * 3 | 4 | if name == 'nt': 5 | from oldezpykit.stdlib.os.nt import * 6 | elif name == 'posix': 7 | from oldezpykit.stdlib.os.posix import * 8 | else: 9 | from oldezpykit.stdlib.os.common import * 10 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/os/nt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import time 3 | 4 | from oldezpykit.stdlib.os.common import * 5 | import subprocess 6 | 7 | 8 | class EnVarKit(EnVarKit): 9 | path_sep = ';' 10 | reg_path = r'HKCU\Environment' 11 | use_reg_expand_sz = True 12 | 13 | @classmethod 14 | def save(cls, *args, **kwargs): 15 | for data in [*args, kwargs]: 16 | for k, v in data.items(): 17 | cmd = ['reg', 'add', cls.reg_path, '/f', '/v', cls.valid_key(k), '/d', str(v)] 18 | if cls.use_reg_expand_sz: 19 | cmd += ['/t', 'REG_EXPAND_SZ'] 20 | subprocess.run( 21 | cmd, 22 | stdout=subprocess.DEVNULL 23 | ) 24 | # subprocess.run(['setx', str(k), str(v)]) # very slow 25 | # https://superuser.com/questions/565771/setting-user-environment-variables-is-very-slow 26 | # after setting user/machine scope environment variable 27 | # it calls native SendMessageTimeout function to notify any process about changes in environment 28 | # 1000 milliseconds (1 second) timeout is given to any recipient to process the message 29 | subprocess.run(['setx', 'LAST_SETX_TIMESTAMP', str(time.time())], stdout=subprocess.DEVNULL) 30 | 31 | @classmethod 32 | def get_saved_path_list(cls): 33 | r = subprocess.run( 34 | ['reg', 'query', cls.reg_path, '/v', 'PATH'], 35 | stdout=subprocess.PIPE, universal_newlines=True, 36 | ) 37 | return r.stdout.strip().splitlines()[-1].strip().split(maxsplit=2)[-1].split(cls.path_sep) 38 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/os/posix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from .common import * 3 | 4 | 5 | class EnVarKit(EnVarKit): 6 | path_sep = ':' 7 | 8 | @staticmethod 9 | def save(*args, **kwargs): 10 | envar_fp = f'~/.ezpykit_envar' 11 | profile_fp = f'~/.profile' 12 | the_line = f'test -f {envar_fp} && source {envar_fp}\n' 13 | with open(tilde_path(profile_fp), 'a+') as f: 14 | end = f.tell() 15 | f.seek(0) 16 | lines = f.readlines() 17 | if the_line not in lines: 18 | f.seek(end) 19 | f.write(the_line) 20 | with open(tilde_path(envar_fp), 'a+') as f: 21 | f.seek(0) 22 | envar = {} 23 | for line in f.readlines(): 24 | if not line.startswith('export '): 25 | continue 26 | line = line.split(' #', maxsplit=1)[0].strip() 27 | name, value = [s.strip(' "\'') for s in line.split('=', maxsplit=1)] 28 | envar[name] = value 29 | for data in [*args, kwargs]: 30 | envar.update(data) 31 | new_lines = [f'export "{name}={value}"\n' for name, value in data.items()] 32 | f.truncate() 33 | f.writelines(new_lines) 34 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/shutil/__deprecated__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from shutil import rmtree 3 | 4 | from oldezpykit.stdlib import os 5 | 6 | 7 | class FilesystemOperationError(Exception): 8 | pass 9 | 10 | 11 | class FileToDirectoryError(FilesystemOperationError): 12 | def __init__(self, src, dst): 13 | self.src = src 14 | self.dst = dst 15 | 16 | 17 | class DirectoryToFileError(FilesystemOperationError): 18 | def __init__(self, src, dst): 19 | self.src = src 20 | self.dst = dst 21 | 22 | 23 | class NeitherFileNorDirectoryError(FilesystemOperationError): 24 | pass 25 | 26 | 27 | def dir_is_empty(p): 28 | if not os.path.isdir(p): 29 | raise NotADirectoryError(p) 30 | return not bool(os.listdir(p)) 31 | 32 | 33 | def remove(p): 34 | try: 35 | os.remove(p) 36 | except PermissionError: 37 | try: 38 | rmtree(p) 39 | except NotADirectoryError: 40 | os.remove(p) 41 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/threading.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from threading import * 3 | 4 | 5 | def thread_factory(group=None, name=None, daemon=None): 6 | def new_thread(target, *args, **kwargs): 7 | return Thread(group=group, target=target, name=name, args=args, kwargs=kwargs, daemon=daemon) 8 | 9 | return new_thread 10 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/urllib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.stdlib.urllib import parse 3 | 4 | ___ref = parse 5 | -------------------------------------------------------------------------------- /oldezpykit/stdlib/urllib/parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from urllib.parse import * 3 | 4 | 5 | def tolerant_urlparse(url: str, default_prefix='scheme://'): 6 | if '://' not in url: 7 | url = default_prefix + url 8 | r = urlparse(url) 9 | # if not r.scheme and not r.netloc: 10 | # r = urlparse(default_prefix + url) 11 | return r 12 | 13 | 14 | def replace(named_tuple, *args, **kwargs): 15 | return named_tuple._replace(*args, **kwargs) 16 | -------------------------------------------------------------------------------- /oldezpykit/wip/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykit/wip/contractor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from contextlib import contextmanager 3 | 4 | from oldezpykit.stdlib.logging import LoggerMixin 5 | 6 | 7 | class ContractorError(Exception): 8 | pass 9 | 10 | 11 | class Failure(ContractorError): 12 | errors: list 13 | 14 | def __init__(self, contractor_method=None, *args, **kwargs): 15 | self.errors = [] 16 | super().__init__((contractor_method, args, kwargs), self.errors) 17 | 18 | 19 | class Abortion(ContractorError): 20 | pass 21 | 22 | 23 | class Contractor(LoggerMixin): 24 | def __init__(self, *children: 'Contractor'): 25 | self.children = children 26 | 27 | def _iter_do_self(self, e: Failure, what, *args, **kwargs): 28 | name = f'{self.do.__name__}_{what}' 29 | m = getattr(self, name, None) 30 | if callable(m): 31 | try: 32 | yield m(*args, **kwargs) 33 | except Abortion: 34 | raise 35 | except Exception as error: 36 | e.errors.append(error) 37 | else: 38 | self.__logger__.debug(f'{name} is not a valid method for {self}') 39 | 40 | def _iter_do_children(self, e: Failure, what, *args, **kwargs): 41 | for c in self.children: 42 | try: 43 | yield c.do(what, *args, **kwargs) 44 | except Abortion: 45 | raise 46 | except Exception as error: 47 | e.errors.append(error) 48 | 49 | def do(self, what, *args, **kwargs): 50 | e = Failure(self.do, what, *args, **kwargs) 51 | for r in self._iter_do_self(e, what, *args, **kwargs): 52 | return r 53 | for r in self._iter_do_children(e, what, *args, **kwargs): 54 | return r 55 | raise e 56 | 57 | def get(self, default, what, *args, **kwargs): 58 | try: 59 | return self.do(what, *args, **kwargs) 60 | except (Failure, Abortion): 61 | return default 62 | -------------------------------------------------------------------------------- /oldezpykitext/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykitext/allinone.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import * 3 | from oldezpykitext.stdlib import os 4 | 5 | ___ref = [ezlist, os] 6 | -------------------------------------------------------------------------------- /oldezpykitext/config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.wip.config import * 3 | from oldezpykit.allinone import * 4 | import codecs 5 | 6 | 7 | def is_utf8_encoding(x): 8 | u8 = codecs.lookup('utf-8') 9 | return codecs.lookup(x) == u8 10 | 11 | 12 | class FileConfigMixin: 13 | filepath = None 14 | encoding = 'utf8' 15 | 16 | def _dump_data_to_bytes(self): 17 | raise NotImplementedError(self._dump_data_to_bytes.__name__) 18 | 19 | def save_data(self): 20 | fp = self.filepath 21 | s = self._dump_data_to_bytes() 22 | if not fp: 23 | return s 24 | io.IOKit.write_exit(open(fp, 'wb'), s) 25 | 26 | def exists(self): 27 | fp = self.filepath 28 | if not fp: 29 | return False 30 | return os.path_isfile(fp) 31 | 32 | 33 | class YAMLConfig(DictConfig, FileConfigMixin): 34 | def __init__(self, filepath=None, stream: str = None): 35 | import yaml 36 | s = '{}' 37 | if filepath: 38 | self.filepath = filepath 39 | if self.exists(): 40 | with open(filepath, encoding=self.encoding) as f: 41 | s = f.read() 42 | if stream: 43 | s = stream 44 | self.set_data(yaml.safe_load(s)) 45 | 46 | def _dump_data_to_bytes(self): 47 | import yaml 48 | return yaml.safe_dump(self.data, encoding=self.encoding) 49 | 50 | 51 | class JSONConfigSource(DictConfig, FileConfigMixin): 52 | def __init__(self, filepath=None, string=None): 53 | import json 54 | if filepath: 55 | self.filepath = filepath 56 | if self.exists(): 57 | self.set_data(json.load(filepath, encodings=self.encoding)) 58 | elif string: 59 | self.set_data(json.loads(string)) 60 | else: 61 | raise ValueError('neither filepath nor string') 62 | 63 | def _dump_data_to_bytes(self): 64 | import json 65 | return json.dumps(self.data, indent=4, ensure_ascii=not is_utf8_encoding(self.encoding)).encode(self.encoding) 66 | 67 | 68 | class UnionConfig: 69 | def __init__(self, *config: ConfigABC): 70 | self.config_sequence = config 71 | 72 | def __contains__(self, item): 73 | for config in self.config_sequence: 74 | if item in config: 75 | return True 76 | return False 77 | 78 | def __getitem__(self, item): 79 | for c in self.config_sequence: 80 | if item in c: 81 | return c[item] 82 | raise KeyError(item) 83 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/PIL.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import io 3 | import os 4 | import re 5 | 6 | from oldezpykit.stdlib import base64 7 | from oldezpykit.allinone import ctx_ensure_module 8 | 9 | with ctx_ensure_module('PIL', 'Pillow'): 10 | from PIL import Image, ImageFile, ImageGrab 11 | 12 | __ref = ImageGrab 13 | 14 | 15 | class PillowConfig: 16 | class LoadTruncatedImages: 17 | @staticmethod 18 | def enable(): 19 | ImageFile.LOAD_TRUNCATED_IMAGES = True 20 | 21 | @staticmethod 22 | def disable(): 23 | ImageFile.LOAD_TRUNCATED_IMAGES = False 24 | 25 | LoadTruncatedImages.enable() 26 | 27 | 28 | class ImageWrapper: 29 | image: Image.Image 30 | 31 | def __init__(self, source=None, *args, **kwargs): 32 | if isinstance(source, Image.Image): 33 | self.image = source 34 | elif isinstance(source, os.PathLike): 35 | self.image = Image.open(source, *args, **kwargs) 36 | elif isinstance(source, str): 37 | source = source.strip().strip('"') 38 | if source.startswith('data:image/') and ';base64,' in source: 39 | m = re.match(r'data:image/([+\w]+);(charset=.+;)?base64,(.+)', source) 40 | if not m: 41 | raise ValueError('invalid html base64 image data', source) 42 | fmt = m.group(1) 43 | if fmt == 'svg+xml': 44 | raise NotImplementedError('base64', fmt) 45 | data = m.group(3).strip() 46 | self.open_file_from_bytes(base64.tolerant_b64decode(data)) 47 | else: 48 | self.image = Image.open(source, *args, **kwargs) 49 | elif isinstance(source, (bytes, bytearray, memoryview)): 50 | if os.path.isfile(source): 51 | self.image = Image.open(source, *args, **kwargs) 52 | elif args or kwargs: 53 | self.image = Image.frombytes(*args, data=source, **kwargs) 54 | else: 55 | self.open_file_from_bytes(source) 56 | elif source is None: 57 | pass 58 | else: 59 | raise NotImplementedError() 60 | 61 | def open_file_from_bytes(self, b): 62 | fd = io.BytesIO() 63 | fd.write(b) 64 | fd.seek(0) 65 | self.image = Image.open(fd) 66 | 67 | def save_to_bytes(self, format=None, **params): 68 | with io.BytesIO() as _: 69 | self.image.save(_, format=format, **params) 70 | return _.getvalue() 71 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/backoff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import ctx_ensure_module 3 | 4 | with ctx_ensure_module('backoff'): 5 | from backoff import * 6 | 7 | ___ref = on_exception 8 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/daemoniker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.metautil import ctx_ensure_module 3 | 4 | with ctx_ensure_module('daemoniker'): 5 | from daemoniker import * 6 | 7 | ___ref = [Daemonizer] 8 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/filetype.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import ctx_ensure_module 3 | 4 | with ctx_ensure_module('filetype'): 5 | from filetype import * 6 | 7 | ___ref = guess_mime 8 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/retry.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import ctx_ensure_module 3 | 4 | with ctx_ensure_module('retry'): 5 | from retry import * 6 | 7 | ___ref = retry 8 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/retrying.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import ctx_ensure_module 3 | 4 | with ctx_ensure_module('retrying'): 5 | from retrying import * 6 | 7 | ___ref = retry 8 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/termcolor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import ctx_ensure_module, logging 3 | 4 | __logger__ = logging.get_logger(__name__) 5 | 6 | with ctx_ensure_module('colorama'): 7 | import colorama 8 | 9 | with ctx_ensure_module('termcolor'): 10 | from termcolor import * 11 | 12 | colorama.init() 13 | 14 | ___ref = [cprint] 15 | 16 | 17 | def styled(text, stylesheet=None): 18 | kwargs = {} 19 | ss = stylesheet 20 | if not ss: 21 | return colored(text) 22 | if isinstance(ss, str): 23 | ss = ss.split() 24 | ss = list(ss) 25 | 26 | on_colors = [] 27 | for x in ss: 28 | if x.startswith('on'): 29 | on_colors.append(x) 30 | bg = x[2:].strip('-_') 31 | on_color = f'on_{bg}' 32 | if on_color in HIGHLIGHTS.keys(): 33 | kwargs['on_color'] = on_color 34 | else: 35 | __logger__.warning(f'ignore invalid background color: {bg}') 36 | 37 | attributes = [] 38 | for x in ss: 39 | if x in ATTRIBUTES.keys() and x not in attributes: 40 | attributes.append(x) 41 | kwargs['attrs'] = attributes 42 | 43 | possible_colors = [e for e in ss if e not in attributes and e not in on_colors] 44 | for c in possible_colors: 45 | if c in COLORS.keys(): 46 | kwargs['color'] = c 47 | else: 48 | __logger__.warning(f'ignore invalid color: {c}') 49 | 50 | try: 51 | return colored(text, **kwargs) 52 | except Exception: 53 | __logger__.error(f'{text}, {kwargs}') 54 | raise 55 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/win32clipboard.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.metautil import ctx_ensure_module 3 | 4 | with ctx_ensure_module('win32clipboard', 'pywin32'): 5 | from win32clipboard import * 6 | import win32clipboard 7 | 8 | error = win32clipboard.error 9 | 10 | ___ref = OpenClipboard 11 | -------------------------------------------------------------------------------- /oldezpykitext/extlib/yaml.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import ctx_ensure_module, os 3 | 4 | with ctx_ensure_module('yaml', 'PyYAML'): 5 | from yaml import * 6 | 7 | 8 | class YAMLFile: 9 | default_encoding = 'utf8' 10 | 11 | def __init__(self, fp, auto_create_file=False): 12 | self.filepath = fp 13 | if auto_create_file and not os.path_isfile(fp): 14 | os.touch(fp) 15 | 16 | def load(self, load_method=safe_load, encoding=None, **kwargs): 17 | return load_method(open(self.filepath, encoding=encoding or self.default_encoding), **kwargs) 18 | 19 | def dump(self, data, dump_method=safe_dump, encoding=None, allow_unicode=True, **kwargs): 20 | if issubclass(type(data), dict): 21 | data = dict(data) 22 | return dump_method( 23 | data, open(self.filepath, 'w', encoding=encoding or self.default_encoding), 24 | allow_unicode=allow_unicode, **kwargs 25 | ) 26 | -------------------------------------------------------------------------------- /oldezpykitext/rig/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykitext/rig/aria2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import subprocess 3 | 4 | 5 | class Aria2CommandLineList(subprocess.CommandLineList): 6 | exec = 'aria2c' 7 | 8 | def _kwarg_to_option(self, key, value): 9 | k, v = super()._kwarg_to_option(key, value) 10 | if v is False: 11 | return f'{k}=false', True 12 | return k, v 13 | 14 | def force_sequential(self, enable=True): 15 | return self.add(force_sequence=enable) 16 | 17 | def set_split(self, num=10, size='1M'): 18 | return self.add(s=num, x=num, k=size) 19 | 20 | def load_cookies_file(self, fp): 21 | return self.add(load_cookies=fp) 22 | 23 | def disable_async_dns(self): 24 | return self.add(async_dns=False) 25 | 26 | def set_dir(self, dp): 27 | return self.add(d=dp) 28 | 29 | def set_filename(self, fn): 30 | return self.add(o=fn) 31 | 32 | def disable_auto_rename(self): 33 | return self.add(auto_file_renaming=False) 34 | 35 | def set_quiet(self, enable=True): 36 | return self.add(quiet=enable) 37 | 38 | def set_session(self, session_file, save_interval=None): 39 | self.add(i=session_file, save_session=session_file) 40 | if save_interval: 41 | self.add(save_session_interval=save_interval) 42 | return self 43 | 44 | def enable_rpc(self, port=None, secret=None, listen_all=False, allow_origin_all=False): 45 | self.add(enable_rpc=True) 46 | if port: 47 | self.add(rpc_listen_port=port) 48 | if secret: 49 | self.add(rpc_secret=secret) 50 | if listen_all: 51 | self.add(rpc_listen_all=listen_all) 52 | if allow_origin_all: 53 | self.add(rpc_allow_origin_all=allow_origin_all) 54 | return self 55 | -------------------------------------------------------------------------------- /oldezpykitext/setup.py: -------------------------------------------------------------------------------- 1 | from devkit import setup_for_humans as setup 2 | 3 | setup.VERSION = '0.1a' 4 | setup.DEV = True 5 | setup.NAME = 'oldezpykitext' 6 | setup.DESCRIPTION = 'extend oldezpykit' 7 | setup.URL = 'https://github.com/mo-han/mo-han-toolbox/tree/master/ezpykitext' 8 | setup.EMAIL = 'zmhungrown@gmail.com' 9 | setup.AUTHOR = 'mo-han' 10 | setup.REQUIRES_PYTHON = '>=3.6.0' 11 | 12 | setup.main() 13 | -------------------------------------------------------------------------------- /oldezpykitext/stdlib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykitext/stdlib/os/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.stdlib.os import * 3 | from oldezpykitext.stdlib.os import clipboard 4 | 5 | clpb: clipboard.Clipboard = clipboard.Clipboard() 6 | 7 | __ref = path 8 | -------------------------------------------------------------------------------- /oldezpykitext/stdlib/os/clipboard/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os as _os 3 | 4 | from .common import * 5 | 6 | if _os.name == 'nt': 7 | from .nt import * 8 | elif _os.name == 'posix': 9 | from .posix import * 10 | else: 11 | raise NotImplementedError 12 | -------------------------------------------------------------------------------- /oldezpykitext/stdlib/os/clipboard/common.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from abc import ABC, abstractmethod 3 | from urllib.parse import urlparse 4 | 5 | from oldezpykit.builtin import ensure_str 6 | from oldezpykit.wip.call import SimpleCall 7 | 8 | 9 | class ClipboardError(Exception): 10 | pass 11 | 12 | 13 | class ClipboardURIError(ClipboardError): 14 | pass 15 | 16 | 17 | class ClipboardABC(ABC): 18 | @abstractmethod 19 | def get(self): 20 | pass 21 | 22 | @abstractmethod 23 | def set(self, data): 24 | pass 25 | 26 | @abstractmethod 27 | def clear(self): 28 | pass 29 | 30 | @abstractmethod 31 | def get_path(self, exist_only=True) -> list: 32 | pass 33 | 34 | @abstractmethod 35 | def __enter__(self): 36 | return self 37 | 38 | @abstractmethod 39 | def __exit__(self, exc_type, exc_val, exc_tb): 40 | pass 41 | 42 | def get_lines(self): 43 | return self.get().splitlines() 44 | 45 | def resolve_uri(self, uri: str) -> SimpleCall: 46 | uri = ensure_str(uri) 47 | slash = '/' 48 | calling_map = { 49 | 'get': SimpleCall(self.get), 50 | 'get/path': SimpleCall(self.get_path), 51 | 'get/lines': SimpleCall(self.get_lines), 52 | 'set': SimpleCall(self.set) 53 | } 54 | 55 | pr = urlparse(uri) 56 | if pr.scheme not in ('clip', 'clipboard'): 57 | raise ClipboardURIError('invalid scheme', pr.scheme) 58 | if pr.netloc not in ('', 'localhost'): 59 | raise NotImplementedError('remote clipboard') 60 | if pr.params or pr.query: 61 | raise NotImplementedError('URL parameters & query string') 62 | entry = pr.path.strip(slash) 63 | if entry in calling_map: 64 | return calling_map[entry] 65 | else: 66 | raise NotImplementedError('URI path entry', entry) 67 | 68 | def check_uri(self, uri: str): 69 | uri = ensure_str(uri) 70 | try: 71 | if self.resolve_uri(uri): 72 | return True 73 | except (ClipboardURIError, NotImplementedError): 74 | return False 75 | 76 | def uri_api(self, uri: str, *args, **kwargs): 77 | call = self.resolve_uri(uri) 78 | if args or kwargs: 79 | call.args = args 80 | call.kwargs = kwargs 81 | return call.run() 82 | -------------------------------------------------------------------------------- /oldezpykitext/stdlib/os/clipboard/nt_win32cb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import contextlib 3 | import functools 4 | import random 5 | import time 6 | 7 | from oldezpykitext.extlib.win32clipboard import * 8 | 9 | 10 | @contextlib.contextmanager 11 | def ctx_open_win32clipboard(): 12 | is_opened = False 13 | while not is_opened: 14 | try: 15 | OpenClipboard(0) 16 | except Exception as e: 17 | n = e.winerror 18 | if n == 5: 19 | time.sleep(random.random() / 100) 20 | elif n in (0, 1418): 21 | pass 22 | else: 23 | raise 24 | else: 25 | yield 26 | is_opened = True 27 | finally: 28 | CloseClipboard() 29 | 30 | 31 | def deco_ctx_open_win32clipboard(target): 32 | @functools.wraps(target) 33 | def tgt(*args, **kwargs): 34 | with ctx_open_win32clipboard(): 35 | return target(*args, **kwargs) 36 | 37 | return tgt 38 | -------------------------------------------------------------------------------- /oldezpykitext/stdlib/os/clipboard/posix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | 4 | from oldezpykit.allinone import ctx_ensure_module, deco_singleton 5 | from oldezpykitext.stdlib.os.clipboard.common import ClipboardABC 6 | 7 | with ctx_ensure_module('pyperclip'): 8 | import pyperclip 9 | 10 | 11 | @deco_singleton 12 | class Clipboard(ClipboardABC): 13 | _cb = pyperclip 14 | 15 | def __enter__(self): 16 | return self 17 | 18 | def __exit__(self, exc_type, exc_val, exc_tb): 19 | pass 20 | 21 | def clear(self): 22 | self.set('') 23 | return self 24 | 25 | def set(self, data): 26 | self._cb.copy(data) 27 | 28 | def get(self): 29 | return self._cb.paste() 30 | 31 | def get_path(self, exist_only=True) -> list: 32 | lines = [line.strip() for line in str(self.get()).splitlines()] 33 | return [line for line in lines if os.path.exists(line)] 34 | -------------------------------------------------------------------------------- /oldezpykitext/webclient/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.allinone import ctx_ensure_module 3 | from oldezpykitext.webclient import browser 4 | from oldezpykitext.webclient import cookie 5 | from oldezpykitext.webclient import header 6 | from oldezpykitext.webclient import lxml_html 7 | 8 | with ctx_ensure_module('requests'): 9 | import requests 10 | 11 | ___ref = [requests] 12 | -------------------------------------------------------------------------------- /oldezpykitext/webclient/lxml_html.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.metautil import hasattr_batch, ctx_ensure_module 3 | 4 | with ctx_ensure_module('lxml'): 5 | from lxml.html import * 6 | from lxml.html import HtmlElement, InputElement, TextareaElement 7 | 8 | with ctx_ensure_module('cssselect'): 9 | pass 10 | 11 | __ref = Element, InputElement, TextareaElement 12 | 13 | 14 | def html_etree_from(x, **kwargs) -> HtmlElement: 15 | if hasattr_batch(x, ('url', 'status_code', 'ok', 'request', 'content', 'text')): 16 | x = x.text 17 | if not isinstance(x, (str, bytes)): 18 | raise TypeError('x is not or does not contain string (str, bytes)', type(x)) 19 | return document_fromstring(x, **kwargs) 20 | 21 | 22 | def e_is_null(e): 23 | return e is None 24 | -------------------------------------------------------------------------------- /oldezpykitext/wip/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykitext/wip/rpc/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /oldezpykitext/wip/rpc/common_bak.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import json 3 | import threading 4 | 5 | from functools import lru_cache 6 | 7 | __ref_import = json, threading, lru_cache 8 | 9 | 10 | class RPCError(Exception): 11 | pass 12 | 13 | 14 | def test_hello(x): 15 | print(x) 16 | return x 17 | -------------------------------------------------------------------------------- /oldezpykitext/wip/rpc/nanomsg_bak.py: -------------------------------------------------------------------------------- 1 | import pynng 2 | 3 | from .common_bak import * 4 | 5 | 6 | class NanomsgRPCServer: 7 | @staticmethod 8 | def ping(): 9 | return 'pong' 10 | 11 | @staticmethod 12 | def new_req(name: str, *args, **kwargs): 13 | return json.dumps(dict(name=name, args=args, kwargs=kwargs)).encode() 14 | 15 | def __init__(self, url): 16 | self.url = url 17 | self.__reset__() 18 | 19 | def __reset__(self): 20 | self._running = False 21 | self._rep_socket = pynng.Rep0() 22 | 23 | def __start__(self): 24 | if not self._running: 25 | t = threading.Thread(target=self.__run__, daemon=True) 26 | t.start() 27 | else: 28 | raise RPCError('thread still running, or stopped incorrectly') 29 | 30 | def __stop__(self): 31 | self.__send_result__(True) 32 | self._rep_socket.close() 33 | self.__reset__() 34 | 35 | def __run__(self): 36 | self._rep_socket.listen(self.url) 37 | self._running = True 38 | print('running') 39 | while self._running: 40 | try: 41 | q = self.__receive_request__() 42 | name = q['name'] 43 | target = self.__find_call_target__(name) 44 | args = q['args'] 45 | kwargs = q['kwargs'] 46 | r = target(*args, **kwargs) 47 | try: 48 | self.__send_result__(r) 49 | except pynng.BadState: 50 | if name != 'stop': 51 | raise 52 | except Exception as e: 53 | self.__send_error__(e) 54 | 55 | @lru_cache() 56 | def __find_call_target__(self, name): 57 | try: 58 | return getattr(self, name) 59 | except AttributeError: 60 | try: 61 | return globals()[name] 62 | except KeyError: 63 | raise NameError(name) 64 | 65 | def __send_dict__(self, d): 66 | try: 67 | s = json.dumps(d, ensure_ascii=False).encode() 68 | except Exception as e: 69 | self.__send_error__(e) 70 | else: 71 | self._rep_socket.send(s) 72 | 73 | def __receive_request__(self): 74 | return json.loads(self._rep_socket.recv()) 75 | 76 | def __send_error__(self, e: Exception): 77 | d = dict(ok=False, error=f'Python Exception: {type(e).__name__}: {e}') 78 | self.__send_dict__(d) 79 | 80 | def __send_result__(self, json_obj): 81 | d = dict(ok=True, result=json_obj) 82 | self.__send_dict__(d) 83 | -------------------------------------------------------------------------------- /oldezpykitext/wip/rpc/nng.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import pynng 3 | 4 | -------------------------------------------------------------------------------- /oldezpykitext/yaml.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from oldezpykit.stdlib.io import IOKit 3 | 4 | try: 5 | import yaml 6 | except ModuleNotFoundError: 7 | import os 8 | 9 | os.system('pip install pyyaml') 10 | import yaml 11 | 12 | DEFAULT_ENCODING = 'UTF-8-SIG' 13 | 14 | 15 | class EzYAML: 16 | filename = None 17 | documents = None 18 | encoding = DEFAULT_ENCODING 19 | 20 | def set_file(self, fp, encoding=DEFAULT_ENCODING): 21 | self.filename = fp 22 | self.encoding = encoding 23 | return self 24 | 25 | def set_doc(self, documents): 26 | self.documents = documents 27 | return self 28 | 29 | def load(self, stream=None, as_list=True): 30 | stream = stream or IOKit.read_exit(open(self.filename, encoding=self.encoding)) 31 | self.documents = yaml.safe_load_all(stream) 32 | if as_list: 33 | self.documents = list(self.documents) 34 | return self 35 | 36 | def dump(self, **kwargs): 37 | return yaml.safe_dump_all(self.documents, **kwargs) 38 | 39 | def save(self, encoding=None, allow_unicode=True, **kwargs): 40 | self.save_as(self.filename, encoding=encoding, allow_unicode=allow_unicode, **kwargs) 41 | return self 42 | 43 | def save_as(self, fp, encoding=None, allow_unicode=True, **kwargs): 44 | with open(fp, 'wb') as f: 45 | yaml.safe_dump_all( 46 | self.documents, 47 | f, 48 | encoding=encoding or self.encoding, 49 | allow_unicode=allow_unicode, 50 | **kwargs 51 | ) 52 | return self 53 | -------------------------------------------------------------------------------- /requirements/_async_io.txt: -------------------------------------------------------------------------------- 1 | pyuv #MIT #posix #mswin #last-update:2017 -------------------------------------------------------------------------------- /requirements/_cli.txt: -------------------------------------------------------------------------------- 1 | colorama #BSD 2 | colored #MIT #console #color #style #depended-by:gooey 3 | colour #BSD-3 4 | cmd2 #MIT 5 | terminaltables #MIT #console #draw-table 6 | prettytable #BSD-3-clause #console #draw-table 7 | tabulate #MIT #console #draw-table #favorite 8 | py-getch #MIT #getch #console 9 | readkeys #EUPL-1.2 #getch #console #getkey #Python>=3.8 10 | pytermgui #MIT #console #TUI 11 | asciimatics #Apache-2.0 #console #TUI 12 | windows-curses #PSF2 #console #curses #ms-windows -------------------------------------------------------------------------------- /requirements/_decorator.txt: -------------------------------------------------------------------------------- 1 | decorator #BSD-2-Clause 2 | wrapt #BSD 3 | pydecor #MIT -------------------------------------------------------------------------------- /requirements/_device_input.txt: -------------------------------------------------------------------------------- 1 | pynput #LGPLv3 #keyboard #mouse #os-mac #os-windows #os-posix -------------------------------------------------------------------------------- /requirements/_ecad.txt: -------------------------------------------------------------------------------- 1 | myhdl #LGPL-2.1 #HDL -------------------------------------------------------------------------------- /requirements/_enthought_tool_suite.txt: -------------------------------------------------------------------------------- 1 | enable #BSD 2 | etsdemo #BSD 3 | pyface #BSD 4 | pyside2 #LGPL 5 | qt-binder #BSD 6 | traitsui #BSD -------------------------------------------------------------------------------- /requirements/_graphic.txt: -------------------------------------------------------------------------------- 1 | gizeh #MIT #graphic #2D #cairo 2 | pyqtgraph #MIT #graphic #GUI #2D #3D #Qt #OpenGL 3 | PythonQwt #LGPLv2 #graphic #GUI #Qt #plot #2D -------------------------------------------------------------------------------- /requirements/_html_parse.txt: -------------------------------------------------------------------------------- 1 | cssselect #BSD #CSS3 -------------------------------------------------------------------------------- /requirements/_i18n.txt: -------------------------------------------------------------------------------- 1 | python-i18n[YAML] #MIT 2 | language-tags #MIT 3 | langcodes #MIT #BCP-47 4 | langtags #GPL-v3 #BCP-47 5 | bcp47 #MIT #BCP-47 -------------------------------------------------------------------------------- /requirements/_image.txt: -------------------------------------------------------------------------------- 1 | imutils #MIT #image-process #helper -------------------------------------------------------------------------------- /requirements/_json_query.txt: -------------------------------------------------------------------------------- 1 | jsonpath-rw #Apache2.0 #JSONPath 2 | jsonpath-ng #Apache2.0 #JSONPath #fork-from:python-jsonpath-rw 3 | jmespath #MIT #JSONPath 4 | objectpath #MIT #JSONPath -------------------------------------------------------------------------------- /requirements/_macos_enhance.txt: -------------------------------------------------------------------------------- 1 | readline #GPL #gnu-readline #console -------------------------------------------------------------------------------- /requirements/_mswin_enhance.txt: -------------------------------------------------------------------------------- 1 | pyreadline #BSD #gnu-readline #console -------------------------------------------------------------------------------- /requirements/_new_stdlib.txt: -------------------------------------------------------------------------------- 1 | dataclasses #Apache -------------------------------------------------------------------------------- /requirements/_ocr.txt: -------------------------------------------------------------------------------- 1 | pytesseract #Apache-2.0 #ocr #tesseract #cli-wrapper 2 | paddleocr #Apache-2.0 #ocr #chinese #baidu #depend-on:PaddlePaddle #cpu-perf:slow #gpu 3 | paddlepaddle #Apache #deep-learning #baidu #depended-by:PaddleOCR 4 | tesserocr #MIT #ocr #tesseract #cython #c-api 5 | cnocr #Apache-2.0 #chinese #very-fast-for-small-size-image #slow-for-medium-or-large-size-image 6 | easyocr #Apache-2.0 #very-slow:seconds #ocr #multi-lang 7 | ABBYY #MIT #ocr #cloud #web-api 8 | -------------------------------------------------------------------------------- /requirements/_plot_data.txt: -------------------------------------------------------------------------------- 1 | pybleau #MIT #depend-on:ets,dash,... -------------------------------------------------------------------------------- /requirements/_pypi.txt: -------------------------------------------------------------------------------- 1 | Basket 2 | minirepo #MIT 3 | pipwin #BSD 4 | pip2pi #BSD -------------------------------------------------------------------------------- /requirements/_toolkit_for_devel.txt: -------------------------------------------------------------------------------- 1 | #pip-autoremove 2 | #ptpython 3 | cython>=3a 4 | ipython 5 | objbrowser 6 | perfplot 7 | pip-chill 8 | pipdeptree 9 | pipenv 10 | pyinstaller 11 | httpie #BSD-3-Clause #web #test #debug -------------------------------------------------------------------------------- /requirements/_webp.txt: -------------------------------------------------------------------------------- 1 | webptools #MIT #binary-executable -------------------------------------------------------------------------------- /requirements/common.txt: -------------------------------------------------------------------------------- 1 | #bitmath #MIT #filesize #unit 2 | #conda #BSD 3 | #dhash #MIT 4 | QtPy #MIT 5 | auxlib #Apache #BSD 6 | datefinder #MIT 7 | dateparser #BSD-3 8 | dill #BSD-3 9 | disjoint-set #MIT 10 | ffmpeg-python 11 | filetype #MIT 12 | fs #MIT # PyFilesystem2 13 | gallery-dl 14 | humanize #MIT 15 | imagehash #BSD 16 | inflection #MIT 17 | keyboard 18 | lxml #BSD 19 | more-itertools #MIT 20 | mouse 21 | ndrop 22 | opencv-python 23 | pillow 24 | pinyin #BSD 25 | psutil 26 | pure-python-adb 27 | pyautogui # pyautogui==0.9.39 28 | pymediainfo #MIT 29 | pynput #LGPLv3 30 | pyperclip 31 | pypinyin #MIT 32 | pyreadline 33 | pyserial 34 | python-dateutil #Apache #BSD 35 | python-i18n #MIT 36 | pyyaml #MIT 37 | regex #Apache 38 | requests 39 | requests-html #MIT #python>=3.6 40 | selenium<3.8 # phantomjs 41 | send2trash 42 | si-prefix #BSD-3 43 | splinter<0.8 # phantomjs 44 | sqlitedict 45 | typer #MIT 46 | uiautomator2 47 | you-get 48 | youtube-dl -------------------------------------------------------------------------------- /requirements/discard.txt: -------------------------------------------------------------------------------- 1 | splinter[zope.testbrowser] # zope.testbrowser with splinter not support py3 2 | bs4 3 | -------------------------------------------------------------------------------- /requirements/gui.txt: -------------------------------------------------------------------------------- 1 | dearpygui #imgui #MIT 2 | enaml #BSD 3 | enaml-web #MIT 4 | gooey #need:wxpython:https://extras.wxpython.org/wxPython4/extras/ 5 | pysimpleguiqt 6 | qt-binder #BSD 7 | -------------------------------------------------------------------------------- /requirements/linux.txt: -------------------------------------------------------------------------------- 1 | -r common.txt 2 | pywinauto<0.6.7 3 | -------------------------------------------------------------------------------- /requirements/mswin.txt: -------------------------------------------------------------------------------- 1 | -r common.txt 2 | pyclean #GPLv3 3 | pywin32 4 | pywinauto 5 | winshell 6 | -------------------------------------------------------------------------------- /requirements/note.txt: -------------------------------------------------------------------------------- 1 | install wxpython on linux: 2 | https://extras.wxpython.org/wxPython4/extras/linux/ 3 | https://stackoverflow.com/questions/61390486/wxpython-installation-failure 4 | https://askubuntu.com/questions/1073145/how-to-install-wxpython-4-ubuntu-18-04/1073183#1073183 5 | -------------------------------------------------------------------------------- /requirements/telegram.txt: -------------------------------------------------------------------------------- 1 | #telethon 2 | python-telegram-bot #LGPLv3 3 | telegraph #MIT -------------------------------------------------------------------------------- /requirements/wishlist.txt: -------------------------------------------------------------------------------- 1 | asciimatics #Apache2 2 | av # PyAV 3 | fs # PyFilesystem 4 | picotui #MIT 5 | pyyaml #YAML #MIT 6 | selenium-wire #MIT 7 | termgraph #MIT 8 | fire #Apache2.0 #google #CLI #argparse 9 | argh #LGPL #CLI #argparse #wrapper 10 | plac #BSD #CLI #argparse 11 | commando #MIT #CLI #argparse #wrapper #shallow -------------------------------------------------------------------------------- /scpi_shell/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 -------------------------------------------------------------------------------- /scpi_shell/cli.onefile.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | block_cipher = None 4 | 5 | 6 | a = Analysis(['cli.py'], 7 | pathex=['.'], 8 | binaries=[], 9 | datas=[], 10 | hiddenimports=[], 11 | hookspath=[], 12 | runtime_hooks=[], 13 | excludes=[], 14 | win_no_prefer_redirects=False, 15 | win_private_assemblies=False, 16 | cipher=block_cipher, 17 | noarchive=False) 18 | pyz = PYZ(a.pure, a.zipped_data, 19 | cipher=block_cipher) 20 | exe = EXE(pyz, 21 | a.scripts, 22 | a.binaries, 23 | a.zipfiles, 24 | a.datas, 25 | [], 26 | name='scpicli', 27 | debug=False, 28 | bootloader_ignore_signals=False, 29 | strip=False, 30 | icon='icon.ico', 31 | upx=True, 32 | upx_exclude=['vcruntime140.dll'], 33 | runtime_tmpdir=None, 34 | console=True ) 35 | -------------------------------------------------------------------------------- /scpi_shell/cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding=utf8 3 | import argparse 4 | 5 | import core 6 | from core import win32_ctrl_c 7 | 8 | try: 9 | from extra import SCPIShellCustom as SCPIShell 10 | except ImportError as e: 11 | from core import SCPIShell 12 | 13 | 14 | def run_cli_app(): 15 | parser = argparse.ArgumentParser(description=SCPIShell.intro, formatter_class=argparse.RawDescriptionHelpFormatter) 16 | parser.add_argument('-r', '--remote', 17 | help='address or port or link of remote instrument') 18 | parser.add_argument('-t', '--type', default='VXI-11', 19 | help=f'connection type: vxi11, serial, {core.S_YOKOGAWA_ETHERNET_LEGACY}') 20 | parser.add_argument('-o', '--timeout', type=float, 21 | help='connection timeout') 22 | parser.add_argument('-c', '--command', nargs='+', metavar='arg', 23 | help='commands to be run once') 24 | parser.add_argument('-l', '--tcp-relay', metavar='[listen_addr]:', 25 | help='start a tcp relay server listening on the given address') 26 | parser.add_argument('--list', action='store_true') 27 | args = parser.parse_args() 28 | 29 | remote = args.remote 30 | conn_type = args.type 31 | timeout = args.timeout 32 | command_list = args.command 33 | relay_addr = args.tcp_relay 34 | list = args.list 35 | win32_ctrl_c() 36 | 37 | if remote: 38 | shell = SCPIShell(address=remote, conn_type=conn_type, timeout=timeout) 39 | if command_list: 40 | shell.onecmd(' '.join(command_list)) 41 | elif relay_addr: 42 | shell.do_tcprelay(relay_addr) 43 | else: 44 | shell.cmdloop() 45 | elif list: 46 | SCPIShell().do_list() 47 | elif timeout or command_list: 48 | parser.error('--type, --timeout or --command has no effect when --remote is missing') 49 | elif relay_addr: 50 | shell = SCPIShell() 51 | shell.do_tcprelay(relay_addr) 52 | else: 53 | shell = SCPIShell() 54 | shell.cmdloop() 55 | 56 | 57 | if __name__ == '__main__': 58 | run_cli_app() 59 | -------------------------------------------------------------------------------- /scpi_shell/cli.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | block_cipher = None 4 | 5 | 6 | a = Analysis(['cli.py'], 7 | pathex=['.'], 8 | binaries=[], 9 | datas=[], 10 | hiddenimports=['pyreadline'], 11 | hookspath=[], 12 | runtime_hooks=[], 13 | excludes=[], 14 | win_no_prefer_redirects=False, 15 | win_private_assemblies=False, 16 | cipher=block_cipher, 17 | noarchive=False) 18 | pyz = PYZ(a.pure, a.zipped_data, 19 | cipher=block_cipher) 20 | exe = EXE(pyz, 21 | a.scripts, 22 | [], 23 | exclude_binaries=True, 24 | name='scpicli', 25 | debug=False, 26 | bootloader_ignore_signals=False, 27 | strip=False, 28 | icon='icon.ico', 29 | upx=True, 30 | console=True ) 31 | coll = COLLECT(exe, 32 | a.binaries, 33 | a.zipfiles, 34 | a.datas, 35 | strip=False, 36 | upx=True, 37 | upx_exclude=['vcruntime140.dll'], 38 | name='scpicli') 39 | -------------------------------------------------------------------------------- /scpi_shell/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/scpi_shell/icon.ico -------------------------------------------------------------------------------- /scpi_shell/icon.ico.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/scpi_shell/icon.ico.bak -------------------------------------------------------------------------------- /scpi_shell/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/scpi_shell/icon.png -------------------------------------------------------------------------------- /scpi_shell/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 24 | -------------------------------------------------------------------------------- /scpi_shell/requirements.txt: -------------------------------------------------------------------------------- 1 | pyreadline 2 | python-vxi11 3 | pyinstaller<4 -------------------------------------------------------------------------------- /the_new_protoplasm/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /the_new_protoplasm/base64.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import base64 3 | import binascii 4 | import logging 5 | 6 | from . import func 7 | 8 | __logger__ = logging.getLogger('.'.join(func.get_parent_folder_name_and_basename(__file__))) 9 | 10 | 11 | def decode_base64_string_to_bytes(s: str): 12 | if '-' in s: 13 | return b''.join(decode_base64_string_to_bytes(i) for i in s.split('-')) 14 | try: 15 | return base64.b64decode(s) 16 | except binascii.Error as e: 17 | if e.args == ('Incorrect padding',): 18 | __logger__.debug(f'{e}: {s}') 19 | return decode_base64_string_to_bytes(s + '=') 20 | else: 21 | __logger__.debug(f'class: {e.__class__.__name__}') 22 | __logger__.debug(f'args: {e.args}') 23 | raise e 24 | -------------------------------------------------------------------------------- /the_new_protoplasm/func.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def get_parent_folder_name_and_basename(the_path): 5 | the_path = os.path.abspath(the_path) 6 | return os.path.basename(os.path.dirname(the_path)), os.path.basename(the_path) -------------------------------------------------------------------------------- /the_new_protoplasm/the_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /websites/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | -------------------------------------------------------------------------------- /websites/bilibili/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from websites.bilibili import webapi 3 | -------------------------------------------------------------------------------- /whl/tesserocr-2.4.0-cp36-cp36m-win32.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/whl/tesserocr-2.4.0-cp36-cp36m-win32.whl -------------------------------------------------------------------------------- /whl/tesserocr-2.4.0-cp36-cp36m-win_amd64.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/whl/tesserocr-2.4.0-cp36-cp36m-win_amd64.whl -------------------------------------------------------------------------------- /whl/tesserocr-2.4.0-cp37-cp37m-win32.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/whl/tesserocr-2.4.0-cp37-cp37m-win32.whl -------------------------------------------------------------------------------- /whl/tesserocr-2.4.0-cp37-cp37m-win_amd64.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/whl/tesserocr-2.4.0-cp37-cp37m-win_amd64.whl -------------------------------------------------------------------------------- /whl_gohlke/enable-4.8.1-cp36-cp36m-win32.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/whl_gohlke/enable-4.8.1-cp36-cp36m-win32.whl -------------------------------------------------------------------------------- /whl_gohlke/enable-4.8.1-cp36-cp36m-win_amd64.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mo-han/mo-han-toolbox/42e556a23b682441e2d826d0250fd511c8cbc2df/whl_gohlke/enable-4.8.1-cp36-cp36m-win_amd64.whl --------------------------------------------------------------------------------