├── #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 |
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
--------------------------------------------------------------------------------