absfuyu 4.1.0__py3-none-any.whl → 4.2.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.
Potentially problematic release.
This version of absfuyu might be problematic. Click here for more details.
- absfuyu/__init__.py +1 -1
- absfuyu/cli/__init__.py +4 -2
- absfuyu/cli/do_group.py +14 -38
- absfuyu/cli/tool_group.py +136 -0
- absfuyu/core.py +4 -5
- absfuyu/extensions/__init__.py +1 -0
- absfuyu/pkg_data/__init__.py +2 -1
- absfuyu/pkg_data/passwordlib_lzma.pkl +0 -0
- absfuyu/tools/checksum.py +104 -6
- absfuyu/tools/converter.py +36 -7
- absfuyu/{extensions/dev → tools}/passwordlib.py +52 -50
- absfuyu/tools/shutdownizer.py +266 -0
- absfuyu/util/shorten_number.py +1 -1
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/METADATA +13 -18
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/RECORD +19 -21
- absfuyu/extensions/dev/__init__.py +0 -244
- absfuyu/extensions/dev/password_hash.py +0 -80
- absfuyu/extensions/dev/project_starter.py +0 -60
- absfuyu/extensions/dev/shutdownizer.py +0 -156
- absfuyu/extensions/extra/__init__.py +0 -24
- /absfuyu/extensions/{extra/data_analysis.py → data_analysis.py} +0 -0
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/WHEEL +0 -0
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-4.1.0.dist-info → absfuyu-4.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
Absfuyu: Development
|
|
6
|
-
--------------------
|
|
7
|
-
Some stuffs that are not ready to use yet.
|
|
8
|
-
Use at your own risk, everything is subject to change
|
|
9
|
-
|
|
10
|
-
Version: 2.0.0
|
|
11
|
-
Date updated: 23/11/2023 (dd/mm/yyyy)
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
# Module level
|
|
15
|
-
###########################################################################
|
|
16
|
-
__all__ = [
|
|
17
|
-
"password_check",
|
|
18
|
-
"fib",
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# Library
|
|
23
|
-
###########################################################################
|
|
24
|
-
import base64
|
|
25
|
-
import re
|
|
26
|
-
from collections import deque
|
|
27
|
-
from functools import lru_cache
|
|
28
|
-
from typing import Dict, Final, List, NamedTuple
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# PASSWORD CHECKER
|
|
32
|
-
def password_check(password: str) -> bool:
|
|
33
|
-
"""
|
|
34
|
-
Verify the strength of 'password'.
|
|
35
|
-
Returns a dict indicating the wrong criteria.
|
|
36
|
-
A password is considered strong if:
|
|
37
|
-
- 8 characters length or more
|
|
38
|
-
- 1 digit or more
|
|
39
|
-
- 1 symbol or more
|
|
40
|
-
- 1 uppercase letter or more
|
|
41
|
-
- 1 lowercase letter or more
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
# calculating the length
|
|
45
|
-
length_error = len(password) < 8
|
|
46
|
-
|
|
47
|
-
# searching for digits
|
|
48
|
-
digit_error = re.search(r"\d", password) is None
|
|
49
|
-
|
|
50
|
-
# searching for uppercase
|
|
51
|
-
uppercase_error = re.search(r"[A-Z]", password) is None
|
|
52
|
-
|
|
53
|
-
# searching for lowercase
|
|
54
|
-
lowercase_error = re.search(r"[a-z]", password) is None
|
|
55
|
-
|
|
56
|
-
# searching for symbols
|
|
57
|
-
symbols = re.compile(r"[ !#$%&'()*+,-./[\\\]^_`{|}~" + r'"]')
|
|
58
|
-
symbol_error = symbols.search(password) is None
|
|
59
|
-
|
|
60
|
-
detail = {
|
|
61
|
-
"password_ok": not any(
|
|
62
|
-
[ # overall result
|
|
63
|
-
length_error,
|
|
64
|
-
digit_error,
|
|
65
|
-
uppercase_error,
|
|
66
|
-
lowercase_error,
|
|
67
|
-
symbol_error,
|
|
68
|
-
]
|
|
69
|
-
),
|
|
70
|
-
"length_error": length_error,
|
|
71
|
-
"digit_error": digit_error,
|
|
72
|
-
"uppercase_error": uppercase_error,
|
|
73
|
-
"lowercase_error": lowercase_error,
|
|
74
|
-
"symbol_error": symbol_error,
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return detail["password_ok"]
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# FIBONACCI WITH CACHE
|
|
81
|
-
@lru_cache(maxsize=5)
|
|
82
|
-
def fib(n: int) -> int:
|
|
83
|
-
"""Fibonacci (recursive)"""
|
|
84
|
-
# max recursion is 484
|
|
85
|
-
if n < 2:
|
|
86
|
-
return n
|
|
87
|
-
return fib(n - 1) + fib(n - 2)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
# https://stackoverflow.com/questions/563022/whats-python-good-practice-for-importing-and-offering-optional-features
|
|
91
|
-
def optional_import(module: str, name: str = None, package: str = None):
|
|
92
|
-
import importlib
|
|
93
|
-
|
|
94
|
-
try:
|
|
95
|
-
module = importlib.import_module(module)
|
|
96
|
-
return module if name is None else getattr(module, name)
|
|
97
|
-
except ImportError as e:
|
|
98
|
-
if package is None:
|
|
99
|
-
package = module
|
|
100
|
-
msg = f"install the '{package}' package to make use of this feature"
|
|
101
|
-
import_error = e
|
|
102
|
-
|
|
103
|
-
def _failed_import(*args):
|
|
104
|
-
raise ValueError(msg) from import_error
|
|
105
|
-
|
|
106
|
-
return _failed_import
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def load_toml_file(toml_file: str):
|
|
110
|
-
"""
|
|
111
|
-
Load ``.toml`` file
|
|
112
|
-
|
|
113
|
-
:param toml_file: Path to ``.toml`` file
|
|
114
|
-
"""
|
|
115
|
-
from sys import version_info as _python_version
|
|
116
|
-
|
|
117
|
-
if _python_version.minor < 11:
|
|
118
|
-
try:
|
|
119
|
-
import tomli as tomllib # type: ignore
|
|
120
|
-
except ImportError:
|
|
121
|
-
raise ImportError("Please install tomli python package")
|
|
122
|
-
except:
|
|
123
|
-
raise SystemExit
|
|
124
|
-
else:
|
|
125
|
-
import tomllib
|
|
126
|
-
|
|
127
|
-
with open(toml_file, "rb") as file:
|
|
128
|
-
toml_data = tomllib.load(file)
|
|
129
|
-
return toml_data
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def get_sitemap(url: str):
|
|
133
|
-
import re
|
|
134
|
-
|
|
135
|
-
import requests
|
|
136
|
-
|
|
137
|
-
class Url(NamedTuple):
|
|
138
|
-
base: str
|
|
139
|
-
extra: str
|
|
140
|
-
|
|
141
|
-
def __str__(self) -> str:
|
|
142
|
-
return f"{self.base}{self.extra}"
|
|
143
|
-
|
|
144
|
-
def __repr__(self) -> str:
|
|
145
|
-
return f"{self.__class__.__name__}({self.base}{self.extra})"
|
|
146
|
-
|
|
147
|
-
# robots.txt
|
|
148
|
-
# sitemap.xml
|
|
149
|
-
if not url.endswith("/"):
|
|
150
|
-
url += "/"
|
|
151
|
-
pattern = re.compile(
|
|
152
|
-
r"([(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b)([-a-zA-Z0-9@:%_\+.~#?&//=]*)",
|
|
153
|
-
re.IGNORECASE,
|
|
154
|
-
)
|
|
155
|
-
try:
|
|
156
|
-
url += "sitemap.xml"
|
|
157
|
-
res = requests.get(url).text
|
|
158
|
-
except:
|
|
159
|
-
# W.I.P
|
|
160
|
-
url += "robots.txt"
|
|
161
|
-
res = requests.get(url).text
|
|
162
|
-
regex = re.findall(pattern, res)
|
|
163
|
-
return list(map(Url._make, regex))
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
from absfuyu.general import ClassBase
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
class SimpleStrEncrypt(ClassBase):
|
|
170
|
-
"""
|
|
171
|
-
Simple Encryption
|
|
172
|
-
|
|
173
|
-
Logic:
|
|
174
|
-
- Base64
|
|
175
|
-
- Shift characters
|
|
176
|
-
"""
|
|
177
|
-
|
|
178
|
-
def __init__(self, times_to_base64_encode: int = 10, shift: int = 13) -> None:
|
|
179
|
-
"""
|
|
180
|
-
:param times_to_base64_encode: How many time to base64 encode
|
|
181
|
-
:type times_to_base64_encode: int
|
|
182
|
-
:param shift: Shift characters to the right for how many position
|
|
183
|
-
:type shift: int
|
|
184
|
-
"""
|
|
185
|
-
self.times_to_base64_encode = times_to_base64_encode
|
|
186
|
-
self.shift = shift
|
|
187
|
-
|
|
188
|
-
# Support
|
|
189
|
-
def _convert_table(self, text: str, shift: int) -> Dict[str, str]:
|
|
190
|
-
data = text
|
|
191
|
-
|
|
192
|
-
data = deque(sorted(list(set(data))))
|
|
193
|
-
translate = data.copy()
|
|
194
|
-
translate.rotate(shift)
|
|
195
|
-
convert_table = dict(zip(data, translate))
|
|
196
|
-
|
|
197
|
-
return convert_table
|
|
198
|
-
|
|
199
|
-
@staticmethod
|
|
200
|
-
def _use_convert_table(text: str, convert_table: Dict[str, str]) -> str:
|
|
201
|
-
"""Use convert table"""
|
|
202
|
-
data = list(text)
|
|
203
|
-
for i, x in enumerate(data):
|
|
204
|
-
data[i] = convert_table[x]
|
|
205
|
-
return "".join(data)
|
|
206
|
-
|
|
207
|
-
@staticmethod
|
|
208
|
-
def _b64encode(text: str) -> str:
|
|
209
|
-
return base64.b64encode(text.encode()).decode()
|
|
210
|
-
|
|
211
|
-
@staticmethod
|
|
212
|
-
def _b64decode(text: str) -> str:
|
|
213
|
-
return base64.b64decode(text).decode()
|
|
214
|
-
|
|
215
|
-
# Main
|
|
216
|
-
def encode(self, text: str) -> str:
|
|
217
|
-
# Base64
|
|
218
|
-
data = text
|
|
219
|
-
for _ in range(self.times_to_base64_encode):
|
|
220
|
-
data = self._b64encode(data)
|
|
221
|
-
|
|
222
|
-
# Shift
|
|
223
|
-
convert_table = self._convert_table(data, self.shift)
|
|
224
|
-
return self._use_convert_table(data, convert_table)
|
|
225
|
-
|
|
226
|
-
def decode(self, text: str) -> str:
|
|
227
|
-
# Shift back
|
|
228
|
-
data = text
|
|
229
|
-
convert_table = self._convert_table(data, -self.shift)
|
|
230
|
-
data = self._use_convert_table(data, convert_table)
|
|
231
|
-
|
|
232
|
-
# Base64
|
|
233
|
-
for _ in range(self.times_to_base64_encode):
|
|
234
|
-
data = self._b64decode(data)
|
|
235
|
-
|
|
236
|
-
return data
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
# testing
|
|
240
|
-
CON_VAR: Final[List[str]] = ["a", "b"] # Declare as final
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if __name__ == "__main__":
|
|
244
|
-
print(get_sitemap("https://kingdomality.com/"))
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
|
-
# Library
|
|
5
|
-
##############################################################
|
|
6
|
-
import hashlib as __hash
|
|
7
|
-
import os as __os
|
|
8
|
-
from typing import Dict as __Dict
|
|
9
|
-
from typing import NewType as __NewType
|
|
10
|
-
from typing import TypeVar as __TypeVar
|
|
11
|
-
from typing import Union as __Union
|
|
12
|
-
|
|
13
|
-
# Define type
|
|
14
|
-
##############################################################
|
|
15
|
-
Password = __NewType("Password", str)
|
|
16
|
-
Salt = __NewType("Salt", str)
|
|
17
|
-
Key = __NewType("Key", str)
|
|
18
|
-
Salt_V = __NewType("Salt_V", bytes)
|
|
19
|
-
Key_V = __NewType("Key_V", bytes)
|
|
20
|
-
Combo = __Dict[__Union[Salt, Key], __Union[Salt_V, Key_V]]
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# Function
|
|
24
|
-
##############################################################
|
|
25
|
-
def password_hash(password: Password) -> Combo:
|
|
26
|
-
"""
|
|
27
|
-
Generate hash for password
|
|
28
|
-
"""
|
|
29
|
-
salt = __os.urandom(32)
|
|
30
|
-
key = __hash.pbkdf2_hmac(
|
|
31
|
-
hash_name="sha256",
|
|
32
|
-
password=password.encode("utf-8"),
|
|
33
|
-
salt=salt,
|
|
34
|
-
iterations=100000,
|
|
35
|
-
)
|
|
36
|
-
out = {
|
|
37
|
-
"salt": salt,
|
|
38
|
-
"key": key,
|
|
39
|
-
}
|
|
40
|
-
return out
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def password_hash_check(
|
|
44
|
-
password: Password,
|
|
45
|
-
combo: Combo,
|
|
46
|
-
) -> bool:
|
|
47
|
-
"""
|
|
48
|
-
Compare hashes between 2 passwords
|
|
49
|
-
"""
|
|
50
|
-
if "salt" in combo and "key" in combo:
|
|
51
|
-
salt = combo["salt"]
|
|
52
|
-
compare_key = combo["key"]
|
|
53
|
-
else:
|
|
54
|
-
return None
|
|
55
|
-
|
|
56
|
-
key = __hash.pbkdf2_hmac(
|
|
57
|
-
hash_name="sha256",
|
|
58
|
-
password=password.encode("utf-8"),
|
|
59
|
-
salt=salt,
|
|
60
|
-
iterations=100000,
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
if key == compare_key:
|
|
64
|
-
return True
|
|
65
|
-
else:
|
|
66
|
-
return False
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def tj():
|
|
70
|
-
import json
|
|
71
|
-
|
|
72
|
-
combo = password_hash("lmao")
|
|
73
|
-
for k, v in combo.items():
|
|
74
|
-
combo[k] = str(v)
|
|
75
|
-
j = json.dumps(combo, indent=4)
|
|
76
|
-
return j
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if __name__ == "__main__":
|
|
80
|
-
print(tj())
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
Absfuyu: Project starter
|
|
6
|
-
------------------------
|
|
7
|
-
|
|
8
|
-
Version: 1.0.0dev1
|
|
9
|
-
Date updated: 01/12/2023 (dd/mm/yyyy)
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
# Module level
|
|
13
|
-
###########################################################################
|
|
14
|
-
__all__ = ["get_parser"]
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
# Library
|
|
18
|
-
###########################################################################
|
|
19
|
-
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
|
|
20
|
-
from typing import Optional
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# Function
|
|
24
|
-
###########################################################################
|
|
25
|
-
def get_parser(
|
|
26
|
-
name: Optional[str] = None,
|
|
27
|
-
description: Optional[str] = None,
|
|
28
|
-
epilog: Optional[str] = None,
|
|
29
|
-
*,
|
|
30
|
-
version: str = "",
|
|
31
|
-
add_help: bool = True,
|
|
32
|
-
) -> ArgumentParser:
|
|
33
|
-
arg_parser = ArgumentParser(
|
|
34
|
-
prog=name,
|
|
35
|
-
description=description,
|
|
36
|
-
epilog=epilog,
|
|
37
|
-
add_help=add_help,
|
|
38
|
-
formatter_class=ArgumentDefaultsHelpFormatter,
|
|
39
|
-
# allow_abbrev=False, # Disable long options recognize
|
|
40
|
-
# exit_on_error=True
|
|
41
|
-
)
|
|
42
|
-
arg_parser.add_argument(
|
|
43
|
-
"--version", action="version", version=f"%(prog)s {version}"
|
|
44
|
-
)
|
|
45
|
-
_ll_val = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
|
46
|
-
arg_parser.add_argument(
|
|
47
|
-
"--log-level",
|
|
48
|
-
metavar="LOG_LEVEL",
|
|
49
|
-
dest="log_level",
|
|
50
|
-
choices=_ll_val,
|
|
51
|
-
default="INFO",
|
|
52
|
-
help=f"Log level: {_ll_val}",
|
|
53
|
-
)
|
|
54
|
-
return arg_parser
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# Run
|
|
58
|
-
###########################################################################
|
|
59
|
-
if __name__ == "__main__":
|
|
60
|
-
pass
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# type: ignore
|
|
2
|
-
# flake8: noqa
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
Absfuyu: Shutdownizer
|
|
6
|
-
---------------------
|
|
7
|
-
This shutdowns
|
|
8
|
-
|
|
9
|
-
Version: 1.0.0dev
|
|
10
|
-
Date updated: 27/11/2023 (dd/mm/yyyy)
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
# Module level
|
|
14
|
-
###########################################################################
|
|
15
|
-
__all__ = ["ShutDownizer"]
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# Library
|
|
19
|
-
###########################################################################
|
|
20
|
-
import datetime
|
|
21
|
-
import os
|
|
22
|
-
import random
|
|
23
|
-
import subprocess
|
|
24
|
-
import sys
|
|
25
|
-
from pathlib import Path
|
|
26
|
-
|
|
27
|
-
from absfuyu.logger import LogLevel, logger
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# Class
|
|
31
|
-
###########################################################################
|
|
32
|
-
class Dummy:
|
|
33
|
-
def __init__(self) -> None:
|
|
34
|
-
pass
|
|
35
|
-
|
|
36
|
-
def __str__(self) -> str:
|
|
37
|
-
return f"{self.__class__.__name__}()"
|
|
38
|
-
|
|
39
|
-
def __repr__(self) -> str:
|
|
40
|
-
return self.__str__()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class ShutDownizer(Dummy):
|
|
44
|
-
"""
|
|
45
|
-
ShutDownizer
|
|
46
|
-
|
|
47
|
-
Shutdown tool because why not
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
def __init__(self) -> None:
|
|
51
|
-
"""doc_string"""
|
|
52
|
-
self.os: str = sys.platform
|
|
53
|
-
logger.debug(f"Current OS: {self.os}")
|
|
54
|
-
|
|
55
|
-
if self.os in ["win32", "cygwin"]: # Windows
|
|
56
|
-
self.engine = ShutDownizerWin()
|
|
57
|
-
elif self.os == "darwin": # MacOS
|
|
58
|
-
self.engine = ShutDownizerMac()
|
|
59
|
-
elif self.os == "linux": # Linux
|
|
60
|
-
self.engine = ShutDownizerLinux()
|
|
61
|
-
else: # Other (probably linux)
|
|
62
|
-
self.engine = ShutDownizerLinux()
|
|
63
|
-
|
|
64
|
-
def __str__(self) -> str:
|
|
65
|
-
return f"{self.__class__.__name__}({self.os})"
|
|
66
|
-
|
|
67
|
-
def shutdown(self):
|
|
68
|
-
"""Shutdown"""
|
|
69
|
-
self.engine.shutdown()
|
|
70
|
-
|
|
71
|
-
def restart(self):
|
|
72
|
-
"""Restart"""
|
|
73
|
-
self.engine.restart()
|
|
74
|
-
|
|
75
|
-
def cancel(self):
|
|
76
|
-
"""Cancel"""
|
|
77
|
-
self.engine.cancel()
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class ShutDownizerEngine(Dummy):
|
|
81
|
-
"""
|
|
82
|
-
Abstract class for different type of OS
|
|
83
|
-
"""
|
|
84
|
-
|
|
85
|
-
def __init__(self) -> None:
|
|
86
|
-
self.shutdown_cmd = ""
|
|
87
|
-
self.restart_cmd = ""
|
|
88
|
-
self.cancel_cmd = ""
|
|
89
|
-
|
|
90
|
-
def _excute_cmd(self, cmd) -> None:
|
|
91
|
-
"""Execute the cmd"""
|
|
92
|
-
try:
|
|
93
|
-
if isinstance(cmd, str):
|
|
94
|
-
subprocess.run(cmd.split())
|
|
95
|
-
elif isinstance(cmd, list):
|
|
96
|
-
subprocess.run(cmd)
|
|
97
|
-
else:
|
|
98
|
-
logger.error(f'"{cmd}" failed to run')
|
|
99
|
-
except:
|
|
100
|
-
logger.error(f'"{cmd}" failed to run')
|
|
101
|
-
|
|
102
|
-
def shutdown(self):
|
|
103
|
-
"""Shutdown"""
|
|
104
|
-
try:
|
|
105
|
-
self._excute_cmd(self.shutdown_cmd)
|
|
106
|
-
except:
|
|
107
|
-
pass
|
|
108
|
-
|
|
109
|
-
def restart(self):
|
|
110
|
-
"""Restart"""
|
|
111
|
-
self._excute_cmd(self.restart_cmd)
|
|
112
|
-
|
|
113
|
-
def cancel(self):
|
|
114
|
-
"""Cancel shutdown/restart"""
|
|
115
|
-
self._excute_cmd(self.cancel_cmd)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
class ShutDownizerWin(ShutDownizerEngine):
|
|
119
|
-
"""ShutDownizer - Windows"""
|
|
120
|
-
|
|
121
|
-
def __init__(self) -> None:
|
|
122
|
-
self.shutdown_cmd = "shutdown -f -s -t 0"
|
|
123
|
-
self.cancel_cmd = "shutdown -a"
|
|
124
|
-
|
|
125
|
-
def _punish(self):
|
|
126
|
-
"""Create a `batch` script that shut down computer when boot up"""
|
|
127
|
-
try:
|
|
128
|
-
startup_folder_win = Path(os.getenv("appdata")).joinpath(
|
|
129
|
-
"Microsoft", "Windows", "Start Menu", "Programs", "Startup"
|
|
130
|
-
)
|
|
131
|
-
with open(startup_folder_win.joinpath("system.bat"), "w") as f:
|
|
132
|
-
f.write(self.shutdown_cmd)
|
|
133
|
-
except:
|
|
134
|
-
logger.error("Cannot write file to startup folder")
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
class ShutDownizerMac(ShutDownizerEngine):
|
|
138
|
-
"""ShutDownizer - MacOS"""
|
|
139
|
-
|
|
140
|
-
def __init__(self) -> None:
|
|
141
|
-
self.shutdown_cmd = ["osascript", "-e", 'tell app "System Events" to shut down']
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
class ShutDownizerLinux(ShutDownizerEngine):
|
|
145
|
-
"""ShutDownizer - Linux"""
|
|
146
|
-
|
|
147
|
-
def __init__(self) -> None:
|
|
148
|
-
self.shutdown_cmd = "shutdown -h now"
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
# Run
|
|
152
|
-
###########################################################################
|
|
153
|
-
if __name__ == "__main__":
|
|
154
|
-
logger.setLevel(LogLevel.DEBUG)
|
|
155
|
-
test = ShutDownizer()
|
|
156
|
-
print(ShutDownizerLinux().shutdown())
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Absfuyu: Extra
|
|
3
|
-
--------------
|
|
4
|
-
Extra feature that require additional libraries
|
|
5
|
-
|
|
6
|
-
Version: 1.0.1
|
|
7
|
-
Date updated: 24/11/2023 (dd/mm/yyyy)
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
# Module level
|
|
11
|
-
###########################################################################
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Library
|
|
15
|
-
###########################################################################
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# Function
|
|
19
|
-
###########################################################################
|
|
20
|
-
|
|
21
|
-
# Run
|
|
22
|
-
###########################################################################
|
|
23
|
-
if __name__ == "__main__":
|
|
24
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|