Merge branch 'fix_kill_process'
- kill process automatic with interactive question to protect system crash - fix erplibre installation python - poetry update - fix markdown translation
This commit is contained in:
commit
cbe4288b87
9 changed files with 854 additions and 747 deletions
18
doc/AGENT.INFO.base.md
Normal file
18
doc/AGENT.INFO.base.md
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!---------------------------->
|
||||||
|
<!-- multilingual suffix: en, fr -->
|
||||||
|
<!-- no suffix: en -->
|
||||||
|
<!---------------------------->
|
||||||
|
|
||||||
|
<!-- [en] -->
|
||||||
|
# Agent GPT information
|
||||||
|
|
||||||
|
## How to build
|
||||||
|
|
||||||
|
Source for Best practices and workflows to use with an AI agent on any project https://gist.github.com/CodeLeom/519e930f70895924f0d2b9862b95a10b
|
||||||
|
|
||||||
|
<!-- [fr] -->
|
||||||
|
# Information Agent GPT
|
||||||
|
|
||||||
|
## Comment construire
|
||||||
|
|
||||||
|
Source des meilleures pratiques et flux de travail pour utiliser un agent IA sur n'importe quel projet https://gist.github.com/CodeLeom/519e930f70895924f0d2b9862b95a10b
|
||||||
6
doc/AGENT.INFO.fr.md
Normal file
6
doc/AGENT.INFO.fr.md
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
# Information Agent GPT
|
||||||
|
|
||||||
|
## Comment construire
|
||||||
|
|
||||||
|
Source des meilleures pratiques et flux de travail pour utiliser un agent IA sur n'importe quel projet https://gist.github.com/CodeLeom/519e930f70895924f0d2b9862b95a10b
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
# Agent GPT information
|
# Agent GPT information
|
||||||
|
|
||||||
## How to build
|
## How to build
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ openupgradelib
|
||||||
unidiff
|
unidiff
|
||||||
colorama
|
colorama
|
||||||
wheel
|
wheel
|
||||||
cloudflare
|
|
||||||
selenium
|
selenium
|
||||||
uvloop
|
uvloop
|
||||||
python-randomword-fr
|
python-randomword-fr
|
||||||
|
|
@ -32,6 +31,8 @@ cloudflare
|
||||||
psutil
|
psutil
|
||||||
mmg
|
mmg
|
||||||
pip-audit
|
pip-audit
|
||||||
|
tldextract
|
||||||
|
PyYAML
|
||||||
|
|
||||||
# For mobile
|
# For mobile
|
||||||
pillow
|
pillow
|
||||||
|
|
@ -44,3 +45,7 @@ git+https://github.com/psf/black.git@24.8.0
|
||||||
pre-commit
|
pre-commit
|
||||||
|
|
||||||
odoo-module-migrator
|
odoo-module-migrator
|
||||||
|
|
||||||
|
# Ignore because need installation system
|
||||||
|
# pymysql
|
||||||
|
# Don't forget to install selenium script/selenium/requirements.txt
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -22,18 +22,18 @@ python = ">=3.12.10,<3.13"
|
||||||
a2wsgi = ">=1.10.6"
|
a2wsgi = ">=1.10.6"
|
||||||
aiobotocore = "3.1.2"
|
aiobotocore = "3.1.2"
|
||||||
ansi2html = "^1.9.2"
|
ansi2html = "^1.9.2"
|
||||||
apispec = "^6.9.0"
|
apispec = "^6.10.0"
|
||||||
asn1crypto = "1.5.1"
|
asn1crypto = "1.5.1"
|
||||||
astor = "^0.8.1"
|
astor = "^0.8.1"
|
||||||
avalara = "^26.2.0"
|
avalara = "^26.2.0"
|
||||||
babel = "2.10.3"
|
babel = "2.10.3"
|
||||||
bandit = "^1.9.3"
|
bandit = "^1.9.4"
|
||||||
base64io = "^1.0.3"
|
base64io = "^1.0.3"
|
||||||
beautifulsoup4 = "4.13.5"
|
beautifulsoup4 = "4.13.5"
|
||||||
bokeh = "3.6.3"
|
bokeh = "3.6.3"
|
||||||
boto3 = "1.42.42"
|
boto3 = "1.42.42"
|
||||||
botocore = "1.42.42"
|
botocore = "1.42.42"
|
||||||
cachetools = "^7.0.1"
|
cachetools = "^7.0.3"
|
||||||
cairosvg = "^2.8.2"
|
cairosvg = "^2.8.2"
|
||||||
caldav = "1.3.9"
|
caldav = "1.3.9"
|
||||||
cbor2 = "5.6.2"
|
cbor2 = "5.6.2"
|
||||||
|
|
@ -71,7 +71,7 @@ gitpython = "^3.1.46"
|
||||||
giturlparse = "0.12.0"
|
giturlparse = "0.12.0"
|
||||||
googletrans-py = "4.0.0"
|
googletrans-py = "4.0.0"
|
||||||
greenlet = "3.0.3"
|
greenlet = "3.0.3"
|
||||||
httpagentparser = "^1.9.5"
|
httpagentparser = "^1.9.9"
|
||||||
icalendar = "5.0.13"
|
icalendar = "5.0.13"
|
||||||
idna = "3.6"
|
idna = "3.6"
|
||||||
img2pdf = "^0.6.3"
|
img2pdf = "^0.6.3"
|
||||||
|
|
@ -81,7 +81,7 @@ js2py = "^0.74"
|
||||||
libsass = "0.22.0"
|
libsass = "0.22.0"
|
||||||
lottie = "^0.7.2"
|
lottie = "^0.7.2"
|
||||||
lxml = "5.2.1"
|
lxml = "5.2.1"
|
||||||
lxml-html-clean = "^0.4.3"
|
lxml-html-clean = "^0.4.4"
|
||||||
mako = "^1.3.10"
|
mako = "^1.3.10"
|
||||||
markdown2 = "2.5.1"
|
markdown2 = "2.5.1"
|
||||||
markdownify = "0.13.1"
|
markdownify = "0.13.1"
|
||||||
|
|
@ -101,7 +101,7 @@ oauthlib = "^3.3.1"
|
||||||
odoorpc = "^0.10.1"
|
odoorpc = "^0.10.1"
|
||||||
ofxparse = "0.21"
|
ofxparse = "0.21"
|
||||||
ollama = "^0.6.1"
|
ollama = "^0.6.1"
|
||||||
openai = "^2.21.0"
|
openai = "^2.26.0"
|
||||||
openpyxl = "3.1.2"
|
openpyxl = "3.1.2"
|
||||||
openupgradelib = "^3.12.0"
|
openupgradelib = "^3.12.0"
|
||||||
openwebui-client = ">=0.3.0"
|
openwebui-client = ">=0.3.0"
|
||||||
|
|
@ -114,10 +114,10 @@ pathspec = "^1.0.4"
|
||||||
pdf2image = "^1.17.0"
|
pdf2image = "^1.17.0"
|
||||||
pdfminer-six = "20260107"
|
pdfminer-six = "20260107"
|
||||||
pexpect = "^4.9.0"
|
pexpect = "^4.9.0"
|
||||||
phonenumbers = "^9.0.24"
|
phonenumbers = "^9.0.25"
|
||||||
pillow = "12.1.1"
|
pillow = "12.1.1"
|
||||||
plaid-python = "^38.1.0"
|
plaid-python = "^38.4.0"
|
||||||
plotly = "^6.5.2"
|
plotly = "^6.6.0"
|
||||||
polib = "1.1.1"
|
polib = "1.1.1"
|
||||||
pre-commit = "^4.5.1"
|
pre-commit = "^4.5.1"
|
||||||
premailer = "^3.10.0"
|
premailer = "^3.10.0"
|
||||||
|
|
@ -127,7 +127,7 @@ psycopg2 = "2.9.9"
|
||||||
py3dns = "^4.0.2"
|
py3dns = "^4.0.2"
|
||||||
py3o-formats = "^0.3"
|
py3o-formats = "^0.3"
|
||||||
py3o-template = "^0.10.0"
|
py3o-template = "^0.10.0"
|
||||||
pycountry = "^24.6.1"
|
pycountry = "^26.2.16"
|
||||||
pycups = "^2.0.4"
|
pycups = "^2.0.4"
|
||||||
pydantic = ">=2.0.0"
|
pydantic = ">=2.0.0"
|
||||||
pydevd-odoo = "^1.2.2"
|
pydevd-odoo = "^1.2.2"
|
||||||
|
|
@ -135,8 +135,8 @@ pyftpdlib = "^2.2.0"
|
||||||
pygithub = "^2.8.1"
|
pygithub = "^2.8.1"
|
||||||
pyjsparser = "^2.7.1"
|
pyjsparser = "^2.7.1"
|
||||||
pyjwt = "^2.11.0"
|
pyjwt = "^2.11.0"
|
||||||
pylint = "^4.0.4"
|
pylint = "^4.0.5"
|
||||||
pylint-odoo = "^10.0.0"
|
pylint-odoo = "^10.0.1"
|
||||||
pymupdf = "^1.27.1"
|
pymupdf = "^1.27.1"
|
||||||
pyncclient = "^0.7"
|
pyncclient = "^0.7"
|
||||||
pyopenssl = "25.3.0"
|
pyopenssl = "25.3.0"
|
||||||
|
|
@ -159,7 +159,7 @@ python-resize-image = "^1.1.20"
|
||||||
python-slugify = "^8.0.4"
|
python-slugify = "^8.0.4"
|
||||||
python-stdnum = "1.19"
|
python-stdnum = "1.19"
|
||||||
python-telegram-bot = "^22.6"
|
python-telegram-bot = "^22.6"
|
||||||
pytz = "^2025.2"
|
pytz = "^2026.1.post1"
|
||||||
pyusb = "1.2.1"
|
pyusb = "1.2.1"
|
||||||
pyyaml = "^6.0.3"
|
pyyaml = "^6.0.3"
|
||||||
pyzbar = "^0.1.9"
|
pyzbar = "^0.1.9"
|
||||||
|
|
@ -167,13 +167,13 @@ pyzk = "^0.9"
|
||||||
qifparse = "^0.5"
|
qifparse = "^0.5"
|
||||||
qrcode = "7.4.2"
|
qrcode = "7.4.2"
|
||||||
radon = "^6.0.1"
|
radon = "^6.0.1"
|
||||||
redis = "^7.1.1"
|
redis = "^7.3.0"
|
||||||
regex = "^2026.1.15"
|
regex = "^2026.2.28"
|
||||||
reportlab = "4.1.0"
|
reportlab = "4.1.0"
|
||||||
requests = "2.31.0"
|
requests = ">=2.31.0"
|
||||||
requests-oauthlib = "^2.0.0"
|
requests-oauthlib = "^2.0.0"
|
||||||
requests-toolbelt = "^1.0.0"
|
requests-toolbelt = "^1.0.0"
|
||||||
responses = "^0.25.8"
|
responses = "^0.26.0"
|
||||||
rjsmin = "1.2.0"
|
rjsmin = "1.2.0"
|
||||||
roulier = "^1.1.1"
|
roulier = "^1.1.1"
|
||||||
s3fs = "2026.2.0"
|
s3fs = "2026.2.0"
|
||||||
|
|
@ -181,11 +181,11 @@ schwifty = "2024.4.0"
|
||||||
sentry-sdk = ">=2.0.0,<=2.22.0"
|
sentry-sdk = ">=2.0.0,<=2.22.0"
|
||||||
setuptools = "80.10.2"
|
setuptools = "80.10.2"
|
||||||
shapely = "^2.1.2"
|
shapely = "^2.1.2"
|
||||||
sqlalchemy = "^2.0.46"
|
sqlalchemy = "^2.0.48"
|
||||||
statsd = "^4.0.1"
|
statsd = "^4.0.1"
|
||||||
tldextract = "^5.3.1"
|
tldextract = "^5.3.1"
|
||||||
tweepy = "^4.16.0"
|
tweepy = "^4.16.0"
|
||||||
twilio = "^9.10.1"
|
twilio = "^9.10.2"
|
||||||
typing-extensions = "^4.15.0"
|
typing-extensions = "^4.15.0"
|
||||||
ujson = "^5.11.0"
|
ujson = "^5.11.0"
|
||||||
unidecode = "^1.4.0"
|
unidecode = "^1.4.0"
|
||||||
|
|
@ -217,7 +217,7 @@ rev = "replace-pyopenssl"
|
||||||
|
|
||||||
[tool.poetry.dependencies.webdav4]
|
[tool.poetry.dependencies.webdav4]
|
||||||
extras = [ "fsspec",]
|
extras = [ "fsspec",]
|
||||||
version = "^0.10.0"
|
version = "^0.11.0"
|
||||||
|
|
||||||
[poetry.group.dev.dependencies]
|
[poetry.group.dev.dependencies]
|
||||||
websocket_client = "^1.1.0"
|
websocket_client = "^1.1.0"
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,30 @@ import psutil
|
||||||
|
|
||||||
STOP_PARENT_KILL = ["./odoo_bin.sh", "./run.sh"]
|
STOP_PARENT_KILL = ["./odoo_bin.sh", "./run.sh"]
|
||||||
|
|
||||||
|
# Processes that must never be killed — killing these
|
||||||
|
# can crash the desktop session or the system.
|
||||||
|
PROTECTED_NAMES = {
|
||||||
|
"systemd",
|
||||||
|
"init",
|
||||||
|
"gnome-session",
|
||||||
|
"gnome-session-binary",
|
||||||
|
"gnome-shell",
|
||||||
|
"gdm",
|
||||||
|
"gdm3",
|
||||||
|
"gdm-session-worker",
|
||||||
|
"lightdm",
|
||||||
|
"sddm",
|
||||||
|
"Xorg",
|
||||||
|
"Xwayland",
|
||||||
|
"plasmashell",
|
||||||
|
"kwin_wayland",
|
||||||
|
"kwin_x11",
|
||||||
|
"loginctl",
|
||||||
|
"login",
|
||||||
|
"sshd",
|
||||||
|
"tmux: server",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def proc_desc(p: psutil.Process) -> str:
|
def proc_desc(p: psutil.Process) -> str:
|
||||||
try:
|
try:
|
||||||
|
|
@ -131,6 +155,11 @@ def main():
|
||||||
default=1,
|
default=1,
|
||||||
help="Kill parent too",
|
help="Kill parent too",
|
||||||
)
|
)
|
||||||
|
ap.add_argument(
|
||||||
|
"--automatic",
|
||||||
|
action="store_true",
|
||||||
|
help="Ignore ask confirmation before killing",
|
||||||
|
)
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
|
|
||||||
if not (1 <= args.port <= 65535):
|
if not (1 <= args.port <= 65535):
|
||||||
|
|
@ -151,20 +180,53 @@ def main():
|
||||||
|
|
||||||
print(f"\nListener PID {pid} ancestry:")
|
print(f"\nListener PID {pid} ancestry:")
|
||||||
for i, p in enumerate(chain):
|
for i, p in enumerate(chain):
|
||||||
prefix = " " + ("-> " if p == target else " ")
|
prefix = " " + ("-> " if p == target else " ")
|
||||||
print(prefix + proc_desc(p))
|
print(f"[{i}]" + prefix + proc_desc(p))
|
||||||
|
|
||||||
if target is None:
|
if target is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if target.pid == 1 and not args.allow_pid1:
|
if target.pid == 1:
|
||||||
print(
|
print(
|
||||||
"Refus: la cible est PID 1 (systemd). Utilise plutôt systemctl pour arrêter le service.",
|
"Refus: la cible est PID 1 (systemd)."
|
||||||
file=sys.stderr,
|
" Utilise plutôt systemctl pour arrêter"
|
||||||
|
" le service.",
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
if target.name() in PROTECTED_NAMES:
|
||||||
|
print(
|
||||||
|
f"Refus: le process '{target.name()}' semble être protégé et dangereux à être arrêter.",
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
action = "KILL" if args.force else "TERM"
|
action = "KILL" if args.force else "TERM"
|
||||||
|
|
||||||
|
if not args.automatic:
|
||||||
|
has_response = False
|
||||||
|
ignore_kill = False
|
||||||
|
while not has_response and not ignore_kill:
|
||||||
|
confirm = (
|
||||||
|
input(
|
||||||
|
f"Tuer ce processus index {args.nb_parent} (enter) ou mettre "
|
||||||
|
f"l'index [0 to {len(chain) - 1}] du "
|
||||||
|
f"process à tuer, (c/C) pour annuler : \n"
|
||||||
|
)
|
||||||
|
.strip()
|
||||||
|
.lower()
|
||||||
|
)
|
||||||
|
if not confirm:
|
||||||
|
has_response = True
|
||||||
|
continue
|
||||||
|
if confirm == "c":
|
||||||
|
ignore_kill = True
|
||||||
|
print("Cancel")
|
||||||
|
continue
|
||||||
|
if confirm.isdigit():
|
||||||
|
has_response = True
|
||||||
|
target = chain[int(confirm)]
|
||||||
|
if ignore_kill:
|
||||||
|
continue
|
||||||
|
|
||||||
if args.kill_tree:
|
if args.kill_tree:
|
||||||
print(f"Target: pid={target.pid} ({action}) + children (tree)")
|
print(f"Target: pid={target.pid} ({action}) + children (tree)")
|
||||||
if not args.dry_run:
|
if not args.dry_run:
|
||||||
|
|
@ -173,7 +235,6 @@ def main():
|
||||||
print(
|
print(
|
||||||
"Toujours vivants:",
|
"Toujours vivants:",
|
||||||
", ".join(str(p.pid) for p in alive),
|
", ".join(str(p.pid) for p in alive),
|
||||||
file=sys.stderr,
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print(f"Target: pid={target.pid} ({action})")
|
print(f"Target: pid={target.pid} ({action})")
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@ PyGObject==3.44.1
|
||||||
gst
|
gst
|
||||||
# python-vlc
|
# python-vlc
|
||||||
python-randomword-fr
|
python-randomword-fr
|
||||||
|
webdriver_manager
|
||||||
|
|
|
||||||
|
|
@ -897,9 +897,7 @@ class TODO:
|
||||||
db_name = "test_todo_tmp"
|
db_name = "test_todo_tmp"
|
||||||
|
|
||||||
# Extra modules
|
# Extra modules
|
||||||
extra_modules = input(
|
extra_modules = input(t("test_install_extra_modules")).strip()
|
||||||
t("test_install_extra_modules")
|
|
||||||
).strip()
|
|
||||||
|
|
||||||
# Log level
|
# Log level
|
||||||
log_level = input(t("test_log_level")).strip()
|
log_level = input(t("test_log_level")).strip()
|
||||||
|
|
@ -913,9 +911,7 @@ class TODO:
|
||||||
|
|
||||||
# Step 1: Create temp DB
|
# Step 1: Create temp DB
|
||||||
print(f"\n--- {t('test_creating_db')} '{db_name}' ---")
|
print(f"\n--- {t('test_creating_db')} '{db_name}' ---")
|
||||||
cmd_restore = (
|
cmd_restore = f"./script/database/db_restore.py --database {db_name}"
|
||||||
f"./script/database/db_restore.py --database {db_name}"
|
|
||||||
)
|
|
||||||
self.execute.exec_command_live(
|
self.execute.exec_command_live(
|
||||||
cmd_restore,
|
cmd_restore,
|
||||||
source_erplibre=False,
|
source_erplibre=False,
|
||||||
|
|
@ -923,7 +919,9 @@ class TODO:
|
||||||
)
|
)
|
||||||
|
|
||||||
# Step 2: Install modules
|
# Step 2: Install modules
|
||||||
print(f"\n--- {t('test_installing_modules')}: {modules_to_install} ---")
|
print(
|
||||||
|
f"\n--- {t('test_installing_modules')}: {modules_to_install} ---"
|
||||||
|
)
|
||||||
cmd_install = (
|
cmd_install = (
|
||||||
f"./script/addons/install_addons.sh"
|
f"./script/addons/install_addons.sh"
|
||||||
f" {db_name} {modules_to_install}"
|
f" {db_name} {modules_to_install}"
|
||||||
|
|
@ -960,16 +958,12 @@ class TODO:
|
||||||
# Step 4: Cleanup
|
# Step 4: Cleanup
|
||||||
lang = get_lang()
|
lang = get_lang()
|
||||||
keep_input = input(t("test_keep_db")).strip().lower()
|
keep_input = input(t("test_keep_db")).strip().lower()
|
||||||
keep = keep_input in (
|
keep = keep_input in (("o", "oui") if lang == "fr" else ("y", "yes"))
|
||||||
("o", "oui") if lang == "fr" else ("y", "yes")
|
|
||||||
)
|
|
||||||
if keep:
|
if keep:
|
||||||
print(f"{t('test_db_kept')}: {db_name}")
|
print(f"{t('test_db_kept')}: {db_name}")
|
||||||
else:
|
else:
|
||||||
print(f"\n--- {t('test_cleaning_db')} '{db_name}' ---")
|
print(f"\n--- {t('test_cleaning_db')} '{db_name}' ---")
|
||||||
cmd_drop = (
|
cmd_drop = f"./odoo_bin.sh db --drop --database {db_name}"
|
||||||
f"./odoo_bin.sh db --drop --database {db_name}"
|
|
||||||
)
|
|
||||||
self.execute.exec_command_live(
|
self.execute.exec_command_live(
|
||||||
cmd_drop,
|
cmd_drop,
|
||||||
source_erplibre=False,
|
source_erplibre=False,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue