2323# imports
2424import sys
2525import os
26+ import shutil
2627import subprocess
2728import platform
2829from re import match , I
2930from clint .textui import colored , prompt
31+ import adafruit_platformdetect
3032
3133__version__ = "0.0.0-auto.0"
3234__repo__ = "https://github.com/adafruit/Adafruit_Python_Shell.git"
3335
34-
36+ # pylint: disable=too-many-public-methods
3537class Shell :
3638 """
3739 Class to help with converting Shell scripts over to Python. Having all
@@ -105,11 +107,20 @@ def error(self, message):
105107 print (message )
106108
107109 @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 ):
109118 """
110119 A Yes/No prompt that accepts optional defaults
111120 Returns True for Yes and False for No
112121 """
122+ if force_arg is not None and self .argument_exists (force_arg ):
123+ return True
113124 if default is None :
114125 choicebox = "[y/n]"
115126 else :
@@ -157,24 +168,80 @@ def chdir(self, directory):
157168 directory = self .getcwd () + "/" + directory
158169 return os .chdir (directory )
159170
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+
160185 @staticmethod
161186 def is_root ():
162187 """
163188 Return whether the current user is logged in as root or has super user access
164189 """
165190 return os .geteuid () == 0
166191
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+
167235 def require_root (self ):
168236 """
169237 Check if the current user has root access and exit if not.
170238 """
171239 if not self .is_root ():
172240 print ("Installer must be run as root." )
173- print ("Try 'sudo python3 {}'" .format (sys . argv [ 0 ] ))
241+ print ("Try 'sudo python3 {}'" .format (self . script () ))
174242 sys .exit (1 )
175243
176- @staticmethod
177- def write_text_file (path , content , append = True ):
244+ def write_text_file (self , path , content , append = True ):
178245 """
179246 Write the contents to a file at the specified path
180247 """
@@ -183,7 +250,7 @@ def write_text_file(path, content, append=True):
183250 content = "\n " + content
184251 else :
185252 mode = "w"
186- service_file = open (path , mode )
253+ service_file = open (self . path ( path ) , mode )
187254 service_file .write (content )
188255 service_file .close ()
189256
@@ -192,7 +259,115 @@ def is_linux():
192259 """
193260 Check that we are running linux
194261 """
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 ()
196371
197372 @staticmethod
198373 def kernel_minimum (version ):
0 commit comments