Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
corpnewt
GitHub Repository: corpnewt/gibMacOS
Path: blob/master/Scripts/utils.py
175 views
1
import sys, os, time, re, json, datetime, ctypes, subprocess
2
3
if os.name == "nt":
4
# Windows
5
import msvcrt
6
else:
7
# Not Windows \o/
8
import select
9
10
class Utils:
11
12
def __init__(self, name = "Python Script", interactive = True):
13
self.name = name
14
self.interactive = interactive
15
# Init our colors before we need to print anything
16
cwd = os.getcwd()
17
os.chdir(os.path.dirname(os.path.realpath(__file__)))
18
if os.path.exists("colors.json"):
19
self.colors_dict = json.load(open("colors.json"))
20
else:
21
self.colors_dict = {}
22
os.chdir(cwd)
23
24
def check_admin(self):
25
# Returns whether or not we're admin
26
try:
27
is_admin = os.getuid() == 0
28
except AttributeError:
29
is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0
30
return is_admin
31
32
def elevate(self, file):
33
# Runs the passed file as admin
34
if self.check_admin():
35
return
36
if os.name == "nt":
37
ctypes.windll.shell32.ShellExecuteW(None, "runas", '"{}"'.format(sys.executable), '"{}"'.format(file), None, 1)
38
else:
39
try:
40
p = subprocess.Popen(["which", "sudo"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
41
c = p.communicate()[0].decode("utf-8", "ignore").replace("\n", "")
42
os.execv(c, [ sys.executable, 'python'] + sys.argv)
43
except:
44
exit(1)
45
46
def compare_versions(self, vers1, vers2, **kwargs):
47
# Helper method to compare ##.## strings
48
#
49
# vers1 < vers2 = True
50
# vers1 = vers2 = None
51
# vers1 > vers2 = False
52
53
# Sanitize the pads
54
pad = str(kwargs.get("pad", ""))
55
sep = str(kwargs.get("separator", "."))
56
57
ignore_case = kwargs.get("ignore_case", True)
58
59
# Cast as strings
60
vers1 = str(vers1)
61
vers2 = str(vers2)
62
63
if ignore_case:
64
vers1 = vers1.lower()
65
vers2 = vers2.lower()
66
67
# Split and pad lists
68
v1_parts, v2_parts = self.pad_length(vers1.split(sep), vers2.split(sep))
69
70
# Iterate and compare
71
for i in range(len(v1_parts)):
72
# Remove non-numeric
73
v1 = ''.join(c.lower() for c in v1_parts[i] if c.isalnum())
74
v2 = ''.join(c.lower() for c in v2_parts[i] if c.isalnum())
75
# Equalize the lengths
76
v1, v2 = self.pad_length(v1, v2)
77
# Compare
78
if str(v1) < str(v2):
79
return True
80
elif str(v1) > str(v2):
81
return False
82
# Never differed - return None, must be equal
83
return None
84
85
def pad_length(self, var1, var2, pad = "0"):
86
# Pads the vars on the left side to make them equal length
87
pad = "0" if len(str(pad)) < 1 else str(pad)[0]
88
if not type(var1) == type(var2):
89
# Type mismatch! Just return what we got
90
return (var1, var2)
91
if len(var1) < len(var2):
92
if type(var1) is list:
93
var1.extend([str(pad) for x in range(len(var2) - len(var1))])
94
else:
95
var1 = "{}{}".format((pad*(len(var2)-len(var1))), var1)
96
elif len(var2) < len(var1):
97
if type(var2) is list:
98
var2.extend([str(pad) for x in range(len(var1) - len(var2))])
99
else:
100
var2 = "{}{}".format((pad*(len(var1)-len(var2))), var2)
101
return (var1, var2)
102
103
def check_path(self, path):
104
# Let's loop until we either get a working path, or no changes
105
test_path = path
106
last_path = None
107
while True:
108
# Bail if we've looped at least once and the path didn't change
109
if last_path != None and last_path == test_path: return None
110
last_path = test_path
111
# Check if we stripped everything out
112
if not len(test_path): return None
113
# Check if we have a valid path
114
if os.path.exists(test_path):
115
return os.path.abspath(test_path)
116
# Check for quotes
117
if test_path[0] == test_path[-1] and test_path[0] in ('"',"'"):
118
test_path = test_path[1:-1]
119
continue
120
# Check for a tilde and expand if needed
121
if test_path[0] == "~":
122
tilde_expanded = os.path.expanduser(test_path)
123
if tilde_expanded != test_path:
124
# Got a change
125
test_path = tilde_expanded
126
continue
127
# Let's check for spaces - strip from the left first, then the right
128
if test_path[0] in (" ","\t"):
129
test_path = test_path[1:]
130
continue
131
if test_path[-1] in (" ","\t"):
132
test_path = test_path[:-1]
133
continue
134
# Maybe we have escapes to handle?
135
test_path = "\\".join([x.replace("\\", "") for x in test_path.split("\\\\")])
136
137
def grab(self, prompt, **kwargs):
138
# Takes a prompt, a default, and a timeout and shows it with that timeout
139
# returning the result
140
timeout = kwargs.get("timeout",0)
141
default = kwargs.get("default","")
142
if not self.interactive:
143
return default
144
# If we don't have a timeout - then skip the timed sections
145
if timeout <= 0:
146
try:
147
if sys.version_info >= (3, 0):
148
return input(prompt)
149
else:
150
return str(raw_input(prompt))
151
except EOFError:
152
return default
153
# Write our prompt
154
sys.stdout.write(prompt)
155
sys.stdout.flush()
156
if os.name == "nt":
157
start_time = time.time()
158
i = ''
159
while True:
160
if msvcrt.kbhit():
161
c = msvcrt.getche()
162
if ord(c) == 13: # enter_key
163
break
164
elif ord(c) >= 32: # space_char
165
i += c.decode() if sys.version_info >= (3,0) and isinstance(c,bytes) else c
166
else:
167
time.sleep(0.02) # Delay for 20ms to prevent CPU workload
168
if len(i) == 0 and (time.time() - start_time) > timeout:
169
break
170
else:
171
i, o, e = select.select( [sys.stdin], [], [], timeout )
172
if i:
173
i = sys.stdin.readline().strip()
174
print('') # needed to move to next line
175
if len(i) > 0:
176
return i
177
else:
178
return default
179
180
def cls(self):
181
if not self.interactive:
182
return
183
if os.name == "nt":
184
os.system("cls")
185
elif os.environ.get("TERM"):
186
os.system("clear")
187
188
def cprint(self, message, **kwargs):
189
strip_colors = kwargs.get("strip_colors", False)
190
if os.name == "nt" or not self.interactive:
191
strip_colors = True
192
reset = u"\u001b[0m"
193
# Requires sys import
194
for c in self.colors:
195
if strip_colors:
196
message = message.replace(c["find"], "")
197
else:
198
message = message.replace(c["find"], c["replace"])
199
if strip_colors:
200
return message
201
sys.stdout.write(message)
202
print(reset)
203
204
# Needs work to resize the string if color chars exist
205
'''# Header drawing method
206
def head(self, text = None, width = 55):
207
if text == None:
208
text = self.name
209
self.cls()
210
print(" {}".format("#"*width))
211
len_text = self.cprint(text, strip_colors=True)
212
mid_len = int(round(width/2-len(len_text)/2)-2)
213
middle = " #{}{}{}#".format(" "*mid_len, len_text, " "*((width - mid_len - len(len_text))-2))
214
if len(middle) > width+1:
215
# Get the difference
216
di = len(middle) - width
217
# Add the padding for the ...#
218
di += 3
219
# Trim the string
220
middle = middle[:-di]
221
newlen = len(middle)
222
middle += "...#"
223
find_list = [ c["find"] for c in self.colors ]
224
225
# Translate colored string to len
226
middle = middle.replace(len_text, text + self.rt_color) # always reset just in case
227
self.cprint(middle)
228
print("#"*width)'''
229
230
# Header drawing method
231
def head(self, text = None, width = 55):
232
if not self.interactive:
233
sys.stderr.write(str(text)+"\n")
234
sys.stderr.flush()
235
return
236
if text is None:
237
text = self.name
238
self.cls()
239
print(" {}".format("#"*width))
240
mid_len = int(round(width/2-len(text)/2)-2)
241
middle = " #{}{}{}#".format(" "*mid_len, text, " "*((width - mid_len - len(text))-2))
242
if len(middle) > width+1:
243
# Get the difference
244
di = len(middle) - width
245
# Add the padding for the ...#
246
di += 3
247
# Trim the string
248
middle = middle[:-di] + "...#"
249
print(middle)
250
print("#"*width)
251
print("")
252
253
def info(self, text):
254
if self.interactive:
255
print(text)
256
else:
257
sys.stderr.write(str(text)+"\n")
258
sys.stderr.flush()
259
260
def resize(self, width, height):
261
print('\033[8;{};{}t'.format(height, width))
262
263
def custom_quit(self):
264
self.head()
265
print("by CorpNewt\n")
266
print("Thanks for testing it out, for bugs/comments/complaints")
267
print("send me a message on Reddit, or check out my GitHub:\n")
268
print("www.reddit.com/u/corpnewt")
269
print("www.github.com/corpnewt\n")
270
# Get the time and wish them a good morning, afternoon, evening, and night
271
hr = datetime.datetime.now().time().hour
272
if hr > 3 and hr < 12:
273
print("Have a nice morning!\n\n")
274
elif hr >= 12 and hr < 17:
275
print("Have a nice afternoon!\n\n")
276
elif hr >= 17 and hr < 21:
277
print("Have a nice evening!\n\n")
278
else:
279
print("Have a nice night!\n\n")
280
exit(0)
281
282