23
23
# imports
24
24
import sys
25
25
import os
26
+ import shutil
26
27
import subprocess
27
28
import platform
28
29
from re import match , I
29
30
from clint .textui import colored , prompt
31
+ import adafruit_platformdetect
30
32
31
33
__version__ = "0.0.0-auto.0"
32
34
__repo__ = "https://github.com/adafruit/Adafruit_Python_Shell.git"
33
35
34
-
36
+ # pylint: disable=too-many-public-methods
35
37
class Shell :
36
38
"""
37
39
Class to help with converting Shell scripts over to Python. Having all
@@ -105,11 +107,20 @@ def error(self, message):
105
107
print (message )
106
108
107
109
@staticmethod
108
- def prompt (message , default = None ):
110
+ def print_colored (message , color ):
111
+ """Print out a message in a specific color"""
112
+ colors = ("red" , "green" , "yellow" , "blue" , "black" , "magenta" , "cyan" , "white" )
113
+ if color in colors :
114
+ colorize = getattr (colored , color )
115
+ print (colorize (message ))
116
+
117
+ def prompt (self , message , * , default = None , force_arg = None ):
109
118
"""
110
119
A Yes/No prompt that accepts optional defaults
111
120
Returns True for Yes and False for No
112
121
"""
122
+ if force_arg is not None and self .argument_exists (force_arg ):
123
+ return True
113
124
if default is None :
114
125
choicebox = "[y/n]"
115
126
else :
@@ -157,24 +168,80 @@ def chdir(self, directory):
157
168
directory = self .getcwd () + "/" + directory
158
169
return os .chdir (directory )
159
170
171
+ @staticmethod
172
+ def path (file_path ):
173
+ """
174
+ Return the relative path. This works for paths starting with ~
175
+ """
176
+ return os .path .expanduser (file_path )
177
+
178
+ @staticmethod
179
+ def home_dir ():
180
+ """
181
+ Return the User's home directory
182
+ """
183
+ return os .path .expanduser ("~" )
184
+
160
185
@staticmethod
161
186
def is_root ():
162
187
"""
163
188
Return whether the current user is logged in as root or has super user access
164
189
"""
165
190
return os .geteuid () == 0
166
191
192
+ @staticmethod
193
+ def script ():
194
+ """
195
+ Return the name of the script that is running
196
+ """
197
+ return sys .argv [0 ]
198
+
199
+ def grep (self , search_term , location ):
200
+ """
201
+ Run the grep command and return the result
202
+ """
203
+ location = self .path (location )
204
+ return self .run_command (
205
+ "grep {} {}" .format (search_term , location ), suppress_message = True
206
+ )
207
+
208
+ def exists (self , location ):
209
+ """
210
+ Check if a path or file exists
211
+ """
212
+ location = self .path (location )
213
+ return os .path .exists (location )
214
+
215
+ def move (self , source , destination ):
216
+ """
217
+ Move a file or directory from source to destination
218
+ """
219
+ source = self .path (source )
220
+ destination = self .path (destination )
221
+ if os .path .exists (source ):
222
+ shutil .move (source , destination )
223
+
224
+ def remove (self , location ):
225
+ """
226
+ Remove a file or directory if it exists
227
+ """
228
+ location = self .path (location )
229
+ if os .path .exists (location ):
230
+ if os .path .isdir (location ):
231
+ shutil .rmtree (location )
232
+ else :
233
+ os .remove (location )
234
+
167
235
def require_root (self ):
168
236
"""
169
237
Check if the current user has root access and exit if not.
170
238
"""
171
239
if not self .is_root ():
172
240
print ("Installer must be run as root." )
173
- print ("Try 'sudo python3 {}'" .format (sys . argv [ 0 ] ))
241
+ print ("Try 'sudo python3 {}'" .format (self . script () ))
174
242
sys .exit (1 )
175
243
176
- @staticmethod
177
- def write_text_file (path , content , append = True ):
244
+ def write_text_file (self , path , content , append = True ):
178
245
"""
179
246
Write the contents to a file at the specified path
180
247
"""
@@ -183,7 +250,7 @@ def write_text_file(path, content, append=True):
183
250
content = "\n " + content
184
251
else :
185
252
mode = "w"
186
- service_file = open (path , mode )
253
+ service_file = open (self . path ( path ) , mode )
187
254
service_file .write (content )
188
255
service_file .close ()
189
256
@@ -192,7 +259,115 @@ def is_linux():
192
259
"""
193
260
Check that we are running linux
194
261
"""
195
- return platform .system () == "Linux"
262
+ return platform .system () == "Linux" or platform .system () == "Darwin"
263
+
264
+ @staticmethod
265
+ def is_armhf ():
266
+ """
267
+ Check if Platform.machine() (same as uname -m) returns an ARM platform that
268
+ supports hardware floating point
269
+ """
270
+ return bool (match ("armv.l" , platform .machine ()))
271
+
272
+ @staticmethod
273
+ def is_armv6 ():
274
+ """
275
+ Check if Platform.machine() returns ARM v6
276
+ """
277
+ return platform .machine () == "armv6l"
278
+
279
+ @staticmethod
280
+ def is_armv7 ():
281
+ """
282
+ Check if Platform.machine() returns ARM v7
283
+ """
284
+ return platform .machine () == "armv7l"
285
+
286
+ @staticmethod
287
+ def is_armv8 ():
288
+ """
289
+ Check if Platform.machine() returns ARM v8
290
+ """
291
+ return platform .machine () == "armv8l"
292
+
293
+ @staticmethod
294
+ def get_arch ():
295
+ """Return a string containing the architecture"""
296
+ return platform .machine ()
297
+
298
+ # pylint: disable=invalid-name
299
+ def get_os (self ):
300
+ """Return a string containing the release which we can use to compare in the script"""
301
+ os_releases = (
302
+ "Raspbian" ,
303
+ "Debian" ,
304
+ "Kano" ,
305
+ "Mate" ,
306
+ "PiTop" ,
307
+ "Ubuntu" ,
308
+ "Darwin" ,
309
+ "Kali" ,
310
+ )
311
+ release = None
312
+ if os .path .exists ("/etc/os-release" ):
313
+ with open ("/etc/os-release" ) as f :
314
+ if "Raspbian" in f .read ():
315
+ release = "Raspian"
316
+ if self .run_command ("command -v apt-get" , suppress_message = True ):
317
+ with open ("/etc/os-release" ) as f :
318
+ release_file = f .read ()
319
+ for opsys in os_releases :
320
+ if opsys in release_file :
321
+ release = opsys
322
+ if os .path .isdir (os .path .expanduser ("~/.kano-settings" )) or os .path .isdir (
323
+ os .path .expanduser ("~/.kanoprofile" )
324
+ ):
325
+ release = "Kano"
326
+ if os .path .isdir (os .path .expanduser ("~/.config/ubuntu-mate" )):
327
+ release = "Mate"
328
+ if platform .system () == "Darwin" :
329
+ release = "Darwin"
330
+ return release
331
+
332
+ def get_raspbian_version (self ):
333
+ """Return a string containing the raspbian version"""
334
+ if self .get_os () != "Raspbian" :
335
+ return None
336
+ raspbian_releases = ("buster" , "stretch" , "jessie" , "wheezy" )
337
+ if os .path .exists ("/etc/os-release" ):
338
+ with open ("/etc/os-release" ) as f :
339
+ release_file = f .read ()
340
+ if "/sid" in release_file :
341
+ return "unstable"
342
+ for raspbian in raspbian_releases :
343
+ if raspbian in release_file :
344
+ return raspbian
345
+ return None
346
+
347
+ # pylint: enable=invalid-name
348
+
349
+ @staticmethod
350
+ def is_raspberry_pi ():
351
+ """
352
+ Use PlatformDetect to check if this is a Raspberry Pi
353
+ """
354
+ detector = adafruit_platformdetect .Detector ()
355
+ return detector .board .any_raspberry_pi
356
+
357
+ @staticmethod
358
+ def get_board_model ():
359
+ """
360
+ Use PlatformDetect to get the board model
361
+ """
362
+ detector = adafruit_platformdetect .Detector ()
363
+ return detector .board .id
364
+
365
+ @staticmethod
366
+ def get_architecture ():
367
+ """
368
+ Get the type of Processor
369
+ """
370
+ return platform .machine ()
196
371
197
372
@staticmethod
198
373
def kernel_minimum (version ):
0 commit comments