pyhoster 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyhoster/__init__.py +1 -0
- pyhoster/main.py +143 -0
- pyhoster-1.0.0.data/data/share/man/man8/pyhoster.8 +22 -0
- pyhoster-1.0.0.dist-info/METADATA +42 -0
- pyhoster-1.0.0.dist-info/RECORD +10 -0
- pyhoster-1.0.0.dist-info/WHEEL +5 -0
- pyhoster-1.0.0.dist-info/entry_points.txt +2 -0
- pyhoster-1.0.0.dist-info/top_level.txt +1 -0
- pyserve/__init__.py +1 -0
- pyserve/main.py +143 -0
pyhoster/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from . import main
|
pyhoster/main.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import subprocess
|
|
5
|
+
import psutil
|
|
6
|
+
import signal
|
|
7
|
+
import argparse
|
|
8
|
+
import platform
|
|
9
|
+
|
|
10
|
+
if platform.system() == "Windows":
|
|
11
|
+
print("pyhoster does not support Windows")
|
|
12
|
+
exit()
|
|
13
|
+
|
|
14
|
+
def choose(text, post=None, **kwargs):
|
|
15
|
+
while True:
|
|
16
|
+
if len(kwargs) == 1:
|
|
17
|
+
print(post)
|
|
18
|
+
return list(kwargs.keys())[0]
|
|
19
|
+
print(text)
|
|
20
|
+
for i, arg in enumerate(kwargs.values(), 1):
|
|
21
|
+
print(f"({i}): {arg}")
|
|
22
|
+
if post:
|
|
23
|
+
print(post)
|
|
24
|
+
try:
|
|
25
|
+
choice = int(input(f"Choose (1-{len(kwargs)}): "))
|
|
26
|
+
except ValueError:
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
if len(kwargs) >= choice and choice != 0:
|
|
30
|
+
return list(kwargs.keys())[choice - 1]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
operations = {
|
|
34
|
+
"reboot": "Reboot app",
|
|
35
|
+
"kill": "Kill app",
|
|
36
|
+
"start": "Start app",
|
|
37
|
+
"rm": "Remove pyhoster from app",
|
|
38
|
+
"create": "Create app",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def create():
|
|
43
|
+
path = Path(input("Path to the Python executable file: ")).expanduser()
|
|
44
|
+
if not path.exists():
|
|
45
|
+
print("File not found")
|
|
46
|
+
create()
|
|
47
|
+
|
|
48
|
+
logfile = Path(input("Log file path (log.txt): ")
|
|
49
|
+
or "log.txt").expanduser()
|
|
50
|
+
|
|
51
|
+
pypath = input("Python interpreter path (python): ") or "python"
|
|
52
|
+
|
|
53
|
+
process = subprocess.Popen(f"{pypath} -u {path} > {logfile} 2>&1",
|
|
54
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
55
|
+
|
|
56
|
+
with open(".pyhoster", 'w', encoding='utf-8') as cf:
|
|
57
|
+
json.dump({"pid": process.pid, "logfile": str(logfile),
|
|
58
|
+
"pypath": pypath, "path": str(path)}, cf)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def kill():
|
|
62
|
+
pid = config["pid"]
|
|
63
|
+
if not psutil.pid_exists(pid):
|
|
64
|
+
print("Process not found. Maybe app has been turned off")
|
|
65
|
+
else:
|
|
66
|
+
os.kill(pid, signal.SIGTERM)
|
|
67
|
+
os.kill(pid + 1, signal.SIGTERM)
|
|
68
|
+
print("App killed succesfully")
|
|
69
|
+
config["pid"] = None
|
|
70
|
+
with open(".pyhoster", "w", encoding='utf-8') as cf:
|
|
71
|
+
json.dump(config, cf)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def reboot():
|
|
75
|
+
pid = config["pid"]
|
|
76
|
+
if psutil.pid_exists(pid):
|
|
77
|
+
os.kill(pid, signal.SIGTERM)
|
|
78
|
+
os.kill(pid + 1, signal.SIGTERM)
|
|
79
|
+
|
|
80
|
+
process = subprocess.Popen(f"{config["pypath"]} -u {config["path"]} > {config["logfile"]} 2>&1",
|
|
81
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
82
|
+
|
|
83
|
+
config["pid"] = process.pid
|
|
84
|
+
|
|
85
|
+
with open(".pyhoster", 'w', encoding='utf-8') as cf:
|
|
86
|
+
json.dump(config, cf)
|
|
87
|
+
print("App rebooted succesfully")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def rm():
|
|
91
|
+
if not os.path.exists(".pyhoster"):
|
|
92
|
+
print("pyhoster isn't installed in this directory")
|
|
93
|
+
return
|
|
94
|
+
pid = config["pid"]
|
|
95
|
+
|
|
96
|
+
if psutil.pid_exists(pid):
|
|
97
|
+
os.kill(pid, signal.SIGTERM)
|
|
98
|
+
os.kill(pid + 1, signal.SIGTERM)
|
|
99
|
+
|
|
100
|
+
os.remove(".pyhoster")
|
|
101
|
+
print("pyhoster removed succesfully")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def start():
|
|
105
|
+
process = subprocess.Popen(f"{config["pypath"]} -u {config["path"]} > {config["logfile"]} 2>&1",
|
|
106
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
107
|
+
|
|
108
|
+
config["pid"] = process.pid
|
|
109
|
+
|
|
110
|
+
with open(".pyhoster", 'w', encoding='utf-8') as cf:
|
|
111
|
+
json.dump(config, cf)
|
|
112
|
+
print("App started succesfully")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def main():
|
|
116
|
+
global config
|
|
117
|
+
argparser = argparse.ArgumentParser(usage="Just write `pyhoster` in root directory of your project", description="A simple tool for servers that host python projects")
|
|
118
|
+
config = None
|
|
119
|
+
if os.path.exists(".pyhoster"):
|
|
120
|
+
with open(".pyhoster", "r", encoding="utf-8") as cf:
|
|
121
|
+
config = json.load(cf)
|
|
122
|
+
|
|
123
|
+
if config["pid"]:
|
|
124
|
+
menu = ["reboot", "kill", "rm"]
|
|
125
|
+
else:
|
|
126
|
+
menu = ["start", "rm"]
|
|
127
|
+
else:
|
|
128
|
+
menu = ["create"]
|
|
129
|
+
|
|
130
|
+
argparser.add_argument("operation", choices=menu, help="run operation CLI (not TUI)", default=None, nargs='?')
|
|
131
|
+
args = argparser.parse_args()
|
|
132
|
+
if args.operation:
|
|
133
|
+
globals()[args.operation]()
|
|
134
|
+
else:
|
|
135
|
+
globals()[choose("What do you want to do?",
|
|
136
|
+
"Press Ctrl+C to stop", **{i: operations[i] for i in menu})]()
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def launch():
|
|
140
|
+
try:
|
|
141
|
+
main()
|
|
142
|
+
except KeyboardInterrupt:
|
|
143
|
+
exit()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.TH pyhoster 8
|
|
2
|
+
.SH NAME
|
|
3
|
+
pyhoster - a simple tool for servers that host python projects
|
|
4
|
+
|
|
5
|
+
.SH SYNOPSIS
|
|
6
|
+
pyhoster # for TUI
|
|
7
|
+
.br
|
|
8
|
+
pyhoster [operation] # for CLI
|
|
9
|
+
|
|
10
|
+
.SH DESCRIPTION
|
|
11
|
+
pyhoster is a simple tool for servers that host python projects.
|
|
12
|
+
.br
|
|
13
|
+
With it you can easily create, reboot, kill, start processes
|
|
14
|
+
|
|
15
|
+
.SH AUTHOR
|
|
16
|
+
written by mbutsk <mbutsk@icloud.com> (https://github.com/mbutsk)
|
|
17
|
+
|
|
18
|
+
.SH REPO
|
|
19
|
+
You can find source at https://github.com/mbutsk/pyhoster
|
|
20
|
+
|
|
21
|
+
.SH REPORTING BUGS
|
|
22
|
+
https://github.com/mbutsk/pyhoster/issues
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyhoster
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A simple tool for servers that host python projects
|
|
5
|
+
Home-page: https://github.com/mbutsk/pyhoster
|
|
6
|
+
Author: mbutsk
|
|
7
|
+
Author-email: mbutsk@icloud.com
|
|
8
|
+
License: MIT License, see LICENSE.md file
|
|
9
|
+
Keywords: cli,server,process,manager,console,script
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Topic :: System :: Systems Administration
|
|
12
|
+
Classifier: Topic :: Utilities
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Operating System :: Unix
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: psutil
|
|
18
|
+
Dynamic: author
|
|
19
|
+
Dynamic: author-email
|
|
20
|
+
Dynamic: classifier
|
|
21
|
+
Dynamic: description
|
|
22
|
+
Dynamic: description-content-type
|
|
23
|
+
Dynamic: home-page
|
|
24
|
+
Dynamic: keywords
|
|
25
|
+
Dynamic: license
|
|
26
|
+
Dynamic: requires-dist
|
|
27
|
+
Dynamic: summary
|
|
28
|
+
|
|
29
|
+
# pyhoster
|
|
30
|
+
|
|
31
|
+
pyhoster is a tool for those who host Python projects on their servers. It can reboot, kill processes, and more.
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### TUI
|
|
36
|
+
|
|
37
|
+
Just write pyhoster in the root directory of the project and follow the instructions.
|
|
38
|
+
|
|
39
|
+
### CLI
|
|
40
|
+
|
|
41
|
+
In the root directory of the project, write `pyhoster kill` to kill the process, `pyhoster reboot` to reboot, etc.
|
|
42
|
+
`pyhoster -h` / `pyhoster --help` for full list available commands in moment
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pyhoster/__init__.py,sha256=yOHNZm_ZjPI2TywkyAVTTj5JaNghV7jQEcJLIUaQqQA,18
|
|
2
|
+
pyhoster/main.py,sha256=n0ifYnVOGMKMNSKzvvi6EdbC7bzRf9v5OE0PwlxRQro,4123
|
|
3
|
+
pyhoster-1.0.0.data/data/share/man/man8/pyhoster.8,sha256=Gs9O02cSZCKJXhYY6_mmIcz7hU9xvnXmmhO6HsGK52A,510
|
|
4
|
+
pyserve/__init__.py,sha256=yOHNZm_ZjPI2TywkyAVTTj5JaNghV7jQEcJLIUaQqQA,18
|
|
5
|
+
pyserve/main.py,sha256=gV4joqNkkxOGRcx1h_hiT4UHMjYhmGuhrg-DEMEMJsQ,4110
|
|
6
|
+
pyhoster-1.0.0.dist-info/METADATA,sha256=-dmrKtpF-alS8vfDH55KGibEV1Pmi9b_kjJt8ikt1qc,1274
|
|
7
|
+
pyhoster-1.0.0.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
|
8
|
+
pyhoster-1.0.0.dist-info/entry_points.txt,sha256=Y1yJ8V0MXsrxNyRZrH-V_RECzBM-OnZ0KR6pkZ3I4sQ,50
|
|
9
|
+
pyhoster-1.0.0.dist-info/top_level.txt,sha256=2YUlyyG5-GI6vm_tLodWzUdBWHqMlrwBOKiSUxpDzqw,9
|
|
10
|
+
pyhoster-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pyhoster
|
pyserve/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from . import main
|
pyserve/main.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import subprocess
|
|
5
|
+
import psutil
|
|
6
|
+
import signal
|
|
7
|
+
import argparse
|
|
8
|
+
import platform
|
|
9
|
+
|
|
10
|
+
if platform.system() == "Windows":
|
|
11
|
+
print("pyserve does not support Windows")
|
|
12
|
+
exit()
|
|
13
|
+
|
|
14
|
+
def choose(text, post=None, **kwargs):
|
|
15
|
+
while True:
|
|
16
|
+
if len(kwargs) == 1:
|
|
17
|
+
print(post)
|
|
18
|
+
return list(kwargs.keys())[0]
|
|
19
|
+
print(text)
|
|
20
|
+
for i, arg in enumerate(kwargs.values(), 1):
|
|
21
|
+
print(f"({i}): {arg}")
|
|
22
|
+
if post:
|
|
23
|
+
print(post)
|
|
24
|
+
try:
|
|
25
|
+
choice = int(input(f"Choose (1-{len(kwargs)}): "))
|
|
26
|
+
except ValueError:
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
if len(kwargs) >= choice and choice != 0:
|
|
30
|
+
return list(kwargs.keys())[choice - 1]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
operations = {
|
|
34
|
+
"reboot": "Reboot app",
|
|
35
|
+
"kill": "Kill app",
|
|
36
|
+
"start": "Start app",
|
|
37
|
+
"rm": "Remove pyserve from app",
|
|
38
|
+
"create": "Create app",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def create():
|
|
43
|
+
path = Path(input("Path to the Python executable file: ")).expanduser()
|
|
44
|
+
if not path.exists():
|
|
45
|
+
print("File not found")
|
|
46
|
+
create()
|
|
47
|
+
|
|
48
|
+
logfile = Path(input("Log file path (log.txt): ")
|
|
49
|
+
or "log.txt").expanduser()
|
|
50
|
+
|
|
51
|
+
pypath = input("Python interpreter path (python): ") or "python"
|
|
52
|
+
|
|
53
|
+
process = subprocess.Popen(f"{pypath} -u {path} > {logfile} 2>&1",
|
|
54
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
55
|
+
|
|
56
|
+
with open(".pyserve", 'w', encoding='utf-8') as cf:
|
|
57
|
+
json.dump({"pid": process.pid, "logfile": str(logfile),
|
|
58
|
+
"pypath": pypath, "path": str(path)}, cf)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def kill():
|
|
62
|
+
pid = config["pid"]
|
|
63
|
+
if not psutil.pid_exists(pid):
|
|
64
|
+
print("Process not found. Maybe app has been turned off")
|
|
65
|
+
else:
|
|
66
|
+
os.kill(pid, signal.SIGTERM)
|
|
67
|
+
os.kill(pid + 1, signal.SIGTERM)
|
|
68
|
+
print("App killed succesfully")
|
|
69
|
+
config["pid"] = None
|
|
70
|
+
with open(".pyserve", "w", encoding='utf-8') as cf:
|
|
71
|
+
json.dump(config, cf)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def reboot():
|
|
75
|
+
pid = config["pid"]
|
|
76
|
+
if psutil.pid_exists(pid):
|
|
77
|
+
os.kill(pid, signal.SIGTERM)
|
|
78
|
+
os.kill(pid + 1, signal.SIGTERM)
|
|
79
|
+
|
|
80
|
+
process = subprocess.Popen(f"{config["pypath"]} -u {config["path"]} > {config["logfile"]} 2>&1",
|
|
81
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
82
|
+
|
|
83
|
+
config["pid"] = process.pid
|
|
84
|
+
|
|
85
|
+
with open(".pyserve", 'w', encoding='utf-8') as cf:
|
|
86
|
+
json.dump(config, cf)
|
|
87
|
+
print("App rebooted succesfully")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def rm():
|
|
91
|
+
if not os.path.exists(".pyserve"):
|
|
92
|
+
print("Pyserve isn't installed in this directory")
|
|
93
|
+
return
|
|
94
|
+
pid = config["pid"]
|
|
95
|
+
|
|
96
|
+
if psutil.pid_exists(pid):
|
|
97
|
+
os.kill(pid, signal.SIGTERM)
|
|
98
|
+
os.kill(pid + 1, signal.SIGTERM)
|
|
99
|
+
|
|
100
|
+
os.remove(".pyserve")
|
|
101
|
+
print("Pyserve removed succesfully")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def start():
|
|
105
|
+
process = subprocess.Popen(f"{config["pypath"]} -u {config["path"]} > {config["logfile"]} 2>&1",
|
|
106
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
107
|
+
|
|
108
|
+
config["pid"] = process.pid
|
|
109
|
+
|
|
110
|
+
with open(".pyserve", 'w', encoding='utf-8') as cf:
|
|
111
|
+
json.dump(config, cf)
|
|
112
|
+
print("App started succesfully")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def main():
|
|
116
|
+
global config
|
|
117
|
+
argparser = argparse.ArgumentParser(usage="Just write `pyserve` in root directory of your project", description="A simple tool for servers that host python projects")
|
|
118
|
+
config = None
|
|
119
|
+
if os.path.exists(".pyserve"):
|
|
120
|
+
with open(".pyserve", "r", encoding="utf-8") as cf:
|
|
121
|
+
config = json.load(cf)
|
|
122
|
+
|
|
123
|
+
if config["pid"]:
|
|
124
|
+
menu = ["reboot", "kill", "rm"]
|
|
125
|
+
else:
|
|
126
|
+
menu = ["start", "rm"]
|
|
127
|
+
else:
|
|
128
|
+
menu = ["create"]
|
|
129
|
+
|
|
130
|
+
argparser.add_argument("operation", choices=menu, help="run operation CLI (not TUI)", default=None, nargs='?')
|
|
131
|
+
args = argparser.parse_args()
|
|
132
|
+
if args.operation:
|
|
133
|
+
globals()[args.operation]()
|
|
134
|
+
else:
|
|
135
|
+
globals()[choose("What do you want to do?",
|
|
136
|
+
"Press Ctrl+C to stop", **{i: operations[i] for i in menu})]()
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def launch():
|
|
140
|
+
try:
|
|
141
|
+
main()
|
|
142
|
+
except KeyboardInterrupt:
|
|
143
|
+
exit()
|